mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 20:56:42 +00:00 
			
		
		
		
	Detect crime of sleeping in other NPC's beds. ShowRestMenu needs to support an explicit/implicit reference for this.
This commit is contained in:
		
							parent
							
								
									b99ca92fee
								
							
						
					
					
						commit
						7b33f6f2ac
					
				
					 7 changed files with 85 additions and 24 deletions
				
			
		|  | @ -104,13 +104,17 @@ namespace MWBase | |||
|              * @brief Commit a crime. If any actors witness the crime and report it, | ||||
|              *        reportCrime will be called automatically. | ||||
|              * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. | ||||
|              * @return was the crime reported? | ||||
|              */ | ||||
|             virtual void commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|             virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|                                       OffenseType type, int arg=0) = 0; | ||||
|             virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|                                       OffenseType type, int arg=0) = 0; | ||||
|             /// Utility to check if taking this item is illegal and calling commitCrime if so
 | ||||
|             virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0; | ||||
|             /// Attempt sleeping in a bed. If this is illegal, call commitCrime.
 | ||||
|             /// @return was it illegal, and someone saw you doing it?
 | ||||
|             virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0; | ||||
| 
 | ||||
|             enum PersuasionType | ||||
|             { | ||||
|  |  | |||
|  | @ -16,6 +16,27 @@ | |||
| 
 | ||||
| #include "spellcasting.hpp" | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
|     /// @return is \a ptr allowed to take/use \a item or is it a crime?
 | ||||
|     bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) | ||||
|     { | ||||
|         const std::string& owner = item.getCellRef().mOwner; | ||||
|         bool isOwned = !owner.empty(); | ||||
| 
 | ||||
|         const std::string& faction = item.getCellRef().mFaction; | ||||
|         bool isFactionOwned = false; | ||||
|         if (!faction.empty()) | ||||
|         { | ||||
|             const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks(); | ||||
|             if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end()) | ||||
|                 isFactionOwned = true; | ||||
|         } | ||||
| 
 | ||||
|         return (!isOwned && !isFactionOwned); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| namespace MWMechanics | ||||
| { | ||||
|     void MechanicsManager::buildPlayer() | ||||
|  | @ -729,33 +750,35 @@ namespace MWMechanics | |||
|         return mAI; | ||||
|     } | ||||
| 
 | ||||
|     bool MechanicsManager::sleepInBed(const MWWorld::Ptr &ptr, const MWWorld::Ptr &bed) | ||||
|     { | ||||
|         if (isAllowedToUse(ptr, bed)) | ||||
|             return false; | ||||
|         MWWorld::Ptr victim; | ||||
|         if (!bed.getCellRef().mOwner.empty()) | ||||
|             victim = MWBase::Environment::get().getWorld()->getPtr(bed.getCellRef().mOwner, true); | ||||
| 
 | ||||
|         if(commitCrime(ptr, victim, OT_SleepingInOwnedBed)) | ||||
|         { | ||||
|             MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage64}"); | ||||
|             return true; | ||||
|         } | ||||
|         else | ||||
|             return false; | ||||
|     } | ||||
| 
 | ||||
|     void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count) | ||||
|     { | ||||
|         const std::string& owner = item.getCellRef().mOwner; | ||||
|         bool isOwned = !owner.empty(); | ||||
| 
 | ||||
|         const std::string& faction = item.getCellRef().mFaction; | ||||
|         bool isFactionOwned = false; | ||||
|         if (!faction.empty()) | ||||
|         { | ||||
|             const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks(); | ||||
|             if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end()) | ||||
|                 isFactionOwned = true; | ||||
|         } | ||||
| 
 | ||||
|         if (!isOwned && !isFactionOwned) | ||||
|         if (isAllowedToUse(ptr, item)) | ||||
|             return; | ||||
| 
 | ||||
|         MWWorld::Ptr victim; | ||||
|         if (!owner.empty()) | ||||
|             victim = MWBase::Environment::get().getWorld()->getPtr(owner, true); | ||||
| 
 | ||||
|         // TODO: expell from faction
 | ||||
|         if (!item.getCellRef().mOwner.empty()) | ||||
|             victim = MWBase::Environment::get().getWorld()->getPtr(item.getCellRef().mOwner, true); | ||||
| 
 | ||||
|         commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); | ||||
|     } | ||||
| 
 | ||||
|     void MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) | ||||
|     bool MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) | ||||
|     { | ||||
|         // TODO: expell from faction
 | ||||
| 
 | ||||
|  | @ -787,6 +810,7 @@ namespace MWMechanics | |||
| 
 | ||||
|         if (reported) | ||||
|             reportCrime(ptr, victim, type, arg); | ||||
|         return reported; | ||||
|     } | ||||
| 
 | ||||
|     void MechanicsManager::reportCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) | ||||
|  |  | |||
|  | @ -105,13 +105,17 @@ namespace MWMechanics | |||
|              * @brief Commit a crime. If any actors witness the crime and report it, | ||||
|              *        reportCrime will be called automatically. | ||||
|              * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. | ||||
|              * @return was the crime reported? | ||||
|              */ | ||||
|             virtual void commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|             virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|                                       OffenseType type, int arg=0); | ||||
|             virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, | ||||
|                                       OffenseType type, int arg=0); | ||||
|             /// Utility to check if taking this item is illegal and calling commitCrime if so
 | ||||
|             virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count); | ||||
|             /// Attempt sleeping in a bed. If this is illegal, call commitCrime.
 | ||||
|             /// @return was it illegal, and someone saw you doing it?
 | ||||
|             virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed); | ||||
| 
 | ||||
|         virtual void forceStateUpdate(const MWWorld::Ptr &ptr); | ||||
| 
 | ||||
|  |  | |||
|  | @ -371,4 +371,6 @@ op 0x2000230: Resurrect, explicit | |||
| op 0x2000231: GetSpellReadied | ||||
| op 0x2000232: GetSpellReadied, explicit | ||||
| op 0x2000233: GetPcJumping | ||||
| opcodes 0x2000234-0x3ffffff unused | ||||
| op 0x2000234: ShowRestMenu, explicit | ||||
| opcodes 0x2000235-0x3ffffff unused | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,11 +11,15 @@ | |||
| #include <components/interpreter/opcodes.hpp> | ||||
| 
 | ||||
| #include "../mwworld/esmstore.hpp" | ||||
| #include "../mwworld/player.hpp" | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/windowmanager.hpp" | ||||
| 
 | ||||
| #include "../mwbase/mechanicsmanager.hpp" | ||||
| 
 | ||||
| #include "interpretercontext.hpp" | ||||
| #include "ref.hpp" | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|  | @ -45,6 +49,27 @@ namespace MWScript | |||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|         template <class R> | ||||
|         class OpShowRestMenu : public Interpreter::Opcode0 | ||||
|         { | ||||
|         public: | ||||
|             virtual void execute (Interpreter::Runtime& runtime) | ||||
|             { | ||||
|                 // FIXME: No way to tell if we have a reference before trying to get it, and it will
 | ||||
|                 // cause an exception is there isn't one :(
 | ||||
|                 MWWorld::Ptr bed; | ||||
|                 try { | ||||
|                     bed = R()(runtime); | ||||
|                 } | ||||
|                 catch(std::runtime_error&) { | ||||
|                 } | ||||
| 
 | ||||
|                 if (bed.isEmpty() || !MWBase::Environment::get().getMechanicsManager()->sleepInBed(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), | ||||
|                                                                              bed)) | ||||
|                     MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_RestBed); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         class OpShowDialogue : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 MWGui::GuiMode mDialogue; | ||||
|  | @ -172,7 +197,8 @@ namespace MWScript | |||
|                 new OpEnableRest ()); | ||||
| 
 | ||||
|             interpreter.installSegment5 (Compiler::Gui::opcodeShowRestMenu, | ||||
|                 new OpShowDialogue (MWGui::GM_RestBed)); | ||||
|                 new OpShowRestMenu<ImplicitRef>); | ||||
|             interpreter.installSegment5 (Compiler::Gui::opcodeShowRestMenuExplicit, new OpShowRestMenu<ExplicitRef>); | ||||
| 
 | ||||
|             interpreter.installSegment5 (Compiler::Gui::opcodeGetButtonPressed, new OpGetButtonPressed); | ||||
| 
 | ||||
|  |  | |||
|  | @ -198,7 +198,7 @@ namespace Compiler | |||
|             extensions.registerInstruction ("enablerest", "", opcodeEnableRest); | ||||
|             extensions.registerInstruction ("enablelevelupmenu", "", opcodeEnableRest); | ||||
| 
 | ||||
|             extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu); | ||||
|             extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu, opcodeShowRestMenuExplicit); | ||||
| 
 | ||||
|             extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed); | ||||
| 
 | ||||
|  |  | |||
|  | @ -161,6 +161,7 @@ namespace Compiler | |||
|         const int opcodeEnableStatsMenu = 0x2000016; | ||||
|         const int opcodeEnableRest = 0x2000017; | ||||
|         const int opcodeShowRestMenu = 0x2000018; | ||||
|         const int opcodeShowRestMenuExplicit = 0x2000234; | ||||
|         const int opcodeGetButtonPressed = 0x2000137; | ||||
|         const int opcodeToggleFogOfWar = 0x2000145; | ||||
|         const int opcodeToggleFullHelp = 0x2000151; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue