From 654cc6bb193e07f9f8ac47854cbb789d04260fb5 Mon Sep 17 00:00:00 2001 From: kuroppoi <68156848+kuroppoi@users.noreply.github.com> Date: Fri, 22 Jul 2022 11:34:54 +0200 Subject: [PATCH] Passive health regeneration --- .../brainwine/gameserver/entity/Entity.java | 20 ++++++++++++++++--- .../brainwine/gameserver/entity/npc/Npc.java | 9 ++++++++- .../gameserver/entity/player/Player.java | 17 ++++++++++++++-- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/gameserver/src/main/java/brainwine/gameserver/entity/Entity.java b/gameserver/src/main/java/brainwine/gameserver/entity/Entity.java index 0473e79..2961a4b 100644 --- a/gameserver/src/main/java/brainwine/gameserver/entity/Entity.java +++ b/gameserver/src/main/java/brainwine/gameserver/entity/Entity.java @@ -12,12 +12,13 @@ import brainwine.gameserver.zone.Zone; public abstract class Entity { + public static final float DEFAULT_HEALTH = 5; public static final float POSITION_MODIFIER = 100F; public static final int VELOCITY_MODIFIER = (int)POSITION_MODIFIER; protected final List trackers = new ArrayList<>(); protected int type; protected String name; - protected float health; + protected float health = getMaxHealth(); protected int id; protected Zone zone; protected float x; @@ -28,10 +29,10 @@ public abstract class Entity { protected int targetY; protected FacingDirection direction = FacingDirection.WEST; protected int animation; + protected long lastDamagedAt; public Entity(Zone zone) { this.zone = zone; - health = 10; // TODO } public void tick(float deltaTime) { @@ -42,6 +43,12 @@ public abstract class Entity { // Override } + public void heal(float amount) { + if(health > 0) { + setHealth(health + amount); + } + } + public void damage(float amount) { damage(amount, null); } @@ -52,6 +59,8 @@ public abstract class Entity { if(health <= 0) { die(attacker); } + + lastDamagedAt = System.currentTimeMillis(); } public boolean canSee(Entity other) { @@ -103,12 +112,17 @@ public abstract class Entity { return name; } + public float getMaxHealth() { + return DEFAULT_HEALTH; + } + public boolean isDead() { return health <= 0; } public void setHealth(float health) { - this.health = health < 0 ? 0 : health; + float maxHealth = getMaxHealth(); + this.health = health < 0 ? 0 : health > maxHealth ? maxHealth : health; } public float getHealth() { diff --git a/gameserver/src/main/java/brainwine/gameserver/entity/npc/Npc.java b/gameserver/src/main/java/brainwine/gameserver/entity/npc/Npc.java index 3fc54e8..ff806ec 100644 --- a/gameserver/src/main/java/brainwine/gameserver/entity/npc/Npc.java +++ b/gameserver/src/main/java/brainwine/gameserver/entity/npc/Npc.java @@ -42,6 +42,7 @@ public class Npc extends Entity { private final SequenceBehavior behaviorTree; private final Vector2i size; private final String typeName; + private final float maxHealth; private final float baseSpeed; private float speed; private int moveX; @@ -98,7 +99,8 @@ public class Npc extends Entity { type = config.getType(); typeName = config.getName(); - health = config.getMaxHealth(); + maxHealth = config.getMaxHealth(); + health = maxHealth; baseSpeed = config.getBaseSpeed(); speed = baseSpeed; size = config.getSize(); @@ -170,6 +172,11 @@ public class Npc extends Entity { } } + @Override + public float getMaxHealth() { + return maxHealth; + } + @Override public Map getStatusConfig() { Map config = super.getStatusConfig(); diff --git a/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java b/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java index 41b9794..7025eb2 100644 --- a/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java +++ b/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java @@ -73,7 +73,9 @@ public class Player extends Entity implements CommandExecutor { public static final int HEARTBEAT_TIMEOUT = 30000; public static final int MAX_AUTH_TOKENS = 3; public static final int TRACKED_ENTITY_UPDATE_INTERVAL = 100; + public static final int REGEN_NO_DAMAGE_TIME = 3000; public static final float ENTITY_VISIBILITY_RANGE = 40; + public static final float BASE_REGEN_AMOUNT = 0.1F; private static int dialogDiscriminator; @JacksonInject("documentId") @@ -151,12 +153,19 @@ public class Player extends Entity implements CommandExecutor { public void tick(float deltaTime) { long now = System.currentTimeMillis(); + // Check timeout if(lastHeartbeat != 0) { if(System.currentTimeMillis() - lastHeartbeat >= HEARTBEAT_TIMEOUT) { kick("Connection timed out."); } } + // Regenerate health out of combat + if(!isDead() && now >= lastDamagedAt + REGEN_NO_DAMAGE_TIME) { + heal(BASE_REGEN_AMOUNT * deltaTime); + } + + // Update tracked entities if(now - lastTrackedEntityUpdate >= TRACKED_ENTITY_UPDATE_INTERVAL) { updateTrackedEntities(); @@ -188,6 +197,11 @@ public class Player extends Entity implements CommandExecutor { return admin; } + @Override + public float getMaxHealth() { + return 10; // TODO + } + @Override public void setHealth(float health) { super.setHealth(health); @@ -411,13 +425,12 @@ public class Player extends Entity implements CommandExecutor { public void respawn() { if(isDead()) { - health = 10; // TODO max health + setHealth(getMaxHealth()); } int x = spawnPoint.getX(); int y = spawnPoint.getY(); sendMessage(new PlayerPositionMessage(x, y)); - sendMessage(new HealthMessage(health)); sendMessageToPeers(new EntityStatusMessage(this, EntityStatus.REVIVED)); zone.sendMessage(new EffectMessage(x, y, "spawn", 20)); }