Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
miscgameplayfunctions.c
Go to the documentation of this file.
2{
3 bool m_TransferAgents;
4 bool m_TransferVariables;
5 bool m_TransferHealth;
6 bool m_ExcludeQuantity;
7 float m_quantity_override;
8
9 void TurnItemIntoItemLambda (EntityAI old_item, string new_item_type, PlayerBase player)
10 {
11 SetTransferParams();
12 }
13
14 void SetTransferParams (bool transfer_agents = true, bool transfer_variables = true, bool transfer_health = true, bool exclude_quantity = false, float quantity_override = -1)
15 {
16 m_TransferAgents = transfer_agents;
17 m_TransferVariables = transfer_variables;
18 m_TransferHealth = transfer_health;
19 m_ExcludeQuantity = exclude_quantity;
20 m_quantity_override = quantity_override;
21 }
22
23 override void CopyOldPropertiesToNew (notnull EntityAI old_item, EntityAI new_item)
24 {
25 super.CopyOldPropertiesToNew(old_item, new_item);
26
27 if (new_item)
28 {
29 MiscGameplayFunctions.TransferItemProperties(old_item, new_item, m_TransferAgents, m_TransferVariables, m_TransferHealth, m_ExcludeQuantity);
30 MiscGameplayFunctions.TransferInventory(old_item, new_item, m_Player);
31
32 //quantity override
33 if (ItemBase.Cast(new_item) && m_quantity_override != -1)
34 {
35 m_quantity_override = Math.Max(m_quantity_override,0);
36 ItemBase.Cast(new_item).SetQuantity(m_quantity_override);
37 }
38 }
39 else
40 {
41 Debug.LogError("TurnItemIntoItemLambda: failed to create new item","static");
42 }
43 }
44
46 override void VerifyItemTypeBySlotType ()
47 {
48 if (m_NewLocation.GetType() == InventoryLocationType.ATTACHMENT && m_OldItem.ConfigIsExisting("ChangeIntoOnAttach"))
49 {
50 string str;
51 int idx = -1;
52 TStringArray inventory_slots = new TStringArray;
53 TIntArray inventory_slots_idx = new TIntArray;
54 TStringArray attach_types = new TStringArray;
55
56 m_OldItem.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
57 if (inventory_slots.Count() < 1) //is string
58 {
59 inventory_slots_idx.Insert(InventorySlots.GetSlotIdFromString(m_OldItem.ConfigGetString("ChangeInventorySlot")));
60 attach_types.Insert(m_OldItem.ConfigGetString("ChangeIntoOnAttach"));
61 }
62 else //is array
63 {
64 inventory_slots_idx.Clear();
65 for (int i = 0; i < inventory_slots.Count(); ++i)
66 {
67 inventory_slots_idx.Insert(InventorySlots.GetSlotIdFromString(inventory_slots.Get(i)));
68 }
69 m_OldItem.ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
70 }
71
72 idx = m_NewLocation.GetSlot();
73 str = attach_types.Get(inventory_slots_idx.Find(idx));
74 if (str != "")
75 {
76 m_NewItemType = str;
77 }
78 }
79 }
80
81 override void OnSuccess (EntityAI new_item)
82 {
83 super.OnSuccess(new_item);
84 if( m_Player )
85 {
86 m_Player.GetItemAccessor().OnItemInHandsChanged();
87 }
88 }
89};
90
91class TurnItemIntoItemLambdaAnimSysNotifyLambda extends TurnItemIntoItemLambda
92{
93 override void OnSuccess (EntityAI new_item)
94 {
95 super.OnSuccess(new_item);
96 if( m_Player )
97 {
98 m_Player.GetItemAccessor().OnItemInHandsChanged();
99 }
100 }
101}
102
103class TurnItemIntoItemLambdaRestrainLambda extends TurnItemIntoItemLambdaAnimSysNotifyLambda
104{
105 override void OnSuccess (EntityAI new_item)
106 {
107 super.OnSuccess(new_item);
108 m_Player.SetRestrained(true);
109 }
110}
111
116{
117 PlayerBase m_Player;
118
119 void DropEquipAndDestroyRootLambda (EntityAI old_item, string new_item_type, PlayerBase player)
120 {
121 m_Player = player;
122 }
123
124 override void CopyOldPropertiesToNew (notnull EntityAI old_item, EntityAI new_item)
125 {
126 super.CopyOldPropertiesToNew(old_item, new_item);
127
128 InventoryLocation understash_src = m_NewLocation; // m_NewLocation is a backup of original old_item's src before the operation started
129
130 array<EntityAI> children = new array<EntityAI>;
131 old_item.GetInventory().EnumerateInventory(InventoryTraversalType.LEVELORDER, children);
132 int count = children.Count();
133 for (int i = 0; i < count; ++i)
134 {
135 EntityAI child = children.Get(i);
136 if (child)
137 {
138 InventoryLocation child_src = new InventoryLocation;
139 child.GetInventory().GetCurrentInventoryLocation(child_src);
140
141 InventoryLocation child_dst = new InventoryLocation;
142 //@TODO: modify _dst with place on gnd?
143
144 vector m4[4];
145 Math3D.MatrixIdentity4(m4);
146
148 GameInventory.PrepareDropEntityPos(old_item, child, m4, false, -1);
149
150 child_dst.SetGround(child,m4);
151
152 m_Player.LocalTakeToDst(child_src, child_dst);
153
154 GetGame().RemoteObjectTreeCreate(child); // this forces server to send CreateVehicle Message to client. This is needed for preserving the appearance of network operations on client (so that DeleteObject(old) arrives before CreateVehicle(new)). @NOTE: this does not delete the object on server, only it's network representation.
155 }
156 }
157 }
158}
159
164{
167
168 void MoveEquipToExistingItemAndDestroyOldRootLambda (EntityAI old_item, string new_item_type, PlayerBase player, EntityAI new_item)
169 {
170 m_Player = player;
171 m_NewItem = new_item;
172 if (new_item_type != string.Empty)
173 Error("MoveEquipAndDestroyRootLambda expects new_item_type to be empty");
174 }
175
176 override protected void RemoveNetworkObjectInfo ()
177 {
178 super.RemoveNetworkObjectInfo();
179 GetGame().RemoteObjectTreeDelete(m_NewItem);
180 }
181 override protected void UndoRemoveNetworkObjectInfo ()
182 {
183 super.UndoRemoveNetworkObjectInfo();
184 GetGame().RemoteObjectTreeCreate(m_NewItem);
185 }
186
187 override void CopyOldPropertiesToNew (notnull EntityAI old_item, EntityAI new_item)
188 {
189 // @NOTE: new_item is NULL, this lambda does not create new entity
190 super.CopyOldPropertiesToNew(old_item, new_item);
191
192 MiscGameplayFunctions.TransferInventory(old_item, m_NewItem, m_Player);
193 }
194
195 override protected void CreateNetworkObjectInfo (EntityAI new_item)
196 {
197 super.CreateNetworkObjectInfo(new_item);
198 GetGame().RemoteObjectTreeCreate(m_NewItem);
199 }
200};
201
206
208{
209 NONE = 0,
210 SPLIT = 1, //< Splits the item when it has quantity, recommended to use when called on an attachment
211}
212
213class MiscGameplayFunctions
214{
216 static float Truncate(float value, int decimals = 2)
218 int multiplier = Math.Pow(10,decimals);
219 return Math.Clamp(Math.Floor(value * multiplier),float.LOWEST, float.MAX) / multiplier;
220 }
222 static string TruncateToS(float value, int decimals = 2)
223 {
224 return Truncate(value, decimals).ToString();
225 }
227 static vector TruncateVec(vector value, int decimals = 2)
228 {
229 int multiplier = Math.Pow(10,decimals);
230 float v1 = Math.Clamp(Math.Floor(value[0] * multiplier),float.LOWEST, float.MAX) / multiplier;
231 float v2 = Math.Clamp(Math.Floor(value[1] * multiplier),float.LOWEST, float.MAX) / multiplier;
232 float v3 = Math.Clamp(Math.Floor(value[2] * multiplier),float.LOWEST, float.MAX) / multiplier;
233 return Vector(v1,v2,v3);
234 }
235
236 static string TruncateVecToS(vector value,int decimals = 2, string delimiter = " ")
237 {
238 return MiscGameplayFunctions.TruncateToS(value[0],decimals) + delimiter + MiscGameplayFunctions.TruncateToS(value[1],decimals) +delimiter + MiscGameplayFunctions.TruncateToS(value[2],decimals);
239 }
240
241 static string GetColorString(float r, float g, float b, float a)
242 {
243 return string.Format("#(argb,8,8,3)color(%1,CO)", string.Format("%1,%2,%3,%4", r, g, b, a));
244 }
245
247 static string ValueToBar(float value, string bar = "[----------]", string mark = "x")
248 {
249 int length = bar.Length() - 2;
250 float index = Math.Lerp(0,length, value);
251 index = Math.Round(index);
252 index = Math.Clamp(index,0,length);
253
254 return InsertAtPos(bar,mark,index);
255 }
256
258 static string InsertAtPos(string base, string insert, int pos)
259 {
260 int length_first = pos+1;
261 int length_base = base.Length();
262 int length_second = length_base - length_first;
263 string first = base.Substring(0,length_first);
264 string second = base.Substring(pos+1,length_second);
265 return first + insert + second;
266 }
267
269 static void TransferItemProperties(EntityAI source, notnull EntityAI target, bool transfer_agents = true, bool transfer_variables = true, bool transfer_health = true, bool exclude_quantity = false)
270 {
271 ItemBase target_ib = ItemBase.Cast(target);
272
273 if (transfer_agents && target_ib)
274 target_ib.TransferAgents(source.GetAgents());
275
276 if (transfer_variables)
277 MiscGameplayFunctions.TransferEntityVariables(source, target, exclude_quantity);
278
279 if (GetGame().IsServer() || !GetGame().IsMultiplayer())
280 {
281 if (transfer_health)
282 {
283 TransferEntityHealth(source,target,{"Health"});
284 }
285 }
286 }
287
288 static void TransferEntityVariables(EntityAI source, EntityAI target, bool exclude_quantity = false)
289 {
290 if (exclude_quantity)
291 {
292 int maskOriginal = source.m_VariablesMask;
293 source.RemoveItemVariable(VARIABLE_QUANTITY);
294 target.TransferVariablesFloat(source.GetVariablesFloat());
295 source.m_VariablesMask = maskOriginal;
296 }
297 else
298 {
299 target.TransferVariablesFloat(source.GetVariablesFloat());
300 }
301
302 if (source.IsMagazine() && target.IsMagazine())
303 {
304 Magazine source_mag = Magazine.Cast(source);
305 Magazine target_mag = Magazine.Cast(target);
306
307 target_mag.ServerSetAmmoCount(source_mag.GetAmmoCount());
308 }
309
310 if (source.IsWeapon() && target.IsWeapon())
311 {
312 Weapon_Base source_wpn = Weapon_Base.Cast(source);
313 Weapon_Base target_wpn = Weapon_Base.Cast(target);
314
315 target_wpn.CopyWeaponStateFrom(source_wpn);
316 }
317
318 if (source.HasEnergyManager() && target.HasEnergyManager())
319 {
320 ComponentEnergyManager ems = source.GetCompEM();
321 ComponentEnergyManager emt = target.GetCompEM();
322
323 emt.SetEnergy(ems.GetEnergy());
324
325 if (ems.IsSwitchedOn())
326 emt.SwitchOn();
327 }
328
329 Edible_Base source_edb = Edible_Base.Cast(source);
330 Edible_Base target_edb = Edible_Base.Cast(target);
331 if (Class.CastTo(source_edb,source) && Class.CastTo(target_edb,target))
332 {
333 if (source_edb.CanDecay() && target_edb.CanDecay())
334 target_edb.TransferFoodStage(source_edb);
335 }
336 }
337
339 static void TransferItemVariables(ItemBase source, ItemBase target, bool exclude_quantity = false)
340 {
341 TransferEntityVariables(source,target,exclude_quantity);
342 }
343
344 static TransferInventoryResult TransferInventory( EntityAI sourceItem, EntityAI targetItem, PlayerBase player)
345 {
347
348 array<EntityAI> children = new array<EntityAI>;
349 sourceItem.GetInventory().EnumerateInventory(InventoryTraversalType.LEVELORDER, children);
350 int count = children.Count();
351 for (int i = 0; i < count; ++i)
352 {
353 EntityAI child = children.Get(i);
354 if (child)
355 {
356 InventoryLocation child_src = new InventoryLocation;
357 child.GetInventory().GetCurrentInventoryLocation( child_src );
358
359 InventoryLocation child_dst = new InventoryLocation;
360 child_dst.Copy( child_src );
361 child_dst.SetParent( targetItem );
362
363 bool drop = false;
364
365 if (GameInventory.LocationCanAddEntity(child_dst))
366 {
367 // try to move it to the same exact place in dst
368 targetItem.GetInventory().TakeToDst(InventoryMode.LOCAL, child_src, child_dst);
369 }
370 else
371 {
372 drop = true; // or drop otherwise
373 }
374
375 if (drop)
376 {
377 player.LocalDropEntity(child);
378 GetGame().RemoteObjectTreeCreate(child);
379 result = TransferInventoryResult.DroppedSome;
380 }
381 }
382 }
383 return result;
384 }
385
386 static void TransferEntityHealth(EntityAI source, EntityAI target, array<string> healthTypes = null, bool transferZoneDamage = true)
387 {
388 array<string> HPTypes = new array<string>;
389 if (!healthTypes || healthTypes.Count() == 0)
390 HPTypes.Insert("Health");
391 else
392 HPTypes.Copy(healthTypes);
393
394 if (transferZoneDamage)
395 {
396 TStringArray zonesSrc = new TStringArray;
397 TStringArray zonesTgt = new TStringArray;
398 source.GetDamageZones(zonesSrc);
399 target.GetDamageZones(zonesTgt);
400
401 foreach (string zone : zonesSrc)
402 {
403 if (zonesTgt.Find(zone) == -1)
404 continue;
405
406 foreach (string health : HPTypes)
407 {
408 target.SetHealth01(zone,health,source.GetHealth01(zone,health));
409 }
410 }
411 }
412
413 foreach (string gHealth : HPTypes)
414 {
415 target.SetHealth01("",gHealth,source.GetHealth01("",gHealth)); //global health last
416 }
417 }
418
419 static void UnlimitedAmmoDebugCheck(Weapon_Base weapon)
420 {
421 if ( ItemBase.GetDebugActionsMask() & DebugActionType.UNLIMITED_AMMO )
422 {
423 Magazine magazine;
424 if ( GetGame().IsServer() )
425 {
426 magazine = weapon.GetMagazine(weapon.GetCurrentMuzzle());
427
428 if (magazine)
429 {
430 if (magazine.GetAmmoCount() <= 5)
431 {
432 magazine.ServerSetAmmoMax();
433 }
434 }
435 }
436 else
437 {
438 magazine = weapon.GetMagazine(weapon.GetCurrentMuzzle());
439
440 if (magazine)
441 {
442 if (magazine.GetAmmoCount() <= 5)
443 {
444 magazine.LocalSetAmmoMax();
445 }
446 }
447
448 }
449 }
450 }
451
452
453
454 static void TurnItemIntoItem (notnull ItemBase old_item, string new_item_type, notnull PlayerBase player)
455 {
456 TurnItemIntoItemEx(player, new TurnItemIntoItemLambda(old_item, new_item_type, player));
457 }
458
459 static void TurnItemIntoItemEx (notnull PlayerBase player, ReplaceItemWithNewLambdaBase lambda)
460 {
461 player.ServerReplaceItemWithNew(lambda);
462 }
463
464 static void TurnItemInHandsIntoItem (notnull ItemBase old_item, string new_item_type, notnull PlayerBase player)
465 {
466 TurnItemInHandsIntoItemEx(player, new TurnItemIntoItemLambda(old_item, new_item_type, player));
467 }
468
469 static void TurnItemInHandsIntoItemEx (notnull PlayerBase player, ReplaceItemWithNewLambdaBase lambda)
470 {
471 player.ServerReplaceItemInHandsWithNew(lambda);
472 }
473
475 static array<ItemBase> CreateItemBasePiles(string item_name, vector ground_position, float quantity, float health, bool floaty_spawn = false)
476 {
477 array<ItemBase> item_piles;
478 float max_stack_size;
479 ItemBase pile;
480
481 item_piles = new array<ItemBase>;
482 max_stack_size = g_Game.ConfigGetInt("cfgVehicles " + item_name + " varStackMax");
483 if( max_stack_size < 1)
484 max_stack_size = g_Game.ConfigGetInt("cfgVehicles " + item_name + " varQuantityMax");
485 if( max_stack_size < 1)
486 max_stack_size = 1;
487
488 int full_piles_count = Math.Floor(quantity/max_stack_size);
489 int rest = quantity - (full_piles_count*max_stack_size);
490
491 for (int i = 0; i < full_piles_count; ++i)
492 {
493 if (floaty_spawn)
494 pile = ItemBase.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_CREATEPHYSICS|ECE_UPDATEPATHGRAPH));
495 else
496 pile = ItemBase.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_PLACE_ON_SURFACE));
497 pile.SetQuantity(max_stack_size);
498 pile.SetHealth(health);
499 item_piles.Insert(pile);
500 }
501
502 if (rest > 0)
503 {
504 if (floaty_spawn)
505 pile = ItemBase.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_CREATEPHYSICS|ECE_UPDATEPATHGRAPH));
506 else
507 pile = ItemBase.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_PLACE_ON_SURFACE));
508 pile.SetQuantity(rest);
509 pile.SetHealth(health);
510 item_piles.Insert(pile);
511 }
512 return item_piles;
513 }
514
516 static array<ItemBase> CreateItemBasePilesDispersed(string item_name, vector starPos, vector targetPos, float radius, float quantity, float health, Object ignoreObjectCollison)
517 {
518 array<ItemBase> item_piles;
519 float max_stack_size;
520 ItemBase pile;
521
522 item_piles = new array<ItemBase>;
523 max_stack_size = g_Game.ConfigGetInt("cfgVehicles " + item_name + " varStackMax");
524 if( max_stack_size < 1)
525 max_stack_size = g_Game.ConfigGetInt("cfgVehicles " + item_name + " varQuantityMax");
526 if( max_stack_size < 1)
527 max_stack_size = 1;
528
529 int full_piles_count = Math.Floor(quantity/max_stack_size);
530 int rest = quantity - (full_piles_count*max_stack_size);
531 vector randomizedPos;
532
533 for (int i = 0; i < full_piles_count; ++i)
534 {
535 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
536 pile = ItemBase.Cast(GetGame().CreateObjectEx(item_name, randomizedPos, ECE_PLACE_ON_SURFACE));
537 pile.SetQuantity(max_stack_size);
538 pile.SetHealth(health);
539 item_piles.Insert(pile);
540 }
541
542 if (rest > 0)
543 {
544 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
545 pile = ItemBase.Cast(GetGame().CreateObjectEx(item_name, randomizedPos, ECE_PLACE_ON_SURFACE));
546 pile.SetQuantity(rest);
547 pile.SetHealth(health);
548 item_piles.Insert(pile);
549 }
550 return item_piles;
551 }
552
553 static array<Magazine> CreateMagazinePiles(string item_name, vector ground_position, float quantity, float health )
554 {
555 array<Magazine> items;
556 float stack_size;
557 Magazine pile;
558
559 items = new array<Magazine>;
560 stack_size = g_Game.ConfigGetInt("cfgMagazines " + item_name + " count");
561
562 int piles_count = Math.Floor(quantity/stack_size);
563 int rest = quantity - (piles_count*stack_size);
564
565 for (int i = 0; i < piles_count; ++i)
566 {
567 pile = Magazine.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_PLACE_ON_SURFACE));
568 pile.ServerSetAmmoCount(stack_size);
569 items.Insert(pile);
570 }
571 if (rest > 0)
572 {
573 pile = Magazine.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_PLACE_ON_SURFACE));
574 pile.ServerSetAmmoCount(rest);
575 items.Insert(pile);
576 }
577 return items;
578 }
579
581 static array<Magazine> CreateMagazinePilesDispersed(string item_name, vector starPos, vector targetPos, float radius, float quantity, float health, Object ignoreObjectCollison)
582 {
583 array<Magazine> items;
584 float stack_size;
585 Magazine pile;
586
587 items = new array<Magazine>;
588 stack_size = g_Game.ConfigGetInt("cfgMagazines " + item_name + " count");
589
590 int piles_count = Math.Floor(quantity/stack_size);
591 int rest = quantity - (piles_count*stack_size);
592 vector randomizedPos;
593
594 for (int i = 0; i < piles_count; ++i)
595 {
596 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
597 pile = Magazine.Cast(GetGame().CreateObjectEx(item_name, randomizedPos, ECE_CREATEPHYSICS|ECE_UPDATEPATHGRAPH));
598 pile.ServerSetAmmoCount(stack_size);
599 items.Insert(pile);
600 }
601
602 if (rest > 0)
603 {
604 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
605 pile = Magazine.Cast(GetGame().CreateObjectEx(item_name, randomizedPos, ECE_CREATEPHYSICS|ECE_UPDATEPATHGRAPH));
606 pile.ServerSetAmmoCount(rest);
607 items.Insert(pile);
608 }
609 return items;
610 }
611
612 static array<Magazine> CreateMagazinePilesFromBullet(string bullet_type, vector ground_position, float quantity, float health )
613 {
614 array<Magazine> items;
615 items = new array<Magazine>;
616 float stack_size;
617 Magazine pile;
618 string item_name;
619 if (!g_Game.ConfigGetText("cfgAmmo " + bullet_type + " spawnPileType", item_name))
620 return items;
621
622 stack_size = g_Game.ConfigGetInt("cfgMagazines " + item_name + " count");
623
624 if (stack_size > 0)
625 {
626 int piles_count = Math.Floor(quantity/stack_size);
627 int rest = quantity - (piles_count*stack_size);
628
629 for (int i = 0; i < piles_count; ++i)
630 {
631 pile = Magazine.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_PLACE_ON_SURFACE));
632 pile.ServerSetAmmoCount(stack_size);
633 items.Insert(pile);
634 }
635
636 if (rest > 0)
637 {
638 pile = Magazine.Cast(GetGame().CreateObjectEx(item_name, ground_position, ECE_PLACE_ON_SURFACE));
639 pile.ServerSetAmmoCount(rest);
640 items.Insert(pile);
641 }
642 }
643 return items;
644 }
645
646 //CreateMagazinePilesDispersed(string item_name, vector starPos, vector targetPos, float radius, float quantity, float health, Object ignoreObjectCollison)
647 static array<Magazine> CreateMagazinePilesFromBulletDispersed(string bullet_type, vector starPos, vector targetPos, float radius, float quantity, float health, Object ignoreObjectCollison)
648 {
650 Magazine pile;
651 string item_name;
652 if (!g_Game.ConfigGetText("cfgAmmo " + bullet_type + " spawnPileType", item_name))
653 return items;
654
655 items = CreateMagazinePilesDispersed(item_name,starPos,targetPos,radius,quantity,health,ignoreObjectCollison);
656 return items;
657 }
658
659 static int GetHealthLevelForAmmo(string class_name, float health)
660 {
661 float health_normalized = health / 100;
662 string config_path = CFG_WEAPONSPATH + " " + class_name + " DamageSystem" + " GlobalHealth" + " healthLabels";
663 CachedObjectsArrays.ARRAY_FLOAT.Clear();
664 GetGame().ConfigGetFloatArray(config_path, CachedObjectsArrays.ARRAY_FLOAT);
665 for(int i = 0; i < CachedObjectsArrays.ARRAY_FLOAT.Count(); ++i)
666 {
667 if( health_normalized >= CachedObjectsArrays.ARRAY_FLOAT.Get(i) )
668 {
669 return i;
670 }
671 }
672 return -1;
673 }
674
675 static float GetTypeMaxGlobalHealth(string class_name, string health_type = "Health")
676 {
677 float max_health;
678 string cfg_path;
679
680 if ( GetGame().ConfigIsExisting(CFG_VEHICLESPATH+" "+class_name) )
681 {
682 cfg_path = CFG_VEHICLESPATH;
683 }
684 else if ( GetGame().ConfigIsExisting(CFG_WEAPONSPATH+" "+class_name) )
685 {
686 cfg_path = CFG_WEAPONSPATH;
687 }
688 else if ( GetGame().ConfigIsExisting(CFG_MAGAZINESPATH+" "+class_name) )
689 {
690 cfg_path = CFG_MAGAZINESPATH;
691 }
692 cfg_path = cfg_path + " "+class_name+" DamageSystem GlobalHealth " + health_type + " hitpoints";
693 max_health = GetGame().ConfigGetFloat(cfg_path);
694
695 return max_health;
696 }
697
698 static bool GetProjectedCursorPos3d (out vector position, Weapon_Base weapon)
699 {
700 vector usti_hlavne_position = weapon.GetSelectionPositionMS( "usti hlavne" );
701 vector konec_hlavne_position = weapon.GetSelectionPositionMS( "konec hlavne" );
702 vector end_point = weapon.ModelToWorld(usti_hlavne_position);
703 vector begin_point = weapon.ModelToWorld(konec_hlavne_position);
704 vector contact_dir;
705 int contact_component;
706
707 vector aim_point = end_point - begin_point;
708 aim_point = aim_point.Normalized() * PROJECTED_CURSOR_DISTANCE;
709 aim_point = aim_point + end_point;
710
711 if (DayZPhysics.RaycastRV(begin_point, aim_point, position, contact_dir, contact_component, null, null, null, false, false, ObjIntersectFire))
712 return true;
713 return false;
714 }
715
716 static void GetHeadBonePos(notnull PlayerBase player, out vector pos)
717 {
718 // Get position of head for starting trace pos, otherwise use sane default
719 int headBoneIdx = player.GetBoneIndexByName("Head");
720 if ( headBoneIdx == -1 )
721 { pos = player.GetPosition()[1] + 1.6; }
722 else
723 { pos = player.GetBonePositionWS(headBoneIdx); }
724 }
725
726 static vector GetHeadingVector(notnull PlayerBase player)
727 {
728 vector dir = vector.Zero;
729 float headingAngle = GetHeadingAngle(player);
730 dir[0] = Math.Cos(headingAngle + Math.PI_HALF);
731 dir[2] = Math.Sin(headingAngle + Math.PI_HALF);
732
733 return dir.Normalized();
734 }
735
736 static float GetHeadingAngle(notnull DayZPlayerImplement player)
737 {
738 HumanInputController hic = player.GetInputController();
739 float headingAngle = hic.GetHeadingAngle();
740
741 return headingAngle;
742 }
743
744 static float GetEnergyMetabolicSpeed(int movement_speed)
745 {
746 float speed;
747 switch (movement_speed)
748 {
749 case DayZPlayerConstants.MOVEMENTIDX_WALK:
750 speed = PlayerConstants.METABOLIC_SPEED_ENERGY_WALK;
751 break;
752 case DayZPlayerConstants.MOVEMENTIDX_RUN:
753 speed = PlayerConstants.METABOLIC_SPEED_ENERGY_JOG;
754 break;
755 case DayZPlayerConstants.MOVEMENTIDX_SPRINT:
756 speed = PlayerConstants.METABOLIC_SPEED_ENERGY_SPRINT;
757 break;
758 default:
759 speed = 0;
760 break;
761 }
762
763 speed += PlayerConstants.METABOLIC_SPEED_ENERGY_BASAL;
764 return speed;
765 }
766
767 static float GetWaterMetabolicSpeed(int movement_speed)
768 {
769 float speed;
770 switch (movement_speed)
771 {
772 case DayZPlayerConstants.MOVEMENTIDX_WALK:
773 speed = PlayerConstants.METABOLIC_SPEED_WATER_WALK;
774 break;
775 case DayZPlayerConstants.MOVEMENTIDX_RUN:
776 speed = PlayerConstants.METABOLIC_SPEED_WATER_JOG;
777 break;
778 case DayZPlayerConstants.MOVEMENTIDX_SPRINT:
779 speed = PlayerConstants.METABOLIC_SPEED_WATER_SPRINT;
780 break;
781 default:
782 speed = 0;
783 break;
784 }
785
786 speed += PlayerConstants.METABOLIC_SPEED_WATER_BASAL;
787 return speed;
788 }
789
790 static string ObtainRestrainItemTargetClassname(notnull EntityAI entity)
791 {
792 return entity.ConfigGetString( "OnRestrainChange");
793 }
794
795 static void TransformRestrainItem(EntityAI current_item, EntityAI tool, PlayerBase player_source, PlayerBase player_target, bool destroy = false)
796 {
797 bool type;
798
799 if ( tool )
800 {
801 //is unrestrain and not struggle
802 type = tool.ConfigGetBool("RestrainUnlockType");
803 }
804 string new_item_name = current_item.ConfigGetString( "OnRestrainChange");
805
806 if ( new_item_name != "" )
807 {
808 if ( player_target )
809 {
810 if (player_target.IsAlive())
811 MiscGameplayFunctions.TurnItemIntoItemEx(player_target, new ReplaceAndDestroyLambdaEx(current_item, new_item_name, player_target, type));
812 else
813 MiscGameplayFunctions.TurnItemIntoItemEx(player_source, new DestroyItemInCorpsesHandsAndCreateNewOnGndLambda(current_item, new_item_name, player_target, type));
814 }
815 else
816 {
817 MiscGameplayFunctions.TurnItemIntoItemEx(player_target, new ReplaceAndDestroyLambdaEx(current_item, new_item_name, player_target, type));
818 }
819 }
820 else
821 {
822 Error("current_item:" +current_item+ ", tool:" +tool +". No value for 'OnRestrainChange' config parameter");
823 }
824 }
825
826 static bool IsValueInRange(float value, float from, float to)
827 {
828 return (value >= from) && (value <= to);
829 }
830
832 static bool IsPlayerOrientedTowardPos(notnull DayZPlayerImplement player, vector target_pos, float cone_angle)
833 {
834 if (player)
835 {
836 vector player_dir = player.GetDirection();
837 vector to_target_dir = target_pos - player.GetPosition();
838
839 player_dir[1] = 0;
840 to_target_dir[1] = 0;
841
842 player_dir.Normalize();
843 to_target_dir.Normalize();
844
845 float cos_fi = vector.Dot(player_dir, to_target_dir);
846 vector cross = player_dir * to_target_dir;
847
848 int dir = Math.Acos(cos_fi) * Math.RAD2DEG;
849
850 if( cross[1] < 0 )
851 dir = -dir;
852
854 if( (dir <= cone_angle && dir >= -cone_angle) || Math.AbsFloat(dir) == 90 )
855 {
856 return true;
857 }
858 }
859
860 return false;
861 }
862
863 static string SanitizeString(string input)
864 {
865 int max_length = 512;
866 string output = input;
867
868 output = output.Substring(0,Math.Clamp(max_length,0,output.Length()));
869 return output;
870 }
871
872 // deprecated - dont use
873 static bool ComplexBuildCollideCheckClient( PlayerBase player, ActionTarget target, ItemBase item, string partName = "" )
874 {
875 return true;
876 }
877
878 static bool ComplexBuildCollideCheckClient( PlayerBase player, ActionTarget target, ItemBase item, int constraction_index )
879 {
880 BaseBuildingBase base_building = BaseBuildingBase.Cast( target.GetObject() );
881 if (base_building)
882 {
883 Construction construction = base_building.GetConstruction();
884 if (construction && BuildCondition( player, target, item, false, constraction_index ))
885 {
886 ConstructionActionData construction_action_data = player.GetConstructionActionData();
887 string partName;
888 if ( item )
889 {
890 partName = construction_action_data.GetBuildPartAtIndex(constraction_index).GetPartName();
891 }
892 else
893 {
894 partName = construction_action_data.GetBuildPartNoToolAtIndex(constraction_index).GetPartName();
895 }
896 bool boo;
897 if (base_building.PerformRoofCheckForBase(partName,player,boo) && boo)
898 return false;
899 if ( player.IsPlacingLocal() || player.IsPlacingServer() )
900 return false;
901
902 /*float distance_root = vector.DistanceSq(target.GetCursorHitPos(), player.GetPosition());
903
904 if (!CfgGameplayHandler.GetDisableDistanceCheck() && distance_root < UAMaxDistances.BASEBUILDING_SHORT)
905 {
906 return false;
907 } */
908 return !construction.IsColliding( partName );
909 }
910 }
911 return false;
912 }
913
914 // deprecated - dont use
915 static bool BuildCondition( PlayerBase player, ActionTarget target, ItemBase item, bool camera_check )
916 {
917 return true;
918 }
919
920 static bool BuildCondition( PlayerBase player, ActionTarget target, ItemBase item, bool camera_check, int constraction_index )
921 {
922 Object targetObject = target.GetObject();
923 if ( targetObject && targetObject.CanUseConstruction() )
924 {
925 BaseBuildingBase base_building = BaseBuildingBase.Cast( targetObject );
926 ConstructionActionData construction_action_data = player.GetConstructionActionData();
927 construction_action_data.SetTarget( targetObject );
928
929 ConstructionPart constrution_part;
930 if ( item )
931 {
932 constrution_part = construction_action_data.GetBuildPartAtIndex(constraction_index);
933 }
934 else
935 {
936 constrution_part = construction_action_data.GetBuildPartNoToolAtIndex(constraction_index);
937 }
938
939 //Debug
940 /*
941 if ( constrution_part )
942 {
943 Construction construction = base_building.GetConstruction();
944 construction.IsColliding( constrution_part.GetPartName() );
945 }
946 */
947
948 if ( constrution_part )
949 {
950 //camera and position checks
951 bool position_check = ( base_building.MustBeBuiltFromOutside() && !base_building.IsPlayerInside(player, constrution_part.GetMainPartName()) ) || ( !base_building.MustBeBuiltFromOutside() && base_building.IsPlayerInside(player, constrution_part.GetMainPartName()) );
952 if ( position_check && !player.GetInputController().CameraIsFreeLook() )
953 {
954 //Camera check (client-only)
955 if ( camera_check )
956 {
957 if ( GetGame() && ( !GetGame().IsDedicatedServer() ) )
958 {
959 return !base_building.IsFacingCamera( constrution_part.GetMainPartName() );
960 }
961 }
962
963 return true;
964 }
965 }
966 }
967
968 return false;
969 }
970
971 static void IsUnderRoofFromToCalculation(EntityAI entity, out vector from, out vector to, float height = GameConstants.ROOF_CHECK_RAYCAST_DIST)
972 {
973 vector minMax[2];
974 entity.GetCollisionBox(minMax);
975
976 vector size = Vector(0,0,0);
977 //size[1] = minMax[1][1] - minMax[0][1];
978 float from_override = entity.HeightStartCheckOverride();
979 if (from_override > 0.0)
980 {
981 size[1] = from_override;
982 }
983 else
984 {
985 size[1] = minMax[1][1] - minMax[0][1];
986 }
987
988 from = entity.GetPosition() + size;
989 if ( entity.HeightCheckOverride() > 0 )
990 {
991 to = entity.GetPosition() + Vector(0, entity.HeightCheckOverride(), 0);
992 }
993 else
994 {
995 vector ceiling = "0 0 0";
996 ceiling[1] = height;
997 to = from + ceiling; //+size ??? offset to cast same distance
998 }
999 }
1000
1001 static bool IsUnderRoof(EntityAI entity, float height = GameConstants.ROOF_CHECK_RAYCAST_DIST)
1002 {
1003 return IsUnderRoofEx(entity, height, ObjIntersectIFire);
1004 }
1005
1006 static bool IsUnderRoofEx(EntityAI entity, float height = GameConstants.ROOF_CHECK_RAYCAST_DIST, int geometry = ObjIntersectView)
1007 {
1008 vector from;
1009 vector to;
1010
1011 IsUnderRoofFromToCalculation(entity, from, to, height);
1012
1013 vector contact_pos;
1014 vector contact_dir;
1015 int contact_component;
1016
1017 return DayZPhysics.RaycastRV(from, to, contact_pos, contact_dir, contact_component, NULL, NULL, entity, false, false, geometry,0.25);
1018 }
1019
1020 // cooking equipment effects (get position for steam particle)
1021 static vector GetSteamPosition( EntityAI parent )
1022 {
1023 vector particle_pos;
1024 float steam_offset = 0;
1025
1026 if ( parent )
1027 {
1028 particle_pos = parent.GetPosition();
1029
1030 if ( parent.IsInherited( PortableGasStove ) )
1031 {
1032 steam_offset = 0.2;
1033 }
1034 else if ( parent.IsInherited( FireplaceBase ) )
1035 {
1036 FireplaceBase fireplace = FireplaceBase.Cast( parent );
1037
1038 if ( fireplace.IsBaseFireplace() )
1039 {
1040 steam_offset = 0.8;
1041 }
1042 else if ( fireplace.IsBarrelWithHoles() )
1043 {
1044 steam_offset = 1.1;
1045 }
1046 else if ( fireplace.IsFireplaceIndoor() )
1047 {
1048 steam_offset = 0.45;
1049 }
1050 else if ( fireplace.IsIndoorOven() )
1051 {
1052 steam_offset = 0.9;
1053 }
1054 }
1055 }
1056
1057 particle_pos[1] = particle_pos[1] + steam_offset;
1058
1059 return particle_pos;
1060 }
1061
1062 static vector GetRandomizedPosition(vector targetPos, float radius)
1063 {
1064 int angle = Math.RandomIntInclusive(1,360);
1065 float usedRadius = Math.RandomFloat01() * radius;
1066 vector randomPos = Vector(targetPos[0] + (Math.Cos(angle) * usedRadius), targetPos[1], targetPos[2] + (Math.Sin(angle) * usedRadius));
1067
1068 return randomPos;
1069 }
1070
1071 static vector GetRandomizedPositionVerified(vector startPos, vector targetPos, float radius, Object ignore = null)
1072 {
1073 vector ret = GetRandomizedPosition(targetPos,radius);
1074 RaycastRVParams params = new RaycastRVParams(startPos,ret,ignore);
1075 params.type = ObjIntersectIFire;
1077 array<Object> excluded = new array<Object>;
1078 if (DayZPhysics.RaycastRVProxy(params,results,excluded))
1079 {
1080 ret = results[0].pos;
1081 ret[1] = targetPos[1];
1082 }
1083 return ret;
1084 }
1085
1086 static vector GetRandomizedPositionVerifiedPlayer(Man player, float distance, float radius, Object ignore)
1087 {
1088 vector startPos;
1089 MiscGameplayFunctions.GetHeadBonePos(PlayerBase.Cast(player),startPos);
1090 vector targetPos = player.GetPosition() + (player.GetDirection() * distance);
1091 return GetRandomizedPositionVerified(startPos,targetPos,radius,ignore);
1092 }
1093
1094 static void DropAllItemsInInventoryInBounds(ItemBase ib, vector halfExtents)
1095 {
1096 if (!GetGame().IsServer())
1097 return;
1098 array<EntityAI> items = new array<EntityAI>;
1099 ib.GetInventory().EnumerateInventory(InventoryTraversalType.LEVELORDER, items);
1100
1101 vector direction = ib.GetDirection();
1102 float dot = vector.Dot(direction, vector.Forward);
1103
1104 float angle = Math.Acos(dot);
1105 if (direction[0] < 0)
1106 angle = -angle;
1107
1108 float cos = Math.Cos(angle);
1109 float sin = Math.Sin(angle);
1110
1111 EntityAI item;
1112 int count = items.Count();
1113 for ( int i = 0; i < count; ++i )
1114 {
1115 item = items.Get(i);
1116 if ( item )
1117 ib.GetInventory().DropEntityInBounds(InventoryMode.SERVER, ib, item, halfExtents, angle, cos, sin);
1118 }
1119 }
1120
1121 static void ThrowAllItemsInInventory(notnull EntityAI parent, int flags)
1122 {
1123 vector position = parent.GetPosition();
1124 vector orientation = parent.GetOrientation();
1125 vector rotation_matrix[3];
1126 float direction[4];
1127 vector randomPos;
1128 vector minmax[2];
1129 parent.GetCollisionBox(minmax);
1130
1131 Math3D.YawPitchRollMatrix( orientation, rotation_matrix );
1132 Math3D.MatrixToQuat( rotation_matrix, direction );
1133
1134 //gather entities first
1136 int count, i;
1137 //atts
1138 count = parent.GetInventory().AttachmentCount();
1139 for (i = 0; i < count; ++i)
1140 {
1141 ents.Insert(parent.GetInventory().GetAttachmentFromIndex(i));
1142 }
1143
1144 //cargo
1145 count = parent.GetInventory().GetCargo().GetItemCount();
1146 for (i = 0; i < count; ++i)
1147 {
1148 ents.Insert(parent.GetInventory().GetCargo().GetItem(i));
1149 }
1150
1151 //now throw them all
1152 foreach (EntityAI ent : ents)
1153 {
1154 randomPos = Vector(position[0] + Math.RandomFloat(minmax[0][0], minmax[1][0]),
1155 position[1] + Math.RandomFloat(minmax[0][1], minmax[1][1]),
1156 position[2] + Math.RandomFloat(minmax[0][2], minmax[1][2]));
1157 ThrowEntityFromInventory(ent, randomPos, direction, -GetVelocity(parent), ThrowEntityFlags.NONE);
1158 }
1159 }
1160
1161 static void ThrowEntityFromInventory(notnull EntityAI entity, vector position, float direction[4], vector force, int flags)
1162 {
1163 InventoryMode invMode = InventoryMode.SERVER;
1164 if ( !GetGame().IsMultiplayer() )
1165 invMode = InventoryMode.LOCAL;
1166
1167 ItemBase entityIB;
1168 if (CastTo(entityIB, entity))
1169 {
1171 dst.SetGroundEx(entity, position, direction);
1172
1173 if ( (flags & ThrowEntityFlags.SPLIT) && entityIB.CanBeSplit() )
1174 {
1175 for (int l = 0; l < entityIB.GetQuantity(); ++l)
1176 {
1177 ItemBase new_item = ItemBase.Cast( GameInventory.LocationCreateEntity( dst, entityIB.GetType(), ECE_NONE, RF_DEFAULT ) );
1178
1179 if ( new_item )
1180 {
1181 MiscGameplayFunctions.TransferItemProperties(entityIB, new_item);
1182 entityIB.AddQuantity( -1 );
1183 new_item.SetQuantity( 1 );
1184 new_item.ThrowPhysically(null, force, false);
1185 }
1186 }
1187 }
1188 else
1189 {
1190 float stackable = entityIB.GetTargetQuantityMax();
1191 if ( !(stackable == 0 || stackable >= entityIB.GetQuantity()) )
1192 {
1193 while (entityIB.GetQuantity() > stackable)
1194 {
1196 position[1] = position[1] + 0.1;
1197 spltDst.SetGroundEx(entity, position, direction);
1198
1199 ItemBase splitItem = entityIB.SplitIntoStackMaxToInventoryLocationEx( spltDst );
1200 splitItem.ThrowPhysically(null, force, false);
1201 }
1202 }
1203
1205 entity.GetInventory().GetCurrentInventoryLocation(src);
1206
1207 entity.GetInventory().TakeToDst(invMode, src, dst);
1208 entityIB.ThrowPhysically(null, force, false);
1209 }
1210 }
1211 else
1212 {
1213 entity.GetInventory().DropEntity(invMode, entity.GetHierarchyRoot(), entity);
1214 dBodyApplyImpulse(entity, force);
1215 }
1216 }
1217
1218 static float GetCurrentItemHeatIsolation( ItemBase pItem )
1219 {
1220 float wetFactor;
1221 float healthFactor;
1222
1223 float heatIsolation = pItem.GetHeatIsolation();
1224 float itemHealthLabel = pItem.GetHealthLevel();
1225 float itemWetness = pItem.GetWet();
1226
1228 if ( itemWetness >= GameConstants.STATE_DRY && itemWetness < GameConstants.STATE_DAMP )
1229 {
1230 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_DRY;
1231 }
1232 else if ( itemWetness >= GameConstants.STATE_DAMP && itemWetness < GameConstants.STATE_WET )
1233 {
1234 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_DAMP;
1235 }
1236 else if ( itemWetness >= GameConstants.STATE_WET && itemWetness < GameConstants.STATE_SOAKING_WET )
1237 {
1238 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_WET;
1239 }
1240 else if ( itemWetness >= GameConstants.STATE_SOAKING_WET && itemWetness < GameConstants.STATE_DRENCHED )
1241 {
1242 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_SOAKED;
1243 }
1244 else if ( itemWetness >= GameConstants.STATE_DRENCHED )
1245 {
1246 return GameConstants.ENVIRO_ISOLATION_WETFACTOR_DRENCHED;
1247 }
1248
1250 switch (itemHealthLabel)
1251 {
1252 case GameConstants.STATE_PRISTINE:
1253 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_PRISTINE;
1254 break;
1255
1256 case GameConstants.STATE_WORN:
1257 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_WORN;
1258 break;
1259
1260 case GameConstants.STATE_DAMAGED:
1261 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_DAMAGED;
1262 break;
1263
1264 case GameConstants.STATE_BADLY_DAMAGED:
1265 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_B_DAMAGED;
1266 break;
1267
1268 case GameConstants.STATE_RUINED:
1269 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_RUINED;
1270 break;
1271 }
1272
1274 heatIsolation *= healthFactor;
1275 heatIsolation *= wetFactor;
1276
1277 return heatIsolation;
1278 }
1279
1280 static void FilterObstructingObjects(array<Object> potentiallyObstructingObjects, out array<Object> obstructingObjects)
1281 {
1282 if (!obstructingObjects)
1283 obstructingObjects = new array<Object>;
1284
1285 for ( int i = 0; i < potentiallyObstructingObjects.Count(); ++i )
1286 {
1287 Object obj = potentiallyObstructingObjects[i];
1288 if ( obj && ( obj.CanObstruct() || obj.CanProxyObstruct() ) )
1289 obstructingObjects.Insert(obj);
1290 }
1291 }
1292
1293 static bool CanIgnoreDistanceCheck(Object obj)
1294 {
1295 return obj.IsTransport() || obj.CanUseConstruction();
1296 }
1297
1299 static void FilterObstructedObjectsByGrouping(vector origin, float range, float distanceDelta, array<Object> objects, array<Object> obstructingObjects, out array<Object> filteredObjects, bool doDistanceCheck = false, bool checkIfDistanceCanBeIgnored = false, float maxDist = 0)
1300 {
1301 array<Object> vicinityObjects= new array<Object>;
1302 vicinityObjects.Copy(objects);
1303
1304 int i = 0;
1305 int j = 0;
1306 int k = 0;
1307 int mCount = vicinityObjects.Count();
1308
1309 if (!filteredObjects)
1310 filteredObjects = new array<Object>;
1311
1312 // Remove objects that are too far from the player anyways
1313 if ( doDistanceCheck )
1314 {
1315 for ( i = vicinityObjects.Count() - 1; i >= 0; --i )
1316 {
1317 Object obj = vicinityObjects[i];
1318 if ( obj && !CanIgnoreDistanceCheck( obj ) && vector.DistanceSq(origin, obj.GetPosition()) > maxDist * maxDist )
1319 vicinityObjects.Remove(i);
1320 }
1321 }
1322
1323 // Sort obstructingObjects to have the furthest one first
1324 array<Object> sortedObstructingObjects = new array<Object>;
1325 array<float> distanceHelper = new array<float>;
1326 array<float> distanceHelperUnsorted = new array<float>;
1327 float distance, dist1, dist2;
1328
1329 for ( i = 0; i < obstructingObjects.Count(); ++i )
1330 {
1331 distance = vector.DistanceSq(obstructingObjects[i].GetWorldPosition(), origin);
1332 distanceHelper.Insert(distance);
1333 }
1334
1335 distanceHelperUnsorted.Copy(distanceHelper);
1336 distanceHelper.Sort();
1337
1338 for ( i = distanceHelper.Count() - 1; i >= 0; --i )
1339 sortedObstructingObjects.Insert(obstructingObjects[distanceHelperUnsorted.Find(distanceHelper[i])]);
1340
1343 array<Object> group;
1344
1345 float cos = Math.Cos(90);
1346 float sin = Math.Sin(90);
1347
1348 // Iterate through sorted obstructingObjects
1349 for ( i = 0; i < sortedObstructingObjects.Count(); ++i )
1350 {
1351 Object obstrObj = sortedObstructingObjects[i];
1352 vector worldPos = obstrObj.GetWorldPosition();
1353 vector min, max;
1354 vector minMax[2];
1355 if ( obstrObj.GetCollisionBox(minMax) )
1356 {
1357 min = minMax[0];
1358 max = minMax[1];
1359 max = max * (obstrObj.GetOrientation() * range);
1360
1361 vector center, dx, dy, dz, half;
1362 center = (min + max) * 0.5;
1363 dz = obstrObj.GetOrientation();
1364 dx = vector.RotateAroundZero(dz, vector.Up, cos, sin);
1365 dy = vector.RotateAroundZero(dz, vector.Aside, cos, sin);
1366 half = (max - min) * 0.5;
1367 half = Vector(Math.AbsFloat(half[0]), Math.AbsFloat(half[1]), Math.AbsFloat(half[2]));
1368
1369 group = new array<Object>;
1370
1371 // Group objects within the above box
1372 for ( j = vicinityObjects.Count() - 1; j >= 0; --j )
1373 {
1374 Object vicObj = vicinityObjects[j];
1375 if ( vicObj )
1376 {
1377 vector d = vicObj.GetWorldPosition() - worldPos + center;
1378 if ( Math.AbsFloat(vector.Dot(d, dx)) <= half[0] && Math.AbsFloat(vector.Dot(d, dy)) <= half[1] && Math.AbsFloat(vector.Dot(d, dz)) <= half[2] )
1379 {
1380 group.Insert(vicObj);
1381 vicinityObjects.Remove(j);
1382 }
1383 }
1384 }
1385
1386 if ( group.Count() > 0 )
1387 tempGroups.Insert(group);
1388 }
1389 }
1390
1391 // Go through the objects grouped by obstruction to split them by distance too
1392 for ( i = 0; i < tempGroups.Count(); ++i )
1393 SplitArrayIntoGroupsByDistance(tempGroups[i], objectGroups, distanceDelta);
1394
1395 // Split initial groups by distance
1396 SplitArrayIntoGroupsByDistance(vicinityObjects, objectGroups, distanceDelta);
1397
1398 // Raycast accordingly to groups
1399 IsObjectObstructedCache cache = new IsObjectObstructedCache(origin, mCount);
1400 for ( i = 0; i < objectGroups.Count(); ++i )
1401 {
1402 array<Object> objectGroup = objectGroups[i];
1403 Object sampleObject = objectGroup[0];
1404
1405 if ( !IsObjectObstructedEx(sampleObject, cache) )
1406 filteredObjects.InsertAll(objectGroup);
1407
1408 cache.ClearCache();
1409 }
1410 }
1411
1412 static void SplitArrayIntoGroupsByDistance(array<Object> objects, array<ref array<Object>> objectGroups, float squaredDistanceDelta)
1413 {
1414 array<Object> group;
1415 for ( int i = 0; i < objects.Count(); )
1416 {
1417 Object obj1 = objects[i];
1418 if ( obj1 )
1419 {
1420 group = new array<Object>;
1421 group.Insert(obj1);
1422 for ( int j = objects.Count() - 1; j > i; --j )
1423 {
1424 Object obj2 = objects[j];
1425 if ( obj1 && obj2 )
1426 {
1427 vector start = obj1.GetWorldPosition();
1428 vector end = obj2.GetWorldPosition();
1429
1430 float distance = vector.DistanceSq(start, end);
1431 if ( distance < squaredDistanceDelta )
1432 {
1433 group.Insert(obj2);
1434 objects.Remove(j);
1435 }
1436 }
1437 }
1438 objectGroups.Insert(group);
1439 objects.Remove(i);
1440 continue;
1441 }
1442 ++i;
1443 }
1444 }
1445
1446 static bool IsObjectObstructed(Object object, bool doDistanceCheck = false, vector distanceCheckPos = "0 0 0", float maxDist = 0)
1447 {
1448 vector rayStart;
1449 MiscGameplayFunctions.GetHeadBonePos(PlayerBase.Cast(GetGame().GetPlayer()), rayStart);
1450 IsObjectObstructedCache cache = new IsObjectObstructedCache(rayStart, 1);
1451
1452 return IsObjectObstructedEx(object, cache, doDistanceCheck, distanceCheckPos, maxDist);
1453 }
1454
1455 static bool IsObjectObstructedEx(Object object, IsObjectObstructedCache cache, bool doDistanceCheck = false, vector distanceCheckPos = "0 0 0", float maxDist = 0)
1456 {
1457 if (!object)
1458 return true;
1459
1460 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
1461 if (doDistanceCheck && vector.DistanceSq(player.GetPosition(), distanceCheckPos) > maxDist * maxDist)
1462 return true;
1463
1464 cache.ObjectCenterPos = object.GetCenter();
1465
1466 return IsObjectObstructedFilterEx(object, cache, player);
1467 }
1468
1469 static bool IsObjectObstructedProxy(Object object, IsObjectObstructedCache cache, PlayerBase player)
1470 {
1471 if (object.CanProxyObstruct())
1472 {
1473 RaycastRVParams rayInput = new RaycastRVParams(cache.RaycastStart, cache.ObjectCenterPos, player);
1474 DayZPhysics.RaycastRVProxy(rayInput, cache.HitProxyObjects);
1475 if (cache.HitProxyObjects)
1476 {
1477 if (cache.HitProxyObjects.Count() > 0)
1478 {
1479 if (cache.HitProxyObjects[0].hierLevel > 0)
1480 {
1481 // ignores attachments on player
1482 if (!cache.HitProxyObjects[0].parent.IsMan())
1483 {
1484 if (cache.HitProxyObjects[0].parent)
1485 {
1486 EntityAI proxyParent = EntityAI.Cast(cache.HitProxyObjects[0].parent);
1487 if (proxyParent.GetInventory() && proxyParent.GetInventory().GetCargo())
1488 return true;
1489 }
1490 }
1491 }
1492 }
1493 }
1494 }
1495 return false;
1496 }
1497
1498 static bool IsObjectObstructedFilter(Object object, IsObjectObstructedCache cache, PlayerBase player)
1499 {
1500 for (int m = 0; m < cache.HitObjects.Count(); ++m)
1501 {
1502 Object hit_object = cache.HitObjects.Get(m);
1503
1504 if ( hit_object.CanObstruct() )
1505 return true;
1506
1507 //4.3. ignore item if items are big and heavy >= OBJECT_OBSTRUCTION_WEIGHT
1508 //EntityAI eai;
1509 //if ( Class.CastTo( eai, hit_object ) )
1510 //{
1511 // if ( eai.GetWeight() >= OBJECT_OBSTRUCTION_WEIGHT )
1512 // {
1513 // if ( eai != filtered_object && eai.GetHierarchyRoot() != filtered_object )
1514 // {
1515 // //Print("!!!!!obstacle vaha: " + hit_object);
1516 // is_obstructed = true;
1517 // }
1518 // }
1519 //}
1520 }
1521
1522 return false;
1523 }
1524
1526 static bool IsObjectObstructedFilterEx(Object object, IsObjectObstructedCache cache, PlayerBase player, int geometryTypeOverride = -1)
1527 {
1528 //first proxy geometries
1529 RaycastRVParams rayInput = new RaycastRVParams(cache.RaycastStart, cache.ObjectCenterPos, player);
1530 rayInput.flags = CollisionFlags.ALLOBJECTS;
1531 if (geometryTypeOverride != -1)
1532 rayInput.type = geometryTypeOverride; //default 'ObjIntersectView'
1533 DayZPhysics.RaycastRVProxy(rayInput, cache.HitProxyObjects);
1534 int count;
1535 int i;
1536
1537 if (cache.HitProxyObjects)
1538 {
1539 count = cache.HitProxyObjects.Count();
1540 Object parent;
1541 for (i = 0; i < count; ++i)
1542 {
1543 if (cache.HitProxyObjects[i].hierLevel > 0) //parent has to exist, skipping nullcheck
1544 {
1545 parent = cache.HitProxyObjects[i].parent;
1546 if (parent && !parent.IsMan() && parent.CanProxyObstruct())
1547 {
1548 if (parent != object || (parent == object && object.CanProxyObstructSelf()))
1549 return true;
1550 }
1551 }
1552 }
1553 }
1554
1555 //second, regular raycast
1556 int geometry = ObjIntersectFire; //default for the RV raycast
1557 if (geometryTypeOverride != -1)
1558 geometry = geometryTypeOverride;
1559 DayZPhysics.RaycastRV(cache.RaycastStart, cache.ObjectCenterPos, cache.ObjectContactPos, cache.ObjectContactDir, cache.ContactComponent, cache.HitObjects, object, GetGame().GetPlayer(), false, false, geometry, 0.0, CollisionFlags.ALLOBJECTS);
1560 count = cache.HitObjects.Count();
1561 for (i = 0; i < count; ++i)
1562 {
1563 if (cache.HitObjects[i].CanObstruct())
1564 return true;
1565 }
1566
1567 return false;
1568 }
1569
1570 //Inflict damage to item based on environmental temperature and surface type
1571 static void DealEvinronmentAdjustedDmg(ItemBase item, PlayerBase player, float baseDamage)
1572 {
1573 string surfaceType;
1574 int liquidType;
1575 float adjustedDamage;
1576
1577 GetGame().SurfaceUnderObject(player, surfaceType, liquidType);
1578 float modifierSurface = Surface.GetParamFloat(surfaceType, "toolDamage"); // toolDamage
1579 if (modifierSurface == 0)
1580 modifierSurface = 1;
1581
1582 if (player.GetInColdArea())
1583 adjustedDamage = baseDamage * (modifierSurface + GetGame().GetMission().GetWorldData().GetColdAreaToolDamageModifier());
1584 else
1585 adjustedDamage = baseDamage * modifierSurface;
1586
1587 DealAbsoluteDmg(item, adjustedDamage);
1588 }
1589
1590 //Inflict absolute damage to item (used on tools when completing actions)
1591 static void DealAbsoluteDmg(ItemBase item, float dmg)
1592 {
1593 item.DecreaseHealth(dmg, false);
1594 }
1595
1596 //Function used to normailze values, enter the used value and the max value (max will become 1)
1597 static float Normalize(int val, int maxVal)
1598 {
1599 if (maxVal == 0)
1600 {
1601 Debug.LogError("Division by 0 is not allowed");
1602 return 0;
1603 }
1604
1605 return val / maxVal;
1606 }
1607
1608 static float Bobbing(float period, float amplitude, float elapsedTime)
1609 {
1610 //Prevent division by 0
1611 if ( period == 0 )
1612 period = 1;
1613
1614 elapsedTime /= period;
1615
1616 float cycle;
1617 cycle += elapsedTime;
1618 cycle = FModulus(cycle, 360);
1619 cycle = Math.Sin(cycle) * amplitude;
1620
1621 return cycle;
1622 }
1623
1624 // DEPRECATED, use Math.ModFloat directly instead
1625 static float FModulus(float x, float y)
1626 {
1627 return Math.ModFloat(x, y);
1628 }
1629
1630 static void RemoveSplint( PlayerBase player )
1631 {
1632 EntityAI entity = player.GetInventory().CreateInInventory("Splint");
1633 if (!entity)
1634 entity = player.SpawnEntityOnGroundOnCursorDir("Splint", 0.5);
1635
1636 EntityAI attachment;
1637 ItemBase new_item = ItemBase.Cast(entity);
1638 Class.CastTo(attachment, player.GetItemOnSlot("Splint_Right"));
1639 if ( attachment && attachment.GetType() == "Splint_Applied" )
1640 {
1641 if (new_item)
1642 {
1643 MiscGameplayFunctions.TransferItemProperties(attachment,new_item);
1644
1645 if (GetGame().IsServer())
1646 {
1647 //Lower health level of splint after use
1648 if (new_item.GetHealthLevel() < 4)
1649 {
1650 int newDmgLevel = new_item.GetHealthLevel() + 1;
1651
1652 float max = new_item.GetMaxHealth("","");
1653
1654 switch ( newDmgLevel )
1655 {
1656 case GameConstants.STATE_BADLY_DAMAGED:
1657 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_BADLY_DAMAGED_VALUE );
1658 break;
1659
1660 case GameConstants.STATE_DAMAGED:
1661 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_DAMAGED_VALUE );
1662 break;
1663
1664 case GameConstants.STATE_WORN:
1665 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_WORN_VALUE );
1666 break;
1667
1668 case GameConstants.STATE_RUINED:
1669 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_RUINED_VALUE );
1670 break;
1671
1672 default:
1673 break;
1674 }
1675 }
1676 }
1677 }
1678
1679 attachment.Delete();
1680 }
1681 }
1682
1684 static void TeleportCheck(notnull PlayerBase player, notnull array<ref array<float>> safe_positions)
1685 {
1686 if( player.GetSimulationTimeStamp() < 20 && !player.IsPersistentFlag(PersistentFlag.AREA_PRESENCE) )
1687 {
1688 //simulation time is bellow a threshold, which means the player has recently connected,
1689 //the player does not have the AREA_PRESENCE flag set, which means they were not inside the area when they disconnected,
1690 //that means they just spawned into a contaminated area, lets move them somewhere safe
1691 vector player_pos = player.GetPosition();
1692 vector closest_safe_pos = MiscGameplayFunctions.GetClosestSafePos(player_pos, safe_positions);
1693
1694 if (player_pos!=closest_safe_pos)
1695 {
1696 closest_safe_pos[1] = GetGame().SurfaceY(closest_safe_pos[0], closest_safe_pos[2]);
1697
1698 player.SetPosition( closest_safe_pos );//...so lets teleport them somewhere safe
1699 //DeveloperTeleport.SetPlayerPosition(player, closest_safe_pos);
1700 GetGame().RPCSingleParam(player, ERPCs.RPC_WARNING_TELEPORT, null, true, player.GetIdentity());
1701
1702 PluginAdminLog adminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
1703 if (adminLog)
1704 adminLog.PlayerTeleportedLog(player,player_pos,closest_safe_pos,"Unwillingly spawning in contaminated area.");
1705 }
1706
1707 player.SetPersistentFlag(PersistentFlag.AREA_PRESENCE, false);
1708 }
1709 }
1710
1711 static vector GetClosestSafePos(vector to_pos, notnull array<ref array<float>> positions)
1712 {
1713 vector closest_pos = to_pos;
1714 float smallest_dist = float.MAX;
1715 foreach( array<float> pos:positions)
1716 {
1717 vector vpos = "0 0 0";
1718 vpos[0] = pos[0];
1719 vpos[2] = pos[1];
1720
1721 to_pos[1] = 0;
1722 float dist = vector.DistanceSq(to_pos, vpos);//2d dist sq
1723 if ( dist < smallest_dist)
1724 {
1725 smallest_dist = dist;
1726 closest_pos = vpos;
1727 }
1728 }
1729 return closest_pos;
1730 }
1731
1733 static bool TeleportPlayerToSafeLocation3D(notnull PlayerBase player, vector safePos)
1734 {
1735 vector playerPos = player.GetPosition();
1736 if (playerPos != safePos)
1737 {
1738 player.SetPosition(safePos);
1739 GetGame().RPCSingleParam(player, ERPCs.RPC_WARNING_TELEPORT, null, true, player.GetIdentity());
1740
1741 return true;
1742 }
1743
1744 return false;
1745 }
1746
1747 static void GenerateAINoiseAtPosition(vector position, float lifeTime, NoiseParams noiseParams)
1748 {
1749 if (GetGame().IsServer())
1750 {
1751 NoiseSystem noise = GetGame().GetNoiseSystem();
1752 if (noise)
1753 {
1754 noise.AddNoiseTarget(position, lifeTime, noiseParams, NoiseAIEvaluate.GetNoiseReduction(GetGame().GetWeather()));
1755 }
1756 }
1757 }
1758
1759 static float GetMinValue(array<float> pArray)
1760 {
1761 float minValue = 0.0;
1762 for (int i = 0; i < pArray.Count(); ++i)
1763 {
1764 if (minValue == 0 || pArray.Get(i) < minValue)
1765 {
1766 minValue = pArray.Get(i);
1767 }
1768 }
1769
1770 return minValue;
1771 }
1772
1773 static float GetMaxValue(array<float> pArray)
1774 {
1775 float maxValue = 0.0;
1776 for (int i = 0; i < pArray.Count(); ++i)
1777 {
1778 if (maxValue == 0 || pArray.Get(i) > maxValue)
1779 {
1780 maxValue = pArray.Get(i);
1781 }
1782 }
1783
1784 return maxValue;
1785 }
1786
1787 static string GetItemDisplayName(string type)
1788 {
1789 return GetGame().ConfigGetTextOut("CfgVehicles " + type + " displayName");
1790 }
1791
1792 static bool IsComponentInSelection(array<Selection> pSelection, string pCompName)
1793 {
1794 if (pSelection.Count() == 0 || pCompName.Length() == 0)
1795 {
1796 return false;
1797 }
1798
1799 for (int i = 0; i < pSelection.Count(); ++i)
1800 {
1801 pCompName.ToLower();
1802 if (pSelection[i] && pSelection[i].GetName() == pCompName)
1803 {
1804 return true;
1805 }
1806 }
1807
1808 return false;
1809 }
1810
1811 static int GetComponentIndex(array<Selection> pSelection, string pCompName)
1812 {
1813 if (!MiscGameplayFunctions.IsComponentInSelection(pSelection, pCompName))
1814 {
1815 return INDEX_NOT_FOUND;
1816 }
1817
1818 for (int i = 0; i < pSelection.Count(); ++i)
1819 {
1820 pCompName.ToLower();
1821 if (pSelection[i] && pSelection[i].GetName() == pCompName)
1822 {
1823 return i;
1824 }
1825 }
1826
1827 return INDEX_NOT_FOUND;
1828 }
1829
1830 static void RemoveAllAttachedChildrenByTypename(notnull EntityAI parent, array<typename> listOfTypenames)
1831 {
1832 if (listOfTypenames.Count() > 0)
1833 {
1834 Object child = Object.Cast(parent.GetChildren());
1835 while (child)
1836 {
1837 Object childToRemove = child;
1838 child = Object.Cast(child.GetSibling());
1839
1840 if (childToRemove.IsAnyInherited(listOfTypenames))
1841 {
1842 vector pos = parent.GetPosition();
1843 parent.RemoveChild(childToRemove, false);
1844
1845 vector m4[4];
1846 Math3D.MatrixIdentity4(m4);
1847 m4[3] = pos;
1848 childToRemove.SetTransform(m4);
1849 childToRemove.PlaceOnSurface();
1850 }
1851 }
1852 }
1853 }
1854
1855 static void DeleteAttachedChildrenByTypename(notnull EntityAI parent, array<typename> listOfTypenames)
1856 {
1857 if (listOfTypenames.Count() > 0)
1858 {
1859 Object child = Object.Cast(parent.GetChildren());
1860 while (child)
1861 {
1862 Object childToRemove = child;
1863 child = Object.Cast(child.GetSibling());
1864
1865 if (childToRemove.IsAnyInherited(listOfTypenames))
1866 {
1867 parent.RemoveChild(childToRemove, false);
1868 childToRemove.Delete();
1869 }
1870 }
1871 }
1872 }
1873
1875 static void GetAttachedChildren(IEntity parent, array<IEntity> outputObjects)
1876 {
1877 IEntity child = parent.GetChildren();
1878 while (child)
1879 {
1880 outputObjects.Insert(child);
1881 child = child.GetSibling();
1882 }
1883 }
1884
1885 static void SoakItemInsideParentContainingLiquidAboveThreshold(notnull ItemBase item, notnull ItemBase parent, float liquidQuantityThresholdPercentage = 0.05)
1886 {
1887 if (g_Game.IsServer())
1888 {
1889 if (parent.GetLiquidType() != 0 && parent.GetQuantityNormalized() > liquidQuantityThresholdPercentage && !parent.GetIsFrozen())
1890 item.SetWetMax();
1891 }
1892 }
1893
1894 static float GetCombinedSnowfallWindValue()
1895 {
1896 float windMin;
1897 float windMax;
1898 g_Game.GetWeather().GetWindMagnitude().GetLimits(windMin, windMax);
1899 float snowfall = g_Game.GetWeather().GetSnowfall().GetActual();
1900 float value = snowfall + g_Game.GetWeather().GetWindMagnitude().GetActual() / windMax;
1901
1902 return value;
1903 }
1904}
1905
1907{
1908 // @NOTE m_Player == target player - i.e. restrained one
1909 void DestroyItemInCorpsesHandsAndCreateNewOnGndLambda(EntityAI old_item, string new_item_type, PlayerBase player, bool destroy = false)
1910 {
1912 vector mtx[4];
1913 if (old_item)
1914 old_item.GetTransform(mtx);
1915 else
1916 player.GetTransform(mtx);
1917 gnd.SetGround(NULL, mtx);
1918 OverrideNewLocation(gnd);
1919 }
1920
1921 protected override void RemoveOldItemFromLocation()
1922 {
1923 super.RemoveOldItemFromLocation();
1924 m_Player.GetHumanInventory().OnEntityInHandsDestroyed(m_OldLocation);
1925 }
1926}
1927
1928// This was created since IsObjectObstructed is often called multiple times in one frame
1929// And apparently it seems that keeping this data in one struct seems to be more efficient than creating the variables dozens of times per frame
1930class IsObjectObstructedCache // Pretending this is a struct
1931{
1932 // Outside data
1935
1936 // Inside data
1942 ref set<Object> HitObjects = new set<Object>;
1943
1944 void IsObjectObstructedCache(vector rayCastStart, int totalObjects)
1945 {
1946 RaycastStart = rayCastStart;
1947 TotalObjects = totalObjects;
1948 }
1949
1950 // Only inside data
1952 {
1953 ObjectCenterPos = "0 0 0";
1954 ObjectContactPos = "0 0 0";
1955 ObjectContactDir = "0 0 0";
1956 ContactComponent = -1;
1957 HitProxyObjects.Clear();
1958 HitObjects.Clear();
1959 }
1960}
InventoryMode
NOTE: PREDICTIVE is not to be used at all in multiplayer.
Definition inventory.c:22
override void OnSuccess(EntityAI new_item)
const int ECE_NONE
const int ECE_PLACE_ON_SURFACE
const int ECE_UPDATEPATHGRAPH
const int RF_DEFAULT
const int ECE_CREATEPHYSICS
override bool IsPlayerInside(PlayerBase player, string selection)
Definition fence.c:615
override bool IsFacingCamera(string selection)
Definition fence.c:678
proto native float SurfaceY(float x, float z)
proto void SurfaceUnderObject(notnull Object object, out string type, out int liquidType)
Super root of all classes in Enforce script.
Definition enscript.c:11
void SwitchOn()
Energy manager: Switches ON the device so it starts doing its work if it has enough energy.
float GetEnergy()
Energy manager: Returns the amount of stored energy this device has.
void SetEnergy(float new_energy)
Energy manager: Sets stored energy for this device. It ignores the min/max limit!
bool IsSwitchedOn()
Energy manager: Returns state of the switch. Whenever the device is working or not does not matter....
ConstructionPart GetBuildPartNoToolAtIndex(int idx)
void SetTarget(Object target)
ConstructionPart GetBuildPartAtIndex(int idx)
override void OnItemInHandsChanged()
Definition debug.c:2
this one is a bit special: it drops all items and destroys the ex-root of the hierarchy
override bool CanDecay()
void TransferFoodStage(notnull Edible_Base source)
override bool IsBaseFireplace()
override bool IsIndoorOven()
Definition ovenindoor.c:159
override bool IsBarrelWithHoles()
script counterpart to engine's class Inventory
Definition inventory.c:79
static proto native bool PrepareDropEntityPos(EntityAI owner, notnull EntityAI item, out vector mat[4], bool useValuesInMatrix=false, int conflictCheckDepth=-1)
Finds a transformation for the item to be dropped to If the initial transforation overlaps with anoth...
static proto native EntityAI LocationCreateEntity(notnull InventoryLocation inv_loc, string type, int iSetupFlags, int iRotation)
creates new item directly at location
static proto native bool LocationCanAddEntity(notnull InventoryLocation inv_loc)
queries if the entity contained in inv_loc.m_item can be added to ground/attachment/cargo/hands/....
InventoryLocation.
provides access to slot configuration
Definition enmath.c:7
this one is a also bit special: it moves all items to already existing item and destroys the ex-root ...
base class for transformation operations (creating one item from another)
void CreateNetworkObjectInfo(EntityAI new_item)
Step G. - create NetworkObjectInfo for new item.
void CopyOldPropertiesToNew(notnull EntityAI old_item, EntityAI new_item)
Step E. copy properties from old object to the created one.
void RemoveNetworkObjectInfo()
Step C. - remove network part of the object @NOTE this operation does not delete the object,...
adds automatic QuickBar handling
float GetColdAreaToolDamageModifier()
Definition worlddata.c:262
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
void Construction(BaseBuildingBase parent)
DayZGame g_Game
Definition dayzgame.c:3868
proto native int GetComponentIndex()
DayZPlayerConstants
defined in C++
Definition dayzplayer.c:602
bool IsUnderRoof()
Is character under roof (periodically checked - GameConstants.ENVIRO_TICK_ROOF_RC_CHECK)....
ERPCs
Definition erpcs.c:2
const int INDEX_NOT_FOUND
Definition gameplay.c:13
InventoryTraversalType
tree traversal type, for more see http://en.wikipedia.org/wiki/Tree_traversal
Definition gameplay.c:6
proto native CGame GetGame()
void Error(string err)
Messagebox with error message.
Definition endebug.c:90
CollisionFlags
Definition endebug.c:141
const float PROJECTED_CURSOR_DISTANCE
Definition constants.c:640
array< string > TStringArray
Definition enscript.c:709
array< int > TIntArray
Definition enscript.c:711
proto native IEntity GetSibling()
Returns pointer to next child Entity on the same hierarchy.
proto native IEntity GetChildren()
Returns pointer to first child Entity in hierarchy.
const int VARIABLE_QUANTITY
Definition constants.c:628
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
const string CFG_VEHICLESPATH
Definition constants.c:220
const string CFG_WEAPONSPATH
Definition constants.c:221
const string CFG_MAGAZINESPATH
Definition constants.c:222
proto native vector GetVelocity(notnull IEntity ent)
Returns linear velocity.
proto void dBodyApplyImpulse(notnull IEntity body, vector impulse)
Applies impuls on a rigidbody (origin)
DayZPlayer m_Player
Definition hand_events.c:42
Empty
Definition hand_states.c:14
Icon x
Icon y
InventoryLocationType
types of Inventory Location
string GetColorString()
Returns item's PROCEDURAL color as formated string, i.e. "#(argb,8,8,3)color(0.15,...
Definition itembase.c:8660
PlayerBase m_Player
ref array< ref RaycastRVResult > HitProxyObjects
DestroyItemInCorpsesHandsAndCreateNewOnGndLambda RaycastStart
TransferInventoryResult
int TotalObjects
EntityAI m_NewItem
vector ObjectContactDir
vector ObjectContactPos
enum ThrowEntityFlags Truncate(float value, int decimals=2)
truncate float to specified precision
vector ObjectCenterPos
ref set< Object > HitObjects
void MoveEquipToExistingItemAndDestroyOldRootLambda(EntityAI old_item, string new_item_type, PlayerBase player, EntityAI new_item)
void IsObjectObstructedCache(vector rayCastStart, int totalObjects)
int ContactComponent
void ClearCache()
override void CopyOldPropertiesToNew(notnull EntityAI old_item, EntityAI new_item)
PlayerBase GetPlayer()
class NoiseSystem NoiseParams()
Definition noise.c:15
class OptionSelectorMultistate extends OptionSelector class_name
PersistentFlag
DebugActionType
PluginBase GetPlugin(typename plugin_type)
float GetMinValue()
float GetMaxValue()