sources » ObjectClass » ReceiveDamage
/*
* eDamageState values:
* 0 dsUnaffected - not affected (100% health)
* 1 dsUnchanged - didn't change state
* 2 dsNowYellow - changed to yellow (only if was in green, otherwise remains unchanged)
* 3 dsNowRed - changed to red
* 4 dsDeath - changed to dead, Health = 0
* 5 dsPostMortem - dead, just cleaning up
*/
eDamageState ObjectClass::ReceiveDamage(int &damage, int unknown, WarheadTypeClass *WH, TechnoClass *attacker, bool ignoreDefenses, int arg10, HouseClass *attackerHouse) {
eDamageState TransitionState = dsUnaffected;
int preDmgHealth = this->Health;
if( preDmgHealth <= 0 )
return TransitionState;
int actualDamage = damage;
if( !damage )
return TransitionState;
if( !ignoreDefenses && this->GetType()->Immune )
return TransitionState;
ObjectTypeClass *objType = this->GetType();
int Strength = objType->Strength;
if ( !ignoreDefenses ) {
TechnoTypeClass *Type = this->GetType();
actualDamage = GetVersedDamage(actualDamage, WH, Type->Armor, unknown);
}
if ( this ) {
if ( this->What_Am_I() == IS_BUILDING ) {
if ( !this->BuildingType->CanC4 ) {
actualDamage = max(actualDamage, 1);
}
}
}
if ( !actualDamage )
return dsUnaffected;
if ( actualDamage >= 0 ) {
TransitionState = dsUnchanged;
if ( preDmgHealth <= realDamage ) {
actualDamage = preDmgHealth;
} else {
if ( preDmgHealth >= Strength / 2 ) {
if ( preDmgHealth - realDamage < strength / 2 )
TransitionState = dsNowYellow;
}
}
if ( preDmgHealth > Rules->ConditionRed ) {
if ( (preDmgHealth - actualDamage) <= Rules->ConditionRed )
tmpTransitionState = dsNowRed;
}
int remainHealth = preDmgHealth - actualDamage;
this->Health = remainHealth;
if ( remainHealth > 0
|| this->What_Am_I() != eInfantry
|| ignoreDefenses
|| !((InfantryClass *)this)->InfantryType
|| this->IsCyborgRespawn ) {
transitionState = tmpTransitionState;
} else { // Cyborg death
new AnimClass(
Rules->InfantryExplode,
this->pos,
0,
1,
sizeof(AnimClass),
0,
0);
int tmpHealth = FloatToInt(this->InfantryType->Strength * 0.25);
this->Health = tmpHealth;
if ( tmpHealth <= 1 )
tmpHealth = 1;
this->Health = tmpHealth;
this->IsCyborgRespawn = 1;
this->PlayAnim(ANIM_CRAWL);
TransitionState = dsNowRed;
}
int preTagHealth = this->Health;
if ( TransitionState == dsNowYellow ) {
if ( source ) {
if ( this->Tag )
this->Tag->RaiseEvent(ekHalfHealth_combatonly, this, blankCoords, 0, NULL);
}
if ( !this->Alive )
return dsPostMortem;
if ( this->Tag )
this->Tag->RaiseEvent(ekHalfHealth_anysource, this, blankCoords, 0, NULL);
}
if ( this->Alive ) {
if ( transitionState == dsNowRed ) {
if ( source ) {
if ( this->Tag )
this->Tag->RaiseEvent(ekQuarterHealth_combatonly, this, blankCoords, 0, NULL);
}
if ( !this->Alive )
return dsPostMortem;
if ( this->Tag )
this->Tag->RaiseEvent(ekQuarterHealth_anysource, this, blankCoords, 0, NULL);
}
if ( this->Alive ) {
if ( this->Health != preDmgHealth ) {
if ( this->vt->GetType() ) {
if ( predmgHealth == this->GetType()->Strength ) {
if ( source ) {
if ( this->Tag )
this->Tag->RaiseEvent(ekFirstDamaged_combatonly, this, blankCoords, 0, NULL);
}
if ( this->Tag ) {
if ( this->Alive )
this->Tag->RaiseEvent(ekFirstDamaged_anysource, this, blankCoords, 0, NULL);
}
if ( this->Tag )
{
if ( !this->Alive )
return dsPostMortem;
if ( source )
this->Tag->RaiseEvent(ekFirstDamaged_anysource, this, blankCoords, 0, source);
}
}
}
}
if ( this->Alive && (preTagHealth <= 0 || this->Health > 0) ) {
unknown = 0;
if ( !this->Health ) {
if ( source )
srcHouse = source->t.OwningPlayer;
if ( House || source && House == srcHouse )
this->RegisterDestruction();
else
this->Techno_E4();
TransitionState = dsNowDead;
this->Object_DC();
}
if ( this->Alive ) {
if ( source ) {
if ( this->Tag ) {
if ( TransitionState != dsNowDead )
this->Tag->RaiseEvent(v30, ekAttackedByAnybody, this, blankCoords, 0, source);
}
}
if ( this->Alive ) {
if ( source ) {
if ( this->Tag ) {
if ( TransitionState != dsNowDead )
this->Tag->RaiseEvent(v31, ekAttackedByHouse, this, blankCoords, 0, source);
}
}
if ( this->Alive ) {
if ( transitionState ) {
if ( this->Selected )
this->vt->SetLayer(LAYER_GROUND);
}
}
}
}
return TransitionState;
}
}
}
return dsPostMortem;
}
int curHealth = this->Health;
this->Health = curHealth - realDamage;
if ( curHealth - realDamage > Strength )
this->Health = Strength;
if ( curHealth != this->Health )
this->BlinkDisguise(7);
return dsUnaffected;
}