Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
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
60 static PlayerSpawnPreset GetCharacterPresetByName(string presetName)
61 {
62 foreach (PlayerSpawnPreset preset : m_Data.presets)
63 {
64 if (preset.IsValid() && preset.name == presetName)
65 return preset;
66 }
67
68 return null;
69 }
70
72 static bool ProcessEquipmentData(PlayerBase player, PlayerSpawnPreset data)
73 {
74 if (data.IsValid())
75 {
76 ProcessSlotsEquipment(player, data);
77 ProcessCargoEquipment(player, data);
78 }
79
80 return true;
81 }
82
84 private static void ProcessSlotsEquipment(PlayerBase player, PlayerSpawnPreset data)
85 {
86 if (!data.HasAttachmentSlotSetsDefined())
87 {
88 Debug.Log("No non-empty 'attachmentSlotItemSets' array found. Skipping slot spawns","n/a","n/a","ProcessSlotsEquipment");
89 return;
90 }
91
92 foreach (PlayerSpawnPresetSlotData slotData : data.attachmentSlotItemSets)
93 {
94 SelectAndSpawnSlotEquipment(player,slotData);
95 }
96 }
97
99 private static bool SelectAndSpawnSlotEquipment(PlayerBase player, PlayerSpawnPresetSlotData slotData)
100 {
101 int slotID;
102 if (!slotData.TranslateAndValidateSlot(player,slotID))
103 return false;
104
105 if (!slotData.IsValid())
106 return false;
107
108 array<int> weightedDiscreteSetIndexes = new array<int>();
109 int count = slotData.discreteItemSets.Count();
111 for (int i = 0; i < count; i++)
112 {
113 dis = slotData.discreteItemSets[i];
114
115 if (dis.IsValid()) //only when the type exists and spawnWeight is set
116 {
117 for (int j = 0; j < dis.spawnWeight; j++)
118 {
119 weightedDiscreteSetIndexes.Insert(i);
120 }
121 }
122 }
123
124 dis = null;
125 if (weightedDiscreteSetIndexes.Count() > 0)
126 dis = slotData.discreteItemSets.Get(weightedDiscreteSetIndexes.GetRandomElement());
127 return SpawnDiscreteSlotItemSet(player,dis,slotID);
128 }
129
131 private static void ProcessCargoEquipment(PlayerBase player, PlayerSpawnPreset data)
132 {
133 if (!data.HasDiscreteUnsortedItemSetsDefined())
134 {
135 Debug.Log("No non-empty 'discreteUnsortedItemSets' array found. Skipping cargo spawns","n/a","n/a","ProcessCargoEquipment");
136 return;
137 }
138
139 SelectAndSpawnCargoSet(player,data);
140 }
141
142 private static bool SelectAndSpawnCargoSet(PlayerBase player, PlayerSpawnPreset data)
143 {
144 array<int> weightedDiscreteSetIndexes = new array<int>();
145 int count = data.discreteUnsortedItemSets.Count();
146 PlayerSpawnPresetDiscreteCargoSetData csd;
147 for (int i = 0; i < count; i++)
148 {
149 csd = data.discreteUnsortedItemSets[i];
150
151 if (csd.IsValid()) //only when the spawnWeight is set
152 {
153 for (int j = 0; j < csd.spawnWeight; j++)
154 {
155 weightedDiscreteSetIndexes.Insert(i);
156 }
157 }
158 }
159
160 csd = null;
161 if (weightedDiscreteSetIndexes.Count() > 0)
162 csd = data.discreteUnsortedItemSets.Get(weightedDiscreteSetIndexes.GetRandomElement());
163 return SpawnDiscreteCargoItemSet(player,csd);
164 }
165
166 private static bool SpawnDiscreteCargoItemSet(PlayerBase player, PlayerSpawnPresetDiscreteCargoSetData csd)
167 {
168 SpawnComplexChildrenItems(player,csd);
169 SpawnSimpleChildrenItems(player,csd);
170 return true;
171 }
172
173 private static bool SpawnDiscreteSlotItemSet(PlayerBase player, PlayerSpawnPresetDiscreteItemSetSlotData dis, int slotID)
174 {
175 if (!dis)
176 {
177 Debug.Log("No PlayerSpawnPresetDiscreteItemSet found. Skipping spawn for slot: " + InventorySlots.GetSlotName(slotID),"n/a","n/a","SpawnDiscreteSlotItemSet");
178 return false;
179 }
180
181 ItemBase item;
182 if (slotID == InventorySlots.HANDS) //hands exception
183 item = ItemBase.Cast(player.GetHumanInventory().CreateInHands(dis.itemType));
184 else
185 item = ItemBase.Cast(player.GetInventory().CreateAttachmentEx(dis.itemType,slotID));
186
187 if (item)
188 {
189 HandleNewItem(item,dis);
190 }
191 else if (dis.itemType != string.Empty)
192 {
193 Debug.Log("FAILED spawning item type: " + dis.itemType + " into slot: " + InventorySlots.GetSlotName(slotID) + " of parent: " + player,"n/a","n/a","SpawnDiscreteSlotItemSet");
194 return false;
195 }
196
197 return item != null;
198 }
199
201 private static bool SpawnComplexChildrenItems(EntityAI parent, notnull PlayerSpawnPresetItemSetBase data)
202 {
203 if (!data.complexChildrenTypes || data.complexChildrenTypes.Count() < 1) //no children defined, still valid!
204 {
205 return false;
206 }
207
208 foreach (PlayerSpawnPresetComplexChildrenType cct : data.complexChildrenTypes)
209 {
210 if (cct.itemType == string.Empty)
211 {
212 Debug.Log("Empty item type found in 'complexChildrenTypes' of parent : " + parent,"n/a","n/a","SpawnSimpleChildrenItems");
213 continue;
214 }
215
216 ItemBase item;
217 Class.CastTo(item,CreateChildItem(parent,cct.itemType));
218
219 if (item)
220 {
221 HandleNewItem(item,cct);
222 }
223 else
224 {
225 Weapon_Base wep;
226 if (!Class.CastTo(wep,parent) || !IsWeaponAndMagazineType(parent,cct.itemType) || !wep.HasInternalMagazine(-1))
227 Debug.Log("FAILED spawning item: " + cct.itemType + " of parent: " + parent,"n/a","n/a","SpawnComplexChildrenItems");
228 }
229 }
230
231 return true;
232 }
233
234 private static bool SpawnSimpleChildrenItems(EntityAI parent, PlayerSpawnPresetItemSetBase data)
235 {
236 if (!data || !data.simpleChildrenTypes || data.simpleChildrenTypes.Count() < 1) //no children defined, still valid!
237 {
238 return false;
239 }
240
241 int count = data.simpleChildrenTypes.Count();
242 string itemType;
243 for (int i = 0; i < count; i++)
244 {
245 itemType = data.simpleChildrenTypes[i];
246 if (itemType == string.Empty)
247 {
248 Debug.Log("Empty item type found at idx: " + i.ToString() + " of 'simpleChildrenTypes' array. Skipping","n/a","n/a","SpawnSimpleChildrenItems");
249 continue;
250 }
251
252 ItemBase item;
253 Class.CastTo(item,CreateChildItem(parent,itemType));
254
255 if (item)
256 {
257 if (!data.simpleChildrenUseDefaultAttributes)
258 ApplyAttributes(item,data.attributes);
259 }
260 else
261 {
262 Weapon_Base wep;
263 if (!Class.CastTo(wep,parent) || !IsWeaponAndMagazineType(parent,itemType) || !wep.HasInternalMagazine(-1))
264 Debug.Log("FAILED spawning item type: " + itemType + " to parent: " + parent,"n/a","n/a","SpawnSimpleChildrenItems");
265 }
266 }
267 return true;
268 }
269
270 private static void HandleNewItem(notnull ItemBase item, PlayerSpawnPresetItemSetBase data)
271 {
272 ApplyAttributes(item,data.attributes);
273
274 PlayerBase player;
275 if (Class.CastTo(player,item.GetHierarchyRootPlayer()) && data.GetQuickbarIdx() > -1)
276 player.SetQuickBarEntityShortcut(item,data.GetQuickbarIdx());
277
278 SpawnComplexChildrenItems(item,data);
279 SpawnSimpleChildrenItems(item,data);
280 }
281
282 private static EntityAI CreateChildItem(EntityAI parent, string type)
283 {
284 PlayerBase player;
285 ItemBase newItem;
286 if (Class.CastTo(player,parent)) //special behavior
287 {
288 if (Class.CastTo(newItem,player.GetInventory().CreateInInventory(type)))
289 return newItem;
290
291 Debug.Log("FAILED spawning item: " + type + ", it fits in no cargo or attachment on any worn item","n/a","n/a","CreateChildItem");
292 return null;
293 }
294
295 //weapon magazine exception
296 if (GetGame().ConfigIsExisting(CFG_MAGAZINESPATH + " " + type) && parent.IsWeapon())
297 {
298 Weapon_Base wep
299 if (Class.CastTo(wep,parent) && wep.SpawnAmmo(type) && !wep.HasInternalMagazine(-1)) //assuming weps with internal magazine don't attach external magazines
300 {
301 Magazine mag;
302 int muzzleCount = wep.GetMuzzleCount();
303 for (int i = 0; i < muzzleCount; i++)
304 {
305 if (Class.CastTo(mag,wep.GetMagazine(i)) && mag.GetType() == type)
306 return mag;
307 }
308 }
309
310 return null;
311 }
312
313 return parent.GetInventory().CreateInInventory(type);
314 }
315
316 private static void ApplyAttributes(ItemBase item, PlayerSpawnAttributesData attributes)
317 {
318 if (!attributes)
319 return;
320
321 float health01 = Math.RandomFloatInclusive(attributes.healthMin,attributes.healthMax);
322 item.SetHealth01("","Health",health01);
323
324 float quantity01 = Math.RandomFloatInclusive(attributes.quantityMin,attributes.quantityMax);
325 if (item.IsMagazine())
326 {
327 Magazine mag = Magazine.Cast(item);
328 /*if (attributes.magazineAmmoOrdered && attributes.magazineAmmoOrdered.Count() > 0)
329 {
330 mag.ServerSetAmmoCount(0);
331 foreach (string bulletType : attributes.magazineAmmoOrdered)
332 {
333 mag.ServerStoreCartridge(health01,bulletType);
334 }
335 mag.SetSynchDirty();
336 }
337 else*/
338 {
339 int ammoQuantity = (int)Math.Lerp(0,mag.GetAmmoMax(),quantity01);
340 mag.ServerSetAmmoCount(ammoQuantity);
341 }
342 }
343 else //'varQuantityDestroyOnMin' quantity safeguard
344 {
345 float quantityAbsolute = Math.Lerp(item.GetQuantityMin(),item.GetQuantityMax(),quantity01);
346 quantityAbsolute = Math.Round(quantityAbsolute); //avoids weird floats
347 if (quantityAbsolute <= item.GetQuantityMin() && item.ConfigGetBool("varQuantityDestroyOnMin"))
348 quantityAbsolute++;
349 item.SetQuantity(quantityAbsolute);
350 }
351 }
352
354 private static bool IsWeaponAndMagazineType(EntityAI parent, string type)
355 {
356 return (GetGame().ConfigIsExisting(CFG_MAGAZINESPATH + " " + type) && parent.IsWeapon());
357 }
358}
Param3 int
bool m_Initialized
Super root of all classes in Enforce script.
Definition enscript.c:11
Definition debug.c:2
provides access to slot configuration
Definition enmath.c:7
used for specific hierarchical child spawning
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto native CGame GetGame()
enum ShapeType ErrorEx
const string CFG_MAGAZINESPATH
Definition constants.c:222
Empty
Definition hand_states.c:14