mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Merged pull request #1901
This commit is contained in:
commit
78a84042ad
@ -141,6 +141,7 @@
|
||||
Task #4605: Optimize skinning
|
||||
Task #4606: Support Rapture3D's OpenAL driver
|
||||
Task #4613: Incomplete type errors when compiling with g++ on OSX 10.9
|
||||
Task #4621: Optimize combat AI
|
||||
|
||||
0.44.0
|
||||
------
|
||||
|
@ -190,11 +190,6 @@ namespace MWMechanics
|
||||
|
||||
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);
|
||||
if (rating > bestActionRating)
|
||||
{
|
||||
@ -215,14 +210,12 @@ namespace MWMechanics
|
||||
|
||||
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||
{
|
||||
const ESM::Spell* spell = it->first;
|
||||
|
||||
float rating = rateSpell(spell, actor, enemy);
|
||||
float rating = rateSpell(it->first, actor, enemy);
|
||||
if (rating > bestActionRating)
|
||||
{
|
||||
bestActionRating = rating;
|
||||
bestAction.reset(new ActionSpell(spell->mId));
|
||||
antiFleeRating = vanillaRateSpell(spell, actor, enemy);
|
||||
bestAction.reset(new ActionSpell(it->first->mId));
|
||||
antiFleeRating = vanillaRateSpell(it->first, actor, enemy);
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,11 +258,6 @@ namespace MWMechanics
|
||||
|
||||
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);
|
||||
if (rating > bestActionRating)
|
||||
{
|
||||
@ -280,9 +268,7 @@ namespace MWMechanics
|
||||
|
||||
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||
{
|
||||
const ESM::Spell* spell = it->first;
|
||||
|
||||
float rating = rateSpell(spell, actor, enemy);
|
||||
float rating = rateSpell(it->first, actor, enemy);
|
||||
if (rating > bestActionRating)
|
||||
{
|
||||
bestActionRating = rating;
|
||||
|
@ -228,7 +228,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
||||
{
|
||||
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)
|
||||
if (target.isEmpty())
|
||||
@ -242,11 +242,11 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
||||
|
||||
const ESM::Position &targetPos = target.getRefData().getPosition();
|
||||
|
||||
float distTo = (targetPos.asVec3() - vActorPos).length();
|
||||
float distTo = (targetPos.asVec3() - vActorPos).length2();
|
||||
|
||||
// Small threshold for changing target
|
||||
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 (rating > bestRating || ((distTo < nearestDist) && rating == bestRating))
|
||||
|
@ -34,13 +34,17 @@ namespace MWMechanics
|
||||
{
|
||||
ESM::Skill::SkillEnum spellSchoolToSkill(int school)
|
||||
{
|
||||
std::map<int, ESM::Skill::SkillEnum> schoolSkillMap; // maps spell school to skill id
|
||||
schoolSkillMap[0] = ESM::Skill::Alteration;
|
||||
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
||||
schoolSkillMap[3] = ESM::Skill::Illusion;
|
||||
schoolSkillMap[2] = ESM::Skill::Destruction;
|
||||
schoolSkillMap[4] = ESM::Skill::Mysticism;
|
||||
schoolSkillMap[5] = ESM::Skill::Restoration;
|
||||
static std::map<int, ESM::Skill::SkillEnum> schoolSkillMap; // maps spell school to skill id
|
||||
if (schoolSkillMap.empty())
|
||||
{
|
||||
schoolSkillMap[0] = ESM::Skill::Alteration;
|
||||
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
||||
schoolSkillMap[3] = ESM::Skill::Illusion;
|
||||
schoolSkillMap[2] = ESM::Skill::Destruction;
|
||||
schoolSkillMap[4] = ESM::Skill::Mysticism;
|
||||
schoolSkillMap[5] = ESM::Skill::Restoration;
|
||||
}
|
||||
|
||||
assert(schoolSkillMap.find(school) != schoolSkillMap.end());
|
||||
return schoolSkillMap[school];
|
||||
}
|
||||
@ -48,7 +52,11 @@ namespace MWMechanics
|
||||
float calcEffectCost(const ESM::ENAMstruct& effect)
|
||||
{
|
||||
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 maxMagn = 1;
|
||||
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <components/esm/effectlist.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
@ -25,6 +26,7 @@ namespace MWMechanics
|
||||
ESM::Skill::SkillEnum spellSchoolToSkill(int school);
|
||||
|
||||
float calcEffectCost(const ESM::ENAMstruct& effect);
|
||||
float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect);
|
||||
|
||||
bool isSummoningEffect(int effectId);
|
||||
|
||||
|
@ -515,8 +515,6 @@ namespace MWMechanics
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
||||
|
||||
// Underwater casting not possible
|
||||
if (effect.mRange == ESM::RT_Target)
|
||||
{
|
||||
@ -530,6 +528,7 @@ namespace MWMechanics
|
||||
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)
|
||||
{
|
||||
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.
|
||||
// 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)
|
||||
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 rangedMult=1.f;
|
||||
|
||||
|
@ -274,43 +274,46 @@ short MagicEffect::getResistanceEffect(short effect)
|
||||
// Source https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attribute
|
||||
|
||||
// <Effect, Effect providing resistance against first effect>
|
||||
std::map<short, short> effects;
|
||||
effects[DisintegrateArmor] = Sanctuary;
|
||||
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)
|
||||
static std::map<short, short> effects;
|
||||
if (effects.empty())
|
||||
{
|
||||
effects[CalmHumanoid+i] = ResistMagicka;
|
||||
effects[FrenzyHumanoid+i] = ResistMagicka;
|
||||
effects[DemoralizeHumanoid+i] = ResistMagicka;
|
||||
effects[RallyHumanoid+i] = ResistMagicka;
|
||||
effects[DisintegrateArmor] = Sanctuary;
|
||||
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[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())
|
||||
return effects[effect];
|
||||
else
|
||||
@ -319,42 +322,44 @@ short MagicEffect::getResistanceEffect(short effect)
|
||||
|
||||
short MagicEffect::getWeaknessEffect(short effect)
|
||||
{
|
||||
std::map<short, short> effects;
|
||||
|
||||
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)
|
||||
static std::map<short, short> effects;
|
||||
if (effects.empty())
|
||||
{
|
||||
effects[CalmHumanoid+i] = WeaknessToMagicka;
|
||||
effects[FrenzyHumanoid+i] = WeaknessToMagicka;
|
||||
effects[DemoralizeHumanoid+i] = WeaknessToMagicka;
|
||||
effects[RallyHumanoid+i] = WeaknessToMagicka;
|
||||
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;
|
||||
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())
|
||||
return effects[effect];
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user