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

◆ UnlockFromParent()

void SpawnItemOnLocation::UnlockFromParent ( )
private

Unlocks this item from its attachment slot of its parent.

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

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

Используется в DestroyPlant(), CarWheel_Ruined::EEHealthLevelChanged(), InventoryItemSuper::EEHealthLevelChanged() и RemovePlantEx().