Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
cfgplayerspawnhandler.c
Go to the documentation of this file.
2 {
3  private static bool m_Initialized;
4  static ref PlayerSpawnJsonData m_Data = new PlayerSpawnJsonData();
5 
6  static bool LoadData()
7  {
8  array<string> spawnGearPresetFiles = CfgGameplayHandler.GetPlayerSpawnGearPresetFiles();
9  if (!spawnGearPresetFiles || (spawnGearPresetFiles && spawnGearPresetFiles.Count() == 0))
10  return false;
11 
12  m_Data.presets = {};
13 
14  foreach (string spawnPresetFile : spawnGearPresetFiles)
15  {
16  PlayerSpawnPreset preset;
17  string path = "$mission:" + spawnPresetFile;
18 
19  string errorMessage;
20  if (!JsonFileLoader<PlayerSpawnPreset>.LoadFile(path, preset, errorMessage))
21  {
22  ErrorEx(errorMessage);
23  return false;
24  }
25 
26  if (preset != null)
27  m_Data.presets.Insert(preset);
28  }
29 
30  m_Initialized = m_Data.presets.Count() > 0;
31 
32  return true;
33  }
34 
35  static bool IsInitialized()
36  {
37  return m_Initialized;
38  }
39 
40  static PlayerSpawnPreset GetRandomCharacterPreset()
41  {
42  array<int> weightedPresetIndexes = new array<int>();
43  int count = m_Data.presets.Count();
45  for (int i = 0; i < count; i++)
46  {
47  p = m_Data.presets[i];
48  if (p.IsValid())
49  {
50  for (int j = 0; j < p.spawnWeight; j++)
51  {
52  weightedPresetIndexes.Insert(i);
53  }
54  }
55  }
56 
57  return m_Data.presets.Get(weightedPresetIndexes.GetRandomElement());
58  }
59 
61  static bool ProcessEquipmentData(PlayerBase player, PlayerSpawnPreset data)
62  {
63  if (data.IsValid())
64  {
65  ProcessSlotsEquipment(player, data);
66  ProcessCargoEquipment(player, data);
67  }
68 
69  return true;
70  }
71 
73  private static void ProcessSlotsEquipment(PlayerBase player, PlayerSpawnPreset data)
74  {
75  if (!data.HasAttachmentSlotSetsDefined())
76  {
77  Debug.Log("No non-empty 'attachmentSlotItemSets' array found. Skipping slot spawns","n/a","n/a","ProcessSlotsEquipment");
78  return;
79  }
80 
81  foreach (PlayerSpawnPresetSlotData slotData : data.attachmentSlotItemSets)
82  {
83  SelectAndSpawnSlotEquipment(player,slotData);
84  }
85  }
86 
88  private static bool SelectAndSpawnSlotEquipment(PlayerBase player, PlayerSpawnPresetSlotData slotData)
89  {
90  int slotID;
91  if (!slotData.TranslateAndValidateSlot(player,slotID))
92  return false;
93 
94  if (!slotData.IsValid())
95  return false;
96 
97  array<int> weightedDiscreteSetIndexes = new array<int>();
98  int count = slotData.discreteItemSets.Count();
100  for (int i = 0; i < count; i++)
101  {
102  dis = slotData.discreteItemSets[i];
103 
104  if (dis.IsValid()) //only when the type exists and spawnWeight is set
105  {
106  for (int j = 0; j < dis.spawnWeight; j++)
107  {
108  weightedDiscreteSetIndexes.Insert(i);
109  }
110  }
111  }
112 
113  dis = null;
114  if (weightedDiscreteSetIndexes.Count() > 0)
115  dis = slotData.discreteItemSets.Get(weightedDiscreteSetIndexes.GetRandomElement());
116  return SpawnDiscreteSlotItemSet(player,dis,slotID);
117  }
118 
120  private static void ProcessCargoEquipment(PlayerBase player, PlayerSpawnPreset data)
121  {
122  if (!data.HasDiscreteUnsortedItemSetsDefined())
123  {
124  Debug.Log("No non-empty 'discreteUnsortedItemSets' array found. Skipping cargo spawns","n/a","n/a","ProcessCargoEquipment");
125  return;
126  }
127 
128  SelectAndSpawnCargoSet(player,data);
129  }
130 
131  private static bool SelectAndSpawnCargoSet(PlayerBase player, PlayerSpawnPreset data)
132  {
133  array<int> weightedDiscreteSetIndexes = new array<int>();
134  int count = data.discreteUnsortedItemSets.Count();
135  PlayerSpawnPresetDiscreteCargoSetData csd;
136  for (int i = 0; i < count; i++)
137  {
138  csd = data.discreteUnsortedItemSets[i];
139 
140  if (csd.IsValid()) //only when the spawnWeight is set
141  {
142  for (int j = 0; j < csd.spawnWeight; j++)
143  {
144  weightedDiscreteSetIndexes.Insert(i);
145  }
146  }
147  }
148 
149  csd = null;
150  if (weightedDiscreteSetIndexes.Count() > 0)
151  csd = data.discreteUnsortedItemSets.Get(weightedDiscreteSetIndexes.GetRandomElement());
152  return SpawnDiscreteCargoItemSet(player,csd);
153  }
154 
155  private static bool SpawnDiscreteCargoItemSet(PlayerBase player, PlayerSpawnPresetDiscreteCargoSetData csd)
156  {
157  SpawnComplexChildrenItems(player,csd);
158  SpawnSimpleChildrenItems(player,csd);
159  return true;
160  }
161 
162  private static bool SpawnDiscreteSlotItemSet(PlayerBase player, PlayerSpawnPresetDiscreteItemSetSlotData dis, int slotID)
163  {
164  if (!dis)
165  {
166  Debug.Log("No PlayerSpawnPresetDiscreteItemSet found. Skipping spawn for slot: " + InventorySlots.GetSlotName(slotID),"n/a","n/a","SpawnDiscreteSlotItemSet");
167  return false;
168  }
169 
170  ItemBase item;
171  if (slotID == InventorySlots.HANDS) //hands exception
172  item = ItemBase.Cast(player.GetHumanInventory().CreateInHands(dis.itemType));
173  else
174  item = ItemBase.Cast(player.GetInventory().CreateAttachmentEx(dis.itemType,slotID));
175 
176  if (item)
177  {
178  HandleNewItem(item,dis);
179  }
180  else if (dis.itemType != string.Empty)
181  {
182  Debug.Log("FAILED spawning item type: " + dis.itemType + " into slot: " + InventorySlots.GetSlotName(slotID) + " of parent: " + player,"n/a","n/a","SpawnDiscreteSlotItemSet");
183  return false;
184  }
185 
186  return item != null;
187  }
188 
190  private static bool SpawnComplexChildrenItems(EntityAI parent, notnull PlayerSpawnPresetItemSetBase data)
191  {
192  if (!data.complexChildrenTypes || data.complexChildrenTypes.Count() < 1) //no children defined, still valid!
193  {
194  return false;
195  }
196 
197  foreach (PlayerSpawnPresetComplexChildrenType cct : data.complexChildrenTypes)
198  {
199  //todo: slotID option over nyah?
200  if (cct.itemType == string.Empty)
201  {
202  Debug.Log("Empty item type found in 'complexChildrenTypes' of parent : " + parent,"n/a","n/a","SpawnSimpleChildrenItems");
203  continue;
204  }
205 
206  ItemBase item;
207  Class.CastTo(item,CreateChildItem(parent,cct.itemType));
208 
209  if (item)
210  {
211  HandleNewItem(item,cct);
212  }
213  else
214  {
215  Debug.Log("FAILED spawning item: " + cct.itemType + " of parent: " + parent,"n/a","n/a","SpawnComplexChildrenItems");
216  }
217  }
218 
219  return true;
220  }
221 
222  private static bool SpawnSimpleChildrenItems(EntityAI parent, PlayerSpawnPresetItemSetBase data)
223  {
224  if (!data || !data.simpleChildrenTypes || data.simpleChildrenTypes.Count() < 1) //no children defined, still valid!
225  {
226  return false;
227  }
228 
229  int count = data.simpleChildrenTypes.Count();
230  string itemType;
231  for (int i = 0; i < count; i++)
232  {
233  itemType = data.simpleChildrenTypes[i];
234  if (itemType == string.Empty)
235  {
236  Debug.Log("Empty item type found at idx: " + i.ToString() + " of 'simpleChildrenTypes' array. Skipping","n/a","n/a","SpawnSimpleChildrenItems");
237  continue;
238  }
239 
240  ItemBase item;
241  Class.CastTo(item,CreateChildItem(parent,itemType));
242 
243  if (item)
244  {
245  if (!data.simpleChildrenUseDefaultAttributes)
246  ApplyAttributes(item,data.attributes);
247  }
248  else
249  {
250  Debug.Log("FAILED spawning item type: " + itemType + " to parent: " + parent,"n/a","n/a","SpawnSimpleChildrenItems");
251  }
252  }
253  return true;
254  }
255 
256  private static void HandleNewItem(notnull ItemBase item, PlayerSpawnPresetItemSetBase data)
257  {
258  ApplyAttributes(item,data.attributes);
259 
260  PlayerBase player;
261  if (Class.CastTo(player,item.GetHierarchyRootPlayer()) && data.GetQuickbarIdx() > -1)
262  player.SetQuickBarEntityShortcut(item,data.GetQuickbarIdx());
263 
264  SpawnComplexChildrenItems(item,data);
265  SpawnSimpleChildrenItems(item,data);
266  }
267 
268  private static EntityAI CreateChildItem(EntityAI parent, string type)
269  {
270  PlayerBase player;
271  ItemBase newItem;
272  if (Class.CastTo(player,parent)) //special behavior
273  {
274  int count = player.GetInventory().AttachmentCount();
275  if (Class.CastTo(newItem,player.GetInventory().CreateInInventory(type)))
276  return newItem;
277 
278  Debug.Log("FAILED spawning item: " + type + ", it fits in no cargo or attachment on any worn item","n/a","n/a","CreateChildItem");
279  return null;
280  }
281 
282  //weapon magazine exception
283  if (GetGame().ConfigIsExisting(CFG_MAGAZINESPATH + " " + type) && parent.IsWeapon())
284  {
285  Weapon_Base wep
286  if (Class.CastTo(wep,parent))
287  return wep.SpawnAttachedMagazine(type);
288  }
289 
290  return parent.GetInventory().CreateInInventory(type);
291  }
292 
293  private static void ApplyAttributes(ItemBase item, PlayerSpawnAttributesData attributes)
294  {
295  if (!attributes)
296  return;
297 
298  float health01 = Math.RandomFloatInclusive(attributes.healthMin,attributes.healthMax);
299  item.SetHealth01("","Health",health01);
300 
301  float quantity01 = Math.RandomFloatInclusive(attributes.quantityMin,attributes.quantityMax);
302  if (item.IsMagazine())
303  {
304  Magazine mag = Magazine.Cast(item);
305  //todo: magazine bullet customization?
306  /*if (attributes.magazineAmmoOrdered && attributes.magazineAmmoOrdered.Count() > 0)
307  {
308  mag.ServerSetAmmoCount(0);
309  foreach (string bulletType : attributes.magazineAmmoOrdered)
310  {
311  mag.ServerStoreCartridge(health01,bulletType);
312  }
313  mag.SetSynchDirty();
314  }
315  else*/
316  {
317  int ammoQuantity = (int)Math.Lerp(0,mag.GetAmmoMax(),quantity01);
318  mag.ServerSetAmmoCount(ammoQuantity);
319  }
320  }
321  else //'varQuantityDestroyOnMin' quantity safeguard
322  {
323  float quantityAbsolute = Math.Lerp(item.GetQuantityMin(),item.GetQuantityMax(),quantity01);
324  quantityAbsolute = Math.Round(quantityAbsolute); //avoids weird floats
325  if (quantityAbsolute <= item.GetQuantityMin() && item.ConfigGetBool("varQuantityDestroyOnMin"))
326  quantityAbsolute++;
327  item.SetQuantity(quantityAbsolute);
328  }
329  }
330 }
ItemBase
Definition: inventoryitem.c:730
GetGame
proto native CGame GetGame()
InventorySlots
provides access to slot configuration
Definition: inventoryslots.c:5
m_Data
string m_Data
Definition: universaltemperaturesource.c:205
PlayerSpawnPresetItemSetBase
base for any item set
Definition: cfgplayerspawndatajson.c:115
ErrorEx
enum ShapeType ErrorEx
PlayerBase
Definition: playerbaseclient.c:1
PlayerSpawnPresetDiscreteItemSetSlotData
one item set for slot
Definition: cfgplayerspawndatajson.c:149
CFG_MAGAZINESPATH
const string CFG_MAGAZINESPATH
Definition: constants.c:211
CfgGameplayHandler
Definition: cfggameplayhandler.c:1
array< string >
Empty
Empty
Definition: hand_states.c:3
int
Param3 int
Debug
Definition: debug.c:13
Weapon_Base
shorthand
Definition: boltactionrifle_base.c:5
m_Initialized
protected bool m_Initialized
Definition: uihintpanel.c:23
PlayerSpawnHandler
Definition: cfgplayerspawnhandler.c:1
Math
Definition: enmath.c:6
Class
Super root of all classes in Enforce script.
Definition: enscript.c:10
PlayerSpawnPresetComplexChildrenType
used for specific hierarchical child spawning
Definition: cfgplayerspawndatajson.c:185
EntityAI
Definition: building.c:5
PlayerSpawnPreset
Definition: cfgplayerspawndatajson.c:16
path
string path
Definition: optionselectormultistate.c:135