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