DayZ 1.27
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
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 {
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 {
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
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
198 {
199 if (cct.itemType == string.Empty)
200 {
201 Debug.Log("Empty item type found in 'complexChildrenTypes' of parent : " + parent,"n/a","n/a","SpawnSimpleChildrenItems");
202 continue;
203 }
204
205 ItemBase item;
206 Class.CastTo(item,CreateChildItem(parent,cct.itemType));
207
208 if (item)
209 {
210 HandleNewItem(item,cct);
211 }
212 else
213 {
214 Weapon_Base wep;
215 if (!Class.CastTo(wep,parent) || !IsWeaponAndMagazineType(parent,cct.itemType) || !wep.HasInternalMagazine(-1))
216 Debug.Log("FAILED spawning item: " + cct.itemType + " of parent: " + parent,"n/a","n/a","SpawnComplexChildrenItems");
217 }
218 }
219
220 return true;
221 }
222
224 {
225 if (!data || !data.simpleChildrenTypes || data.simpleChildrenTypes.Count() < 1) //no children defined, still valid!
226 {
227 return false;
228 }
229
230 int count = data.simpleChildrenTypes.Count();
231 string itemType;
232 for (int i = 0; i < count; i++)
233 {
234 itemType = data.simpleChildrenTypes[i];
235 if (itemType == string.Empty)
236 {
237 Debug.Log("Empty item type found at idx: " + i.ToString() + " of 'simpleChildrenTypes' array. Skipping","n/a","n/a","SpawnSimpleChildrenItems");
238 continue;
239 }
240
241 ItemBase item;
242 Class.CastTo(item,CreateChildItem(parent,itemType));
243
244 if (item)
245 {
247 ApplyAttributes(item,data.attributes);
248 }
249 else
250 {
251 Weapon_Base wep;
252 if (!Class.CastTo(wep,parent) || !IsWeaponAndMagazineType(parent,itemType) || !wep.HasInternalMagazine(-1))
253 Debug.Log("FAILED spawning item type: " + itemType + " to parent: " + parent,"n/a","n/a","SpawnSimpleChildrenItems");
254 }
255 }
256 return true;
257 }
258
259 private static void HandleNewItem(notnull ItemBase item, PlayerSpawnPresetItemSetBase data)
260 {
261 ApplyAttributes(item,data.attributes);
262
263 PlayerBase player;
264 if (Class.CastTo(player,item.GetHierarchyRootPlayer()) && data.GetQuickbarIdx() > -1)
265 player.SetQuickBarEntityShortcut(item,data.GetQuickbarIdx());
266
267 SpawnComplexChildrenItems(item,data);
268 SpawnSimpleChildrenItems(item,data);
269 }
270
271 private static EntityAI CreateChildItem(EntityAI parent, string type)
272 {
273 PlayerBase player;
274 ItemBase newItem;
275 if (Class.CastTo(player,parent)) //special behavior
276 {
277 if (Class.CastTo(newItem,player.GetInventory().CreateInInventory(type)))
278 return newItem;
279
280 Debug.Log("FAILED spawning item: " + type + ", it fits in no cargo or attachment on any worn item","n/a","n/a","CreateChildItem");
281 return null;
282 }
283
284 //weapon magazine exception
285 if (GetGame().ConfigIsExisting(CFG_MAGAZINESPATH + " " + type) && parent.IsWeapon())
286 {
287 Weapon_Base wep
288 if (Class.CastTo(wep,parent) && wep.SpawnAmmo(type) && !wep.HasInternalMagazine(-1)) //assuming weps with internal magazine don't attach external magazines
289 {
290 Magazine mag;
291 int muzzleCount = wep.GetMuzzleCount();
292 for (int i = 0; i < muzzleCount; i++)
293 {
294 if (Class.CastTo(mag,wep.GetMagazine(i)) && mag.GetType() == type)
295 return mag;
296 }
297 }
298
299 return null;
300 }
301
302 return parent.GetInventory().CreateInInventory(type);
303 }
304
305 private static void ApplyAttributes(ItemBase item, PlayerSpawnAttributesData attributes)
306 {
307 if (!attributes)
308 return;
309
310 float health01 = Math.RandomFloatInclusive(attributes.healthMin,attributes.healthMax);
311 item.SetHealth01("","Health",health01);
312
313 float quantity01 = Math.RandomFloatInclusive(attributes.quantityMin,attributes.quantityMax);
314 if (item.IsMagazine())
315 {
316 Magazine mag = Magazine.Cast(item);
317 /*if (attributes.magazineAmmoOrdered && attributes.magazineAmmoOrdered.Count() > 0)
318 {
319 mag.ServerSetAmmoCount(0);
320 foreach (string bulletType : attributes.magazineAmmoOrdered)
321 {
322 mag.ServerStoreCartridge(health01,bulletType);
323 }
324 mag.SetSynchDirty();
325 }
326 else*/
327 {
328 int ammoQuantity = (int)Math.Lerp(0,mag.GetAmmoMax(),quantity01);
329 mag.ServerSetAmmoCount(ammoQuantity);
330 }
331 }
332 else //'varQuantityDestroyOnMin' quantity safeguard
333 {
334 float quantityAbsolute = Math.Lerp(item.GetQuantityMin(),item.GetQuantityMax(),quantity01);
335 quantityAbsolute = Math.Round(quantityAbsolute); //avoids weird floats
336 if (quantityAbsolute <= item.GetQuantityMin() && item.ConfigGetBool("varQuantityDestroyOnMin"))
337 quantityAbsolute++;
338 item.SetQuantity(quantityAbsolute);
339 }
340 }
341
343 private static bool IsWeaponAndMagazineType(EntityAI parent, string type)
344 {
345 return (GetGame().ConfigIsExisting(CFG_MAGAZINESPATH + " " + type) && parent.IsWeapon());
346 }
347}
Param3 int
Empty
Определения Hand_States.c:14
string path
Определения OptionSelectorMultistate.c:142
static TStringArray GetPlayerSpawnGearPresetFiles()
Определения CfgGameplayHandler.c:443
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.
Определения Debug.c:122
Определения Debug.c:2
Определения Building.c:6
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
Определения InventoryItem.c:731
Определения EnMath.c:7
Определения PlayerBaseClient.c:2
static bool IsInitialized()
Определения CfgPlayerSpawnHandler.c:35
static bool SpawnDiscreteSlotItemSet(PlayerBase player, PlayerSpawnPresetDiscreteItemSetSlotData dis, int slotID)
Определения CfgPlayerSpawnHandler.c:162
static void ProcessSlotsEquipment(PlayerBase player, PlayerSpawnPreset data)
iterates over each object and spawns alternatives
Определения CfgPlayerSpawnHandler.c:73
static void ApplyAttributes(ItemBase item, PlayerSpawnAttributesData attributes)
Определения CfgPlayerSpawnHandler.c:305
static ref PlayerSpawnJsonData m_Data
Определения CfgPlayerSpawnHandler.c:4
static bool SpawnSimpleChildrenItems(EntityAI parent, PlayerSpawnPresetItemSetBase data)
Определения CfgPlayerSpawnHandler.c:223
static bool SpawnDiscreteCargoItemSet(PlayerBase player, PlayerSpawnPresetDiscreteCargoSetData csd)
Определения CfgPlayerSpawnHandler.c:155
static bool SpawnComplexChildrenItems(EntityAI parent, notnull PlayerSpawnPresetItemSetBase data)
could spawn other items recursively. Parent item is guaranteed here.
Определения CfgPlayerSpawnHandler.c:190
static bool SelectAndSpawnSlotEquipment(PlayerBase player, PlayerSpawnPresetSlotData slotData)
selects weighted slot equipment variant
Определения CfgPlayerSpawnHandler.c:88
static bool ProcessEquipmentData(PlayerBase player, PlayerSpawnPreset data)
equips character with the chosen preset
Определения CfgPlayerSpawnHandler.c:61
static bool SelectAndSpawnCargoSet(PlayerBase player, PlayerSpawnPreset data)
Определения CfgPlayerSpawnHandler.c:131
static void ProcessCargoEquipment(PlayerBase player, PlayerSpawnPreset data)
chooses one object from the array
Определения CfgPlayerSpawnHandler.c:120
static bool LoadData()
Определения CfgPlayerSpawnHandler.c:6
static bool m_Initialized
Определения CfgPlayerSpawnHandler.c:3
static void HandleNewItem(notnull ItemBase item, PlayerSpawnPresetItemSetBase data)
Определения CfgPlayerSpawnHandler.c:259
static PlayerSpawnPreset GetRandomCharacterPreset()
Определения CfgPlayerSpawnHandler.c:40
static bool IsWeaponAndMagazineType(EntityAI parent, string type)
Used for exceptions in the system.
Определения CfgPlayerSpawnHandler.c:343
static EntityAI CreateChildItem(EntityAI parent, string type)
Определения CfgPlayerSpawnHandler.c:271
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
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
Определения constants.c:222
static const string Empty
Определения EnString.c:7