mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 16:49:54 +00:00
Crime is now checked every frame call
This commit is contained in:
parent
510f2d10ac
commit
58b135a2be
12 changed files with 76 additions and 93 deletions
|
@ -513,8 +513,6 @@ namespace MWBase
|
|||
|
||||
virtual void explodeSpell (const Ogre::Vector3& origin, const MWWorld::Ptr& object, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName) = 0;
|
||||
|
||||
virtual void resetCrimes(const MWWorld::Ptr& ptr) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#include "aicombat.hpp"
|
||||
#include "aifollow.hpp"
|
||||
#include "aipersue.hpp"
|
||||
|
||||
#include "../mwbase/dialoguemanager.hpp" //------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -175,14 +178,16 @@ namespace MWMechanics
|
|||
adjustMagicEffects (ptr);
|
||||
if (ptr.getClass().getCreatureStats(ptr).needToRecalcDynamicStats())
|
||||
calculateDynamicStats (ptr);
|
||||
|
||||
calculateCreatureStatModifiers (ptr, duration);
|
||||
|
||||
// AI
|
||||
if(MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
||||
{
|
||||
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||
//engage combat or not?
|
||||
CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr);
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
//engage combat or not?
|
||||
if(ptr != player && !creatureStats.isHostile())
|
||||
{
|
||||
ESM::Position playerpos = player.getRefData().getPosition();
|
||||
|
@ -214,7 +219,7 @@ namespace MWMechanics
|
|||
creatureStats.setHostile(true);
|
||||
}
|
||||
}
|
||||
|
||||
updateCrimePersuit(ptr, duration);
|
||||
creatureStats.getAiSequence().execute (ptr,duration);
|
||||
}
|
||||
|
||||
|
@ -711,6 +716,48 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
int bounty = player.getClass().getNpcStats(player).getBounty();
|
||||
|
||||
// TODO: Move me! I shouldn't be here...
|
||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||
float cutoff = float(esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->getInt()) *
|
||||
float(esmStore.get<ESM::GameSetting>().find("iCrimeThresholdMultiplier")->getInt()) *
|
||||
esmStore.get<ESM::GameSetting>().find("fCrimeGoldDiscountMult")->getFloat();
|
||||
|
||||
if (ptr != player)
|
||||
{
|
||||
CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr);
|
||||
// Alarmed or not, I will kill you because you've commited heinous against the empire
|
||||
if ((!creatureStats.isAlarmed() || creatureStats.isAlarmed()) &&
|
||||
ptr.getClass().isClass(ptr, "Guard") && bounty >= cutoff && !creatureStats.isHostile())
|
||||
creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)));
|
||||
else if (creatureStats.isAlarmed())
|
||||
{
|
||||
MWBase::Environment::get().getDialogueManager()->say(ptr, "Thief");
|
||||
if(bounty == 0)
|
||||
{
|
||||
creatureStats.setAlarmed(false);
|
||||
creatureStats.setHostile(false);
|
||||
if (ptr.getClass().isClass(ptr, "Guard"))
|
||||
creatureStats.getAiSequence().stopPersue();
|
||||
creatureStats.getAiSequence().stopCombat();
|
||||
|
||||
}
|
||||
|
||||
if (ptr.getClass().isClass(ptr, "Guard") && !creatureStats.isHostile())
|
||||
creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)));
|
||||
else if (!creatureStats.isHostile())
|
||||
{
|
||||
creatureStats.getAiSequence().stack(AiCombat(player));
|
||||
creatureStats.setHostile(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Actors::Actors() {}
|
||||
|
||||
Actors::~Actors()
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace MWMechanics
|
|||
|
||||
void updateEquippedLight (const MWWorld::Ptr& ptr, float duration);
|
||||
|
||||
void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration);
|
||||
|
||||
public:
|
||||
|
||||
Actors();
|
||||
|
|
|
@ -19,10 +19,8 @@ MWMechanics::AiPersue *MWMechanics::AiPersue::clone() const
|
|||
{
|
||||
return new AiPersue(*this);
|
||||
}
|
||||
bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor,float duration)
|
||||
bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
|
||||
{
|
||||
//TODO: Guards should not dialague with player after crime reset
|
||||
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
ESM::Position pos = actor.getRefData().getPosition();
|
||||
Movement &movement = actor.getClass().getMovementSettings(actor);
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace MWMechanics
|
|||
CreatureStats::CreatureStats()
|
||||
: mLevel (0), mDead (false), mDied (false), mFriendlyHits (0),
|
||||
mTalkedTo (false), mAlarmed (false),
|
||||
mAttacked (false), mHostile (false),
|
||||
mAttacked (false), mHostile (false), mAssaulted(false),
|
||||
mAttackingOrSpell(false),
|
||||
mIsWerewolf(false),
|
||||
mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false), mBlock(false),
|
||||
|
@ -316,6 +316,16 @@ namespace MWMechanics
|
|||
mHostile = hostile;
|
||||
}
|
||||
|
||||
bool CreatureStats::isAssaulted() const
|
||||
{
|
||||
return mAssaulted;
|
||||
}
|
||||
|
||||
void CreatureStats::setAssaulted (bool assaulted)
|
||||
{
|
||||
mAssaulted = assaulted;
|
||||
}
|
||||
|
||||
bool CreatureStats::getCreatureTargetted() const
|
||||
{
|
||||
std::string target;
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace MWMechanics
|
|||
bool mAlarmed;
|
||||
bool mAttacked;
|
||||
bool mHostile;
|
||||
bool mAssaulted;
|
||||
bool mAttackingOrSpell;
|
||||
bool mKnockdown;
|
||||
bool mHitRecovery;
|
||||
|
@ -186,6 +187,10 @@ namespace MWMechanics
|
|||
|
||||
void setHostile (bool hostile);
|
||||
|
||||
bool isAssaulted() const;
|
||||
|
||||
void setAssaulted (bool assaulted);
|
||||
|
||||
bool getCreatureTargetted() const;
|
||||
|
||||
float getEvasion() const;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#include "mechanicsmanagerimp.hpp"
|
||||
#include "npcstats.hpp"
|
||||
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
@ -12,10 +13,6 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "aicombat.hpp"
|
||||
#include "aipersue.hpp"
|
||||
#include "aiactivate.hpp"
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include "spellcasting.hpp"
|
||||
|
@ -827,11 +824,6 @@ namespace MWMechanics
|
|||
else if (type == OT_Theft)
|
||||
alarm = esmStore.get<ESM::GameSetting>().find("iAlarmStealing")->getInt();
|
||||
|
||||
// what is the bounty cutoff? To high the guards will attack
|
||||
float cutoff = float(esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->getInt()) *
|
||||
float(esmStore.get<ESM::GameSetting>().find("iCrimeThresholdMultiplier")->getInt()) *
|
||||
esmStore.get<ESM::GameSetting>().find("fCrimeGoldDiscountMult")->getFloat();
|
||||
|
||||
// Innocent until proven guilty
|
||||
bool reported = false;
|
||||
|
||||
|
@ -846,8 +838,9 @@ namespace MWMechanics
|
|||
|
||||
CreatureStats& creatureStats = MWWorld::Class::get(*it).getCreatureStats(*it);
|
||||
|
||||
// Did a witness see the crime?
|
||||
if ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) )
|
||||
// Was the crime seen or the victim assulted?
|
||||
if ( ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) ||
|
||||
type == OT_Assault)
|
||||
{
|
||||
// Say something!
|
||||
// TODO: Add more messages
|
||||
|
@ -858,7 +851,6 @@ namespace MWMechanics
|
|||
if (creatureStats.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm)
|
||||
{
|
||||
reported = true;
|
||||
reportCrime(ptr, victim, type, arg);
|
||||
|
||||
// Tell everyone else
|
||||
for (std::vector<MWWorld::Ptr>::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1)
|
||||
|
@ -870,38 +862,13 @@ namespace MWMechanics
|
|||
CreatureStats& creatureStats1 = MWWorld::Class::get(*it1).getCreatureStats(*it1);
|
||||
if (creatureStats1.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm)
|
||||
creatureStats1.setAlarmed(true);
|
||||
|
||||
// was the witness a guard?
|
||||
if (it1->getClass().isClass(*it1, "Guard"))
|
||||
{
|
||||
// will the guard try to kill the player?
|
||||
if (ptr.getClass().getNpcStats(ptr).getBounty() >= cutoff)
|
||||
{
|
||||
creatureStats1.getAiSequence().stack(AiCombat(ptr));
|
||||
creatureStats1.setHostile(true);
|
||||
creatureStats1.getAiSequence().execute(*it1,0);
|
||||
}
|
||||
else // will the guard persue the player?
|
||||
{
|
||||
creatureStats1.getAiSequence().stack(AiPersue(ptr.getClass().getId(ptr)));
|
||||
creatureStats1.getAiSequence().execute(*it1,0);
|
||||
}
|
||||
}
|
||||
// will the witness fight the player?
|
||||
else if (creatureStats1.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm ||
|
||||
type == OT_Assault)
|
||||
{
|
||||
creatureStats1.getAiSequence().stack(AiCombat(ptr));
|
||||
creatureStats1.setHostile(true);
|
||||
creatureStats1.getAiSequence().execute(*it1,0);
|
||||
}
|
||||
}
|
||||
break; // Someone saw the crime and everyone has been told
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reported)
|
||||
MWBase::Environment::get().getWorld()->getPlayer().addPlayerWitnesses(neighbors);
|
||||
if(reported)
|
||||
reportCrime(ptr, victim, type, arg);
|
||||
return reported;
|
||||
}
|
||||
|
||||
|
|
|
@ -810,11 +810,8 @@ namespace MWScript
|
|||
public:
|
||||
virtual void execute(Interpreter::Runtime &runtime)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
player.getClass().getNpcStats(player).setBounty(0);
|
||||
world->confiscateStolenItems(player);
|
||||
world->resetCrimes(player);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -823,10 +820,8 @@ namespace MWScript
|
|||
public:
|
||||
virtual void execute(Interpreter::Runtime &runtime)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
player.getClass().getNpcStats(player).setBounty(0);
|
||||
world->resetCrimes(player);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -274,17 +274,4 @@ namespace MWWorld
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Player::addPlayerWitnesses(std::vector<MWWorld::Ptr> witnesses)
|
||||
{
|
||||
mWitnesses.insert(mWitnesses.end(), witnesses.begin(), witnesses.end());
|
||||
}
|
||||
std::vector<MWWorld::Ptr> Player::getPlayerWitnesses() const
|
||||
{
|
||||
return mWitnesses;
|
||||
}
|
||||
void Player::resetPlayerWitnesses()
|
||||
{
|
||||
mWitnesses.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,10 +96,6 @@ namespace MWWorld
|
|||
void write (ESM::ESMWriter& writer) const;
|
||||
|
||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
||||
|
||||
void addPlayerWitnesses(std::vector<MWWorld::Ptr> witnesses);
|
||||
std::vector<MWWorld::Ptr> getPlayerWitnesses() const;
|
||||
void resetPlayerWitnesses();
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2765,33 +2765,12 @@ namespace MWWorld
|
|||
|
||||
// TODO: Sleep the player
|
||||
|
||||
resetCrimes(player);
|
||||
|
||||
std::vector<std::string> buttons;
|
||||
buttons.push_back("#{sOk}");
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(message, buttons);
|
||||
}
|
||||
}
|
||||
|
||||
void World::resetCrimes(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
// Reset witnesses to the players crimes
|
||||
std::vector<MWWorld::Ptr> neighbors = mPlayer->getPlayerWitnesses();
|
||||
for (std::vector<MWWorld::Ptr>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
|
||||
{
|
||||
// Reset states
|
||||
// TODO: More research is needed to complete this list
|
||||
it->getClass().getCreatureStats(*it).setHostile(false);
|
||||
it->getClass().getCreatureStats(*it).setAlarmed(false);
|
||||
|
||||
// Stop guard persue
|
||||
if(it->getClass().isClass(*it, "Guard"))
|
||||
it->getClass().getCreatureStats(*it).getAiSequence().stopPersue();
|
||||
|
||||
}
|
||||
mPlayer->resetPlayerWitnesses();
|
||||
}
|
||||
|
||||
void World::spawnRandomCreature(const std::string &creatureList)
|
||||
{
|
||||
const ESM::CreatureLevList* list = getStore().get<ESM::CreatureLevList>().find(creatureList);
|
||||
|
|
|
@ -611,7 +611,6 @@ namespace MWWorld
|
|||
|
||||
virtual void explodeSpell (const Ogre::Vector3& origin, const MWWorld::Ptr& object, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName);
|
||||
virtual void resetCrimes(const MWWorld::Ptr& ptr);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue