mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 08:53:52 +00:00
Implement Calm effect removing combat packages (Fixes #1985)
This commit is contained in:
parent
4f3995a4d8
commit
2b78e9795d
11 changed files with 49 additions and 4 deletions
|
@ -891,4 +891,10 @@ namespace MWClass
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
|
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 respawn (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void restock (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
|
// 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
|
// voiced dialog for various conditions like health loss and combat taunts. Maybe
|
||||||
// only for biped creatures?
|
// only for biped creatures?
|
||||||
|
|
||||||
if(name == "moan")
|
if(name == "moan")
|
||||||
return "";
|
return "";
|
||||||
if(name == "roar")
|
if(name == "roar")
|
||||||
|
@ -1380,4 +1381,10 @@ namespace MWClass
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
|
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 respawn (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void restock (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?
|
// 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
|
// Update bound effects
|
||||||
static std::map<int, std::string> boundItemsMap;
|
static std::map<int, std::string> boundItemsMap;
|
||||||
if (boundItemsMap.empty())
|
if (boundItemsMap.empty())
|
||||||
|
@ -1056,6 +1069,7 @@ namespace MWMechanics
|
||||||
// Reset factors to attack
|
// Reset factors to attack
|
||||||
creatureStats.setAttacked(false);
|
creatureStats.setAttacked(false);
|
||||||
creatureStats.setAlarmed(false);
|
creatureStats.setAlarmed(false);
|
||||||
|
creatureStats.setAiSetting(CreatureStats::AI_Fight, ptr.getClass().getBaseFightRating(ptr));
|
||||||
|
|
||||||
// Update witness crime id
|
// Update witness crime id
|
||||||
npcStats.setCrimeId(-1);
|
npcStats.setCrimeId(-1);
|
||||||
|
|
|
@ -455,7 +455,10 @@ namespace MWMechanics
|
||||||
// Default to hand-to-hand combat
|
// Default to hand-to-hand combat
|
||||||
boost::shared_ptr<Action> bestAction (new ActionWeapon(MWWorld::Ptr()));
|
boost::shared_ptr<Action> bestAction (new ActionWeapon(MWWorld::Ptr()));
|
||||||
if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
||||||
|
{
|
||||||
|
bestAction->prepare(actor);
|
||||||
return bestAction;
|
return bestAction;
|
||||||
|
}
|
||||||
|
|
||||||
if (actor.getClass().hasInventoryStore(actor))
|
if (actor.getClass().hasInventoryStore(actor))
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,15 +86,14 @@ std::list<AiPackage*>::const_iterator AiSequence::end() const
|
||||||
return mPackages.end();
|
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?
|
// Not sure if manually terminated packages should trigger mDone, probably not?
|
||||||
for(std::list<AiPackage*>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
|
for(std::list<AiPackage*>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
|
||||||
{
|
{
|
||||||
if (package == it)
|
if (package == it)
|
||||||
{
|
{
|
||||||
mPackages.erase(it);
|
return mPackages.erase(it);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::runtime_error("can't find package to erase");
|
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 begin() const;
|
||||||
std::list<AiPackage*>::const_iterator end() 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
|
/// Returns currently executing AiPackage type
|
||||||
/** \see enum AiPackage::TypeId **/
|
/** \see enum AiPackage::TypeId **/
|
||||||
|
|
|
@ -1096,6 +1096,11 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
startCombat(*it, player);
|
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
|
// Set the crime ID, which we will use to calm down participants
|
||||||
// once the bounty has been paid.
|
// once the bounty has been paid.
|
||||||
it->getClass().getNpcStats(*it).setCrimeId(id);
|
it->getClass().getNpcStats(*it).setCrimeId(id);
|
||||||
|
|
|
@ -429,4 +429,9 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
return std::string();
|
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
|
/// Returns sound id
|
||||||
virtual std::string getSound(const MWWorld::Ptr& ptr) const;
|
virtual std::string getSound(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue