Respawn system

This commit is contained in:
austin 2022-04-27 21:01:35 -04:00
parent 2764522b16
commit 6a3bedf808
5 changed files with 123 additions and 23 deletions

View File

@ -157,6 +157,7 @@
{
"messageName" : "Kill",
"data" : [
"time",
"entityID"
]
},

View File

@ -1,27 +1,46 @@
package electrosphere.entity.state.life;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Vector3d;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.HealthSystem;
import electrosphere.main.Globals;
import electrosphere.main.Main;
import electrosphere.net.parser.net.message.CharacterMessage;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.actor.Actor;
public class LifeState {
public class LifeState implements BehaviorTree {
public static enum LifeStateEnum {
ALIVE,
DYING,
DEAD,
}
LifeStateEnum state = LifeStateEnum.ALIVE;
Entity parent;
boolean isAlive;
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;
isAlive = true;
isInvincible = false;
lifeMax = system.getMaxHealth();
lifeCurrent = lifeMax;
@ -29,9 +48,8 @@ public class LifeState {
iFrameCurrent = 0;
}
public LifeState(Entity parent, boolean isAlive, boolean isInvincible, int lifeCurrent, int lifeMax, int iFrameMaxCount) {
public LifeState(Entity parent, boolean isInvincible, int lifeCurrent, int lifeMax, int iFrameMaxCount) {
this.parent = parent;
this.isAlive = isAlive;
this.isInvincible = isInvincible;
this.lifeCurrent = lifeCurrent;
this.lifeMax = lifeMax;
@ -39,7 +57,7 @@ public class LifeState {
}
public boolean isIsAlive() {
return isAlive;
return state == LifeStateEnum.ALIVE;
}
public boolean isIsInvincible() {
@ -54,8 +72,8 @@ public class LifeState {
return lifeMax;
}
public void setIsAlive(boolean isAlive) {
this.isAlive = isAlive;
public void setState(LifeStateEnum state) {
this.state = state;
}
public void setIsInvincible(boolean isInvincible) {
@ -92,15 +110,16 @@ public class LifeState {
isInvincible = true;
if(lifeCurrent < 0){
lifeCurrent = 0;
isAlive = false;
if(Globals.RUN_SERVER){
state = LifeStateEnum.DYING;
Vector3d position = EntityUtils.getPosition(parent);
Globals.dataCellManager.sendNetworkMessageToChunk(
EntityMessage.constructKillMessage(
parent.getId()
),
Globals.serverWorldData.convertRealToChunkSpace(position.x),
Globals.serverWorldData.convertRealToChunkSpace(position.z)
EntityMessage.constructKillMessage(
Main.getCurrentFrame(),
parent.getId()
),
Globals.serverWorldData.convertRealToChunkSpace(position.x),
Globals.serverWorldData.convertRealToChunkSpace(position.z)
);
}
} else {
@ -110,18 +129,81 @@ public class LifeState {
}
public void revive(){
isAlive = true;
state = LifeStateEnum.ALIVE;
isInvincible = false;
lifeCurrent = lifeMax;
}
public void simulate(){
if(iFrameCurrent > 0){
iFrameCurrent--;
if(iFrameCurrent == 0){
isInvincible = false;
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)(Main.getCurrentFrame() - message.gettime());
deathFrameCurrent = frameskip;
}
break;
case ATTACHENTITYTOENTITY:
case ATTACKUPDATE:
case CREATE:
case DESTROY:
case SETBEHAVIORTREE:
case SETPOSITION:
case SETPROPERTY:
case MOVE:
case SETFACING:
case MOVEUPDATE:
//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,1);
entityActor.incrementAnimationTime(0.01);
}
}
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);
}
}

View File

@ -7,6 +7,8 @@ package electrosphere.game.data.creature.type;
public class HealthSystem {
int maxHealth;
int onDamageIFrames;
int deathFrames;
String deathAnimation;
public int getMaxHealth() {
return maxHealth;
@ -16,10 +18,19 @@ public class HealthSystem {
return onDamageIFrames;
}
public int getDeathFrames(){
return deathFrames;
}
public String getDeathAnimation(){
return deathAnimation;
}
public HealthSystem clone(){
HealthSystem rVal = new HealthSystem();
rVal.maxHealth = maxHealth;
rVal.onDamageIFrames = onDamageIFrames;
rVal.deathFrames = deathFrames;
return rVal;
}

View File

@ -462,12 +462,14 @@ public class EntityMessage extends NetworkMessage {
public static EntityMessage parseKillMessage(List<Byte> byteStream){
EntityMessage rVal = new EntityMessage(EntityMessageType.KILL);
stripPacketHeader(byteStream);
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
return rVal;
}
public static EntityMessage constructKillMessage(int entityID){
public static EntityMessage constructKillMessage(long time,int entityID){
EntityMessage rVal = new EntityMessage(EntityMessageType.KILL);
rVal.settime(time);
rVal.setentityID(entityID);
rVal.serialize();
return rVal;
@ -786,14 +788,18 @@ public class EntityMessage extends NetworkMessage {
}
break;
case KILL:
rawBytes = new byte[2+4];
rawBytes = new byte[2+8+4];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
//entity messaage header
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_KILL;
intValues = ByteStreamUtils.serializeLongToBytes(time);
for(int i = 0; i < 8; i++){
rawBytes[2+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
for(int i = 0; i < 4; i++){
rawBytes[2+i] = intValues[i];
rawBytes[10+i] = intValues[i];
}
break;
case DESTROY:

View File

@ -34,7 +34,7 @@ Message categories
public static final byte ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE = 74;
public static final byte ENTITY_MESSAGE_TYPE_ATTACKUPDATE_SIZE = 74;
public static final byte ENTITY_MESSAGE_TYPE_MOVE_SIZE = 38;
public static final byte ENTITY_MESSAGE_TYPE_KILL_SIZE = 6;
public static final byte ENTITY_MESSAGE_TYPE_KILL_SIZE = 14;
public static final byte ENTITY_MESSAGE_TYPE_DESTROY_SIZE = 6;
public static final byte ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE_SIZE = 22;
public static final byte ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE = 22;