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

◆ OnEndPlacement()

void SpawnItemOnLocation::OnEndPlacement ( )
private

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

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