added get-, set- and mod-instructions for attributes

actorid
Marc Zinnschlag 15 years ago
parent aa4e79c0de
commit 77a0215d53

@ -50,6 +50,7 @@ set(GAMESCRIPT
mwscript/guiextensions.cpp
mwscript/soundextensions.cpp
mwscript/skyextensions.cpp
mwscript/statsextensions.cpp
mwscript/extensions.cpp
mwscript/globalscripts.cpp
)
@ -63,6 +64,7 @@ set(GAMESCRIPT_HEADER
mwscript/guiextensions.hpp
mwscript/soundextensions.hpp
mwscript/skyextensions.hpp
mwscript/statsextensions.hpp
mwscript/extensions.hpp
mwscript/globalscripts.hpp
)

@ -1,6 +1,8 @@
#ifndef GAME_MWMECHANICS_STAT_H
#define GAME_MWMECHANICS_STAT_H
#include <limits>
namespace MWMechanics
{
template<typename T>
@ -37,6 +39,26 @@ namespace MWMechanics
mModified += diff;
}
/// Set modified value an adjust base accordingly.
void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max())
{
T diff = value - mModified;
if (mBase+diff<min)
{
value = min + (mModified - mBase);
diff = value - mModified;
}
else if (mBase>max-diff)
{
value = max + (mModified - mBase);
diff = value - mModified;
}
mModified = value;
mBase += diff;
}
/// Change modified relatively.
void modify (const T& diff)
{

@ -60,5 +60,11 @@ op 0x2000023: TurnMoonRed
op 0x2000024: GetMasserPhase
op 0x2000025: GetSecundaPhase
op 0x2000026: COC
opcodes 0x2000027-0x3ffffff unused
op 0x2000027-0x200002e: GetAttribute
op 0x200002f-0x2000036: GetAttribute, explicit reference
op 0x2000037-0x200003e: SetAttribute
op 0x200003f-0x2000046: SetAttribute, explicit reference
op 0x2000047-0x200004e: ModAttribute
op 0x200004f-0x2000056: ModAttribute, explicit reference
opcodes 0x2000057-0x3ffffff unused

@ -9,6 +9,7 @@
#include "miscextensions.hpp"
#include "guiextensions.hpp"
#include "skyextensions.hpp"
#include "statsextensions.hpp"
namespace MWScript
{
@ -19,6 +20,7 @@ namespace MWScript
Gui::registerExtensions (extensions);
Sound::registerExtensions (extensions);
Sky::registerExtensions (extensions);
Stats::registerExtensions (extensions);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
@ -29,6 +31,7 @@ namespace MWScript
Gui::installOpcodes (interpreter);
Sound::installOpcodes (interpreter);
Sky::installOpcodes (interpreter);
Stats::installOpcodes (interpreter);
}
}

@ -242,7 +242,7 @@ namespace MWScript
MWWorld::Ptr InterpreterContext::getReference()
{
return mReference;
return getReference ("", true);
}
}

@ -0,0 +1,211 @@
#include "statsextensions.hpp"
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include "interpretercontext.hpp"
namespace MWScript
{
namespace Stats
{
class OpGetAttribute : public Interpreter::Opcode0
{
int mIndex;
public:
OpGetAttribute (int index) : mIndex (index) {}
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
Interpreter::Type_Integer value =
context.getReference().getCreatureStats().mAttributes[mIndex].
getModified();
runtime.push (value);
}
};
class OpGetAttributeExplicit : public Interpreter::Opcode0
{
int mIndex;
public:
OpGetAttributeExplicit (int index) : mIndex (index) {}
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer value =
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
getModified();
runtime.push (value);
}
};
class OpSetAttribute : public Interpreter::Opcode0
{
int mIndex;
public:
OpSetAttribute (int index) : mIndex (index) {}
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
context.getReference().getCreatureStats().mAttributes[mIndex].
setModified (value, 0);
}
};
class OpSetAttributeExplicit : public Interpreter::Opcode0
{
int mIndex;
public:
OpSetAttributeExplicit (int index) : mIndex (index) {}
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
setModified (value, 0);
}
};
class OpModAttribute : public Interpreter::Opcode0
{
int mIndex;
public:
OpModAttribute (int index) : mIndex (index) {}
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
value += context.getReference().getCreatureStats().mAttributes[mIndex].
getModified();
context.getReference().getCreatureStats().mAttributes[mIndex].
setModified (value, 0, 100);
}
};
class OpModAttributeExplicit : public Interpreter::Opcode0
{
int mIndex;
public:
OpModAttributeExplicit (int index) : mIndex (index) {}
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer value = runtime[0].mInteger;
runtime.pop();
value +=
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
getModified();
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
setModified (value, 0, 100);
}
};
const int numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027;
const int opcodeGetAttributeExplicit = 0x200002f;
const int opcodeSetAttribute = 0x2000037;
const int opcodeSetAttributeExplicit = 0x200003f;
const int opcodeModAttribute = 0x2000047;
const int opcodeModAttributeExplicit = 0x200004f;
void registerExtensions (Compiler::Extensions& extensions)
{
static const char *attributes[numberOfAttributes] =
{
"strength", "intelligence", "willpower", "agility", "speed", "endurance",
"personality", "luck"
};
std::string get ("get");
std::string set ("set");
std::string mod ("mod");
for (int i=0; i<numberOfAttributes; ++i)
{
extensions.registerFunction (get + attributes[i], 'l', "",
opcodeGetAttribute+i, opcodeGetAttributeExplicit+i);
extensions.registerInstruction (set + attributes[i], "l",
opcodeSetAttribute+i, opcodeSetAttributeExplicit+i);
extensions.registerInstruction (mod + attributes[i], "l",
opcodeModAttribute+i, opcodeModAttributeExplicit+i);
}
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
for (int i=0; i<numberOfAttributes; ++i)
{
interpreter.installSegment5 (opcodeGetAttribute+i, new OpGetAttribute (i));
interpreter.installSegment5 (opcodeGetAttributeExplicit+i,
new OpGetAttributeExplicit (i));
interpreter.installSegment5 (opcodeSetAttribute+i, new OpSetAttribute (i));
interpreter.installSegment5 (opcodeSetAttributeExplicit+i,
new OpSetAttributeExplicit (i));
interpreter.installSegment5 (opcodeModAttribute+i, new OpModAttribute (i));
interpreter.installSegment5 (opcodeModAttributeExplicit+i,
new OpModAttributeExplicit (i));
}
}
}
}

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_STATSEXTENSIONS_H
#define GAME_SCRIPT_STATSEXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief stats-related script functionality (creatures and NPCs)
namespace Stats
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

@ -79,8 +79,8 @@ namespace MWWorld
{
if (mPtr.type()==typeid (ESMS::LiveCellRef<ESM::Creature, RefData> *))
{
boost::shared_ptr<MWMechanics::CreatureStats> stats;
data.getCreatureStats() = stats;
boost::shared_ptr<MWMechanics::CreatureStats> stats (
new MWMechanics::CreatureStats);
ESMS::LiveCellRef<ESM::Creature, RefData> *ref = get<ESM::Creature>();
@ -92,11 +92,13 @@ namespace MWWorld
stats->mAttributes[5].set (ref->base->data.endurance);
stats->mAttributes[6].set (ref->base->data.personality);
stats->mAttributes[7].set (ref->base->data.luck);
data.getCreatureStats() = stats;
}
else if (mPtr.type()==typeid (ESMS::LiveCellRef<ESM::NPC, RefData> *))
{
boost::shared_ptr<MWMechanics::CreatureStats> stats;
data.getCreatureStats() = stats;
boost::shared_ptr<MWMechanics::CreatureStats> stats (
new MWMechanics::CreatureStats);
ESMS::LiveCellRef<ESM::NPC, RefData> *ref = get<ESM::NPC>();
@ -108,6 +110,8 @@ namespace MWWorld
stats->mAttributes[5].set (ref->base->npdt52.endurance);
stats->mAttributes[6].set (ref->base->npdt52.personality);
stats->mAttributes[7].set (ref->base->npdt52.luck);
data.getCreatureStats() = stats;
}
else
throw std::runtime_error (

Loading…
Cancel
Save