attack animation sounds
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-08-06 13:27:44 -04:00
parent cdfa594c06
commit 920f3912de
10 changed files with 319 additions and 162 deletions

Binary file not shown.

View File

@ -375,20 +375,26 @@
"driftFrameStart" : 7, "driftFrameStart" : 7,
"driftFrameEnd" : 15, "driftFrameEnd" : 15,
"initialMove" : true, "initialMove" : true,
"animationWindup" : { "windupState" : {
"nameFirstPerson" : "Sword1HSlash1", "animation" : {
"nameThirdPerson" : "Sword1HSlash1", "nameFirstPerson" : "Sword1HSlash1",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "Sword1HSlash1",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
}, },
"animationHold" : { "holdState" : {
"nameFirstPerson" : "Sword1HSlash1", "animation" : {
"nameThirdPerson" : "Sword1HSlash1", "nameFirstPerson" : "Sword1HSlash1",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "Sword1HSlash1",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
}, },
"animationAttack" : { "attackState" : {
"nameFirstPerson" : "Sword1HSlash1", "animation" : {
"nameThirdPerson" : "Sword1HSlash1", "nameFirstPerson" : "Sword1HSlash1",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "Sword1HSlash1",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
} }
}, },
{ {
@ -405,20 +411,26 @@
"driftFrameStart" : 1, "driftFrameStart" : 1,
"driftFrameEnd" : 10, "driftFrameEnd" : 10,
"initialMove" : false, "initialMove" : false,
"animationWindup" : { "windupState" : {
"nameFirstPerson" : "Jump", "animation" : {
"nameThirdPerson" : "Jump", "nameFirstPerson" : "Jump",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "Jump",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
}, },
"animationHold" : { "holdState" : {
"nameFirstPerson" : "Jump", "animation" : {
"nameThirdPerson" : "Jump", "nameFirstPerson" : "Jump",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "Jump",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
}, },
"animationAttack" : { "attackState" : {
"nameFirstPerson" : "Sword1HSlash2", "animation" : {
"nameThirdPerson" : "Sword1HSlash2", "nameFirstPerson" : "Sword1HSlash2",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "Sword1HSlash2",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
} }
}, },
{ {
@ -434,10 +446,15 @@
"driftFrameStart" : 1, "driftFrameStart" : 1,
"driftFrameEnd" : 10, "driftFrameEnd" : 10,
"initialMove" : true, "initialMove" : true,
"animationAttack" : { "attackState" : {
"nameFirstPerson" : "SwordR2HSlash", "animation" : {
"nameThirdPerson" : "SwordR2HSlash", "nameFirstPerson" : "SwordR2HSlash",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "SwordR2HSlash",
"priorityCategory" : "MOVEMENT_MODIFIER"
},
"audioData" : {
"audioPath" : "Audio/weapons/swoosh-03.ogg"
}
} }
}, },
{ {
@ -453,20 +470,26 @@
"movementEnd" : 0, "movementEnd" : 0,
"movementGoal" : 0, "movementGoal" : 0,
"initialMove" : true, "initialMove" : true,
"animationWindup" : { "windupState" : {
"nameFirstPerson" : "Jump", "animation" : {
"nameThirdPerson" : "HoldBowString", "nameFirstPerson" : "Jump",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "HoldBowString",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
}, },
"animationHold" : { "holdState" : {
"nameFirstPerson" : "Jump", "animation" : {
"nameThirdPerson" : "HoldBow", "nameFirstPerson" : "Jump",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "HoldBow",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
}, },
"animationAttack" : { "attackState" : {
"nameFirstPerson" : "Jump", "animation" : {
"nameThirdPerson" : "HoldBowString", "nameFirstPerson" : "Sword1HSlash2",
"priorityCategory" : "MOVEMENT_MODIFIER" "nameThirdPerson" : "HoldBowString",
"priorityCategory" : "MOVEMENT_MODIFIER"
}
} }
} }
], ],

View File

@ -16,3 +16,12 @@ Things that feel bad:
No audio No audio
Short movement bursts feel jittery Short movement bursts feel jittery
Part of this may be cylinder collidable instead of capsule Part of this may be cylinder collidable instead of capsule
Sound effect on hit
Sound effect on walk
Sound effect on jump
Sound effect on land
Sound effect on block
Allow block hotboxes to block damage
Server packet on damage collision

View File

@ -508,6 +508,7 @@ Audio on block state transitions
(08/04/2024) (08/04/2024)
Strafe/backpedal movement speed multipliers Strafe/backpedal movement speed multipliers
Properly equipping/unequipping 2hand items
# TODO # TODO

View File

@ -135,7 +135,7 @@ public class Globals {
public static boolean RUN_DEMO = false; public static boolean RUN_DEMO = false;
public static boolean RUN_CLIENT = true; public static boolean RUN_CLIENT = true;
public static boolean RUN_HIDDEN = false; //glfw session will be created with hidden window public static boolean RUN_HIDDEN = false; //glfw session will be created with hidden window
public static boolean RUN_AUDIO = false; public static boolean RUN_AUDIO = true;
public static int clientCharacterID; public static int clientCharacterID;
// //
@ -469,6 +469,7 @@ public class Globals {
"/Audio/closeMenu.ogg", "/Audio/closeMenu.ogg",
"/Audio/ambienceWind1SeamlessMono.ogg", "/Audio/ambienceWind1SeamlessMono.ogg",
"/Audio/weapons/swordUnsheath1.ogg", "/Audio/weapons/swordUnsheath1.ogg",
"/Audio/weapons/swoosh-03.ogg",
}; };
LoggerInterface.loggerStartup.INFO("Loading default audio resources"); LoggerInterface.loggerStartup.INFO("Loading default audio resources");
for(String path : audioToInit){ for(String path : audioToInit){

View File

@ -6,7 +6,6 @@ import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.game.data.common.TreeDataAnimation; import electrosphere.game.data.common.TreeDataAnimation;
import electrosphere.game.data.common.TreeDataAudio; import electrosphere.game.data.common.TreeDataAudio;
@ -181,7 +180,7 @@ public class StateTransitionUtil {
if(state.onComplete != null){ if(state.onComplete != null){
state.onComplete.run(); state.onComplete.run();
} }
} else if(!poseActor.isPlayingAnimation() && state.onComplete != null && state.startedAnimation == true){ } else if(!poseActor.isPlayingAnimation(animation) && state.onComplete != null && state.startedAnimation == true){
//state transition if this isn't set to loop //state transition if this isn't set to loop
state.onComplete.run(); state.onComplete.run();
state.startedAnimation = false; state.startedAnimation = false;

View File

@ -8,7 +8,8 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; 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.client.firstPerson.FirstPersonTree; import electrosphere.entity.btree.StateTransitionUtil;
import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem;
import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState;
@ -17,12 +18,12 @@ import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils; 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.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.attack.AttackMove;
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;
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
import electrosphere.renderer.actor.Actor;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -94,10 +95,95 @@ public class ClientAttackTree implements BehaviorTree {
String projectileToFire = null; String projectileToFire = null;
String attackingPoint = null; String attackingPoint = null;
//The state transition util
StateTransitionUtil stateTransitionUtil;
private ClientAttackTree(Entity e, Object ... params){ private ClientAttackTree(Entity e, Object ... params){
setState(AttackTreeState.IDLE); setState(AttackTreeState.IDLE);
setDriftState(AttackTreeDriftState.NO_DRIFT); setDriftState(AttackTreeDriftState.NO_DRIFT);
parent = e; parent = e;
this.stateTransitionUtil = StateTransitionUtil.create(parent, false, new StateTransitionUtilItem[]{
StateTransitionUtilItem.create(
AttackTreeState.WINDUP,
() -> {
TreeDataState state = currentMove.getWindupState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
() -> {
TreeDataState state = currentMove.getWindupState();
if(state == null){
return null;
} else {
return state.getAudioData();
}
},
null
),
StateTransitionUtilItem.create(
AttackTreeState.HOLD,
() -> {
TreeDataState state = currentMove.getHoldState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
() -> {
TreeDataState state = currentMove.getHoldState();
if(state == null){
return null;
} else {
return state.getAudioData();
}
},
null
),
StateTransitionUtilItem.create(
AttackTreeState.ATTACK,
() -> {
TreeDataState state = currentMove.getAttackState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
() -> {
TreeDataState state = currentMove.getAttackState();
if(state == null){
return null;
} else {
return state.getAudioData();
}
},
null
),
StateTransitionUtilItem.create(
AttackTreeState.COOLDOWN,
() -> {
TreeDataState state = currentMove.getCooldownState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
() -> {
TreeDataState state = currentMove.getCooldownState();
if(state == null){
return null;
} else {
return state.getAudioData();
}
},
null
),
});
} }
/** /**
@ -148,7 +234,6 @@ public class ClientAttackTree implements BehaviorTree {
@Override @Override
public void simulate(float deltaTime){ public void simulate(float deltaTime){
frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames(); frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames();
Actor entityActor = EntityUtils.getActor(parent);
Vector3d movementVector = CreatureUtils.getFacingVector(parent); Vector3d movementVector = CreatureUtils.getFacingVector(parent);
// //
@ -237,49 +322,13 @@ public class ClientAttackTree implements BehaviorTree {
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){ if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
RotatorTree.getClientRotatorTree(parent).setActive(true); RotatorTree.getClientRotatorTree(parent).setActive(true);
} }
if(currentMove != null && entityActor != null && currentMove.getAnimationWindup() != null){ this.stateTransitionUtil.simulate(AttackTreeState.WINDUP);
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getAnimationWindup())){
entityActor.playAnimation(
currentMove.getAnimationWindup(),
true
);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(
parent,
currentMove.getAnimationWindup()
);
}
} break; } break;
case HOLD: { case HOLD: {
if(entityActor != null && currentMove.getAnimationHold() != null){ this.stateTransitionUtil.simulate(AttackTreeState.HOLD);
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getAnimationHold())){
entityActor.playAnimation(
currentMove.getAnimationHold(),
true
);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(
parent,
currentMove.getAnimationHold()
);
}
} break; } break;
case ATTACK: { case ATTACK: {
if(entityActor != null && currentMove != null){ this.stateTransitionUtil.simulate(AttackTreeState.ATTACK);
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getAnimationAttack())){
entityActor.playAnimation(
currentMove.getAnimationAttack(),
true
);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(
parent,
currentMove.getAnimationAttack()
);
}
//activate hitboxes //activate hitboxes
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent); List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
if(attachedEntities != null){ if(attachedEntities != null){
@ -292,6 +341,7 @@ public class ClientAttackTree implements BehaviorTree {
} }
} break; } break;
case COOLDOWN: { case COOLDOWN: {
this.stateTransitionUtil.simulate(AttackTreeState.COOLDOWN);
//deactive hitboxes //deactive hitboxes
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent); List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
if(attachedEntities != null){ if(attachedEntities != null){

View File

@ -12,7 +12,8 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; 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.btree.StateTransitionUtil;
import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem;
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState; import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState;
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState; import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.collidable.Impulse;
@ -25,14 +26,15 @@ import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.projectile.ProjectileUtils; 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.attack.AttackMove;
import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.creature.type.equip.EquipPoint;
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;
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.Realm;
import electrosphere.server.poseactor.PoseActor;
import electrosphere.util.math.MathUtils; import electrosphere.util.math.MathUtils;
import java.util.List; import java.util.List;
@ -80,10 +82,91 @@ public class ServerAttackTree implements BehaviorTree {
String projectileToFire = null; String projectileToFire = null;
String attackingPoint = null; String attackingPoint = null;
//The state transition util
StateTransitionUtil stateTransitionUtil;
private ServerAttackTree(Entity e, Object ... params){ private ServerAttackTree(Entity e, Object ... params){
state = AttackTreeState.IDLE; state = AttackTreeState.IDLE;
driftState = AttackTreeDriftState.NO_DRIFT; driftState = AttackTreeDriftState.NO_DRIFT;
parent = e; parent = e;
this.stateTransitionUtil = StateTransitionUtil.create(parent, true, new StateTransitionUtilItem[]{
StateTransitionUtilItem.create(
AttackTreeState.WINDUP,
() -> {
TreeDataState state = currentMove.getWindupState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
() -> {
TreeDataState state = currentMove.getWindupState();
if(state == null){
return null;
} else {
return state.getAudioData();
}
},
() -> {
if(currentMoveCanHold && stillHold){
setState(AttackTreeState.HOLD);
} else {
setState(AttackTreeState.ATTACK);
}
this.stateTransitionUtil.interrupt(AttackTreeState.WINDUP);
}
),
StateTransitionUtilItem.create(
AttackTreeState.HOLD,
() -> {
TreeDataState state = currentMove.getHoldState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
() -> {
TreeDataState state = currentMove.getHoldState();
if(state == null){
return null;
} else {
return state.getAudioData();
}
},
null
),
StateTransitionUtilItem.create(
AttackTreeState.ATTACK,
() -> {
TreeDataState state = currentMove.getAttackState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
null,
() -> {
this.setState(AttackTreeState.COOLDOWN);
this.stateTransitionUtil.interrupt(AttackTreeState.ATTACK);
}
),
StateTransitionUtilItem.create(
AttackTreeState.COOLDOWN,
() -> {
TreeDataState state = currentMove.getCooldownState();
if(state == null){
return null;
} else {
return state.getAnimation();
}
},
null,
null
),
});
} }
/** /**
@ -122,14 +205,19 @@ public class ServerAttackTree implements BehaviorTree {
projectileToFire = ItemUtils.getWeaponDataRaw(currentWeapon).getProjectileModel(); projectileToFire = ItemUtils.getWeaponDataRaw(currentWeapon).getProjectileModel();
} }
animationName = currentMove.getAnimationAttack().getNameThirdPerson(); //set initial stuff (this alerts the client as well)
//intuit windup from presence of windup anim setCurrentMoveId(currentMove.getAttackMoveId());
currentMoveHasWindup = currentMove.getAnimationWindup() != null;
if(currentMoveHasWindup){ //start tree
animationName = currentMove.getAnimationWindup().getNameThirdPerson(); if(currentMove.getWindupState() != null){
setState(AttackTreeState.WINDUP);
} else if(currentMove.getAttackState() != null){
setState(AttackTreeState.ATTACK);
} else {
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Trying to start attacking tree, but current move does not have windup or attack states defined!"));
} }
//intuit can hold from presence of windup anim //intuit can hold from presence of windup anim
currentMoveCanHold = currentMove.getAnimationHold() != null; currentMoveCanHold = currentMove.getHoldState() != null;
//stop movement tree //stop movement tree
if(parent.containsKey(EntityDataStrings.SERVER_MOVEMENT_BT)){ if(parent.containsKey(EntityDataStrings.SERVER_MOVEMENT_BT)){
BehaviorTree movementTree = CreatureUtils.serverGetEntityMovementTree(parent); BehaviorTree movementTree = CreatureUtils.serverGetEntityMovementTree(parent);
@ -139,9 +227,6 @@ public class ServerAttackTree implements BehaviorTree {
} }
Vector3d movementVector = CreatureUtils.getFacingVector(parent); Vector3d movementVector = CreatureUtils.getFacingVector(parent);
EntityUtils.getRotation(parent).rotationTo(MathUtils.getOriginVector(), new Vector3d(movementVector.x,movementVector.y,movementVector.z)); EntityUtils.getRotation(parent).rotationTo(MathUtils.getOriginVector(), new Vector3d(movementVector.x,movementVector.y,movementVector.z));
//set initial stuff (this alerts the client as well)
setCurrentMoveId(currentMove.getAttackMoveId());
setState(AttackTreeState.WINDUP);
frameCurrent = 0; frameCurrent = 0;
} else { } else {
setState(AttackTreeState.IDLE); setState(AttackTreeState.IDLE);
@ -166,7 +251,6 @@ public class ServerAttackTree implements BehaviorTree {
public void simulate(float deltaTime){ public void simulate(float deltaTime){
frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames(); frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames();
float velocity = CreatureUtils.getVelocity(parent); float velocity = CreatureUtils.getVelocity(parent);
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
Vector3d position = EntityUtils.getPosition(parent); Vector3d position = EntityUtils.getPosition(parent);
Vector3d movementVector = CreatureUtils.getFacingVector(parent); Vector3d movementVector = CreatureUtils.getFacingVector(parent);
@ -216,58 +300,31 @@ public class ServerAttackTree implements BehaviorTree {
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){ if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
ServerRotatorTree.getServerRotatorTree(parent).setActive(true); ServerRotatorTree.getServerRotatorTree(parent).setActive(true);
} }
if(entityPoseActor != null){ this.stateTransitionUtil.simulate(AttackTreeState.WINDUP);
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
entityPoseActor.playAnimation(
animationName,
AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER)
);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
if(frameCurrent > currentMove.getWindupFrames()){
if(currentMoveCanHold && stillHold){
setState(AttackTreeState.HOLD);
} else {
setState(AttackTreeState.ATTACK);
}
}
Globals.server.broadcastMessage( Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage( EntityMessage.constructattackUpdateMessage(
parent.getId(), parent.getId(),
System.currentTimeMillis(), System.currentTimeMillis(),
(float)position.x, (float)position.x,
(float)position.y, (float)position.y,
(float)position.z, (float)position.z,
movementVector.x, movementVector.x,
movementVector.y, movementVector.y,
movementVector.z, movementVector.z,
velocity, velocity,
0 0
) )
); );
} break; } break;
case HOLD: { case HOLD: {
if(entityPoseActor != null){ this.stateTransitionUtil.simulate(AttackTreeState.HOLD);
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
entityPoseActor.playAnimation(
animationName,
AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER)
);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
if(!stillHold){ if(!stillHold){
setState(AttackTreeState.ATTACK); setState(AttackTreeState.ATTACK);
this.stateTransitionUtil.interrupt(AttackTreeState.HOLD);
} }
} break; } break;
case ATTACK: { case ATTACK: {
if(entityPoseActor != null && currentMove != null){ this.stateTransitionUtil.simulate(AttackTreeState.ATTACK);
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(currentMove.getAnimationAttack())){
entityPoseActor.playAnimation(currentMove.getAnimationAttack());
entityPoseActor.incrementAnimationTime(0.0001);
}
}
//activate hitboxes //activate hitboxes
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent); List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
for(Entity currentAttached : attachedEntities){ for(Entity currentAttached : attachedEntities){
@ -310,9 +367,6 @@ public class ServerAttackTree implements BehaviorTree {
ProjectileUtils.serverSpawnBasicProjectile(parentRealm, projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f); ProjectileUtils.serverSpawnBasicProjectile(parentRealm, projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f);
projectileToFire = null; projectileToFire = null;
} }
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames()){
setState(AttackTreeState.COOLDOWN);
}
Globals.server.broadcastMessage( Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage( EntityMessage.constructattackUpdateMessage(
parent.getId(), parent.getId(),
@ -329,6 +383,7 @@ public class ServerAttackTree implements BehaviorTree {
); );
} break; } break;
case COOLDOWN: { case COOLDOWN: {
this.stateTransitionUtil.simulate(AttackTreeState.COOLDOWN);
//deactive hitboxes //deactive hitboxes
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent); List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
for(Entity currentAttached : attachedEntities){ for(Entity currentAttached : attachedEntities){
@ -339,6 +394,7 @@ public class ServerAttackTree implements BehaviorTree {
} }
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){ if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
setState(AttackTreeState.IDLE); setState(AttackTreeState.IDLE);
this.stateTransitionUtil.interrupt(AttackTreeState.COOLDOWN);
frameCurrent = 0; frameCurrent = 0;
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){ if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
ServerRotatorTree.getServerRotatorTree(parent).setActive(false); ServerRotatorTree.getServerRotatorTree(parent).setActive(false);

View File

@ -84,9 +84,18 @@ public class CreatureDataValidator {
List<TreeDataAnimation> animations = new LinkedList<TreeDataAnimation>(); List<TreeDataAnimation> animations = new LinkedList<TreeDataAnimation>();
if(data.getAttackMoves() != null){ if(data.getAttackMoves() != null){
for(AttackMove move : data.getAttackMoves()){ for(AttackMove move : data.getAttackMoves()){
animations.add(move.getAnimationAttack()); if(move.getWindupState() != null){
animations.add(move.getAnimationHold()); animations.add(move.getWindupState().getAnimation());
animations.add(move.getAnimationWindup()); }
if(move.getHoldState() != null){
animations.add(move.getHoldState().getAnimation());
}
if(move.getAttackState() != null){
animations.add(move.getAttackState().getAnimation());
}
if(move.getCooldownState() != null){
animations.add(move.getCooldownState().getAnimation());
}
} }
} }
if(data.getEquipPoints() != null){ if(data.getEquipPoints() != null){

View File

@ -1,6 +1,6 @@
package electrosphere.game.data.creature.type.attack; package electrosphere.game.data.creature.type.attack;
import electrosphere.game.data.common.TreeDataAnimation; import electrosphere.game.data.common.TreeDataState;
/** /**
* Data about a single attack move this creature is capable of * Data about a single attack move this creature is capable of
@ -16,9 +16,10 @@ public class AttackMove {
/* /*
Animation stuff Animation stuff
*/ */
TreeDataAnimation animationWindup; TreeDataState windupState;
TreeDataAnimation animationHold; TreeDataState holdState;
TreeDataAnimation animationAttack; TreeDataState attackState;
TreeDataState cooldownState;
/* /*
Damage stuff Damage stuff
@ -61,27 +62,35 @@ public class AttackMove {
} }
/** /**
* Gets the animation to play for the windup * Gets the state to play for the windup
* @return the animation * @return the state data
*/ */
public TreeDataAnimation getAnimationWindup() { public TreeDataState getWindupState() {
return animationWindup; return windupState;
} }
/** /**
* Gets the name of the animation to play for the hold * Gets the state to play for the hold
* @return the animation * @return the state data
*/ */
public TreeDataAnimation getAnimationHold() { public TreeDataState getHoldState() {
return animationHold; return holdState;
} }
/** /**
* Gets the animation to play for the attack * Gets the state to play for the attack
* @return the animation * @return the state data
*/ */
public TreeDataAnimation getAnimationAttack() { public TreeDataState getAttackState() {
return animationAttack; return attackState;
}
/**
* Gets the state to play for the cooldown
* @return the state data
*/
public TreeDataState getCooldownState() {
return cooldownState;
} }
/** /**