forked from mirror/openmw-tes3mp
added get, set and mod instructions for health, magicka and fatigue
This commit is contained in:
parent
089a385686
commit
9e9b014f1d
5 changed files with 379 additions and 94 deletions
|
@ -8,6 +8,7 @@ namespace MWMechanics
|
||||||
struct CreatureStats
|
struct CreatureStats
|
||||||
{
|
{
|
||||||
Stat<int> mAttributes[8];
|
Stat<int> mAttributes[8];
|
||||||
|
DynamicStat<int> mDynamic[3]; // health, magicka, fatigue
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,27 +10,27 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
T mBase;
|
T mBase;
|
||||||
T mModified;
|
T mModified;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Stat() : mBase (0), mModified (0) {}
|
Stat() : mBase (0), mModified (0) {}
|
||||||
|
|
||||||
const T& getBase() const
|
const T& getBase() const
|
||||||
{
|
{
|
||||||
return mBase;
|
return mBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& getModified() const
|
const T& getModified() const
|
||||||
{
|
{
|
||||||
return mModified;
|
return mModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set base and modified to \a value.
|
/// Set base and modified to \a value.
|
||||||
void set (const T& value)
|
void set (const T& value)
|
||||||
{
|
{
|
||||||
mBase = mModified = value;
|
mBase = mModified = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set base and adjust modified accordingly.
|
/// Set base and adjust modified accordingly.
|
||||||
void setBase (const T& value)
|
void setBase (const T& value)
|
||||||
{
|
{
|
||||||
|
@ -38,12 +38,12 @@ namespace MWMechanics
|
||||||
mBase = value;
|
mBase = value;
|
||||||
mModified += diff;
|
mModified += diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set modified value an adjust base accordingly.
|
/// Set modified value an adjust base accordingly.
|
||||||
void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max())
|
void setModified (T value, const T& min, const T& max = std::numeric_limits<T>::max())
|
||||||
{
|
{
|
||||||
T diff = value - mModified;
|
T diff = value - mModified;
|
||||||
|
|
||||||
if (mBase+diff<min)
|
if (mBase+diff<min)
|
||||||
{
|
{
|
||||||
value = min + (mModified - mBase);
|
value = min + (mModified - mBase);
|
||||||
|
@ -54,31 +54,110 @@ namespace MWMechanics
|
||||||
value = max + (mModified - mBase);
|
value = max + (mModified - mBase);
|
||||||
diff = value - mModified;
|
diff = value - mModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
mModified = value;
|
mModified = value;
|
||||||
mBase += diff;
|
mBase += diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change modified relatively.
|
/// Change modified relatively.
|
||||||
void modify (const T& diff)
|
void modify (const T& diff)
|
||||||
{
|
{
|
||||||
mModified += diff;
|
mModified += diff;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool operator== (const Stat<T>& left, const Stat<T>& right)
|
inline bool operator== (const Stat<T>& left, const Stat<T>& right)
|
||||||
{
|
{
|
||||||
return left.getBase()==right.getBase() &&
|
return left.getBase()==right.getBase() &&
|
||||||
left.getModified()==right.getModified();
|
left.getModified()==right.getModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool operator!= (const Stat<T>& left, const Stat<T>& right)
|
inline bool operator!= (const Stat<T>& left, const Stat<T>& right)
|
||||||
{
|
{
|
||||||
return !(left==right);
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -66,5 +66,10 @@ op 0x2000037-0x200003e: SetAttribute
|
||||||
op 0x200003f-0x2000046: SetAttribute, explicit reference
|
op 0x200003f-0x2000046: SetAttribute, explicit reference
|
||||||
op 0x2000047-0x200004e: ModAttribute
|
op 0x2000047-0x200004e: ModAttribute
|
||||||
op 0x200004f-0x2000056: ModAttribute, explicit reference
|
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
|
||||||
|
|
|
@ -16,32 +16,32 @@ namespace MWScript
|
||||||
class OpGetAttribute : public Interpreter::Opcode0
|
class OpGetAttribute : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OpGetAttribute (int index) : mIndex (index) {}
|
OpGetAttribute (int index) : mIndex (index) {}
|
||||||
|
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWScript::InterpreterContext& context
|
MWScript::InterpreterContext& context
|
||||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
Interpreter::Type_Integer value =
|
Interpreter::Type_Integer value =
|
||||||
context.getReference().getCreatureStats().mAttributes[mIndex].
|
context.getReference().getCreatureStats().mAttributes[mIndex].
|
||||||
getModified();
|
getModified();
|
||||||
|
|
||||||
runtime.push (value);
|
runtime.push (value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpGetAttributeExplicit : public Interpreter::Opcode0
|
class OpGetAttributeExplicit : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OpGetAttributeExplicit (int index) : mIndex (index) {}
|
OpGetAttributeExplicit (int index) : mIndex (index) {}
|
||||||
|
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWScript::InterpreterContext& context
|
MWScript::InterpreterContext& context
|
||||||
|
@ -49,44 +49,44 @@ namespace MWScript
|
||||||
|
|
||||||
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
Interpreter::Type_Integer value =
|
Interpreter::Type_Integer value =
|
||||||
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
|
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
|
||||||
getModified();
|
getModified();
|
||||||
|
|
||||||
runtime.push (value);
|
runtime.push (value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpSetAttribute : public Interpreter::Opcode0
|
class OpSetAttribute : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OpSetAttribute (int index) : mIndex (index) {}
|
OpSetAttribute (int index) : mIndex (index) {}
|
||||||
|
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWScript::InterpreterContext& context
|
MWScript::InterpreterContext& context
|
||||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
context.getReference().getCreatureStats().mAttributes[mIndex].
|
context.getReference().getCreatureStats().mAttributes[mIndex].
|
||||||
setModified (value, 0);
|
setModified (value, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpSetAttributeExplicit : public Interpreter::Opcode0
|
class OpSetAttributeExplicit : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OpSetAttributeExplicit (int index) : mIndex (index) {}
|
OpSetAttributeExplicit (int index) : mIndex (index) {}
|
||||||
|
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWScript::InterpreterContext& context
|
MWScript::InterpreterContext& context
|
||||||
|
@ -100,41 +100,41 @@ namespace MWScript
|
||||||
|
|
||||||
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
|
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
|
||||||
setModified (value, 0);
|
setModified (value, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpModAttribute : public Interpreter::Opcode0
|
class OpModAttribute : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OpModAttribute (int index) : mIndex (index) {}
|
OpModAttribute (int index) : mIndex (index) {}
|
||||||
|
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWScript::InterpreterContext& context
|
MWScript::InterpreterContext& context
|
||||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
value += context.getReference().getCreatureStats().mAttributes[mIndex].
|
value += context.getReference().getCreatureStats().mAttributes[mIndex].
|
||||||
getModified();
|
getModified();
|
||||||
|
|
||||||
context.getReference().getCreatureStats().mAttributes[mIndex].
|
context.getReference().getCreatureStats().mAttributes[mIndex].
|
||||||
setModified (value, 0, 100);
|
setModified (value, 0, 100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpModAttributeExplicit : public Interpreter::Opcode0
|
class OpModAttributeExplicit : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OpModAttributeExplicit (int index) : mIndex (index) {}
|
OpModAttributeExplicit (int index) : mIndex (index) {}
|
||||||
|
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWScript::InterpreterContext& context
|
MWScript::InterpreterContext& context
|
||||||
|
@ -151,10 +151,165 @@ namespace MWScript
|
||||||
getModified();
|
getModified();
|
||||||
|
|
||||||
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
|
context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex].
|
||||||
setModified (value, 0, 100);
|
setModified (value, 0, 100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 numberOfAttributes = 8;
|
||||||
|
|
||||||
const int opcodeGetAttribute = 0x2000027;
|
const int opcodeGetAttribute = 0x2000027;
|
||||||
|
@ -163,7 +318,16 @@ namespace MWScript
|
||||||
const int opcodeSetAttributeExplicit = 0x200003f;
|
const int opcodeSetAttributeExplicit = 0x200003f;
|
||||||
const int opcodeModAttribute = 0x2000047;
|
const int opcodeModAttribute = 0x2000047;
|
||||||
const int opcodeModAttributeExplicit = 0x200004f;
|
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)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
static const char *attributes[numberOfAttributes] =
|
static const char *attributes[numberOfAttributes] =
|
||||||
|
@ -171,11 +335,16 @@ namespace MWScript
|
||||||
"strength", "intelligence", "willpower", "agility", "speed", "endurance",
|
"strength", "intelligence", "willpower", "agility", "speed", "endurance",
|
||||||
"personality", "luck"
|
"personality", "luck"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *dynamics[numberOfDynamics] =
|
||||||
|
{
|
||||||
|
"health", "magicka", "fatigue"
|
||||||
|
};
|
||||||
|
|
||||||
std::string get ("get");
|
std::string get ("get");
|
||||||
std::string set ("set");
|
std::string set ("set");
|
||||||
std::string mod ("mod");
|
std::string mod ("mod");
|
||||||
|
|
||||||
for (int i=0; i<numberOfAttributes; ++i)
|
for (int i=0; i<numberOfAttributes; ++i)
|
||||||
{
|
{
|
||||||
extensions.registerFunction (get + attributes[i], 'l', "",
|
extensions.registerFunction (get + attributes[i], 'l', "",
|
||||||
|
@ -185,10 +354,22 @@ namespace MWScript
|
||||||
opcodeSetAttribute+i, opcodeSetAttributeExplicit+i);
|
opcodeSetAttribute+i, opcodeSetAttributeExplicit+i);
|
||||||
|
|
||||||
extensions.registerInstruction (mod + attributes[i], "l",
|
extensions.registerInstruction (mod + attributes[i], "l",
|
||||||
opcodeModAttribute+i, opcodeModAttributeExplicit+i);
|
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)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
for (int i=0; i<numberOfAttributes; ++i)
|
for (int i=0; i<numberOfAttributes; ++i)
|
||||||
|
@ -196,16 +377,30 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (opcodeGetAttribute+i, new OpGetAttribute (i));
|
interpreter.installSegment5 (opcodeGetAttribute+i, new OpGetAttribute (i));
|
||||||
interpreter.installSegment5 (opcodeGetAttributeExplicit+i,
|
interpreter.installSegment5 (opcodeGetAttributeExplicit+i,
|
||||||
new OpGetAttributeExplicit (i));
|
new OpGetAttributeExplicit (i));
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeSetAttribute+i, new OpSetAttribute (i));
|
interpreter.installSegment5 (opcodeSetAttribute+i, new OpSetAttribute (i));
|
||||||
interpreter.installSegment5 (opcodeSetAttributeExplicit+i,
|
interpreter.installSegment5 (opcodeSetAttributeExplicit+i,
|
||||||
new OpSetAttributeExplicit (i));
|
new OpSetAttributeExplicit (i));
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeModAttribute+i, new OpModAttribute (i));
|
interpreter.installSegment5 (opcodeModAttribute+i, new OpModAttribute (i));
|
||||||
interpreter.installSegment5 (opcodeModAttributeExplicit+i,
|
interpreter.installSegment5 (opcodeModAttributeExplicit+i,
|
||||||
new OpModAttributeExplicit (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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,33 +16,33 @@
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
/// \brief Pointer to a LiveCellRef
|
/// \brief Pointer to a LiveCellRef
|
||||||
|
|
||||||
class Ptr
|
class Ptr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef ESMS::CellStore<RefData> CellStore;
|
typedef ESMS::CellStore<RefData> CellStore;
|
||||||
|
|
||||||
boost::any mPtr;
|
boost::any mPtr;
|
||||||
ESM::CellRef *mCellRef;
|
ESM::CellRef *mCellRef;
|
||||||
RefData *mRefData;
|
RefData *mRefData;
|
||||||
CellStore *mCell;
|
CellStore *mCell;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Ptr() : mCellRef (0), mRefData (0), mCell (0) {}
|
Ptr() : mCellRef (0), mRefData (0), mCell (0) {}
|
||||||
|
|
||||||
bool isEmpty() const
|
bool isEmpty() const
|
||||||
{
|
{
|
||||||
return mPtr.empty();
|
return mPtr.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::type_info& getType()
|
const std::type_info& getType()
|
||||||
{
|
{
|
||||||
assert (!mPtr.empty());
|
assert (!mPtr.empty());
|
||||||
return mPtr.type();
|
return mPtr.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef, CellStore *cell)
|
Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef, CellStore *cell)
|
||||||
{
|
{
|
||||||
|
@ -51,45 +51,45 @@ namespace MWWorld
|
||||||
mRefData = &liveCellRef->mData;
|
mRefData = &liveCellRef->mData;
|
||||||
mCell = cell;
|
mCell = cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ESMS::LiveCellRef<T, RefData> *get() const
|
ESMS::LiveCellRef<T, RefData> *get() const
|
||||||
{
|
{
|
||||||
return boost::any_cast<ESMS::LiveCellRef<T, RefData>*> (mPtr);
|
return boost::any_cast<ESMS::LiveCellRef<T, RefData>*> (mPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESM::CellRef& getCellRef() const
|
ESM::CellRef& getCellRef() const
|
||||||
{
|
{
|
||||||
assert (mCellRef);
|
assert (mCellRef);
|
||||||
return *mCellRef;
|
return *mCellRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefData& getRefData() const
|
RefData& getRefData() const
|
||||||
{
|
{
|
||||||
assert (mRefData);
|
assert (mRefData);
|
||||||
return *mRefData;
|
return *mRefData;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr::CellStore *getCell() const
|
Ptr::CellStore *getCell() const
|
||||||
{
|
{
|
||||||
assert (mCell);
|
assert (mCell);
|
||||||
return mCell;
|
return mCell;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Throws an exception, if the ID type does not support creature stats.
|
/// Throws an exception, if the ID type does not support creature stats.
|
||||||
MWMechanics::CreatureStats& getCreatureStats() const
|
MWMechanics::CreatureStats& getCreatureStats() const
|
||||||
{
|
{
|
||||||
RefData& data = getRefData();
|
RefData& data = getRefData();
|
||||||
|
|
||||||
if (!data.getCreatureStats().get())
|
if (!data.getCreatureStats().get())
|
||||||
{
|
{
|
||||||
if (mPtr.type()==typeid (ESMS::LiveCellRef<ESM::Creature, RefData> *))
|
if (mPtr.type()==typeid (ESMS::LiveCellRef<ESM::Creature, RefData> *))
|
||||||
{
|
{
|
||||||
boost::shared_ptr<MWMechanics::CreatureStats> stats (
|
boost::shared_ptr<MWMechanics::CreatureStats> stats (
|
||||||
new MWMechanics::CreatureStats);
|
new MWMechanics::CreatureStats);
|
||||||
|
|
||||||
ESMS::LiveCellRef<ESM::Creature, RefData> *ref = get<ESM::Creature>();
|
ESMS::LiveCellRef<ESM::Creature, RefData> *ref = get<ESM::Creature>();
|
||||||
|
|
||||||
stats->mAttributes[0].set (ref->base->data.strength);
|
stats->mAttributes[0].set (ref->base->data.strength);
|
||||||
stats->mAttributes[1].set (ref->base->data.intelligence);
|
stats->mAttributes[1].set (ref->base->data.intelligence);
|
||||||
stats->mAttributes[2].set (ref->base->data.willpower);
|
stats->mAttributes[2].set (ref->base->data.willpower);
|
||||||
|
@ -98,6 +98,9 @@ namespace MWWorld
|
||||||
stats->mAttributes[5].set (ref->base->data.endurance);
|
stats->mAttributes[5].set (ref->base->data.endurance);
|
||||||
stats->mAttributes[6].set (ref->base->data.personality);
|
stats->mAttributes[6].set (ref->base->data.personality);
|
||||||
stats->mAttributes[7].set (ref->base->data.luck);
|
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;
|
data.getCreatureStats() = stats;
|
||||||
}
|
}
|
||||||
|
@ -105,9 +108,9 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
boost::shared_ptr<MWMechanics::CreatureStats> stats (
|
boost::shared_ptr<MWMechanics::CreatureStats> stats (
|
||||||
new MWMechanics::CreatureStats);
|
new MWMechanics::CreatureStats);
|
||||||
|
|
||||||
ESMS::LiveCellRef<ESM::NPC, RefData> *ref = get<ESM::NPC>();
|
ESMS::LiveCellRef<ESM::NPC, RefData> *ref = get<ESM::NPC>();
|
||||||
|
|
||||||
stats->mAttributes[0].set (ref->base->npdt52.strength);
|
stats->mAttributes[0].set (ref->base->npdt52.strength);
|
||||||
stats->mAttributes[1].set (ref->base->npdt52.intelligence);
|
stats->mAttributes[1].set (ref->base->npdt52.intelligence);
|
||||||
stats->mAttributes[2].set (ref->base->npdt52.willpower);
|
stats->mAttributes[2].set (ref->base->npdt52.willpower);
|
||||||
|
@ -116,23 +119,26 @@ namespace MWWorld
|
||||||
stats->mAttributes[5].set (ref->base->npdt52.endurance);
|
stats->mAttributes[5].set (ref->base->npdt52.endurance);
|
||||||
stats->mAttributes[6].set (ref->base->npdt52.personality);
|
stats->mAttributes[6].set (ref->base->npdt52.personality);
|
||||||
stats->mAttributes[7].set (ref->base->npdt52.luck);
|
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;
|
data.getCreatureStats() = stats;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw std::runtime_error (
|
throw std::runtime_error (
|
||||||
"CreatureStats not available for this ID type");
|
"CreatureStats not available for this ID type");
|
||||||
}
|
}
|
||||||
|
|
||||||
return *data.getCreatureStats();
|
return *data.getCreatureStats();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator== (const Ptr& left, const Ptr& right)
|
inline bool operator== (const Ptr& left, const Ptr& right)
|
||||||
{
|
{
|
||||||
return left.mRefData==right.mRefData;
|
return left.mRefData==right.mRefData;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!= (const Ptr& left, const Ptr& right)
|
inline bool operator!= (const Ptr& left, const Ptr& right)
|
||||||
{
|
{
|
||||||
return !(left==right);
|
return !(left==right);
|
||||||
|
@ -160,4 +166,3 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue