void Entity_Damage(ServerEntity_t *seEntity, ServerEntity_t *seInflictor, int iDamage, DamageType_t dtType) { // Don't bother if there's no actual damage inflicted. if (iDamage <= 0) return; // Only continue if we can damage the entity. if (!Entity_CanDamage(seInflictor, seEntity, dtType)) return; // If it's a monster or player, hand it over to the monster code. if (Entity_IsMonster(seEntity) || Entity_IsPlayer(seEntity)) { Monster_Damage(seEntity, seInflictor, iDamage, dtType); return; } // Otherwise we'll do our own thing here... seEntity->v.iHealth -= iDamage; if (seEntity->v.iHealth <= 0) { if (seEntity->local.KilledFunction) seEntity->local.KilledFunction(seEntity, seInflictor); return; } if (seEntity->local.DamagedFunction) seEntity->local.DamagedFunction(seEntity, seInflictor); }
void MONSTER_Damage(edict_t *target,edict_t *inflictor,int iDamage, int iDamageType) { /* TODO If the new inflicted damage is greater than the last amount, we're a monster and the attacker is client (or other) then we should change our target to this other entity as it's most likely more dangerous! Suggested that amount of damage should multiply on each call and then slowly decrease after sometime. */ if(!target->v.bTakeDamage || (target->v.flags & FL_GODMODE) || !Entity_CanDamage(inflictor, target, iDamageType)) return; // [28/8/2012] Blood is now handled here :) ~hogsy if(target->local.bBleed) { char cBlood[6]; PARTICLE_BLOOD(cBlood); Engine.Particle(target->v.origin,target->v.velocity,10.0f,cBlood,20); } // [3/10/2012] Only do this for clients ~hogsy if(Entity_IsPlayer(inflictor)) { #ifdef GAME_OPENKATANA if(inflictor->local.power_finished > Server.dTime) iDamage *= 3; #endif // [3/10/2012] Half the amount of damage we can inflict in hard ~hogsy // [15/11/2012] Removed vita check here... Vita should not be acting like armor! ~hogsy if(cvServerSkill.value >= 3) iDamage /= 2; } else if(Entity_IsMonster(inflictor)) { // [3/10/2012] Double if we're a monster ~hogsy if(cvServerSkill.value >= 3) iDamage *= 2; } if(Entity_IsMonster(target)) // [27/4/2014] Automatically wake us up if asleep ~hogsy if(target->monster.iState == STATE_ASLEEP) Monster_SetState(target,STATE_AWAKE); target->v.iHealth -= iDamage; if(target->v.iHealth <= 0) Monster_Killed(target,inflictor); else if(target->monster.think_pain) target->monster.think_pain(target,inflictor); }
/* Damage entities within a specific radius. */ void Entity_RadiusDamage(edict_t *eInflictor,float fRadius,int iDamage,int iDamageType) { int i; float fDistance; vec3_t vOrigin; edict_t *eTarget = Engine.Server_FindRadius(eInflictor->v.origin,fRadius); Engine.WriteByte(MSG_BROADCAST,SVC_TEMPENTITY); Engine.WriteByte(MSG_BROADCAST,CTE_EXPLOSION); for(i = 0; i < 3; i++) Engine.WriteCoord(MSG_BROADCAST,eInflictor->v.origin[i]); do { if(eTarget->v.bTakeDamage) { int i; for(i = 0; i < 3; i++) vOrigin[i] = eTarget->v.origin[i]+(eTarget->v.mins[i]+eTarget->v.maxs[i])*0.5f; Math_VectorSubtract(eInflictor->v.origin,vOrigin,vOrigin); fDistance = 0.5f*(float)Math_VectorLength(vOrigin); if(fDistance > 0) { Math_VectorInverse(vOrigin); Math_VectorAdd(eTarget->v.velocity,vOrigin,eTarget->v.velocity); // [15/7/2013] Reduce the damage by distance ~hogsy fDistance = (float)iDamage-(100.0f/fDistance); // [15/8/2013] Less damage for the inflictor ~hogsy if(eTarget == eInflictor) fDistance = fDistance/2.0f; if(fDistance > 0) if(Entity_CanDamage(eInflictor,eTarget, iDamageType)) MONSTER_Damage(eTarget,eInflictor,(int)fDistance,iDamageType); } } eTarget = eTarget->v.chain; } while(eTarget); }