updated regen system
This commit is contained in:
@@ -5599,6 +5599,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public void resetRegenUpdateTime() {
|
public void resetRegenUpdateTime() {
|
||||||
this.lastUpdateTime = System.currentTimeMillis();
|
this.lastUpdateTime = System.currentTimeMillis();
|
||||||
this.lastStamUpdateTime = System.currentTimeMillis();
|
this.lastStamUpdateTime = System.currentTimeMillis();
|
||||||
|
this.timestamps.put("LastRegenHealth", System.currentTimeMillis());
|
||||||
|
this.timestamps.put("LastRegenMana", System.currentTimeMillis());
|
||||||
|
this.timestamps.put("LastRegenStamina", System.currentTimeMillis());
|
||||||
|
this.timestamps.put("LastConsumeStamina", System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCharacterHeight() {
|
public float getCharacterHeight() {
|
||||||
@@ -5690,211 +5694,6 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
dirtyLock.writeLock().unlock();
|
dirtyLock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunRegen(){
|
|
||||||
|
|
||||||
float healthRegen = 0f;
|
|
||||||
float manaRegen = 0f;
|
|
||||||
float stamRegen = 0f;
|
|
||||||
|
|
||||||
boolean updateClient = false;
|
|
||||||
|
|
||||||
// Early exit if char is dead or disconnected
|
|
||||||
if ((this.isAlive() == false)
|
|
||||||
|| (this.isActive() == false) || this.getLoc().x == 0 && this.getLoc().z == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Calculate Regen amount from last simulation tick
|
|
||||||
switch (this.movementState) {
|
|
||||||
|
|
||||||
case IDLE:
|
|
||||||
|
|
||||||
healthRegen = ((this.healthMax * MBServerStatics.HEALTH_REGEN_IDLE) + MBServerStatics.HEALTH_REGEN_IDLE_STATIC) * (getRegenModifier(ModType.HealthRecoverRate));
|
|
||||||
|
|
||||||
if (this.isCasting() || this.isItemCasting())
|
|
||||||
healthRegen *= .75f;
|
|
||||||
// Characters regen mana when in only walk mode and idle
|
|
||||||
if (this.walkMode)
|
|
||||||
manaRegen = (this.manaMax * 0.01f) * getRegenModifier(ModType.ManaRecoverRate) * MBServerStatics.MANA_REGEN_WALK;
|
|
||||||
else {
|
|
||||||
manaRegen = (this.manaMax * 0.01f) * getRegenModifier(ModType.ManaRecoverRate) * MBServerStatics.MANA_REGEN_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PlayerCharacter.CanBreathe(this))
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_SWIM;
|
|
||||||
else if ((!this.isCasting() && !this.isItemCasting()) || this.lastMovementState.equals(MovementState.FLYING))
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_IDLE * getRegenModifier(ModType.StaminaRecoverRate);
|
|
||||||
else
|
|
||||||
stamRegen = 0;
|
|
||||||
break;
|
|
||||||
case SITTING:
|
|
||||||
healthRegen = ((this.healthMax * MBServerStatics.HEALTH_REGEN_SIT) + MBServerStatics.HEALTH_REGEN_SIT_STATIC) * getRegenModifier(ModType.HealthRecoverRate);
|
|
||||||
manaRegen = (this.manaMax * MBServerStatics.MANA_REGEN_SIT) * (getRegenModifier(ModType.ManaRecoverRate));
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_SIT * getRegenModifier(ModType.StaminaRecoverRate);
|
|
||||||
break;
|
|
||||||
case RUNNING:
|
|
||||||
if (this.walkMode == true) {
|
|
||||||
healthRegen = ((this.healthMax * MBServerStatics.HEALTH_REGEN_WALK) + MBServerStatics.HEALTH_REGEN_IDLE_STATIC) * getRegenModifier(ModType.HealthRecoverRate);
|
|
||||||
manaRegen = this.manaMax * MBServerStatics.MANA_REGEN_WALK * getRegenModifier(ModType.ManaRecoverRate);
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_WALK;
|
|
||||||
} else {
|
|
||||||
healthRegen = 0;
|
|
||||||
manaRegen = 0;
|
|
||||||
|
|
||||||
if (this.combat == true)
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_RUN_COMBAT;
|
|
||||||
else
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_RUN_NONCOMBAT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FLYING:
|
|
||||||
|
|
||||||
float seventyFive = this.staminaMax * .75f;
|
|
||||||
float fifty = this.staminaMax * .5f;
|
|
||||||
float twentyFive = this.staminaMax * .25f;
|
|
||||||
|
|
||||||
if (this.getDesiredAltitude() == 0 && this.getAltitude() <= 10) {
|
|
||||||
if (this.isCombat())
|
|
||||||
stamRegen = 0;
|
|
||||||
else
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_IDLE * getRegenModifier(ModType.StaminaRecoverRate);
|
|
||||||
} else if (!this.useFlyMoveRegen()) {
|
|
||||||
|
|
||||||
healthRegen = ((this.healthMax * MBServerStatics.HEALTH_REGEN_IDLE) + MBServerStatics.HEALTH_REGEN_IDLE_STATIC) * (getRegenModifier(ModType.HealthRecoverRate));
|
|
||||||
|
|
||||||
if (this.isCasting() || this.isItemCasting())
|
|
||||||
healthRegen *= .75f;
|
|
||||||
// Characters regen mana when in only walk mode and idle
|
|
||||||
if (this.walkMode)
|
|
||||||
manaRegen = (this.manaMax * MBServerStatics.MANA_REGEN_IDLE + (this.getSpiMod() * .015f)) * (getRegenModifier(ModType.ManaRecoverRate));
|
|
||||||
else if (!this.isCasting() && !this.isItemCasting())
|
|
||||||
manaRegen = (this.manaMax * MBServerStatics.MANA_REGEN_IDLE + (this.getSpiMod() * .015f)) * (getRegenModifier(ModType.ManaRecoverRate));
|
|
||||||
else
|
|
||||||
manaRegen = 0;
|
|
||||||
|
|
||||||
if (!this.isItemCasting() && !this.isCasting() || this.getTakeOffTime() != 0)
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_FLY_IDLE;
|
|
||||||
else
|
|
||||||
stamRegen = -1f;
|
|
||||||
} else if (this.walkMode == true) {
|
|
||||||
healthRegen = ((this.healthMax * MBServerStatics.HEALTH_REGEN_WALK) + MBServerStatics.HEALTH_REGEN_IDLE_STATIC) * getRegenModifier(ModType.HealthRecoverRate);
|
|
||||||
manaRegen = ((this.manaMax * MBServerStatics.MANA_REGEN_WALK) + (this.getSpiMod() * .015f)) * (getRegenModifier(ModType.ManaRecoverRate));
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_FLY_WALK;
|
|
||||||
} else {
|
|
||||||
healthRegen = 0;
|
|
||||||
manaRegen = 0;
|
|
||||||
if (this.isCombat())
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_FLY_RUN_COMBAT;
|
|
||||||
else
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_FLY_RUN;
|
|
||||||
}
|
|
||||||
|
|
||||||
float oldStamina = this.stamina.get();
|
|
||||||
|
|
||||||
if (FastMath.between(oldStamina, 0, twentyFive) && !this.wasTripped25) {
|
|
||||||
updateClient = true;
|
|
||||||
this.wasTripped25 = true;
|
|
||||||
this.wasTripped50 = false;
|
|
||||||
this.wasTripped75 = false;
|
|
||||||
} else if (FastMath.between(oldStamina, twentyFive, fifty) && !this.wasTripped50) {
|
|
||||||
updateClient = true;
|
|
||||||
this.wasTripped25 = false;
|
|
||||||
this.wasTripped50 = true;
|
|
||||||
this.wasTripped75 = false;
|
|
||||||
} else if (FastMath.between(oldStamina, fifty, seventyFive) && !this.wasTripped75) {
|
|
||||||
updateClient = true;
|
|
||||||
this.wasTripped25 = false;
|
|
||||||
this.wasTripped50 = false;
|
|
||||||
this.wasTripped75 = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SWIMMING:
|
|
||||||
if (this.walkMode == true) {
|
|
||||||
healthRegen = ((this.healthMax * MBServerStatics.HEALTH_REGEN_WALK) + MBServerStatics.HEALTH_REGEN_IDLE_STATIC) * getRegenModifier(ModType.HealthRecoverRate);
|
|
||||||
manaRegen = ((this.manaMax * MBServerStatics.MANA_REGEN_WALK) + (this.getSpiMod() * .015f)) * (getRegenModifier(ModType.ManaRecoverRate));
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_SWIM;
|
|
||||||
} else {
|
|
||||||
healthRegen = 0;
|
|
||||||
manaRegen = 0;
|
|
||||||
stamRegen = MBServerStatics.STAMINA_REGEN_SWIM;
|
|
||||||
|
|
||||||
if (this.combat == true)
|
|
||||||
stamRegen += MBServerStatics.STAMINA_REGEN_RUN_COMBAT;
|
|
||||||
else
|
|
||||||
stamRegen += MBServerStatics.STAMINA_REGEN_RUN_NONCOMBAT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Are we drowning?
|
|
||||||
if ((this.getStamina() <= 0)
|
|
||||||
&& (PlayerCharacter.CanBreathe(this) == false))
|
|
||||||
healthRegen = (this.healthMax * -.03f);
|
|
||||||
|
|
||||||
// Multiple regen values by current deltaTime
|
|
||||||
// Logger.info("", healthRegen + "");
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
Long regenTime;
|
|
||||||
if(this.timestamps.containsKey("LastRegen"))
|
|
||||||
regenTime = this.timestamps.get("LastRegen");
|
|
||||||
else
|
|
||||||
regenTime = currentTime;
|
|
||||||
float secondsPassed = (currentTime - regenTime) / 1000f;
|
|
||||||
healthRegen *= secondsPassed;
|
|
||||||
manaRegen *= secondsPassed;
|
|
||||||
stamRegen *= secondsPassed;
|
|
||||||
|
|
||||||
this.timestamps.put("LastRegen",currentTime);
|
|
||||||
|
|
||||||
//ChatManager.chatSystemInfo(this,"Mana: " + this.mana.get());
|
|
||||||
|
|
||||||
boolean workedHealth = false;
|
|
||||||
boolean workedMana = false;
|
|
||||||
boolean workedStamina = false;
|
|
||||||
|
|
||||||
float old, mod;
|
|
||||||
while (!workedHealth || !workedMana || !workedStamina) {
|
|
||||||
if (!this.isAlive() || !this.isActive())
|
|
||||||
return;
|
|
||||||
if (!workedHealth) {
|
|
||||||
old = this.health.get();
|
|
||||||
mod = old + healthRegen;
|
|
||||||
if (mod > this.healthMax)
|
|
||||||
mod = healthMax;
|
|
||||||
else if (mod <= 0) {
|
|
||||||
if (this.isAlive.compareAndSet(true, false))
|
|
||||||
killCharacter("Water");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
workedHealth = this.health.compareAndSet(old, mod);
|
|
||||||
}
|
|
||||||
if (!workedStamina) {
|
|
||||||
old = this.stamina.get();
|
|
||||||
mod = old + stamRegen;
|
|
||||||
if (mod > this.staminaMax)
|
|
||||||
mod = staminaMax;
|
|
||||||
else if (mod < 0)
|
|
||||||
mod = 0;
|
|
||||||
workedStamina = this.stamina.compareAndSet(old, mod);
|
|
||||||
}
|
|
||||||
if (!workedMana) {
|
|
||||||
old = this.mana.get();
|
|
||||||
mod = old + manaRegen;
|
|
||||||
if (mod > this.manaMax)
|
|
||||||
mod = manaMax;
|
|
||||||
else if (mod < 0)
|
|
||||||
mod = 0;
|
|
||||||
workedMana = this.mana.compareAndSet(old, mod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateClient)
|
|
||||||
this.syncClient();
|
|
||||||
|
|
||||||
// Reset this char's frame time.
|
|
||||||
this.lastUpdateTime = System.currentTimeMillis();
|
|
||||||
this.lastStamUpdateTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getRegenRate(PlayerCharacter player, ModType type){
|
public static float getRegenRate(PlayerCharacter player, ModType type){
|
||||||
float regenRate = player.getRegenModifier(type);
|
float regenRate = player.getRegenModifier(type);
|
||||||
|
|
||||||
@@ -6064,4 +5863,156 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void doRegen(){
|
||||||
|
if (this.updateLock.writeLock().tryLock()) {
|
||||||
|
try {
|
||||||
|
regenerateHealth();
|
||||||
|
regenerateMana();
|
||||||
|
regenerateStamina();
|
||||||
|
consumeStamina();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(e);
|
||||||
|
} finally {
|
||||||
|
this.updateLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void regenerateHealth(){
|
||||||
|
Long regenTime;
|
||||||
|
Long currentTime = System.currentTimeMillis();
|
||||||
|
regenTime = this.timestamps.getOrDefault("LastRegenHealth", currentTime);
|
||||||
|
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||||
|
float onePercent = this.healthMax * 0.01f;
|
||||||
|
float rate = RecoveryType.getRecoveryType(this).healthRate;
|
||||||
|
rate *= this.getRegenModifier(ModType.HealthRecoverRate);
|
||||||
|
|
||||||
|
float healthRegenerated = onePercent * secondsPassed * rate;
|
||||||
|
|
||||||
|
boolean workedHealth = false;
|
||||||
|
float old,mod;
|
||||||
|
while(!workedHealth) {
|
||||||
|
old = this.health.get();
|
||||||
|
mod = old + healthRegenerated;
|
||||||
|
if (mod > this.healthMax)
|
||||||
|
mod = healthMax;
|
||||||
|
else if (mod <= 0) {
|
||||||
|
if (this.isAlive.compareAndSet(true, false))
|
||||||
|
killCharacter("Water");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
workedHealth = this.health.compareAndSet(old, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.timestamps.put("LastRegenHealth",currentTime);
|
||||||
|
}
|
||||||
|
public void regenerateMana(){
|
||||||
|
Long regenTime;
|
||||||
|
Long currentTime = System.currentTimeMillis();
|
||||||
|
regenTime = this.timestamps.getOrDefault("LastRegenMana", currentTime);
|
||||||
|
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||||
|
float onePercent = this.manaMax * 0.01f;
|
||||||
|
float rate = RecoveryType.getRecoveryType(this).manaRate;
|
||||||
|
rate *= this.getRegenModifier(ModType.ManaRecoverRate);
|
||||||
|
|
||||||
|
float manaRegenerated = onePercent * secondsPassed * rate;
|
||||||
|
|
||||||
|
boolean workedMana = false;
|
||||||
|
float old,mod;
|
||||||
|
while(!workedMana) {
|
||||||
|
old = this.mana.get();
|
||||||
|
mod = old + manaRegenerated;
|
||||||
|
if (mod > this.manaMax)
|
||||||
|
mod = manaMax;
|
||||||
|
else if (mod < 0)
|
||||||
|
mod = 0;
|
||||||
|
workedMana = this.mana.compareAndSet(old, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.timestamps.put("LastRegenMana",currentTime);
|
||||||
|
}
|
||||||
|
public void regenerateStamina(){
|
||||||
|
Long regenTime;
|
||||||
|
Long currentTime = System.currentTimeMillis();
|
||||||
|
regenTime = this.timestamps.getOrDefault("LastRegenStamina", currentTime);
|
||||||
|
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||||
|
|
||||||
|
float rate = RecoveryType.getRecoveryType(this).staminaRate;
|
||||||
|
rate *= this.getRegenModifier(ModType.StaminaRecoverRate); // Adjust rate with modifiers
|
||||||
|
|
||||||
|
float staminaRegenerated = secondsPassed / rate; // Stamina regenerates 1 point per `rate` seconds
|
||||||
|
|
||||||
|
boolean workedStamina = false;
|
||||||
|
float old, mod;
|
||||||
|
while (!workedStamina) {
|
||||||
|
old = this.stamina.get();
|
||||||
|
mod = old + staminaRegenerated;
|
||||||
|
if (mod > this.staminaMax)
|
||||||
|
mod = staminaMax;
|
||||||
|
else if (mod < 0)
|
||||||
|
mod = 0;
|
||||||
|
workedStamina = this.stamina.compareAndSet(old, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.timestamps.put("LastRegenStamina", currentTime);
|
||||||
|
}
|
||||||
|
public void consumeStamina(){
|
||||||
|
Long regenTime;
|
||||||
|
Long currentTime = System.currentTimeMillis();
|
||||||
|
regenTime = this.timestamps.getOrDefault("LastConsumeStamina", currentTime);
|
||||||
|
float secondsPassed = (currentTime - regenTime) / 1000f;
|
||||||
|
|
||||||
|
float consumption;
|
||||||
|
if(!this.isMoving() && !this.isFlying())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!this.combat){
|
||||||
|
consumption = 0.4f * secondsPassed;
|
||||||
|
}else{
|
||||||
|
consumption = 0.65f * secondsPassed;
|
||||||
|
}
|
||||||
|
if(!this.canBreathe || this.isFlying())
|
||||||
|
consumption *= 2;
|
||||||
|
|
||||||
|
boolean workedStamina = false;
|
||||||
|
float old,mod;
|
||||||
|
while (!workedStamina) {
|
||||||
|
old = this.stamina.get();
|
||||||
|
mod = old - consumption;
|
||||||
|
if (mod <= 0)
|
||||||
|
mod = 0;
|
||||||
|
workedStamina = this.stamina.compareAndSet(old, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RecoveryType{
|
||||||
|
//Values for health and mana are in terms of the number of seconds it takes to recover 1% of max pool
|
||||||
|
//Values for stamina are in terms of the number of seconds it takes to recover 1 point
|
||||||
|
RESTING(3.0f,1.2f,0.5f), //sitting
|
||||||
|
IDLING(15.0f,6.0f,5.0f), //standing not moving
|
||||||
|
WALKING(20.0f,8.0f,0.0f), // moving in walk mode
|
||||||
|
RUNNING(0.0f,0.0f,0.0f); // moving in run mode
|
||||||
|
public float healthRate;
|
||||||
|
public float manaRate;
|
||||||
|
public float staminaRate;
|
||||||
|
RecoveryType(float health, float mana, float stamina) {
|
||||||
|
this.healthRate = health;
|
||||||
|
this.manaRate = mana;
|
||||||
|
this.staminaRate = stamina;
|
||||||
|
}
|
||||||
|
public static RecoveryType getRecoveryType(PlayerCharacter pc){
|
||||||
|
if (pc.isMoving()) {
|
||||||
|
if(pc.walkMode){
|
||||||
|
return RecoveryType.WALKING;
|
||||||
|
}else{
|
||||||
|
return RecoveryType.RUNNING;
|
||||||
|
}
|
||||||
|
}else if(pc.isSit()){
|
||||||
|
return RecoveryType.RESTING;
|
||||||
|
}else{
|
||||||
|
return RecoveryType.IDLING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class UpdateThread implements Runnable {
|
|||||||
try {
|
try {
|
||||||
for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()){
|
for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()){
|
||||||
//player.update(true);
|
//player.update(true);
|
||||||
player.regenerate();
|
player.doRegen();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.error("UPDATE ERROR");
|
Logger.error("UPDATE ERROR");
|
||||||
|
|||||||
Reference in New Issue
Block a user