forked from Mirrors/openclonk
Split C4Effect construction into static function and constructor
This way, the function can return the effect that absorbed the new effect.
parent
7827f60775
commit
b533c8b8fc
|
@ -67,13 +67,12 @@ C4AulScript *C4Effect::GetCallbackScript()
|
|||
return pSrcScript;
|
||||
}
|
||||
|
||||
C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber)
|
||||
C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
|
||||
{
|
||||
C4Effect *pPrev, *pCheck;
|
||||
// assign values
|
||||
SCopy(szName, Name, C4MaxDefString);
|
||||
iPriority = 0; // effect is not yet valid; some callbacks to other effects are done before
|
||||
riStoredAsNumber = 0;
|
||||
iInterval = iTimerInterval;
|
||||
iTime = 0;
|
||||
CommandTarget = pCmdTarget;
|
||||
|
@ -102,24 +101,27 @@ C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t
|
|||
pNext = *ppEffectList;
|
||||
*ppEffectList = this;
|
||||
}
|
||||
// no calls to be done: finished here
|
||||
if (!fDoCalls) return;
|
||||
}
|
||||
|
||||
C4Effect * C4Effect::New(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, 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);
|
||||
// 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
|
||||
// or do other things with the effect list
|
||||
// (which does not quite make sense, because the effect might be denied by another effect)
|
||||
// so the priority is assigned after this call, marking this effect dead before it's definitely valid
|
||||
if (fRemoveUpper && pNext)
|
||||
if (fRemoveUpper && pEffect->pNext)
|
||||
{
|
||||
int32_t iResult = pNext->Check(pForObj, Name, iPrio, iInterval, rVal1, rVal2, rVal3, rVal4);
|
||||
if (iResult)
|
||||
C4Effect * pEffect2 = pEffect->pNext->Check(pForObj, szName, iPrio, iTimerInterval, rVal1, rVal2, rVal3, rVal4);
|
||||
if (pEffect2)
|
||||
{
|
||||
// effect denied (iResult = -1), added to an effect (iResult = Number of that effect)
|
||||
// or added to an effect that destroyed itself (iResult = -2)
|
||||
if (iResult != C4Fx_Effect_Deny) riStoredAsNumber = iResult;
|
||||
if (pEffect2 != (C4Effect*)C4Fx_Effect_Deny && pEffect2 != (C4Effect*)C4Fx_Effect_Annul) return pEffect2;
|
||||
// effect is still marked dead
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// init effect
|
||||
|
@ -128,23 +130,22 @@ C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t
|
|||
// because that would cause a wrong initialization order
|
||||
// (hardly ever causing trouble, however...)
|
||||
C4Effect *pLastRemovedEffect=NULL;
|
||||
if (fRemoveUpper && pNext && pFnStart)
|
||||
TempRemoveUpperEffects(pForObj, false, &pLastRemovedEffect);
|
||||
if (fRemoveUpper && pEffect->pNext && pEffect->pFnStart)
|
||||
pEffect->TempRemoveUpperEffects(pForObj, false, &pLastRemovedEffect);
|
||||
// bad things may happen
|
||||
if (pForObj && !pForObj->Status) return; // this will be invalid!
|
||||
iPriority = iPrio; // validate effect now
|
||||
if (pFnStart)
|
||||
if (pFnStart->Exec(CommandTarget, &C4AulParSet(C4VObj(pForObj), C4VPropList(this), C4VInt(0), rVal1, rVal2, rVal3, rVal4)).getInt() == C4Fx_Start_Deny)
|
||||
if (pForObj && !pForObj->Status) return 0; // this will be invalid!
|
||||
pEffect->iPriority = iPrio; // validate effect now
|
||||
if (pEffect->pFnStart)
|
||||
if (pEffect->pFnStart->Exec(pCmdTarget, &C4AulParSet(C4VObj(pForObj), C4VPropList(pEffect), C4VInt(0), rVal1, rVal2, rVal3, rVal4)).getInt() == C4Fx_Start_Deny)
|
||||
// the effect denied to start: assume it hasn't, and mark it dead
|
||||
SetDead();
|
||||
if (fRemoveUpper && pNext && pFnStart)
|
||||
TempReaddUpperEffects(pForObj, pLastRemovedEffect);
|
||||
if (pForObj && !pForObj->Status) return; // this will be invalid!
|
||||
pEffect->SetDead();
|
||||
if (fRemoveUpper && pEffect->pNext && pEffect->pFnStart)
|
||||
pEffect->TempReaddUpperEffects(pForObj, pLastRemovedEffect);
|
||||
if (pForObj && !pForObj->Status) return 0; // this will be invalid!
|
||||
// Update OnFire cache
|
||||
if (!IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, szName))
|
||||
if (!pEffect->IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, szName))
|
||||
pForObj->SetOnFire(true);
|
||||
// this effect has been created; hand back the number
|
||||
riStoredAsNumber = iNumber;
|
||||
return pEffect;
|
||||
}
|
||||
|
||||
C4Effect::C4Effect(StdCompiler *pComp)
|
||||
|
@ -268,7 +269,7 @@ int32_t C4Effect::GetCount(const char *szMask, int32_t iMaxPriority)
|
|||
return iCnt;
|
||||
}
|
||||
|
||||
int32_t C4Effect::Check(C4Object *pForObj, const char *szCheckEffect, int32_t iPrio, int32_t iTimer, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4)
|
||||
C4Effect* C4Effect::Check(C4Object *pForObj, const char *szCheckEffect, int32_t iPrio, int32_t iTimer, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
|
||||
{
|
||||
// priority=1: always OK; no callbacks
|
||||
if (iPrio == 1) return 0;
|
||||
|
@ -282,7 +283,7 @@ int32_t C4Effect::Check(C4Object *pForObj, const char *szCheckEffect, int32_t iP
|
|||
int32_t iResult = pCheck->pFnEffect->Exec(pCheck->CommandTarget, &C4AulParSet(C4VString(szCheckEffect), C4VObj(pForObj), C4VPropList(pCheck), C4Value(), rVal1, rVal2, rVal3, rVal4)).getInt();
|
||||
if (iResult == C4Fx_Effect_Deny)
|
||||
// effect denied
|
||||
return C4Fx_Effect_Deny;
|
||||
return (C4Effect*)C4Fx_Effect_Deny;
|
||||
// add to other effect
|
||||
if (iResult == C4Fx_Effect_Annul || iResult == C4Fx_Effect_AnnulCalls)
|
||||
{
|
||||
|
@ -306,11 +307,11 @@ int32_t C4Effect::Check(C4Object *pForObj, const char *szCheckEffect, int32_t iP
|
|||
if (iResult == C4Fx_Start_Deny)
|
||||
{
|
||||
pAddToEffect->Kill(pForObj);
|
||||
return C4Fx_Effect_Annul;
|
||||
return (C4Effect*)C4Fx_Effect_Annul;
|
||||
}
|
||||
else
|
||||
// other effect is the target effect number
|
||||
return pAddToEffect->iNumber;
|
||||
return pAddToEffect;
|
||||
}
|
||||
// added to no effect and not denied
|
||||
return 0;
|
||||
|
@ -427,7 +428,7 @@ void C4Effect::DoDamage(C4Object *pObj, int32_t &riDamage, int32_t iDamageType,
|
|||
while ((pEff = pEff->pNext) && riDamage);
|
||||
}
|
||||
|
||||
C4Value C4Effect::DoCall(C4Object *pObj, const char *szFn, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4, C4Value &rVal5, C4Value &rVal6, C4Value &rVal7)
|
||||
C4Value C4Effect::DoCall(C4Object *pObj, const char *szFn, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, const C4Value &rVal5, const C4Value &rVal6, const C4Value &rVal7)
|
||||
{
|
||||
// def script or global only?
|
||||
C4AulScript *pSrcScript; C4Def *pDef;
|
||||
|
|
|
@ -92,8 +92,9 @@ protected:
|
|||
|
||||
void AssignCallbackFunctions(); // resolve callback function names
|
||||
|
||||
C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4);
|
||||
public:
|
||||
C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber); // ctor
|
||||
static C4Effect * New(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerInterval, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4);
|
||||
C4Effect(StdCompiler *pComp); // ctor: compile
|
||||
~C4Effect(); // dtor - deletes all following effects
|
||||
|
||||
|
@ -110,7 +111,7 @@ public:
|
|||
C4Effect *Get(const char *szName, int32_t iIndex=0, int32_t iMaxPriority=0); // get effect by name
|
||||
C4Effect *Get(int32_t iNumber, bool fIncludeDead, int32_t iMaxPriority=0); // get effect by number
|
||||
int32_t GetCount(const char *szMask, int32_t iMaxPriority=0); // count effects that match the mask
|
||||
int32_t Check(C4Object *pForObj, const char *szCheckEffect, int32_t iPrio, int32_t iTimer, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4); // do some effect callbacks
|
||||
C4Effect *Check(C4Object *pForObj, const char *szCheckEffect, int32_t iPrio, int32_t iTimer, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4); // do some effect callbacks
|
||||
C4AulScript *GetCallbackScript(); // get script context for effect callbacks
|
||||
|
||||
void Execute(C4Object *pObj); // execute all effects
|
||||
|
@ -118,7 +119,7 @@ public:
|
|||
void ClearAll(C4Object *pObj, int32_t iClearFlag);// kill all effects doing removal calls w/o reagard of inactive effects
|
||||
void DoDamage(C4Object *pObj, int32_t &riDamage, int32_t iDamageType, int32_t iCausePlr); // ask all effects for damage
|
||||
|
||||
C4Value DoCall(C4Object *pObj, const char *szFn, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4, C4Value &rVal5, C4Value &rVal6, C4Value &rVal7); // custom call
|
||||
C4Value DoCall(C4Object *pObj, const char *szFn, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, const C4Value &rVal5, const C4Value &rVal6, const C4Value &rVal7); // custom call
|
||||
|
||||
void ReAssignCallbackFunctions()
|
||||
{ AssignCallbackFunctions(); }
|
||||
|
|
|
@ -1973,13 +1973,9 @@ static C4Value FnAddEffect_C4V(C4AulContext *ctx, C4Value *pvsEffectName, C4Valu
|
|||
if (pTarget && !pTarget->Status) return C4Value();
|
||||
if (!szEffect || !*szEffect || !iPrio) return C4Value();
|
||||
// create effect
|
||||
int32_t iEffectNumber;
|
||||
new C4Effect(pTarget, szEffect, iPrio, iTimerInterval, pCmdTarget, idCmdTarget, *pvVal1, *pvVal2, *pvVal3, *pvVal4, true, iEffectNumber);
|
||||
C4Effect * pEffect = C4Effect::New(pTarget, szEffect, iPrio, iTimerInterval, pCmdTarget, idCmdTarget, *pvVal1, *pvVal2, *pvVal3, *pvVal4);
|
||||
// return effect - may be 0 if he effect has been denied by another effect
|
||||
// may also be another effect
|
||||
C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects;
|
||||
if (!pEffect) return C4Value();
|
||||
pEffect = pEffect->Get(iEffectNumber, true);
|
||||
return C4VPropList(pEffect);
|
||||
}
|
||||
|
||||
|
@ -2032,7 +2028,10 @@ static C4Value FnCheckEffect_C4V(C4AulContext *ctx, C4Value *pvsEffectName, C4Va
|
|||
C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects;
|
||||
if (!pEffect) return C4Value();
|
||||
// let them check
|
||||
return C4VInt(pEffect->Check(pTarget, szEffect, iPrio, iTimerInterval, *pvVal1, *pvVal2, *pvVal3, *pvVal4));
|
||||
C4Effect * r = pEffect->Check(pTarget, szEffect, iPrio, iTimerInterval, *pvVal1, *pvVal2, *pvVal3, *pvVal4);
|
||||
if (r == (C4Effect *)C4Fx_Effect_Deny) return C4VInt(C4Fx_Effect_Deny);
|
||||
if (r == (C4Effect *)C4Fx_Effect_Annul) return C4VInt(C4Fx_Effect_Annul);
|
||||
return C4VPropList(r);
|
||||
}
|
||||
|
||||
static long FnGetEffectCount(C4AulContext *ctx, C4String *psEffectName, C4Object *pTarget, long iMaxPriority)
|
||||
|
|
Loading…
Reference in New Issue