1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 16:19:41 +00:00

Crime is now checked every frame call

This commit is contained in:
Jeffrey Haines 2014-04-03 00:50:09 -04:00
parent 510f2d10ac
commit 58b135a2be
12 changed files with 76 additions and 93 deletions

View file

@ -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;
};
}

View file

@ -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()

View file

@ -42,6 +42,8 @@ namespace MWMechanics
void updateEquippedLight (const MWWorld::Ptr& ptr, float duration);
void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration);
public:
Actors();

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}
};

View file

@ -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();
}
}

View file

@ -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

View file

@ -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);

View file

@ -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);
};
}