Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
203 lines
6.2 KiB
Java
203 lines
6.2 KiB
Java
package electrosphere.entity.state.life;
|
|
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
|
|
|
import org.joml.Vector3d;
|
|
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.entity.Entity;
|
|
import electrosphere.entity.EntityUtils;
|
|
import electrosphere.entity.btree.BehaviorTree;
|
|
import electrosphere.entity.state.AnimationPriorities;
|
|
import electrosphere.entity.types.creature.CreatureUtils;
|
|
import electrosphere.game.data.creature.type.CreatureType;
|
|
import electrosphere.game.data.creature.type.HealthSystem;
|
|
import electrosphere.net.parser.net.message.CharacterMessage;
|
|
import electrosphere.net.parser.net.message.EntityMessage;
|
|
import electrosphere.renderer.actor.Actor;
|
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
|
|
|
/**
|
|
* The status of the life value of a given entity
|
|
*/
|
|
public class LifeState implements BehaviorTree {
|
|
|
|
|
|
public static enum LifeStateEnum {
|
|
ALIVE,
|
|
DYING,
|
|
DEAD,
|
|
}
|
|
|
|
LifeStateEnum state = LifeStateEnum.ALIVE;
|
|
|
|
Entity parent;
|
|
|
|
boolean isInvincible;
|
|
int lifeCurrent;
|
|
int lifeMax;
|
|
int iFrameMaxCount;
|
|
int iFrameCurrent;
|
|
|
|
int deathFrameCurrent = -1;
|
|
|
|
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
|
|
|
public LifeState(Entity parent, HealthSystem system){
|
|
this.parent = parent;
|
|
isInvincible = false;
|
|
lifeMax = system.getMaxHealth();
|
|
lifeCurrent = lifeMax;
|
|
iFrameMaxCount = system.getOnDamageIFrames();
|
|
iFrameCurrent = 0;
|
|
}
|
|
|
|
public LifeState(Entity parent, boolean isInvincible, int lifeCurrent, int lifeMax, int iFrameMaxCount) {
|
|
this.parent = parent;
|
|
this.isInvincible = isInvincible;
|
|
this.lifeCurrent = lifeCurrent;
|
|
this.lifeMax = lifeMax;
|
|
this.iFrameMaxCount = iFrameMaxCount;
|
|
}
|
|
|
|
public boolean isIsAlive() {
|
|
return state == LifeStateEnum.ALIVE;
|
|
}
|
|
|
|
public boolean isIsInvincible() {
|
|
return isInvincible;
|
|
}
|
|
|
|
public int getLifeCurrent() {
|
|
return lifeCurrent;
|
|
}
|
|
|
|
public int getLifeMax() {
|
|
return lifeMax;
|
|
}
|
|
|
|
public void setState(LifeStateEnum state) {
|
|
this.state = state;
|
|
}
|
|
|
|
public void setIsInvincible(boolean isInvincible) {
|
|
this.isInvincible = isInvincible;
|
|
}
|
|
|
|
public void setLifeCurrent(int lifeCurrent) {
|
|
this.lifeCurrent = lifeCurrent;
|
|
}
|
|
|
|
public void setLifeMax(int lifeMax) {
|
|
this.lifeMax = lifeMax;
|
|
}
|
|
|
|
public int getiFrameMaxCount() {
|
|
return iFrameMaxCount;
|
|
}
|
|
|
|
public int getiFrameCurrent() {
|
|
return iFrameCurrent;
|
|
}
|
|
|
|
public void setiFrameMaxCount(int iFrameMaxCount) {
|
|
this.iFrameMaxCount = iFrameMaxCount;
|
|
}
|
|
|
|
public void setiFrameCurrent(int iFrameCurrent) {
|
|
this.iFrameCurrent = iFrameCurrent;
|
|
}
|
|
|
|
public void damage(int damage){
|
|
if(!isInvincible){
|
|
lifeCurrent = lifeCurrent - damage;
|
|
isInvincible = true;
|
|
if(lifeCurrent < 0){
|
|
lifeCurrent = 0;
|
|
if(Globals.RUN_SERVER){
|
|
state = LifeStateEnum.DYING;
|
|
Vector3d position = EntityUtils.getPosition(parent);
|
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
|
EntityMessage.constructKillMessage(
|
|
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
|
parent.getId()
|
|
)
|
|
);
|
|
}
|
|
} else {
|
|
iFrameCurrent = iFrameMaxCount;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void revive(){
|
|
state = LifeStateEnum.ALIVE;
|
|
isInvincible = false;
|
|
lifeCurrent = lifeMax;
|
|
}
|
|
|
|
public void simulate(float deltaTime){
|
|
for(EntityMessage message : networkMessageQueue){
|
|
networkMessageQueue.remove(message);
|
|
long updateTime = message.gettime();
|
|
switch(message.getMessageSubtype()){
|
|
case KILL:
|
|
//start death
|
|
if(Globals.RUN_CLIENT){
|
|
state = LifeStateEnum.DYING;
|
|
lifeCurrent = 0;
|
|
int frameskip = (int)(Globals.timekeeper.getNumberOfSimFramesElapsed() - message.gettime());
|
|
deathFrameCurrent = frameskip;
|
|
}
|
|
break;
|
|
default:
|
|
//silently ignore
|
|
break;
|
|
}
|
|
}
|
|
switch(state){
|
|
case ALIVE:
|
|
if(iFrameCurrent > 0){
|
|
iFrameCurrent--;
|
|
if(iFrameCurrent == 0){
|
|
isInvincible = false;
|
|
}
|
|
}
|
|
break;
|
|
case DYING:
|
|
CreatureType creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(parent));
|
|
if(deathFrameCurrent > creatureType.getHealthSystem().getDeathFrames()){
|
|
state = LifeStateEnum.DEAD;
|
|
}
|
|
Actor entityActor = EntityUtils.getActor(parent);
|
|
if(entityActor != null){
|
|
String animationToPlay = creatureType.getHealthSystem().getDeathAnimation();
|
|
if(
|
|
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay)
|
|
){
|
|
entityActor.playAnimation(animationToPlay,AnimationPriorities.DEATH);
|
|
entityActor.incrementAnimationTime(0.0001);
|
|
}
|
|
}
|
|
break;
|
|
case DEAD:
|
|
if(Globals.RUN_CLIENT && parent == Globals.playerEntity){
|
|
if(!Globals.RUN_SERVER){
|
|
//destroy current (client) world stuff
|
|
//only if not also running server
|
|
}
|
|
//submit respawn request
|
|
Globals.clientConnection.queueOutgoingMessage(
|
|
CharacterMessage.constructRequestSpawnCharacterMessage()
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void addNetworkMessage(EntityMessage networkMessage) {
|
|
networkMessageQueue.add(networkMessage);
|
|
}
|
|
|
|
}
|