You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw-tes3mp/apps/openmw/mwscript/miscextensions.cpp

684 lines
27 KiB
C++

#include "miscextensions.hpp"
#include <libs/openengine/ogre/fader.hpp>
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwmechanics/npcstats.hpp"
12 years ago
#include "../mwmechanics/creaturestats.hpp"
#include "interpretercontext.hpp"
#include "ref.hpp"
namespace MWScript
{
namespace Misc
{
12 years ago
class OpPlayBink : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
bool allowSkipping = runtime[0].mInteger;
runtime.pop();
MWBase::Environment::get().getWorld ()->playVideo (name, allowSkipping);
12 years ago
}
};
class OpGetPcSleep : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.push (MWBase::Environment::get().getWindowManager ()->getPlayerSleeping());
}
};
class OpWakeUpPc : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWBase::Environment::get().getWindowManager ()->wakeUpPlayer();
}
};
class OpXBox : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.push (0);
}
};
15 years ago
class OpOnActivate : public Interpreter::Opcode0
{
public:
15 years ago
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
MWWorld::Ptr ptr = context.getReference();
runtime.push (context.hasBeenActivated (ptr));
}
15 years ago
};
class OpActivate : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
MWWorld::Ptr ptr = context.getReference();
context.executeActivation();
}
};
template<class R>
class OpLock : public Interpreter::Opcode1
{
public:
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer lockLevel = 100;
if (arg0==1)
{
lockLevel = runtime[0].mInteger;
runtime.pop();
}
MWWorld::Class::get (ptr).lock (ptr, lockLevel);
}
};
template<class R>
class OpUnlock : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWWorld::Class::get (ptr).unlock (ptr);
}
};
class OpToggleCollisionDebug : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
bool enabled =
MWBase::Environment::get().getWorld()->toggleRenderMode (MWBase::World::Render_CollisionDebug);
context.report (enabled ?
"Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off");
}
};
class OpToggleCollisionBoxes : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
bool enabled =
MWBase::Environment::get().getWorld()->toggleRenderMode (MWBase::World::Render_BoundingBoxes);
context.report (enabled ?
"Bounding Box Rendering -> On" : "Bounding Box Rendering -> Off");
}
};
class OpToggleWireframe : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
bool enabled =
MWBase::Environment::get().getWorld()->toggleRenderMode (MWBase::World::Render_Wireframe);
context.report (enabled ?
"Wireframe Rendering -> On" : "Wireframe Rendering -> Off");
}
};
13 years ago
class OpTogglePathgrid : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
bool enabled =
MWBase::Environment::get().getWorld()->toggleRenderMode (MWBase::World::Render_Pathgrid);
context.report (enabled ?
"Path Grid rendering -> On" : "Path Grid Rendering -> Off");
}
};
class OpFadeIn : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->getFader()->fadeIn(time);
}
};
class OpFadeOut : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->getFader()->fadeOut(time);
}
};
class OpFadeTo : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
Interpreter::Type_Float alpha = runtime[0].mFloat;
runtime.pop();
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->getFader()->fadeTo(alpha, time);
}
};
class OpToggleWater : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWBase::Environment::get().getWorld()->toggleWater();
}
};
class OpDontSaveObject : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
// We are ignoring the DontSaveObject statement for now. Probably not worth
/// bothering with. The incompatibility we are creating should be marginal at most.
}
};
class OpToggleVanityMode : public Interpreter::Opcode0
{
static bool sActivate;
public:
virtual void execute(Interpreter::Runtime &runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
MWBase::World *world =
MWBase::Environment::get().getWorld();
if (world->toggleVanityMode(sActivate, true)) {
context.report(
(sActivate) ? "Vanity Mode -> On" : "Vanity Mode -> Off"
);
sActivate = !sActivate;
} else {
context.report("Vanity Mode -> No");
}
}
};
bool OpToggleVanityMode::sActivate = true;
12 years ago
template <class R>
class OpGetLocked : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push (ptr.getCellRef ().mLockLevel > 0);
}
};
12 years ago
template <class R>
class OpGetEffect : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
int key = runtime[0].mInteger;
runtime.pop();
runtime.push (MWWorld::Class::get(ptr).getCreatureStats (ptr).getMagicEffects ().get (
MWMechanics::EffectKey(key)).mMagnitude > 0);
}
};
template<class R>
class OpAddSoulGem : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string creature = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
std::string gem = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), gem);
ref.getPtr().getRefData().setCount (1);
ref.getPtr().getCellRef().mSoul = creature;
MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());
}
};
12 years ago
template<class R>
class OpRemoveSoulGem : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string soul = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
{
if (::Misc::StringUtils::ciEqual(iter->getCellRef().mSoul, soul))
{
if (iter->getRefData().getCount() <= 1)
iter->getRefData().setCount (0);
else
iter->getRefData().setCount (iter->getRefData().getCount() - 1);
break;
}
}
}
};
template<class R>
class OpDrop : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer amount = runtime[0].mInteger;
runtime.pop();
MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
{
if (::Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item))
{
if(iter->getRefData().getCount() <= amount)
{
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
iter->getRefData().setCount(0);
}
else
{
int original = iter->getRefData().getCount();
iter->getRefData().setCount(amount);
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
iter->getRefData().setCount(original - amount);
}
break;
}
}
}
};
template<class R>
class OpDropSoulGem : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string soul = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
{
if (::Misc::StringUtils::ciEqual(iter->getCellRef().mSoul, soul))
{
if(iter->getRefData().getCount() <= 1)
{
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
iter->getRefData().setCount(0);
}
else
{
int original = iter->getRefData().getCount();
iter->getRefData().setCount(1);
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter);
iter->getRefData().setCount(original - 1);
}
break;
}
}
}
};
12 years ago
template <class R>
class OpGetAttacked : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(MWWorld::Class::get(ptr).getCreatureStats (ptr).getAttacked ());
}
};
12 years ago
template <class R>
class OpGetWeaponDrawn : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(MWWorld::Class::get(ptr).getNpcStats (ptr).getDrawState () == MWMechanics::DrawState_Weapon);
}
};
template <class R>
class OpGetSpellEffects : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string id = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop();
runtime.push(MWWorld::Class::get(ptr).getCreatureStats(ptr).getActiveSpells().isSpellActive(id));
}
};
class OpGetCurrentTime : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.push(MWBase::Environment::get().getWorld()->getTimeStamp().getHour());
}
};
template <class R>
class OpSetDelete : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
int parameter = runtime[0].mInteger;
runtime.pop();
if (parameter == 1)
{
if (ptr.isInCell())
MWBase::Environment::get().getWorld()->deleteObject (ptr);
else
ptr.getRefData().setCount(0);
}
}
};
class OpGetSquareRoot : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
float param = runtime[0].mFloat;
runtime.pop();
runtime.push(std::sqrt (param));
}
};
const int opcodeXBox = 0x200000c;
const int opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075;
const int opcodeLock = 0x20004;
const int opcodeLockExplicit = 0x20005;
const int opcodeUnlock = 0x200008c;
const int opcodeUnlockExplicit = 0x200008d;
const int opcodeToggleCollisionDebug = 0x2000132;
const int opcodeToggleCollisionBoxes = 0x20001ac;
const int opcodeToggleWireframe = 0x200013b;
const int opcodeFadeIn = 0x200013c;
const int opcodeFadeOut = 0x200013d;
const int opcodeFadeTo = 0x200013e;
const int opcodeToggleWater = 0x2000144;
const int opcodeTogglePathgrid = 0x2000146;
const int opcodeDontSaveObject = 0x2000153;
const int opcodeToggleVanityMode = 0x2000174;
const int opcodeGetPcSleep = 0x200019f;
const int opcodeWakeUpPc = 0x20001a2;
12 years ago
const int opcodeGetLocked = 0x20001c7;
const int opcodeGetLockedExplicit = 0x20001c8;
12 years ago
const int opcodeGetEffect = 0x20001cf;
const int opcodeGetEffectExplicit = 0x20001d0;
const int opcodeAddSoulGem = 0x20001f3;
const int opcodeAddSoulGemExplicit = 0x20001f4;
const int opcodeRemoveSoulGem = 0x20001f5;
const int opcodeRemoveSoulGemExplicit = 0x20001f6;
const int opcodeDrop = 0x20001f8;
const int opcodeDropExplicit = 0x20001f9;
const int opcodeDropSoulGem = 0x20001fa;
const int opcodeDropSoulGemExplicit = 0x20001fb;
12 years ago
const int opcodeGetAttacked = 0x20001d3;
const int opcodeGetAttackedExplicit = 0x20001d4;
12 years ago
const int opcodeGetWeaponDrawn = 0x20001d7;
const int opcodeGetWeaponDrawnExplicit = 0x20001d8;
const int opcodeGetSpellEffects = 0x20001db;
const int opcodeGetSpellEffectsExplicit = 0x20001dc;
const int opcodeGetCurrentTime = 0x20001dd;
const int opcodeSetDelete = 0x20001e5;
const int opcodeSetDeleteExplicit = 0x20001e6;
const int opcodeGetSquareRoot = 0x20001e7;
const int opcodePlayBink = 0x20001f7;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerFunction ("xbox", 'l', "", opcodeXBox);
15 years ago
extensions.registerFunction ("onactivate", 'l', "", opcodeOnActivate);
extensions.registerInstruction ("activate", "", opcodeActivate);
extensions.registerInstruction ("lock", "/l", opcodeLock, opcodeLockExplicit);
extensions.registerInstruction ("unlock", "", opcodeUnlock, opcodeUnlockExplicit);
extensions.registerInstruction ("togglecollisionboxes", "", opcodeToggleCollisionBoxes);
extensions.registerInstruction ("togglecollisiongrid", "", opcodeToggleCollisionDebug);
extensions.registerInstruction ("tcb", "", opcodeToggleCollisionBoxes);
extensions.registerInstruction ("tcg", "", opcodeToggleCollisionDebug);
extensions.registerInstruction ("twf", "", opcodeToggleWireframe);
extensions.registerInstruction ("togglewireframe", "", opcodeToggleWireframe);
extensions.registerInstruction ("fadein", "f", opcodeFadeIn);
extensions.registerInstruction ("fadeout", "f", opcodeFadeOut);
extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
extensions.registerInstruction ("togglewater", "", opcodeToggleWater);
extensions.registerInstruction ("twa", "", opcodeToggleWater);
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep);
extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc);
extensions.registerInstruction ("playbink", "Sl", opcodePlayBink);
12 years ago
extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit);
12 years ago
extensions.registerFunction ("geteffect", 'l', "l", opcodeGetEffect, opcodeGetEffectExplicit);
extensions.registerInstruction ("addsoulgem", "cc", opcodeAddSoulGem, opcodeAddSoulGemExplicit);
extensions.registerInstruction ("removesoulgem", "c", opcodeRemoveSoulGem, opcodeRemoveSoulGemExplicit);
extensions.registerInstruction ("drop", "cl", opcodeDrop, opcodeDropExplicit);
extensions.registerInstruction ("dropsoulgem", "c", opcodeDropSoulGem, opcodeDropSoulGemExplicit);
12 years ago
extensions.registerFunction ("getattacked", 'l', "", opcodeGetAttacked, opcodeGetAttackedExplicit);
12 years ago
extensions.registerFunction ("getweapondrawn", 'l', "", opcodeGetWeaponDrawn, opcodeGetWeaponDrawnExplicit);
extensions.registerFunction ("getspelleffects", 'l', "c", opcodeGetSpellEffects, opcodeGetSpellEffectsExplicit);
extensions.registerFunction ("getcurrenttime", 'f', "", opcodeGetCurrentTime);
extensions.registerInstruction ("setdelete", "l", opcodeSetDelete, opcodeSetDeleteExplicit);
extensions.registerFunction ("getsquareroot", 'f', "f", opcodeGetSquareRoot);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (opcodeXBox, new OpXBox);
15 years ago
interpreter.installSegment5 (opcodeOnActivate, new OpOnActivate);
interpreter.installSegment5 (opcodeActivate, new OpActivate);
interpreter.installSegment3 (opcodeLock, new OpLock<ImplicitRef>);
interpreter.installSegment3 (opcodeLockExplicit, new OpLock<ExplicitRef>);
interpreter.installSegment5 (opcodeUnlock, new OpUnlock<ImplicitRef>);
interpreter.installSegment5 (opcodeUnlockExplicit, new OpUnlock<ExplicitRef>);
interpreter.installSegment5 (opcodeToggleCollisionDebug, new OpToggleCollisionDebug);
interpreter.installSegment5 (opcodeToggleCollisionBoxes, new OpToggleCollisionBoxes);
interpreter.installSegment5 (opcodeToggleWireframe, new OpToggleWireframe);
interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn);
interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut);
interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo);
13 years ago
interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid);
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject);
interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode);
interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep);
interpreter.installSegment5 (opcodeWakeUpPc, new OpWakeUpPc);
12 years ago
interpreter.installSegment5 (opcodePlayBink, new OpPlayBink);
12 years ago
interpreter.installSegment5 (opcodeGetLocked, new OpGetLocked<ImplicitRef>);
interpreter.installSegment5 (opcodeGetLockedExplicit, new OpGetLocked<ExplicitRef>);
12 years ago
interpreter.installSegment5 (opcodeGetEffect, new OpGetEffect<ImplicitRef>);
interpreter.installSegment5 (opcodeGetEffectExplicit, new OpGetEffect<ExplicitRef>);
interpreter.installSegment5 (opcodeAddSoulGem, new OpAddSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeAddSoulGemExplicit, new OpAddSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeRemoveSoulGem, new OpRemoveSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeRemoveSoulGemExplicit, new OpRemoveSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeDrop, new OpDrop<ImplicitRef>);
interpreter.installSegment5 (opcodeDropExplicit, new OpDrop<ExplicitRef>);
interpreter.installSegment5 (opcodeDropSoulGem, new OpDropSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeDropSoulGemExplicit, new OpDropSoulGem<ExplicitRef>);
12 years ago
interpreter.installSegment5 (opcodeGetAttacked, new OpGetAttacked<ImplicitRef>);
interpreter.installSegment5 (opcodeGetAttackedExplicit, new OpGetAttacked<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponDrawn, new OpGetWeaponDrawn<ImplicitRef>);
12 years ago
interpreter.installSegment5 (opcodeGetWeaponDrawnExplicit, new OpGetWeaponDrawn<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSpellEffects, new OpGetSpellEffects<ImplicitRef>);
interpreter.installSegment5 (opcodeGetSpellEffectsExplicit, new OpGetSpellEffects<ExplicitRef>);
interpreter.installSegment5 (opcodeGetCurrentTime, new OpGetCurrentTime);
interpreter.installSegment5 (opcodeSetDelete, new OpSetDelete<ImplicitRef>);
interpreter.installSegment5 (opcodeSetDeleteExplicit, new OpSetDelete<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSquareRoot, new OpGetSquareRoot);
}
}
}