diff --git a/assets/Data/entity/items.json b/assets/Data/entity/items.json index ff26506e..8727d5db 100644 --- a/assets/Data/entity/items.json +++ b/assets/Data/entity/items.json @@ -356,6 +356,37 @@ "offsetZ" : 0 }, "iconPath" : "Textures/icons/itemIconItemGeneric.png" + }, + + { + "id" : "spawningPalette", + "tokens" : [ + "GRAVITY", + "TARGETABLE" + ], + "equipData": { + "equipClass" : "tool" + }, + "graphicsTemplate": { + "model": { + "path" : "Models/basic/geometry/unitcapsule.glb" + } + }, + "clientSidePrimary": "OPEN_SPAWN_PALETTE", + "collidable": { + "type" : "CUBE", + "dimension1" : 0.1, + "dimension2" : 0.1, + "dimension3" : 0.35, + "rotX": 0, + "rotY": 0, + "rotZ": 0, + "rotW": 1, + "offsetX" : 0, + "offsetY" : 0.05, + "offsetZ" : 0 + }, + "iconPath" : "Textures/icons/itemIconItemGeneric.png" } diff --git a/docs/src/highlevel-design/narrativemanager/narrativearcdesign.md b/docs/src/highlevel-design/narrativemanager/narrativearcdesign.md index 9f95b631..89c48eb6 100644 --- a/docs/src/highlevel-design/narrativemanager/narrativearcdesign.md +++ b/docs/src/highlevel-design/narrativemanager/narrativearcdesign.md @@ -2,4 +2,10 @@ Use the idea of conspiracy to create mystery eventually leading to a big series of confrontations and narrative payoff The primary challenge with this is coming up with ways to redirect the eventual conspiracy -IE, you don't want to introduce the ultimate bad guy at the start, there need to be middle men that you work towards defeating prior to capturing the big bad \ No newline at end of file +IE, you don't want to introduce the ultimate bad guy at the start, there need to be middle men that you work towards defeating prior to capturing the big bad + +Another challenge to consider is creating teasers for the narrative peaks. +IE, if your big bad is supposed to be a dark paladin, how do you tease him in the story without making it a final encounter. + - "Visions", "Proxies", etc that aren't the real version + - For certain types of creatures (ie dragons), you can have them fly by in a way that wouldn't be easily interacted with + \ No newline at end of file diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index d5185f34..7d71d400 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -14,22 +14,22 @@ Ticketed randomizer node for BTs to more heavily weight attacking and waiting + feedback driven requirements - Item/Equip overhaul (again) - - Add punching/unarmed combat - - Implement gadgets - - Trap - - Bear - - Freeze - - Flame - - Bomb (to be thrown) - - Regular (Deals damage, ignites) - - Air (high push coeff) - - Flash (dazes) - - Sleep (puts enemies to sleep) - - Smoke (creates LOS blockers) - - Decoy (creates a decoy) - - Torch - - Throwable potions + Add punching/unarmed combat + - Weapon raised/lowered component + Implement gadgets + - Trap + - Bear + - Freeze + - Flame + - Bomb (to be thrown) + - Regular (Deals damage, ignites) + - Air (high push coeff) + - Flash (dazes) + - Sleep (puts enemies to sleep) + - Smoke (creates LOS blockers) + - Decoy (creates a decoy) + - Torch + - Throwable potions Fix ui scaling on abnormal monitors Crouching Model clothing, hair for the human diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 57c06fdf..9845b935 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -851,6 +851,11 @@ Work on toolbar refactor (09/27/2024) Toolbar state mostly working +Filter toolbar slots out of equip menu + +(09/30/2024) +Fix attack tree checks +Disable client equip tests until can review # TODO diff --git a/src/main/java/electrosphere/client/item/ItemActions.java b/src/main/java/electrosphere/client/item/ItemActions.java index a2fc33b7..315e9eb9 100644 --- a/src/main/java/electrosphere/client/item/ItemActions.java +++ b/src/main/java/electrosphere/client/item/ItemActions.java @@ -6,8 +6,10 @@ import electrosphere.client.ui.menu.ingame.MenuGeneratorsTerrainEditing; import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; import electrosphere.entity.Entity; -import electrosphere.entity.state.equip.ClientEquipState; +import electrosphere.entity.state.attack.ClientAttackTree; +import electrosphere.entity.state.attack.ShooterTree; import electrosphere.entity.state.equip.ClientToolbarState; +import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.game.data.item.type.Item; import electrosphere.net.parser.net.message.InventoryMessage; @@ -27,6 +29,54 @@ public class ItemActions { //the state for releasing the item action code public static final int ITEM_ACTION_CODE_STATE_OFF = 0; + //the state for performing the item action code + public static final int ITEM_ACTION_CODE_STATE_REPEAT = 2; + + /** + * Attempts to perform the primary item action + */ + public static void attemptPrimaryItemAction(){ + //tell the server we want the secondary hand item to START doing something + Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestPerformItemActionMessage("handRight", ITEM_ACTION_CODE_PRIMARY, ITEM_ACTION_CODE_STATE_ON)); + //TODO: do any immediate client side calculations here (ie start playing an animation until we get response from server) + if(Globals.playerEntity != null){ + ClientAttackTree attackTree = CreatureUtils.clientGetAttackTree(Globals.playerEntity); + if(attackTree != null){ + attackTree.start(); + } + ShooterTree shooterTree = ShooterTree.getShooterTree(Globals.playerEntity); + if(shooterTree != null){ + shooterTree.fire(); + } + } + } + + /** + * Repeats the primary item action + */ + public static void repeatPrimaryItemAction(){ + //tell the server we want the secondary hand item to STOP doing something + Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestPerformItemActionMessage("handRight", ITEM_ACTION_CODE_PRIMARY, ITEM_ACTION_CODE_STATE_REPEAT)); + //TODO: do any immediate client side calculations here (ie start playing an animation until we get response from server) + } + + /** + * Releases the primary item action + */ + public static void releasePrimaryItemAction(){ + //tell the server we want the secondary hand item to STOP doing something + Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestPerformItemActionMessage("handRight", ITEM_ACTION_CODE_PRIMARY, ITEM_ACTION_CODE_STATE_OFF)); + //TODO: do any immediate client side calculations here (ie start playing an animation until we get response from server) + if(Globals.playerEntity != null){ + // Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); + ClientAttackTree attackTree = CreatureUtils.clientGetAttackTree(Globals.playerEntity); + if(attackTree != null){ + // CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); + attackTree.release(); + } + } + } + /** * Attempts to perform the secondary item action */ diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index be7b4eaa..910ef0d8 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -858,8 +858,23 @@ public class ControlHandler { }}); + /* + Attack + */ + mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY)); + controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnPress(new ControlMethod(){public void execute(){ + ItemActions.attemptPrimaryItemAction(); + }}); + controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRepeat(new ControlMethod(){public void execute(){ + ItemActions.repeatPrimaryItemAction(); + }}); + controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRelease(new ControlMethod(){public void execute(){ + ItemActions.releasePrimaryItemAction(); + }}); + controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setRepeatTimeout(0.5f * Main.targetFrameRate); + /** - * Item actions + * Secondary item actions */ mainGameControlList.add(controls.get(ITEM_SECONDARY)); controls.get(ITEM_SECONDARY).setOnPress(new ControlMethod() {public void execute() { @@ -899,44 +914,6 @@ public class ControlHandler { } }}); - /* - Attack - */ - mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY)); - controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnPress(new ControlMethod(){public void execute(){ - if(Globals.playerEntity != null){ - // Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); - ClientAttackTree attackTree = CreatureUtils.clientGetAttackTree(Globals.playerEntity); - if(attackTree != null){ - // CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); - attackTree.start(); - } - ShooterTree shooterTree = ShooterTree.getShooterTree(Globals.playerEntity); - if(shooterTree != null){ - shooterTree.fire(); - } - } - }}); - controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRepeat(new ControlMethod(){public void execute(){ - if(Globals.playerEntity != null){ - ShooterTree shooterTree = ShooterTree.getShooterTree(Globals.playerEntity); - if(shooterTree != null){ - shooterTree.fire(); - } - } - }}); - controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRelease(new ControlMethod(){public void execute(){ - if(Globals.playerEntity != null){ - // Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); - ClientAttackTree attackTree = CreatureUtils.clientGetAttackTree(Globals.playerEntity); - if(attackTree != null){ - // CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); - attackTree.release(); - } - } - }}); - controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setRepeatTimeout(0.5f * Main.targetFrameRate); - /* Lock on crosshair diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java index 63070fcc..1ac3c40a 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java @@ -175,6 +175,7 @@ public class LoadingUtils { } } template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool")); + template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette")); //set player character template serverPlayerConnection.setCreatureTemplate(template); Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage()); diff --git a/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java b/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java index 6c3865bd..e6666f8e 100644 --- a/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java +++ b/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java @@ -11,6 +11,7 @@ import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem; import electrosphere.entity.state.attach.AttachUtils; import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.equip.ClientEquipState; +import electrosphere.entity.state.equip.ClientToolbarState; import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.movement.fall.ClientFallTree; import electrosphere.entity.state.movement.jump.ClientJumpTree; @@ -401,24 +402,21 @@ public class ClientAttackTree implements BehaviorTree { */ protected String getAttackType(){ String rVal = null; - if(ClientEquipState.hasEquipState(parent)){ - ClientEquipState equipState = ClientEquipState.getEquipState(parent); - for(String point : equipState.getEquippedPoints()){ - Entity item = equipState.getEquippedItemAtPoint(point); - if(ItemUtils.isWeapon(item)){ - attackingPoint = point; - currentWeapon = item; - switch(ItemUtils.getWeaponClass(item)){ - case "sword1h": - rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND; - break; - case "sword2h": - rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_TWO_HAND; - break; - case "bow2h": - rVal = EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND; - break; - } + if(ClientToolbarState.getClientToolbarState(parent) != null){ + ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(parent); + Entity item = clientToolbarState.getCurrentPrimaryItem(); + if(ItemUtils.isWeapon(item)){ + currentWeapon = item; + switch(ItemUtils.getWeaponClass(item)){ + case "sword1h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND; + break; + case "sword2h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_TWO_HAND; + break; + case "bow2h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND; + break; } } } diff --git a/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java b/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java index 564bd230..33aeea0d 100644 --- a/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java +++ b/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java @@ -17,6 +17,7 @@ import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState; import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState; import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.equip.ServerEquipState; +import electrosphere.entity.state.equip.ServerToolbarState; import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.movement.fall.ServerFallTree; import electrosphere.entity.state.movement.jump.ServerJumpTree; @@ -475,24 +476,21 @@ public class ServerAttackTree implements BehaviorTree { */ protected String getAttackType(){ String rVal = null; - if(ServerEquipState.hasEquipState(parent)){ - ServerEquipState equipState = ServerEquipState.getEquipState(parent); - for(String point : equipState.equippedPoints()){ - Entity item = equipState.getEquippedItemAtPoint(point); - if(ItemUtils.isWeapon(item)){ - attackingPoint = point; - currentWeapon = item; - switch(ItemUtils.getWeaponClass(item)){ - case "sword1h": - rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND; - break; - case "sword2h": - rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_TWO_HAND; - break; - case "bow2h": - rVal = EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND; - break; - } + if(ServerToolbarState.getServerToolbarState(parent) != null){ + ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent); + Entity item = serverToolbarState.getRealWorldItem(); + if(ItemUtils.isWeapon(item)){ + currentWeapon = item; + switch(ItemUtils.getWeaponClass(item)){ + case "sword1h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND; + break; + case "sword2h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_TWO_HAND; + break; + case "bow2h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND; + break; } } } diff --git a/src/main/java/electrosphere/entity/state/equip/ServerToolbarState.java b/src/main/java/electrosphere/entity/state/equip/ServerToolbarState.java index 2e58f287..6bc1b930 100644 --- a/src/main/java/electrosphere/entity/state/equip/ServerToolbarState.java +++ b/src/main/java/electrosphere/entity/state/equip/ServerToolbarState.java @@ -90,6 +90,7 @@ public class ServerToolbarState implements BehaviorTree { //add to toolbar toolbarInventory.tryRemoveItem(inInventoryEntity); + this.unequip(inInventoryEntity); toolbarInventory.addItem(slotId + "", inInventoryEntity); if(slotId == selectedSlot){ visuallyEquipCurrentSlot(); @@ -286,6 +287,14 @@ public class ServerToolbarState implements BehaviorTree { dataCell.broadcastNetworkMessage(unequipMessage); } + /** + * Gets the real world item of the toolbar + * @return The real world item if it exists, null otherwise + */ + public Entity getRealWorldItem(){ + return realWorldItem; + } + /** *
(initially) Automatically generated
*
diff --git a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java
index d858a4ae..088fbf86 100644
--- a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java
+++ b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java
@@ -34,38 +34,39 @@ public class InventoryProtocol implements ClientProtocolTemplate