mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +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;
|
||||
}
|
||||
|
||||
void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count)
|
||||
bool MechanicsManager::sleepInBed(const MWWorld::Ptr &ptr, const MWWorld::Ptr &bed)
|
||||
{
|
||||
const std::string& owner = item.getCellRef().mOwner;
|
||||
bool isOwned = !owner.empty();
|
||||
if (isAllowedToUse(ptr, bed))
|
||||
return false;
|
||||
MWWorld::Ptr victim;
|
||||
if (!bed.getCellRef().mOwner.empty())
|
||||
victim = MWBase::Environment::get().getWorld()->getPtr(bed.getCellRef().mOwner, true);
|
||||
|
||||
const std::string& faction = item.getCellRef().mFaction;
|
||||
bool isFactionOwned = false;
|
||||
if (!faction.empty())
|
||||
if(commitCrime(ptr, victim, OT_SleepingInOwnedBed))
|
||||
{
|
||||
const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks();
|
||||
if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end())
|
||||
isFactionOwned = true;
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage64}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isOwned && !isFactionOwned)
|
||||
void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
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