diff --git a/data.mv.db b/data.mv.db index 408d1a5..c8a0751 100644 Binary files a/data.mv.db and b/data.mv.db differ diff --git a/maps/551e1afc-9cda-4d9f-8817-bfd831fc0a75.dat b/maps/551e1afc-9cda-4d9f-8817-bfd831fc0a75.dat index 1915183..3cd5383 100644 Binary files a/maps/551e1afc-9cda-4d9f-8817-bfd831fc0a75.dat and b/maps/551e1afc-9cda-4d9f-8817-bfd831fc0a75.dat differ diff --git a/project.bep b/project.bep index 5c360f5..99e07bc 100644 --- a/project.bep +++ b/project.bep @@ -19,7 +19,8 @@ $ab9d40b4-eb28-45d7-bff2-9432a05eb41a(ab9d40b4-eb28-45d7-bff2-9432a05eb41a.xml Start MenuB[ $56ca6b39-f949-4212-9c23-312db25887e0(56ca6b39-f949-4212-9c23-312db25887e0.xml Game MenuBU $00bd0625-b3b8-4abf-97b7-91f42bce28ec(00bd0625-b3b8-4abf-97b7-91f42bce28ec.xmlHUDB[ -$c473a91a-ff25-4e71-9bec-b35e48102aeb(c473a91a-ff25-4e71-9bec-b35e48102aeb.xml EquipmentJZ +$c473a91a-ff25-4e71-9bec-b35e48102aeb(c473a91a-ff25-4e71-9bec-b35e48102aeb.xml EquipmentB^ +$53ca3e54-0f8d-44fa-8281-acd9c5bba743(53ca3e54-0f8d-44fa-8281-acd9c5bba743.xml Eq Item MenuJZ $e6f067f1-eba0-4e62-99c3-2fd867e6f142(e6f067f1-eba0-4e62-99c3-2fd867e6f142.pngPoof (J[ $312cc4e6-8c44-43e7-828a-e7e2a77836f3(312cc4e6-8c44-43e7-828a-e7e2a77836f3.pngArrow (J[ $54f657bd-8108-464c-9bbe-63944fc14f6b(54f657bd-8108-464c-9bbe-63944fc14f6b.pngPunch (J[ diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/Creature.java b/src/main/java/com/bartlomiejpluta/demo/entity/Creature.java index 0595aec..ce903ad 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/Creature.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/Creature.java @@ -1,6 +1,7 @@ package com.bartlomiejpluta.demo.entity; import com.bartlomiejpluta.base.api.character.Character; +import com.bartlomiejpluta.demo.world.item.Item; import com.bartlomiejpluta.demo.world.weapon.Weapon; import lombok.Getter; import lombok.NonNull; @@ -58,6 +59,12 @@ public abstract class Creature extends NamedCharacter { hp -= dmg; } + public void useEquipmentItem(Item item) { + if (item instanceof Weapon weapon) { + setWeapon(weapon); + } + } + @Override public void update(float dt) { super.update(dt); diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/Player.java b/src/main/java/com/bartlomiejpluta/demo/entity/Player.java index e8460c7..48a54c9 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/Player.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/Player.java @@ -2,11 +2,13 @@ package com.bartlomiejpluta.demo.entity; import com.bartlomiejpluta.base.api.character.Character; import com.bartlomiejpluta.demo.world.item.Item; +import com.bartlomiejpluta.demo.world.weapon.Weapon; import lombok.NonNull; import org.joml.Vector2i; public class Player extends Creature { private final Item[] equipment = new Item[4 * 4]; + private int pickingItemToEquipmentCooldown = 0; public Player(@NonNull Character entity) { super(entity); @@ -17,7 +19,7 @@ public class Player extends Creature { public void interact() { var coords = getCoordinates().add(getFaceDirection().vector, new Vector2i()); var entities = getLayer().getEntities(); - for (var i=0; i< entities.size(); ++i) { + for (var i = 0; i < entities.size(); ++i) { var entity = entities.get(i); if (entity.getCoordinates().equals(coords) && entity instanceof MapObject object) { @@ -25,16 +27,18 @@ public class Player extends Creature { return; } - if (entity.getCoordinates().equals(getCoordinates()) && entity instanceof Item item) { + if (pickingItemToEquipmentCooldown == 0 && entity.getCoordinates().equals(getCoordinates()) && entity instanceof Item item) { pushItemToEquipment(item); getLayer().removeEntity(item); + pickingItemToEquipmentCooldown = PICKING_ITEM_TO_EQUIPMENT_COOLDOWN; + return; } } } private void pushItemToEquipment(@NonNull Item item) { - for(int i=0; i 0) { + pickingItemToEquipmentCooldown = (int) Math.max(0, pickingItemToEquipmentCooldown - dt * 1000); + } + } + + private static final int PICKING_ITEM_TO_EQUIPMENT_COOLDOWN = 300; } \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/gui/EquipmentWindow.java b/src/main/java/com/bartlomiejpluta/demo/gui/EquipmentWindow.java index b332a2f..2494126 100644 --- a/src/main/java/com/bartlomiejpluta/demo/gui/EquipmentWindow.java +++ b/src/main/java/com/bartlomiejpluta/demo/gui/EquipmentWindow.java @@ -1,39 +1,119 @@ package com.bartlomiejpluta.demo.gui; import com.bartlomiejpluta.base.api.context.Context; -import com.bartlomiejpluta.base.api.gui.Component; -import com.bartlomiejpluta.base.api.gui.GUI; -import com.bartlomiejpluta.base.api.gui.Ref; -import com.bartlomiejpluta.base.api.gui.WindowManager; -import com.bartlomiejpluta.base.api.screen.Screen; +import com.bartlomiejpluta.base.api.gui.*; +import com.bartlomiejpluta.base.lib.gui.Label; import com.bartlomiejpluta.base.lib.gui.VGridOptionChoice; +import com.bartlomiejpluta.base.lib.gui.VOptionChoice; import com.bartlomiejpluta.demo.entity.Player; import com.bartlomiejpluta.demo.runner.DemoRunner; +import com.bartlomiejpluta.demo.world.item.Item; +import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon; +import com.bartlomiejpluta.demo.world.weapon.RangedWeapon; +import com.bartlomiejpluta.demo.world.weapon.Weapon; import java.util.Map; +import java.util.function.Consumer; + +import static java.lang.String.format; public class EquipmentWindow extends DecoratedWindow { private final DemoRunner runner; private final Player player; + private final Window eqItemMenuWindow; + private final Button useBtn; + private final Button dropBtn; + private final Button cancelBtn; + private final VOptionChoice eqItemMenu; + @Ref("eq") private VGridOptionChoice eqGrid; + @Ref("item-name") + private Label nameLbl; + + @Ref("item-details") + private Label detailsLbl; + public EquipmentWindow(Context context, GUI gui, Map refs) { super(context, gui, refs); this.runner = (DemoRunner) context.getGameRunner(); this.player = runner.getPlayer(); + this.eqItemMenuWindow = gui.inflateWindow(A.widgets.eq_item_menu.uid); + this.eqItemMenu = eqItemMenuWindow.reference("menu", VOptionChoice.class); + this.useBtn = eqItemMenuWindow.reference("use", Button.class); + this.dropBtn = eqItemMenuWindow.reference("drop", Button.class); + this.cancelBtn = eqItemMenuWindow.reference("cancel", Button.class); } @Override public void onOpen(WindowManager manager) { super.onOpen(manager); + cancelBtn.setAction(manager::close); + eqGrid.setOnSelect(this::updateItemDetails); + var i = 0; - for(var child : eqGrid.getChildren()) { + for (var child : eqGrid.getChildren()) { var slot = (ItemIconView) child; - slot.setIcon(player.getEquipmentItem(i++)); + slot.setItem(player.getEquipmentItem(i++)); + slot.setAction(handleItem(slot)); + } + + eqGrid.select(0, 0); + eqGrid.focus(); + } + + private Consumer handleItem(ItemIconView slot) { + return item -> { + useBtn.setText(getButtonTitle(item)); + eqItemMenu.select(0); + eqItemMenu.focus(); + + manager.open(eqItemMenuWindow); + + useBtn.setAction(() -> { + player.useEquipmentItem(item); + manager.close(); + }); + + dropBtn.setAction(() -> { + player.dropItemFromEquipment(item); + slot.setItem(null); + updateItemDetails(slot); + manager.close(); + }); + }; + } + + private void updateItemDetails(Component slot) { + var item = ((ItemIconView) slot).getItem(); + + if (item == null) { + nameLbl.setText(""); + detailsLbl.setText(""); + return; + } + + nameLbl.setText(item.getName()); + + if (item instanceof MeleeWeapon weapon) { + detailsLbl.setText(format("Damage: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getCooldown())); + return; + } + + if (item instanceof RangedWeapon weapon) { + detailsLbl.setText(format("Damage: %s\nRange: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getRangeRoller(), weapon.getCooldown())); } } + + private String getButtonTitle(Item item) { + if (item instanceof Weapon) { + return "Equip"; + } + + return "Use"; + } } \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/gui/ItemIconView.java b/src/main/java/com/bartlomiejpluta/demo/gui/ItemIconView.java index 58c9cb6..6d77057 100644 --- a/src/main/java/com/bartlomiejpluta/demo/gui/ItemIconView.java +++ b/src/main/java/com/bartlomiejpluta/demo/gui/ItemIconView.java @@ -4,8 +4,19 @@ import com.bartlomiejpluta.base.api.context.Context; import com.bartlomiejpluta.base.api.gui.Color; import com.bartlomiejpluta.base.api.gui.Component; import com.bartlomiejpluta.base.api.gui.GUI; +import com.bartlomiejpluta.base.api.icon.Icon; +import com.bartlomiejpluta.base.api.input.Key; +import com.bartlomiejpluta.base.api.input.KeyAction; +import com.bartlomiejpluta.base.api.input.KeyEvent; import com.bartlomiejpluta.base.api.screen.Screen; import com.bartlomiejpluta.base.lib.gui.IconView; +import com.bartlomiejpluta.demo.world.item.Item; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; + +import java.util.Map; +import java.util.function.Consumer; import java.util.Map; @@ -13,6 +24,12 @@ public class ItemIconView extends IconView { private final Color normal; private final Color hover; + @Getter + private Item item; + + @Setter + private Consumer action; + public ItemIconView(Context context, GUI gui, Map refs) { super(context, gui, refs); this.normal = gui.createColor(); @@ -21,6 +38,40 @@ public class ItemIconView extends IconView { normal.setRGBA(0x444444FF); hover.setRGBA(0x888888FF); super.setScale(2f); + + addEventListener(KeyEvent.TYPE, this::handleKeyEvent); + } + + public void setItem(Item item) { + this.item = item; + super.setIcon(item); + } + + @Override + public void setIcon(Icon icon) { + throw new UnsupportedOperationException(); + } + + @Override + public void setIconSet(String iconSetUid) { + throw new UnsupportedOperationException(); + } + + @Override + public void setIconSetRow(@NonNull Integer iconSetRow) { + throw new UnsupportedOperationException(); + } + + @Override + public void setIconSetColumn(@NonNull Integer iconSetColumn) { + throw new UnsupportedOperationException(); + } + + private void handleKeyEvent(KeyEvent event) { + if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && item != null && action != null) { + event.consume(); + action.accept(item); + } } @Override diff --git a/src/main/java/com/bartlomiejpluta/demo/gui/StartMenuWindow.java b/src/main/java/com/bartlomiejpluta/demo/gui/StartMenuWindow.java index 0175cda..2695e7d 100644 --- a/src/main/java/com/bartlomiejpluta/demo/gui/StartMenuWindow.java +++ b/src/main/java/com/bartlomiejpluta/demo/gui/StartMenuWindow.java @@ -20,12 +20,16 @@ public class StartMenuWindow extends DecoratedWindow implements Inflatable { @Getter private Button exitBtn; + @Ref("menu") + private VOptionChoice menu; + public StartMenuWindow(Context context, GUI gui, Map refs) { super(context, gui, refs); } @Override public void onInflate() { - newGameBtn.focus(); + menu.select(0); + menu.focus(); } } \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java b/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java index a69ba1a..862a8ec 100644 --- a/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java +++ b/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java @@ -74,7 +74,6 @@ public class DemoRunner implements GameRunner { this.player.setSpeed(4f); this.player.setAnimationSpeed(1f); this.player.setBlocking(true); - this.player.setWeapon(new RangedWeapon("wooden_bow")); } public void newGame() { diff --git a/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java b/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java index 56d75a0..1617a22 100644 --- a/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java +++ b/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java @@ -13,15 +13,17 @@ import lombok.Getter; import lombok.NonNull; import org.joml.Vector2i; -import java.util.Random; - public class MeleeWeapon extends IconDelegate implements Weapon { private final Context context; - private final DiceRoller roller; private final AnimationRunner animation; private final String sound; + @Getter private final String name; + + @Getter + private final DiceRoller dmgRoller; + @Getter private final int cooldown; @@ -34,7 +36,7 @@ public class MeleeWeapon extends IconDelegate implements Weapon { this.context = ContextHolder.INSTANCE.getContext(); this.name = template.getName(); - this.roller = DiceRoller.of(template.getDamage()); + this.dmgRoller = DiceRoller.of(template.getDamage()); this.cooldown = template.getCooldown(); this.animation = new RandomAnimationsRunner(2).nRange(0, 2f).nScale(0.2f, 0.15f).uAnimationSpeed(0.5f, 1f).nRotation(0, 10).offset(0, -10).uDelay(250, 500).with(A.animations.get(template.getAnimation()).uid); this.sound = A.sounds.get(template.getSound()).uid; @@ -45,7 +47,7 @@ public class MeleeWeapon extends IconDelegate implements Weapon { var facingNeighbour = attacker.getCoordinates().add(attacker.getFaceDirection().vector, new Vector2i()); for (var entity : attacker.getLayer().getEntities()) { if (entity.getCoordinates().equals(facingNeighbour) && entity.isBlocking() && entity instanceof Creature character) { - var damage = roller.roll(); + var damage = dmgRoller.roll(); character.hit(attacker, damage); animation.run(context, character.getLayer(), character); context.playSound(sound); diff --git a/src/main/java/com/bartlomiejpluta/demo/world/weapon/RangedWeapon.java b/src/main/java/com/bartlomiejpluta/demo/world/weapon/RangedWeapon.java index 6311fcc..8708b1e 100644 --- a/src/main/java/com/bartlomiejpluta/demo/world/weapon/RangedWeapon.java +++ b/src/main/java/com/bartlomiejpluta/demo/world/weapon/RangedWeapon.java @@ -18,16 +18,22 @@ import lombok.NonNull; public class RangedWeapon extends IconDelegate implements Weapon { private final Context context; - private final DiceRoller dmgRoller; - private final DiceRoller rangeRoller; private final BulletAnimationRunner animation; private final String sound; private final AnimationRunner punchAnimation; private final String punchSound; private final AnimationRunner missAnimation; private final String missSound; + @Getter private final String name; + + @Getter + private final DiceRoller dmgRoller; + + @Getter + private final DiceRoller rangeRoller; + @Getter private final int cooldown; diff --git a/widgets/53ca3e54-0f8d-44fa-8281-acd9c5bba743.xml b/widgets/53ca3e54-0f8d-44fa-8281-acd9c5bba743.xml new file mode 100644 index 0000000..d01c39c --- /dev/null +++ b/widgets/53ca3e54-0f8d-44fa-8281-acd9c5bba743.xml @@ -0,0 +1,42 @@ + + + + + Use + + + Drop + + + Cancel + + + + \ No newline at end of file diff --git a/widgets/c473a91a-ff25-4e71-9bec-b35e48102aeb.xml b/widgets/c473a91a-ff25-4e71-9bec-b35e48102aeb.xml index a3f0d97..14998aa 100644 --- a/widgets/c473a91a-ff25-4e71-9bec-b35e48102aeb.xml +++ b/widgets/c473a91a-ff25-4e71-9bec-b35e48102aeb.xml @@ -20,24 +20,46 @@ fontSize="30f">Equipment - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file