void C4Effect::Kill(C4Object *pObj) { // active? C4Effect *pLastRemovedEffect = NULL; if (IsActive()) // then temp remove all higher priority effects TempRemoveUpperEffects(pObj, false, &pLastRemovedEffect); else // otherwise: temp reactivate before real removal // this happens only if a lower priority effect removes an upper priority // effect in its add- or removal-call if (pFnStart && iPriority != 1) pFnStart->Exec(pCommandTarget, &C4AulParSet(C4VObj(pObj), C4VInt(iNumber), C4VInt(C4FxCall_TempAddForRemoval))); // remove this effect int32_t iPrevPrio = iPriority; SetDead(); if (pFnStop) if (pFnStop->Exec(pCommandTarget, &C4AulParSet(C4VObj(pObj), C4VInt(iNumber))).getInt() == C4Fx_Stop_Deny) // effect denied to be removed: recover iPriority = iPrevPrio; // reactivate other effects TempReaddUpperEffects(pObj, pLastRemovedEffect); }
void C4Effect::Kill() { // active? C4Effect *pLastRemovedEffect=NULL; if (IsActive()) // then temp remove all higher priority effects TempRemoveUpperEffects(false, &pLastRemovedEffect); else // otherwise: temp reactivate before real removal // this happens only if a lower priority effect removes an upper priority effect in its add- or removal-call if (iPriority!=1) CallStart(C4FxCall_TempAddForRemoval, C4Value(), C4Value(), C4Value(), C4Value()); // remove this effect int32_t iPrevPrio = iPriority; SetDead(); if (CallStop(C4FxCall_Normal, false) == C4Fx_Stop_Deny) // effect denied to be removed: recover iPriority = iPrevPrio; // reactivate other effects TempReaddUpperEffects(pLastRemovedEffect); // Update OnFire cache if (Target && WildcardMatch(C4Fx_AnyFire, GetName())) if (!Get(C4Fx_AnyFire)) Target->SetOnFire(false); if (IsDead() && !GetCallbackScript()) Call(P_Destruction, &C4AulParSet(C4FxCall_Normal)); }
C4Effect * C4Effect::Init(C4PropList *pForObj, int32_t iPrio, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4) { Target = pForObj; // 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) { C4Effect * pEffect2 = pNext->Check(GetName(), iPrio, iInterval, 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 (pEffect2 != (C4Effect*)C4Fx_Effect_Deny && pEffect2 != (C4Effect*)C4Fx_Effect_Annul) return pEffect2; // effect is still marked dead return 0; } } // init effect // higher-priority effects must be deactivated temporarily, and then reactivated regarding the new effect // higher-level effects should not be inserted during the process of removing or adding a lower-level effect // because that would cause a wrong initialization order // (hardly ever causing trouble, however...) C4Effect *pLastRemovedEffect=NULL; C4AulFunc * pFn; if (!GetCallbackScript()) { Call(P_Construction, &C4AulParSet(rVal1, rVal2, rVal3, rVal4)).getInt(); if (pForObj && !pForObj->Status) return 0; pFn = GetFunc(P_Start); } else pFn = pFnStart; if (fRemoveUpper && pNext && pFn) TempRemoveUpperEffects(false, &pLastRemovedEffect); // bad things may happen if (pForObj && !pForObj->Status) return 0; // this will be invalid! iPriority = iPrio; // validate effect now if (CallStart(0, rVal1, rVal2, rVal3, rVal4) == C4Fx_Start_Deny) // the effect denied to start: assume it hasn't, and mark it dead SetDead(); if (fRemoveUpper && pNext && pFn) TempReaddUpperEffects(pLastRemovedEffect); if (pForObj && !pForObj->Status) return 0; // this will be invalid! // Update OnFire cache if (!IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, GetName())) pForObj->SetOnFire(true); return this; }
void C4Effect::Kill(C4Object *pObj) { // active? C4Effect *pLastRemovedEffect=NULL; if (IsActive()) // then temp remove all higher priority effects TempRemoveUpperEffects(pObj, false, &pLastRemovedEffect); else // otherwise: temp reactivate before real removal // this happens only if a lower priority effect removes an upper priority effect in its add- or removal-call if (pFnStart && iPriority!=1) pFnStart->Exec(CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(this), C4VInt(C4FxCall_TempAddForRemoval))); // remove this effect int32_t iPrevPrio = iPriority; SetDead(); if (pFnStop) if (pFnStop->Exec(CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(this), C4VInt(C4FxCall_Normal))).getInt() == C4Fx_Stop_Deny) // effect denied to be removed: recover iPriority = iPrevPrio; // reactivate other effects TempReaddUpperEffects(pObj, pLastRemovedEffect); // Update OnFire cache if (pObj && WildcardMatch(C4Fx_AnyFire, GetName())) if (!Get(C4Fx_AnyFire)) pObj->SetOnFire(false); }
C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerIntervall, C4Object *pCmdTarget, C4ID idCmdTarget, C4Value &rVal1, C4Value &rVal2, C4Value &rVal3, C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber) : EffectVars(0) { 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; iIntervall = iTimerIntervall; iTime = 0; pCommandTarget = pCmdTarget; idCommandTarget = idCmdTarget; AssignCallbackFunctions(); // get effect target C4Effect **ppEffectList = pForObj ? &pForObj->pEffects : &Game.pGlobalEffects; // assign a unique number for that object iNumber = 1; for (pCheck = *ppEffectList; pCheck; pCheck = pCheck->pNext) if (pCheck->iNumber >= iNumber) iNumber = pCheck->iNumber + 1; // register into object pPrev = *ppEffectList; if (pPrev && Abs(pPrev->iPriority) < iPrio) { while (pCheck = pPrev->pNext) if (Abs(pCheck->iPriority) >= iPrio) break; else pPrev = pCheck; // insert after previous pNext = pPrev->pNext; pPrev->pNext = this; } else { // insert as first effect pNext = *ppEffectList; *ppEffectList = this; } // no calls to be done: finished here if (!fDoCalls) return; // 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) { int32_t iResult = pNext->Check(pForObj, Name, iPrio, iIntervall, rVal1, rVal2, rVal3, rVal4); if (iResult) { // 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; // effect is still marked dead return; } } // init effect // higher-priority effects must be deactivated temporarily, and then // reactivated regarding the new effect // higher-level effects should not be inserted during the process of removing // or adding a lower-level effect // because that would cause a wrong initialization order // (hardly ever causing trouble, however...) C4Effect *pLastRemovedEffect = NULL; if (fRemoveUpper && pNext && pFnStart) 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(pCommandTarget, &C4AulParSet(C4VObj(pForObj), C4VInt(iNumber), 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! // this effect has been created; hand back the number riStoredAsNumber = iNumber; }