Implement Calm effect removing combat packages (Fixes #1985)

moveref
scrawl 10 years ago
parent 4f3995a4d8
commit 2b78e9795d

@ -891,4 +891,10 @@ namespace MWClass
MWWorld::ContainerStore& store = getContainerStore(ptr);
store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
}
int Creature::getBaseFightRating(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
return ref->mBase->mAiData.mFight;
}
}

@ -154,6 +154,8 @@ namespace MWClass
virtual void respawn (const MWWorld::Ptr& ptr) const;
virtual void restock (const MWWorld::Ptr &ptr) const;
virtual int getBaseFightRating(const MWWorld::Ptr &ptr) const;
};
}

@ -1266,6 +1266,7 @@ namespace MWClass
// TODO: I have no idea what these are supposed to do for NPCs since they use
// voiced dialog for various conditions like health loss and combat taunts. Maybe
// only for biped creatures?
if(name == "moan")
return "";
if(name == "roar")
@ -1380,4 +1381,10 @@ namespace MWClass
MWWorld::ContainerStore& store = getContainerStore(ptr);
store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
}
int Npc::getBaseFightRating (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
return ref->mBase->mAiData.mFight;
}
}

@ -185,6 +185,8 @@ namespace MWClass
virtual void respawn (const MWWorld::Ptr& ptr) const;
virtual void restock (const MWWorld::Ptr& ptr) const;
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
};
}

@ -677,6 +677,19 @@ namespace MWMechanics
// TODO: dirty flag for magic effects to avoid some unnecessary work below?
// any value of calm > 0 will stop the actor from fighting
if ((creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() > 0 && ptr.getClass().isNpc())
|| (creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmCreature).getMagnitude() > 0 && !ptr.getClass().isNpc()))
{
for (std::list<AiPackage*>::const_iterator it = creatureStats.getAiSequence().begin(); it != creatureStats.getAiSequence().end(); )
{
if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
it = creatureStats.getAiSequence().erase(it);
else
++it;
}
}
// Update bound effects
static std::map<int, std::string> boundItemsMap;
if (boundItemsMap.empty())
@ -1056,6 +1069,7 @@ namespace MWMechanics
// Reset factors to attack
creatureStats.setAttacked(false);
creatureStats.setAlarmed(false);
creatureStats.setAiSetting(CreatureStats::AI_Fight, ptr.getClass().getBaseFightRating(ptr));
// Update witness crime id
npcStats.setCrimeId(-1);

@ -455,7 +455,10 @@ namespace MWMechanics
// Default to hand-to-hand combat
boost::shared_ptr<Action> bestAction (new ActionWeapon(MWWorld::Ptr()));
if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
{
bestAction->prepare(actor);
return bestAction;
}
if (actor.getClass().hasInventoryStore(actor))
{

@ -86,15 +86,14 @@ std::list<AiPackage*>::const_iterator AiSequence::end() const
return mPackages.end();
}
void AiSequence::erase(std::list<AiPackage*>::const_iterator package)
std::list<AiPackage*>::const_iterator AiSequence::erase(std::list<AiPackage*>::const_iterator package)
{
// Not sure if manually terminated packages should trigger mDone, probably not?
for(std::list<AiPackage*>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
{
if (package == it)
{
mPackages.erase(it);
return;
return mPackages.erase(it);
}
}
throw std::runtime_error("can't find package to erase");

@ -61,7 +61,7 @@ namespace MWMechanics
std::list<AiPackage*>::const_iterator begin() const;
std::list<AiPackage*>::const_iterator end() const;
void erase (std::list<AiPackage*>::const_iterator package);
std::list<AiPackage*>::const_iterator erase (std::list<AiPackage*>::const_iterator package);
/// Returns currently executing AiPackage type
/** \see enum AiPackage::TypeId **/

@ -1096,6 +1096,11 @@ namespace MWMechanics
{
startCombat(*it, player);
// Apply aggression value to the base Fight rating, so that the actor can continue fighting
// after a Calm spell wears off
int fightBase = it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Fight).getBase();
it->getClass().getCreatureStats(*it).setAiSetting(CreatureStats::AI_Fight, fightBase + aggression);
// Set the crime ID, which we will use to calm down participants
// once the bounty has been paid.
it->getClass().getNpcStats(*it).setCrimeId(id);

@ -429,4 +429,9 @@ namespace MWWorld
{
return std::string();
}
int Class::getBaseFightRating(const Ptr &ptr) const
{
throw std::runtime_error("class does not support fight rating");
}
}

@ -339,6 +339,8 @@ namespace MWWorld
/// Returns sound id
virtual std::string getSound(const MWWorld::Ptr& ptr) const;
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
};
}

Loading…
Cancel
Save