From 940c88d2ecd6b25a3919596eff3a60b7a7d2d0fe Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sat, 5 Apr 2014 10:26:14 -0400 Subject: [PATCH] Cleaned up code, implemented crime ids There is a problem with my game freezing. ToggleAi stops my character --- apps/openmw/mwmechanics/actors.cpp | 57 +++++++++++-------- apps/openmw/mwmechanics/creaturestats.hpp | 4 -- .../mwmechanics/mechanicsmanagerimp.cpp | 35 ++++++------ apps/openmw/mwmechanics/npcstats.cpp | 11 ++++ apps/openmw/mwmechanics/npcstats.hpp | 6 +- apps/openmw/mwscript/miscextensions.cpp | 4 ++ apps/openmw/mwworld/player.cpp | 19 ++++++- apps/openmw/mwworld/player.hpp | 12 ++-- 8 files changed, 95 insertions(+), 53 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index fcec5a3fb..ee30dae6d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -31,8 +31,6 @@ #include "aifollow.hpp" #include "aipersue.hpp" -#include "../mwbase/dialoguemanager.hpp" //------------------------ - namespace { @@ -718,49 +716,58 @@ namespace MWMechanics void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); - - /// \todo Move me! I shouldn't be here... - const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - float cutoff = float(esmStore.get().find("iCrimeThreshold")->getInt()) * - float(esmStore.get().find("iCrimeThresholdMultiplier")->getInt()) * - esmStore.get().find("fCrimeGoldDiscountMult")->getFloat(); - - if (ptr != player) + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); + if (ptr != playerPtr) { + // get stats of witness + CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); + NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats(ptr); + MWWorld::Player player = MWBase::Environment::get().getWorld()->getPlayer(); + // If I'm a guard and I'm not hostile if (ptr.getClass().isClass(ptr, "Guard") && !creatureStats.isHostile()) { + /// \todo Move me! I shouldn't be here... + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); + float cutoff = float(esmStore.get().find("iCrimeThreshold")->getInt()) * + float(esmStore.get().find("iCrimeThresholdMultiplier")->getInt()) * + esmStore.get().find("fCrimeGoldDiscountMult")->getFloat(); // Attack on sight if bounty is greater than the cutoff - if ( player.getClass().getNpcStats(player).getBounty() >= cutoff - && MWBase::Environment::get().getWorld()->getLOS(ptr, player) - && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)) + if ( playerPtr.getClass().getNpcStats(playerPtr).getBounty() >= cutoff + && MWBase::Environment::get().getWorld()->getLOS(ptr, playerPtr) + && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(playerPtr, ptr)) { - creatureStats.getAiSequence().stack(AiCombat(player)); + creatureStats.getAiSequence().stack(AiCombat(playerPtr)); creatureStats.setHostile(true); - creatureStats.setAlarmed(true); + npcStats.setCrimeId(player.getNewCrimeId()); } } // if I was a witness to a crime - if (creatureStats.isAlarmed()) + if (npcStats.getCrimeId() != -1) { - if(player.getClass().getNpcStats(player).getBounty() == 0) + // if you've payed for your crimes and I havent noticed + if(npcStats.getCrimeId() < player.getCrimeId() ) { - creatureStats.setAlarmed(false); - creatureStats.setHostile(false); - creatureStats.setAttacked(false); + // Calm witness down if (ptr.getClass().isClass(ptr, "Guard")) creatureStats.getAiSequence().stopPersue(); creatureStats.getAiSequence().stopCombat(); + + // Reset factors to attack + // TODO: Not a complete list, disposition changes? + creatureStats.setHostile(false); + creatureStats.setAttacked(false); + + // Update witness crime id + npcStats.setCrimeId(-1); } else if (!creatureStats.isHostile()) { if (ptr.getClass().isClass(ptr, "Guard")) - creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player))); + creatureStats.getAiSequence().stack(AiPersue(playerPtr.getClass().getId(playerPtr))); else - creatureStats.getAiSequence().stack(AiCombat(player)); + creatureStats.getAiSequence().stack(AiCombat(playerPtr)); creatureStats.setHostile(true); } } @@ -768,7 +775,7 @@ namespace MWMechanics // if I didn't report a crime was I attacked? else if (creatureStats.getAttacked() && !creatureStats.isHostile()) { - creatureStats.getAiSequence().stack(AiCombat(player)); + creatureStats.getAiSequence().stack(AiCombat(playerPtr)); creatureStats.setHostile(true); } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 97bcd719c..5dc59e5ab 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -39,7 +39,6 @@ namespace MWMechanics bool mAlarmed; bool mAttacked; bool mHostile; - bool mAssaulted; bool mAttackingOrSpell; bool mKnockdown; bool mHitRecovery; @@ -176,15 +175,12 @@ namespace MWMechanics void talkedToPlayer(); bool isAlarmed() const; - void setAlarmed (bool alarmed); bool getAttacked() const; - void setAttacked (bool attacked); bool isHostile() const; - void setHostile (bool hostile); bool getCreatureTargetted() const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 8d546b598..a26520fc7 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -828,42 +828,43 @@ namespace MWMechanics // Innocent until proven guilty bool reported = false; - // Find all the NPC's close enough, ie. within fAlarmRadius of the player + // Find all the NPCs within the alarm radius std::vector neighbors; mActors.getObjectsInRange(Ogre::Vector3(ptr.getRefData().getPosition().pos), - esmStore.get().find("fAlarmRadius")->getInt(), neighbors); + esmStore.get().find("fAlarmRadius")->getInt(), neighbors); + + // Find an actor who witnessed the crime for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { - if (*it == ptr) // Not the player - continue; - - CreatureStats& creatureStats = MWWorld::Class::get(*it).getCreatureStats(*it); + if (*it == ptr) continue; // not the player // Was the crime seen? if ( ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) || type == OT_Assault ) { - // Say something! // TODO: Add more messages if (type == OT_Theft) - MWBase::Environment::get().getDialogueManager()->say(*it, "Thief"); + MWBase::Environment::get().getDialogueManager()->say(*it, "thief"); + else if (type == OT_Assault) + MWBase::Environment::get().getDialogueManager()->say(*it, "attack"); // Will the witness report the crime? - if (creatureStats.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm) + if (it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm) { reported = true; + int id = player.getNewCrimeId(); - // Tell everyone else + // Tell everyone, including yourself for (std::vector::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1) { - if (*it1 == ptr) // Not the player - continue; + if (*it1 == ptr) continue; // not the player - // Will the witness be affected by the crime? - CreatureStats& creatureStats1 = MWWorld::Class::get(*it1).getCreatureStats(*it1); - if (creatureStats1.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm || - type == OT_Assault) - creatureStats1.setAlarmed(true); + // Will other witnesses paticipate in crime + if ( it1->getClass().getCreatureStats(*it1).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm + || type == OT_Assault ) + { + it1->getClass().getNpcStats(*it1).setCrimeId(id); + } } break; // Someone saw the crime and everyone has been told } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 74587a626..4f014102d 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -29,6 +29,7 @@ MWMechanics::NpcStats::NpcStats() , mLevelProgress(0) , mDisposition(0) , mReputation(0) +, mCrimeId(-1) , mWerewolfKills (0) , mProfit(0) , mTimeToStartDrowning(20.0) @@ -340,6 +341,16 @@ void MWMechanics::NpcStats::setReputation(int reputation) mReputation = reputation; } +int MWMechanics::NpcStats::getCrimeId() const +{ + return mCrimeId; +} + +void MWMechanics::NpcStats::setCrimeId(int id) +{ + mCrimeId = id; +} + bool MWMechanics::NpcStats::hasSkillsForRank (const std::string& factionId, int rank) const { if (rank<0 || rank>=10) diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index ad493be3c..0ae596a54 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -37,6 +37,7 @@ namespace MWMechanics std::set mExpelled; std::map mFactionReputation; int mReputation; + int mCrimeId; int mWerewolfKills; int mProfit; float mAttackStrength; @@ -63,13 +64,14 @@ namespace MWMechanics void modifyProfit(int diff); int getBaseDisposition() const; - void setBaseDisposition(int disposition); int getReputation() const; - void setReputation(int reputation); + int getCrimeId() const; + void setCrimeId(int id); + const SkillValue& getSkill (int index) const; SkillValue& getSkill (int index); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a7f31c80b..aa554adc3 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -21,6 +21,7 @@ #include "../mwbase/scriptmanager.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" @@ -802,6 +803,7 @@ namespace MWScript { MWBase::World* world = MWBase::Environment::get().getWorld(); world->goToJail(); + MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId(); } }; @@ -812,6 +814,7 @@ namespace MWScript { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getNpcStats(player).setBounty(0); + MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId(); } }; @@ -823,6 +826,7 @@ namespace MWScript MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getNpcStats(player).setBounty(0); MWBase::Environment::get().getWorld()->confiscateStolenItems(player); + MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId(); } }; diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index bfeca9653..d39ec2c0f 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -30,7 +30,9 @@ namespace MWWorld mAutoMove(false), mForwardBackward(0), mTeleported(false), - mMarkedCell(NULL) + mMarkedCell(NULL), + mCurrentCrimeId(-1), + mPayedCrimeId(-1) { mPlayer.mBase = player; mPlayer.mRef.mRefID = "player"; @@ -274,4 +276,19 @@ namespace MWWorld return false; } + + int Player::getNewCrimeId() + { + return mCurrentCrimeId++; + } + + void Player::recordCrimeId() + { + mPayedCrimeId = mCurrentCrimeId; + } + + int Player::getCrimeId() const + { + return mCurrentCrimeId; + } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 9d3fbbeec..7dbaaddb4 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -41,6 +41,9 @@ namespace MWWorld bool mAutoMove; int mForwardBackward; bool mTeleported; + + int mCurrentCrimeId; // the id assigned witnesses + int mPayedCrimeId; // the last id payed off (0 bounty) public: @@ -64,15 +67,12 @@ namespace MWWorld MWWorld::Ptr getPlayer(); void setBirthSign(const std::string &sign); - const std::string &getBirthSign() const; void setDrawState (MWMechanics::DrawState_ state); - - bool getAutoMove() const; - MWMechanics::DrawState_ getDrawState(); /// \todo constness + bool getAutoMove() const; void setAutoMove (bool enable); void setLeftRight (int value); @@ -95,6 +95,10 @@ namespace MWWorld void write (ESM::ESMWriter& writer) const; bool readRecord (ESM::ESMReader& reader, int32_t type); + + int getNewCrimeId(); // get new id for witnesses + void recordCrimeId(); // record the payed crime id when bounty is 0 + int getCrimeId() const; // get the last payed crime id }; } #endif