Commit 14b70a3c authored by scrawl's avatar scrawl

Implement AI related magic effects (calm, frenzy, rally, demoralize, turn undead)

parent 634a5321
......@@ -263,7 +263,7 @@ namespace
static const char *sCreatureTypes[] =
{
"Creature", "Deadra", "Undead", "Humanoid", 0
"Creature", "Daedra", "Undead", "Humanoid", 0
};
static const char *sWeaponTypes[] =
......@@ -342,4 +342,4 @@ std::vector<std::string> CSMWorld::Columns::getEnums (ColumnId column)
}
return enums;
}
\ No newline at end of file
}
......@@ -84,10 +84,10 @@ namespace MWClass
data->mCreatureStats.getAiSequence().fill(ref->mBase->mAiPackage);
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello);
data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Fight, ref->mBase->mAiData.mFight);
data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Flee, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAiSetting (MWMechanics::CreatureStats::AI_Alarm, ref->mBase->mAiData.mAlarm);
// spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
......
......@@ -309,10 +309,10 @@ namespace MWClass
data->mNpcStats.getAiSequence().fill(ref->mBase->mAiPackage);
data->mNpcStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mNpcStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mNpcStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mNpcStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Hello, ref->mBase->mAiData.mHello);
data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Fight, ref->mBase->mAiData.mFight);
data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Flee, ref->mBase->mAiData.mFlee);
data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Alarm, ref->mBase->mAiData.mAlarm);
// spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
......
......@@ -279,7 +279,8 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
case SelectWrapper::Function_AiSetting:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument());
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (
(MWMechanics::CreatureStats::AiSetting)select.getArgument()).getModified();
case SelectWrapper::Function_PcAttribute:
......
......@@ -172,7 +172,7 @@ namespace MWMechanics
float d = sqrt((actorpos.pos[0] - playerpos.pos[0])*(actorpos.pos[0] - playerpos.pos[0])
+(actorpos.pos[1] - playerpos.pos[1])*(actorpos.pos[1] - playerpos.pos[1])
+(actorpos.pos[2] - playerpos.pos[2])*(actorpos.pos[2] - playerpos.pos[2]));
float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(1);
float fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified();
float disp = 100; //creatures don't have disposition, so set it to 100 by default
if(ptr.getTypeName() == typeid(ESM::NPC).name())
{
......@@ -341,6 +341,30 @@ namespace MWMechanics
creatureStats.setDynamic(i, stat);
}
// AI setting modifiers
int creature = !ptr.getClass().isNpc();
if (creature && ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Humanoid)
creature = false;
// Note: the Creature variants only work on normal creatures, not on daedra or undead creatures.
if (!creature || ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Creatures)
{
Stat<int> stat = creatureStats.getAiSetting(CreatureStats::AI_Fight);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::FrenzyHumanoid+creature).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid+creature).mMagnitude);
creatureStats.setAiSetting(CreatureStats::AI_Fight, stat);
stat = creatureStats.getAiSetting(CreatureStats::AI_Flee);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::DemoralizeHumanoid+creature).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::RallyHumanoid+creature).mMagnitude);
creatureStats.setAiSetting(CreatureStats::AI_Flee, stat);
}
if (creature && ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Undead)
{
Stat<int> stat = creatureStats.getAiSetting(CreatureStats::AI_Flee);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::TurnUndead).mMagnitude);
creatureStats.setAiSetting(CreatureStats::AI_Flee, stat);
}
// Apply disintegration (reduces item health)
float disintegrateWeapon = effects.get(ESM::MagicEffect::DisintegrateWeapon).mMagnitude;
if (disintegrateWeapon > 0)
......
......@@ -122,7 +122,7 @@ namespace MWMechanics
return mLevel;
}
int CreatureStats::getAiSetting (int index) const
Stat<int> CreatureStats::getAiSetting (AiSetting index) const
{
assert (index>=0 && index<4);
return mAiSettings[index];
......@@ -240,12 +240,18 @@ namespace MWMechanics
mAttackingOrSpell = attackingOrSpell;
}
void CreatureStats::setAiSetting (int index, int value)
void CreatureStats::setAiSetting (AiSetting index, Stat<int> value)
{
assert (index>=0 && index<4);
mAiSettings[index] = value;
}
void CreatureStats::setAiSetting (AiSetting index, int base)
{
Stat<int> stat(base);
setAiSetting(index, stat);
}
bool CreatureStats::isDead() const
{
return mDead;
......
......@@ -24,7 +24,7 @@ namespace MWMechanics
Spells mSpells;
ActiveSpells mActiveSpells;
MagicEffects mMagicEffects;
int mAiSettings[4];
Stat<int> mAiSettings[4];
AiSequence mAiSequence;
float mLevelHealthBonus;
bool mDead;
......@@ -85,9 +85,6 @@ namespace MWMechanics
int getLevel() const;
int getAiSetting (int index) const;
///< 0: hello, 1 fight, 2 flee, 3 alarm
Spells & getSpells();
ActiveSpells & getActiveSpells();
......@@ -125,8 +122,16 @@ namespace MWMechanics
void setLevel(int level);
void setAiSetting (int index, int value);
///< 0: hello, 1 fight, 2 flee, 3 alarm
enum AiSetting
{
AI_Hello,
AI_Fight,
AI_Flee,
AI_Alarm
};
void setAiSetting (AiSetting index, Stat<int> value);
void setAiSetting (AiSetting index, int base);
Stat<int> getAiSetting (AiSetting index) const;
const AiSequence& getAiSequence() const;
......
......@@ -605,8 +605,12 @@ namespace MWMechanics
{
float s = int(r * fPerDieRollMult * fPerTempMult);
npcStats.setAiSetting (2, std::max(0, std::min(100, npcStats.getAiSetting (2) + int(std::max(iPerMinChange, s)))));
npcStats.setAiSetting (1, std::max(0, std::min(100, npcStats.getAiSetting (1) + int(std::min(-iPerMinChange, -s)))));
int flee = npcStats.getAiSetting(MWMechanics::CreatureStats::AI_Flee).getBase();
int fight = npcStats.getAiSetting(MWMechanics::CreatureStats::AI_Fight).getBase();
npcStats.setAiSetting (MWMechanics::CreatureStats::AI_Flee,
std::max(0, std::min(100, flee + int(std::max(iPerMinChange, s)))));
npcStats.setAiSetting (MWMechanics::CreatureStats::AI_Fight,
std::max(0, std::min(100, fight + int(std::min(-iPerMinChange, -s)))));
}
float c = -std::abs(int(r * fPerDieRollMult));
......@@ -640,8 +644,12 @@ namespace MWMechanics
{
float s = c * fPerDieRollMult * fPerTempMult;
npcStats.setAiSetting (2, std::max(0, std::min(100, npcStats.getAiSetting (2) + std::min(-int(iPerMinChange), int(-s)))));
npcStats.setAiSetting (1, std::max(0, std::min(100, npcStats.getAiSetting (1) + std::max(int(iPerMinChange), int(s)))));
int flee = npcStats.getAiSetting (CreatureStats::AI_Flee).getBase();
int fight = npcStats.getAiSetting (CreatureStats::AI_Fight).getBase();
npcStats.setAiSetting (CreatureStats::AI_Flee,
std::max(0, std::min(100, flee + std::min(-int(iPerMinChange), int(-s)))));
npcStats.setAiSetting (CreatureStats::AI_Fight,
std::max(0, std::min(100, fight + std::max(int(iPerMinChange), int(s)))));
}
x = int(-c * fPerDieRollMult);
......
......@@ -225,7 +225,8 @@ namespace MWScript
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (mIndex));
runtime.push(MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (
(MWMechanics::CreatureStats::AiSetting)mIndex).getModified());
}
};
template<class R>
......@@ -241,8 +242,11 @@ namespace MWScript
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (mIndex,
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (mIndex) + value);
MWMechanics::CreatureStats::AiSetting setting
= MWMechanics::CreatureStats::AiSetting(mIndex);
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (setting,
MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSetting (setting).getBase() + value);
}
};
template<class R>
......@@ -258,8 +262,11 @@ namespace MWScript
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (mIndex,
value);
MWMechanics::CreatureStats::AiSetting setting = (MWMechanics::CreatureStats::AiSetting)mIndex;
MWMechanics::Stat<int> stat = ptr.getClass().getCreatureStats(ptr).getAiSetting(setting);
stat.setModified(value, 0);
ptr.getClass().getCreatureStats(ptr).setAiSetting(setting, stat);
}
};
......
......@@ -40,7 +40,7 @@ struct Creature
enum Type
{
Creatures = 0,
Deadra = 1,
Daedra = 1,
Undead = 2,
Humanoid = 3
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment