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

◆ CombineItemsClient()

override void SpawnItemOnLocation::CombineItemsClient ( EntityAI entity2,
bool use_stack_max = true )
private

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

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