526 lines
14 KiB
C++
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;
|
|
|
|
}
|
|
}
|