mirror of
https://github.com/TES3MP/TES3MP.git
synced 2025-09-27 23:21:20 -04:00
Merged pull request #1901
This commit is contained in:
commit
78a84042ad
@ -141,6 +141,7 @@
|
|||||||
Task #4605: Optimize skinning
|
Task #4605: Optimize skinning
|
||||||
Task #4606: Support Rapture3D's OpenAL driver
|
Task #4606: Support Rapture3D's OpenAL driver
|
||||||
Task #4613: Incomplete type errors when compiling with g++ on OSX 10.9
|
Task #4613: Incomplete type errors when compiling with g++ on OSX 10.9
|
||||||
|
Task #4621: Optimize combat AI
|
||||||
|
|
||||||
0.44.0
|
0.44.0
|
||||||
------
|
------
|
||||||
|
@ -190,11 +190,6 @@ namespace MWMechanics
|
|||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
{
|
{
|
||||||
std::vector<int> equipmentSlots = it->getClass().getEquipmentSlots(*it).first;
|
|
||||||
if (std::find(equipmentSlots.begin(), equipmentSlots.end(), (int)MWWorld::InventoryStore::Slot_CarriedRight)
|
|
||||||
== equipmentSlots.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
@ -215,14 +210,12 @@ namespace MWMechanics
|
|||||||
|
|
||||||
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||||
{
|
{
|
||||||
const ESM::Spell* spell = it->first;
|
float rating = rateSpell(it->first, actor, enemy);
|
||||||
|
|
||||||
float rating = rateSpell(spell, actor, enemy);
|
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
bestActionRating = rating;
|
bestActionRating = rating;
|
||||||
bestAction.reset(new ActionSpell(spell->mId));
|
bestAction.reset(new ActionSpell(it->first->mId));
|
||||||
antiFleeRating = vanillaRateSpell(spell, actor, enemy);
|
antiFleeRating = vanillaRateSpell(it->first, actor, enemy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,11 +258,6 @@ namespace MWMechanics
|
|||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
{
|
{
|
||||||
std::vector<int> equipmentSlots = it->getClass().getEquipmentSlots(*it).first;
|
|
||||||
if (std::find(equipmentSlots.begin(), equipmentSlots.end(), (int)MWWorld::InventoryStore::Slot_CarriedRight)
|
|
||||||
== equipmentSlots.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
@ -280,9 +268,7 @@ namespace MWMechanics
|
|||||||
|
|
||||||
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||||
{
|
{
|
||||||
const ESM::Spell* spell = it->first;
|
float rating = rateSpell(it->first, actor, enemy);
|
||||||
|
|
||||||
float rating = rateSpell(spell, actor, enemy);
|
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
bestActionRating = rating;
|
bestActionRating = rating;
|
||||||
|
@ -228,7 +228,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||||||
{
|
{
|
||||||
if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break;
|
if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break;
|
||||||
|
|
||||||
MWWorld::Ptr target = static_cast<const AiCombat *>(*it)->getTarget();
|
MWWorld::Ptr target = (*it)->getTarget();
|
||||||
|
|
||||||
// target disappeared (e.g. summoned creatures)
|
// target disappeared (e.g. summoned creatures)
|
||||||
if (target.isEmpty())
|
if (target.isEmpty())
|
||||||
@ -242,11 +242,11 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
|||||||
|
|
||||||
const ESM::Position &targetPos = target.getRefData().getPosition();
|
const ESM::Position &targetPos = target.getRefData().getPosition();
|
||||||
|
|
||||||
float distTo = (targetPos.asVec3() - vActorPos).length();
|
float distTo = (targetPos.asVec3() - vActorPos).length2();
|
||||||
|
|
||||||
// Small threshold for changing target
|
// Small threshold for changing target
|
||||||
if (it == mPackages.begin())
|
if (it == mPackages.begin())
|
||||||
distTo = std::max(0.f, distTo - 50.f);
|
distTo = std::max(0.f, distTo - 2500.f);
|
||||||
|
|
||||||
// if a target has higher priority than current target or has same priority but closer
|
// if a target has higher priority than current target or has same priority but closer
|
||||||
if (rating > bestRating || ((distTo < nearestDist) && rating == bestRating))
|
if (rating > bestRating || ((distTo < nearestDist) && rating == bestRating))
|
||||||
|
@ -34,13 +34,17 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
ESM::Skill::SkillEnum spellSchoolToSkill(int school)
|
ESM::Skill::SkillEnum spellSchoolToSkill(int school)
|
||||||
{
|
{
|
||||||
std::map<int, ESM::Skill::SkillEnum> schoolSkillMap; // maps spell school to skill id
|
static std::map<int, ESM::Skill::SkillEnum> schoolSkillMap; // maps spell school to skill id
|
||||||
schoolSkillMap[0] = ESM::Skill::Alteration;
|
if (schoolSkillMap.empty())
|
||||||
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
{
|
||||||
schoolSkillMap[3] = ESM::Skill::Illusion;
|
schoolSkillMap[0] = ESM::Skill::Alteration;
|
||||||
schoolSkillMap[2] = ESM::Skill::Destruction;
|
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
||||||
schoolSkillMap[4] = ESM::Skill::Mysticism;
|
schoolSkillMap[3] = ESM::Skill::Illusion;
|
||||||
schoolSkillMap[5] = ESM::Skill::Restoration;
|
schoolSkillMap[2] = ESM::Skill::Destruction;
|
||||||
|
schoolSkillMap[4] = ESM::Skill::Mysticism;
|
||||||
|
schoolSkillMap[5] = ESM::Skill::Restoration;
|
||||||
|
}
|
||||||
|
|
||||||
assert(schoolSkillMap.find(school) != schoolSkillMap.end());
|
assert(schoolSkillMap.find(school) != schoolSkillMap.end());
|
||||||
return schoolSkillMap[school];
|
return schoolSkillMap[school];
|
||||||
}
|
}
|
||||||
@ -48,7 +52,11 @@ namespace MWMechanics
|
|||||||
float calcEffectCost(const ESM::ENAMstruct& effect)
|
float calcEffectCost(const ESM::ENAMstruct& effect)
|
||||||
{
|
{
|
||||||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
||||||
|
return calcEffectCost(effect, magicEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect)
|
||||||
|
{
|
||||||
int minMagn = 1;
|
int minMagn = 1;
|
||||||
int maxMagn = 1;
|
int maxMagn = 1;
|
||||||
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <components/esm/effectlist.hpp>
|
#include <components/esm/effectlist.hpp>
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
#include <components/esm/loadmgef.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ namespace MWMechanics
|
|||||||
ESM::Skill::SkillEnum spellSchoolToSkill(int school);
|
ESM::Skill::SkillEnum spellSchoolToSkill(int school);
|
||||||
|
|
||||||
float calcEffectCost(const ESM::ENAMstruct& effect);
|
float calcEffectCost(const ESM::ENAMstruct& effect);
|
||||||
|
float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect);
|
||||||
|
|
||||||
bool isSummoningEffect(int effectId);
|
bool isSummoningEffect(int effectId);
|
||||||
|
|
||||||
|
@ -515,8 +515,6 @@ namespace MWMechanics
|
|||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
|
||||||
|
|
||||||
// Underwater casting not possible
|
// Underwater casting not possible
|
||||||
if (effect.mRange == ESM::RT_Target)
|
if (effect.mRange == ESM::RT_Target)
|
||||||
{
|
{
|
||||||
@ -530,6 +528,7 @@ namespace MWMechanics
|
|||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
||||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful)
|
if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful)
|
||||||
{
|
{
|
||||||
rating *= -1.f;
|
rating *= -1.f;
|
||||||
@ -565,7 +564,7 @@ namespace MWMechanics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rating *= calcEffectCost(effect);
|
rating *= calcEffectCost(effect, magicEffect);
|
||||||
|
|
||||||
// Currently treating all "on target" or "on touch" effects to target the enemy actor.
|
// Currently treating all "on target" or "on touch" effects to target the enemy actor.
|
||||||
// Combat AI is egoistic, so doesn't consider applying positive effects to friendly actors.
|
// Combat AI is egoistic, so doesn't consider applying positive effects to friendly actors.
|
||||||
|
@ -29,6 +29,9 @@ namespace MWMechanics
|
|||||||
if (type != -1 && weapon->mData.mType != type)
|
if (type != -1 && weapon->mData.mType != type)
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
|
if (type == -1 && (weapon->mData.mType == ESM::Weapon::Arrow || weapon->mData.mType == ESM::Weapon::Bolt))
|
||||||
|
return 0.f;
|
||||||
|
|
||||||
float rating=0.f;
|
float rating=0.f;
|
||||||
float rangedMult=1.f;
|
float rangedMult=1.f;
|
||||||
|
|
||||||
|
@ -274,43 +274,46 @@ short MagicEffect::getResistanceEffect(short effect)
|
|||||||
// Source https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attribute
|
// Source https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attribute
|
||||||
|
|
||||||
// <Effect, Effect providing resistance against first effect>
|
// <Effect, Effect providing resistance against first effect>
|
||||||
std::map<short, short> effects;
|
static std::map<short, short> effects;
|
||||||
effects[DisintegrateArmor] = Sanctuary;
|
if (effects.empty())
|
||||||
effects[DisintegrateWeapon] = Sanctuary;
|
|
||||||
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DrainAttribute+i] = ResistMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DamageAttribute+i] = ResistMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[AbsorbAttribute+i] = ResistMagicka;
|
|
||||||
for (int i=0; i<10; ++i)
|
|
||||||
effects[WeaknessToFire+i] = ResistMagicka;
|
|
||||||
|
|
||||||
effects[Burden] = ResistMagicka;
|
|
||||||
effects[Charm] = ResistMagicka;
|
|
||||||
effects[Silence] = ResistMagicka;
|
|
||||||
effects[Blind] = ResistMagicka;
|
|
||||||
effects[Sound] = ResistMagicka;
|
|
||||||
|
|
||||||
for (int i=0; i<2; ++i)
|
|
||||||
{
|
{
|
||||||
effects[CalmHumanoid+i] = ResistMagicka;
|
effects[DisintegrateArmor] = Sanctuary;
|
||||||
effects[FrenzyHumanoid+i] = ResistMagicka;
|
effects[DisintegrateWeapon] = Sanctuary;
|
||||||
effects[DemoralizeHumanoid+i] = ResistMagicka;
|
|
||||||
effects[RallyHumanoid+i] = ResistMagicka;
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[DrainAttribute+i] = ResistMagicka;
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[DamageAttribute+i] = ResistMagicka;
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[AbsorbAttribute+i] = ResistMagicka;
|
||||||
|
for (int i=0; i<10; ++i)
|
||||||
|
effects[WeaknessToFire+i] = ResistMagicka;
|
||||||
|
|
||||||
|
effects[Burden] = ResistMagicka;
|
||||||
|
effects[Charm] = ResistMagicka;
|
||||||
|
effects[Silence] = ResistMagicka;
|
||||||
|
effects[Blind] = ResistMagicka;
|
||||||
|
effects[Sound] = ResistMagicka;
|
||||||
|
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
effects[CalmHumanoid+i] = ResistMagicka;
|
||||||
|
effects[FrenzyHumanoid+i] = ResistMagicka;
|
||||||
|
effects[DemoralizeHumanoid+i] = ResistMagicka;
|
||||||
|
effects[RallyHumanoid+i] = ResistMagicka;
|
||||||
|
}
|
||||||
|
|
||||||
|
effects[TurnUndead] = ResistMagicka;
|
||||||
|
|
||||||
|
effects[FireDamage] = ResistFire;
|
||||||
|
effects[FrostDamage] = ResistFrost;
|
||||||
|
effects[ShockDamage] = ResistShock;
|
||||||
|
effects[Vampirism] = ResistCommonDisease;
|
||||||
|
effects[Corprus] = ResistCorprusDisease;
|
||||||
|
effects[Poison] = ResistPoison;
|
||||||
|
effects[Paralyze] = ResistParalysis;
|
||||||
}
|
}
|
||||||
|
|
||||||
effects[TurnUndead] = ResistMagicka;
|
|
||||||
|
|
||||||
effects[FireDamage] = ResistFire;
|
|
||||||
effects[FrostDamage] = ResistFrost;
|
|
||||||
effects[ShockDamage] = ResistShock;
|
|
||||||
effects[Vampirism] = ResistCommonDisease;
|
|
||||||
effects[Corprus] = ResistCorprusDisease;
|
|
||||||
effects[Poison] = ResistPoison;
|
|
||||||
effects[Paralyze] = ResistParalysis;
|
|
||||||
|
|
||||||
if (effects.find(effect) != effects.end())
|
if (effects.find(effect) != effects.end())
|
||||||
return effects[effect];
|
return effects[effect];
|
||||||
else
|
else
|
||||||
@ -319,42 +322,44 @@ short MagicEffect::getResistanceEffect(short effect)
|
|||||||
|
|
||||||
short MagicEffect::getWeaknessEffect(short effect)
|
short MagicEffect::getWeaknessEffect(short effect)
|
||||||
{
|
{
|
||||||
std::map<short, short> effects;
|
static std::map<short, short> effects;
|
||||||
|
if (effects.empty())
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DrainAttribute+i] = WeaknessToMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DamageAttribute+i] = WeaknessToMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[AbsorbAttribute+i] = WeaknessToMagicka;
|
|
||||||
for (int i=0; i<10; ++i)
|
|
||||||
effects[WeaknessToFire+i] = WeaknessToMagicka;
|
|
||||||
|
|
||||||
effects[Burden] = WeaknessToMagicka;
|
|
||||||
effects[Charm] = WeaknessToMagicka;
|
|
||||||
effects[Silence] = WeaknessToMagicka;
|
|
||||||
effects[Blind] = WeaknessToMagicka;
|
|
||||||
effects[Sound] = WeaknessToMagicka;
|
|
||||||
|
|
||||||
for (int i=0; i<2; ++i)
|
|
||||||
{
|
{
|
||||||
effects[CalmHumanoid+i] = WeaknessToMagicka;
|
for (int i=0; i<5; ++i)
|
||||||
effects[FrenzyHumanoid+i] = WeaknessToMagicka;
|
effects[DrainAttribute+i] = WeaknessToMagicka;
|
||||||
effects[DemoralizeHumanoid+i] = WeaknessToMagicka;
|
for (int i=0; i<5; ++i)
|
||||||
effects[RallyHumanoid+i] = WeaknessToMagicka;
|
effects[DamageAttribute+i] = WeaknessToMagicka;
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[AbsorbAttribute+i] = WeaknessToMagicka;
|
||||||
|
for (int i=0; i<10; ++i)
|
||||||
|
effects[WeaknessToFire+i] = WeaknessToMagicka;
|
||||||
|
|
||||||
|
effects[Burden] = WeaknessToMagicka;
|
||||||
|
effects[Charm] = WeaknessToMagicka;
|
||||||
|
effects[Silence] = WeaknessToMagicka;
|
||||||
|
effects[Blind] = WeaknessToMagicka;
|
||||||
|
effects[Sound] = WeaknessToMagicka;
|
||||||
|
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
effects[CalmHumanoid+i] = WeaknessToMagicka;
|
||||||
|
effects[FrenzyHumanoid+i] = WeaknessToMagicka;
|
||||||
|
effects[DemoralizeHumanoid+i] = WeaknessToMagicka;
|
||||||
|
effects[RallyHumanoid+i] = WeaknessToMagicka;
|
||||||
|
}
|
||||||
|
|
||||||
|
effects[TurnUndead] = WeaknessToMagicka;
|
||||||
|
|
||||||
|
effects[FireDamage] = WeaknessToFire;
|
||||||
|
effects[FrostDamage] = WeaknessToFrost;
|
||||||
|
effects[ShockDamage] = WeaknessToShock;
|
||||||
|
effects[Vampirism] = WeaknessToCommonDisease;
|
||||||
|
effects[Corprus] = WeaknessToCorprusDisease;
|
||||||
|
effects[Poison] = WeaknessToPoison;
|
||||||
|
|
||||||
|
effects[Paralyze] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
effects[TurnUndead] = WeaknessToMagicka;
|
|
||||||
|
|
||||||
effects[FireDamage] = WeaknessToFire;
|
|
||||||
effects[FrostDamage] = WeaknessToFrost;
|
|
||||||
effects[ShockDamage] = WeaknessToShock;
|
|
||||||
effects[Vampirism] = WeaknessToCommonDisease;
|
|
||||||
effects[Corprus] = WeaknessToCorprusDisease;
|
|
||||||
effects[Poison] = WeaknessToPoison;
|
|
||||||
|
|
||||||
effects[Paralyze] = -1;
|
|
||||||
|
|
||||||
if (effects.find(effect) != effects.end())
|
if (effects.find(effect) != effects.end())
|
||||||
return effects[effect];
|
return effects[effect];
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user