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());
|
||||
}
|
||||
|
||||
}
|
@ -124,6 +124,36 @@ public class Shapes {
|
||||
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 {
|
||||
|
||||
private final ShapeRenderProgram program;
|
||||
@ -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,13 +18,9 @@
|
||||
package ru.windcorp.progressia.client.graphics.world.hud;
|
||||
|
||||
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.texture.SimpleTextures;
|
||||
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||
import ru.windcorp.progressia.test.inv.SlotComponent;
|
||||
|
||||
public class PermanentHUD extends Component {
|
||||
|
||||
@ -37,16 +33,7 @@ public class PermanentHUD extends Component {
|
||||
throw new IllegalStateException("Player " + player + " does not have an associated entity");
|
||||
}
|
||||
|
||||
Group handDisplays = new Group(
|
||||
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));
|
||||
addChild(new HandsHUD(name + ".Hands", player).setLayoutHint(LayoutBorderVertical.UP));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,12 +15,10 @@
|
||||
* 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;
|
||||
package ru.windcorp.progressia.client.graphics.world.hud;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
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.RenderTarget;
|
||||
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.layout.LayoutAlign;
|
||||
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.Shapes.PgmBuilder;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
import ru.windcorp.progressia.client.world.item.ItemRenderRegistry;
|
||||
import ru.windcorp.progressia.client.world.item.ItemRenderable;
|
||||
@ -52,6 +49,7 @@ public class SlotComponent extends Component {
|
||||
private String amountDisplayString = "";
|
||||
|
||||
private Renderable background = null;
|
||||
private BooleanSupplier backgroundCondition = null;
|
||||
|
||||
public SlotComponent(String name, ItemContainer container, int index) {
|
||||
super(name);
|
||||
@ -80,20 +78,18 @@ public class SlotComponent extends Component {
|
||||
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) {
|
||||
background = 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
|
||||
)
|
||||
);
|
||||
return setBackground(texture, null);
|
||||
}
|
||||
|
||||
public SlotComponent setBackgroundDisplayCondition(BooleanSupplier backgroundCondition) {
|
||||
this.backgroundCondition = backgroundCondition;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -132,7 +128,9 @@ public class SlotComponent extends Component {
|
||||
if (itemRenderer != null) {
|
||||
itemRenderer.render(renderer);
|
||||
} 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;
|
||||
|
||||
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.world.item.ItemContainerMixedSimple;
|
||||
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 {
|
||||
|
||||
private final ObjectStateField<SpeciesDatalet> speciesDatalet = field("Core:SpeciesDatalet").setShared()
|
||||
.of(SpeciesDataRegistry.getInstance().getCodec()).build();
|
||||
|
||||
private final ObjectStateField<ItemContainerMixedSimple> inventory = field("Core:Inventory").setShared().def(
|
||||
() -> new ItemContainerMixedSimple("Core:PlayerInventory", Units.get(15, "kg"), Units.get(50, "L"))
|
||||
).build();
|
||||
|
||||
private final ObjectStateField<ItemContainerHand> leftHand = field("Core:LeftHand").setShared().def(
|
||||
() -> new ItemContainerHand("Core:PlayerLeftHand", Units.get(10, "kg"), Units.get(5, "L"))
|
||||
).build();
|
||||
private final IntStateField selectedHand = field("Core:SelectedHand").setShared().ofInt().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);
|
||||
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);
|
||||
}
|
||||
|
||||
public ItemContainerHand getLeftHand() {
|
||||
return leftHand.get(this);
|
||||
private void setSpecies(SpeciesData species) {
|
||||
speciesDatalet.setNow(this, species.createDatalet());
|
||||
setCollisionModel(species.getCollisionModel());
|
||||
}
|
||||
|
||||
public ItemContainerHand getRightHand() {
|
||||
return rightHand.get(this);
|
||||
public SpeciesData getSpecies() {
|
||||
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;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
import ru.windcorp.progressia.common.Units;
|
||||
import ru.windcorp.progressia.common.world.entity.SpeciesData;
|
||||
import ru.windcorp.progressia.common.world.entity.SpeciesData.Hand;
|
||||
|
||||
import ru.windcorp.progressia.common.state.Encodable;
|
||||
import ru.windcorp.progressia.common.state.IOContext;
|
||||
public class ItemContainerHand extends ItemContainerSingle {
|
||||
|
||||
public class ItemContainerHand extends ItemContainer {
|
||||
private static final float HAND_MASS_LIMIT = Units.get("10 kg");
|
||||
private static final float HAND_VOLUME_LIMIT = Units.get("5 kg");
|
||||
|
||||
private final ItemSlot slot = new ItemSlot();
|
||||
private final SpeciesData.Hand hand;
|
||||
|
||||
private final float massLimit;
|
||||
private final float volumeLimit;
|
||||
|
||||
public ItemContainerHand(String id, float massLimit, float volumeLimit) {
|
||||
super(id);
|
||||
this.massLimit = massLimit;
|
||||
this.volumeLimit = volumeLimit;
|
||||
|
||||
slot.setContainer(this);
|
||||
public ItemContainerHand(String id, Hand hand) {
|
||||
super(id, HAND_MASS_LIMIT, HAND_VOLUME_LIMIT);
|
||||
this.hand = hand;
|
||||
}
|
||||
|
||||
@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(((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;
|
||||
public SpeciesData.Hand getHand() {
|
||||
return hand;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.world.WorldRenderProgram;
|
||||
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.EntityRenderable;
|
||||
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.*;
|
||||
|
||||
public class TestEntityRenderHuman extends EntityRender {
|
||||
public class HumanModelFactory {
|
||||
|
||||
private static final float SECOND_LAYER_OFFSET = 1 / 12f;
|
||||
|
||||
@ -51,9 +50,7 @@ public class TestEntityRenderHuman extends EntityRender {
|
||||
|
||||
private final TexturePrimitive skin;
|
||||
|
||||
public TestEntityRenderHuman(String id) {
|
||||
super(id);
|
||||
|
||||
public HumanModelFactory() {
|
||||
this.skin = fetchSkin();
|
||||
|
||||
ComplexTexture texture = new ComplexTexture(
|
||||
@ -203,8 +200,7 @@ public class TestEntityRenderHuman extends EntityRender {
|
||||
return b.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityRenderable createRenderable(EntityData entity) {
|
||||
public EntityRenderable createRenderable(EntityDataPlayer entity) {
|
||||
return new HumanoidModel(
|
||||
entity,
|
||||
|
||||
@ -237,7 +233,7 @@ public class TestEntityRenderHuman extends EntityRender {
|
||||
0.0f
|
||||
),
|
||||
|
||||
1.8f / (3 + 3 + 2)
|
||||
SpeciesDataHuman.HEIGHT / (3 + 3 + 2)
|
||||
)
|
||||
.setWalkingArmSwing((float) toRadians(30))
|
||||
.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() {
|
||||
registerEntity("Core:Player", EntityDataPlayer::new);
|
||||
register(new TestEntityRenderHuman("Core:Player"));
|
||||
register(new EntityLogic("Core:Player"));
|
||||
registerPlayer();
|
||||
|
||||
registerEntity("Test:Statie", TestEntityDataStatie::new);
|
||||
register(new TestEntityRenderStatie("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() {
|
||||
ControlDataRegistry data = ControlDataRegistry.getInstance();
|
||||
ControlTriggerRegistry triggers = ControlTriggerRegistry.getInstance();
|
||||
|
@ -84,6 +84,7 @@ public class TestPlayerControls {
|
||||
|
||||
private double lastSpacePress = Double.NEGATIVE_INFINITY;
|
||||
private double lastSprintPress = Double.NEGATIVE_INFINITY;
|
||||
private double lastCtrlPress = Double.NEGATIVE_INFINITY;
|
||||
|
||||
private int selectedBlock = 0;
|
||||
private int selectedTile = 0;
|
||||
@ -251,6 +252,13 @@ public class TestPlayerControls {
|
||||
switchPlacingMode();
|
||||
break;
|
||||
|
||||
case GLFW.GLFW_KEY_LEFT_CONTROL:
|
||||
case GLFW.GLFW_KEY_RIGHT_CONTROL:
|
||||
if (event.isRepeat())
|
||||
return false;
|
||||
handleCtrl(event);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -436,7 +444,59 @@ public class TestPlayerControls {
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
public EntityData getEntity() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ package ru.windcorp.progressia.test.inv;
|
||||
import glm.vec._2.i.Vec2i;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Button;
|
||||
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.ItemSlot;
|
||||
|
||||
|
@ -18,65 +18,129 @@
|
||||
package ru.windcorp.progressia.test.inv;
|
||||
|
||||
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.flat.RenderTarget;
|
||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||
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 {
|
||||
|
||||
private final SlotComponent left;
|
||||
private final SlotComponent right;
|
||||
private class CursorBoundSlot {
|
||||
|
||||
/**
|
||||
* Right is 0, left is 1
|
||||
*/
|
||||
private float selection = 0;
|
||||
private static final float ANIMATION_SPEED = 10f;
|
||||
private final SlotComponent component;
|
||||
private final Renderable renderable;
|
||||
|
||||
public HandSlots(String name, SlotComponent left, SlotComponent right) {
|
||||
super(name);
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
/**
|
||||
* 0 is not selected, 1 is selected
|
||||
*/
|
||||
private final ExponentAnimation selection = new ExponentAnimation(10, 0);
|
||||
private final double angle;
|
||||
|
||||
addChild(left);
|
||||
addChild(right);
|
||||
setLayout(null);
|
||||
public CursorBoundSlot(SlotComponent component, double angle) {
|
||||
this.component = component;
|
||||
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) {
|
||||
Vec2i size = component.getPreferredSize();
|
||||
component.setBounds(-size.x / 2, -size.y / 2, size);
|
||||
private final EntityDataPlayer player;
|
||||
|
||||
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
|
||||
protected void assembleChildren(RenderTarget target) {
|
||||
|
||||
Renderable leftRenderable = left.assembleToRenderable();
|
||||
Renderable rightRenderable = right.assembleToRenderable();
|
||||
|
||||
target.addCustomRenderer(renderer -> {
|
||||
|
||||
tickAnimation();
|
||||
|
||||
renderer.pushTransform().translate(
|
||||
(float) InputTracker.getCursorX(),
|
||||
(float) InputTracker.getCursorY(),
|
||||
0
|
||||
);
|
||||
|
||||
if (selection > 0.5) {
|
||||
renderHand(renderer, leftRenderable, selection, -1);
|
||||
renderHand(renderer, rightRenderable, 1 - selection, +1);
|
||||
} else {
|
||||
renderHand(renderer, rightRenderable, 1 - selection, +1);
|
||||
renderHand(renderer, leftRenderable, selection, -1);
|
||||
for (CursorBoundSlot slot : slots) {
|
||||
slot.render(renderer);
|
||||
}
|
||||
|
||||
renderer.popTransform();
|
||||
@ -85,26 +149,4 @@ public class HandSlots extends Component {
|
||||
|
||||
}
|
||||
|
||||
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.Supplier;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.Colors;
|
||||
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
||||
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.common.Units;
|
||||
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.Items;
|
||||
|
||||
@ -43,27 +40,19 @@ public class InventoryScreen extends Component {
|
||||
|
||||
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 EntityDataPlayer player;
|
||||
|
||||
private double lastLeftClick = Double.NEGATIVE_INFINITY;
|
||||
private ItemSlot lastLeftClickSlot = null;
|
||||
|
||||
public InventoryScreen(String name, InventoryComponent mainInventory, EntityDataPlayer player) {
|
||||
super(name);
|
||||
|
||||
isLeftHandSelected = false;
|
||||
this.mainInventory = mainInventory;
|
||||
this.leftHand = player.getLeftHand();
|
||||
this.rightHand = player.getRightHand();
|
||||
|
||||
this.player = player;
|
||||
|
||||
setLayout(new LayoutFill(0));
|
||||
|
||||
@ -73,39 +62,15 @@ public class InventoryScreen extends Component {
|
||||
mainInventoryPanel.addChild(mainInventory);
|
||||
addChild(Components.center(mainInventoryPanel));
|
||||
|
||||
SlotComponent leftComponent = new SlotComponent(name + ".HandLeft", leftHand, 0);
|
||||
SlotComponent rightComponent = new SlotComponent(name + ".HandRight", rightHand, 0);
|
||||
|
||||
addChild(new HandSlots(name + ".Hands", leftComponent, rightComponent));
|
||||
addChild(new HandSlots(name + ".Hands", player));
|
||||
|
||||
addListeners(mainInventory);
|
||||
|
||||
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) {
|
||||
|
||||
ItemSlot left = leftHand.getSlot(0);
|
||||
ItemSlot right = rightHand.getSlot(0);
|
||||
|
||||
Supplier<ItemSlot> handSlot = () -> isLeftHandSelected() ? left : right;
|
||||
Supplier<ItemSlot> handSlot = () -> player.getSelectedHand().slot();
|
||||
|
||||
Consumer<BasicButton> pickAll = createPickAllAction(handSlot);
|
||||
|
||||
@ -139,10 +104,6 @@ public class InventoryScreen extends Component {
|
||||
lastLeftClickSlot = invSlot;
|
||||
}
|
||||
|
||||
if (!success && !leftHand.getSlot(0).isEmpty() && rightHand.getSlot(0).isEmpty()) {
|
||||
success = Items.pour(leftHand.getSlot(0), invSlot) != 0;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
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.common.world.entity.EntityDataPlayer;
|
||||
import ru.windcorp.progressia.common.world.item.ItemContainerMixed;
|
||||
import ru.windcorp.progressia.test.TestPlayerControls;
|
||||
|
||||
public class TestInventoryGUILayer extends GUILayer {
|
||||
|
||||
@ -39,6 +40,10 @@ public class TestInventoryGUILayer extends GUILayer {
|
||||
setCursorPolicy(CursorPolicy.INDIFFERENT);
|
||||
}
|
||||
|
||||
public boolean hasContainer() {
|
||||
return container != null;
|
||||
}
|
||||
|
||||
public void setContainer(ItemContainerMixed container, EntityDataPlayer player) {
|
||||
this.container = container;
|
||||
|
||||
@ -84,6 +89,8 @@ public class TestInventoryGUILayer extends GUILayer {
|
||||
}
|
||||
}
|
||||
|
||||
TestPlayerControls.getInstance().handleCtrlIfApplicable(input);
|
||||
|
||||
super.handleInput(input);
|
||||
input.consume();
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||
|
||||
public class TestInventoryGUIManager {
|
||||
|
||||
private static TestInventoryGUILayer layer;
|
||||
public static TestInventoryGUILayer layer;
|
||||
|
||||
public static void setup() {
|
||||
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