forked from Mirrors/openclonk
Drop the roundtrip through C4ID for the effect C4Def command target
Unfortunately, this complicates the C4Effect::CompileFunc to stay compatible.liquid_container
parent
632c5cbd0f
commit
bfb9b6b1fd
|
@ -2145,14 +2145,17 @@ static long FnLoadScenarioSection(C4PropList * _this, C4String *pstrSection, lon
|
|||
}
|
||||
|
||||
static C4Value FnAddEffect(C4PropList * _this, C4String * szEffect, C4Object * pTarget,
|
||||
int iPrio, int iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget,
|
||||
int iPrio, int iTimerInterval, C4Object * pCmdTarget, C4Def * idCmdTarget,
|
||||
const C4Value & Val1, const C4Value & Val2, const C4Value & Val3, const C4Value & Val4)
|
||||
{
|
||||
// safety
|
||||
if (pTarget && !pTarget->Status) return C4Value();
|
||||
if (!szEffect || !*szEffect->GetCStr() || !iPrio) return C4Value();
|
||||
// create effect
|
||||
C4Effect * pEffect = C4Effect::New(pTarget, szEffect, iPrio, iTimerInterval, pCmdTarget, idCmdTarget, Val1, Val2, Val3, Val4);
|
||||
C4PropList * p = pCmdTarget;
|
||||
if (!p) p = idCmdTarget;
|
||||
if (!p) p = ::ScriptEngine.GetPropList();
|
||||
C4Effect * pEffect = C4Effect::New(pTarget, szEffect, iPrio, iTimerInterval, p, Val1, Val2, Val3, Val4);
|
||||
// return effect - may be 0 if the effect has been denied by another effect
|
||||
if (!pEffect) return C4Value();
|
||||
return C4VPropList(pEffect);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <C4Include.h>
|
||||
#include <C4Effect.h>
|
||||
|
||||
#include <C4DefList.h>
|
||||
#include <C4Object.h>
|
||||
#include <C4Game.h>
|
||||
|
||||
|
@ -39,27 +38,16 @@ void C4Effect::AssignCallbackFunctions()
|
|||
|
||||
C4PropList * C4Effect::GetCallbackScript()
|
||||
{
|
||||
C4Def *pDef;
|
||||
if (CommandTarget)
|
||||
{
|
||||
// overwrite ID for sync safety in runtime join
|
||||
idCommandTarget = CommandTarget->id;
|
||||
return CommandTarget;
|
||||
}
|
||||
else if (idCommandTarget && (pDef=::Definitions.ID2Def(idCommandTarget)))
|
||||
return pDef;
|
||||
else
|
||||
return ::ScriptEngine.GetPropList();
|
||||
return CommandTarget._getPropList();
|
||||
}
|
||||
|
||||
C4Effect::C4Effect(C4Object *pForObj, C4String *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
|
||||
C4Effect::C4Effect(C4Object *pForObj, C4String *szName, int32_t iPrio, int32_t iTimerInterval, C4PropList *pCmdTarget)
|
||||
{
|
||||
// assign values
|
||||
iPriority = 0; // effect is not yet valid; some callbacks to other effects are done before
|
||||
iInterval = iTimerInterval;
|
||||
iTime = 0;
|
||||
CommandTarget = pCmdTarget;
|
||||
idCommandTarget = idCmdTarget;
|
||||
CommandTarget.SetPropList(pCmdTarget);
|
||||
AcquireNumber();
|
||||
Register(pForObj, iPrio);
|
||||
// Set name and callback functions
|
||||
|
@ -87,9 +75,9 @@ void C4Effect::Register(C4Object *pForObj, int32_t iPrio)
|
|||
}
|
||||
}
|
||||
|
||||
C4Effect * C4Effect::New(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
|
||||
C4Effect * C4Effect::New(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4PropList * pCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
|
||||
{
|
||||
C4Effect * pEffect = new C4Effect(pForObj, szName, iPrio, iTimerInterval, pCmdTarget, idCmdTarget, rVal1, rVal2, rVal3, rVal4);
|
||||
C4Effect * pEffect = new C4Effect(pForObj, szName, iPrio, iTimerInterval, pCmdTarget);
|
||||
// ask all effects with higher priority first - except for prio 1 effects, which are considered out of the priority call chain (as per doc)
|
||||
bool fRemoveUpper = (iPrio != 1);
|
||||
// note that apart from denying the creation of this effect, higher priority effects may also remove themselves
|
||||
|
@ -135,7 +123,7 @@ C4Effect::C4Effect()
|
|||
{
|
||||
// defaults
|
||||
iPriority=iTime=iInterval=0;
|
||||
CommandTarget=NULL;
|
||||
CommandTarget.Set0();
|
||||
pNext = NULL;
|
||||
}
|
||||
|
||||
|
@ -158,7 +146,7 @@ void C4Effect::Denumerate(C4ValueNumbers * numbers)
|
|||
do
|
||||
{
|
||||
// command target
|
||||
pEff->CommandTarget.DenumeratePointers();
|
||||
pEff->CommandTarget.Denumerate(numbers);
|
||||
// assign any callback functions
|
||||
pEff->AssignCallbackFunctions();
|
||||
pEff->C4PropList::Denumerate(numbers);
|
||||
|
@ -166,16 +154,16 @@ void C4Effect::Denumerate(C4ValueNumbers * numbers)
|
|||
while ((pEff=pEff->pNext));
|
||||
}
|
||||
|
||||
void C4Effect::ClearPointers(C4Object *pObj)
|
||||
void C4Effect::ClearPointers(C4PropList *pObj)
|
||||
{
|
||||
// clear pointers in all effects
|
||||
C4Effect *pEff = this;
|
||||
do
|
||||
// command target lost: effect dead w/o callback
|
||||
if (pEff->CommandTarget == pObj)
|
||||
if (pEff->CommandTarget.getPropList() == pObj)
|
||||
{
|
||||
pEff->SetDead();
|
||||
pEff->CommandTarget=NULL;
|
||||
pEff->CommandTarget.Set0();
|
||||
}
|
||||
while ((pEff=pEff->pNext));
|
||||
}
|
||||
|
@ -383,34 +371,34 @@ C4Value C4Effect::DoCall(C4Object *pObj, const char *szFn, const C4Value &rVal1,
|
|||
int C4Effect::CallStart(C4Object * obj, int temporary, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
|
||||
{
|
||||
if (pFnStart)
|
||||
return pFnStart->Exec(CommandTarget, &C4AulParSet(obj, this, temporary, var1, var2, var3, var4)).getInt();
|
||||
return pFnStart->Exec(GetCallbackScript(), &C4AulParSet(obj, this, temporary, var1, var2, var3, var4)).getInt();
|
||||
return C4Fx_OK;
|
||||
}
|
||||
int C4Effect::CallStop(C4Object * obj, int reason, bool temporary)
|
||||
{
|
||||
if (pFnStop)
|
||||
return pFnStop->Exec(CommandTarget, &C4AulParSet(obj, this, reason, temporary)).getInt();
|
||||
return pFnStop->Exec(GetCallbackScript(), &C4AulParSet(obj, this, reason, temporary)).getInt();
|
||||
return C4Fx_OK;
|
||||
}
|
||||
int C4Effect::CallTimer(C4Object * obj, int time)
|
||||
{
|
||||
if (pFnTimer)
|
||||
return pFnTimer->Exec(CommandTarget, &C4AulParSet(obj, this, time)).getInt();
|
||||
return pFnTimer->Exec(GetCallbackScript(), &C4AulParSet(obj, this, time)).getInt();
|
||||
return C4Fx_Execute_Kill;
|
||||
}
|
||||
void C4Effect::CallDamage(C4Object * obj, int32_t & damage, int damagetype, int plr)
|
||||
{
|
||||
if (pFnDamage)
|
||||
damage = pFnDamage->Exec(CommandTarget, &C4AulParSet(obj, this, damage, damagetype, plr)).getInt();
|
||||
damage = pFnDamage->Exec(GetCallbackScript(), &C4AulParSet(obj, this, damage, damagetype, plr)).getInt();
|
||||
}
|
||||
int C4Effect::CallEffect(const char * effect, C4Object * obj, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
|
||||
{
|
||||
if (pFnEffect)
|
||||
return pFnEffect->Exec(CommandTarget, &C4AulParSet(effect, obj, this, var1, var2, var3, var4)).getInt();
|
||||
return pFnEffect->Exec(GetCallbackScript(), &C4AulParSet(effect, obj, this, var1, var2, var3, var4)).getInt();
|
||||
return C4Fx_OK;
|
||||
}
|
||||
|
||||
void C4Effect::OnObjectChangedDef(C4Object *pObj)
|
||||
void C4Effect::OnObjectChangedDef(C4PropList *pObj)
|
||||
{
|
||||
// safety
|
||||
if (!pObj) return;
|
||||
|
@ -418,7 +406,7 @@ void C4Effect::OnObjectChangedDef(C4Object *pObj)
|
|||
C4Effect *pCheck = this;
|
||||
while (pCheck)
|
||||
{
|
||||
if (pCheck->CommandTarget == pObj)
|
||||
if (pCheck->GetCallbackScript() == pObj)
|
||||
pCheck->ReAssignCallbackFunctions();
|
||||
pCheck = pCheck->pNext;
|
||||
}
|
||||
|
@ -479,9 +467,34 @@ void C4Effect::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
|
|||
pComp->Value(iTime); pComp->Separator();
|
||||
pComp->Value(iInterval); pComp->Separator();
|
||||
// read object number
|
||||
pComp->Value(CommandTarget); pComp->Separator();
|
||||
// FIXME: replace with this when savegame compat breaks for other reasons
|
||||
// pComp->Value(mkParAdapt(CommandTarget, numbers));
|
||||
int32_t nptr = 0;
|
||||
if (!pComp->isCompiler() && CommandTarget.getPropList() && CommandTarget._getPropList()->GetPropListNumbered())
|
||||
nptr = CommandTarget._getPropList()->GetPropListNumbered()->Number;
|
||||
pComp->Value(nptr);
|
||||
if (pComp->isCompiler())
|
||||
CommandTarget.SetObjectEnum(nptr);
|
||||
pComp->Separator();
|
||||
// read ID
|
||||
pComp->Value(idCommandTarget); pComp->Separator();
|
||||
if (pComp->isDecompiler())
|
||||
{
|
||||
const C4PropListStatic * p = CommandTarget.getPropList()->IsStatic();
|
||||
if (p)
|
||||
p->RefCompileFunc(pComp, numbers);
|
||||
else
|
||||
pComp->String(const_cast<char*>("None"), 5, StdCompiler::RCT_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
StdStrBuf s;
|
||||
pComp->Value(mkParAdapt(s, StdCompiler::RCT_ID));
|
||||
// An Object trumps a definition as command target
|
||||
if (!nptr)
|
||||
if (!::ScriptEngine.GetGlobalConstant(s.getData(), &CommandTarget))
|
||||
CommandTarget.Set0();
|
||||
}
|
||||
pComp->Separator();
|
||||
// proplist
|
||||
C4PropListNumbered::CompileFunc(pComp, numbers);
|
||||
pComp->Separator(StdCompiler::SEP_END); // ')'
|
||||
|
@ -555,16 +568,7 @@ bool C4Effect::GetPropertyByS(C4String *k, C4Value *pResult) const
|
|||
case P_Name: return C4PropListNumbered::GetPropertyByS(k, pResult);
|
||||
case P_Priority: *pResult = C4VInt(Abs(iPriority)); return true;
|
||||
case P_Interval: *pResult = C4VInt(iInterval); return true;
|
||||
case P_CommandTarget:
|
||||
if (CommandTarget)
|
||||
*pResult = C4VObj(CommandTarget);
|
||||
else if (idCommandTarget)
|
||||
*pResult = C4VPropList(Definitions.ID2Def(idCommandTarget));
|
||||
else
|
||||
*pResult = C4VNull;
|
||||
//*pResult = CommandTarget ? C4VObj(CommandTarget) :
|
||||
// (idCommandTarget ? C4VPropList(Definitions.ID2Def(idCommandTarget)) : C4VNull);
|
||||
return true;
|
||||
case P_CommandTarget: *pResult = CommandTarget; return true;
|
||||
case P_Time: *pResult = C4VInt(iTime); return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#ifndef INC_C4Effects
|
||||
#define INC_C4Effects
|
||||
|
||||
#include <C4ObjectPtr.h>
|
||||
#include <C4PropList.h>
|
||||
|
||||
// callback return values
|
||||
|
@ -70,15 +69,13 @@
|
|||
class C4Effect: public C4PropListNumbered
|
||||
{
|
||||
public:
|
||||
C4ObjectPtr CommandTarget; // target object for script callbacks - if deleted, the effect is removed without callbacks
|
||||
C4ID idCommandTarget; // ID of command target definition
|
||||
|
||||
int32_t iPriority; // effect priority for sorting into effect list; -1 indicates a dead effect
|
||||
int32_t iTime, iInterval; // effect time; effect callback intervall
|
||||
|
||||
C4Effect *pNext; // next effect in linked list
|
||||
|
||||
protected:
|
||||
C4Value CommandTarget; // target object for script callbacks - if deleted, the effect is removed without callbacks
|
||||
// presearched callback functions for faster calling
|
||||
C4AulFunc *pFnTimer; // timer function Fx%sTimer
|
||||
C4AulFunc *pFnStart, *pFnStop; // init/deinit-functions Fx%sStart, Fx%sStop
|
||||
|
@ -93,17 +90,17 @@ protected:
|
|||
void CallDamage(C4Object * obj, int32_t & damage, int damagetype, int plr);
|
||||
int CallEffect(const char * effect, C4Object * obj, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4);
|
||||
|
||||
C4Effect(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4);
|
||||
C4Effect(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4PropList * pCmdTarget);
|
||||
C4Effect(const C4Effect &); // unimplemented, do not use
|
||||
C4Effect(); // for the StdCompiler
|
||||
friend void CompileNewFunc<C4Effect, C4ValueNumbers *>(C4Effect *&, StdCompiler *, C4ValueNumbers * const &);
|
||||
public:
|
||||
static C4Effect * New(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4);
|
||||
static C4Effect * New(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4PropList * pCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4);
|
||||
~C4Effect(); // dtor - deletes all following effects
|
||||
|
||||
void Register(C4Object *pForObj, int32_t iPrio); // add into effect list of object or global effect list
|
||||
void Denumerate(C4ValueNumbers *); // numbers to object pointers
|
||||
void ClearPointers(C4Object *pObj); // clear all pointers to object - may kill some effects w/o callback, because the callback target is lost
|
||||
void ClearPointers(C4PropList *pObj); // clear all pointers to object - may kill some effects w/o callback, because the callback target is lost
|
||||
|
||||
void SetDead() { iPriority=0; } // mark effect to be removed in next execution cycle
|
||||
bool IsDead() { return !iPriority; } // return whether effect is to be removed
|
||||
|
@ -130,7 +127,7 @@ public:
|
|||
ReAssignCallbackFunctions();
|
||||
if (pNext) pNext->ReAssignAllCallbackFunctions();
|
||||
}
|
||||
void OnObjectChangedDef(C4Object *pObj);
|
||||
void OnObjectChangedDef(C4PropList *pObj);
|
||||
|
||||
void CompileFunc(StdCompiler *pComp, C4ValueNumbers *);
|
||||
virtual C4Effect * GetEffect() { return this; }
|
||||
|
|
|
@ -130,6 +130,7 @@ public:
|
|||
void SetArray(C4ValueArray * Array) { C4V_Data d; d.Array = Array; Set(d, C4V_Array); }
|
||||
void SetFunction(C4AulFunc * Fn) { C4V_Data d; d.Fn = Fn; Set(d, C4V_Function); }
|
||||
void SetPropList(C4PropList * PropList) { C4V_Data d; d.PropList = PropList; Set(d, C4V_PropList); }
|
||||
void SetObjectEnum(int i) { C4V_Data d; d.Int = i; Set(d, C4V_C4ObjectEnum); }
|
||||
void Set0();
|
||||
|
||||
bool operator == (const C4Value& Value2) const;
|
||||
|
|
Loading…
Reference in New Issue