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

◆ ~ItemBase()

void SpawnItemOnLocation::~ItemBase ( )
private

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

5645{
5646 override bool CanPutAsAttachment(EntityAI parent)
5647 {
5648 return true;
5649 }
5650};
5651
5653{
5654
5655};
5656
5657//const bool QUANTITY_DEBUG_REMOVE_ME = false;
5658
5659class ItemBase extends InventoryItem
5660{
5664
5666
5667 static int m_DebugActionsMask;
5669 // ============================================
5670 // Variable Manipulation System
5671 // ============================================
5672 // Quantity
5673
5674 float m_VarQuantity;
5675 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
5677 int m_VarQuantityMin;
5678 int m_VarQuantityMax;
5679 int m_Count;
5680 float m_VarStackMax;
5681 float m_StoreLoadedQuantity = float.LOWEST;
5682 // Wet
5683 float m_VarWet;
5684 float m_VarWetPrev;//for client to know wetness changed during synchronization
5685 float m_VarWetInit;
5686 float m_VarWetMin;
5687 float m_VarWetMax;
5688 // Cleanness
5689 int m_Cleanness;
5690 int m_CleannessInit;
5691 int m_CleannessMin;
5692 int m_CleannessMax;
5693 // impact sounds
5695 bool m_CanPlayImpactSound = true;
5696 float m_ImpactSpeed;
5698 //
5699 float m_HeatIsolation;
5700 float m_ItemModelLength;
5701 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
5703 int m_VarLiquidType;
5704 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
5705 int m_QuickBarBonus;
5706 bool m_IsBeingPlaced;
5707 bool m_IsHologram;
5708 bool m_IsTakeable;
5709 bool m_ThrowItemOnDrop;
5712 bool m_FixDamageSystemInit = false; //can be changed on storage version check
5713 bool can_this_be_combined; //Check if item can be combined
5714 bool m_CanThisBeSplit; //Check if item can be split
5715 bool m_IsStoreLoad = false;
5716 bool m_CanShowQuantity;
5717 bool m_HasQuantityBar;
5718 protected bool m_CanBeDigged;
5719 protected bool m_IsResultOfSplit
5720
5721 string m_SoundAttType;
5722 // items color variables
5727 //-------------------------------------------------------
5728
5729 // light source managing
5731
5735
5736 //==============================================
5737 // agent system
5738 private int m_AttachedAgents;
5739
5741 void TransferModifiers(PlayerBase reciever);
5742
5743
5744 // Weapons & suppressors particle effects
5748 ref static map<string, int> m_WeaponTypeToID;
5749 static int m_LastRegisteredWeaponID = 0;
5750
5751 // Overheating effects
5753 float m_OverheatingShots;
5754 ref Timer m_CheckOverheating;
5755 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
5756 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
5757 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
5758 ref array <ref OverheatingParticle> m_OverheatingParticles;
5759
5761 protected bool m_HideSelectionsBySlot;
5762
5763 // Admin Log
5764 PluginAdminLog m_AdminLog;
5765
5766 // misc
5767 ref Timer m_PhysDropTimer;
5768
5769 // Attachment Locking variables
5770 ref array<int> m_CompatibleLocks;
5771 protected int m_LockType;
5772 protected ref EffectSound m_LockingSound;
5773 protected string m_LockSoundSet;
5774
5775 // ItemSoundHandler variables
5776 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
5777 protected int m_SoundSyncPlay; // id for sound to play
5778 protected int m_SoundSyncStop; // id for sound to stop
5779 protected int m_SoundSyncSlotID = InventorySlots.INVALID; // slot id for attach/detach sound based on slot
5780
5782
5783 //temperature
5784 private float m_TemperaturePerQuantityWeight;
5785
5786 // -------------------------------------------------------------------------
5787 void ItemBase()
5788 {
5789 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
5793
5794 if (!g_Game.IsDedicatedServer())
5795 {
5796 if (HasMuzzle())
5797 {
5799
5801 {
5803 }
5804 }
5805
5807 m_ActionsInitialize = false;
5808 }
5809
5810 m_OldLocation = null;
5811
5812 if (g_Game.IsServer())
5813 {
5814 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
5815 }
5816
5817 if (ConfigIsExisting("headSelectionsToHide"))
5818 {
5820 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
5821 }
5822
5823 m_HideSelectionsBySlot = false;
5824 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
5825 {
5826 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
5827 }
5828
5829 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
5830
5831 m_IsResultOfSplit = false;
5832
5834 }
5835
5836 override void InitItemVariables()
5837 {
5838 super.InitItemVariables();
5839
5840 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
5841 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
5842 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
5843 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
5844 m_VarStackMax = ConfigGetFloat("varStackMax");
5845 m_Count = ConfigGetInt("count");
5846
5847 m_CanShowQuantity = ConfigGetBool("quantityShow");
5848 m_HasQuantityBar = ConfigGetBool("quantityBar");
5849
5850 m_CleannessInit = ConfigGetInt("varCleannessInit");
5852 m_CleannessMin = ConfigGetInt("varCleannessMin");
5853 m_CleannessMax = ConfigGetInt("varCleannessMax");
5854
5855 m_WantPlayImpactSound = false;
5856 m_ImpactSpeed = 0.0;
5857
5858 m_VarWetInit = ConfigGetFloat("varWetInit");
5860 m_VarWetMin = ConfigGetFloat("varWetMin");
5861 m_VarWetMax = ConfigGetFloat("varWetMax");
5862
5863 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
5864 if (IsLiquidContainer() && GetQuantity() != 0)
5866 m_IsBeingPlaced = false;
5867 m_IsHologram = false;
5868 m_IsTakeable = true;
5869 m_CanBeMovedOverride = false;
5873 m_CanBeDigged = ConfigGetBool("canBeDigged");
5874
5875 m_CompatibleLocks = new array<int>();
5876 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
5877 m_LockType = ConfigGetInt("lockType");
5878
5879 //Define if item can be split and set ability to be combined accordingly
5880 m_CanThisBeSplit = false;
5881 can_this_be_combined = false;
5882 if (ConfigIsExisting("canBeSplit"))
5883 {
5884 can_this_be_combined = ConfigGetBool("canBeSplit");
5886 }
5887
5888 m_ItemBehaviour = -1;
5889 if (ConfigIsExisting("itemBehaviour"))
5890 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
5891
5892 //RegisterNetSyncVariableInt("m_VariablesMask");
5893 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
5894 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
5895 RegisterNetSyncVariableInt("m_VarLiquidType");
5896 RegisterNetSyncVariableInt("m_Cleanness",0,1);
5897
5898 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
5899 RegisterNetSyncVariableFloat("m_ImpactSpeed");
5900 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
5901
5902 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
5903 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
5904 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
5905 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
5906
5907 RegisterNetSyncVariableBool("m_IsBeingPlaced");
5908 RegisterNetSyncVariableBool("m_IsTakeable");
5909 RegisterNetSyncVariableBool("m_IsHologram");
5910
5913 {
5914 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
5915 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
5916 RegisterNetSyncVariableInt("m_SoundSyncSlotID", int.MIN, int.MAX);
5917 }
5918
5919 m_LockSoundSet = ConfigGetString("lockSoundSet");
5920
5922 if (ConfigIsExisting("temperaturePerQuantityWeight"))
5923 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
5924
5925 m_SoundSyncSlotID = -1;
5926 }
5927
5928 override int GetQuickBarBonus()
5929 {
5930 return m_QuickBarBonus;
5931 }
5932
5933 void InitializeActions()
5934 {
5936 if (!m_InputActionMap)
5937 {
5939 m_InputActionMap = iam;
5940 SetActions();
5942 }
5943 }
5944
5945 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
5946 {
5948 {
5949 m_ActionsInitialize = true;
5951 }
5952
5953 actions = m_InputActionMap.Get(action_input_type);
5954 }
5955
5956 void SetActions()
5957 {
5958 AddAction(ActionTakeItem);
5959 AddAction(ActionTakeItemToHands);
5960 AddAction(ActionWorldCraft);
5962 AddAction(ActionAttachWithSwitch);
5963 }
5964
5965 void SetActionAnimOverrides(); // Override action animation for specific item
5966
5967 void AddAction(typename actionName)
5968 {
5969 ActionBase action = ActionManagerBase.GetAction(actionName);
5970
5971 if (!action)
5972 {
5973 Debug.LogError("Action " + actionName + " dosn't exist!");
5974 return;
5975 }
5976
5977 typename ai = action.GetInputType();
5978 if (!ai)
5979 {
5980 m_ActionsInitialize = false;
5981 return;
5982 }
5983
5984 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
5985 if (!action_array)
5986 {
5987 action_array = new array<ActionBase_Basic>;
5988 m_InputActionMap.Insert(ai, action_array);
5989 }
5990 if (LogManager.IsActionLogEnable())
5991 {
5992 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
5993 }
5994
5995 if (action_array.Find(action) != -1)
5996 {
5997 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
5998 }
5999 else
6000 {
6001 action_array.Insert(action);
6002 }
6003 }
6004
6005 void RemoveAction(typename actionName)
6006 {
6007 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
6008 ActionBase action = player.GetActionManager().GetAction(actionName);
6009 typename ai = action.GetInputType();
6010 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
6011
6012 if (action_array)
6013 {
6014 action_array.RemoveItem(action);
6015 }
6016 }
6017
6018 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
6019 // Set -1 for params which should stay in default state
6020 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
6021 {
6022 ActionOverrideData overrideData = new ActionOverrideData();
6023 overrideData.m_CommandUID = commandUID;
6024 overrideData.m_CommandUIDProne = commandUIDProne;
6025 overrideData.m_StanceMask = stanceMask;
6026
6027 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
6028 if (!actionMap) // create new map of action > overidables map
6029 {
6030 actionMap = new TActionAnimOverrideMap();
6031 m_ItemActionOverrides.Insert(action, actionMap);
6032 }
6033
6034 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
6035
6036 }
6037
6038 void OnItemInHandsPlayerSwimStart(PlayerBase player);
6039
6040 ScriptedLightBase GetLight();
6041
6042 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6043 void LoadParticleConfigOnFire(int id)
6044 {
6045 if (!m_OnFireEffect)
6047
6050
6051 string config_to_search = "CfgVehicles";
6052 string muzzle_owner_config;
6053
6054 if (!m_OnFireEffect.Contains(id))
6055 {
6056 if (IsInherited(Weapon))
6057 config_to_search = "CfgWeapons";
6058
6059 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6060
6061 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
6062
6063 int config_OnFire_subclass_count = g_Game.ConfigGetChildrenCount(config_OnFire_class);
6064
6065 if (config_OnFire_subclass_count > 0)
6066 {
6067 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
6068
6069 for (int i = 0; i < config_OnFire_subclass_count; i++)
6070 {
6071 string particle_class = "";
6072 g_Game.ConfigGetChildName(config_OnFire_class, i, particle_class);
6073 string config_OnFire_entry = config_OnFire_class + particle_class;
6074 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
6075 WPOF_array.Insert(WPOF);
6076 }
6077
6078
6079 m_OnFireEffect.Insert(id, WPOF_array);
6080 }
6081 }
6082
6083 if (!m_OnBulletCasingEjectEffect.Contains(id))
6084 {
6085 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
6086 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6087
6088 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
6089
6090 int config_OnBulletCasingEject_count = g_Game.ConfigGetChildrenCount(config_OnBulletCasingEject_class);
6091
6092 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
6093 {
6094 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
6095
6096 for (i = 0; i < config_OnBulletCasingEject_count; i++)
6097 {
6098 string particle_class2 = "";
6099 g_Game.ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
6100 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
6101 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
6102 WPOBE_array.Insert(WPOBE);
6103 }
6104
6105
6106 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
6107 }
6108 }
6109 }
6110
6111 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6113 {
6116
6117 if (!m_OnOverheatingEffect.Contains(id))
6118 {
6119 string config_to_search = "CfgVehicles";
6120
6121 if (IsInherited(Weapon))
6122 config_to_search = "CfgWeapons";
6123
6124 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
6125 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
6126
6127 if (g_Game.ConfigIsExisting(config_OnOverheating_class))
6128 {
6129
6130 m_ShotsToStartOverheating = g_Game.ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
6131
6133 {
6134 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
6135 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
6136 Error(error);
6137 return;
6138 }
6139
6140 m_OverheatingDecayInterval = g_Game.ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
6141 m_MaxOverheatingValue = g_Game.ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
6142
6143
6144
6145 int config_OnOverheating_subclass_count = g_Game.ConfigGetChildrenCount(config_OnOverheating_class);
6146 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
6147
6148 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
6149 {
6150 string particle_class = "";
6151 g_Game.ConfigGetChildName(config_OnOverheating_class, i, particle_class);
6152 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
6153 int entry_type = g_Game.ConfigGetType(config_OnOverheating_entry);
6154
6155 if (entry_type == CT_CLASS)
6156 {
6157 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
6158 WPOOH_array.Insert(WPOF);
6159 }
6160 }
6161
6162
6163 m_OnOverheatingEffect.Insert(id, WPOOH_array);
6164 }
6165 }
6166 }
6167
6168 float GetOverheatingValue()
6169 {
6170 return m_OverheatingShots;
6171 }
6172
6173 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
6174 {
6175 if (m_MaxOverheatingValue > 0)
6176 {
6178
6179 if (!m_CheckOverheating)
6181
6183 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6184
6185 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6186 }
6187 }
6188
6189 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6190 {
6192 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6193
6195 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6196
6198 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6199
6201 {
6203 }
6204 }
6205
6207 {
6209 }
6210
6211 void OnOverheatingDecay()
6212 {
6213 if (m_MaxOverheatingValue > 0)
6214 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
6215 else
6217
6218 if (m_OverheatingShots <= 0)
6219 {
6222 }
6223 else
6224 {
6225 if (!m_CheckOverheating)
6227
6229 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6230 }
6231
6232 CheckOverheating(this, "", this);
6233 }
6234
6235 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6236 {
6238 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6239 }
6240
6241 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6242 {
6244 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6246 }
6247
6248 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6249 {
6251 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6252 }
6253
6254 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
6255 {
6257 m_OverheatingParticles = new array<ref OverheatingParticle>;
6258
6259 OverheatingParticle OP = new OverheatingParticle();
6260 OP.RegisterParticle(p);
6261 OP.SetOverheatingLimitMin(min_heat_coef);
6262 OP.SetOverheatingLimitMax(max_heat_coef);
6263 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
6264
6265 m_OverheatingParticles.Insert(OP);
6266 }
6267
6268 float GetOverheatingCoef()
6269 {
6270 if (m_MaxOverheatingValue > 0)
6272
6273 return -1;
6274 }
6275
6277 {
6279 {
6280 float overheat_coef = GetOverheatingCoef();
6281 int count = m_OverheatingParticles.Count();
6282
6283 for (int i = count; i > 0; --i)
6284 {
6285 int id = i - 1;
6286 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6287 Particle p = OP.GetParticle();
6288
6289 float overheat_min = OP.GetOverheatingLimitMin();
6290 float overheat_max = OP.GetOverheatingLimitMax();
6291
6292 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
6293 {
6294 if (p)
6295 {
6296 p.Stop();
6297 OP.RegisterParticle(null);
6298 }
6299 }
6300 }
6301 }
6302 }
6303
6305 {
6307 {
6308 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
6309 {
6310 int id = i - 1;
6311 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6312
6313 if (OP)
6314 {
6315 Particle p = OP.GetParticle();
6316
6317 if (p)
6318 {
6319 p.Stop();
6320 }
6321
6322 delete OP;
6323 }
6324 }
6325
6326 m_OverheatingParticles.Clear();
6328 }
6329 }
6330
6332 float GetInfectionChance(int system = 0, Param param = null)
6333 {
6334 return 0.0;
6335 }
6336
6337
6338 float GetDisinfectQuantity(int system = 0, Param param1 = null)
6339 {
6340 return 250;//default value
6341 }
6342
6343 float GetFilterDamageRatio()
6344 {
6345 return 0;
6346 }
6347
6349 bool HasMuzzle()
6350 {
6351 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
6352 return true;
6353
6354 return false;
6355 }
6356
6358 int GetMuzzleID()
6359 {
6360 if (!m_WeaponTypeToID)
6361 m_WeaponTypeToID = new map<string, int>;
6362
6363 if (m_WeaponTypeToID.Contains(GetType()))
6364 {
6365 return m_WeaponTypeToID.Get(GetType());
6366 }
6367 else
6368 {
6369 // Register new weapon ID
6371 }
6372
6374 }
6375
6382 {
6383 return -1;
6384 }
6385
6386
6387
6388 // -------------------------------------------------------------------------
6389 void ~ItemBase()
6390 {
6391 if (g_Game && g_Game.GetPlayer() && (!g_Game.IsDedicatedServer()))
6392 {
6393 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
6394 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
6395
6396 if (r_index >= 0)
6397 {
6398 InventoryLocation r_il = new InventoryLocation;
6399 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
6400
6401 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
6402 int r_type = r_il.GetType();
6403 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
6404 {
6405 r_il.GetParent().GetOnReleaseLock().Invoke(this);
6406 }
6407 else if (r_type == InventoryLocationType.ATTACHMENT)
6408 {
6409 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
6410 }
6411
6412 }
6413
6414 player.GetHumanInventory().ClearUserReservedLocation(this);
6415 }
6416
6417 if (m_LockingSound)
6418 SEffectManager.DestroyEffect(m_LockingSound);
6419 }
6420
6421
6422
6423 // -------------------------------------------------------------------------
6424 static int GetDebugActionsMask()
6425 {
6426 return ItemBase.m_DebugActionsMask;
6427 }
6428
6429 static bool HasDebugActionsMask(int mask)
6430 {
6431 return ItemBase.m_DebugActionsMask & mask;
6432 }
6433
6434 static void SetDebugActionsMask(int mask)
6435 {
6436 ItemBase.m_DebugActionsMask = mask;
6437 }
6438
6439 static void AddDebugActionsMask(int mask)
6440 {
6441 ItemBase.m_DebugActionsMask |= mask;
6442 }
6443
6444 static void RemoveDebugActionsMask(int mask)
6445 {
6446 ItemBase.m_DebugActionsMask &= ~mask;
6447 }
6448
6449 static void ToggleDebugActionsMask(int mask)
6450 {
6451 if (HasDebugActionsMask(mask))
6452 {
6454 }
6455 else
6456 {
6457 AddDebugActionsMask(mask);
6458 }
6459 }
6460
6461 // -------------------------------------------------------------------------
6462 void SetCEBasedQuantity()
6463 {
6464 if (GetEconomyProfile())
6465 {
6466 float q_max = GetEconomyProfile().GetQuantityMax();
6467 if (q_max > 0)
6468 {
6469 float q_min = GetEconomyProfile().GetQuantityMin();
6470 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
6471
6472 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
6473 {
6474 ComponentEnergyManager comp = GetCompEM();
6475 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
6476 {
6477 comp.SetEnergy0To1(quantity_randomized);
6478 }
6479 }
6480 else if (HasQuantity())
6481 {
6482 SetQuantityNormalized(quantity_randomized, false);
6483 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
6484 }
6485
6486 }
6487 }
6488 }
6489
6491 void LockToParent()
6492 {
6493 EntityAI parent = GetHierarchyParent();
6494
6495 if (parent)
6496 {
6497 InventoryLocation inventory_location_to_lock = new InventoryLocation;
6498 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
6499 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
6500 }
6501 }
6502
6504 void UnlockFromParent()
6505 {
6506 EntityAI parent = GetHierarchyParent();
6507
6508 if (parent)
6509 {
6510 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
6511 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
6512 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
6513 }
6514 }
6515
6516 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
6517 {
6518 /*
6519 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
6520 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, g_Game.GetPlayer());
6521 */
6522 ItemBase item2 = ItemBase.Cast(entity2);
6523
6524 if (g_Game.IsClient())
6525 {
6526 if (ScriptInputUserData.CanStoreInputUserData())
6527 {
6528 ScriptInputUserData ctx = new ScriptInputUserData;
6530 ctx.Write(-1);
6531 ItemBase i1 = this; // @NOTE: workaround for correct serialization
6532 ctx.Write(i1);
6533 ctx.Write(item2);
6534 ctx.Write(use_stack_max);
6535 ctx.Write(-1);
6536 ctx.Send();
6537
6538 if (IsCombineAll(item2, use_stack_max))
6539 {
6540 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
6541 }
6542 }
6543 }
6544 else if (!g_Game.IsMultiplayer())
6545 {
6546 CombineItems(item2, use_stack_max);
6547 }
6548 }
6549
6550 bool IsLiquidPresent()
6551 {
6552 return (GetLiquidType() != 0 && HasQuantity());
6553 }
6554
6555 bool IsLiquidContainer()
6556 {
6557 return m_LiquidContainerMask != 0;
6558 }
6559
6561 {
6562 return m_LiquidContainerMask;
6563 }
6564
6565 bool IsBloodContainer()
6566 {
6567 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
6568 return false;
6569 }
6570
6571 bool IsNVG()
6572 {
6573 return false;
6574 }
6575
6578 bool IsExplosive()
6579 {
6580 return false;
6581 }
6582
6584 {
6585 return "";
6586 }
6587
6589
6590 bool IsLightSource()
6591 {
6592 return false;
6593 }
6594
6596 {
6597 return true;
6598 }
6599
6600 //--- ACTION CONDITIONS
6601 //direction
6602 bool IsFacingPlayer(PlayerBase player, string selection)
6603 {
6604 return true;
6605 }
6606
6607 bool IsPlayerInside(PlayerBase player, string selection)
6608 {
6609 return true;
6610 }
6611
6612 override bool CanObstruct()
6613 {
6614 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
6615 return !player || !IsPlayerInside(player, "");
6616 }
6617
6618 override bool IsBeingPlaced()
6619 {
6620 return m_IsBeingPlaced;
6621 }
6622
6623 void SetIsBeingPlaced(bool is_being_placed)
6624 {
6625 m_IsBeingPlaced = is_being_placed;
6626 if (!is_being_placed)
6628 SetSynchDirty();
6629 }
6630
6631 //server-side
6632 void OnEndPlacement() {}
6633
6634 override bool IsHologram()
6635 {
6636 return m_IsHologram;
6637 }
6638
6639 bool CanBeDigged()
6640 {
6641 return m_CanBeDigged;
6642 }
6643
6645 {
6646 return 1;
6647 }
6648
6649 bool CanMakeGardenplot()
6650 {
6651 return false;
6652 }
6653
6654 void SetIsHologram(bool is_hologram)
6655 {
6656 m_IsHologram = is_hologram;
6657 SetSynchDirty();
6658 }
6659 /*
6660 protected float GetNutritionalEnergy()
6661 {
6662 Edible_Base edible = Edible_Base.Cast(this);
6663 return edible.GetFoodEnergy();
6664 }
6665
6666 protected float GetNutritionalWaterContent()
6667 {
6668 Edible_Base edible = Edible_Base.Cast(this);
6669 return edible.GetFoodWater();
6670 }
6671
6672 protected float GetNutritionalIndex()
6673 {
6674 Edible_Base edible = Edible_Base.Cast(this);
6675 return edible.GetFoodNutritionalIndex();
6676 }
6677
6678 protected float GetNutritionalFullnessIndex()
6679 {
6680 Edible_Base edible = Edible_Base.Cast(this);
6681 return edible.GetFoodTotalVolume();
6682 }
6683
6684 protected float GetNutritionalToxicity()
6685 {
6686 Edible_Base edible = Edible_Base.Cast(this);
6687 return edible.GetFoodToxicity();
6688
6689 }
6690 */
6691
6692
6693 // -------------------------------------------------------------------------
6694 override void OnMovedInsideCargo(EntityAI container)
6695 {
6696 super.OnMovedInsideCargo(container);
6697
6698 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
6699 }
6700
6701 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
6702 {
6703 super.EEItemLocationChanged(oldLoc, newLoc);
6704
6705 PlayerBase newPlayer = null;
6706 PlayerBase oldPlayer = null;
6707
6708 if (newLoc.GetParent())
6709 newPlayer = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
6710
6711 if (oldLoc.GetParent())
6712 oldPlayer = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
6713
6714 if (oldPlayer && oldLoc.GetType() == InventoryLocationType.HANDS)
6715 {
6716 int rIndex = oldPlayer.GetHumanInventory().FindUserReservedLocationIndex(this);
6717
6718 if (rIndex >= 0)
6719 {
6720 InventoryLocation rIl = new InventoryLocation;
6721 oldPlayer.GetHumanInventory().GetUserReservedLocation(rIndex, rIl);
6722
6723 oldPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(rIndex);
6724 int rType = rIl.GetType();
6725 if (rType == InventoryLocationType.CARGO || rType == InventoryLocationType.PROXYCARGO)
6726 {
6727 rIl.GetParent().GetOnReleaseLock().Invoke(this);
6728 }
6729 else if (rType == InventoryLocationType.ATTACHMENT)
6730 {
6731 rIl.GetParent().GetOnAttachmentReleaseLock().Invoke(this, rIl.GetSlot());
6732 }
6733
6734 }
6735 }
6736
6737 if (newLoc.GetType() == InventoryLocationType.HANDS && oldLoc.GetType() != InventoryLocationType.TEMP)
6738 {
6739 if (newPlayer)
6740 newPlayer.ForceStandUpForHeavyItems(newLoc.GetItem());
6741
6742 if (newPlayer == oldPlayer)
6743 {
6744 if (oldLoc.GetParent() && newPlayer.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
6745 {
6746 if (oldLoc.GetType() == InventoryLocationType.CARGO)
6747 {
6748 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
6749 {
6750 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
6751 }
6752 }
6753 else
6754 {
6755 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
6756 }
6757 }
6758
6759 if (newPlayer.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
6760 {
6761 int type = oldLoc.GetType();
6762 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
6763 {
6764 oldLoc.GetParent().GetOnSetLock().Invoke(this);
6765 }
6766 else if (type == InventoryLocationType.ATTACHMENT)
6767 {
6768 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
6769 }
6770 }
6771 if (!m_OldLocation)
6772 {
6773 m_OldLocation = new InventoryLocation;
6774 }
6775 m_OldLocation.Copy(oldLoc);
6776 }
6777 else
6778 {
6779 if (m_OldLocation)
6780 {
6781 m_OldLocation.Reset();
6782 }
6783 }
6784
6785 g_Game.GetAnalyticsClient().OnItemAttachedAtPlayer(this,"Hands");
6786 }
6787 else
6788 {
6789 if (newPlayer)
6790 {
6791 int resIndex = newPlayer.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
6792 if (resIndex >= 0)
6793 {
6794 InventoryLocation il = new InventoryLocation;
6795 newPlayer.GetHumanInventory().GetUserReservedLocation(resIndex, il);
6796 ItemBase it = ItemBase.Cast(il.GetItem());
6797 newPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(resIndex);
6798 int rel_type = il.GetType();
6799 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
6800 {
6801 il.GetParent().GetOnReleaseLock().Invoke(it);
6802 }
6803 else if (rel_type == InventoryLocationType.ATTACHMENT)
6804 {
6805 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
6806 }
6807 //it.GetOnReleaseLock().Invoke(it);
6808 }
6809 }
6810 else if (oldPlayer && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
6811 {
6812 //ThrowPhysically(oldPlayer, vector.Zero);
6813 m_ThrowItemOnDrop = false;
6814 }
6815
6816 if (m_OldLocation)
6817 {
6818 m_OldLocation.Reset();
6819 }
6820 }
6821
6822 if (oldLoc.GetType() == InventoryLocationType.TEMP)
6823 {
6824 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Remove(oldLoc.GetItem());
6825 }
6826
6827 if (newLoc.GetType() == InventoryLocationType.TEMP)
6828 {
6829 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Add(oldLoc.GetItem());
6830 }
6831 }
6832
6833 override void EOnContact(IEntity other, Contact extra)
6834 {
6836 {
6837 int liquidType = -1;
6838 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
6839 if (impactSpeed > 0.0)
6840 {
6841 m_ImpactSpeed = impactSpeed;
6842 #ifndef SERVER
6843 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
6844 #else
6845 m_WantPlayImpactSound = true;
6846 SetSynchDirty();
6847 #endif
6848 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
6849 }
6850 }
6851
6852 #ifdef SERVER
6853 if (GetCompEM() && GetCompEM().IsPlugged())
6854 {
6855 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
6856 GetCompEM().UnplugThis();
6857 }
6858 #endif
6859 }
6860
6861 void RefreshPhysics();
6862
6863 override void OnCreatePhysics()
6864 {
6866 }
6867
6868 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
6869 {
6870
6871 }
6872 // -------------------------------------------------------------------------
6873 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
6874 {
6875 super.OnItemLocationChanged(old_owner, new_owner);
6876
6877 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
6878 PlayerBase playerNew = PlayerBase.Cast(new_owner);
6879
6880 if (!relatedPlayer && playerNew)
6881 relatedPlayer = playerNew;
6882
6883 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
6884 {
6885 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
6886 if (actionMgr)
6887 {
6888 ActionBase currentAction = actionMgr.GetRunningAction();
6889 if (currentAction)
6890 currentAction.OnItemLocationChanged(this);
6891 }
6892 }
6893
6894 Man ownerPlayerOld = null;
6895 Man ownerPlayerNew = null;
6896
6897 if (old_owner)
6898 {
6899 if (old_owner.IsMan())
6900 {
6901 ownerPlayerOld = Man.Cast(old_owner);
6902 }
6903 else
6904 {
6905 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
6906 }
6907 }
6908 else
6909 {
6910 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
6911 {
6912 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
6913
6914 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
6915 {
6916 GetCompEM().UnplugThis();
6917 }
6918 }
6919 }
6920
6921 if (new_owner)
6922 {
6923 if (new_owner.IsMan())
6924 {
6925 ownerPlayerNew = Man.Cast(new_owner);
6926 }
6927 else
6928 {
6929 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
6930 }
6931 }
6932
6933 if (ownerPlayerOld != ownerPlayerNew)
6934 {
6935 if (ownerPlayerOld)
6936 {
6937 array<EntityAI> subItemsExit = new array<EntityAI>;
6938 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
6939 for (int i = 0; i < subItemsExit.Count(); i++)
6940 {
6941 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
6942 itemExit.OnInventoryExit(ownerPlayerOld);
6943 }
6944 }
6945
6946 if (ownerPlayerNew)
6947 {
6948 array<EntityAI> subItemsEnter = new array<EntityAI>;
6949 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
6950 for (int j = 0; j < subItemsEnter.Count(); j++)
6951 {
6952 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
6953 itemEnter.OnInventoryEnter(ownerPlayerNew);
6954 }
6955 }
6956 }
6957 else if (ownerPlayerNew != null)
6958 {
6959 PlayerBase nplayer;
6960 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
6961 {
6962 array<EntityAI> subItemsUpdate = new array<EntityAI>;
6963 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
6964 for (int k = 0; k < subItemsUpdate.Count(); k++)
6965 {
6966 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
6967 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
6968 }
6969 }
6970 }
6971
6972 if (old_owner)
6973 old_owner.OnChildItemRemoved(this);
6974 if (new_owner)
6975 new_owner.OnChildItemReceived(this);
6976 }
6977
6978 // -------------------------------------------------------------------------------
6979 override void EEDelete(EntityAI parent)
6980 {
6981 super.EEDelete(parent);
6982 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
6983 if (player)
6984 {
6985 OnInventoryExit(player);
6986
6987 if (player.IsAlive())
6988 {
6989 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
6990 if (r_index >= 0)
6991 {
6992 InventoryLocation r_il = new InventoryLocation;
6993 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
6994
6995 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
6996 int r_type = r_il.GetType();
6997 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
6998 {
6999 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7000 }
7001 else if (r_type == InventoryLocationType.ATTACHMENT)
7002 {
7003 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7004 }
7005
7006 }
7007
7008 player.RemoveQuickBarEntityShortcut(this);
7009 }
7010 }
7011 }
7012 // -------------------------------------------------------------------------------
7013 override void EEKilled(Object killer)
7014 {
7015 super.EEKilled(killer);
7016
7018 if (killer && killer.IsFireplace() && CanExplodeInFire())
7019 {
7020 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
7021 {
7022 if (IsMagazine())
7023 {
7024 if (Magazine.Cast(this).GetAmmoCount() > 0)
7025 {
7026 ExplodeAmmo();
7027 }
7028 }
7029 else
7030 {
7031 Explode(DamageType.EXPLOSION);
7032 }
7033 }
7034 }
7035 }
7036
7037 override void OnWasAttached(EntityAI parent, int slot_id)
7038 {
7039 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
7040
7041 super.OnWasAttached(parent, slot_id);
7042
7043 if (HasQuantity())
7044 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7045
7046 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
7047 StartItemSoundServer(SoundConstants.ITEM_ATTACH, slot_id);
7048 }
7049
7050 override void OnWasDetached(EntityAI parent, int slot_id)
7051 {
7052 super.OnWasDetached(parent, slot_id);
7053
7054 if (HasQuantity())
7055 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7056
7057 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
7058 StartItemSoundServer(SoundConstants.ITEM_DETACH, slot_id);
7059 }
7060
7061 override string ChangeIntoOnAttach(string slot)
7062 {
7063 int idx;
7064 TStringArray inventory_slots = new TStringArray;
7065 TStringArray attach_types = new TStringArray;
7066
7067 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7068 if (inventory_slots.Count() < 1) //is string
7069 {
7070 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
7071 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
7072 }
7073 else //is array
7074 {
7075 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
7076 }
7077
7078 idx = inventory_slots.Find(slot);
7079 if (idx < 0)
7080 return "";
7081
7082 return attach_types.Get(idx);
7083 }
7084
7085 override string ChangeIntoOnDetach()
7086 {
7087 int idx = -1;
7088 string slot;
7089
7090 TStringArray inventory_slots = new TStringArray;
7091 TStringArray detach_types = new TStringArray;
7092
7093 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7094 if (inventory_slots.Count() < 1) //is string
7095 {
7096 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
7097 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7098 }
7099 else //is array
7100 {
7101 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
7102 if (detach_types.Count() < 1)
7103 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7104 }
7105
7106 for (int i = 0; i < inventory_slots.Count(); i++)
7107 {
7108 slot = inventory_slots.Get(i);
7109 }
7110
7111 if (slot != "")
7112 {
7113 if (detach_types.Count() == 1)
7114 idx = 0;
7115 else
7116 idx = inventory_slots.Find(slot);
7117 }
7118 if (idx < 0)
7119 return "";
7120
7121 return detach_types.Get(idx);
7122 }
7123
7124 void ExplodeAmmo()
7125 {
7126 //timer
7127 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
7128
7129 //min/max time
7130 float min_time = 1;
7131 float max_time = 3;
7132 float delay = Math.RandomFloat(min_time, max_time);
7133
7134 explode_timer.Run(delay, this, "DoAmmoExplosion");
7135 }
7136
7137 void DoAmmoExplosion()
7138 {
7139 Magazine magazine = Magazine.Cast(this);
7140 int pop_sounds_count = 6;
7141 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
7142
7143 //play sound
7144 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
7145 string sound_name = pop_sounds[ sound_idx ];
7146 g_Game.CreateSoundOnObject(this, sound_name, 20, false);
7147
7148 //remove ammo count
7149 magazine.ServerAddAmmoCount(-1);
7150
7151 //if condition then repeat -> ExplodeAmmo
7152 float min_temp_to_explode = 100; //min temperature for item to explode
7153
7154 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
7155 {
7156 ExplodeAmmo();
7157 }
7158 }
7159
7160 // -------------------------------------------------------------------------------
7161 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
7162 {
7163 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
7164
7165 const int CHANCE_DAMAGE_CARGO = 4;
7166 const int CHANCE_DAMAGE_ATTACHMENT = 1;
7167 const int CHANCE_DAMAGE_NOTHING = 2;
7168
7169 if (IsClothing() || IsContainer() || IsItemTent())
7170 {
7171 float dmg = damageResult.GetDamage("","Health") * -0.5;
7172 int chances;
7173 int rnd;
7174
7175 if (GetInventory().GetCargo())
7176 {
7177 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7178 rnd = Math.RandomInt(0,chances);
7179
7180 if (rnd < CHANCE_DAMAGE_CARGO)
7181 {
7182 DamageItemInCargo(dmg);
7183 }
7184 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
7185 {
7187 }
7188 }
7189 else
7190 {
7191 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7192 rnd = Math.RandomInt(0,chances);
7193
7194 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
7195 {
7197 }
7198 }
7199 }
7200 }
7201
7202 bool DamageItemInCargo(float damage)
7203 {
7204 CargoBase cargo = GetInventory().GetCargo();
7205 if (cargo)
7206 {
7207 int item_count = cargo.GetItemCount();
7208 if (item_count > 0)
7209 {
7210 int random_pick = Math.RandomInt(0, item_count);
7211 ItemBase item = ItemBase.Cast(cargo.GetItem(random_pick));
7212 if (!item.IsExplosive())
7213 {
7214 item.AddHealth("","",damage);
7215 return true;
7216 }
7217 }
7218 }
7219 return false;
7220 }
7221
7222 bool DamageItemAttachments(float damage)
7223 {
7224 GameInventory inventory = GetInventory();
7225 int attachment_count = inventory.AttachmentCount();
7226 if (attachment_count > 0)
7227 {
7228 int random_pick = Math.RandomInt(0, attachment_count);
7229 ItemBase attachment = ItemBase.Cast(inventory.GetAttachmentFromIndex(random_pick));
7230 if (!attachment.IsExplosive())
7231 {
7232 attachment.AddHealth("","",damage);
7233 return true;
7234 }
7235 }
7236 return false;
7237 }
7238
7239 override bool IsSplitable()
7240 {
7241 return m_CanThisBeSplit;
7242 }
7243 //----------------
7244 override bool CanBeSplit()
7245 {
7246 if (IsSplitable() && (GetQuantity() > 1))
7247 return GetInventory().CanRemoveEntity();
7248
7249 return false;
7250 }
7251
7252 protected bool ShouldSplitQuantity(float quantity)
7253 {
7254 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
7255 if (!IsSplitable())
7256 return false;
7257
7258 // nothing to split?
7259 if (GetQuantity() <= 1)
7260 return false;
7261
7262 // check if we should re-use the item instead of creating a new copy?
7263 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
7264 int delta = GetQuantity() - quantity;
7265 if (delta == 0)
7266 return false;
7267
7268 // valid to split
7269 return true;
7270 }
7271
7272 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
7273 {
7274 if (g_Game.IsClient())
7275 {
7276 if (ScriptInputUserData.CanStoreInputUserData())
7277 {
7278 ScriptInputUserData ctx = new ScriptInputUserData;
7280 ctx.Write(1);
7281 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7282 ctx.Write(i1);
7283 ctx.Write(destination_entity);
7284 ctx.Write(true);
7285 ctx.Write(slot_id);
7286 ctx.Send();
7287 }
7288 }
7289 else if (!g_Game.IsMultiplayer())
7290 {
7291 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(g_Game.GetPlayer()));
7292 }
7293 }
7294
7295 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
7296 {
7297 float split_quantity_new;
7298 ItemBase new_item;
7299 float quantity = GetQuantity();
7300 float stack_max = GetTargetQuantityMax(slot_id);
7301 InventoryLocation loc = new InventoryLocation;
7302
7303 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7304 {
7305 if (stack_max <= GetQuantity())
7306 split_quantity_new = stack_max;
7307 else
7308 split_quantity_new = GetQuantity();
7309
7310 if (ShouldSplitQuantity(split_quantity_new))
7311 {
7312 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7313 if (new_item)
7314 {
7315 new_item.SetResultOfSplit(true);
7316 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7317 AddQuantity(-split_quantity_new, false, true);
7318 new_item.SetQuantity(split_quantity_new, false, true);
7319 }
7320 }
7321 }
7322 else if (destination_entity && slot_id == -1)
7323 {
7324 if (quantity > stack_max)
7325 split_quantity_new = stack_max;
7326 else
7327 split_quantity_new = quantity;
7328
7329 if (ShouldSplitQuantity(split_quantity_new))
7330 {
7331 GameInventory destinationInventory = destination_entity.GetInventory();
7332 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7333 {
7334 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7335 new_item = ItemBase.Cast(o);
7336 }
7337
7338 if (new_item)
7339 {
7340 new_item.SetResultOfSplit(true);
7341 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7342 AddQuantity(-split_quantity_new, false, true);
7343 new_item.SetQuantity(split_quantity_new, false, true);
7344 }
7345 }
7346 }
7347 else
7348 {
7349 if (stack_max != 0)
7350 {
7351 if (stack_max < GetQuantity())
7352 {
7353 split_quantity_new = GetQuantity() - stack_max;
7354 }
7355
7356 if (split_quantity_new == 0)
7357 {
7358 if (!g_Game.IsMultiplayer())
7359 player.PhysicalPredictiveDropItem(this);
7360 else
7361 player.ServerDropEntity(this);
7362 return;
7363 }
7364
7365 if (ShouldSplitQuantity(split_quantity_new))
7366 {
7367 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7368
7369 if (new_item)
7370 {
7371 new_item.SetResultOfSplit(true);
7372 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7373 SetQuantity(split_quantity_new, false, true);
7374 new_item.SetQuantity(stack_max, false, true);
7375 new_item.PlaceOnSurface();
7376 }
7377 }
7378 }
7379 }
7380 }
7381
7382 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
7383 {
7384 float split_quantity_new;
7385 ItemBase new_item;
7386 float quantity = GetQuantity();
7387 float stack_max = GetTargetQuantityMax(slot_id);
7388 InventoryLocation loc = new InventoryLocation;
7389
7390 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7391 {
7392 if (stack_max <= GetQuantity())
7393 split_quantity_new = stack_max;
7394 else
7395 split_quantity_new = GetQuantity();
7396
7397 if (ShouldSplitQuantity(split_quantity_new))
7398 {
7399 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7400 if (new_item)
7401 {
7402 new_item.SetResultOfSplit(true);
7403 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7404 AddQuantity(-split_quantity_new, false, true);
7405 new_item.SetQuantity(split_quantity_new, false, true);
7406 }
7407 }
7408 }
7409 else if (destination_entity && slot_id == -1)
7410 {
7411 if (quantity > stack_max)
7412 split_quantity_new = stack_max;
7413 else
7414 split_quantity_new = quantity;
7415
7416 if (ShouldSplitQuantity(split_quantity_new))
7417 {
7418 GameInventory destinationInventory = destination_entity.GetInventory();
7419 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7420 {
7421 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7422 new_item = ItemBase.Cast(o);
7423 }
7424
7425 if (new_item)
7426 {
7427 new_item.SetResultOfSplit(true);
7428 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7429 AddQuantity(-split_quantity_new, false, true);
7430 new_item.SetQuantity(split_quantity_new, false, true);
7431 }
7432 }
7433 }
7434 else
7435 {
7436 if (stack_max != 0)
7437 {
7438 if (stack_max < GetQuantity())
7439 {
7440 split_quantity_new = GetQuantity() - stack_max;
7441 }
7442
7443 if (ShouldSplitQuantity(split_quantity_new))
7444 {
7445 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7446
7447 if (new_item)
7448 {
7449 new_item.SetResultOfSplit(true);
7450 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7451 SetQuantity(split_quantity_new, false, true);
7452 new_item.SetQuantity(stack_max, false, true);
7453 new_item.PlaceOnSurface();
7454 }
7455 }
7456 }
7457 }
7458 }
7459
7460 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
7461 {
7462 if (g_Game.IsClient())
7463 {
7464 if (ScriptInputUserData.CanStoreInputUserData())
7465 {
7466 ScriptInputUserData ctx = new ScriptInputUserData;
7468 ctx.Write(4);
7469 ItemBase thiz = this; // @NOTE: workaround for correct serialization
7470 ctx.Write(thiz);
7471 dst.WriteToContext(ctx);
7472 ctx.Send();
7473 }
7474 }
7475 else if (!g_Game.IsMultiplayer())
7476 {
7478 }
7479 }
7480
7481 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
7482 {
7483 if (g_Game.IsClient())
7484 {
7485 if (ScriptInputUserData.CanStoreInputUserData())
7486 {
7487 ScriptInputUserData ctx = new ScriptInputUserData;
7489 ctx.Write(2);
7490 ItemBase dummy = this; // @NOTE: workaround for correct serialization
7491 ctx.Write(dummy);
7492 ctx.Write(destination_entity);
7493 ctx.Write(true);
7494 ctx.Write(idx);
7495 ctx.Write(row);
7496 ctx.Write(col);
7497 ctx.Send();
7498 }
7499 }
7500 else if (!g_Game.IsMultiplayer())
7501 {
7502 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
7503 }
7504 }
7505
7506 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
7507 {
7509 }
7510
7511 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
7512 {
7513 float quantity = GetQuantity();
7514 float split_quantity_new;
7515 ItemBase new_item;
7516 if (dst.IsValid())
7517 {
7518 int slot_id = dst.GetSlot();
7519 float stack_max = GetTargetQuantityMax(slot_id);
7520
7521 if (quantity > stack_max)
7522 split_quantity_new = stack_max;
7523 else
7524 split_quantity_new = quantity;
7525
7526 if (ShouldSplitQuantity(split_quantity_new))
7527 {
7528 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
7529
7530 if (new_item)
7531 {
7532 new_item.SetResultOfSplit(true);
7533 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7534 AddQuantity(-split_quantity_new, false, true);
7535 new_item.SetQuantity(split_quantity_new, false, true);
7536 }
7537
7538 return new_item;
7539 }
7540 }
7541
7542 return null;
7543 }
7544
7545 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
7546 {
7547 float quantity = GetQuantity();
7548 float split_quantity_new;
7549 ItemBase new_item;
7550 if (destination_entity)
7551 {
7552 float stackable = GetTargetQuantityMax();
7553 if (quantity > stackable)
7554 split_quantity_new = stackable;
7555 else
7556 split_quantity_new = quantity;
7557
7558 if (ShouldSplitQuantity(split_quantity_new))
7559 {
7560 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
7561 if (new_item)
7562 {
7563 new_item.SetResultOfSplit(true);
7564 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7565 AddQuantity(-split_quantity_new, false, true);
7566 new_item.SetQuantity(split_quantity_new, false, true);
7567 }
7568 }
7569 }
7570 }
7571
7572 void SplitIntoStackMaxHandsClient(PlayerBase player)
7573 {
7574 if (g_Game.IsClient())
7575 {
7576 if (ScriptInputUserData.CanStoreInputUserData())
7577 {
7578 ScriptInputUserData ctx = new ScriptInputUserData;
7580 ctx.Write(3);
7581 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7582 ctx.Write(i1);
7583 ItemBase destination_entity = this;
7584 ctx.Write(destination_entity);
7585 ctx.Write(true);
7586 ctx.Write(0);
7587 ctx.Send();
7588 }
7589 }
7590 else if (!g_Game.IsMultiplayer())
7591 {
7592 SplitIntoStackMaxHands(player);
7593 }
7594 }
7595
7596 void SplitIntoStackMaxHands(PlayerBase player)
7597 {
7598 float quantity = GetQuantity();
7599 float split_quantity_new;
7600 ref ItemBase new_item;
7601 if (player)
7602 {
7603 float stackable = GetTargetQuantityMax();
7604 if (quantity > stackable)
7605 split_quantity_new = stackable;
7606 else
7607 split_quantity_new = quantity;
7608
7609 if (ShouldSplitQuantity(split_quantity_new))
7610 {
7611 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
7612 new_item = ItemBase.Cast(in_hands);
7613 if (new_item)
7614 {
7615 new_item.SetResultOfSplit(true);
7616 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7617 AddQuantity(-split_quantity_new, false, true);
7618 new_item.SetQuantity(split_quantity_new, false, true);
7619 }
7620 }
7621 }
7622 }
7623
7624 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
7625 {
7626 float quantity = GetQuantity();
7627 float split_quantity_new = Math.Floor(quantity * 0.5);
7628
7629 if (!ShouldSplitQuantity(split_quantity_new))
7630 return;
7631
7632 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
7633
7634 if (new_item)
7635 {
7636 if (new_item.GetQuantityMax() < split_quantity_new)
7637 {
7638 split_quantity_new = new_item.GetQuantityMax();
7639 }
7640
7641 new_item.SetResultOfSplit(true);
7642 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7643
7644 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
7645 {
7646 AddQuantity(-1, false, true);
7647 new_item.SetQuantity(1, false, true);
7648 }
7649 else
7650 {
7651 AddQuantity(-split_quantity_new, false, true);
7652 new_item.SetQuantity(split_quantity_new, false, true);
7653 }
7654 }
7655 }
7656
7657 void SplitItem(PlayerBase player)
7658 {
7659 float quantity = GetQuantity();
7660 float split_quantity_new = Math.Floor(quantity / 2);
7661
7662 if (!ShouldSplitQuantity(split_quantity_new))
7663 return;
7664
7665 InventoryLocation invloc = new InventoryLocation;
7666 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
7667
7668 ItemBase new_item;
7669 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
7670
7671 if (new_item)
7672 {
7673 if (new_item.GetQuantityMax() < split_quantity_new)
7674 {
7675 split_quantity_new = new_item.GetQuantityMax();
7676 }
7677 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
7678 {
7679 AddQuantity(-1, false, true);
7680 new_item.SetQuantity(1, false, true);
7681 }
7682 else if (split_quantity_new > 1)
7683 {
7684 AddQuantity(-split_quantity_new, false, true);
7685 new_item.SetQuantity(split_quantity_new, false, true);
7686 }
7687 }
7688 }
7689
7691 void OnQuantityChanged(float delta)
7692 {
7693 SetWeightDirty();
7694 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
7695
7696 if (parent)
7697 parent.OnAttachmentQuantityChangedEx(this, delta);
7698
7699 if (IsLiquidContainer())
7700 {
7701 if (GetQuantityNormalized() <= 0.0)
7702 {
7704 }
7705 else if (GetLiquidType() == LIQUID_NONE)
7706 {
7707 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
7709 }
7710 }
7711 }
7712
7715 {
7716 // insert code here
7717 }
7718
7720 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
7721 {
7723 }
7724
7725 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
7726 {
7727 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
7728
7729 if (g_Game.IsServer())
7730 {
7731 if (newLevel == GameConstants.STATE_RUINED)
7732 {
7734 EntityAI parent = GetHierarchyParent();
7735 if (parent && parent.IsFireplace())
7736 {
7737 CargoBase cargo = GetInventory().GetCargo();
7738 if (cargo)
7739 {
7740 for (int i = 0; i < cargo.GetItemCount(); ++i)
7741 {
7742 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
7743 }
7744 }
7745 }
7746 }
7747
7748 if (IsResultOfSplit())
7749 {
7750 // reset the splitting result flag, return to normal item behavior
7751 SetResultOfSplit(false);
7752 return;
7753 }
7754
7755 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
7756 {
7757 SetCleanness(0);//unclean the item upon damage dealt
7758 }
7759 }
7760 }
7761
7762 // just the split? TODO: verify
7763 override void OnRightClick()
7764 {
7765 super.OnRightClick();
7766
7767 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !g_Game.GetPlayer().GetInventory().HasInventoryReservation(this,null))
7768 {
7769 if (g_Game.IsClient())
7770 {
7771 if (ScriptInputUserData.CanStoreInputUserData())
7772 {
7773 EntityAI root = GetHierarchyRoot();
7774 Man playerOwner = GetHierarchyRootPlayer();
7775 InventoryLocation dst = new InventoryLocation;
7776
7777 // 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
7778 if (!playerOwner && root && root == this)
7779 {
7781 }
7782 else
7783 {
7784 // 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
7785 GetInventory().GetCurrentInventoryLocation(dst);
7786 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
7787 {
7788 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7789 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
7790 {
7792 }
7793 else
7794 {
7795 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
7796 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
7797 this shouldnt cause issues within this scope*/
7798 if (g_Game.GetPlayer().GetInventory().HasInventoryReservation(this, dst))
7799 {
7801 }
7802 else
7803 {
7804 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
7805 }
7806 }
7807 }
7808 }
7809
7810 ScriptInputUserData ctx = new ScriptInputUserData;
7812 ctx.Write(4);
7813 ItemBase thiz = this; // @NOTE: workaround for correct serialization
7814 ctx.Write(thiz);
7815 dst.WriteToContext(ctx);
7816 ctx.Write(true); // dummy
7817 ctx.Send();
7818 }
7819 }
7820 else if (!g_Game.IsMultiplayer())
7821 {
7822 SplitItem(PlayerBase.Cast(g_Game.GetPlayer()));
7823 }
7824 }
7825 }
7826
7827 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
7828 {
7829 if (root)
7830 {
7831 vector m4[4];
7832 root.GetTransform(m4);
7833 dst.SetGround(this, m4);
7834 }
7835 else
7836 {
7837 GetInventory().GetCurrentInventoryLocation(dst);
7838 }
7839 }
7840
7841 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
7842 {
7843 //TODO: delete check zero quantity check after fix double posts hands fsm events
7844 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
7845 return false;
7846
7847 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
7848 return false;
7849
7850 //can_this_be_combined = ConfigGetBool("canBeSplit");
7852 return false;
7853
7854
7855 Magazine mag = Magazine.Cast(this);
7856 if (mag)
7857 {
7858 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
7859 return false;
7860
7861 if (stack_max_limit)
7862 {
7863 Magazine other_mag = Magazine.Cast(other_item);
7864 if (other_item)
7865 {
7866 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
7867 return false;
7868 }
7869
7870 }
7871 }
7872 else
7873 {
7874 //TODO: delete check zero quantity check after fix double posts hands fsm events
7875 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
7876 return false;
7877
7878 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
7879 return false;
7880 }
7881
7882 PlayerBase player = null;
7883 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
7884 {
7885 if (player.GetInventory().HasAttachment(this))
7886 return false;
7887
7888 if (player.IsItemsToDelete())
7889 return false;
7890 }
7891
7892 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
7893 return false;
7894
7895 int slotID;
7896 string slotName;
7897 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
7898 return false;
7899
7900 return true;
7901 }
7902
7903 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
7904 {
7905 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
7906 }
7907
7908 bool IsResultOfSplit()
7909 {
7910 return m_IsResultOfSplit;
7911 }
7912
7913 void SetResultOfSplit(bool value)
7914 {
7915 m_IsResultOfSplit = value;
7916 }
7917
7918 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
7919 {
7920 return ComputeQuantityUsedEx(other_item, use_stack_max);
7921 }
7922
7923 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
7924 {
7925 float other_item_quantity = other_item.GetQuantity();
7926 float this_free_space;
7927
7928 float stack_max = GetQuantityMax();
7929
7930 this_free_space = stack_max - GetQuantity();
7931
7932 if (other_item_quantity > this_free_space)
7933 {
7934 return this_free_space;
7935 }
7936 else
7937 {
7938 return other_item_quantity;
7939 }
7940 }
7941
7942 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
7943 {
7944 CombineItems(ItemBase.Cast(entity2),use_stack_max);
7945 }
7946
7947 void CombineItems(ItemBase other_item, bool use_stack_max = true)
7948 {
7949 if (!CanBeCombined(other_item, false))
7950 return;
7951
7952 if (!IsMagazine() && other_item)
7953 {
7954 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
7955 if (quantity_used != 0)
7956 {
7957 float hp1 = GetHealth01("","");
7958 float hp2 = other_item.GetHealth01("","");
7959 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
7960 hpResult = hpResult / (GetQuantity() + quantity_used);
7961
7962 hpResult *= GetMaxHealth();
7963 Math.Round(hpResult);
7964 SetHealth("", "Health", hpResult);
7965
7966 AddQuantity(quantity_used);
7967 other_item.AddQuantity(-quantity_used);
7968 }
7969 }
7970 OnCombine(other_item);
7971 }
7972
7973 void OnCombine(ItemBase other_item)
7974 {
7975 #ifdef SERVER
7976 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
7977 GetHierarchyParent().IncreaseLifetimeUp();
7978 #endif
7979 };
7980
7981 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
7982 {
7983 PlayerBase p = PlayerBase.Cast(player);
7984
7985 array<int> recipesIds = p.m_Recipes;
7986 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
7987 if (moduleRecipesManager)
7988 {
7989 EntityAI itemInHands = player.GetEntityInHands();
7990 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
7991 }
7992
7993 for (int i = 0;i < recipesIds.Count(); i++)
7994 {
7995 int key = recipesIds.Get(i);
7996 string recipeName = moduleRecipesManager.GetRecipeName(key);
7997 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
7998 }
7999 }
8000
8001 // -------------------------------------------------------------------------
8002 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
8003 {
8004 super.GetDebugActions(outputList);
8005
8006 //quantity
8007 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
8008 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
8009 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
8010 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
8011 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8012
8013 //health
8014 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
8015 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
8016 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
8017 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8018 //temperature
8019 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
8020 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
8021 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
8022 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8023
8024 //wet
8025 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
8026 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
8027 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8028
8029 //liquidtype
8030 if (IsLiquidContainer())
8031 {
8032 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
8033 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
8034 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8035 }
8036
8037 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
8038 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8039
8040 // watch
8041 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
8042 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
8043 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8044
8045 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
8046
8047 InventoryLocation loc = new InventoryLocation();
8048 GetInventory().GetCurrentInventoryLocation(loc);
8049 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
8050 {
8051 if (Gizmo_IsSupported())
8052 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
8053 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
8054 }
8055
8056 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8057 }
8058
8059 // -------------------------------------------------------------------------
8060 // -------------------------------------------------------------------------
8061 // -------------------------------------------------------------------------
8062 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
8063 {
8064 super.OnAction(action_id, player, ctx);
8065
8066 if (g_Game.IsClient() || !g_Game.IsMultiplayer())
8067 {
8068 switch (action_id)
8069 {
8070 case EActions.GIZMO_OBJECT:
8071 if (GetGizmoApi())
8072 GetGizmoApi().SelectObject(this);
8073 return true;
8074 case EActions.GIZMO_PHYSICS:
8075 if (GetGizmoApi())
8076 GetGizmoApi().SelectPhysics(GetPhysics());
8077 return true;
8078 }
8079 }
8080
8081 if (g_Game.IsServer())
8082 {
8083 switch (action_id)
8084 {
8085 case EActions.DELETE:
8086 Delete();
8087 return true;
8088 }
8089 }
8090
8091 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
8092 {
8093 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
8094 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
8095 PlayerBase p = PlayerBase.Cast(player);
8096 if (EActions.RECIPES_RANGE_START < 1000)
8097 {
8098 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
8099 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
8100 }
8101 }
8102 #ifndef SERVER
8103 else if (action_id == EActions.WATCH_PLAYER)
8104 {
8105 PluginDeveloper.SetDeveloperItemClientEx(player);
8106 }
8107 #endif
8108 if (g_Game.IsServer())
8109 {
8110 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
8111 {
8112 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
8113 OnDebugButtonPressServer(id + 1);
8114 }
8115
8116 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
8117 {
8118 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
8119 InsertAgent(agent_id,100);
8120 }
8121
8122 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
8123 {
8124 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
8125 RemoveAgent(agent_id2);
8126 }
8127
8128 else if (action_id == EActions.ADD_QUANTITY)
8129 {
8130 if (IsMagazine())
8131 {
8132 Magazine mag = Magazine.Cast(this);
8133 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
8134 }
8135 else
8136 {
8137 AddQuantity(GetQuantityMax() * 0.2);
8138 }
8139
8140 if (m_EM)
8141 {
8142 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
8143 }
8144 //PrintVariables();
8145 }
8146
8147 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
8148 {
8149 if (IsMagazine())
8150 {
8151 Magazine mag2 = Magazine.Cast(this);
8152 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
8153 }
8154 else
8155 {
8156 AddQuantity(- GetQuantityMax() * 0.2);
8157 }
8158 if (m_EM)
8159 {
8160 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
8161 }
8162 //PrintVariables();
8163 }
8164
8165 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
8166 {
8167 SetQuantity(0);
8168
8169 if (m_EM)
8170 {
8171 m_EM.SetEnergy(0);
8172 }
8173 }
8174
8175 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
8176 {
8178
8179 if (m_EM)
8180 {
8181 m_EM.SetEnergy(m_EM.GetEnergyMax());
8182 }
8183 }
8184
8185 else if (action_id == EActions.ADD_HEALTH)
8186 {
8187 AddHealth("","",GetMaxHealth("","Health")/5);
8188 }
8189 else if (action_id == EActions.REMOVE_HEALTH)
8190 {
8191 AddHealth("","",-GetMaxHealth("","Health")/5);
8192 }
8193 else if (action_id == EActions.DESTROY_HEALTH)
8194 {
8195 SetHealth01("","",0);
8196 }
8197 else if (action_id == EActions.WATCH_ITEM)
8198 {
8200 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
8201 #ifdef DEVELOPER
8202 SetDebugDeveloper_item(this);
8203 #endif
8204 }
8205
8206 else if (action_id == EActions.ADD_TEMPERATURE)
8207 {
8208 AddTemperature(20);
8209 //PrintVariables();
8210 }
8211
8212 else if (action_id == EActions.REMOVE_TEMPERATURE)
8213 {
8214 AddTemperature(-20);
8215 //PrintVariables();
8216 }
8217
8218 else if (action_id == EActions.FLIP_FROZEN)
8219 {
8220 SetFrozen(!GetIsFrozen());
8221 //PrintVariables();
8222 }
8223
8224 else if (action_id == EActions.ADD_WETNESS)
8225 {
8226 AddWet(GetWetMax()/5);
8227 //PrintVariables();
8228 }
8229
8230 else if (action_id == EActions.REMOVE_WETNESS)
8231 {
8232 AddWet(-GetWetMax()/5);
8233 //PrintVariables();
8234 }
8235
8236 else if (action_id == EActions.LIQUIDTYPE_UP)
8237 {
8238 int curr_type = GetLiquidType();
8239 SetLiquidType(curr_type * 2);
8240 //AddWet(1);
8241 //PrintVariables();
8242 }
8243
8244 else if (action_id == EActions.LIQUIDTYPE_DOWN)
8245 {
8246 int curr_type2 = GetLiquidType();
8247 SetLiquidType(curr_type2 / 2);
8248 }
8249
8250 else if (action_id == EActions.MAKE_SPECIAL)
8251 {
8252 auto debugParams = DebugSpawnParams.WithPlayer(player);
8253 OnDebugSpawnEx(debugParams);
8254 }
8255
8256 }
8257
8258
8259 return false;
8260 }
8261
8262 // -------------------------------------------------------------------------
8263
8264
8267 void OnActivatedByTripWire();
8268
8270 void OnActivatedByItem(notnull ItemBase item);
8271
8272 //----------------------------------------------------------------
8273 //returns true if item is able to explode when put in fire
8274 bool CanExplodeInFire()
8275 {
8276 return false;
8277 }
8278
8279 //----------------------------------------------------------------
8280 bool CanEat()
8281 {
8282 return true;
8283 }
8284
8285 //----------------------------------------------------------------
8286 override bool IsIgnoredByConstruction()
8287 {
8288 return true;
8289 }
8290
8291 //----------------------------------------------------------------
8292 //has FoodStages in config?
8293 bool HasFoodStage()
8294 {
8295 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
8296 return g_Game.ConfigIsExisting(config_path);
8297 }
8298
8300 FoodStage GetFoodStage()
8301 {
8302 return null;
8303 }
8304
8305 bool CanBeCooked()
8306 {
8307 return false;
8308 }
8309
8310 bool CanBeCookedOnStick()
8311 {
8312 return false;
8313 }
8314
8316 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
8318
8319 //----------------------------------------------------------------
8320 bool CanRepair(ItemBase item_repair_kit)
8321 {
8322 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8323 return module_repairing.CanRepair(this, item_repair_kit);
8324 }
8325
8326 //----------------------------------------------------------------
8327 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
8328 {
8329 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8330 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
8331 }
8332
8333 //----------------------------------------------------------------
8334 int GetItemSize()
8335 {
8336 /*
8337 vector v_size = this.ConfigGetVector("itemSize");
8338 int v_size_x = v_size[0];
8339 int v_size_y = v_size[1];
8340 int size = v_size_x * v_size_y;
8341 return size;
8342 */
8343
8344 return 1;
8345 }
8346
8347 //----------------------------------------------------------------
8348 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8349 bool CanBeMovedOverride()
8350 {
8351 return m_CanBeMovedOverride;
8352 }
8353
8354 //----------------------------------------------------------------
8355 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8356 void SetCanBeMovedOverride(bool setting)
8357 {
8358 m_CanBeMovedOverride = setting;
8359 }
8360
8361 //----------------------------------------------------------------
8369 void MessageToOwnerStatus(string text)
8370 {
8371 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8372
8373 if (player)
8374 {
8375 player.MessageStatus(text);
8376 }
8377 }
8378
8379 //----------------------------------------------------------------
8387 void MessageToOwnerAction(string text)
8388 {
8389 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8390
8391 if (player)
8392 {
8393 player.MessageAction(text);
8394 }
8395 }
8396
8397 //----------------------------------------------------------------
8405 void MessageToOwnerFriendly(string text)
8406 {
8407 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8408
8409 if (player)
8410 {
8411 player.MessageFriendly(text);
8412 }
8413 }
8414
8415 //----------------------------------------------------------------
8423 void MessageToOwnerImportant(string text)
8424 {
8425 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8426
8427 if (player)
8428 {
8429 player.MessageImportant(text);
8430 }
8431 }
8432
8433 override bool IsItemBase()
8434 {
8435 return true;
8436 }
8437
8438 // Checks if item is of questioned kind
8439 override bool KindOf(string tag)
8440 {
8441 bool found = false;
8442 string item_name = this.GetType();
8443 ref TStringArray item_tag_array = new TStringArray;
8444 g_Game.ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
8445
8446 int array_size = item_tag_array.Count();
8447 for (int i = 0; i < array_size; i++)
8448 {
8449 if (item_tag_array.Get(i) == tag)
8450 {
8451 found = true;
8452 break;
8453 }
8454 }
8455 return found;
8456 }
8457
8458
8459 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
8460 {
8461 //Debug.Log("OnRPC called");
8462 super.OnRPC(sender, rpc_type,ctx);
8463
8464 //Play soundset for attachment locking (ActionLockAttachment.c)
8465 switch (rpc_type)
8466 {
8467 #ifndef SERVER
8468 case ERPCs.RPC_SOUND_LOCK_ATTACH:
8469 Param2<bool, string> p = new Param2<bool, string>(false, "");
8470
8471 if (!ctx.Read(p))
8472 return;
8473
8474 bool play = p.param1;
8475 string soundSet = p.param2;
8476
8477 if (play)
8478 {
8479 if (m_LockingSound)
8480 {
8482 {
8483 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
8484 }
8485 }
8486 else
8487 {
8488 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
8489 }
8490 }
8491 else
8492 {
8493 SEffectManager.DestroyEffect(m_LockingSound);
8494 }
8495
8496 break;
8497 #endif
8498
8499 }
8500
8501 if (GetWrittenNoteData())
8502 {
8503 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
8504 }
8505 }
8506
8507 //-----------------------------
8508 // VARIABLE MANIPULATION SYSTEM
8509 //-----------------------------
8510 int NameToID(string name)
8511 {
8512 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
8513 return plugin.GetID(name);
8514 }
8515
8516 string IDToName(int id)
8517 {
8518 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
8519 return plugin.GetName(id);
8520 }
8521
8523 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
8524 {
8525 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
8526 //read the flags
8527 int varFlags;
8528 if (!ctx.Read(varFlags))
8529 return;
8530
8531 if (varFlags & ItemVariableFlags.FLOAT)
8532 {
8533 ReadVarsFromCTX(ctx);
8534 }
8535 }
8536
8537 override void SerializeNumericalVars(array<float> floats_out)
8538 {
8539 //some variables handled on EntityAI level already!
8540 super.SerializeNumericalVars(floats_out);
8541
8542 // the order of serialization must be the same as the order of de-serialization
8543 //--------------------------------------------
8544 if (IsVariableSet(VARIABLE_QUANTITY))
8545 {
8546 floats_out.Insert(m_VarQuantity);
8547 }
8548 //--------------------------------------------
8549 if (IsVariableSet(VARIABLE_WET))
8550 {
8551 floats_out.Insert(m_VarWet);
8552 }
8553 //--------------------------------------------
8554 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
8555 {
8556 floats_out.Insert(m_VarLiquidType);
8557 }
8558 //--------------------------------------------
8559 if (IsVariableSet(VARIABLE_COLOR))
8560 {
8561 floats_out.Insert(m_ColorComponentR);
8562 floats_out.Insert(m_ColorComponentG);
8563 floats_out.Insert(m_ColorComponentB);
8564 floats_out.Insert(m_ColorComponentA);
8565 }
8566 //--------------------------------------------
8567 if (IsVariableSet(VARIABLE_CLEANNESS))
8568 {
8569 floats_out.Insert(m_Cleanness);
8570 }
8571 }
8572
8573 override void DeSerializeNumericalVars(array<float> floats)
8574 {
8575 //some variables handled on EntityAI level already!
8576 super.DeSerializeNumericalVars(floats);
8577
8578 // the order of serialization must be the same as the order of de-serialization
8579 int index = 0;
8580 int mask = Math.Round(floats.Get(index));
8581
8582 index++;
8583 //--------------------------------------------
8584 if (mask & VARIABLE_QUANTITY)
8585 {
8586 if (m_IsStoreLoad)
8587 {
8588 SetStoreLoadedQuantity(floats.Get(index));
8589 }
8590 else
8591 {
8592 float quantity = floats.Get(index);
8593 SetQuantity(quantity, true, false, false, false);
8594 }
8595 index++;
8596 }
8597 //--------------------------------------------
8598 if (mask & VARIABLE_WET)
8599 {
8600 float wet = floats.Get(index);
8601 SetWet(wet);
8602 index++;
8603 }
8604 //--------------------------------------------
8605 if (mask & VARIABLE_LIQUIDTYPE)
8606 {
8607 int liquidtype = Math.Round(floats.Get(index));
8608 SetLiquidType(liquidtype);
8609 index++;
8610 }
8611 //--------------------------------------------
8612 if (mask & VARIABLE_COLOR)
8613 {
8614 m_ColorComponentR = Math.Round(floats.Get(index));
8615 index++;
8616 m_ColorComponentG = Math.Round(floats.Get(index));
8617 index++;
8618 m_ColorComponentB = Math.Round(floats.Get(index));
8619 index++;
8620 m_ColorComponentA = Math.Round(floats.Get(index));
8621 index++;
8622 }
8623 //--------------------------------------------
8624 if (mask & VARIABLE_CLEANNESS)
8625 {
8626 int cleanness = Math.Round(floats.Get(index));
8627 SetCleanness(cleanness);
8628 index++;
8629 }
8630 }
8631
8632 override void WriteVarsToCTX(ParamsWriteContext ctx)
8633 {
8634 super.WriteVarsToCTX(ctx);
8635
8636 //--------------------------------------------
8637 if (IsVariableSet(VARIABLE_QUANTITY))
8638 {
8639 ctx.Write(GetQuantity());
8640 }
8641 //--------------------------------------------
8642 if (IsVariableSet(VARIABLE_WET))
8643 {
8644 ctx.Write(GetWet());
8645 }
8646 //--------------------------------------------
8647 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
8648 {
8649 ctx.Write(GetLiquidType());
8650 }
8651 //--------------------------------------------
8652 if (IsVariableSet(VARIABLE_COLOR))
8653 {
8654 int r,g,b,a;
8655 GetColor(r,g,b,a);
8656 ctx.Write(r);
8657 ctx.Write(g);
8658 ctx.Write(b);
8659 ctx.Write(a);
8660 }
8661 //--------------------------------------------
8662 if (IsVariableSet(VARIABLE_CLEANNESS))
8663 {
8664 ctx.Write(GetCleanness());
8665 }
8666 }
8667
8668 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
8669 {
8670 if (!super.ReadVarsFromCTX(ctx,version))
8671 return false;
8672
8673 int intValue;
8674 float value;
8675
8676 if (version < 140)
8677 {
8678 if (!ctx.Read(intValue))
8679 return false;
8680
8681 m_VariablesMask = intValue;
8682 }
8683
8684 if (m_VariablesMask & VARIABLE_QUANTITY)
8685 {
8686 if (!ctx.Read(value))
8687 return false;
8688
8689 if (IsStoreLoad())
8690 {
8692 }
8693 else
8694 {
8695 SetQuantity(value, true, false, false, false);
8696 }
8697 }
8698 //--------------------------------------------
8699 if (version < 140)
8700 {
8701 if (m_VariablesMask & VARIABLE_TEMPERATURE)
8702 {
8703 if (!ctx.Read(value))
8704 return false;
8705 SetTemperatureDirect(value);
8706 }
8707 }
8708 //--------------------------------------------
8709 if (m_VariablesMask & VARIABLE_WET)
8710 {
8711 if (!ctx.Read(value))
8712 return false;
8713 SetWet(value);
8714 }
8715 //--------------------------------------------
8716 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
8717 {
8718 if (!ctx.Read(intValue))
8719 return false;
8720 SetLiquidType(intValue);
8721 }
8722 //--------------------------------------------
8723 if (m_VariablesMask & VARIABLE_COLOR)
8724 {
8725 int r,g,b,a;
8726 if (!ctx.Read(r))
8727 return false;
8728 if (!ctx.Read(g))
8729 return false;
8730 if (!ctx.Read(b))
8731 return false;
8732 if (!ctx.Read(a))
8733 return false;
8734
8735 SetColor(r,g,b,a);
8736 }
8737 //--------------------------------------------
8738 if (m_VariablesMask & VARIABLE_CLEANNESS)
8739 {
8740 if (!ctx.Read(intValue))
8741 return false;
8742 SetCleanness(intValue);
8743 }
8744 //--------------------------------------------
8745 if (version >= 138 && version < 140)
8746 {
8747 if (m_VariablesMask & VARIABLE_TEMPERATURE)
8748 {
8749 if (!ctx.Read(intValue))
8750 return false;
8751 SetFrozen(intValue);
8752 }
8753 }
8754
8755 return true;
8756 }
8757
8758 //----------------------------------------------------------------
8759 override bool OnStoreLoad(ParamsReadContext ctx, int version)
8760 {
8761 m_IsStoreLoad = true;
8763 {
8764 m_FixDamageSystemInit = true;
8765 }
8766
8767 if (!super.OnStoreLoad(ctx, version))
8768 {
8769 m_IsStoreLoad = false;
8770 return false;
8771 }
8772
8773 if (version >= 114)
8774 {
8775 bool hasQuickBarIndexSaved;
8776
8777 if (!ctx.Read(hasQuickBarIndexSaved))
8778 {
8779 m_IsStoreLoad = false;
8780 return false;
8781 }
8782
8783 if (hasQuickBarIndexSaved)
8784 {
8785 int itmQBIndex;
8786
8787 //Load quickbar item bind
8788 if (!ctx.Read(itmQBIndex))
8789 {
8790 m_IsStoreLoad = false;
8791 return false;
8792 }
8793
8794 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
8795 if (itmQBIndex != -1 && parentPlayer)
8796 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
8797 }
8798 }
8799 else
8800 {
8801 // Backup of how it used to be
8802 PlayerBase player;
8803 int itemQBIndex;
8804 if (version == int.MAX)
8805 {
8806 if (!ctx.Read(itemQBIndex))
8807 {
8808 m_IsStoreLoad = false;
8809 return false;
8810 }
8811 }
8812 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
8813 {
8814 //Load quickbar item bind
8815 if (!ctx.Read(itemQBIndex))
8816 {
8817 m_IsStoreLoad = false;
8818 return false;
8819 }
8820 if (itemQBIndex != -1 && player)
8821 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
8822 }
8823 }
8824
8825 if (version < 140)
8826 {
8827 // variable management system
8828 if (!LoadVariables(ctx, version))
8829 {
8830 m_IsStoreLoad = false;
8831 return false;
8832 }
8833 }
8834
8835 //agent trasmission system
8836 if (!LoadAgents(ctx, version))
8837 {
8838 m_IsStoreLoad = false;
8839 return false;
8840 }
8841 if (version >= 132)
8842 {
8843 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
8844 if (raib)
8845 {
8846 if (!raib.OnStoreLoad(ctx,version))
8847 {
8848 m_IsStoreLoad = false;
8849 return false;
8850 }
8851 }
8852 }
8853
8854 m_IsStoreLoad = false;
8855 return true;
8856 }
8857
8858 //----------------------------------------------------------------
8859
8860 override void OnStoreSave(ParamsWriteContext ctx)
8861 {
8862 super.OnStoreSave(ctx);
8863
8864 PlayerBase player;
8865 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
8866 {
8867 ctx.Write(true); // Keep track of if we should actually read this in or not
8868 //Save quickbar item bind
8869 int itemQBIndex = -1;
8870 itemQBIndex = player.FindQuickBarEntityIndex(this);
8871 ctx.Write(itemQBIndex);
8872 }
8873 else
8874 {
8875 ctx.Write(false); // Keep track of if we should actually read this in or not
8876 }
8877
8878 SaveAgents(ctx);//agent trasmission system
8879
8880 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
8881 if (raib)
8882 {
8883 raib.OnStoreSave(ctx);
8884 }
8885 }
8886 //----------------------------------------------------------------
8887
8888 override void AfterStoreLoad()
8889 {
8890 super.AfterStoreLoad();
8891
8893 {
8895 }
8896
8897 if (GetStoreLoadedQuantity() != float.LOWEST)
8898 {
8900 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
8901 }
8902 }
8903
8904 override void EEOnAfterLoad()
8905 {
8906 super.EEOnAfterLoad();
8907
8909 {
8910 m_FixDamageSystemInit = false;
8911 }
8912
8915 }
8916
8917 bool CanBeDisinfected()
8918 {
8919 return false;
8920 }
8921
8922
8923 //----------------------------------------------------------------
8924 override void OnVariablesSynchronized()
8925 {
8926 if (m_Initialized)
8927 {
8928 #ifdef PLATFORM_CONSOLE
8929 //bruteforce it is
8930 if (IsSplitable())
8931 {
8932 UIScriptedMenu menu = g_Game.GetUIManager().FindMenu(MENU_INVENTORY);
8933 if (menu)
8934 {
8935 menu.Refresh();
8936 }
8937 }
8938 #endif
8939 }
8940
8942 {
8943 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
8944 m_WantPlayImpactSound = false;
8945 }
8946
8948 {
8949 SetWeightDirty();
8951 }
8952 if (m_VarWet != m_VarWetPrev)
8953 {
8956 }
8957
8958 if (m_SoundSyncPlay != 0)
8959 {
8962
8963 m_SoundSyncPlay = 0;
8964 m_SoundSyncSlotID = -1;
8965 }
8966 if (m_SoundSyncStop != 0)
8967 {
8969 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
8970 m_SoundSyncStop = 0;
8971 }
8972
8973 super.OnVariablesSynchronized();
8974 }
8975
8976 //------------------------- Quantity
8977 //----------------------------------------------------------------
8979 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
8980 {
8981 if (!IsServerCheck(allow_client))
8982 return false;
8983
8984 if (!HasQuantity())
8985 return false;
8986
8987 float min = GetQuantityMin();
8988 float max = GetQuantityMax();
8989
8990 if (value <= (min + 0.001))
8991 value = min;
8992
8993 if (value == min)
8994 {
8995 if (destroy_config)
8996 {
8997 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
8998 if (dstr)
8999 {
9000 m_VarQuantity = Math.Clamp(value, min, max);
9001 this.Delete();
9002 return true;
9003 }
9004 }
9005 else if (destroy_forced)
9006 {
9007 m_VarQuantity = Math.Clamp(value, min, max);
9008 this.Delete();
9009 return true;
9010 }
9011 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
9012 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
9013 }
9014
9015 float delta = m_VarQuantity;
9016 m_VarQuantity = Math.Clamp(value, min, max);
9017
9018 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
9019 {
9020 EntityAI parent = GetHierarchyRoot();
9021 InventoryLocation iLoc = new InventoryLocation();
9022 GetInventory().GetCurrentInventoryLocation(iLoc);
9023 if (iLoc && iLoc.IsValid() && delta != m_VarQuantity)
9024 {
9025 int iLocSlot = iLoc.GetSlot();
9026 if (delta < m_VarQuantity && iLoc.GetType() != InventoryLocationType.GROUND)
9027 {
9028 StartItemSoundServer(SoundConstants.ITEM_ATTACH, iLocSlot);
9029 }
9030 if (delta > m_VarQuantity && m_VarQuantity != 0 && !IsPrepareToDelete() && iLoc.GetType() == InventoryLocationType.ATTACHMENT)
9031 {
9032 StartItemSoundServer(SoundConstants.ITEM_DETACH, iLocSlot);
9033 }
9034 }
9035 }
9036
9037 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
9038 {
9039 delta = m_VarQuantity - delta;
9040
9041 if (delta)
9042 OnQuantityChanged(delta);
9043 }
9044
9045 SetVariableMask(VARIABLE_QUANTITY);
9046
9047 return false;
9048 }
9049
9050 //----------------------------------------------------------------
9052 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
9053 {
9054 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
9055 }
9056 //----------------------------------------------------------------
9057 void SetQuantityMax()
9058 {
9059 float max = GetQuantityMax();
9060 SetQuantity(max);
9061 }
9062
9063 override void SetQuantityToMinimum()
9064 {
9065 float min = GetQuantityMin();
9066 SetQuantity(min);
9067 }
9068 //----------------------------------------------------------------
9070 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
9071 {
9072 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
9073 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
9074 SetQuantity(result, destroy_config, destroy_forced);
9075 }
9076
9077 //----------------------------------------------------------------
9079 override float GetQuantityNormalized()
9080 {
9081 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
9082 }
9083
9085 {
9086 return GetQuantityNormalized();
9087 }
9088
9089 /*void SetAmmoNormalized(float value)
9090 {
9091 float value_clamped = Math.Clamp(value, 0, 1);
9092 Magazine this_mag = Magazine.Cast(this);
9093 int max_rounds = this_mag.GetAmmoMax();
9094 int result = value * max_rounds;//can the rounded if higher precision is required
9095 this_mag.SetAmmoCount(result);
9096 }*/
9097 //----------------------------------------------------------------
9098 override int GetQuantityMax()
9099 {
9100 int slot = -1;
9101 GameInventory inventory = GetInventory();
9102 if (inventory)
9103 {
9104 InventoryLocation il = new InventoryLocation;
9105 inventory.GetCurrentInventoryLocation(il);
9106 slot = il.GetSlot();
9107 }
9108
9109 return GetTargetQuantityMax(slot);
9110 }
9111
9112 override int GetTargetQuantityMax(int attSlotID = -1)
9113 {
9114 float quantity_max = 0;
9115
9116 if (IsSplitable()) //only stackable/splitable items can check for stack size
9117 {
9118 if (attSlotID != -1)
9119 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
9120
9121 if (quantity_max <= 0)
9122 quantity_max = m_VarStackMax;
9123 }
9124
9125 if (quantity_max <= 0)
9126 quantity_max = m_VarQuantityMax;
9127
9128 return quantity_max;
9129 }
9130 //----------------------------------------------------------------
9131 override int GetQuantityMin()
9132 {
9133 return m_VarQuantityMin;
9134 }
9135 //----------------------------------------------------------------
9136 int GetQuantityInit()
9137 {
9138 return m_VarQuantityInit;
9139 }
9140
9141 //----------------------------------------------------------------
9142 override bool HasQuantity()
9143 {
9144 return !(GetQuantityMax() - GetQuantityMin() == 0);
9145 }
9146
9147 override float GetQuantity()
9148 {
9149 return m_VarQuantity;
9150 }
9151
9152 bool IsFullQuantity()
9153 {
9154 return GetQuantity() >= GetQuantityMax();
9155 }
9156
9157 //Calculates weight of single item without attachments and cargo
9158 override float GetSingleInventoryItemWeightEx()
9159 {
9160 //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
9161 float weightEx = GetWeightEx();//overall weight of the item
9162 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
9163 return weightEx - special;
9164 }
9165
9166 // Obsolete, use GetSingleInventoryItemWeightEx() instead
9168 {
9170 }
9171
9172 override protected float GetWeightSpecialized(bool forceRecalc = false)
9173 {
9174 if (IsSplitable()) //quantity determines size of the stack
9175 {
9176 #ifdef DEVELOPER
9177 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9178 {
9179 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
9180 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
9181 }
9182 #endif
9183
9184 return GetQuantity() * GetConfigWeightModified();
9185 }
9186 else if (HasEnergyManager())// items with energy manager
9187 {
9188 #ifdef DEVELOPER
9189 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9190 {
9191 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
9192 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
9193 }
9194 #endif
9195 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9196 }
9197 else//everything else
9198 {
9199 #ifdef DEVELOPER
9200 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9201 {
9202 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
9203 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
9204 }
9205 #endif
9206 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9207 }
9208 }
9209
9211 int GetNumberOfItems()
9212 {
9213 int item_count = 0;
9214 ItemBase item;
9215
9216 GameInventory inventory = GetInventory();
9217 CargoBase cargo = inventory.GetCargo();
9218 if (cargo != NULL)
9219 {
9220 item_count = cargo.GetItemCount();
9221 }
9222
9223 int nAttachments = inventory.AttachmentCount();
9224 for (int i = 0; i < nAttachments; ++i)
9225 {
9226 Class.CastTo(item, inventory.GetAttachmentFromIndex(i));
9227 if (item)
9228 item_count += item.GetNumberOfItems();
9229 }
9230 return item_count;
9231 }
9232
9234 float GetUnitWeight(bool include_wetness = true)
9235 {
9236 float weight = 0;
9237 float wetness = 1;
9238 if (include_wetness)
9239 wetness += GetWet();
9240 if (IsSplitable()) //quantity determines size of the stack
9241 {
9242 weight = wetness * m_ConfigWeight;
9243 }
9244 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
9245 {
9246 weight = 1;
9247 }
9248 return weight;
9249 }
9250
9251 //-----------------------------------------------------------------
9252
9253 override void ClearInventory()
9254 {
9255 GameInventory inventory = GetInventory();
9256 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && inventory)
9257 {
9258 array<EntityAI> items = new array<EntityAI>;
9259 inventory.EnumerateInventory(InventoryTraversalType.INORDER, items);
9260 for (int i = 0; i < items.Count(); ++i)
9261 {
9262 ItemBase item = ItemBase.Cast(items.Get(i));
9263 if (item)
9264 {
9265 g_Game.ObjectDelete(item);
9266 }
9267 }
9268 }
9269 }
9270
9271 //------------------------- Energy
9272
9273 //----------------------------------------------------------------
9274 float GetEnergy()
9275 {
9276 float energy = 0;
9277 if (HasEnergyManager())
9278 {
9279 energy = GetCompEM().GetEnergy();
9280 }
9281 return energy;
9282 }
9283
9284
9285 override void OnEnergyConsumed()
9286 {
9287 super.OnEnergyConsumed();
9288
9290 }
9291
9292 override void OnEnergyAdded()
9293 {
9294 super.OnEnergyAdded();
9295
9297 }
9298
9299 // Converts energy (from Energy Manager) to quantity, if enabled.
9301 {
9302 if (g_Game.IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
9303 {
9304 if (HasQuantity())
9305 {
9306 float energy_0to1 = GetCompEM().GetEnergy0To1();
9307 SetQuantityNormalized(energy_0to1);
9308 }
9309 }
9310 }
9311
9312 //----------------------------------------------------------------
9313 float GetHeatIsolationInit()
9314 {
9315 return ConfigGetFloat("heatIsolation");
9316 }
9317
9318 float GetHeatIsolation()
9319 {
9320 return m_HeatIsolation;
9321 }
9322
9323 float GetDryingIncrement(string pIncrementName)
9324 {
9325 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
9326 if (g_Game.ConfigIsExisting(paramPath))
9327 return g_Game.ConfigGetFloat(paramPath);
9328
9329 return 0.0;
9330 }
9331
9332 float GetSoakingIncrement(string pIncrementName)
9333 {
9334 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
9335 if (g_Game.ConfigIsExisting(paramPath))
9336 return g_Game.ConfigGetFloat(paramPath);
9337
9338 return 0.0;
9339 }
9340 //----------------------------------------------------------------
9341 override void SetWet(float value, bool allow_client = false)
9342 {
9343 if (!IsServerCheck(allow_client))
9344 return;
9345
9346 float min = GetWetMin();
9347 float max = GetWetMax();
9348
9349 float previousValue = m_VarWet;
9350
9351 m_VarWet = Math.Clamp(value, min, max);
9352
9353 if (previousValue != m_VarWet)
9354 {
9355 SetVariableMask(VARIABLE_WET);
9356 OnWetChanged(m_VarWet, previousValue);
9357 }
9358 }
9359 //----------------------------------------------------------------
9360 override void AddWet(float value)
9361 {
9362 SetWet(GetWet() + value);
9363 }
9364 //----------------------------------------------------------------
9365 override void SetWetMax()
9366 {
9368 }
9369 //----------------------------------------------------------------
9370 override float GetWet()
9371 {
9372 return m_VarWet;
9373 }
9374 //----------------------------------------------------------------
9375 override float GetWetMax()
9376 {
9377 return m_VarWetMax;
9378 }
9379 //----------------------------------------------------------------
9380 override float GetWetMin()
9381 {
9382 return m_VarWetMin;
9383 }
9384 //----------------------------------------------------------------
9385 override float GetWetInit()
9386 {
9387 return m_VarWetInit;
9388 }
9389 //----------------------------------------------------------------
9390 override void OnWetChanged(float newVal, float oldVal)
9391 {
9392 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
9393 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
9394 if (newLevel != oldLevel)
9395 {
9396 OnWetLevelChanged(newLevel,oldLevel);
9397 }
9398 }
9399
9400 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
9401 {
9402 SetWeightDirty();
9403 }
9404
9405 override EWetnessLevel GetWetLevel()
9406 {
9407 return GetWetLevelInternal(m_VarWet);
9408 }
9409
9410 //----------------------------------------------------------------
9411
9412 override void SetStoreLoad(bool value)
9413 {
9414 m_IsStoreLoad = value;
9415 }
9416
9417 override bool IsStoreLoad()
9418 {
9419 return m_IsStoreLoad;
9420 }
9421
9422 override void SetStoreLoadedQuantity(float value)
9423 {
9424 m_StoreLoadedQuantity = value;
9425 }
9426
9427 override float GetStoreLoadedQuantity()
9428 {
9429 return m_StoreLoadedQuantity;
9430 }
9431
9432 //----------------------------------------------------------------
9433
9434 float GetItemModelLength()
9435 {
9436 if (ConfigIsExisting("itemModelLength"))
9437 {
9438 return ConfigGetFloat("itemModelLength");
9439 }
9440 return 0;
9441 }
9442
9443 float GetItemAttachOffset()
9444 {
9445 if (ConfigIsExisting("itemAttachOffset"))
9446 {
9447 return ConfigGetFloat("itemAttachOffset");
9448 }
9449 return 0;
9450 }
9451
9452 override void SetCleanness(int value, bool allow_client = false)
9453 {
9454 if (!IsServerCheck(allow_client))
9455 return;
9456
9457 int previousValue = m_Cleanness;
9458
9459 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
9460
9461 if (previousValue != m_Cleanness)
9462 SetVariableMask(VARIABLE_CLEANNESS);
9463 }
9464
9465 override int GetCleanness()
9466 {
9467 return m_Cleanness;
9468 }
9469
9471 {
9472 return true;
9473 }
9474
9475 //----------------------------------------------------------------
9476 // ATTACHMENT LOCKING
9477 // Getters relevant to generic ActionLockAttachment
9478 int GetLockType()
9479 {
9480 return m_LockType;
9481 }
9482
9483 string GetLockSoundSet()
9484 {
9485 return m_LockSoundSet;
9486 }
9487
9488 //----------------------------------------------------------------
9489 //------------------------- Color
9490 // sets items color variable given color components
9491 override void SetColor(int r, int g, int b, int a)
9492 {
9497 SetVariableMask(VARIABLE_COLOR);
9498 }
9500 override void GetColor(out int r,out int g,out int b,out int a)
9501 {
9506 }
9507
9508 bool IsColorSet()
9509 {
9510 return IsVariableSet(VARIABLE_COLOR);
9511 }
9512
9514 string GetColorString()
9515 {
9516 int r,g,b,a;
9517 GetColor(r,g,b,a);
9518 r = r/255;
9519 g = g/255;
9520 b = b/255;
9521 a = a/255;
9522 return MiscGameplayFunctions.GetColorString(r, g, b, a);
9523 }
9524 //----------------------------------------------------------------
9525 //------------------------- LiquidType
9526
9527 override void SetLiquidType(int value, bool allow_client = false)
9528 {
9529 if (!IsServerCheck(allow_client))
9530 return;
9531
9532 int old = m_VarLiquidType;
9533 m_VarLiquidType = value;
9534 OnLiquidTypeChanged(old,value);
9535 SetVariableMask(VARIABLE_LIQUIDTYPE);
9536 }
9537
9538 int GetLiquidTypeInit()
9539 {
9540 return ConfigGetInt("varLiquidTypeInit");
9541 }
9542
9543 override int GetLiquidType()
9544 {
9545 return m_VarLiquidType;
9546 }
9547
9548 protected void OnLiquidTypeChanged(int oldType, int newType)
9549 {
9550 if (newType == LIQUID_NONE && GetIsFrozen())
9551 SetFrozen(false);
9552 }
9553
9555 void UpdateQuickbarShortcutVisibility(PlayerBase player)
9556 {
9557 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
9558 }
9559
9560 // -------------------------------------------------------------------------
9562 void OnInventoryEnter(Man player)
9563 {
9564 PlayerBase nplayer;
9565 if (PlayerBase.CastTo(nplayer, player))
9566 {
9567 m_CanPlayImpactSound = true;
9568 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
9569 }
9570 }
9571
9572 // -------------------------------------------------------------------------
9574 void OnInventoryExit(Man player)
9575 {
9576 PlayerBase nplayer;
9577 if (PlayerBase.CastTo(nplayer,player))
9578 {
9579 nplayer.SetEnableQuickBarEntityShortcut(this, false);
9580 }
9581
9582 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
9583
9584 if (HasEnergyManager())
9585 {
9586 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
9587 }
9588 }
9589
9590 // ADVANCED PLACEMENT EVENTS
9591 override void OnPlacementStarted(Man player)
9592 {
9593 super.OnPlacementStarted(player);
9594
9595 SetTakeable(false);
9596 }
9597
9598 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
9599 {
9600 if (m_AdminLog)
9601 {
9602 m_AdminLog.OnPlacementComplete(player, this);
9603 }
9604
9605 super.OnPlacementComplete(player, position, orientation);
9606 }
9607
9608 //-----------------------------
9609 // AGENT SYSTEM
9610 //-----------------------------
9611 //--------------------------------------------------------------------------
9612 bool ContainsAgent(int agent_id)
9613 {
9614 if (agent_id & m_AttachedAgents)
9615 {
9616 return true;
9617 }
9618 else
9619 {
9620 return false;
9621 }
9622 }
9623
9624 //--------------------------------------------------------------------------
9625 override void RemoveAgent(int agent_id)
9626 {
9627 if (ContainsAgent(agent_id))
9628 {
9629 m_AttachedAgents = ~agent_id & m_AttachedAgents;
9630 }
9631 }
9632
9633 //--------------------------------------------------------------------------
9634 override void RemoveAllAgents()
9635 {
9636 m_AttachedAgents = 0;
9637 }
9638 //--------------------------------------------------------------------------
9639 override void RemoveAllAgentsExcept(int agent_to_keep)
9640 {
9641 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
9642 }
9643 // -------------------------------------------------------------------------
9644 override void InsertAgent(int agent, float count = 1)
9645 {
9646 if (count < 1)
9647 return;
9648 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
9650 }
9651
9653 void TransferAgents(int agents)
9654 {
9656 }
9657
9658 // -------------------------------------------------------------------------
9659 override int GetAgents()
9660 {
9661 return m_AttachedAgents;
9662 }
9663 //----------------------------------------------------------------------
9664
9665 /*int GetContaminationType()
9666 {
9667 int contamination_type;
9668
9669 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
9670 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
9671 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
9672 const int DIRTY_MASK = eAgents.WOUND_AGENT;
9673
9674 Edible_Base edible = Edible_Base.Cast(this);
9675 int agents = GetAgents();
9676 if (edible)
9677 {
9678 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
9679 if (profile)
9680 {
9681 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
9682 }
9683 }
9684 if (agents & CONTAMINATED_MASK)
9685 {
9686 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
9687 }
9688 if (agents & POISONED_MASK)
9689 {
9690 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
9691 }
9692 if (agents & NERVE_GAS_MASK)
9693 {
9694 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
9695 }
9696 if (agents & DIRTY_MASK)
9697 {
9698 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
9699 }
9700
9701 return agents;
9702 }*/
9703
9704 // -------------------------------------------------------------------------
9705 bool LoadAgents(ParamsReadContext ctx, int version)
9706 {
9707 if (!ctx.Read(m_AttachedAgents))
9708 return false;
9709 return true;
9710 }
9711 // -------------------------------------------------------------------------
9713 {
9714
9716 }
9717 // -------------------------------------------------------------------------
9718
9720 override void CheckForRoofLimited(float timeTresholdMS = 3000)
9721 {
9722 super.CheckForRoofLimited(timeTresholdMS);
9723
9724 float time = g_Game.GetTime();
9725 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
9726 {
9727 m_PreviousRoofTestTime = time;
9728 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
9729 }
9730 }
9731
9732 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
9733 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
9734 {
9735 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
9736 {
9737 return 0;
9738 }
9739
9740 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
9741 {
9742 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
9743 if (filter)
9744 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
9745 else
9746 return 0;//otherwise return 0 when no filter attached
9747 }
9748
9749 string subclassPath, entryName;
9750
9751 switch (type)
9752 {
9753 case DEF_BIOLOGICAL:
9754 entryName = "biological";
9755 break;
9756 case DEF_CHEMICAL:
9757 entryName = "chemical";
9758 break;
9759 default:
9760 entryName = "biological";
9761 break;
9762 }
9763
9764 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
9765
9766 return g_Game.ConfigGetFloat(subclassPath + entryName);
9767 }
9768
9769
9770
9772 override void EEOnCECreate()
9773 {
9774 if (!IsMagazine())
9776
9778 }
9779
9780
9781 //-------------------------
9782 // OPEN/CLOSE USER ACTIONS
9783 //-------------------------
9785 void Open();
9786 void Close();
9787 bool IsOpen()
9788 {
9789 return true;
9790 }
9791
9792 override bool CanDisplayCargo()
9793 {
9794 return IsOpen();
9795 }
9796
9797
9798 // ------------------------------------------------------------
9799 // CONDITIONS
9800 // ------------------------------------------------------------
9801 override bool CanPutInCargo(EntityAI parent)
9802 {
9803 if (parent)
9804 {
9805 if (parent.IsInherited(DayZInfected))
9806 return true;
9807
9808 if (!parent.IsRuined())
9809 return true;
9810 }
9811
9812 return true;
9813 }
9814
9815 override bool CanPutAsAttachment(EntityAI parent)
9816 {
9817 if (!super.CanPutAsAttachment(parent))
9818 {
9819 return false;
9820 }
9821
9822 if (!IsRuined() && !parent.IsRuined())
9823 {
9824 return true;
9825 }
9826
9827 return false;
9828 }
9829
9830 override bool CanReceiveItemIntoCargo(EntityAI item)
9831 {
9832 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9833 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9834 // return false;
9835
9836 return super.CanReceiveItemIntoCargo(item);
9837 }
9838
9839 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
9840 {
9841 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9842 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9843 // return false;
9844
9845 GameInventory attachmentInv = attachment.GetInventory();
9846 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
9847 {
9848 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
9849 return false;
9850 }
9851
9852 InventoryLocation loc = new InventoryLocation();
9853 attachment.GetInventory().GetCurrentInventoryLocation(loc);
9854 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
9855 return false;
9856
9857 return super.CanReceiveAttachment(attachment, slotId);
9858 }
9859
9860 override bool CanReleaseAttachment(EntityAI attachment)
9861 {
9862 if (!super.CanReleaseAttachment(attachment))
9863 return false;
9864
9865 return GetInventory().AreChildrenAccessible();
9866 }
9867
9868 /*override bool CanLoadAttachment(EntityAI attachment)
9869 {
9870 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9871 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9872 // return false;
9873
9874 GameInventory attachmentInv = attachment.GetInventory();
9875 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
9876 {
9877 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
9878 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
9879
9880 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
9881 return false;
9882 }
9883
9884 return super.CanLoadAttachment(attachment);
9885 }*/
9886
9887 // Plays muzzle flash particle effects
9888 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9889 {
9890 int id = muzzle_owner.GetMuzzleID();
9891 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
9892
9893 if (WPOF_array)
9894 {
9895 for (int i = 0; i < WPOF_array.Count(); i++)
9896 {
9897 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
9898
9899 if (WPOF)
9900 {
9901 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
9902 }
9903 }
9904 }
9905 }
9906
9907 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
9908 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9909 {
9910 int id = muzzle_owner.GetMuzzleID();
9911 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
9912
9913 if (WPOBE_array)
9914 {
9915 for (int i = 0; i < WPOBE_array.Count(); i++)
9916 {
9917 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
9918
9919 if (WPOBE)
9920 {
9921 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
9922 }
9923 }
9924 }
9925 }
9926
9927 // Plays all weapon overheating particles
9928 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9929 {
9930 int id = muzzle_owner.GetMuzzleID();
9931 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9932
9933 if (WPOOH_array)
9934 {
9935 for (int i = 0; i < WPOOH_array.Count(); i++)
9936 {
9937 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9938
9939 if (WPOOH)
9940 {
9941 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
9942 }
9943 }
9944 }
9945 }
9946
9947 // Updates all weapon overheating particles
9948 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9949 {
9950 int id = muzzle_owner.GetMuzzleID();
9951 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9952
9953 if (WPOOH_array)
9954 {
9955 for (int i = 0; i < WPOOH_array.Count(); i++)
9956 {
9957 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9958
9959 if (WPOOH)
9960 {
9961 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
9962 }
9963 }
9964 }
9965 }
9966
9967 // Stops overheating particles
9968 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9969 {
9970 int id = muzzle_owner.GetMuzzleID();
9971 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9972
9973 if (WPOOH_array)
9974 {
9975 for (int i = 0; i < WPOOH_array.Count(); i++)
9976 {
9977 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9978
9979 if (WPOOH)
9980 {
9981 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
9982 }
9983 }
9984 }
9985 }
9986
9987 //----------------------------------------------------------------
9988 //Item Behaviour - unified approach
9989 override bool IsHeavyBehaviour()
9990 {
9991 if (m_ItemBehaviour == 0)
9992 {
9993 return true;
9994 }
9995
9996 return false;
9997 }
9998
9999 override bool IsOneHandedBehaviour()
10000 {
10001 if (m_ItemBehaviour == 1)
10002 {
10003 return true;
10004 }
10005
10006 return false;
10007 }
10008
10009 override bool IsTwoHandedBehaviour()
10010 {
10011 if (m_ItemBehaviour == 2)
10012 {
10013 return true;
10014 }
10015
10016 return false;
10017 }
10018
10019 bool IsDeployable()
10020 {
10021 return false;
10022 }
10023
10025 float GetDeployTime()
10026 {
10027 return UATimeSpent.DEFAULT_DEPLOY;
10028 }
10029
10030
10031 //----------------------------------------------------------------
10032 // Item Targeting (User Actions)
10033 override void SetTakeable(bool pState)
10034 {
10035 m_IsTakeable = pState;
10036 SetSynchDirty();
10037 }
10038
10039 override bool IsTakeable()
10040 {
10041 return m_IsTakeable;
10042 }
10043
10044 // For cases where we want to show object widget which cant be taken to hands
10046 {
10047 return false;
10048 }
10049
10051 protected void PreLoadSoundAttachmentType()
10052 {
10053 string att_type = "None";
10054
10055 if (ConfigIsExisting("soundAttType"))
10056 {
10057 att_type = ConfigGetString("soundAttType");
10058 }
10059
10060 m_SoundAttType = att_type;
10061 }
10062
10063 override string GetAttachmentSoundType()
10064 {
10065 return m_SoundAttType;
10066 }
10067
10068 //----------------------------------------------------------------
10069 //SOUNDS - ItemSoundHandler
10070 //----------------------------------------------------------------
10071
10072 string GetPlaceSoundset(); // played when deploy starts
10073 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
10074 string GetDeploySoundset(); // played when deploy sucessfully finishes
10075 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
10076 string GetFoldSoundset(); // played when fold sucessfully finishes
10077
10079 {
10080 if (!m_ItemSoundHandler)
10082
10083 return m_ItemSoundHandler;
10084 }
10085
10086 // override to initialize sounds
10087 protected void InitItemSounds()
10088 {
10089 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty && !GetInventoryItemType().SetDetachSoundEvent() && !GetInventoryItemType().SetAttachSoundEvent())
10090 return;
10091
10093
10094 if (GetPlaceSoundset() != string.Empty)
10095 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
10096
10097 if (GetDeploySoundset() != string.Empty)
10098 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
10099
10100 SoundParameters params = new SoundParameters();
10101 params.m_Loop = true;
10102 if (GetLoopDeploySoundset() != string.Empty)
10103 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
10104 }
10105
10106 // Start sound using ItemSoundHandler
10107 void StartItemSoundServer(int id, int slotId)
10108 {
10109 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
10110 {
10111 m_SoundSyncSlotID = slotId;
10112 m_SoundSyncPlay = id;
10113
10114 SetSynchDirty();
10115
10116 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
10117 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStartItemSoundServer, 100);
10118 }
10119 }
10120
10121 void StartItemSoundServer(int id)
10122 {
10123 StartItemSoundServer(id, InventorySlots.INVALID);
10124 }
10125
10126 // Stop sound using ItemSoundHandler
10127 void StopItemSoundServer(int id)
10128 {
10129 if (!g_Game.IsServer())
10130 return;
10131
10132 m_SoundSyncStop = id;
10133 SetSynchDirty();
10134
10135 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
10136 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStopItemSoundServer, 100);
10137 }
10138
10139 protected void ClearStartItemSoundServer()
10140 {
10141 m_SoundSyncPlay = 0;
10142 m_SoundSyncSlotID = InventorySlots.INVALID;
10143 }
10144
10145 protected void ClearStopItemSoundServer()
10146 {
10147 m_SoundSyncStop = 0;
10148 }
10149
10150 void OnApply(PlayerBase player);
10151
10153 {
10154 return 1.0;
10155 };
10156 //returns applicable selection
10157 array<string> GetHeadHidingSelection()
10158 {
10160 }
10161
10163 {
10165 }
10166
10167 WrittenNoteData GetWrittenNoteData() {};
10168
10170 {
10171 SetDynamicPhysicsLifeTime(0.01);
10172 m_ItemBeingDroppedPhys = false;
10173 }
10174
10176 {
10177 array<string> zone_names = new array<string>;
10178 GetDamageZones(zone_names);
10179 for (int i = 0; i < zone_names.Count(); i++)
10180 {
10181 SetHealthMax(zone_names.Get(i),"Health");
10182 }
10183 SetHealthMax("","Health");
10184 }
10185
10187 void SetZoneDamageCEInit()
10188 {
10189 float global_health = GetHealth01("","Health");
10190 array<string> zones = new array<string>;
10191 GetDamageZones(zones);
10192 //set damage of all zones to match global health level
10193 for (int i = 0; i < zones.Count(); i++)
10194 {
10195 SetHealth01(zones.Get(i),"Health",global_health);
10196 }
10197 }
10198
10200 bool IsCoverFaceForShave(string slot_name)
10201 {
10202 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
10203 }
10204
10205 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10206 {
10207 if (!hasRootAsPlayer)
10208 {
10209 if (refParentIB)
10210 {
10211 // parent is wet
10212 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
10213 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
10214 // parent has liquid inside
10215 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
10216 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
10217 // drying
10218 else if (m_VarWet > m_VarWetMin)
10219 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
10220 }
10221 else
10222 {
10223 // drying on ground or inside non-itembase (car, ...)
10224 if (m_VarWet > m_VarWetMin)
10225 AddWet(-1 * delta * GetDryingIncrement("ground"));
10226 }
10227 }
10228 }
10229
10230 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10231 {
10233 {
10234 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
10235 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
10236 {
10237 float heatPermCoef = 1.0;
10238 EntityAI ent = this;
10239 while (ent)
10240 {
10241 heatPermCoef *= ent.GetHeatPermeabilityCoef();
10242 ent = ent.GetHierarchyParent();
10243 }
10244
10245 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
10246 }
10247 }
10248 }
10249
10250 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
10251 {
10252 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
10253 EntityAI parent = GetHierarchyParent();
10254 if (!parent)
10255 {
10256 hasParent = false;
10257 hasRootAsPlayer = false;
10258 }
10259 else
10260 {
10261 hasParent = true;
10262 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
10263 refParentIB = ItemBase.Cast(parent);
10264 }
10265 }
10266
10267 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
10268 {
10269 // this is stub, implemented on Edible_Base
10270 }
10271
10272 bool CanDecay()
10273 {
10274 // return true used on selected food clases so they can decay
10275 return false;
10276 }
10277
10278 protected bool CanProcessDecay()
10279 {
10280 // this is stub, implemented on Edible_Base class
10281 // used to determine whether it is still necessary for the food to decay
10282 return false;
10283 }
10284
10285 protected bool CanHaveWetness()
10286 {
10287 // return true used on selected items that have a wetness effect
10288 return false;
10289 }
10290
10292 bool CanBeConsumed(ConsumeConditionData data = null)
10293 {
10294 return !GetIsFrozen() && IsOpen();
10295 }
10296
10297 override void ProcessVariables()
10298 {
10299 bool hasParent = false, hasRootAsPlayer = false;
10300 ItemBase refParentIB;
10301
10302 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
10303 bool foodDecay = g_Game.IsFoodDecayEnabled();
10304
10305 if (wwtu || foodDecay)
10306 {
10307 bool processWetness = wwtu && CanHaveWetness();
10308 bool processTemperature = wwtu && CanHaveTemperature();
10309 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
10310
10311 if (processWetness || processTemperature || processDecay)
10312 {
10313 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
10314
10315 if (processWetness)
10316 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10317
10318 if (processTemperature)
10319 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10320
10321 if (processDecay)
10322 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
10323 }
10324 }
10325 }
10326
10329 {
10330 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
10331 }
10332
10333 override float GetTemperatureFreezeThreshold()
10334 {
10336 return Liquid.GetFreezeThreshold(GetLiquidType());
10337
10338 return super.GetTemperatureFreezeThreshold();
10339 }
10340
10341 override float GetTemperatureThawThreshold()
10342 {
10344 return Liquid.GetThawThreshold(GetLiquidType());
10345
10346 return super.GetTemperatureThawThreshold();
10347 }
10348
10349 override float GetItemOverheatThreshold()
10350 {
10352 return Liquid.GetBoilThreshold(GetLiquidType());
10353
10354 return super.GetItemOverheatThreshold();
10355 }
10356
10357 override float GetTemperatureFreezeTime()
10358 {
10359 if (HasQuantity())
10360 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
10361
10362 return super.GetTemperatureFreezeTime();
10363 }
10364
10365 override float GetTemperatureThawTime()
10366 {
10367 if (HasQuantity())
10368 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
10369
10370 return super.GetTemperatureThawTime();
10371 }
10372
10374 void AffectLiquidContainerOnFill(int liquid_type, float amount);
10376 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
10377
10378 bool IsCargoException4x3(EntityAI item)
10379 {
10380 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
10381 }
10382
10384 {
10385 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
10386 }
10387
10389 void AddLightSourceItem(ItemBase lightsource)
10390 {
10391 m_LightSourceItem = lightsource;
10392 }
10393
10395 {
10396 m_LightSourceItem = null;
10397 }
10398
10400 {
10401 return m_LightSourceItem;
10402 }
10403
10405 array<int> GetValidFinishers()
10406 {
10407 return null;
10408 }
10409
10411 bool GetActionWidgetOverride(out typename name)
10412 {
10413 return false;
10414 }
10415
10416 bool PairWithDevice(notnull ItemBase otherDevice)
10417 {
10418 if (g_Game.IsServer())
10419 {
10420 ItemBase explosive = otherDevice;
10422 if (!trg)
10423 {
10424 trg = RemoteDetonatorTrigger.Cast(otherDevice);
10425 explosive = this;
10426 }
10427
10428 explosive.PairRemote(trg);
10429 trg.SetControlledDevice(explosive);
10430
10431 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
10432 trg.SetPersistentPairID(persistentID);
10433 explosive.SetPersistentPairID(persistentID);
10434
10435 return true;
10436 }
10437 return false;
10438 }
10439
10441 float GetBaitEffectivity()
10442 {
10443 float ret = 1.0;
10444 if (HasQuantity())
10445 ret *= GetQuantityNormalized();
10446 ret *= GetHealth01();
10447
10448 return ret;
10449 }
10450
10451 #ifdef DEVELOPER
10452 override void SetDebugItem()
10453 {
10454 super.SetDebugItem();
10455 _itemBase = this;
10456 }
10457
10458 override string GetDebugText()
10459 {
10460 string text = super.GetDebugText();
10461
10462 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
10463 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
10464
10465 return text;
10466 }
10467 #endif
10468
10469 bool CanBeUsedForSuicide()
10470 {
10471 return true;
10472 }
10473
10475 //DEPRECATED BELOW
10477 // Backwards compatibility
10478 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10479 {
10480 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
10481 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
10482 }
10483
10484 // replaced by ItemSoundHandler
10485 protected EffectSound m_SoundDeployFinish;
10486 protected EffectSound m_SoundPlace;
10487 protected EffectSound m_DeployLoopSoundEx;
10488 protected EffectSound m_SoundDeploy;
10489 bool m_IsPlaceSound;
10490 bool m_IsDeploySound;
10492
10493 string GetDeployFinishSoundset();
10494 void PlayDeploySound();
10495 void PlayDeployFinishSound();
10496 void PlayPlaceSound();
10497 void PlayDeployLoopSoundEx();
10498 void StopDeployLoopSoundEx();
10499 void SoundSynchRemoteReset();
10500 void SoundSynchRemote();
10501 bool UsesGlobalDeploy(){return false;}
10502 bool CanPlayDeployLoopSound(){return false;}
10504 bool IsPlaceSound(){return m_IsPlaceSound;}
10505 bool IsDeploySound(){return m_IsDeploySound;}
10506 void SetIsPlaceSound(bool is_place_sound);
10507 void SetIsDeploySound(bool is_deploy_sound);
10508
10509 [Obsolete("Use ItemSoundHandler instead")]
10511 void PlayAttachSound(string slot_type)
10512 {
10513 if (!g_Game.IsDedicatedServer())
10514 {
10515 if (ConfigIsExisting("attachSoundSet"))
10516 {
10517 string cfg_path = "";
10518 string soundset = "";
10519 string type_name = GetType();
10520
10521 TStringArray cfg_soundset_array = new TStringArray;
10522 TStringArray cfg_slot_array = new TStringArray;
10523 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
10524 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
10525
10526 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
10527 {
10528 for (int i = 0; i < cfg_soundset_array.Count(); i++)
10529 {
10530 if (cfg_slot_array[i] == slot_type)
10531 {
10532 soundset = cfg_soundset_array[i];
10533 break;
10534 }
10535 }
10536 }
10537
10538 if (soundset != "")
10539 {
10540 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
10541 sound.SetAutodestroy(true);
10542 }
10543 }
10544 }
10545 }
10546
10547 void PlayDetachSound(string slot_type) {}
10548}
10549
10550EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
10551{
10552 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
10553 if (entity)
10554 {
10555 bool is_item = entity.IsInherited(ItemBase);
10556 if (is_item && full_quantity)
10557 {
10558 ItemBase item = ItemBase.Cast(entity);
10559 item.SetQuantity(item.GetQuantityInit());
10560 }
10561 }
10562 else
10563 {
10564 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
10565 return NULL;
10566 }
10567 return entity;
10568}
10569
10570void SetupSpawnedItem(ItemBase item, float health, float quantity)
10571{
10572 if (item)
10573 {
10574 if (health > 0)
10575 item.SetHealth("", "", health);
10576
10577 if (item.CanHaveTemperature())
10578 {
10579 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
10580 if (item.CanFreeze())
10581 item.SetFrozen(false);
10582 }
10583
10584 if (item.HasEnergyManager())
10585 {
10586 if (quantity >= 0)
10587 {
10588 item.GetCompEM().SetEnergy0To1(quantity);
10589 }
10590 else
10591 {
10592 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
10593 }
10594 }
10595 else if (item.IsMagazine())
10596 {
10597 Magazine mag = Magazine.Cast(item);
10598 if (quantity >= 0)
10599 {
10600 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
10601 }
10602 else
10603 {
10604 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
10605 }
10606
10607 }
10608 else
10609 {
10610 if (quantity >= 0)
10611 {
10612 item.SetQuantityNormalized(quantity, false);
10613 }
10614 else
10615 {
10616 item.SetQuantity(Math.AbsFloat(quantity));
10617 }
10618
10619 }
10620 }
10621}
10622
10623#ifdef DEVELOPER
10624ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
10625#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()