Пример #1
0
C4Effect *C4Effect::Get(const char *szName, int32_t iIndex,
                        int32_t iMaxPriority) {
  // safety
  if (!szName)
    return NULL;
  // check all effects
  C4Effect *pEff = this;
  do {
    // skip dead
    if (pEff->IsDead())
      continue;
    // skip effects with too high priority
    if (iMaxPriority && pEff->iPriority > iMaxPriority)
      continue;
    // wildcard compare name
    const char *szEffectName = pEff->Name;
    if (!SWildcardMatchEx(szEffectName, szName))
      continue;
    // effect name matches
    // check index
    if (iIndex--)
      continue;
    // effect found
    return pEff;
  } while (pEff = pEff->pNext);
  // nothing found
  return NULL;
}
Пример #2
0
void C4Effect::TempRemoveUpperEffects(C4Object *pObj, bool fTempRemoveThis,
                                      C4Effect **ppLastRemovedEffect) {
  if (pObj && !pObj->Status)
    return; // this will be invalid!
  // priority=1: no callbacks
  if (iPriority == 1)
    return;
  // remove from high to low priority
  // recursive implementation...
  C4Effect *pEff = pNext;
  while (pEff)
    if (pEff->IsActive())
      break;
    else
      pEff = pEff->pNext;
  // temp remove active effects with higher priority
  if (pEff)
    pEff->TempRemoveUpperEffects(pObj, true, ppLastRemovedEffect);
  // temp remove this
  if (fTempRemoveThis) {
    FlipActive();
    // temp callbacks only for higher priority effects
    if (pFnStop && iPriority != 1)
      pFnStop->Exec(pCommandTarget,
                    &C4AulParSet(C4VObj(pObj), C4VInt(iNumber),
                                 C4VInt(C4FxCall_Temp), C4VBool(true)));
    if (!*ppLastRemovedEffect)
      *ppLastRemovedEffect = this;
  }
}
Пример #3
0
void C4Effect::OnObjectChangedDef(C4Object *pObj) {
  // safety
  if (!pObj) return;
  // check all effects for reassignment
  C4Effect *pCheck = this;
  while (pCheck) {
    if (pCheck->pCommandTarget == pObj) pCheck->ReAssignCallbackFunctions();
    pCheck = pCheck->pNext;
  }
}
Пример #4
0
void C4Effect::ClearPointers(C4Object *pObj) {
  // clear pointers in all effects
  C4Effect *pEff = this;
  do
    // command target lost: effect dead w/o callback
    if (pEff->pCommandTarget == pObj) {
      pEff->SetDead();
      pEff->pCommandTarget = NULL;
    }
  while (pEff = pEff->pNext);
}
Пример #5
0
void C4Effect::DoDamage(int32_t &riDamage, int32_t iDamageType, int32_t iCausePlr)
{
	// ask all effects for damage adjustments
	C4Effect *pEff = this;
	do
	{
		if (!pEff->IsDead())
			pEff->CallDamage(riDamage, iDamageType, iCausePlr);
		if (Target && !Target->Status) return;
	}
	while ((pEff = pEff->pNext) && riDamage);
}
Пример #6
0
void C4Effect::DenumeratePointers() {
  // denum in all effects
  C4Effect *pEff = this;
  do {
    // command target
    pEff->pCommandTarget = Game.Objects.ObjectPointer(pEff->nCommandTarget);
    // variable pointers
    pEff->EffectVars.DenumeratePointers();
    // assign any callback functions
    pEff->AssignCallbackFunctions();
  } while (pEff = pEff->pNext);
}
Пример #7
0
int32_t C4Effect::GetCount(const char *szMask, int32_t iMaxPriority)
{
	// count all matching effects
	int32_t iCnt=0; C4Effect *pEff = this;
	do if (!pEff->IsDead())
			if (!szMask || SWildcardMatchEx(pEff->GetName(), szMask))
				if (!iMaxPriority || pEff->iPriority <= iMaxPriority)
					++iCnt;
	while ((pEff = pEff->pNext));
	// return count
	return iCnt;
}
Пример #8
0
void C4Effect::DoDamage(C4Object *pObj, int32_t &riDamage, int32_t iDamageType, int32_t iCausePlr)
{
	// ask all effects for damage adjustments
	C4Effect *pEff = this;
	do
	{
		if (!pEff->IsDead() && pEff->pFnDamage)
			riDamage = pEff->pFnDamage->Exec(pEff->CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(pEff), C4VInt(riDamage), C4VInt(iDamageType), C4VInt(iCausePlr))).getInt();
		if (pObj && !pObj->Status) return;
	}
	while ((pEff = pEff->pNext) && riDamage);
}
Пример #9
0
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.getPropList() == pObj)
		{
			pEff->SetDead();
			pEff->CommandTarget.Set0();
		}
	while ((pEff=pEff->pNext));
}
Пример #10
0
void C4Effect::OnObjectChangedDef(C4PropList *pObj)
{
	// safety
	if (!pObj) return;
	// check all effects for reassignment
	C4Effect *pCheck = this;
	while (pCheck)
	{
		if (pCheck->GetCallbackScript() == pObj)
			pCheck->ReAssignCallbackFunctions();
		pCheck = pCheck->pNext;
	}
}
Пример #11
0
void C4Effect::Denumerate(C4ValueNumbers * numbers)
{
	// denum in all effects
	C4Effect *pEff = this;
	do
	{
		// command target
		pEff->CommandTarget.Denumerate(numbers);
		// assign any callback functions
		pEff->AssignCallbackFunctions();
		pEff->C4PropList::Denumerate(numbers);
	}
	while ((pEff=pEff->pNext));
}
Пример #12
0
C4Effect *C4Effect::Get(int32_t iNumber, bool fIncludeDead,
                        int32_t iMaxPriority) {
  // check all effects
  C4Effect *pEff = this;
  do
    if (pEff->iNumber == iNumber) {
      if (!pEff->IsDead() || fIncludeDead)
        if (!iMaxPriority || pEff->iPriority <= iMaxPriority) return pEff;
      // effect found but denied
      return NULL;
    }
  while (pEff = pEff->pNext);
  // nothing found
  return NULL;
}
Пример #13
0
void C4Effect::Execute(C4Object *pObj)
{
	// get effect list
	C4Effect **ppEffectList = pObj ? &pObj->pEffects : &Game.pGlobalEffects;
	// execute all effects not marked as dead
	C4Effect *pEffect = this, **ppPrevEffect=ppEffectList;
	do
	{
		// effect dead?
		if (pEffect->IsDead())
		{
			// delete it, then
			C4Effect *pNextEffect = pEffect->pNext;
			pEffect->pNext = NULL;
			delete pEffect;
			// next effect
			*ppPrevEffect = pEffect = pNextEffect;
		}
		else
		{
			// execute effect: time elapsed
			++pEffect->iTime;
			// check timer execution
			if (pEffect->iInterval && !(pEffect->iTime % pEffect->iInterval))
			{
				if (pEffect->pFnTimer)
				{
					if (pEffect->pFnTimer->Exec(pEffect->CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(pEffect), C4VInt(pEffect->iTime))).getInt() == C4Fx_Execute_Kill)
					{
						// safety: this class got deleted!
						if (pObj && !pObj->Status) return;
						// timer function decided to finish it
						pEffect->Kill(pObj);
					}
					// safety: this class got deleted!
					if (pObj && !pObj->Status) return;
				}
				else
					// no timer function: mark dead after time elapsed
					pEffect->Kill(pObj);
			}
			// next effect
			ppPrevEffect = &pEffect->pNext;
			pEffect = pEffect->pNext;
		}
	}
	while (pEffect);
}
Пример #14
0
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 * 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 && pEffect->pNext)
	{
		C4Effect * pEffect2 = pEffect->pNext->Check(pForObj, szName->GetCStr(), 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 (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;
	if (fRemoveUpper && pEffect->pNext && pEffect->pFnStart)
		pEffect->TempRemoveUpperEffects(pForObj, false, &pLastRemovedEffect);
	// bad things may happen
	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
			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 (!pEffect->IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, szName->GetCStr()))
		pForObj->SetOnFire(true);
	return pEffect;
}
Пример #15
0
void C4Effect::TempReaddUpperEffects(C4Object *pObj, C4Effect *pLastReaddEffect)
{
	// nothing to do? - this will also happen if TempRemoveUpperEffects did nothing due to priority==1
	if (!pLastReaddEffect) return;
	if (pObj && !pObj->Status) return; // this will be invalid!
	// simply activate all following, inactive effects
	for (C4Effect *pEff = pNext; pEff; pEff = pEff->pNext)
	{
		if (pEff->IsInactiveAndNotDead())
		{
			pEff->FlipActive();
			if (pEff->pFnStart && pEff->iPriority!=1) pEff->pFnStart->Exec(pEff->CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(pEff), C4VInt(C4FxCall_Temp)));
			if (pObj && WildcardMatch(C4Fx_AnyFire, pEff->GetName()))
				pObj->SetOnFire(true);
		}
		// done?
		if (pEff == pLastReaddEffect) break;
	}
}
Пример #16
0
void C4Effect::TempReaddUpperEffects(C4Effect *pLastReaddEffect)
{
	// nothing to do? - this will also happen if TempRemoveUpperEffects did nothing due to priority==1
	if (!pLastReaddEffect) return;
	if (Target && !Target->Status) return; // this will be invalid!
	// simply activate all following, inactive effects
	for (C4Effect *pEff = pNext; pEff; pEff = pEff->pNext)
	{
		if (pEff->IsInactiveAndNotDead())
		{
			pEff->FlipActive();
			if (pEff->iPriority!=1) pEff->CallStart(C4FxCall_Temp, C4Value(), C4Value(), C4Value(), C4Value());
			if (Target && WildcardMatch(C4Fx_AnyFire, pEff->GetName()))
				Target->SetOnFire(true);
		}
		// done?
		if (pEff == pLastReaddEffect) break;
	}
}
Пример #17
0
void C4Effect::Execute(C4Effect **ppEffectList)
{
	// get effect list
	// execute all effects not marked as dead
	C4Effect *pEffect = *ppEffectList, **ppPrevEffect=ppEffectList;
	while (pEffect)
	{
		// effect dead?
		if (pEffect->IsDead())
		{
			// delete it, then
			C4Effect *pNextEffect = pEffect->pNext;
			pEffect->pNext = NULL;
			delete pEffect;
			// next effect
			*ppPrevEffect = pEffect = pNextEffect;
		}
		else
		{
			// execute effect: time elapsed
			++pEffect->iTime;
			// check timer execution
			if (pEffect->iInterval && !(pEffect->iTime % pEffect->iInterval))
			{
				if (pEffect->CallTimer(pEffect->iTime) == C4Fx_Execute_Kill)
				{
					// safety: this class got deleted!
					if (pEffect->Target && !pEffect->Target->Status) return;
					// timer function decided to finish it
					pEffect->Kill();
				}
				// safety: this class got deleted!
				if (pEffect->Target && !pEffect->Target->Status) return;
			}
			// next effect
			ppPrevEffect = &pEffect->pNext;
			pEffect = pEffect->pNext;
		}
	}
}
Пример #18
0
int32_t C4Effect::Check(C4Object *pForObj, const char *szCheckEffect,
                        int32_t iPrio, int32_t iTimer, C4Value &rVal1,
                        C4Value &rVal2, C4Value &rVal3, C4Value &rVal4) {
  // priority=1: always OK; no callbacks
  if (iPrio == 1)
    return 0;
  // check this and other effects
  C4Effect *pAddToEffect = NULL;
  bool fDoTempCallsForAdd = false;
  C4Effect *pLastRemovedEffect = NULL;
  for (C4Effect *pCheck = this; pCheck; pCheck = pCheck->pNext) {
    if (!pCheck->IsDead() && pCheck->pFnEffect && pCheck->iPriority >= iPrio) {
      int32_t iResult =
          pCheck->pFnEffect->Exec(pCheck->pCommandTarget,
                                  &C4AulParSet(C4VString(szCheckEffect),
                                               C4VObj(pForObj),
                                               C4VInt(pCheck->iNumber),
                                               C4Value(), rVal1, rVal2, rVal3,
                                               rVal4)).getInt();
      if (iResult == C4Fx_Effect_Deny)
        // effect denied
        return C4Fx_Effect_Deny;
      // add to other effect
      if (iResult == C4Fx_Effect_Annul || iResult == C4Fx_Effect_AnnulCalls) {
        pAddToEffect = pCheck;
        fDoTempCallsForAdd = (iResult == C4Fx_Effect_AnnulCalls);
      }
    }
  }
  // adding to other effect?
  if (pAddToEffect) {
    // do temp remove calls if desired
    if (pAddToEffect->pNext && fDoTempCallsForAdd)
      pAddToEffect->TempRemoveUpperEffects(pForObj, false, &pLastRemovedEffect);
    C4Value Par1 = C4VString(szCheckEffect), Par2 = C4VInt(iTimer), Par8;
    int32_t iResult =
        pAddToEffect->DoCall(pForObj, PSFS_FxAdd, Par1, Par2, rVal1, rVal2,
                             rVal3, rVal4, Par8).getInt();
    // do temp readd calls if desired
    if (pAddToEffect->pNext && fDoTempCallsForAdd)
      pAddToEffect->TempReaddUpperEffects(pForObj, pLastRemovedEffect);
    // effect removed by this call?
    if (iResult == C4Fx_Start_Deny) {
      pAddToEffect->Kill(pForObj);
      return C4Fx_Effect_Annul;
    } else
      // other effect is the target effect number
      return pAddToEffect->iNumber;
  }
  // added to no effect and not denied
  return 0;
}
Пример #19
0
void C4Effect::TempRemoveUpperEffects(bool fTempRemoveThis, C4Effect **ppLastRemovedEffect)
{
	if (Target && !Target->Status) return; // this will be invalid!
	// priority=1: no callbacks
	if (iPriority == 1) return;
	// remove from high to low priority
	// recursive implementation...
	C4Effect *pEff = pNext;
		while (pEff) if (pEff->IsActive()) break; else pEff = pEff->pNext;
	// temp remove active effects with higher priority
	if (pEff) pEff->TempRemoveUpperEffects(true, ppLastRemovedEffect);
	// temp remove this
	if (fTempRemoveThis)
	{
		FlipActive();
		// Update OnFire cache
		if (Target && WildcardMatch(C4Fx_AnyFire, GetName()))
			if (!Get(C4Fx_AnyFire))
				Target->SetOnFire(false);
		// temp callbacks only for higher priority effects
		if (iPriority!=1) CallStop(C4FxCall_Temp, true);
		if (!*ppLastRemovedEffect) *ppLastRemovedEffect = this;
	}
}
Пример #20
0
int32_t FnFxFireTimer(C4AulContext *ctx, C4Object *pObj, int32_t iNumber,
                      int32_t iTime) {
  // safety
  if (!pObj)
    return C4Fx_Execute_Kill;

  // get cause
  int32_t iCausedByPlr = NO_OWNER;
  C4Effect *pEffect;
  if (pEffect = pObj->pEffects)
    if (pEffect = pEffect->Get(iNumber, true)) {
      iCausedByPlr = FxFireVarCausedBy(pEffect).getInt();
      if (!ValidPlr(iCausedByPlr))
        iCausedByPlr = NO_OWNER;
    }

  // causes on object
  pObj->ExecFire(iNumber, iCausedByPlr);

  // special effects only if loaded
  if (!Game.Particles.IsFireParticleLoaded())
    return C4Fx_OK;

  // get effect: May be NULL after object fire execution, in which case the fire
  // has been extinguished
  if (!pObj->GetOnFire())
    return C4Fx_Execute_Kill;
  if (!(pEffect = pObj->pEffects))
    return C4Fx_Execute_Kill;
  if (!(pEffect = pEffect->Get(iNumber, true)))
    return C4Fx_Execute_Kill;

  /* Fire execution behaviour transferred from script (FIRE) */

  // get fire mode
  int32_t iFireMode = FxFireVarMode(pEffect).getInt();

  // special effects only each four frames, except for objects (e.g.:
  // Projectiles)
  if (iTime % 4 && iFireMode != C4Fx_FireMode_Object)
    return C4Fx_OK;

  // no gfx for contained
  if (pObj->Contained)
    return C4Fx_OK;

  // some constant effect parameters for this object
  int32_t iWidth = Max<int32_t>(pObj->Def->Shape.Wdt, 1),
          iHeight = pObj->Def->Shape.Hgt,
          iYOff = iHeight / 2 - pObj->Def->Shape.FireTop;

  int32_t iCount = int32_t(sqrt(double(iWidth * iHeight)) /
                           4); // Number of particles per execution
  const int32_t iBaseParticleSize =
      30; // With of particles in pixels/10, w/o add of values below
  const int32_t iParticleSizeDiff = 10; // Size variation among particles
  const int32_t iRelParticleSize =
      12; // Influence of object size on particle size

  // some varying effect parameters
  int32_t iX = pObj->x, iY = pObj->y;
  int32_t iXDir, iYDir, iCon, iWdtCon, iA, iSize;

  // get remainign size (%)
  iCon = iWdtCon = Max<int32_t>((100 * pObj->GetCon()) / FullCon, 1);
  if (!pObj->Def->GrowthType)
    // fixed width for not-stretched-objects
    if (iWdtCon < 100)
      iWdtCon = 100;

  // regard non-center object offsets
  iX += pObj->Shape.x + pObj->Shape.Wdt / 2;
  iY += pObj->Shape.y + pObj->Shape.Hgt / 2;

  // apply rotation
  float fRot[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
  if (pObj->r && pObj->Def->Rotateable) {
    fRot[0] = (float)cosf((float)(pObj->r * pi / 180.0));
    fRot[1] = (float)-sinf((float)(pObj->r * pi / 180.0));
    fRot[2] = -fRot[1];
    fRot[3] = fRot[0];
    // rotated objects usually better burn from the center
    if (iYOff > 0)
      iYOff = 0;
  }

  // Adjust particle number by con
  iCount = Max(2, iCount * iWdtCon / 100);

  // calc base for particle size parameter
  iA = (int32_t)(sqrt(sqrt(double(iWidth * iHeight)) * (iCon + 20) / 120) *
                 iRelParticleSize);

  // create a double set of particles; first quarter normal (Fire); remaining
  // three quarters additive (Fire2)
  for (int32_t i = 0; i < iCount * 2; ++i) {
    // calc actual size to be used in this frame
    // Using Random instead of SafeRandom would be safe here
    // However, since it's just affecting particles there's no need to use
    // synchronized random values
    iSize = SafeRandom(iParticleSizeDiff + 1) + iBaseParticleSize -
            iParticleSizeDiff / 2 - 1 + iA;

    // get particle target list
    C4ParticleList *pParticleList =
        SafeRandom(4) ? &(pObj->BackParticles) : &(pObj->FrontParticles);

    // get particle def and color
    C4ParticleDef *pPartDef;
    DWORD dwClr;
    if (i < iCount / 2) {
      dwClr = 0x32004000 + ((SafeRandom(59) + 196) << 16);
      pPartDef = Game.Particles.pFire1;
    } else {
      dwClr = 0xffffff;
      pPartDef = Game.Particles.pFire2;
    }
    if (iFireMode == C4Fx_FireMode_Object)
      dwClr += 0x62000000;

    // get particle creation pos...
    int32_t iRandX = SafeRandom(iWidth + 1) - iWidth / 2 - 1;

    int32_t iPx = iRandX * iWdtCon / 100;
    int32_t iPy = iYOff * iCon / 100;
    if (iFireMode == C4Fx_FireMode_LivingVeg)
      iPy -= iPx * iPx * 100 / iWidth /
             iWdtCon; // parable form particle pos on livings

    // ...and movement speed
    if (iFireMode != C4Fx_FireMode_Object) {
      // ...for normal fire proc
      iXDir = iRandX * iCon / 400 - int32_t(iPx / 3) -
              int32_t(fixtof(pObj->xdir) * 3);
      iYDir = -SafeRandom(15 + iHeight * iCon / 300) - 1 -
              int32_t(fixtof(pObj->ydir) * 3);
    } else {
      // ...for objects
      iXDir = -int32_t(fixtof(pObj->xdir) * 3);
      iYDir = -int32_t(fixtof(pObj->ydir) * 3);
      if (!iYDir)
        iYDir = -SafeRandom(13 + iHeight / 4) - 1;
    }

    // OK; create it!
    Game.Particles.Create(pPartDef, float(iX) + fRot[0] * iPx + fRot[1] * iPy,
                          float(iY) + fRot[2] * iPx + fRot[3] * iPy,
                          (float)iXDir / 10.0f, (float)iYDir / 10.0f,
                          (float)iSize / 10.0f, dwClr, pParticleList, pObj);
  }

  return C4Fx_OK;
}
Пример #21
0
int32_t FnFxFireStart(C4AulContext *ctx, C4Object *pObj, int32_t iNumber,
                      int32_t iTemp, int32_t iCausedBy, bool fBlasted,
                      C4Object *pIncineratingObject) {
  // safety
  if (!pObj)
    return -1;
  // temp readd
  if (iTemp) {
    pObj->SetOnFire(true);
    return 1;
  }
  // fail if already on fire
  if (pObj->GetOnFire())
    return -1;
  // get associated effect
  C4Effect *pEffect;
  if (!(pEffect = pObj->pEffects))
    return -1;
  if (!(pEffect = pEffect->Get(iNumber, true)))
    return -1;
  // structures must eject contents now, because DoCon is not guaranteed to be
  // executed!
  // In extinguishing material
  BOOL fFireCaused = TRUE;
  int32_t iMat;
  if (MatValid(iMat = GBackMat(pObj->x, pObj->y)))
    if (Game.Material.Map[iMat].Extinguisher) {
      // blasts should changedef in water, too!
      if (fBlasted)
        if (pObj->Def->BurnTurnTo != C4ID_None)
          pObj->ChangeDef(pObj->Def->BurnTurnTo);
      // no fire caused
      fFireCaused = FALSE;
    }
  // BurnTurnTo
  if (fFireCaused)
    if (pObj->Def->BurnTurnTo != C4ID_None)
      pObj->ChangeDef(pObj->Def->BurnTurnTo);
  // eject contents
  C4Object *cobj;
  if (!pObj->Def->IncompleteActivity && !pObj->Def->NoBurnDecay)
    while (cobj = pObj->Contents.GetObject()) {
      cobj->Controller = iCausedBy; // update controller, so incinerating a hut
                                    // full of flints attributes the damage to
                                    // the incinerator
      if (pObj->Contained)
        cobj->Enter(pObj->Contained);
      else
        cobj->Exit(cobj->x, cobj->y);
    }
  // Detach attached objects
  cobj = 0;
  if (!pObj->Def->IncompleteActivity && !pObj->Def->NoBurnDecay)
    while (cobj = Game.FindObject(0, 0, 0, 0, 0, OCF_All, 0, pObj, 0, 0,
                                  ANY_OWNER, cobj))
      if ((cobj->Action.Act > ActIdle) &&
          (cobj->Def->ActMap[cobj->Action.Act].Procedure == DFA_ATTACH))
        cobj->SetAction(ActIdle);
  // fire caused?
  if (!fFireCaused) {
    // if object was blasted but not incinerated (i.e., inside extinguisher)
    // do a script callback
    if (fBlasted)
      pObj->Call(PSF_IncinerationEx, &C4AulParSet(C4VInt(iCausedBy)));
    return -1;
  }
  // determine fire appearance
  int32_t iFireMode;
  if (!(iFireMode = pObj->Call(PSF_FireMode).getInt())) {
    // set default fire modes
    DWORD dwCat = pObj->Category;
    if (dwCat & (C4D_Living | C4D_StaticBack)) // Tiere, Bäume
      iFireMode = C4Fx_FireMode_LivingVeg;
    else if (dwCat & (C4D_Structure | C4D_Vehicle)) // Gebäude und Fahrzeuge
                                                    // sind unten meist kantig
      iFireMode = C4Fx_FireMode_StructVeh;
    else
      iFireMode = C4Fx_FireMode_Object;
  } else if (!Inside<int32_t>(iFireMode, 1, C4Fx_FireMode_Last)) {
    DebugLogF("Warning: FireMode %d of object %s (%s) is invalid!", iFireMode,
              pObj->GetName(), pObj->Def->GetName());
    iFireMode = C4Fx_FireMode_Object;
  }
  // store causes in effect vars
  FxFireVarMode(pEffect).SetInt(iFireMode);
  FxFireVarCausedBy(pEffect)
      .SetInt(iCausedBy); // used in C4Object::GetFireCause and timer!
  FxFireVarBlasted(pEffect).SetBool(fBlasted);
  FxFireVarIncineratingObj(pEffect).SetObject(pIncineratingObject);
  // Set values
  pObj->SetOnFire(true);
  pObj->FirePhase = Random(MaxFirePhase);
  if (pObj->Shape.Wdt * pObj->Shape.Hgt > 500)
    StartSoundEffect("Inflame", false, 100, pObj);
  if (pObj->Def->Mass >= 100)
    StartSoundEffect("Fire", true, 100, pObj);
  // Engine script call
  pObj->Call(PSF_Incineration, &C4AulParSet(C4VInt(iCausedBy)));
  // Done, success
  return C4Fx_OK;
}
Пример #22
0
C4Effect * C4Effect::New(C4PropList *pForObj, C4Effect **ppEffectList, C4PropList * prototype, int32_t iPrio, int32_t iTimerInterval, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
{
	C4Effect * pEffect = new C4Effect(ppEffectList, prototype, iPrio, iTimerInterval);
	return pEffect->Init(pForObj, iPrio, rVal1, rVal2, rVal3, rVal4);
}
Пример #23
0
C4Effect * C4Effect::New(C4PropList *pForObj, C4Effect **ppEffectList, 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(ppEffectList, szName, iPrio, iTimerInterval, pCmdTarget);
	return pEffect->Init(pForObj, iPrio, rVal1, rVal2, rVal3, rVal4);
}