movement penalty on swinging weapon
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-09-09 18:14:19 -04:00
parent 79688e8575
commit 9301996bac
10 changed files with 84 additions and 8 deletions

View File

@ -58,6 +58,7 @@
"weaponData" : { "weaponData" : {
"weaponClass" : "sword2h", "weaponClass" : "sword2h",
"damage" : 10, "damage" : 10,
"weaponActionMovePenalty" : 0.4,
"hitboxes" : [ "hitboxes" : [
{ {
"type": "hit_connected", "type": "hit_connected",

View File

@ -14,8 +14,6 @@
+ fix the vibes + fix the vibes
Stability Stability
Recoil State on attack
Movement penalty while swinging weapon
Ticketed randomizer node for BTs to more heavily weight attacking and waiting Ticketed randomizer node for BTs to more heavily weight attacking and waiting
+ bug fixes + bug fixes

View File

@ -706,6 +706,7 @@ Framebuffer + RenderingEngine tests
(09/09/2024) (09/09/2024)
Fix obnoxious opengl state caching bug w/ framebuffers in junit context Fix obnoxious opengl state caching bug w/ framebuffers in junit context
Recoil on attack block Recoil on attack block
Movement speed penalty on swinging sword
# TODO # TODO

View File

@ -19,6 +19,7 @@ import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.common.TreeDataState; import electrosphere.game.data.common.TreeDataState;
import electrosphere.game.data.creature.type.attack.AttackMove; 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.parser.net.message.EntityMessage;
import electrosphere.net.synchronization.annotation.SyncedField; import electrosphere.net.synchronization.annotation.SyncedField;
import electrosphere.net.synchronization.annotation.SynchronizableEnum; import electrosphere.net.synchronization.annotation.SynchronizableEnum;
@ -490,6 +491,20 @@ public class ClientAttackTree implements BehaviorTree {
public List<AttackMove> getMoveset(String attackType){ public List<AttackMove> getMoveset(String attackType){
return (List<AttackMove>)parent.getData(attackType); return (List<AttackMove>)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;
}
/** /**
* <p> Automatically generated </p> * <p> Automatically generated </p>

View File

@ -28,6 +28,7 @@ import electrosphere.entity.types.projectile.ProjectileUtils;
import electrosphere.game.data.common.TreeDataState; import electrosphere.game.data.common.TreeDataState;
import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.attack.AttackMove;
import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.game.data.item.type.WeaponData;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.synchronization.annotation.SyncedField; 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 * Adds a network message to the tree
* @param networkMessage The network message * @param networkMessage The network message

View File

@ -16,6 +16,7 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.AnimationPriorities; import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.movement.fall.ClientFallTree; import electrosphere.entity.state.movement.fall.ClientFallTree;
import electrosphere.entity.state.movement.jump.ClientJumpTree; import electrosphere.entity.state.movement.jump.ClientJumpTree;
@ -500,13 +501,17 @@ public class ClientGroundMovementTree implements BehaviorTree {
float velocity = CreatureUtils.getVelocity(parent); float velocity = CreatureUtils.getVelocity(parent);
float sprintModifier = 1.0f; float sprintModifier = 1.0f;
float walkModifier = 1.0f; float walkModifier = 1.0f;
float attackModifier = 1.0f;
if(ClientWalkTree.getClientWalkTree(parent) != null && ClientWalkTree.getClientWalkTree(parent).isWalking()){ if(ClientWalkTree.getClientWalkTree(parent) != null && ClientWalkTree.getClientWalkTree(parent).isWalking()){
walkModifier = ClientWalkTree.getClientWalkTree(parent).getModifier(); walkModifier = ClientWalkTree.getClientWalkTree(parent).getModifier();
} }
if(ClientSprintTree.getClientSprintTree(parent) != null && ClientSprintTree.getClientSprintTree(parent).isSprinting()){ if(ClientSprintTree.getClientSprintTree(parent) != null && ClientSprintTree.getClientSprintTree(parent).isSprinting()){
sprintModifier = ClientSprintTree.getClientSprintTree(parent).getSprintSystem().getModifier(); 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;
} }
/** /**

View File

@ -15,6 +15,7 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.AnimationPriorities; import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.movement.fall.ServerFallTree; import electrosphere.entity.state.movement.fall.ServerFallTree;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
@ -451,13 +452,17 @@ public class ServerGroundMovementTree implements BehaviorTree {
float velocity = CreatureUtils.getVelocity(parent); float velocity = CreatureUtils.getVelocity(parent);
float sprintModifier = 1.0f; float sprintModifier = 1.0f;
float walkModifier = 1.0f; float walkModifier = 1.0f;
float attackModifier = 1.0f;
if(ServerWalkTree.getServerWalkTree(parent) != null && ServerWalkTree.getServerWalkTree(parent).isWalking()){ if(ServerWalkTree.getServerWalkTree(parent) != null && ServerWalkTree.getServerWalkTree(parent).isWalking()){
walkModifier = ServerWalkTree.getServerWalkTree(parent).getModifier(); walkModifier = ServerWalkTree.getServerWalkTree(parent).getModifier();
} }
if(ServerSprintTree.getServerSprintTree(parent) != null && ServerSprintTree.getServerSprintTree(parent).isSprinting()){ if(ServerSprintTree.getServerSprintTree(parent) != null && ServerSprintTree.getServerSprintTree(parent).isSprinting()){
sprintModifier = ServerSprintTree.getServerSprintTree(parent).getSprintSystem().getModifier(); 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) { public void addNetworkMessage(EntityMessage networkMessage) {

View File

@ -489,6 +489,11 @@ public class ItemUtils {
return (Entity) inInventory.getData(EntityDataStrings.ITEM_IN_WORLD_REPRESENTATION); 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){ public static WeaponData getWeaponDataRaw(Entity item){
return (WeaponData) item.getData(EntityDataStrings.ITEM_WEAPON_DATA_RAW); return (WeaponData) item.getData(EntityDataStrings.ITEM_WEAPON_DATA_RAW);
} }

View File

@ -22,10 +22,10 @@ public class WeaponData {
String projectileModel; String projectileModel;
//The movespeed penalty applied when this weapon is used to perform an action //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 //The base move penalty applied when having the weapon equipped in the first place
double weaponBaseMovePenalty; Double weaponBaseMovePenalty;
/** /**
* Gets the weapon class * 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 * 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) * @return The movement penalty percentage (ie 0.7 means you should be 70% as fast)
*/ */
public double getWeaponActionMovePenalty(){ public Double getWeaponActionMovePenalty(){
return weaponActionMovePenalty; return weaponActionMovePenalty;
} }
@ -71,7 +71,7 @@ public class WeaponData {
* Gets the movement penalty (a percentage) applied when this weapon is equipped * 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) * @return The movementy penalty percentage (ie a 0.7 means you should be 70% as fast)
*/ */
public double getWeaponBaseMovePenalty(){ public Double getWeaponBaseMovePenalty(){
return weaponBaseMovePenalty; return weaponBaseMovePenalty;
} }

View File

@ -12,6 +12,8 @@ import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.movement.fall.ServerFallTree; 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.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
@ -59,4 +61,33 @@ public class ServerAttackTreeTests extends EntityTestTemplate {
assertNotEquals(serverAttackTree.getState(), AttackTreeState.IDLE); 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()));
}
} }