Changeset View
Standalone View
binaries/data/mods/public/simulation/components/Health.js
Show First 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | Health.prototype.SetHitpoints = function(value) | ||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging); | let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging); | ||||
if (cmpFogging) | if (cmpFogging) | ||||
cmpFogging.Activate(); | cmpFogging.Activate(); | ||||
let old = this.hitpoints; | let old = this.hitpoints; | ||||
this.hitpoints = Math.max(1, Math.min(this.GetMaxHitpoints(), value)); | this.hitpoints = Math.max(1, Math.min(this.GetMaxHitpoints(), value)); | ||||
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); | let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); | ||||
if (cmpRangeManager) | if (cmpRangeManager) | ||||
cmpRangeManager.SetEntityFlag(this.entity, "injured", this.hitpoints < this.GetMaxHitpoints()); | cmpRangeManager.SetEntityFlag(this.entity, "injured", this.hitpoints < this.GetMaxHitpoints()); | ||||
Stan: This is another example it's fixed in D1770, but maybe the checks should be unified. | |||||
this.RegisterHealthChanged(old); | this.RegisterHealthChanged(old); | ||||
}; | }; | ||||
Health.prototype.IsRepairable = function() | Health.prototype.IsRepairable = function() | ||||
{ | { | ||||
return Engine.QueryInterface(this.entity, IID_Repairable) != null; | return Engine.QueryInterface(this.entity, IID_Repairable) != null; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
Health.prototype.Kill = function() | Health.prototype.Kill = function() | ||||
{ | { | ||||
this.Reduce(this.hitpoints); | this.Reduce(this.hitpoints); | ||||
}; | }; | ||||
/** | /** | ||||
* Reduces entity's health by amount HP. | * Reduces entity's health by amount HP. | ||||
* Returns object of the form { "killed": false, "change": -12 } | * Returns object of the form { "killed": false, "change": -12 } | ||||
Not Done Inline Actions@return {{ "killed": boolean, "change": number }} The new state of the entity. Stan: @return {{ "killed": boolean, "change": number }} The new state of the entity. | |||||
Not Done Inline ActionsActually you can use mine. If your editor is smart it will automatically guess the return type to be an object and offer autosuggestion which is nice :) Stan: Actually you can use mine. If your editor is smart it will automatically guess the return type… | |||||
*/ | */ | ||||
Health.prototype.Reduce = function(amount) | Health.prototype.Reduce = function(amount) | ||||
{ | { | ||||
if (!amount) | |||||
return {"killed": false, "change": 0}; | |||||
// Before changing the value, activate Fogging if necessary to hide changes | // Before changing the value, activate Fogging if necessary to hide changes | ||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging); | let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging); | ||||
if (cmpFogging) | if (cmpFogging) | ||||
Not Done Inline ActionsAre you sure that's not true ? Stan: Are you sure that's not `true` ? | |||||
Done Inline Actionsyes, when you look at current code, killed = true only if entity is killed by taking damage, if it is dead allready, killed is false the reason is that if some entity tries to injure dead entity, it will not get loot and statistics. see CauseDamage in Damage.js Silier: yes, when you look at current code, killed = true only if entity is killed by taking damage, if… | |||||
cmpFogging.Activate(); | cmpFogging.Activate(); | ||||
let state = { "killed": false }; | let state = { "killed": false }; | ||||
if (amount >= 0 && this.hitpoints == this.GetMaxHitpoints()) | let oldHitpoints = this.hitpoints; | ||||
if (amount >= this.hitpoints) | |||||
{ | |||||
Not Done Inline Actions(Just out of curiosity, is the case mentioned in this comment handled?) lyv: (Just out of curiosity, is the case mentioned in this comment handled?) | |||||
Not Done Inline ActionsYes by virtue of the check on the first line. wraitii: Yes by virtue of the check on the first line.
The comment probably should be moved though now. | |||||
Not Done Inline ActionsAh yes, completely missed that line. And yes, the comment would be more helpful up there. lyv: Ah yes, completely missed that line. And yes, the comment would be more helpful up there. | |||||
state.killed = this.DeathCheck(); | |||||
state.change = this.hitpoints - oldHitpoints; | |||||
return state; | |||||
} | |||||
Not Done Inline Actionsappears to be a whittling oddity here wraitii: appears to be a whittling oddity here | |||||
if (this.hitpoints == this.GetMaxHitpoints()) | |||||
{ | { | ||||
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); | let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); | ||||
if (cmpRangeManager) | if (cmpRangeManager) | ||||
Not Done Inline ActionsI feel like this warrants a comment such as "If we were not marked injured, do it now" because it reads weird. wraitii: I feel like this warrants a comment such as "If we were not marked injured, do it now" because… | |||||
Not Done Inline ActionsCouldn't that be (!unitInjured && amount > 0) ? Stan: Couldn't that be (!unitInjured && amount > 0) ? | |||||
Done Inline Actionshitpoints==maxhittpoints means !injured Silier: hitpoints==maxhittpoints means !injured
amount > 0 is guaranteed by first if in function | |||||
Not Done Inline ActionsSince this.GetHitpoints() == this.GetMaxHitpoints() is used in quite a few places, one could make a function called IsInjured() and replace it in the and unify this.hitpoints and this.GetHitpoints calls. Stan: Since this.GetHitpoints() == this.GetMaxHitpoints() is used in quite a few places, one could… | |||||
Not Done Inline ActionsYes that's better than a comment actually. wraitii: Yes that's better than a comment actually. | |||||
cmpRangeManager.SetEntityFlag(this.entity, "injured", true); | cmpRangeManager.SetEntityFlag(this.entity, "injured", true); | ||||
} | } | ||||
let oldHitpoints = this.hitpoints; | |||||
if (amount >= this.hitpoints) | this.hitpoints -= amount; | ||||
this.RegisterHealthChanged(oldHitpoints); | |||||
state.change = this.hitpoints - oldHitpoints; | |||||
return state; | |||||
}; | |||||
/** | |||||
* Checks if unit is alive and kill it | |||||
* Returns true if unit has been killed and false if allready dead | |||||
*/ | |||||
Health.prototype.DeathCheck = function() | |||||
{ | { | ||||
// If this is the first time we reached 0, then die. | // If this is the first time we reached 0, then die. | ||||
// (The entity will exist a little while after calling DestroyEntity so this | // (The entity will exist a little while after calling DestroyEntity so this | ||||
// might get called multiple times) | // might get called multiple times) | ||||
if (this.hitpoints) | if (!this.hitpoints) | ||||
{ | return false; | ||||
let oldHitpoints = this.hitpoints; | |||||
this.hitpoints = 0; | this.hitpoints = 0; | ||||
this.RegisterHealthChanged(oldHitpoints); | this.RegisterHealthChanged(oldHitpoints); | ||||
state.killed = true; | |||||
let cmpDeathDamage = Engine.QueryInterface(this.entity, IID_DeathDamage); | let cmpDeathDamage = Engine.QueryInterface(this.entity, IID_DeathDamage); | ||||
if (cmpDeathDamage) | if (cmpDeathDamage) | ||||
cmpDeathDamage.CauseDeathDamage(); | cmpDeathDamage.CauseDeathDamage(); | ||||
PlaySound("death", this.entity); | PlaySound("death", this.entity); | ||||
if (this.template.SpawnEntityOnDeath) | if (this.template.SpawnEntityOnDeath) | ||||
this.CreateDeathSpawnedEntity(); | this.CreateDeathSpawnedEntity(); | ||||
Not Done Inline ActionsThis will then return null so this can be removed and the above comment amended to "Handle what happens when the entity dies". wraitii: This will then return null so this can be removed and the above comment amended to "Handle what… | |||||
Not Done Inline Actions@return {{ "killed": boolean, "change": number }} The new state of the entity. Stan: @return {{ "killed": boolean, "change": number }} The new state of the entity. | |||||
switch (this.template.DeathType) | switch (this.template.DeathType) | ||||
{ | { | ||||
Not Done Inline ActionsIsDead/IsAlive/ShouldDie/ ? Stan: IsDead/IsAlive/ShouldDie/ ? | |||||
Not Done Inline ActionsHandleDeath rather, as this should only be called when we are actually dying. Reduce() should handle all "checks" such as the hotpoint check. wraitii: HandleDeath rather, as this should only be called when we are actually dying. Reduce() should… | |||||
case "corpse": | case "corpse": | ||||
this.CreateCorpse(); | this.CreateCorpse(); | ||||
break; | break; | ||||
Not Done Inline ActionsLikewise this comment should be moved back to Reduce() wraitii: Likewise this comment should be moved back to Reduce() | |||||
case "remain": | case "remain": | ||||
{ | { | ||||
Not Done Inline Actionsreturn; wraitii: return;
(see below) | |||||
let resource = this.CreateCorpse(true); | let resource = this.CreateCorpse(true); | ||||
if (resource != INVALID_ENTITY) | if (resource != INVALID_ENTITY) | ||||
Engine.PostMessage(this.entity, MT_EntityRenamed, { "entity": this.entity, "newentity": resource }); | Engine.PostMessage(this.entity, MT_EntityRenamed, { "entity": this.entity, "newentity": resource }); | ||||
break; | break; | ||||
Not Done Inline ActionsHandle death in a separate function and return early, add a check for "amount > 0" at the very top - no need to do anything on 0 damage - then move the "injured" change below the death-check. wraitii: Handle death in a separate function and return early, add a check for "amount > 0" at the very… | |||||
} | } | ||||
case "vanish": | case "vanish": | ||||
break; | break; | ||||
default: | default: | ||||
error("Invalid template.DeathType: " + this.template.DeathType); | error("Invalid template.DeathType: " + this.template.DeathType); | ||||
break; | break; | ||||
} | } | ||||
Engine.DestroyEntity(this.entity); | Engine.DestroyEntity(this.entity); | ||||
return true; | |||||
Not Done Inline ActionsMove this back in Reduce(), this function should only handle what happens on death. wraitii: Move this back in Reduce(), this function should only handle what happens on death. | |||||
} | } | ||||
} | |||||
else | |||||
{ | |||||
this.hitpoints -= amount; | |||||
this.RegisterHealthChanged(oldHitpoints); | |||||
} | |||||
state.change = this.hitpoints - oldHitpoints; | |||||
return state; | |||||
}; | |||||
Health.prototype.Increase = function(amount) | Health.prototype.Increase = function(amount) | ||||
{ | { | ||||
// Before changing the value, activate Fogging if necessary to hide changes | // Before changing the value, activate Fogging if necessary to hide changes | ||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging); | let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging); | ||||
if (cmpFogging) | if (cmpFogging) | ||||
cmpFogging.Activate(); | cmpFogging.Activate(); | ||||
if (this.hitpoints == this.GetMaxHitpoints()) | if (this.hitpoints == this.GetMaxHitpoints()) | ||||
return { "old": this.hitpoints, "new": this.hitpoints }; | return { "old": this.hitpoints, "new": this.hitpoints }; | ||||
// If we're already dead, don't allow resurrection | // If we're already dead, don't allow resurrection | ||||
if (this.hitpoints == 0) | if (this.hitpoints == 0) | ||||
return undefined; | return undefined; | ||||
let old = this.hitpoints; | let old = this.hitpoints; | ||||
this.hitpoints = Math.min(this.hitpoints + amount, this.GetMaxHitpoints()); | this.hitpoints = Math.min(this.hitpoints + amount, this.GetMaxHitpoints()); | ||||
if (this.hitpoints == this.GetMaxHitpoints()) | if (this.hitpoints == this.GetMaxHitpoints()) | ||||
Not Done Inline ActionsI guess the weirdness above is fixed here. Unit gets an increase, then cancel. Stan: I guess the weirdness above is fixed here. Unit gets an increase, then cancel. | |||||
{ | { | ||||
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); | let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); | ||||
if (cmpRangeManager) | if (cmpRangeManager) | ||||
cmpRangeManager.SetEntityFlag(this.entity, "injured", false); | cmpRangeManager.SetEntityFlag(this.entity, "injured", false); | ||||
} | } | ||||
this.RegisterHealthChanged(old); | this.RegisterHealthChanged(old); | ||||
▲ Show 20 Lines • Show All 134 Lines • Show Last 20 Lines |
This is another example it's fixed in D1770, but maybe the checks should be unified.