OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4Effect.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 // C4AulFun-based effects assigned to an object
19 /* Also contains some helper functions for various landscape effects */
20 
21 #include "C4Include.h"
22 #include "script/C4Effect.h"
23 
24 #include "game/C4GameScript.h"
25 #include "script/C4Aul.h"
26 
28 {
30  if (!p) return;
31  // compose function names and search them
32  char fn[C4AUL_MAX_Identifier+1];
33  sprintf(fn, PSF_FxStart, GetName()); pFnStart = p->GetFunc(fn);
34  sprintf(fn, PSF_FxStop, GetName()); pFnStop = p->GetFunc(fn);
35  sprintf(fn, PSF_FxTimer, GetName()); pFnTimer = p->GetFunc(fn);
36  sprintf(fn, PSF_FxEffect, GetName()); pFnEffect = p->GetFunc(fn);
37  sprintf(fn, PSF_FxDamage, GetName()); pFnDamage = p->GetFunc(fn);
38 }
39 
41 {
42  return CommandTarget._getPropList();
43 }
44 
45 C4Effect::C4Effect(C4Effect **ppEffectList, C4String *szName, int32_t iPrio, int32_t iTimerInterval, C4PropList *pCmdTarget)
46 {
47  // assign values
48  iPriority = 0; // effect is not yet valid; some callbacks to other effects are done before
49  iInterval = iTimerInterval;
50  iTime = 0;
51  CommandTarget.SetPropList(pCmdTarget);
52  AcquireNumber();
53  Register(ppEffectList, iPrio);
54  // Set name and callback functions
55  SetProperty(P_Name, C4VString(szName));
56 }
57 
58 C4Effect::C4Effect(C4Effect **ppEffectList, C4PropList * prototype, int32_t iPrio, int32_t iTimerInterval):
59  C4PropListNumbered(prototype)
60 {
61  // assign values
62  iPriority = 0; // effect is not yet valid; some callbacks to other effects are done before
63  iInterval = iTimerInterval;
64  iTime = 0;
66  AcquireNumber();
67  Register(ppEffectList, iPrio);
68  SetProperty(P_Name, C4VString(prototype->GetName()));
69 }
70 
71 void C4Effect::Register(C4Effect **ppEffectList, int32_t iPrio)
72 {
73  // get effect target
74  C4Effect *pCheck, *pPrev = *ppEffectList;
75  if (pPrev && Abs(pPrev->iPriority) < iPrio)
76  {
77  while ((pCheck = pPrev->pNext))
78  if (Abs(pCheck->iPriority) >= iPrio) break; else pPrev = pCheck;
79  // insert after previous
80  pNext = pPrev->pNext;
81  pPrev->pNext = this;
82  }
83  else
84  {
85  // insert as first effect
86  pNext = *ppEffectList;
87  *ppEffectList = this;
88  }
89 }
90 
91 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)
92 {
93  C4Effect * pEffect = new C4Effect(ppEffectList, szName, iPrio, iTimerInterval, pCmdTarget);
94  return pEffect->Init(pForObj, iPrio, rVal1, rVal2, rVal3, rVal4);
95 }
96 
97 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)
98 {
99  C4Effect * pEffect = new C4Effect(ppEffectList, prototype, iPrio, iTimerInterval);
100  return pEffect->Init(pForObj, iPrio, rVal1, rVal2, rVal3, rVal4);
101 }
102 
103 C4Effect * C4Effect::Init(C4PropList *pForObj, int32_t iPrio, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
104 {
105  Target = pForObj;
106  // ask all effects with higher priority first - except for prio 1 effects, which are considered out of the priority call chain (as per doc)
107  bool fRemoveUpper = (iPrio != 1);
108  // note that apart from denying the creation of this effect, higher priority effects may also remove themselves
109  // or do other things with the effect list
110  // (which does not quite make sense, because the effect might be denied by another effect)
111  // so the priority is assigned after this call, marking this effect dead before it's definitely valid
112  if (fRemoveUpper && pNext)
113  {
114  C4Effect * pEffect2 = pNext->Check(GetName(), iPrio, iInterval, rVal1, rVal2, rVal3, rVal4);
115  if (pEffect2)
116  {
117  // effect denied (iResult = -1), added to an effect (iResult = Number of that effect)
118  // or added to an effect that destroyed itself (iResult = -2)
119  if (pEffect2 != (C4Effect*)C4Fx_Effect_Deny && pEffect2 != (C4Effect*)C4Fx_Effect_Annul) return pEffect2;
120  // effect is still marked dead
121  return nullptr;
122  }
123  }
124  // init effect
125  // higher-priority effects must be deactivated temporarily, and then reactivated regarding the new effect
126  // higher-level effects should not be inserted during the process of removing or adding a lower-level effect
127  // because that would cause a wrong initialization order
128  // (hardly ever causing trouble, however...)
129  C4Effect *pLastRemovedEffect=nullptr;
130  C4AulFunc * pFn;
131  if (!GetCallbackScript())
132  {
133  Call(P_Construction, &C4AulParSet(rVal1, rVal2, rVal3, rVal4)).getInt();
134  if (pForObj && !pForObj->Status) return nullptr;
135  pFn = GetFunc(P_Start);
136  }
137  else
138  pFn = pFnStart;
139  if (fRemoveUpper && pNext && pFn)
140  TempRemoveUpperEffects(false, &pLastRemovedEffect);
141  // bad things may happen
142  if (pForObj && !pForObj->Status) return nullptr; // this will be invalid!
143  iPriority = iPrio; // validate effect now
144  if (CallStart(0, rVal1, rVal2, rVal3, rVal4) == C4Fx_Start_Deny)
145  // the effect denied to start: assume it hasn't, and mark it dead
146  SetDead();
147  if (fRemoveUpper && pNext && pFn)
148  TempReaddUpperEffects(pLastRemovedEffect);
149  if (pForObj && !pForObj->Status) return nullptr; // this will be invalid!
150  // Update OnFire cache
151  if (!IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, GetName()))
152  pForObj->SetOnFire(true);
153  return this;
154 }
155 
157 {
158  // defaults
161  pNext = nullptr;
162 }
163 
165 {
166  // del following effects (not recursively)
167  C4Effect *pEffect;
168  while ((pEffect = pNext))
169  {
170  pNext = pEffect->pNext;
171  pEffect->pNext = nullptr;
172  delete pEffect;
173  }
174 }
175 
177 {
178  // denum in all effects
179  C4Effect *pEff = this;
180  do
181  {
182  // command target
183  pEff->CommandTarget.Denumerate(numbers);
184  // assign any callback functions
185  pEff->AssignCallbackFunctions();
186  pEff->C4PropList::Denumerate(numbers);
187  }
188  while ((pEff=pEff->pNext));
189 }
190 
192 {
193  // clear pointers in all effects
194  C4Effect *pEff = this;
195  do
196  // command target lost: effect dead w/o callback
197  if (pEff->CommandTarget.getPropList() == pObj)
198  {
199  pEff->SetDead();
200  pEff->CommandTarget.Set0();
201  }
202  while ((pEff=pEff->pNext));
203 }
204 
206 {
207  iPriority = 0;
208 }
209 
210 C4Effect *C4Effect::Get(const char *szName, int32_t iIndex, int32_t iMaxPriority)
211 {
212  // safety
213  if (!szName) return nullptr;
214  // check all effects
215  C4Effect *pEff = this;
216  do
217  {
218  // skip dead
219  if (pEff->IsDead()) continue;
220  // skip effects with too high priority
221  if (iMaxPriority && pEff->iPriority > iMaxPriority) continue;
222  // wildcard compare name
223  const char *szEffectName = pEff->GetName();
224  if (!SWildcardMatchEx(szEffectName, szName)) continue;
225  // effect name matches
226  // check index
227  if (iIndex--) continue;
228  // effect found
229  return pEff;
230  }
231  while ((pEff=pEff->pNext));
232  // nothing found
233  return nullptr;
234 }
235 
236 int32_t C4Effect::GetCount(const char *szMask, int32_t iMaxPriority)
237 {
238  // count all matching effects
239  int32_t iCnt=0; C4Effect *pEff = this;
240  do if (!pEff->IsDead())
241  if (!szMask || SWildcardMatchEx(pEff->GetName(), szMask))
242  if (!iMaxPriority || pEff->iPriority <= iMaxPriority)
243  ++iCnt;
244  while ((pEff = pEff->pNext));
245  // return count
246  return iCnt;
247 }
248 
249 C4Effect* C4Effect::Check(const char *szCheckEffect, int32_t iPrio, int32_t iTimer, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
250 {
251  // priority=1: always OK; no callbacks
252  if (iPrio == 1) return nullptr;
253  // check this and other effects
254  C4Effect *pAddToEffect = nullptr; bool fDoTempCallsForAdd = false;
255  C4Effect *pLastRemovedEffect=nullptr;
256  for (C4Effect *pCheck = this; pCheck; pCheck = pCheck->pNext)
257  {
258  if (!pCheck->IsDead() && pCheck->iPriority >= iPrio)
259  {
260  int32_t iResult = pCheck->CallEffect(szCheckEffect, rVal1, rVal2, rVal3, rVal4);
261  if (iResult == C4Fx_Effect_Deny)
262  // effect denied
263  return (C4Effect*)C4Fx_Effect_Deny;
264  // add to other effect
265  if (iResult == C4Fx_Effect_Annul || iResult == C4Fx_Effect_AnnulCalls)
266  {
267  pAddToEffect = pCheck;
268  fDoTempCallsForAdd = (iResult == C4Fx_Effect_AnnulCalls);
269  }
270  }
271  }
272  // adding to other effect?
273  if (pAddToEffect)
274  {
275  // do temp remove calls if desired
276  if (pAddToEffect->pNext && fDoTempCallsForAdd)
277  pAddToEffect->TempRemoveUpperEffects(false, &pLastRemovedEffect);
278  C4Value Par1 = C4VString(szCheckEffect), Par2 = C4VInt(iTimer), Par8;
279  int32_t iResult = pAddToEffect->DoCall(Target, PSFS_FxAdd, Par1, Par2, rVal1, rVal2, rVal3, rVal4, Par8).getInt();
280  // do temp readd calls if desired
281  if (pAddToEffect->pNext && fDoTempCallsForAdd)
282  pAddToEffect->TempReaddUpperEffects(pLastRemovedEffect);
283  // effect removed by this call?
284  if (iResult == C4Fx_Start_Deny)
285  {
286  pAddToEffect->Kill();
287  return (C4Effect*)C4Fx_Effect_Annul;
288  }
289  else
290  // other effect is the target effect number
291  return pAddToEffect;
292  }
293  // added to no effect and not denied
294  return nullptr;
295 }
296 
297 void C4Effect::Execute(C4Effect **ppEffectList)
298 {
299  // advance all effect timers first; then do execution
300  // this prevents a possible endless loop if timers register into the same effect list with interval 1 while it is being executed
301  for (C4Effect *pEffect = *ppEffectList; pEffect; pEffect = pEffect->pNext)
302  {
303  // ignore dead status; adjusting their time doesn't hurt
304  ++pEffect->iTime;
305  }
306  // get effect list
307  // execute all effects not marked as dead
308  C4Effect *pEffect = *ppEffectList, **ppPrevEffect=ppEffectList;
309  while (pEffect)
310  {
311  // effect dead?
312  if (pEffect->IsDead())
313  {
314  // delete it, then
315  C4Effect *pNextEffect = pEffect->pNext;
316  pEffect->pNext = nullptr;
317  delete pEffect;
318  // next effect
319  *ppPrevEffect = pEffect = pNextEffect;
320  }
321  else
322  {
323  // check timer execution
324  if (pEffect->iInterval && !(pEffect->iTime % pEffect->iInterval) && pEffect->iTime)
325  {
326  if (pEffect->CallTimer(pEffect->iTime) == C4Fx_Execute_Kill)
327  {
328  // safety: this class got deleted!
329  if (pEffect->Target && !pEffect->Target->Status) return;
330  // timer function decided to finish it
331  pEffect->Kill();
332  }
333  // safety: this class got deleted!
334  if (pEffect->Target && !pEffect->Target->Status) return;
335  }
336  // next effect
337  ppPrevEffect = &pEffect->pNext;
338  pEffect = pEffect->pNext;
339  }
340  }
341 }
342 
344 {
345  // active?
346  C4Effect *pLastRemovedEffect=nullptr;
347  if (IsActive())
348  // then temp remove all higher priority effects
349  TempRemoveUpperEffects(false, &pLastRemovedEffect);
350  else
351  // otherwise: temp reactivate before real removal
352  // this happens only if a lower priority effect removes an upper priority effect in its add- or removal-call
354  // remove this effect
355  int32_t iPrevPrio = iPriority; SetDead();
356  if (CallStop(C4FxCall_Normal, false) == C4Fx_Stop_Deny)
357  // effect denied to be removed: recover
358  iPriority = iPrevPrio;
359  // reactivate other effects
360  TempReaddUpperEffects(pLastRemovedEffect);
361  // Update OnFire cache
363  if (!Get(C4Fx_AnyFire))
364  Target->SetOnFire(false);
365  if (IsDead() && !GetCallbackScript())
367 }
368 
369 void C4Effect::ClearAll(int32_t iClearFlag)
370 {
371  // simply remove access all effects recursively, and do removal calls
372  // this does not regard lower-level effects being added in the removal calls,
373  // because this could hang the engine with poorly coded effects
374  if (pNext) pNext->ClearAll(iClearFlag);
375  if ((Target && !Target->Status) || IsDead()) return;
376  int32_t iPrevPrio = iPriority;
377  SetDead();
378  if (CallStop(iClearFlag, false) == C4Fx_Stop_Deny)
379  {
380  // this stop-callback might have deleted the object and then denied its own removal
381  // must not modify self in this case...
382  if (Target && !Target->Status) return;
383  // effect denied to be removed: recover it
384  iPriority = iPrevPrio;
385  }
386  // Update OnFire cache
388  if (!Get(C4Fx_AnyFire))
389  Target->SetOnFire(false);
390  if (IsDead() && !GetCallbackScript())
391  Call(P_Destruction, &C4AulParSet(iClearFlag));
392 }
393 
394 void C4Effect::DoDamage(int32_t &riDamage, int32_t iDamageType, int32_t iCausePlr)
395 {
396  // ask all effects for damage adjustments
397  C4Effect *pEff = this;
398  do
399  {
400  if (!pEff->IsDead())
401  pEff->CallDamage(riDamage, iDamageType, iCausePlr);
402  if (Target && !Target->Status) return;
403  }
404  while ((pEff = pEff->pNext) && riDamage);
405 }
406 
407 static C4Object * Obj(C4PropList * p) { return p ? p->GetObject() : nullptr; }
408 
409 C4Value C4Effect::DoCall(C4PropList *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)
410 {
412  if (!p)
413  {
414  C4AulFunc * fn = GetFunc(szFn);
415  if (fn) return fn->Exec(this, &C4AulParSet(rVal1, rVal2, rVal3, rVal4, rVal5, rVal6, rVal7));
416  }
417  else
418  {
419  // old variant
420  // compose function name
421  C4AulFunc * fn = p->GetFunc(FormatString(PSF_FxCustom, GetName(), szFn).getData());
422  if (fn) return fn->Exec(p, &C4AulParSet(Obj(pObj), this, rVal1, rVal2, rVal3, rVal4, rVal5, rVal6, rVal7));
423  }
424  return C4Value();
425 }
426 
427 int C4Effect::CallStart(int temporary, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
428 {
429  if (!GetCallbackScript())
430  return Call(P_Start, &C4AulParSet(temporary, var1, var2, var3, var4)).getInt();
431  if (pFnStart)
432  return pFnStart->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, temporary, var1, var2, var3, var4)).getInt();
433  return C4Fx_OK;
434 }
435 int C4Effect::CallStop(int reason, bool temporary)
436 {
437  if (!GetCallbackScript())
438  return Call(P_Stop, &C4AulParSet(reason, temporary)).getInt();
439  if (pFnStop)
440  return pFnStop->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, reason, temporary)).getInt();
441  return C4Fx_OK;
442 }
443 int C4Effect::CallTimer(int time)
444 {
445  if (!GetCallbackScript())
446  return Call(P_Timer, &C4AulParSet(time)).getInt();
447  if (pFnTimer)
448  return pFnTimer->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, time)).getInt();
449  return C4Fx_Execute_Kill;
450 }
451 void C4Effect::CallDamage(int32_t & damage, int damagetype, int plr)
452 {
453  if (!GetCallbackScript())
454  {
455  C4AulFunc *pFn = GetFunc(P_Damage);
456  if (pFn)
457  damage = pFn->Exec(this, &C4AulParSet(damage, damagetype, plr)).getInt();
458  }
459  else if (pFnDamage)
460  damage = pFnDamage->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, damage, damagetype, plr)).getInt();
461 }
462 int C4Effect::CallEffect(const char * effect, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
463 {
464  if (!GetCallbackScript())
465  return Call(P_Effect, &C4AulParSet(effect, var1, var2, var3, var4)).getInt();
466  if (pFnEffect)
467  return pFnEffect->Exec(GetCallbackScript(), &C4AulParSet(effect, Obj(Target), this, var1, var2, var3, var4)).getInt();
468  return C4Fx_OK;
469 }
470 
472 {
473  // safety
474  if (!pObj) return;
475  // check all effects for reassignment
476  C4Effect *pCheck = this;
477  while (pCheck)
478  {
479  if (pCheck->GetCallbackScript() == pObj)
480  pCheck->ReAssignCallbackFunctions();
481  pCheck = pCheck->pNext;
482  }
483 }
484 
485 void C4Effect::TempRemoveUpperEffects(bool fTempRemoveThis, C4Effect **ppLastRemovedEffect)
486 {
487  if (Target && !Target->Status) return; // this will be invalid!
488  // priority=1: no callbacks
489  if (iPriority == 1) return;
490  // remove from high to low priority
491  // recursive implementation...
492  C4Effect *pEff = pNext;
493  while (pEff) if (pEff->IsActive()) break; else pEff = pEff->pNext;
494  // temp remove active effects with higher priority
495  if (pEff) pEff->TempRemoveUpperEffects(true, ppLastRemovedEffect);
496  // temp remove this
497  if (fTempRemoveThis)
498  {
499  FlipActive();
500  // Update OnFire cache
502  if (!Get(C4Fx_AnyFire))
503  Target->SetOnFire(false);
504  // temp callbacks only for higher priority effects
505  if (iPriority!=1) CallStop(C4FxCall_Temp, true);
506  if (!*ppLastRemovedEffect) *ppLastRemovedEffect = this;
507  }
508 }
509 
511 {
512  // nothing to do? - this will also happen if TempRemoveUpperEffects did nothing due to priority==1
513  if (!pLastReaddEffect) return;
514  if (Target && !Target->Status) return; // this will be invalid!
515  // simply activate all following, inactive effects
516  for (C4Effect *pEff = pNext; pEff; pEff = pEff->pNext)
517  {
518  if (pEff->IsInactiveAndNotDead())
519  {
520  pEff->FlipActive();
521  if (pEff->iPriority!=1) pEff->CallStart(C4FxCall_Temp, C4Value(), C4Value(), C4Value(), C4Value());
522  if (Target && WildcardMatch(C4Fx_AnyFire, pEff->GetName()))
523  Target->SetOnFire(true);
524  }
525  // done?
526  if (pEff == pLastReaddEffect) break;
527  }
528 }
529 
531 {
532  if (pComp->isDeserializer()) Target = Owner;
533  // read name
534  pComp->Separator(StdCompiler::SEP_START); // '('
535  // read priority
536  pComp->Value(iPriority); pComp->Separator();
537  // read time and intervall
538  pComp->Value(iTime); pComp->Separator();
539  pComp->Value(iInterval); pComp->Separator();
540  // read object number
541  // FIXME: replace with this when savegame compat breaks for other reasons
542  // pComp->Value(mkParAdapt(CommandTarget, numbers));
543  int32_t nptr = 0;
546  pComp->Value(nptr);
547  if (pComp->isDeserializer())
549  pComp->Separator();
550  // read ID
551  if (pComp->isSerializer())
552  {
554  if (p)
555  p->RefCompileFunc(pComp, numbers);
556  else
557  pComp->String(const_cast<char*>("None"), 5, StdCompiler::RCT_ID);
558  }
559  else
560  {
561  StdStrBuf s;
563  // An Object trumps a definition as command target
564  if (!nptr)
567  }
568  pComp->Separator();
569  // proplist
570  C4PropListNumbered::CompileFunc(pComp, numbers);
571  pComp->Separator(StdCompiler::SEP_END); // ')'
572  // is there a next effect?
573  bool fNext = !! pNext;
574  if (pComp->hasNaming())
575  {
576  if (fNext || pComp->isDeserializer())
577  fNext = pComp->Separator();
578  }
579  else
580  pComp->Value(fNext);
581  if (!fNext) return;
582  // read next
583  pComp->Value(mkParAdapt(mkPtrAdaptNoNull(pNext), Owner, numbers));
584  // denumeration and callback assignment will be done later
585 }
586 
588 {
589  if (k >= &Strings.P[0] && k < &Strings.P[P_LAST])
590  {
591  switch(k - &Strings.P[0])
592  {
593  case P_Name:
594  if (!to.getStr() || !*to.getStr()->GetCStr())
595  throw C4AulExecError("effect: Name has to be a nonempty string");
598  return;
599  case P_Priority:
600  throw C4AulExecError("effect: Priority is readonly");
601  case P_Interval: iInterval = to.getInt(); return;
602  case P_CommandTarget:
603  throw C4AulExecError("effect: CommandTarget is readonly");
604  case P_Target:
605  throw C4AulExecError("effect: Target is readonly");
606  case P_Time: iTime = to.getInt(); return;
607  case P_Prototype:
608  throw new C4AulExecError("effect: Prototype is readonly");
609  }
610  }
612 }
613 
615 {
616  if (k >= &Strings.P[0] && k < &Strings.P[P_LAST])
617  {
618  switch(k - &Strings.P[0])
619  {
620  case P_Name:
621  throw C4AulExecError("effect: Name has to be a nonempty string");
622  case P_Priority:
623  throw C4AulExecError("effect: Priority is readonly");
624  case P_Interval: iInterval = 0; return;
625  case P_CommandTarget:
626  throw C4AulExecError("effect: CommandTarget is readonly");
627  case P_Target:
628  throw C4AulExecError("effect: Target is readonly");
629  case P_Time: iTime = 0; return;
630  case P_Prototype:
631  throw new C4AulExecError("effect: Prototype is readonly");
632  }
633  }
635 }
636 
637 bool C4Effect::GetPropertyByS(const C4String *k, C4Value *pResult) const
638 {
639  if (k >= &Strings.P[0] && k < &Strings.P[P_LAST])
640  {
641  switch(k - &Strings.P[0])
642  {
643  case P_Name: return C4PropListNumbered::GetPropertyByS(k, pResult);
644  case P_Priority: *pResult = C4VInt(Abs(iPriority)); return true;
645  case P_Interval: *pResult = C4VInt(iInterval); return true;
646  case P_CommandTarget: *pResult = CommandTarget; return true;
647  case P_Target: *pResult = C4Value(Target); return true;
648  case P_Time: *pResult = C4VInt(iTime); return true;
649  }
650  }
651  return C4PropListNumbered::GetPropertyByS(k, pResult);
652 }
653 
655 {
657  int i;
658  i = a->GetSize();
659  a->SetSize(i + 5);
660  (*a)[i++] = C4VString(&::Strings.P[P_Name]);
661  (*a)[i++] = C4VString(&::Strings.P[P_Priority]);
662  (*a)[i++] = C4VString(&::Strings.P[P_Interval]);
663  (*a)[i++] = C4VString(&::Strings.P[P_CommandTarget]);
664  (*a)[i++] = C4VString(&::Strings.P[P_Target]);
665  (*a)[i++] = C4VString(&::Strings.P[P_Time]);
666  return a;
667 }
C4Effect * pNext
Definition: C4Effect.h:75
virtual void ResetProperty(C4String *k)
Definition: C4PropList.cpp:973
const char * getData() const
Definition: StdBuf.h:442
int CallStart(int temporary, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
Definition: C4Effect.cpp:427
C4String P[P_LAST]
virtual bool Separator(Sep eSep=SEP_SEP)
Definition: StdCompiler.h:119
void ClearAll(int32_t iClearFlag)
Definition: C4Effect.cpp:369
virtual bool hasNaming()
Definition: StdCompiler.h:58
void SetPropertyByS(C4String *k, const C4Value &to) override
Definition: C4Effect.cpp:587
#define PSF_FxCustom
Definition: C4GameScript.h:114
C4String * getStr() const
Definition: C4Value.h:117
C4AulFunc * pFnStop
Definition: C4Effect.h:82
void Register(C4Effect **ppEffectList, int32_t iPrio)
Definition: C4Effect.cpp:71
C4AulScriptEngine ScriptEngine
Definition: C4Globals.cpp:43
#define sprintf
Definition: Standard.h:164
void CompileFunc(StdCompiler *pComp, C4ValueNumbers *numbers)
Definition: C4PropList.cpp:180
C4AulFunc * GetFunc(C4PropertyName k) const
Definition: C4PropList.h:105
bool IsDead()
Definition: C4Effect.h:110
void Denumerate(C4ValueNumbers *) override
Definition: C4Effect.cpp:176
const char * GetCStr() const
Definition: C4StringTable.h:49
friend class C4Value
Definition: C4PropList.h:165
C4Value C4VInt(int32_t i)
Definition: C4Value.h:242
#define PSF_FxTimer
Definition: C4GameScript.h:111
void SetProperty(C4PropertyName k, const C4Value &to)
Definition: C4PropList.h:120
void FlipActive()
Definition: C4Effect.h:111
C4Effect * Init(C4PropList *pForObj, int32_t iPrio, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
Definition: C4Effect.cpp:103
int32_t iInterval
Definition: C4Effect.h:73
bool GetGlobalConstant(const char *szName, C4Value *pTargetValue)
#define C4FxCall_TempAddForRemoval
Definition: C4Effect.h:44
void Set0()
Definition: C4Value.h:336
#define PSF_FxStop
Definition: C4GameScript.h:110
#define PSF_FxStart
Definition: C4GameScript.h:109
virtual class C4PropListStatic * IsStatic()
Definition: C4PropList.h:85
void SetObjectEnum(int i)
Definition: C4Value.h:142
#define a
int32_t GetCount(const char *szMask, int32_t iMaxPriority=0)
Definition: C4Effect.cpp:236
void TempReaddUpperEffects(C4Effect *pLastReaddEffect)
Definition: C4Effect.cpp:510
#define PSFS_FxAdd
Definition: C4GameScript.h:156
virtual C4Object * GetObject()
Definition: C4PropList.cpp:667
#define C4Fx_Effect_Deny
Definition: C4Effect.h:32
virtual void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped)=0
void TempRemoveUpperEffects(bool fTempRemoveThis, C4Effect **ppLastRemovedEffect)
Definition: C4Effect.cpp:485
C4AulFunc * pFnEffect
Definition: C4Effect.h:83
bool IsActive()
Definition: C4Effect.h:112
#define C4FxCall_Normal
Definition: C4Effect.h:42
#define PSF_FxEffect
Definition: C4GameScript.h:112
void ReAssignCallbackFunctions()
Definition: C4Effect.h:127
#define C4Fx_Effect_AnnulCalls
Definition: C4Effect.h:34
bool isSerializer()
Definition: StdCompiler.h:54
int CallStop(int reason, bool temporary)
Definition: C4Effect.cpp:435
int iResult
Definition: C4GroupMain.cpp:39
void Denumerate(C4ValueNumbers *)
Definition: C4Value.cpp:251
void Kill()
Definition: C4Effect.cpp:343
void AssignCallbackFunctions()
Definition: C4Effect.cpp:27
C4Effect * Check(const char *szCheckEffect, int32_t iPrio, int32_t iTimer, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
Definition: C4Effect.cpp:249
C4Value CommandTarget
Definition: C4Effect.h:78
C4StringTable Strings
Definition: C4Globals.cpp:42
int iCnt
Definition: TstC4NetIO.cpp:32
virtual bool GetPropertyByS(const C4String *k, C4Value *pResult) const
Definition: C4PropList.cpp:757
static 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)
Definition: C4Effect.cpp:91
virtual const char * GetName() const
Definition: C4PropList.cpp:649
virtual C4ValueArray * GetProperties() const
Definition: C4PropList.cpp:914
bool SWildcardMatchEx(const char *szString, const char *szWildcard)
Definition: Standard.cpp:607
#define C4Fx_AnyFire
Definition: C4Effect.h:151
#define C4Fx_Execute_Kill
Definition: C4Effect.h:36
int32_t iTime
Definition: C4Effect.h:73
StdPtrAdapt< T > mkPtrAdaptNoNull(T *&rpObj)
Definition: StdAdaptors.h:606
#define C4AUL_MAX_Identifier
Definition: C4Aul.h:26
void RefCompileFunc(StdCompiler *pComp, C4ValueNumbers *numbers) const
Definition: C4PropList.cpp:240
static void Execute(C4Effect **ppEffectList)
Definition: C4Effect.cpp:297
C4PropList * GetCallbackScript()
Definition: C4Effect.cpp:40
void SetDead()
Definition: C4Effect.cpp:205
void SetSize(int32_t inSize)
void CompileFunc(StdCompiler *pComp, C4PropList *Owner, C4ValueNumbers *)
Definition: C4Effect.cpp:530
C4Value Exec(C4PropList *p=nullptr, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4AulFunc.h:72
int32_t Status
Definition: C4PropList.h:168
void Value(const T &rStruct)
Definition: StdCompiler.h:161
C4AulFunc * pFnStart
Definition: C4Effect.h:82
C4ValueArray * GetProperties() const override
Definition: C4Effect.cpp:654
C4AulFunc * pFnTimer
Definition: C4Effect.h:81
int32_t GetSize() const
Definition: C4ValueArray.h:36
#define PSF_FxDamage
Definition: C4GameScript.h:113
C4AulFunc * pFnDamage
Definition: C4Effect.h:84
C4Effect * Get(const char *szName, int32_t iIndex=0, int32_t iMaxPriority=0)
Definition: C4Effect.cpp:210
int32_t getInt() const
Definition: C4Value.h:112
virtual bool isDeserializer()
Definition: StdCompiler.h:53
#define C4Fx_Start_Deny
Definition: C4Effect.h:39
#define C4FxCall_Temp
Definition: C4Effect.h:43
C4PropList * Target
Definition: C4Effect.h:79
void ResetProperty(C4String *k) override
Definition: C4Effect.cpp:614
int32_t iPriority
Definition: C4Effect.h:72
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:374
#define C4Fx_Effect_Annul
Definition: C4Effect.h:33
C4Value C4VString(C4String *pStr)
Definition: C4Value.h:246
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:458
virtual void SetPropertyByS(C4String *k, const C4Value &to)
Definition: C4PropList.cpp:952
void SetPropList(C4PropList *PropList)
Definition: C4Value.h:141
void CallDamage(int32_t &damage, int damagetype, int plr)
Definition: C4Effect.cpp:451
T Abs(T val)
Definition: Standard.h:42
C4Value DoCall(C4PropList *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)
Definition: C4Effect.cpp:409
int CallEffect(const char *effect, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
Definition: C4Effect.cpp:462
C4PropList * _getPropList() const
Definition: C4Value.h:129
#define C4Fx_Stop_Deny
Definition: C4Effect.h:38
void DoDamage(int32_t &riDamage, int32_t iDamageType, int32_t iCausePlr)
Definition: C4Effect.cpp:394
virtual C4PropListNumbered * GetPropListNumbered()
Definition: C4PropList.cpp:703
void ClearPointers(C4PropList *pObj)
Definition: C4Effect.cpp:191
#define s
int CallTimer(int time)
Definition: C4Effect.cpp:443
virtual void SetOnFire(bool OnFire)
Definition: C4PropList.h:69
#define C4Fx_OK
Definition: C4Effect.h:30
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
void OnObjectChangedDef(C4PropList *pObj)
Definition: C4Effect.cpp:471
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4PropList.h:110
bool GetPropertyByS(const C4String *k, C4Value *pResult) const override
Definition: C4Effect.cpp:637
~C4Effect() override
Definition: C4Effect.cpp:164
C4PropList * getPropList() const
Definition: C4Value.h:116