DayZ 1.28
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
CfgPlayerSpawnHandler.c
См. документацию.
2{
3 private static bool m_Initialized;
4 static ref PlayerSpawnJsonData m_Data = new PlayerSpawnJsonData();
5
6 static bool LoadData()
7 {
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
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 {
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
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 {
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 {
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
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
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
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 {
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
Empty
Определения Hand_States.c:14
string path
Определения OptionSelectorMultistate.c:142
static TStringArray GetPlayerSpawnGearPresetFiles()
Определения CfgGameplayHandler.c:453
Super root of all classes in Enforce script.
Определения EnScript.c:11
static void Log(string message=LOG_DEFAULT, string plugin=LOG_DEFAULT, string author=LOG_DEFAULT, string label=LOG_DEFAULT, string entity=LOG_DEFAULT)
Prints debug message with normal prio.
Определения 3_Game/tools/Debug.c:122
Определения 3_Game/tools/Debug.c:2
static proto native owned string GetSlotName(int id)
converts slot_id to string
provides access to slot configuration
Определения InventorySlots.c:6
override bool SetQuantity(float value, bool destroy_config=true, bool destroy_forced=false, bool allow_client=false, bool clamp_to_stack_max=true)
Определения PileOfWoodenPlanks.c:88
Определения EnMath.c:7
Определения PlayerBaseClient.c:2
static bool IsInitialized()
Определения CfgPlayerSpawnHandler.c:35
static bool SpawnDiscreteSlotItemSet(PlayerBase player, PlayerSpawnPresetDiscreteItemSetSlotData dis, int slotID)
Определения CfgPlayerSpawnHandler.c:173
static void ProcessSlotsEquipment(PlayerBase player, PlayerSpawnPreset data)
iterates over each object and spawns alternatives
Определения CfgPlayerSpawnHandler.c:84
static void ApplyAttributes(ItemBase item, PlayerSpawnAttributesData attributes)
Определения CfgPlayerSpawnHandler.c:316
static ref PlayerSpawnJsonData m_Data
Определения CfgPlayerSpawnHandler.c:4
static PlayerSpawnPreset GetCharacterPresetByName(string presetName)
Определения CfgPlayerSpawnHandler.c:60
static bool SpawnSimpleChildrenItems(EntityAI parent, PlayerSpawnPresetItemSetBase data)
Определения CfgPlayerSpawnHandler.c:234
static bool SpawnDiscreteCargoItemSet(PlayerBase player, PlayerSpawnPresetDiscreteCargoSetData csd)
Определения CfgPlayerSpawnHandler.c:166
static bool SpawnComplexChildrenItems(EntityAI parent, notnull PlayerSpawnPresetItemSetBase data)
could spawn other items recursively. Parent item is guaranteed here.
Определения CfgPlayerSpawnHandler.c:201
static bool SelectAndSpawnSlotEquipment(PlayerBase player, PlayerSpawnPresetSlotData slotData)
selects weighted slot equipment variant
Определения CfgPlayerSpawnHandler.c:99
static bool ProcessEquipmentData(PlayerBase player, PlayerSpawnPreset data)
equips character with the chosen preset
Определения CfgPlayerSpawnHandler.c:72
static bool SelectAndSpawnCargoSet(PlayerBase player, PlayerSpawnPreset data)
Определения CfgPlayerSpawnHandler.c:142
static void ProcessCargoEquipment(PlayerBase player, PlayerSpawnPreset data)
chooses one object from the array
Определения CfgPlayerSpawnHandler.c:131
static bool LoadData()
Определения CfgPlayerSpawnHandler.c:6
static bool m_Initialized
Определения CfgPlayerSpawnHandler.c:3
static void HandleNewItem(notnull ItemBase item, PlayerSpawnPresetItemSetBase data)
Определения CfgPlayerSpawnHandler.c:270
static PlayerSpawnPreset GetRandomCharacterPreset()
Определения CfgPlayerSpawnHandler.c:40
static bool IsWeaponAndMagazineType(EntityAI parent, string type)
Used for exceptions in the system.
Определения CfgPlayerSpawnHandler.c:354
static EntityAI CreateChildItem(EntityAI parent, string type)
Определения CfgPlayerSpawnHandler.c:282
ref array< ref PlayerSpawnPresetDiscreteCargoSetData > discreteUnsortedItemSets
Определения CfgPlayerSpawnDataJson.c:22
ref array< ref PlayerSpawnPresetSlotData > attachmentSlotItemSets
Определения CfgPlayerSpawnDataJson.c:21
int spawnWeight
Определения CfgPlayerSpawnDataJson.c:18
override bool IsValid()
Определения CfgPlayerSpawnDataJson.c:33
bool HasDiscreteUnsortedItemSetsDefined()
preset might be valid even with no unsorted item sets configured, checked separately
Определения CfgPlayerSpawnDataJson.c:54
string name
Определения CfgPlayerSpawnDataJson.c:19
bool HasAttachmentSlotSetsDefined()
preset might be valid even with no attachmentSlotItemSets configured, checked separately
Определения CfgPlayerSpawnDataJson.c:48
used for specific hierarchical child spawning
Определения CfgPlayerSpawnDataJson.c:186
int GetQuickbarIdx()
overriden later
Определения CfgPlayerSpawnDataJson.c:123
bool simpleChildrenUseDefaultAttributes
Определения CfgPlayerSpawnDataJson.c:117
ref array< string > simpleChildrenTypes
Определения CfgPlayerSpawnDataJson.c:120
ref PlayerSpawnAttributesData attributes
Определения CfgPlayerSpawnDataJson.c:118
ref array< ref PlayerSpawnPresetComplexChildrenType > complexChildrenTypes
Определения CfgPlayerSpawnDataJson.c:119
base for any item set
Определения CfgPlayerSpawnDataJson.c:116
shorthand
Определения BoltActionRifle_Base.c:6
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto native CGame GetGame()
enum ShapeType ErrorEx
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
static proto float Lerp(float a, float b, float time)
Linearly interpolates between 'a' and 'b' given 'time'.
static float RandomFloatInclusive(float min, float max)
Returns a random float number between and min [inclusive] and max [inclusive].
Определения EnMath.c:106
static proto float Round(float f)
Returns mathematical round of value.
const string CFG_MAGAZINESPATH
Определения 3_Game/constants.c:222
static const string Empty
Определения EnString.c:7