DayZ 1.28
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено

◆ OnWasAttached()

override void SpawnItemOnLocation::OnWasAttached ( EntityAI parent,
int slot_id )
private

См. определение в файле ItemBase.c строка 6219

6223{
6224 override bool CanPutAsAttachment(EntityAI parent)
6225 {
6226 return true;
6227 }
6228};
6229
6230//const bool QUANTITY_DEBUG_REMOVE_ME = false;
6231
6232class ItemBase extends InventoryItem
6233{
6237
6239
6240 static int m_DebugActionsMask;
6242 // ============================================
6243 // Variable Manipulation System
6244 // ============================================
6245 // Quantity
6246
6247 float m_VarQuantity;
6248 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
6250 int m_VarQuantityMin;
6251 int m_VarQuantityMax;
6252 int m_Count;
6253 float m_VarStackMax;
6254 float m_StoreLoadedQuantity = float.LOWEST;
6255 // Wet
6256 float m_VarWet;
6257 float m_VarWetPrev;//for client to know wetness changed during synchronization
6258 float m_VarWetInit;
6259 float m_VarWetMin;
6260 float m_VarWetMax;
6261 // Cleanness
6262 int m_Cleanness;
6263 int m_CleannessInit;
6264 int m_CleannessMin;
6265 int m_CleannessMax;
6266 // impact sounds
6268 bool m_CanPlayImpactSound = true;
6269 float m_ImpactSpeed;
6271 //
6272 float m_HeatIsolation;
6273 float m_ItemModelLength;
6274 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
6276 int m_VarLiquidType;
6277 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
6278 int m_QuickBarBonus;
6279 bool m_IsBeingPlaced;
6280 bool m_IsHologram;
6281 bool m_IsTakeable;
6282 bool m_ThrowItemOnDrop;
6285 bool m_FixDamageSystemInit = false; //can be changed on storage version check
6286 bool can_this_be_combined; //Check if item can be combined
6287 bool m_CanThisBeSplit; //Check if item can be split
6288 bool m_IsStoreLoad = false;
6289 bool m_CanShowQuantity;
6290 bool m_HasQuantityBar;
6291 protected bool m_CanBeDigged;
6292 protected bool m_IsResultOfSplit
6293
6294 string m_SoundAttType;
6295 // items color variables
6300 //-------------------------------------------------------
6301
6302 // light source managing
6304
6308
6309 //==============================================
6310 // agent system
6311 private int m_AttachedAgents;
6312
6314 void TransferModifiers(PlayerBase reciever);
6315
6316
6317 // Weapons & suppressors particle effects
6322 static int m_LastRegisteredWeaponID = 0;
6323
6324 // Overheating effects
6326 float m_OverheatingShots;
6327 ref Timer m_CheckOverheating;
6328 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
6329 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
6330 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
6331 ref array <ref OverheatingParticle> m_OverheatingParticles;
6332
6334 protected bool m_HideSelectionsBySlot;
6335
6336 // Admin Log
6337 PluginAdminLog m_AdminLog;
6338
6339 // misc
6340 ref Timer m_PhysDropTimer;
6341
6342 // Attachment Locking variables
6343 ref array<int> m_CompatibleLocks;
6344 protected int m_LockType;
6345 protected ref EffectSound m_LockingSound;
6346 protected string m_LockSoundSet;
6347
6348 // ItemSoundHandler
6349 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
6350 protected int m_SoundSyncPlay; // id for sound to play
6351 protected int m_SoundSyncStop; // id for sound to stop
6353
6354 //temperature
6355 private float m_TemperaturePerQuantityWeight;
6356
6357 // -------------------------------------------------------------------------
6358 void ItemBase()
6359 {
6360 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
6364
6365 if (!GetGame().IsDedicatedServer())
6366 {
6367 if (HasMuzzle())
6368 {
6370
6372 {
6374 }
6375 }
6376
6378 m_ActionsInitialize = false;
6379 }
6380
6381 m_OldLocation = null;
6382
6383 if (GetGame().IsServer())
6384 {
6385 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
6386 }
6387
6388 if (ConfigIsExisting("headSelectionsToHide"))
6389 {
6391 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
6392 }
6393
6394 m_HideSelectionsBySlot = false;
6395 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
6396 {
6397 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
6398 }
6399
6400 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
6401
6402 m_IsResultOfSplit = false;
6403
6405 }
6406
6407 override void InitItemVariables()
6408 {
6409 super.InitItemVariables();
6410
6411 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
6412 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
6413 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
6414 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
6415 m_VarStackMax = ConfigGetFloat("varStackMax");
6416 m_Count = ConfigGetInt("count");
6417
6418 m_CanShowQuantity = ConfigGetBool("quantityShow");
6419 m_HasQuantityBar = ConfigGetBool("quantityBar");
6420
6421 m_CleannessInit = ConfigGetInt("varCleannessInit");
6423 m_CleannessMin = ConfigGetInt("varCleannessMin");
6424 m_CleannessMax = ConfigGetInt("varCleannessMax");
6425
6426 m_WantPlayImpactSound = false;
6427 m_ImpactSpeed = 0.0;
6428
6429 m_VarWetInit = ConfigGetFloat("varWetInit");
6431 m_VarWetMin = ConfigGetFloat("varWetMin");
6432 m_VarWetMax = ConfigGetFloat("varWetMax");
6433
6434 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
6435 if (IsLiquidContainer() && GetQuantity() != 0)
6437 m_IsBeingPlaced = false;
6438 m_IsHologram = false;
6439 m_IsTakeable = true;
6440 m_CanBeMovedOverride = false;
6444 m_CanBeDigged = ConfigGetBool("canBeDigged");
6445
6446 m_CompatibleLocks = new array<int>();
6447 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
6448 m_LockType = ConfigGetInt("lockType");
6449
6450 //Define if item can be split and set ability to be combined accordingly
6451 m_CanThisBeSplit = false;
6452 can_this_be_combined = false;
6453 if (ConfigIsExisting("canBeSplit"))
6454 {
6455 can_this_be_combined = ConfigGetBool("canBeSplit");
6457 }
6458
6459 m_ItemBehaviour = -1;
6460 if (ConfigIsExisting("itemBehaviour"))
6461 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
6462
6463 //RegisterNetSyncVariableInt("m_VariablesMask");
6464 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
6465 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
6466 RegisterNetSyncVariableInt("m_VarLiquidType");
6467 RegisterNetSyncVariableInt("m_Cleanness",0,1);
6468
6469 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
6470 RegisterNetSyncVariableFloat("m_ImpactSpeed");
6471 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
6472
6473 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
6474 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
6475 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
6476 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
6477
6478 RegisterNetSyncVariableBool("m_IsBeingPlaced");
6479 RegisterNetSyncVariableBool("m_IsTakeable");
6480 RegisterNetSyncVariableBool("m_IsHologram");
6481
6482 InitItemSounds();
6484 {
6485 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
6486 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
6487 }
6488
6489 m_LockSoundSet = ConfigGetString("lockSoundSet");
6490
6492 if (ConfigIsExisting("temperaturePerQuantityWeight"))
6493 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
6494
6495 }
6496
6497 override int GetQuickBarBonus()
6498 {
6499 return m_QuickBarBonus;
6500 }
6501
6502 void InitializeActions()
6503 {
6505 if (!m_InputActionMap)
6506 {
6508 m_InputActionMap = iam;
6509 SetActions();
6511 }
6512 }
6513
6514 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
6515 {
6517 {
6518 m_ActionsInitialize = true;
6520 }
6521
6522 actions = m_InputActionMap.Get(action_input_type);
6523 }
6524
6525 void SetActions()
6526 {
6527 AddAction(ActionTakeItem);
6528 AddAction(ActionTakeItemToHands);
6529 AddAction(ActionWorldCraft);
6531 AddAction(ActionAttachWithSwitch);
6532 }
6533
6534 void SetActionAnimOverrides(); // Override action animation for specific item
6535
6536 void AddAction(typename actionName)
6537 {
6538 ActionBase action = ActionManagerBase.GetAction(actionName);
6539
6540 if (!action)
6541 {
6542 Debug.LogError("Action " + actionName + " dosn't exist!");
6543 return;
6544 }
6545
6546 typename ai = action.GetInputType();
6547 if (!ai)
6548 {
6549 m_ActionsInitialize = false;
6550 return;
6551 }
6552
6553 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
6554 if (!action_array)
6555 {
6556 action_array = new array<ActionBase_Basic>;
6557 m_InputActionMap.Insert(ai, action_array);
6558 }
6559 if (LogManager.IsActionLogEnable())
6560 {
6561 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
6562 }
6563
6564 if (action_array.Find(action) != -1)
6565 {
6566 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
6567 }
6568 else
6569 {
6570 action_array.Insert(action);
6571 }
6572 }
6573
6574 void RemoveAction(typename actionName)
6575 {
6576 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
6577 ActionBase action = player.GetActionManager().GetAction(actionName);
6578 typename ai = action.GetInputType();
6579 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
6580
6581 if (action_array)
6582 {
6583 action_array.RemoveItem(action);
6584 }
6585 }
6586
6587 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
6588 // Set -1 for params which should stay in default state
6589 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
6590 {
6591 ActionOverrideData overrideData = new ActionOverrideData();
6592 overrideData.m_CommandUID = commandUID;
6593 overrideData.m_CommandUIDProne = commandUIDProne;
6594 overrideData.m_StanceMask = stanceMask;
6595
6596 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
6597 if (!actionMap) // create new map of action > overidables map
6598 {
6599 actionMap = new TActionAnimOverrideMap();
6600 m_ItemActionOverrides.Insert(action, actionMap);
6601 }
6602
6603 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
6604
6605 }
6606
6607 void OnItemInHandsPlayerSwimStart(PlayerBase player);
6608
6609 ScriptedLightBase GetLight();
6610
6611 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6612 void LoadParticleConfigOnFire(int id)
6613 {
6614 if (!m_OnFireEffect)
6616
6619
6620 string config_to_search = "CfgVehicles";
6621 string muzzle_owner_config;
6622
6623 if (!m_OnFireEffect.Contains(id))
6624 {
6625 if (IsInherited(Weapon))
6626 config_to_search = "CfgWeapons";
6627
6628 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6629
6630 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
6631
6632 int config_OnFire_subclass_count = GetGame().ConfigGetChildrenCount(config_OnFire_class);
6633
6634 if (config_OnFire_subclass_count > 0)
6635 {
6636 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
6637
6638 for (int i = 0; i < config_OnFire_subclass_count; i++)
6639 {
6640 string particle_class = "";
6641 GetGame().ConfigGetChildName(config_OnFire_class, i, particle_class);
6642 string config_OnFire_entry = config_OnFire_class + particle_class;
6643 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
6644 WPOF_array.Insert(WPOF);
6645 }
6646
6647
6648 m_OnFireEffect.Insert(id, WPOF_array);
6649 }
6650 }
6651
6652 if (!m_OnBulletCasingEjectEffect.Contains(id))
6653 {
6654 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
6655 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6656
6657 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
6658
6659 int config_OnBulletCasingEject_count = GetGame().ConfigGetChildrenCount(config_OnBulletCasingEject_class);
6660
6661 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
6662 {
6663 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
6664
6665 for (i = 0; i < config_OnBulletCasingEject_count; i++)
6666 {
6667 string particle_class2 = "";
6668 GetGame().ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
6669 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
6670 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
6671 WPOBE_array.Insert(WPOBE);
6672 }
6673
6674
6675 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
6676 }
6677 }
6678 }
6679
6680 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6682 {
6685
6686 if (!m_OnOverheatingEffect.Contains(id))
6687 {
6688 string config_to_search = "CfgVehicles";
6689
6690 if (IsInherited(Weapon))
6691 config_to_search = "CfgWeapons";
6692
6693 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
6694 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
6695
6696 if (GetGame().ConfigIsExisting(config_OnOverheating_class))
6697 {
6698
6699 m_ShotsToStartOverheating = GetGame().ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
6700
6702 {
6703 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
6704 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
6705 Error(error);
6706 return;
6707 }
6708
6709 m_OverheatingDecayInterval = GetGame().ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
6710 m_MaxOverheatingValue = GetGame().ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
6711
6712
6713
6714 int config_OnOverheating_subclass_count = GetGame().ConfigGetChildrenCount(config_OnOverheating_class);
6715 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
6716
6717 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
6718 {
6719 string particle_class = "";
6720 GetGame().ConfigGetChildName(config_OnOverheating_class, i, particle_class);
6721 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
6722 int entry_type = GetGame().ConfigGetType(config_OnOverheating_entry);
6723
6724 if (entry_type == CT_CLASS)
6725 {
6726 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
6727 WPOOH_array.Insert(WPOF);
6728 }
6729 }
6730
6731
6732 m_OnOverheatingEffect.Insert(id, WPOOH_array);
6733 }
6734 }
6735 }
6736
6737 float GetOverheatingValue()
6738 {
6739 return m_OverheatingShots;
6740 }
6741
6742 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
6743 {
6744 if (m_MaxOverheatingValue > 0)
6745 {
6747
6748 if (!m_CheckOverheating)
6750
6752 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6753
6754 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6755 }
6756 }
6757
6758 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6759 {
6761 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6762
6764 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6765
6767 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6768
6770 {
6772 }
6773 }
6774
6776 {
6778 }
6779
6780 void OnOverheatingDecay()
6781 {
6782 if (m_MaxOverheatingValue > 0)
6783 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
6784 else
6786
6787 if (m_OverheatingShots <= 0)
6788 {
6791 }
6792 else
6793 {
6794 if (!m_CheckOverheating)
6796
6798 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6799 }
6800
6801 CheckOverheating(this, "", this);
6802 }
6803
6804 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6805 {
6807 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6808 }
6809
6810 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6811 {
6813 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6815 }
6816
6817 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6818 {
6820 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6821 }
6822
6823 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
6824 {
6826 m_OverheatingParticles = new array<ref OverheatingParticle>;
6827
6828 OverheatingParticle OP = new OverheatingParticle();
6829 OP.RegisterParticle(p);
6830 OP.SetOverheatingLimitMin(min_heat_coef);
6831 OP.SetOverheatingLimitMax(max_heat_coef);
6832 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
6833
6834 m_OverheatingParticles.Insert(OP);
6835 }
6836
6837 float GetOverheatingCoef()
6838 {
6839 if (m_MaxOverheatingValue > 0)
6841
6842 return -1;
6843 }
6844
6846 {
6848 {
6849 float overheat_coef = GetOverheatingCoef();
6850 int count = m_OverheatingParticles.Count();
6851
6852 for (int i = count; i > 0; --i)
6853 {
6854 int id = i - 1;
6855 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6856 Particle p = OP.GetParticle();
6857
6858 float overheat_min = OP.GetOverheatingLimitMin();
6859 float overheat_max = OP.GetOverheatingLimitMax();
6860
6861 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
6862 {
6863 if (p)
6864 {
6865 p.Stop();
6866 OP.RegisterParticle(null);
6867 }
6868 }
6869 }
6870 }
6871 }
6872
6874 {
6876 {
6877 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
6878 {
6879 int id = i - 1;
6880 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6881
6882 if (OP)
6883 {
6884 Particle p = OP.GetParticle();
6885
6886 if (p)
6887 {
6888 p.Stop();
6889 }
6890
6891 delete OP;
6892 }
6893 }
6894
6895 m_OverheatingParticles.Clear();
6897 }
6898 }
6899
6901 float GetInfectionChance(int system = 0, Param param = null)
6902 {
6903 return 0.0;
6904 }
6905
6906
6907 float GetDisinfectQuantity(int system = 0, Param param1 = null)
6908 {
6909 return 250;//default value
6910 }
6911
6912 float GetFilterDamageRatio()
6913 {
6914 return 0;
6915 }
6916
6918 bool HasMuzzle()
6919 {
6920 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
6921 return true;
6922
6923 return false;
6924 }
6925
6927 int GetMuzzleID()
6928 {
6929 if (!m_WeaponTypeToID)
6931
6932 if (m_WeaponTypeToID.Contains(GetType()))
6933 {
6934 return m_WeaponTypeToID.Get(GetType());
6935 }
6936 else
6937 {
6938 // Register new weapon ID
6940 }
6941
6943 }
6944
6951 {
6952 return -1;
6953 }
6954
6955
6956
6957 // -------------------------------------------------------------------------
6958 void ~ItemBase()
6959 {
6960 if (GetGame() && GetGame().GetPlayer() && (!GetGame().IsDedicatedServer()))
6961 {
6962 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
6963 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
6964
6965 if (r_index >= 0)
6966 {
6967 InventoryLocation r_il = new InventoryLocation;
6968 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
6969
6970 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
6971 int r_type = r_il.GetType();
6972 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
6973 {
6974 r_il.GetParent().GetOnReleaseLock().Invoke(this);
6975 }
6976 else if (r_type == InventoryLocationType.ATTACHMENT)
6977 {
6978 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
6979 }
6980
6981 }
6982
6983 player.GetHumanInventory().ClearUserReservedLocation(this);
6984 }
6985
6986 if (m_LockingSound)
6987 SEffectManager.DestroyEffect(m_LockingSound);
6988 }
6989
6990
6991
6992 // -------------------------------------------------------------------------
6993 static int GetDebugActionsMask()
6994 {
6995 return ItemBase.m_DebugActionsMask;
6996 }
6997
6998 static bool HasDebugActionsMask(int mask)
6999 {
7000 return ItemBase.m_DebugActionsMask & mask;
7001 }
7002
7003 static void SetDebugActionsMask(int mask)
7004 {
7005 ItemBase.m_DebugActionsMask = mask;
7006 }
7007
7008 static void AddDebugActionsMask(int mask)
7009 {
7010 ItemBase.m_DebugActionsMask |= mask;
7011 }
7012
7013 static void RemoveDebugActionsMask(int mask)
7014 {
7015 ItemBase.m_DebugActionsMask &= ~mask;
7016 }
7017
7018 static void ToggleDebugActionsMask(int mask)
7019 {
7020 if (HasDebugActionsMask(mask))
7021 {
7023 }
7024 else
7025 {
7026 AddDebugActionsMask(mask);
7027 }
7028 }
7029
7030 // -------------------------------------------------------------------------
7031 void SetCEBasedQuantity()
7032 {
7033 if (GetEconomyProfile())
7034 {
7035 float q_max = GetEconomyProfile().GetQuantityMax();
7036 if (q_max > 0)
7037 {
7038 float q_min = GetEconomyProfile().GetQuantityMin();
7039 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
7040
7041 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
7042 {
7043 ComponentEnergyManager comp = GetCompEM();
7044 if (comp && (comp.GetEnergyMaxPristine() || comp.GetEnergyAtSpawn()))//checking for a potential for energy, we need to check both values, as both are optional, only when both are set to 0, we know the item can't have energy
7045 {
7046 comp.SetEnergy0To1(quantity_randomized);
7047 }
7048 }
7049 else if (HasQuantity())
7050 {
7051 SetQuantityNormalized(quantity_randomized, false);
7052 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
7053 }
7054
7055 }
7056 }
7057 }
7058
7060 void LockToParent()
7061 {
7062 EntityAI parent = GetHierarchyParent();
7063
7064 if (parent)
7065 {
7066 InventoryLocation inventory_location_to_lock = new InventoryLocation;
7067 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
7068 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
7069 }
7070 }
7071
7073 void UnlockFromParent()
7074 {
7075 EntityAI parent = GetHierarchyParent();
7076
7077 if (parent)
7078 {
7079 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
7080 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
7081 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
7082 }
7083 }
7084
7085 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
7086 {
7087 /*
7088 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
7089 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, GetGame().GetPlayer());
7090 */
7091 ItemBase item2 = ItemBase.Cast(entity2);
7092
7093 if (GetGame().IsClient())
7094 {
7095 if (ScriptInputUserData.CanStoreInputUserData())
7096 {
7097 ScriptInputUserData ctx = new ScriptInputUserData;
7099 ctx.Write(-1);
7100 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7101 ctx.Write(i1);
7102 ctx.Write(item2);
7103 ctx.Write(use_stack_max);
7104 ctx.Write(-1);
7105 ctx.Send();
7106
7107 if (IsCombineAll(item2, use_stack_max))
7108 {
7109 GetGame().GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
7110 }
7111 }
7112 }
7113 else if (!GetGame().IsMultiplayer())
7114 {
7115 CombineItems(item2, use_stack_max);
7116 }
7117 }
7118
7119 bool IsLiquidPresent()
7120 {
7121 return (GetLiquidType() != 0 && HasQuantity());
7122 }
7123
7124 bool IsLiquidContainer()
7125 {
7126 return m_LiquidContainerMask != 0;
7127 }
7128
7130 {
7131 return m_LiquidContainerMask;
7132 }
7133
7134 bool IsBloodContainer()
7135 {
7136 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
7137 return false;
7138 }
7139
7140 bool IsNVG()
7141 {
7142 return false;
7143 }
7144
7147 bool IsExplosive()
7148 {
7149 return false;
7150 }
7151
7153 {
7154 return "";
7155 }
7156
7158
7159 bool IsLightSource()
7160 {
7161 return false;
7162 }
7163
7165 {
7166 return true;
7167 }
7168
7169 //--- ACTION CONDITIONS
7170 //direction
7171 bool IsFacingPlayer(PlayerBase player, string selection)
7172 {
7173 return true;
7174 }
7175
7176 bool IsPlayerInside(PlayerBase player, string selection)
7177 {
7178 return true;
7179 }
7180
7181 override bool CanObstruct()
7182 {
7183 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7184 return !player || !IsPlayerInside(player, "");
7185 }
7186
7187 override bool IsBeingPlaced()
7188 {
7189 return m_IsBeingPlaced;
7190 }
7191
7192 void SetIsBeingPlaced(bool is_being_placed)
7193 {
7194 m_IsBeingPlaced = is_being_placed;
7195 if (!is_being_placed)
7197 SetSynchDirty();
7198 }
7199
7200 //server-side
7201 void OnEndPlacement() {}
7202
7203 override bool IsHologram()
7204 {
7205 return m_IsHologram;
7206 }
7207
7208 bool CanBeDigged()
7209 {
7210 return m_CanBeDigged;
7211 }
7212
7214 {
7215 return 1;
7216 }
7217
7218 bool CanMakeGardenplot()
7219 {
7220 return false;
7221 }
7222
7223 void SetIsHologram(bool is_hologram)
7224 {
7225 m_IsHologram = is_hologram;
7226 SetSynchDirty();
7227 }
7228 /*
7229 protected float GetNutritionalEnergy()
7230 {
7231 Edible_Base edible = Edible_Base.Cast(this);
7232 return edible.GetFoodEnergy();
7233 }
7234
7235 protected float GetNutritionalWaterContent()
7236 {
7237 Edible_Base edible = Edible_Base.Cast(this);
7238 return edible.GetFoodWater();
7239 }
7240
7241 protected float GetNutritionalIndex()
7242 {
7243 Edible_Base edible = Edible_Base.Cast(this);
7244 return edible.GetFoodNutritionalIndex();
7245 }
7246
7247 protected float GetNutritionalFullnessIndex()
7248 {
7249 Edible_Base edible = Edible_Base.Cast(this);
7250 return edible.GetFoodTotalVolume();
7251 }
7252
7253 protected float GetNutritionalToxicity()
7254 {
7255 Edible_Base edible = Edible_Base.Cast(this);
7256 return edible.GetFoodToxicity();
7257
7258 }
7259 */
7260
7261
7262 // -------------------------------------------------------------------------
7263 override void OnMovedInsideCargo(EntityAI container)
7264 {
7265 super.OnMovedInsideCargo(container);
7266
7267 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
7268 }
7269
7270 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
7271 {
7272 super.EEItemLocationChanged(oldLoc,newLoc);
7273
7274 PlayerBase new_player = null;
7275 PlayerBase old_player = null;
7276
7277 if (newLoc.GetParent())
7278 new_player = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
7279
7280 if (oldLoc.GetParent())
7281 old_player = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
7282
7283 if (old_player && oldLoc.GetType() == InventoryLocationType.HANDS)
7284 {
7285 int r_index = old_player.GetHumanInventory().FindUserReservedLocationIndex(this);
7286
7287 if (r_index >= 0)
7288 {
7289 InventoryLocation r_il = new InventoryLocation;
7290 old_player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
7291
7292 old_player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
7293 int r_type = r_il.GetType();
7294 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
7295 {
7296 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7297 }
7298 else if (r_type == InventoryLocationType.ATTACHMENT)
7299 {
7300 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7301 }
7302
7303 }
7304 }
7305
7306 if (newLoc.GetType() == InventoryLocationType.HANDS)
7307 {
7308 if (new_player)
7309 new_player.ForceStandUpForHeavyItems(newLoc.GetItem());
7310
7311 if (new_player == old_player)
7312 {
7313
7314 if (oldLoc.GetParent() && new_player.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
7315 {
7316 if (oldLoc.GetType() == InventoryLocationType.CARGO)
7317 {
7318 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
7319 {
7320 new_player.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
7321 }
7322 }
7323 else
7324 {
7325 new_player.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
7326 }
7327 }
7328
7329 if (new_player.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
7330 {
7331 int type = oldLoc.GetType();
7332 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
7333 {
7334 oldLoc.GetParent().GetOnSetLock().Invoke(this);
7335 }
7336 else if (type == InventoryLocationType.ATTACHMENT)
7337 {
7338 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
7339 }
7340 }
7341 if (!m_OldLocation)
7342 {
7343 m_OldLocation = new InventoryLocation;
7344 }
7345 m_OldLocation.Copy(oldLoc);
7346 }
7347 else
7348 {
7349 if (m_OldLocation)
7350 {
7351 m_OldLocation.Reset();
7352 }
7353 }
7354
7356 }
7357 else
7358 {
7359 if (new_player)
7360 {
7361 int res_index = new_player.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
7362 if (res_index >= 0)
7363 {
7364 InventoryLocation il = new InventoryLocation;
7365 new_player.GetHumanInventory().GetUserReservedLocation(res_index,il);
7366 ItemBase it = ItemBase.Cast(il.GetItem());
7367 new_player.GetHumanInventory().ClearUserReservedLocationAtIndex(res_index);
7368 int rel_type = il.GetType();
7369 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
7370 {
7371 il.GetParent().GetOnReleaseLock().Invoke(it);
7372 }
7373 else if (rel_type == InventoryLocationType.ATTACHMENT)
7374 {
7375 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
7376 }
7377 //it.GetOnReleaseLock().Invoke(it);
7378 }
7379 }
7380 else if (old_player && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
7381 {
7382 //ThrowPhysically(old_player, vector.Zero);
7383 m_ThrowItemOnDrop = false;
7384 }
7385
7386 if (m_OldLocation)
7387 {
7388 m_OldLocation.Reset();
7389 }
7390 }
7391 }
7392
7393 override void EOnContact(IEntity other, Contact extra)
7394 {
7396 {
7397 int liquidType = -1;
7398 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
7399 if (impactSpeed > 0.0)
7400 {
7401 m_ImpactSpeed = impactSpeed;
7402 #ifndef SERVER
7403 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
7404 #else
7405 m_WantPlayImpactSound = true;
7406 SetSynchDirty();
7407 #endif
7408 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
7409 }
7410 }
7411
7412 #ifdef SERVER
7413 if (GetCompEM() && GetCompEM().IsPlugged())
7414 {
7415 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
7416 GetCompEM().UnplugThis();
7417 }
7418 #endif
7419 }
7420
7421 void RefreshPhysics();
7422
7423 override void OnCreatePhysics()
7424 {
7426 }
7427
7428 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
7429 {
7430
7431 }
7432 // -------------------------------------------------------------------------
7433 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
7434 {
7435 super.OnItemLocationChanged(old_owner, new_owner);
7436
7437 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
7438 PlayerBase playerNew = PlayerBase.Cast(new_owner);
7439
7440 if (!relatedPlayer && playerNew)
7441 relatedPlayer = playerNew;
7442
7443 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
7444 {
7445 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
7446 if (actionMgr)
7447 {
7448 ActionBase currentAction = actionMgr.GetRunningAction();
7449 if (currentAction)
7450 currentAction.OnItemLocationChanged(this);
7451 }
7452 }
7453
7454 Man ownerPlayerOld = null;
7455 Man ownerPlayerNew = null;
7456
7457 if (old_owner)
7458 {
7459 if (old_owner.IsMan())
7460 {
7461 ownerPlayerOld = Man.Cast(old_owner);
7462 }
7463 else
7464 {
7465 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
7466 }
7467 }
7468 else
7469 {
7470 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
7471 {
7472 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
7473
7474 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
7475 {
7476 GetCompEM().UnplugThis();
7477 }
7478 }
7479 }
7480
7481 if (new_owner)
7482 {
7483 if (new_owner.IsMan())
7484 {
7485 ownerPlayerNew = Man.Cast(new_owner);
7486 }
7487 else
7488 {
7489 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
7490 }
7491 }
7492
7493 if (ownerPlayerOld != ownerPlayerNew)
7494 {
7495 if (ownerPlayerOld)
7496 {
7497 array<EntityAI> subItemsExit = new array<EntityAI>;
7498 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
7499 for (int i = 0; i < subItemsExit.Count(); i++)
7500 {
7501 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
7502 itemExit.OnInventoryExit(ownerPlayerOld);
7503 }
7504 }
7505
7506 if (ownerPlayerNew)
7507 {
7508 array<EntityAI> subItemsEnter = new array<EntityAI>;
7509 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
7510 for (int j = 0; j < subItemsEnter.Count(); j++)
7511 {
7512 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
7513 itemEnter.OnInventoryEnter(ownerPlayerNew);
7514 }
7515 }
7516 }
7517 else if (ownerPlayerNew != null)
7518 {
7519 PlayerBase nplayer;
7520 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
7521 {
7522 array<EntityAI> subItemsUpdate = new array<EntityAI>;
7523 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
7524 for (int k = 0; k < subItemsUpdate.Count(); k++)
7525 {
7526 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
7527 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
7528 }
7529 }
7530 }
7531
7532 if (old_owner)
7533 old_owner.OnChildItemRemoved(this);
7534 if (new_owner)
7535 new_owner.OnChildItemReceived(this);
7536 }
7537
7538 // -------------------------------------------------------------------------------
7539 override void EEDelete(EntityAI parent)
7540 {
7541 super.EEDelete(parent);
7542 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
7543 if (player)
7544 {
7545 OnInventoryExit(player);
7546
7547 if (player.IsAlive())
7548 {
7549 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
7550 if (r_index >= 0)
7551 {
7552 InventoryLocation r_il = new InventoryLocation;
7553 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
7554
7555 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
7556 int r_type = r_il.GetType();
7557 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
7558 {
7559 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7560 }
7561 else if (r_type == InventoryLocationType.ATTACHMENT)
7562 {
7563 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7564 }
7565
7566 }
7567
7568 player.RemoveQuickBarEntityShortcut(this);
7569 }
7570 }
7571 }
7572 // -------------------------------------------------------------------------------
7573 override void EEKilled(Object killer)
7574 {
7575 super.EEKilled(killer);
7576
7578 if (killer && killer.IsFireplace() && CanExplodeInFire())
7579 {
7580 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
7581 {
7582 if (IsMagazine())
7583 {
7584 if (Magazine.Cast(this).GetAmmoCount() > 0)
7585 {
7586 ExplodeAmmo();
7587 }
7588 }
7589 else
7590 {
7591 Explode(DamageType.EXPLOSION);
7592 }
7593 }
7594 }
7595 }
7596
7597 override void OnWasAttached(EntityAI parent, int slot_id)
7598 {
7599 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
7600
7601 super.OnWasAttached(parent, slot_id);
7602
7603 if (HasQuantity())
7604 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7605
7606 PlayAttachSound(InventorySlots.GetSlotName(slot_id));
7607 }
7608
7609 override void OnWasDetached(EntityAI parent, int slot_id)
7610 {
7611 super.OnWasDetached(parent, slot_id);
7612
7613 if (HasQuantity())
7614 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7615 }
7616
7617 override string ChangeIntoOnAttach(string slot)
7618 {
7619 int idx;
7620 TStringArray inventory_slots = new TStringArray;
7621 TStringArray attach_types = new TStringArray;
7622
7623 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7624 if (inventory_slots.Count() < 1) //is string
7625 {
7626 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
7627 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
7628 }
7629 else //is array
7630 {
7631 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
7632 }
7633
7634 idx = inventory_slots.Find(slot);
7635 if (idx < 0)
7636 return "";
7637
7638 return attach_types.Get(idx);
7639 }
7640
7641 override string ChangeIntoOnDetach()
7642 {
7643 int idx = -1;
7644 string slot;
7645
7646 TStringArray inventory_slots = new TStringArray;
7647 TStringArray detach_types = new TStringArray;
7648
7649 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7650 if (inventory_slots.Count() < 1) //is string
7651 {
7652 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
7653 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7654 }
7655 else //is array
7656 {
7657 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
7658 if (detach_types.Count() < 1)
7659 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7660 }
7661
7662 for (int i = 0; i < inventory_slots.Count(); i++)
7663 {
7664 slot = inventory_slots.Get(i);
7665 }
7666
7667 if (slot != "")
7668 {
7669 if (detach_types.Count() == 1)
7670 idx = 0;
7671 else
7672 idx = inventory_slots.Find(slot);
7673 }
7674 if (idx < 0)
7675 return "";
7676
7677 return detach_types.Get(idx);
7678 }
7679
7680 void ExplodeAmmo()
7681 {
7682 //timer
7683 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
7684
7685 //min/max time
7686 float min_time = 1;
7687 float max_time = 3;
7688 float delay = Math.RandomFloat(min_time, max_time);
7689
7690 explode_timer.Run(delay, this, "DoAmmoExplosion");
7691 }
7692
7693 void DoAmmoExplosion()
7694 {
7695 Magazine magazine = Magazine.Cast(this);
7696 int pop_sounds_count = 6;
7697 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
7698
7699 //play sound
7700 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
7701 string sound_name = pop_sounds[ sound_idx ];
7702 GetGame().CreateSoundOnObject(this, sound_name, 20, false);
7703
7704 //remove ammo count
7705 magazine.ServerAddAmmoCount(-1);
7706
7707 //if condition then repeat -> ExplodeAmmo
7708 float min_temp_to_explode = 100; //min temperature for item to explode
7709
7710 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
7711 {
7712 ExplodeAmmo();
7713 }
7714 }
7715
7716 // -------------------------------------------------------------------------------
7717 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
7718 {
7719 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
7720
7721 const int CHANCE_DAMAGE_CARGO = 4;
7722 const int CHANCE_DAMAGE_ATTACHMENT = 1;
7723 const int CHANCE_DAMAGE_NOTHING = 2;
7724
7725 if (IsClothing() || IsContainer() || IsItemTent())
7726 {
7727 float dmg = damageResult.GetDamage("","Health") * -0.5;
7728 int chances;
7729 int rnd;
7730
7731 if (GetInventory().GetCargo())
7732 {
7733 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7734 rnd = Math.RandomInt(0,chances);
7735
7736 if (rnd < CHANCE_DAMAGE_CARGO)
7737 {
7738 DamageItemInCargo(dmg);
7739 }
7740 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
7741 {
7743 }
7744 }
7745 else
7746 {
7747 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7748 rnd = Math.RandomInt(0,chances);
7749
7750 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
7751 {
7753 }
7754 }
7755 }
7756 }
7757
7758 bool DamageItemInCargo(float damage)
7759 {
7760 if (GetInventory().GetCargo())
7761 {
7762 int item_count = GetInventory().GetCargo().GetItemCount();
7763 if (item_count > 0)
7764 {
7765 int random_pick = Math.RandomInt(0, item_count);
7766 ItemBase item = ItemBase.Cast(GetInventory().GetCargo().GetItem(random_pick));
7767 if (!item.IsExplosive())
7768 {
7769 item.AddHealth("","",damage);
7770 return true;
7771 }
7772 }
7773 }
7774 return false;
7775 }
7776
7777 bool DamageItemAttachments(float damage)
7778 {
7779 int attachment_count = GetInventory().AttachmentCount();
7780 if (attachment_count > 0)
7781 {
7782 int random_pick = Math.RandomInt(0, attachment_count);
7783 ItemBase attachment = ItemBase.Cast(GetInventory().GetAttachmentFromIndex(random_pick));
7784 if (!attachment.IsExplosive())
7785 {
7786 attachment.AddHealth("","",damage);
7787 return true;
7788 }
7789 }
7790 return false;
7791 }
7792
7793 override bool IsSplitable()
7794 {
7795 return m_CanThisBeSplit;
7796 }
7797 //----------------
7798 override bool CanBeSplit()
7799 {
7800 if (IsSplitable() && (GetQuantity() > 1))
7801 return GetInventory().CanRemoveEntity();
7802
7803 return false;
7804 }
7805
7806 protected bool ShouldSplitQuantity(float quantity)
7807 {
7808 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
7809 if (!IsSplitable())
7810 return false;
7811
7812 // nothing to split?
7813 if (GetQuantity() <= 1)
7814 return false;
7815
7816 // check if we should re-use the item instead of creating a new copy?
7817 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
7818 int delta = GetQuantity() - quantity;
7819 if (delta == 0)
7820 return false;
7821
7822 // valid to split
7823 return true;
7824 }
7825
7826 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
7827 {
7828 if (GetGame().IsClient())
7829 {
7830 if (ScriptInputUserData.CanStoreInputUserData())
7831 {
7832 ScriptInputUserData ctx = new ScriptInputUserData;
7834 ctx.Write(1);
7835 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7836 ctx.Write(i1);
7837 ctx.Write(destination_entity);
7838 ctx.Write(true);
7839 ctx.Write(slot_id);
7840 ctx.Send();
7841 }
7842 }
7843 else if (!GetGame().IsMultiplayer())
7844 {
7845 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(GetGame().GetPlayer()));
7846 }
7847 }
7848
7849 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
7850 {
7851 float split_quantity_new;
7852 ItemBase new_item;
7853 float quantity = GetQuantity();
7854 float stack_max = GetTargetQuantityMax(slot_id);
7855 InventoryLocation loc = new InventoryLocation;
7856
7857 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7858 {
7859 if (stack_max <= GetQuantity())
7860 split_quantity_new = stack_max;
7861 else
7862 split_quantity_new = GetQuantity();
7863
7864 if (ShouldSplitQuantity(split_quantity_new))
7865 {
7866 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7867 if (new_item)
7868 {
7869 new_item.SetResultOfSplit(true);
7870 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7871 AddQuantity(-split_quantity_new, false, true);
7872 new_item.SetQuantity(split_quantity_new, false, true);
7873 }
7874 }
7875 }
7876 else if (destination_entity && slot_id == -1)
7877 {
7878 if (quantity > stack_max)
7879 split_quantity_new = stack_max;
7880 else
7881 split_quantity_new = quantity;
7882
7883 if (ShouldSplitQuantity(split_quantity_new))
7884 {
7885 if (destination_entity.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7886 {
7887 Object o = destination_entity.GetInventory().LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7888 new_item = ItemBase.Cast(o);
7889 }
7890
7891 if (new_item)
7892 {
7893 new_item.SetResultOfSplit(true);
7894 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7895 AddQuantity(-split_quantity_new, false, true);
7896 new_item.SetQuantity(split_quantity_new, false, true);
7897 }
7898 }
7899 }
7900 else
7901 {
7902 if (stack_max != 0)
7903 {
7904 if (stack_max < GetQuantity())
7905 {
7906 split_quantity_new = GetQuantity() - stack_max;
7907 }
7908
7909 if (split_quantity_new == 0)
7910 {
7911 if (!GetGame().IsMultiplayer())
7912 player.PhysicalPredictiveDropItem(this);
7913 else
7914 player.ServerDropEntity(this);
7915 return;
7916 }
7917
7918 if (ShouldSplitQuantity(split_quantity_new))
7919 {
7920 new_item = ItemBase.Cast(GetGame().CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7921
7922 if (new_item)
7923 {
7924 new_item.SetResultOfSplit(true);
7925 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7926 SetQuantity(split_quantity_new, false, true);
7927 new_item.SetQuantity(stack_max, false, true);
7928 new_item.PlaceOnSurface();
7929 }
7930 }
7931 }
7932 }
7933 }
7934
7935 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
7936 {
7937 float split_quantity_new;
7938 ItemBase new_item;
7939 float quantity = GetQuantity();
7940 float stack_max = GetTargetQuantityMax(slot_id);
7941 InventoryLocation loc = new InventoryLocation;
7942
7943 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7944 {
7945 if (stack_max <= GetQuantity())
7946 split_quantity_new = stack_max;
7947 else
7948 split_quantity_new = GetQuantity();
7949
7950 if (ShouldSplitQuantity(split_quantity_new))
7951 {
7952 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7953 if (new_item)
7954 {
7955 new_item.SetResultOfSplit(true);
7956 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7957 AddQuantity(-split_quantity_new, false, true);
7958 new_item.SetQuantity(split_quantity_new, false, true);
7959 }
7960 }
7961 }
7962 else if (destination_entity && slot_id == -1)
7963 {
7964 if (quantity > stack_max)
7965 split_quantity_new = stack_max;
7966 else
7967 split_quantity_new = quantity;
7968
7969 if (ShouldSplitQuantity(split_quantity_new))
7970 {
7971 if (destination_entity.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7972 {
7973 Object o = destination_entity.GetInventory().LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7974 new_item = ItemBase.Cast(o);
7975 }
7976
7977 if (new_item)
7978 {
7979 new_item.SetResultOfSplit(true);
7980 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7981 AddQuantity(-split_quantity_new, false, true);
7982 new_item.SetQuantity(split_quantity_new, false, true);
7983 }
7984 }
7985 }
7986 else
7987 {
7988 if (stack_max != 0)
7989 {
7990 if (stack_max < GetQuantity())
7991 {
7992 split_quantity_new = GetQuantity() - stack_max;
7993 }
7994
7995 if (ShouldSplitQuantity(split_quantity_new))
7996 {
7997 new_item = ItemBase.Cast(GetGame().CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7998
7999 if (new_item)
8000 {
8001 new_item.SetResultOfSplit(true);
8002 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8003 SetQuantity(split_quantity_new, false, true);
8004 new_item.SetQuantity(stack_max, false, true);
8005 new_item.PlaceOnSurface();
8006 }
8007 }
8008 }
8009 }
8010 }
8011
8012 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
8013 {
8014 if (GetGame().IsClient())
8015 {
8016 if (ScriptInputUserData.CanStoreInputUserData())
8017 {
8018 ScriptInputUserData ctx = new ScriptInputUserData;
8020 ctx.Write(4);
8021 ItemBase thiz = this; // @NOTE: workaround for correct serialization
8022 ctx.Write(thiz);
8023 dst.WriteToContext(ctx);
8024 ctx.Send();
8025 }
8026 }
8027 else if (!GetGame().IsMultiplayer())
8028 {
8030 }
8031 }
8032
8033 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
8034 {
8035 if (GetGame().IsClient())
8036 {
8037 if (ScriptInputUserData.CanStoreInputUserData())
8038 {
8039 ScriptInputUserData ctx = new ScriptInputUserData;
8041 ctx.Write(2);
8042 ItemBase dummy = this; // @NOTE: workaround for correct serialization
8043 ctx.Write(dummy);
8044 ctx.Write(destination_entity);
8045 ctx.Write(true);
8046 ctx.Write(idx);
8047 ctx.Write(row);
8048 ctx.Write(col);
8049 ctx.Send();
8050 }
8051 }
8052 else if (!GetGame().IsMultiplayer())
8053 {
8054 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
8055 }
8056 }
8057
8058 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
8059 {
8061 }
8062
8063 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
8064 {
8065 float quantity = GetQuantity();
8066 float split_quantity_new;
8067 ItemBase new_item;
8068 if (dst.IsValid())
8069 {
8070 int slot_id = dst.GetSlot();
8071 float stack_max = GetTargetQuantityMax(slot_id);
8072
8073 if (quantity > stack_max)
8074 split_quantity_new = stack_max;
8075 else
8076 split_quantity_new = quantity;
8077
8078 if (ShouldSplitQuantity(split_quantity_new))
8079 {
8080 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
8081
8082 if (new_item)
8083 {
8084 new_item.SetResultOfSplit(true);
8085 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8086 AddQuantity(-split_quantity_new, false, true);
8087 new_item.SetQuantity(split_quantity_new, false, true);
8088 }
8089
8090 return new_item;
8091 }
8092 }
8093
8094 return null;
8095 }
8096
8097 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
8098 {
8099 float quantity = GetQuantity();
8100 float split_quantity_new;
8101 ItemBase new_item;
8102 if (destination_entity)
8103 {
8104 float stackable = GetTargetQuantityMax();
8105 if (quantity > stackable)
8106 split_quantity_new = stackable;
8107 else
8108 split_quantity_new = quantity;
8109
8110 if (ShouldSplitQuantity(split_quantity_new))
8111 {
8112 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
8113 if (new_item)
8114 {
8115 new_item.SetResultOfSplit(true);
8116 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8117 AddQuantity(-split_quantity_new, false, true);
8118 new_item.SetQuantity(split_quantity_new, false, true);
8119 }
8120 }
8121 }
8122 }
8123
8124 void SplitIntoStackMaxHandsClient(PlayerBase player)
8125 {
8126 if (GetGame().IsClient())
8127 {
8128 if (ScriptInputUserData.CanStoreInputUserData())
8129 {
8130 ScriptInputUserData ctx = new ScriptInputUserData;
8132 ctx.Write(3);
8133 ItemBase i1 = this; // @NOTE: workaround for correct serialization
8134 ctx.Write(i1);
8135 ItemBase destination_entity = this;
8136 ctx.Write(destination_entity);
8137 ctx.Write(true);
8138 ctx.Write(0);
8139 ctx.Send();
8140 }
8141 }
8142 else if (!GetGame().IsMultiplayer())
8143 {
8144 SplitIntoStackMaxHands(player);
8145 }
8146 }
8147
8148 void SplitIntoStackMaxHands(PlayerBase player)
8149 {
8150 float quantity = GetQuantity();
8151 float split_quantity_new;
8152 ref ItemBase new_item;
8153 if (player)
8154 {
8155 float stackable = GetTargetQuantityMax();
8156 if (quantity > stackable)
8157 split_quantity_new = stackable;
8158 else
8159 split_quantity_new = quantity;
8160
8161 if (ShouldSplitQuantity(split_quantity_new))
8162 {
8163 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
8164 new_item = ItemBase.Cast(in_hands);
8165 if (new_item)
8166 {
8167 new_item.SetResultOfSplit(true);
8168 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8169 AddQuantity(-split_quantity_new, false, true);
8170 new_item.SetQuantity(split_quantity_new, false, true);
8171 }
8172 }
8173 }
8174 }
8175
8176 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
8177 {
8178 float quantity = GetQuantity();
8179 float split_quantity_new = Math.Floor(quantity * 0.5);
8180
8181 if (!ShouldSplitQuantity(split_quantity_new))
8182 return;
8183
8184 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
8185
8186 if (new_item)
8187 {
8188 if (new_item.GetQuantityMax() < split_quantity_new)
8189 {
8190 split_quantity_new = new_item.GetQuantityMax();
8191 }
8192
8193 new_item.SetResultOfSplit(true);
8194 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8195
8196 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
8197 {
8198 AddQuantity(-1, false, true);
8199 new_item.SetQuantity(1, false, true);
8200 }
8201 else
8202 {
8203 AddQuantity(-split_quantity_new, false, true);
8204 new_item.SetQuantity(split_quantity_new, false, true);
8205 }
8206 }
8207 }
8208
8209 void SplitItem(PlayerBase player)
8210 {
8211 float quantity = GetQuantity();
8212 float split_quantity_new = Math.Floor(quantity / 2);
8213
8214 if (!ShouldSplitQuantity(split_quantity_new))
8215 return;
8216
8217 InventoryLocation invloc = new InventoryLocation;
8218 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
8219
8220 ItemBase new_item;
8221 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
8222
8223 if (new_item)
8224 {
8225 if (new_item.GetQuantityMax() < split_quantity_new)
8226 {
8227 split_quantity_new = new_item.GetQuantityMax();
8228 }
8229 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
8230 {
8231 AddQuantity(-1, false, true);
8232 new_item.SetQuantity(1, false, true);
8233 }
8234 else if (split_quantity_new > 1)
8235 {
8236 AddQuantity(-split_quantity_new, false, true);
8237 new_item.SetQuantity(split_quantity_new, false, true);
8238 }
8239 }
8240 }
8241
8243 void OnQuantityChanged(float delta)
8244 {
8245 SetWeightDirty();
8246 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
8247
8248 if (parent)
8249 parent.OnAttachmentQuantityChangedEx(this, delta);
8250
8251 if (IsLiquidContainer())
8252 {
8253 if (GetQuantityNormalized() <= 0.0)
8254 {
8256 }
8257 else if (GetLiquidType() == LIQUID_NONE)
8258 {
8259 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
8261 }
8262 }
8263
8264 }
8265
8268 {
8269 // insert code here
8270 }
8271
8273 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
8274 {
8276 }
8277
8278 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
8279 {
8280 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
8281
8282 if (GetGame().IsServer())
8283 {
8284 if (newLevel == GameConstants.STATE_RUINED)
8285 {
8287 EntityAI parent = GetHierarchyParent();
8288 if (parent && parent.IsFireplace())
8289 {
8290 CargoBase cargo = GetInventory().GetCargo();
8291 if (cargo)
8292 {
8293 for (int i = 0; i < cargo.GetItemCount(); ++i)
8294 {
8295 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
8296 }
8297 }
8298 }
8299 }
8300
8301 if (IsResultOfSplit())
8302 {
8303 // reset the splitting result flag, return to normal item behavior
8304 SetResultOfSplit(false);
8305 return;
8306 }
8307
8308 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
8309 {
8310 SetCleanness(0);//unclean the item upon damage dealt
8311 }
8312 }
8313 }
8314
8315 // just the split? TODO: verify
8316 override void OnRightClick()
8317 {
8318 super.OnRightClick();
8319
8320 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !GetGame().GetPlayer().GetInventory().HasInventoryReservation(this,null))
8321 {
8322 if (GetGame().IsClient())
8323 {
8324 if (ScriptInputUserData.CanStoreInputUserData())
8325 {
8326 EntityAI root = GetHierarchyRoot();
8327 Man playerOwner = GetHierarchyRootPlayer();
8328 InventoryLocation dst = new InventoryLocation;
8329
8330 // If we have no hierarchy root player and the root is the same as this item the source item is in the vicinity so we want to create the new split item there also
8331 if (!playerOwner && root && root == this)
8332 {
8334 }
8335 else
8336 {
8337 // Check if we can place the new split item in the same parent where the source item is placed in or otherwise drop it in vicinity
8338 GetInventory().GetCurrentInventoryLocation(dst);
8339 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
8340 {
8341 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
8342 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
8343 {
8345 }
8346 else
8347 {
8348 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
8349 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
8350 this shouldnt cause issues within this scope*/
8351 if (GetGame().GetPlayer().GetInventory().HasInventoryReservation(this, dst))
8352 {
8354 }
8355 else
8356 {
8357 GetGame().GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
8358 }
8359 }
8360 }
8361 }
8362
8363 ScriptInputUserData ctx = new ScriptInputUserData;
8365 ctx.Write(4);
8366 ItemBase thiz = this; // @NOTE: workaround for correct serialization
8367 ctx.Write(thiz);
8368 dst.WriteToContext(ctx);
8369 ctx.Write(true); // dummy
8370 ctx.Send();
8371 }
8372 }
8373 else if (!GetGame().IsMultiplayer())
8374 {
8375 SplitItem(PlayerBase.Cast(GetGame().GetPlayer()));
8376 }
8377 }
8378 }
8379
8380 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
8381 {
8382 if (root)
8383 {
8384 vector m4[4];
8385 root.GetTransform(m4);
8386 dst.SetGround(this, m4);
8387 }
8388 else
8389 {
8390 GetInventory().GetCurrentInventoryLocation(dst);
8391 }
8392 }
8393
8394 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
8395 {
8396 //TODO: delete check zero quantity check after fix double posts hands fsm events
8397 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
8398 return false;
8399
8400 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
8401 return false;
8402
8403 //can_this_be_combined = ConfigGetBool("canBeSplit");
8405 return false;
8406
8407
8408 Magazine mag = Magazine.Cast(this);
8409 if (mag)
8410 {
8411 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
8412 return false;
8413
8414 if (stack_max_limit)
8415 {
8416 Magazine other_mag = Magazine.Cast(other_item);
8417 if (other_item)
8418 {
8419 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
8420 return false;
8421 }
8422
8423 }
8424 }
8425 else
8426 {
8427 //TODO: delete check zero quantity check after fix double posts hands fsm events
8428 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
8429 return false;
8430
8431 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
8432 return false;
8433 }
8434
8435 PlayerBase player = null;
8436 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
8437 {
8438 if (player.GetInventory().HasAttachment(this))
8439 return false;
8440
8441 if (player.IsItemsToDelete())
8442 return false;
8443 }
8444
8445 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
8446 return false;
8447
8448 int slotID;
8449 string slotName;
8450 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
8451 return false;
8452
8453 return true;
8454 }
8455
8456 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
8457 {
8458 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
8459 }
8460
8461 bool IsResultOfSplit()
8462 {
8463 return m_IsResultOfSplit;
8464 }
8465
8466 void SetResultOfSplit(bool value)
8467 {
8468 m_IsResultOfSplit = value;
8469 }
8470
8471 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
8472 {
8473 return ComputeQuantityUsedEx(other_item, use_stack_max);
8474 }
8475
8476 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
8477 {
8478 float other_item_quantity = other_item.GetQuantity();
8479 float this_free_space;
8480
8481 float stack_max = GetQuantityMax();
8482
8483 this_free_space = stack_max - GetQuantity();
8484
8485 if (other_item_quantity > this_free_space)
8486 {
8487 return this_free_space;
8488 }
8489 else
8490 {
8491 return other_item_quantity;
8492 }
8493 }
8494
8495 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
8496 {
8497 CombineItems(ItemBase.Cast(entity2),use_stack_max);
8498 }
8499
8500 void CombineItems(ItemBase other_item, bool use_stack_max = true)
8501 {
8502 if (!CanBeCombined(other_item, false))
8503 return;
8504
8505 if (!IsMagazine() && other_item)
8506 {
8507 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
8508 if (quantity_used != 0)
8509 {
8510 float hp1 = GetHealth01("","");
8511 float hp2 = other_item.GetHealth01("","");
8512 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
8513 hpResult = hpResult / (GetQuantity() + quantity_used);
8514
8515 hpResult *= GetMaxHealth();
8516 Math.Round(hpResult);
8517 SetHealth("", "Health", hpResult);
8518
8519 AddQuantity(quantity_used);
8520 other_item.AddQuantity(-quantity_used);
8521 }
8522 }
8523 OnCombine(other_item);
8524 }
8525
8526 void OnCombine(ItemBase other_item)
8527 {
8528 #ifdef SERVER
8529 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
8530 GetHierarchyParent().IncreaseLifetimeUp();
8531 #endif
8532 };
8533
8534 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
8535 {
8536 PlayerBase p = PlayerBase.Cast(player);
8537
8538 array<int> recipesIds = p.m_Recipes;
8539 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
8540 if (moduleRecipesManager)
8541 {
8542 EntityAI itemInHands = player.GetHumanInventory().GetEntityInHands();
8543 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
8544 }
8545
8546 for (int i = 0;i < recipesIds.Count(); i++)
8547 {
8548 int key = recipesIds.Get(i);
8549 string recipeName = moduleRecipesManager.GetRecipeName(key);
8550 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
8551 }
8552 }
8553
8554 // -------------------------------------------------------------------------
8555 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
8556 {
8557 super.GetDebugActions(outputList);
8558
8559 //quantity
8560 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
8561 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
8562 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
8563 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
8564 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8565
8566 //health
8567 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
8568 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
8569 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
8570 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8571 //temperature
8572 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
8573 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
8574 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
8575 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8576
8577 //wet
8578 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
8579 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
8580 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8581
8582 //liquidtype
8583 if (IsLiquidContainer())
8584 {
8585 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
8586 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
8587 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8588 }
8589
8590 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
8591 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8592
8593 // watch
8594 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
8595 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
8596 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8597
8598 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
8599
8600 InventoryLocation loc = new InventoryLocation();
8601 GetInventory().GetCurrentInventoryLocation(loc);
8602 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
8603 {
8604 if (Gizmo_IsSupported())
8605 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
8606 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
8607 }
8608
8609 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8610 }
8611
8612 // -------------------------------------------------------------------------
8613 // -------------------------------------------------------------------------
8614 // -------------------------------------------------------------------------
8615 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
8616 {
8617 super.OnAction(action_id, player, ctx);
8618
8619 if (GetGame().IsClient() || !GetGame().IsMultiplayer())
8620 {
8621 switch (action_id)
8622 {
8623 case EActions.GIZMO_OBJECT:
8624 GetGame().GizmoSelectObject(this);
8625 return true;
8626 case EActions.GIZMO_PHYSICS:
8627 GetGame().GizmoSelectPhysics(GetPhysics());
8628 return true;
8629 }
8630 }
8631
8632 if (GetGame().IsServer())
8633 {
8634 switch (action_id)
8635 {
8636 case EActions.DELETE:
8637 Delete();
8638 return true;
8639 }
8640 }
8641
8642 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
8643 {
8644 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
8645 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
8646 PlayerBase p = PlayerBase.Cast(player);
8647 if (EActions.RECIPES_RANGE_START < 1000)
8648 {
8649 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
8650 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
8651 }
8652 }
8653 #ifndef SERVER
8654 else if (action_id == EActions.WATCH_PLAYER)
8655 {
8656 PluginDeveloper.SetDeveloperItemClientEx(player);
8657 }
8658 #endif
8659 if (GetGame().IsServer())
8660 {
8661 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
8662 {
8663 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
8664 OnDebugButtonPressServer(id + 1);
8665 }
8666
8667 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
8668 {
8669 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
8670 InsertAgent(agent_id,100);
8671 }
8672
8673 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
8674 {
8675 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
8676 RemoveAgent(agent_id2);
8677 }
8678
8679 else if (action_id == EActions.ADD_QUANTITY)
8680 {
8681 if (IsMagazine())
8682 {
8683 Magazine mag = Magazine.Cast(this);
8684 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
8685 }
8686 else
8687 {
8688 AddQuantity(GetQuantityMax() * 0.2);
8689 }
8690
8691 if (m_EM)
8692 {
8693 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
8694 }
8695 //PrintVariables();
8696 }
8697
8698 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
8699 {
8700 if (IsMagazine())
8701 {
8702 Magazine mag2 = Magazine.Cast(this);
8703 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
8704 }
8705 else
8706 {
8707 AddQuantity(- GetQuantityMax() * 0.2);
8708 }
8709 if (m_EM)
8710 {
8711 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
8712 }
8713 //PrintVariables();
8714 }
8715
8716 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
8717 {
8718 SetQuantity(0);
8719
8720 if (m_EM)
8721 {
8722 m_EM.SetEnergy(0);
8723 }
8724 }
8725
8726 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
8727 {
8729
8730 if (m_EM)
8731 {
8732 m_EM.SetEnergy(m_EM.GetEnergyMax());
8733 }
8734 }
8735
8736 else if (action_id == EActions.ADD_HEALTH)
8737 {
8738 AddHealth("","",GetMaxHealth("","Health")/5);
8739 }
8740 else if (action_id == EActions.REMOVE_HEALTH)
8741 {
8742 AddHealth("","",-GetMaxHealth("","Health")/5);
8743 }
8744 else if (action_id == EActions.DESTROY_HEALTH)
8745 {
8746 SetHealth01("","",0);
8747 }
8748 else if (action_id == EActions.WATCH_ITEM)
8749 {
8751 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
8752 #ifdef DEVELOPER
8753 SetDebugDeveloper_item(this);
8754 #endif
8755 }
8756
8757 else if (action_id == EActions.ADD_TEMPERATURE)
8758 {
8759 AddTemperature(20);
8760 //PrintVariables();
8761 }
8762
8763 else if (action_id == EActions.REMOVE_TEMPERATURE)
8764 {
8765 AddTemperature(-20);
8766 //PrintVariables();
8767 }
8768
8769 else if (action_id == EActions.FLIP_FROZEN)
8770 {
8771 SetFrozen(!GetIsFrozen());
8772 //PrintVariables();
8773 }
8774
8775 else if (action_id == EActions.ADD_WETNESS)
8776 {
8777 AddWet(GetWetMax()/5);
8778 //PrintVariables();
8779 }
8780
8781 else if (action_id == EActions.REMOVE_WETNESS)
8782 {
8783 AddWet(-GetWetMax()/5);
8784 //PrintVariables();
8785 }
8786
8787 else if (action_id == EActions.LIQUIDTYPE_UP)
8788 {
8789 int curr_type = GetLiquidType();
8790 SetLiquidType(curr_type * 2);
8791 //AddWet(1);
8792 //PrintVariables();
8793 }
8794
8795 else if (action_id == EActions.LIQUIDTYPE_DOWN)
8796 {
8797 int curr_type2 = GetLiquidType();
8798 SetLiquidType(curr_type2 / 2);
8799 }
8800
8801 else if (action_id == EActions.MAKE_SPECIAL)
8802 {
8803 auto debugParams = DebugSpawnParams.WithPlayer(player);
8804 OnDebugSpawnEx(debugParams);
8805 }
8806
8807 }
8808
8809
8810 return false;
8811 }
8812
8813 // -------------------------------------------------------------------------
8814
8815
8818 void OnActivatedByTripWire();
8819
8821 void OnActivatedByItem(notnull ItemBase item);
8822
8823 //----------------------------------------------------------------
8824 //returns true if item is able to explode when put in fire
8825 bool CanExplodeInFire()
8826 {
8827 return false;
8828 }
8829
8830 //----------------------------------------------------------------
8831 bool CanEat()
8832 {
8833 return true;
8834 }
8835
8836 //----------------------------------------------------------------
8837 override bool IsIgnoredByConstruction()
8838 {
8839 return true;
8840 }
8841
8842 //----------------------------------------------------------------
8843 //has FoodStages in config?
8844 bool HasFoodStage()
8845 {
8846 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
8847 return GetGame().ConfigIsExisting(config_path);
8848 }
8849
8851 FoodStage GetFoodStage()
8852 {
8853 return null;
8854 }
8855
8856 bool CanBeCooked()
8857 {
8858 return false;
8859 }
8860
8861 bool CanBeCookedOnStick()
8862 {
8863 return false;
8864 }
8865
8867 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
8869
8870 //----------------------------------------------------------------
8871 bool CanRepair(ItemBase item_repair_kit)
8872 {
8873 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8874 return module_repairing.CanRepair(this, item_repair_kit);
8875 }
8876
8877 //----------------------------------------------------------------
8878 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
8879 {
8880 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8881 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
8882 }
8883
8884 //----------------------------------------------------------------
8885 int GetItemSize()
8886 {
8887 /*
8888 vector v_size = this.ConfigGetVector("itemSize");
8889 int v_size_x = v_size[0];
8890 int v_size_y = v_size[1];
8891 int size = v_size_x * v_size_y;
8892 return size;
8893 */
8894
8895 return 1;
8896 }
8897
8898 //----------------------------------------------------------------
8899 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8900 bool CanBeMovedOverride()
8901 {
8902 return m_CanBeMovedOverride;
8903 }
8904
8905 //----------------------------------------------------------------
8906 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8907 void SetCanBeMovedOverride(bool setting)
8908 {
8909 m_CanBeMovedOverride = setting;
8910 }
8911
8912 //----------------------------------------------------------------
8920 void MessageToOwnerStatus(string text)
8921 {
8922 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8923
8924 if (player)
8925 {
8926 player.MessageStatus(text);
8927 }
8928 }
8929
8930 //----------------------------------------------------------------
8938 void MessageToOwnerAction(string text)
8939 {
8940 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8941
8942 if (player)
8943 {
8944 player.MessageAction(text);
8945 }
8946 }
8947
8948 //----------------------------------------------------------------
8956 void MessageToOwnerFriendly(string text)
8957 {
8958 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8959
8960 if (player)
8961 {
8962 player.MessageFriendly(text);
8963 }
8964 }
8965
8966 //----------------------------------------------------------------
8974 void MessageToOwnerImportant(string text)
8975 {
8976 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8977
8978 if (player)
8979 {
8980 player.MessageImportant(text);
8981 }
8982 }
8983
8984 override bool IsItemBase()
8985 {
8986 return true;
8987 }
8988
8989 // Checks if item is of questioned kind
8990 override bool KindOf(string tag)
8991 {
8992 bool found = false;
8993 string item_name = this.GetType();
8994 ref TStringArray item_tag_array = new TStringArray;
8995 GetGame().ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
8996
8997 int array_size = item_tag_array.Count();
8998 for (int i = 0; i < array_size; i++)
8999 {
9000 if (item_tag_array.Get(i) == tag)
9001 {
9002 found = true;
9003 break;
9004 }
9005 }
9006 return found;
9007 }
9008
9009
9010 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
9011 {
9012 //Debug.Log("OnRPC called");
9013 super.OnRPC(sender, rpc_type,ctx);
9014
9015 //Play soundset for attachment locking (ActionLockAttachment.c)
9016 switch (rpc_type)
9017 {
9018 #ifndef SERVER
9019 case ERPCs.RPC_SOUND_LOCK_ATTACH:
9020 Param2<bool, string> p = new Param2<bool, string>(false, "");
9021
9022 if (!ctx.Read(p))
9023 return;
9024
9025 bool play = p.param1;
9026 string soundSet = p.param2;
9027
9028 if (play)
9029 {
9030 if (m_LockingSound)
9031 {
9033 {
9034 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
9035 }
9036 }
9037 else
9038 {
9039 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
9040 }
9041 }
9042 else
9043 {
9044 SEffectManager.DestroyEffect(m_LockingSound);
9045 }
9046
9047 break;
9048 #endif
9049
9050 }
9051
9052 if (GetWrittenNoteData())
9053 {
9054 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
9055 }
9056 }
9057
9058 //-----------------------------
9059 // VARIABLE MANIPULATION SYSTEM
9060 //-----------------------------
9061 int NameToID(string name)
9062 {
9063 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
9064 return plugin.GetID(name);
9065 }
9066
9067 string IDToName(int id)
9068 {
9069 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
9070 return plugin.GetName(id);
9071 }
9072
9074 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
9075 {
9076 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
9077 //read the flags
9078 int varFlags;
9079 if (!ctx.Read(varFlags))
9080 return;
9081
9082 if (varFlags & ItemVariableFlags.FLOAT)
9083 {
9084 ReadVarsFromCTX(ctx);
9085 }
9086 }
9087
9088 override void SerializeNumericalVars(array<float> floats_out)
9089 {
9090 //some variables handled on EntityAI level already!
9091 super.SerializeNumericalVars(floats_out);
9092
9093 // the order of serialization must be the same as the order of de-serialization
9094 //--------------------------------------------
9095 if (IsVariableSet(VARIABLE_QUANTITY))
9096 {
9097 floats_out.Insert(m_VarQuantity);
9098 }
9099 //--------------------------------------------
9100 if (IsVariableSet(VARIABLE_WET))
9101 {
9102 floats_out.Insert(m_VarWet);
9103 }
9104 //--------------------------------------------
9105 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
9106 {
9107 floats_out.Insert(m_VarLiquidType);
9108 }
9109 //--------------------------------------------
9110 if (IsVariableSet(VARIABLE_COLOR))
9111 {
9112 floats_out.Insert(m_ColorComponentR);
9113 floats_out.Insert(m_ColorComponentG);
9114 floats_out.Insert(m_ColorComponentB);
9115 floats_out.Insert(m_ColorComponentA);
9116 }
9117 //--------------------------------------------
9118 if (IsVariableSet(VARIABLE_CLEANNESS))
9119 {
9120 floats_out.Insert(m_Cleanness);
9121 }
9122 }
9123
9124 override void DeSerializeNumericalVars(array<float> floats)
9125 {
9126 //some variables handled on EntityAI level already!
9127 super.DeSerializeNumericalVars(floats);
9128
9129 // the order of serialization must be the same as the order of de-serialization
9130 int index = 0;
9131 int mask = Math.Round(floats.Get(index));
9132
9133 index++;
9134 //--------------------------------------------
9135 if (mask & VARIABLE_QUANTITY)
9136 {
9137 if (m_IsStoreLoad)
9138 {
9139 SetStoreLoadedQuantity(floats.Get(index));
9140 }
9141 else
9142 {
9143 float quantity = floats.Get(index);
9144 SetQuantity(quantity, true, false, false, false);
9145 }
9146 index++;
9147 }
9148 //--------------------------------------------
9149 if (mask & VARIABLE_WET)
9150 {
9151 float wet = floats.Get(index);
9152 SetWet(wet);
9153 index++;
9154 }
9155 //--------------------------------------------
9156 if (mask & VARIABLE_LIQUIDTYPE)
9157 {
9158 int liquidtype = Math.Round(floats.Get(index));
9159 SetLiquidType(liquidtype);
9160 index++;
9161 }
9162 //--------------------------------------------
9163 if (mask & VARIABLE_COLOR)
9164 {
9165 m_ColorComponentR = Math.Round(floats.Get(index));
9166 index++;
9167 m_ColorComponentG = Math.Round(floats.Get(index));
9168 index++;
9169 m_ColorComponentB = Math.Round(floats.Get(index));
9170 index++;
9171 m_ColorComponentA = Math.Round(floats.Get(index));
9172 index++;
9173 }
9174 //--------------------------------------------
9175 if (mask & VARIABLE_CLEANNESS)
9176 {
9177 int cleanness = Math.Round(floats.Get(index));
9178 SetCleanness(cleanness);
9179 index++;
9180 }
9181 }
9182
9183 override void WriteVarsToCTX(ParamsWriteContext ctx)
9184 {
9185 super.WriteVarsToCTX(ctx);
9186
9187 //--------------------------------------------
9188 if (IsVariableSet(VARIABLE_QUANTITY))
9189 {
9190 ctx.Write(GetQuantity());
9191 }
9192 //--------------------------------------------
9193 if (IsVariableSet(VARIABLE_WET))
9194 {
9195 ctx.Write(GetWet());
9196 }
9197 //--------------------------------------------
9198 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
9199 {
9200 ctx.Write(GetLiquidType());
9201 }
9202 //--------------------------------------------
9203 if (IsVariableSet(VARIABLE_COLOR))
9204 {
9205 int r,g,b,a;
9206 GetColor(r,g,b,a);
9207 ctx.Write(r);
9208 ctx.Write(g);
9209 ctx.Write(b);
9210 ctx.Write(a);
9211 }
9212 //--------------------------------------------
9213 if (IsVariableSet(VARIABLE_CLEANNESS))
9214 {
9215 ctx.Write(GetCleanness());
9216 }
9217 }
9218
9219 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
9220 {
9221 if (!super.ReadVarsFromCTX(ctx,version))
9222 return false;
9223
9224 int intValue;
9225 float value;
9226
9227 if (version < 140)
9228 {
9229 if (!ctx.Read(intValue))
9230 return false;
9231
9232 m_VariablesMask = intValue;
9233 }
9234
9235 if (m_VariablesMask & VARIABLE_QUANTITY)
9236 {
9237 if (!ctx.Read(value))
9238 return false;
9239
9240 if (IsStoreLoad())
9241 {
9243 }
9244 else
9245 {
9246 SetQuantity(value, true, false, false, false);
9247 }
9248 }
9249 //--------------------------------------------
9250 if (version < 140)
9251 {
9252 if (m_VariablesMask & VARIABLE_TEMPERATURE)
9253 {
9254 if (!ctx.Read(value))
9255 return false;
9256 SetTemperatureDirect(value);
9257 }
9258 }
9259 //--------------------------------------------
9260 if (m_VariablesMask & VARIABLE_WET)
9261 {
9262 if (!ctx.Read(value))
9263 return false;
9264 SetWet(value);
9265 }
9266 //--------------------------------------------
9267 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
9268 {
9269 if (!ctx.Read(intValue))
9270 return false;
9271 SetLiquidType(intValue);
9272 }
9273 //--------------------------------------------
9274 if (m_VariablesMask & VARIABLE_COLOR)
9275 {
9276 int r,g,b,a;
9277 if (!ctx.Read(r))
9278 return false;
9279 if (!ctx.Read(g))
9280 return false;
9281 if (!ctx.Read(b))
9282 return false;
9283 if (!ctx.Read(a))
9284 return false;
9285
9286 SetColor(r,g,b,a);
9287 }
9288 //--------------------------------------------
9289 if (m_VariablesMask & VARIABLE_CLEANNESS)
9290 {
9291 if (!ctx.Read(intValue))
9292 return false;
9293 SetCleanness(intValue);
9294 }
9295 //--------------------------------------------
9296 if (version >= 138 && version < 140)
9297 {
9298 if (m_VariablesMask & VARIABLE_TEMPERATURE)
9299 {
9300 if (!ctx.Read(intValue))
9301 return false;
9302 SetFrozen(intValue);
9303 }
9304 }
9305
9306 return true;
9307 }
9308
9309 //----------------------------------------------------------------
9310 override bool OnStoreLoad(ParamsReadContext ctx, int version)
9311 {
9312 m_IsStoreLoad = true;
9314 {
9315 m_FixDamageSystemInit = true;
9316 }
9317
9318 if (!super.OnStoreLoad(ctx, version))
9319 {
9320 m_IsStoreLoad = false;
9321 return false;
9322 }
9323
9324 if (version >= 114)
9325 {
9326 bool hasQuickBarIndexSaved;
9327
9328 if (!ctx.Read(hasQuickBarIndexSaved))
9329 {
9330 m_IsStoreLoad = false;
9331 return false;
9332 }
9333
9334 if (hasQuickBarIndexSaved)
9335 {
9336 int itmQBIndex;
9337
9338 //Load quickbar item bind
9339 if (!ctx.Read(itmQBIndex))
9340 {
9341 m_IsStoreLoad = false;
9342 return false;
9343 }
9344
9345 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
9346 if (itmQBIndex != -1 && parentPlayer)
9347 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
9348 }
9349 }
9350 else
9351 {
9352 // Backup of how it used to be
9353 PlayerBase player;
9354 int itemQBIndex;
9355 if (version == int.MAX)
9356 {
9357 if (!ctx.Read(itemQBIndex))
9358 {
9359 m_IsStoreLoad = false;
9360 return false;
9361 }
9362 }
9363 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
9364 {
9365 //Load quickbar item bind
9366 if (!ctx.Read(itemQBIndex))
9367 {
9368 m_IsStoreLoad = false;
9369 return false;
9370 }
9371 if (itemQBIndex != -1 && player)
9372 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
9373 }
9374 }
9375
9376 if (version < 140)
9377 {
9378 // variable management system
9379 if (!LoadVariables(ctx, version))
9380 {
9381 m_IsStoreLoad = false;
9382 return false;
9383 }
9384 }
9385
9386 //agent trasmission system
9387 if (!LoadAgents(ctx, version))
9388 {
9389 m_IsStoreLoad = false;
9390 return false;
9391 }
9392 if (version >= 132)
9393 {
9394 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
9395 if (raib)
9396 {
9397 if (!raib.OnStoreLoad(ctx,version))
9398 {
9399 m_IsStoreLoad = false;
9400 return false;
9401 }
9402 }
9403 }
9404
9405 m_IsStoreLoad = false;
9406 return true;
9407 }
9408
9409 //----------------------------------------------------------------
9410
9411 override void OnStoreSave(ParamsWriteContext ctx)
9412 {
9413 super.OnStoreSave(ctx);
9414
9415 PlayerBase player;
9416 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
9417 {
9418 ctx.Write(true); // Keep track of if we should actually read this in or not
9419 //Save quickbar item bind
9420 int itemQBIndex = -1;
9421 itemQBIndex = player.FindQuickBarEntityIndex(this);
9422 ctx.Write(itemQBIndex);
9423 }
9424 else
9425 {
9426 ctx.Write(false); // Keep track of if we should actually read this in or not
9427 }
9428
9429 SaveAgents(ctx);//agent trasmission system
9430
9431 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
9432 if (raib)
9433 {
9434 raib.OnStoreSave(ctx);
9435 }
9436 }
9437 //----------------------------------------------------------------
9438
9439 override void AfterStoreLoad()
9440 {
9441 super.AfterStoreLoad();
9442
9444 {
9446 }
9447
9448 if (GetStoreLoadedQuantity() != float.LOWEST)
9449 {
9451 SetStoreLoadedQuantity(float.LOWEST);//IMPORTANT to do this !! we use 'm_StoreLoadedQuantity' inside SetQuantity to distinguish between initial quantity setting and the consequent(normal gameplay) calls
9452 }
9453 }
9454
9455 override void EEOnAfterLoad()
9456 {
9457 super.EEOnAfterLoad();
9458
9460 {
9461 m_FixDamageSystemInit = false;
9462 }
9463
9466 }
9467
9468 bool CanBeDisinfected()
9469 {
9470 return false;
9471 }
9472
9473
9474 //----------------------------------------------------------------
9475 override void OnVariablesSynchronized()
9476 {
9477 if (m_Initialized)
9478 {
9479 #ifdef PLATFORM_CONSOLE
9480 //bruteforce it is
9481 if (IsSplitable())
9482 {
9483 UIScriptedMenu menu = GetGame().GetUIManager().FindMenu(MENU_INVENTORY);
9484 if (menu)
9485 {
9486 menu.Refresh();
9487 }
9488 }
9489 #endif
9490 }
9491
9493 {
9494 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
9495 m_WantPlayImpactSound = false;
9496 }
9497
9499 {
9500 SetWeightDirty();
9502 }
9503 if (m_VarWet != m_VarWetPrev)
9504 {
9507 }
9508
9509 if (m_SoundSyncPlay != 0)
9510 {
9511 m_ItemSoundHandler.PlayItemSoundClient(m_SoundSyncPlay);
9512 m_SoundSyncPlay = 0;
9513 }
9514 if (m_SoundSyncStop != 0)
9515 {
9516 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
9517 m_SoundSyncStop = 0;
9518 }
9519
9520 super.OnVariablesSynchronized();
9521 }
9522
9523 //------------------------- Quantity
9524 //----------------------------------------------------------------
9526 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
9527 {
9528 if (!IsServerCheck(allow_client))
9529 return false;
9530
9531 if (!HasQuantity())
9532 return false;
9533
9534 float min = GetQuantityMin();
9535 float max = GetQuantityMax();
9536
9537 if (value <= (min + 0.001))
9538 value = min;
9539
9540 if (value == min)
9541 {
9542 if (destroy_config)
9543 {
9544 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
9545 if (dstr)
9546 {
9547 m_VarQuantity = Math.Clamp(value, min, max);
9548 this.Delete();
9549 return true;
9550 }
9551 }
9552 else if (destroy_forced)
9553 {
9554 m_VarQuantity = Math.Clamp(value, min, max);
9555 this.Delete();
9556 return true;
9557 }
9558 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
9559 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
9560 }
9561
9562 float delta = m_VarQuantity;
9563 m_VarQuantity = Math.Clamp(value, min, max);
9564
9565 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
9566 {
9567 delta = m_VarQuantity - delta;
9568
9569 if (delta)
9570 OnQuantityChanged(delta);
9571 }
9572
9573 SetVariableMask(VARIABLE_QUANTITY);
9574
9575 return false;
9576 }
9577
9578 //----------------------------------------------------------------
9580 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
9581 {
9582 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
9583 }
9584 //----------------------------------------------------------------
9585 void SetQuantityMax()
9586 {
9587 float max = GetQuantityMax();
9588 SetQuantity(max);
9589 }
9590
9591 override void SetQuantityToMinimum()
9592 {
9593 float min = GetQuantityMin();
9594 SetQuantity(min);
9595 }
9596 //----------------------------------------------------------------
9598 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
9599 {
9600 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
9601 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
9602 SetQuantity(result, destroy_config, destroy_forced);
9603 }
9604
9605 //----------------------------------------------------------------
9607 override float GetQuantityNormalized()
9608 {
9609 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
9610 }
9611
9613 {
9614 return GetQuantityNormalized();
9615 }
9616
9617 /*void SetAmmoNormalized(float value)
9618 {
9619 float value_clamped = Math.Clamp(value, 0, 1);
9620 Magazine this_mag = Magazine.Cast(this);
9621 int max_rounds = this_mag.GetAmmoMax();
9622 int result = value * max_rounds;//can the rounded if higher precision is required
9623 this_mag.SetAmmoCount(result);
9624 }*/
9625 //----------------------------------------------------------------
9626 override int GetQuantityMax()
9627 {
9628 int slot = -1;
9629 if (GetInventory())
9630 {
9631 InventoryLocation il = new InventoryLocation;
9632 GetInventory().GetCurrentInventoryLocation(il);
9633 slot = il.GetSlot();
9634 }
9635
9636 return GetTargetQuantityMax(slot);
9637 }
9638
9639 override int GetTargetQuantityMax(int attSlotID = -1)
9640 {
9641 float quantity_max = 0;
9642
9643 if (IsSplitable()) //only stackable/splitable items can check for stack size
9644 {
9645 if (attSlotID != -1)
9646 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
9647
9648 if (quantity_max <= 0)
9649 quantity_max = m_VarStackMax;
9650 }
9651
9652 if (quantity_max <= 0)
9653 quantity_max = m_VarQuantityMax;
9654
9655 return quantity_max;
9656 }
9657 //----------------------------------------------------------------
9658 override int GetQuantityMin()
9659 {
9660 return m_VarQuantityMin;
9661 }
9662 //----------------------------------------------------------------
9663 int GetQuantityInit()
9664 {
9665 return m_VarQuantityInit;
9666 }
9667
9668 //----------------------------------------------------------------
9669 override bool HasQuantity()
9670 {
9671 return !(GetQuantityMax() - GetQuantityMin() == 0);
9672 }
9673
9674 override float GetQuantity()
9675 {
9676 return m_VarQuantity;
9677 }
9678
9679 bool IsFullQuantity()
9680 {
9681 return GetQuantity() >= GetQuantityMax();
9682 }
9683
9684 //Calculates weight of single item without attachments and cargo
9685 override float GetSingleInventoryItemWeightEx()
9686 {
9687 //this needs to be first stored inside local variables, when returned directly during inside return call, the result is completely different due to enforce script bug
9688 float weightEx = GetWeightEx();//overall weight of the item
9689 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
9690 return weightEx - special;
9691 }
9692
9693 // Obsolete, use GetSingleInventoryItemWeightEx() instead
9695 {
9697 }
9698
9699 override protected float GetWeightSpecialized(bool forceRecalc = false)
9700 {
9701 if (IsSplitable()) //quantity determines size of the stack
9702 {
9703 #ifdef DEVELOPER
9704 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9705 {
9706 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
9707 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
9708 }
9709 #endif
9710
9711 return GetQuantity() * GetConfigWeightModified();
9712 }
9713 else if (HasEnergyManager())// items with energy manager
9714 {
9715 #ifdef DEVELOPER
9716 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9717 {
9718 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
9719 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
9720 }
9721 #endif
9722 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9723 }
9724 else//everything else
9725 {
9726 #ifdef DEVELOPER
9727 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9728 {
9729 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
9730 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
9731 }
9732 #endif
9733 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9734 }
9735 }
9736
9738 int GetNumberOfItems()
9739 {
9740 int item_count = 0;
9741 ItemBase item;
9742
9743 if (GetInventory().GetCargo() != NULL)
9744 {
9745 item_count = GetInventory().GetCargo().GetItemCount();
9746 }
9747
9748 for (int i = 0; i < GetInventory().AttachmentCount(); i++)
9749 {
9750 Class.CastTo(item,GetInventory().GetAttachmentFromIndex(i));
9751 if (item)
9752 item_count += item.GetNumberOfItems();
9753 }
9754 return item_count;
9755 }
9756
9758 float GetUnitWeight(bool include_wetness = true)
9759 {
9760 float weight = 0;
9761 float wetness = 1;
9762 if (include_wetness)
9763 wetness += GetWet();
9764 if (IsSplitable()) //quantity determines size of the stack
9765 {
9766 weight = wetness * m_ConfigWeight;
9767 }
9768 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
9769 {
9770 weight = 1;
9771 }
9772 return weight;
9773 }
9774
9775 //-----------------------------------------------------------------
9776
9777 override void ClearInventory()
9778 {
9779 if ((GetGame().IsServer() || !GetGame().IsMultiplayer()) && GetInventory())
9780 {
9781 GameInventory inv = GetInventory();
9782 array<EntityAI> items = new array<EntityAI>;
9783 inv.EnumerateInventory(InventoryTraversalType.INORDER, items);
9784 for (int i = 0; i < items.Count(); i++)
9785 {
9786 ItemBase item = ItemBase.Cast(items.Get(i));
9787 if (item)
9788 {
9789 GetGame().ObjectDelete(item);
9790 }
9791 }
9792 }
9793 }
9794
9795 //------------------------- Energy
9796
9797 //----------------------------------------------------------------
9798 float GetEnergy()
9799 {
9800 float energy = 0;
9801 if (HasEnergyManager())
9802 {
9803 energy = GetCompEM().GetEnergy();
9804 }
9805 return energy;
9806 }
9807
9808
9809 override void OnEnergyConsumed()
9810 {
9811 super.OnEnergyConsumed();
9812
9814 }
9815
9816 override void OnEnergyAdded()
9817 {
9818 super.OnEnergyAdded();
9819
9821 }
9822
9823 // Converts energy (from Energy Manager) to quantity, if enabled.
9825 {
9826 if (GetGame().IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
9827 {
9828 if (HasQuantity())
9829 {
9830 float energy_0to1 = GetCompEM().GetEnergy0To1();
9831 SetQuantityNormalized(energy_0to1);
9832 }
9833 }
9834 }
9835
9836 //----------------------------------------------------------------
9837 float GetHeatIsolationInit()
9838 {
9839 return ConfigGetFloat("heatIsolation");
9840 }
9841
9842 float GetHeatIsolation()
9843 {
9844 return m_HeatIsolation;
9845 }
9846
9847 float GetDryingIncrement(string pIncrementName)
9848 {
9849 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
9850 if (GetGame().ConfigIsExisting(paramPath))
9851 return GetGame().ConfigGetFloat(paramPath);
9852
9853 return 0.0;
9854 }
9855
9856 float GetSoakingIncrement(string pIncrementName)
9857 {
9858 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
9859 if (GetGame().ConfigIsExisting(paramPath))
9860 return GetGame().ConfigGetFloat(paramPath);
9861
9862 return 0.0;
9863 }
9864 //----------------------------------------------------------------
9865 override void SetWet(float value, bool allow_client = false)
9866 {
9867 if (!IsServerCheck(allow_client))
9868 return;
9869
9870 float min = GetWetMin();
9871 float max = GetWetMax();
9872
9873 float previousValue = m_VarWet;
9874
9875 m_VarWet = Math.Clamp(value, min, max);
9876
9877 if (previousValue != m_VarWet)
9878 {
9879 SetVariableMask(VARIABLE_WET);
9880 OnWetChanged(m_VarWet, previousValue);
9881 }
9882 }
9883 //----------------------------------------------------------------
9884 override void AddWet(float value)
9885 {
9886 SetWet(GetWet() + value);
9887 }
9888 //----------------------------------------------------------------
9889 override void SetWetMax()
9890 {
9892 }
9893 //----------------------------------------------------------------
9894 override float GetWet()
9895 {
9896 return m_VarWet;
9897 }
9898 //----------------------------------------------------------------
9899 override float GetWetMax()
9900 {
9901 return m_VarWetMax;
9902 }
9903 //----------------------------------------------------------------
9904 override float GetWetMin()
9905 {
9906 return m_VarWetMin;
9907 }
9908 //----------------------------------------------------------------
9909 override float GetWetInit()
9910 {
9911 return m_VarWetInit;
9912 }
9913 //----------------------------------------------------------------
9914 override void OnWetChanged(float newVal, float oldVal)
9915 {
9916 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
9917 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
9918 if (newLevel != oldLevel)
9919 {
9920 OnWetLevelChanged(newLevel,oldLevel);
9921 }
9922 }
9923
9924 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
9925 {
9926 SetWeightDirty();
9927 }
9928
9929 override EWetnessLevel GetWetLevel()
9930 {
9931 return GetWetLevelInternal(m_VarWet);
9932 }
9933
9934 //----------------------------------------------------------------
9935
9936 override void SetStoreLoad(bool value)
9937 {
9938 m_IsStoreLoad = value;
9939 }
9940
9941 override bool IsStoreLoad()
9942 {
9943 return m_IsStoreLoad;
9944 }
9945
9946 override void SetStoreLoadedQuantity(float value)
9947 {
9948 m_StoreLoadedQuantity = value;
9949 }
9950
9951 override float GetStoreLoadedQuantity()
9952 {
9953 return m_StoreLoadedQuantity;
9954 }
9955
9956 //----------------------------------------------------------------
9957
9958 float GetItemModelLength()
9959 {
9960 if (ConfigIsExisting("itemModelLength"))
9961 {
9962 return ConfigGetFloat("itemModelLength");
9963 }
9964 return 0;
9965 }
9966
9967 float GetItemAttachOffset()
9968 {
9969 if (ConfigIsExisting("itemAttachOffset"))
9970 {
9971 return ConfigGetFloat("itemAttachOffset");
9972 }
9973 return 0;
9974 }
9975
9976 override void SetCleanness(int value, bool allow_client = false)
9977 {
9978 if (!IsServerCheck(allow_client))
9979 return;
9980
9981 int previousValue = m_Cleanness;
9982
9983 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
9984
9985 if (previousValue != m_Cleanness)
9986 SetVariableMask(VARIABLE_CLEANNESS);
9987 }
9988
9989 override int GetCleanness()
9990 {
9991 return m_Cleanness;
9992 }
9993
9995 {
9996 return true;
9997 }
9998
9999 //----------------------------------------------------------------
10000 // ATTACHMENT LOCKING
10001 // Getters relevant to generic ActionLockAttachment
10002 int GetLockType()
10003 {
10004 return m_LockType;
10005 }
10006
10007 string GetLockSoundSet()
10008 {
10009 return m_LockSoundSet;
10010 }
10011
10012 //----------------------------------------------------------------
10013 //------------------------- Color
10014 // sets items color variable given color components
10015 override void SetColor(int r, int g, int b, int a)
10016 {
10021 SetVariableMask(VARIABLE_COLOR);
10022 }
10024 override void GetColor(out int r,out int g,out int b,out int a)
10025 {
10030 }
10031
10032 bool IsColorSet()
10033 {
10034 return IsVariableSet(VARIABLE_COLOR);
10035 }
10036
10038 string GetColorString()
10039 {
10040 int r,g,b,a;
10041 GetColor(r,g,b,a);
10042 r = r/255;
10043 g = g/255;
10044 b = b/255;
10045 a = a/255;
10046 return MiscGameplayFunctions.GetColorString(r, g, b, a);
10047 }
10048 //----------------------------------------------------------------
10049 //------------------------- LiquidType
10050
10051 override void SetLiquidType(int value, bool allow_client = false)
10052 {
10053 if (!IsServerCheck(allow_client))
10054 return;
10055
10056 int old = m_VarLiquidType;
10057 m_VarLiquidType = value;
10058 OnLiquidTypeChanged(old,value);
10059 SetVariableMask(VARIABLE_LIQUIDTYPE);
10060 }
10061
10062 int GetLiquidTypeInit()
10063 {
10064 return ConfigGetInt("varLiquidTypeInit");
10065 }
10066
10067 override int GetLiquidType()
10068 {
10069 return m_VarLiquidType;
10070 }
10071
10072 protected void OnLiquidTypeChanged(int oldType, int newType)
10073 {
10074 if (newType == LIQUID_NONE && GetIsFrozen())
10075 SetFrozen(false);
10076 }
10077
10079 void UpdateQuickbarShortcutVisibility(PlayerBase player)
10080 {
10081 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
10082 }
10083
10084 // -------------------------------------------------------------------------
10086 void OnInventoryEnter(Man player)
10087 {
10088 PlayerBase nplayer;
10089 if (PlayerBase.CastTo(nplayer, player))
10090 {
10091 m_CanPlayImpactSound = true;
10092 //nplayer.OnItemInventoryEnter(this);
10093 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
10094 }
10095 }
10096
10097 // -------------------------------------------------------------------------
10099 void OnInventoryExit(Man player)
10100 {
10101 PlayerBase nplayer;
10102 if (PlayerBase.CastTo(nplayer,player))
10103 {
10104 //nplayer.OnItemInventoryExit(this);
10105 nplayer.SetEnableQuickBarEntityShortcut(this,false);
10106
10107 }
10108
10109 //if (!GetGame().IsDedicatedServer())
10110 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
10111
10112
10113 if (HasEnergyManager())
10114 {
10115 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
10116 }
10117 }
10118
10119 // ADVANCED PLACEMENT EVENTS
10120 override void OnPlacementStarted(Man player)
10121 {
10122 super.OnPlacementStarted(player);
10123
10124 SetTakeable(false);
10125 }
10126
10127 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
10128 {
10129 if (m_AdminLog)
10130 {
10131 m_AdminLog.OnPlacementComplete(player, this);
10132 }
10133
10134 super.OnPlacementComplete(player, position, orientation);
10135 }
10136
10137 //-----------------------------
10138 // AGENT SYSTEM
10139 //-----------------------------
10140 //--------------------------------------------------------------------------
10141 bool ContainsAgent(int agent_id)
10142 {
10143 if (agent_id & m_AttachedAgents)
10144 {
10145 return true;
10146 }
10147 else
10148 {
10149 return false;
10150 }
10151 }
10152
10153 //--------------------------------------------------------------------------
10154 override void RemoveAgent(int agent_id)
10155 {
10156 if (ContainsAgent(agent_id))
10157 {
10158 m_AttachedAgents = ~agent_id & m_AttachedAgents;
10159 }
10160 }
10161
10162 //--------------------------------------------------------------------------
10163 override void RemoveAllAgents()
10164 {
10165 m_AttachedAgents = 0;
10166 }
10167 //--------------------------------------------------------------------------
10168 override void RemoveAllAgentsExcept(int agent_to_keep)
10169 {
10170 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
10171 }
10172 // -------------------------------------------------------------------------
10173 override void InsertAgent(int agent, float count = 1)
10174 {
10175 if (count < 1)
10176 return;
10177 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
10179 }
10180
10182 void TransferAgents(int agents)
10183 {
10185 }
10186
10187 // -------------------------------------------------------------------------
10188 override int GetAgents()
10189 {
10190 return m_AttachedAgents;
10191 }
10192 //----------------------------------------------------------------------
10193
10194 /*int GetContaminationType()
10195 {
10196 int contamination_type;
10197
10198 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
10199 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
10200 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
10201 const int DIRTY_MASK = eAgents.WOUND_AGENT;
10202
10203 Edible_Base edible = Edible_Base.Cast(this);
10204 int agents = GetAgents();
10205 if (edible)
10206 {
10207 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
10208 if (profile)
10209 {
10210 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
10211 }
10212 }
10213 if (agents & CONTAMINATED_MASK)
10214 {
10215 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
10216 }
10217 if (agents & POISONED_MASK)
10218 {
10219 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
10220 }
10221 if (agents & NERVE_GAS_MASK)
10222 {
10223 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
10224 }
10225 if (agents & DIRTY_MASK)
10226 {
10227 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
10228 }
10229
10230 return agents;
10231 }*/
10232
10233 // -------------------------------------------------------------------------
10234 bool LoadAgents(ParamsReadContext ctx, int version)
10235 {
10236 if (!ctx.Read(m_AttachedAgents))
10237 return false;
10238 return true;
10239 }
10240 // -------------------------------------------------------------------------
10242 {
10243
10245 }
10246 // -------------------------------------------------------------------------
10247
10249 override void CheckForRoofLimited(float timeTresholdMS = 3000)
10250 {
10251 super.CheckForRoofLimited(timeTresholdMS);
10252
10253 float time = GetGame().GetTime();
10254 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
10255 {
10256 m_PreviousRoofTestTime = time;
10257 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
10258 }
10259 }
10260
10261 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
10262 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
10263 {
10264 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
10265 {
10266 return 0;
10267 }
10268
10269 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
10270 {
10271 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
10272 if (filter)
10273 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
10274 else
10275 return 0;//otherwise return 0 when no filter attached
10276 }
10277
10278 string subclassPath, entryName;
10279
10280 switch (type)
10281 {
10282 case DEF_BIOLOGICAL:
10283 entryName = "biological";
10284 break;
10285 case DEF_CHEMICAL:
10286 entryName = "chemical";
10287 break;
10288 default:
10289 entryName = "biological";
10290 break;
10291 }
10292
10293 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
10294
10295 return GetGame().ConfigGetFloat(subclassPath + entryName);
10296 }
10297
10298
10299
10301 override void EEOnCECreate()
10302 {
10303 if (!IsMagazine())
10305
10307 }
10308
10309
10310 //-------------------------
10311 // OPEN/CLOSE USER ACTIONS
10312 //-------------------------
10314 void Open();
10315 void Close();
10316 bool IsOpen()
10317 {
10318 return true;
10319 }
10320
10321 override bool CanDisplayCargo()
10322 {
10323 return IsOpen();
10324 }
10325
10326
10327 // ------------------------------------------------------------
10328 // CONDITIONS
10329 // ------------------------------------------------------------
10330 override bool CanPutInCargo(EntityAI parent)
10331 {
10332 if (parent)
10333 {
10334 if (parent.IsInherited(DayZInfected))
10335 return true;
10336
10337 if (!parent.IsRuined())
10338 return true;
10339 }
10340
10341 return true;
10342 }
10343
10344 override bool CanPutAsAttachment(EntityAI parent)
10345 {
10346 if (!super.CanPutAsAttachment(parent))
10347 {
10348 return false;
10349 }
10350
10351 if (!IsRuined() && !parent.IsRuined())
10352 {
10353 return true;
10354 }
10355
10356 return false;
10357 }
10358
10359 override bool CanReceiveItemIntoCargo(EntityAI item)
10360 {
10361 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
10362 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
10363 // return false;
10364
10365 return super.CanReceiveItemIntoCargo(item);
10366 }
10367
10368 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
10369 {
10370 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
10371 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
10372 // return false;
10373
10374 GameInventory attachmentInv = attachment.GetInventory();
10375 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
10376 {
10377 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
10378 return false;
10379 }
10380
10381 InventoryLocation loc = new InventoryLocation();
10382 attachment.GetInventory().GetCurrentInventoryLocation(loc);
10383 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
10384 return false;
10385
10386 return super.CanReceiveAttachment(attachment, slotId);
10387 }
10388
10389 override bool CanReleaseAttachment(EntityAI attachment)
10390 {
10391 if (!super.CanReleaseAttachment(attachment))
10392 return false;
10393
10394 return GetInventory().AreChildrenAccessible();
10395 }
10396
10397 /*override bool CanLoadAttachment(EntityAI attachment)
10398 {
10399 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
10400 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
10401 // return false;
10402
10403 GameInventory attachmentInv = attachment.GetInventory();
10404 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
10405 {
10406 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
10407 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
10408
10409 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
10410 return false;
10411 }
10412
10413 return super.CanLoadAttachment(attachment);
10414 }*/
10415
10416 // Plays muzzle flash particle effects
10417 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10418 {
10419 int id = muzzle_owner.GetMuzzleID();
10420 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
10421
10422 if (WPOF_array)
10423 {
10424 for (int i = 0; i < WPOF_array.Count(); i++)
10425 {
10426 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
10427
10428 if (WPOF)
10429 {
10430 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
10431 }
10432 }
10433 }
10434 }
10435
10436 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
10437 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10438 {
10439 int id = muzzle_owner.GetMuzzleID();
10440 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
10441
10442 if (WPOBE_array)
10443 {
10444 for (int i = 0; i < WPOBE_array.Count(); i++)
10445 {
10446 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
10447
10448 if (WPOBE)
10449 {
10450 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
10451 }
10452 }
10453 }
10454 }
10455
10456 // Plays all weapon overheating particles
10457 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10458 {
10459 int id = muzzle_owner.GetMuzzleID();
10460 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
10461
10462 if (WPOOH_array)
10463 {
10464 for (int i = 0; i < WPOOH_array.Count(); i++)
10465 {
10466 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
10467
10468 if (WPOOH)
10469 {
10470 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
10471 }
10472 }
10473 }
10474 }
10475
10476 // Updates all weapon overheating particles
10477 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10478 {
10479 int id = muzzle_owner.GetMuzzleID();
10480 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
10481
10482 if (WPOOH_array)
10483 {
10484 for (int i = 0; i < WPOOH_array.Count(); i++)
10485 {
10486 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
10487
10488 if (WPOOH)
10489 {
10490 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
10491 }
10492 }
10493 }
10494 }
10495
10496 // Stops overheating particles
10497 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10498 {
10499 int id = muzzle_owner.GetMuzzleID();
10500 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
10501
10502 if (WPOOH_array)
10503 {
10504 for (int i = 0; i < WPOOH_array.Count(); i++)
10505 {
10506 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
10507
10508 if (WPOOH)
10509 {
10510 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
10511 }
10512 }
10513 }
10514 }
10515
10516 //----------------------------------------------------------------
10517 //Item Behaviour - unified approach
10518 override bool IsHeavyBehaviour()
10519 {
10520 if (m_ItemBehaviour == 0)
10521 {
10522 return true;
10523 }
10524
10525 return false;
10526 }
10527
10528 override bool IsOneHandedBehaviour()
10529 {
10530 if (m_ItemBehaviour == 1)
10531 {
10532 return true;
10533 }
10534
10535 return false;
10536 }
10537
10538 override bool IsTwoHandedBehaviour()
10539 {
10540 if (m_ItemBehaviour == 2)
10541 {
10542 return true;
10543 }
10544
10545 return false;
10546 }
10547
10548 bool IsDeployable()
10549 {
10550 return false;
10551 }
10552
10554 float GetDeployTime()
10555 {
10556 return UATimeSpent.DEFAULT_DEPLOY;
10557 }
10558
10559
10560 //----------------------------------------------------------------
10561 // Item Targeting (User Actions)
10562 override void SetTakeable(bool pState)
10563 {
10564 m_IsTakeable = pState;
10565 SetSynchDirty();
10566 }
10567
10568 override bool IsTakeable()
10569 {
10570 return m_IsTakeable;
10571 }
10572
10573 // For cases where we want to show object widget which cant be taken to hands
10575 {
10576 return false;
10577 }
10578
10580 protected void PreLoadSoundAttachmentType()
10581 {
10582 string att_type = "None";
10583
10584 if (ConfigIsExisting("soundAttType"))
10585 {
10586 att_type = ConfigGetString("soundAttType");
10587 }
10588
10589 m_SoundAttType = att_type;
10590 }
10591
10592 override string GetAttachmentSoundType()
10593 {
10594 return m_SoundAttType;
10595 }
10596
10597 //----------------------------------------------------------------
10598 //SOUNDS - ItemSoundHandler
10599 //----------------------------------------------------------------
10600
10601 string GetPlaceSoundset(); // played when deploy starts
10602 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
10603 string GetDeploySoundset(); // played when deploy sucessfully finishes
10604 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
10605 string GetFoldSoundset(); // played when fold sucessfully finishes
10606
10608 {
10609 if (!m_ItemSoundHandler)
10611
10612 return m_ItemSoundHandler;
10613 }
10614
10615 // override to initialize sounds
10616 protected void InitItemSounds()
10617 {
10618 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty)
10619 return;
10620
10622
10623 if (GetPlaceSoundset() != string.Empty)
10624 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
10625
10626 if (GetDeploySoundset() != string.Empty)
10627 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
10628
10629 SoundParameters params = new SoundParameters();
10630 params.m_Loop = true;
10631 if (GetLoopDeploySoundset() != string.Empty)
10632 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
10633 }
10634
10635 // Start sound using ItemSoundHandler
10636 void StartItemSoundServer(int id)
10637 {
10638 if (!GetGame().IsServer())
10639 return;
10640
10641 m_SoundSyncPlay = id;
10642 SetSynchDirty();
10643
10644 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
10646 }
10647
10648 // Stop sound using ItemSoundHandler
10649 void StopItemSoundServer(int id)
10650 {
10651 if (!GetGame().IsServer())
10652 return;
10653
10654 m_SoundSyncStop = id;
10655 SetSynchDirty();
10656
10657 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
10659 }
10660
10661 protected void ClearStartItemSoundServer()
10662 {
10663 m_SoundSyncPlay = 0;
10664 }
10665
10666 protected void ClearStopItemSoundServer()
10667 {
10668 m_SoundSyncStop = 0;
10669 }
10670
10672 void PlayAttachSound(string slot_type)
10673 {
10674 if (!GetGame().IsDedicatedServer())
10675 {
10676 if (ConfigIsExisting("attachSoundSet"))
10677 {
10678 string cfg_path = "";
10679 string soundset = "";
10680 string type_name = GetType();
10681
10682 TStringArray cfg_soundset_array = new TStringArray;
10683 TStringArray cfg_slot_array = new TStringArray;
10684 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
10685 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
10686
10687 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
10688 {
10689 for (int i = 0; i < cfg_soundset_array.Count(); i++)
10690 {
10691 if (cfg_slot_array[i] == slot_type)
10692 {
10693 soundset = cfg_soundset_array[i];
10694 break;
10695 }
10696 }
10697 }
10698
10699 if (soundset != "")
10700 {
10701 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
10702 sound.SetAutodestroy(true);
10703 }
10704 }
10705 }
10706 }
10707
10708 void PlayDetachSound(string slot_type)
10709 {
10710 //TODO - evaluate if needed and devise universal config structure if so
10711 }
10712
10713 void OnApply(PlayerBase player);
10714
10716 {
10717 return 1.0;
10718 };
10719 //returns applicable selection
10720 array<string> GetHeadHidingSelection()
10721 {
10723 }
10724
10726 {
10728 }
10729
10730 WrittenNoteData GetWrittenNoteData() {};
10731
10733 {
10734 SetDynamicPhysicsLifeTime(0.01);
10735 m_ItemBeingDroppedPhys = false;
10736 }
10737
10739 {
10740 array<string> zone_names = new array<string>;
10741 GetDamageZones(zone_names);
10742 for (int i = 0; i < zone_names.Count(); i++)
10743 {
10744 SetHealthMax(zone_names.Get(i),"Health");
10745 }
10746 SetHealthMax("","Health");
10747 }
10748
10750 void SetZoneDamageCEInit()
10751 {
10752 float global_health = GetHealth01("","Health");
10753 array<string> zones = new array<string>;
10754 GetDamageZones(zones);
10755 //set damage of all zones to match global health level
10756 for (int i = 0; i < zones.Count(); i++)
10757 {
10758 SetHealth01(zones.Get(i),"Health",global_health);
10759 }
10760 }
10761
10763 bool IsCoverFaceForShave(string slot_name)
10764 {
10765 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
10766 }
10767
10768 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10769 {
10770 if (!hasRootAsPlayer)
10771 {
10772 if (refParentIB)
10773 {
10774 // parent is wet
10775 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
10776 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
10777 // parent has liquid inside
10778 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
10779 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
10780 // drying
10781 else if (m_VarWet > m_VarWetMin)
10782 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
10783 }
10784 else
10785 {
10786 // drying on ground or inside non-itembase (car, ...)
10787 if (m_VarWet > m_VarWetMin)
10788 AddWet(-1 * delta * GetDryingIncrement("ground"));
10789 }
10790 }
10791 }
10792
10793 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10794 {
10796 {
10797 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
10798 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
10799 {
10800 float heatPermCoef = 1.0;
10801 EntityAI ent = this;
10802 while (ent)
10803 {
10804 heatPermCoef *= ent.GetHeatPermeabilityCoef();
10805 ent = ent.GetHierarchyParent();
10806 }
10807
10808 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
10809 }
10810 }
10811 }
10812
10813 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
10814 {
10815 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
10816 EntityAI parent = GetHierarchyParent();
10817 if (!parent)
10818 {
10819 hasParent = false;
10820 hasRootAsPlayer = false;
10821 }
10822 else
10823 {
10824 hasParent = true;
10825 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
10826 refParentIB = ItemBase.Cast(parent);
10827 }
10828 }
10829
10830 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
10831 {
10832 // this is stub, implemented on Edible_Base
10833 }
10834
10835 bool CanDecay()
10836 {
10837 // return true used on selected food clases so they can decay
10838 return false;
10839 }
10840
10841 protected bool CanProcessDecay()
10842 {
10843 // this is stub, implemented on Edible_Base class
10844 // used to determine whether it is still necessary for the food to decay
10845 return false;
10846 }
10847
10848 protected bool CanHaveWetness()
10849 {
10850 // return true used on selected items that have a wetness effect
10851 return false;
10852 }
10853
10855 bool CanBeConsumed(ConsumeConditionData data = null)
10856 {
10857 return !GetIsFrozen() && IsOpen();
10858 }
10859
10860 override void ProcessVariables()
10861 {
10862 bool hasParent = false, hasRootAsPlayer = false;
10863 ItemBase refParentIB;
10864
10865 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
10866 bool foodDecay = g_Game.IsFoodDecayEnabled();
10867
10868 if (wwtu || foodDecay)
10869 {
10870 bool processWetness = wwtu && CanHaveWetness();
10871 bool processTemperature = wwtu && CanHaveTemperature();
10872 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
10873
10874 if (processWetness || processTemperature || processDecay)
10875 {
10876 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
10877
10878 if (processWetness)
10879 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10880
10881 if (processTemperature)
10882 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10883
10884 if (processDecay)
10885 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
10886 }
10887 }
10888 }
10889
10892 {
10893 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
10894 }
10895
10896 override float GetTemperatureFreezeThreshold()
10897 {
10899 return Liquid.GetFreezeThreshold(GetLiquidType());
10900
10901 return super.GetTemperatureFreezeThreshold();
10902 }
10903
10904 override float GetTemperatureThawThreshold()
10905 {
10907 return Liquid.GetThawThreshold(GetLiquidType());
10908
10909 return super.GetTemperatureThawThreshold();
10910 }
10911
10912 override float GetItemOverheatThreshold()
10913 {
10915 return Liquid.GetBoilThreshold(GetLiquidType());
10916
10917 return super.GetItemOverheatThreshold();
10918 }
10919
10920 override float GetTemperatureFreezeTime()
10921 {
10922 if (HasQuantity())
10923 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
10924
10925 return super.GetTemperatureFreezeTime();
10926 }
10927
10928 override float GetTemperatureThawTime()
10929 {
10930 if (HasQuantity())
10931 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
10932
10933 return super.GetTemperatureThawTime();
10934 }
10935
10937 void AffectLiquidContainerOnFill(int liquid_type, float amount);
10939 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
10940
10941 bool IsCargoException4x3(EntityAI item)
10942 {
10943 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
10944 }
10945
10947 {
10948 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
10949 }
10950
10952 void AddLightSourceItem(ItemBase lightsource)
10953 {
10954 m_LightSourceItem = lightsource;
10955 }
10956
10958 {
10959 m_LightSourceItem = null;
10960 }
10961
10963 {
10964 return m_LightSourceItem;
10965 }
10966
10968 array<int> GetValidFinishers()
10969 {
10970 return null;
10971 }
10972
10974 bool GetActionWidgetOverride(out typename name)
10975 {
10976 return false;
10977 }
10978
10979 bool PairWithDevice(notnull ItemBase otherDevice)
10980 {
10981 if (GetGame().IsServer())
10982 {
10983 ItemBase explosive = otherDevice;
10985 if (!trg)
10986 {
10987 trg = RemoteDetonatorTrigger.Cast(otherDevice);
10988 explosive = this;
10989 }
10990
10991 explosive.PairRemote(trg);
10992 trg.SetControlledDevice(explosive);
10993
10994 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
10995 trg.SetPersistentPairID(persistentID);
10996 explosive.SetPersistentPairID(persistentID);
10997
10998 return true;
10999 }
11000 return false;
11001 }
11002
11004 float GetBaitEffectivity()
11005 {
11006 float ret = 1.0;
11007 if (HasQuantity())
11008 ret *= GetQuantityNormalized();
11009 ret *= GetHealth01();
11010
11011 return ret;
11012 }
11013
11014 #ifdef DEVELOPER
11015 override void SetDebugItem()
11016 {
11017 super.SetDebugItem();
11018 _itemBase = this;
11019 }
11020
11021 override string GetDebugText()
11022 {
11023 string text = super.GetDebugText();
11024
11025 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
11026 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
11027
11028 return text;
11029 }
11030 #endif
11031
11032 bool CanBeUsedForSuicide()
11033 {
11034 return true;
11035 }
11036
11038 //DEPRECATED BELOW
11040 // Backwards compatibility
11041 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
11042 {
11043 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
11044 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
11045 }
11046
11047 // replaced by ItemSoundHandler
11048 protected EffectSound m_SoundDeployFinish;
11049 protected EffectSound m_SoundPlace;
11050 protected EffectSound m_DeployLoopSoundEx;
11051 protected EffectSound m_SoundDeploy;
11052 bool m_IsPlaceSound;
11053 bool m_IsDeploySound;
11055
11056 string GetDeployFinishSoundset();
11057 void PlayDeploySound();
11058 void PlayDeployFinishSound();
11059 void PlayPlaceSound();
11060 void PlayDeployLoopSoundEx();
11061 void StopDeployLoopSoundEx();
11062 void SoundSynchRemoteReset();
11063 void SoundSynchRemote();
11064 bool UsesGlobalDeploy(){return false;}
11065 bool CanPlayDeployLoopSound(){return false;}
11067 bool IsPlaceSound(){return m_IsPlaceSound;}
11068 bool IsDeploySound(){return m_IsDeploySound;}
11069 void SetIsPlaceSound(bool is_place_sound);
11070 void SetIsDeploySound(bool is_deploy_sound);
11071}
11072
11073EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
11074{
11075 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
11076 if (entity)
11077 {
11078 bool is_item = entity.IsInherited(ItemBase);
11079 if (is_item && full_quantity)
11080 {
11081 ItemBase item = ItemBase.Cast(entity);
11082 item.SetQuantity(item.GetQuantityInit());
11083 }
11084 }
11085 else
11086 {
11087 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
11088 return NULL;
11089 }
11090 return entity;
11091}
11092
11093void SetupSpawnedItem(ItemBase item, float health, float quantity)
11094{
11095 if (item)
11096 {
11097 if (health > 0)
11098 item.SetHealth("", "", health);
11099
11100 if (item.CanHaveTemperature())
11101 {
11102 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
11103 if (item.CanFreeze())
11104 item.SetFrozen(false);
11105 }
11106
11107 if (item.HasEnergyManager())
11108 {
11109 if (quantity >= 0)
11110 {
11111 item.GetCompEM().SetEnergy0To1(quantity);
11112 }
11113 else
11114 {
11115 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
11116 }
11117 }
11118 else if (item.IsMagazine())
11119 {
11120 Magazine mag = Magazine.Cast(item);
11121 if (quantity >= 0)
11122 {
11123 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
11124 }
11125 else
11126 {
11127 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
11128 }
11129
11130 }
11131 else
11132 {
11133 if (quantity >= 0)
11134 {
11135 item.SetQuantityNormalized(quantity, false);
11136 }
11137 else
11138 {
11139 item.SetQuantity(Math.AbsFloat(quantity));
11140 }
11141
11142 }
11143 }
11144}
11145
11146#ifdef DEVELOPER
11147ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
11148#endif
Param4< int, int, string, int > TSelectableActionInfoWithColor
Определения 3_Game/Entities/EntityAI.c:97
Param3 TSelectableActionInfo
EWetnessLevel
Определения 3_Game/Entities/EntityAI.c:2
InventoryMode
NOTE: PREDICTIVE is not to be used at all in multiplayer.
const int INPUT_UDT_ITEM_MANIPULATION
class LogManager EntityAI
eBleedingSourceType GetType()
ItemSuppressor SuppressorBase
void ActionDropItem()
Определения ActionDropItem.c:14
void ActionManagerBase(PlayerBase player)
Определения ActionManagerBase.c:63
map< typename, ref array< ActionBase_Basic > > TInputActionMap
Определения ActionManagerClient.c:1
void AddAction(typename actionName)
Определения AdvancedCommunication.c:220
void RemoveAction(typename actionName)
Определения AdvancedCommunication.c:252
TInputActionMap m_InputActionMap
Определения AdvancedCommunication.c:137
bool m_ActionsInitialize
Определения AdvancedCommunication.c:138
override void GetActions(typename action_input_type, out array< ActionBase_Basic > actions)
Определения AdvancedCommunication.c:202
void InitializeActions()
Определения AdvancedCommunication.c:190
int GetLiquidType()
Определения CCTWaterSurface.c:129
const int ECE_PLACE_ON_SURFACE
Определения CentralEconomy.c:37
proto native void SpawnEntity(string sClassName, vector vPos, float fRange, int iCount)
Spawn an entity through CE.
const int ECE_IN_INVENTORY
Определения CentralEconomy.c:36
const int RF_DEFAULT
Определения CentralEconomy.c:65
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
PlayerSpawnPreset slotName
Open
Implementations only.
override void EEOnCECreate()
Определения ContaminatedArea_Dynamic.c:42
map
Определения ControlsXboxNew.c:4
CookingMethodType
Определения Cooking.c:2
DamageType
exposed from C++ (do not change)
Определения DamageSystem.c:11
DayZGame g_Game
Определения DayZGame.c:3868
DayZGame GetDayZGame()
Определения DayZGame.c:3870
EActions
Определения EActions.c:2
ERPCs
Определения ERPCs.c:2
PluginAdminLog m_AdminLog
Определения EmoteManager.c:142
const int MAX
Определения EnConvert.c:27
float GetTemperature()
Определения Environment.c:497
override bool IsExplosive()
Определения ExplosivesBase.c:59
override bool CanHaveTemperature()
Определения FireplaceBase.c:559
class GP5GasMask extends MaskBase ItemBase
Empty
Определения Hand_States.c:14
FindInventoryLocationType
flags for searching locations in inventory
Определения InventoryLocation.c:17
InventoryLocationType
types of Inventory Location
Определения InventoryLocation.c:4
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
bool DamageItemInCargo(float damage)
Определения ItemBase.c:6380
static bool HasDebugActionsMask(int mask)
Определения ItemBase.c:5620
bool HidesSelectionBySlot()
Определения ItemBase.c:9347
float m_VarWetMin
Определения ItemBase.c:4881
void SplitItem(PlayerBase player)
Определения ItemBase.c:6831
void CopyScriptPropertiesFrom(EntityAI oldItem)
Определения ItemBase.c:9568
override void InsertAgent(int agent, float count=1)
Определения ItemBase.c:8795
override float GetQuantityNormalized()
Gets quantity in normalized 0..1 form between the item's Min a Max values as defined by item's config...
Определения ItemBase.c:8229
static void SetDebugActionsMask(int mask)
Определения ItemBase.c:5625
void SetIsDeploySound(bool is_deploy_sound)
bool IsOpen()
Определения ItemBase.c:8938
void SplitItemToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6798
override bool IsHeavyBehaviour()
Определения ItemBase.c:9140
override void SetWetMax()
Определения ItemBase.c:8511
bool IsCoverFaceForShave(string slot_name)
DEPRECATED in use, but returns correct values nontheless. Check performed elsewhere.
Определения ItemBase.c:9385
void ClearStartItemSoundServer()
Определения ItemBase.c:9283
float m_VarWet
Определения ItemBase.c:4878
void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9415
map< typename, ref ActionOverrideData > TActionAnimOverrideMap
Определения ItemBase.c:2
override void RemoveAllAgentsExcept(int agent_to_keep)
Определения ItemBase.c:8790
static ref map< int, ref array< ref WeaponParticlesOnBulletCasingEject > > m_OnBulletCasingEjectEffect
Определения ItemBase.c:4941
bool CanBeMovedOverride()
Определения ItemBase.c:7522
override void SetWet(float value, bool allow_client=false)
Определения ItemBase.c:8487
ref TIntArray m_SingleUseActions
Определения ItemBase.c:4927
override void ProcessVariables()
Определения ItemBase.c:9482
ref TStringArray m_HeadHidingSelections
Определения ItemBase.c:4955
float GetWeightSpecialized(bool forceRecalc=false)
Определения ItemBase.c:8321
bool LoadAgents(ParamsReadContext ctx, int version)
Определения ItemBase.c:8856
void UpdateQuickbarShortcutVisibility(PlayerBase player)
To be called on moving item within character's inventory; 'player' should never be null.
Определения ItemBase.c:8701
void OverrideActionAnimation(typename action, int commandUID, int stanceMask=-1, int commandUIDProne=-1)
Определения ItemBase.c:5211
ref array< ref OverheatingParticle > m_OverheatingParticles
Определения ItemBase.c:4953
override float GetTemperatureFreezeThreshold()
Определения ItemBase.c:9518
bool m_IsSoundSynchRemote
Определения ItemBase.c:9676
float m_OverheatingShots
Определения ItemBase.c:4948
void StopItemSoundServer(int id)
Определения ItemBase.c:9271
static void ToggleDebugActionsMask(int mask)
Определения ItemBase.c:5640
void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:5364
override float GetTemperatureFreezeTime()
Определения ItemBase.c:9542
ref array< int > m_CompatibleLocks
Определения ItemBase.c:4965
bool CanBeCooked()
Определения ItemBase.c:7478
override void CombineItemsClient(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:5707
float m_TemperaturePerQuantityWeight
Определения ItemBase.c:4977
bool m_RecipesInitialized
Определения ItemBase.c:4863
void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
Определения ItemBase.c:6471
override float GetTemperatureThawThreshold()
Определения ItemBase.c:9526
override void OnEnergyConsumed()
Определения ItemBase.c:8431
void RefreshAudioVisualsOnClient(CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned)
cooking-related effect methods
Определения Bottle_Base.c:158
int GetNumberOfItems()
Returns the number of items in cargo, otherwise returns 0(non-cargo objects). Recursive.
Определения ItemBase.c:8360
override EWetnessLevel GetWetLevel()
Определения ItemBase.c:8551
float GetSingleInventoryItemWeight()
Определения ItemBase.c:8316
ref TIntArray m_InteractActions
Определения ItemBase.c:4929
void MessageToOwnerStatus(string text)
Send message to owner player in grey color.
Определения ItemBase.c:7542
float m_VarQuantity
Определения ItemBase.c:4869
bool CanPlayDeployLoopSound()
Определения ItemBase.c:9687
override float GetWetMax()
Определения ItemBase.c:8521
bool CanBeUsedForSuicide()
Определения ItemBase.c:9654
override void CombineItemsEx(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:7117
void OnItemInHandsPlayerSwimStart(PlayerBase player)
void SetIsHologram(bool is_hologram)
Определения ItemBase.c:5845
void OnSyncVariables(ParamsReadContext ctx)
DEPRECATED (most likely)
Определения ItemBase.c:7696
void StartItemSoundServer(int id)
Определения ItemBase.c:9258
void DoAmmoExplosion()
Определения ItemBase.c:6315
static ref map< int, ref array< ref WeaponParticlesOnFire > > m_OnFireEffect
Определения ItemBase.c:4940
void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6655
int GetItemSize()
Определения ItemBase.c:7507
bool m_CanBeMovedOverride
Определения ItemBase.c:4906
override string ChangeIntoOnAttach(string slot)
Определения ItemBase.c:6239
void UpdateOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5432
bool CanDecay()
Определения ItemBase.c:9457
ScriptedLightBase GetLight()
string GetPlaceSoundset()
bool AddQuantity(float value, bool destroy_config=true, bool destroy_forced=false)
add item quantity[related to varQuantity... config entry], destroy_config = true > if the quantity re...
Определения ItemBase.c:8202
void SetQuantityMax()
Определения ItemBase.c:8207
override float GetQuantity()
Определения ItemBase.c:8296
int m_ColorComponentR
Определения ItemBase.c:4918
int m_ShotsToStartOverheating
Определения ItemBase.c:4950
override void OnWetChanged(float newVal, float oldVal)
Определения ItemBase.c:8536
void StopOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5439
static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9039
void OnOverheatingDecay()
Определения ItemBase.c:5402
float GetDryingIncrement(string pIncrementName)
Определения ItemBase.c:8469
void SoundSynchRemoteReset()
int m_Cleanness
Определения ItemBase.c:4884
bool HasMuzzle()
Returns true if this item has a muzzle (weapons, suppressors)
Определения ItemBase.c:5540
bool UsesGlobalDeploy()
Определения ItemBase.c:9686
int m_ItemBehaviour
Определения ItemBase.c:4899
override bool CanReleaseAttachment(EntityAI attachment)
Определения ItemBase.c:9011
float m_HeatIsolation
Определения ItemBase.c:4894
float m_VarWetInit
Определения ItemBase.c:4880
override void OnMovedInsideCargo(EntityAI container)
Определения ItemBase.c:5885
void SetCEBasedQuantity()
Определения ItemBase.c:5653
bool m_CanPlayImpactSound
Определения ItemBase.c:4890
override string GetAttachmentSoundType()
Определения ItemBase.c:9214
float GetOverheatingCoef()
Определения ItemBase.c:5459
array< string > GetHeadHidingSelection()
Определения ItemBase.c:9342
void PlayAttachSound(string slot_type)
Plays sound on item attach. Be advised, the config structure may slightly change in 1....
Определения ItemBase.c:9294
override bool IsStoreLoad()
Определения ItemBase.c:8563
int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7093
bool IsLightSource()
Определения ItemBase.c:5781
bool m_HasQuantityBar
Определения ItemBase.c:4912
void SetResultOfSplit(bool value)
Определения ItemBase.c:7088
void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6719
void OnAttachmentQuantityChanged(ItemBase item)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6889
void UpdateAllOverheatingParticles()
Определения ItemBase.c:5467
float GetSoakingIncrement(string pIncrementName)
Определения ItemBase.c:8478
static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9119
override float GetStoreLoadedQuantity()
Определения ItemBase.c:8573
int m_LockType
Определения ItemBase.c:4966
const int ITEM_SOUNDS_MAX
Определения ItemBase.c:4971
bool m_CanBeDigged
Определения ItemBase.c:4913
float m_ItemAttachOffset
Определения ItemBase.c:4896
float GetItemModelLength()
Определения ItemBase.c:8580
bool m_ThrowItemOnDrop
Определения ItemBase.c:4904
override bool ReadVarsFromCTX(ParamsReadContext ctx, int version=-1)
Определения ItemBase.c:7841
override void CheckForRoofLimited(float timeTresholdMS=3000)
Roof check for entity, limited by time (anti-spam solution)
Определения ItemBase.c:8871
void Close()
float GetHeatIsolation()
Определения ItemBase.c:8464
void CombineItems(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7122
void TransferModifiers(PlayerBase reciever)
appears to be deprecated, legacy code
float GetTemperaturePerQuantityWeight()
Used in heat comfort calculations only!
Определения ItemBase.c:9513
bool CanHaveWetness()
Определения ItemBase.c:9470
int m_CleannessMin
Определения ItemBase.c:4886
void TransferAgents(int agents)
transfer agents from another item
Определения ItemBase.c:8804
string IDToName(int id)
Определения ItemBase.c:7689
bool CanBeConsumed(ConsumeConditionData data=null)
Items cannot be consumed if frozen by default. Override for exceptions.
Определения ItemBase.c:9477
float GetHeatIsolationInit()
Определения ItemBase.c:8459
void PlayPlaceSound()
void SetCanBeMovedOverride(bool setting)
Определения ItemBase.c:7529
override bool HasQuantity()
Определения ItemBase.c:8291
float m_VarWetPrev
Определения ItemBase.c:4879
int m_SoundSyncStop
Определения ItemBase.c:4973
bool IsCargoException4x3(EntityAI item)
Определения ItemBase.c:9563
ref TIntArray m_ContinuousActions
Определения ItemBase.c:4928
int GetMuzzleID()
Returns global muzzle ID. If not found, then it gets automatically registered.
Определения ItemBase.c:5549
void LoadParticleConfigOnFire(int id)
Определения ItemBase.c:5234
int m_VarLiquidType
Определения ItemBase.c:4898
int m_QuickBarBonus
Определения ItemBase.c:4900
void PreLoadSoundAttachmentType()
Attachment Sound Type getting from config file.
Определения ItemBase.c:9202
override float GetWetInit()
Определения ItemBase.c:8531
int m_ImpactSoundSurfaceHash
Определения ItemBase.c:4892
int m_SoundSyncPlay
Определения ItemBase.c:4972
int m_MaxOverheatingValue
Определения ItemBase.c:4951
void SetupSpawnedItem(ItemBase item, float health, float quantity)
Определения ItemBase.c:4875
bool m_IsTakeable
Определения ItemBase.c:4903
bool ShouldSplitQuantity(float quantity)
Определения ItemBase.c:6428
static ref map< string, int > m_WeaponTypeToID
Определения ItemBase.c:4943
string GetLockSoundSet()
Определения ItemBase.c:8629
string GetColorString()
Returns item's PROCEDURAL color as formated string, i.e. "#(argb,8,8,3)color(0.15,...
Определения ItemBase.c:8660
array< int > GetValidFinishers()
returns an array of possible finishers
Определения ItemBase.c:9590
void OnAttachmentQuantityChangedEx(ItemBase item, float delta)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6895
class ItemBase extends InventoryItem SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
Определения ItemBase.c:4855
ItemSoundHandler GetItemSoundHandler()
Определения ItemBase.c:9229
override int GetQuantityMin()
Определения ItemBase.c:8280
void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
Определения ItemBase.c:6634
override int GetQuickBarBonus()
Определения ItemBase.c:5119
override void SetTakeable(bool pState)
Определения ItemBase.c:9184
float m_OverheatingDecayInterval
Определения ItemBase.c:4952
void SetIsPlaceSound(bool is_place_sound)
override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6448
void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
Определения ItemBase.c:9435
bool CanProcessDecay()
Определения ItemBase.c:9463
void RemoveAudioVisualsOnClient()
Определения Bottle_Base.c:151
void SoundSynchRemote()
static void AddDebugActionsMask(int mask)
Определения ItemBase.c:5630
void PlayDeployLoopSoundEx()
void RemoveLightSourceItem()
Определения ItemBase.c:9579
bool CanRepair(ItemBase item_repair_kit)
Определения ItemBase.c:7493
bool can_this_be_combined
Определения ItemBase.c:4908
EffectSound m_SoundDeploy
Определения ItemBase.c:9673
int m_Count
Определения ItemBase.c:4874
float GetBaitEffectivity()
generic effectivity as a bait for animal catching
Определения ItemBase.c:9626
float GetDeployTime()
how long it takes to deploy this item in seconds
Определения ItemBase.c:9176
override bool IsSplitable()
Определения ItemBase.c:6415
bool DamageItemAttachments(float damage)
Определения ItemBase.c:6399
override void WriteVarsToCTX(ParamsWriteContext ctx)
Определения ItemBase.c:7805
void ConvertEnergyToQuantity()
Определения ItemBase.c:8446
override void RemoveAllAgents()
Определения ItemBase.c:8785
override void SetQuantityToMinimum()
Определения ItemBase.c:8213
bool m_WantPlayImpactSound
Определения ItemBase.c:4889
override float GetTemperatureThawTime()
Определения ItemBase.c:9550
ref map< int, ref array< ref WeaponParticlesOnOverheating > > m_OnOverheatingEffect
Определения ItemBase.c:4942
int m_ColorComponentG
Определения ItemBase.c:4919
float m_StoreLoadedQuantity
Определения ItemBase.c:4876
void MessageToOwnerAction(string text)
Send message to owner player in yellow color.
Определения ItemBase.c:7560
int m_ColorComponentA
Определения ItemBase.c:4921
int m_VarQuantityInit
Определения ItemBase.c:4871
float GetFilterDamageRatio()
Определения ItemBase.c:5534
override void SetLiquidType(int value, bool allow_client=false)
Определения ItemBase.c:8673
void OnQuantityChanged(float delta)
Called on server side when this item's quantity is changed. Call super.OnQuantityChanged(); first whe...
Определения ItemBase.c:6865
void OnApply(PlayerBase player)
override void SetQuantityNormalized(float value, bool destroy_config=true, bool destroy_forced=false)
Sets quantity in normalized 0..1 form between the item's Min a Max values as defined by item's config...
Определения ItemBase.c:8220
bool m_HideSelectionsBySlot
Определения ItemBase.c:4956
bool IsOverheatingEffectActive()
Определения ItemBase.c:5397
void SetIsBeingPlaced(bool is_being_placed)
Определения ItemBase.c:5814
int GetLiquidContainerMask()
Определения ItemBase.c:5751
void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
Определения ItemBase.c:7002
ref Timer m_CheckOverheating
Определения ItemBase.c:4949
void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
Определения ItemBase.c:5445
float GetEnergy()
Определения ItemBase.c:8420
bool CanBeDigged()
Определения ItemBase.c:5830
bool GetActionWidgetOverride(out typename name)
If we need a different (handheld)item action widget displayed, the logic goes in here.
Определения ItemBase.c:9596
bool IsNVG()
Определения ItemBase.c:5762
float GetUnitWeight(bool include_wetness=true)
Obsolete, use GetWeightEx instead.
Определения ItemBase.c:8380
void SetZoneDamageCEInit()
Sets zone damages to match randomized global health set by CE (CE spawn only)
Определения ItemBase.c:9372
bool m_IsDeploySound
Определения ItemBase.c:9675
bool CanEat()
Определения ItemBase.c:7453
static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9079
override bool IsOneHandedBehaviour()
Определения ItemBase.c:9150
void AddLightSourceItem(ItemBase lightsource)
Adds a light source child.
Определения ItemBase.c:9574
bool IsLiquidContainer()
Определения ItemBase.c:5746
FoodStage GetFoodStage()
overridden on Edible_Base; so we don't have to parse configs all the time
Определения ItemBase.c:7473
override float GetSingleInventoryItemWeightEx()
Определения ItemBase.c:8307
void SaveAgents(ParamsWriteContext ctx)
Определения ItemBase.c:8863
override int GetTargetQuantityMax(int attSlotID=-1)
Определения ItemBase.c:8261
int m_CleannessInit
Определения ItemBase.c:4885
float GetDisinfectQuantity(int system=0, Param param1=null)
Определения ItemBase.c:5529
override int GetAgents()
Определения ItemBase.c:8810
int m_VarQuantityMax
Определения ItemBase.c:4873
override bool IsHologram()
Определения ItemBase.c:5825
float GetItemAttachOffset()
Определения ItemBase.c:8589
bool IsPlaceSound()
Определения ItemBase.c:9689
static int GetDebugActionsMask()
Определения ItemBase.c:5615
void ProcessDecay(float delta, bool hasRootAsPlayer)
Определения ItemBase.c:9452
override bool IsItemBase()
Определения ItemBase.c:7606
void PlayDeploySound()
override bool IsTwoHandedBehaviour()
Определения ItemBase.c:9160
void ExplodeAmmo()
Определения ItemBase.c:6302
bool IsCombineAll(ItemBase other_item, bool use_stack_max=false)
Определения ItemBase.c:7078
float GetProtectionLevel(int type, bool consider_filter=false, int system=0)
Определения ItemBase.c:8884
static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9059
override void OnEnergyAdded()
Определения ItemBase.c:8438
void AffectLiquidContainerOnFill(int liquid_type, float amount)
from enviro source
void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature)
from other liquid container source
string GetExplosiveTriggerSlotName()
Определения ItemBase.c:5774
EffectSound m_DeployLoopSoundEx
Определения ItemBase.c:9672
override void DeSerializeNumericalVars(array< float > floats)
Определения ItemBase.c:7746
void StopItemDynamicPhysics()
Определения ItemBase.c:9354
bool HasFoodStage()
Определения ItemBase.c:7466
override void SetStoreLoad(bool value)
Определения ItemBase.c:8558
float GetOverheatingValue()
Определения ItemBase.c:5359
bool ContainsAgent(int agent_id)
Определения ItemBase.c:8763
override void AddWet(float value)
Определения ItemBase.c:8506
bool IsLiquidPresent()
Определения ItemBase.c:5741
bool IsFullQuantity()
Определения ItemBase.c:8301
override void EOnContact(IEntity other, Contact extra)
Определения ItemBase.c:6015
void SplitIntoStackMaxHands(PlayerBase player)
Определения ItemBase.c:6770
void SplitIntoStackMaxHandsClient(PlayerBase player)
Определения ItemBase.c:6746
int m_CleannessMax
Определения ItemBase.c:4887
float m_VarStackMax
Определения ItemBase.c:4875
ref Timer m_PhysDropTimer
Определения ItemBase.c:4962
void MessageToOwnerFriendly(string text)
Send message to owner player in green color.
Определения ItemBase.c:7578
override void SetStoreLoadedQuantity(float value)
Определения ItemBase.c:8568
bool m_IsResultOfSplit string m_SoundAttType
distinguish if item has been created as new or it came from splitting (server only flag)
Определения ItemBase.c:4916
void CheckOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5380
void UnlockFromParent()
Unlocks this item from its attachment slot of its parent.
Определения ItemBase.c:5695
bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
Определения ItemBase.c:7500
void OnLiquidTypeChanged(int oldType, int newType)
Определения ItemBase.c:8694
void StartOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5426
void PlayDeployFinishSound()
bool AllowFoodConsumption()
Определения ItemBase.c:8616
bool m_IsOverheatingEffectActive
Определения ItemBase.c:4947
int m_LiquidContainerMask
Определения ItemBase.c:4897
void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9390
override int GetCleanness()
Определения ItemBase.c:8611
bool PairWithDevice(notnull ItemBase otherDevice)
Определения ItemBase.c:9601
bool IsDeploySound()
Определения ItemBase.c:9690
static void RemoveDebugActionsMask(int mask)
Определения ItemBase.c:5635
static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9099
int m_VarQuantityMin
Определения ItemBase.c:4872
void PerformDamageSystemReinit()
Определения ItemBase.c:9360
override void ClearInventory()
Определения ItemBase.c:8399
static int m_LastRegisteredWeaponID
Определения ItemBase.c:4944
ItemBase GetLightSourceItem()
Определения ItemBase.c:9584
void MessageToOwnerImportant(string text)
Send message to owner player in red color.
Определения ItemBase.c:7596
override float GetItemOverheatThreshold()
Определения ItemBase.c:9534
void StopDeployLoopSoundEx()
bool m_CanThisBeSplit
Определения ItemBase.c:4909
override void SerializeNumericalVars(array< float > floats_out)
Определения ItemBase.c:7710
ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
Определения ItemBase.c:6685
float m_ItemModelLength
Определения ItemBase.c:4895
bool m_IsHologram
Определения ItemBase.c:4902
static int m_DebugActionsMask
Определения ItemBase.c:4862
void KillAllOverheatingParticles()
Определения ItemBase.c:5495
bool CanBeCookedOnStick()
Определения ItemBase.c:7483
override int GetQuantityMax()
Определения ItemBase.c:8248
void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
Определения ItemBase.c:7156
void OnActivatedByTripWire()
bool IsColorSet()
Определения ItemBase.c:8654
override void RemoveAgent(int agent_id)
Определения ItemBase.c:8776
bool m_ItemBeingDroppedPhys
Определения ItemBase.c:4905
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:8966
void PlayDetachSound(string slot_type)
Определения ItemBase.c:9330
static ref map< typename, ref TInputActionMap > m_ItemTypeActionsMap
Определения ItemBase.c:4856
void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9663
override bool IsBeingPlaced()
Определения ItemBase.c:5809
int GetQuantityInit()
Определения ItemBase.c:8285
float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7098
bool IsResultOfSplit()
Определения ItemBase.c:7083
bool m_FixDamageSystemInit
Определения ItemBase.c:4907
float m_ImpactSpeed
Определения ItemBase.c:4891
bool m_IsStoreLoad
Определения ItemBase.c:4910
int GetLiquidTypeInit()
Определения ItemBase.c:8684
string GetDeployFinishSoundset()
ItemBase m_LightSourceItem
Определения ItemBase.c:4925
void LockToParent()
Locks this item in it's current attachment slot of its parent. This makes the "locked" icon visible i...
Определения ItemBase.c:5682
override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6557
int m_AttachedAgents
Определения ItemBase.c:4933
string m_LockSoundSet
Определения ItemBase.c:4968
void LoadParticleConfigOnOverheating(int id)
Определения ItemBase.c:5303
float m_VarQuantityPrev
Определения ItemBase.c:4870
bool IsSoundSynchRemote()
Определения ItemBase.c:9688
bool m_CanShowQuantity
Определения ItemBase.c:4911
override void OnRightClick()
Определения ItemBase.c:6938
int m_ColorComponentB
Определения ItemBase.c:4920
static ref map< typename, ref TActionAnimOverrideMap > m_ItemActionOverrides
Определения ItemBase.c:4858
bool IsActionTargetVisible()
Определения ItemBase.c:9196
override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения ItemBase.c:6050
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Определения ItemBase.c:6339
bool m_IsBeingPlaced
Определения ItemBase.c:4901
int NameToID(string name)
Определения ItemBase.c:7683
void ~ItemBase()
Определения ItemBase.c:5580
override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
Определения ItemBase.c:8546
void ClearStopItemSoundServer()
Определения ItemBase.c:9288
override string ChangeIntoOnDetach()
Определения ItemBase.c:6263
float m_VarWetMax
Определения ItemBase.c:4882
void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6680
int GetLockType()
Определения ItemBase.c:8624
EffectSound m_SoundDeployFinish
Определения ItemBase.c:9670
override float GetWet()
Определения ItemBase.c:8516
EffectSound m_SoundPlace
Определения ItemBase.c:9671
float GetQuantityNormalizedScripted()
Определения ItemBase.c:8234
override void SetCleanness(int value, bool allow_client=false)
Определения ItemBase.c:8598
bool m_IsPlaceSound
Определения ItemBase.c:9674
override float GetWetMin()
Определения ItemBase.c:8526
ref ItemSoundHandler m_ItemSoundHandler
Определения ItemBase.c:4974
override bool KindOf(string tag)
Определения ItemBase.c:7612
void ItemSoundHandler(ItemBase parent)
Определения ItemSoundHandler.c:31
string Type
Определения JsonDataContaminatedArea.c:11
EffectSound m_LockingSound
Определения Land_Underground_Entrance.c:321
string GetDebugText()
Определения ModifierBase.c:71
PlayerBase GetPlayer()
Определения ModifierBase.c:51
@ LOWEST
Определения PPEConstants.c:54
void PluginItemDiagnostic()
Определения PluginItemDiagnostic.c:74
PluginBase GetPlugin(typename plugin_type)
Определения PluginManager.c:316
EntityAI GetItem()
Определения RadialQuickbarMenu.c:37
override RemotelyActivatedItemBehaviour GetRemotelyActivatedItemBehaviour()
Определения RemoteDetonator.c:272
void RemoteDetonatorTrigger()
Определения RemoteDetonator.c:233
override void OnActivatedByItem(notnull ItemBase item)
Called when this item is activated by other.
Определения RemoteDetonator.c:305
int particle_id
Определения SmokeSimulation.c:28
ETemperatureAccessTypes
Определения TemperatureAccessConstants.c:2
override void Explode(int damageType, string ammoType="")
Определения Trap_LandMine.c:220
bool m_Initialized
Определения UiHintPanel.c:317
void Debug()
Определения UniversalTemperatureSource.c:349
int GetID()
Определения ActionBase.c:1360
void OnItemLocationChanged(ItemBase item)
Определения ActionBase.c:998
GetInputType()
Определения ActionBase.c:215
int m_StanceMask
Определения ActionBase.c:25
int m_CommandUIDProne
Определения ActionBase.c:24
int m_CommandUID
Определения ActionBase.c:23
void OnItemAttachedAtPlayer(EntityAI item, string slot_name)
Определения AnalyticsManagerClient.c:77
proto native UIManager GetUIManager()
proto bool ConfigGetChildName(string path, int index, out string name)
Get name of subclass in config class on path.
proto native float ConfigGetFloat(string path)
Get float value from config on path.
override ScriptCallQueue GetCallQueue(int call_category)
Определения DayZGame.c:1187
proto native void GizmoSelectObject(Object object)
proto native bool ConfigIsExisting(string path)
proto native void ConfigGetTextArray(string path, out TStringArray values)
Get array of strings from config on path.
proto native DayZPlayer GetPlayer()
proto native void GizmoSelectPhysics(Physics physics)
proto int GetTime()
returns mission time in milliseconds
proto native int ConfigGetType(string path)
Returns type of config value.
AnalyticsManagerClient GetAnalyticsClient()
Определения Global/game.c:1568
proto native int ConfigGetChildrenCount(string path)
Get count of subclasses in config class on path.
proto native SoundOnVehicle CreateSoundOnObject(Object source, string sound_name, float distance, bool looped, bool create_local=false)
proto native void ObjectDelete(Object obj)
proto native int GetItemCount()
proto native EntityAI GetItem(int index)
float GetEnergyAtSpawn()
Определения ComponentEnergyManager.c:1280
void SetEnergy0To1(float energy01)
Energy manager: Sets stored energy for this device between 0 and MAX based on relative input value be...
Определения ComponentEnergyManager.c:541
float GetEnergyMaxPristine()
Energy manager: Returns the maximum amount of energy this device can store. It's damage is NOT taken ...
Определения ComponentEnergyManager.c:1275
override void SetAutodestroy(bool auto_destroy)
Sets whether Effect automatically cleans up when it stops.
Определения EffectSound.c:603
bool IsSoundPlaying()
Get whether EffectSound is currently playing.
Определения EffectSound.c:274
override bool IsMan()
Определения 3_Game/Entities/Man.c:44
proto native bool EnumerateInventory(InventoryTraversalType tt, out array< EntityAI > items)
enumerate inventory using traversal type and filling items array
proto native CargoBase GetCargo()
cargo
Определения ItemBase.c:15
proto native bool IsValid()
verify current set inventory location
proto native EntityAI GetParent()
returns parent of current inventory location
proto native int GetSlot()
returns slot id if current type is Attachment
proto native int GetCol()
returns column of cargo if current type is Cargo / ProxyCargo
proto native int GetRow()
returns row of cargo if current type is Cargo / ProxyCargo
bool WriteToContext(ParamsWriteContext ctx)
Определения InventoryLocation.c:469
proto native int GetType()
returns type of InventoryLocation
proto native int GetIdx()
returns index of cargo if current type is Cargo / ProxyCargo
proto native void SetCargo(notnull EntityAI parent, EntityAI e, int idx, int row, int col, bool flip)
sets current inventory location type to Cargo with coordinates (idx, row, col)
proto native bool GetFlip()
returns flip status of cargo
proto native EntityAI GetItem()
returns item of current inventory location
InventoryLocation.
Определения InventoryLocation.c:29
override bool CanDisplayCargo()
Определения UndergroundStash.c:24
override void OnInventoryEnter(Man player)
Определения BarbedWire.c:203
override string GetFoldSoundset()
Определения BaseBuildingBase.c:108
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:6
override bool CanReceiveItemIntoCargo(EntityAI item)
Определения TentBase.c:913
override bool OnStoreLoad(ParamsReadContext ctx, int version)
Определения GardenBase.c:199
override void OnWasDetached(EntityAI parent, int slot_id)
override void EEOnAfterLoad()
Определения GardenBase.c:242
override void EEDelete(EntityAI parent)
Определения BaseBuildingBase.c:68
override bool CanBeRepairedByCrafting()
Определения TentBase.c:86
override void OnPlacementStarted(Man player)
Определения BatteryCharger.c:376
override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
Определения BarbedWire.c:357
override bool IsElectricAppliance()
Определения BatteryCharger.c:43
override bool IsItemTent()
Определения TentBase.c:81
override void SetActions()
override string GetLoopFoldSoundset()
Определения BaseBuildingBase.c:113
override bool CanMakeGardenplot()
Определения FieldShovel.c:3
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
Определения PowerGenerator.c:412
override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения HandcuffsLocked.c:12
override WrittenNoteData GetWrittenNoteData()
Определения Paper.c:30
override int GetDamageSystemVersionChange()
Определения BaseBuildingBase.c:1238
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
override void InitItemVariables()
Определения Matchbox.c:3
override void SetActionAnimOverrides()
Определения PickAxe.c:28
override void OnCreatePhysics()
Определения BaseBuildingBase.c:489
override string GetDeploySoundset()
Определения BarbedWire.c:392
override float GetBandagingEffectivity()
Определения BandageDressing.c:49
override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
Определения PowerGenerator.c:424
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
Определения BaseBuildingBase.c:496
override void OnStoreSave(ParamsWriteContext ctx)
Определения GardenBase.c:266
override void AfterStoreLoad()
Определения BarbedWire.c:155
override int GetOnDigWormsAmount()
Определения FieldShovel.c:27
override bool IsSelfAdjustingTemperature()
Определения PortableGasStove.c:287
override bool IsPlayerInside(PlayerBase player, string selection)
Определения BaseBuildingBase.c:1037
override void OnVariablesSynchronized()
Определения GardenBase.c:97
override void RefreshPhysics()
Определения BatteryCharger.c:359
override bool CanObstruct()
Определения BaseBuildingBase.c:84
override void OnWasAttached(EntityAI parent, int slot_id)
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
Определения BaseBuildingBase.c:982
override bool CanPutInCargo(EntityAI parent)
Определения GardenBase.c:331
override string GetLoopDeploySoundset()
Определения BarbedWire.c:397
override void OnPlacementComplete(Man player, vector position="0 0 0", vector orientation="0 0 0")
Определения BarbedWire.c:372
override void OnInventoryExit(Man player)
Определения BatteryCharger.c:341
override bool IsTakeable()
Определения BaseBuildingBase.c:1008
override bool IsIgnoredByConstruction()
Определения BaseBuildingBase.c:1170
override void InitItemSounds()
Определения BaseBuildingBase.c:94
override void EEKilled(Object killer)
Определения HandcuffsLocked.c:70
override void OnCombine(ItemBase other_item)
Определения BandageDressing.c:71
override bool CanExplodeInFire()
Определения LargeGasCannister.c:3
override bool IsFacingPlayer(PlayerBase player, string selection)
Определения BaseBuildingBase.c:1032
override bool CanBeCombined(EntityAI other_item, bool reservation_check=true, bool stack_max_limit=false)
Определения Rag.c:61
override bool IsBloodContainer()
Определения BloodContainerBase.c:10
override bool IsClothing()
override bool CanBeSplit()
Определения Rag.c:34
override bool IsDeployable()
Определения BaseBuildingBase.c:365
override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения ToolBase.c:24
override bool CanBeDisinfected()
Определения BandageDressing.c:54
override float GetInfectionChance(int system=0, Param param=null)
Определения BandageDressing.c:59
override void OnEndPlacement()
Определения KitBase.c:65
Определения EnMath.c:7
float GetOverheatingLimitMax()
Определения WeaponParticles.c:417
void SetOverheatingLimitMax(float max)
Определения WeaponParticles.c:407
void SetParticleParams(int particle_id, Object parent, vector local_pos, vector local_ori)
Определения WeaponParticles.c:422
float GetOverheatingLimitMin()
Определения WeaponParticles.c:412
Particle GetParticle()
Определения WeaponParticles.c:397
void SetOverheatingLimitMin(float min)
Определения WeaponParticles.c:402
void RegisterParticle(Particle p)
Определения WeaponParticles.c:392
void Stop()
Legacy function for backwards compatibility with 1.14 and below.
Определения Particle.c:266
void SetControlledDevice(EntityAI pDevice)
Определения RemoteDetonator.c:140
bool OnStoreLoad(ParamsReadContext ctx, int version)
void OnStoreSave(ParamsWriteContext ctx)
proto void Remove(func fn)
remove specific call from queue
proto void CallLater(func fn, int delay=0, bool repeat=false, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
adds call into the queue with given parameters and arguments (arguments are held in memory until the ...
proto native void Send()
proto bool Write(void value_out)
proto bool Read(void value_in)
bool m_Loop
Определения ItemSoundHandler.c:5
override void Stop()
Определения DayZPlayerImplement.c:64
proto native float GetDamage(string zoneName, string healthType)
UIScriptedMenu FindMenu(int id)
Returns menu with specific ID if it is open (see MenuID)
Определения UIManager.c:160
override void Refresh()
Определения ChatInputMenu.c:70
void SetCalcDetails(string details)
Определения 3_Game/tools/Debug.c:816
void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения WrittenNoteData.c:13
const float LOWEST
Определения EnConvert.c:100
Serializer ParamsReadContext
Определения gameplay.c:15
class LOD Object
InventoryTraversalType
tree traversal type, for more see http://en.wikipedia.org/wiki/Tree_traversal
Определения gameplay.c:6
proto native CGame GetGame()
Serializer ParamsWriteContext
Определения gameplay.c:16
const int DEF_BIOLOGICAL
Определения 3_Game/constants.c:512
const int DEF_CHEMICAL
Определения 3_Game/constants.c:513
const int COMP_TYPE_ENERGY_MANAGER
Определения Component.c:9
ErrorExSeverity
Определения EnDebug.c:62
void Error(string err)
Messagebox with error message.
Определения EnDebug.c:90
enum ShapeType ErrorEx
proto native void SetColor(int color)
array< string > TStringArray
Определения EnScript.c:709
array< int > TIntArray
Определения EnScript.c:711
EntityEvent
Entity events for event-mask, or throwing event from code.
Определения EnEntity.c:45
static const float ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE
Определения 3_Game/constants.c:808
const int VARIABLE_LIQUIDTYPE
Определения 3_Game/constants.c:632
const int VARIABLE_CLEANNESS
Определения 3_Game/constants.c:635
const int VARIABLE_COLOR
Определения 3_Game/constants.c:634
const int VARIABLE_TEMPERATURE
Определения 3_Game/constants.c:630
const int VARIABLE_QUANTITY
Определения 3_Game/constants.c:628
const int VARIABLE_WET
Определения 3_Game/constants.c:631
const int LIQUID_NONE
Определения 3_Game/constants.c:529
static proto float AbsFloat(float f)
Returns absolute value.
const int MENU_INVENTORY
Определения 3_Game/constants.c:180
proto native bool dBodyIsDynamic(notnull IEntity ent)
const int SAT_CRAFTING
Определения 3_Game/constants.c:453
const int SAT_DEBUG_ACTION
Определения 3_Game/constants.c:454
class JsonUndergroundAreaTriggerData GetPosition
Определения UndergroundAreaLoader.c:9
static proto string Format(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
Gets n-th character from string.
const int CALL_CATEGORY_GAMEPLAY
Определения 3_Game/tools/tools.c:10
const int CALL_CATEGORY_SYSTEM
Определения 3_Game/tools/tools.c:8
proto native int GetColor()

Используется в Entity::EEItemLocationChanged().