unify animation data on disk
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-07-28 14:51:20 -04:00
parent ceb4786228
commit ad823fcbb4
29 changed files with 689 additions and 152 deletions

View File

@ -130,41 +130,33 @@
"acceleration" : 5000.0, "acceleration" : 5000.0,
"maxVelocity" : 500.5, "maxVelocity" : 500.5,
"animationStartup" : { "animationStartup" : {
"name" : "Jog", "nameThirdPerson" : "Jog",
"length" : 1, "length" : 1,
"loops" : false "loops" : false
}, },
"animationFirstPersonStartup" : { "animationFirstPersonStartup" : {
"name" : "Jog" "nameFirstPerson" : "Jog"
}, },
"animationLoop" : { "animationLoop" : {
"name" : "Jog", "nameThirdPerson" : "Jog"
"length" : 1,
"loops" : false
}, },
"animationFirstPersonLoop" : { "animationFirstPersonLoop" : {
"name" : "Jog" "nameFirstPerson" : "Jog"
}, },
"animationWindDown" : { "animationWindDown" : {
"name" : "Jog", "nameThirdPerson" : "Jog"
"length" : 1,
"loops" : false
}, },
"animationFirstPersonWindDown" : { "animationFirstPersonWindDown" : {
"name" : "Jog" "nameFirstPerson" : "Jog"
}, },
"sprintSystem" : { "sprintSystem" : {
"maxVelocity" : 0.058, "maxVelocity" : 0.058,
"staminaMax" : 500, "staminaMax" : 500,
"animationStartUp" : { "animationStartUp" : {
"name" : "Sprint", "nameThirdPerson" : "Sprint"
"length" : 1,
"loops" : false
}, },
"animationMain" : { "animationMain" : {
"name" : "Sprint", "nameThirdPerson" : "Sprint"
"length" : 1,
"loops" : false
} }
} }
}, },
@ -173,33 +165,25 @@
"jumpFrames" : 3, "jumpFrames" : 3,
"jumpForce" : 500, "jumpForce" : 500,
"animationJump" : { "animationJump" : {
"name" : "Jump", "nameThirdPerson" : "Jump"
"length" : 1,
"loops" : false
}, },
"animationFirstPersonJump" : { "animationFirstPersonJump" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
} }
}, },
{ {
"type" : "FALL", "type" : "FALL",
"fallState" : { "fallState" : {
"firstPersonAnimation" : { "animation" : {
"name" : "Fall", "nameThirdPerson" : "Fall",
"priority": 4 "nameFirstPerson" : "Fall",
},
"thirdPersonAnimation" : {
"name" : "Fall",
"priority": 4 "priority": 4
} }
}, },
"landState" : { "landState" : {
"firstPersonAnimation" : { "animation" : {
"name" : "Land", "nameThirdPerson" : "Land",
"priority": 4 "nameFirstPerson" : "Land",
},
"thirdPersonAnimation" : {
"name" : "Land",
"priority": 4 "priority": 4
} }
} }
@ -270,7 +254,13 @@
"tool", "tool",
"weapon", "weapon",
"item" "item"
] ],
"equippedAnimation" : {
"nameThirdPerson" : "",
"nameFirstPerson" : "",
"priority" : 4,
"boneGroups" : ["handRight"]
}
}, },
{ {
"equipPointId" : "Torso", "equipPointId" : "Torso",
@ -344,13 +334,13 @@
"driftFrameEnd" : 15, "driftFrameEnd" : 15,
"initialMove" : true, "initialMove" : true,
"animationFirstPersonWindup" : { "animationFirstPersonWindup" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
}, },
"animationFirstPersonHold" : { "animationFirstPersonHold" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
}, },
"animationFirstPersonAttack" : { "animationFirstPersonAttack" : {
"name" : "Sword1HSlash1" "nameFirstPerson" : "Sword1HSlash1"
} }
}, },
{ {
@ -369,13 +359,13 @@
"driftFrameEnd" : 10, "driftFrameEnd" : 10,
"initialMove" : false, "initialMove" : false,
"animationFirstPersonWindup" : { "animationFirstPersonWindup" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
}, },
"animationFirstPersonHold" : { "animationFirstPersonHold" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
}, },
"animationFirstPersonAttack" : { "animationFirstPersonAttack" : {
"name" : "Sword1HSlash2" "nameFirstPerson" : "Sword1HSlash2"
} }
}, },
{ {
@ -393,13 +383,13 @@
"driftFrameEnd" : 10, "driftFrameEnd" : 10,
"initialMove" : true, "initialMove" : true,
"animationFirstPersonWindup" : { "animationFirstPersonWindup" : {
"name" : "HoldItemR2H" "nameFirstPerson" : "HoldItemR2H"
}, },
"animationFirstPersonHold" : { "animationFirstPersonHold" : {
"name" : "HoldItemR2H" "nameFirstPerson" : "HoldItemR2H"
}, },
"animationFirstPersonAttack" : { "animationFirstPersonAttack" : {
"name" : "SwordR2HSlash" "nameFirstPerson" : "SwordR2HSlash"
} }
}, },
{ {
@ -419,13 +409,13 @@
"movementGoal" : 0, "movementGoal" : 0,
"initialMove" : true, "initialMove" : true,
"animationFirstPersonWindup" : { "animationFirstPersonWindup" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
}, },
"animationFirstPersonHold" : { "animationFirstPersonHold" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
}, },
"animationFirstPersonAttack" : { "animationFirstPersonAttack" : {
"name" : "Jump" "nameFirstPerson" : "Jump"
} }
} }
], ],
@ -451,6 +441,84 @@
"attackRange" : 2, "attackRange" : 2,
"stateChangeTimeout" : "240" "stateChangeTimeout" : "240"
} }
],
"boneGroups" : [
{
"id" : "torso",
"boneNamesThirdPerson" : [
"Bone", "UpperTorso", "Shoulder.R", "Shoulder.L", "Breast.R", "Breast.L", "Butt.L", "Butt.R"
]
},
{
"id" : "head",
"boneNamesThirdPerson" : [
"Neck", "Head", "Ear.L", "Ear.R", "Eye.L", "Eye.R", "Jaw", "Nose", "MouthCorner.R", "MouthCorner.L", "JawTop", "Iris.L", "Iris.R"
]
},
{
"id" : "armRight",
"boneNamesThirdPerson" : [
"Bicep.R", "Forearm.R"
],
"boneNamesFirstPerson" : [
"clavicle.R", "deltoid.R", "upper_arm.R", "forearm.R"
]
},
{
"id" : "handRight",
"boneNamesThirdPerson" : [
"Hand.R", "MiddleUpper.R", "ThumbUpper.R"
],
"boneNamesFirstPerson" : [
"hand.R",
"palm_pinky.R",
"f_pinky.01.R",
"f_pinky.02.R",
"f_pinky.03.R",
"palm_middle.R",
"f_middle.01.R",
"f_middle.02.R",
"f_middle.03.R",
"palm_ring.R",
"f_ring.01.R",
"f_ring.02.R",
"f_ring.03.R",
"thumb.01.R",
"thumb.02.R",
"thumb.03.R",
"palm_index.R",
"f_index.01.R",
"f_index.02.R",
"f_index.03.R"
]
},
{
"id" : "armLeft",
"boneNamesThirdPerson" : [
"Bicep.L", "Forearm.L"
],
"boneNamesFirstPerson" : [
"clavicle.L", "deltoid.L", "upper_arm.L", "forearm.L"
]
},
{
"id" : "handLeft",
"boneNamesThirdPerson" : [
"Hand.L", "MiddleUpper.L", "ThumbUpper.L"
]
},
{
"id" : "legLeft",
"boneNamesThirdPerson" : [
"Leg.L", "LowerLeg.L", "Foot.L"
]
},
{
"id" : "legRight",
"boneNamesThirdPerson" : [
"Leg.R", "LowerLeg.R", "Foot.R"
]
}
] ]
} }
], ],

View File

@ -11,7 +11,7 @@ import org.joml.Vector3i;
import electrosphere.auth.AuthenticationManager; import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.types.creature.CreatureTemplate; import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.game.server.world.MacroData; import electrosphere.game.server.world.MacroData;
import electrosphere.net.NetUtils; import electrosphere.net.NetUtils;
@ -152,7 +152,7 @@ public class LoadingUtils {
// //
//send default template back //send default template back
String race = Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().get(0); String race = Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().get(0);
CreatureType type = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(race); CreatureData type = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(race);
CreatureTemplate template = new CreatureTemplate(race); CreatureTemplate template = new CreatureTemplate(race);
for(VisualAttribute attribute : type.getVisualAttributes()){ for(VisualAttribute attribute : type.getVisualAttributes()){
if(attribute.getType().equals(VisualAttribute.TYPE_BONE)){ if(attribute.getType().equals(VisualAttribute.TYPE_BONE)){

View File

@ -130,15 +130,21 @@ public class StateTransitionUtil {
} }
} }
actor.playAnimation(thirdPersonAnimation,state.getAnimationPriority()); if(state.animation == null){
actor.playAnimation(firstPersonAnimation, state.getAnimationPriority());
} else {
actor.playAnimation(state.animation,true);
}
actor.incrementAnimationTime(0.0001); actor.incrementAnimationTime(0.0001);
state.startedAnimation = true; state.startedAnimation = true;
} else if(thirdPersonAnimation == null && state.onComplete != null){ } else if(thirdPersonAnimation == null && state.onComplete != null){
state.onComplete.run(); state.onComplete.run();
state.startedAnimation = false; state.startedAnimation = false;
} }
if(firstPersonAnimation != null){ if(state.animation == null){
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, firstPersonAnimation, state.getAnimationPriority()); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, firstPersonAnimation, state.getAnimationPriority());
} else if(firstPersonAnimation != null){
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, state.animation);
} }
} }
} }
@ -162,7 +168,11 @@ public class StateTransitionUtil {
state.startedAnimation = false; state.startedAnimation = false;
} else if(thirdPersonAnimation != null && (!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(thirdPersonAnimation))){ } else if(thirdPersonAnimation != null && (!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(thirdPersonAnimation))){
//play animation for state //play animation for state
poseActor.playAnimation(thirdPersonAnimation,state.getAnimationPriority()); if(state.animation == null){
poseActor.playAnimation(thirdPersonAnimation, state.getAnimationPriority());
} else {
poseActor.playAnimation(state.animation,true);
}
poseActor.incrementAnimationTime(0.0001); poseActor.incrementAnimationTime(0.0001);
state.startedAnimation = true; state.startedAnimation = true;
} else if(thirdPersonAnimation == null && state.onComplete != null){ } else if(thirdPersonAnimation == null && state.onComplete != null){
@ -183,14 +193,11 @@ public class StateTransitionUtil {
//the priority of this animation in particular //the priority of this animation in particular
int animPriority; int animPriority;
//The animation to play in first person //The animation to play
TreeDataAnimation firstPersonAnimation; TreeDataAnimation animation;
//Gets the first person animation's name //Gets the first person animation's name
Supplier<String> getFirstPersonAnimation; Supplier<String> getFirstPersonAnimation;
//The animation to play in third person
TreeDataAnimation thirdPersonAnimation;
//Gets the third person animation's name //Gets the third person animation's name
Supplier<String> getThirdPersonAnimation; Supplier<String> getThirdPersonAnimation;
@ -210,8 +217,8 @@ public class StateTransitionUtil {
*/ */
String getThirdPersonAnimation(){ String getThirdPersonAnimation(){
String toPlay = null; String toPlay = null;
if(thirdPersonAnimation != null){ if(animation != null){
toPlay = thirdPersonAnimation.getName(); toPlay = animation.getNameThirdPerson();
} }
if(getThirdPersonAnimation != null){ if(getThirdPersonAnimation != null){
toPlay = getThirdPersonAnimation.get(); toPlay = getThirdPersonAnimation.get();
@ -225,8 +232,8 @@ public class StateTransitionUtil {
*/ */
String getFirstPersonAnimation(){ String getFirstPersonAnimation(){
String toPlay = null; String toPlay = null;
if(firstPersonAnimation != null){ if(animation != null){
toPlay = firstPersonAnimation.getName(); toPlay = animation.getNameFirstPerson();
} }
if(getFirstPersonAnimation != null){ if(getFirstPersonAnimation != null){
toPlay = getFirstPersonAnimation.get(); toPlay = getFirstPersonAnimation.get();
@ -240,8 +247,8 @@ public class StateTransitionUtil {
*/ */
int getAnimationPriority(){ int getAnimationPriority(){
int priority = this.animPriority; int priority = this.animPriority;
if(thirdPersonAnimation != null && thirdPersonAnimation.getPriority() != null){ if(animation != null && animation.getPriority() != null){
priority = thirdPersonAnimation.getPriority(); priority = animation.getPriority();
} }
return priority; return priority;
} }
@ -251,14 +258,12 @@ public class StateTransitionUtil {
*/ */
private StateTransitionUtilItem( private StateTransitionUtilItem(
Object stateEnum, Object stateEnum,
TreeDataAnimation firstPersonAnimation, TreeDataAnimation animation,
TreeDataAnimation thirdPersonAnimation,
TreeDataAudio audioData, TreeDataAudio audioData,
Runnable onComplete Runnable onComplete
){ ){
this.stateEnum = stateEnum; this.stateEnum = stateEnum;
this.firstPersonAnimation = firstPersonAnimation; this.animation = animation;
this.thirdPersonAnimation = thirdPersonAnimation;
this.audioData = audioData; this.audioData = audioData;
this.onComplete = onComplete; this.onComplete = onComplete;
} }
@ -326,8 +331,7 @@ public class StateTransitionUtil {
if(treeData != null){ if(treeData != null){
rVal = new StateTransitionUtilItem( rVal = new StateTransitionUtilItem(
stateEnum, stateEnum,
treeData.getFirstPersonAnimation(), treeData.getAnimation(),
treeData.getThirdPersonAnimation(),
treeData.getAudioData(), treeData.getAudioData(),
onComplete onComplete
); );

View File

@ -244,7 +244,7 @@ public class ClientAttackTree implements BehaviorTree {
entityActor.playAnimation(currentMove.getWindupAnimationName(),AnimationPriorities.ATTACK); entityActor.playAnimation(currentMove.getWindupAnimationName(),AnimationPriorities.ATTACK);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getName(), AnimationPriorities.ATTACK); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getNameFirstPerson(), AnimationPriorities.ATTACK);
} }
} }
} break; } break;
@ -254,7 +254,7 @@ public class ClientAttackTree implements BehaviorTree {
entityActor.playAnimation(currentMove.getHoldAnimationName(),AnimationPriorities.ATTACK); entityActor.playAnimation(currentMove.getHoldAnimationName(),AnimationPriorities.ATTACK);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getName(), AnimationPriorities.ATTACK); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getNameFirstPerson(), AnimationPriorities.ATTACK);
} }
} break; } break;
case ATTACK: { case ATTACK: {
@ -263,7 +263,7 @@ public class ClientAttackTree implements BehaviorTree {
entityActor.playAnimation(currentMove.getAttackAnimationName(),AnimationPriorities.ATTACK); entityActor.playAnimation(currentMove.getAttackAnimationName(),AnimationPriorities.ATTACK);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonAttack().getName(), AnimationPriorities.ATTACK); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonAttack().getNameFirstPerson(), AnimationPriorities.ATTACK);
} }
//activate hitboxes //activate hitboxes
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent); List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);

View File

@ -5,6 +5,7 @@ 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.game.data.common.TreeDataAnimation;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
/** /**
@ -104,15 +105,44 @@ public class FirstPersonTree implements BehaviorTree {
} }
} }
/**
* Plays an animation if it exists
* @param animationName the name of the animation
*/
public void playAnimation(TreeDataAnimation animation){
if(Globals.firstPersonEntity != null){
Actor actor = EntityUtils.getActor(Globals.firstPersonEntity);
if(
(!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animation.getNameFirstPerson())) &&
(Globals.assetManager.fetchModel(actor.getModelPath()) != null && Globals.assetManager.fetchModel(actor.getModelPath()).getAnimation(animation.getNameFirstPerson()) != null)
){
actor.playAnimation(animation, false);
actor.incrementAnimationTime(0.0001);
}
}
}
/** /**
* If the entity has a first person tree, plays the provided animation * If the entity has a first person tree, plays the provided animation
* @param entity The entity * @param entity The entity
* @param animationName the name of the animation * @param animationName the name of the animation
* @param priority The priority of the animation
*/ */
public static void conditionallyPlayAnimation(Entity entity, String animationName, int priority){ public static void conditionallyPlayAnimation(Entity entity, String animationName, int priority){
if(entity != null && FirstPersonTree.hasTree(entity)){ if(entity != null && FirstPersonTree.hasTree(entity)){
FirstPersonTree.getTree(entity).playAnimation(animationName, priority); FirstPersonTree.getTree(entity).playAnimation(animationName, priority);
} }
} }
/**
* If the entity has a first person tree, plays the provided animation
* @param entity The entity
* @param animationName the name of the animation
*/
public static void conditionallyPlayAnimation(Entity entity, TreeDataAnimation animation){
if(entity != null && FirstPersonTree.hasTree(entity)){
FirstPersonTree.getTree(entity).playAnimation(animation);
}
}
} }

View File

@ -404,6 +404,9 @@ public class ClientEquipState implements BehaviorTree {
@Override @Override
public void simulate(float deltaTime) { public void simulate(float deltaTime) {
} }

View File

@ -14,7 +14,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.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.IdleData; import electrosphere.game.data.creature.type.IdleData;
import electrosphere.net.synchronization.annotation.SyncedField; import electrosphere.net.synchronization.annotation.SyncedField;
import electrosphere.net.synchronization.annotation.SynchronizableEnum; import electrosphere.net.synchronization.annotation.SynchronizableEnum;
@ -49,7 +49,7 @@ public class ClientIdleTree implements BehaviorTree {
state = IdleTreeState.IDLE; state = IdleTreeState.IDLE;
parent = e; parent = e;
//check if this is a creature, if so add its idle data //check if this is a creature, if so add its idle data
CreatureType creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(parent)); CreatureData creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(parent));
if(creatureType != null){ if(creatureType != null){
idleData = creatureType.getIdleData(); idleData = creatureType.getIdleData();
} }

View File

@ -91,12 +91,12 @@ public class FallTree implements BehaviorTree {
Actor entityActor = EntityUtils.getActor(parent); Actor entityActor = EntityUtils.getActor(parent);
if(entityActor != null){ if(entityActor != null){
if( if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getLandState().getThirdPersonAnimation().getName()) !entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getLandState().getAnimation().getNameThirdPerson())
){ ){
entityActor.playAnimation(fallMovementSystem.getLandState().getThirdPersonAnimation().getName(),AnimationPriorities.LAND); entityActor.playAnimation(fallMovementSystem.getLandState().getAnimation().getNameThirdPerson(),AnimationPriorities.LAND);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, fallMovementSystem.getLandState().getFirstPersonAnimation().getName(), AnimationPriorities.LAND); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, fallMovementSystem.getLandState().getAnimation().getNameFirstPerson(), AnimationPriorities.LAND);
} }
} }
} }

View File

@ -60,11 +60,11 @@ public class JumpTree implements BehaviorTree {
switch(state){ switch(state){
case ACTIVE: case ACTIVE:
if(entityActor != null){ if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(jumpData.getAnimationJump().getName())){ if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(jumpData.getAnimationJump().getNameThirdPerson())){
entityActor.playAnimation(jumpData.getAnimationJump().getName(),AnimationPriorities.JUMP); entityActor.playAnimation(jumpData.getAnimationJump().getNameThirdPerson(),AnimationPriorities.JUMP);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, jumpData.getAnimationFirstPersonJump().getName(), AnimationPriorities.JUMP); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, jumpData.getAnimationFirstPersonJump().getNameFirstPerson(), AnimationPriorities.JUMP);
} }
currentFrame++; currentFrame++;
currentJumpForce = currentJumpForce * jumpFalloff; currentJumpForce = currentJumpForce * jumpFalloff;

View File

@ -294,7 +294,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE); entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonStartup().getName(), AnimationPriorities.GROUND_MOVE); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonStartup().getNameThirdPerson(), AnimationPriorities.GROUND_MOVE);
} }
//run startup code //run startup code
velocity = velocity + acceleration * (float)Globals.timekeeper.getSimFrameTime(); velocity = velocity + acceleration * (float)Globals.timekeeper.getSimFrameTime();
@ -328,7 +328,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE); entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonLoop().getName(), AnimationPriorities.GROUND_MOVE); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonLoop().getNameThirdPerson(), AnimationPriorities.GROUND_MOVE);
} }
if(velocity != maxNaturalVelocity){ if(velocity != maxNaturalVelocity){
velocity = maxNaturalVelocity; velocity = maxNaturalVelocity;
@ -356,7 +356,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE); entityActor.playAnimation(animationToPlay,AnimationPriorities.GROUND_MOVE);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonWindDown().getName(), AnimationPriorities.GROUND_MOVE); FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonWindDown().getNameThirdPerson(), AnimationPriorities.GROUND_MOVE);
} }
//velocity stuff //velocity stuff
velocity = velocity - acceleration * (float)Globals.timekeeper.getSimFrameTime(); velocity = velocity - acceleration * (float)Globals.timekeeper.getSimFrameTime();

View File

@ -46,7 +46,7 @@ import electrosphere.entity.state.rotator.RotatorTree;
import electrosphere.entity.state.rotator.ServerRotatorTree; import electrosphere.entity.state.rotator.ServerRotatorTree;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.collidable.CollidableTemplate;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.SprintSystem; import electrosphere.game.data.creature.type.SprintSystem;
import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.attack.AttackMove;
import electrosphere.game.data.creature.type.movement.AirplaneMovementSystem; import electrosphere.game.data.creature.type.movement.AirplaneMovementSystem;
@ -91,7 +91,7 @@ public class CreatureUtils {
* @return The creature entity * @return The creature entity
*/ */
public static Entity clientSpawnBasicCreature(String type, CreatureTemplate template){ public static Entity clientSpawnBasicCreature(String type, CreatureTemplate template){
CreatureType rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type); CreatureData rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type);
Entity rVal = EntityCreationUtils.createClientSpatialEntity(); Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath()); EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
Actor creatureActor = EntityUtils.getActor(rVal); Actor creatureActor = EntityUtils.getActor(rVal);
@ -130,26 +130,26 @@ public class CreatureUtils {
GroundMovementSystem groundMovementSystem = (GroundMovementSystem)movementSystem; GroundMovementSystem groundMovementSystem = (GroundMovementSystem)movementSystem;
ClientGroundMovementTree moveTree = ClientGroundMovementTree.attachTree(rVal, CollisionObjUtils.getCollidable(rVal), groundMovementSystem); ClientGroundMovementTree moveTree = ClientGroundMovementTree.attachTree(rVal, CollisionObjUtils.getCollidable(rVal), groundMovementSystem);
if(groundMovementSystem.getAnimationStartup() != null){ if(groundMovementSystem.getAnimationStartup() != null){
moveTree.setAnimationStartUp(groundMovementSystem.getAnimationStartup().getName()); moveTree.setAnimationStartUp(groundMovementSystem.getAnimationStartup().getNameThirdPerson());
} }
if(groundMovementSystem.getAnimationLoop() != null){ if(groundMovementSystem.getAnimationLoop() != null){
moveTree.setAnimationMain(groundMovementSystem.getAnimationLoop().getName()); moveTree.setAnimationMain(groundMovementSystem.getAnimationLoop().getNameThirdPerson());
} }
if(groundMovementSystem.getAnimationWindDown()!= null){ if(groundMovementSystem.getAnimationWindDown()!= null){
moveTree.setAnimationSlowDown(groundMovementSystem.getAnimationWindDown().getName()); moveTree.setAnimationSlowDown(groundMovementSystem.getAnimationWindDown().getNameThirdPerson());
} }
//sprint system //sprint system
if(groundMovementSystem.getSprintSystem() != null){ if(groundMovementSystem.getSprintSystem() != null){
SprintSystem sprintSystem = groundMovementSystem.getSprintSystem(); SprintSystem sprintSystem = groundMovementSystem.getSprintSystem();
SprintTree sprintTree = new SprintTree(rVal,sprintSystem.getMaxVelocity(),sprintSystem.getStaminaMax()); SprintTree sprintTree = new SprintTree(rVal,sprintSystem.getMaxVelocity(),sprintSystem.getStaminaMax());
if(sprintSystem.getAnimationStartUp()!= null){ if(sprintSystem.getAnimationStartUp()!= null){
moveTree.setAnimationSprintStartUp(sprintSystem.getAnimationStartUp().getName()); moveTree.setAnimationSprintStartUp(sprintSystem.getAnimationStartUp().getNameThirdPerson());
} }
if(sprintSystem.getAnimationMain()!= null){ if(sprintSystem.getAnimationMain()!= null){
moveTree.setAnimationSprint(sprintSystem.getAnimationMain().getName()); moveTree.setAnimationSprint(sprintSystem.getAnimationMain().getNameThirdPerson());
} }
if(sprintSystem.getAnimationWindDown()!= null){ if(sprintSystem.getAnimationWindDown()!= null){
moveTree.setAnimationSprintWindDown(sprintSystem.getAnimationWindDown().getName()); moveTree.setAnimationSprintWindDown(sprintSystem.getAnimationWindDown().getNameThirdPerson());
} }
sprintTree.setGroundMovementTree(moveTree); sprintTree.setGroundMovementTree(moveTree);
moveTree.setSprintTree(sprintTree); moveTree.setSprintTree(sprintTree);
@ -172,7 +172,7 @@ public class CreatureUtils {
JumpMovementSystem jumpMovementSystem = (JumpMovementSystem)movementSystem; JumpMovementSystem jumpMovementSystem = (JumpMovementSystem)movementSystem;
JumpTree jumpTree = new JumpTree(rVal, jumpMovementSystem.getJumpFrames(), jumpMovementSystem.getJumpForce(), jumpMovementSystem); JumpTree jumpTree = new JumpTree(rVal, jumpMovementSystem.getJumpFrames(), jumpMovementSystem.getJumpForce(), jumpMovementSystem);
if(jumpMovementSystem.getAnimationJump() != null){ if(jumpMovementSystem.getAnimationJump() != null){
jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getName()); jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getNameThirdPerson());
} }
if(CreatureUtils.clientGetEntityMovementTree(rVal) != null && CreatureUtils.clientGetEntityMovementTree(rVal) instanceof ClientGroundMovementTree){ if(CreatureUtils.clientGetEntityMovementTree(rVal) != null && CreatureUtils.clientGetEntityMovementTree(rVal) instanceof ClientGroundMovementTree){
((ClientGroundMovementTree)CreatureUtils.clientGetEntityMovementTree(rVal)).setClientJumpTree(jumpTree); ((ClientGroundMovementTree)CreatureUtils.clientGetEntityMovementTree(rVal)).setClientJumpTree(jumpTree);
@ -384,7 +384,7 @@ public class CreatureUtils {
* @return The creature entity * @return The creature entity
*/ */
public static Entity serverSpawnBasicCreature(Realm realm, Vector3d position, String type, CreatureTemplate template){ public static Entity serverSpawnBasicCreature(Realm realm, Vector3d position, String type, CreatureTemplate template){
CreatureType rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type); CreatureData rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type);
Entity rVal = EntityCreationUtils.createServerEntity(realm, position); Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath()); EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
@ -417,26 +417,26 @@ public class CreatureUtils {
GroundMovementSystem groundMovementSystem = (GroundMovementSystem)movementSystem; GroundMovementSystem groundMovementSystem = (GroundMovementSystem)movementSystem;
ServerGroundMovementTree moveTree = ServerGroundMovementTree.attachTree(rVal,CollisionObjUtils.getCollidable(rVal)); ServerGroundMovementTree moveTree = ServerGroundMovementTree.attachTree(rVal,CollisionObjUtils.getCollidable(rVal));
if(groundMovementSystem.getAnimationStartup() != null){ if(groundMovementSystem.getAnimationStartup() != null){
moveTree.setAnimationStartUp(groundMovementSystem.getAnimationStartup().getName()); moveTree.setAnimationStartUp(groundMovementSystem.getAnimationStartup().getNameThirdPerson());
} }
if(groundMovementSystem.getAnimationLoop() != null){ if(groundMovementSystem.getAnimationLoop() != null){
moveTree.setAnimationMain(groundMovementSystem.getAnimationLoop().getName()); moveTree.setAnimationMain(groundMovementSystem.getAnimationLoop().getNameThirdPerson());
} }
if(groundMovementSystem.getAnimationWindDown()!= null){ if(groundMovementSystem.getAnimationWindDown()!= null){
moveTree.setAnimationSlowDown(groundMovementSystem.getAnimationWindDown().getName()); moveTree.setAnimationSlowDown(groundMovementSystem.getAnimationWindDown().getNameThirdPerson());
} }
//sprint system //sprint system
if(groundMovementSystem.getSprintSystem() != null){ if(groundMovementSystem.getSprintSystem() != null){
SprintSystem sprintSystem = groundMovementSystem.getSprintSystem(); SprintSystem sprintSystem = groundMovementSystem.getSprintSystem();
ServerSprintTree sprintTree = new ServerSprintTree(rVal,sprintSystem.getMaxVelocity(),sprintSystem.getStaminaMax()); ServerSprintTree sprintTree = new ServerSprintTree(rVal,sprintSystem.getMaxVelocity(),sprintSystem.getStaminaMax());
if(sprintSystem.getAnimationStartUp()!= null){ if(sprintSystem.getAnimationStartUp()!= null){
moveTree.setAnimationSprintStartUp(sprintSystem.getAnimationStartUp().getName()); moveTree.setAnimationSprintStartUp(sprintSystem.getAnimationStartUp().getNameThirdPerson());
} }
if(sprintSystem.getAnimationMain()!= null){ if(sprintSystem.getAnimationMain()!= null){
moveTree.setAnimationSprint(sprintSystem.getAnimationMain().getName()); moveTree.setAnimationSprint(sprintSystem.getAnimationMain().getNameThirdPerson());
} }
if(sprintSystem.getAnimationWindDown()!= null){ if(sprintSystem.getAnimationWindDown()!= null){
moveTree.setAnimationSprintWindDown(sprintSystem.getAnimationWindDown().getName()); moveTree.setAnimationSprintWindDown(sprintSystem.getAnimationWindDown().getNameThirdPerson());
} }
sprintTree.setServerGroundMovementTree(moveTree); sprintTree.setServerGroundMovementTree(moveTree);
moveTree.setServerSprintTree(sprintTree); moveTree.setServerSprintTree(sprintTree);
@ -459,7 +459,7 @@ public class CreatureUtils {
JumpMovementSystem jumpMovementSystem = (JumpMovementSystem)movementSystem; JumpMovementSystem jumpMovementSystem = (JumpMovementSystem)movementSystem;
ServerJumpTree jumpTree = new ServerJumpTree(rVal, jumpMovementSystem.getJumpFrames(), jumpMovementSystem.getJumpForce()); ServerJumpTree jumpTree = new ServerJumpTree(rVal, jumpMovementSystem.getJumpFrames(), jumpMovementSystem.getJumpForce());
if(jumpMovementSystem.getAnimationJump() != null){ if(jumpMovementSystem.getAnimationJump() != null){
jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getName()); jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getNameThirdPerson());
} }
if(CreatureUtils.serverGetEntityMovementTree(rVal) != null && CreatureUtils.serverGetEntityMovementTree(rVal) instanceof ClientGroundMovementTree){ if(CreatureUtils.serverGetEntityMovementTree(rVal) != null && CreatureUtils.serverGetEntityMovementTree(rVal) instanceof ClientGroundMovementTree){
((ServerGroundMovementTree)CreatureUtils.serverGetEntityMovementTree(rVal)).setServerJumpTree(jumpTree); ((ServerGroundMovementTree)CreatureUtils.serverGetEntityMovementTree(rVal)).setServerJumpTree(jumpTree);

View File

@ -3,7 +3,7 @@ package electrosphere.game.data;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.CreatureTypeLoader; import electrosphere.game.data.creature.type.CreatureTypeLoader;
import electrosphere.game.data.creature.type.attack.AttackMoveResolver; import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
import electrosphere.game.data.creature.type.model.CreatureTypeMap; import electrosphere.game.data.creature.type.model.CreatureTypeMap;
@ -57,6 +57,11 @@ public class Config {
config.projectileTypeHolder = FileUtils.loadObjectFromAssetPath("Data/projectile.json", ProjectileTypeHolder.class); config.projectileTypeHolder = FileUtils.loadObjectFromAssetPath("Data/projectile.json", ProjectileTypeHolder.class);
config.hintData = FileUtils.loadObjectFromAssetPath("Data/tutorial/hints.json", HintDefinition.class); config.hintData = FileUtils.loadObjectFromAssetPath("Data/tutorial/hints.json", HintDefinition.class);
config.projectileTypeHolder.init(); config.projectileTypeHolder.init();
//validate
ConfigValidator.valdiate(config);
return config; return config;
} }
@ -65,17 +70,17 @@ public class Config {
* @param filename The filename * @param filename The filename
* @return The list of creatures in the file * @return The list of creatures in the file
*/ */
static List<CreatureType> readCreatureTypeFile(String filename){ static List<CreatureData> readCreatureTypeFile(String filename){
List<CreatureType> typeList = new LinkedList<CreatureType>(); List<CreatureData> typeList = new LinkedList<CreatureData>();
CreatureTypeMap typeMap = FileUtils.loadObjectFromAssetPath(filename, CreatureTypeMap.class); CreatureTypeMap typeMap = FileUtils.loadObjectFromAssetPath(filename, CreatureTypeMap.class);
//push the types from this file //push the types from this file
for(CreatureType type : typeMap.getCreatures()){ for(CreatureData type : typeMap.getCreatures()){
typeList.add(type); typeList.add(type);
} }
//push types from any other files //push types from any other files
for(String filepath : typeMap.getFiles()){ for(String filepath : typeMap.getFiles()){
List<CreatureType> parsedTypeList = readCreatureTypeFile(filepath); List<CreatureData> parsedTypeList = readCreatureTypeFile(filepath);
for(CreatureType type : parsedTypeList){ for(CreatureData type : parsedTypeList){
typeList.add(type); typeList.add(type);
} }
} }
@ -89,8 +94,8 @@ public class Config {
*/ */
static CreatureTypeLoader loadCreatureTypes(String initialPath) { static CreatureTypeLoader loadCreatureTypes(String initialPath) {
CreatureTypeLoader loader = new CreatureTypeLoader(); CreatureTypeLoader loader = new CreatureTypeLoader();
List<CreatureType> typeList = readCreatureTypeFile(initialPath); List<CreatureData> typeList = readCreatureTypeFile(initialPath);
for(CreatureType type : typeList){ for(CreatureData type : typeList){
if(type.getAttackMoves() != null){ if(type.getAttackMoves() != null){
type.setAttackMoveResolver(new AttackMoveResolver(type.getAttackMoves())); type.setAttackMoveResolver(new AttackMoveResolver(type.getAttackMoves()));
} }

View File

@ -0,0 +1,24 @@
package electrosphere.game.data;
import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.CreatureDataValidator;
import electrosphere.game.data.creature.type.CreatureTypeLoader;
/**
* Used to validate the config
*/
public class ConfigValidator {
/**
* Validates a config
* @param config The config
*/
public static void valdiate(Config config){
//validate the creatures
CreatureTypeLoader creatureTypeLoader = config.getCreatureTypeLoader();
for(CreatureData creatureData : creatureTypeLoader.getCreatures()){
CreatureDataValidator.validate(creatureData);
}
}
}

View File

@ -1,14 +1,21 @@
package electrosphere.game.data.common; package electrosphere.game.data.common;
import java.util.List;
/** /**
* Data about an animation * Data about an animation
*/ */
public class TreeDataAnimation { public class TreeDataAnimation {
/** /**
* The name of the animation if it exists, null otherwise * The name of the animation to play in third person if it exists, null otherwise
*/ */
String name; String nameThirdPerson;
/**
* The name of the animation to play in first person if it exists, null otherwise
*/
String nameFirstPerson;
/** /**
* The length of the animation in frames if it exists, null otherwise * The length of the animation in frames if it exists, null otherwise
@ -26,11 +33,24 @@ public class TreeDataAnimation {
Integer priority; Integer priority;
/** /**
* Gets the name of the animation * The list of bone groups this animation applies to
* @return The name of the animation
*/ */
public String getName() { List<String> boneGroups;
return name;
/**
* Gets the name of the animation to play in third person
* @return The name of the animation to play in third person
*/
public String getNameThirdPerson() {
return nameThirdPerson;
}
/**
* Gets the name of the animation to play in first person
* @return The name of the animation to play in first person
*/
public String getNameFirstPerson() {
return nameFirstPerson;
} }
/** /**
@ -56,5 +76,13 @@ public class TreeDataAnimation {
public Integer getPriority(){ public Integer getPriority(){
return priority; return priority;
} }
/**
* Gets the bone groups this animation applies to
* @return The list of bone groups this animation applies to
*/
public List<String> getBoneGroups(){
return boneGroups;
}
} }

View File

@ -6,14 +6,9 @@ package electrosphere.game.data.common;
public class TreeDataState { public class TreeDataState {
/** /**
* The animation to play for the tree's state when in first person * The animation to play for the tree's state
*/ */
TreeDataAnimation firstPersonAnimation; TreeDataAnimation animation;
/**
* The animation to play for the tree's state when in third person
*/
TreeDataAnimation thirdPersonAnimation;
/** /**
* The audio to play when running this state of the tree * The audio to play when running this state of the tree
@ -21,19 +16,11 @@ public class TreeDataState {
TreeDataAudio audioData; TreeDataAudio audioData;
/** /**
* Gets the first person animation data * Gets the animation data
* @return The first person animation data if it exists, null otherwise * @return The animation data if it exists, null otherwise
*/ */
public TreeDataAnimation getFirstPersonAnimation(){ public TreeDataAnimation getAnimation(){
return firstPersonAnimation; return animation;
}
/**
* Gets the third person animation data
* @return The third person animation data if it exists, null otherwise
*/
public TreeDataAnimation getThirdPersonAnimation(){
return thirdPersonAnimation;
} }
/** /**

View File

@ -17,7 +17,7 @@ import java.util.List;
/** /**
* A given type of creature * A given type of creature
*/ */
public class CreatureType { public class CreatureData {
/** /**
* The id of the creature * The id of the creature

View File

@ -0,0 +1,71 @@
package electrosphere.game.data.creature.type;
import java.util.LinkedList;
import java.util.List;
import electrosphere.game.data.creature.type.bonegroups.BoneGroup;
import electrosphere.logger.LoggerInterface;
/**
* Validates a creature
*/
public class CreatureDataValidator {
/**
* Validates a creature's data
* @param data The creature's data
*/
public static void validate(CreatureData data){
CreatureDataValidator.validateBoneGroups(data);
}
/**
* Validates the bone groups
* @param data The creature data
*/
static void validateBoneGroups(CreatureData data){
List<String> bonesUsedFirstPerson = new LinkedList<String>();
List<String> bonesUsedThirdPerson = new LinkedList<String>();
List<BoneGroup> boneGroups = data.getBoneGroups();
if(boneGroups != null){
for(BoneGroup group : boneGroups){
//check first person bones
if(group.getBoneNamesFirstPerson() != null){
for(String boneName : group.getBoneNamesFirstPerson()){
if(bonesUsedFirstPerson.contains(boneName)){
//same bone used in multiple groups
String message = "Two bone groups have the same bone in them!\n" +
"Bone name: " + boneName + "\n" +
"Second group: " + group.getId() + "\n" +
"Creature name: " + data.getCreatureId()
;
LoggerInterface.loggerEngine.WARNING(message);
} else {
bonesUsedFirstPerson.add(boneName);
}
}
}
//check third person bones
if(group.getBoneNamesThirdPerson() != null){
for(String boneName : group.getBoneNamesThirdPerson()){
if(bonesUsedThirdPerson.contains(boneName)){
//same bone used in multiple groups
String message = "Two bone groups have the same bone in them!\n" +
"Bone name: " + boneName + "\n" +
"Second group: " + group.getId() + "\n" +
"Creature name: " + data.getCreatureId()
;
LoggerInterface.loggerEngine.WARNING(message);
} else {
bonesUsedThirdPerson.add(boneName);
}
}
}
}
}
}
}

View File

@ -7,23 +7,49 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
/**
* The creature type loader
*/
public class CreatureTypeLoader { public class CreatureTypeLoader {
Map<String,CreatureType> creatureMap = new HashMap<String,CreatureType>(); /**
* The map of creature name -> creature data
*/
Map<String,CreatureData> creatureMap = new HashMap<String,CreatureData>();
/**
* The list of playable races
*/
List<String> playableRaceNames = new LinkedList<String>(); List<String> playableRaceNames = new LinkedList<String>();
/**
* The lock on playable races
*/
Semaphore playableRaceLock = new Semaphore(1); Semaphore playableRaceLock = new Semaphore(1);
public void putCreature(String name, CreatureType type){ /**
* Adds creature data to the loader
* @param name The name of the creature
* @param type The creature data
*/
public void putCreature(String name, CreatureData type){
creatureMap.put(name,type); creatureMap.put(name,type);
} }
/**
* Adds a playable race to the loader
* @param name The race name
*/
public void putPlayableRace(String name){ public void putPlayableRace(String name){
playableRaceNames.add(name); playableRaceNames.add(name);
} }
public CreatureType getCreature(String name){ /**
* Gets creature data from the name of a creature
* @param name The name of the creature
* @return The creature data if it exists, null otherwise
*/
public CreatureData getCreature(String name){
return creatureMap.get(name); return creatureMap.get(name);
} }
@ -31,10 +57,14 @@ public class CreatureTypeLoader {
* Gets the collection of all creature data * Gets the collection of all creature data
* @return the collection of all creature data * @return the collection of all creature data
*/ */
public Collection<CreatureType> getCreatures(){ public Collection<CreatureData> getCreatures(){
return creatureMap.values(); return creatureMap.values();
} }
/**
* Gets the list of playable races
* @return The list of playable race names
*/
public List<String> getPlayableRaces(){ public List<String> getPlayableRaces(){
List<String> races = null; List<String> races = null;
playableRaceLock.acquireUninterruptibly(); playableRaceLock.acquireUninterruptibly();
@ -43,10 +73,17 @@ public class CreatureTypeLoader {
return races; return races;
} }
/**
* Clears the playable race list
*/
public void clearPlayableRaces(){ public void clearPlayableRaces(){
playableRaceNames.clear(); playableRaceNames.clear();
} }
/**
* Loads the list of playable races
* @param races The list of playable races
*/
public void loadPlayableRaces(List<String> races){ public void loadPlayableRaces(List<String> races){
playableRaceLock.acquireUninterruptibly(); playableRaceLock.acquireUninterruptibly();
playableRaceNames = races; playableRaceNames = races;

View File

@ -13,9 +13,14 @@ public class BoneGroup {
String id; String id;
/** /**
* The list of names of bones that are within this group * The list of names of bones that are within this group for the third person model
*/ */
List<String> boneNames; List<String> boneNamesThirdPerson;
/**
* The list of names of bones that are within this group for the first person model
*/
List<String> boneNamesFirstPerson;
/** /**
* Gets the id of the bone group * Gets the id of the bone group
@ -26,11 +31,19 @@ public class BoneGroup {
} }
/** /**
* Gets the list of names of bones in the group * Gets the list of names of bones in the group on the third person model
* @return The list of names of bones * @return The list of names of bones
*/ */
public List<String> getBoneNames(){ public List<String> getBoneNamesThirdPerson(){
return boneNames; return boneNamesThirdPerson;
}
/**
* Gets the list of names of bones in the group on the first person model
* @return The list of names of bones
*/
public List<String> getBoneNamesFirstPerson(){
return boneNamesFirstPerson;
} }
} }

View File

@ -2,6 +2,8 @@ package electrosphere.game.data.creature.type.equip;
import java.util.List; import java.util.List;
import electrosphere.game.data.common.TreeDataAnimation;
/** /**
* A portion of the creature that can have an item attached to it * A portion of the creature that can have an item attached to it
*/ */
@ -9,23 +11,34 @@ public class EquipPoint {
//the id of the equip point //the id of the equip point
String equipPointId; String equipPointId;
//the bone that can have the item attached to it (may not be defined depending on the type of equip point (think legs)) //the bone that can have the item attached to it (may not be defined depending on the type of equip point (think legs))
String bone; String bone;
//the bone to attach items to for the first person viewmodel (may not be defined based on the viewmodel) //the bone to attach items to for the first person viewmodel (may not be defined based on the viewmodel)
String firstPersonBone; String firstPersonBone;
//the offset to apply to items that are attached to the bone //the offset to apply to items that are attached to the bone
List<Float> offsetVectorThirdPerson; List<Float> offsetVectorThirdPerson;
//the offset to apply to items that are attached to the bone //the offset to apply to items that are attached to the bone
List<Float> offsetVectorFirstPerson; List<Float> offsetVectorFirstPerson;
//the rotation to apply to the items that are attached to the bone //the rotation to apply to the items that are attached to the bone
List<Float> offsetRotationThirdPerson; List<Float> offsetRotationThirdPerson;
//the rotation to apply to the items that are attached to the view model's bone //the rotation to apply to the items that are attached to the view model's bone
List<Float> offsetRotationFirstPerson; List<Float> offsetRotationFirstPerson;
//signals that this equip point can block //signals that this equip point can block
boolean canBlock; boolean canBlock;
//the equip classes that are whitelisted for this equip point //the equip classes that are whitelisted for this equip point
List<String> equipClassWhitelist; List<String> equipClassWhitelist;
//The animation to play when this equip point has an item equipped (ie if a hand is grasping something)
TreeDataAnimation equippedAnimation;
/** /**
* Gets the equip point id * Gets the equip point id
* @return the id of the equip point * @return the id of the equip point
@ -131,5 +144,13 @@ public class EquipPoint {
public List<String> getEquipClassWhitelist(){ public List<String> getEquipClassWhitelist(){
return equipClassWhitelist; return equipClassWhitelist;
} }
/**
* Gets the animation to play when this point has an item equipped
* @return The animation if it exists, null otherwise
*/
public TreeDataAnimation getEquippedAnimation(){
return equippedAnimation;
}
} }

View File

@ -1,14 +1,14 @@
package electrosphere.game.data.creature.type.model; package electrosphere.game.data.creature.type.model;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import java.util.List; import java.util.List;
public class CreatureTypeMap { public class CreatureTypeMap {
List<CreatureType> creatures; List<CreatureData> creatures;
List<String> files; List<String> files;
public List<CreatureType> getCreatures(){ public List<CreatureData> getCreatures(){
return creatures; return creatures;
} }

View File

@ -9,7 +9,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils; import electrosphere.menu.WindowUtils;
@ -376,7 +376,7 @@ public class MenuGeneratorsInGame {
Entity playerEntity = Globals.playerEntity; Entity playerEntity = Globals.playerEntity;
Actor playerActor = EntityUtils.getActor(playerEntity); Actor playerActor = EntityUtils.getActor(playerEntity);
ActorStaticMorph staticMorph = playerActor.getStaticMorph(); ActorStaticMorph staticMorph = playerActor.getStaticMorph();
CreatureType playeCreatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(playerEntity)); CreatureData playeCreatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(playerEntity));
int offset = 0; int offset = 0;
for(VisualAttribute attribute : playeCreatureType.getVisualAttributes()){ for(VisualAttribute attribute : playeCreatureType.getVisualAttributes()){
int posY = offset * 350 + 100; int posY = offset * 350 + 100;

View File

@ -13,7 +13,7 @@ import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils; import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.foliage.type.FoliageType; import electrosphere.game.data.foliage.type.FoliageType;
import electrosphere.game.data.item.type.Item; import electrosphere.game.data.item.type.Item;
import electrosphere.game.data.object.type.ObjectData; import electrosphere.game.data.object.type.ObjectData;
@ -159,7 +159,7 @@ public class MenuGeneratorsLevelEditor {
})); }));
//button for spawning all creatures //button for spawning all creatures
for(CreatureType data : Globals.gameConfigCurrent.getCreatureTypeLoader().getCreatures()){ for(CreatureData data : Globals.gameConfigCurrent.getCreatureTypeLoader().getCreatures()){
//spawn creature button //spawn creature button
scrollable.addChild(Button.createButton("Spawn " + data.getCreatureId(), () -> { scrollable.addChild(Button.createButton("Spawn " + data.getCreatureId(), () -> {
LoggerInterface.loggerEngine.INFO("spawn " + data.getCreatureId() + "!"); LoggerInterface.loggerEngine.INFO("spawn " + data.getCreatureId() + "!");

View File

@ -8,7 +8,7 @@ import org.joml.Vector3f;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.creature.CreatureTemplate; import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.visualattribute.AttributeVariant; import electrosphere.game.data.creature.type.visualattribute.AttributeVariant;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.menu.MenuGenerators; import electrosphere.menu.MenuGenerators;
@ -87,7 +87,7 @@ public class MenuGeneratorsMultiplayer {
int horizontalPosition = 300; int horizontalPosition = 300;
//figure out race data //figure out race data
CreatureType selectedRaceType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(race); CreatureData selectedRaceType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(race);
//spawn camera so renderer doesn't crash (once render pipeline is modularized this shouldn't be necessary) //spawn camera so renderer doesn't crash (once render pipeline is modularized this shouldn't be necessary)
Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(0,0.3f,1).normalize()); Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(0,0.3f,1).normalize());

View File

@ -16,7 +16,7 @@ import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils; import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.ViewModelData; import electrosphere.game.data.creature.type.ViewModelData;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
@ -169,7 +169,7 @@ public class EntityProtocol {
if(target != null){ if(target != null){
CreatureUtils.setControllerPlayerId(target, message.getpropertyValue()); CreatureUtils.setControllerPlayerId(target, message.getpropertyValue());
String creatureTypeRaw = CreatureUtils.getType(target); String creatureTypeRaw = CreatureUtils.getType(target);
CreatureType creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(creatureTypeRaw); CreatureData creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(creatureTypeRaw);
ViewModelData viewModelData = creatureType.getViewModelData(); ViewModelData viewModelData = creatureType.getViewModelData();
if(Globals.clientPlayer != null && message.getpropertyValue() == Globals.clientPlayer.getId()){ if(Globals.clientPlayer != null && message.getpropertyValue() == Globals.clientPlayer.getId()){
Globals.clientCharacterID = message.getentityID(); Globals.clientCharacterID = message.getentityID();

View File

@ -1,6 +1,8 @@
package electrosphere.renderer.actor; package electrosphere.renderer.actor;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.game.data.common.TreeDataAnimation;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.model.Bone; import electrosphere.renderer.model.Bone;
@ -125,6 +127,11 @@ public class Actor {
} }
} }
/**
* Plays an animation provided as a string with a given priority
* @param animationName The name of the animation
* @param priority The priority of the animation
*/
public void playAnimation(String animationName, int priority){ public void playAnimation(String animationName, int priority){
// animationTime = 0; // animationTime = 0;
// playingAnimation = true; // playingAnimation = true;
@ -150,6 +157,81 @@ public class Actor {
} }
} }
/**
* Plays animation data
* @param animation The animation data
* @param isThirdPerson true if is third person, false if is first person
*/
public void playAnimation(TreeDataAnimation animation, boolean isThirdPerson){
//Get the animation's name
String animationName = "";
if(isThirdPerson){
animationName = animation.getNameThirdPerson();
} else {
animationName = animation.getNameFirstPerson();
}
//Get the animation's priority
int priority = AnimationPriorities.DEFAULT;
if(animation.getPriority() != null){
priority = animation.getPriority();
}
//Gets the mask
List<String> boneMask = null;
if(animation.getBoneGroups() != null){
boneMask = new LinkedList<String>();
}
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null && model.getAnimation(animationName) != null){
//get data from the actual animation in the model
double length = model.getAnimation(animationName).duration;
//construct the animation mask
ActorAnimationMask animMask;
if(boneMask == null){
animMask = new ActorAnimationMask(
priority,
animationName,
length
);
} else {
animMask = new ActorAnimationMask(
priority,
animationName,
length,
boneMask
);
}
//if a mask wasn't defined, apply this mask to all animations
if(boneMask == null){
for(Bone bone : model.getBones()){
animMask.addBone(bone.boneID);
}
}
//clear existing masks that are lower priority
toRemoveMasks.clear();
for(ActorAnimationMask currentMask : animationQueue){
if(currentMask.getPriority() == animMask.getPriority()){
toRemoveMasks.add(currentMask);
break;
}
}
for(ActorAnimationMask currentMask : toRemoveMasks){
animationQueue.remove(currentMask);
}
animationQueue.add(animMask);
}
}
public void playAnimationWithMask(String animationName, int priority, List<String> boneMask){ public void playAnimationWithMask(String animationName, int priority, List<String> boneMask){
Model model = Globals.assetManager.fetchModel(modelPath); Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){ if(model != null){

View File

@ -3,14 +3,34 @@ package electrosphere.renderer.actor;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
/**
* An animation mask. Combines an animation name, priority, and a list of bones to apply that animation to
*/
public class ActorAnimationMask implements Comparable<ActorAnimationMask> { public class ActorAnimationMask implements Comparable<ActorAnimationMask> {
//The priority of the mask
int priority; int priority;
//The name of the animation
String animationName; String animationName;
//The current time of this mask
double time; double time;
//The maximum time to play this mask for
double timeMax; double timeMax;
//The mask of bones to apply this animation to
List<String> boneMask; List<String> boneMask;
/**
* Constructor
* @param priority
* @param animationName
* @param time
* @param timeMax
* @param boneMask
*/
public ActorAnimationMask(int priority, String animationName, double time, double timeMax, List<String> boneMask){ public ActorAnimationMask(int priority, String animationName, double time, double timeMax, List<String> boneMask){
this.priority = priority; this.priority = priority;
this.animationName = animationName; this.animationName = animationName;
@ -19,34 +39,93 @@ public class ActorAnimationMask implements Comparable<ActorAnimationMask> {
this.boneMask = boneMask; this.boneMask = boneMask;
} }
/**
* Constructor
* @param priority
* @param animationName
* @param timeMax
* @param boneMask
*/
public ActorAnimationMask(int priority, String animationName, double timeMax, List<String> boneMask){
this.priority = priority;
this.animationName = animationName;
this.timeMax = timeMax;
this.boneMask = boneMask;
}
/**
* Constructor
* @param priority
* @param animationName
* @param time
* @param timeMax
*/
public ActorAnimationMask(int priority, String animationName, double time, double timeMax){ public ActorAnimationMask(int priority, String animationName, double time, double timeMax){
this(priority, animationName, time, timeMax, new LinkedList<String>()); this(priority, animationName, time, timeMax, new LinkedList<String>());
} }
/**
* Constructor
* @param priority
* @param animationName
* @param timeMax
*/
public ActorAnimationMask(int priority, String animationName, double timeMax){
this(priority, animationName, 0, timeMax, new LinkedList<String>());
}
/**
* Adds a bone to the mask
* @param boneName The name of the bone
*/
public void addBone(String boneName){ public void addBone(String boneName){
boneMask.add(boneName); boneMask.add(boneName);
} }
/**
* Gets the list of bones this mask applies to
* @return The list of bones
*/
public List<String> getBones(){ public List<String> getBones(){
return boneMask; return boneMask;
} }
/**
* Gets the name of the animation this mask uses
* @return The name of the animation
*/
public String getAnimationName(){ public String getAnimationName(){
return animationName; return animationName;
} }
/**
* Gets the priority of the mask
* @return The priority
*/
public int getPriority(){ public int getPriority(){
return priority; return priority;
} }
/**
* Gets the time of the mask
* @return The time
*/
public double getTime(){ public double getTime(){
return time; return time;
} }
/**
* Sets the time of this mask
* @param time The time
*/
public void setTime(double time){ public void setTime(double time){
this.time = time; this.time = time;
} }
/**
* Gets the duration of the mask
* @return The duration
*/
public double getDuration(){ public double getDuration(){
return timeMax; return timeMax;
} }

View File

@ -14,6 +14,8 @@ import org.joml.Vector3f;
import org.joml.Vector4d; import org.joml.Vector4d;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.state.AnimationPriorities;
import electrosphere.game.data.common.TreeDataAnimation;
import electrosphere.renderer.actor.ActorAnimationMask; import electrosphere.renderer.actor.ActorAnimationMask;
import electrosphere.renderer.actor.ActorBoneRotator; import electrosphere.renderer.actor.ActorBoneRotator;
import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorStaticMorph;
@ -143,6 +145,81 @@ public class PoseActor {
} }
} }
/**
* Plays animation data
* @param animation The animation data
* @param isThirdPerson true if is third person, false if is first person
*/
public void playAnimation(TreeDataAnimation animation, boolean isThirdPerson){
//Get the animation's name
String animationName = "";
if(isThirdPerson){
animationName = animation.getNameThirdPerson();
} else {
animationName = animation.getNameFirstPerson();
}
//Get the animation's priority
int priority = AnimationPriorities.DEFAULT;
if(animation.getPriority() != null){
priority = animation.getPriority();
}
//Gets the mask
List<String> boneMask = null;
if(animation.getBoneGroups() != null){
boneMask = new LinkedList<String>();
}
PoseModel model = Globals.assetManager.fetchPoseModel(modelPath);
if(model != null && model.getAnimation(animationName) != null){
//get data from the actual animation in the model
double length = model.getAnimation(animationName).duration;
//construct the animation mask
ActorAnimationMask animMask;
if(boneMask == null){
animMask = new ActorAnimationMask(
priority,
animationName,
length
);
} else {
animMask = new ActorAnimationMask(
priority,
animationName,
length,
boneMask
);
}
//if a mask wasn't defined, apply this mask to all animations
if(boneMask == null){
for(Bone bone : model.getBones()){
animMask.addBone(bone.boneID);
}
}
//clear existing masks that are lower priority
toRemoveMasks.clear();
for(ActorAnimationMask currentMask : animationQueue){
if(currentMask.getPriority() == animMask.getPriority()){
toRemoveMasks.add(currentMask);
break;
}
}
for(ActorAnimationMask currentMask : toRemoveMasks){
animationQueue.remove(currentMask);
}
animationQueue.add(animMask);
}
}
/** /**
* Play an animation with a mask that makes the animation only apply to specific bones * Play an animation with a mask that makes the animation only apply to specific bones
* @param animationName The name of the animation * @param animationName The name of the animation

View File

@ -211,4 +211,12 @@ public class PoseModel {
return animMap.get(animName); return animMap.get(animName);
} }
/**
* Gets the list of bones in this pose model
* @return The list of bones
*/
public List<Bone> getBones(){
return this.bones;
}
} }