Added ItemData, ItemRender and related stuff
- Added ItemData, ItemSlot, ItemContainer - Added ItemRender - Added a player inventory - Added temporary inventory display - Font now has a scale setting
This commit is contained in:
		@@ -26,6 +26,7 @@ import ru.windcorp.progressia.server.ServerState;
 | 
				
			|||||||
import ru.windcorp.progressia.test.LayerAbout;
 | 
					import ru.windcorp.progressia.test.LayerAbout;
 | 
				
			||||||
import ru.windcorp.progressia.test.LayerTestUI;
 | 
					import ru.windcorp.progressia.test.LayerTestUI;
 | 
				
			||||||
import ru.windcorp.progressia.test.TestContent;
 | 
					import ru.windcorp.progressia.test.TestContent;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.test.inv.TestInventoryGUIManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ClientState {
 | 
					public class ClientState {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,6 +56,7 @@ public class ClientState {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		GUI.addBottomLayer(new LayerWorld(client));
 | 
							GUI.addBottomLayer(new LayerWorld(client));
 | 
				
			||||||
		GUI.addTopLayer(new LayerTestUI());
 | 
							GUI.addTopLayer(new LayerTestUI());
 | 
				
			||||||
 | 
							TestInventoryGUIManager.setup();
 | 
				
			||||||
		GUI.addTopLayer(new LayerAbout());
 | 
							GUI.addTopLayer(new LayerAbout());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,6 +77,12 @@ public class GUI {
 | 
				
			|||||||
			layer.onRemoved();
 | 
								layer.onRemoved();
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public static void updateLayer(Layer layer) {
 | 
				
			||||||
 | 
							modify(layers -> {
 | 
				
			||||||
 | 
								// Do nothing
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void modify(LayerStackModification mod) {
 | 
						private static void modify(LayerStackModification mod) {
 | 
				
			||||||
		MODIFICATION_QUEUE.add(mod);
 | 
							MODIFICATION_QUEUE.add(mod);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,20 +32,23 @@ public class Font {
 | 
				
			|||||||
	private final int style;
 | 
						private final int style;
 | 
				
			||||||
	private final float align;
 | 
						private final float align;
 | 
				
			||||||
	private final Vec4 color;
 | 
						private final Vec4 color;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private final int scale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font(Typeface typeface, int style, float align, Vec4 color) {
 | 
						public Font(Typeface typeface, int style, float align, Vec4 color, int scale) {
 | 
				
			||||||
		this.typeface = typeface;
 | 
							this.typeface = typeface;
 | 
				
			||||||
		this.style = style;
 | 
							this.style = style;
 | 
				
			||||||
		this.align = align;
 | 
							this.align = align;
 | 
				
			||||||
		this.color = color;
 | 
							this.color = color;
 | 
				
			||||||
 | 
							this.scale = scale;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font(Typeface typeface, int style, float align, int color) {
 | 
						public Font(Typeface typeface, int style, float align, int color, int scale) {
 | 
				
			||||||
		this(typeface, style, align, Colors.toVector(color));
 | 
							this(typeface, style, align, Colors.toVector(color), scale);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font(Typeface typeface) {
 | 
						public Font(Typeface typeface) {
 | 
				
			||||||
		this(typeface, Typeface.Style.PLAIN, Typeface.ALIGN_LEFT, Colors.WHITE);
 | 
							this(typeface, Typeface.Style.PLAIN, Typeface.ALIGN_LEFT, Colors.WHITE, 2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font() {
 | 
						public Font() {
 | 
				
			||||||
@@ -67,31 +70,63 @@ public class Font {
 | 
				
			|||||||
	public Vec4 getColor() {
 | 
						public Vec4 getColor() {
 | 
				
			||||||
		return color;
 | 
							return color;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	public Renderable assemble(
 | 
						public int getScale() {
 | 
				
			||||||
		CharSequence chars,
 | 
							return scale;
 | 
				
			||||||
		float maxWidth
 | 
						}
 | 
				
			||||||
	) {
 | 
						
 | 
				
			||||||
		return typeface.assembleStatic(chars, style, align, maxWidth, color);
 | 
						private Renderable applyScale(Renderable unscaled) {
 | 
				
			||||||
 | 
							if (scale == 1) {
 | 
				
			||||||
 | 
								return unscaled;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							return renderer -> {
 | 
				
			||||||
 | 
								renderer.pushTransform().scale(scale);
 | 
				
			||||||
 | 
								unscaled.render(renderer);
 | 
				
			||||||
 | 
								renderer.popTransform();
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Renderable assembleDynamic(
 | 
						public Renderable assemble(CharSequence chars, float maxWidth) {
 | 
				
			||||||
		Supplier<CharSequence> supplier,
 | 
							return applyScale(typeface.assembleStatic(chars, style, align, maxWidth, color));
 | 
				
			||||||
		float maxWidth
 | 
						}
 | 
				
			||||||
	) {
 | 
					
 | 
				
			||||||
		return typeface.assembleDynamic(supplier, style, align, maxWidth, color);
 | 
						public Renderable assembleDynamic(Supplier<CharSequence> supplier, float maxWidth) {
 | 
				
			||||||
 | 
							return applyScale(typeface.assembleDynamic(supplier, style, align, maxWidth, color));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public Renderable assemble(CharSequence chars) {
 | 
				
			||||||
 | 
							return assemble(chars, Float.POSITIVE_INFINITY);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Renderable assembleDynamic(Supplier<CharSequence> supplier) {
 | 
				
			||||||
 | 
							return assembleDynamic(supplier, Float.POSITIVE_INFINITY);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public int getWidth(CharSequence chars, float maxWidth) {
 | 
						public int getWidth(CharSequence chars, float maxWidth) {
 | 
				
			||||||
		return typeface.getWidth(chars, style, align, maxWidth);
 | 
							return scale * typeface.getWidth(chars, style, align, maxWidth);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public int getHeight(CharSequence chars, float maxWidth) {
 | 
						public int getHeight(CharSequence chars, float maxWidth) {
 | 
				
			||||||
		return typeface.getHeight(chars, style, align, maxWidth);
 | 
							return scale * typeface.getHeight(chars, style, align, maxWidth);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Vec2i getSize(CharSequence chars, float maxWidth, Vec2i result) {
 | 
						public Vec2i getSize(CharSequence chars, float maxWidth, Vec2i result) {
 | 
				
			||||||
		return typeface.getSize(chars, style, align, maxWidth, result);
 | 
							result = typeface.getSize(chars, style, align, maxWidth, result);
 | 
				
			||||||
 | 
							result.mul(scale);
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public int getWidth(CharSequence chars) {
 | 
				
			||||||
 | 
							return getWidth(chars, Float.POSITIVE_INFINITY);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public int getHeight(CharSequence chars) {
 | 
				
			||||||
 | 
							return getHeight(chars, Float.POSITIVE_INFINITY);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Vec2i getSize(CharSequence chars, Vec2i result) {
 | 
				
			||||||
 | 
							return getSize(chars, Float.POSITIVE_INFINITY, result);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public boolean supports(char c) {
 | 
						public boolean supports(char c) {
 | 
				
			||||||
@@ -106,7 +141,7 @@ public class Font {
 | 
				
			|||||||
	 * @return the new font
 | 
						 * @return the new font
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public Font withStyle(int style) {
 | 
						public Font withStyle(int style) {
 | 
				
			||||||
		return new Font(getTypeface(), style, getAlign(), getColor());
 | 
							return new Font(getTypeface(), style, getAlign(), getColor(), getScale());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font deriveBold() {
 | 
						public Font deriveBold() {
 | 
				
			||||||
@@ -158,15 +193,19 @@ public class Font {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font withAlign(float align) {
 | 
						public Font withAlign(float align) {
 | 
				
			||||||
		return new Font(getTypeface(), getStyle(), align, getColor());
 | 
							return new Font(getTypeface(), getStyle(), align, getColor(), getScale());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font withColor(Vec4 color) {
 | 
						public Font withColor(Vec4 color) {
 | 
				
			||||||
		return new Font(getTypeface(), getStyle(), getAlign(), color);
 | 
							return new Font(getTypeface(), getStyle(), getAlign(), color, getScale());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font withColor(int color) {
 | 
						public Font withColor(int color) {
 | 
				
			||||||
		return new Font(getTypeface(), getStyle(), getAlign(), color);
 | 
							return new Font(getTypeface(), getStyle(), getAlign(), color, getScale());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public Font withScale(int scale) {
 | 
				
			||||||
 | 
							return new Font(getTypeface(), getStyle(), getAlign(), getColor(), scale);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,10 +45,15 @@ public abstract class BasicButton extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public BasicButton(String name, String label, Font labelFont) {
 | 
						public BasicButton(String name, String label, Font labelFont) {
 | 
				
			||||||
		super(name);
 | 
							super(name);
 | 
				
			||||||
		this.label = new Label(name + ".Label", labelFont, label);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setLayout(new LayoutAlign(10));
 | 
							setLayout(new LayoutAlign(10));
 | 
				
			||||||
		addChild(this.label);
 | 
							
 | 
				
			||||||
 | 
							if (label == null) {
 | 
				
			||||||
 | 
								this.label = null;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.label = new Label(name + ".Label", labelFont, label);
 | 
				
			||||||
 | 
								addChild(this.label);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setFocusable(true);
 | 
							setFocusable(true);
 | 
				
			||||||
		reassembleAt(ARTrigger.HOVER, ARTrigger.FOCUS, ARTrigger.ENABLE);
 | 
							reassembleAt(ARTrigger.HOVER, ARTrigger.FOCUS, ARTrigger.ENABLE);
 | 
				
			||||||
@@ -148,4 +153,8 @@ public abstract class BasicButton extends Component {
 | 
				
			|||||||
		return label;
 | 
							return label;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						public boolean hasLabel() {
 | 
				
			||||||
 | 
							return label != null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,10 +25,13 @@ import ru.windcorp.progressia.client.graphics.Colors;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public class Button extends BasicButton {
 | 
					public class Button extends BasicButton {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static final int MARGIN = 2;
 | 
				
			||||||
 | 
						public static final int BORDER = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Button(String name, String label, Font labelFont) {
 | 
						public Button(String name, String label, Font labelFont) {
 | 
				
			||||||
		super(name, label, labelFont);
 | 
							super(name, label, labelFont);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	public Button(String name, String label) {
 | 
						public Button(String name, String label) {
 | 
				
			||||||
		this(name, label, new Font());
 | 
							this(name, label, new Font());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -36,7 +39,7 @@ public class Button extends BasicButton {
 | 
				
			|||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	protected void assembleSelf(RenderTarget target) {
 | 
						protected void assembleSelf(RenderTarget target) {
 | 
				
			||||||
		// Border
 | 
							// Border
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		Vec4 borderColor;
 | 
							Vec4 borderColor;
 | 
				
			||||||
		if (isPressed() || isHovered() || isFocused()) {
 | 
							if (isPressed() || isHovered() || isFocused()) {
 | 
				
			||||||
			borderColor = Colors.BLUE;
 | 
								borderColor = Colors.BLUE;
 | 
				
			||||||
@@ -44,9 +47,9 @@ public class Button extends BasicButton {
 | 
				
			|||||||
			borderColor = Colors.LIGHT_GRAY;
 | 
								borderColor = Colors.LIGHT_GRAY;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		target.fill(getX(), getY(), getWidth(), getHeight(), borderColor);
 | 
							target.fill(getX(), getY(), getWidth(), getHeight(), borderColor);
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		// Inside area
 | 
							// Inside area
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if (isPressed()) {
 | 
							if (isPressed()) {
 | 
				
			||||||
			// Do nothing
 | 
								// Do nothing
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
@@ -56,22 +59,30 @@ public class Button extends BasicButton {
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				backgroundColor = Colors.WHITE;
 | 
									backgroundColor = Colors.WHITE;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, backgroundColor);
 | 
								target.fill(
 | 
				
			||||||
 | 
									getX() + MARGIN,
 | 
				
			||||||
 | 
									getY() + MARGIN,
 | 
				
			||||||
 | 
									getWidth() - 2 * MARGIN,
 | 
				
			||||||
 | 
									getHeight() - 2 * MARGIN,
 | 
				
			||||||
 | 
									backgroundColor
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		// Change label font color
 | 
							// Change label font color
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if (isPressed()) {
 | 
							if (hasLabel()) {
 | 
				
			||||||
			getLabel().setFont(getLabel().getFont().withColor(Colors.WHITE));
 | 
								if (isPressed()) {
 | 
				
			||||||
		} else {
 | 
									getLabel().setFont(getLabel().getFont().withColor(Colors.WHITE));
 | 
				
			||||||
			getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
 | 
								} else {
 | 
				
			||||||
 | 
									getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	protected void postAssembleSelf(RenderTarget target) {
 | 
						protected void postAssembleSelf(RenderTarget target) {
 | 
				
			||||||
		// Apply disable tint
 | 
							// Apply disable tint
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if (!isEnabled()) {
 | 
							if (!isEnabled()) {
 | 
				
			||||||
			target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
 | 
								target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ public class DynamicLabel extends Component {
 | 
				
			|||||||
		super(name);
 | 
							super(name);
 | 
				
			||||||
		this.font = font;
 | 
							this.font = font;
 | 
				
			||||||
		this.contents = contents;
 | 
							this.contents = contents;
 | 
				
			||||||
		setPreferredSize(width, font.getHeight("", Float.POSITIVE_INFINITY) * 2);
 | 
							setPreferredSize(width, font.getHeight("", Float.POSITIVE_INFINITY));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Font getFont() {
 | 
						public Font getFont() {
 | 
				
			||||||
@@ -46,7 +46,7 @@ public class DynamicLabel extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	protected void assembleSelf(RenderTarget target) {
 | 
						protected void assembleSelf(RenderTarget target) {
 | 
				
			||||||
		target.pushTransform(new Mat4().identity().translate(getX(), getY(), -1000).scale(2));
 | 
							target.pushTransform(new Mat4().identity().translate(getX(), getY(), -1000));
 | 
				
			||||||
		target.addCustomRenderer(font.assembleDynamic(getContentSupplier(), Float.POSITIVE_INFINITY));
 | 
							target.addCustomRenderer(font.assembleDynamic(getContentSupplier(), Float.POSITIVE_INFINITY));
 | 
				
			||||||
		target.popTransform();
 | 
							target.popTransform();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,7 +70,7 @@ public class Label extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public void update() {
 | 
						public void update() {
 | 
				
			||||||
		currentText = contents.get();
 | 
							currentText = contents.get();
 | 
				
			||||||
		currentSize = font.getSize(currentText, maxWidth, null).mul(2);
 | 
							currentSize = font.getSize(currentText, maxWidth, null);
 | 
				
			||||||
		requestReassembly();
 | 
							requestReassembly();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -99,12 +99,8 @@ public class Label extends Component {
 | 
				
			|||||||
	protected void assembleSelf(RenderTarget target) {
 | 
						protected void assembleSelf(RenderTarget target) {
 | 
				
			||||||
		float startX = getX() + font.getAlign() * (getWidth() - currentSize.x);
 | 
							float startX = getX() + font.getAlign() * (getWidth() - currentSize.x);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		target.pushTransform(
 | 
							target.pushTransform(new Mat4().identity().translate(startX, getY(), 0));
 | 
				
			||||||
			new Mat4().identity().translate(startX, getY(), 0).scale(2)
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		target.addCustomRenderer(font.assemble(currentText, maxWidth));
 | 
							target.addCustomRenderer(font.assemble(currentText, maxWidth));
 | 
				
			||||||
 | 
					 | 
				
			||||||
		target.popTransform();
 | 
							target.popTransform();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,20 +15,23 @@
 | 
				
			|||||||
 * You should have received a copy of the GNU General Public License
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
package ru.windcorp.progressia.client.graphics.world;
 | 
					package ru.windcorp.progressia.client.graphics.world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.apache.logging.log4j.LogManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ru.windcorp.progressia.client.Client;
 | 
					import ru.windcorp.progressia.client.Client;
 | 
				
			||||||
import ru.windcorp.progressia.client.world.WorldRender;
 | 
					import ru.windcorp.progressia.client.world.WorldRender;
 | 
				
			||||||
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
 | 
					import ru.windcorp.progressia.client.world.entity.EntityRenderable;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
					import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class LocalPlayer {
 | 
					public class LocalPlayer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final Client client;
 | 
						private final Client client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private long entityId = EntityData.NULL_ENTITY_ID;
 | 
						private long entityId = EntityData.NULL_ENTITY_ID;
 | 
				
			||||||
	private EntityData lastKnownEntity = null;
 | 
						private EntityDataPlayer lastKnownEntity = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final Selection selection = new Selection();
 | 
						private final Selection selection = new Selection();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,19 +62,31 @@ public class LocalPlayer {
 | 
				
			|||||||
		return getEntity() != null;
 | 
							return getEntity() != null;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public EntityData getEntity() {
 | 
						public EntityDataPlayer getEntity() {
 | 
				
			||||||
		if (!hasEntityId()) {
 | 
							if (!hasEntityId()) {
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		EntityData entity = getClient().getWorld().getData().getEntity(getEntityId());
 | 
							EntityData entity = getClient().getWorld().getData().getEntity(getEntityId());
 | 
				
			||||||
 | 
							EntityDataPlayer playerEntity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (entity != lastKnownEntity) {
 | 
							if (entity == null || entity instanceof EntityDataPlayer) {
 | 
				
			||||||
			getClient().onLocalPlayerEntityChanged(entity, lastKnownEntity);
 | 
								playerEntity = (EntityDataPlayer) entity;
 | 
				
			||||||
			this.lastKnownEntity = entity;
 | 
							} else {
 | 
				
			||||||
 | 
								LogManager.getLogger().warn(
 | 
				
			||||||
 | 
									"Entity ID of local player is {}, but the entity is not an EntityDataPlayer: {}",
 | 
				
			||||||
 | 
									EntityData.formatEntityId(getEntityId()),
 | 
				
			||||||
 | 
									entity
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								playerEntity = null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return entity;
 | 
							if (playerEntity != lastKnownEntity) {
 | 
				
			||||||
 | 
								getClient().onLocalPlayerEntityChanged(playerEntity, lastKnownEntity);
 | 
				
			||||||
 | 
								this.lastKnownEntity = playerEntity;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return playerEntity;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Selection getSelection() {
 | 
						public Selection getSelection() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.client.world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.model.Renderable;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class UpdatingRenderable implements Renderable {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private long stateComputedForFrame = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Updates the state of this model. This method is invoked exactly once per
 | 
				
			||||||
 | 
						 * renderable per frame before this model is queried for the first time.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						protected void update() {
 | 
				
			||||||
 | 
							// Do nothing
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						protected void updateIfNecessary() {
 | 
				
			||||||
 | 
							if (stateComputedForFrame != GraphicsInterface.getFramesRendered()) {
 | 
				
			||||||
 | 
								update();
 | 
				
			||||||
 | 
								stateComputedForFrame = GraphicsInterface.getFramesRendered();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public final void render(ShapeRenderHelper renderer) {
 | 
				
			||||||
 | 
							updateIfNecessary();
 | 
				
			||||||
 | 
							doRender(renderer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						protected abstract void doRender(ShapeRenderHelper renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -19,45 +19,18 @@
 | 
				
			|||||||
package ru.windcorp.progressia.client.world.entity;
 | 
					package ru.windcorp.progressia.client.world.entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import glm.vec._3.Vec3;
 | 
					import glm.vec._3.Vec3;
 | 
				
			||||||
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
 | 
					import ru.windcorp.progressia.client.world.UpdatingRenderable;
 | 
				
			||||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
 | 
					 | 
				
			||||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
 | 
					 | 
				
			||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
					import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.generic.EntityGeneric;
 | 
					import ru.windcorp.progressia.common.world.generic.EntityGeneric;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public abstract class EntityRenderable implements Renderable, EntityGeneric {
 | 
					public abstract class EntityRenderable extends UpdatingRenderable implements EntityGeneric {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final EntityData data;
 | 
						private final EntityData data;
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private long stateComputedForFrame = -1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public EntityRenderable(EntityData data) {
 | 
						public EntityRenderable(EntityData data) {
 | 
				
			||||||
		this.data = data;
 | 
							this.data = data;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Updates the state of this model. This method is invoked exactly once per
 | 
					 | 
				
			||||||
	 * renderable per frame before this entity is queried for the first time.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	protected void update() {
 | 
					 | 
				
			||||||
		// Do nothing
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private void updateIfNecessary() {
 | 
					 | 
				
			||||||
		if (stateComputedForFrame != GraphicsInterface.getFramesRendered()) {
 | 
					 | 
				
			||||||
			update();
 | 
					 | 
				
			||||||
			stateComputedForFrame = GraphicsInterface.getFramesRendered();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	@Override
 | 
					 | 
				
			||||||
	public final void render(ShapeRenderHelper renderer) {
 | 
					 | 
				
			||||||
		updateIfNecessary();
 | 
					 | 
				
			||||||
		doRender(renderer);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	protected abstract void doRender(ShapeRenderHelper renderer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public EntityData getData() {
 | 
						public EntityData getData() {
 | 
				
			||||||
		return data;
 | 
							return data;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.client.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.util.namespaces.Namespaced;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class ItemRender extends Namespaced {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ItemRender(String id) {
 | 
				
			||||||
 | 
							super(id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public abstract ItemRenderable createRenderable(ItemData data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.client.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.texture.Atlases;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.texture.SimpleTexture;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.texture.Texture;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.texture.Atlases.AtlasGroup;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.resource.ResourceManager;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ItemRenderRegistry extends NamespacedInstanceRegistry<ItemRender> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final ItemRenderRegistry INSTANCE = new ItemRenderRegistry();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final AtlasGroup ITEMS_ATLAS_GROUP = new AtlasGroup("Items", 1 << 12);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static ItemRenderRegistry getInstance() {
 | 
				
			||||||
 | 
							return INSTANCE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static Texture getItemTexture(String name) {
 | 
				
			||||||
 | 
							return new SimpleTexture(
 | 
				
			||||||
 | 
								Atlases.getSprite(
 | 
				
			||||||
 | 
									ResourceManager.getTextureResource("items/" + name),
 | 
				
			||||||
 | 
									ITEMS_ATLAS_GROUP
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static AtlasGroup getItemsAtlasGroup() {
 | 
				
			||||||
 | 
							return ITEMS_ATLAS_GROUP;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.client.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import glm.vec._3.Vec3;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.Colors;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.backend.Usage;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.model.Renderable;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.model.Shape;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.model.ShapeParts;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.texture.Texture;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ItemRenderSimple extends ItemRender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private Texture texture;
 | 
				
			||||||
 | 
						private Renderable renderable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ItemRenderSimple(String id, Texture texture) {
 | 
				
			||||||
 | 
							super(id);
 | 
				
			||||||
 | 
							this.texture = texture;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							this.renderable = new Shape(
 | 
				
			||||||
 | 
								Usage.STATIC, 
 | 
				
			||||||
 | 
								FlatRenderProgram.getDefault(),
 | 
				
			||||||
 | 
								ShapeParts.createRectangle(
 | 
				
			||||||
 | 
									FlatRenderProgram.getDefault(),
 | 
				
			||||||
 | 
									texture,
 | 
				
			||||||
 | 
									Colors.WHITE,
 | 
				
			||||||
 | 
									new Vec3(0, 0, 0),
 | 
				
			||||||
 | 
									new Vec3(24, 0, 0),
 | 
				
			||||||
 | 
									new Vec3(0, 24, 0),
 | 
				
			||||||
 | 
									false
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public Texture getTexture() {
 | 
				
			||||||
 | 
							return texture;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public ItemRenderable createRenderable(ItemData data) {
 | 
				
			||||||
 | 
							return new ItemRenderable(data) {
 | 
				
			||||||
 | 
								@Override
 | 
				
			||||||
 | 
								protected void doRender(ShapeRenderHelper renderer) {
 | 
				
			||||||
 | 
									renderable.render(renderer);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.client.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.world.UpdatingRenderable;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class ItemRenderable extends UpdatingRenderable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final ItemData data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ItemRenderable(ItemData data) {
 | 
				
			||||||
 | 
							this.data = data;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public ItemData getData() {
 | 
				
			||||||
 | 
							return data;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -65,6 +65,8 @@ public class Units {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Volume
 | 
						// Volume
 | 
				
			||||||
	public static final float CUBIC_CENTIMETERS = CENTIMETERS * CENTIMETERS * CENTIMETERS;
 | 
						public static final float CUBIC_CENTIMETERS = CENTIMETERS * CENTIMETERS * CENTIMETERS;
 | 
				
			||||||
 | 
						@RegisteredUnit("L")
 | 
				
			||||||
 | 
						public static final float LITERS = (10 * CENTIMETERS) * (10 * CENTIMETERS) * (10 * CENTIMETERS);
 | 
				
			||||||
	public static final float CUBIC_METERS = METERS * METERS * METERS;
 | 
						public static final float CUBIC_METERS = METERS * METERS * METERS;
 | 
				
			||||||
	public static final float CUBIC_MILLIMETERS = MILLIMETERS * MILLIMETERS * MILLIMETERS;
 | 
						public static final float CUBIC_MILLIMETERS = MILLIMETERS * MILLIMETERS * MILLIMETERS;
 | 
				
			||||||
	public static final float CUBIC_KILOMETERS = KILOMETERS * KILOMETERS * KILOMETERS;
 | 
						public static final float CUBIC_KILOMETERS = KILOMETERS * KILOMETERS * KILOMETERS;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,6 +42,16 @@ public class StatefulObjectRegistry<T extends StatefulObject> {
 | 
				
			|||||||
		 */
 | 
							 */
 | 
				
			||||||
		T build();
 | 
							T build();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@FunctionalInterface
 | 
				
			||||||
 | 
						public static interface IdFactory<T> {
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * Initializes a new, independent instance of the stateful object.
 | 
				
			||||||
 | 
							 * 
 | 
				
			||||||
 | 
							 * @return the created object
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							T build(String id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected static class Type<T> extends Namespaced {
 | 
						protected static class Type<T> extends Namespaced {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,5 +120,9 @@ public class StatefulObjectRegistry<T extends StatefulObject> {
 | 
				
			|||||||
	public void register(String id, Factory<T> factory) {
 | 
						public void register(String id, Factory<T> factory) {
 | 
				
			||||||
		registry.register(new Type<>(id, factory));
 | 
							registry.register(new Type<>(id, factory));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public void register(String id, IdFactory<T> factory) {
 | 
				
			||||||
 | 
							register(id, () -> factory.build(id));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.entity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.Units;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.collision.AABB;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.ObjectStateField;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.DefaultItemContainer;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemContainer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class EntityDataPlayer extends EntityData {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private final ObjectStateField<DefaultItemContainer> inventory = field("Core:Inventory").setShared().def(
 | 
				
			||||||
 | 
							() -> new DefaultItemContainer("Core:PlayerInventory", Units.get(15, "kg"), Units.get(50, "L"))
 | 
				
			||||||
 | 
						).build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public EntityDataPlayer(String id) {
 | 
				
			||||||
 | 
							super(id);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							setCollisionModel(new AABB(0, 0, 1.8f / 2, 0.8f, 0.8f, 1.8f));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public ItemContainer getInventory() {
 | 
				
			||||||
 | 
							return inventory.get(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.generic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface ItemGeneric {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						String getId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class DefaultItemContainer extends ItemContainer {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private final float massLimit;
 | 
				
			||||||
 | 
						private final float volumeLimit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public DefaultItemContainer(String id, float massLimit, float volumeLimit) {
 | 
				
			||||||
 | 
							super(id, new ArrayList<>());
 | 
				
			||||||
 | 
							this.massLimit = massLimit;
 | 
				
			||||||
 | 
							this.volumeLimit = volumeLimit;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public void addSlots(int amount) {
 | 
				
			||||||
 | 
							synchronized (getSlots()) {
 | 
				
			||||||
 | 
								((ArrayList<ItemSlot>) list).ensureCapacity(list.size() + amount);
 | 
				
			||||||
 | 
								for (int i = 0; i < amount; ++i) {
 | 
				
			||||||
 | 
									list.add(new ItemSlot());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public float getMassLimit() {
 | 
				
			||||||
 | 
							return massLimit;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public float getVolumeLimit() {
 | 
				
			||||||
 | 
							return volumeLimit;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,165 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.DataInput;
 | 
				
			||||||
 | 
					import java.io.DataOutput;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.Encodable;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.IOContext;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.util.namespaces.Namespaced;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A collection of {@link ItemSlot}s representing a single storage unit. The set
 | 
				
			||||||
 | 
					 * of slots is dynamic: new slots may be added and existing slots may be removed
 | 
				
			||||||
 | 
					 * at will. A container may impose limits on the maximum total mass and volume
 | 
				
			||||||
 | 
					 * of its contents, although this is not enforced on data structure level.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public abstract class ItemContainer extends Namespaced implements Encodable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final List<ItemSlot> synchronizedListView;
 | 
				
			||||||
 | 
						protected final List<ItemSlot> list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ItemContainer(String id, List<ItemSlot> list) {
 | 
				
			||||||
 | 
							super(id);
 | 
				
			||||||
 | 
							this.list = list;
 | 
				
			||||||
 | 
							this.synchronizedListView = Collections.synchronizedList(list);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Retrieves the modifiable {@link List} of all slots. Edits commissioned
 | 
				
			||||||
 | 
						 * through the returned object update the state of the container.
 | 
				
			||||||
 | 
						 * <p>
 | 
				
			||||||
 | 
						 * It should be assumed that the returned list is
 | 
				
			||||||
 | 
						 * {@linkplain Collections#synchronizedList(List) synchronized}.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return a list view of this container
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public final List<ItemSlot> getSlots() {
 | 
				
			||||||
 | 
							return this.synchronizedListView;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Appends additional empty slots to the end of this container.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @param amount the amount of slots to add
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public abstract void addSlots(int amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Computes and returns the mass limit that the container imposes.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the maximum allowed total mass of the container's contents, or
 | 
				
			||||||
 | 
						 *         {@code Float.POSITIVE_INFINITY} to indicate that no upper
 | 
				
			||||||
 | 
						 *         boundary is set
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public abstract float getMassLimit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Computes and returns the volume limit that the container imposes.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the maximum allowed total volume of the container's contents, or
 | 
				
			||||||
 | 
						 *         {@code Float.POSITIVE_INFINITY} to indicate that no upper
 | 
				
			||||||
 | 
						 *         boundary is set
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public abstract float getVolumeLimit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public synchronized void read(DataInput input, IOContext context) throws IOException {
 | 
				
			||||||
 | 
							List<ItemSlot> slots = getSlots();
 | 
				
			||||||
 | 
							synchronized (slots) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int needSlots = input.readInt();
 | 
				
			||||||
 | 
								int hasSlots = slots.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int costOfResetting = needSlots;
 | 
				
			||||||
 | 
								int costOfEditing = Math.abs(needSlots - hasSlots);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (costOfResetting < costOfEditing) {
 | 
				
			||||||
 | 
									slots.clear();
 | 
				
			||||||
 | 
									addSlots(needSlots);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									while (slots.size() > needSlots) {
 | 
				
			||||||
 | 
										getSlots().remove(slots.size() - 1);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (slots.size() < needSlots) {
 | 
				
			||||||
 | 
										addSlots(needSlots - slots.size());
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (int i = 0; i < needSlots; ++i) {
 | 
				
			||||||
 | 
									slots.get(i).read(input, context);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public synchronized void write(DataOutput output, IOContext context) throws IOException {
 | 
				
			||||||
 | 
							List<ItemSlot> slots = getSlots();
 | 
				
			||||||
 | 
							synchronized (slots) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								output.writeInt(slots.size());
 | 
				
			||||||
 | 
								for (int i = 0; i < slots.size(); ++i) {
 | 
				
			||||||
 | 
									slots.get(i).write(output, context);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public void copy(Encodable destination) {
 | 
				
			||||||
 | 
							ItemContainer container = (ItemContainer) destination;
 | 
				
			||||||
 | 
							List<ItemSlot> mySlots = this.getSlots();
 | 
				
			||||||
 | 
							List<ItemSlot> containerSlots = container.getSlots();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							synchronized (mySlots) {
 | 
				
			||||||
 | 
								synchronized (containerSlots) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									int needSlots = mySlots.size();
 | 
				
			||||||
 | 
									int hasSlots = containerSlots.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									int costOfResetting = needSlots;
 | 
				
			||||||
 | 
									int costOfEditing = Math.abs(needSlots - hasSlots);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (costOfResetting < costOfEditing) {
 | 
				
			||||||
 | 
										containerSlots.clear();
 | 
				
			||||||
 | 
										container.addSlots(needSlots);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										while (containerSlots.size() > needSlots) {
 | 
				
			||||||
 | 
											getSlots().remove(containerSlots.size() - 1);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (containerSlots.size() < needSlots) {
 | 
				
			||||||
 | 
											addSlots(needSlots - containerSlots.size());
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									for (int i = 0; i < needSlots; ++i) {
 | 
				
			||||||
 | 
										mySlots.get(i).copy(containerSlots.get(i));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.IntStateField;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.StatefulObject;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.generic.ItemGeneric;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A collection of identical items identified by their ID, properties and
 | 
				
			||||||
 | 
					 * amount, able to reside in a slot. Also known as an item stack.
 | 
				
			||||||
 | 
					 * <p>
 | 
				
			||||||
 | 
					 * An empty stack does not have an {@code ItemData} representation; stack size
 | 
				
			||||||
 | 
					 * is at least 1.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public abstract class ItemData extends StatefulObject implements ItemGeneric {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final IntStateField size = field("Core:Size").setShared().ofInt().build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ItemData(String id) {
 | 
				
			||||||
 | 
							super(ItemDataRegistry.getInstance(), id);
 | 
				
			||||||
 | 
							size.setNow(this, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Returns the amount of individual items represented by this item stack.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the size of this stack
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public final int getSize() {
 | 
				
			||||||
 | 
							return size.get(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Sets the amount of items represented by this item stack.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @param size the new size of this stack, strictly positive
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public final void setSizeNow(int size) {
 | 
				
			||||||
 | 
							if (size <= 0) {
 | 
				
			||||||
 | 
								throw new IllegalArgumentException("size cannot be negative, given size " + size);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							this.size.setNow(this, size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Computes and returns the total mass of this item stack. It is defined as
 | 
				
			||||||
 | 
						 * the item's unit mass (see {@link #getUnitMass()}) multiplied by the
 | 
				
			||||||
 | 
						 * amount of items in the stack.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the mass of this stack
 | 
				
			||||||
 | 
						 * @see #getUnitMass()
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public final float getMass() {
 | 
				
			||||||
 | 
							return getUnitMass() * getSize();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Computes and returns the mass of a single unit (single item) of this item
 | 
				
			||||||
 | 
						 * stack.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the mass of a single item in this stack
 | 
				
			||||||
 | 
						 * @see #getMass()
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public abstract float getUnitMass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Computes and returns the total volume of this item stack. It is defined
 | 
				
			||||||
 | 
						 * as the item's unit volume (see {@link #getUnitVolume()}) multiplied by
 | 
				
			||||||
 | 
						 * the amount of items in the stack.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the mass of this stack
 | 
				
			||||||
 | 
						 * @see #getUnitVolume()
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public final float getVolume() {
 | 
				
			||||||
 | 
							return getUnitVolume() * getSize();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Computes and returns the volume of a single unit (single item) of this
 | 
				
			||||||
 | 
						 * item stack.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the volume of a single item in this stack
 | 
				
			||||||
 | 
						 * @see #getVolume()
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public abstract float getUnitVolume();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.StatefulObjectRegistry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ItemDataRegistry extends StatefulObjectRegistry<ItemData> {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private static final ItemDataRegistry INSTANCE = new ItemDataRegistry();
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public static ItemDataRegistry getInstance() {
 | 
				
			||||||
 | 
							return INSTANCE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ItemDataSimple extends ItemData {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final float unitMass;
 | 
				
			||||||
 | 
						private final float unitVolume;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public ItemDataSimple(String id, float unitMass, float unitVolume) {
 | 
				
			||||||
 | 
							super(id);
 | 
				
			||||||
 | 
							this.unitMass = unitMass;
 | 
				
			||||||
 | 
							this.unitVolume = unitVolume;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public float getUnitMass() {
 | 
				
			||||||
 | 
							return unitMass;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public float getUnitVolume() {
 | 
				
			||||||
 | 
							return unitVolume;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.common.world.item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.DataInput;
 | 
				
			||||||
 | 
					import java.io.DataOutput;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.Encodable;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.state.IOContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * An entity optionally containing an {@link ItemData}. Item slots are typically
 | 
				
			||||||
 | 
					 * found in {@link ItemContainer}s.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class ItemSlot implements Encodable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private ItemData contents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Retrieves the contents of this slot.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @return the stored {@link ItemData} or {@code null}
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public synchronized final ItemData getContents() {
 | 
				
			||||||
 | 
							return contents;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Sets the new contents of this slot. If an item stack was present
 | 
				
			||||||
 | 
						 * previously, it is discarded.
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @param contents the new contents of this slot or {@code null} to clear
 | 
				
			||||||
 | 
						 *                 the slot
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public synchronized final void setContents(ItemData contents) {
 | 
				
			||||||
 | 
							this.contents = contents;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public synchronized void read(DataInput input, IOContext context) throws IOException {
 | 
				
			||||||
 | 
							if (input.readBoolean()) {
 | 
				
			||||||
 | 
								String id = input.readUTF();
 | 
				
			||||||
 | 
								contents = ItemDataRegistry.getInstance().create(id);
 | 
				
			||||||
 | 
								contents.read(input, context);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								contents = null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public synchronized void write(DataOutput output, IOContext context) throws IOException {
 | 
				
			||||||
 | 
							output.writeBoolean(contents != null);
 | 
				
			||||||
 | 
							if (contents != null) {
 | 
				
			||||||
 | 
								output.writeUTF(contents.getId());
 | 
				
			||||||
 | 
								contents.write(output, context);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public void copy(Encodable destination) {
 | 
				
			||||||
 | 
							ItemSlot slot = (ItemSlot) destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this.contents == null) {
 | 
				
			||||||
 | 
								slot.contents = null;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (slot.contents == null || !slot.contents.isLike(this.contents)) {
 | 
				
			||||||
 | 
									slot.contents = ItemDataRegistry.getInstance().create(this.contents.getId());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								this.contents.copy(slot.contents);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,7 +25,10 @@ import java.util.Collections;
 | 
				
			|||||||
import glm.vec._3.Vec3;
 | 
					import glm.vec._3.Vec3;
 | 
				
			||||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
 | 
					import ru.windcorp.progressia.common.util.crash.CrashReports;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
					import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
 | 
					import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemData;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemDataRegistry;
 | 
				
			||||||
import ru.windcorp.progressia.server.events.PlayerJoinedEvent;
 | 
					import ru.windcorp.progressia.server.events.PlayerJoinedEvent;
 | 
				
			||||||
import ru.windcorp.progressia.test.TestContent;
 | 
					import ru.windcorp.progressia.test.TestContent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,16 +61,22 @@ public class PlayerManager {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private EntityData spawnPlayerEntity(String login) {
 | 
						private EntityDataPlayer spawnPlayerEntity(String login) {
 | 
				
			||||||
		EntityData player = EntityDataRegistry.getInstance().create("Test:Player");
 | 
							EntityDataPlayer player = (EntityDataPlayer) EntityDataRegistry.getInstance().create("Core:Player");
 | 
				
			||||||
 | 
					 | 
				
			||||||
		player.setEntityId(TestContent.PLAYER_ENTITY_ID);
 | 
					 | 
				
			||||||
		player.setPosition(getServer().getWorld().getGenerator().suggestSpawnLocation());
 | 
					 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 | 
							player.getInventory().addSlots(10);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							ItemData stack = ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream");
 | 
				
			||||||
 | 
							stack.setSizeNow(5);
 | 
				
			||||||
 | 
							player.getInventory().getSlots().get(3).setContents(stack);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							player.getInventory().getSlots().get(6).setContents(ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							player.setPosition(getServer().getWorld().getGenerator().suggestSpawnLocation());
 | 
				
			||||||
		player.setUpVector(new Vec3(0, 0, 1));
 | 
							player.setUpVector(new Vec3(0, 0, 1));
 | 
				
			||||||
		player.setLookingAt(new Vec3(2, 1, 0));
 | 
							player.setLookingAt(new Vec3(2, 1, 0));
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		getServer().getWorld().getData().addEntity(player);
 | 
							getServer().getWorld().spawnEntity(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return player;
 | 
							return player;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ import glm.vec._3.Vec3;
 | 
				
			|||||||
import glm.vec._3.i.Vec3i;
 | 
					import glm.vec._3.i.Vec3i;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
 | 
					import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
					import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
 | 
				
			||||||
import ru.windcorp.progressia.server.world.block.BlockLogic;
 | 
					import ru.windcorp.progressia.server.world.block.BlockLogic;
 | 
				
			||||||
import ru.windcorp.progressia.server.world.block.TickableBlock;
 | 
					import ru.windcorp.progressia.server.world.block.TickableBlock;
 | 
				
			||||||
import ru.windcorp.progressia.server.world.context.ServerBlockContext;
 | 
					import ru.windcorp.progressia.server.world.context.ServerBlockContext;
 | 
				
			||||||
@@ -36,7 +37,7 @@ public class TestBlockLogicStatieSpawner extends BlockLogic implements TickableB
 | 
				
			|||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void tick(ServerBlockContext context) {
 | 
						public void tick(ServerBlockContext context) {
 | 
				
			||||||
		Vec3i loc = context.toAbsolute(context.getLocation(), null);
 | 
							Vec3i loc = context.toAbsolute(context.getLocation(), null);
 | 
				
			||||||
		EntityData entity = new TestEntityDataStatie();
 | 
							EntityData entity = EntityDataRegistry.getInstance().create("Test:Statie");
 | 
				
			||||||
		entity.setPosition(new Vec3(loc.x, loc.y, loc.z));
 | 
							entity.setPosition(new Vec3(loc.x, loc.y, loc.z));
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		context.addEntity(entity);
 | 
							context.addEntity(entity);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ package ru.windcorp.progressia.test;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import static ru.windcorp.progressia.client.world.block.BlockRenderRegistry.getBlockTexture;
 | 
					import static ru.windcorp.progressia.client.world.block.BlockRenderRegistry.getBlockTexture;
 | 
				
			||||||
import static ru.windcorp.progressia.client.world.tile.TileRenderRegistry.getTileTexture;
 | 
					import static ru.windcorp.progressia.client.world.tile.TileRenderRegistry.getTileTexture;
 | 
				
			||||||
 | 
					import static ru.windcorp.progressia.client.world.item.ItemRenderRegistry.getItemTexture;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
@@ -27,7 +28,6 @@ import java.util.Comparator;
 | 
				
			|||||||
import java.util.HashSet;
 | 
					import java.util.HashSet;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
import java.util.function.Consumer;
 | 
					 | 
				
			||||||
import org.lwjgl.glfw.GLFW;
 | 
					import org.lwjgl.glfw.GLFW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import glm.vec._3.i.Vec3i;
 | 
					import glm.vec._3.i.Vec3i;
 | 
				
			||||||
@@ -42,15 +42,21 @@ import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerRegistry;
 | 
				
			|||||||
import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSimple;
 | 
					import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSimple;
 | 
				
			||||||
import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface;
 | 
					import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface;
 | 
				
			||||||
import ru.windcorp.progressia.client.world.entity.*;
 | 
					import ru.windcorp.progressia.client.world.entity.*;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.world.item.ItemRender;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.world.item.ItemRenderRegistry;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.world.item.ItemRenderSimple;
 | 
				
			||||||
import ru.windcorp.progressia.client.world.tile.*;
 | 
					import ru.windcorp.progressia.client.world.tile.*;
 | 
				
			||||||
import ru.windcorp.progressia.common.collision.AABB;
 | 
					import ru.windcorp.progressia.common.Units;
 | 
				
			||||||
import ru.windcorp.progressia.common.collision.CollisionModel;
 | 
					import ru.windcorp.progressia.common.collision.CollisionModel;
 | 
				
			||||||
import ru.windcorp.progressia.common.comms.controls.*;
 | 
					import ru.windcorp.progressia.common.comms.controls.*;
 | 
				
			||||||
import ru.windcorp.progressia.common.state.StatefulObjectRegistry.Factory;
 | 
					import ru.windcorp.progressia.common.state.StatefulObjectRegistry.IdFactory;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.GravityModelRegistry;
 | 
					import ru.windcorp.progressia.common.world.GravityModelRegistry;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.block.*;
 | 
					import ru.windcorp.progressia.common.world.block.*;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.entity.*;
 | 
					import ru.windcorp.progressia.common.world.entity.*;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.io.ChunkIO;
 | 
					import ru.windcorp.progressia.common.world.io.ChunkIO;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemData;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemDataRegistry;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemDataSimple;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
 | 
					import ru.windcorp.progressia.common.world.rels.AbsFace;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.tile.*;
 | 
					import ru.windcorp.progressia.common.world.tile.*;
 | 
				
			||||||
import ru.windcorp.progressia.server.Server;
 | 
					import ru.windcorp.progressia.server.Server;
 | 
				
			||||||
@@ -64,12 +70,11 @@ import ru.windcorp.progressia.server.world.generation.planet.PlanetGravityModel;
 | 
				
			|||||||
import ru.windcorp.progressia.server.world.tile.*;
 | 
					import ru.windcorp.progressia.server.world.tile.*;
 | 
				
			||||||
import ru.windcorp.progressia.test.Rocks.RockType;
 | 
					import ru.windcorp.progressia.test.Rocks.RockType;
 | 
				
			||||||
import ru.windcorp.progressia.test.gen.TestGravityModel;
 | 
					import ru.windcorp.progressia.test.gen.TestGravityModel;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.test.inv.TestInventoryGUIManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class TestContent {
 | 
					public class TestContent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static final String PLAYER_LOGIN = "Sasha";
 | 
						public static final String PLAYER_LOGIN = "Sasha";
 | 
				
			||||||
	public static final long PLAYER_ENTITY_ID = 0x42;
 | 
					 | 
				
			||||||
	public static final long STATIE_ENTITY_ID = 0xDEADBEEF;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static final List<BlockData> PLACEABLE_BLOCKS = new ArrayList<>();
 | 
						public static final List<BlockData> PLACEABLE_BLOCKS = new ArrayList<>();
 | 
				
			||||||
	public static final List<TileData> PLACEABLE_TILES = new ArrayList<>();
 | 
						public static final List<TileData> PLACEABLE_TILES = new ArrayList<>();
 | 
				
			||||||
@@ -85,6 +90,7 @@ public class TestContent {
 | 
				
			|||||||
	private static void registerWorldContent() {
 | 
						private static void registerWorldContent() {
 | 
				
			||||||
		registerBlocks();
 | 
							registerBlocks();
 | 
				
			||||||
		registerTiles();
 | 
							registerTiles();
 | 
				
			||||||
 | 
							registerItems();
 | 
				
			||||||
		registerEntities();
 | 
							registerEntities();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -235,6 +241,10 @@ public class TestContent {
 | 
				
			|||||||
		PLACEABLE_TILES.removeIf(b -> placeableBlacklist.contains(b.getId()));
 | 
							PLACEABLE_TILES.removeIf(b -> placeableBlacklist.contains(b.getId()));
 | 
				
			||||||
		PLACEABLE_TILES.sort(Comparator.comparing(TileData::getId));
 | 
							PLACEABLE_TILES.sort(Comparator.comparing(TileData::getId));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private static void registerItems() {
 | 
				
			||||||
 | 
							registerSimplestItem("MoonTypeIceCream", Units.get("200 g"), Units.get("1 L"));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void registerSimplestBlock(String name) {
 | 
						private static void registerSimplestBlock(String name) {
 | 
				
			||||||
		String id = "Test:" + name;
 | 
							String id = "Test:" + name;
 | 
				
			||||||
@@ -263,14 +273,19 @@ public class TestContent {
 | 
				
			|||||||
		register(new TileRenderHerb(id, getTileTexture(name), maxCount));
 | 
							register(new TileRenderHerb(id, getTileTexture(name), maxCount));
 | 
				
			||||||
		register(new HangingTileLogic(id));
 | 
							register(new HangingTileLogic(id));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private static void registerSimplestItem(String name, float mass, float volume) {
 | 
				
			||||||
 | 
							String id = "Test:" + name;
 | 
				
			||||||
 | 
							registerItem(id, s -> new ItemDataSimple(s, mass, volume));
 | 
				
			||||||
 | 
							register(new ItemRenderSimple(id, getItemTexture(name)));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void registerEntities() {
 | 
						private static void registerEntities() {
 | 
				
			||||||
		float scale = 1.8f / 8;
 | 
							registerEntity("Core:Player", EntityDataPlayer::new);
 | 
				
			||||||
		registerEntityData("Test:Player", e -> e.setCollisionModel(new AABB(0, 0, 4 * scale, 0.8f, 0.8f, 1.8f)));
 | 
							register(new TestEntityRenderHuman("Core:Player"));
 | 
				
			||||||
		register(new TestEntityRenderHuman("Test:Player"));
 | 
							register(new EntityLogic("Core:Player"));
 | 
				
			||||||
		register(new EntityLogic("Test:Player"));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		register("Test:Statie", TestEntityDataStatie::new);
 | 
							registerEntity("Test:Statie", TestEntityDataStatie::new);
 | 
				
			||||||
		register(new TestEntityRenderStatie("Test:Statie"));
 | 
							register(new TestEntityRenderStatie("Test:Statie"));
 | 
				
			||||||
		register(new TestEntityLogicStatie("Test:Statie"));
 | 
							register(new TestEntityLogicStatie("Test:Statie"));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -325,6 +340,15 @@ public class TestContent {
 | 
				
			|||||||
				KeyMatcher.of(GLFW.GLFW_KEY_M).matcher()
 | 
									KeyMatcher.of(GLFW.GLFW_KEY_M).matcher()
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							triggers.register(
 | 
				
			||||||
 | 
								ControlTriggers.localOf(
 | 
				
			||||||
 | 
									"Test:OpenInventory",
 | 
				
			||||||
 | 
									KeyEvent.class,
 | 
				
			||||||
 | 
									TestInventoryGUIManager::openGUI,
 | 
				
			||||||
 | 
									KeyMatcher.of(GLFW.GLFW_KEY_E).matcher()
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void register(BlockData x) {
 | 
						private static void register(BlockData x) {
 | 
				
			||||||
@@ -334,28 +358,18 @@ public class TestContent {
 | 
				
			|||||||
	private static void register(TileData x) {
 | 
						private static void register(TileData x) {
 | 
				
			||||||
		TileDataRegistry.getInstance().register(x);
 | 
							TileDataRegistry.getInstance().register(x);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	private static void register(
 | 
						private static void registerItem(String id, IdFactory<ItemData> factory) {
 | 
				
			||||||
 | 
							ItemDataRegistry.getInstance().register(id, factory);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private static void registerEntity(
 | 
				
			||||||
		String id,
 | 
							String id,
 | 
				
			||||||
		Factory<EntityData> factory
 | 
							IdFactory<EntityData> factory
 | 
				
			||||||
	) {
 | 
						) {
 | 
				
			||||||
		EntityDataRegistry.getInstance().register(id, factory);
 | 
							EntityDataRegistry.getInstance().register(id, factory);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void registerEntityData(
 | 
					 | 
				
			||||||
		String id,
 | 
					 | 
				
			||||||
		Consumer<EntityData> transform
 | 
					 | 
				
			||||||
	) {
 | 
					 | 
				
			||||||
		EntityDataRegistry.getInstance().register(id, new Factory<EntityData>() {
 | 
					 | 
				
			||||||
			@Override
 | 
					 | 
				
			||||||
			public EntityData build() {
 | 
					 | 
				
			||||||
				EntityData entity = new EntityData(id);
 | 
					 | 
				
			||||||
				transform.accept(entity);
 | 
					 | 
				
			||||||
				return entity;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private static void register(BlockRender x) {
 | 
						private static void register(BlockRender x) {
 | 
				
			||||||
		BlockRenderRegistry.getInstance().register(x);
 | 
							BlockRenderRegistry.getInstance().register(x);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -363,6 +377,10 @@ public class TestContent {
 | 
				
			|||||||
	private static void register(TileRender x) {
 | 
						private static void register(TileRender x) {
 | 
				
			||||||
		TileRenderRegistry.getInstance().register(x);
 | 
							TileRenderRegistry.getInstance().register(x);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private static void register(ItemRender x) {
 | 
				
			||||||
 | 
							ItemRenderRegistry.getInstance().register(x);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void register(EntityRender x) {
 | 
						private static void register(EntityRender x) {
 | 
				
			||||||
		EntityRenderRegistry.getInstance().register(x);
 | 
							EntityRenderRegistry.getInstance().register(x);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,10 +26,6 @@ public class TestEntityDataStatie extends EntityData {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	private final IntStateField size = field("Test:Size").setShared().ofInt().build();
 | 
						private final IntStateField size = field("Test:Size").setShared().ofInt().build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public TestEntityDataStatie() {
 | 
					 | 
				
			||||||
		this("Test:Statie");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	protected TestEntityDataStatie(String id) {
 | 
						protected TestEntityDataStatie(String id) {
 | 
				
			||||||
		super(id);
 | 
							super(id);
 | 
				
			||||||
		setCollisionModel(new AABB(0, 0, 0, 1, 1, 1));
 | 
							setCollisionModel(new AABB(0, 0, 0, 1, 1, 1));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@
 | 
				
			|||||||
 * You should have received a copy of the GNU General Public License
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
package ru.windcorp.progressia.test;
 | 
					package ru.windcorp.progressia.test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import glm.Glm;
 | 
					import glm.Glm;
 | 
				
			||||||
@@ -41,6 +41,7 @@ import ru.windcorp.progressia.common.util.VectorUtil;
 | 
				
			|||||||
import ru.windcorp.progressia.common.util.Vectors;
 | 
					import ru.windcorp.progressia.common.util.Vectors;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.block.BlockData;
 | 
					import ru.windcorp.progressia.common.world.block.BlockData;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
					import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
 | 
				
			||||||
import ru.windcorp.progressia.common.world.tile.TileData;
 | 
					import ru.windcorp.progressia.common.world.tile.TileData;
 | 
				
			||||||
import ru.windcorp.progressia.server.ServerState;
 | 
					import ru.windcorp.progressia.server.ServerState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -114,8 +115,9 @@ public class TestPlayerControls {
 | 
				
			|||||||
			desiredVelocity.normalize();
 | 
								desiredVelocity.normalize();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		desiredVelocity.z = movementUp;
 | 
							desiredVelocity.z = movementUp;
 | 
				
			||||||
		movementTransform.mul_(desiredVelocity); // bug in jglm, .mul() and .mul_() are
 | 
							movementTransform.mul_(desiredVelocity); // bug in jglm, .mul() and
 | 
				
			||||||
										         // swapped
 | 
																		// .mul_() are
 | 
				
			||||||
 | 
																		// swapped
 | 
				
			||||||
		desiredVelocity.mul(speed);
 | 
							desiredVelocity.mul(speed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Vec3 newVelocity = new Vec3()
 | 
							Vec3 newVelocity = new Vec3()
 | 
				
			||||||
@@ -134,8 +136,8 @@ public class TestPlayerControls {
 | 
				
			|||||||
		player.getVelocity().set(newVelocity);
 | 
							player.getVelocity().set(newVelocity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// THIS IS TERRIBLE TEST
 | 
							// THIS IS TERRIBLE TEST
 | 
				
			||||||
		EntityData serverEntity = ServerState.getInstance().getWorld().getData()
 | 
							EntityData serverEntity = ServerState.getInstance().getWorld().getEntities().stream()
 | 
				
			||||||
			.getEntity(TestContent.PLAYER_ENTITY_ID);
 | 
								.filter(EntityDataPlayer.class::isInstance).findAny().orElse(null);
 | 
				
			||||||
		if (serverEntity != null) {
 | 
							if (serverEntity != null) {
 | 
				
			||||||
			serverEntity.setPosition(player.getPosition());
 | 
								serverEntity.setPosition(player.getPosition());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -146,15 +148,21 @@ public class TestPlayerControls {
 | 
				
			|||||||
		if (mat == null) {
 | 
							if (mat == null) {
 | 
				
			||||||
			mat = new Mat3();
 | 
								mat = new Mat3();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		Vec3 f = player.getForwardVector(null);
 | 
							Vec3 f = player.getForwardVector(null);
 | 
				
			||||||
		Vec3 u = player.getUpVector();
 | 
							Vec3 u = player.getUpVector();
 | 
				
			||||||
		Vec3 s = u.cross_(f);
 | 
							Vec3 s = u.cross_(f);
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		return mat.set(
 | 
							return mat.set(
 | 
				
			||||||
			+f.x, +f.y, +f.z,
 | 
								+f.x,
 | 
				
			||||||
			-s.x, -s.y, -s.z,
 | 
								+f.y,
 | 
				
			||||||
			+u.x, +u.y, +u.z
 | 
								+f.z,
 | 
				
			||||||
 | 
								-s.x,
 | 
				
			||||||
 | 
								-s.y,
 | 
				
			||||||
 | 
								-s.z,
 | 
				
			||||||
 | 
								+u.x,
 | 
				
			||||||
 | 
								+u.y,
 | 
				
			||||||
 | 
								+u.z
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -201,7 +209,7 @@ public class TestPlayerControls {
 | 
				
			|||||||
		case GLFW.GLFW_KEY_ESCAPE:
 | 
							case GLFW.GLFW_KEY_ESCAPE:
 | 
				
			||||||
			if (!event.isPress())
 | 
								if (!event.isPress())
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			handleEscape();
 | 
								handleEscape();
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -296,7 +304,7 @@ public class TestPlayerControls {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Vec3 up = getEntity().getUpVector();
 | 
							Vec3 up = getEntity().getUpVector();
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		getEntity().getVelocity().add(
 | 
							getEntity().getVelocity().add(
 | 
				
			||||||
			up.x * JUMP_VELOCITY,
 | 
								up.x * JUMP_VELOCITY,
 | 
				
			||||||
			up.y * JUMP_VELOCITY,
 | 
								up.y * JUMP_VELOCITY,
 | 
				
			||||||
@@ -359,31 +367,31 @@ public class TestPlayerControls {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		final double yawScale = -0.002f;
 | 
							final double yawScale = -0.002f;
 | 
				
			||||||
		final double pitchScale = -yawScale;
 | 
							final double pitchScale = -yawScale;
 | 
				
			||||||
		final double pitchExtremum = Math.PI/2 * 0.95f;
 | 
							final double pitchExtremum = Math.PI / 2 * 0.95f;
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		double yawChange = event.getChangeX() * yawScale;
 | 
							double yawChange = event.getChangeX() * yawScale;
 | 
				
			||||||
		double pitchChange = event.getChangeY() * pitchScale;
 | 
							double pitchChange = event.getChangeY() * pitchScale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		EntityData player = getEntity();
 | 
							EntityData player = getEntity();
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		double startPitch = player.getPitch();
 | 
							double startPitch = player.getPitch();
 | 
				
			||||||
		double endPitch = startPitch + pitchChange;
 | 
							double endPitch = startPitch + pitchChange;
 | 
				
			||||||
		endPitch = Glm.clamp(endPitch, -pitchExtremum, +pitchExtremum);
 | 
							endPitch = Glm.clamp(endPitch, -pitchExtremum, +pitchExtremum);
 | 
				
			||||||
		pitchChange = endPitch - startPitch;
 | 
							pitchChange = endPitch - startPitch;
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		Mat4 mat = Matrices.grab4();
 | 
							Mat4 mat = Matrices.grab4();
 | 
				
			||||||
		Vec3 lookingAt = Vectors.grab3();		
 | 
							Vec3 lookingAt = Vectors.grab3();
 | 
				
			||||||
		Vec3 rightVector = Vectors.grab3();
 | 
							Vec3 rightVector = Vectors.grab3();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rightVector.set(player.getLookingAt()).cross(player.getUpVector()).normalize();
 | 
							rightVector.set(player.getLookingAt()).cross(player.getUpVector()).normalize();
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		mat.identity()
 | 
							mat.identity()
 | 
				
			||||||
			.rotate((float) yawChange, player.getUpVector())
 | 
								.rotate((float) yawChange, player.getUpVector())
 | 
				
			||||||
			.rotate((float) pitchChange, rightVector);
 | 
								.rotate((float) pitchChange, rightVector);
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		VectorUtil.applyMat4(player.getLookingAt(), mat, lookingAt);
 | 
							VectorUtil.applyMat4(player.getLookingAt(), mat, lookingAt);
 | 
				
			||||||
		player.setLookingAt(lookingAt);
 | 
							player.setLookingAt(lookingAt);
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		Vectors.release(rightVector);
 | 
							Vectors.release(rightVector);
 | 
				
			||||||
		Vectors.release(lookingAt);
 | 
							Vectors.release(lookingAt);
 | 
				
			||||||
		Matrices.release(mat);
 | 
							Matrices.release(mat);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.test.inv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import glm.vec._2.i.Vec2i;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.Component;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.Group;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.layout.LayoutBorderHorizontal;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.layout.LayoutGrid;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemContainer;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemSlot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class InventoryComponent extends Component {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final TestInventoryGUILayer layer;
 | 
				
			||||||
 | 
						private final Group slots = new Group("Inventory.Slots", new LayoutGrid(15));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public InventoryComponent(TestInventoryGUILayer layer) {
 | 
				
			||||||
 | 
							super("Inventory");
 | 
				
			||||||
 | 
							this.layer = layer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							setLayout(new LayoutBorderHorizontal(15));
 | 
				
			||||||
 | 
							addChild(slots.setLayoutHint(LayoutBorderHorizontal.CENTER));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							getContainer().getSlots().forEach(this::addSlot);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void addSlot(ItemSlot slot) {
 | 
				
			||||||
 | 
							final int maxX = 6;
 | 
				
			||||||
 | 
							int i = slots.getChildren().size();
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							SlotComponent component = new SlotComponent("Inventory.Slot" + i, slot);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							Vec2i pos = new Vec2i(i % maxX, i / maxX);
 | 
				
			||||||
 | 
							slots.addChild(component.setLayoutHint(pos));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private ItemContainer getContainer() {
 | 
				
			||||||
 | 
							return layer.container;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.test.inv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import glm.mat._4.Mat4;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.font.Font;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.Button;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.DynamicLabel;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.world.item.ItemRenderRegistry;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.world.item.ItemRenderable;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemData;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemSlot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SlotComponent extends Button {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final float TEXTURE_SIZE = 24;
 | 
				
			||||||
 | 
						private static final float SCALE = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final ItemSlot slot;
 | 
				
			||||||
 | 
						private ItemRenderable itemRenderer = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private int sizeDisplayInt = 0;
 | 
				
			||||||
 | 
						private String sizeDisplayString = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public SlotComponent(String name, ItemSlot slot) {
 | 
				
			||||||
 | 
							super(name, null, null);
 | 
				
			||||||
 | 
							this.slot = slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int side = (int) (TEXTURE_SIZE * SCALE) + 2 * BORDER;
 | 
				
			||||||
 | 
							setPreferredSize(side, side);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Font sizeFont = new Font().deriveOutlined().withScale(1);
 | 
				
			||||||
 | 
							addChild(new DynamicLabel(name + ".Size", sizeFont, () -> sizeDisplayString, side - 2 * MARGIN));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							setLayout(new LayoutAlign(0, 0, MARGIN));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ItemSlot getSlot() {
 | 
				
			||||||
 | 
							return slot;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						protected void assembleSelf(RenderTarget target) {
 | 
				
			||||||
 | 
							super.assembleSelf(target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							updateItemRenderer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							assembleItem(target);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void updateItemRenderer() {
 | 
				
			||||||
 | 
							ItemData contents = slot.getContents();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (contents == null) {
 | 
				
			||||||
 | 
								itemRenderer = null;
 | 
				
			||||||
 | 
								sizeDisplayInt = 0;
 | 
				
			||||||
 | 
								sizeDisplayString = "";
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (itemRenderer == null || itemRenderer.getData() != contents) {
 | 
				
			||||||
 | 
									itemRenderer = ItemRenderRegistry.getInstance().get(contents.getId()).createRenderable(contents);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int newSize = contents.getSize();
 | 
				
			||||||
 | 
								if (newSize != sizeDisplayInt) {
 | 
				
			||||||
 | 
									sizeDisplayInt = newSize;
 | 
				
			||||||
 | 
									sizeDisplayString = newSize == 1 ? "" : Integer.toString(newSize);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void assembleItem(RenderTarget target) {
 | 
				
			||||||
 | 
							if (itemRenderer != null) {
 | 
				
			||||||
 | 
								target.pushTransform(new Mat4().translate(getX() + BORDER, getY() + BORDER, 0).scale(SCALE));
 | 
				
			||||||
 | 
								target.addCustomRenderer(itemRenderer);
 | 
				
			||||||
 | 
								target.popTransform();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.test.inv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.lwjgl.glfw.GLFW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.GUI;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.gui.menu.MenuLayer;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.input.InputEvent;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.input.KeyEvent;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.input.bus.Input;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.item.ItemContainer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class TestInventoryGUILayer extends MenuLayer {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						ItemContainer container;
 | 
				
			||||||
 | 
						private InventoryComponent display = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public TestInventoryGUILayer() {
 | 
				
			||||||
 | 
							super("Inventory");
 | 
				
			||||||
 | 
							setCursorPolicy(CursorPolicy.INDIFFERENT);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							addTitle(); // pppffffttt
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public void setContainer(ItemContainer container) {
 | 
				
			||||||
 | 
							this.container = container;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							getContent().removeChild(display);
 | 
				
			||||||
 | 
							display = null;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if (container != null) {
 | 
				
			||||||
 | 
								display = new InventoryComponent(this);
 | 
				
			||||||
 | 
								getContent().addChild(display);
 | 
				
			||||||
 | 
								invalidate();
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								setCursorPolicy(CursorPolicy.REQUIRE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								setCursorPolicy(CursorPolicy.INDIFFERENT);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							GUI.updateLayer(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						protected Runnable getCloseAction() {
 | 
				
			||||||
 | 
							return () -> setContainer(null);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						protected void doRender() {
 | 
				
			||||||
 | 
							if (container != null) {
 | 
				
			||||||
 | 
								super.doRender();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						protected void handleInput(Input input) {
 | 
				
			||||||
 | 
							if (container != null) {
 | 
				
			||||||
 | 
								if (!input.isConsumed()) {
 | 
				
			||||||
 | 
									InputEvent event = input.getEvent();
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									if (event instanceof KeyEvent) {
 | 
				
			||||||
 | 
										KeyEvent keyEvent = (KeyEvent) event;
 | 
				
			||||||
 | 
										if (keyEvent.isPress() && keyEvent.getKey() == GLFW.GLFW_KEY_E) {
 | 
				
			||||||
 | 
											getCloseAction().run();
 | 
				
			||||||
 | 
											input.consume();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								super.handleInput(input);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Progressia
 | 
				
			||||||
 | 
					 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package ru.windcorp.progressia.test.inv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.Client;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.ClientState;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.client.graphics.GUI;
 | 
				
			||||||
 | 
					import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class TestInventoryGUIManager {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private static TestInventoryGUILayer layer;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public static void setup() {
 | 
				
			||||||
 | 
							layer = new TestInventoryGUILayer();
 | 
				
			||||||
 | 
							GUI.addTopLayer(layer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public static void shutdown() {
 | 
				
			||||||
 | 
							GUI.getLayers().stream().filter(TestInventoryGUILayer.class::isInstance).forEach(GUI::removeLayer);
 | 
				
			||||||
 | 
							layer = null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public static void openGUI() {
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							Client client = ClientState.getInstance();
 | 
				
			||||||
 | 
							if (client == null) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if (layer == null) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							EntityDataPlayer entity = client.getLocalPlayer().getEntity();
 | 
				
			||||||
 | 
							if (entity == null) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							layer.setContainer(entity.getInventory());
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -21,4 +21,5 @@ LayerTestGUI.PlacementModeHint = (Blocks %s Tiles: Ctrl + Mouse Wheel)
 | 
				
			|||||||
LayerTestGUI.IsFullscreen = Fullscreen:     %5s (F11)
 | 
					LayerTestGUI.IsFullscreen = Fullscreen:     %5s (F11)
 | 
				
			||||||
LayerTestGUI.IsVSync = VSync:          %5s (F12)
 | 
					LayerTestGUI.IsVSync = VSync:          %5s (F12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LayerButtonTest.Title = Button Test
 | 
					LayerButtonTest.Title = Button Test
 | 
				
			||||||
 | 
					LayerInventory.Title = Player
 | 
				
			||||||
@@ -21,4 +21,5 @@ LayerTestGUI.PlacementModeHint = (Блок %s плитки: Ctrl + прокру
 | 
				
			|||||||
LayerTestGUI.IsFullscreen = Полный экран:   %5s (F11)
 | 
					LayerTestGUI.IsFullscreen = Полный экран:   %5s (F11)
 | 
				
			||||||
LayerTestGUI.IsVSync = Верт. синхр.:   %5s (F12)
 | 
					LayerTestGUI.IsVSync = Верт. синхр.:   %5s (F12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LayerButtonTest.Title = Тест Кнопок
 | 
					LayerButtonTest.Title = Тест Кнопок
 | 
				
			||||||
 | 
					LayerInventory.Title = Игрок
 | 
				
			||||||
		Reference in New Issue
	
	Block a user