mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 22:53:53 +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);
|
||||
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…
Reference in a new issue