172 lines
6.5 KiB
Java
172 lines
6.5 KiB
Java
package electrosphere.entity.state;
|
|
|
|
import electrosphere.entity.CreatureUtils;
|
|
import electrosphere.entity.Entity;
|
|
import electrosphere.entity.EntityUtils;
|
|
import electrosphere.main.Globals;
|
|
import electrosphere.net.NetUtils;
|
|
import electrosphere.net.message.EntityMessage;
|
|
import electrosphere.renderer.Animation;
|
|
import electrosphere.renderer.Model;
|
|
import java.util.LinkedList;
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
|
import org.joml.Vector3f;
|
|
|
|
/**
|
|
*
|
|
* @author amaterasu
|
|
*/
|
|
/*
|
|
Behavior tree for movement in an entity
|
|
*/
|
|
public class MovementTree {
|
|
|
|
public static enum MovementTreeState {
|
|
STARTUP,
|
|
MOVE,
|
|
SLOWDOWN,
|
|
IDLE,
|
|
}
|
|
|
|
MovementTreeState state;
|
|
|
|
Entity parent;
|
|
|
|
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList();
|
|
|
|
public MovementTree(Entity e){
|
|
state = MovementTreeState.IDLE;
|
|
parent = e;
|
|
}
|
|
|
|
public MovementTreeState getState(){
|
|
return state;
|
|
}
|
|
|
|
public void start(){
|
|
//TODO: check if can start moving
|
|
state = MovementTreeState.STARTUP;
|
|
}
|
|
|
|
public void interrupt(){
|
|
state = MovementTreeState.IDLE;
|
|
}
|
|
|
|
public void slowdown(){
|
|
state = MovementTreeState.SLOWDOWN;
|
|
}
|
|
|
|
public void transitionState(){
|
|
switch(state){
|
|
case STARTUP:
|
|
//transition if velocity >= acceleration
|
|
state = MovementTreeState.MOVE;
|
|
break;
|
|
case MOVE:
|
|
state = MovementTreeState.SLOWDOWN;
|
|
break;
|
|
case SLOWDOWN:
|
|
state = MovementTreeState.IDLE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void simulate(){
|
|
float velocity = CreatureUtils.getVelocity(parent);
|
|
float acceleration = CreatureUtils.getAcceleration(parent);
|
|
float maxNaturalVelocity = CreatureUtils.getMaxNaturalVelocity(parent);
|
|
Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent));
|
|
Vector3f position = EntityUtils.getEntityPosition(parent);
|
|
Vector3f movementVector = CreatureUtils.getMovementVector(parent);
|
|
|
|
//parse attached network messages
|
|
for(EntityMessage message : networkMessageQueue){
|
|
networkMessageQueue.remove(message);
|
|
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
|
switch(message.getEntityMessageType()){
|
|
case MOVE:
|
|
position.set(message.getX(), message.getY(), message.getZ());
|
|
if(Globals.mainConfig.runServer){
|
|
Globals.server.broadcastMessage(EntityMessage.constructMoveMessage(parent.getId(), message.getX(), message.getY(), message.getZ()));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//state machine
|
|
switch(state){
|
|
case STARTUP:
|
|
//run startup code
|
|
velocity = velocity + acceleration;
|
|
CreatureUtils.setVelocity(parent, velocity);
|
|
if(entityModel != null){
|
|
if(entityModel.currentAnimation == null || !entityModel.currentAnimation.name.equals(Animation.ANIMATION_MOVEMENT_STARTUP)){
|
|
entityModel.playAnimation(Animation.ANIMATION_MOVEMENT_STARTUP);
|
|
entityModel.currentAnimation.incrementTime(0.01);
|
|
}
|
|
}
|
|
//check if can transition state
|
|
if(velocity >= maxNaturalVelocity){
|
|
velocity = maxNaturalVelocity;
|
|
state = MovementTreeState.MOVE;
|
|
}
|
|
//move the entity
|
|
position.add(new Vector3f(movementVector).mul(velocity));
|
|
position.y = Globals.drawCellManager.getElevationAtRealPoint(position.x, position.z);
|
|
EntityUtils.getEntityRotation(parent).rotationTo(new Vector3f(0,0,1), movementVector);
|
|
break;
|
|
case MOVE:
|
|
//check if can restart animation
|
|
//if yes, restart animation
|
|
if(entityModel != null){
|
|
if(entityModel.currentAnimation == null || !entityModel.currentAnimation.name.equals(Animation.ANIMATION_MOVEMENT_MOVE)){
|
|
entityModel.playAnimation(Animation.ANIMATION_MOVEMENT_MOVE);
|
|
entityModel.currentAnimation.incrementTime(0.01);
|
|
}
|
|
}
|
|
//check if can move forward (collision engine)
|
|
//if can, move forward by entity movement stats
|
|
position.add(new Vector3f(movementVector).mul(velocity));
|
|
position.y = Globals.drawCellManager.getElevationAtRealPoint(position.x, position.z);
|
|
EntityUtils.getEntityRotation(parent).rotationTo(new Vector3f(0,0,1), movementVector);
|
|
break;
|
|
case SLOWDOWN:
|
|
//run slowdown code
|
|
velocity = velocity - acceleration;
|
|
CreatureUtils.setVelocity(parent, velocity);
|
|
if(entityModel != null){
|
|
if(entityModel.currentAnimation == null || !entityModel.currentAnimation.name.equals(Animation.ANIMATION_MOVEMENT_STARTUP)){
|
|
entityModel.playAnimation(Animation.ANIMATION_MOVEMENT_STARTUP);
|
|
entityModel.currentAnimation.incrementTime(0.01);
|
|
}
|
|
}
|
|
//check if can transition state
|
|
if(velocity <= 0){
|
|
velocity = 0;
|
|
state = MovementTreeState.IDLE;
|
|
}
|
|
//move the entity
|
|
position.add(new Vector3f(movementVector).mul(velocity));
|
|
position.y = Globals.drawCellManager.getElevationAtRealPoint(position.x, position.z);
|
|
EntityUtils.getEntityRotation(parent).rotationTo(new Vector3f(0,0,1), movementVector);
|
|
break;
|
|
case IDLE:
|
|
if(entityModel != null){
|
|
if(entityModel.currentAnimation == null || !entityModel.currentAnimation.name.equals(Animation.ANIMATION_IDLE_1)){
|
|
entityModel.playAnimation(Animation.ANIMATION_IDLE_1);
|
|
entityModel.currentAnimation.incrementTime(0.01);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void addNetworkMessage(EntityMessage networkMessage) {
|
|
networkMessageQueue.add(networkMessage);
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|