Added player species and refactored everything hands-related
- Players species is now a thing - Currently defines hands, equipment slots (unused), collision model and appearance - EntityDataPlayer now contains a species-provided datalet - EntityRenderPlayer now searches for a species-defined delegate to render players - Hand count can now be arbitrary - Split ItemContainerSingle into ItemContainerHand and ItemContainerEquipment - Added HUDTextures class
This commit is contained in:
parent
73ee339dcc
commit
6cd812f7c3
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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.graphics;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
||||||
|
|
||||||
|
public class ExponentAnimation {
|
||||||
|
|
||||||
|
private final float speed;
|
||||||
|
private float value;
|
||||||
|
|
||||||
|
public ExponentAnimation(float speed, float value) {
|
||||||
|
this.speed = speed;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(float value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float update(float target, double timeStep) {
|
||||||
|
float difference = value - target;
|
||||||
|
value += difference * (1 - Math.exp(speed * timeStep));
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float updateForFrame(float target) {
|
||||||
|
return update(target, GraphicsInterface.getFrameLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -123,6 +123,36 @@ public class Shapes {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Shape createParallelogram(
|
||||||
|
// Try saying that 10 times fast
|
||||||
|
ShapeRenderProgram program,
|
||||||
|
|
||||||
|
Vec3 origin,
|
||||||
|
|
||||||
|
Vec3 width,
|
||||||
|
Vec3 height,
|
||||||
|
|
||||||
|
Vec4 colorMultiplier,
|
||||||
|
|
||||||
|
Texture texture
|
||||||
|
) {
|
||||||
|
Shape result = new Shape(
|
||||||
|
Usage.STATIC,
|
||||||
|
program,
|
||||||
|
ShapeParts.createRectangle(
|
||||||
|
program,
|
||||||
|
texture,
|
||||||
|
colorMultiplier,
|
||||||
|
origin,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static class PppBuilder {
|
public static class PppBuilder {
|
||||||
|
|
||||||
@ -297,4 +327,108 @@ public class Shapes {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class PgmBuilder {
|
||||||
|
|
||||||
|
private final ShapeRenderProgram program;
|
||||||
|
|
||||||
|
private final Vec3 origin = new Vec3(0, 0, 0);
|
||||||
|
|
||||||
|
private final Vec3 width = new Vec3(1, 0, 0);
|
||||||
|
private final Vec3 height = new Vec3(0, 1, 0);
|
||||||
|
|
||||||
|
private final Vec4 colorMultiplier = new Vec4(1, 1, 1, 1);
|
||||||
|
|
||||||
|
private final Texture texture;
|
||||||
|
|
||||||
|
public PgmBuilder(ShapeRenderProgram program, Texture texture) {
|
||||||
|
this.program = program;
|
||||||
|
this.texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setOrigin(Vec3 origin) {
|
||||||
|
this.origin.set(origin);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setOrigin(float x, float y, float z) {
|
||||||
|
this.origin.set(x, y, z);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setColorMultiplier(Vec4 colorMultiplier) {
|
||||||
|
this.colorMultiplier.set(colorMultiplier);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setColorMultiplier(float r, float g, float b) {
|
||||||
|
this.colorMultiplier.set(r, g, b, 1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setColorMultiplier(float r, float g, float b, float a) {
|
||||||
|
this.colorMultiplier.set(r, g, b, a);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setWidth(Vec3 vector) {
|
||||||
|
this.width.set(vector);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setWidth(float x, float y, float z) {
|
||||||
|
this.width.set(x, y, z);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setWidth(float x) {
|
||||||
|
this.width.set(x, 0, 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setHeight(Vec3 vector) {
|
||||||
|
this.height.set(vector);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setHeight(float x, float y, float z) {
|
||||||
|
this.height.set(x, y, z);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setHeight(float y) {
|
||||||
|
this.height.set(0, y, 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setSize(float x, float y) {
|
||||||
|
return this.setWidth(x).setHeight(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder setSize(float size) {
|
||||||
|
return this.setSize(size, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgmBuilder centerAt(float x, float y, float z) {
|
||||||
|
origin.set(x, y, z);
|
||||||
|
|
||||||
|
origin.mul(2);
|
||||||
|
origin.sub(width);
|
||||||
|
origin.div(2);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shape create() {
|
||||||
|
return createParallelogram(
|
||||||
|
program,
|
||||||
|
origin,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
colorMultiplier,
|
||||||
|
texture
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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.graphics.world.hud;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class HUDTextures {
|
||||||
|
|
||||||
|
private static final AtlasGroup HUD_ATLAS_GROUP = new AtlasGroup("HUD", 1 << 12);
|
||||||
|
|
||||||
|
public static Texture getHUDTexture(String name) {
|
||||||
|
return new SimpleTexture(
|
||||||
|
Atlases.getSprite(
|
||||||
|
ResourceManager.getTextureResource("gui/" + name),
|
||||||
|
HUD_ATLAS_GROUP
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AtlasGroup getHUDAtlasGroup() {
|
||||||
|
return HUD_ATLAS_GROUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* 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.graphics.world.hud;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import glm.vec._2.i.Vec2i;
|
||||||
|
import ru.windcorp.progressia.client.graphics.ExponentAnimation;
|
||||||
|
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Group;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutBorderHorizontal;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutHorizontal;
|
||||||
|
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.SpeciesRender;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.SpeciesRenderRegistry;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand;
|
||||||
|
import ru.windcorp.progressia.test.inv.TestInventoryGUIManager;
|
||||||
|
|
||||||
|
public class HandsHUD extends Component {
|
||||||
|
|
||||||
|
public class ScaledSlotComponent extends Component {
|
||||||
|
|
||||||
|
private final SlotComponent slotComponent;
|
||||||
|
private final ExponentAnimation selected = new ExponentAnimation(10, 1);
|
||||||
|
|
||||||
|
public ScaledSlotComponent(SlotComponent component) {
|
||||||
|
super(component.getName() + ".Scaled");
|
||||||
|
this.slotComponent = component;
|
||||||
|
addChild(component);
|
||||||
|
|
||||||
|
Vec2i size = slotComponent.getPreferredSize();
|
||||||
|
setPreferredSize(size.x * 2, size.y * 2);
|
||||||
|
slotComponent.setBounds(-size.x / 2, 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assembleChildren(RenderTarget target) {
|
||||||
|
Renderable renderable = slotComponent.assembleToRenderable();
|
||||||
|
|
||||||
|
target.addCustomRenderer(renderer -> {
|
||||||
|
float scale = player.getEntity().getSelectedHand() == slotComponent.getSlot().getContainer() ? 2 : 1;
|
||||||
|
renderer.pushTransform()
|
||||||
|
.translate(getX() + getWidth() / 2, getY(), 0)
|
||||||
|
.scale(selected.updateForFrame(scale));
|
||||||
|
|
||||||
|
renderable.render(renderer);
|
||||||
|
|
||||||
|
renderer.popTransform();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Side {
|
||||||
|
LEFT("Left", LayoutBorderHorizontal.LEFT, 0.0),
|
||||||
|
RIGHT("Right", LayoutBorderHorizontal.RIGHT, 1.0),
|
||||||
|
CENTER("Center", LayoutBorderHorizontal.CENTER, 0.5);
|
||||||
|
|
||||||
|
private final String ccName;
|
||||||
|
private final Object lbhHint;
|
||||||
|
private final double align;
|
||||||
|
|
||||||
|
private Side(String ccName, Object lbhHint, double align) {
|
||||||
|
this.ccName = ccName;
|
||||||
|
this.lbhHint = lbhHint;
|
||||||
|
this.align = align;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final LocalPlayer player;
|
||||||
|
|
||||||
|
public HandsHUD(String name, LocalPlayer player) {
|
||||||
|
super(name);
|
||||||
|
this.player = player;
|
||||||
|
|
||||||
|
EntityDataPlayer entity = player.getEntity();
|
||||||
|
String speciesId = entity.getSpecies().getId();
|
||||||
|
SpeciesRender speciesRender = SpeciesRenderRegistry.getInstance().get(speciesId);
|
||||||
|
|
||||||
|
Map<Side, Component> containers = Maps.toMap(
|
||||||
|
Arrays.asList(Side.values()),
|
||||||
|
side -> new Group(name + "." + side.ccName, new LayoutHorizontal(15))
|
||||||
|
);
|
||||||
|
|
||||||
|
for (int i = 0; i < entity.getHandCount(); ++i) {
|
||||||
|
|
||||||
|
Hand hand = entity.getSpecies().getHands().get(i);
|
||||||
|
|
||||||
|
SlotComponent display = new SlotComponent(name + "." + hand.getName(), entity.getHand(i), 0)
|
||||||
|
.setBackground(speciesRender.getHandBackground(hand), this::shouldRenderHandPlaceholder)
|
||||||
|
.setScale(2);
|
||||||
|
|
||||||
|
Component scaledDisplay = new ScaledSlotComponent(display);
|
||||||
|
|
||||||
|
containers.get(speciesRender.getHandSide(hand)).addChild(scaledDisplay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setLayout(new LayoutBorderHorizontal());
|
||||||
|
|
||||||
|
containers.forEach((side, comp) -> {
|
||||||
|
addChild(
|
||||||
|
new Group(name + "." + side.ccName + ".Aligner", new LayoutAlign(side.align, 0.5, 0), comp)
|
||||||
|
.setLayoutHint(side.lbhHint)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldRenderHandPlaceholder() {
|
||||||
|
return TestInventoryGUIManager.layer.hasContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,35 +18,22 @@
|
|||||||
package ru.windcorp.progressia.client.graphics.world.hud;
|
package ru.windcorp.progressia.client.graphics.world.hud;
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
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.LayoutBorderVertical;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutBorderVertical;
|
||||||
import ru.windcorp.progressia.client.graphics.texture.SimpleTextures;
|
|
||||||
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
|
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
import ru.windcorp.progressia.test.inv.SlotComponent;
|
|
||||||
|
|
||||||
public class PermanentHUD extends Component {
|
public class PermanentHUD extends Component {
|
||||||
|
|
||||||
public PermanentHUD(String name, LocalPlayer player) {
|
public PermanentHUD(String name, LocalPlayer player) {
|
||||||
super(name);
|
super(name);
|
||||||
setLayout(new LayoutBorderVertical());
|
setLayout(new LayoutBorderVertical());
|
||||||
|
|
||||||
EntityDataPlayer entity = player.getEntity();
|
EntityDataPlayer entity = player.getEntity();
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
throw new IllegalStateException("Player " + player + " does not have an associated entity");
|
throw new IllegalStateException("Player " + player + " does not have an associated entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
Group handDisplays = new Group(
|
addChild(new HandsHUD(name + ".Hands", player).setLayoutHint(LayoutBorderVertical.UP));
|
||||||
getName() + ".Hands",
|
|
||||||
new LayoutBorderHorizontal(),
|
|
||||||
new SlotComponent(getName() + ".Hands.LeftHand", entity.getLeftHand(), 0)
|
|
||||||
.setBackground(SimpleTextures.get("gui/LeftHand")).setScale(4).setLayoutHint(LayoutBorderHorizontal.LEFT),
|
|
||||||
new SlotComponent(getName() + ".Hands.RightHand", entity.getRightHand(), 0)
|
|
||||||
.setBackground(SimpleTextures.get("gui/RightHand")).setScale(4).setLayoutHint(LayoutBorderHorizontal.RIGHT)
|
|
||||||
);
|
|
||||||
|
|
||||||
addChild(handDisplays.setLayoutHint(LayoutBorderVertical.UP));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,10 @@
|
|||||||
* 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.inv;
|
package ru.windcorp.progressia.client.graphics.world.hud;
|
||||||
|
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
import glm.mat._4.Mat4;
|
import glm.mat._4.Mat4;
|
||||||
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.flat.FlatRenderProgram;
|
||||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||||
@ -28,8 +26,7 @@ import ru.windcorp.progressia.client.graphics.gui.Component;
|
|||||||
import ru.windcorp.progressia.client.graphics.gui.DynamicLabel;
|
import ru.windcorp.progressia.client.graphics.gui.DynamicLabel;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||||
import ru.windcorp.progressia.client.graphics.model.Shape;
|
import ru.windcorp.progressia.client.graphics.model.Shapes.PgmBuilder;
|
||||||
import ru.windcorp.progressia.client.graphics.model.ShapeParts;
|
|
||||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||||
import ru.windcorp.progressia.client.world.item.ItemRenderRegistry;
|
import ru.windcorp.progressia.client.world.item.ItemRenderRegistry;
|
||||||
import ru.windcorp.progressia.client.world.item.ItemRenderable;
|
import ru.windcorp.progressia.client.world.item.ItemRenderable;
|
||||||
@ -52,6 +49,7 @@ public class SlotComponent extends Component {
|
|||||||
private String amountDisplayString = "";
|
private String amountDisplayString = "";
|
||||||
|
|
||||||
private Renderable background = null;
|
private Renderable background = null;
|
||||||
|
private BooleanSupplier backgroundCondition = null;
|
||||||
|
|
||||||
public SlotComponent(String name, ItemContainer container, int index) {
|
public SlotComponent(String name, ItemContainer container, int index) {
|
||||||
super(name);
|
super(name);
|
||||||
@ -80,20 +78,18 @@ public class SlotComponent extends Component {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SlotComponent setBackground(Texture texture, BooleanSupplier when) {
|
||||||
|
background = new PgmBuilder(FlatRenderProgram.getDefault(), texture).setSize(TEXTURE_SIZE).create();
|
||||||
|
setBackgroundDisplayCondition(when);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public SlotComponent setBackground(Texture texture) {
|
public SlotComponent setBackground(Texture texture) {
|
||||||
background = new Shape(
|
return setBackground(texture, null);
|
||||||
Usage.STATIC,
|
}
|
||||||
FlatRenderProgram.getDefault(),
|
|
||||||
ShapeParts.createRectangle(
|
public SlotComponent setBackgroundDisplayCondition(BooleanSupplier backgroundCondition) {
|
||||||
FlatRenderProgram.getDefault(),
|
this.backgroundCondition = backgroundCondition;
|
||||||
texture,
|
|
||||||
Colors.WHITE,
|
|
||||||
new Vec3(0, 0, 0),
|
|
||||||
new Vec3(24, 0, 0),
|
|
||||||
new Vec3(0, 24, 0),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +128,9 @@ public class SlotComponent extends Component {
|
|||||||
if (itemRenderer != null) {
|
if (itemRenderer != null) {
|
||||||
itemRenderer.render(renderer);
|
itemRenderer.render(renderer);
|
||||||
} else if (background != null) {
|
} else if (background != null) {
|
||||||
background.render(renderer);
|
if (backgroundCondition == null || backgroundCondition.getAsBoolean()) {
|
||||||
|
background.render(renderer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.entity;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
|
|
||||||
|
public class EntityRenderPlayer extends EntityRender {
|
||||||
|
|
||||||
|
public EntityRenderPlayer(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityRenderable createRenderable(EntityData entity) {
|
||||||
|
EntityDataPlayer playerEntity = (EntityDataPlayer) entity;
|
||||||
|
|
||||||
|
String speciesId = playerEntity.getSpecies().getId();
|
||||||
|
SpeciesRender speciesRender = SpeciesRenderRegistry.getInstance().get(speciesId);
|
||||||
|
|
||||||
|
return speciesRender.createRenderable(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.entity;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.hud.HUDTextures;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.hud.HandsHUD;
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.EquipmentSlot;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand;
|
||||||
|
|
||||||
|
public abstract class SpeciesRender extends Namespaced {
|
||||||
|
|
||||||
|
public SpeciesRender(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract EntityRenderable createRenderable(EntityDataPlayer entity);
|
||||||
|
|
||||||
|
public abstract HandsHUD.Side getHandSide(Hand hand);
|
||||||
|
|
||||||
|
public Texture getTexture(String name) {
|
||||||
|
return HUDTextures.getHUDTexture(getNamespace() + "_" + getName() + "/" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture getHandBackground(Hand hand) {
|
||||||
|
return getTexture("Hand" + hand.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture getEquipmentSlotBackground(EquipmentSlot slot) {
|
||||||
|
return getTexture("EquipmentSlot" + slot.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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.entity;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
|
|
||||||
|
public class SpeciesRenderRegistry extends NamespacedInstanceRegistry<SpeciesRender> {
|
||||||
|
|
||||||
|
private static final SpeciesRenderRegistry INSTANCE = new SpeciesRenderRegistry();
|
||||||
|
|
||||||
|
public static SpeciesRenderRegistry getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpeciesRender get(EntityDataPlayer player) {
|
||||||
|
return get(player.getSpecies().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,41 +18,63 @@
|
|||||||
package ru.windcorp.progressia.common.world.entity;
|
package ru.windcorp.progressia.common.world.entity;
|
||||||
|
|
||||||
import ru.windcorp.progressia.common.Units;
|
import ru.windcorp.progressia.common.Units;
|
||||||
import ru.windcorp.progressia.common.collision.AABB;
|
import ru.windcorp.progressia.common.state.IntStateField;
|
||||||
import ru.windcorp.progressia.common.state.ObjectStateField;
|
import ru.windcorp.progressia.common.state.ObjectStateField;
|
||||||
import ru.windcorp.progressia.common.world.item.ItemContainerMixedSimple;
|
|
||||||
import ru.windcorp.progressia.common.world.item.ItemContainerHand;
|
import ru.windcorp.progressia.common.world.item.ItemContainerHand;
|
||||||
import ru.windcorp.progressia.common.world.item.ItemContainerMixed;
|
import ru.windcorp.progressia.common.world.item.ItemContainerMixedSimple;
|
||||||
|
|
||||||
public class EntityDataPlayer extends EntityData {
|
public class EntityDataPlayer extends EntityData {
|
||||||
|
|
||||||
|
private final ObjectStateField<SpeciesDatalet> speciesDatalet = field("Core:SpeciesDatalet").setShared()
|
||||||
|
.of(SpeciesDataRegistry.getInstance().getCodec()).build();
|
||||||
|
|
||||||
private final ObjectStateField<ItemContainerMixedSimple> inventory = field("Core:Inventory").setShared().def(
|
private final ObjectStateField<ItemContainerMixedSimple> inventory = field("Core:Inventory").setShared().def(
|
||||||
() -> new ItemContainerMixedSimple("Core:PlayerInventory", Units.get(15, "kg"), Units.get(50, "L"))
|
() -> new ItemContainerMixedSimple("Core:PlayerInventory", Units.get(15, "kg"), Units.get(50, "L"))
|
||||||
).build();
|
).build();
|
||||||
|
|
||||||
private final ObjectStateField<ItemContainerHand> leftHand = field("Core:LeftHand").setShared().def(
|
private final IntStateField selectedHand = field("Core:SelectedHand").setShared().ofInt().build();
|
||||||
() -> new ItemContainerHand("Core:PlayerLeftHand", Units.get(10, "kg"), Units.get(5, "L"))
|
|
||||||
).build();
|
|
||||||
|
|
||||||
private final ObjectStateField<ItemContainerHand> rightHand = field("Core:RightHand").setShared().def(
|
|
||||||
() -> new ItemContainerHand("Core:PlayerRightHand", Units.get(10, "kg"), Units.get(5, "L"))
|
|
||||||
).build();
|
|
||||||
|
|
||||||
public EntityDataPlayer(String id) {
|
public EntityDataPlayer(String id, SpeciesData species) {
|
||||||
super(id);
|
super(id);
|
||||||
setCollisionModel(new AABB(0, 0, 1.8f / 2, 0.8f, 0.8f, 1.8f));
|
|
||||||
|
setSpecies(species);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemContainerMixed getInventory() {
|
public ItemContainerMixedSimple getInventory() {
|
||||||
return inventory.get(this);
|
return inventory.get(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemContainerHand getLeftHand() {
|
private void setSpecies(SpeciesData species) {
|
||||||
return leftHand.get(this);
|
speciesDatalet.setNow(this, species.createDatalet());
|
||||||
|
setCollisionModel(species.getCollisionModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemContainerHand getRightHand() {
|
public SpeciesData getSpecies() {
|
||||||
return rightHand.get(this);
|
return speciesDatalet.get(this).getSpecies();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemContainerHand getHand(int index) {
|
||||||
|
return speciesDatalet.get(this).getHands()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHandCount() {
|
||||||
|
return speciesDatalet.get(this).getHands().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEquipmentCount() {
|
||||||
|
return speciesDatalet.get(this).getEquipment().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelectedHandIndex() {
|
||||||
|
return selectedHand.get(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedHandIndexNow(int index) {
|
||||||
|
selectedHand.setNow(this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemContainerHand getSelectedHand() {
|
||||||
|
return getHand(getSelectedHandIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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 java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.state.IOContext;
|
||||||
|
import ru.windcorp.progressia.common.state.codec.ObjectCodec;
|
||||||
|
|
||||||
|
public class SpeciesCodec extends ObjectCodec<SpeciesDatalet> {
|
||||||
|
|
||||||
|
public SpeciesCodec() {
|
||||||
|
super(SpeciesDatalet.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpeciesDatalet doRead(SpeciesDatalet previous, DataInput input, IOContext context) throws IOException {
|
||||||
|
String id = input.readUTF();
|
||||||
|
|
||||||
|
SpeciesDatalet result = previous;
|
||||||
|
|
||||||
|
if (result == null || !result.getSpecies().getId().equals(id)) {
|
||||||
|
SpeciesData species = SpeciesDataRegistry.getInstance().get(id);
|
||||||
|
if (species == null) {
|
||||||
|
throw new IOException("Unknown species ID " + species);
|
||||||
|
}
|
||||||
|
result = species.createDatalet();
|
||||||
|
}
|
||||||
|
|
||||||
|
result.read(input, context);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doWrite(SpeciesDatalet obj, DataOutput output, IOContext context) throws IOException {
|
||||||
|
output.writeUTF(obj.getSpecies().getId());
|
||||||
|
obj.write(output, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpeciesDatalet copy(SpeciesDatalet object, SpeciesDatalet previous) {
|
||||||
|
SpeciesDatalet result = previous;
|
||||||
|
|
||||||
|
if (result == null || result.getSpecies() != object.getSpecies()) {
|
||||||
|
result = object.getSpecies().createDatalet();
|
||||||
|
}
|
||||||
|
|
||||||
|
object.copy(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* 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 java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.collision.CollisionModel;
|
||||||
|
import ru.windcorp.progressia.common.util.Named;
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||||
|
import ru.windcorp.progressia.common.world.item.ItemData;
|
||||||
|
|
||||||
|
public abstract class SpeciesData extends Namespaced {
|
||||||
|
|
||||||
|
public static class Hand extends Named {
|
||||||
|
|
||||||
|
private int index = -1;
|
||||||
|
|
||||||
|
public Hand(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EquipmentSlot extends Named {
|
||||||
|
|
||||||
|
private int index = -1;
|
||||||
|
|
||||||
|
private Predicate<ItemData> filter;
|
||||||
|
|
||||||
|
public EquipmentSlot(String name, Predicate<ItemData> filter) {
|
||||||
|
super(name);
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Predicate<ItemData> getFilter() {
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Hand> hands;
|
||||||
|
private List<EquipmentSlot> equipmentSlots;
|
||||||
|
|
||||||
|
public SpeciesData(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withHands(Hand... hands) {
|
||||||
|
if (this.hands != null) {
|
||||||
|
throw new IllegalStateException("Hands already set");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hands.length == 0) {
|
||||||
|
throw new IllegalArgumentException("At least one hand required");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hands = ImmutableList.copyOf(hands);
|
||||||
|
|
||||||
|
for (int i = 0; i < hands.length; ++i) {
|
||||||
|
hands[i].index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withEquipmentSlots(EquipmentSlot... equipmentSlots) {
|
||||||
|
if (this.equipmentSlots != null) {
|
||||||
|
throw new IllegalStateException("Equipment slots already set");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.equipmentSlots = ImmutableList.copyOf(equipmentSlots);
|
||||||
|
|
||||||
|
for (int i = 0; i < equipmentSlots.length; ++i) {
|
||||||
|
equipmentSlots[i].index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Hand> getHands() {
|
||||||
|
return hands;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EquipmentSlot> getEquipmentSlots() {
|
||||||
|
return equipmentSlots;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract CollisionModel getCollisionModel();
|
||||||
|
|
||||||
|
public SpeciesDatalet createDatalet() {
|
||||||
|
return new SpeciesDatalet(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.state.codec.ObjectCodec;
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry;
|
||||||
|
|
||||||
|
public class SpeciesDataRegistry extends NamespacedInstanceRegistry<SpeciesData> {
|
||||||
|
|
||||||
|
private static final SpeciesDataRegistry INSTANCE = new SpeciesDataRegistry();
|
||||||
|
|
||||||
|
private final ObjectCodec<SpeciesDatalet> codec = new SpeciesCodec();
|
||||||
|
|
||||||
|
public static SpeciesDataRegistry getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectCodec<SpeciesDatalet> getCodec() {
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* 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 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;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.EquipmentSlot;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand;
|
||||||
|
import ru.windcorp.progressia.common.world.item.ItemContainerEquipment;
|
||||||
|
import ru.windcorp.progressia.common.world.item.ItemContainerHand;
|
||||||
|
|
||||||
|
public class SpeciesDatalet implements Encodable {
|
||||||
|
|
||||||
|
private final SpeciesData species;
|
||||||
|
|
||||||
|
private final ItemContainerHand[] hands;
|
||||||
|
private final ItemContainerEquipment[] equipment;
|
||||||
|
|
||||||
|
public SpeciesDatalet(SpeciesData species) {
|
||||||
|
this.species = species;
|
||||||
|
|
||||||
|
this.hands = new ItemContainerHand[species.getHands().size()];
|
||||||
|
for (int i = 0; i < hands.length; ++i) {
|
||||||
|
Hand hand = species.getHands().get(i);
|
||||||
|
this.hands[i] = new ItemContainerHand(species.getId() + "Hand" + hand.getName(), hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.equipment = new ItemContainerEquipment[species.getEquipmentSlots().size()];
|
||||||
|
for (int i = 0; i < equipment.length; ++i) {
|
||||||
|
EquipmentSlot equipmentSlot = species.getEquipmentSlots().get(i);
|
||||||
|
this.equipment[i] = new ItemContainerEquipment(
|
||||||
|
species.getId() + "EquipmentSlot" + equipmentSlot.getName(),
|
||||||
|
equipmentSlot
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpeciesData getSpecies() {
|
||||||
|
return species;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInput input, IOContext context) throws IOException {
|
||||||
|
for (int i = 0; i < hands.length; ++i) {
|
||||||
|
hands[i].read(input, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < equipment.length; ++i) {
|
||||||
|
equipment[i].read(input, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutput output, IOContext context) throws IOException {
|
||||||
|
for (int i = 0; i < hands.length; ++i) {
|
||||||
|
hands[i].write(output, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < equipment.length; ++i) {
|
||||||
|
equipment[i].write(output, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copy(Encodable destination) {
|
||||||
|
SpeciesDatalet other = (SpeciesDatalet) destination;
|
||||||
|
|
||||||
|
if (other.getSpecies() != getSpecies()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot copy datalet of species " + other.getSpecies() + " into datalet of species " + getSpecies()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < hands.length; ++i) {
|
||||||
|
hands[i].copy(other.hands[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < equipment.length; ++i) {
|
||||||
|
equipment[i].copy(other.equipment[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the hands
|
||||||
|
*/
|
||||||
|
public ItemContainerHand[] getHands() {
|
||||||
|
return hands;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the equipment
|
||||||
|
*/
|
||||||
|
public ItemContainerEquipment[] getEquipment() {
|
||||||
|
return equipment;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.Units;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData;
|
||||||
|
|
||||||
|
public class ItemContainerEquipment extends ItemContainerSingle {
|
||||||
|
|
||||||
|
private static final float EQUIP_MASS_LIMIT = Units.get("15 kg");
|
||||||
|
private static final float EQUIP_VOLUME_LIMIT = Units.get("60 kg");
|
||||||
|
|
||||||
|
private final SpeciesData.EquipmentSlot equipmentSlot;
|
||||||
|
|
||||||
|
public ItemContainerEquipment(String id, SpeciesData.EquipmentSlot equipmentSlot) {
|
||||||
|
super(id, EQUIP_MASS_LIMIT, EQUIP_VOLUME_LIMIT);
|
||||||
|
this.equipmentSlot = equipmentSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpeciesData.EquipmentSlot getEquipmentSlot() {
|
||||||
|
return equipmentSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -17,71 +17,24 @@
|
|||||||
*/
|
*/
|
||||||
package ru.windcorp.progressia.common.world.item;
|
package ru.windcorp.progressia.common.world.item;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import ru.windcorp.progressia.common.Units;
|
||||||
import java.io.DataOutput;
|
import ru.windcorp.progressia.common.world.entity.SpeciesData;
|
||||||
import java.io.IOException;
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import ru.windcorp.progressia.common.state.Encodable;
|
public class ItemContainerHand extends ItemContainerSingle {
|
||||||
import ru.windcorp.progressia.common.state.IOContext;
|
|
||||||
|
|
||||||
public class ItemContainerHand extends ItemContainer {
|
|
||||||
|
|
||||||
private final ItemSlot slot = new ItemSlot();
|
private static final float HAND_MASS_LIMIT = Units.get("10 kg");
|
||||||
|
private static final float HAND_VOLUME_LIMIT = Units.get("5 kg");
|
||||||
|
|
||||||
private final float massLimit;
|
private final SpeciesData.Hand hand;
|
||||||
private final float volumeLimit;
|
|
||||||
|
|
||||||
public ItemContainerHand(String id, float massLimit, float volumeLimit) {
|
public ItemContainerHand(String id, Hand hand) {
|
||||||
super(id);
|
super(id, HAND_MASS_LIMIT, HAND_VOLUME_LIMIT);
|
||||||
this.massLimit = massLimit;
|
this.hand = hand;
|
||||||
this.volumeLimit = volumeLimit;
|
|
||||||
|
|
||||||
slot.setContainer(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public SpeciesData.Hand getHand() {
|
||||||
public void read(DataInput input, IOContext context) throws IOException {
|
return hand;
|
||||||
slot.read(input, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(DataOutput output, IOContext context) throws IOException {
|
|
||||||
slot.write(output, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void copy(Encodable destination) {
|
|
||||||
slot.copy(((ItemContainerHand) destination).slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemSlot getSlot(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
return slot;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSlotCount() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void forEach(Consumer<ItemSlot> action) {
|
|
||||||
action.accept(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getMassLimit() {
|
|
||||||
return massLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getVolumeLimit() {
|
|
||||||
return volumeLimit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.common.world.item;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.state.Encodable;
|
||||||
|
import ru.windcorp.progressia.common.state.IOContext;
|
||||||
|
|
||||||
|
public abstract class ItemContainerSingle extends ItemContainer {
|
||||||
|
|
||||||
|
private final ItemSlot slot = new ItemSlot();
|
||||||
|
|
||||||
|
private final float massLimit;
|
||||||
|
private final float volumeLimit;
|
||||||
|
|
||||||
|
public ItemContainerSingle(String id, float massLimit, float volumeLimit) {
|
||||||
|
super(id);
|
||||||
|
this.massLimit = massLimit;
|
||||||
|
this.volumeLimit = volumeLimit;
|
||||||
|
|
||||||
|
slot.setContainer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInput input, IOContext context) throws IOException {
|
||||||
|
slot.read(input, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutput output, IOContext context) throws IOException {
|
||||||
|
slot.write(output, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copy(Encodable destination) {
|
||||||
|
slot.copy(((ItemContainerSingle) destination).slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemSlot getSlot(int index) {
|
||||||
|
if (index == 0) {
|
||||||
|
return slot;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemSlot slot() {
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlotCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEach(Consumer<ItemSlot> action) {
|
||||||
|
action.accept(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMassLimit() {
|
||||||
|
return massLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getVolumeLimit() {
|
||||||
|
return volumeLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -30,15 +30,14 @@ import ru.windcorp.progressia.client.graphics.texture.ComplexTexture;
|
|||||||
import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive;
|
import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive;
|
||||||
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
||||||
import ru.windcorp.progressia.client.world.entity.HumanoidModel;
|
import ru.windcorp.progressia.client.world.entity.HumanoidModel;
|
||||||
import ru.windcorp.progressia.client.world.entity.EntityRender;
|
|
||||||
import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
|
import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
|
||||||
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
||||||
import ru.windcorp.progressia.common.util.FloatMathUtil;
|
import ru.windcorp.progressia.common.util.FloatMathUtil;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
|
|
||||||
import static java.lang.Math.*;
|
import static java.lang.Math.*;
|
||||||
|
|
||||||
public class TestEntityRenderHuman extends EntityRender {
|
public class HumanModelFactory {
|
||||||
|
|
||||||
private static final float SECOND_LAYER_OFFSET = 1 / 12f;
|
private static final float SECOND_LAYER_OFFSET = 1 / 12f;
|
||||||
|
|
||||||
@ -51,9 +50,7 @@ public class TestEntityRenderHuman extends EntityRender {
|
|||||||
|
|
||||||
private final TexturePrimitive skin;
|
private final TexturePrimitive skin;
|
||||||
|
|
||||||
public TestEntityRenderHuman(String id) {
|
public HumanModelFactory() {
|
||||||
super(id);
|
|
||||||
|
|
||||||
this.skin = fetchSkin();
|
this.skin = fetchSkin();
|
||||||
|
|
||||||
ComplexTexture texture = new ComplexTexture(
|
ComplexTexture texture = new ComplexTexture(
|
||||||
@ -203,8 +200,7 @@ public class TestEntityRenderHuman extends EntityRender {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public EntityRenderable createRenderable(EntityDataPlayer entity) {
|
||||||
public EntityRenderable createRenderable(EntityData entity) {
|
|
||||||
return new HumanoidModel(
|
return new HumanoidModel(
|
||||||
entity,
|
entity,
|
||||||
|
|
||||||
@ -237,7 +233,7 @@ public class TestEntityRenderHuman extends EntityRender {
|
|||||||
0.0f
|
0.0f
|
||||||
),
|
),
|
||||||
|
|
||||||
1.8f / (3 + 3 + 2)
|
SpeciesDataHuman.HEIGHT / (3 + 3 + 2)
|
||||||
)
|
)
|
||||||
.setWalkingArmSwing((float) toRadians(30))
|
.setWalkingArmSwing((float) toRadians(30))
|
||||||
.setWalkingLegSwing((float) toRadians(50))
|
.setWalkingLegSwing((float) toRadians(50))
|
@ -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.test;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.Units;
|
||||||
|
import ru.windcorp.progressia.common.collision.AABB;
|
||||||
|
import ru.windcorp.progressia.common.collision.CollisionModel;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData;
|
||||||
|
|
||||||
|
public class SpeciesDataHuman extends SpeciesData {
|
||||||
|
|
||||||
|
public static final float HEIGHT = Units.get("180 cm");
|
||||||
|
public static final float WIDTH = Units.get("80 cm");
|
||||||
|
|
||||||
|
public SpeciesDataHuman(String id) {
|
||||||
|
super(id);
|
||||||
|
|
||||||
|
withHands(new Hand("Right"), new Hand("Left"));
|
||||||
|
withEquipmentSlots(/* ._. nope */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollisionModel getCollisionModel() {
|
||||||
|
return new AABB(0, 0, HEIGHT / 2, WIDTH, WIDTH, HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.hud.HandsHUD.Side;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.SpeciesRender;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand;
|
||||||
|
|
||||||
|
public class SpeciesRenderHuman extends SpeciesRender {
|
||||||
|
|
||||||
|
private final HumanModelFactory modelFactory = new HumanModelFactory();
|
||||||
|
|
||||||
|
public SpeciesRenderHuman(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityRenderable createRenderable(EntityDataPlayer entity) {
|
||||||
|
return modelFactory.createRenderable(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Side getHandSide(Hand hand) {
|
||||||
|
return hand.getIndex() == 0 ? Side.RIGHT : Side.LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -283,15 +283,23 @@ public class TestContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void registerEntities() {
|
private static void registerEntities() {
|
||||||
registerEntity("Core:Player", EntityDataPlayer::new);
|
registerPlayer();
|
||||||
register(new TestEntityRenderHuman("Core:Player"));
|
|
||||||
register(new EntityLogic("Core:Player"));
|
|
||||||
|
|
||||||
registerEntity("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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void registerPlayer() {
|
||||||
|
SpeciesData human = new SpeciesDataHuman("Core:Human");
|
||||||
|
SpeciesDataRegistry.getInstance().register(human);
|
||||||
|
SpeciesRenderRegistry.getInstance().register(new SpeciesRenderHuman("Core:Human"));
|
||||||
|
|
||||||
|
registerEntity("Core:Player", id -> new EntityDataPlayer(id, human));
|
||||||
|
register(new EntityRenderPlayer("Core:Player"));
|
||||||
|
register(new EntityLogic("Core:Player"));
|
||||||
|
}
|
||||||
|
|
||||||
private static void regsiterControls() {
|
private static void regsiterControls() {
|
||||||
ControlDataRegistry data = ControlDataRegistry.getInstance();
|
ControlDataRegistry data = ControlDataRegistry.getInstance();
|
||||||
ControlTriggerRegistry triggers = ControlTriggerRegistry.getInstance();
|
ControlTriggerRegistry triggers = ControlTriggerRegistry.getInstance();
|
||||||
|
@ -84,6 +84,7 @@ public class TestPlayerControls {
|
|||||||
|
|
||||||
private double lastSpacePress = Double.NEGATIVE_INFINITY;
|
private double lastSpacePress = Double.NEGATIVE_INFINITY;
|
||||||
private double lastSprintPress = Double.NEGATIVE_INFINITY;
|
private double lastSprintPress = Double.NEGATIVE_INFINITY;
|
||||||
|
private double lastCtrlPress = Double.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
private int selectedBlock = 0;
|
private int selectedBlock = 0;
|
||||||
private int selectedTile = 0;
|
private int selectedTile = 0;
|
||||||
@ -250,6 +251,13 @@ public class TestPlayerControls {
|
|||||||
return false;
|
return false;
|
||||||
switchPlacingMode();
|
switchPlacingMode();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GLFW.GLFW_KEY_LEFT_CONTROL:
|
||||||
|
case GLFW.GLFW_KEY_RIGHT_CONTROL:
|
||||||
|
if (event.isRepeat())
|
||||||
|
return false;
|
||||||
|
handleCtrl(event);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -435,8 +443,60 @@ public class TestPlayerControls {
|
|||||||
isBlockSelected = !isBlockSelected;
|
isBlockSelected = !isBlockSelected;
|
||||||
updateGUI();
|
updateGUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleCtrlIfApplicable(Input input) {
|
||||||
|
if (input.getEvent() instanceof KeyEvent) {
|
||||||
|
KeyEvent ke = (KeyEvent) input.getEvent();
|
||||||
|
if (ke.isRepeat()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ke.getKey() == GLFW.GLFW_KEY_LEFT_CONTROL || ke.getKey() == GLFW.GLFW_KEY_RIGHT_CONTROL) {
|
||||||
|
handleCtrl(ke);
|
||||||
|
input.consume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public EntityData getEntity() {
|
private void handleCtrl(KeyEvent event) {
|
||||||
|
if (ClientState.getInstance() == null || !ClientState.getInstance().isReady()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double now = GraphicsInterface.getTime();
|
||||||
|
int change = 0;
|
||||||
|
|
||||||
|
if (event.isPress()) {
|
||||||
|
change = +1;
|
||||||
|
lastCtrlPress = now;
|
||||||
|
} else {
|
||||||
|
if (now - lastCtrlPress > Units.get("200 ms")) {
|
||||||
|
change = -1;
|
||||||
|
lastCtrlPress = Double.NEGATIVE_INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.hasShift()) {
|
||||||
|
change *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int selected = getEntity().getSelectedHandIndex();
|
||||||
|
int maxSelected = getEntity().getHandCount() - 1;
|
||||||
|
|
||||||
|
selected += change;
|
||||||
|
if (selected < 0) {
|
||||||
|
selected = maxSelected;
|
||||||
|
} else if (selected > maxSelected) {
|
||||||
|
selected = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEntity().setSelectedHandIndexNow(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityDataPlayer getEntity() {
|
||||||
return getPlayer().getEntity();
|
return getPlayer().getEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ package ru.windcorp.progressia.test.inv;
|
|||||||
import glm.vec._2.i.Vec2i;
|
import glm.vec._2.i.Vec2i;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Button;
|
import ru.windcorp.progressia.client.graphics.gui.Button;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutFill;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutFill;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.hud.SlotComponent;
|
||||||
import ru.windcorp.progressia.common.world.item.ItemContainer;
|
import ru.windcorp.progressia.common.world.item.ItemContainer;
|
||||||
import ru.windcorp.progressia.common.world.item.ItemSlot;
|
import ru.windcorp.progressia.common.world.item.ItemSlot;
|
||||||
|
|
||||||
|
@ -18,93 +18,135 @@
|
|||||||
package ru.windcorp.progressia.test.inv;
|
package ru.windcorp.progressia.test.inv;
|
||||||
|
|
||||||
import glm.vec._2.i.Vec2i;
|
import glm.vec._2.i.Vec2i;
|
||||||
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
import ru.windcorp.progressia.client.graphics.ExponentAnimation;
|
||||||
import ru.windcorp.progressia.client.graphics.backend.InputTracker;
|
import ru.windcorp.progressia.client.graphics.backend.InputTracker;
|
||||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.hud.SlotComponent;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.SpeciesRender;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.SpeciesRenderRegistry;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand;
|
||||||
|
import ru.windcorp.progressia.common.world.item.ItemContainerHand;
|
||||||
|
|
||||||
public class HandSlots extends Component {
|
public class HandSlots extends Component {
|
||||||
|
|
||||||
private final SlotComponent left;
|
private class CursorBoundSlot {
|
||||||
private final SlotComponent right;
|
|
||||||
|
|
||||||
/**
|
private final SlotComponent component;
|
||||||
* Right is 0, left is 1
|
private final Renderable renderable;
|
||||||
*/
|
|
||||||
private float selection = 0;
|
|
||||||
private static final float ANIMATION_SPEED = 10f;
|
|
||||||
|
|
||||||
public HandSlots(String name, SlotComponent left, SlotComponent right) {
|
/**
|
||||||
super(name);
|
* 0 is not selected, 1 is selected
|
||||||
this.left = left;
|
*/
|
||||||
this.right = right;
|
private final ExponentAnimation selection = new ExponentAnimation(10, 0);
|
||||||
|
private final double angle;
|
||||||
|
|
||||||
addChild(left);
|
public CursorBoundSlot(SlotComponent component, double angle) {
|
||||||
addChild(right);
|
this.component = component;
|
||||||
setLayout(null);
|
this.angle = angle;
|
||||||
|
|
||||||
|
Vec2i size = component.getPreferredSize();
|
||||||
|
component.setBounds(-size.x / 2, -size.y / 2, size);
|
||||||
|
|
||||||
|
this.renderable = component.assembleToRenderable();
|
||||||
|
|
||||||
|
if (player.getHandCount() == 1) {
|
||||||
|
// Disable opening animation hint
|
||||||
|
selection.setValue(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(ShapeRenderHelper renderer) {
|
||||||
|
|
||||||
|
float target = player.getSelectedHand() == component.getSlot().getContainer() ? 1 : 0;
|
||||||
|
float sel = selection.updateForFrame(target);
|
||||||
|
|
||||||
|
float distance = HandSlots.this.distance * (1 - sel);
|
||||||
|
float x = (float) Math.cos(angle) * distance;
|
||||||
|
float y = (float) Math.sin(angle) * distance;
|
||||||
|
float scale = 0.5f + 0.5f * sel;
|
||||||
|
|
||||||
|
renderer.pushTransform().translate(x, y, 0).scale(scale);
|
||||||
|
|
||||||
|
boolean popColor = false;
|
||||||
|
if (sel > 0.5f && component.getSlot().isEmpty()) {
|
||||||
|
renderer.pushColorMultiplier().mul(1, 1, 1, 1 - 2 * (sel - 0.5f));
|
||||||
|
popColor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderable.render(renderer);
|
||||||
|
|
||||||
|
if (popColor) {
|
||||||
|
renderer.popColorMultiplier();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.popTransform();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
centerAtOrigin(left);
|
|
||||||
centerAtOrigin(right);
|
|
||||||
layoutSelf();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void centerAtOrigin(Component component) {
|
private final EntityDataPlayer player;
|
||||||
Vec2i size = component.getPreferredSize();
|
|
||||||
component.setBounds(-size.x / 2, -size.y / 2, size);
|
private final float distance = 50;
|
||||||
|
private final double startAngle = Math.PI / 4;
|
||||||
|
private final double endAngle = -3 * Math.PI / 4;
|
||||||
|
|
||||||
|
private final CursorBoundSlot[] slots;
|
||||||
|
|
||||||
|
public HandSlots(String name, EntityDataPlayer player) {
|
||||||
|
super(name);
|
||||||
|
this.player = player;
|
||||||
|
|
||||||
|
this.slots = new CursorBoundSlot[player.getHandCount()];
|
||||||
|
|
||||||
|
// This produces NaN when there is only one hand, but then it is unused
|
||||||
|
double angleStep = (endAngle - startAngle) / (slots.length - 1);
|
||||||
|
|
||||||
|
double angle = startAngle;
|
||||||
|
for (int i = 0; i < slots.length; ++i) {
|
||||||
|
|
||||||
|
SpeciesRender speciesRender = SpeciesRenderRegistry.getInstance().get(player);
|
||||||
|
|
||||||
|
ItemContainerHand container = player.getHand(i);
|
||||||
|
Hand hand = container.getHand();
|
||||||
|
|
||||||
|
SlotComponent component = new SlotComponent(name + ".Hand" + hand.getName(), container, 0)
|
||||||
|
.setBackground(speciesRender.getHandBackground(hand));
|
||||||
|
|
||||||
|
addChild(component);
|
||||||
|
|
||||||
|
slots[i] = new CursorBoundSlot(component, angle);
|
||||||
|
|
||||||
|
angle += angleStep;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setLayout(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assembleChildren(RenderTarget target) {
|
protected void assembleChildren(RenderTarget target) {
|
||||||
|
|
||||||
Renderable leftRenderable = left.assembleToRenderable();
|
|
||||||
Renderable rightRenderable = right.assembleToRenderable();
|
|
||||||
|
|
||||||
target.addCustomRenderer(renderer -> {
|
target.addCustomRenderer(renderer -> {
|
||||||
|
|
||||||
tickAnimation();
|
|
||||||
|
|
||||||
renderer.pushTransform().translate(
|
renderer.pushTransform().translate(
|
||||||
(float) InputTracker.getCursorX(),
|
(float) InputTracker.getCursorX(),
|
||||||
(float) InputTracker.getCursorY(),
|
(float) InputTracker.getCursorY(),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
if (selection > 0.5) {
|
for (CursorBoundSlot slot : slots) {
|
||||||
renderHand(renderer, leftRenderable, selection, -1);
|
slot.render(renderer);
|
||||||
renderHand(renderer, rightRenderable, 1 - selection, +1);
|
|
||||||
} else {
|
|
||||||
renderHand(renderer, rightRenderable, 1 - selection, +1);
|
|
||||||
renderHand(renderer, leftRenderable, selection, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.popTransform();
|
renderer.popTransform();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private float stretch(float t, float zero, float one) {
|
|
||||||
return zero * (1 - t) + one * t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderHand(ShapeRenderHelper renderer, Renderable renderable, float selected, float direction) {
|
|
||||||
|
|
||||||
float offsetX = direction * stretch(selected, 40, 0);
|
|
||||||
float offsetY = direction * stretch(selected, 30, 0);
|
|
||||||
float scale = selected < 0.5 ? stretch(selected * 2, 0.6f, 1.0f) : 1;
|
|
||||||
|
|
||||||
renderer.pushTransform().translate(offsetX, offsetY, 0).scale(scale);
|
|
||||||
renderable.render(renderer);
|
|
||||||
renderer.popTransform();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tickAnimation() {
|
|
||||||
float desired = InventoryScreen.isLeftHandSelected() ? 1 : 0;
|
|
||||||
float difference = selection - desired;
|
|
||||||
selection += difference * (1 - Math.exp(ANIMATION_SPEED * GraphicsInterface.getFrameLength()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@ package ru.windcorp.progressia.test.inv;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.graphics.Colors;
|
import ru.windcorp.progressia.client.graphics.Colors;
|
||||||
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.BasicButton;
|
import ru.windcorp.progressia.client.graphics.gui.BasicButton;
|
||||||
@ -35,7 +33,6 @@ import ru.windcorp.progressia.client.graphics.input.WheelScrollEvent;
|
|||||||
import ru.windcorp.progressia.client.graphics.input.bus.InputListener;
|
import ru.windcorp.progressia.client.graphics.input.bus.InputListener;
|
||||||
import ru.windcorp.progressia.common.Units;
|
import ru.windcorp.progressia.common.Units;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
import ru.windcorp.progressia.common.world.item.ItemContainer;
|
|
||||||
import ru.windcorp.progressia.common.world.item.ItemSlot;
|
import ru.windcorp.progressia.common.world.item.ItemSlot;
|
||||||
import ru.windcorp.progressia.common.world.item.Items;
|
import ru.windcorp.progressia.common.world.item.Items;
|
||||||
|
|
||||||
@ -43,16 +40,9 @@ public class InventoryScreen extends Component {
|
|||||||
|
|
||||||
private static final double MIN_PICK_ALL_DELAY = Units.get("0.5 s");
|
private static final double MIN_PICK_ALL_DELAY = Units.get("0.5 s");
|
||||||
|
|
||||||
private static boolean isLeftHandSelected = false;
|
|
||||||
private static double controlStart = Double.NEGATIVE_INFINITY;
|
|
||||||
|
|
||||||
public static boolean isLeftHandSelected() {
|
|
||||||
return isLeftHandSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ItemContainer leftHand;
|
|
||||||
private final ItemContainer rightHand;
|
|
||||||
private final InventoryComponent mainInventory;
|
private final InventoryComponent mainInventory;
|
||||||
|
|
||||||
|
private final EntityDataPlayer player;
|
||||||
|
|
||||||
private double lastLeftClick = Double.NEGATIVE_INFINITY;
|
private double lastLeftClick = Double.NEGATIVE_INFINITY;
|
||||||
private ItemSlot lastLeftClickSlot = null;
|
private ItemSlot lastLeftClickSlot = null;
|
||||||
@ -60,10 +50,9 @@ public class InventoryScreen extends Component {
|
|||||||
public InventoryScreen(String name, InventoryComponent mainInventory, EntityDataPlayer player) {
|
public InventoryScreen(String name, InventoryComponent mainInventory, EntityDataPlayer player) {
|
||||||
super(name);
|
super(name);
|
||||||
|
|
||||||
isLeftHandSelected = false;
|
|
||||||
this.mainInventory = mainInventory;
|
this.mainInventory = mainInventory;
|
||||||
this.leftHand = player.getLeftHand();
|
|
||||||
this.rightHand = player.getRightHand();
|
this.player = player;
|
||||||
|
|
||||||
setLayout(new LayoutFill(0));
|
setLayout(new LayoutFill(0));
|
||||||
|
|
||||||
@ -73,39 +62,15 @@ public class InventoryScreen extends Component {
|
|||||||
mainInventoryPanel.addChild(mainInventory);
|
mainInventoryPanel.addChild(mainInventory);
|
||||||
addChild(Components.center(mainInventoryPanel));
|
addChild(Components.center(mainInventoryPanel));
|
||||||
|
|
||||||
SlotComponent leftComponent = new SlotComponent(name + ".HandLeft", leftHand, 0);
|
addChild(new HandSlots(name + ".Hands", player));
|
||||||
SlotComponent rightComponent = new SlotComponent(name + ".HandRight", rightHand, 0);
|
|
||||||
|
|
||||||
addChild(new HandSlots(name + ".Hands", leftComponent, rightComponent));
|
|
||||||
|
|
||||||
addListeners(mainInventory);
|
addListeners(mainInventory);
|
||||||
|
|
||||||
mainInventory.focusNext();
|
mainInventory.focusNext();
|
||||||
mainInventory.addListener(KeyEvent.class, input -> {
|
|
||||||
if (input.getKey() == GLFW.GLFW_KEY_LEFT_CONTROL || input.getKey() == GLFW.GLFW_KEY_RIGHT_CONTROL) {
|
|
||||||
double now = GraphicsInterface.getTime();
|
|
||||||
if (input.isPress()) {
|
|
||||||
isLeftHandSelected = !isLeftHandSelected;
|
|
||||||
controlStart = now;
|
|
||||||
} else if (input.isRelease()) {
|
|
||||||
if (now - controlStart > Units.get("200 ms")) {
|
|
||||||
isLeftHandSelected = !isLeftHandSelected;
|
|
||||||
controlStart = Double.NEGATIVE_INFINITY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addListeners(InventoryComponent mainInventory) {
|
private void addListeners(InventoryComponent mainInventory) {
|
||||||
|
Supplier<ItemSlot> handSlot = () -> player.getSelectedHand().slot();
|
||||||
ItemSlot left = leftHand.getSlot(0);
|
|
||||||
ItemSlot right = rightHand.getSlot(0);
|
|
||||||
|
|
||||||
Supplier<ItemSlot> handSlot = () -> isLeftHandSelected() ? left : right;
|
|
||||||
|
|
||||||
Consumer<BasicButton> pickAll = createPickAllAction(handSlot);
|
Consumer<BasicButton> pickAll = createPickAllAction(handSlot);
|
||||||
|
|
||||||
@ -139,10 +104,6 @@ public class InventoryScreen extends Component {
|
|||||||
lastLeftClickSlot = invSlot;
|
lastLeftClickSlot = invSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success && !leftHand.getSlot(0).isEmpty() && rightHand.getSlot(0).isEmpty()) {
|
|
||||||
success = Items.pour(leftHand.getSlot(0), invSlot) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
success = Items.pour(handSlot, invSlot) != 0;
|
success = Items.pour(handSlot, invSlot) != 0;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
|||||||
import ru.windcorp.progressia.client.graphics.input.bus.Input;
|
import ru.windcorp.progressia.client.graphics.input.bus.Input;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||||
import ru.windcorp.progressia.common.world.item.ItemContainerMixed;
|
import ru.windcorp.progressia.common.world.item.ItemContainerMixed;
|
||||||
|
import ru.windcorp.progressia.test.TestPlayerControls;
|
||||||
|
|
||||||
public class TestInventoryGUILayer extends GUILayer {
|
public class TestInventoryGUILayer extends GUILayer {
|
||||||
|
|
||||||
@ -38,6 +39,10 @@ public class TestInventoryGUILayer extends GUILayer {
|
|||||||
super("Inventory", new LayoutFill(0));
|
super("Inventory", new LayoutFill(0));
|
||||||
setCursorPolicy(CursorPolicy.INDIFFERENT);
|
setCursorPolicy(CursorPolicy.INDIFFERENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasContainer() {
|
||||||
|
return container != null;
|
||||||
|
}
|
||||||
|
|
||||||
public void setContainer(ItemContainerMixed container, EntityDataPlayer player) {
|
public void setContainer(ItemContainerMixed container, EntityDataPlayer player) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
@ -83,6 +88,8 @@ public class TestInventoryGUILayer extends GUILayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestPlayerControls.getInstance().handleCtrlIfApplicable(input);
|
||||||
|
|
||||||
super.handleInput(input);
|
super.handleInput(input);
|
||||||
input.consume();
|
input.consume();
|
||||||
|
@ -24,7 +24,7 @@ import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
|||||||
|
|
||||||
public class TestInventoryGUIManager {
|
public class TestInventoryGUIManager {
|
||||||
|
|
||||||
private static TestInventoryGUILayer layer;
|
public static TestInventoryGUILayer layer;
|
||||||
|
|
||||||
public static void setup() {
|
public static void setup() {
|
||||||
layer = new TestInventoryGUILayer();
|
layer = new TestInventoryGUILayer();
|
||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Reference in New Issue
Block a user