OpenClonk
C4GameScript.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 /* Functions mapped by C4Script */
19 
20 #include "C4Include.h"
22 #include "game/C4GameScript.h"
23 
24 #include "control/C4GameControl.h"
25 #include "control/C4RoundResults.h"
26 #include "editor/C4Console.h"
27 #include "game/C4Application.h"
28 #include "game/C4GraphicsSystem.h"
29 #include "game/C4Viewport.h"
31 #include "graphics/C4Shader.h"
32 #include "gui/C4GameMessage.h"
33 #include "gui/C4MessageInput.h"
34 #include "gui/C4MouseControl.h"
35 #include "gui/C4ScriptGuiWindow.h"
36 #include "landscape/C4Landscape.h"
37 #include "landscape/C4PXS.h"
38 #include "landscape/C4Particles.h"
39 #include "landscape/C4Sky.h"
40 #include "landscape/C4Texture.h"
41 #include "landscape/C4Weather.h"
42 #include "landscape/fow/C4FoW.h"
43 #include "object/C4Command.h"
44 #include "object/C4DefList.h"
45 #include "object/C4GameObjects.h"
46 #include "platform/C4GamePadCon.h"
47 #include "player/C4Player.h"
48 #include "player/C4PlayerList.h"
49 #include "script/C4AulDefFunc.h"
50 
51 
52 void MakeAbsCoordinates(C4PropList * _this, int32_t &x, int32_t &y)
53 {
54  C4Object *obj = Object(_this);
55  if (obj)
56  {
57  x += obj->GetX();
58  y += obj->GetY();
59  }
60 }
61 
62 void MakeAbsCoordinates(C4PropList * _this, long &x, long &y)
63 {
64  C4Object *obj = Object(_this);
65  if (obj)
66  {
67  x += obj->GetX();
68  y += obj->GetY();
69  }
70 }
71 
73 {
74  if (target)
75  {
76  if (target == ScriptEngine.GetPropList())
77  {
79  }
80  if (target == GameScript.ScenPropList.getPropList())
81  {
83  }
84  C4Object * obj = target->GetObject();
85  if (!obj)
86  {
87  throw C4AulExecError("Effect target has to be an object");
88  }
89  return &obj->pEffects;
90  }
92 }
93 
94 // undocumented!
95 static bool FnIncinerateLandscape(C4PropList * _this, long x, long y, long caused_by_plr)
96 {
97  MakeAbsCoordinates(_this, x, y);
98  return !!::Landscape.Incinerate(x, y, caused_by_plr);
99 }
100 
101 static void FnSetGravity(C4PropList * _this, long gravity)
102 {
103  // Gravity in 1/100 pixel/tick^2
104  ::Landscape.SetGravity(C4REAL100(Clamp<long>(gravity, -1000, 1000)));
105 }
106 
107 static long FnGetGravity(C4PropList * _this)
108 {
109  return fixtoi(::Landscape.GetGravity() * 100);
110 }
111 
112 static C4String *FnGetPlayerName(C4PropList * _this, long player_nr)
113 {
114  if (!ValidPlr(player_nr))
115  {
116  return nullptr;
117  }
118  return String(::Players.Get(player_nr)->GetName());
119 }
120 
121 static long FnGetPlayerType(C4PropList * _this, long player_nr)
122 {
123  C4Player *player = ::Players.Get(player_nr);
124  if (!player)
125  {
126  return 0;
127  }
128  return player->GetType();
129 }
130 
131 static long FnGetPlayerColor(C4PropList * _this, long player_nr)
132 {
133  C4Player *player = ::Players.Get(player_nr);
134  return player ? player->ColorDw : 0;
135 }
136 
137 // undocumented!
138 static Nillable<long> FnGetPlrClonkSkin(C4PropList * _this, long player_nr)
139 {
140  C4Player *player = ::Players.Get(player_nr);
141  if (player)
142  {
143  return player->PrefClonkSkin;
144  }
145  return C4Void();
146 }
147 
148 static Nillable<long> FnGetX(C4PropList * _this, long precision)
149 {
150  if (!Object(_this))
151  {
152  return C4Void();
153  }
154  if (!precision)
155  {
156  precision = 1;
157  }
158  return fixtoi(Object(_this)->fix_x, precision);
159 }
160 
161 static Nillable<long> FnGetY(C4PropList * _this, long precision)
162 {
163  if (!Object(_this))
164  {
165  return C4Void();
166  }
167  if (!precision)
168  {
169  precision = 1;
170  }
171  return fixtoi(Object(_this)->fix_y, precision);
172 }
173 
175 {
176  if (owner.IsNil())
177  {
178  if (Object(_this))
179  {
180  return Object(_this)->Controller;
181  }
182  else
183  {
184  return NO_OWNER;
185  }
186  }
187  return owner;
188 }
189 
191 {
192  // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player
193  if (obj && Object(_this) && Object(_this)->Controller > NO_OWNER)
194  {
195  obj->Controller = Object(_this)->Controller;
196  }
197 }
198 
199 static C4Object *FnCreateObjectAbove(C4PropList * _this, C4PropList * PropList, long x, long y, Nillable<long> owner)
200 {
201  MakeAbsCoordinates(_this, x, y);
202  long set_owner = GetValidOwner(_this, owner);
203 
204  C4Object *obj = Game.CreateObject(PropList, Object(_this), set_owner, x, y);
205 
206  // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player
207  AssignController(_this, obj);
208 
209  return obj;
210 }
211 
212 static C4Object *FnCreateObject(C4PropList * _this, C4PropList * PropList, long x, long y, Nillable<long> owner)
213 {
214  MakeAbsCoordinates(_this, x, y);
215  long set_owner = GetValidOwner(_this, owner);
216 
217  C4Object *obj = Game.CreateObject(PropList, Object(_this), set_owner, x, y, 0, true);
218 
219  // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player
220  AssignController(_this, obj);
221 
222  return obj;
223 }
224 
225 
226 static C4Object *FnCreateConstruction(C4PropList * _this,
227  C4PropList * PropList, long x, long y, Nillable<long> owner,
228  long completion, bool adjust_terrain, bool check_site)
229 {
230  // Make sure parameters are valid
231  if (!PropList || !PropList->GetDef())
232  {
233  return nullptr;
234  }
235 
236  // Local object calls override position offset, owner
237  MakeAbsCoordinates(_this, x, y);
238 
239  // Check site
240  if (check_site && !ConstructionCheck(PropList, x, y, Object(_this)))
241  {
242  return nullptr;
243  }
244 
245  long set_owner = GetValidOwner(_this, owner);
246 
247  // Create site object
248  C4Object *obj = Game.CreateObjectConstruction(PropList, Object(_this), set_owner, x, y, completion*FullCon/100, adjust_terrain);
249 
250  // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player
251  AssignController(_this, obj);
252 
253  return obj;
254 }
255 
256 static C4ValueArray *FnFindConstructionSite(C4PropList * _this, C4PropList * PropList, int32_t abs_x, int32_t abs_y)
257 {
258  // Get def
259  C4Def *def;
260  if (!(def = PropList->GetDef()))
261  {
262  return nullptr;
263  }
264  // Construction check at starting position
265  if (ConstructionCheck(PropList, abs_x, abs_y))
266  {
267  return nullptr;
268  }
269  // Search for real
270  bool result = !!FindConSiteSpot(abs_x, abs_y, def->Shape.Wdt, def->Shape.Hgt, 20);
271  if (!result)
272  {
273  return nullptr;
274  }
275  auto *array = new C4ValueArray(2);
276  array->SetItem(0, C4VInt(abs_x));
277  array->SetItem(1, C4VInt(abs_y));
278  return array;
279 }
280 
281 static bool FnCheckConstructionSite(C4PropList * _this, C4PropList * PropList, int32_t x, int32_t y)
282 {
283  // Make sure parameters are valid
284  if (!PropList || !PropList->GetDef())
285  {
286  return false;
287  }
288 
289  // Local object calls override position offset, owner
290  MakeAbsCoordinates(_this, x, y);
291 
292  // Check construction site
293  return ConstructionCheck(PropList, x, y);
294 }
295 
296 C4FindObject *CreateCriterionsFromPars(C4Value *parameters, C4FindObject **pFOs, C4SortObject **pSOs, const C4Object *context)
297 {
298  int count = 0;
299  int sort_count = 0;
300  bool has_layer_check = false;
301  // Read all parameters
302  for (int i = 0; i < C4AUL_MAX_Par; i++)
303  {
304  C4Value Data = *(parameters++);
305  // No data given?
306  if (!Data)
307  {
308  break;
309  }
310  // Construct
311  C4SortObject *pSO = nullptr;
312  C4FindObject *pFO = C4FindObject::CreateByValue(Data, pSOs ? &pSO : nullptr, context, &has_layer_check);
313  // Add FindObject
314  if (pFO)
315  {
316  pFOs[count++] = pFO;
317  }
318  // Add SortObject
319  if (pSO)
320  {
321  pSOs[sort_count++] = pSO;
322  }
323  }
324  // No criterions?
325  if (!count)
326  {
327  for (int i = 0; i < sort_count; ++i)
328  {
329  delete pSOs[i];
330  }
331  return nullptr;
332  }
333  // Implicit layer check
334  if (context && !has_layer_check)
335  {
336  pFOs[count++] = new C4FindObjectLayer(context->Layer);
337  }
338  // create sort criterion
339  C4SortObject *pSO = nullptr;
340  if (sort_count)
341  {
342  if (sort_count == 1)
343  {
344  pSO = pSOs[0];
345  }
346  else
347  {
348  pSO = new C4SortObjectMultiple(sort_count, pSOs, false);
349  }
350  }
351  // Create search object
352  C4FindObject *pFO;
353  if (count == 1)
354  {
355  pFO = pFOs[0];
356  }
357  else
358  {
359  pFO = new C4FindObjectAnd(count, pFOs, false);
360  }
361  if (pSO)
362  {
363  pFO->SetSort(pSO);
364  }
365  return pFO;
366 }
367 
368 static C4Value FnObjectCount(C4PropList * _this, C4Value *parameters)
369 {
370  // Create FindObject-structure
371  C4FindObject *pFOs[C4AUL_MAX_Par+1]; // +1 array element to include space for implicit layer check
372  C4FindObject *pFO = CreateCriterionsFromPars(parameters, pFOs, nullptr, Object(_this));
373  // Error?
374  if (!pFO)
375  {
376  throw C4AulExecError("ObjectCount: No valid search criterions supplied");
377  }
378  // Search
379  int32_t count = pFO->Count(::Objects, ::Objects.Sectors);
380  // Free
381  delete pFO;
382  // Return
383  return C4VInt(count);
384 }
385 
386 static C4Value FnFindObject(C4PropList * _this, C4Value *parameters)
387 {
388  // Create FindObject-structure
389  C4FindObject *pFOs[C4AUL_MAX_Par]; // +1 array element to include space for implicit layer check
391  C4FindObject *pFO = CreateCriterionsFromPars(parameters, pFOs, pSOs, Object(_this));
392  // Error?
393  if (!pFO)
394  {
395  throw C4AulExecError("FindObject: No valid search criterions supplied");
396  }
397  // Search
398  C4Object *obj = pFO->Find(::Objects, ::Objects.Sectors);
399  // Free
400  delete pFO;
401  // Return
402  return C4VObj(obj);
403 }
404 
405 static C4Value FnFindObjects(C4PropList * _this, C4Value *parameters)
406 {
407  // Create FindObject-structure
408  C4FindObject *pFOs[C4AUL_MAX_Par]; // +1 array element to include space for implicit layer check
410  C4FindObject *pFO = CreateCriterionsFromPars(parameters, pFOs, pSOs, Object(_this));
411  // Error?
412  if (!pFO)
413  {
414  throw C4AulExecError("FindObjects: No valid search criterions supplied");
415  }
416  // Search
417  C4ValueArray *results = pFO->FindMany(::Objects, ::Objects.Sectors);
418  // Free
419  delete pFO;
420  // Return
421  return C4VArray(results);
422 }
423 
424 static bool FnInsertMaterial(C4PropList * _this, long mat, long x, long y, long vx, long vy, C4PropList *insert_position)
425 {
426  MakeAbsCoordinates(_this, x, y);
427  int32_t insert_x = x;
428  int32_t insert_y = y;
429  if (!::Landscape.InsertMaterial(mat, &insert_x, &insert_y, vx, vy))
430  {
431  return false;
432  }
433 
434  // output insertion position if desired (may be out of landscape range)
435  if (insert_position && !insert_position->IsFrozen())
436  {
437  insert_position->SetProperty(P_X, C4VInt(insert_x));
438  insert_position->SetProperty(P_Y, C4VInt(insert_y));
439  }
440  return true;
441 }
442 
443 static bool FnCanInsertMaterial(C4PropList * _this, long mat, long x, long y, C4PropList *insert_position)
444 {
445  MakeAbsCoordinates(_this, x, y);
446  int32_t insert_x = x;
447  int32_t insert_y = y;
448  if (!::Landscape.InsertMaterial(mat, &insert_x, &insert_y, 0, 0, true))
449  {
450  return false;
451  }
452 
453  // output insertion position if desired
454  if (insert_position && !insert_position->IsFrozen())
455  {
456  insert_position->SetProperty(P_X, C4VInt(insert_x));
457  insert_position->SetProperty(P_Y, C4VInt(insert_y));
458  }
459  return true;
460 }
461 
462 static bool FnExecutePXS(C4PropList * _this, long frames, C4PropList *callback)
463 {
464  for (long i = 0; i < frames; i++)
465  {
466  ::PXS.Execute();
467  if (callback)
468  {
469  callback->Call(P_Timer, &C4AulParSet(i));
470  }
471  }
472  return true;
473 }
474 
475 static long FnGetMaterialCount(C4PropList * _this, long material_nr, bool real)
476 {
477  if (!MatValid(material_nr))
478  {
479  return -1;
480  }
481  if (real || !::MaterialMap.Map[material_nr].MinHeightCount)
482  {
483  return ::Landscape.GetMatCount(material_nr);
484  }
485  else
486  {
488  }
489 }
490 
491 static long FnGetMaterial(C4PropList * _this, long x, long y)
492 {
493  MakeAbsCoordinates(_this, x, y);
494  return GBackMat(x, y);
495 }
496 
497 static long FnGetBackMaterial(C4PropList * _this, long x, long y)
498 {
499  MakeAbsCoordinates(_this, x, y);
501 }
502 
503 C4String *GetTextureName(int32_t texture_nr)
504 {
505  if (!texture_nr)
506  {
507  return nullptr;
508  }
509  // Get material-texture mapping
510  const C4TexMapEntry *texture = ::TextureMap.GetEntry(texture_nr);
511  if (!texture)
512  {
513  return nullptr;
514  }
515  // Return tex name
516  return String(texture->GetTextureName());
517 }
518 
519 static C4String *FnGetTexture(C4PropList * _this, long x, long y)
520 {
521  MakeAbsCoordinates(_this, x, y);
522  return GetTextureName(PixCol2Tex(::Landscape.GetPix(x, y)));
523 }
524 
525 static C4String *FnGetBackTexture(C4PropList * _this, long x, long y)
526 {
527  MakeAbsCoordinates(_this, x, y);
529 }
530 
531 // Note: Might be async in case of 16<->32 bit textures!
532 static Nillable<long> FnGetAverageTextureColor(C4PropList * _this, C4String* texture)
533 {
534  // Safety
535  if (!texture)
536  {
537  return C4Void();
538  }
539  // Check texture
540  StdStrBuf texture_name;
541  texture_name.Ref(texture->GetCStr());
542  const char* pch = strchr(texture_name.getData(), '-');
543  if (pch != nullptr)
544  {
545  size_t len = pch - texture_name.getData();
546  texture_name.Copy();
547  texture_name.SetLength(len);
548  }
549  C4Texture* Tex = ::TextureMap.GetTexture(texture_name.getData());
550  if (!Tex)
551  {
552  return C4Void();
553  }
554  return Tex->GetAverageColor();
555 }
556 
557 static bool FnGBackSolid(C4PropList * _this, long x, long y)
558 {
559  MakeAbsCoordinates(_this, x, y);
560  return GBackSolid(x, y);
561 }
562 
563 static bool FnGBackSemiSolid(C4PropList * _this, long x, long y)
564 {
565  MakeAbsCoordinates(_this, x, y);
566  return GBackSemiSolid(x, y);
567 }
568 
569 static bool FnGBackLiquid(C4PropList * _this, long x, long y)
570 {
571  MakeAbsCoordinates(_this, x, y);
572  return GBackLiquid(x, y);
573 }
574 
575 static bool FnGBackSky(C4PropList * _this, long x, long y)
576 {
577  MakeAbsCoordinates(_this, x, y);
578  return Landscape.GetBackPix(x, y) == 0;
579 }
580 
581 static long FnExtractMaterialAmount(C4PropList * _this, long x, long y, long mat, long amount, bool distant_first)
582 {
583  MakeAbsCoordinates(_this, x, y);
584  long extracted = 0;
585  for (; extracted<amount; extracted++)
586  {
587  if (GBackMat(x, y) != mat)
588  {
589  return extracted;
590  }
591  if (::Landscape.ExtractMaterial(x, y,distant_first) != mat)
592  {
593  return extracted;
594  }
595  }
596  return extracted;
597 }
598 
599 static void FnBlastFree(C4PropList * _this, long iX, long iY, long iLevel, Nillable<long> caused_by_player_nr, Nillable<long> max_density)
600 {
601  if (caused_by_player_nr.IsNil() && Object(_this))
602  {
603  caused_by_player_nr = Object(_this)->Controller;
604  }
605  if (max_density.IsNil())
606  {
607  max_density = C4M_Vehicle;
608  }
609 
610  ::Landscape.BlastFree(iX, iY, iLevel, caused_by_player_nr, Object(_this), max_density);
611 }
612 
613 static bool FnSoundAt(C4PropList * _this, C4String *szSound, long x, long y, Nillable<long> level, Nillable<long> at_player_nr, long custom_falloff_distance, long pitch, C4PropList *modifier_props)
614 {
615  // play here?
616  if (!at_player_nr.IsNil())
617  {
618  // get player to play at
619  C4Player *player = ::Players.Get(at_player_nr);
620  // not existant? fail
621  if (!player)
622  {
623  return false;
624  }
625  // network client: don't play here
626  // return true for network sync
627  if (!player->LocalControl)
628  {
629  return true;
630  }
631  }
632  // even less than nothing?
633  if (level < 0)
634  {
635  return true;
636  }
637  // default sound level
638  if (level.IsNil() || level > 100)
639  {
640  level = 100;
641  }
642  // modifier from prop list
643  C4SoundModifier *modifier;
644  if (modifier_props)
645  {
646  modifier = Application.SoundSystem.Modifiers.Get(modifier_props, true);
647  }
648  else
649  {
650  modifier = nullptr;
651  }
652  // target object
653  MakeAbsCoordinates(_this, x, y);
654  StartSoundEffectAt(FnStringPar(szSound), x, y, level, custom_falloff_distance, pitch, modifier);
655  // always return true (network safety!)
656  return true;
657 }
658 
659 static bool FnSound(C4PropList * _this, C4String *sound, bool global, Nillable<long> level, Nillable<long> at_player_nr, long loop_count, long custom_falloff_distance, long pitch, C4PropList *modifier_props)
660 {
661  // play here?
662  if (!at_player_nr.IsNil())
663  {
664  // get player to play at
665  C4Player *player = ::Players.Get(at_player_nr);
666  // not existant? fail
667  if (!player)
668  {
669  return false;
670  }
671  // network client: don't play here
672  // return true for network sync
673  if (!player->LocalControl)
674  {
675  return true;
676  }
677  }
678  // even less than nothing?
679  if (level < 0) return true;
680  // default sound level
681  if (level.IsNil() || level>100)
682  {
683  level = 100;
684  }
685  // modifier from prop list
686  C4SoundModifier *modifier;
687  if (modifier_props)
688  {
689  modifier = Application.SoundSystem.Modifiers.Get(modifier_props, true);
690  }
691  else
692  {
693  modifier = nullptr;
694  }
695  // target object
696  C4Object *obj = nullptr;
697  if (!global)
698  {
699  obj = Object(_this);
700  }
701  // play/stop?
702  if (loop_count >= 0)
703  {
704  // already playing?
705  C4SoundInstance *inst = GetSoundInstance(FnStringPar(sound), obj);
706  if (inst)
707  {
708  // then just update parameters
709  SoundUpdate(inst, level, pitch);
710  }
711  else
712  {
713  // try to play effect
714  StartSoundEffect(FnStringPar(sound), !!loop_count, level, obj, custom_falloff_distance, pitch, modifier);
715  }
716  }
717  else
718  {
719  StopSoundEffect(FnStringPar(sound), obj);
720  }
721  // always return true (network safety!)
722  return true;
723 }
724 
725 static bool FnChangeSoundModifier(C4PropList * _this, C4PropList *modifier_props, bool release)
726 {
727  // internal function to be used by sound library: Updates sound modifier
728  C4SoundModifier *modifier = Application.SoundSystem.Modifiers.Get(modifier_props, false);
729  // modifier not found. May be due to savegame resume.
730  // In that case, creation/updates will happen automatically next time Sound() is called
731  // always return true for sync safety because the internal C4SoundModifierList is not synchronized
732  if (!modifier)
733  {
734  return true;
735  }
736  if (release)
737  {
738  modifier->Release();
739  }
740  else
741  {
742  modifier->Update();
743  }
744  return true;
745 }
746 
747 static bool FnSetGlobalSoundModifier(C4PropList * _this, C4PropList *modifier_props, Nillable<long> at_player)
748 {
749  // set modifier to be applied to all future sounds
750  if (at_player.IsNil())
751  {
752  // no player given: Global modifier for all players.
753  Game.SetGlobalSoundModifier(modifier_props);
754  }
755  else
756  {
757  // modifier for all viewports of a player
758  C4Player *player = ::Players.Get(at_player);
759  if (!player)
760  {
761  return false;
762  }
763  player->SetSoundModifier(modifier_props);
764  }
765  // always true on valid params for sync safety
766  return true;
767 }
768 
769 static bool FnMusic(C4PropList * _this, C4String *song_name, bool loop, long fade_time_ms, long max_resume_time_ms)
770 {
771  if (max_resume_time_ms < 0)
772  {
773  return false; // Safety
774  }
775  bool success;
776  if (!song_name)
777  {
778  success = Application.MusicSystem.Stop();
779  }
780  else
781  {
782  success = Application.MusicSystem.Play(FnStringPar(song_name), !!loop, fade_time_ms, double(max_resume_time_ms)/1000.0);
783  }
784  if (::Control.SyncMode())
785  {
786  return true;
787  }
788  return success;
789 }
790 
791 static long FnMusicLevel(C4PropList * _this, long iLevel)
792 {
794 }
795 
796 static long FnSetPlayList(C4PropList * _this, const C4Value & playlist_data, Nillable<long> at_player_nr, bool force_switch, long fade_time_ms, long max_resume_time_ms)
797 {
798  // Safety
799  if (max_resume_time_ms < 0)
800  {
801  return 0;
802  }
803  // If a player number is provided, set play list for clients where given player is local only
804  if (!at_player_nr.IsNil() && at_player_nr != NO_OWNER)
805  {
806  C4Player *at_plr = ::Players.Get(at_player_nr);
807  if (!at_plr)
808  {
809  return 0;
810  }
811  if (!at_plr->LocalControl)
812  {
813  return 0;
814  }
815  }
816  // Playlist might be a string for the new playlist, a proplist with more info, or nil to reset the playlist
817  C4String * playlist = playlist_data.getStr();
818  C4PropList *playlist_props = nullptr;
819  if (!playlist)
820  {
821  playlist_props = playlist_data.getPropList();
822  if (playlist_props)
823  {
824  playlist = playlist_props->GetPropertyStr(P_PlayList);
825  // Update playlist properties
826  C4Value val;
827  if (playlist_props->GetProperty(P_MusicBreakMin, &val)) ::Application.MusicSystem.SetMusicBreakMin(val.getInt());
828  if (playlist_props->GetProperty(P_MusicBreakMax, &val)) ::Application.MusicSystem.SetMusicBreakMax(val.getInt());
831  }
832  }
833  // Set playlist; count entries
834  long files_in_playlist = ::Application.MusicSystem.SetPlayList(FnStringPar(playlist), force_switch, fade_time_ms, double(max_resume_time_ms)/1000.0f);
835  // network/record/replay: return 0 for sync reasons
836  if (::Control.SyncMode())
837  {
838  return 0;
839  }
840  return files_in_playlist;
841 }
842 
843 static bool FnGameOver(C4PropList * _this, long iGameOverValue /* provided for future compatibility */)
844 {
845  return !!Game.DoGameOver();
846 }
847 
848 static bool FnGainScenarioAccess(C4PropList * _this, C4String *szPassword)
849 {
850  if (std::strlen(Config.General.MissionAccess)+std::strlen(FnStringPar(szPassword)) + 3 > CFG_MaxString)
851  {
852  return false;
853  }
854  SAddModule(Config.General.MissionAccess, FnStringPar(szPassword));
855  return true;
856 }
857 
858 static C4Value FnPlayerMessage(C4PropList * _this, C4Value * parameters)
859 {
860  if (!Object(_this))
861  {
862  throw NeedObjectContext("PlayerMessage");
863  }
864  int player_nr = parameters[0].getInt();
865  C4String * message = parameters[1].getStr();
866  if (!message)
867  {
868  return C4VBool(false);
869  }
870  StdStrBuf buf;
871  buf.SetLength(message->GetData().getLength());
872 
873  // Speech
874  bool is_spoken = false;
875  if (SCopySegment(FnStringPar(message), 1,buf.getMData(), '$'))
876  {
877  if (StartSoundEffect(buf.getData(), false, 100, Object(_this)))
878  {
879  is_spoken = true;
880  }
881  }
882 
883  // Text
884  if (!is_spoken)
885  {
886  buf.Take(FnStringFormat(_this, message, &parameters[2], 8));
887  const char * dollar = strchr(buf.getData(), '$');
888  if (dollar)
889  {
890  buf.Shrink(dollar - buf.getData());
891  }
892  GameMsgObjectPlayer(buf.getData(), Object(_this), player_nr);
893  }
894  return C4VBool(true);
895 }
896 
897 static C4Value FnMessage(C4PropList * _this, C4Value * Pars)
898 {
899  if (!Object(_this)) throw NeedObjectContext("Message");
900  C4String * szMessage = Pars[0].getStr();
901  if (!szMessage) return C4VBool(false);
902  StdStrBuf buf;
903  buf.SetLength(szMessage->GetData().getLength());
904 
905  // Speech
906  bool fSpoken=false;
907  if (SCopySegment(FnStringPar(szMessage), 1,buf.getMData(), '$'))
908  if (StartSoundEffect(buf.getData(), false, 100, Object(_this)))
909  fSpoken=true;
910 
911  // Text
912  if (!fSpoken)
913  {
914  buf.Take(FnStringFormat(_this, szMessage, &Pars[1], 9));
915  const char * dollar = strchr(buf.getData(), '$');
916  if (dollar) buf.Shrink(dollar - buf.getData());
917  GameMsgObject(buf.getData(), Object(_this));
918  }
919  return C4VBool(true);
920 }
921 
922 // undocumented!
923 static C4Value FnAddMessage(C4PropList * _this, C4Value * parameters)
924 {
925  if (!Object(_this))
926  {
927  throw NeedObjectContext("AddMessage");
928  }
929  C4String * message = parameters[0].getStr();
930  if (!message)
931  {
932  return C4VBool(false);
933  }
934 
935  ::Messages.Append(C4GM_Target, FnStringFormat(_this, message, &parameters[1], 9).getData(),
936  Object(_this), NO_OWNER, 0,0, C4RGB(0xff, 0xff, 0xff));
937  return C4VBool(true);
938 }
939 
940 static long FnMaterial(C4PropList * _this, C4String *mat_name)
941 {
942  return ::MaterialMap.Get(FnStringPar(mat_name));
943 }
944 
945 C4Object* FnPlaceVegetation(C4PropList * _this, C4PropList * Def, long x, long y, long wdt, long hgt, long growth, C4PropList * shape)
946 {
947  if (shape)
948  {
949  // New-style call with scripted shape
950  C4PropList *out_pos = C4PropList::New(nullptr);
951  C4Value vout_pos = C4VPropList(out_pos);
952  return Game.PlaceVegetation(Def, x, y, wdt, hgt, growth, shape, out_pos);
953  }
954  else
955  {
956  // Call in old-style shape
957  // Local call: relative coordinates
958  MakeAbsCoordinates(_this, x, y);
959  // Place vegetation
960  return Game.PlaceVegetation(Def, x, y, wdt, hgt, growth, nullptr, nullptr);
961  }
962 }
963 
965 {
966  return Game.PlaceAnimal(Def? Def : _this);
967 }
968 
969 static bool FnHostile(C4PropList * _this, long player_nr1, long player_nr2, bool check_one_way_only)
970 {
971  if (check_one_way_only)
972  {
973  return ::Players.HostilityDeclared(player_nr1, player_nr2);
974  }
975  else
976  {
977  return !!Hostile(player_nr1, player_nr2);
978  }
979 }
980 
981 static bool FnSetHostility(C4PropList * _this, long player_nr1, long player_nr2, bool hostile, bool silent, bool no_calls)
982 {
983  C4Player *player = ::Players.Get(player_nr1);
984  if (!player)
985  {
986  return false;
987  }
988  // do rejection test first
989  if (!no_calls)
990  {
991  if (!!::Game.GRBroadcast(PSF_RejectHostilityChange, &C4AulParSet(player_nr1, player_nr2, hostile), true, true))
992  {
993  return false;
994  }
995  }
996  // OK; set hostility
997  bool old_hostility = ::Players.HostilityDeclared(player_nr1, player_nr2);
998  if (!player->SetHostility(player_nr2, hostile, silent))
999  {
1000  return false;
1001  }
1002  // calls afterwards
1003  ::Game.GRBroadcast(PSF_OnHostilityChange, &C4AulParSet(C4VInt(player_nr1), C4VInt(player_nr2), C4VBool(hostile), C4VBool(old_hostility)), true);
1004  return true;
1005 }
1006 
1007 static bool FnSetPlrView(C4PropList * _this, long player_nr, C4Object *target, bool immediate_position)
1008 {
1009  if (!ValidPlr(player_nr))
1010  {
1011  return false;
1012  }
1013  ::Players.Get(player_nr)->SetViewMode(C4PVM_Target, target, immediate_position);
1014  return true;
1015 }
1016 
1017 static long FnGetPlrViewMode(C4PropList * _this, long player_nr)
1018 {
1019  if (!ValidPlr(player_nr))
1020  {
1021  return -1;
1022  }
1023  if (::Control.SyncMode())
1024  {
1025  return -1;
1026  }
1027  return ::Players.Get(player_nr)->ViewMode;
1028 }
1029 
1030 static void FnResetCursorView(C4PropList * _this, long player_nr, bool immediate_position)
1031 {
1032  C4Player *player = ::Players.Get(player_nr);
1033  if (player)
1034  {
1035  player->ResetCursorView(immediate_position);
1036  }
1037 }
1038 
1039 static C4Object *FnGetPlrView(C4PropList * _this, long player_nr)
1040 {
1041  C4Player *player = ::Players.Get(player_nr);
1042  if (!player || player->ViewMode != C4PVM_Target)
1043  {
1044  return nullptr;
1045  }
1046  return player->ViewTarget;
1047 }
1048 
1049 // flags for SetPlayerZoom* calls
1050 static const int PLRZOOM_Direct = 0x01,
1051  PLRZOOM_NoIncrease = 0x04,
1052  PLRZOOM_NoDecrease = 0x08,
1053  PLRZOOM_LimitMin = 0x10,
1054  PLRZOOM_LimitMax = 0x20,
1055  PLRZOOM_Set = 0x40;
1056 
1057 static bool FnSetPlayerZoomByViewRange(C4PropList * _this, long player_nr, long range_wdt, long range_hgt, long flags)
1058 {
1059  // zoom size safety - both ranges 0 is fine, it causes a zoom reset to default
1060  if (range_wdt < 0 || range_hgt < 0)
1061  {
1062  return false;
1063  }
1064  // special player NO_OWNER: apply to all viewports
1065  if (player_nr == NO_OWNER)
1066  {
1067  for (C4Player *player = ::Players.First; player; player = player->Next)
1068  {
1069  if (player->Number != NO_OWNER) // can't happen, but would be a crash if it did...
1070  {
1071  FnSetPlayerZoomByViewRange(_this, player->Number, range_wdt, range_hgt, flags);
1072  }
1073  }
1074  return true;
1075  }
1076  else
1077  {
1078  // safety check on player only, so function return result is always in sync
1079  C4Player *player = ::Players.Get(player_nr);
1080  if (!player)
1081  {
1082  return false;
1083  }
1084  // adjust values in player
1085  if (flags & PLRZOOM_LimitMin) player->SetMinZoomByViewRange(range_wdt, range_hgt, !!(flags & PLRZOOM_NoIncrease), !!(flags & PLRZOOM_NoDecrease));
1086  if (flags & PLRZOOM_LimitMax) player->SetMaxZoomByViewRange(range_wdt, range_hgt, !!(flags & PLRZOOM_NoIncrease), !!(flags & PLRZOOM_NoDecrease));
1087  // set values after setting min/max to ensure old limits don't block new value
1088  if ((flags & PLRZOOM_Set) || !(flags & (PLRZOOM_LimitMin | PLRZOOM_LimitMax)))
1089  {
1090  player->SetZoomByViewRange(range_wdt, range_hgt, !!(flags & PLRZOOM_Direct), !!(flags & PLRZOOM_NoIncrease), !!(flags & PLRZOOM_NoDecrease));
1091  }
1092 
1093  }
1094  return true;
1095 }
1096 
1097 static C4PropList *FnGetPlayerZoomLimits(C4PropList * _this, long player_nr)
1098 {
1099  // get player
1100  C4Player *player = ::Players.Get(player_nr);
1101  if (!player)
1102  {
1103  return nullptr;
1104  }
1105  // collect limits in a prop list
1106  // if neither width not height is set for zoom limits, return engine defaults.
1107  C4PropList *result = C4PropList::New();
1108  if (!result)
1109  {
1110  return nullptr;
1111  }
1112  result->SetPropertyByS(::Strings.RegString("MaxWidth"), C4VInt((player->ZoomLimitMaxWdt || player->ZoomLimitMaxHgt) ? player->ZoomLimitMaxWdt : C4VP_DefMaxViewRangeX));
1113  result->SetPropertyByS(::Strings.RegString("MaxHeight"), C4VInt(player->ZoomLimitMaxHgt));
1114  result->SetPropertyByS(::Strings.RegString("MaxValue"), C4VInt(fixtoi(player->ZoomLimitMaxVal, 100)));
1115  result->SetPropertyByS(::Strings.RegString("MinWidth"), C4VInt((player->ZoomLimitMinWdt || player->ZoomLimitMinHgt) ? player->ZoomLimitMinWdt : C4VP_DefMinViewRangeX));
1116  result->SetPropertyByS(::Strings.RegString("MinHeight"), C4VInt(player->ZoomLimitMinHgt));
1117  result->SetPropertyByS(::Strings.RegString("MinValue"), C4VInt(fixtoi(player->ZoomLimitMinVal, 100)));
1118  return result;
1119 }
1120 
1121 static bool FnSetPlayerZoom(C4PropList * _this, long player_nr, long zoom, long precision, long flags)
1122 {
1123  // parameter safety. 0/0 means "reset to default".
1124  if (zoom < 0 || precision < 0)
1125  {
1126  return false;
1127  }
1128  // special player NO_OWNER: apply to all viewports
1129  if (player_nr == NO_OWNER)
1130  {
1131  for (C4Player *player = ::Players.First; player; player = player->Next)
1132  {
1133  if (player->Number != NO_OWNER) // can't happen, but would be a crash if it did...
1134  {
1135  FnSetPlayerZoom(_this, player->Number, zoom, precision, flags);
1136  }
1137  }
1138  return true;
1139  }
1140  else
1141  {
1142  // zoom factor calculation
1143  if (!precision)
1144  {
1145  precision = 1;
1146  }
1147  C4Real fZoom = itofix(zoom, precision);
1148  // safety check on player only, so function return result is always in sync
1149  C4Player *player = ::Players.Get(player_nr);
1150  if (!player)
1151  {
1152  return false;
1153  }
1154  // adjust values in player
1155  if (flags & PLRZOOM_LimitMin) player->SetMinZoom(fZoom, !!(flags & PLRZOOM_NoIncrease), !!(flags & PLRZOOM_NoDecrease));
1156  if (flags & PLRZOOM_LimitMax) player->SetMaxZoom(fZoom, !!(flags & PLRZOOM_NoIncrease), !!(flags & PLRZOOM_NoDecrease));
1157  if ((flags & PLRZOOM_Set) || !(flags & (PLRZOOM_LimitMin | PLRZOOM_LimitMax)))
1158  {
1159  player->SetZoom(fZoom, !!(flags & PLRZOOM_Direct), !!(flags & PLRZOOM_NoIncrease), !!(flags & PLRZOOM_NoDecrease));
1160  }
1161 
1162  }
1163  return true;
1164 }
1165 
1166 static bool FnSetPlayerViewLock(C4PropList * _this, long player_nr, bool is_locked)
1167 {
1168  // special player NO_OWNER: apply to all players
1169  if (player_nr == NO_OWNER)
1170  {
1171  for (C4Player *player = ::Players.First; player; player=player->Next)
1172  {
1173  if (player->Number != NO_OWNER) // can't happen, but would be a crash if it did...
1174  {
1175  FnSetPlayerViewLock(_this, player->Number, is_locked);
1176  }
1177  }
1178  return true;
1179  }
1180  C4Player *player = ::Players.Get(player_nr);
1181  if (!player)
1182  {
1183  return false;
1184  }
1185  player->SetViewLocked(is_locked);
1186  return true;
1187 }
1188 
1189 static bool FnDoBaseMaterial(C4PropList * _this, long player_nr, C4ID id, long change)
1190 {
1191  // validity check
1192  if (!ValidPlr(player_nr))
1193  {
1194  return false;
1195  }
1196  C4Def *def = C4Id2Def(id);
1197  if (!def)
1198  {
1199  return false;
1200  }
1201  // add to material
1202  long last_count = ::Players.Get(player_nr)->BaseMaterial.GetIDCount(id);
1203  return ::Players.Get(player_nr)->BaseMaterial.SetIDCount(id, last_count + change, true);
1204 }
1205 
1206 static bool FnDoBaseProduction(C4PropList * _this, long player_nr, C4ID id, long change)
1207 {
1208  // validity check
1209  if (!ValidPlr(player_nr))
1210  {
1211  return false;
1212  }
1213  C4Def *def = C4Id2Def(id);
1214  if (!def)
1215  {
1216  return false;
1217  }
1218  // add to material
1219  long last_count = ::Players.Get(player_nr)->BaseProduction.GetIDCount(id);
1220  return ::Players.Get(player_nr)->BaseProduction.SetIDCount(id, last_count + change, true);
1221 }
1222 
1223 static bool FnSetPlrKnowledge(C4PropList * _this, Nillable<long> player_nr, C4ID id, bool remove)
1224 {
1225  bool success = false;
1226  // player_nr == nil: Call for all players
1227  if (player_nr.IsNil())
1228  {
1229  for (C4Player *player = ::Players.First; player; player = player->Next)
1230  {
1231  if (player->SetKnowledge(id, remove))
1232  {
1233  success = true;
1234  }
1235  }
1236  }
1237  else
1238  {
1239  // Otherwise call for requested player
1240  C4Player *player = ::Players.Get(player_nr);
1241  if (player)
1242  {
1243  success = player->SetKnowledge(id, remove);
1244  }
1245  }
1246  return success;
1247 }
1248 
1249 static C4Value FnGetPlrKnowledge(C4PropList * _this, int player_nr, C4ID id, int index, int category)
1250 {
1251  if (!ValidPlr(player_nr))
1252  {
1253  return C4VBool(false);
1254  }
1255  // Search by id, check if available, return bool
1256  if (id)
1257  {
1258  return C4VBool(::Players.Get(player_nr)->Knowledge.GetIDCount(id, 1) != 0);
1259  }
1260  // Search indexed item of given category, return C4ID
1261  return C4VPropList(C4Id2Def(::Players.Get(player_nr)->Knowledge.GetID( ::Definitions, category, index )));
1262 }
1263 
1264 static C4Def * FnGetDefinition(C4PropList * _this, long iIndex)
1265 {
1266  return ::Definitions.GetDef(iIndex);
1267 }
1268 
1269 static C4String * FnGetDefinitionGroupPath(C4PropList * _this)
1270 {
1271  // Must have loaded all paths
1272  if (Application.isEditor)
1273  {
1275  }
1276  // Resolve definition
1277  C4Def *def = _this->GetDef();
1278  if (!def || !def->ConsoleGroupPath.getData())
1279  {
1280  return nullptr;
1281  }
1283 }
1284 
1285 static C4Value FnGetBaseMaterial(C4PropList * _this, int player_nr, C4ID id, int index, int category)
1286 {
1287  if (!ValidPlr(player_nr))
1288  {
1289  return C4VBool(false);
1290  }
1291  // Search by id, return available count
1292  if (id)
1293  {
1294  return C4VInt(::Players.Get(player_nr)->BaseMaterial.GetIDCount(id));
1295  }
1296  // Search indexed item of given category, return C4ID
1297  return C4VPropList(C4Id2Def(::Players.Get(player_nr)->BaseMaterial.GetID( ::Definitions, category, index )));
1298 }
1299 
1300 static C4Value FnGetBaseProduction(C4PropList * _this, int player_nr, C4ID id, int index, int category)
1301 {
1302  if (!ValidPlr(player_nr))
1303  {
1304  return C4VBool(false);
1305  }
1306  // Search by id, return available count
1307  if (id)
1308  {
1309  return C4VInt(::Players.Get(player_nr)->BaseProduction.GetIDCount(id));
1310  }
1311  // Search indexed item of given category, return C4ID
1312  return C4VPropList(C4Id2Def(::Players.Get(player_nr)->BaseProduction.GetID( ::Definitions, category, index )));
1313 }
1314 
1315 static long FnGetWealth(C4PropList * _this, long player_nr)
1316 {
1317  if (!ValidPlr(player_nr)) return 0;
1318  return ::Players.Get(player_nr)->Wealth;
1319 }
1320 
1321 static bool FnSetWealth(C4PropList * _this, long player_nr, long value)
1322 {
1323  if (!ValidPlr(player_nr)) return false;
1324  ::Players.Get(player_nr)->SetWealth(value);
1325  return true;
1326 }
1327 
1328 static long FnDoPlayerScore(C4PropList * _this, long player_nr, long change)
1329 {
1330  if (!ValidPlr(player_nr)) return false;
1331  return ::Players.Get(player_nr)->DoScore(change);
1332 }
1333 
1334 static long FnGetPlayerScore(C4PropList * _this, long player_nr)
1335 {
1336  if (!ValidPlr(player_nr)) return 0;
1337  return ::Players.Get(player_nr)->CurrentScore;
1338 }
1339 
1340 static long FnGetPlayerScoreGain(C4PropList * _this, long player_nr)
1341 {
1342  if (!ValidPlr(player_nr)) return 0;
1343  return ::Players.Get(player_nr)->CurrentScore - ::Players.Get(player_nr)->InitialScore;
1344 }
1345 
1346 static C4Object *FnGetHiRank(C4PropList * _this, long player_nr)
1347 {
1348  if (!ValidPlr(player_nr)) return nullptr;
1350 }
1351 
1352 static C4Object *FnGetCrew(C4PropList * _this, long player_nr, long index)
1353 {
1354  if (!ValidPlr(player_nr)) return nullptr;
1355  return ::Players.Get(player_nr)->Crew.GetObject(index);
1356 }
1357 
1358 static long FnGetCrewCount(C4PropList * _this, long player_nr)
1359 {
1360  if (!ValidPlr(player_nr)) return 0;
1361  return ::Players.Get(player_nr)->Crew.ObjectCount();
1362 }
1363 
1364 static long FnGetPlayerCount(C4PropList * _this, long type)
1365 {
1366  if (!type)
1367  {
1369  }
1370  else
1371  {
1373  }
1374 }
1375 
1376 static long FnGetPlayerByIndex(C4PropList * _this, long index, long type)
1377 {
1378  C4Player *player;
1379  if (type)
1380  {
1382  }
1383  else
1384  {
1385  player = ::Players.GetByIndex(index);
1386  }
1387  if (!player) return NO_OWNER;
1388  return player->Number;
1389 }
1390 
1391 static long FnEliminatePlayer(C4PropList * _this, long player_nr, bool remove_direct)
1392 {
1393  C4Player *player = ::Players.Get(player_nr);
1394  if (!player)
1395  {
1396  return false;
1397  }
1398  // direct removal?
1399  if (remove_direct)
1400  {
1401  // do direct removal (no fate)
1402  if (::Control.isCtrlHost())
1403  {
1404  ::Players.CtrlRemove(player_nr, false);
1405  }
1406  return true;
1407  }
1408  else
1409  {
1410  // do regular elimination
1411  if (player->Eliminated)
1412  {
1413  return false;
1414  }
1415  player->Eliminate();
1416  }
1417  return true;
1418 }
1419 
1420 // undocumented!
1421 static bool FnSurrenderPlayer(C4PropList * _this, long player_nr)
1422 {
1423  C4Player *player = ::Players.Get(player_nr);
1424  if (!player)
1425  {
1426  return false;
1427  }
1428  if (player->Eliminated)
1429  {
1430  return false;
1431  }
1432  player->Surrender();
1433  return true;
1434 }
1435 
1436 // undocumented!
1437 static bool FnSetLeaguePerformance(C4PropList * _this, long iScore, long player_id)
1438 {
1439  if (!Game.Parameters.isLeague())
1440  {
1441  return false;
1442  }
1443  if (player_id && !Game.PlayerInfos.GetPlayerInfoByID(player_id))
1444  {
1445  return false;
1446  }
1447  Game.RoundResults.SetLeaguePerformance(iScore, player_id);
1448  return true;
1449 }
1450 
1451 
1452 static const int32_t CSPF_FixedAttributes = 1 << 0,
1453  CSPF_NoScenarioInit = 1 << 1,
1454  CSPF_NoEliminationCheck = 1 << 2,
1455  CSPF_Invisible = 1 << 3,
1456  CSPF_NoScenarioSave = 1 << 4;
1457 
1458 
1459 static bool FnCreateScriptPlayer(C4PropList * _this, C4String *name, long dwColor, long team_id, long dwFlags, C4ID idExtra)
1460 {
1461  // safety
1462  if (!name || !name->GetData().getLength())
1463  {
1464  return false;
1465  }
1466  // this script command puts a new script player info into the list
1467  // the actual join will be delayed and synchronized via queue
1468  // processed by control host only - clients/replay/etc. will perform the join via queue
1469  if (!::Control.isCtrlHost())
1470  {
1471  return true;
1472  }
1473  C4PlayerInfo *pScriptPlrInfo = new C4PlayerInfo();
1474  uint32_t dwInfoFlags = 0u;
1475  if (dwFlags & CSPF_FixedAttributes ) dwInfoFlags |= C4PlayerInfo::PIF_AttributesFixed;
1476  if (dwFlags & CSPF_NoScenarioInit ) dwInfoFlags |= C4PlayerInfo::PIF_NoScenarioInit;
1477  if (dwFlags & CSPF_NoEliminationCheck) dwInfoFlags |= C4PlayerInfo::PIF_NoEliminationCheck;
1478  if (dwFlags & CSPF_Invisible ) dwInfoFlags |= C4PlayerInfo::PIF_Invisible;
1479  if (dwFlags & CSPF_NoScenarioSave) dwInfoFlags |= C4PlayerInfo::PIF_NoScenarioSave;
1480  pScriptPlrInfo->SetAsScriptPlayer(name->GetCStr(), dwColor, dwInfoFlags, idExtra);
1481  pScriptPlrInfo->SetTeam(team_id);
1482  C4ClientPlayerInfos JoinPkt(nullptr, true, pScriptPlrInfo);
1483  // add to queue!
1485  // always successful for sync reasons
1486  return true;
1487 }
1488 
1489 static C4Object *FnGetCursor(C4PropList * _this, long player_nr)
1490 {
1491  // get player
1492  C4Player *player = ::Players.Get(player_nr);
1493  // invalid player?
1494  if (!player)
1495  {
1496  return nullptr;
1497  }
1498  return player->Cursor;
1499 }
1500 
1501 // undocumented!
1502 static C4Object *FnGetViewCursor(C4PropList * _this, long player_nr)
1503 {
1504  // get player
1505  C4Player *player = ::Players.Get(player_nr);
1506  // get viewcursor
1507  return player ? player->ViewCursor : nullptr;
1508 }
1509 
1510 static bool FnSetCursor(C4PropList * _this, long player_nr, C4Object *obj, bool no_select_arrow)
1511 {
1512  C4Player *player = ::Players.Get(player_nr);
1513  if (!player || (obj && !obj->Status) || (obj && obj->CrewDisabled)) return false;
1514  player->SetCursor(obj, !no_select_arrow);
1515  return true;
1516 }
1517 
1518 // undocumented!
1519 static bool FnSetViewCursor(C4PropList * _this, long player_nr, C4Object *obj)
1520 {
1521  // get player
1522  C4Player *player = ::Players.Get(player_nr);
1523  // invalid player?
1524  if (!player)
1525  {
1526  return false;
1527  }
1528  // set viewcursor
1529  player->ViewCursor = obj;
1530  return true;
1531 }
1532 
1533 static long FnGetWind(C4PropList * _this, long x, long y, bool global)
1534 {
1535  // global wind
1536  if (global)
1537  {
1539  }
1540  // local wind
1541  MakeAbsCoordinates(_this, x, y);
1542  return ::Weather.GetWind(x, y);
1543 }
1544 
1545 static void FnSetWind(C4PropList * _this, long wind)
1546 {
1547  ::Weather.SetWind(wind);
1548 }
1549 
1550 static void FnSetTemperature(C4PropList * _this, long temperature)
1551 {
1552  ::Weather.SetTemperature(temperature);
1553 }
1554 
1555 static long FnGetTemperature(C4PropList * _this)
1556 {
1558 }
1559 
1560 static void FnSetAmbientBrightness(C4PropList * _this, long brightness)
1561 {
1562  if (::Landscape.HasFoW())
1563  {
1564  ::Landscape.GetFoW()->Ambient.SetBrightness(brightness / 100.);
1565  }
1566 }
1567 
1568 static long FnGetAmbientBrightness(C4PropList * _this)
1569 {
1570  if (!::Landscape.HasFoW())
1571  {
1572  return 100;
1573  }
1574  return static_cast<long>(::Landscape.GetFoW()->Ambient.GetBrightness() * 100. + 0.5);
1575 }
1576 
1577 static void FnSetSeason(C4PropList * _this, long season)
1578 {
1579  ::Weather.SetSeason(season);
1580 }
1581 
1582 static long FnGetSeason(C4PropList * _this)
1583 {
1585 }
1586 
1587 static void FnSetClimate(C4PropList * _this, long climate)
1588 {
1589  ::Weather.SetClimate(climate);
1590 }
1591 
1592 static long FnGetClimate(C4PropList * _this)
1593 {
1595 }
1596 
1597 static long FnLandscapeWidth(C4PropList * _this)
1598 {
1600 }
1601 
1602 static long FnLandscapeHeight(C4PropList * _this)
1603 {
1605 }
1606 
1607 static void FnShakeFree(C4PropList * _this, long x, long y, long radius)
1608 {
1609  ::Landscape.ShakeFree(x, y,radius);
1610 }
1611 
1612 static long FnDigFree(C4PropList * _this, long x, long y, long radius, bool no_dig2objects, bool no_instability_check)
1613 {
1614  return ::Landscape.DigFree(x, y,radius, Object(_this), no_dig2objects, no_instability_check);
1615 }
1616 
1617 static long FnDigFreeRect(C4PropList * _this, long x, long y, long wdt, long hgt, bool no_dig2objects, bool no_instability_check)
1618 {
1619  return ::Landscape.DigFreeRect(x, y, wdt, hgt, Object(_this), no_dig2objects, no_instability_check);
1620 }
1621 
1622 static void FnClearFreeRect(C4PropList * _this, long x, long y, long wdt, long hgt)
1623 {
1624  ::Landscape.ClearFreeRect(x, y, wdt, hgt);
1625 }
1626 
1627 static bool FnPathFree(C4PropList * _this, long x1, long y1, long x2, long y2)
1628 {
1629  return !!PathFree(x1, y1, x2, y2);
1630 }
1631 
1632 // undocumented!
1633 static C4ValueArray* FnPathFree2(C4PropList * _this, int32_t x1, int32_t y1, int32_t x2, int32_t y2)
1634 {
1635  int32_t x = -1, y = -1;
1636  if (!PathFree(x1, y1, x2, y2, &x, &y))
1637  {
1638  C4ValueArray *array = new C4ValueArray(2);
1639  array->SetItem(0, C4VInt(x));
1640  array->SetItem(1, C4VInt(y));
1641  return array;
1642  }
1643  return nullptr;
1644 }
1645 
1646 C4Object* FnObject(C4PropList * _this, long iNumber)
1647 {
1649  // See FnObjectNumber
1650 }
1651 
1652 static C4Value FnGameCallEx(C4PropList * _this, C4Value * parameters)
1653 {
1654  C4String * fn = parameters[0].getStr();
1655  if (!fn) return C4Value();
1656 
1657  // copy parameters
1658  C4AulParSet ParSet;
1659  ParSet.Copy(&parameters[1], 9);
1660  // Call
1661  return ::Game.GRBroadcast(fn->GetCStr(), &ParSet, true);
1662 }
1663 
1664 static C4Object * FnEditCursor(C4PropList * _this)
1665 {
1666  if (::Control.SyncMode())
1667  {
1668  return nullptr;
1669  }
1670  return Console.EditCursor.GetTarget();
1671 }
1672 
1673 static bool FnIsNetwork(C4PropList * _this) { return Game.Parameters.IsNetworkGame; }
1674 
1675 static bool FnIsEditor(C4PropList * _this) { return Game.Parameters.IsEditor; }
1676 
1677 // undocumented!
1678 static C4String *FnGetLeague(C4PropList * _this, long idx)
1679 {
1680  // get indexed league
1681  StdStrBuf sIdxLeague;
1682  if (!Game.Parameters.League.GetSection(idx, &sIdxLeague)) return nullptr;
1683  return String(sIdxLeague.getData());
1684 }
1685 
1686 static int32_t FnGetLeagueScore(C4PropList * _this, long player_id)
1687 {
1688  // security
1689  if (player_id < 1)
1690  {
1691  return 0;
1692  }
1693  // get info
1694  C4PlayerInfo *info = Game.PlayerInfos.GetPlayerInfoByID(player_id);
1695  if (!info)
1696  {
1697  return 0;
1698  }
1699  // get league score
1700  return info->getLeagueScore();
1701 }
1702 
1703 static bool FnSetLeagueProgressData(C4PropList * _this, C4String *pNewData, long player_id)
1704 {
1705  if (!Game.Parameters.League.getLength() || !player_id)
1706  {
1707  return false;
1708  }
1709  C4PlayerInfo *info = Game.PlayerInfos.GetPlayerInfoByID(player_id);
1710  if (!info)
1711  {
1712  return false;
1713  }
1714  info->SetLeagueProgressData(pNewData ? pNewData->GetCStr() : nullptr);
1715  return true;
1716 }
1717 
1718 static C4String *FnGetLeagueProgressData(C4PropList * _this, long player_id)
1719 {
1721  {
1722  return nullptr;
1723  }
1724  C4PlayerInfo *info = Game.PlayerInfos.GetPlayerInfoByID(player_id);
1725  if (!info)
1726  {
1727  return nullptr;
1728  }
1729  return String(info->GetLeagueProgressData());
1730 }
1731 
1732 // undocumented!
1733 static bool FnTestMessageBoard(C4PropList * _this, long player_nr, bool test_if_in_use)
1734 {
1735  // multi-query-MessageBoard is always available if the player is valid =)
1736  // (but it won't do anything in developer mode...)
1737  C4Player *player = ::Players.Get(player_nr);
1738  if (!player) return false;
1739  if (!test_if_in_use) return true;
1740  // single query only if no query is scheduled
1741  return player->HasMessageBoardQuery();
1742 }
1743 
1744 // undocumented!
1745 static bool FnCallMessageBoard(C4PropList * _this, C4Object *obj, bool upper_case, C4String *query_string, long player_nr)
1746 {
1747  if (!obj)
1748  {
1749  obj = Object(_this);
1750  }
1751  if (obj && !obj->Status)
1752  {
1753  return false;
1754  }
1755  // check player
1756  C4Player *player = ::Players.Get(player_nr);
1757  if (!player)
1758  {
1759  return false;
1760  }
1761  // remove any previous
1762  player->CallMessageBoard(obj, StdStrBuf(FnStringPar(query_string)), !!upper_case);
1763  return true;
1764 }
1765 
1766 // undocumented!
1767 static bool FnAbortMessageBoard(C4PropList * _this, C4Object *obj, long player_nr)
1768 {
1769  if (!obj)
1770  {
1771  obj = Object(_this);
1772  }
1773  // check player
1774  C4Player *player = ::Players.Get(player_nr);
1775  if (!player)
1776  {
1777  return false;
1778  }
1779  // close TypeIn if active
1780  ::MessageInput.AbortMsgBoardQuery(obj, player_nr);
1781  // abort for it
1782  return player->RemoveMessageBoardQuery(obj);
1783 }
1784 
1785 static void FnSetFoW(C4PropList * _this, bool enabled, long player_nr)
1786 {
1787  // safety
1788  if (!ValidPlr(player_nr))
1789  {
1790  return;
1791  }
1792  // set enabled
1793  ::Players.Get(player_nr)->SetFoW(!!enabled);
1794 }
1795 
1796 static long FnSetMaxPlayer(C4PropList * _this, long player_count)
1797 {
1798  // think positive! :)
1799  if (player_count < 0)
1800  {
1801  return false;
1802  }
1803  // script functions don't need to pass ControlQueue!
1804  Game.Parameters.MaxPlayers = player_count;
1805  // success
1806  return true;
1807 }
1808 
1809 static bool FnGetScenarioAccess(C4PropList * _this, C4String *password)
1810 {
1811  // safety
1812  if (!password) return false;
1813 
1814  // non-sync mode: warn
1815  if (::Control.SyncMode())
1816  {
1817  Log("Warning: using GetScenarioAccess may cause desyncs when playing records!");
1818  }
1819 
1820  return SIsModule(Config.General.MissionAccess, FnStringPar(password));
1821 }
1822 
1823 // Helper to read or write a value from/to a structure. Must be two
1825 {
1826 public:
1827  C4ValueCompiler(const char **pszNames, int iNameCnt, int iEntryNr)
1828  : pszNames(pszNames), iNameCnt(iNameCnt), iEntryNr(iEntryNr)
1829  { }
1830 
1831  bool isDeserializer() override { return false; }
1832  bool hasNaming() override { return true; }
1833  bool isVerbose() override { return false; }
1834 
1835  bool Name(const char *szName) override
1836  {
1837  // match possible? (no match yet / continued match)
1838  if (!iMatchStart || haveCurrentMatch())
1839  // already got all names?
1840  if (!haveCompleteMatch())
1841  // check name
1842  if (SEqual(pszNames[iMatchCount], szName))
1843  {
1844  // got match
1845  if (!iMatchCount) iMatchStart = iDepth + 1;
1846  iMatchCount++;
1847  }
1848  iDepth++;
1849  return true;
1850  }
1851 
1852  bool Default(const char *szName) override
1853  {
1854  // Always process values even if they are default!
1855  return false;
1856  }
1857 
1858  void NameEnd(bool fBreak = false) override
1859  {
1860  // end of matched name section?
1861  if (haveCurrentMatch())
1862  {
1863  iMatchCount--;
1864  if (!iMatchCount) iMatchStart = 0;
1865  }
1866  iDepth--;
1867  }
1868 
1869  void Begin() override
1870  {
1871  // set up
1872  iDepth = iMatchStart = iMatchCount = 0;
1873  }
1874 
1875 protected:
1876  // value function forward to be overwritten by get or set compiler
1877  virtual void ProcessInt(int32_t &rInt) = 0;
1878  virtual void ProcessBool(bool &rBool) = 0;
1879  virtual void ProcessChar(char &rChar) = 0;
1880  virtual void ProcessString(char *szString, size_t iMaxLength, bool fIsID) = 0;
1881  virtual void ProcessString(char **pszString, bool fIsID) = 0;
1882  virtual void ProcessString(std::string &str, bool isID) = 0;
1883 
1884  // value functions
1885 private:
1886  template<class T>
1887  void MaybeProcessInt(T &t)
1888  {
1889  if (haveCompleteMatch() && !iEntryNr--)
1890  {
1891  int32_t i = t;
1892  ProcessInt(i);
1893  t = i;
1894  }
1895  }
1896 public:
1897  void DWord(int32_t &rInt) override { MaybeProcessInt(rInt); }
1898  void DWord(uint32_t &rInt) override { MaybeProcessInt(rInt); }
1899  void Word(int16_t &rShort) override { MaybeProcessInt(rShort); }
1900  void Word(uint16_t &rShort) override { MaybeProcessInt(rShort); }
1901  void Byte(int8_t &rByte) override { MaybeProcessInt(rByte); }
1902  void Byte(uint8_t &rByte) override { MaybeProcessInt(rByte); }
1903  void Boolean(bool &rBool) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessBool(rBool); }
1904  void Character(char &rChar) override { if (haveCompleteMatch()) if (!iEntryNr--) ProcessChar(rChar); }
1905 
1906  // The C4ID-Adaptor will set RCT_ID for it's strings (see C4Id.h), so we don't have to guess the type.
1907  void String(char *szString, size_t iMaxLength, RawCompileType eType) override
1908  { if (haveCompleteMatch()) if (!iEntryNr--) ProcessString(szString, iMaxLength, eType == StdCompiler::RCT_ID); }
1909  void String(char **pszString, RawCompileType eType) override
1910  { if (haveCompleteMatch()) if (!iEntryNr--) ProcessString(pszString, eType == StdCompiler::RCT_ID); }
1911  void String(std::string &str, RawCompileType type) override
1912  { if (haveCompleteMatch()) if (!iEntryNr--) ProcessString(str, type == StdCompiler::RCT_ID); }
1913  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override
1914  { /* C4Script can't handle this */ }
1915 
1916 private:
1917 
1918  // Name(s) of the entry to read
1919  const char **pszNames;
1920  int iNameCnt;
1921  // Number of the element that is to be read
1922  int iEntryNr;
1923 
1924  // current depth
1925  int iDepth;
1926  // match start (where did the first name match?),
1927  // match count (how many names did match, from that point?)
1928  int iMatchStart, iMatchCount;
1929 
1930 private:
1931  // match active?
1932  bool haveCurrentMatch() const { return iDepth + 1 == iMatchStart + iMatchCount; }
1933  // match complete?
1934  bool haveCompleteMatch() const { return haveCurrentMatch() && iMatchCount == iNameCnt; }
1935 };
1936 
1938 {
1939 private:
1940  // Result
1941  C4Value Res;
1942 public:
1943  C4ValueGetCompiler(const char **pszNames, int iNameCnt, int iEntryNr)
1944  : C4ValueCompiler(pszNames, iNameCnt, iEntryNr)
1945  { }
1946 
1947  // Result-getter
1948  const C4Value &getResult() const { return Res; }
1949 
1950 protected:
1951  // get values as C4Value
1952  void ProcessInt(int32_t &rInt) override { Res = C4VInt(rInt); }
1953  void ProcessBool(bool &rBool) override { Res = C4VBool(rBool); }
1954  void ProcessChar(char &rChar) override { Res = C4VString(FormatString("%c", rChar)); }
1955 
1956  void ProcessString(char *szString, size_t iMaxLength, bool fIsID) override
1957  { Res = (fIsID ? C4VPropList(C4Id2Def(C4ID(szString))) : C4VString(szString)); }
1958  void ProcessString(char **pszString, bool fIsID) override
1959  { Res = (fIsID ? C4VPropList(C4Id2Def(C4ID(*pszString))) : C4VString(*pszString)); }
1960  void ProcessString(std::string &str, bool fIsID) override
1961  { Res = (fIsID ? C4VPropList(C4Id2Def(C4ID(str.c_str()))) : C4VString(str.c_str())); }
1962 };
1963 
1964 // Use the compiler to find a named value in a structure
1965 template <class T>
1966 C4Value GetValByStdCompiler(const char *strEntry, const char *strSection, int iEntryNr, const T &rFrom)
1967 {
1968  // Set up name array, create compiler
1969  const char *szNames[2] = { strSection ? strSection : strEntry, strSection ? strEntry : nullptr };
1970  C4ValueGetCompiler Comp(szNames, strSection ? 2 : 1, iEntryNr);
1971 
1972  // Compile
1973  try
1974  {
1975  Comp.Decompile(rFrom);
1976  return Comp.getResult();
1977  }
1978  // Should not happen, catch it anyway.
1979  catch (StdCompiler::Exception *)
1980  {
1981  return C4VNull;
1982  }
1983 }
1984 
1985 static C4Value FnGetDefCoreVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int iEntryNr)
1986 {
1987  if (!_this || !_this->GetDef())
1988  throw NeedNonGlobalContext("GetDefCoreVal");
1989 
1990  return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : nullptr,
1991  iEntryNr, mkNamingAdapt(*_this->GetDef(), "DefCore"));
1992 }
1993 
1994 static C4Value FnGetObjectVal(C4Object * _this, C4String * strEntry, C4String * strSection, int iEntryNr)
1995 {
1996  // get value
1997  C4ValueNumbers numbers;
1998  C4Value retval = GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : nullptr,
1999  iEntryNr, mkNamingAdapt(mkParAdapt(*Object(_this), &numbers), "Object"));
2000  numbers.Denumerate();
2001  retval.Denumerate(&numbers);
2002  return retval;
2003 }
2004 
2005 static C4Value FnGetObjectInfoCoreVal(C4Object * _this, C4String * strEntry, C4String * strSection, int iEntryNr)
2006 {
2007  // get obj info
2008  C4ObjectInfo* pObjInfo = Object(_this)->Info;
2009 
2010  if (!pObjInfo) return C4VNull;
2011 
2012  // get obj info core
2013  C4ObjectInfoCore* pObjInfoCore = (C4ObjectInfoCore*) pObjInfo;
2014 
2015  // get value
2016  return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : nullptr,
2017  iEntryNr, mkNamingAdapt(*pObjInfoCore, "ObjectInfo"));
2018 }
2019 
2020 static C4Value FnGetScenarioVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int iEntryNr)
2021 {
2022  return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : nullptr,
2023  iEntryNr, mkParAdapt(Game.C4S, false));
2024 }
2025 
2026 static C4Value FnGetPlayerVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int player_nr, int iEntryNr)
2027 {
2028  // get player
2029  C4Player* pPlayer = ::Players.Get(player_nr);
2030  if (!pPlayer) return C4Value();
2031 
2032  // get value
2033  C4ValueNumbers numbers;
2034  C4Value retval = GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : nullptr,
2035  iEntryNr, mkNamingAdapt(mkParAdapt(*pPlayer, &numbers), "Player"));
2036  numbers.Denumerate();
2037  retval.Denumerate(&numbers);
2038  return retval;
2039 }
2040 
2041 static C4Value FnGetPlayerInfoCoreVal(C4PropList * _this, C4String * strEntry, C4String * strSection, int player_nr, int iEntryNr)
2042 {
2043  // get player
2044  C4Player* pPlayer = ::Players.Get(player_nr);
2045  if (!pPlayer) return C4Value();
2046 
2047  // get plr info core
2048  C4PlayerInfoCore* pPlayerInfoCore = (C4PlayerInfoCore*) pPlayer;
2049 
2050  // get value
2051  return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : nullptr,
2052  iEntryNr, *pPlayerInfoCore);
2053 }
2054 
2055 static C4Value FnGetMaterialVal(C4PropList * _this, C4String * strEntry, C4String* strSection, int iMat, int iEntryNr)
2056 {
2057  if (iMat < 0 || iMat >= ::MaterialMap.Num) return C4Value();
2058 
2059  // get material
2060  C4Material *pMaterial = &::MaterialMap.Map[iMat];
2061 
2062  // get plr info core
2063  C4MaterialCore* pMaterialCore = static_cast<C4MaterialCore*>(pMaterial);
2064 
2065  // get value
2066  return GetValByStdCompiler(FnStringPar(strEntry), strSection ? strSection->GetCStr() : nullptr, iEntryNr, *pMaterialCore);
2067 }
2068 
2069 static C4String *FnMaterialName(C4PropList * _this, long iMat)
2070 {
2071  // mat valid?
2072  if (!MatValid(iMat)) return nullptr;
2073  // return mat name
2074  return String(::MaterialMap.Map[iMat].Name);
2075 }
2076 
2077 static bool FnSetSky(C4PropList * _this, C4String * name)
2078 {
2079  if (!name) return false;
2080  auto& sky = ::Landscape.GetSky();
2081 
2082  // Open Graphics.ocg -- we might need to fetch some shader (slices)
2083  // from there when reloading the sky.
2084  if (!::GraphicsResource.RegisterGlobalGraphics()) return false;
2085  if (!::GraphicsResource.RegisterMainGroups()) return false;
2086 
2087  sky.Clear();
2088  const bool result = sky.Init(false, name->GetCStr());
2089 
2090  // close Graphics.ocg again
2092 
2093  return result;
2094 }
2095 
2096 static bool FnSetSkyAdjust(C4PropList * _this, long dwAdjust, long dwBackClr)
2097 {
2098  // set adjust
2099  ::Landscape.GetSky().SetModulation(dwAdjust, dwBackClr);
2100  // success
2101  return true;
2102 }
2103 
2104 static bool FnSetMatAdjust(C4PropList * _this, long dwAdjust)
2105 {
2106  // set adjust
2107  ::Landscape.SetModulation(dwAdjust);
2108  // success
2109  return true;
2110 }
2111 
2112 static long FnGetSkyAdjust(C4PropList * _this, bool fBackColor)
2113 {
2114  // get adjust
2115  return ::Landscape.GetSky().GetModulation(!!fBackColor);
2116 }
2117 
2118 static long FnGetMatAdjust(C4PropList * _this)
2119 {
2120  // get adjust
2122 }
2123 
2124 static long FnGetTime(C4PropList * _this)
2125 {
2126  // check network, record, etc
2127  if (::Control.SyncMode()) return 0;
2128  return C4TimeMilliseconds::Now().AsInt();
2129 }
2130 
2131 static C4Value FnSetPlrExtraData(C4PropList * _this, int player_nr, C4String * DataName, const C4Value & Data)
2132 {
2133  const char * strDataName = FnStringPar(DataName);
2134  // do not allow data type C4V_Array or C4V_C4Object
2135  if (Data.GetType() != C4V_Nil &&
2136  Data.GetType() != C4V_Int &&
2137  Data.GetType() != C4V_Bool &&
2138  Data.GetType() != C4V_String) return C4VNull;
2139  C4Player* pPlayer = ::Players.Get(player_nr);
2140  if (!pPlayer) return C4Value();
2141  // no name list created yet?
2142  if (!pPlayer->ExtraData.pNames)
2143  // create name list
2144  pPlayer->ExtraData.CreateTempNameList();
2145  // data name already exists?
2146  long ival;
2147  if ((ival = pPlayer->ExtraData.pNames->GetItemNr(strDataName)) != -1)
2148  pPlayer->ExtraData[ival] = Data;
2149  else
2150  {
2151  // add name
2152  pPlayer->ExtraData.pNames->AddName(strDataName);
2153  // get val id & set
2154  if ((ival = pPlayer->ExtraData.pNames->GetItemNr(strDataName)) == -1) return C4Value();
2155  pPlayer->ExtraData[ival] = Data;
2156  }
2157  // ok, return the value that has been set
2158  return Data;
2159 }
2160 
2161 static C4Value FnGetPlrExtraData(C4PropList * _this, int player_nr, C4String * DataName)
2162 {
2163  const char *strDataName = FnStringPar(DataName);
2164  C4Player* pPlayer = ::Players.Get(player_nr);
2165  if (!pPlayer) return C4Value();
2166  // no name list?
2167  if (!pPlayer->ExtraData.pNames) return C4Value();
2168  long ival;
2169  if ((ival = pPlayer->ExtraData.pNames->GetItemNr(strDataName)) == -1) return C4Value();
2170  // return data
2171  return pPlayer->ExtraData[ival];
2172 }
2173 
2174 // undocumented!
2175 static long FnDrawMatChunks(C4PropList * _this, long tx, long ty, long twdt, long thgt, long icntx, long icnty, C4String *strMaterial, C4String *strTexture, bool bIFT)
2176 {
2177  return ::Landscape.DrawChunks(tx, ty, twdt, thgt, icntx, icnty, FnStringPar(strMaterial), FnStringPar(strTexture), bIFT != 0);
2178 }
2179 
2180 static long FnDrawMap(C4PropList * _this, long iX, long iY, long iWdt, long iHgt, C4String *szMapDef)
2181 {
2182  // draw it!
2183  // don't clear the old map before drawing
2184  return ::Landscape.DrawMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef), true);
2185 }
2186 
2187 static long FnDrawDefMap(C4PropList * _this, long iX, long iY, long iWdt, long iHgt, C4String *szMapDef)
2188 {
2189  // draw it!
2190  // don't clear the old map before drawing
2191  return ::Landscape.DrawDefMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef), true);
2192 }
2193 
2194 static bool FnCreateParticle(C4PropList * _this, C4String *name, C4Value x, C4Value y, C4Value speedX, C4Value speedY, C4Value lifetime, C4PropList *properties, int amount)
2195 {
2196  // safety
2197  C4Object *obj = Object(_this);
2198  if (obj && !_this->Status) return false;
2199 #ifndef USE_CONSOLE
2200  if (amount <= 0) amount = 1;
2201 
2202  // get particle
2203  C4ParticleDef *pDef = ::Particles.definitions.GetDef(FnStringPar(name));
2204  if (!pDef) return false;
2205  // construct data
2206  C4ParticleValueProvider valueX, valueY, valueSpeedX, valueSpeedY, valueLifetime;
2207  valueX.Set(x);
2208  valueY.Set(y);
2209  valueSpeedX.Set(speedX);
2210  valueSpeedY.Set(speedY);
2211  valueLifetime.Set(lifetime);
2212  // create
2213  ::Particles.Create(pDef, valueX, valueY, valueSpeedX, valueSpeedY, valueLifetime, properties, amount, obj);
2214 #endif
2215  // success, even if not created
2216  return true;
2217 }
2218 
2219 static bool FnClearParticles(C4PropList * _this)
2220 {
2221 #ifndef USE_CONSOLE
2222  C4Object *obj;
2223  if ((obj = Object(_this)))
2224  {
2225  if (obj->BackParticles)
2226  obj->BackParticles->Clear();
2227  if (obj->FrontParticles)
2228  obj->FrontParticles->Clear();
2229  }
2230  else
2231  {
2232  if (::Particles.GetGlobalParticles())
2234  }
2235 #endif
2236  // always return true
2237  return true;
2238 }
2239 
2240 static C4ValueArray* FnPV_Linear(C4PropList * _this, C4Value startValue, C4Value endValue)
2241 {
2242  C4ValueArray *array = new C4ValueArray(3);
2243  array->SetItem(0, C4VInt(C4PV_Linear));
2244  array->SetItem(1, startValue);
2245  array->SetItem(2, endValue);
2246  return array;
2247 }
2248 
2249 static C4ValueArray* FnPV_Random(C4PropList * _this, C4Value startValue, C4Value endValue, C4Value rerollInterval, C4Value seed)
2250 {
2251  C4ValueArray *array = new C4ValueArray(4);
2252  array->SetItem(0, C4VInt(C4PV_Random));
2253  array->SetItem(1, startValue);
2254  array->SetItem(2, endValue);
2255  array->SetItem(3, rerollInterval);
2256  array->SetItem(4, seed);
2257  return array;
2258 }
2259 
2260 static C4ValueArray* FnPV_Direction(C4PropList * _this, C4Value factor)
2261 {
2262  C4ValueArray *array = new C4ValueArray(2);
2263  array->SetItem(0, C4VInt(C4PV_Direction));
2264  array->SetItem(1, factor.GetType() != C4V_Nil ? factor : C4VInt(1000));
2265  return array;
2266 }
2267 
2268 static C4ValueArray* FnPV_Step(C4PropList * _this, C4Value step, C4Value startValue, C4Value delay, C4Value maximumValue)
2269 {
2270  C4ValueArray *array = new C4ValueArray(5);
2271  array->SetItem(0, C4VInt(C4PV_Step));
2272  array->SetItem(1, step);
2273  array->SetItem(2, startValue);
2274  array->SetItem(3, delay);
2275  array->SetItem(4, maximumValue);
2276  return array;
2277 }
2278 
2279 static C4Value FnPV_KeyFrames(C4PropList * _this, C4Value *pars)
2280 {
2281  C4ValueArray *array = new C4ValueArray(C4AUL_MAX_Par);
2282  array->SetItem(0, C4VInt(C4PV_KeyFrames));
2283  const int offset = 1;
2284 
2285  // Read all parameters
2286  int i = 0;
2287  for (; i < C4AUL_MAX_Par; i++)
2288  {
2289  C4Value Data = *(pars++);
2290  // No data given?
2291  if (Data.GetType() == C4V_Nil) break;
2292 
2293  array->SetItem(offset + i, Data);
2294  }
2295  array->SetSize(i + offset);
2296  return C4Value(array);
2297 }
2298 
2299 static C4ValueArray* FnPV_Sin(C4PropList * _this, C4Value value, C4Value amplitude, C4Value offset)
2300 {
2301  C4ValueArray *array = new C4ValueArray(5);
2302  array->SetItem(0, C4VInt(C4PV_Sin));
2303  array->SetItem(1, value);
2304  array->SetItem(2, amplitude);
2305  array->SetItem(3, offset);
2306  return array;
2307 }
2308 
2309 static C4ValueArray* FnPV_Cos(C4PropList * _this, C4Value value, C4Value amplitude, C4Value offset)
2310 {
2311  C4ValueArray *array = new C4ValueArray(5);
2312  array->SetItem(0, C4VInt(C4PV_Cos));
2313  array->SetItem(1, value);
2314  array->SetItem(2, amplitude);
2315  array->SetItem(3, offset);
2316  return array;
2317 }
2318 
2319 static C4ValueArray* FnPV_Speed(C4PropList * _this, C4Value factor, C4Value startValue)
2320 {
2321  C4ValueArray *array = new C4ValueArray(3);
2322  array->SetItem(0, C4VInt(C4PV_Speed));
2323  array->SetItem(1, factor.GetType() == C4V_Nil ? C4VInt(1000) : factor);
2324  array->SetItem(2, startValue);
2325  return array;
2326 }
2327 
2328 static C4ValueArray* FnPV_Wind(C4PropList * _this, C4Value factor, C4Value startValue)
2329 {
2330  C4ValueArray *array = new C4ValueArray(3);
2331  array->SetItem(0, C4VInt(C4PV_Wind));
2332  array->SetItem(1, factor.GetType() == C4V_Nil ? C4VInt(1000) : factor);
2333  array->SetItem(2, startValue);
2334  return array;
2335 }
2336 
2337 static C4ValueArray* FnPV_Gravity(C4PropList * _this, C4Value factor, C4Value startValue)
2338 {
2339  C4ValueArray *array = new C4ValueArray(3);
2340  array->SetItem(0, C4VInt(C4PV_Gravity));
2341  array->SetItem(1, factor.GetType() == C4V_Nil ? C4VInt(1000) : factor);
2342  array->SetItem(2, startValue);
2343  return array;
2344 }
2345 
2346 static C4ValueArray* FnPC_Die(C4PropList * _this)
2347 {
2348  C4ValueArray *array = new C4ValueArray(1);
2349  array->SetItem(0, C4VInt(C4PC_Die));
2350  return array;
2351 }
2352 
2353 static C4ValueArray* FnPC_Bounce(C4PropList * _this, C4Value bouncyness)
2354 {
2355  C4ValueArray *array = new C4ValueArray(2);
2356  array->SetItem(0, C4VInt(C4PC_Bounce));
2357  array->SetItem(1, bouncyness.GetType() != C4V_Nil ? bouncyness : C4VInt(1000));
2358  return array;
2359 }
2360 
2361 static C4ValueArray* FnPC_Stop(C4PropList * _this)
2362 {
2363  C4ValueArray *array = new C4ValueArray(1);
2364  array->SetItem(0, C4VInt(C4PC_Stop));
2365  return array;
2366 }
2367 
2368 static bool FnSetSkyParallax(C4PropList * _this, Nillable<long> iMode, Nillable<long> iParX, Nillable<long> iParY, Nillable<long> iXDir, Nillable<long> iYDir, Nillable<long> iX, Nillable<long> iY)
2369 {
2370  // set all parameters that aren't nil
2371  if (!iMode.IsNil())
2372  if (Inside<long>(iMode, 0, 1)) ::Landscape.GetSky().ParallaxMode = iMode;
2373  if (!iParX.IsNil() && iParX) ::Landscape.GetSky().ParX = iParX;
2374  if (!iParY.IsNil() && iParY) ::Landscape.GetSky().ParY = iParY;
2375  if (!iXDir.IsNil()) ::Landscape.GetSky().xdir = itofix(iXDir);
2376  if (!iYDir.IsNil()) ::Landscape.GetSky().ydir = itofix(iYDir);
2377  if (!iX.IsNil()) ::Landscape.GetSky().x = itofix(iX);
2378  if (!iY.IsNil()) ::Landscape.GetSky().y = itofix(iY);
2379  // success
2380  return true;
2381 }
2382 
2383 static long FnReloadDef(C4PropList * _this, C4ID idDef, long iReloadWhat)
2384 {
2385  // get def
2386  C4Def *pDef=nullptr;
2387  if (!idDef)
2388  {
2389  // no def given: local def
2390  if (Object(_this)) pDef=Object(_this)->Def;
2391  }
2392  else
2393  // def by ID
2394  pDef=::Definitions.ID2Def(idDef);
2395  // safety
2396  if (!pDef) return false;
2397  // reload everything if nothing has been specified
2398  if (!iReloadWhat) iReloadWhat=C4D_Load_RX;
2399  // perform reload
2400  return Game.ReloadDef(pDef->id);
2401 }
2402 
2403 static long FnReloadParticle(C4PropList * _this, C4String *szParticleName)
2404 {
2405  // perform reload
2406  return Game.ReloadParticle(FnStringPar(szParticleName));
2407 }
2408 
2409 static bool FnSetGamma(C4PropList * _this, long iRed, long iGreen, long iBlue, long iRampIndex)
2410 {
2411  pDraw->SetGamma(float(iRed) / 100,
2412  float(iGreen) / 100,
2413  float(iBlue) / 100,
2414  iRampIndex);
2415  return true;
2416 }
2417 
2418 static bool FnResetGamma(C4PropList * _this, long iRampIndex)
2419 {
2421  return true;
2422 }
2423 
2424 static Nillable<long> FnAddFragmentShader(C4PropList * _this, C4String * name, C4String * shader)
2425 {
2426  if (!name || !shader) return C4Void();
2427  return ScriptShader.Add(name->GetCStr(), C4ScriptShader::FragmentShader, shader->GetCStr());
2428 }
2429 
2430 static bool FnRemoveShader(C4PropList * _this, long id)
2431 {
2432  return ScriptShader.Remove(id);
2433 }
2434 
2435 // undocumented!
2436 static long FnFrameCounter(C4PropList * _this) { return Game.FrameCounter; }
2437 
2438 struct PathInfo
2439 {
2440  long ilx, ily;
2441  long ilen;
2442 };
2443 
2445 {
2446  explicit SumPathLength(PathInfo *info) : pPathInfo(info) {}
2447  bool operator()(int32_t iX, int32_t iY, C4Object *TransferTarget)
2448  {
2449  pPathInfo->ilen += Distance(pPathInfo->ilx, pPathInfo->ily, iX, iY);
2450  pPathInfo->ilx = iX;
2451  pPathInfo->ily = iY;
2452  return true;
2453  }
2454 
2455 private:
2456  PathInfo *pPathInfo;
2457 };
2458 
2459 static Nillable<long> FnGetPathLength(C4PropList * _this, long iFromX, long iFromY, long iToX, long iToY, long iLevel)
2460 {
2462  PathInfo.ilx = iFromX;
2463  PathInfo.ily = iFromY;
2464  PathInfo.ilen = 0;
2465  if (!iLevel)
2466  iLevel = 1;
2467  Game.PathFinder.SetLevel(iLevel);
2468  if (!Game.PathFinder.Find(iFromX, iFromY, iToX, iToY, SumPathLength(&PathInfo)))
2469  return C4Void();
2470  return PathInfo.ilen + Distance(PathInfo.ilx, PathInfo.ily, iToX, iToY);
2471 }
2472 
2473 // undocumented!
2474 static long FnSetTextureIndex(C4PropList * _this, C4String *psMatTex, long iNewIndex, bool fInsert)
2475 {
2476  if (!Inside(iNewIndex, 0l, 255l)) return false;
2477  return ::Landscape.SetTextureIndex(FnStringPar(psMatTex), BYTE(iNewIndex), !!fInsert);
2478 }
2479 
2480 // undocumented!
2481 static long FnRemoveUnusedTexMapEntries(C4PropList * _this)
2482 {
2484  return true;
2485 }
2486 
2487 static const int32_t DMQ_Sky = 0, // draw w/ sky IFT
2488  DMQ_Sub = 1, // draw w/ tunnel IFT
2489  DMQ_Bridge = 2; // draw only over materials you can bridge over
2490 
2491 static bool FnDrawMaterialQuad(C4PropList * _this, C4String *szMaterial, long iX1, long iY1, long iX2, long iY2, long iX3, long iY3, long iX4, long iY4, const C4Value& draw_mode)
2492 {
2493  const char *szMat = FnStringPar(szMaterial);
2494 
2495  const char *szBackMat = nullptr;
2496  bool fBridge = false;
2497  if (draw_mode.GetType() == C4V_Int)
2498  {
2499  // Default behaviour: Default background material
2500  const int draw_mode_value = draw_mode.getInt();
2501  switch(draw_mode_value)
2502  {
2503  case DMQ_Sky: break;
2504  case DMQ_Sub: szBackMat = "Tunnel"; break; // TODO: Go via DefaultBkgMat
2505  case DMQ_Bridge: fBridge = true; break;
2506  }
2507  }
2508  else if (draw_mode.GetType() == C4V_String)
2509  {
2510  szBackMat = FnStringPar(draw_mode.getStr());
2511  }
2512 
2513  return !! ::Landscape.DrawQuad(iX1, iY1, iX2, iY2, iX3, iY3, iX4, iY4, szMat, szBackMat, fBridge);
2514 }
2515 
2516 static bool FnSetFilmView(C4PropList * _this, long iToPlr)
2517 {
2518  // check player
2519  if (!ValidPlr(iToPlr) && iToPlr != NO_OWNER) return false;
2520  // real switch in replays only
2521  if (!::Control.isReplay()) return true;
2522  // set new target plr
2523  if (C4Viewport *vp = ::Viewports.GetFirstViewport()) vp->Init(iToPlr, true);
2524  // done, always success (sync)
2525  return true;
2526 }
2527 
2528 static bool FnAddMsgBoardCmd(C4PropList * _this, C4String *pstrCommand, C4String *pstrScript)
2529 {
2530  // safety
2531  if (!pstrCommand || !pstrScript) return false;
2532  // add command
2533  ::MessageInput.AddCommand(FnStringPar(pstrCommand), FnStringPar(pstrScript));
2534  return true;
2535 }
2536 
2537 static bool FnSetGameSpeed(C4PropList * _this, long iSpeed)
2538 {
2539  // safety
2540  if (iSpeed) if (!Inside<long>(iSpeed, 0, 1000)) return false;
2541  if (!iSpeed) iSpeed = 38;
2542  // set speed, restart timer
2543  Application.SetGameTickDelay(1000 / iSpeed);
2544  return true;
2545 }
2546 
2547 bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t iDensityMin, int32_t iDensityMax, int32_t &iIter);
2548 
2549 static C4ValueArray* FnSimFlight(C4PropList * _this, int X, int Y, Nillable<int> pvrXDir, Nillable<int> pvrYDir, Nillable<int> pviDensityMin, Nillable<int> pviDensityMax, Nillable<int> pviIter, int precision)
2550 {
2551  if (!precision) precision = 10;
2552  // check and set parameters
2553  MakeAbsCoordinates(_this, X, Y);
2554  int XDir = pvrXDir.IsNil() && Object(_this) ? fixtoi(Object(_this)->xdir, precision) : static_cast<int>(pvrXDir);
2555  int YDir = pvrXDir.IsNil() && Object(_this) ? fixtoi(Object(_this)->ydir, precision) : static_cast<int>(pvrYDir);
2556 
2557  int iDensityMin = pviDensityMin.IsNil() ? C4M_Solid : static_cast<int>(pviDensityMin);
2558  int iDensityMax = pviDensityMax.IsNil() ? 100 : static_cast<int>(pviDensityMax);
2559  int iIter = pviIter.IsNil() ? -1 : static_cast<int>(pviIter);
2560 
2561  // convert to C4Real
2562  C4Real x = itofix(X), y = itofix(Y),
2563  xdir = itofix(XDir, precision), ydir = itofix(YDir, precision);
2564 
2565  // simulate
2566  if (!SimFlight(x, y, xdir, ydir, iDensityMin, iDensityMax, iIter))
2567  {
2568  iIter *= -1;
2569  }
2570 
2571  // write results to array
2572  C4ValueArray *pResults = new C4ValueArray(5);
2573  pResults->SetItem(0, C4VInt(fixtoi(x)));
2574  pResults->SetItem(1, C4VInt(fixtoi(y)));
2575  pResults->SetItem(2, C4VInt(fixtoi(xdir * precision)));
2576  pResults->SetItem(3, C4VInt(fixtoi(ydir * precision)));
2577  pResults->SetItem(4, C4VInt(iIter));
2578  return pResults;
2579 }
2580 
2581 // undocumented!
2582 static long FnLoadScenarioSection(C4PropList * _this, C4String *pstrSection, long dwFlags)
2583 {
2584  // safety
2585  const char *szSection;
2586  if (!pstrSection || !*(szSection=FnStringPar(pstrSection))) return false;
2587  // try to load it
2588  return Game.LoadScenarioSection(szSection, dwFlags);
2589 }
2590 
2591 static bool FnSetViewOffset(C4PropList * _this, long player_nr, long iX, long iY)
2592 {
2593  if (!ValidPlr(player_nr)) return false;
2594  // get player viewport
2595  C4Viewport *pView = ::Viewports.GetViewport(player_nr);
2596  if (!pView) return true; // sync safety
2597  // set
2598  pView->SetViewOffset(iX, iY);
2599  // ok
2600  return true;
2601 }
2602 
2603 // undocumented!
2604 static bool FnSetPreSend(C4PropList * _this, long iToVal, C4String *pNewName)
2605 {
2606  if (!::Control.isNetwork()) return true;
2607  // dbg: manual presend
2608  const char *szClient = FnStringPar(pNewName);
2609  if (!szClient || !*szClient || WildcardMatch(szClient, Game.Clients.getLocalName()))
2610  {
2611  ::Control.Network.setTargetFPS(iToVal);
2612  ::GraphicsSystem.FlashMessage(FormatString("TargetFPS: %ld", iToVal).getData());
2613  }
2614  return true;
2615 }
2616 
2617 static long FnGetPlayerID(C4PropList * _this, long player_nr)
2618 {
2619  C4Player *player = ::Players.Get(player_nr);
2620  return player ? player->ID : 0;
2621 }
2622 
2623 static long FnGetPlayerTeam(C4PropList * _this, long player_nr)
2624 {
2625  // get player
2626  C4Player *player = ::Players.Get(player_nr);
2627  if (!player) return 0;
2628  // search team containing this player
2629  C4Team *pTeam = Game.Teams.GetTeamByPlayerID(player->ID);
2630  if (pTeam) return pTeam->GetID();
2631  // special value of -1 indicating that the team is still to be chosen
2632  if (player->IsChosingTeam()) return -1;
2633  // No team.
2634  return 0;
2635 }
2636 
2637 static bool FnSetPlayerTeam(C4PropList * _this, long player_nr, long idNewTeam, bool fNoCalls)
2638 {
2639  // no team changing in league games
2640  if (Game.Parameters.isLeague()) return false;
2641  // get player
2642  C4Player *player = ::Players.Get(player_nr);
2643  if (!player) return false;
2644  C4PlayerInfo *pPlrInfo = player->GetInfo();
2645  if (!pPlrInfo) return false;
2646  // already in that team?
2647  if (player->Team == idNewTeam) return true;
2648  // ask team setting if it's allowed (also checks for valid team)
2649  if (!Game.Teams.IsJoin2TeamAllowed(idNewTeam, pPlrInfo->GetType())) return false;
2650  // ask script if it's allowed
2651  if (!fNoCalls)
2652  {
2653  if (!!::Game.GRBroadcast(PSF_RejectTeamSwitch, &C4AulParSet(player_nr, idNewTeam), true, true))
2654  return false;
2655  }
2656  // exit previous team
2657  C4Team *pOldTeam = Game.Teams.GetTeamByPlayerID(player->ID);
2658  int32_t idOldTeam = 0;
2659  if (pOldTeam)
2660  {
2661  idOldTeam = pOldTeam->GetID();
2662  pOldTeam->RemovePlayerByID(player->ID);
2663  }
2664  // enter new team
2665  if (idNewTeam)
2666  {
2667  C4Team *pNewTeam = Game.Teams.GetGenerateTeamByID(idNewTeam);
2668  if (pNewTeam)
2669  {
2670  pNewTeam->AddPlayer(*pPlrInfo, true);
2671  idNewTeam = pNewTeam->GetID();
2672  }
2673  else
2674  {
2675  // unknown error
2676  player->Team = idNewTeam = 0;
2677  }
2678  }
2679  // update hositlities if this is not a "silent" change
2680  if (!fNoCalls)
2681  {
2682  player->SetTeamHostility();
2683  }
2684  // do callback to reflect change in scenario
2685  if (!fNoCalls)
2686  ::Game.GRBroadcast(PSF_OnTeamSwitch, &C4AulParSet(player_nr, idNewTeam, idOldTeam), true);
2687  return true;
2688 }
2689 
2690 // undocumented!
2691 static C4PropList *FnGetScriptPlayerExtraID(C4PropList * _this, long player_number)
2692 {
2693  C4Player *plr = ::Players.Get(player_number);
2694  if (!plr) return nullptr;
2695  C4PlayerInfo *info = plr->GetInfo();
2696  if (!info) return nullptr;
2697  return C4Id2Def(info->GetScriptPlayerExtraID());
2698 }
2699 
2700 // undocumented!
2701 static long FnGetTeamConfig(C4PropList * _this, long iConfigValue)
2702 {
2703  // query value
2704  switch (iConfigValue)
2705  {
2706  case C4TeamList::TEAM_Custom: return Game.Teams.IsCustom();
2713  }
2714  // undefined value
2715  DebugLogF("GetTeamConfig: Unknown config value: %ld", iConfigValue);
2716  return 0;
2717 }
2718 
2719 static C4String *FnGetTeamName(C4PropList * _this, long iTeam)
2720 {
2721  C4Team *pTeam = Game.Teams.GetTeamByID(iTeam);
2722  if (!pTeam) return nullptr;
2723  return String(pTeam->GetName());
2724 }
2725 
2726 static long FnGetTeamColor(C4PropList * _this, long iTeam)
2727 {
2728  C4Team *pTeam = Game.Teams.GetTeamByID(iTeam);
2729  return pTeam ? pTeam->GetColor() : 0u;
2730 }
2731 
2732 static long FnGetTeamByIndex(C4PropList * _this, long iIndex)
2733 {
2734  C4Team *pTeam = Game.Teams.GetTeamByIndex(iIndex);
2735  return pTeam ? pTeam->GetID() : 0;
2736 }
2737 
2738 static long FnGetTeamCount(C4PropList * _this)
2739 {
2740  return Game.Teams.GetTeamCount();
2741 }
2742 
2743 // undocumented!
2744 static bool FnInitScenarioPlayer(C4PropList * _this, long player_nr, long team_id)
2745 {
2746  C4Player *player = ::Players.Get(player_nr);
2747  if (!player) return false;
2748  return player->ScenarioAndTeamInit(team_id);
2749 }
2750 
2751 static bool FnSetScoreboardData(C4PropList * _this, long iRowID, long iColID, C4String *pText, long iData)
2752 {
2753  Game.Scoreboard.SetCell(iColID, iRowID, pText ? pText->GetCStr() : nullptr, iData);
2754  return true;
2755 }
2756 
2757 // undocumented!
2758 static C4String *FnGetScoreboardString(C4PropList * _this, long iRowID, long iColID)
2759 {
2760  return String(Game.Scoreboard.GetCellString(iColID, iRowID));
2761 }
2762 
2763 // undocumented!
2764 static int32_t FnGetScoreboardData(C4PropList * _this, long iRowID, long iColID)
2765 {
2766  return Game.Scoreboard.GetCellData(iColID, iRowID);
2767 }
2768 
2769 static bool FnDoScoreboardShow(C4PropList * _this, long change, long iForPlr)
2770 {
2771  C4Player *player;
2772  if (iForPlr)
2773  {
2774  // abort if the specified player is not local - but always return if the player exists,
2775  // to ensure sync safety
2776  if (!(player = ::Players.Get(iForPlr-1))) return false;
2777  if (!player->LocalControl) return true;
2778  }
2779  Game.Scoreboard.DoDlgShow(change, false);
2780  return true;
2781 }
2782 
2783 static bool FnSortScoreboard(C4PropList * _this, long iByColID, bool fReverse)
2784 {
2785  return Game.Scoreboard.SortBy(iByColID, !!fReverse);
2786 }
2787 
2788 // undocumented!
2789 static bool FnAddEvaluationData(C4PropList * _this, C4String *pText, long player_id)
2790 {
2791  // safety
2792  if (!pText) return false;
2793  if (!pText->GetCStr()) return false;
2794  if (player_id && !Game.PlayerInfos.GetPlayerInfoByID(player_id)) return false;
2795  // add data
2796  Game.RoundResults.AddCustomEvaluationString(pText->GetCStr(), player_id);
2797  return true;
2798 }
2799 
2800 // undocumented!
2801 static void FnHideSettlementScoreInEvaluation(C4PropList * _this, bool fHide)
2802 {
2804 }
2805 
2806 static bool FnCustomMessage(C4PropList * _this, C4String *pMsg, C4Object *pObj, Nillable<long> iOwner, long iOffX, long iOffY, long dwClr, C4ID idDeco, C4PropList *pSrc, long dwFlags, long iHSize)
2807 {
2808  // safeties: for global messages pSrc needs to be object/definition. For object-local messages, any proplist is OK
2809  if (pSrc)
2810  if (!pSrc->GetDef() && !pSrc->GetObject() && !pSrc->GetPropertyPropList(P_Source) && !pObj) return false;
2811  if (!pMsg) return false;
2812  if (pObj && !pObj->Status) return false;
2813  const char *szMsg = pMsg->GetCStr();
2814  if (!szMsg) return false;
2815  if (idDeco && !C4Id2Def(idDeco)) return false;
2816  if (iOwner.IsNil()) iOwner = NO_OWNER;
2817  // only one positioning flag per direction allowed
2818  uint32_t hpos = dwFlags & (C4GM_Left | C4GM_HCenter | C4GM_Right);
2819  uint32_t vpos = dwFlags & (C4GM_Top | C4GM_VCenter | C4GM_Bottom);
2820  if (((hpos | (hpos-1)) + 1)>>1 != hpos)
2821  {
2822  throw C4AulExecError("CustomMessage: Only one horizontal positioning flag allowed");
2823  }
2824  if (((vpos | (vpos-1)) + 1)>>1 != vpos)
2825  {
2826  throw C4AulExecError("CustomMessage: Only one vertical positioning flag allowed");
2827  }
2828  // message color
2829  if (!dwClr) dwClr = 0xffffffff;
2830  else dwClr = (dwClr&0xffffff) | (0xff000000u - uint32_t(dwClr|0xff000000)); // message internals use inverted alpha channel
2831  // message type
2832  int32_t iType;
2833  if (pObj)
2834  if (iOwner != NO_OWNER)
2835  iType = C4GM_TargetPlayer;
2836  else
2837  iType = C4GM_Target;
2838  else if (iOwner != NO_OWNER)
2839  iType = C4GM_GlobalPlayer;
2840  else
2841  iType = C4GM_Global;
2842  // remove speech?
2843  StdStrBuf sMsg;
2844  sMsg.Ref(szMsg);
2845  if (dwFlags & C4GM_DropSpeech) sMsg.SplitAtChar('$', nullptr);
2846  // create it!
2847  return ::Messages.New(iType, sMsg, pObj, iOwner, iOffX, iOffY, (uint32_t)dwClr, idDeco, pSrc, dwFlags, iHSize);
2848 }
2849 
2850 static int FnGuiOpen(C4PropList * _this, C4PropList *menu)
2851 {
2852  C4ScriptGuiWindow *window = new C4ScriptGuiWindow;
2853 
2854  ::Game.ScriptGuiRoot->AddChild(window);
2855 
2856  if (!window->CreateFromPropList(menu, true))
2857  {
2858  ::Game.ScriptGuiRoot->RemoveChild(window, false);
2859  return 0;
2860  }
2861 
2862  return window->GetID();
2863 }
2864 
2865 static bool FnGuiUpdateTag(C4PropList * _this, C4String *tag, int32_t guiID, int32_t childID, C4Object *target)
2866 {
2867  C4ScriptGuiWindow *window = ::Game.ScriptGuiRoot->GetChildByID(guiID);
2868  if (!window) return false;
2869  if (childID) // note: valid child IDs are always non-zero
2870  {
2871  C4ScriptGuiWindow *subwindow = window->GetSubWindow(childID, target);
2872  if (!subwindow) return false;
2873  subwindow->SetTag(tag);
2874  return true;
2875  }
2876  window->SetTag(tag);
2877  return true;
2878 }
2879 
2880 static bool FnGuiClose(C4PropList *_this, int32_t guiID, int32_t childID, C4Object *target)
2881 {
2882  C4ScriptGuiWindow *window = ::Game.ScriptGuiRoot->GetChildByID(guiID);
2883  if (!window) return false;
2884  if (childID) // note: valid child IDs are always non-zero
2885  {
2886  C4ScriptGuiWindow *subwindow = window->GetSubWindow(childID, target);
2887  if (!subwindow) return false;
2888  subwindow->Close();
2889  return true;
2890  }
2891  window->Close();
2892  return true;
2893 }
2894 
2895 static bool FnGuiUpdate(C4PropList *_this, C4PropList *update, int32_t guiID, int32_t childID, C4Object *target)
2896 {
2897  if (!update) return false;
2898  C4ScriptGuiWindow *window = ::Game.ScriptGuiRoot->GetChildByID(guiID);
2899  if (!window) return false;
2900  if (childID) // note: valid child IDs are always non-zero
2901  {
2902  C4ScriptGuiWindow *subwindow = window->GetSubWindow(childID, target);
2903  if (!subwindow) return false;
2904  subwindow->CreateFromPropList(update, false, true);
2905  return true;
2906  }
2907  window->CreateFromPropList(update, false, true);
2908  return true;
2909 }
2910 
2911 // undocumented!
2912 static bool FnPauseGame(C4PropList * _this, bool fToggle)
2913 {
2914  // not in replay (film)
2915  if (::Control.isReplay()) return true;
2916  // script method for halting game (for films)
2917  if (fToggle)
2918  Console.TogglePause();
2919  else
2920  Console.DoHalt();
2921  return true;
2922 }
2923 
2924 static bool FnSetNextScenario(C4PropList * _this, C4String *szNextMission, C4String *szNextMissionText, C4String *szNextMissionDesc)
2925 {
2926  if (!szNextMission || !szNextMission->GetData().getLength())
2927  {
2928  // param empty: clear next mission
2931  }
2932  else
2933  {
2934  // set next mission, button and button desc if given
2935  Game.NextMission.Copy(szNextMission->GetData());
2936  if (szNextMissionText && szNextMissionText->GetCStr())
2937  {
2938  Game.NextMissionText.Copy(szNextMissionText->GetData());
2939  }
2940  else
2941  {
2942  Game.NextMissionText.Copy(LoadResStr("IDS_BTN_NEXTMISSION"));
2943  }
2944  if (szNextMissionDesc && szNextMissionDesc->GetCStr())
2945  {
2946  Game.NextMissionDesc.Copy(szNextMissionDesc->GetData());
2947  }
2948  else
2949  {
2950  Game.NextMissionDesc.Copy(LoadResStr("IDS_DESC_NEXTMISSION"));
2951  }
2952  }
2953  return true;
2954 }
2955 
2956 static long FnGetPlayerControlState(C4PropList * _this, long player_nr, long iControl, bool fMovedState)
2957 {
2958  // get control set to check
2959  C4PlayerControl *pCheckCtrl = nullptr;
2960  if (player_nr != NO_OWNER)
2961  {
2962  C4Player *player = ::Players.Get(player_nr);
2963  if (player)
2964  {
2965  pCheckCtrl = &(player->Control);
2966  }
2967  }
2968  // invalid player or no controls
2969  if (!pCheckCtrl) return 0;
2970  // query control
2971  const C4PlayerControl::CSync::ControlDownState *pControlState = pCheckCtrl->GetControlDownState(iControl);
2972  // no state means not down
2973  if (!pControlState) return 0;
2974  // otherwise take either down-value or moved-value
2975  return fMovedState ? pControlState->MovedState.iStrength : pControlState->DownState.iStrength;
2976 }
2977 
2978 // undocumented!
2979 static bool FnSetPlayerControlEnabled(C4PropList * _this, long iplr, long ctrl, bool is_enabled)
2980 {
2981  // get control set to check
2982  C4PlayerControl *plrctrl = nullptr;
2983  if (iplr != NO_OWNER)
2984  {
2985  C4Player *plr = ::Players.Get(iplr);
2986  if (plr)
2987  {
2988  plrctrl = &(plr->Control);
2989  }
2990  }
2991  // invalid player or no controls
2992  if (!plrctrl) return false;
2993  // invalid control
2994  if (ctrl >= int32_t(Game.PlayerControlDefs.GetCount())) return false;
2995  // query
2996  return plrctrl->SetControlDisabled(ctrl, !is_enabled);
2997 }
2998 
2999 // undocumented!
3000 static bool FnGetPlayerControlEnabled(C4PropList * _this, long iplr, long ctrl)
3001 {
3002  // get control set to check
3003  C4PlayerControl *plrctrl = nullptr;
3004  if (iplr != NO_OWNER)
3005  {
3006  C4Player *plr = ::Players.Get(iplr);
3007  if (plr)
3008  {
3009  plrctrl = &(plr->Control);
3010  }
3011  }
3012  // invalid player or no controls
3013  if (!plrctrl) return false;
3014  return !plrctrl->IsControlDisabled(ctrl);
3015 }
3016 
3017 // undocumented!
3018 static C4String *FnGetPlayerControlAssignment(C4PropList * _this, long player, long control, bool human_readable, bool short_name)
3019 {
3020  // WARNING: As many functions returning strings, the result is not sync safe!
3021  // "" is returned for invalid controls to make the obvious if (GetPlayerControlAssignmentName(...)) not cause a sync loss
3022  // get desired assignment from parameters
3023  C4Player *plr = ::Players.Get(player);
3024  if (!plr) return nullptr; // invalid player
3025  if (!plr->ControlSet) return String(""); // player has no control (remote player)
3026  C4PlayerControlAssignment *assignment = plr->ControlSet->GetAssignmentByControl(control);
3027  if (!assignment) return String("");
3028  // get assignment as readable string
3029  return String(assignment->GetKeysAsString(human_readable, short_name).getData());
3030 }
3031 
3032 // strength: 0-1000, length: milliseconds
3033 static bool FnPlayRumble(C4PropList * _this, long player, long strength, long length)
3034 {
3035  // Check parameters.
3036  if (strength <= 0 || strength > 1000) return false;
3037  if (length <= 0) return false;
3038  // NO_OWNER: play rumble for all players (e.g. earthquakes)
3039  if (player == NO_OWNER)
3040  {
3041  for (C4Player *plr = ::Players.First; plr; plr=plr->Next)
3042  if (plr->Number != NO_OWNER) // can't happen, but would be a crash if it did...
3043  FnPlayRumble(_this, plr->Number, strength, length);
3044  return true;
3045  }
3046  C4Player *plr = ::Players.Get(player);
3047  if (!plr) return false;
3048  if (plr->pGamepad)
3049  plr->pGamepad->PlayRumble(strength / 1000.f, length);
3050  // We can't return whether the rumble was actually played.
3051  return true;
3052 }
3053 
3054 static bool FnStopRumble(C4PropList * _this, long player)
3055 {
3056  // NO_OWNER: stop rumble for all players
3057  // Not sure whether this makes sense to do - mainly provided for symmetry with PlayRumble().
3058  if (player == NO_OWNER)
3059  {
3060  for (C4Player *plr = ::Players.First; plr; plr=plr->Next)
3061  if (plr->Number != NO_OWNER) // can't happen, but would be a crash if it did...
3062  FnStopRumble(_this, plr->Number);
3063  return true;
3064  }
3065  C4Player *plr = ::Players.Get(player);
3066  if (!plr) return false;
3067  if (plr->pGamepad)
3068  plr->pGamepad->StopRumble();
3069  return true;
3070 }
3071 
3072 static int32_t FnGetStartupPlayerCount(C4PropList * _this)
3073 {
3074  // returns number of players when game was initially started
3076 }
3077 
3078 static int32_t FnGetStartupTeamCount(C4PropList * _this)
3079 {
3080  // returns number of non-empty teams when game was initially started
3082 }
3083 
3084 static bool FnGainScenarioAchievement(C4PropList * _this, C4String *achievement_name, Nillable<long> avalue, Nillable<long> player, C4String *for_scenario)
3085 {
3086  // safety
3087  if (!achievement_name || !achievement_name->GetData().getLength()) return false;
3088  // default parameter
3089  long value = avalue.IsNil() ? 1 : (long)avalue;
3090  // gain achievement
3091  bool result = true;
3092  if (!player.IsNil() && player != NO_OWNER)
3093  {
3094  C4Player *plr = ::Players.Get(player);
3095  if (!plr) return false;
3096  result = plr->GainScenarioAchievement(achievement_name->GetCStr(), value, for_scenario ? for_scenario->GetCStr() : nullptr);
3097  }
3098  else
3099  {
3100  for (C4Player *plr = ::Players.First; plr; plr = plr->Next)
3101  if (!plr->GainScenarioAchievement(achievement_name->GetCStr(), value, for_scenario ? for_scenario->GetCStr() : nullptr))
3102  result = false;
3103  }
3104  return result;
3105 }
3106 
3107 static long FnGetPXSCount(C4PropList * _this, Nillable<long> iMaterial, Nillable<long> iX0, Nillable<long> iY0, Nillable<long> iWdt, Nillable<long> iHgt)
3108 {
3109  if (iX0.IsNil())
3110  {
3111  // Search everywhere
3112  // All materials everywhere
3113  if (iMaterial.IsNil() || iMaterial == MNone) return ::PXS.GetCount();
3114  // Specific material everywhere
3115  return ::PXS.GetCount(iMaterial);
3116  }
3117  else
3118  {
3119  // Material in area; offset by caller
3120  int32_t x = iX0, y = iY0;
3121  MakeAbsCoordinates(_this, x, y);
3122  return ::PXS.GetCount(iMaterial.IsNil() ? MNone : static_cast<int32_t>(iMaterial), x, y, iWdt, iHgt);
3123  }
3124 }
3125 
3126 static C4String *FnGetTranslatedString(C4PropList * _this, const C4Value & string_data)
3127 {
3128  // Resolve proplists containing localized strings to the current localization
3129  return ::Game.GetTranslatedString(string_data, nullptr, false);
3130 }
3131 
3134 
3136 {
3137  // add all def constants (all Int)
3138  for (C4ScriptConstDef *pCDef = &C4ScriptGameConstMap[0]; pCDef->Identifier; pCDef++)
3139  {
3140  assert(pCDef->ValType == C4V_Int); // only int supported currently
3141  pEngine->RegisterGlobalConstant(pCDef->Identifier, C4VInt(pCDef->Data));
3142  }
3143  C4PropListStatic * p = pEngine->GetPropList();
3144  // add all def script funcs
3145  for (C4ScriptFnDef *pDef = &C4ScriptGameFnMap[0]; pDef->Identifier; pDef++)
3146  new C4AulDefFunc(p, pDef);
3147 #define F(f) ::AddFunc(p, #f, Fn##f)
3148  F(GetX);
3149  F(GetY);
3150  F(GetDefinition);
3151  F(GetDefinitionGroupPath);
3152  F(GetPlayerName);
3153  F(GetPlayerType);
3154  F(GetPlayerColor);
3155  F(GetPlrClonkSkin);
3156  F(CreateObject);
3157  F(CreateObjectAbove);
3158  F(CreateConstruction);
3159  F(FindConstructionSite);
3160  F(CheckConstructionSite);
3161  F(Sound);
3162  F(SoundAt);
3163  F(ChangeSoundModifier);
3164  F(SetGlobalSoundModifier);
3165  F(Music);
3166  F(MusicLevel);
3167  F(SetPlayList);
3168  F(SetPlrView);
3169  F(SetPlrKnowledge);
3170  F(GetPlrViewMode);
3171  F(ResetCursorView);
3172  F(GetPlrView);
3173  F(GetWealth);
3174  F(SetWealth);
3175  F(DoPlayerScore);
3176  F(GetPlayerScore);
3177  F(GetPlayerScoreGain);
3178  F(GetWind);
3179  F(SetWind);
3180  F(GetTemperature);
3181  F(SetTemperature);
3182  F(ShakeFree);
3183  F(DigFree);
3184  F(DigFreeRect);
3185  F(ClearFreeRect);
3186  F(Hostile);
3187  F(SetHostility);
3188  F(PlaceVegetation);
3189  F(PlaceAnimal);
3190  F(GameOver);
3191  F(GetHiRank);
3192  F(GetCrew);
3193  F(GetCrewCount);
3194  F(GetPlayerCount);
3195  F(GetPlayerByIndex);
3196  F(EliminatePlayer);
3197  F(SurrenderPlayer);
3198  F(GetLeagueScore);
3199  F(SetLeaguePerformance);
3200  F(SetLeagueProgressData);
3201  F(GetLeagueProgressData);
3202  F(CreateScriptPlayer);
3203  F(GetCursor);
3204  F(GetViewCursor);
3205  F(SetCursor);
3206  F(SetViewCursor);
3207  F(GetMaterial);
3208  F(GetBackMaterial);
3209  F(GetTexture);
3210  F(GetBackTexture);
3211  F(GetAverageTextureColor);
3212  F(GetMaterialCount);
3213  F(GBackSolid);
3214  F(GBackSemiSolid);
3215  F(GBackLiquid);
3216  F(GBackSky);
3217  F(Material);
3218  F(BlastFree);
3219  F(InsertMaterial);
3220  F(CanInsertMaterial);
3221  F(ExecutePXS);
3222  F(LandscapeWidth);
3223  F(LandscapeHeight);
3224  F(SetAmbientBrightness);
3225  F(GetAmbientBrightness);
3226  F(SetSeason);
3227  F(GetSeason);
3228  F(SetClimate);
3229  F(GetClimate);
3230  F(SetPlayerZoomByViewRange);
3231  F(GetPlayerZoomLimits);
3232  F(SetPlayerZoom);
3233  F(SetPlayerViewLock);
3234  F(DoBaseMaterial);
3235  F(DoBaseProduction);
3236  F(GainScenarioAccess);
3237  F(IsNetwork);
3238  F(IsEditor);
3239  F(GetLeague);
3240  ::AddFunc(p, "TestMessageBoard", FnTestMessageBoard, false);
3241  ::AddFunc(p, "CallMessageBoard", FnCallMessageBoard, false);
3242  ::AddFunc(p, "AbortMessageBoard", FnAbortMessageBoard, false);
3243  F(SetFoW);
3244  F(SetMaxPlayer);
3245  F(Object);
3246  F(GetTime);
3247  F(GetScenarioAccess);
3248  F(MaterialName);
3249  F(DrawMap);
3250  F(DrawDefMap);
3251  F(CreateParticle);
3252  F(ClearParticles);
3253  F(SetSky);
3254  F(SetSkyAdjust);
3255  F(SetMatAdjust);
3256  F(GetSkyAdjust);
3257  F(GetMatAdjust);
3258  F(SetSkyParallax);
3259  F(ReloadDef);
3260  F(ReloadParticle);
3261  F(SetGamma);
3262  F(ResetGamma);
3263  F(AddFragmentShader);
3264  F(RemoveShader);
3265  F(FrameCounter);
3266  F(DrawMaterialQuad);
3267  F(SetFilmView);
3268  F(AddMsgBoardCmd);
3269  ::AddFunc(p, "SetGameSpeed", FnSetGameSpeed, false);
3270  ::AddFunc(p, "DrawMatChunks", FnDrawMatChunks, false);
3271  F(GetPathLength);
3272  F(SetTextureIndex);
3273  F(RemoveUnusedTexMapEntries);
3274  F(SimFlight);
3275  F(LoadScenarioSection);
3276  F(SetViewOffset);
3277  ::AddFunc(p, "SetPreSend", FnSetPreSend, false);
3278  F(GetPlayerID);
3279  F(GetPlayerTeam);
3280  F(SetPlayerTeam);
3281  F(GetScriptPlayerExtraID);
3282  F(GetTeamConfig);
3283  F(GetTeamName);
3284  F(GetTeamColor);
3285  F(GetTeamByIndex);
3286  F(GetTeamCount);
3287  ::AddFunc(p, "InitScenarioPlayer", FnInitScenarioPlayer, false);
3288  F(SetScoreboardData);
3289  ::AddFunc(p, "GetScoreboardString", FnGetScoreboardString, false);
3290  ::AddFunc(p, "GetScoreboardData", FnGetScoreboardData, false);
3291  F(DoScoreboardShow);
3292  F(SortScoreboard);
3293  F(AddEvaluationData);
3294  F(HideSettlementScoreInEvaluation);
3295  F(ExtractMaterialAmount);
3296  F(CustomMessage);
3297  F(GuiOpen);
3298  F(GuiUpdateTag);
3299  F(GuiClose);
3300  F(GuiUpdate);
3301  ::AddFunc(p, "PauseGame", FnPauseGame, false);
3302  F(PathFree);
3303  F(PathFree2);
3304  F(SetNextScenario);
3305  F(GetPlayerControlState);
3306  F(SetPlayerControlEnabled);
3307  F(GetPlayerControlEnabled);
3308  F(GetPlayerControlAssignment);
3309  F(PlayRumble);
3310  F(StopRumble);
3311  F(GetStartupPlayerCount);
3312  F(GetStartupTeamCount);
3313  F(EditCursor);
3314  F(GainScenarioAchievement);
3315  F(GetPXSCount);
3316  F(GetPlrKnowledge);
3317  F(GetBaseMaterial);
3318  F(GetBaseProduction);
3319  F(GetDefCoreVal);
3320  F(GetObjectVal);
3321  F(GetObjectInfoCoreVal);
3322  F(GetScenarioVal);
3323  F(GetPlayerVal);
3324  F(GetPlayerInfoCoreVal);
3325  F(GetMaterialVal);
3326  F(SetPlrExtraData);
3327  F(GetPlrExtraData);
3328  F(PV_Linear);
3329  F(PV_Random);
3330  F(PV_Direction);
3331  F(PV_Step);
3332  F(PV_Speed);
3333  F(PV_Wind);
3334  F(PV_Gravity);
3335  // F(PV_KeyFrames); added below
3336  F(PV_Sin);
3337  F(PV_Cos);
3338  F(PC_Die);
3339  F(PC_Bounce);
3340  F(PC_Stop);
3341  F(IncinerateLandscape);
3342  F(GetGravity);
3343  F(SetGravity);
3344  F(GetTranslatedString);
3345 #undef F
3346 }
3347 
3349 {
3350  { "NO_OWNER" ,C4V_Int, NO_OWNER }, // invalid player number
3351 
3352  // material density
3353  { "C4M_Vehicle" ,C4V_Int, C4M_Vehicle },
3354  { "C4M_Solid" ,C4V_Int, C4M_Solid },
3355  { "C4M_SemiSolid" ,C4V_Int, C4M_SemiSolid },
3356  { "C4M_Liquid" ,C4V_Int, C4M_Liquid },
3357  { "C4M_Background" ,C4V_Int, C4M_Background },
3358 
3359  // scoreboard
3360  { "SBRD_Caption" ,C4V_Int, C4Scoreboard::TitleKey }, // used to set row/coloumn headers
3361 
3362  // teams - constants for GetTeamConfig
3363  { "TEAM_Custom" ,C4V_Int, C4TeamList::TEAM_Custom },
3364  { "TEAM_Active" ,C4V_Int, C4TeamList::TEAM_Active },
3365  { "TEAM_AllowHostilityChange" ,C4V_Int, C4TeamList::TEAM_AllowHostilityChange },
3366  { "TEAM_Dist" ,C4V_Int, C4TeamList::TEAM_Dist },
3367  { "TEAM_AllowTeamSwitch" ,C4V_Int, C4TeamList::TEAM_AllowTeamSwitch },
3368  { "TEAM_AutoGenerateTeams" ,C4V_Int, C4TeamList::TEAM_AutoGenerateTeams },
3369  { "TEAM_TeamColors" ,C4V_Int, C4TeamList::TEAM_TeamColors },
3370 
3371  { "C4FO_Not" ,C4V_Int, C4FO_Not },
3372  { "C4FO_And" ,C4V_Int, C4FO_And },
3373  { "C4FO_Or" ,C4V_Int, C4FO_Or },
3374  { "C4FO_Exclude" ,C4V_Int, C4FO_Exclude },
3375  { "C4FO_InRect" ,C4V_Int, C4FO_InRect },
3376  { "C4FO_AtPoint" ,C4V_Int, C4FO_AtPoint },
3377  { "C4FO_AtRect" ,C4V_Int, C4FO_AtRect },
3378  { "C4FO_OnLine" ,C4V_Int, C4FO_OnLine },
3379  { "C4FO_Distance" ,C4V_Int, C4FO_Distance },
3380  { "C4FO_ID" ,C4V_Int, C4FO_ID },
3381  { "C4FO_OCF" ,C4V_Int, C4FO_OCF },
3382  { "C4FO_Category" ,C4V_Int, C4FO_Category },
3383  { "C4FO_Action" ,C4V_Int, C4FO_Action },
3384  { "C4FO_ActionTarget" ,C4V_Int, C4FO_ActionTarget },
3385  { "C4FO_Procedure" ,C4V_Int, C4FO_Procedure },
3386  { "C4FO_Container" ,C4V_Int, C4FO_Container },
3387  { "C4FO_AnyContainer" ,C4V_Int, C4FO_AnyContainer },
3388  { "C4FO_Owner" ,C4V_Int, C4FO_Owner },
3389  { "C4FO_Controller" ,C4V_Int, C4FO_Controller },
3390  { "C4FO_Func" ,C4V_Int, C4FO_Func },
3391  { "C4FO_Layer" ,C4V_Int, C4FO_Layer },
3392  { "C4FO_InArray" ,C4V_Int, C4FO_InArray },
3393  { "C4FO_Property" ,C4V_Int, C4FO_Property },
3394  { "C4FO_AnyLayer" ,C4V_Int, C4FO_AnyLayer },
3395  { "C4FO_Cone" ,C4V_Int, C4FO_Cone },
3396 
3397  { "MD_DragSource" ,C4V_Int, C4MC_MD_DragSource },
3398  { "MD_DropTarget" ,C4V_Int, C4MC_MD_DropTarget },
3399  { "MD_NoClick" ,C4V_Int, C4MC_MD_NoClick },
3400 
3401  { "C4SO_Reverse" ,C4V_Int, C4SO_Reverse },
3402  { "C4SO_Multiple" ,C4V_Int, C4SO_Multiple },
3403  { "C4SO_Distance" ,C4V_Int, C4SO_Distance },
3404  { "C4SO_Random" ,C4V_Int, C4SO_Random },
3405  { "C4SO_Speed" ,C4V_Int, C4SO_Speed },
3406  { "C4SO_Mass" ,C4V_Int, C4SO_Mass },
3407  { "C4SO_Value" ,C4V_Int, C4SO_Value },
3408  { "C4SO_Func" ,C4V_Int, C4SO_Func },
3409 
3410  { "C4SECT_SaveLandscape" ,C4V_Int, C4S_SAVE_LANDSCAPE },
3411  { "C4SECT_SaveObjects" ,C4V_Int, C4S_SAVE_OBJECTS },
3412  { "C4SECT_KeepEffects" ,C4V_Int, C4S_KEEP_EFFECTS },
3413  { "C4SECT_ReinitScenario" ,C4V_Int, C4S_REINIT_SCENARIO },
3414 
3415  { "TEAMID_New" ,C4V_Int, TEAMID_New },
3416 
3417  { "MSG_NoLinebreak" ,C4V_Int, C4GM_NoBreak },
3418  { "MSG_Bottom" ,C4V_Int, C4GM_Bottom },
3419  { "MSG_Multiple" ,C4V_Int, C4GM_Multiple },
3420  { "MSG_Top" ,C4V_Int, C4GM_Top },
3421  { "MSG_Left" ,C4V_Int, C4GM_Left },
3422  { "MSG_Right" ,C4V_Int, C4GM_Right },
3423  { "MSG_HCenter" ,C4V_Int, C4GM_HCenter },
3424  { "MSG_VCenter" ,C4V_Int, C4GM_VCenter },
3425  { "MSG_DropSpeech" ,C4V_Int, C4GM_DropSpeech },
3426  { "MSG_WidthRel" ,C4V_Int, C4GM_WidthRel },
3427  { "MSG_XRel" ,C4V_Int, C4GM_XRel },
3428  { "MSG_YRel" ,C4V_Int, C4GM_YRel },
3429  { "MSG_Zoom" ,C4V_Int, C4GM_Zoom },
3430 
3431  { "C4PT_User" ,C4V_Int, C4PT_User },
3432  { "C4PT_Script" ,C4V_Int, C4PT_Script },
3433 
3434  { "CSPF_FixedAttributes" ,C4V_Int, CSPF_FixedAttributes },
3435  { "CSPF_NoScenarioInit" ,C4V_Int, CSPF_NoScenarioInit },
3436  { "CSPF_NoEliminationCheck" ,C4V_Int, CSPF_NoEliminationCheck },
3437  { "CSPF_Invisible" ,C4V_Int, CSPF_Invisible },
3438  { "CSPF_NoScenarioSave" ,C4V_Int, CSPF_NoScenarioSave },
3439 
3440  { "DMQ_Sky" ,C4V_Int, DMQ_Sky },
3441  { "DMQ_Sub" ,C4V_Int, DMQ_Sub },
3442  { "DMQ_Bridge" ,C4V_Int, DMQ_Bridge },
3443 
3444  { "PLRZOOM_Direct" ,C4V_Int, PLRZOOM_Direct },
3445  { "PLRZOOM_NoIncrease" ,C4V_Int, PLRZOOM_NoIncrease },
3446  { "PLRZOOM_NoDecrease" ,C4V_Int, PLRZOOM_NoDecrease },
3447  { "PLRZOOM_LimitMin" ,C4V_Int, PLRZOOM_LimitMin },
3448  { "PLRZOOM_LimitMax" ,C4V_Int, PLRZOOM_LimitMax },
3449  { "PLRZOOM_Set" ,C4V_Int, PLRZOOM_Set },
3450 
3451  { "ATTACH_Front" ,C4V_Int, C4ATTACH_Front },
3452  { "ATTACH_Back" ,C4V_Int, C4ATTACH_Back },
3453  { "ATTACH_MoveRelative" ,C4V_Int, C4ATTACH_MoveRelative },
3454 
3455  // sound modifier type
3456  { "C4SMT_Reverb" ,C4V_Int, C4SoundModifier::C4SMT_Reverb },
3457  { "C4SMT_Echo" ,C4V_Int, C4SoundModifier::C4SMT_Echo },
3458  { "C4SMT_Equalizer" ,C4V_Int, C4SoundModifier::C4SMT_Equalizer },
3459 
3460  { "GUI_SetTag" ,C4V_Int, C4ScriptGuiWindowActionID::SetTag },
3461  { "GUI_Call" ,C4V_Int, C4ScriptGuiWindowActionID::Call },
3462  { "GUI_GridLayout" ,C4V_Int, C4ScriptGuiWindowStyleFlag::GridLayout },
3463  { "GUI_TightGridLayout" ,C4V_Int, C4ScriptGuiWindowStyleFlag::TightGridLayout },
3464  { "GUI_VerticalLayout" ,C4V_Int, C4ScriptGuiWindowStyleFlag::VerticalLayout },
3465  { "GUI_TextVCenter" ,C4V_Int, C4ScriptGuiWindowStyleFlag::TextVCenter },
3466  { "GUI_TextHCenter" ,C4V_Int, C4ScriptGuiWindowStyleFlag::TextHCenter },
3467  { "GUI_TextRight" ,C4V_Int, C4ScriptGuiWindowStyleFlag::TextRight },
3468  { "GUI_TextBottom" ,C4V_Int, C4ScriptGuiWindowStyleFlag::TextBottom },
3469  { "GUI_TextTop" ,C4V_Int, C4ScriptGuiWindowStyleFlag::None }, // note that top and left are considered default
3470  { "GUI_TextLeft" ,C4V_Int, C4ScriptGuiWindowStyleFlag::None }, // they are only included for completeness
3471  { "GUI_FitChildren" ,C4V_Int, C4ScriptGuiWindowStyleFlag::FitChildren },
3472  { "GUI_Multiple" ,C4V_Int, C4ScriptGuiWindowStyleFlag::Multiple },
3473  { "GUI_IgnoreMouse" ,C4V_Int, C4ScriptGuiWindowStyleFlag::IgnoreMouse },
3474  { "GUI_NoCrop" ,C4V_Int, C4ScriptGuiWindowStyleFlag::NoCrop },
3475 
3476  // control states
3477  { "CONS_Down" ,C4V_Int, C4PlayerControl::CONS_Down },
3478  { "CONS_Up" ,C4V_Int, C4PlayerControl::CONS_Up },
3479  { "CONS_Moved" ,C4V_Int, C4PlayerControl::CONS_Moved },
3480 
3481  { "PLRCON_MaxStrength" ,C4V_Int, C4GamePadControl::MaxStrength },
3482 
3483  { nullptr, C4V_Nil, 0}
3484 };
3485 
3487 {
3488  { "FindObject", true, C4V_Object, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObject },
3489  { "FindObjects", true, C4V_Array, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFindObjects },
3490  { "ObjectCount", true, C4V_Int, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnObjectCount },
3491  { "GameCallEx", true, C4V_Any, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnGameCallEx },
3492  { "PlayerMessage", true, C4V_Int, { C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPlayerMessage },
3493  { "Message", true, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnMessage },
3494  { "AddMessage", true, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnAddMessage },
3495  { "PV_KeyFrames", true, C4V_Array, { C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnPV_KeyFrames },
3496 
3497  { nullptr, false, C4V_Nil, { C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil}, nullptr }
3498 };
#define X(sdl, oc)
C4Object * Object(C4PropList *_this)
Definition: C4AulDefFunc.h:34
StdStrBuf FnStringFormat(C4PropList *_this, C4String *szFormatPar, C4Value *Pars, int ParCount)
Definition: C4Script.cpp:30
C4String * String(const char *str)
Definition: C4AulDefFunc.h:30
void AddFunc(C4PropListStatic *Parent, const char *Name, RType(*pFunc)(ThisType *, ParTypes...), bool Public=true)
Definition: C4AulDefFunc.h:261
const char * Identifier
Definition: C4AulDefFunc.h:269
#define C4AUL_MAX_Par
Definition: C4AulFunc.h:26
C4Config Config
Definition: C4Config.cpp:930
@ CFG_MaxString
Definition: C4Config.h:28
const int32_t FullCon
Definition: C4Constants.h:181
const int32_t C4M_Background
Definition: C4Constants.h:175
const int32_t C4M_Vehicle
Definition: C4Constants.h:171
const int32_t C4M_Solid
Definition: C4Constants.h:172
const int32_t MNone
Definition: C4Constants.h:177
const int32_t C4M_Liquid
Definition: C4Constants.h:174
const int32_t C4M_SemiSolid
Definition: C4Constants.h:173
C4PlayerType
Definition: C4Constants.h:152
@ C4PT_User
Definition: C4Constants.h:154
@ C4PT_Script
Definition: C4Constants.h:155
const int NO_OWNER
Definition: C4Constants.h:137
const DWORD C4D_Load_RX
Definition: C4Def.h:91
C4Def * C4Id2Def(C4ID id)
Definition: C4DefList.h:84
C4Draw * pDraw
Definition: C4Draw.cpp:42
@ C4FO_Container
Definition: C4FindObject.h:40
@ C4FO_AnyLayer
Definition: C4FindObject.h:48
@ C4FO_AtPoint
Definition: C4FindObject.h:30
@ C4FO_OnLine
Definition: C4FindObject.h:32
@ C4FO_Distance
Definition: C4FindObject.h:33
@ C4FO_Action
Definition: C4FindObject.h:37
@ C4FO_AnyContainer
Definition: C4FindObject.h:41
@ C4FO_Procedure
Definition: C4FindObject.h:39
@ C4FO_OCF
Definition: C4FindObject.h:35
@ C4FO_InRect
Definition: C4FindObject.h:29
@ C4FO_AtRect
Definition: C4FindObject.h:31
@ C4FO_Exclude
Definition: C4FindObject.h:28
@ C4FO_Controller
Definition: C4FindObject.h:43
@ C4FO_Category
Definition: C4FindObject.h:36
@ C4FO_And
Definition: C4FindObject.h:26
@ C4FO_ActionTarget
Definition: C4FindObject.h:38
@ C4FO_ID
Definition: C4FindObject.h:34
@ C4FO_Layer
Definition: C4FindObject.h:45
@ C4FO_InArray
Definition: C4FindObject.h:46
@ C4FO_Property
Definition: C4FindObject.h:47
@ C4FO_Or
Definition: C4FindObject.h:27
@ C4FO_Cone
Definition: C4FindObject.h:49
@ C4FO_Not
Definition: C4FindObject.h:25
@ C4FO_Owner
Definition: C4FindObject.h:42
@ C4FO_Func
Definition: C4FindObject.h:44
@ C4SO_Mass
Definition: C4FindObject.h:62
@ C4SO_Reverse
Definition: C4FindObject.h:57
@ C4SO_Distance
Definition: C4FindObject.h:59
@ C4SO_Random
Definition: C4FindObject.h:60
@ C4SO_Speed
Definition: C4FindObject.h:61
@ C4SO_Value
Definition: C4FindObject.h:63
@ C4SO_Multiple
Definition: C4FindObject.h:58
@ C4SO_Func
Definition: C4FindObject.h:64
C4GameControl Control
C4GameMessageList Messages
const int32_t C4GM_Bottom
Definition: C4GameMessage.h:35
const int32_t C4GM_NoBreak
Definition: C4GameMessage.h:34
const int32_t C4GM_DropSpeech
Definition: C4GameMessage.h:42
const int32_t C4GM_Multiple
Definition: C4GameMessage.h:36
const int32_t C4GM_XRel
Definition: C4GameMessage.h:44
const int32_t C4GM_HCenter
Definition: C4GameMessage.h:40
const int32_t C4GM_VCenter
Definition: C4GameMessage.h:41
const int32_t C4GM_GlobalPlayer
Definition: C4GameMessage.h:30
const int32_t C4GM_Top
Definition: C4GameMessage.h:37
void GameMsgObjectPlayer(const char *szText, C4Object *pTarget, int32_t iPlayer)
const int32_t C4GM_Right
Definition: C4GameMessage.h:39
const int32_t C4GM_TargetPlayer
Definition: C4GameMessage.h:32
const int32_t C4GM_Zoom
Definition: C4GameMessage.h:46
const int32_t C4GM_WidthRel
Definition: C4GameMessage.h:43
const int32_t C4GM_Target
Definition: C4GameMessage.h:31
void GameMsgObject(const char *szText, C4Object *pTarget)
const int32_t C4GM_Left
Definition: C4GameMessage.h:38
const int32_t C4GM_Global
Definition: C4GameMessage.h:29
const int32_t C4GM_YRel
Definition: C4GameMessage.h:45
bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t iDensityMin, int32_t iDensityMax, int32_t &iIter)
Definition: C4Movement.cpp:810
long GetValidOwner(C4PropList *_this, Nillable< long > owner)
C4FindObject * CreateCriterionsFromPars(C4Value *parameters, C4FindObject **pFOs, C4SortObject **pSOs, const C4Object *context)
C4String * GetTextureName(int32_t texture_nr)
void MakeAbsCoordinates(C4PropList *_this, int32_t &x, int32_t &y)
C4ScriptConstDef C4ScriptGameConstMap[]
C4Object * FnPlaceVegetation(C4PropList *_this, C4PropList *Def, long x, long y, long wdt, long hgt, long growth, C4PropList *shape)
C4Object * FnPlaceAnimal(C4PropList *_this, C4PropList *Def)
C4Effect ** FnGetEffectsFor(C4PropList *target)
void AssignController(C4PropList *_this, C4Object *obj)
C4Object * FnObject(C4PropList *_this, long iNumber)
#define F(f)
void InitGameFunctionMap(C4AulScriptEngine *pEngine)
C4Value GetValByStdCompiler(const char *strEntry, const char *strSection, int iEntryNr, const T &rFrom)
C4ScriptFnDef C4ScriptGameFnMap[]
#define PSF_OnHostilityChange
Definition: C4GameScript.h:144
#define PSF_RejectHostilityChange
Definition: C4GameScript.h:130
#define PSF_OnTeamSwitch
Definition: C4GameScript.h:145
#define PSF_RejectTeamSwitch
Definition: C4GameScript.h:131
C4Game Game
Definition: C4Globals.cpp:52
C4AulScriptEngine ScriptEngine
Definition: C4Globals.cpp:43
C4Console Console
Definition: C4Globals.cpp:45
C4Application Application
Definition: C4Globals.cpp:44
C4GameObjects Objects
Definition: C4Globals.cpp:48
C4DefList Definitions
Definition: C4Globals.cpp:49
C4StringTable Strings
Definition: C4Globals.cpp:42
C4GraphicsSystem GraphicsSystem
Definition: C4Globals.cpp:51
C4GraphicsResource GraphicsResource
bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
bool FindConSiteSpot(int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt, int32_t hrange)
C4Landscape Landscape
bool ConstructionCheck(C4PropList *PropList, int32_t iX, int32_t iY, C4Object *pByObj)
bool GBackLiquid(int32_t x, int32_t y)
Definition: C4Landscape.h:239
int32_t PixCol2Tex(BYTE pixc)
Definition: C4Landscape.h:211
bool GBackSemiSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:234
int32_t GBackMat(int32_t x, int32_t y)
Definition: C4Landscape.h:219
bool GBackSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:229
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool Log(const char *szMessage)
Definition: C4Log.cpp:204
bool DebugLogF(const char *strMessage ...)
Definition: C4Log.cpp:290
C4MaterialMap MaterialMap
Definition: C4Material.cpp:974
bool MatValid(int32_t mat)
Definition: C4Material.h:210
C4MessageInput MessageInput
const int32_t C4MC_MD_DragSource
const int32_t C4MC_MD_NoClick
const int32_t C4MC_MD_DropTarget
C4PXSSystem PXS
Definition: C4PXS.cpp:423
C4ParticleSystem Particles
@ C4ATTACH_Front
Definition: C4Particles.h:49
@ C4ATTACH_MoveRelative
Definition: C4Particles.h:51
@ C4ATTACH_Back
Definition: C4Particles.h:50
@ C4PV_Direction
Definition: C4Particles.h:39
@ C4PV_Cos
Definition: C4Particles.h:38
@ C4PV_Linear
Definition: C4Particles.h:34
@ C4PV_Speed
Definition: C4Particles.h:41
@ C4PV_Sin
Definition: C4Particles.h:37
@ C4PV_Random
Definition: C4Particles.h:35
@ C4PV_Gravity
Definition: C4Particles.h:43
@ C4PV_Wind
Definition: C4Particles.h:42
@ C4PV_KeyFrames
Definition: C4Particles.h:36
@ C4PV_Step
Definition: C4Particles.h:40
@ C4PC_Stop
Definition: C4Particles.h:58
@ C4PC_Bounce
Definition: C4Particles.h:57
@ C4PC_Die
Definition: C4Particles.h:56
const int32_t C4PVM_Target
Definition: C4Player.h:32
C4PlayerList Players
int32_t Hostile(int32_t plr1, int32_t plr2)
int32_t ValidPlr(int32_t plr)
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
int fixtoi(const C4Fixed &x)
Definition: C4Real.h:259
C4Real C4REAL100(int x)
Definition: C4Real.h:267
#define C4S_REINIT_SCENARIO
Definition: C4Scenario.h:51
#define C4S_SAVE_OBJECTS
Definition: C4Scenario.h:49
#define C4S_SAVE_LANDSCAPE
Definition: C4Scenario.h:48
#define C4S_KEEP_EFFECTS
Definition: C4Scenario.h:50
C4GameScriptHost GameScript
C4ScriptShader ScriptShader
Definition: C4Shader.cpp:719
void SoundUpdate(C4SoundInstance *pInst, int32_t iLevel, int32_t iPitch)
void StopSoundEffect(const char *szSndName, C4Object *pObj)
C4SoundInstance * GetSoundInstance(const char *szSndName, C4Object *pObj)
C4SoundInstance * StartSoundEffect(const char *szSndName, bool fLoop, int32_t iVolume, C4Object *pObj, int32_t iCustomFalloffDistance, int32_t iPitch, C4SoundModifier *modifier)
@ P_MusicMaxPositionMemory
@ P_MusicBreakChance
@ P_Y
@ P_MusicBreakMin
@ P_Timer
@ P_PlayList
@ P_MusicBreakMax
@ P_Source
@ P_X
const int32_t TEAMID_New
Definition: C4Teams.h:27
C4TextureMap TextureMap
Definition: C4Texture.cpp:576
C4Value C4VObj(C4Object *pObj)
Definition: C4Value.cpp:88
const C4Value C4VNull
Definition: C4Value.cpp:30
C4Value C4VBool(bool b)
Definition: C4Value.h:240
C4Value C4VArray(C4ValueArray *pArray)
Definition: C4Value.h:246
@ C4V_Int
Definition: C4Value.h:26
@ C4V_Object
Definition: C4Value.h:38
@ C4V_Any
Definition: C4Value.h:37
@ C4V_Bool
Definition: C4Value.h:27
@ C4V_Array
Definition: C4Value.h:30
@ C4V_Nil
Definition: C4Value.h:25
@ C4V_String
Definition: C4Value.h:29
C4Value C4VInt(int32_t i)
Definition: C4Value.h:239
C4Value C4VPropList(C4PropList *p)
Definition: C4Value.h:242
C4Value C4VString(C4String *pStr)
Definition: C4Value.h:243
C4ViewportList Viewports
C4Weather Weather
Definition: C4Weather.cpp:206
uint8_t BYTE
bool SIsModule(const char *szList, const char *szString, int *ipIndex, bool fCaseSensitive)
Definition: Standard.cpp:547
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
Definition: Standard.cpp:279
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2)
Definition: Standard.cpp:25
bool SAddModule(char *szList, const char *szModule, bool fCaseSensitive)
Definition: Standard.cpp:563
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:43
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:490
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
#define C4RGB(r, g, b)
Definition: StdColors.h:26
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:396
int iSize
Definition: TstC4NetIO.cpp:32
C4MusicSystem MusicSystem
Definition: C4Application.h:41
void SetGameTickDelay(int iDelay)
C4SoundSystem SoundSystem
Definition: C4Application.h:42
C4PropListStatic * GetPropList()
Definition: C4Aul.h:151
C4Effect * pGlobalEffects
Definition: C4Aul.h:144
void RegisterGlobalConstant(const char *szName, const C4Value &rValue)
Definition: C4Aul.cpp:123
const char * getLocalName() const
Definition: C4Client.h:170
char MissionAccess[CFG_MaxString+1]
Definition: C4Config.h:47
C4ConfigGeneral General
Definition: C4Config.h:255
void EnsureDefinitionListInitialized()
Definition: C4ConsoleGUI.h:115
void DoHalt()
Definition: C4Console.cpp:100
C4EditCursor EditCursor
Definition: C4Console.h:90
bool TogglePause()
Definition: C4Console.cpp:617
Definition: C4Def.h:99
C4ID id
Definition: C4Def.h:101
C4Shape Shape
Definition: C4Def.h:104
StdCopyStrBuf ConsoleGroupPath
Definition: C4Def.h:177
C4Def * GetDef(int32_t Index)
C4Def * ID2Def(C4ID id)
void SetGamma(float r, float g, float b, int32_t iRampIndex)
Definition: C4Draw.cpp:738
C4Object * GetTarget()
C4ValueArray * FindMany(const C4ObjectList &Objs)
C4Object * Find(const C4ObjectList &Objs)
int32_t Count(const C4ObjectList &Objs)
static C4FindObject * CreateByValue(const C4Value &Data, C4SortObject **ppSortObj=nullptr, const C4Object *context=nullptr, bool *has_layer_check=nullptr)
void SetSort(C4SortObject *pToSort)
Definition: C4Real.h:59
void SetBrightness(double brightness)
Definition: C4FoWAmbient.h:55
double GetBrightness() const
Definition: C4FoWAmbient.h:56
C4FoWAmbient Ambient
Definition: C4FoW.h:115
C4GameControlNetwork Network
Definition: C4GameControl.h:67
bool isReplay() const
Definition: C4GameControl.h:98
bool isCtrlHost() const
Definition: C4GameControl.h:99
bool SyncMode() const
bool isNetwork() const
Definition: C4GameControl.h:97
void setTargetFPS(int32_t iToVal)
C4RoundResults & RoundResults
Definition: C4Game.h:73
C4TeamList & Teams
Definition: C4Game.h:70
C4Scenario C4S
Definition: C4Game.h:74
bool LoadScenarioSection(const char *section_name, DWORD flags)
Definition: C4Game.cpp:4309
C4String * GetTranslatedString(const class C4Value &input_string, C4Value *selected_language, bool fail_silently) const
Definition: C4Game.cpp:4810
C4Object * PlaceVegetation(C4PropList *def, int32_t x, int32_t y, int32_t wdt, int32_t hgt, int32_t growth, C4PropList *shape_proplist, C4PropList *out_pos_proplist)
Definition: C4Game.cpp:3323
C4PathFinder PathFinder
Definition: C4Game.h:84
bool ReloadDef(C4ID id)
Definition: C4Game.cpp:2488
std::unique_ptr< C4ScriptGuiWindow > ScriptGuiRoot
Definition: C4Game.h:234
C4Object * PlaceAnimal(C4PropList *def)
Definition: C4Game.cpp:3446
C4Scoreboard Scoreboard
Definition: C4Game.h:94
StdCopyStrBuf NextMissionText
Definition: C4Game.h:147
StdCopyStrBuf NextMissionDesc
Definition: C4Game.h:147
C4ClientList & Clients
Definition: C4Game.h:69
C4PlayerInfoList & PlayerInfos
Definition: C4Game.h:71
int32_t StartupPlayerCount
Definition: C4Game.h:109
int32_t FrameCounter
Definition: C4Game.h:129
C4GameParameters & Parameters
Definition: C4Game.h:67
int32_t StartupTeamCount
Definition: C4Game.h:110
void SetDefaultGamma()
Definition: C4Game.cpp:4780
C4Object * CreateObjectConstruction(C4PropList *type, C4Object *creator, int32_t owner, int32_t center_x=0, int32_t bottom_y=0, int32_t con=1, bool adjust_terrain=false)
Definition: C4Game.cpp:1373
void SetGlobalSoundModifier(C4PropList *modifier_props)
Definition: C4Game.cpp:4793
bool DoGameOver()
Definition: C4Game.cpp:3806
C4PlayerControlDefs PlayerControlDefs
Definition: C4Game.h:92
C4Value GRBroadcast(const char *function, C4AulParSet *pars=nullptr, bool pass_error=false, bool reject_test=false)
Definition: C4Game.cpp:4761
C4Object * CreateObject(C4PropList *type, C4Object *creator, int32_t owner=NO_OWNER, int32_t x=50, int32_t y=50, int32_t r=0, bool grow_from_center=false, C4Real xdir=Fix0, C4Real ydir=Fix0, C4Real rdir=Fix0, int32_t controller=NO_OWNER)
Definition: C4Game.cpp:1334
bool ReloadParticle(const char *name)
Definition: C4Game.cpp:2565
StdCopyStrBuf NextMission
Definition: C4Game.h:147
bool Append(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t bCol, bool fNoDuplicates=false)
bool New(int32_t iType, const StdStrBuf &Text, C4Object *pTarget, int32_t iPlayer, int32_t iX=-1, int32_t iY=-1, uint32_t dwClr=0xffFFFFFF, C4ID idDecoID=C4ID::None, C4PropList *pSrc=nullptr, uint32_t dwFlags=0u, int32_t width=0)
C4LSectors Sectors
Definition: C4GameObjects.h:42
C4Object * SafeObjectPointer(int32_t object_number)
static const int32_t MaxStrength
Definition: C4GamePadCon.h:48
bool isLeague() const
StdCopyStrBuf League
C4Effect * pScenarioEffects
Definition: C4ScriptHost.h:166
C4Value ScenPropList
Definition: C4ScriptHost.h:164
void FlashMessage(const char *message)
Definition: C4Id.h:26
bool SetIDCount(C4ID c_id, int32_t iCount, bool fAddNewID=false)
Definition: stub-handle.cpp:68
C4ID GetID(size_t index, int32_t *ipCount=nullptr) const
Definition: C4IDList.cpp:103
int32_t GetIDCount(C4ID c_id, int32_t iZeroDefVal=0) const
Definition: stub-handle.cpp:67
bool HasFoW() const
C4Real GetGravity() const
bool DrawMap(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, const char *szMapDef, bool ignoreSky=false)
int32_t GetWidth() const
int32_t GetEffectiveMatCount(int material) const
int32_t DigFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, C4Object *by_object=nullptr, bool no_dig2objects=false, bool no_instability_check=false)
BYTE GetPix(int32_t x, int32_t y) const
int32_t ExtractMaterial(int32_t fx, int32_t fy, bool distant_first)
BYTE GetBackPix(int32_t x, int32_t y) const
class C4Sky & GetSky()
bool DrawQuad(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2, int32_t iX3, int32_t iY3, int32_t iX4, int32_t iY4, const char *szMaterial, const char *szBackMaterial, bool fDrawBridge)
void ClearFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt)
void SetGravity(C4Real g)
bool DrawChunks(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, int32_t icntx, int32_t icnty, const char *szMaterial, const char *szTexture, bool bIFT)
int32_t GetBackMat(int32_t x, int32_t y) const
int32_t GetHeight() const
bool InsertMaterial(int32_t mat, int32_t *tx, int32_t *ty, int32_t vx=0, int32_t vy=0, bool query_only=false)
bool SetTextureIndex(const char *szMatTex, BYTE iNewIndex, bool fInsert)
int32_t DigFree(int32_t tx, int32_t ty, int32_t rad, C4Object *by_object=nullptr, bool no_dig2objects=false, bool no_instability_check=false)
void ShakeFree(int32_t tx, int32_t ty, int32_t rad)
DWORD GetModulation() const
class C4FoW * GetFoW()
int32_t GetMatCount(int material) const
bool DrawDefMap(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, const char *szMapDef, bool ignoreSky=false)
void RemoveUnusedTexMapEntries()
bool Incinerate(int32_t x, int32_t y, int32_t cause_player)
void BlastFree(int32_t tx, int32_t ty, int32_t rad, int32_t caused_by=NO_OWNER, C4Object *by_object=nullptr, int32_t iMaxDensity=C4M_Vehicle)
bool SetModulation(DWORD dwWithClr)
char Name[C4M_MaxName+1]
Definition: C4Material.h:89
int32_t MinHeightCount
Definition: C4Material.h:130
int32_t Num
Definition: C4Material.h:168
C4Material * Map
Definition: C4Material.h:169
int32_t Get(const char *szMaterial)
Definition: C4Material.cpp:365
void AbortMsgBoardQuery(C4Object *pObj, int32_t iPlr)
void AddCommand(const char *strCommand, const char *strScript)
bool Play(const char *szSongname=nullptr, bool fLoop=false, int fadetime_ms=0, double max_resume_time=0.0, bool allow_break=false)
void SetMusicBreakChance(int32_t val)
void SetMusicMaxPositionMemory(int32_t val)
void SetMusicBreakMax(int32_t val)
int SetPlayList(const char *szPlayList, bool fForceSwitch=false, int fadetime_ms=0, double max_resume_time=0.0)
int32_t SetGameMusicLevel(int32_t val)
void SetMusicBreakMin(int32_t val)
C4ObjectInfo * Info
Definition: C4Object.h:143
C4Effect * pEffects
Definition: C4Object.h:155
bool CrewDisabled
Definition: C4Object.h:162
int32_t GetX() const
Definition: C4Object.h:285
int32_t Controller
Definition: C4Object.h:109
C4ObjectPtr Layer
Definition: C4Object.h:134
int32_t GetY() const
Definition: C4Object.h:286
class C4ParticleList * BackParticles
Definition: C4Object.h:157
C4Def * Def
Definition: C4Object.h:141
class C4ParticleList * FrontParticles
Definition: C4Object.h:157
int ObjectCount(C4ID id=C4ID::None) const
C4Object * GetObject(int index=0) const
int32_t GetCount() const
Definition: C4PXS.h:56
void Execute()
Definition: C4PXS.cpp:186
C4ParticleDef * GetDef(const char *name, C4ParticleDef *exclude=nullptr)
C4ParticleSystemDefinitionList definitions
Definition: C4Particles.h:510
C4ParticleList * GetGlobalParticles()
Definition: C4Particles.h:496
void Create(C4ParticleDef *of_def, C4ParticleValueProvider &x, C4ParticleValueProvider &y, C4ParticleValueProvider &speedX, C4ParticleValueProvider &speedY, C4ParticleValueProvider &lifetime, C4PropList *properties, int amount=1, C4Object *object=nullptr)
void Set(const C4Value &value)
void SetLevel(int iLevel)
bool Find(int32_t iFromX, int32_t iFromY, int32_t iToX, int32_t iToY, SetWaypointFn fnSetWaypoint)
StdStrBuf GetKeysAsString(bool human_readable, bool short_name) const
C4PlayerControlAssignment * GetAssignmentByControl(int32_t control)
size_t GetCount() const
bool SetControlDisabled(int ctrl, bool is_disabled)
const CSync::ControlDownState * GetControlDownState(int32_t iControl) const
bool IsControlDisabled(int ctrl) const
int32_t CurrentScore
Definition: C4Player.h:116
void SetFoW(bool fEnable)
Definition: C4Player.cpp:723
C4IDList BaseProduction
Definition: C4Player.h:121
int32_t InitialScore
Definition: C4Player.h:116
int32_t ViewMode
Definition: C4Player.h:105
C4IDList BaseMaterial
Definition: C4Player.h:120
bool LocalControl
Definition: C4Player.h:99
C4Player * Next
Definition: C4Player.h:142
int32_t Wealth
Definition: C4Player.h:115
bool GainScenarioAchievement(const char *achievement_id, int32_t value, const char *scen_name_override=nullptr)
Definition: C4Player.cpp:1907
const char * GetName() const
Definition: C4Player.h:151
bool SetWealth(int32_t val)
Definition: C4Player.cpp:741
C4PlayerControl Control
Definition: C4Player.h:129
C4ObjectList Crew
Definition: C4Player.h:125
void SetViewMode(int32_t iMode, C4Object *pTarget=nullptr, bool immediate_position=false)
Definition: C4Player.cpp:767
class C4PlayerControlAssignmentSet * ControlSet
Definition: C4Player.h:90
int32_t Number
Definition: C4Player.h:86
C4Object * GetHiRankActiveCrew()
Definition: C4Player.cpp:886
std::shared_ptr< class C4GamePadOpener > pGamepad
Definition: C4Player.h:132
C4IDList Knowledge
Definition: C4Player.h:127
class C4PlayerInfo * GetInfo()
Definition: C4Player.cpp:1552
bool DoScore(int32_t iChange)
Definition: C4Player.cpp:1342
C4ValueMapData ExtraData
Definition: C4InfoCore.h:93
C4ID GetScriptPlayerExtraID() const
Definition: C4PlayerInfo.h:178
int32_t getLeagueScore() const
Definition: C4PlayerInfo.h:185
@ PIF_NoEliminationCheck
Definition: C4PlayerInfo.h:60
void SetTeam(int32_t idToTeam)
Definition: C4PlayerInfo.h:120
const char * GetLeagueProgressData() const
Definition: C4PlayerInfo.h:192
C4PlayerType GetType() const
Definition: C4PlayerInfo.h:152
bool SetAsScriptPlayer(const char *szName, uint32_t dwColor, uint32_t dwFlags, C4ID idExtra)
void SetLeagueProgressData(const char *szNewProgressData)
Definition: C4PlayerInfo.h:139
bool DoPlayerInfoUpdate(C4ClientPlayerInfos *pUpdate)
C4PlayerInfo * GetPlayerInfoByID(int32_t id) const
C4Player * GetByIndex(int iIndex) const
C4Player * Get(int iPlayer) const
C4Player * First
Definition: C4PlayerList.h:31
bool HostilityDeclared(int iPlayer1, int iPlayer2) const
bool CtrlRemove(int iPlayer, bool fDisonnected)
int GetCount() const
bool IsFrozen() const
Definition: C4PropList.h:135
virtual C4Object * GetObject()
Definition: C4PropList.cpp:636
int32_t Status
Definition: C4PropList.h:173
C4PropList * GetPropertyPropList(C4PropertyName k) const
Definition: C4PropList.cpp:869
C4String * GetPropertyStr(C4PropertyName k) const
Definition: C4PropList.cpp:744
virtual C4Def const * GetDef() const
Definition: C4PropList.cpp:654
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4PropList.h:114
virtual void SetPropertyByS(C4String *k, const C4Value &to)
Definition: C4PropList.cpp:940
static C4PropList * New(C4PropList *prototype=nullptr)
Definition: C4PropList.cpp:40
bool GetProperty(C4PropertyName k, C4Value *pResult) const
Definition: C4PropList.h:105
void SetProperty(C4PropertyName k, const C4Value &to)
Definition: C4PropList.h:124
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
void HideSettlementScore(bool fHide=true)
void AddCustomEvaluationString(const char *szCustomString, int32_t idPlayer)
void SetLeaguePerformance(int32_t iNewPerf, int32_t idPlayer=0)
bool SortBy(int32_t iColKey, bool fReverse)
void DoDlgShow(int32_t iChange, bool fUserToggle)
int32_t GetCellData(int32_t iColKey, int32_t iRowKey)
void SetCell(int32_t iColKey, int32_t iRowKey, const char *szValue, int32_t iValue)
const char * GetCellString(int32_t iColKey, int32_t iRowKey)
bool CreateFromPropList(C4PropList *proplist, bool resetStdTag=false, bool isUpdate=false, bool isLoading=false)
C4ScriptGuiWindow * GetSubWindow(int32_t childID, C4Object *childTarget)
void SetTag(C4String *tag)
int Add(const std::string &shaderName, ShaderType type, const std::string &source)
Definition: C4Shader.cpp:730
bool Remove(int id)
Definition: C4Shader.cpp:742
DWORD GetModulation(bool fBackClr)
Definition: C4Sky.h:43
C4Real y
Definition: C4Sky.h:56
bool SetModulation(DWORD dwWithClr, DWORD dwBackClr)
Definition: C4Sky.cpp:229
int32_t ParX
Definition: C4Sky.h:57
C4Real x
Definition: C4Sky.h:56
int32_t ParallaxMode
Definition: C4Sky.h:59
C4Real xdir
Definition: C4Sky.h:55
void Clear()
Definition: C4Sky.cpp:159
int32_t ParY
Definition: C4Sky.h:57
C4Real ydir
Definition: C4Sky.h:55
virtual void Update()
C4SoundModifier * Get(class C4PropList *props, bool create_if_not_found)
C4SoundModifierList Modifiers
Definition: C4SoundSystem.h:54
StdStrBuf GetData() const
Definition: C4StringTable.h:50
const char * GetCStr() const
Definition: C4StringTable.h:49
C4String * RegString(StdStrBuf String)
Definition: C4Teams.h:31
void AddPlayer(class C4PlayerInfo &rInfo, bool fAdjustPlayer)
Definition: C4Teams.cpp:52
uint32_t GetColor() const
Definition: C4Teams.h:70
int32_t GetID() const
Definition: C4Teams.h:66
void RemovePlayerByID(int32_t iID)
Definition: C4Teams.cpp:94
const char * GetName() const
Definition: C4Teams.h:65
C4Team * GetTeamByIndex(int32_t iIndex) const
Definition: C4Teams.cpp:404
C4Team * GetTeamByPlayerID(int32_t iID) const
Definition: C4Teams.cpp:420
bool IsMultiTeams() const
Definition: C4Teams.h:162
C4Team * GetTeamByID(int32_t iID) const
Definition: C4Teams.cpp:383
@ TEAM_Dist
Definition: C4Teams.h:98
@ TEAM_Active
Definition: C4Teams.h:96
@ TEAM_AllowTeamSwitch
Definition: C4Teams.h:99
@ TEAM_Custom
Definition: C4Teams.h:95
@ TEAM_AllowHostilityChange
Definition: C4Teams.h:97
@ TEAM_TeamColors
Definition: C4Teams.h:101
@ TEAM_AutoGenerateTeams
Definition: C4Teams.h:100
bool IsHostilityChangeAllowed() const
Definition: C4Teams.h:164
bool IsAutoGenerateTeams() const
Definition: C4Teams.h:172
bool IsTeamColors() const
Definition: C4Teams.h:169
TeamDist GetTeamDist() const
Definition: C4Teams.h:211
bool IsJoin2TeamAllowed(int32_t idTeam, C4PlayerType plrType)
Definition: C4Teams.cpp:534
int32_t GetTeamCount() const
Definition: C4Teams.h:158
C4Team * GetGenerateTeamByID(int32_t iID)
Definition: C4Teams.cpp:390
bool IsCustom() const
Definition: C4Teams.h:163
bool IsTeamSwitchAllowed() const
Definition: C4Teams.h:165
Definition: C4Texture.h:49
const char * GetTextureName() const
Definition: C4Texture.h:61
uint32_t GetAverageColor() const
Definition: C4Texture.h:38
const char * GetTexture(int32_t iIndex)
Definition: C4Texture.cpp:494
const C4TexMapEntry * GetEntry(int32_t iIndex) const
Definition: C4Texture.h:85
uint32_t AsInt() const
static C4TimeMilliseconds Now()
void SetSize(int32_t inSize)
void SetItem(int32_t iElemNr, const C4Value &Value)
bool isDeserializer() override
bool isVerbose() override
virtual void ProcessString(std::string &str, bool isID)=0
void Boolean(bool &rBool) override
void DWord(uint32_t &rInt) override
void NameEnd(bool fBreak=false) override
void Word(int16_t &rShort) override
void Begin() override
bool Name(const char *szName) override
void Word(uint16_t &rShort) override
virtual void ProcessChar(char &rChar)=0
void Byte(int8_t &rByte) override
void Byte(uint8_t &rByte) override
void String(char **pszString, RawCompileType eType) override
bool Default(const char *szName) override
void DWord(int32_t &rInt) override
bool hasNaming() override
void String(char *szString, size_t iMaxLength, RawCompileType eType) override
virtual void ProcessBool(bool &rBool)=0
void Character(char &rChar) override
void String(std::string &str, RawCompileType type) override
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
virtual void ProcessString(char **pszString, bool fIsID)=0
C4ValueCompiler(const char **pszNames, int iNameCnt, int iEntryNr)
virtual void ProcessInt(int32_t &rInt)=0
virtual void ProcessString(char *szString, size_t iMaxLength, bool fIsID)=0
C4ValueGetCompiler(const char **pszNames, int iNameCnt, int iEntryNr)
void ProcessChar(char &rChar) override
void ProcessString(char **pszString, bool fIsID) override
void ProcessBool(bool &rBool) override
void ProcessString(char *szString, size_t iMaxLength, bool fIsID) override
void ProcessInt(int32_t &rInt) override
void ProcessString(std::string &str, bool fIsID) override
const C4Value & getResult() const
int32_t getInt() const
Definition: C4Value.h:112
C4String * getStr() const
Definition: C4Value.h:117
C4V_Type GetType() const
Definition: C4Value.h:161
C4PropList * getPropList() const
Definition: C4Value.h:116
void Denumerate(C4ValueNumbers *)
Definition: C4Value.cpp:251
C4ValueMapNames * pNames
Definition: C4ValueMap.h:44
C4ValueMapNames * CreateTempNameList()
Definition: C4ValueMap.cpp:146
int32_t AddName(const char *pnName)
Definition: C4ValueMap.cpp:429
int32_t GetItemNr(const char *strName) const
Definition: C4ValueMap.cpp:459
void Denumerate()
Definition: C4Value.cpp:281
void SetViewOffset(int32_t x, int32_t y)
Definition: C4Viewport.h:94
C4Viewport * GetFirstViewport()
Definition: C4Viewport.h:159
C4Viewport * GetViewport(int32_t player_nr, C4Viewport *prev=nullptr)
int32_t GetTemperature()
Definition: C4Weather.cpp:100
void SetClimate(int32_t iClimate)
Definition: C4Weather.cpp:137
int32_t GetWind(int32_t x, int32_t y)
Definition: C4Weather.cpp:94
int32_t Wind
Definition: C4Weather.h:31
int32_t GetSeason()
Definition: C4Weather.cpp:132
void SetTemperature(int32_t iTemperature)
Definition: C4Weather.cpp:120
void SetWind(int32_t iWind)
Definition: C4Weather.cpp:114
void SetSeason(int32_t iSeason)
Definition: C4Weather.cpp:126
int32_t GetClimate()
Definition: C4Weather.cpp:143
bool IsNil() const
Definition: C4AulDefFunc.h:58
void Decompile(const T &rStruct)
Definition: StdCompiler.h:178
void SetLength(size_t iLength)
Definition: StdBuf.h:509
void Ref(const char *pnData)
Definition: StdBuf.h:455
void Shrink(size_t iShrink)
Definition: StdBuf.h:503
const char * getData() const
Definition: StdBuf.h:442
char * getMData()
Definition: StdBuf.h:443
bool SplitAtChar(char cSplit, StdStrBuf *psSplit)
Definition: StdBuf.h:619
void Copy()
Definition: StdBuf.h:467
void Clear()
Definition: StdBuf.h:466
size_t getLength() const
Definition: StdBuf.h:445
bool GetSection(size_t idx, StdStrBuf *psOutSection, char cSeparator=';') const
Definition: StdBuf.cpp:369
void Take(char *pnData)
Definition: StdBuf.h:457
void Copy(const C4Value *Pars, int ParCount)
Definition: C4AulFunc.h:36
SumPathLength(PathInfo *info)
bool operator()(int32_t iX, int32_t iY, C4Object *TransferTarget)
class C4SoundInstance * StartSoundEffectAt(const char *, int32_t, int32_t, int32_t, int32_t, int32_t, class C4SoundModifier *)
Definition: stub-handle.cpp:41