forked from mirror/openmw-tes3mp
added get, set and mod instructions for health, magicka and fatigue
This commit is contained in:
parent
63f686ffab
commit
455bcf3b01
5 changed files with 379 additions and 94 deletions
|
@ -8,6 +8,7 @@ namespace MWMechanics
|
|||
struct CreatureStats
|
||||
{
|
||||
Stat<int> mAttributes[8];
|
||||
DynamicStat<int> mDynamic[3]; // health, magicka, fatigue
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,86 @@ namespace MWMechanics
|
|||
{
|
||||
return !(left==right);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class DynamicStat
|
||||
{
|
||||
Stat<T> mStatic;
|
||||
T mCurrent;
|
||||
|
||||
public:
|
||||
|
||||
const T& getBase() const
|
||||
{
|
||||
return mStatic.getBase();
|
||||
}
|
||||
|
||||
const T& getModified() const
|
||||
{
|
||||
return mStatic.getModified();
|
||||
}
|
||||
|
||||
const T& getCurrent() const
|
||||
{
|
||||
return mCurrent;
|
||||
}
|
||||
|
||||
/// Set base, modified and current to \a value.
|
||||
void set (const T& value)
|
||||
{
|
||||
mStatic.set (value);
|
||||
mCurrent = value;
|
||||
}
|
||||
|
||||
/// Set base and adjust modified accordingly.
|
||||
void setBase (const T& value)
|
||||
{
|
||||
mStatic.setBase (value);
|
||||
|
||||
if (mCurrent>getModified())
|
||||
mCurrent = getModified();
|
||||
}
|
||||
|
||||
/// Set modified value an adjust base accordingly.
|
||||
void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max())
|
||||
{
|
||||
mStatic.setModified (value, min, max);
|
||||
|
||||
if (mCurrent>getModified())
|
||||
mCurrent = getModified();
|
||||
}
|
||||
|
||||
/// Change modified relatively.
|
||||
void modify (const T& diff)
|
||||
{
|
||||
mStatic.modify (diff);
|
||||
modifyCurrent (diff);
|
||||
}
|
||||
|
||||
void setCurrent (const T& value)
|
||||
{
|
||||
mCurrent = value;
|
||||
|
||||
if (mCurrent<0)
|
||||
mCurrent = 0;
|
||||
else if (mCurrent>getModified())
|
||||
mCurrent = getModified();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline bool operator== (const DynamicStat<T>& left, const DynamicStat<T>& right)
|
||||
{
|
||||
return left.getBase()==right.getBase() &&
|
||||
left.getModified()==right.getModified() &&
|
||||
left.getCurrent()==right.getCurrent();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool operator!= (const DynamicStat<T>& left, const DynamicStat<T>& right)
|
||||
{
|
||||
return !(left==right);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -66,5 +66,10 @@ op 0x2000037-0x200003e: SetAttribute
|
|||
op 0x200003f-0x2000046: SetAttribute, explicit reference
|
||||
op 0x2000047-0x200004e: ModAttribute
|
||||
op 0x200004f-0x2000056: ModAttribute, explicit reference
|
||||
opcodes 0x2000057-0x3ffffff unused
|
||||
|
||||
op 0x2000057-0x2000059: GetDynamic (health, magicka, fatigue)
|
||||
op 0x200005a-0x200005c: GetDynamic (health, magicka, fatigue), explicit reference
|
||||
op 0x200005d-0x200005f: SetDynamic (health, magicka, fatigue)
|
||||
op 0x2000060-0x2000062: SetDynamic (health, magicka, fatigue), explicit reference
|
||||
op 0x2000063-0x2000065: ModDynamic (health, magicka, fatigue)
|
||||
op 0x2000066-0x2000068: ModDynamic (health, magicka, fatigue), explicit reference
|
||||
opcodes 0x2000069-0x3ffffff unused
|
||||
|
|
|
@ -155,6 +155,161 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
class OpGetDynamic : public Interpreter::Opcode0
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
|
||||
OpGetDynamic (int index) : mIndex (index) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
if (mIndex==0)
|
||||
{
|
||||
// TODO health is a special case
|
||||
|
||||
|
||||
}
|
||||
|
||||
Interpreter::Type_Integer value =
|
||||
context.getReference().getCreatureStats().mDynamic[mIndex].
|
||||
getCurrent();
|
||||
|
||||
runtime.push (value);
|
||||
}
|
||||
};
|
||||
|
||||
class OpGetDynamicExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
|
||||
OpGetDynamicExplicit (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().mDynamic[mIndex].
|
||||
getCurrent();
|
||||
|
||||
runtime.push (value);
|
||||
}
|
||||
};
|
||||
|
||||
class OpSetDynamic : public Interpreter::Opcode0
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
|
||||
OpSetDynamic (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().mDynamic[mIndex].
|
||||
setModified (value, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class OpSetDynamicExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
|
||||
OpSetDynamicExplicit (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().mDynamic[mIndex].
|
||||
setModified (value, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class OpModDynamic : public Interpreter::Opcode0
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
|
||||
OpModDynamic (int index) : mIndex (index) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
Interpreter::Type_Integer diff = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWMechanics::CreatureStats& stats = context.getReference().getCreatureStats();
|
||||
|
||||
Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent();
|
||||
|
||||
stats.mDynamic[mIndex].setModified (
|
||||
diff + stats.mDynamic[mIndex].getModified(), 0);
|
||||
|
||||
stats.mDynamic[mIndex].setCurrent (diff + current);
|
||||
}
|
||||
};
|
||||
|
||||
class OpModDynamicExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
|
||||
OpModDynamicExplicit (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 diff = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWMechanics::CreatureStats& stats =
|
||||
context.getWorld().getPtr (id, false).getCreatureStats();
|
||||
|
||||
Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent();
|
||||
|
||||
stats.mDynamic[mIndex].setModified (
|
||||
diff + stats.mDynamic[mIndex].getModified(), 0);
|
||||
|
||||
stats.mDynamic[mIndex].setCurrent (diff + current);
|
||||
}
|
||||
};
|
||||
|
||||
const int numberOfAttributes = 8;
|
||||
|
||||
const int opcodeGetAttribute = 0x2000027;
|
||||
|
@ -164,6 +319,15 @@ namespace MWScript
|
|||
const int opcodeModAttribute = 0x2000047;
|
||||
const int opcodeModAttributeExplicit = 0x200004f;
|
||||
|
||||
const int numberOfDynamics = 3;
|
||||
|
||||
const int opcodeGetDynamic = 0x2000057;
|
||||
const int opcodeGetDynamicExplicit = 0x200005a;
|
||||
const int opcodeSetDynamic = 0x200005d;
|
||||
const int opcodeSetDynamicExplicit = 0x2000060;
|
||||
const int opcodeModDynamic = 0x2000063;
|
||||
const int opcodeModDynamicExplicit = 0x2000066;
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions)
|
||||
{
|
||||
static const char *attributes[numberOfAttributes] =
|
||||
|
@ -172,6 +336,11 @@ namespace MWScript
|
|||
"personality", "luck"
|
||||
};
|
||||
|
||||
static const char *dynamics[numberOfDynamics] =
|
||||
{
|
||||
"health", "magicka", "fatigue"
|
||||
};
|
||||
|
||||
std::string get ("get");
|
||||
std::string set ("set");
|
||||
std::string mod ("mod");
|
||||
|
@ -187,6 +356,18 @@ namespace MWScript
|
|||
extensions.registerInstruction (mod + attributes[i], "l",
|
||||
opcodeModAttribute+i, opcodeModAttributeExplicit+i);
|
||||
}
|
||||
|
||||
for (int i=0; i<numberOfDynamics; ++i)
|
||||
{
|
||||
extensions.registerFunction (get + dynamics[i], 'l', "",
|
||||
opcodeGetDynamic+i, opcodeGetDynamicExplicit+i);
|
||||
|
||||
extensions.registerInstruction (set + dynamics[i], "l",
|
||||
opcodeSetDynamic+i, opcodeSetDynamicExplicit+i);
|
||||
|
||||
extensions.registerInstruction (mod + dynamics[i], "l",
|
||||
opcodeModDynamic+i, opcodeModDynamicExplicit+i);
|
||||
}
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
|
@ -205,7 +386,21 @@ namespace MWScript
|
|||
interpreter.installSegment5 (opcodeModAttributeExplicit+i,
|
||||
new OpModAttributeExplicit (i));
|
||||
}
|
||||
|
||||
for (int i=0; i<numberOfDynamics; ++i)
|
||||
{
|
||||
interpreter.installSegment5 (opcodeGetDynamic+i, new OpGetDynamic (i));
|
||||
interpreter.installSegment5 (opcodeGetDynamicExplicit+i,
|
||||
new OpGetDynamicExplicit (i));
|
||||
|
||||
interpreter.installSegment5 (opcodeSetDynamic+i, new OpSetDynamic (i));
|
||||
interpreter.installSegment5 (opcodeSetDynamicExplicit+i,
|
||||
new OpSetDynamicExplicit (i));
|
||||
|
||||
interpreter.installSegment5 (opcodeModDynamic+i, new OpModDynamic (i));
|
||||
interpreter.installSegment5 (opcodeModDynamicExplicit+i,
|
||||
new OpModDynamicExplicit (i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,9 @@ 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);
|
||||
stats->mDynamic[0].set (ref->base->data.health);
|
||||
stats->mDynamic[1].set (ref->base->data.mana);
|
||||
stats->mDynamic[2].set (ref->base->data.fatigue);
|
||||
|
||||
data.getCreatureStats() = stats;
|
||||
}
|
||||
|
@ -116,6 +119,9 @@ 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);
|
||||
stats->mDynamic[0].set (ref->base->npdt52.health);
|
||||
stats->mDynamic[1].set (ref->base->npdt52.mana);
|
||||
stats->mDynamic[2].set (ref->base->npdt52.fatigue);
|
||||
|
||||
data.getCreatureStats() = stats;
|
||||
}
|
||||
|
@ -160,4 +166,3 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue