diff --git a/assets/Data/items.json b/assets/Data/items.json index 3a2392a5..c8722167 100644 --- a/assets/Data/items.json +++ b/assets/Data/items.json @@ -58,6 +58,7 @@ "weaponData" : { "weaponClass" : "sword2h", "damage" : 10, + "weaponActionMovePenalty" : 0.4, "hitboxes" : [ { "type": "hit_connected", diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index fd9a1a6a..ebc4a7e5 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -14,8 +14,6 @@ + fix the vibes Stability - Recoil State on attack - Movement penalty while swinging weapon Ticketed randomizer node for BTs to more heavily weight attacking and waiting + bug fixes diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index ea83114d..b353f67d 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -706,6 +706,7 @@ Framebuffer + RenderingEngine tests (09/09/2024) Fix obnoxious opengl state caching bug w/ framebuffers in junit context Recoil on attack block +Movement speed penalty on swinging sword # TODO diff --git a/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java b/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java index eddb0b99..3de5dd4d 100644 --- a/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java +++ b/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java @@ -19,6 +19,7 @@ import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.common.TreeDataState; import electrosphere.game.data.creature.type.attack.AttackMove; +import electrosphere.game.data.item.type.WeaponData; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.synchronization.annotation.SyncedField; import electrosphere.net.synchronization.annotation.SynchronizableEnum; @@ -490,6 +491,20 @@ public class ClientAttackTree implements BehaviorTree { public List getMoveset(String attackType){ return (List)parent.getData(attackType); } + + /** + * Gets the movement penalty applied due to this tree + * @return The movement penalty + */ + public double getMovementPenalty(){ + if(currentWeapon != null && ItemUtils.getWeaponDataRaw(currentWeapon) != null){ + WeaponData weaponData = ItemUtils.getWeaponDataRaw(currentWeapon); + if(this.state != AttackTreeState.IDLE && weaponData.getWeaponActionMovePenalty() != null){ + return weaponData.getWeaponActionMovePenalty(); + } + } + return 1.0; + } /** *

Automatically generated

diff --git a/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java b/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java index f0927f21..34c14957 100644 --- a/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java +++ b/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java @@ -28,6 +28,7 @@ import electrosphere.entity.types.projectile.ProjectileUtils; import electrosphere.game.data.common.TreeDataState; import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.equip.EquipPoint; +import electrosphere.game.data.item.type.WeaponData; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.synchronization.annotation.SyncedField; @@ -441,6 +442,20 @@ public class ServerAttackTree implements BehaviorTree { } } + /** + * Gets the movement penalty applied due to this tree + * @return The movement penalty + */ + public double getMovementPenalty(){ + if(currentWeapon != null && ItemUtils.getWeaponDataRaw(currentWeapon) != null){ + WeaponData weaponData = ItemUtils.getWeaponDataRaw(currentWeapon); + if(this.state != AttackTreeState.IDLE && weaponData.getWeaponActionMovePenalty() != null){ + return weaponData.getWeaponActionMovePenalty(); + } + } + return 1.0; + } + /** * Adds a network message to the tree * @param networkMessage The network message diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java index e0f43860..004e011b 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java @@ -16,6 +16,7 @@ import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.AnimationPriorities; +import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.movement.fall.ClientFallTree; import electrosphere.entity.state.movement.jump.ClientJumpTree; @@ -500,13 +501,17 @@ public class ClientGroundMovementTree implements BehaviorTree { float velocity = CreatureUtils.getVelocity(parent); float sprintModifier = 1.0f; float walkModifier = 1.0f; + float attackModifier = 1.0f; if(ClientWalkTree.getClientWalkTree(parent) != null && ClientWalkTree.getClientWalkTree(parent).isWalking()){ walkModifier = ClientWalkTree.getClientWalkTree(parent).getModifier(); } if(ClientSprintTree.getClientSprintTree(parent) != null && ClientSprintTree.getClientSprintTree(parent).isSprinting()){ sprintModifier = ClientSprintTree.getClientSprintTree(parent).getSprintSystem().getModifier(); } - return velocity * sprintModifier * walkModifier; + if(ClientAttackTree.getClientAttackTree(parent) != null){ + attackModifier = (float)ClientAttackTree.getClientAttackTree(parent).getMovementPenalty(); + } + return velocity * sprintModifier * walkModifier * attackModifier; } /** diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java index 56cce320..73542b42 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java @@ -15,6 +15,7 @@ import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.AnimationPriorities; +import electrosphere.entity.state.attack.ServerAttackTree; import electrosphere.entity.state.movement.fall.ServerFallTree; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState; @@ -451,13 +452,17 @@ public class ServerGroundMovementTree implements BehaviorTree { float velocity = CreatureUtils.getVelocity(parent); float sprintModifier = 1.0f; float walkModifier = 1.0f; + float attackModifier = 1.0f; if(ServerWalkTree.getServerWalkTree(parent) != null && ServerWalkTree.getServerWalkTree(parent).isWalking()){ walkModifier = ServerWalkTree.getServerWalkTree(parent).getModifier(); } if(ServerSprintTree.getServerSprintTree(parent) != null && ServerSprintTree.getServerSprintTree(parent).isSprinting()){ sprintModifier = ServerSprintTree.getServerSprintTree(parent).getSprintSystem().getModifier(); } - return velocity * sprintModifier * walkModifier; + if(ServerAttackTree.getServerAttackTree(parent) != null){ + attackModifier = (float)ServerAttackTree.getServerAttackTree(parent).getMovementPenalty(); + } + return velocity * sprintModifier * walkModifier * attackModifier; } public void addNetworkMessage(EntityMessage networkMessage) { diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index f5aa9583..01043429 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -489,6 +489,11 @@ public class ItemUtils { return (Entity) inInventory.getData(EntityDataStrings.ITEM_IN_WORLD_REPRESENTATION); } + /** + * Gets the raw weapon data + * @param item The item entity + * @return The weapon data if it exists, null otherwise + */ public static WeaponData getWeaponDataRaw(Entity item){ return (WeaponData) item.getData(EntityDataStrings.ITEM_WEAPON_DATA_RAW); } diff --git a/src/main/java/electrosphere/game/data/item/type/WeaponData.java b/src/main/java/electrosphere/game/data/item/type/WeaponData.java index 15dd14ef..ea1da19f 100644 --- a/src/main/java/electrosphere/game/data/item/type/WeaponData.java +++ b/src/main/java/electrosphere/game/data/item/type/WeaponData.java @@ -22,10 +22,10 @@ public class WeaponData { String projectileModel; //The movespeed penalty applied when this weapon is used to perform an action - double weaponActionMovePenalty; + Double weaponActionMovePenalty; //The base move penalty applied when having the weapon equipped in the first place - double weaponBaseMovePenalty; + Double weaponBaseMovePenalty; /** * Gets the weapon class @@ -63,7 +63,7 @@ public class WeaponData { * Gets the movement penalty (a percentage) applied when an action is performed with this weapon * @return The movement penalty percentage (ie 0.7 means you should be 70% as fast) */ - public double getWeaponActionMovePenalty(){ + public Double getWeaponActionMovePenalty(){ return weaponActionMovePenalty; } @@ -71,7 +71,7 @@ public class WeaponData { * Gets the movement penalty (a percentage) applied when this weapon is equipped * @return The movementy penalty percentage (ie a 0.7 means you should be 70% as fast) */ - public double getWeaponBaseMovePenalty(){ + public Double getWeaponBaseMovePenalty(){ return weaponBaseMovePenalty; } diff --git a/src/test/java/electrosphere/entity/state/attack/ServerAttackTreeTests.java b/src/test/java/electrosphere/entity/state/attack/ServerAttackTreeTests.java index 04e2ea5d..6bf245d2 100644 --- a/src/test/java/electrosphere/entity/state/attack/ServerAttackTreeTests.java +++ b/src/test/java/electrosphere/entity/state/attack/ServerAttackTreeTests.java @@ -12,6 +12,8 @@ import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState; import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.movement.fall.ServerFallTree; +import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree; +import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.types.creature.CreatureTemplate; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; @@ -59,4 +61,33 @@ public class ServerAttackTreeTests extends EntityTestTemplate { assertNotEquals(serverAttackTree.getState(), AttackTreeState.IDLE); } + /** + * Make sure can attack in default scene + */ + @IntegrationTest + public void testCanAttack_WhileMoving_True(){ + //warm up engine + TestEngineUtils.simulateFrames(1); + + //spawn on server + Entity creature = CreatureUtils.serverSpawnBasicCreature(Globals.realmManager.first(), new Vector3d(0,0,0), "human", CreatureTemplate.createDefault("human")); + Entity katana = ItemUtils.serverSpawnBasicItem(Globals.realmManager.first(), new Vector3d(0,0,0), "Katana2H"); + + //equip + Entity inInventoryItem = InventoryUtils.serverAttemptStoreItem(creature, katana); + ServerEquipState serverEquipState = ServerEquipState.getServerEquipState(creature); + serverEquipState.commandAttemptEquip(inInventoryItem, serverEquipState.getEquipPoint("handsCombined")); + + //Get the server-side player's trees + ServerAttackTree serverAttackTree = ServerAttackTree.getServerAttackTree(creature); + ServerGroundMovementTree serverGroundMovementTree = ServerGroundMovementTree.getServerGroundMovementTree(creature); + serverGroundMovementTree.start(MovementRelativeFacing.FORWARD); + + //Make sure move tree is actually active + TestEngineUtils.simulateFrames(1); + + //verify can attack + assertEquals(true, serverAttackTree.canAttack(serverAttackTree.getAttackType())); + } + }