mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +00:00
Implement AI related magic effects (calm, frenzy, rally, demoralize, turn undead)
This commit is contained in:
parent
634a53211c
commit
14b70a3ce6
10 changed files with 81 additions and 30 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue