Renderer/src/main/java/electrosphere/entity/state/life/LifeState.java
austin 57f2befc0e
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
animation/attachment bugfix
2024-07-26 23:12:19 -04:00

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);
}
}