Implement Trespassing crime

This commit is contained in:
scrawl 2014-01-10 21:26:24 +01:00
parent f5a70dccf0
commit 3bf36515d5
7 changed files with 32 additions and 17 deletions

View file

@ -112,6 +112,8 @@ namespace MWBase
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;
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 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;

View file

@ -19,7 +19,7 @@
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)
bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim)
{
const std::string& owner = item.getCellRef().mOwner;
bool isOwned = !owner.empty();
@ -33,6 +33,9 @@ namespace
isFactionOwned = true;
}
if (!item.getCellRef().mOwner.empty())
victim = MWBase::Environment::get().getWorld()->getPtr(item.getCellRef().mOwner, true);
return (!isOwned && !isFactionOwned);
}
}
@ -752,11 +755,9 @@ namespace MWMechanics
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 (isAllowedToUse(ptr, bed, victim))
return false;
if(commitCrime(ptr, victim, OT_SleepingInOwnedBed))
{
@ -767,14 +768,19 @@ namespace MWMechanics
return false;
}
void MechanicsManager::objectOpened(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item)
{
MWWorld::Ptr victim;
if (isAllowedToUse(ptr, item, victim))
return;
commitCrime(ptr, victim, OT_Trespassing);
}
void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, int count)
{
if (isAllowedToUse(ptr, item))
return;
MWWorld::Ptr victim;
if (!item.getCellRef().mOwner.empty())
victim = MWBase::Environment::get().getWorld()->getPtr(item.getCellRef().mOwner, true);
if (isAllowedToUse(ptr, item, victim))
return;
commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count);
}

View file

@ -113,6 +113,8 @@ namespace MWMechanics
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);
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item);
/// 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);

View file

@ -6,6 +6,7 @@
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "npcstats.hpp"
#include "creaturestats.hpp"
@ -45,6 +46,7 @@ namespace MWMechanics
resultMessage = "#{sLockImpossible}";
else
{
MWBase::Environment::get().getMechanicsManager()->objectOpened(mActor, lock);
int roll = static_cast<float> (std::rand()) / RAND_MAX * 100;
if (roll <= x)
{
@ -86,6 +88,7 @@ namespace MWMechanics
resultMessage = "#{sTrapImpossible}";
else
{
MWBase::Environment::get().getMechanicsManager()->objectOpened(mActor, trap);
int roll = static_cast<float> (std::rand()) / RAND_MAX * 100;
if (roll <= x)
{

View file

@ -4,7 +4,7 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/actionteleport.hpp"
@ -167,7 +167,7 @@ namespace MWMechanics
}
}
else
applyInstantEffect(target, EffectKey(*effectIt), magnitude);
applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude);
// HACK: Damage attribute/skill actually has a duration, even though the actual effect is instant and permanent.
// This was probably just done to have the effect visible in the magic menu for a while
@ -177,7 +177,7 @@ namespace MWMechanics
|| effectIt->mEffectID == ESM::MagicEffect::RestoreAttribute
|| effectIt->mEffectID == ESM::MagicEffect::RestoreSkill
)
applyInstantEffect(target, EffectKey(*effectIt), magnitude);
applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude);
if (target.getClass().isActor() || magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)
{
@ -220,7 +220,7 @@ namespace MWMechanics
mSourceName, caster.getRefData().getHandle());
}
void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, MWMechanics::EffectKey effect, float magnitude)
void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, MWMechanics::EffectKey effect, float magnitude)
{
short effectId = effect.mId;
if (!target.getClass().isActor())
@ -232,11 +232,13 @@ namespace MWMechanics
}
else if (effectId == ESM::MagicEffect::Open)
{
// TODO: This is a crime
if (target.getCellRef().mLockLevel <= magnitude)
{
if (target.getCellRef().mLockLevel > 0)
{
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target);
}
target.getCellRef().mLockLevel = 0;
}
else

View file

@ -203,7 +203,7 @@ namespace MWMechanics
void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster,
const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false);
void applyInstantEffect (const MWWorld::Ptr& target, MWMechanics::EffectKey effect, float magnitude);
void applyInstantEffect (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, MWMechanics::EffectKey effect, float magnitude);
};
}

View file

@ -392,7 +392,7 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor)
// Apply instant effects
MWMechanics::CastSpell cast(actor, actor);
if (magnitude)
cast.applyInstantEffect(actor, effectIt->mEffectID, magnitude);
cast.applyInstantEffect(actor, actor, effectIt->mEffectID, magnitude);
}
if (magnitude)