Exemple #1
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
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;
}