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

◆ AddQuantity()

bool SpawnItemOnLocation::AddQuantity ( float value,
bool destroy_config = true,
bool destroy_forced = false )
protected

add item quantity[related to varQuantity... config entry], destroy_config = true > if the quantity reaches varQuantityMin or lower and the item config contains the varQuantityDestroyOnMin = true entry, the item gets destroyed. destroy_forced = true means item gets destroyed when quantity reaches varQuantityMin or lower regardless of config setting, returns true if the item gets deleted

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

8308{
8309 override bool CanPutAsAttachment(EntityAI parent)
8310 {
8311 return true;
8312 }
8313};
8314
8316{
8317
8318};
8319
8320//const bool QUANTITY_DEBUG_REMOVE_ME = false;
8321
8322class ItemBase extends InventoryItem
8323{
8327
8329
8330 static int m_DebugActionsMask;
8332 // ============================================
8333 // Variable Manipulation System
8334 // ============================================
8335 // Quantity
8336
8337 float m_VarQuantity;
8338 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
8340 int m_VarQuantityMin;
8341 int m_VarQuantityMax;
8342 int m_Count;
8343 float m_VarStackMax;
8344 float m_StoreLoadedQuantity = float.LOWEST;
8345 // Wet
8346 float m_VarWet;
8347 float m_VarWetPrev;//for client to know wetness changed during synchronization
8348 float m_VarWetInit;
8349 float m_VarWetMin;
8350 float m_VarWetMax;
8351 // Cleanness
8352 int m_Cleanness;
8353 int m_CleannessInit;
8354 int m_CleannessMin;
8355 int m_CleannessMax;
8356 // impact sounds
8358 bool m_CanPlayImpactSound = true;
8359 float m_ImpactSpeed;
8361 //
8362 float m_HeatIsolation;
8363 float m_ItemModelLength;
8364 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
8366 int m_VarLiquidType;
8367 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
8368 int m_QuickBarBonus;
8369 bool m_IsBeingPlaced;
8370 bool m_IsHologram;
8371 bool m_IsTakeable;
8372 bool m_ThrowItemOnDrop;
8375 bool m_FixDamageSystemInit = false; //can be changed on storage version check
8376 bool can_this_be_combined; //Check if item can be combined
8377 bool m_CanThisBeSplit; //Check if item can be split
8378 bool m_IsStoreLoad = false;
8379 bool m_CanShowQuantity;
8380 bool m_HasQuantityBar;
8381 protected bool m_CanBeDigged;
8382 protected bool m_IsResultOfSplit
8383
8384 string m_SoundAttType;
8385 // items color variables
8390 //-------------------------------------------------------
8391
8392 // light source managing
8394
8398
8399 //==============================================
8400 // agent system
8401 private int m_AttachedAgents;
8402
8404 void TransferModifiers(PlayerBase reciever);
8405
8406
8407 // Weapons & suppressors particle effects
8411 ref static map<string, int> m_WeaponTypeToID;
8412 static int m_LastRegisteredWeaponID = 0;
8413
8414 // Overheating effects
8416 float m_OverheatingShots;
8417 ref Timer m_CheckOverheating;
8418 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
8419 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
8420 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
8421 ref array <ref OverheatingParticle> m_OverheatingParticles;
8422
8424 protected bool m_HideSelectionsBySlot;
8425
8426 // Admin Log
8427 PluginAdminLog m_AdminLog;
8428
8429 // misc
8430 ref Timer m_PhysDropTimer;
8431
8432 // Attachment Locking variables
8433 ref array<int> m_CompatibleLocks;
8434 protected int m_LockType;
8435 protected ref EffectSound m_LockingSound;
8436 protected string m_LockSoundSet;
8437
8438 // ItemSoundHandler variables
8439 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
8440 protected int m_SoundSyncPlay; // id for sound to play
8441 protected int m_SoundSyncStop; // id for sound to stop
8442 protected int m_SoundSyncSlotID = InventorySlots.INVALID; // slot id for attach/detach sound based on slot
8443
8445
8446 //temperature
8447 private float m_TemperaturePerQuantityWeight;
8448
8449 // -------------------------------------------------------------------------
8450 void ItemBase()
8451 {
8452 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
8456
8457 if (!g_Game.IsDedicatedServer())
8458 {
8459 if (HasMuzzle())
8460 {
8462
8464 {
8466 }
8467 }
8468
8470 m_ActionsInitialize = false;
8471 }
8472
8473 m_OldLocation = null;
8474
8475 if (g_Game.IsServer())
8476 {
8477 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
8478 }
8479
8480 if (ConfigIsExisting("headSelectionsToHide"))
8481 {
8483 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
8484 }
8485
8486 m_HideSelectionsBySlot = false;
8487 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
8488 {
8489 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
8490 }
8491
8492 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
8493
8494 m_IsResultOfSplit = false;
8495
8497 }
8498
8499 override void InitItemVariables()
8500 {
8501 super.InitItemVariables();
8502
8503 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
8504 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
8505 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
8506 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
8507 m_VarStackMax = ConfigGetFloat("varStackMax");
8508 m_Count = ConfigGetInt("count");
8509
8510 m_CanShowQuantity = ConfigGetBool("quantityShow");
8511 m_HasQuantityBar = ConfigGetBool("quantityBar");
8512
8513 m_CleannessInit = ConfigGetInt("varCleannessInit");
8515 m_CleannessMin = ConfigGetInt("varCleannessMin");
8516 m_CleannessMax = ConfigGetInt("varCleannessMax");
8517
8518 m_WantPlayImpactSound = false;
8519 m_ImpactSpeed = 0.0;
8520
8521 m_VarWetInit = ConfigGetFloat("varWetInit");
8523 m_VarWetMin = ConfigGetFloat("varWetMin");
8524 m_VarWetMax = ConfigGetFloat("varWetMax");
8525
8526 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
8527 if (IsLiquidContainer() && GetQuantity() != 0)
8529 m_IsBeingPlaced = false;
8530 m_IsHologram = false;
8531 m_IsTakeable = true;
8532 m_CanBeMovedOverride = false;
8536 m_CanBeDigged = ConfigGetBool("canBeDigged");
8537
8538 m_CompatibleLocks = new array<int>();
8539 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
8540 m_LockType = ConfigGetInt("lockType");
8541
8542 //Define if item can be split and set ability to be combined accordingly
8543 m_CanThisBeSplit = false;
8544 can_this_be_combined = false;
8545 if (ConfigIsExisting("canBeSplit"))
8546 {
8547 can_this_be_combined = ConfigGetBool("canBeSplit");
8549 }
8550
8551 m_ItemBehaviour = -1;
8552 if (ConfigIsExisting("itemBehaviour"))
8553 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
8554
8555 //RegisterNetSyncVariableInt("m_VariablesMask");
8556 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
8557 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
8558 RegisterNetSyncVariableInt("m_VarLiquidType");
8559 RegisterNetSyncVariableInt("m_Cleanness",0,1);
8560
8561 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
8562 RegisterNetSyncVariableFloat("m_ImpactSpeed");
8563 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
8564
8565 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
8566 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
8567 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
8568 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
8569
8570 RegisterNetSyncVariableBool("m_IsBeingPlaced");
8571 RegisterNetSyncVariableBool("m_IsTakeable");
8572 RegisterNetSyncVariableBool("m_IsHologram");
8573
8576 {
8577 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
8578 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
8579 RegisterNetSyncVariableInt("m_SoundSyncSlotID", int.MIN, int.MAX);
8580 }
8581
8582 m_LockSoundSet = ConfigGetString("lockSoundSet");
8583
8585 if (ConfigIsExisting("temperaturePerQuantityWeight"))
8586 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
8587
8588 m_SoundSyncSlotID = -1;
8589 }
8590
8591 override int GetQuickBarBonus()
8592 {
8593 return m_QuickBarBonus;
8594 }
8595
8596 void InitializeActions()
8597 {
8599 if (!m_InputActionMap)
8600 {
8602 m_InputActionMap = iam;
8603 SetActions();
8605 }
8606 }
8607
8608 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
8609 {
8611 {
8612 m_ActionsInitialize = true;
8614 }
8615
8616 actions = m_InputActionMap.Get(action_input_type);
8617 }
8618
8619 void SetActions()
8620 {
8621 AddAction(ActionTakeItem);
8622 AddAction(ActionTakeItemToHands);
8623 AddAction(ActionWorldCraft);
8625 AddAction(ActionAttachWithSwitch);
8626 }
8627
8628 void SetActionAnimOverrides(); // Override action animation for specific item
8629
8630 void AddAction(typename actionName)
8631 {
8632 ActionBase action = ActionManagerBase.GetAction(actionName);
8633
8634 if (!action)
8635 {
8636 Debug.LogError("Action " + actionName + " dosn't exist!");
8637 return;
8638 }
8639
8640 typename ai = action.GetInputType();
8641 if (!ai)
8642 {
8643 m_ActionsInitialize = false;
8644 return;
8645 }
8646
8647 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
8648 if (!action_array)
8649 {
8650 action_array = new array<ActionBase_Basic>;
8651 m_InputActionMap.Insert(ai, action_array);
8652 }
8653 if (LogManager.IsActionLogEnable())
8654 {
8655 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
8656 }
8657
8658 if (action_array.Find(action) != -1)
8659 {
8660 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
8661 }
8662 else
8663 {
8664 action_array.Insert(action);
8665 }
8666 }
8667
8668 void RemoveAction(typename actionName)
8669 {
8670 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
8671 ActionBase action = player.GetActionManager().GetAction(actionName);
8672 typename ai = action.GetInputType();
8673 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
8674
8675 if (action_array)
8676 {
8677 action_array.RemoveItem(action);
8678 }
8679 }
8680
8681 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
8682 // Set -1 for params which should stay in default state
8683 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
8684 {
8685 ActionOverrideData overrideData = new ActionOverrideData();
8686 overrideData.m_CommandUID = commandUID;
8687 overrideData.m_CommandUIDProne = commandUIDProne;
8688 overrideData.m_StanceMask = stanceMask;
8689
8690 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
8691 if (!actionMap) // create new map of action > overidables map
8692 {
8693 actionMap = new TActionAnimOverrideMap();
8694 m_ItemActionOverrides.Insert(action, actionMap);
8695 }
8696
8697 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
8698
8699 }
8700
8701 void OnItemInHandsPlayerSwimStart(PlayerBase player);
8702
8703 ScriptedLightBase GetLight();
8704
8705 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
8706 void LoadParticleConfigOnFire(int id)
8707 {
8708 if (!m_OnFireEffect)
8710
8713
8714 string config_to_search = "CfgVehicles";
8715 string muzzle_owner_config;
8716
8717 if (!m_OnFireEffect.Contains(id))
8718 {
8719 if (IsInherited(Weapon))
8720 config_to_search = "CfgWeapons";
8721
8722 muzzle_owner_config = config_to_search + " " + GetType() + " ";
8723
8724 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
8725
8726 int config_OnFire_subclass_count = g_Game.ConfigGetChildrenCount(config_OnFire_class);
8727
8728 if (config_OnFire_subclass_count > 0)
8729 {
8730 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
8731
8732 for (int i = 0; i < config_OnFire_subclass_count; i++)
8733 {
8734 string particle_class = "";
8735 g_Game.ConfigGetChildName(config_OnFire_class, i, particle_class);
8736 string config_OnFire_entry = config_OnFire_class + particle_class;
8737 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
8738 WPOF_array.Insert(WPOF);
8739 }
8740
8741
8742 m_OnFireEffect.Insert(id, WPOF_array);
8743 }
8744 }
8745
8746 if (!m_OnBulletCasingEjectEffect.Contains(id))
8747 {
8748 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
8749 muzzle_owner_config = config_to_search + " " + GetType() + " ";
8750
8751 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
8752
8753 int config_OnBulletCasingEject_count = g_Game.ConfigGetChildrenCount(config_OnBulletCasingEject_class);
8754
8755 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
8756 {
8757 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
8758
8759 for (i = 0; i < config_OnBulletCasingEject_count; i++)
8760 {
8761 string particle_class2 = "";
8762 g_Game.ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
8763 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
8764 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
8765 WPOBE_array.Insert(WPOBE);
8766 }
8767
8768
8769 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
8770 }
8771 }
8772 }
8773
8774 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
8776 {
8779
8780 if (!m_OnOverheatingEffect.Contains(id))
8781 {
8782 string config_to_search = "CfgVehicles";
8783
8784 if (IsInherited(Weapon))
8785 config_to_search = "CfgWeapons";
8786
8787 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
8788 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
8789
8790 if (g_Game.ConfigIsExisting(config_OnOverheating_class))
8791 {
8792
8793 m_ShotsToStartOverheating = g_Game.ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
8794
8796 {
8797 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
8798 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
8799 Error(error);
8800 return;
8801 }
8802
8803 m_OverheatingDecayInterval = g_Game.ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
8804 m_MaxOverheatingValue = g_Game.ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
8805
8806
8807
8808 int config_OnOverheating_subclass_count = g_Game.ConfigGetChildrenCount(config_OnOverheating_class);
8809 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
8810
8811 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
8812 {
8813 string particle_class = "";
8814 g_Game.ConfigGetChildName(config_OnOverheating_class, i, particle_class);
8815 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
8816 int entry_type = g_Game.ConfigGetType(config_OnOverheating_entry);
8817
8818 if (entry_type == CT_CLASS)
8819 {
8820 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
8821 WPOOH_array.Insert(WPOF);
8822 }
8823 }
8824
8825
8826 m_OnOverheatingEffect.Insert(id, WPOOH_array);
8827 }
8828 }
8829 }
8830
8831 float GetOverheatingValue()
8832 {
8833 return m_OverheatingShots;
8834 }
8835
8836 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
8837 {
8838 if (m_MaxOverheatingValue > 0)
8839 {
8841
8842 if (!m_CheckOverheating)
8844
8846 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
8847
8848 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
8849 }
8850 }
8851
8852 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
8853 {
8855 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
8856
8858 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
8859
8861 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
8862
8864 {
8866 }
8867 }
8868
8870 {
8872 }
8873
8874 void OnOverheatingDecay()
8875 {
8876 if (m_MaxOverheatingValue > 0)
8877 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
8878 else
8880
8881 if (m_OverheatingShots <= 0)
8882 {
8885 }
8886 else
8887 {
8888 if (!m_CheckOverheating)
8890
8892 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
8893 }
8894
8895 CheckOverheating(this, "", this);
8896 }
8897
8898 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
8899 {
8901 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
8902 }
8903
8904 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
8905 {
8907 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
8909 }
8910
8911 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
8912 {
8914 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
8915 }
8916
8917 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
8918 {
8920 m_OverheatingParticles = new array<ref OverheatingParticle>;
8921
8922 OverheatingParticle OP = new OverheatingParticle();
8923 OP.RegisterParticle(p);
8924 OP.SetOverheatingLimitMin(min_heat_coef);
8925 OP.SetOverheatingLimitMax(max_heat_coef);
8926 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
8927
8928 m_OverheatingParticles.Insert(OP);
8929 }
8930
8931 float GetOverheatingCoef()
8932 {
8933 if (m_MaxOverheatingValue > 0)
8935
8936 return -1;
8937 }
8938
8940 {
8942 {
8943 float overheat_coef = GetOverheatingCoef();
8944 int count = m_OverheatingParticles.Count();
8945
8946 for (int i = count; i > 0; --i)
8947 {
8948 int id = i - 1;
8949 OverheatingParticle OP = m_OverheatingParticles.Get(id);
8950 Particle p = OP.GetParticle();
8951
8952 float overheat_min = OP.GetOverheatingLimitMin();
8953 float overheat_max = OP.GetOverheatingLimitMax();
8954
8955 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
8956 {
8957 if (p)
8958 {
8959 p.Stop();
8960 OP.RegisterParticle(null);
8961 }
8962 }
8963 }
8964 }
8965 }
8966
8968 {
8970 {
8971 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
8972 {
8973 int id = i - 1;
8974 OverheatingParticle OP = m_OverheatingParticles.Get(id);
8975
8976 if (OP)
8977 {
8978 Particle p = OP.GetParticle();
8979
8980 if (p)
8981 {
8982 p.Stop();
8983 }
8984
8985 delete OP;
8986 }
8987 }
8988
8989 m_OverheatingParticles.Clear();
8991 }
8992 }
8993
8995 float GetInfectionChance(int system = 0, Param param = null)
8996 {
8997 return 0.0;
8998 }
8999
9000
9001 float GetDisinfectQuantity(int system = 0, Param param1 = null)
9002 {
9003 return 250;//default value
9004 }
9005
9006 float GetFilterDamageRatio()
9007 {
9008 return 0;
9009 }
9010
9012 bool HasMuzzle()
9013 {
9014 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
9015 return true;
9016
9017 return false;
9018 }
9019
9021 int GetMuzzleID()
9022 {
9023 if (!m_WeaponTypeToID)
9024 m_WeaponTypeToID = new map<string, int>;
9025
9026 if (m_WeaponTypeToID.Contains(GetType()))
9027 {
9028 return m_WeaponTypeToID.Get(GetType());
9029 }
9030 else
9031 {
9032 // Register new weapon ID
9034 }
9035
9037 }
9038
9045 {
9046 return -1;
9047 }
9048
9049
9050
9051 // -------------------------------------------------------------------------
9052 void ~ItemBase()
9053 {
9054 if (g_Game && g_Game.GetPlayer() && (!g_Game.IsDedicatedServer()))
9055 {
9056 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
9057 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
9058
9059 if (r_index >= 0)
9060 {
9061 InventoryLocation r_il = new InventoryLocation;
9062 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
9063
9064 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
9065 int r_type = r_il.GetType();
9066 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
9067 {
9068 r_il.GetParent().GetOnReleaseLock().Invoke(this);
9069 }
9070 else if (r_type == InventoryLocationType.ATTACHMENT)
9071 {
9072 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
9073 }
9074
9075 }
9076
9077 player.GetHumanInventory().ClearUserReservedLocation(this);
9078 }
9079
9080 if (m_LockingSound)
9081 SEffectManager.DestroyEffect(m_LockingSound);
9082 }
9083
9084
9085
9086 // -------------------------------------------------------------------------
9087 static int GetDebugActionsMask()
9088 {
9089 return ItemBase.m_DebugActionsMask;
9090 }
9091
9092 static bool HasDebugActionsMask(int mask)
9093 {
9094 return ItemBase.m_DebugActionsMask & mask;
9095 }
9096
9097 static void SetDebugActionsMask(int mask)
9098 {
9099 ItemBase.m_DebugActionsMask = mask;
9100 }
9101
9102 static void AddDebugActionsMask(int mask)
9103 {
9104 ItemBase.m_DebugActionsMask |= mask;
9105 }
9106
9107 static void RemoveDebugActionsMask(int mask)
9108 {
9109 ItemBase.m_DebugActionsMask &= ~mask;
9110 }
9111
9112 static void ToggleDebugActionsMask(int mask)
9113 {
9114 if (HasDebugActionsMask(mask))
9115 {
9117 }
9118 else
9119 {
9120 AddDebugActionsMask(mask);
9121 }
9122 }
9123
9124 // -------------------------------------------------------------------------
9125 void SetCEBasedQuantity()
9126 {
9127 if (GetEconomyProfile())
9128 {
9129 float q_max = GetEconomyProfile().GetQuantityMax();
9130 if (q_max > 0)
9131 {
9132 float q_min = GetEconomyProfile().GetQuantityMin();
9133 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
9134
9135 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
9136 {
9137 ComponentEnergyManager comp = GetCompEM();
9138 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
9139 {
9140 comp.SetEnergy0To1(quantity_randomized);
9141 }
9142 }
9143 else if (HasQuantity())
9144 {
9145 SetQuantityNormalized(quantity_randomized, false);
9146 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
9147 }
9148
9149 }
9150 }
9151 }
9152
9154 void LockToParent()
9155 {
9156 EntityAI parent = GetHierarchyParent();
9157
9158 if (parent)
9159 {
9160 InventoryLocation inventory_location_to_lock = new InventoryLocation;
9161 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
9162 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
9163 }
9164 }
9165
9167 void UnlockFromParent()
9168 {
9169 EntityAI parent = GetHierarchyParent();
9170
9171 if (parent)
9172 {
9173 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
9174 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
9175 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
9176 }
9177 }
9178
9179 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
9180 {
9181 /*
9182 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
9183 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, g_Game.GetPlayer());
9184 */
9185 ItemBase item2 = ItemBase.Cast(entity2);
9186
9187 if (g_Game.IsClient())
9188 {
9189 if (ScriptInputUserData.CanStoreInputUserData())
9190 {
9191 ScriptInputUserData ctx = new ScriptInputUserData;
9193 ctx.Write(-1);
9194 ItemBase i1 = this; // @NOTE: workaround for correct serialization
9195 ctx.Write(i1);
9196 ctx.Write(item2);
9197 ctx.Write(use_stack_max);
9198 ctx.Write(-1);
9199 ctx.Send();
9200
9201 if (IsCombineAll(item2, use_stack_max))
9202 {
9203 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
9204 }
9205 }
9206 }
9207 else if (!g_Game.IsMultiplayer())
9208 {
9209 CombineItems(item2, use_stack_max);
9210 }
9211 }
9212
9213 bool IsLiquidPresent()
9214 {
9215 return (GetLiquidType() != 0 && HasQuantity());
9216 }
9217
9218 bool IsLiquidContainer()
9219 {
9220 return m_LiquidContainerMask != 0;
9221 }
9222
9224 {
9225 return m_LiquidContainerMask;
9226 }
9227
9228 bool IsBloodContainer()
9229 {
9230 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
9231 return false;
9232 }
9233
9234 bool IsNVG()
9235 {
9236 return false;
9237 }
9238
9241 bool IsExplosive()
9242 {
9243 return false;
9244 }
9245
9247 {
9248 return "";
9249 }
9250
9252
9253 bool IsLightSource()
9254 {
9255 return false;
9256 }
9257
9259 {
9260 return true;
9261 }
9262
9263 //--- ACTION CONDITIONS
9264 //direction
9265 bool IsFacingPlayer(PlayerBase player, string selection)
9266 {
9267 return true;
9268 }
9269
9270 bool IsPlayerInside(PlayerBase player, string selection)
9271 {
9272 return true;
9273 }
9274
9275 override bool CanObstruct()
9276 {
9277 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
9278 return !player || !IsPlayerInside(player, "");
9279 }
9280
9281 override bool IsBeingPlaced()
9282 {
9283 return m_IsBeingPlaced;
9284 }
9285
9286 void SetIsBeingPlaced(bool is_being_placed)
9287 {
9288 m_IsBeingPlaced = is_being_placed;
9289 if (!is_being_placed)
9291 SetSynchDirty();
9292 }
9293
9294 //server-side
9295 void OnEndPlacement() {}
9296
9297 override bool IsHologram()
9298 {
9299 return m_IsHologram;
9300 }
9301
9302 bool CanBeDigged()
9303 {
9304 return m_CanBeDigged;
9305 }
9306
9308 {
9309 return 1;
9310 }
9311
9312 bool CanMakeGardenplot()
9313 {
9314 return false;
9315 }
9316
9317 void SetIsHologram(bool is_hologram)
9318 {
9319 m_IsHologram = is_hologram;
9320 SetSynchDirty();
9321 }
9322 /*
9323 protected float GetNutritionalEnergy()
9324 {
9325 Edible_Base edible = Edible_Base.Cast(this);
9326 return edible.GetFoodEnergy();
9327 }
9328
9329 protected float GetNutritionalWaterContent()
9330 {
9331 Edible_Base edible = Edible_Base.Cast(this);
9332 return edible.GetFoodWater();
9333 }
9334
9335 protected float GetNutritionalIndex()
9336 {
9337 Edible_Base edible = Edible_Base.Cast(this);
9338 return edible.GetFoodNutritionalIndex();
9339 }
9340
9341 protected float GetNutritionalFullnessIndex()
9342 {
9343 Edible_Base edible = Edible_Base.Cast(this);
9344 return edible.GetFoodTotalVolume();
9345 }
9346
9347 protected float GetNutritionalToxicity()
9348 {
9349 Edible_Base edible = Edible_Base.Cast(this);
9350 return edible.GetFoodToxicity();
9351
9352 }
9353 */
9354
9355
9356 // -------------------------------------------------------------------------
9357 override void OnMovedInsideCargo(EntityAI container)
9358 {
9359 super.OnMovedInsideCargo(container);
9360
9361 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
9362 }
9363
9364 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
9365 {
9366 super.EEItemLocationChanged(oldLoc, newLoc);
9367
9368 PlayerBase newPlayer = null;
9369 PlayerBase oldPlayer = null;
9370
9371 if (newLoc.GetParent())
9372 newPlayer = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
9373
9374 if (oldLoc.GetParent())
9375 oldPlayer = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
9376
9377 if (oldPlayer && oldLoc.GetType() == InventoryLocationType.HANDS)
9378 {
9379 int rIndex = oldPlayer.GetHumanInventory().FindUserReservedLocationIndex(this);
9380
9381 if (rIndex >= 0)
9382 {
9383 InventoryLocation rIl = new InventoryLocation;
9384 oldPlayer.GetHumanInventory().GetUserReservedLocation(rIndex, rIl);
9385
9386 oldPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(rIndex);
9387 int rType = rIl.GetType();
9388 if (rType == InventoryLocationType.CARGO || rType == InventoryLocationType.PROXYCARGO)
9389 {
9390 rIl.GetParent().GetOnReleaseLock().Invoke(this);
9391 }
9392 else if (rType == InventoryLocationType.ATTACHMENT)
9393 {
9394 rIl.GetParent().GetOnAttachmentReleaseLock().Invoke(this, rIl.GetSlot());
9395 }
9396
9397 }
9398 }
9399
9400 if (newLoc.GetType() == InventoryLocationType.HANDS && oldLoc.GetType() != InventoryLocationType.TEMP)
9401 {
9402 if (newPlayer)
9403 newPlayer.ForceStandUpForHeavyItems(newLoc.GetItem());
9404
9405 if (newPlayer == oldPlayer)
9406 {
9407 if (oldLoc.GetParent() && newPlayer.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
9408 {
9409 if (oldLoc.GetType() == InventoryLocationType.CARGO)
9410 {
9411 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
9412 {
9413 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
9414 }
9415 }
9416 else
9417 {
9418 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
9419 }
9420 }
9421
9422 if (newPlayer.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
9423 {
9424 int type = oldLoc.GetType();
9425 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
9426 {
9427 oldLoc.GetParent().GetOnSetLock().Invoke(this);
9428 }
9429 else if (type == InventoryLocationType.ATTACHMENT)
9430 {
9431 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
9432 }
9433 }
9434 if (!m_OldLocation)
9435 {
9436 m_OldLocation = new InventoryLocation;
9437 }
9438 m_OldLocation.Copy(oldLoc);
9439 }
9440 else
9441 {
9442 if (m_OldLocation)
9443 {
9444 m_OldLocation.Reset();
9445 }
9446 }
9447
9448 g_Game.GetAnalyticsClient().OnItemAttachedAtPlayer(this,"Hands");
9449 }
9450 else
9451 {
9452 if (newPlayer)
9453 {
9454 int resIndex = newPlayer.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
9455 if (resIndex >= 0)
9456 {
9457 InventoryLocation il = new InventoryLocation;
9458 newPlayer.GetHumanInventory().GetUserReservedLocation(resIndex, il);
9459 ItemBase it = ItemBase.Cast(il.GetItem());
9460 newPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(resIndex);
9461 int rel_type = il.GetType();
9462 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
9463 {
9464 il.GetParent().GetOnReleaseLock().Invoke(it);
9465 }
9466 else if (rel_type == InventoryLocationType.ATTACHMENT)
9467 {
9468 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
9469 }
9470 //it.GetOnReleaseLock().Invoke(it);
9471 }
9472 }
9473 else if (oldPlayer && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
9474 {
9475 //ThrowPhysically(oldPlayer, vector.Zero);
9476 m_ThrowItemOnDrop = false;
9477 }
9478
9479 if (m_OldLocation)
9480 {
9481 m_OldLocation.Reset();
9482 }
9483 }
9484
9485 if (oldLoc.GetType() == InventoryLocationType.TEMP)
9486 {
9487 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Remove(oldLoc.GetItem());
9488 }
9489
9490 if (newLoc.GetType() == InventoryLocationType.TEMP)
9491 {
9492 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Add(oldLoc.GetItem());
9493 }
9494 }
9495
9496 override void EOnContact(IEntity other, Contact extra)
9497 {
9499 {
9500 int liquidType = -1;
9501 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
9502 if (impactSpeed > 0.0)
9503 {
9504 m_ImpactSpeed = impactSpeed;
9505 #ifndef SERVER
9506 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
9507 #else
9508 m_WantPlayImpactSound = true;
9509 SetSynchDirty();
9510 #endif
9511 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
9512 }
9513 }
9514
9515 #ifdef SERVER
9516 if (GetCompEM() && GetCompEM().IsPlugged())
9517 {
9518 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
9519 GetCompEM().UnplugThis();
9520 }
9521 #endif
9522 }
9523
9524 void RefreshPhysics();
9525
9526 override void OnCreatePhysics()
9527 {
9529 }
9530
9531 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
9532 {
9533
9534 }
9535 // -------------------------------------------------------------------------
9536 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
9537 {
9538 super.OnItemLocationChanged(old_owner, new_owner);
9539
9540 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
9541 PlayerBase playerNew = PlayerBase.Cast(new_owner);
9542
9543 if (!relatedPlayer && playerNew)
9544 relatedPlayer = playerNew;
9545
9546 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
9547 {
9548 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
9549 if (actionMgr)
9550 {
9551 ActionBase currentAction = actionMgr.GetRunningAction();
9552 if (currentAction)
9553 currentAction.OnItemLocationChanged(this);
9554 }
9555 }
9556
9557 Man ownerPlayerOld = null;
9558 Man ownerPlayerNew = null;
9559
9560 if (old_owner)
9561 {
9562 if (old_owner.IsMan())
9563 {
9564 ownerPlayerOld = Man.Cast(old_owner);
9565 }
9566 else
9567 {
9568 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
9569 }
9570 }
9571 else
9572 {
9573 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
9574 {
9575 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
9576
9577 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
9578 {
9579 GetCompEM().UnplugThis();
9580 }
9581 }
9582 }
9583
9584 if (new_owner)
9585 {
9586 if (new_owner.IsMan())
9587 {
9588 ownerPlayerNew = Man.Cast(new_owner);
9589 }
9590 else
9591 {
9592 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
9593 }
9594 }
9595
9596 if (ownerPlayerOld != ownerPlayerNew)
9597 {
9598 if (ownerPlayerOld)
9599 {
9600 array<EntityAI> subItemsExit = new array<EntityAI>;
9601 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
9602 for (int i = 0; i < subItemsExit.Count(); i++)
9603 {
9604 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
9605 itemExit.OnInventoryExit(ownerPlayerOld);
9606 }
9607 }
9608
9609 if (ownerPlayerNew)
9610 {
9611 array<EntityAI> subItemsEnter = new array<EntityAI>;
9612 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
9613 for (int j = 0; j < subItemsEnter.Count(); j++)
9614 {
9615 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
9616 itemEnter.OnInventoryEnter(ownerPlayerNew);
9617 }
9618 }
9619 }
9620 else if (ownerPlayerNew != null)
9621 {
9622 PlayerBase nplayer;
9623 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
9624 {
9625 array<EntityAI> subItemsUpdate = new array<EntityAI>;
9626 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
9627 for (int k = 0; k < subItemsUpdate.Count(); k++)
9628 {
9629 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
9630 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
9631 }
9632 }
9633 }
9634
9635 if (old_owner)
9636 old_owner.OnChildItemRemoved(this);
9637 if (new_owner)
9638 new_owner.OnChildItemReceived(this);
9639 }
9640
9641 // -------------------------------------------------------------------------------
9642 override void EEDelete(EntityAI parent)
9643 {
9644 super.EEDelete(parent);
9645 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
9646 if (player)
9647 {
9648 OnInventoryExit(player);
9649
9650 if (player.IsAlive())
9651 {
9652 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
9653 if (r_index >= 0)
9654 {
9655 InventoryLocation r_il = new InventoryLocation;
9656 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
9657
9658 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
9659 int r_type = r_il.GetType();
9660 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
9661 {
9662 r_il.GetParent().GetOnReleaseLock().Invoke(this);
9663 }
9664 else if (r_type == InventoryLocationType.ATTACHMENT)
9665 {
9666 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
9667 }
9668
9669 }
9670
9671 player.RemoveQuickBarEntityShortcut(this);
9672 }
9673 }
9674 }
9675 // -------------------------------------------------------------------------------
9676 override void EEKilled(Object killer)
9677 {
9678 super.EEKilled(killer);
9679
9681 if (killer && killer.IsFireplace() && CanExplodeInFire())
9682 {
9683 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
9684 {
9685 if (IsMagazine())
9686 {
9687 if (Magazine.Cast(this).GetAmmoCount() > 0)
9688 {
9689 ExplodeAmmo();
9690 }
9691 }
9692 else
9693 {
9694 Explode(DamageType.EXPLOSION);
9695 }
9696 }
9697 }
9698 }
9699
9700 override void OnWasAttached(EntityAI parent, int slot_id)
9701 {
9702 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
9703
9704 super.OnWasAttached(parent, slot_id);
9705
9706 if (HasQuantity())
9707 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
9708
9709 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
9710 StartItemSoundServer(SoundConstants.ITEM_ATTACH, slot_id);
9711 }
9712
9713 override void OnWasDetached(EntityAI parent, int slot_id)
9714 {
9715 super.OnWasDetached(parent, slot_id);
9716
9717 if (HasQuantity())
9718 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
9719
9720 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
9721 StartItemSoundServer(SoundConstants.ITEM_DETACH, slot_id);
9722 }
9723
9724 override string ChangeIntoOnAttach(string slot)
9725 {
9726 int idx;
9727 TStringArray inventory_slots = new TStringArray;
9728 TStringArray attach_types = new TStringArray;
9729
9730 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
9731 if (inventory_slots.Count() < 1) //is string
9732 {
9733 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
9734 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
9735 }
9736 else //is array
9737 {
9738 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
9739 }
9740
9741 idx = inventory_slots.Find(slot);
9742 if (idx < 0)
9743 return "";
9744
9745 return attach_types.Get(idx);
9746 }
9747
9748 override string ChangeIntoOnDetach()
9749 {
9750 int idx = -1;
9751 string slot;
9752
9753 TStringArray inventory_slots = new TStringArray;
9754 TStringArray detach_types = new TStringArray;
9755
9756 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
9757 if (inventory_slots.Count() < 1) //is string
9758 {
9759 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
9760 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
9761 }
9762 else //is array
9763 {
9764 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
9765 if (detach_types.Count() < 1)
9766 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
9767 }
9768
9769 for (int i = 0; i < inventory_slots.Count(); i++)
9770 {
9771 slot = inventory_slots.Get(i);
9772 }
9773
9774 if (slot != "")
9775 {
9776 if (detach_types.Count() == 1)
9777 idx = 0;
9778 else
9779 idx = inventory_slots.Find(slot);
9780 }
9781 if (idx < 0)
9782 return "";
9783
9784 return detach_types.Get(idx);
9785 }
9786
9787 void ExplodeAmmo()
9788 {
9789 //timer
9790 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
9791
9792 //min/max time
9793 float min_time = 1;
9794 float max_time = 3;
9795 float delay = Math.RandomFloat(min_time, max_time);
9796
9797 explode_timer.Run(delay, this, "DoAmmoExplosion");
9798 }
9799
9800 void DoAmmoExplosion()
9801 {
9802 Magazine magazine = Magazine.Cast(this);
9803 int pop_sounds_count = 6;
9804 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
9805
9806 //play sound
9807 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
9808 string sound_name = pop_sounds[ sound_idx ];
9809 g_Game.CreateSoundOnObject(this, sound_name, 20, false);
9810
9811 //remove ammo count
9812 magazine.ServerAddAmmoCount(-1);
9813
9814 //if condition then repeat -> ExplodeAmmo
9815 float min_temp_to_explode = 100; //min temperature for item to explode
9816
9817 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
9818 {
9819 ExplodeAmmo();
9820 }
9821 }
9822
9823 // -------------------------------------------------------------------------------
9824 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
9825 {
9826 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
9827
9828 const int CHANCE_DAMAGE_CARGO = 4;
9829 const int CHANCE_DAMAGE_ATTACHMENT = 1;
9830 const int CHANCE_DAMAGE_NOTHING = 2;
9831
9832 if (IsClothing() || IsContainer() || IsItemTent())
9833 {
9834 float dmg = damageResult.GetDamage("","Health") * -0.5;
9835 int chances;
9836 int rnd;
9837
9838 if (GetInventory().GetCargo())
9839 {
9840 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
9841 rnd = Math.RandomInt(0,chances);
9842
9843 if (rnd < CHANCE_DAMAGE_CARGO)
9844 {
9845 DamageItemInCargo(dmg);
9846 }
9847 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
9848 {
9850 }
9851 }
9852 else
9853 {
9854 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
9855 rnd = Math.RandomInt(0,chances);
9856
9857 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
9858 {
9860 }
9861 }
9862 }
9863 }
9864
9865 bool DamageItemInCargo(float damage)
9866 {
9867 CargoBase cargo = GetInventory().GetCargo();
9868 if (cargo)
9869 {
9870 int item_count = cargo.GetItemCount();
9871 if (item_count > 0)
9872 {
9873 int random_pick = Math.RandomInt(0, item_count);
9874 ItemBase item = ItemBase.Cast(cargo.GetItem(random_pick));
9875 if (!item.IsExplosive())
9876 {
9877 item.AddHealth("","",damage);
9878 return true;
9879 }
9880 }
9881 }
9882 return false;
9883 }
9884
9885 bool DamageItemAttachments(float damage)
9886 {
9887 GameInventory inventory = GetInventory();
9888 int attachment_count = inventory.AttachmentCount();
9889 if (attachment_count > 0)
9890 {
9891 int random_pick = Math.RandomInt(0, attachment_count);
9892 ItemBase attachment = ItemBase.Cast(inventory.GetAttachmentFromIndex(random_pick));
9893 if (!attachment.IsExplosive())
9894 {
9895 attachment.AddHealth("","",damage);
9896 return true;
9897 }
9898 }
9899 return false;
9900 }
9901
9902 override bool IsSplitable()
9903 {
9904 return m_CanThisBeSplit;
9905 }
9906 //----------------
9907 override bool CanBeSplit()
9908 {
9909 if (IsSplitable() && (GetQuantity() > 1))
9910 return GetInventory().CanRemoveEntity();
9911
9912 return false;
9913 }
9914
9915 protected bool ShouldSplitQuantity(float quantity)
9916 {
9917 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
9918 if (!IsSplitable())
9919 return false;
9920
9921 // nothing to split?
9922 if (GetQuantity() <= 1)
9923 return false;
9924
9925 // check if we should re-use the item instead of creating a new copy?
9926 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
9927 int delta = GetQuantity() - quantity;
9928 if (delta == 0)
9929 return false;
9930
9931 // valid to split
9932 return true;
9933 }
9934
9935 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
9936 {
9937 if (g_Game.IsClient())
9938 {
9939 if (ScriptInputUserData.CanStoreInputUserData())
9940 {
9941 ScriptInputUserData ctx = new ScriptInputUserData;
9943 ctx.Write(1);
9944 ItemBase i1 = this; // @NOTE: workaround for correct serialization
9945 ctx.Write(i1);
9946 ctx.Write(destination_entity);
9947 ctx.Write(true);
9948 ctx.Write(slot_id);
9949 ctx.Send();
9950 }
9951 }
9952 else if (!g_Game.IsMultiplayer())
9953 {
9954 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(g_Game.GetPlayer()));
9955 }
9956 }
9957
9958 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
9959 {
9960 float split_quantity_new;
9961 ItemBase new_item;
9962 float quantity = GetQuantity();
9963 float stack_max = GetTargetQuantityMax(slot_id);
9964 InventoryLocation loc = new InventoryLocation;
9965
9966 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
9967 {
9968 if (stack_max <= GetQuantity())
9969 split_quantity_new = stack_max;
9970 else
9971 split_quantity_new = GetQuantity();
9972
9973 if (ShouldSplitQuantity(split_quantity_new))
9974 {
9975 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
9976 if (new_item)
9977 {
9978 new_item.SetResultOfSplit(true);
9979 MiscGameplayFunctions.TransferItemProperties(this, new_item);
9980 AddQuantity(-split_quantity_new, false, true);
9981 new_item.SetQuantity(split_quantity_new, false, true);
9982 }
9983 }
9984 }
9985 else if (destination_entity && slot_id == -1)
9986 {
9987 if (quantity > stack_max)
9988 split_quantity_new = stack_max;
9989 else
9990 split_quantity_new = quantity;
9991
9992 if (ShouldSplitQuantity(split_quantity_new))
9993 {
9994 GameInventory destinationInventory = destination_entity.GetInventory();
9995 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
9996 {
9997 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
9998 new_item = ItemBase.Cast(o);
9999 }
10000
10001 if (new_item)
10002 {
10003 new_item.SetResultOfSplit(true);
10004 MiscGameplayFunctions.TransferItemProperties(this, new_item);
10005 AddQuantity(-split_quantity_new, false, true);
10006 new_item.SetQuantity(split_quantity_new, false, true);
10007 }
10008 }
10009 }
10010 else
10011 {
10012 if (stack_max != 0)
10013 {
10014 if (stack_max < GetQuantity())
10015 {
10016 split_quantity_new = GetQuantity() - stack_max;
10017 }
10018
10019 if (split_quantity_new == 0)
10020 {
10021 if (!g_Game.IsMultiplayer())
10022 player.PhysicalPredictiveDropItem(this);
10023 else
10024 player.ServerDropEntity(this);
10025 return;
10026 }
10027
10028 if (ShouldSplitQuantity(split_quantity_new))
10029 {
10030 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
10031
10032 if (new_item)
10033 {
10034 new_item.SetResultOfSplit(true);
10035 MiscGameplayFunctions.TransferItemProperties(this, new_item);
10036 SetQuantity(split_quantity_new, false, true);
10037 new_item.SetQuantity(stack_max, false, true);
10038 new_item.PlaceOnSurface();
10039 }
10040 }
10041 }
10042 }
10043 }
10044
10045 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
10046 {
10047 float split_quantity_new;
10048 ItemBase new_item;
10049 float quantity = GetQuantity();
10050 float stack_max = GetTargetQuantityMax(slot_id);
10051 InventoryLocation loc = new InventoryLocation;
10052
10053 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
10054 {
10055 if (stack_max <= GetQuantity())
10056 split_quantity_new = stack_max;
10057 else
10058 split_quantity_new = GetQuantity();
10059
10060 if (ShouldSplitQuantity(split_quantity_new))
10061 {
10062 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
10063 if (new_item)
10064 {
10065 new_item.SetResultOfSplit(true);
10066 MiscGameplayFunctions.TransferItemProperties(this, new_item);
10067 AddQuantity(-split_quantity_new, false, true);
10068 new_item.SetQuantity(split_quantity_new, false, true);
10069 }
10070 }
10071 }
10072 else if (destination_entity && slot_id == -1)
10073 {
10074 if (quantity > stack_max)
10075 split_quantity_new = stack_max;
10076 else
10077 split_quantity_new = quantity;
10078
10079 if (ShouldSplitQuantity(split_quantity_new))
10080 {
10081 GameInventory destinationInventory = destination_entity.GetInventory();
10082 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
10083 {
10084 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
10085 new_item = ItemBase.Cast(o);
10086 }
10087
10088 if (new_item)
10089 {
10090 new_item.SetResultOfSplit(true);
10091 MiscGameplayFunctions.TransferItemProperties(this, new_item);
10092 AddQuantity(-split_quantity_new, false, true);
10093 new_item.SetQuantity(split_quantity_new, false, true);
10094 }
10095 }
10096 }
10097 else
10098 {
10099 if (stack_max != 0)
10100 {
10101 if (stack_max < GetQuantity())
10102 {
10103 split_quantity_new = GetQuantity() - stack_max;
10104 }
10105
10106 if (ShouldSplitQuantity(split_quantity_new))
10107 {
10108 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
10109
10110 if (new_item)
10111 {
10112 new_item.SetResultOfSplit(true);
10113 MiscGameplayFunctions.TransferItemProperties(this, new_item);
10114 SetQuantity(split_quantity_new, false, true);
10115 new_item.SetQuantity(stack_max, false, true);
10116 new_item.PlaceOnSurface();
10117 }
10118 }
10119 }
10120 }
10121 }
10122
10123 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
10124 {
10125 if (g_Game.IsClient())
10126 {
10127 if (ScriptInputUserData.CanStoreInputUserData())
10128 {
10129 ScriptInputUserData ctx = new ScriptInputUserData;
10131 ctx.Write(4);
10132 ItemBase thiz = this; // @NOTE: workaround for correct serialization
10133 ctx.Write(thiz);
10134 dst.WriteToContext(ctx);
10135 ctx.Send();
10136 }
10137 }
10138 else if (!g_Game.IsMultiplayer())
10139 {
10141 }
10142 }
10143
10144 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
10145 {
10146 if (g_Game.IsClient())
10147 {
10148 if (ScriptInputUserData.CanStoreInputUserData())
10149 {
10150 ScriptInputUserData ctx = new ScriptInputUserData;
10152 ctx.Write(2);
10153 ItemBase dummy = this; // @NOTE: workaround for correct serialization
10154 ctx.Write(dummy);
10155 ctx.Write(destination_entity);
10156 ctx.Write(true);
10157 ctx.Write(idx);
10158 ctx.Write(row);
10159 ctx.Write(col);
10160 ctx.Send();
10161 }
10162 }
10163 else if (!g_Game.IsMultiplayer())
10164 {
10165 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
10166 }
10167 }
10168
10169 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
10170 {
10172 }
10173
10174 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
10175 {
10176 float quantity = GetQuantity();
10177 float split_quantity_new;
10178 ItemBase new_item;
10179 if (dst.IsValid())
10180 {
10181 int slot_id = dst.GetSlot();
10182 float stack_max = GetTargetQuantityMax(slot_id);
10183
10184 if (quantity > stack_max)
10185 split_quantity_new = stack_max;
10186 else
10187 split_quantity_new = quantity;
10188
10189 if (ShouldSplitQuantity(split_quantity_new))
10190 {
10191 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
10192
10193 if (new_item)
10194 {
10195 new_item.SetResultOfSplit(true);
10196 MiscGameplayFunctions.TransferItemProperties(this,new_item);
10197 AddQuantity(-split_quantity_new, false, true);
10198 new_item.SetQuantity(split_quantity_new, false, true);
10199 }
10200
10201 return new_item;
10202 }
10203 }
10204
10205 return null;
10206 }
10207
10208 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
10209 {
10210 float quantity = GetQuantity();
10211 float split_quantity_new;
10212 ItemBase new_item;
10213 if (destination_entity)
10214 {
10215 float stackable = GetTargetQuantityMax();
10216 if (quantity > stackable)
10217 split_quantity_new = stackable;
10218 else
10219 split_quantity_new = quantity;
10220
10221 if (ShouldSplitQuantity(split_quantity_new))
10222 {
10223 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
10224 if (new_item)
10225 {
10226 new_item.SetResultOfSplit(true);
10227 MiscGameplayFunctions.TransferItemProperties(this,new_item);
10228 AddQuantity(-split_quantity_new, false, true);
10229 new_item.SetQuantity(split_quantity_new, false, true);
10230 }
10231 }
10232 }
10233 }
10234
10235 void SplitIntoStackMaxHandsClient(PlayerBase player)
10236 {
10237 if (g_Game.IsClient())
10238 {
10239 if (ScriptInputUserData.CanStoreInputUserData())
10240 {
10241 ScriptInputUserData ctx = new ScriptInputUserData;
10243 ctx.Write(3);
10244 ItemBase i1 = this; // @NOTE: workaround for correct serialization
10245 ctx.Write(i1);
10246 ItemBase destination_entity = this;
10247 ctx.Write(destination_entity);
10248 ctx.Write(true);
10249 ctx.Write(0);
10250 ctx.Send();
10251 }
10252 }
10253 else if (!g_Game.IsMultiplayer())
10254 {
10255 SplitIntoStackMaxHands(player);
10256 }
10257 }
10258
10259 void SplitIntoStackMaxHands(PlayerBase player)
10260 {
10261 float quantity = GetQuantity();
10262 float split_quantity_new;
10263 ref ItemBase new_item;
10264 if (player)
10265 {
10266 float stackable = GetTargetQuantityMax();
10267 if (quantity > stackable)
10268 split_quantity_new = stackable;
10269 else
10270 split_quantity_new = quantity;
10271
10272 if (ShouldSplitQuantity(split_quantity_new))
10273 {
10274 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
10275 new_item = ItemBase.Cast(in_hands);
10276 if (new_item)
10277 {
10278 new_item.SetResultOfSplit(true);
10279 MiscGameplayFunctions.TransferItemProperties(this,new_item);
10280 AddQuantity(-split_quantity_new, false, true);
10281 new_item.SetQuantity(split_quantity_new, false, true);
10282 }
10283 }
10284 }
10285 }
10286
10287 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
10288 {
10289 float quantity = GetQuantity();
10290 float split_quantity_new = Math.Floor(quantity * 0.5);
10291
10292 if (!ShouldSplitQuantity(split_quantity_new))
10293 return;
10294
10295 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
10296
10297 if (new_item)
10298 {
10299 if (new_item.GetQuantityMax() < split_quantity_new)
10300 {
10301 split_quantity_new = new_item.GetQuantityMax();
10302 }
10303
10304 new_item.SetResultOfSplit(true);
10305 MiscGameplayFunctions.TransferItemProperties(this, new_item);
10306
10307 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
10308 {
10309 AddQuantity(-1, false, true);
10310 new_item.SetQuantity(1, false, true);
10311 }
10312 else
10313 {
10314 AddQuantity(-split_quantity_new, false, true);
10315 new_item.SetQuantity(split_quantity_new, false, true);
10316 }
10317 }
10318 }
10319
10320 void SplitItem(PlayerBase player)
10321 {
10322 float quantity = GetQuantity();
10323 float split_quantity_new = Math.Floor(quantity / 2);
10324
10325 if (!ShouldSplitQuantity(split_quantity_new))
10326 return;
10327
10328 InventoryLocation invloc = new InventoryLocation;
10329 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
10330
10331 ItemBase new_item;
10332 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
10333
10334 if (new_item)
10335 {
10336 if (new_item.GetQuantityMax() < split_quantity_new)
10337 {
10338 split_quantity_new = new_item.GetQuantityMax();
10339 }
10340 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
10341 {
10342 AddQuantity(-1, false, true);
10343 new_item.SetQuantity(1, false, true);
10344 }
10345 else if (split_quantity_new > 1)
10346 {
10347 AddQuantity(-split_quantity_new, false, true);
10348 new_item.SetQuantity(split_quantity_new, false, true);
10349 }
10350 }
10351 }
10352
10354 void OnQuantityChanged(float delta)
10355 {
10356 SetWeightDirty();
10357 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
10358
10359 if (parent)
10360 parent.OnAttachmentQuantityChangedEx(this, delta);
10361
10362 if (IsLiquidContainer())
10363 {
10364 if (GetQuantityNormalized() <= 0.0)
10365 {
10367 }
10368 else if (GetLiquidType() == LIQUID_NONE)
10369 {
10370 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
10372 }
10373 }
10374 }
10375
10378 {
10379 // insert code here
10380 }
10381
10383 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
10384 {
10386 }
10387
10388 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
10389 {
10390 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
10391
10392 if (g_Game.IsServer())
10393 {
10394 if (newLevel == GameConstants.STATE_RUINED)
10395 {
10397 EntityAI parent = GetHierarchyParent();
10398 if (parent && parent.IsFireplace())
10399 {
10400 CargoBase cargo = GetInventory().GetCargo();
10401 if (cargo)
10402 {
10403 for (int i = 0; i < cargo.GetItemCount(); ++i)
10404 {
10405 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
10406 }
10407 }
10408 }
10409 }
10410
10411 if (IsResultOfSplit())
10412 {
10413 // reset the splitting result flag, return to normal item behavior
10414 SetResultOfSplit(false);
10415 return;
10416 }
10417
10418 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
10419 {
10420 SetCleanness(0);//unclean the item upon damage dealt
10421 }
10422 }
10423 }
10424
10425 // just the split? TODO: verify
10426 override void OnRightClick()
10427 {
10428 super.OnRightClick();
10429
10430 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !g_Game.GetPlayer().GetInventory().HasInventoryReservation(this,null))
10431 {
10432 if (g_Game.IsClient())
10433 {
10434 if (ScriptInputUserData.CanStoreInputUserData())
10435 {
10436 EntityAI root = GetHierarchyRoot();
10437 Man playerOwner = GetHierarchyRootPlayer();
10438 InventoryLocation dst = new InventoryLocation;
10439
10440 // 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
10441 if (!playerOwner && root && root == this)
10442 {
10444 }
10445 else
10446 {
10447 // 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
10448 GetInventory().GetCurrentInventoryLocation(dst);
10449 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
10450 {
10451 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
10452 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
10453 {
10455 }
10456 else
10457 {
10458 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
10459 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
10460 this shouldnt cause issues within this scope*/
10461 if (g_Game.GetPlayer().GetInventory().HasInventoryReservation(this, dst))
10462 {
10464 }
10465 else
10466 {
10467 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
10468 }
10469 }
10470 }
10471 }
10472
10473 ScriptInputUserData ctx = new ScriptInputUserData;
10475 ctx.Write(4);
10476 ItemBase thiz = this; // @NOTE: workaround for correct serialization
10477 ctx.Write(thiz);
10478 dst.WriteToContext(ctx);
10479 ctx.Write(true); // dummy
10480 ctx.Send();
10481 }
10482 }
10483 else if (!g_Game.IsMultiplayer())
10484 {
10485 SplitItem(PlayerBase.Cast(g_Game.GetPlayer()));
10486 }
10487 }
10488 }
10489
10490 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
10491 {
10492 if (root)
10493 {
10494 vector m4[4];
10495 root.GetTransform(m4);
10496 dst.SetGround(this, m4);
10497 }
10498 else
10499 {
10500 GetInventory().GetCurrentInventoryLocation(dst);
10501 }
10502 }
10503
10504 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
10505 {
10506 //TODO: delete check zero quantity check after fix double posts hands fsm events
10507 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
10508 return false;
10509
10510 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
10511 return false;
10512
10513 //can_this_be_combined = ConfigGetBool("canBeSplit");
10515 return false;
10516
10517
10518 Magazine mag = Magazine.Cast(this);
10519 if (mag)
10520 {
10521 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
10522 return false;
10523
10524 if (stack_max_limit)
10525 {
10526 Magazine other_mag = Magazine.Cast(other_item);
10527 if (other_item)
10528 {
10529 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
10530 return false;
10531 }
10532
10533 }
10534 }
10535 else
10536 {
10537 //TODO: delete check zero quantity check after fix double posts hands fsm events
10538 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
10539 return false;
10540
10541 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
10542 return false;
10543 }
10544
10545 PlayerBase player = null;
10546 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
10547 {
10548 if (player.GetInventory().HasAttachment(this))
10549 return false;
10550
10551 if (player.IsItemsToDelete())
10552 return false;
10553 }
10554
10555 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
10556 return false;
10557
10558 int slotID;
10559 string slotName;
10560 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
10561 return false;
10562
10563 return true;
10564 }
10565
10566 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
10567 {
10568 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
10569 }
10570
10571 bool IsResultOfSplit()
10572 {
10573 return m_IsResultOfSplit;
10574 }
10575
10576 void SetResultOfSplit(bool value)
10577 {
10578 m_IsResultOfSplit = value;
10579 }
10580
10581 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
10582 {
10583 return ComputeQuantityUsedEx(other_item, use_stack_max);
10584 }
10585
10586 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
10587 {
10588 float other_item_quantity = other_item.GetQuantity();
10589 float this_free_space;
10590
10591 float stack_max = GetQuantityMax();
10592
10593 this_free_space = stack_max - GetQuantity();
10594
10595 if (other_item_quantity > this_free_space)
10596 {
10597 return this_free_space;
10598 }
10599 else
10600 {
10601 return other_item_quantity;
10602 }
10603 }
10604
10605 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
10606 {
10607 CombineItems(ItemBase.Cast(entity2),use_stack_max);
10608 }
10609
10610 void CombineItems(ItemBase other_item, bool use_stack_max = true)
10611 {
10612 if (!CanBeCombined(other_item, false))
10613 return;
10614
10615 if (!IsMagazine() && other_item)
10616 {
10617 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
10618 if (quantity_used != 0)
10619 {
10620 float hp1 = GetHealth01("","");
10621 float hp2 = other_item.GetHealth01("","");
10622 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
10623 hpResult = hpResult / (GetQuantity() + quantity_used);
10624
10625 hpResult *= GetMaxHealth();
10626 Math.Round(hpResult);
10627 SetHealth("", "Health", hpResult);
10628
10629 AddQuantity(quantity_used);
10630 other_item.AddQuantity(-quantity_used);
10631 }
10632 }
10633 OnCombine(other_item);
10634 }
10635
10636 void OnCombine(ItemBase other_item)
10637 {
10638 #ifdef SERVER
10639 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
10640 GetHierarchyParent().IncreaseLifetimeUp();
10641 #endif
10642 };
10643
10644 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
10645 {
10646 PlayerBase p = PlayerBase.Cast(player);
10647
10648 array<int> recipesIds = p.m_Recipes;
10649 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
10650 if (moduleRecipesManager)
10651 {
10652 EntityAI itemInHands = player.GetEntityInHands();
10653 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
10654 }
10655
10656 for (int i = 0;i < recipesIds.Count(); i++)
10657 {
10658 int key = recipesIds.Get(i);
10659 string recipeName = moduleRecipesManager.GetRecipeName(key);
10660 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
10661 }
10662 }
10663
10664 // -------------------------------------------------------------------------
10665 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
10666 {
10667 super.GetDebugActions(outputList);
10668
10669 //quantity
10670 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
10671 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
10672 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
10673 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
10674 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10675
10676 //health
10677 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
10678 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
10679 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
10680 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10681 //temperature
10682 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
10683 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
10684 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
10685 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10686
10687 //wet
10688 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
10689 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
10690 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10691
10692 //liquidtype
10693 if (IsLiquidContainer())
10694 {
10695 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
10696 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
10697 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10698 }
10699
10700 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
10701 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10702
10703 // watch
10704 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
10705 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
10706 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10707
10708 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
10709
10710 InventoryLocation loc = new InventoryLocation();
10711 GetInventory().GetCurrentInventoryLocation(loc);
10712 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
10713 {
10714 if (Gizmo_IsSupported())
10715 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
10716 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
10717 }
10718
10719 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
10720 }
10721
10722 // -------------------------------------------------------------------------
10723 // -------------------------------------------------------------------------
10724 // -------------------------------------------------------------------------
10725 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
10726 {
10727 super.OnAction(action_id, player, ctx);
10728
10729 if (g_Game.IsClient() || !g_Game.IsMultiplayer())
10730 {
10731 switch (action_id)
10732 {
10733 case EActions.GIZMO_OBJECT:
10734 if (GetGizmoApi())
10735 GetGizmoApi().SelectObject(this);
10736 return true;
10737 case EActions.GIZMO_PHYSICS:
10738 if (GetGizmoApi())
10739 GetGizmoApi().SelectPhysics(GetPhysics());
10740 return true;
10741 }
10742 }
10743
10744 if (g_Game.IsServer())
10745 {
10746 switch (action_id)
10747 {
10748 case EActions.DELETE:
10749 Delete();
10750 return true;
10751 }
10752 }
10753
10754 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
10755 {
10756 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
10757 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
10758 PlayerBase p = PlayerBase.Cast(player);
10759 if (EActions.RECIPES_RANGE_START < 1000)
10760 {
10761 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
10762 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
10763 }
10764 }
10765 #ifndef SERVER
10766 else if (action_id == EActions.WATCH_PLAYER)
10767 {
10768 PluginDeveloper.SetDeveloperItemClientEx(player);
10769 }
10770 #endif
10771 if (g_Game.IsServer())
10772 {
10773 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
10774 {
10775 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
10776 OnDebugButtonPressServer(id + 1);
10777 }
10778
10779 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
10780 {
10781 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
10782 InsertAgent(agent_id,100);
10783 }
10784
10785 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
10786 {
10787 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
10788 RemoveAgent(agent_id2);
10789 }
10790
10791 else if (action_id == EActions.ADD_QUANTITY)
10792 {
10793 if (IsMagazine())
10794 {
10795 Magazine mag = Magazine.Cast(this);
10796 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
10797 }
10798 else
10799 {
10800 AddQuantity(GetQuantityMax() * 0.2);
10801 }
10802
10803 if (m_EM)
10804 {
10805 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
10806 }
10807 //PrintVariables();
10808 }
10809
10810 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
10811 {
10812 if (IsMagazine())
10813 {
10814 Magazine mag2 = Magazine.Cast(this);
10815 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
10816 }
10817 else
10818 {
10819 AddQuantity(- GetQuantityMax() * 0.2);
10820 }
10821 if (m_EM)
10822 {
10823 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
10824 }
10825 //PrintVariables();
10826 }
10827
10828 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
10829 {
10830 SetQuantity(0);
10831
10832 if (m_EM)
10833 {
10834 m_EM.SetEnergy(0);
10835 }
10836 }
10837
10838 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
10839 {
10841
10842 if (m_EM)
10843 {
10844 m_EM.SetEnergy(m_EM.GetEnergyMax());
10845 }
10846 }
10847
10848 else if (action_id == EActions.ADD_HEALTH)
10849 {
10850 AddHealth("","",GetMaxHealth("","Health")/5);
10851 }
10852 else if (action_id == EActions.REMOVE_HEALTH)
10853 {
10854 AddHealth("","",-GetMaxHealth("","Health")/5);
10855 }
10856 else if (action_id == EActions.DESTROY_HEALTH)
10857 {
10858 SetHealth01("","",0);
10859 }
10860 else if (action_id == EActions.WATCH_ITEM)
10861 {
10863 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
10864 #ifdef DEVELOPER
10865 SetDebugDeveloper_item(this);
10866 #endif
10867 }
10868
10869 else if (action_id == EActions.ADD_TEMPERATURE)
10870 {
10871 AddTemperature(20);
10872 //PrintVariables();
10873 }
10874
10875 else if (action_id == EActions.REMOVE_TEMPERATURE)
10876 {
10877 AddTemperature(-20);
10878 //PrintVariables();
10879 }
10880
10881 else if (action_id == EActions.FLIP_FROZEN)
10882 {
10883 SetFrozen(!GetIsFrozen());
10884 //PrintVariables();
10885 }
10886
10887 else if (action_id == EActions.ADD_WETNESS)
10888 {
10889 AddWet(GetWetMax()/5);
10890 //PrintVariables();
10891 }
10892
10893 else if (action_id == EActions.REMOVE_WETNESS)
10894 {
10895 AddWet(-GetWetMax()/5);
10896 //PrintVariables();
10897 }
10898
10899 else if (action_id == EActions.LIQUIDTYPE_UP)
10900 {
10901 int curr_type = GetLiquidType();
10902 SetLiquidType(curr_type * 2);
10903 //AddWet(1);
10904 //PrintVariables();
10905 }
10906
10907 else if (action_id == EActions.LIQUIDTYPE_DOWN)
10908 {
10909 int curr_type2 = GetLiquidType();
10910 SetLiquidType(curr_type2 / 2);
10911 }
10912
10913 else if (action_id == EActions.MAKE_SPECIAL)
10914 {
10915 auto debugParams = DebugSpawnParams.WithPlayer(player);
10916 OnDebugSpawnEx(debugParams);
10917 }
10918
10919 }
10920
10921
10922 return false;
10923 }
10924
10925 // -------------------------------------------------------------------------
10926
10927
10930 void OnActivatedByTripWire();
10931
10933 void OnActivatedByItem(notnull ItemBase item);
10934
10935 //----------------------------------------------------------------
10936 //returns true if item is able to explode when put in fire
10937 bool CanExplodeInFire()
10938 {
10939 return false;
10940 }
10941
10942 //----------------------------------------------------------------
10943 bool CanEat()
10944 {
10945 return true;
10946 }
10947
10948 //----------------------------------------------------------------
10949 override bool IsIgnoredByConstruction()
10950 {
10951 return true;
10952 }
10953
10954 //----------------------------------------------------------------
10955 //has FoodStages in config?
10956 bool HasFoodStage()
10957 {
10958 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
10959 return g_Game.ConfigIsExisting(config_path);
10960 }
10961
10963 FoodStage GetFoodStage()
10964 {
10965 return null;
10966 }
10967
10968 bool CanBeCooked()
10969 {
10970 return false;
10971 }
10972
10973 bool CanBeCookedOnStick()
10974 {
10975 return false;
10976 }
10977
10979 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
10981
10982 //----------------------------------------------------------------
10983 bool CanRepair(ItemBase item_repair_kit)
10984 {
10985 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
10986 return module_repairing.CanRepair(this, item_repair_kit);
10987 }
10988
10989 //----------------------------------------------------------------
10990 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
10991 {
10992 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
10993 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
10994 }
10995
10996 //----------------------------------------------------------------
10997 int GetItemSize()
10998 {
10999 /*
11000 vector v_size = this.ConfigGetVector("itemSize");
11001 int v_size_x = v_size[0];
11002 int v_size_y = v_size[1];
11003 int size = v_size_x * v_size_y;
11004 return size;
11005 */
11006
11007 return 1;
11008 }
11009
11010 //----------------------------------------------------------------
11011 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
11012 bool CanBeMovedOverride()
11013 {
11014 return m_CanBeMovedOverride;
11015 }
11016
11017 //----------------------------------------------------------------
11018 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
11019 void SetCanBeMovedOverride(bool setting)
11020 {
11021 m_CanBeMovedOverride = setting;
11022 }
11023
11024 //----------------------------------------------------------------
11032 void MessageToOwnerStatus(string text)
11033 {
11034 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
11035
11036 if (player)
11037 {
11038 player.MessageStatus(text);
11039 }
11040 }
11041
11042 //----------------------------------------------------------------
11050 void MessageToOwnerAction(string text)
11051 {
11052 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
11053
11054 if (player)
11055 {
11056 player.MessageAction(text);
11057 }
11058 }
11059
11060 //----------------------------------------------------------------
11068 void MessageToOwnerFriendly(string text)
11069 {
11070 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
11071
11072 if (player)
11073 {
11074 player.MessageFriendly(text);
11075 }
11076 }
11077
11078 //----------------------------------------------------------------
11086 void MessageToOwnerImportant(string text)
11087 {
11088 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
11089
11090 if (player)
11091 {
11092 player.MessageImportant(text);
11093 }
11094 }
11095
11096 override bool IsItemBase()
11097 {
11098 return true;
11099 }
11100
11101 // Checks if item is of questioned kind
11102 override bool KindOf(string tag)
11103 {
11104 bool found = false;
11105 string item_name = this.GetType();
11106 ref TStringArray item_tag_array = new TStringArray;
11107 g_Game.ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
11108
11109 int array_size = item_tag_array.Count();
11110 for (int i = 0; i < array_size; i++)
11111 {
11112 if (item_tag_array.Get(i) == tag)
11113 {
11114 found = true;
11115 break;
11116 }
11117 }
11118 return found;
11119 }
11120
11121
11122 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
11123 {
11124 //Debug.Log("OnRPC called");
11125 super.OnRPC(sender, rpc_type,ctx);
11126
11127 //Play soundset for attachment locking (ActionLockAttachment.c)
11128 switch (rpc_type)
11129 {
11130 #ifndef SERVER
11131 case ERPCs.RPC_SOUND_LOCK_ATTACH:
11132 Param2<bool, string> p = new Param2<bool, string>(false, "");
11133
11134 if (!ctx.Read(p))
11135 return;
11136
11137 bool play = p.param1;
11138 string soundSet = p.param2;
11139
11140 if (play)
11141 {
11142 if (m_LockingSound)
11143 {
11145 {
11146 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
11147 }
11148 }
11149 else
11150 {
11151 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
11152 }
11153 }
11154 else
11155 {
11156 SEffectManager.DestroyEffect(m_LockingSound);
11157 }
11158
11159 break;
11160 #endif
11161
11162 }
11163
11164 if (GetWrittenNoteData())
11165 {
11166 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
11167 }
11168 }
11169
11170 //-----------------------------
11171 // VARIABLE MANIPULATION SYSTEM
11172 //-----------------------------
11173 int NameToID(string name)
11174 {
11175 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
11176 return plugin.GetID(name);
11177 }
11178
11179 string IDToName(int id)
11180 {
11181 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
11182 return plugin.GetName(id);
11183 }
11184
11186 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
11187 {
11188 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
11189 //read the flags
11190 int varFlags;
11191 if (!ctx.Read(varFlags))
11192 return;
11193
11194 if (varFlags & ItemVariableFlags.FLOAT)
11195 {
11196 ReadVarsFromCTX(ctx);
11197 }
11198 }
11199
11200 override void SerializeNumericalVars(array<float> floats_out)
11201 {
11202 //some variables handled on EntityAI level already!
11203 super.SerializeNumericalVars(floats_out);
11204
11205 // the order of serialization must be the same as the order of de-serialization
11206 //--------------------------------------------
11207 if (IsVariableSet(VARIABLE_QUANTITY))
11208 {
11209 floats_out.Insert(m_VarQuantity);
11210 }
11211 //--------------------------------------------
11212 if (IsVariableSet(VARIABLE_WET))
11213 {
11214 floats_out.Insert(m_VarWet);
11215 }
11216 //--------------------------------------------
11217 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
11218 {
11219 floats_out.Insert(m_VarLiquidType);
11220 }
11221 //--------------------------------------------
11222 if (IsVariableSet(VARIABLE_COLOR))
11223 {
11224 floats_out.Insert(m_ColorComponentR);
11225 floats_out.Insert(m_ColorComponentG);
11226 floats_out.Insert(m_ColorComponentB);
11227 floats_out.Insert(m_ColorComponentA);
11228 }
11229 //--------------------------------------------
11230 if (IsVariableSet(VARIABLE_CLEANNESS))
11231 {
11232 floats_out.Insert(m_Cleanness);
11233 }
11234 }
11235
11236 override void DeSerializeNumericalVars(array<float> floats)
11237 {
11238 //some variables handled on EntityAI level already!
11239 super.DeSerializeNumericalVars(floats);
11240
11241 // the order of serialization must be the same as the order of de-serialization
11242 int index = 0;
11243 int mask = Math.Round(floats.Get(index));
11244
11245 index++;
11246 //--------------------------------------------
11247 if (mask & VARIABLE_QUANTITY)
11248 {
11249 if (m_IsStoreLoad)
11250 {
11251 SetStoreLoadedQuantity(floats.Get(index));
11252 }
11253 else
11254 {
11255 float quantity = floats.Get(index);
11256 SetQuantity(quantity, true, false, false, false);
11257 }
11258 index++;
11259 }
11260 //--------------------------------------------
11261 if (mask & VARIABLE_WET)
11262 {
11263 float wet = floats.Get(index);
11264 SetWet(wet);
11265 index++;
11266 }
11267 //--------------------------------------------
11268 if (mask & VARIABLE_LIQUIDTYPE)
11269 {
11270 int liquidtype = Math.Round(floats.Get(index));
11271 SetLiquidType(liquidtype);
11272 index++;
11273 }
11274 //--------------------------------------------
11275 if (mask & VARIABLE_COLOR)
11276 {
11277 m_ColorComponentR = Math.Round(floats.Get(index));
11278 index++;
11279 m_ColorComponentG = Math.Round(floats.Get(index));
11280 index++;
11281 m_ColorComponentB = Math.Round(floats.Get(index));
11282 index++;
11283 m_ColorComponentA = Math.Round(floats.Get(index));
11284 index++;
11285 }
11286 //--------------------------------------------
11287 if (mask & VARIABLE_CLEANNESS)
11288 {
11289 int cleanness = Math.Round(floats.Get(index));
11290 SetCleanness(cleanness);
11291 index++;
11292 }
11293 }
11294
11295 override void WriteVarsToCTX(ParamsWriteContext ctx)
11296 {
11297 super.WriteVarsToCTX(ctx);
11298
11299 //--------------------------------------------
11300 if (IsVariableSet(VARIABLE_QUANTITY))
11301 {
11302 ctx.Write(GetQuantity());
11303 }
11304 //--------------------------------------------
11305 if (IsVariableSet(VARIABLE_WET))
11306 {
11307 ctx.Write(GetWet());
11308 }
11309 //--------------------------------------------
11310 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
11311 {
11312 ctx.Write(GetLiquidType());
11313 }
11314 //--------------------------------------------
11315 if (IsVariableSet(VARIABLE_COLOR))
11316 {
11317 int r,g,b,a;
11318 GetColor(r,g,b,a);
11319 ctx.Write(r);
11320 ctx.Write(g);
11321 ctx.Write(b);
11322 ctx.Write(a);
11323 }
11324 //--------------------------------------------
11325 if (IsVariableSet(VARIABLE_CLEANNESS))
11326 {
11327 ctx.Write(GetCleanness());
11328 }
11329 }
11330
11331 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
11332 {
11333 if (!super.ReadVarsFromCTX(ctx,version))
11334 return false;
11335
11336 int intValue;
11337 float value;
11338
11339 if (version < 140)
11340 {
11341 if (!ctx.Read(intValue))
11342 return false;
11343
11344 m_VariablesMask = intValue;
11345 }
11346
11347 if (m_VariablesMask & VARIABLE_QUANTITY)
11348 {
11349 if (!ctx.Read(value))
11350 return false;
11351
11352 if (IsStoreLoad())
11353 {
11355 }
11356 else
11357 {
11358 SetQuantity(value, true, false, false, false);
11359 }
11360 }
11361 //--------------------------------------------
11362 if (version < 140)
11363 {
11364 if (m_VariablesMask & VARIABLE_TEMPERATURE)
11365 {
11366 if (!ctx.Read(value))
11367 return false;
11368 SetTemperatureDirect(value);
11369 }
11370 }
11371 //--------------------------------------------
11372 if (m_VariablesMask & VARIABLE_WET)
11373 {
11374 if (!ctx.Read(value))
11375 return false;
11376 SetWet(value);
11377 }
11378 //--------------------------------------------
11379 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
11380 {
11381 if (!ctx.Read(intValue))
11382 return false;
11383 SetLiquidType(intValue);
11384 }
11385 //--------------------------------------------
11386 if (m_VariablesMask & VARIABLE_COLOR)
11387 {
11388 int r,g,b,a;
11389 if (!ctx.Read(r))
11390 return false;
11391 if (!ctx.Read(g))
11392 return false;
11393 if (!ctx.Read(b))
11394 return false;
11395 if (!ctx.Read(a))
11396 return false;
11397
11398 SetColor(r,g,b,a);
11399 }
11400 //--------------------------------------------
11401 if (m_VariablesMask & VARIABLE_CLEANNESS)
11402 {
11403 if (!ctx.Read(intValue))
11404 return false;
11405 SetCleanness(intValue);
11406 }
11407 //--------------------------------------------
11408 if (version >= 138 && version < 140)
11409 {
11410 if (m_VariablesMask & VARIABLE_TEMPERATURE)
11411 {
11412 if (!ctx.Read(intValue))
11413 return false;
11414 SetFrozen(intValue);
11415 }
11416 }
11417
11418 return true;
11419 }
11420
11421 //----------------------------------------------------------------
11422 override bool OnStoreLoad(ParamsReadContext ctx, int version)
11423 {
11424 m_IsStoreLoad = true;
11426 {
11427 m_FixDamageSystemInit = true;
11428 }
11429
11430 if (!super.OnStoreLoad(ctx, version))
11431 {
11432 m_IsStoreLoad = false;
11433 return false;
11434 }
11435
11436 if (version >= 114)
11437 {
11438 bool hasQuickBarIndexSaved;
11439
11440 if (!ctx.Read(hasQuickBarIndexSaved))
11441 {
11442 m_IsStoreLoad = false;
11443 return false;
11444 }
11445
11446 if (hasQuickBarIndexSaved)
11447 {
11448 int itmQBIndex;
11449
11450 //Load quickbar item bind
11451 if (!ctx.Read(itmQBIndex))
11452 {
11453 m_IsStoreLoad = false;
11454 return false;
11455 }
11456
11457 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
11458 if (itmQBIndex != -1 && parentPlayer)
11459 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
11460 }
11461 }
11462 else
11463 {
11464 // Backup of how it used to be
11465 PlayerBase player;
11466 int itemQBIndex;
11467 if (version == int.MAX)
11468 {
11469 if (!ctx.Read(itemQBIndex))
11470 {
11471 m_IsStoreLoad = false;
11472 return false;
11473 }
11474 }
11475 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
11476 {
11477 //Load quickbar item bind
11478 if (!ctx.Read(itemQBIndex))
11479 {
11480 m_IsStoreLoad = false;
11481 return false;
11482 }
11483 if (itemQBIndex != -1 && player)
11484 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
11485 }
11486 }
11487
11488 if (version < 140)
11489 {
11490 // variable management system
11491 if (!LoadVariables(ctx, version))
11492 {
11493 m_IsStoreLoad = false;
11494 return false;
11495 }
11496 }
11497
11498 //agent trasmission system
11499 if (!LoadAgents(ctx, version))
11500 {
11501 m_IsStoreLoad = false;
11502 return false;
11503 }
11504 if (version >= 132)
11505 {
11506 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
11507 if (raib)
11508 {
11509 if (!raib.OnStoreLoad(ctx,version))
11510 {
11511 m_IsStoreLoad = false;
11512 return false;
11513 }
11514 }
11515 }
11516
11517 m_IsStoreLoad = false;
11518 return true;
11519 }
11520
11521 //----------------------------------------------------------------
11522
11523 override void OnStoreSave(ParamsWriteContext ctx)
11524 {
11525 super.OnStoreSave(ctx);
11526
11527 PlayerBase player;
11528 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
11529 {
11530 ctx.Write(true); // Keep track of if we should actually read this in or not
11531 //Save quickbar item bind
11532 int itemQBIndex = -1;
11533 itemQBIndex = player.FindQuickBarEntityIndex(this);
11534 ctx.Write(itemQBIndex);
11535 }
11536 else
11537 {
11538 ctx.Write(false); // Keep track of if we should actually read this in or not
11539 }
11540
11541 SaveAgents(ctx);//agent trasmission system
11542
11543 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
11544 if (raib)
11545 {
11546 raib.OnStoreSave(ctx);
11547 }
11548 }
11549 //----------------------------------------------------------------
11550
11551 override void AfterStoreLoad()
11552 {
11553 super.AfterStoreLoad();
11554
11556 {
11558 }
11559
11560 if (GetStoreLoadedQuantity() != float.LOWEST)
11561 {
11563 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
11564 }
11565 }
11566
11567 override void EEOnAfterLoad()
11568 {
11569 super.EEOnAfterLoad();
11570
11572 {
11573 m_FixDamageSystemInit = false;
11574 }
11575
11578 }
11579
11580 bool CanBeDisinfected()
11581 {
11582 return false;
11583 }
11584
11585
11586 //----------------------------------------------------------------
11587 override void OnVariablesSynchronized()
11588 {
11589 if (m_Initialized)
11590 {
11591 #ifdef PLATFORM_CONSOLE
11592 //bruteforce it is
11593 if (IsSplitable())
11594 {
11595 UIScriptedMenu menu = g_Game.GetUIManager().FindMenu(MENU_INVENTORY);
11596 if (menu)
11597 {
11598 menu.Refresh();
11599 }
11600 }
11601 #endif
11602 }
11603
11605 {
11606 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
11607 m_WantPlayImpactSound = false;
11608 }
11609
11611 {
11612 SetWeightDirty();
11614 }
11615 if (m_VarWet != m_VarWetPrev)
11616 {
11619 }
11620
11621 if (m_SoundSyncPlay != 0)
11622 {
11625
11626 m_SoundSyncPlay = 0;
11627 m_SoundSyncSlotID = -1;
11628 }
11629 if (m_SoundSyncStop != 0)
11630 {
11632 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
11633 m_SoundSyncStop = 0;
11634 }
11635
11636 super.OnVariablesSynchronized();
11637 }
11638
11639 //------------------------- Quantity
11640 //----------------------------------------------------------------
11642 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
11643 {
11644 if (!IsServerCheck(allow_client))
11645 return false;
11646
11647 if (!HasQuantity())
11648 return false;
11649
11650 float min = GetQuantityMin();
11651 float max = GetQuantityMax();
11652
11653 if (value <= (min + 0.001))
11654 value = min;
11655
11656 if (value == min)
11657 {
11658 if (destroy_config)
11659 {
11660 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
11661 if (dstr)
11662 {
11663 m_VarQuantity = Math.Clamp(value, min, max);
11664 this.Delete();
11665 return true;
11666 }
11667 }
11668 else if (destroy_forced)
11669 {
11670 m_VarQuantity = Math.Clamp(value, min, max);
11671 this.Delete();
11672 return true;
11673 }
11674 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
11675 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
11676 }
11677
11678 float delta = m_VarQuantity;
11679 m_VarQuantity = Math.Clamp(value, min, max);
11680
11681 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
11682 {
11683 EntityAI parent = GetHierarchyRoot();
11684 InventoryLocation iLoc = new InventoryLocation();
11685 GetInventory().GetCurrentInventoryLocation(iLoc);
11686 if (iLoc && iLoc.IsValid() && delta != m_VarQuantity)
11687 {
11688 int iLocSlot = iLoc.GetSlot();
11689 if (delta < m_VarQuantity && iLoc.GetType() != InventoryLocationType.GROUND)
11690 {
11691 StartItemSoundServer(SoundConstants.ITEM_ATTACH, iLocSlot);
11692 }
11693 if (delta > m_VarQuantity && m_VarQuantity != 0 && !IsPrepareToDelete() && iLoc.GetType() == InventoryLocationType.ATTACHMENT)
11694 {
11695 StartItemSoundServer(SoundConstants.ITEM_DETACH, iLocSlot);
11696 }
11697 }
11698 }
11699
11700 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
11701 {
11702 delta = m_VarQuantity - delta;
11703
11704 if (delta)
11705 OnQuantityChanged(delta);
11706 }
11707
11708 SetVariableMask(VARIABLE_QUANTITY);
11709
11710 return false;
11711 }
11712
11713 //----------------------------------------------------------------
11715 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
11716 {
11717 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
11718 }
11719 //----------------------------------------------------------------
11720 void SetQuantityMax()
11721 {
11722 float max = GetQuantityMax();
11723 SetQuantity(max);
11724 }
11725
11726 override void SetQuantityToMinimum()
11727 {
11728 float min = GetQuantityMin();
11729 SetQuantity(min);
11730 }
11731 //----------------------------------------------------------------
11733 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
11734 {
11735 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
11736 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
11737 SetQuantity(result, destroy_config, destroy_forced);
11738 }
11739
11740 //----------------------------------------------------------------
11742 override float GetQuantityNormalized()
11743 {
11744 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
11745 }
11746
11748 {
11749 return GetQuantityNormalized();
11750 }
11751
11752 /*void SetAmmoNormalized(float value)
11753 {
11754 float value_clamped = Math.Clamp(value, 0, 1);
11755 Magazine this_mag = Magazine.Cast(this);
11756 int max_rounds = this_mag.GetAmmoMax();
11757 int result = value * max_rounds;//can the rounded if higher precision is required
11758 this_mag.SetAmmoCount(result);
11759 }*/
11760 //----------------------------------------------------------------
11761 override int GetQuantityMax()
11762 {
11763 int slot = -1;
11764 GameInventory inventory = GetInventory();
11765 if (inventory)
11766 {
11767 InventoryLocation il = new InventoryLocation;
11768 inventory.GetCurrentInventoryLocation(il);
11769 slot = il.GetSlot();
11770 }
11771
11772 return GetTargetQuantityMax(slot);
11773 }
11774
11775 override int GetTargetQuantityMax(int attSlotID = -1)
11776 {
11777 float quantity_max = 0;
11778
11779 if (IsSplitable()) //only stackable/splitable items can check for stack size
11780 {
11781 if (attSlotID != -1)
11782 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
11783
11784 if (quantity_max <= 0)
11785 quantity_max = m_VarStackMax;
11786 }
11787
11788 if (quantity_max <= 0)
11789 quantity_max = m_VarQuantityMax;
11790
11791 return quantity_max;
11792 }
11793 //----------------------------------------------------------------
11794 override int GetQuantityMin()
11795 {
11796 return m_VarQuantityMin;
11797 }
11798 //----------------------------------------------------------------
11799 int GetQuantityInit()
11800 {
11801 return m_VarQuantityInit;
11802 }
11803
11804 //----------------------------------------------------------------
11805 override bool HasQuantity()
11806 {
11807 return !(GetQuantityMax() - GetQuantityMin() == 0);
11808 }
11809
11810 override float GetQuantity()
11811 {
11812 return m_VarQuantity;
11813 }
11814
11815 bool IsFullQuantity()
11816 {
11817 return GetQuantity() >= GetQuantityMax();
11818 }
11819
11820 //Calculates weight of single item without attachments and cargo
11821 override float GetSingleInventoryItemWeightEx()
11822 {
11823 //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
11824 float weightEx = GetWeightEx();//overall weight of the item
11825 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
11826 return weightEx - special;
11827 }
11828
11829 // Obsolete, use GetSingleInventoryItemWeightEx() instead
11831 {
11833 }
11834
11835 override protected float GetWeightSpecialized(bool forceRecalc = false)
11836 {
11837 if (IsSplitable()) //quantity determines size of the stack
11838 {
11839 #ifdef DEVELOPER
11840 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
11841 {
11842 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
11843 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
11844 }
11845 #endif
11846
11847 return GetQuantity() * GetConfigWeightModified();
11848 }
11849 else if (HasEnergyManager())// items with energy manager
11850 {
11851 #ifdef DEVELOPER
11852 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
11853 {
11854 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
11855 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
11856 }
11857 #endif
11858 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
11859 }
11860 else//everything else
11861 {
11862 #ifdef DEVELOPER
11863 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
11864 {
11865 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
11866 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
11867 }
11868 #endif
11869 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
11870 }
11871 }
11872
11874 int GetNumberOfItems()
11875 {
11876 int item_count = 0;
11877 ItemBase item;
11878
11879 GameInventory inventory = GetInventory();
11880 CargoBase cargo = inventory.GetCargo();
11881 if (cargo != NULL)
11882 {
11883 item_count = cargo.GetItemCount();
11884 }
11885
11886 int nAttachments = inventory.AttachmentCount();
11887 for (int i = 0; i < nAttachments; ++i)
11888 {
11889 Class.CastTo(item, inventory.GetAttachmentFromIndex(i));
11890 if (item)
11891 item_count += item.GetNumberOfItems();
11892 }
11893 return item_count;
11894 }
11895
11897 float GetUnitWeight(bool include_wetness = true)
11898 {
11899 float weight = 0;
11900 float wetness = 1;
11901 if (include_wetness)
11902 wetness += GetWet();
11903 if (IsSplitable()) //quantity determines size of the stack
11904 {
11905 weight = wetness * m_ConfigWeight;
11906 }
11907 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
11908 {
11909 weight = 1;
11910 }
11911 return weight;
11912 }
11913
11914 //-----------------------------------------------------------------
11915
11916 override void ClearInventory()
11917 {
11918 GameInventory inventory = GetInventory();
11919 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && inventory)
11920 {
11921 array<EntityAI> items = new array<EntityAI>;
11922 inventory.EnumerateInventory(InventoryTraversalType.INORDER, items);
11923 for (int i = 0; i < items.Count(); ++i)
11924 {
11925 ItemBase item = ItemBase.Cast(items.Get(i));
11926 if (item)
11927 {
11928 g_Game.ObjectDelete(item);
11929 }
11930 }
11931 }
11932 }
11933
11934 //------------------------- Energy
11935
11936 //----------------------------------------------------------------
11937 float GetEnergy()
11938 {
11939 float energy = 0;
11940 if (HasEnergyManager())
11941 {
11942 energy = GetCompEM().GetEnergy();
11943 }
11944 return energy;
11945 }
11946
11947
11948 override void OnEnergyConsumed()
11949 {
11950 super.OnEnergyConsumed();
11951
11953 }
11954
11955 override void OnEnergyAdded()
11956 {
11957 super.OnEnergyAdded();
11958
11960 }
11961
11962 // Converts energy (from Energy Manager) to quantity, if enabled.
11964 {
11965 if (g_Game.IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
11966 {
11967 if (HasQuantity())
11968 {
11969 float energy_0to1 = GetCompEM().GetEnergy0To1();
11970 SetQuantityNormalized(energy_0to1);
11971 }
11972 }
11973 }
11974
11975 //----------------------------------------------------------------
11976 float GetHeatIsolationInit()
11977 {
11978 return ConfigGetFloat("heatIsolation");
11979 }
11980
11981 float GetHeatIsolation()
11982 {
11983 return m_HeatIsolation;
11984 }
11985
11986 float GetDryingIncrement(string pIncrementName)
11987 {
11988 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
11989 if (g_Game.ConfigIsExisting(paramPath))
11990 return g_Game.ConfigGetFloat(paramPath);
11991
11992 return 0.0;
11993 }
11994
11995 float GetSoakingIncrement(string pIncrementName)
11996 {
11997 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
11998 if (g_Game.ConfigIsExisting(paramPath))
11999 return g_Game.ConfigGetFloat(paramPath);
12000
12001 return 0.0;
12002 }
12003 //----------------------------------------------------------------
12004 override void SetWet(float value, bool allow_client = false)
12005 {
12006 if (!IsServerCheck(allow_client))
12007 return;
12008
12009 float min = GetWetMin();
12010 float max = GetWetMax();
12011
12012 float previousValue = m_VarWet;
12013
12014 m_VarWet = Math.Clamp(value, min, max);
12015
12016 if (previousValue != m_VarWet)
12017 {
12018 SetVariableMask(VARIABLE_WET);
12019 OnWetChanged(m_VarWet, previousValue);
12020 }
12021 }
12022 //----------------------------------------------------------------
12023 override void AddWet(float value)
12024 {
12025 SetWet(GetWet() + value);
12026 }
12027 //----------------------------------------------------------------
12028 override void SetWetMax()
12029 {
12031 }
12032 //----------------------------------------------------------------
12033 override float GetWet()
12034 {
12035 return m_VarWet;
12036 }
12037 //----------------------------------------------------------------
12038 override float GetWetMax()
12039 {
12040 return m_VarWetMax;
12041 }
12042 //----------------------------------------------------------------
12043 override float GetWetMin()
12044 {
12045 return m_VarWetMin;
12046 }
12047 //----------------------------------------------------------------
12048 override float GetWetInit()
12049 {
12050 return m_VarWetInit;
12051 }
12052 //----------------------------------------------------------------
12053 override void OnWetChanged(float newVal, float oldVal)
12054 {
12055 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
12056 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
12057 if (newLevel != oldLevel)
12058 {
12059 OnWetLevelChanged(newLevel,oldLevel);
12060 }
12061 }
12062
12063 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
12064 {
12065 SetWeightDirty();
12066 }
12067
12068 override EWetnessLevel GetWetLevel()
12069 {
12070 return GetWetLevelInternal(m_VarWet);
12071 }
12072
12073 //----------------------------------------------------------------
12074
12075 override void SetStoreLoad(bool value)
12076 {
12077 m_IsStoreLoad = value;
12078 }
12079
12080 override bool IsStoreLoad()
12081 {
12082 return m_IsStoreLoad;
12083 }
12084
12085 override void SetStoreLoadedQuantity(float value)
12086 {
12087 m_StoreLoadedQuantity = value;
12088 }
12089
12090 override float GetStoreLoadedQuantity()
12091 {
12092 return m_StoreLoadedQuantity;
12093 }
12094
12095 //----------------------------------------------------------------
12096
12097 float GetItemModelLength()
12098 {
12099 if (ConfigIsExisting("itemModelLength"))
12100 {
12101 return ConfigGetFloat("itemModelLength");
12102 }
12103 return 0;
12104 }
12105
12106 float GetItemAttachOffset()
12107 {
12108 if (ConfigIsExisting("itemAttachOffset"))
12109 {
12110 return ConfigGetFloat("itemAttachOffset");
12111 }
12112 return 0;
12113 }
12114
12115 override void SetCleanness(int value, bool allow_client = false)
12116 {
12117 if (!IsServerCheck(allow_client))
12118 return;
12119
12120 int previousValue = m_Cleanness;
12121
12122 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
12123
12124 if (previousValue != m_Cleanness)
12125 SetVariableMask(VARIABLE_CLEANNESS);
12126 }
12127
12128 override int GetCleanness()
12129 {
12130 return m_Cleanness;
12131 }
12132
12134 {
12135 return true;
12136 }
12137
12138 //----------------------------------------------------------------
12139 // ATTACHMENT LOCKING
12140 // Getters relevant to generic ActionLockAttachment
12141 int GetLockType()
12142 {
12143 return m_LockType;
12144 }
12145
12146 string GetLockSoundSet()
12147 {
12148 return m_LockSoundSet;
12149 }
12150
12151 //----------------------------------------------------------------
12152 //------------------------- Color
12153 // sets items color variable given color components
12154 override void SetColor(int r, int g, int b, int a)
12155 {
12160 SetVariableMask(VARIABLE_COLOR);
12161 }
12163 override void GetColor(out int r,out int g,out int b,out int a)
12164 {
12169 }
12170
12171 bool IsColorSet()
12172 {
12173 return IsVariableSet(VARIABLE_COLOR);
12174 }
12175
12177 string GetColorString()
12178 {
12179 int r,g,b,a;
12180 GetColor(r,g,b,a);
12181 r = r/255;
12182 g = g/255;
12183 b = b/255;
12184 a = a/255;
12185 return MiscGameplayFunctions.GetColorString(r, g, b, a);
12186 }
12187 //----------------------------------------------------------------
12188 //------------------------- LiquidType
12189
12190 override void SetLiquidType(int value, bool allow_client = false)
12191 {
12192 if (!IsServerCheck(allow_client))
12193 return;
12194
12195 int old = m_VarLiquidType;
12196 m_VarLiquidType = value;
12197 OnLiquidTypeChanged(old,value);
12198 SetVariableMask(VARIABLE_LIQUIDTYPE);
12199 }
12200
12201 int GetLiquidTypeInit()
12202 {
12203 return ConfigGetInt("varLiquidTypeInit");
12204 }
12205
12206 override int GetLiquidType()
12207 {
12208 return m_VarLiquidType;
12209 }
12210
12211 protected void OnLiquidTypeChanged(int oldType, int newType)
12212 {
12213 if (newType == LIQUID_NONE && GetIsFrozen())
12214 SetFrozen(false);
12215 }
12216
12218 void UpdateQuickbarShortcutVisibility(PlayerBase player)
12219 {
12220 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
12221 }
12222
12223 // -------------------------------------------------------------------------
12225 void OnInventoryEnter(Man player)
12226 {
12227 PlayerBase nplayer;
12228 if (PlayerBase.CastTo(nplayer, player))
12229 {
12230 m_CanPlayImpactSound = true;
12231 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
12232 }
12233 }
12234
12235 // -------------------------------------------------------------------------
12237 void OnInventoryExit(Man player)
12238 {
12239 PlayerBase nplayer;
12240 if (PlayerBase.CastTo(nplayer,player))
12241 {
12242 nplayer.SetEnableQuickBarEntityShortcut(this, false);
12243 }
12244
12245 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
12246
12247 if (HasEnergyManager())
12248 {
12249 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
12250 }
12251 }
12252
12253 // ADVANCED PLACEMENT EVENTS
12254 override void OnPlacementStarted(Man player)
12255 {
12256 super.OnPlacementStarted(player);
12257
12258 SetTakeable(false);
12259 }
12260
12261 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
12262 {
12263 if (m_AdminLog)
12264 {
12265 m_AdminLog.OnPlacementComplete(player, this);
12266 }
12267
12268 super.OnPlacementComplete(player, position, orientation);
12269 }
12270
12271 //-----------------------------
12272 // AGENT SYSTEM
12273 //-----------------------------
12274 //--------------------------------------------------------------------------
12275 bool ContainsAgent(int agent_id)
12276 {
12277 if (agent_id & m_AttachedAgents)
12278 {
12279 return true;
12280 }
12281 else
12282 {
12283 return false;
12284 }
12285 }
12286
12287 //--------------------------------------------------------------------------
12288 override void RemoveAgent(int agent_id)
12289 {
12290 if (ContainsAgent(agent_id))
12291 {
12292 m_AttachedAgents = ~agent_id & m_AttachedAgents;
12293 }
12294 }
12295
12296 //--------------------------------------------------------------------------
12297 override void RemoveAllAgents()
12298 {
12299 m_AttachedAgents = 0;
12300 }
12301 //--------------------------------------------------------------------------
12302 override void RemoveAllAgentsExcept(int agent_to_keep)
12303 {
12304 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
12305 }
12306 // -------------------------------------------------------------------------
12307 override void InsertAgent(int agent, float count = 1)
12308 {
12309 if (count < 1)
12310 return;
12311 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
12313 }
12314
12316 void TransferAgents(int agents)
12317 {
12319 }
12320
12321 // -------------------------------------------------------------------------
12322 override int GetAgents()
12323 {
12324 return m_AttachedAgents;
12325 }
12326 //----------------------------------------------------------------------
12327
12328 /*int GetContaminationType()
12329 {
12330 int contamination_type;
12331
12332 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
12333 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
12334 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
12335 const int DIRTY_MASK = eAgents.WOUND_AGENT;
12336
12337 Edible_Base edible = Edible_Base.Cast(this);
12338 int agents = GetAgents();
12339 if (edible)
12340 {
12341 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
12342 if (profile)
12343 {
12344 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
12345 }
12346 }
12347 if (agents & CONTAMINATED_MASK)
12348 {
12349 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
12350 }
12351 if (agents & POISONED_MASK)
12352 {
12353 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
12354 }
12355 if (agents & NERVE_GAS_MASK)
12356 {
12357 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
12358 }
12359 if (agents & DIRTY_MASK)
12360 {
12361 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
12362 }
12363
12364 return agents;
12365 }*/
12366
12367 // -------------------------------------------------------------------------
12368 bool LoadAgents(ParamsReadContext ctx, int version)
12369 {
12370 if (!ctx.Read(m_AttachedAgents))
12371 return false;
12372 return true;
12373 }
12374 // -------------------------------------------------------------------------
12376 {
12377
12379 }
12380 // -------------------------------------------------------------------------
12381
12383 override void CheckForRoofLimited(float timeTresholdMS = 3000)
12384 {
12385 super.CheckForRoofLimited(timeTresholdMS);
12386
12387 float time = g_Game.GetTime();
12388 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
12389 {
12390 m_PreviousRoofTestTime = time;
12391 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
12392 }
12393 }
12394
12395 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
12396 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
12397 {
12398 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
12399 {
12400 return 0;
12401 }
12402
12403 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
12404 {
12405 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
12406 if (filter)
12407 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
12408 else
12409 return 0;//otherwise return 0 when no filter attached
12410 }
12411
12412 string subclassPath, entryName;
12413
12414 switch (type)
12415 {
12416 case DEF_BIOLOGICAL:
12417 entryName = "biological";
12418 break;
12419 case DEF_CHEMICAL:
12420 entryName = "chemical";
12421 break;
12422 default:
12423 entryName = "biological";
12424 break;
12425 }
12426
12427 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
12428
12429 return g_Game.ConfigGetFloat(subclassPath + entryName);
12430 }
12431
12432
12433
12435 override void EEOnCECreate()
12436 {
12437 if (!IsMagazine())
12439
12441 }
12442
12443
12444 //-------------------------
12445 // OPEN/CLOSE USER ACTIONS
12446 //-------------------------
12448 void Open();
12449 void Close();
12450 bool IsOpen()
12451 {
12452 return true;
12453 }
12454
12455 override bool CanDisplayCargo()
12456 {
12457 return IsOpen();
12458 }
12459
12460
12461 // ------------------------------------------------------------
12462 // CONDITIONS
12463 // ------------------------------------------------------------
12464 override bool CanPutInCargo(EntityAI parent)
12465 {
12466 if (parent)
12467 {
12468 if (parent.IsInherited(DayZInfected))
12469 return true;
12470
12471 if (!parent.IsRuined())
12472 return true;
12473 }
12474
12475 return true;
12476 }
12477
12478 override bool CanPutAsAttachment(EntityAI parent)
12479 {
12480 if (!super.CanPutAsAttachment(parent))
12481 {
12482 return false;
12483 }
12484
12485 if (!IsRuined() && !parent.IsRuined())
12486 {
12487 return true;
12488 }
12489
12490 return false;
12491 }
12492
12493 override bool CanReceiveItemIntoCargo(EntityAI item)
12494 {
12495 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
12496 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
12497 // return false;
12498
12499 return super.CanReceiveItemIntoCargo(item);
12500 }
12501
12502 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
12503 {
12504 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
12505 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
12506 // return false;
12507
12508 GameInventory attachmentInv = attachment.GetInventory();
12509 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
12510 {
12511 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
12512 return false;
12513 }
12514
12515 InventoryLocation loc = new InventoryLocation();
12516 attachment.GetInventory().GetCurrentInventoryLocation(loc);
12517 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
12518 return false;
12519
12520 return super.CanReceiveAttachment(attachment, slotId);
12521 }
12522
12523 override bool CanReleaseAttachment(EntityAI attachment)
12524 {
12525 if (!super.CanReleaseAttachment(attachment))
12526 return false;
12527
12528 return GetInventory().AreChildrenAccessible();
12529 }
12530
12531 /*override bool CanLoadAttachment(EntityAI attachment)
12532 {
12533 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
12534 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
12535 // return false;
12536
12537 GameInventory attachmentInv = attachment.GetInventory();
12538 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
12539 {
12540 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
12541 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
12542
12543 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
12544 return false;
12545 }
12546
12547 return super.CanLoadAttachment(attachment);
12548 }*/
12549
12550 // Plays muzzle flash particle effects
12551 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
12552 {
12553 int id = muzzle_owner.GetMuzzleID();
12554 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
12555
12556 if (WPOF_array)
12557 {
12558 for (int i = 0; i < WPOF_array.Count(); i++)
12559 {
12560 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
12561
12562 if (WPOF)
12563 {
12564 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
12565 }
12566 }
12567 }
12568 }
12569
12570 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
12571 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
12572 {
12573 int id = muzzle_owner.GetMuzzleID();
12574 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
12575
12576 if (WPOBE_array)
12577 {
12578 for (int i = 0; i < WPOBE_array.Count(); i++)
12579 {
12580 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
12581
12582 if (WPOBE)
12583 {
12584 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
12585 }
12586 }
12587 }
12588 }
12589
12590 // Plays all weapon overheating particles
12591 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
12592 {
12593 int id = muzzle_owner.GetMuzzleID();
12594 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
12595
12596 if (WPOOH_array)
12597 {
12598 for (int i = 0; i < WPOOH_array.Count(); i++)
12599 {
12600 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
12601
12602 if (WPOOH)
12603 {
12604 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
12605 }
12606 }
12607 }
12608 }
12609
12610 // Updates all weapon overheating particles
12611 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
12612 {
12613 int id = muzzle_owner.GetMuzzleID();
12614 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
12615
12616 if (WPOOH_array)
12617 {
12618 for (int i = 0; i < WPOOH_array.Count(); i++)
12619 {
12620 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
12621
12622 if (WPOOH)
12623 {
12624 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
12625 }
12626 }
12627 }
12628 }
12629
12630 // Stops overheating particles
12631 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
12632 {
12633 int id = muzzle_owner.GetMuzzleID();
12634 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
12635
12636 if (WPOOH_array)
12637 {
12638 for (int i = 0; i < WPOOH_array.Count(); i++)
12639 {
12640 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
12641
12642 if (WPOOH)
12643 {
12644 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
12645 }
12646 }
12647 }
12648 }
12649
12650 //----------------------------------------------------------------
12651 //Item Behaviour - unified approach
12652 override bool IsHeavyBehaviour()
12653 {
12654 if (m_ItemBehaviour == 0)
12655 {
12656 return true;
12657 }
12658
12659 return false;
12660 }
12661
12662 override bool IsOneHandedBehaviour()
12663 {
12664 if (m_ItemBehaviour == 1)
12665 {
12666 return true;
12667 }
12668
12669 return false;
12670 }
12671
12672 override bool IsTwoHandedBehaviour()
12673 {
12674 if (m_ItemBehaviour == 2)
12675 {
12676 return true;
12677 }
12678
12679 return false;
12680 }
12681
12682 bool IsDeployable()
12683 {
12684 return false;
12685 }
12686
12688 float GetDeployTime()
12689 {
12690 return UATimeSpent.DEFAULT_DEPLOY;
12691 }
12692
12693
12694 //----------------------------------------------------------------
12695 // Item Targeting (User Actions)
12696 override void SetTakeable(bool pState)
12697 {
12698 m_IsTakeable = pState;
12699 SetSynchDirty();
12700 }
12701
12702 override bool IsTakeable()
12703 {
12704 return m_IsTakeable;
12705 }
12706
12707 // For cases where we want to show object widget which cant be taken to hands
12709 {
12710 return false;
12711 }
12712
12714 protected void PreLoadSoundAttachmentType()
12715 {
12716 string att_type = "None";
12717
12718 if (ConfigIsExisting("soundAttType"))
12719 {
12720 att_type = ConfigGetString("soundAttType");
12721 }
12722
12723 m_SoundAttType = att_type;
12724 }
12725
12726 override string GetAttachmentSoundType()
12727 {
12728 return m_SoundAttType;
12729 }
12730
12731 //----------------------------------------------------------------
12732 //SOUNDS - ItemSoundHandler
12733 //----------------------------------------------------------------
12734
12735 string GetPlaceSoundset(); // played when deploy starts
12736 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
12737 string GetDeploySoundset(); // played when deploy sucessfully finishes
12738 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
12739 string GetFoldSoundset(); // played when fold sucessfully finishes
12740
12742 {
12743 if (!m_ItemSoundHandler)
12745
12746 return m_ItemSoundHandler;
12747 }
12748
12749 // override to initialize sounds
12750 protected void InitItemSounds()
12751 {
12752 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty && !GetInventoryItemType().SetDetachSoundEvent() && !GetInventoryItemType().SetAttachSoundEvent())
12753 return;
12754
12756
12757 if (GetPlaceSoundset() != string.Empty)
12758 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
12759
12760 if (GetDeploySoundset() != string.Empty)
12761 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
12762
12763 SoundParameters params = new SoundParameters();
12764 params.m_Loop = true;
12765 if (GetLoopDeploySoundset() != string.Empty)
12766 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
12767 }
12768
12769 // Start sound using ItemSoundHandler
12770 void StartItemSoundServer(int id, int slotId)
12771 {
12772 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
12773 {
12774 m_SoundSyncSlotID = slotId;
12775 m_SoundSyncPlay = id;
12776
12777 SetSynchDirty();
12778
12779 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
12780 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStartItemSoundServer, 100);
12781 }
12782 }
12783
12784 void StartItemSoundServer(int id)
12785 {
12786 StartItemSoundServer(id, InventorySlots.INVALID);
12787 }
12788
12789 // Stop sound using ItemSoundHandler
12790 void StopItemSoundServer(int id)
12791 {
12792 if (!g_Game.IsServer())
12793 return;
12794
12795 m_SoundSyncStop = id;
12796 SetSynchDirty();
12797
12798 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
12799 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStopItemSoundServer, 100);
12800 }
12801
12802 protected void ClearStartItemSoundServer()
12803 {
12804 m_SoundSyncPlay = 0;
12805 m_SoundSyncSlotID = InventorySlots.INVALID;
12806 }
12807
12808 protected void ClearStopItemSoundServer()
12809 {
12810 m_SoundSyncStop = 0;
12811 }
12812
12813 void OnApply(PlayerBase player);
12814
12816 {
12817 return 1.0;
12818 };
12819 //returns applicable selection
12820 array<string> GetHeadHidingSelection()
12821 {
12823 }
12824
12826 {
12828 }
12829
12830 WrittenNoteData GetWrittenNoteData() {};
12831
12833 {
12834 SetDynamicPhysicsLifeTime(0.01);
12835 m_ItemBeingDroppedPhys = false;
12836 }
12837
12839 {
12840 array<string> zone_names = new array<string>;
12841 GetDamageZones(zone_names);
12842 for (int i = 0; i < zone_names.Count(); i++)
12843 {
12844 SetHealthMax(zone_names.Get(i),"Health");
12845 }
12846 SetHealthMax("","Health");
12847 }
12848
12850 void SetZoneDamageCEInit()
12851 {
12852 float global_health = GetHealth01("","Health");
12853 array<string> zones = new array<string>;
12854 GetDamageZones(zones);
12855 //set damage of all zones to match global health level
12856 for (int i = 0; i < zones.Count(); i++)
12857 {
12858 SetHealth01(zones.Get(i),"Health",global_health);
12859 }
12860 }
12861
12863 bool IsCoverFaceForShave(string slot_name)
12864 {
12865 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
12866 }
12867
12868 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
12869 {
12870 if (!hasRootAsPlayer)
12871 {
12872 if (refParentIB)
12873 {
12874 // parent is wet
12875 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
12876 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
12877 // parent has liquid inside
12878 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
12879 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
12880 // drying
12881 else if (m_VarWet > m_VarWetMin)
12882 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
12883 }
12884 else
12885 {
12886 // drying on ground or inside non-itembase (car, ...)
12887 if (m_VarWet > m_VarWetMin)
12888 AddWet(-1 * delta * GetDryingIncrement("ground"));
12889 }
12890 }
12891 }
12892
12893 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
12894 {
12896 {
12897 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
12898 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
12899 {
12900 float heatPermCoef = 1.0;
12901 EntityAI ent = this;
12902 while (ent)
12903 {
12904 heatPermCoef *= ent.GetHeatPermeabilityCoef();
12905 ent = ent.GetHierarchyParent();
12906 }
12907
12908 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
12909 }
12910 }
12911 }
12912
12913 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
12914 {
12915 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
12916 EntityAI parent = GetHierarchyParent();
12917 if (!parent)
12918 {
12919 hasParent = false;
12920 hasRootAsPlayer = false;
12921 }
12922 else
12923 {
12924 hasParent = true;
12925 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
12926 refParentIB = ItemBase.Cast(parent);
12927 }
12928 }
12929
12930 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
12931 {
12932 // this is stub, implemented on Edible_Base
12933 }
12934
12935 bool CanDecay()
12936 {
12937 // return true used on selected food clases so they can decay
12938 return false;
12939 }
12940
12941 protected bool CanProcessDecay()
12942 {
12943 // this is stub, implemented on Edible_Base class
12944 // used to determine whether it is still necessary for the food to decay
12945 return false;
12946 }
12947
12948 protected bool CanHaveWetness()
12949 {
12950 // return true used on selected items that have a wetness effect
12951 return false;
12952 }
12953
12955 bool CanBeConsumed(ConsumeConditionData data = null)
12956 {
12957 return !GetIsFrozen() && IsOpen();
12958 }
12959
12960 override void ProcessVariables()
12961 {
12962 bool hasParent = false, hasRootAsPlayer = false;
12963 ItemBase refParentIB;
12964
12965 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
12966 bool foodDecay = g_Game.IsFoodDecayEnabled();
12967
12968 if (wwtu || foodDecay)
12969 {
12970 bool processWetness = wwtu && CanHaveWetness();
12971 bool processTemperature = wwtu && CanHaveTemperature();
12972 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
12973
12974 if (processWetness || processTemperature || processDecay)
12975 {
12976 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
12977
12978 if (processWetness)
12979 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
12980
12981 if (processTemperature)
12982 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
12983
12984 if (processDecay)
12985 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
12986 }
12987 }
12988 }
12989
12992 {
12993 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
12994 }
12995
12996 override float GetTemperatureFreezeThreshold()
12997 {
12999 return Liquid.GetFreezeThreshold(GetLiquidType());
13000
13001 return super.GetTemperatureFreezeThreshold();
13002 }
13003
13004 override float GetTemperatureThawThreshold()
13005 {
13007 return Liquid.GetThawThreshold(GetLiquidType());
13008
13009 return super.GetTemperatureThawThreshold();
13010 }
13011
13012 override float GetItemOverheatThreshold()
13013 {
13015 return Liquid.GetBoilThreshold(GetLiquidType());
13016
13017 return super.GetItemOverheatThreshold();
13018 }
13019
13020 override float GetTemperatureFreezeTime()
13021 {
13022 if (HasQuantity())
13023 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
13024
13025 return super.GetTemperatureFreezeTime();
13026 }
13027
13028 override float GetTemperatureThawTime()
13029 {
13030 if (HasQuantity())
13031 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
13032
13033 return super.GetTemperatureThawTime();
13034 }
13035
13037 void AffectLiquidContainerOnFill(int liquid_type, float amount);
13039 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
13040
13041 bool IsCargoException4x3(EntityAI item)
13042 {
13043 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
13044 }
13045
13047 {
13048 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
13049 }
13050
13052 void AddLightSourceItem(ItemBase lightsource)
13053 {
13054 m_LightSourceItem = lightsource;
13055 }
13056
13058 {
13059 m_LightSourceItem = null;
13060 }
13061
13063 {
13064 return m_LightSourceItem;
13065 }
13066
13068 array<int> GetValidFinishers()
13069 {
13070 return null;
13071 }
13072
13074 bool GetActionWidgetOverride(out typename name)
13075 {
13076 return false;
13077 }
13078
13079 bool PairWithDevice(notnull ItemBase otherDevice)
13080 {
13081 if (g_Game.IsServer())
13082 {
13083 ItemBase explosive = otherDevice;
13085 if (!trg)
13086 {
13087 trg = RemoteDetonatorTrigger.Cast(otherDevice);
13088 explosive = this;
13089 }
13090
13091 explosive.PairRemote(trg);
13092 trg.SetControlledDevice(explosive);
13093
13094 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
13095 trg.SetPersistentPairID(persistentID);
13096 explosive.SetPersistentPairID(persistentID);
13097
13098 return true;
13099 }
13100 return false;
13101 }
13102
13104 float GetBaitEffectivity()
13105 {
13106 float ret = 1.0;
13107 if (HasQuantity())
13108 ret *= GetQuantityNormalized();
13109 ret *= GetHealth01();
13110
13111 return ret;
13112 }
13113
13114 #ifdef DEVELOPER
13115 override void SetDebugItem()
13116 {
13117 super.SetDebugItem();
13118 _itemBase = this;
13119 }
13120
13121 override string GetDebugText()
13122 {
13123 string text = super.GetDebugText();
13124
13125 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
13126 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
13127
13128 return text;
13129 }
13130 #endif
13131
13132 bool CanBeUsedForSuicide()
13133 {
13134 return true;
13135 }
13136
13138 //DEPRECATED BELOW
13140 // Backwards compatibility
13141 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
13142 {
13143 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
13144 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
13145 }
13146
13147 // replaced by ItemSoundHandler
13148 protected EffectSound m_SoundDeployFinish;
13149 protected EffectSound m_SoundPlace;
13150 protected EffectSound m_DeployLoopSoundEx;
13151 protected EffectSound m_SoundDeploy;
13152 bool m_IsPlaceSound;
13153 bool m_IsDeploySound;
13155
13156 string GetDeployFinishSoundset();
13157 void PlayDeploySound();
13158 void PlayDeployFinishSound();
13159 void PlayPlaceSound();
13160 void PlayDeployLoopSoundEx();
13161 void StopDeployLoopSoundEx();
13162 void SoundSynchRemoteReset();
13163 void SoundSynchRemote();
13164 bool UsesGlobalDeploy(){return false;}
13165 bool CanPlayDeployLoopSound(){return false;}
13167 bool IsPlaceSound(){return m_IsPlaceSound;}
13168 bool IsDeploySound(){return m_IsDeploySound;}
13169 void SetIsPlaceSound(bool is_place_sound);
13170 void SetIsDeploySound(bool is_deploy_sound);
13171
13172 [Obsolete("Use ItemSoundHandler instead")]
13174 void PlayAttachSound(string slot_type)
13175 {
13176 if (!g_Game.IsDedicatedServer())
13177 {
13178 if (ConfigIsExisting("attachSoundSet"))
13179 {
13180 string cfg_path = "";
13181 string soundset = "";
13182 string type_name = GetType();
13183
13184 TStringArray cfg_soundset_array = new TStringArray;
13185 TStringArray cfg_slot_array = new TStringArray;
13186 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
13187 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
13188
13189 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
13190 {
13191 for (int i = 0; i < cfg_soundset_array.Count(); i++)
13192 {
13193 if (cfg_slot_array[i] == slot_type)
13194 {
13195 soundset = cfg_soundset_array[i];
13196 break;
13197 }
13198 }
13199 }
13200
13201 if (soundset != "")
13202 {
13203 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
13204 sound.SetAutodestroy(true);
13205 }
13206 }
13207 }
13208 }
13209
13210 void PlayDetachSound(string slot_type) {}
13211}
13212
13213EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
13214{
13215 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
13216 if (entity)
13217 {
13218 bool is_item = entity.IsInherited(ItemBase);
13219 if (is_item && full_quantity)
13220 {
13221 ItemBase item = ItemBase.Cast(entity);
13222 item.SetQuantity(item.GetQuantityInit());
13223 }
13224 }
13225 else
13226 {
13227 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
13228 return NULL;
13229 }
13230 return entity;
13231}
13232
13233void SetupSpawnedItem(ItemBase item, float health, float quantity)
13234{
13235 if (item)
13236 {
13237 if (health > 0)
13238 item.SetHealth("", "", health);
13239
13240 if (item.CanHaveTemperature())
13241 {
13242 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
13243 if (item.CanFreeze())
13244 item.SetFrozen(false);
13245 }
13246
13247 if (item.HasEnergyManager())
13248 {
13249 if (quantity >= 0)
13250 {
13251 item.GetCompEM().SetEnergy0To1(quantity);
13252 }
13253 else
13254 {
13255 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
13256 }
13257 }
13258 else if (item.IsMagazine())
13259 {
13260 Magazine mag = Magazine.Cast(item);
13261 if (quantity >= 0)
13262 {
13263 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
13264 }
13265 else
13266 {
13267 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
13268 }
13269
13270 }
13271 else
13272 {
13273 if (quantity >= 0)
13274 {
13275 item.SetQuantityNormalized(quantity, false);
13276 }
13277 else
13278 {
13279 item.SetQuantity(Math.AbsFloat(quantity));
13280 }
13281
13282 }
13283 }
13284}
13285
13286#ifdef DEVELOPER
13287ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
13288#endif
Param4< int, int, string, int > TSelectableActionInfoWithColor
Param3 TSelectableActionInfo
EWetnessLevel
Определения 3_Game/DayZ/Entities/EntityAI.c:2
bool SetAttachSoundEvent()
void InventoryItemType()
bool SetDetachSoundEvent()
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:34
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
string Debug()
Определения CachedEquipmentStorageBase.c:29
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:3942
DayZGame GetDayZGame()
Определения DayZGame.c:3944
EActions
Определения EActions.c:2
ERPCs
Определения ERPCs.c:2
PluginAdminLog m_AdminLog
Определения EmoteManager.c:159
const int MIN
Определения EnConvert.c:28
const int MAX
Определения EnConvert.c:27
float GetTemperature()
Определения Environment.c:500
override bool IsExplosive()
Определения ExplosivesBase.c:59
override bool IsPrepareToDelete()
Определения FireplaceBase.c:643
override bool CanHaveTemperature()
Определения FireplaceBase.c:561
class GP5GasMask extends MaskBase ItemBase
proto GizmoApi GetGizmoApi()
Empty
Определения Hand_States.c:14
FindInventoryLocationType
flags for searching locations in inventory
Определения InventoryLocation.c:18
InventoryLocationType
types of Inventory Location
Определения InventoryLocation.c:4
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
bool DamageItemInCargo(float damage)
Определения ItemBase.c:6453
static bool HasDebugActionsMask(int mask)
Определения ItemBase.c:5680
bool HidesSelectionBySlot()
Определения ItemBase.c:9413
float m_VarWetMin
Определения ItemBase.c:4937
void SplitItem(PlayerBase player)
Определения ItemBase.c:6908
void CopyScriptPropertiesFrom(EntityAI oldItem)
Определения ItemBase.c:9634
override void InsertAgent(int agent, float count=1)
Определения ItemBase.c:8895
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:8330
static void SetDebugActionsMask(int mask)
Определения ItemBase.c:5685
void SetIsDeploySound(bool is_deploy_sound)
bool IsOpen()
Определения ItemBase.c:9038
void SplitItemToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6875
override bool IsHeavyBehaviour()
Определения ItemBase.c:9240
override void SetWetMax()
Определения ItemBase.c:8616
bool IsCoverFaceForShave(string slot_name)
DEPRECATED in use, but returns correct values nontheless. Check performed elsewhere.
Определения ItemBase.c:9451
void ClearStartItemSoundServer()
Определения ItemBase.c:9390
float m_VarWet
Определения ItemBase.c:4934
void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9481
map< typename, ref ActionOverrideData > TActionAnimOverrideMap
Определения ItemBase.c:3
override void RemoveAllAgentsExcept(int agent_to_keep)
Определения ItemBase.c:8890
static ref map< int, ref array< ref WeaponParticlesOnBulletCasingEject > > m_OnBulletCasingEjectEffect
Определения ItemBase.c:4997
bool CanBeMovedOverride()
Определения ItemBase.c:7600
override void SetWet(float value, bool allow_client=false)
Определения ItemBase.c:8592
ref TIntArray m_SingleUseActions
Определения ItemBase.c:4983
void StartItemSoundServer(int id, int slotId)
Определения ItemBase.c:9358
override void ProcessVariables()
Определения ItemBase.c:9548
ref TStringArray m_HeadHidingSelections
Определения ItemBase.c:5011
float GetWeightSpecialized(bool forceRecalc=false)
Определения ItemBase.c:8423
bool LoadAgents(ParamsReadContext ctx, int version)
Определения ItemBase.c:8956
void UpdateQuickbarShortcutVisibility(PlayerBase player)
To be called on moving item within character's inventory; 'player' should never be null.
Определения ItemBase.c:8806
void OverrideActionAnimation(typename action, int commandUID, int stanceMask=-1, int commandUIDProne=-1)
Определения ItemBase.c:5271
ref array< ref OverheatingParticle > m_OverheatingParticles
Определения ItemBase.c:5009
override float GetTemperatureFreezeThreshold()
Определения ItemBase.c:9584
bool m_IsSoundSynchRemote
Определения ItemBase.c:9742
float m_OverheatingShots
Определения ItemBase.c:5004
void StopItemSoundServer(int id)
Определения ItemBase.c:9378
static void ToggleDebugActionsMask(int mask)
Определения ItemBase.c:5700
void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:5424
override float GetTemperatureFreezeTime()
Определения ItemBase.c:9608
ref array< int > m_CompatibleLocks
Определения ItemBase.c:5021
bool CanBeCooked()
Определения ItemBase.c:7556
override void CombineItemsClient(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:5767
float m_TemperaturePerQuantityWeight
Определения ItemBase.c:5035
bool m_RecipesInitialized
Определения ItemBase.c:4919
void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
Определения ItemBase.c:6546
override float GetTemperatureThawThreshold()
Определения ItemBase.c:9592
override void OnEnergyConsumed()
Определения ItemBase.c:8536
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:8462
override EWetnessLevel GetWetLevel()
Определения ItemBase.c:8656
float GetSingleInventoryItemWeight()
Определения ItemBase.c:8418
ref TIntArray m_InteractActions
Определения ItemBase.c:4985
void MessageToOwnerStatus(string text)
Send message to owner player in grey color.
Определения ItemBase.c:7620
float m_VarQuantity
Определения ItemBase.c:4925
bool CanPlayDeployLoopSound()
Определения ItemBase.c:9753
override float GetWetMax()
Определения ItemBase.c:8626
bool CanBeUsedForSuicide()
Определения ItemBase.c:9720
override void CombineItemsEx(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:7193
void OnItemInHandsPlayerSwimStart(PlayerBase player)
void SetIsHologram(bool is_hologram)
Определения ItemBase.c:5905
void OnSyncVariables(ParamsReadContext ctx)
DEPRECATED (most likely)
Определения ItemBase.c:7774
void DoAmmoExplosion()
Определения ItemBase.c:6388
static ref map< int, ref array< ref WeaponParticlesOnFire > > m_OnFireEffect
Определения ItemBase.c:4996
void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6732
int GetItemSize()
Определения ItemBase.c:7585
bool m_CanBeMovedOverride
Определения ItemBase.c:4962
override string ChangeIntoOnAttach(string slot)
Определения ItemBase.c:6312
void UpdateOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5492
bool CanDecay()
Определения ItemBase.c:9523
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:8303
void SetQuantityMax()
Определения ItemBase.c:8308
override float GetQuantity()
Определения ItemBase.c:8398
int m_ColorComponentR
Определения ItemBase.c:4974
int m_ShotsToStartOverheating
Определения ItemBase.c:5006
override void OnWetChanged(float newVal, float oldVal)
Определения ItemBase.c:8641
void StopOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5499
static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9139
void OnOverheatingDecay()
Определения ItemBase.c:5462
float GetDryingIncrement(string pIncrementName)
Определения ItemBase.c:8574
void SoundSynchRemoteReset()
int m_Cleanness
Определения ItemBase.c:4940
bool HasMuzzle()
Returns true if this item has a muzzle (weapons, suppressors)
Определения ItemBase.c:5600
bool UsesGlobalDeploy()
Определения ItemBase.c:9752
int m_ItemBehaviour
Определения ItemBase.c:4955
override bool CanReleaseAttachment(EntityAI attachment)
Определения ItemBase.c:9111
float m_HeatIsolation
Определения ItemBase.c:4950
float m_VarWetInit
Определения ItemBase.c:4936
override void OnMovedInsideCargo(EntityAI container)
Определения ItemBase.c:5945
void SetCEBasedQuantity()
Определения ItemBase.c:5713
bool m_CanPlayImpactSound
Определения ItemBase.c:4946
override string GetAttachmentSoundType()
Определения ItemBase.c:9314
float GetOverheatingCoef()
Определения ItemBase.c:5519
array< string > GetHeadHidingSelection()
Определения ItemBase.c:9408
void PlayAttachSound(string slot_type)
Plays sound on item attach. Be advised, the config structure may slightly change in 1....
Определения ItemBase.c:9762
override bool IsStoreLoad()
Определения ItemBase.c:8668
int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7169
bool IsLightSource()
Определения ItemBase.c:5841
bool m_HasQuantityBar
Определения ItemBase.c:4968
void SetResultOfSplit(bool value)
Определения ItemBase.c:7164
void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6796
void OnAttachmentQuantityChanged(ItemBase item)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6965
void UpdateAllOverheatingParticles()
Определения ItemBase.c:5527
float GetSoakingIncrement(string pIncrementName)
Определения ItemBase.c:8583
static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9219
override float GetStoreLoadedQuantity()
Определения ItemBase.c:8678
int m_LockType
Определения ItemBase.c:5022
const int ITEM_SOUNDS_MAX
Определения ItemBase.c:5027
bool m_CanBeDigged
Определения ItemBase.c:4969
float m_ItemAttachOffset
Определения ItemBase.c:4952
float GetItemModelLength()
Определения ItemBase.c:8685
bool m_ThrowItemOnDrop
Определения ItemBase.c:4960
override bool ReadVarsFromCTX(ParamsReadContext ctx, int version=-1)
Определения ItemBase.c:7919
override void CheckForRoofLimited(float timeTresholdMS=3000)
Roof check for entity, limited by time (anti-spam solution)
Определения ItemBase.c:8971
void Close()
float GetHeatIsolation()
Определения ItemBase.c:8569
void CombineItems(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7198
void TransferModifiers(PlayerBase reciever)
appears to be deprecated, legacy code
float GetTemperaturePerQuantityWeight()
Used in heat comfort calculations only!
Определения ItemBase.c:9579
bool CanHaveWetness()
Определения ItemBase.c:9536
int m_CleannessMin
Определения ItemBase.c:4942
void TransferAgents(int agents)
transfer agents from another item
Определения ItemBase.c:8904
string IDToName(int id)
Определения ItemBase.c:7767
bool CanBeConsumed(ConsumeConditionData data=null)
Items cannot be consumed if frozen by default. Override for exceptions.
Определения ItemBase.c:9543
float GetHeatIsolationInit()
Определения ItemBase.c:8564
void PlayPlaceSound()
void SetCanBeMovedOverride(bool setting)
Определения ItemBase.c:7607
override bool HasQuantity()
Определения ItemBase.c:8393
float m_VarWetPrev
Определения ItemBase.c:4935
int m_SoundSyncStop
Определения ItemBase.c:5029
bool IsCargoException4x3(EntityAI item)
Определения ItemBase.c:9629
ref TIntArray m_ContinuousActions
Определения ItemBase.c:4984
int GetMuzzleID()
Returns global muzzle ID. If not found, then it gets automatically registered.
Определения ItemBase.c:5609
void LoadParticleConfigOnFire(int id)
Определения ItemBase.c:5294
int m_VarLiquidType
Определения ItemBase.c:4954
int m_QuickBarBonus
Определения ItemBase.c:4956
void PreLoadSoundAttachmentType()
Attachment Sound Type getting from config file.
Определения ItemBase.c:9302
override float GetWetInit()
Определения ItemBase.c:8636
int m_ImpactSoundSurfaceHash
Определения ItemBase.c:4948
int m_SoundSyncPlay
Определения ItemBase.c:5028
int m_MaxOverheatingValue
Определения ItemBase.c:5007
void SetupSpawnedItem(ItemBase item, float health, float quantity)
Определения ItemBase.c:4931
bool m_IsTakeable
Определения ItemBase.c:4959
bool ShouldSplitQuantity(float quantity)
Определения ItemBase.c:6503
static ref map< string, int > m_WeaponTypeToID
Определения ItemBase.c:4999
string GetLockSoundSet()
Определения ItemBase.c:8734
string GetColorString()
Returns item's PROCEDURAL color as formated string, i.e. "#(argb,8,8,3)color(0.15,...
Определения ItemBase.c:8765
array< int > GetValidFinishers()
returns an array of possible finishers
Определения ItemBase.c:9656
void OnAttachmentQuantityChangedEx(ItemBase item, float delta)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6971
class ItemBase extends InventoryItem SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
Определения ItemBase.c:4911
ItemSoundHandler GetItemSoundHandler()
Определения ItemBase.c:9329
override int GetQuantityMin()
Определения ItemBase.c:8382
void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
Определения ItemBase.c:6711
override int GetQuickBarBonus()
Определения ItemBase.c:5179
override void SetTakeable(bool pState)
Определения ItemBase.c:9284
float m_OverheatingDecayInterval
Определения ItemBase.c:5008
void SetIsPlaceSound(bool is_place_sound)
override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6523
void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
Определения ItemBase.c:9501
bool CanProcessDecay()
Определения ItemBase.c:9529
void RemoveAudioVisualsOnClient()
Определения Bottle_Base.c:151
void SoundSynchRemote()
static void AddDebugActionsMask(int mask)
Определения ItemBase.c:5690
void PlayDeployLoopSoundEx()
void RemoveLightSourceItem()
Определения ItemBase.c:9645
bool CanRepair(ItemBase item_repair_kit)
Определения ItemBase.c:7571
bool can_this_be_combined
Определения ItemBase.c:4964
EffectSound m_SoundDeploy
Определения ItemBase.c:9739
int m_SoundSyncSlotID
Определения ItemBase.c:5030
int m_Count
Определения ItemBase.c:4930
float GetBaitEffectivity()
generic effectivity as a bait for animal catching
Определения ItemBase.c:9692
float GetDeployTime()
how long it takes to deploy this item in seconds
Определения ItemBase.c:9276
override bool IsSplitable()
Определения ItemBase.c:6490
bool DamageItemAttachments(float damage)
Определения ItemBase.c:6473
override void WriteVarsToCTX(ParamsWriteContext ctx)
Определения ItemBase.c:7883
void ConvertEnergyToQuantity()
Определения ItemBase.c:8551
override void RemoveAllAgents()
Определения ItemBase.c:8885
override void SetQuantityToMinimum()
Определения ItemBase.c:8314
bool m_WantPlayImpactSound
Определения ItemBase.c:4945
override float GetTemperatureThawTime()
Определения ItemBase.c:9616
ref map< int, ref array< ref WeaponParticlesOnOverheating > > m_OnOverheatingEffect
Определения ItemBase.c:4998
int m_ColorComponentG
Определения ItemBase.c:4975
float m_StoreLoadedQuantity
Определения ItemBase.c:4932
void MessageToOwnerAction(string text)
Send message to owner player in yellow color.
Определения ItemBase.c:7638
int m_ColorComponentA
Определения ItemBase.c:4977
int m_VarQuantityInit
Определения ItemBase.c:4927
float GetFilterDamageRatio()
Определения ItemBase.c:5594
override void SetLiquidType(int value, bool allow_client=false)
Определения ItemBase.c:8778
void OnQuantityChanged(float delta)
Called on server side when this item's quantity is changed. Call super.OnQuantityChanged(); first whe...
Определения ItemBase.c:6942
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:8321
bool m_HideSelectionsBySlot
Определения ItemBase.c:5012
bool IsOverheatingEffectActive()
Определения ItemBase.c:5457
void SetIsBeingPlaced(bool is_being_placed)
Определения ItemBase.c:5874
int GetLiquidContainerMask()
Определения ItemBase.c:5811
void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
Определения ItemBase.c:7078
ref Timer m_CheckOverheating
Определения ItemBase.c:5005
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:5505
float GetEnergy()
Определения ItemBase.c:8525
bool CanBeDigged()
Определения ItemBase.c:5890
bool GetActionWidgetOverride(out typename name)
If we need a different (handheld)item action widget displayed, the logic goes in here.
Определения ItemBase.c:9662
bool IsNVG()
Определения ItemBase.c:5822
float GetUnitWeight(bool include_wetness=true)
Obsolete, use GetWeightEx instead.
Определения ItemBase.c:8485
void SetZoneDamageCEInit()
Sets zone damages to match randomized global health set by CE (CE spawn only)
Определения ItemBase.c:9438
bool m_IsDeploySound
Определения ItemBase.c:9741
bool CanEat()
Определения ItemBase.c:7531
static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9179
override bool IsOneHandedBehaviour()
Определения ItemBase.c:9250
void AddLightSourceItem(ItemBase lightsource)
Adds a light source child.
Определения ItemBase.c:9640
bool IsLiquidContainer()
Определения ItemBase.c:5806
FoodStage GetFoodStage()
overridden on Edible_Base; so we don't have to parse configs all the time
Определения ItemBase.c:7551
override float GetSingleInventoryItemWeightEx()
Определения ItemBase.c:8409
void SaveAgents(ParamsWriteContext ctx)
Определения ItemBase.c:8963
override int GetTargetQuantityMax(int attSlotID=-1)
Определения ItemBase.c:8363
int m_CleannessInit
Определения ItemBase.c:4941
float GetDisinfectQuantity(int system=0, Param param1=null)
Определения ItemBase.c:5589
override int GetAgents()
Определения ItemBase.c:8910
int m_VarQuantityMax
Определения ItemBase.c:4929
override bool IsHologram()
Определения ItemBase.c:5885
float GetItemAttachOffset()
Определения ItemBase.c:8694
bool IsPlaceSound()
Определения ItemBase.c:9755
static int GetDebugActionsMask()
Определения ItemBase.c:5675
override int GetLiquidType()
Определения ItemBase.c:8794
void ProcessDecay(float delta, bool hasRootAsPlayer)
Определения ItemBase.c:9518
override bool IsItemBase()
Определения ItemBase.c:7684
void PlayDeploySound()
override bool IsTwoHandedBehaviour()
Определения ItemBase.c:9260
void ExplodeAmmo()
Определения ItemBase.c:6375
bool IsCombineAll(ItemBase other_item, bool use_stack_max=false)
Определения ItemBase.c:7154
float GetProtectionLevel(int type, bool consider_filter=false, int system=0)
Определения ItemBase.c:8984
static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9159
override void OnEnergyAdded()
Определения ItemBase.c:8543
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:5834
EffectSound m_DeployLoopSoundEx
Определения ItemBase.c:9738
override void DeSerializeNumericalVars(array< float > floats)
Определения ItemBase.c:7824
void StopItemDynamicPhysics()
Определения ItemBase.c:9420
bool HasFoodStage()
Определения ItemBase.c:7544
override void SetStoreLoad(bool value)
Определения ItemBase.c:8663
float GetOverheatingValue()
Определения ItemBase.c:5419
bool ContainsAgent(int agent_id)
Определения ItemBase.c:8863
override void AddWet(float value)
Определения ItemBase.c:8611
bool IsLiquidPresent()
Определения ItemBase.c:5801
bool IsFullQuantity()
Определения ItemBase.c:8403
override void EOnContact(IEntity other, Contact extra)
Определения ItemBase.c:6084
void SplitIntoStackMaxHands(PlayerBase player)
Определения ItemBase.c:6847
void SplitIntoStackMaxHandsClient(PlayerBase player)
Определения ItemBase.c:6823
int m_CleannessMax
Определения ItemBase.c:4943
float m_VarStackMax
Определения ItemBase.c:4931
ref Timer m_PhysDropTimer
Определения ItemBase.c:5018
void MessageToOwnerFriendly(string text)
Send message to owner player in green color.
Определения ItemBase.c:7656
override void SetStoreLoadedQuantity(float value)
Определения ItemBase.c:8673
bool m_IsResultOfSplit string m_SoundAttType
distinguish if item has been created as new or it came from splitting (server only flag)
Определения ItemBase.c:4972
void CheckOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5440
void UnlockFromParent()
Unlocks this item from its attachment slot of its parent.
Определения ItemBase.c:5755
bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
Определения ItemBase.c:7578
void OnLiquidTypeChanged(int oldType, int newType)
Определения ItemBase.c:8799
void StartOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5486
void PlayDeployFinishSound()
bool AllowFoodConsumption()
Определения ItemBase.c:8721
bool m_IsOverheatingEffectActive
Определения ItemBase.c:5003
int m_LiquidContainerMask
Определения ItemBase.c:4953
void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9456
override int GetCleanness()
Определения ItemBase.c:8716
bool PairWithDevice(notnull ItemBase otherDevice)
Определения ItemBase.c:9667
bool IsDeploySound()
Определения ItemBase.c:9756
static void RemoveDebugActionsMask(int mask)
Определения ItemBase.c:5695
static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9199
int m_VarQuantityMin
Определения ItemBase.c:4928
void PerformDamageSystemReinit()
Определения ItemBase.c:9426
override void ClearInventory()
Определения ItemBase.c:8504
static int m_LastRegisteredWeaponID
Определения ItemBase.c:5000
ItemBase GetLightSourceItem()
Определения ItemBase.c:9650
void MessageToOwnerImportant(string text)
Send message to owner player in red color.
Определения ItemBase.c:7674
override float GetItemOverheatThreshold()
Определения ItemBase.c:9600
void StopDeployLoopSoundEx()
bool m_CanThisBeSplit
Определения ItemBase.c:4965
override void SerializeNumericalVars(array< float > floats_out)
Определения ItemBase.c:7788
ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
Определения ItemBase.c:6762
float m_ItemModelLength
Определения ItemBase.c:4951
bool m_IsHologram
Определения ItemBase.c:4958
static int m_DebugActionsMask
Определения ItemBase.c:4918
void KillAllOverheatingParticles()
Определения ItemBase.c:5555
bool CanBeCookedOnStick()
Определения ItemBase.c:7561
override int GetQuantityMax()
Определения ItemBase.c:8349
void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
Определения ItemBase.c:7232
void OnActivatedByTripWire()
bool IsColorSet()
Определения ItemBase.c:8759
override void RemoveAgent(int agent_id)
Определения ItemBase.c:8876
bool m_ItemBeingDroppedPhys
Определения ItemBase.c:4961
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:9066
void PlayDetachSound(string slot_type)
Определения ItemBase.c:9798
static ref map< typename, ref TInputActionMap > m_ItemTypeActionsMap
Определения ItemBase.c:4912
void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9729
override bool IsBeingPlaced()
Определения ItemBase.c:5869
int GetQuantityInit()
Определения ItemBase.c:8387
float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7174
bool IsResultOfSplit()
Определения ItemBase.c:7159
bool m_FixDamageSystemInit
Определения ItemBase.c:4963
float m_ImpactSpeed
Определения ItemBase.c:4947
bool m_IsStoreLoad
Определения ItemBase.c:4966
int GetLiquidTypeInit()
Определения ItemBase.c:8789
string GetDeployFinishSoundset()
ItemBase m_LightSourceItem
Определения ItemBase.c:4981
void LockToParent()
Locks this item in it's current attachment slot of its parent. This makes the "locked" icon visible i...
Определения ItemBase.c:5742
override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6633
int m_AttachedAgents
Определения ItemBase.c:4989
string m_LockSoundSet
Определения ItemBase.c:5024
void LoadParticleConfigOnOverheating(int id)
Определения ItemBase.c:5363
float m_VarQuantityPrev
Определения ItemBase.c:4926
bool IsSoundSynchRemote()
Определения ItemBase.c:9754
bool m_CanShowQuantity
Определения ItemBase.c:4967
override void OnRightClick()
Определения ItemBase.c:7014
int m_ColorComponentB
Определения ItemBase.c:4976
static ref map< typename, ref TActionAnimOverrideMap > m_ItemActionOverrides
Определения ItemBase.c:4914
bool IsActionTargetVisible()
Определения ItemBase.c:9296
override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения ItemBase.c:6119
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Определения ItemBase.c:6412
bool m_IsBeingPlaced
Определения ItemBase.c:4957
int NameToID(string name)
Определения ItemBase.c:7761
void ~ItemBase()
Определения ItemBase.c:5640
override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
Определения ItemBase.c:8651
void ClearStopItemSoundServer()
Определения ItemBase.c:9396
override string ChangeIntoOnDetach()
Определения ItemBase.c:6336
float m_VarWetMax
Определения ItemBase.c:4938
void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6757
int GetLockType()
Определения ItemBase.c:8729
EffectSound m_SoundDeployFinish
Определения ItemBase.c:9736
override float GetWet()
Определения ItemBase.c:8621
EffectSound m_SoundPlace
Определения ItemBase.c:9737
float GetQuantityNormalizedScripted()
Определения ItemBase.c:8335
override void SetCleanness(int value, bool allow_client=false)
Определения ItemBase.c:8703
bool m_IsPlaceSound
Определения ItemBase.c:9740
override float GetWetMin()
Определения ItemBase.c:8631
ref ItemSoundHandler m_ItemSoundHandler
Определения ItemBase.c:5032
override bool KindOf(string tag)
Определения ItemBase.c:7690
void ItemSoundHandler(ItemBase parent)
Определения ItemSoundHandler.c:31
string Type
Определения JsonDataContaminatedArea.c:11
EffectSound m_LockingSound
Определения Land_Underground_Entrance.c:336
string GetDebugText()
Определения ModifierBase.c:71
@ LOWEST
Определения PPEConstants.c:54
void PluginItemDiagnostic()
Определения PluginItemDiagnostic.c:74
PluginBase GetPlugin(typename plugin_type)
Определения PluginManager.c:325
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
int GetID()
Определения ActionBase.c:1335
void OnItemLocationChanged(ItemBase item)
Определения ActionBase.c:974
GetInputType()
Определения ActionBase.c:221
int m_StanceMask
Определения ActionBase.c:25
int m_CommandUIDProne
Определения ActionBase.c:24
int m_CommandUID
Определения ActionBase.c:23
proto native int GetItemCount()
proto native EntityAI GetItem(int index)
float GetEnergyAtSpawn()
Определения ComponentEnergyManager.c:1325
void SetEnergy0To1(float energy01)
Energy manager: Sets stored energy for this device between 0 and MAX based on relative input value be...
Определения ComponentEnergyManager.c:550
float GetEnergyMaxPristine()
Energy manager: Returns the maximum amount of energy this device can store. It's damage is NOT taken ...
Определения ComponentEnergyManager.c:1320
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/DayZ/Entities/Man.c:48
proto native EntityAI GetAttachmentFromIndex(int index)
proto native bool GetCurrentInventoryLocation(out notnull InventoryLocation loc)
returns information about current item location
proto native bool EnumerateInventory(InventoryTraversalType tt, out array< EntityAI > items)
enumerate inventory using traversal type and filling items array
proto native CargoBase GetCargo()
cargo
static proto native EntityAI LocationCreateEntity(notnull InventoryLocation inv_loc, string type, int iSetupFlags, int iRotation)
creates new item directly at location
proto native int AttachmentCount()
Returns count of attachments attached to this item.
proto native bool FindFreeLocationFor(notnull EntityAI item, FindInventoryLocationType flags, out notnull InventoryLocation loc)
FindFreeLocationFor.
proto void SelectObject(Object object)
proto void SelectPhysics(Physics physics)
Определения ItemBase.c:21
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:507
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:30
override bool CanDisplayCargo()
Определения TentBase.c:91
override void OnInventoryEnter(Man player)
Определения BarbedWire.c:203
override string GetFoldSoundset()
Определения BaseBuildingBase.c:108
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:7
override bool CanReceiveItemIntoCargo(EntityAI item)
Определения TentBase.c:934
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 string GetLoopFoldSoundset()
Определения BaseBuildingBase.c:113
override bool CanMakeGardenplot()
Определения FieldShovel.c:3
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
Определения PowerGenerator.c:397
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:409
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 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
Определения ItemBase.c:14
Определения 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 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:40
proto native float GetDamage(string zoneName, string healthType)
override void Refresh()
Определения ChatInputMenu.c:70
void SetCalcDetails(string details)
Определения 3_Game/DayZ/tools/Debug.c:916
void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения WrittenNoteData.c:13
const float LOWEST
Определения EnConvert.c:113
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
Serializer ParamsWriteContext
Определения gameplay.c:16
const int DEF_BIOLOGICAL
Определения 3_Game/DayZ/constants.c:515
const int DEF_CHEMICAL
Определения 3_Game/DayZ/constants.c:516
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:712
array< int > TIntArray
Определения EnScript.c:714
void Obsolete(string msg="")
Определения EnScript.c:371
EntityEvent
Entity events for event-mask, or throwing event from code.
Определения EnEntity.c:45
static const float ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE
Определения 3_Game/DayZ/constants.c:811
const int VARIABLE_LIQUIDTYPE
Определения 3_Game/DayZ/constants.c:635
const int VARIABLE_CLEANNESS
Определения 3_Game/DayZ/constants.c:638
const int VARIABLE_COLOR
Определения 3_Game/DayZ/constants.c:637
const int VARIABLE_TEMPERATURE
Определения 3_Game/DayZ/constants.c:633
const int VARIABLE_QUANTITY
Определения 3_Game/DayZ/constants.c:631
const int VARIABLE_WET
Определения 3_Game/DayZ/constants.c:634
const int LIQUID_NONE
Определения 3_Game/DayZ/constants.c:532
static proto float AbsFloat(float f)
Returns absolute value.
const int MENU_INVENTORY
Определения 3_Game/DayZ/constants.c:180
proto native bool dBodyIsDynamic(notnull IEntity ent)
const int SAT_CRAFTING
Определения 3_Game/DayZ/constants.c:456
const int SAT_DEBUG_ACTION
Определения 3_Game/DayZ/constants.c:457
vector GetPosition()
Get the world position of the Effect.
Определения Effect.c:473
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/DayZ/tools/tools.c:10
const int CALL_CATEGORY_SYSTEM
Определения 3_Game/DayZ/tools/tools.c:8
proto native int GetColor()

Используется в InventoryItem::CombineItems(), Edible_Base::Consume(), InventoryItem::OnAction(), ItemBase::OnIgnitedTarget(), ItemBase::OnIgnitedTargetFailed(), ItemBase::RemovePlanks(), InventoryItem::SplitIntoStackMax(), InventoryItem::SplitIntoStackMaxCargo(), InventoryItem::SplitIntoStackMaxEx(), InventoryItem::SplitIntoStackMaxHands(), InventoryItem::SplitIntoStackMaxToInventoryLocationEx(), InventoryItem::SplitItem() и InventoryItem::SplitItemToInventoryLocation().