ef2-sdk/dlls/game/DamageModification.cpp
2003-11-05 00:00:00 +00:00

526 lines
14 KiB
C++

//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/DamageModification.cpp $
// $Revision:: 13 $
// $Date:: 10/10/02 2:39p $
//
// Copyright (C) 1999 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DamageModification.cpp: implementation of the DamageModification class.
//
//////////////////////////////////////////////////////////////////////
#include "_pch_cpp.h"
#include "DamageModification.hpp"
#include "actor.h"
// ------------ DamageModificationSystem -----------------------------
//--------------------------------------------------------------
//
// Name: DamageModificationSystem
// Class: DamageModificationSystem
//
// Description: Constructor / Destructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
DamageModificationSystem::DamageModificationSystem()
{
damageModifiers.ClearObjectList();
}
DamageModificationSystem::~DamageModificationSystem()
{
int i;
for ( i=1; i<=damageModifiers.NumObjects(); i++ )
{
DamageModifier *damMod = damageModifiers.ObjectAt(i);
delete damMod;
}
damageModifiers.FreeObjectList();
}
//--------------------------------------------------------------
//
// Name: AddDamageModifier
// Class: DamageModificationSystem
//
// Description: Adds a new damage modifier to the internal
// list.
//
// Parameters: const str &damagemodtype -- String version of the DamageModifierType
// const str &value -- String value to be determined by the type
// float multiplier -- the multiplier to this damage mod.
//
// Returns: None
//
//--------------------------------------------------------------
void DamageModificationSystem::addDamageModifier( const str &damagemodtype, const str &value, float multiplier,
float chance, float painBaseLine )
{
DamageModifier *newMod = 0;
if ( damagemodtype == "tikiname" )
newMod = new DamageModifierTikiName(TIKI_NAME, value, multiplier, chance, painBaseLine );
else if ( damagemodtype == "name" )
newMod = new DamageModifierName(NAME, value, multiplier, chance, painBaseLine );
else if ( damagemodtype == "group" )
{
int groupVal = atoi(value);
newMod = new DamageModifierGroup(GROUP, groupVal, multiplier, chance, painBaseLine );
}
else if ( damagemodtype == "actortype" )
{
int actortype = Actor::ActorTypeStringToInt(value);
newMod = new DamageModifierActorType(ACTOR_TYPE, actortype, multiplier, chance, painBaseLine );
}
else if ( damagemodtype == "targetname" )
newMod = new DamageModifierTargetName(TARGETNAME, value, multiplier, chance, painBaseLine );
else if ( damagemodtype == "damagetype" )
{
int damagetypeVal = MOD_NameToNum(value);
newMod = new DamageModifierDamageType(GROUP, damagetypeVal, multiplier, chance, painBaseLine );
}
damageModifiers.AddObject(newMod);
}
//--------------------------------------------------------------
//
// Name: AddDamageModifier
// Class: DamageModificationSystem
//
// Description: Directly adds a premade DamageModifier object to the list
// (this is currently only called from archive loading)
//
// Parameters: DamageModifier *newModifier -- Modifier to add to the list
//
// Returns: None
//
//--------------------------------------------------------------
void DamageModificationSystem::addDamageModifier(DamageModifier *newModifier)
{
if ( newModifier )
damageModifiers.AddObject(newModifier);
}
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModificationSystem
//
// Description: The main damage resolving function
//
// Parameters: Damage &damage -- The damage class to resolve
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModificationSystem::resolveDamage(Damage &damage)
{
int i;
for ( i=1; i<=damageModifiers.NumObjects(); i++ )
{
DamageModifier *damageMod = damageModifiers.ObjectAt( i );
damageMod->resolveDamage(damage);
}
damage.showPain = false;
for ( i=1; i<=damageModifiers.NumObjects(); i++ )
{
DamageModifier *damageMod = damageModifiers.ObjectAt( i );
damageMod->resolvePain(damage);
}
}
// ------------ Damage -----------------------------------------
//--------------------------------------------------------------
//
// Name: Damage
// Class: Damage
//
// Description: Constructor / Destructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
Damage::Damage()
{
damage = 0.0f;
inflictor = 0;
attacker = 0;
position = vec_zero;
direction = vec_zero;
normal = vec_zero;
knockback = 0;
dflags = 0;
meansofdeath = -1;
surfaceNumber = -1;
boneNumber = -1;
showPain = false;
weapon = 0;
}
// Constructor that takes the typical damage event as the initializer
Damage::Damage( Event *ev )
{
damage = ev->GetFloat ( 1 );
inflictor = ev->GetEntity ( 2 );
attacker = ev->GetEntity ( 3 );
position = ev->GetVector ( 4 );
direction = ev->GetVector ( 5 );
normal = ev->GetVector ( 6 );
knockback = ev->GetInteger( 7 );
dflags = ev->GetInteger( 8 );
meansofdeath = ev->GetInteger( 9 );
if ( ev->NumArgs() > 9 )
surfaceNumber = ev->GetInteger( 10 );
else
surfaceNumber = -1;
if ( ev->NumArgs() > 10 )
boneNumber = ev->GetInteger( 11 );
else
boneNumber = -1;
if ( ev->NumArgs() > 11 )
weapon = ev->GetEntity( 12 );
else
weapon = 0;
}
Damage::~Damage()
{
}
// ------------ DamageModifierTikiName -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierTikiName
//
// Description: Resolve damage for tiki name type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTikiName::resolveDamage(Damage &damage)
{
if ( damage.attacker->model == _tikiName )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierTikiName
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTikiName::resolvePain(Damage &damage)
{
if ( damage.attacker->model == _tikiName )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
// ------------ DamageModifierName -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierName
//
// Description: Resolve damage for name type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierName::resolveDamage(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->name == _name )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierName
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierName::resolvePain(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->name == _name )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
}
// ------------ DamageModifierGroup -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierGroup
//
// Description: Resolve damage for group type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierGroup::resolveDamage(Damage &damage)
{
if ( damage.attacker->GetGroupID() == _group )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierGroup
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierGroup::resolvePain(Damage &damage)
{
if ( damage.attacker->GetGroupID() == _group )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
// ------------ DamageModifierActorType -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierActorType
//
// Description: Resolve damage for ActorType type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierActorType::resolveDamage(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->actortype == _actortype )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierActorType
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierActorType::resolvePain(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->actortype == _actortype )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
}
// ------------ DamageModifierTargetName -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierTargetName
//
// Description: Resolve damage for TargetName type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTargetName::resolveDamage(Damage &damage)
{
if ( damage.attacker->targetname == _targetname )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierTargetName
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTargetName::resolvePain(Damage &damage)
{
if ( damage.attacker->targetname == _targetname )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
// ------------ DamageModifierDamageType -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierDamageType
//
// Description: Resolve damage for DamageType type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierDamageType::resolveDamage(Damage &damage)
{
if ( damage.meansofdeath == _damagetype )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierDamageType
//
// Description: Resolve pain from this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierDamageType::resolvePain(Damage &damage)
{
if ( damage.meansofdeath == _damagetype )
{
if ( G_Random() <= ( damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}