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

◆ CombineItemsEx()

override void SpawnItemOnLocation::CombineItemsEx ( EntityAI entity2,
bool use_stack_max = true )
protected

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

7198{
7199 override bool CanPutAsAttachment(EntityAI parent)
7200 {
7201 return true;
7202 }
7203};
7204
7206{
7207
7208};
7209
7210//const bool QUANTITY_DEBUG_REMOVE_ME = false;
7211
7212class ItemBase extends InventoryItem
7213{
7217
7219
7220 static int m_DebugActionsMask;
7222 // ============================================
7223 // Variable Manipulation System
7224 // ============================================
7225 // Quantity
7226
7227 float m_VarQuantity;
7228 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
7230 int m_VarQuantityMin;
7231 int m_VarQuantityMax;
7232 int m_Count;
7233 float m_VarStackMax;
7234 float m_StoreLoadedQuantity = float.LOWEST;
7235 // Wet
7236 float m_VarWet;
7237 float m_VarWetPrev;//for client to know wetness changed during synchronization
7238 float m_VarWetInit;
7239 float m_VarWetMin;
7240 float m_VarWetMax;
7241 // Cleanness
7242 int m_Cleanness;
7243 int m_CleannessInit;
7244 int m_CleannessMin;
7245 int m_CleannessMax;
7246 // impact sounds
7248 bool m_CanPlayImpactSound = true;
7249 float m_ImpactSpeed;
7251 //
7252 float m_HeatIsolation;
7253 float m_ItemModelLength;
7254 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
7256 int m_VarLiquidType;
7257 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
7258 int m_QuickBarBonus;
7259 bool m_IsBeingPlaced;
7260 bool m_IsHologram;
7261 bool m_IsTakeable;
7262 bool m_ThrowItemOnDrop;
7265 bool m_FixDamageSystemInit = false; //can be changed on storage version check
7266 bool can_this_be_combined; //Check if item can be combined
7267 bool m_CanThisBeSplit; //Check if item can be split
7268 bool m_IsStoreLoad = false;
7269 bool m_CanShowQuantity;
7270 bool m_HasQuantityBar;
7271 protected bool m_CanBeDigged;
7272 protected bool m_IsResultOfSplit
7273
7274 string m_SoundAttType;
7275 // items color variables
7280 //-------------------------------------------------------
7281
7282 // light source managing
7284
7288
7289 //==============================================
7290 // agent system
7291 private int m_AttachedAgents;
7292
7294 void TransferModifiers(PlayerBase reciever);
7295
7296
7297 // Weapons & suppressors particle effects
7301 ref static map<string, int> m_WeaponTypeToID;
7302 static int m_LastRegisteredWeaponID = 0;
7303
7304 // Overheating effects
7306 float m_OverheatingShots;
7307 ref Timer m_CheckOverheating;
7308 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
7309 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
7310 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
7311 ref array <ref OverheatingParticle> m_OverheatingParticles;
7312
7314 protected bool m_HideSelectionsBySlot;
7315
7316 // Admin Log
7317 PluginAdminLog m_AdminLog;
7318
7319 // misc
7320 ref Timer m_PhysDropTimer;
7321
7322 // Attachment Locking variables
7323 ref array<int> m_CompatibleLocks;
7324 protected int m_LockType;
7325 protected ref EffectSound m_LockingSound;
7326 protected string m_LockSoundSet;
7327
7328 // ItemSoundHandler variables
7329 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
7330 protected int m_SoundSyncPlay; // id for sound to play
7331 protected int m_SoundSyncStop; // id for sound to stop
7332 protected int m_SoundSyncSlotID = InventorySlots.INVALID; // slot id for attach/detach sound based on slot
7333
7335
7336 //temperature
7337 private float m_TemperaturePerQuantityWeight;
7338
7339 // -------------------------------------------------------------------------
7340 void ItemBase()
7341 {
7342 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
7346
7347 if (!g_Game.IsDedicatedServer())
7348 {
7349 if (HasMuzzle())
7350 {
7352
7354 {
7356 }
7357 }
7358
7360 m_ActionsInitialize = false;
7361 }
7362
7363 m_OldLocation = null;
7364
7365 if (g_Game.IsServer())
7366 {
7367 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
7368 }
7369
7370 if (ConfigIsExisting("headSelectionsToHide"))
7371 {
7373 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
7374 }
7375
7376 m_HideSelectionsBySlot = false;
7377 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
7378 {
7379 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
7380 }
7381
7382 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
7383
7384 m_IsResultOfSplit = false;
7385
7387 }
7388
7389 override void InitItemVariables()
7390 {
7391 super.InitItemVariables();
7392
7393 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
7394 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
7395 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
7396 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
7397 m_VarStackMax = ConfigGetFloat("varStackMax");
7398 m_Count = ConfigGetInt("count");
7399
7400 m_CanShowQuantity = ConfigGetBool("quantityShow");
7401 m_HasQuantityBar = ConfigGetBool("quantityBar");
7402
7403 m_CleannessInit = ConfigGetInt("varCleannessInit");
7405 m_CleannessMin = ConfigGetInt("varCleannessMin");
7406 m_CleannessMax = ConfigGetInt("varCleannessMax");
7407
7408 m_WantPlayImpactSound = false;
7409 m_ImpactSpeed = 0.0;
7410
7411 m_VarWetInit = ConfigGetFloat("varWetInit");
7413 m_VarWetMin = ConfigGetFloat("varWetMin");
7414 m_VarWetMax = ConfigGetFloat("varWetMax");
7415
7416 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
7417 if (IsLiquidContainer() && GetQuantity() != 0)
7419 m_IsBeingPlaced = false;
7420 m_IsHologram = false;
7421 m_IsTakeable = true;
7422 m_CanBeMovedOverride = false;
7426 m_CanBeDigged = ConfigGetBool("canBeDigged");
7427
7428 m_CompatibleLocks = new array<int>();
7429 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
7430 m_LockType = ConfigGetInt("lockType");
7431
7432 //Define if item can be split and set ability to be combined accordingly
7433 m_CanThisBeSplit = false;
7434 can_this_be_combined = false;
7435 if (ConfigIsExisting("canBeSplit"))
7436 {
7437 can_this_be_combined = ConfigGetBool("canBeSplit");
7439 }
7440
7441 m_ItemBehaviour = -1;
7442 if (ConfigIsExisting("itemBehaviour"))
7443 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
7444
7445 //RegisterNetSyncVariableInt("m_VariablesMask");
7446 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7447 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
7448 RegisterNetSyncVariableInt("m_VarLiquidType");
7449 RegisterNetSyncVariableInt("m_Cleanness",0,1);
7450
7451 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
7452 RegisterNetSyncVariableFloat("m_ImpactSpeed");
7453 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
7454
7455 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
7456 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
7457 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
7458 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
7459
7460 RegisterNetSyncVariableBool("m_IsBeingPlaced");
7461 RegisterNetSyncVariableBool("m_IsTakeable");
7462 RegisterNetSyncVariableBool("m_IsHologram");
7463
7466 {
7467 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
7468 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
7469 RegisterNetSyncVariableInt("m_SoundSyncSlotID", int.MIN, int.MAX);
7470 }
7471
7472 m_LockSoundSet = ConfigGetString("lockSoundSet");
7473
7475 if (ConfigIsExisting("temperaturePerQuantityWeight"))
7476 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
7477
7478 m_SoundSyncSlotID = -1;
7479 }
7480
7481 override int GetQuickBarBonus()
7482 {
7483 return m_QuickBarBonus;
7484 }
7485
7486 void InitializeActions()
7487 {
7489 if (!m_InputActionMap)
7490 {
7492 m_InputActionMap = iam;
7493 SetActions();
7495 }
7496 }
7497
7498 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
7499 {
7501 {
7502 m_ActionsInitialize = true;
7504 }
7505
7506 actions = m_InputActionMap.Get(action_input_type);
7507 }
7508
7509 void SetActions()
7510 {
7511 AddAction(ActionTakeItem);
7512 AddAction(ActionTakeItemToHands);
7513 AddAction(ActionWorldCraft);
7515 AddAction(ActionAttachWithSwitch);
7516 }
7517
7518 void SetActionAnimOverrides(); // Override action animation for specific item
7519
7520 void AddAction(typename actionName)
7521 {
7522 ActionBase action = ActionManagerBase.GetAction(actionName);
7523
7524 if (!action)
7525 {
7526 Debug.LogError("Action " + actionName + " dosn't exist!");
7527 return;
7528 }
7529
7530 typename ai = action.GetInputType();
7531 if (!ai)
7532 {
7533 m_ActionsInitialize = false;
7534 return;
7535 }
7536
7537 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
7538 if (!action_array)
7539 {
7540 action_array = new array<ActionBase_Basic>;
7541 m_InputActionMap.Insert(ai, action_array);
7542 }
7543 if (LogManager.IsActionLogEnable())
7544 {
7545 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
7546 }
7547
7548 if (action_array.Find(action) != -1)
7549 {
7550 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
7551 }
7552 else
7553 {
7554 action_array.Insert(action);
7555 }
7556 }
7557
7558 void RemoveAction(typename actionName)
7559 {
7560 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7561 ActionBase action = player.GetActionManager().GetAction(actionName);
7562 typename ai = action.GetInputType();
7563 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
7564
7565 if (action_array)
7566 {
7567 action_array.RemoveItem(action);
7568 }
7569 }
7570
7571 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
7572 // Set -1 for params which should stay in default state
7573 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
7574 {
7575 ActionOverrideData overrideData = new ActionOverrideData();
7576 overrideData.m_CommandUID = commandUID;
7577 overrideData.m_CommandUIDProne = commandUIDProne;
7578 overrideData.m_StanceMask = stanceMask;
7579
7580 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
7581 if (!actionMap) // create new map of action > overidables map
7582 {
7583 actionMap = new TActionAnimOverrideMap();
7584 m_ItemActionOverrides.Insert(action, actionMap);
7585 }
7586
7587 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
7588
7589 }
7590
7591 void OnItemInHandsPlayerSwimStart(PlayerBase player);
7592
7593 ScriptedLightBase GetLight();
7594
7595 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
7596 void LoadParticleConfigOnFire(int id)
7597 {
7598 if (!m_OnFireEffect)
7600
7603
7604 string config_to_search = "CfgVehicles";
7605 string muzzle_owner_config;
7606
7607 if (!m_OnFireEffect.Contains(id))
7608 {
7609 if (IsInherited(Weapon))
7610 config_to_search = "CfgWeapons";
7611
7612 muzzle_owner_config = config_to_search + " " + GetType() + " ";
7613
7614 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
7615
7616 int config_OnFire_subclass_count = g_Game.ConfigGetChildrenCount(config_OnFire_class);
7617
7618 if (config_OnFire_subclass_count > 0)
7619 {
7620 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
7621
7622 for (int i = 0; i < config_OnFire_subclass_count; i++)
7623 {
7624 string particle_class = "";
7625 g_Game.ConfigGetChildName(config_OnFire_class, i, particle_class);
7626 string config_OnFire_entry = config_OnFire_class + particle_class;
7627 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
7628 WPOF_array.Insert(WPOF);
7629 }
7630
7631
7632 m_OnFireEffect.Insert(id, WPOF_array);
7633 }
7634 }
7635
7636 if (!m_OnBulletCasingEjectEffect.Contains(id))
7637 {
7638 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
7639 muzzle_owner_config = config_to_search + " " + GetType() + " ";
7640
7641 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
7642
7643 int config_OnBulletCasingEject_count = g_Game.ConfigGetChildrenCount(config_OnBulletCasingEject_class);
7644
7645 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
7646 {
7647 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
7648
7649 for (i = 0; i < config_OnBulletCasingEject_count; i++)
7650 {
7651 string particle_class2 = "";
7652 g_Game.ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
7653 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
7654 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
7655 WPOBE_array.Insert(WPOBE);
7656 }
7657
7658
7659 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
7660 }
7661 }
7662 }
7663
7664 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
7666 {
7669
7670 if (!m_OnOverheatingEffect.Contains(id))
7671 {
7672 string config_to_search = "CfgVehicles";
7673
7674 if (IsInherited(Weapon))
7675 config_to_search = "CfgWeapons";
7676
7677 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
7678 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
7679
7680 if (g_Game.ConfigIsExisting(config_OnOverheating_class))
7681 {
7682
7683 m_ShotsToStartOverheating = g_Game.ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
7684
7686 {
7687 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
7688 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
7689 Error(error);
7690 return;
7691 }
7692
7693 m_OverheatingDecayInterval = g_Game.ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
7694 m_MaxOverheatingValue = g_Game.ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
7695
7696
7697
7698 int config_OnOverheating_subclass_count = g_Game.ConfigGetChildrenCount(config_OnOverheating_class);
7699 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
7700
7701 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
7702 {
7703 string particle_class = "";
7704 g_Game.ConfigGetChildName(config_OnOverheating_class, i, particle_class);
7705 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
7706 int entry_type = g_Game.ConfigGetType(config_OnOverheating_entry);
7707
7708 if (entry_type == CT_CLASS)
7709 {
7710 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
7711 WPOOH_array.Insert(WPOF);
7712 }
7713 }
7714
7715
7716 m_OnOverheatingEffect.Insert(id, WPOOH_array);
7717 }
7718 }
7719 }
7720
7721 float GetOverheatingValue()
7722 {
7723 return m_OverheatingShots;
7724 }
7725
7726 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
7727 {
7728 if (m_MaxOverheatingValue > 0)
7729 {
7731
7732 if (!m_CheckOverheating)
7734
7736 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
7737
7738 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7739 }
7740 }
7741
7742 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7743 {
7745 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7746
7748 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7749
7751 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7752
7754 {
7756 }
7757 }
7758
7760 {
7762 }
7763
7764 void OnOverheatingDecay()
7765 {
7766 if (m_MaxOverheatingValue > 0)
7767 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
7768 else
7770
7771 if (m_OverheatingShots <= 0)
7772 {
7775 }
7776 else
7777 {
7778 if (!m_CheckOverheating)
7780
7782 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
7783 }
7784
7785 CheckOverheating(this, "", this);
7786 }
7787
7788 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7789 {
7791 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
7792 }
7793
7794 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7795 {
7797 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
7799 }
7800
7801 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7802 {
7804 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7805 }
7806
7807 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
7808 {
7810 m_OverheatingParticles = new array<ref OverheatingParticle>;
7811
7812 OverheatingParticle OP = new OverheatingParticle();
7813 OP.RegisterParticle(p);
7814 OP.SetOverheatingLimitMin(min_heat_coef);
7815 OP.SetOverheatingLimitMax(max_heat_coef);
7816 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
7817
7818 m_OverheatingParticles.Insert(OP);
7819 }
7820
7821 float GetOverheatingCoef()
7822 {
7823 if (m_MaxOverheatingValue > 0)
7825
7826 return -1;
7827 }
7828
7830 {
7832 {
7833 float overheat_coef = GetOverheatingCoef();
7834 int count = m_OverheatingParticles.Count();
7835
7836 for (int i = count; i > 0; --i)
7837 {
7838 int id = i - 1;
7839 OverheatingParticle OP = m_OverheatingParticles.Get(id);
7840 Particle p = OP.GetParticle();
7841
7842 float overheat_min = OP.GetOverheatingLimitMin();
7843 float overheat_max = OP.GetOverheatingLimitMax();
7844
7845 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
7846 {
7847 if (p)
7848 {
7849 p.Stop();
7850 OP.RegisterParticle(null);
7851 }
7852 }
7853 }
7854 }
7855 }
7856
7858 {
7860 {
7861 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
7862 {
7863 int id = i - 1;
7864 OverheatingParticle OP = m_OverheatingParticles.Get(id);
7865
7866 if (OP)
7867 {
7868 Particle p = OP.GetParticle();
7869
7870 if (p)
7871 {
7872 p.Stop();
7873 }
7874
7875 delete OP;
7876 }
7877 }
7878
7879 m_OverheatingParticles.Clear();
7881 }
7882 }
7883
7885 float GetInfectionChance(int system = 0, Param param = null)
7886 {
7887 return 0.0;
7888 }
7889
7890
7891 float GetDisinfectQuantity(int system = 0, Param param1 = null)
7892 {
7893 return 250;//default value
7894 }
7895
7896 float GetFilterDamageRatio()
7897 {
7898 return 0;
7899 }
7900
7902 bool HasMuzzle()
7903 {
7904 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
7905 return true;
7906
7907 return false;
7908 }
7909
7911 int GetMuzzleID()
7912 {
7913 if (!m_WeaponTypeToID)
7914 m_WeaponTypeToID = new map<string, int>;
7915
7916 if (m_WeaponTypeToID.Contains(GetType()))
7917 {
7918 return m_WeaponTypeToID.Get(GetType());
7919 }
7920 else
7921 {
7922 // Register new weapon ID
7924 }
7925
7927 }
7928
7935 {
7936 return -1;
7937 }
7938
7939
7940
7941 // -------------------------------------------------------------------------
7942 void ~ItemBase()
7943 {
7944 if (g_Game && g_Game.GetPlayer() && (!g_Game.IsDedicatedServer()))
7945 {
7946 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7947 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
7948
7949 if (r_index >= 0)
7950 {
7951 InventoryLocation r_il = new InventoryLocation;
7952 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
7953
7954 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
7955 int r_type = r_il.GetType();
7956 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
7957 {
7958 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7959 }
7960 else if (r_type == InventoryLocationType.ATTACHMENT)
7961 {
7962 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7963 }
7964
7965 }
7966
7967 player.GetHumanInventory().ClearUserReservedLocation(this);
7968 }
7969
7970 if (m_LockingSound)
7971 SEffectManager.DestroyEffect(m_LockingSound);
7972 }
7973
7974
7975
7976 // -------------------------------------------------------------------------
7977 static int GetDebugActionsMask()
7978 {
7979 return ItemBase.m_DebugActionsMask;
7980 }
7981
7982 static bool HasDebugActionsMask(int mask)
7983 {
7984 return ItemBase.m_DebugActionsMask & mask;
7985 }
7986
7987 static void SetDebugActionsMask(int mask)
7988 {
7989 ItemBase.m_DebugActionsMask = mask;
7990 }
7991
7992 static void AddDebugActionsMask(int mask)
7993 {
7994 ItemBase.m_DebugActionsMask |= mask;
7995 }
7996
7997 static void RemoveDebugActionsMask(int mask)
7998 {
7999 ItemBase.m_DebugActionsMask &= ~mask;
8000 }
8001
8002 static void ToggleDebugActionsMask(int mask)
8003 {
8004 if (HasDebugActionsMask(mask))
8005 {
8007 }
8008 else
8009 {
8010 AddDebugActionsMask(mask);
8011 }
8012 }
8013
8014 // -------------------------------------------------------------------------
8015 void SetCEBasedQuantity()
8016 {
8017 if (GetEconomyProfile())
8018 {
8019 float q_max = GetEconomyProfile().GetQuantityMax();
8020 if (q_max > 0)
8021 {
8022 float q_min = GetEconomyProfile().GetQuantityMin();
8023 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
8024
8025 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
8026 {
8027 ComponentEnergyManager comp = GetCompEM();
8028 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
8029 {
8030 comp.SetEnergy0To1(quantity_randomized);
8031 }
8032 }
8033 else if (HasQuantity())
8034 {
8035 SetQuantityNormalized(quantity_randomized, false);
8036 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
8037 }
8038
8039 }
8040 }
8041 }
8042
8044 void LockToParent()
8045 {
8046 EntityAI parent = GetHierarchyParent();
8047
8048 if (parent)
8049 {
8050 InventoryLocation inventory_location_to_lock = new InventoryLocation;
8051 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
8052 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
8053 }
8054 }
8055
8057 void UnlockFromParent()
8058 {
8059 EntityAI parent = GetHierarchyParent();
8060
8061 if (parent)
8062 {
8063 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
8064 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
8065 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
8066 }
8067 }
8068
8069 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
8070 {
8071 /*
8072 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
8073 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, g_Game.GetPlayer());
8074 */
8075 ItemBase item2 = ItemBase.Cast(entity2);
8076
8077 if (g_Game.IsClient())
8078 {
8079 if (ScriptInputUserData.CanStoreInputUserData())
8080 {
8081 ScriptInputUserData ctx = new ScriptInputUserData;
8083 ctx.Write(-1);
8084 ItemBase i1 = this; // @NOTE: workaround for correct serialization
8085 ctx.Write(i1);
8086 ctx.Write(item2);
8087 ctx.Write(use_stack_max);
8088 ctx.Write(-1);
8089 ctx.Send();
8090
8091 if (IsCombineAll(item2, use_stack_max))
8092 {
8093 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
8094 }
8095 }
8096 }
8097 else if (!g_Game.IsMultiplayer())
8098 {
8099 CombineItems(item2, use_stack_max);
8100 }
8101 }
8102
8103 bool IsLiquidPresent()
8104 {
8105 return (GetLiquidType() != 0 && HasQuantity());
8106 }
8107
8108 bool IsLiquidContainer()
8109 {
8110 return m_LiquidContainerMask != 0;
8111 }
8112
8114 {
8115 return m_LiquidContainerMask;
8116 }
8117
8118 bool IsBloodContainer()
8119 {
8120 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
8121 return false;
8122 }
8123
8124 bool IsNVG()
8125 {
8126 return false;
8127 }
8128
8131 bool IsExplosive()
8132 {
8133 return false;
8134 }
8135
8137 {
8138 return "";
8139 }
8140
8142
8143 bool IsLightSource()
8144 {
8145 return false;
8146 }
8147
8149 {
8150 return true;
8151 }
8152
8153 //--- ACTION CONDITIONS
8154 //direction
8155 bool IsFacingPlayer(PlayerBase player, string selection)
8156 {
8157 return true;
8158 }
8159
8160 bool IsPlayerInside(PlayerBase player, string selection)
8161 {
8162 return true;
8163 }
8164
8165 override bool CanObstruct()
8166 {
8167 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
8168 return !player || !IsPlayerInside(player, "");
8169 }
8170
8171 override bool IsBeingPlaced()
8172 {
8173 return m_IsBeingPlaced;
8174 }
8175
8176 void SetIsBeingPlaced(bool is_being_placed)
8177 {
8178 m_IsBeingPlaced = is_being_placed;
8179 if (!is_being_placed)
8181 SetSynchDirty();
8182 }
8183
8184 //server-side
8185 void OnEndPlacement() {}
8186
8187 override bool IsHologram()
8188 {
8189 return m_IsHologram;
8190 }
8191
8192 bool CanBeDigged()
8193 {
8194 return m_CanBeDigged;
8195 }
8196
8198 {
8199 return 1;
8200 }
8201
8202 bool CanMakeGardenplot()
8203 {
8204 return false;
8205 }
8206
8207 void SetIsHologram(bool is_hologram)
8208 {
8209 m_IsHologram = is_hologram;
8210 SetSynchDirty();
8211 }
8212 /*
8213 protected float GetNutritionalEnergy()
8214 {
8215 Edible_Base edible = Edible_Base.Cast(this);
8216 return edible.GetFoodEnergy();
8217 }
8218
8219 protected float GetNutritionalWaterContent()
8220 {
8221 Edible_Base edible = Edible_Base.Cast(this);
8222 return edible.GetFoodWater();
8223 }
8224
8225 protected float GetNutritionalIndex()
8226 {
8227 Edible_Base edible = Edible_Base.Cast(this);
8228 return edible.GetFoodNutritionalIndex();
8229 }
8230
8231 protected float GetNutritionalFullnessIndex()
8232 {
8233 Edible_Base edible = Edible_Base.Cast(this);
8234 return edible.GetFoodTotalVolume();
8235 }
8236
8237 protected float GetNutritionalToxicity()
8238 {
8239 Edible_Base edible = Edible_Base.Cast(this);
8240 return edible.GetFoodToxicity();
8241
8242 }
8243 */
8244
8245
8246 // -------------------------------------------------------------------------
8247 override void OnMovedInsideCargo(EntityAI container)
8248 {
8249 super.OnMovedInsideCargo(container);
8250
8251 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
8252 }
8253
8254 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
8255 {
8256 super.EEItemLocationChanged(oldLoc, newLoc);
8257
8258 PlayerBase newPlayer = null;
8259 PlayerBase oldPlayer = null;
8260
8261 if (newLoc.GetParent())
8262 newPlayer = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
8263
8264 if (oldLoc.GetParent())
8265 oldPlayer = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
8266
8267 if (oldPlayer && oldLoc.GetType() == InventoryLocationType.HANDS)
8268 {
8269 int rIndex = oldPlayer.GetHumanInventory().FindUserReservedLocationIndex(this);
8270
8271 if (rIndex >= 0)
8272 {
8273 InventoryLocation rIl = new InventoryLocation;
8274 oldPlayer.GetHumanInventory().GetUserReservedLocation(rIndex, rIl);
8275
8276 oldPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(rIndex);
8277 int rType = rIl.GetType();
8278 if (rType == InventoryLocationType.CARGO || rType == InventoryLocationType.PROXYCARGO)
8279 {
8280 rIl.GetParent().GetOnReleaseLock().Invoke(this);
8281 }
8282 else if (rType == InventoryLocationType.ATTACHMENT)
8283 {
8284 rIl.GetParent().GetOnAttachmentReleaseLock().Invoke(this, rIl.GetSlot());
8285 }
8286
8287 }
8288 }
8289
8290 if (newLoc.GetType() == InventoryLocationType.HANDS && oldLoc.GetType() != InventoryLocationType.TEMP)
8291 {
8292 if (newPlayer)
8293 newPlayer.ForceStandUpForHeavyItems(newLoc.GetItem());
8294
8295 if (newPlayer == oldPlayer)
8296 {
8297 if (oldLoc.GetParent() && newPlayer.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
8298 {
8299 if (oldLoc.GetType() == InventoryLocationType.CARGO)
8300 {
8301 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
8302 {
8303 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
8304 }
8305 }
8306 else
8307 {
8308 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
8309 }
8310 }
8311
8312 if (newPlayer.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
8313 {
8314 int type = oldLoc.GetType();
8315 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
8316 {
8317 oldLoc.GetParent().GetOnSetLock().Invoke(this);
8318 }
8319 else if (type == InventoryLocationType.ATTACHMENT)
8320 {
8321 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
8322 }
8323 }
8324 if (!m_OldLocation)
8325 {
8326 m_OldLocation = new InventoryLocation;
8327 }
8328 m_OldLocation.Copy(oldLoc);
8329 }
8330 else
8331 {
8332 if (m_OldLocation)
8333 {
8334 m_OldLocation.Reset();
8335 }
8336 }
8337
8338 g_Game.GetAnalyticsClient().OnItemAttachedAtPlayer(this,"Hands");
8339 }
8340 else
8341 {
8342 if (newPlayer)
8343 {
8344 int resIndex = newPlayer.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
8345 if (resIndex >= 0)
8346 {
8347 InventoryLocation il = new InventoryLocation;
8348 newPlayer.GetHumanInventory().GetUserReservedLocation(resIndex, il);
8349 ItemBase it = ItemBase.Cast(il.GetItem());
8350 newPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(resIndex);
8351 int rel_type = il.GetType();
8352 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
8353 {
8354 il.GetParent().GetOnReleaseLock().Invoke(it);
8355 }
8356 else if (rel_type == InventoryLocationType.ATTACHMENT)
8357 {
8358 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
8359 }
8360 //it.GetOnReleaseLock().Invoke(it);
8361 }
8362 }
8363 else if (oldPlayer && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
8364 {
8365 //ThrowPhysically(oldPlayer, vector.Zero);
8366 m_ThrowItemOnDrop = false;
8367 }
8368
8369 if (m_OldLocation)
8370 {
8371 m_OldLocation.Reset();
8372 }
8373 }
8374
8375 if (oldLoc.GetType() == InventoryLocationType.TEMP)
8376 {
8377 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Remove(oldLoc.GetItem());
8378 }
8379
8380 if (newLoc.GetType() == InventoryLocationType.TEMP)
8381 {
8382 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Add(oldLoc.GetItem());
8383 }
8384 }
8385
8386 override void EOnContact(IEntity other, Contact extra)
8387 {
8389 {
8390 int liquidType = -1;
8391 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
8392 if (impactSpeed > 0.0)
8393 {
8394 m_ImpactSpeed = impactSpeed;
8395 #ifndef SERVER
8396 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
8397 #else
8398 m_WantPlayImpactSound = true;
8399 SetSynchDirty();
8400 #endif
8401 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
8402 }
8403 }
8404
8405 #ifdef SERVER
8406 if (GetCompEM() && GetCompEM().IsPlugged())
8407 {
8408 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
8409 GetCompEM().UnplugThis();
8410 }
8411 #endif
8412 }
8413
8414 void RefreshPhysics();
8415
8416 override void OnCreatePhysics()
8417 {
8419 }
8420
8421 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
8422 {
8423
8424 }
8425 // -------------------------------------------------------------------------
8426 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
8427 {
8428 super.OnItemLocationChanged(old_owner, new_owner);
8429
8430 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
8431 PlayerBase playerNew = PlayerBase.Cast(new_owner);
8432
8433 if (!relatedPlayer && playerNew)
8434 relatedPlayer = playerNew;
8435
8436 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
8437 {
8438 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
8439 if (actionMgr)
8440 {
8441 ActionBase currentAction = actionMgr.GetRunningAction();
8442 if (currentAction)
8443 currentAction.OnItemLocationChanged(this);
8444 }
8445 }
8446
8447 Man ownerPlayerOld = null;
8448 Man ownerPlayerNew = null;
8449
8450 if (old_owner)
8451 {
8452 if (old_owner.IsMan())
8453 {
8454 ownerPlayerOld = Man.Cast(old_owner);
8455 }
8456 else
8457 {
8458 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
8459 }
8460 }
8461 else
8462 {
8463 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
8464 {
8465 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
8466
8467 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
8468 {
8469 GetCompEM().UnplugThis();
8470 }
8471 }
8472 }
8473
8474 if (new_owner)
8475 {
8476 if (new_owner.IsMan())
8477 {
8478 ownerPlayerNew = Man.Cast(new_owner);
8479 }
8480 else
8481 {
8482 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
8483 }
8484 }
8485
8486 if (ownerPlayerOld != ownerPlayerNew)
8487 {
8488 if (ownerPlayerOld)
8489 {
8490 array<EntityAI> subItemsExit = new array<EntityAI>;
8491 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
8492 for (int i = 0; i < subItemsExit.Count(); i++)
8493 {
8494 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
8495 itemExit.OnInventoryExit(ownerPlayerOld);
8496 }
8497 }
8498
8499 if (ownerPlayerNew)
8500 {
8501 array<EntityAI> subItemsEnter = new array<EntityAI>;
8502 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
8503 for (int j = 0; j < subItemsEnter.Count(); j++)
8504 {
8505 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
8506 itemEnter.OnInventoryEnter(ownerPlayerNew);
8507 }
8508 }
8509 }
8510 else if (ownerPlayerNew != null)
8511 {
8512 PlayerBase nplayer;
8513 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
8514 {
8515 array<EntityAI> subItemsUpdate = new array<EntityAI>;
8516 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
8517 for (int k = 0; k < subItemsUpdate.Count(); k++)
8518 {
8519 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
8520 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
8521 }
8522 }
8523 }
8524
8525 if (old_owner)
8526 old_owner.OnChildItemRemoved(this);
8527 if (new_owner)
8528 new_owner.OnChildItemReceived(this);
8529 }
8530
8531 // -------------------------------------------------------------------------------
8532 override void EEDelete(EntityAI parent)
8533 {
8534 super.EEDelete(parent);
8535 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
8536 if (player)
8537 {
8538 OnInventoryExit(player);
8539
8540 if (player.IsAlive())
8541 {
8542 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
8543 if (r_index >= 0)
8544 {
8545 InventoryLocation r_il = new InventoryLocation;
8546 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
8547
8548 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
8549 int r_type = r_il.GetType();
8550 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
8551 {
8552 r_il.GetParent().GetOnReleaseLock().Invoke(this);
8553 }
8554 else if (r_type == InventoryLocationType.ATTACHMENT)
8555 {
8556 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
8557 }
8558
8559 }
8560
8561 player.RemoveQuickBarEntityShortcut(this);
8562 }
8563 }
8564 }
8565 // -------------------------------------------------------------------------------
8566 override void EEKilled(Object killer)
8567 {
8568 super.EEKilled(killer);
8569
8571 if (killer && killer.IsFireplace() && CanExplodeInFire())
8572 {
8573 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
8574 {
8575 if (IsMagazine())
8576 {
8577 if (Magazine.Cast(this).GetAmmoCount() > 0)
8578 {
8579 ExplodeAmmo();
8580 }
8581 }
8582 else
8583 {
8584 Explode(DamageType.EXPLOSION);
8585 }
8586 }
8587 }
8588 }
8589
8590 override void OnWasAttached(EntityAI parent, int slot_id)
8591 {
8592 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
8593
8594 super.OnWasAttached(parent, slot_id);
8595
8596 if (HasQuantity())
8597 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
8598
8599 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
8600 StartItemSoundServer(SoundConstants.ITEM_ATTACH, slot_id);
8601 }
8602
8603 override void OnWasDetached(EntityAI parent, int slot_id)
8604 {
8605 super.OnWasDetached(parent, slot_id);
8606
8607 if (HasQuantity())
8608 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
8609
8610 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
8611 StartItemSoundServer(SoundConstants.ITEM_DETACH, slot_id);
8612 }
8613
8614 override string ChangeIntoOnAttach(string slot)
8615 {
8616 int idx;
8617 TStringArray inventory_slots = new TStringArray;
8618 TStringArray attach_types = new TStringArray;
8619
8620 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
8621 if (inventory_slots.Count() < 1) //is string
8622 {
8623 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
8624 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
8625 }
8626 else //is array
8627 {
8628 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
8629 }
8630
8631 idx = inventory_slots.Find(slot);
8632 if (idx < 0)
8633 return "";
8634
8635 return attach_types.Get(idx);
8636 }
8637
8638 override string ChangeIntoOnDetach()
8639 {
8640 int idx = -1;
8641 string slot;
8642
8643 TStringArray inventory_slots = new TStringArray;
8644 TStringArray detach_types = new TStringArray;
8645
8646 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
8647 if (inventory_slots.Count() < 1) //is string
8648 {
8649 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
8650 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
8651 }
8652 else //is array
8653 {
8654 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
8655 if (detach_types.Count() < 1)
8656 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
8657 }
8658
8659 for (int i = 0; i < inventory_slots.Count(); i++)
8660 {
8661 slot = inventory_slots.Get(i);
8662 }
8663
8664 if (slot != "")
8665 {
8666 if (detach_types.Count() == 1)
8667 idx = 0;
8668 else
8669 idx = inventory_slots.Find(slot);
8670 }
8671 if (idx < 0)
8672 return "";
8673
8674 return detach_types.Get(idx);
8675 }
8676
8677 void ExplodeAmmo()
8678 {
8679 //timer
8680 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
8681
8682 //min/max time
8683 float min_time = 1;
8684 float max_time = 3;
8685 float delay = Math.RandomFloat(min_time, max_time);
8686
8687 explode_timer.Run(delay, this, "DoAmmoExplosion");
8688 }
8689
8690 void DoAmmoExplosion()
8691 {
8692 Magazine magazine = Magazine.Cast(this);
8693 int pop_sounds_count = 6;
8694 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
8695
8696 //play sound
8697 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
8698 string sound_name = pop_sounds[ sound_idx ];
8699 g_Game.CreateSoundOnObject(this, sound_name, 20, false);
8700
8701 //remove ammo count
8702 magazine.ServerAddAmmoCount(-1);
8703
8704 //if condition then repeat -> ExplodeAmmo
8705 float min_temp_to_explode = 100; //min temperature for item to explode
8706
8707 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
8708 {
8709 ExplodeAmmo();
8710 }
8711 }
8712
8713 // -------------------------------------------------------------------------------
8714 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
8715 {
8716 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
8717
8718 const int CHANCE_DAMAGE_CARGO = 4;
8719 const int CHANCE_DAMAGE_ATTACHMENT = 1;
8720 const int CHANCE_DAMAGE_NOTHING = 2;
8721
8722 if (IsClothing() || IsContainer() || IsItemTent())
8723 {
8724 float dmg = damageResult.GetDamage("","Health") * -0.5;
8725 int chances;
8726 int rnd;
8727
8728 if (GetInventory().GetCargo())
8729 {
8730 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
8731 rnd = Math.RandomInt(0,chances);
8732
8733 if (rnd < CHANCE_DAMAGE_CARGO)
8734 {
8735 DamageItemInCargo(dmg);
8736 }
8737 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
8738 {
8740 }
8741 }
8742 else
8743 {
8744 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
8745 rnd = Math.RandomInt(0,chances);
8746
8747 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
8748 {
8750 }
8751 }
8752 }
8753 }
8754
8755 bool DamageItemInCargo(float damage)
8756 {
8757 CargoBase cargo = GetInventory().GetCargo();
8758 if (cargo)
8759 {
8760 int item_count = cargo.GetItemCount();
8761 if (item_count > 0)
8762 {
8763 int random_pick = Math.RandomInt(0, item_count);
8764 ItemBase item = ItemBase.Cast(cargo.GetItem(random_pick));
8765 if (!item.IsExplosive())
8766 {
8767 item.AddHealth("","",damage);
8768 return true;
8769 }
8770 }
8771 }
8772 return false;
8773 }
8774
8775 bool DamageItemAttachments(float damage)
8776 {
8777 GameInventory inventory = GetInventory();
8778 int attachment_count = inventory.AttachmentCount();
8779 if (attachment_count > 0)
8780 {
8781 int random_pick = Math.RandomInt(0, attachment_count);
8782 ItemBase attachment = ItemBase.Cast(inventory.GetAttachmentFromIndex(random_pick));
8783 if (!attachment.IsExplosive())
8784 {
8785 attachment.AddHealth("","",damage);
8786 return true;
8787 }
8788 }
8789 return false;
8790 }
8791
8792 override bool IsSplitable()
8793 {
8794 return m_CanThisBeSplit;
8795 }
8796 //----------------
8797 override bool CanBeSplit()
8798 {
8799 if (IsSplitable() && (GetQuantity() > 1))
8800 return GetInventory().CanRemoveEntity();
8801
8802 return false;
8803 }
8804
8805 protected bool ShouldSplitQuantity(float quantity)
8806 {
8807 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
8808 if (!IsSplitable())
8809 return false;
8810
8811 // nothing to split?
8812 if (GetQuantity() <= 1)
8813 return false;
8814
8815 // check if we should re-use the item instead of creating a new copy?
8816 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
8817 int delta = GetQuantity() - quantity;
8818 if (delta == 0)
8819 return false;
8820
8821 // valid to split
8822 return true;
8823 }
8824
8825 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
8826 {
8827 if (g_Game.IsClient())
8828 {
8829 if (ScriptInputUserData.CanStoreInputUserData())
8830 {
8831 ScriptInputUserData ctx = new ScriptInputUserData;
8833 ctx.Write(1);
8834 ItemBase i1 = this; // @NOTE: workaround for correct serialization
8835 ctx.Write(i1);
8836 ctx.Write(destination_entity);
8837 ctx.Write(true);
8838 ctx.Write(slot_id);
8839 ctx.Send();
8840 }
8841 }
8842 else if (!g_Game.IsMultiplayer())
8843 {
8844 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(g_Game.GetPlayer()));
8845 }
8846 }
8847
8848 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
8849 {
8850 float split_quantity_new;
8851 ItemBase new_item;
8852 float quantity = GetQuantity();
8853 float stack_max = GetTargetQuantityMax(slot_id);
8854 InventoryLocation loc = new InventoryLocation;
8855
8856 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
8857 {
8858 if (stack_max <= GetQuantity())
8859 split_quantity_new = stack_max;
8860 else
8861 split_quantity_new = GetQuantity();
8862
8863 if (ShouldSplitQuantity(split_quantity_new))
8864 {
8865 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
8866 if (new_item)
8867 {
8868 new_item.SetResultOfSplit(true);
8869 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8870 AddQuantity(-split_quantity_new, false, true);
8871 new_item.SetQuantity(split_quantity_new, false, true);
8872 }
8873 }
8874 }
8875 else if (destination_entity && slot_id == -1)
8876 {
8877 if (quantity > stack_max)
8878 split_quantity_new = stack_max;
8879 else
8880 split_quantity_new = quantity;
8881
8882 if (ShouldSplitQuantity(split_quantity_new))
8883 {
8884 GameInventory destinationInventory = destination_entity.GetInventory();
8885 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
8886 {
8887 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
8888 new_item = ItemBase.Cast(o);
8889 }
8890
8891 if (new_item)
8892 {
8893 new_item.SetResultOfSplit(true);
8894 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8895 AddQuantity(-split_quantity_new, false, true);
8896 new_item.SetQuantity(split_quantity_new, false, true);
8897 }
8898 }
8899 }
8900 else
8901 {
8902 if (stack_max != 0)
8903 {
8904 if (stack_max < GetQuantity())
8905 {
8906 split_quantity_new = GetQuantity() - stack_max;
8907 }
8908
8909 if (split_quantity_new == 0)
8910 {
8911 if (!g_Game.IsMultiplayer())
8912 player.PhysicalPredictiveDropItem(this);
8913 else
8914 player.ServerDropEntity(this);
8915 return;
8916 }
8917
8918 if (ShouldSplitQuantity(split_quantity_new))
8919 {
8920 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
8921
8922 if (new_item)
8923 {
8924 new_item.SetResultOfSplit(true);
8925 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8926 SetQuantity(split_quantity_new, false, true);
8927 new_item.SetQuantity(stack_max, false, true);
8928 new_item.PlaceOnSurface();
8929 }
8930 }
8931 }
8932 }
8933 }
8934
8935 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
8936 {
8937 float split_quantity_new;
8938 ItemBase new_item;
8939 float quantity = GetQuantity();
8940 float stack_max = GetTargetQuantityMax(slot_id);
8941 InventoryLocation loc = new InventoryLocation;
8942
8943 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
8944 {
8945 if (stack_max <= GetQuantity())
8946 split_quantity_new = stack_max;
8947 else
8948 split_quantity_new = GetQuantity();
8949
8950 if (ShouldSplitQuantity(split_quantity_new))
8951 {
8952 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
8953 if (new_item)
8954 {
8955 new_item.SetResultOfSplit(true);
8956 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8957 AddQuantity(-split_quantity_new, false, true);
8958 new_item.SetQuantity(split_quantity_new, false, true);
8959 }
8960 }
8961 }
8962 else if (destination_entity && slot_id == -1)
8963 {
8964 if (quantity > stack_max)
8965 split_quantity_new = stack_max;
8966 else
8967 split_quantity_new = quantity;
8968
8969 if (ShouldSplitQuantity(split_quantity_new))
8970 {
8971 GameInventory destinationInventory = destination_entity.GetInventory();
8972 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
8973 {
8974 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
8975 new_item = ItemBase.Cast(o);
8976 }
8977
8978 if (new_item)
8979 {
8980 new_item.SetResultOfSplit(true);
8981 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8982 AddQuantity(-split_quantity_new, false, true);
8983 new_item.SetQuantity(split_quantity_new, false, true);
8984 }
8985 }
8986 }
8987 else
8988 {
8989 if (stack_max != 0)
8990 {
8991 if (stack_max < GetQuantity())
8992 {
8993 split_quantity_new = GetQuantity() - stack_max;
8994 }
8995
8996 if (ShouldSplitQuantity(split_quantity_new))
8997 {
8998 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
8999
9000 if (new_item)
9001 {
9002 new_item.SetResultOfSplit(true);
9003 MiscGameplayFunctions.TransferItemProperties(this, new_item);
9004 SetQuantity(split_quantity_new, false, true);
9005 new_item.SetQuantity(stack_max, false, true);
9006 new_item.PlaceOnSurface();
9007 }
9008 }
9009 }
9010 }
9011 }
9012
9013 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
9014 {
9015 if (g_Game.IsClient())
9016 {
9017 if (ScriptInputUserData.CanStoreInputUserData())
9018 {
9019 ScriptInputUserData ctx = new ScriptInputUserData;
9021 ctx.Write(4);
9022 ItemBase thiz = this; // @NOTE: workaround for correct serialization
9023 ctx.Write(thiz);
9024 dst.WriteToContext(ctx);
9025 ctx.Send();
9026 }
9027 }
9028 else if (!g_Game.IsMultiplayer())
9029 {
9031 }
9032 }
9033
9034 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
9035 {
9036 if (g_Game.IsClient())
9037 {
9038 if (ScriptInputUserData.CanStoreInputUserData())
9039 {
9040 ScriptInputUserData ctx = new ScriptInputUserData;
9042 ctx.Write(2);
9043 ItemBase dummy = this; // @NOTE: workaround for correct serialization
9044 ctx.Write(dummy);
9045 ctx.Write(destination_entity);
9046 ctx.Write(true);
9047 ctx.Write(idx);
9048 ctx.Write(row);
9049 ctx.Write(col);
9050 ctx.Send();
9051 }
9052 }
9053 else if (!g_Game.IsMultiplayer())
9054 {
9055 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
9056 }
9057 }
9058
9059 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
9060 {
9062 }
9063
9064 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
9065 {
9066 float quantity = GetQuantity();
9067 float split_quantity_new;
9068 ItemBase new_item;
9069 if (dst.IsValid())
9070 {
9071 int slot_id = dst.GetSlot();
9072 float stack_max = GetTargetQuantityMax(slot_id);
9073
9074 if (quantity > stack_max)
9075 split_quantity_new = stack_max;
9076 else
9077 split_quantity_new = quantity;
9078
9079 if (ShouldSplitQuantity(split_quantity_new))
9080 {
9081 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
9082
9083 if (new_item)
9084 {
9085 new_item.SetResultOfSplit(true);
9086 MiscGameplayFunctions.TransferItemProperties(this,new_item);
9087 AddQuantity(-split_quantity_new, false, true);
9088 new_item.SetQuantity(split_quantity_new, false, true);
9089 }
9090
9091 return new_item;
9092 }
9093 }
9094
9095 return null;
9096 }
9097
9098 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
9099 {
9100 float quantity = GetQuantity();
9101 float split_quantity_new;
9102 ItemBase new_item;
9103 if (destination_entity)
9104 {
9105 float stackable = GetTargetQuantityMax();
9106 if (quantity > stackable)
9107 split_quantity_new = stackable;
9108 else
9109 split_quantity_new = quantity;
9110
9111 if (ShouldSplitQuantity(split_quantity_new))
9112 {
9113 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
9114 if (new_item)
9115 {
9116 new_item.SetResultOfSplit(true);
9117 MiscGameplayFunctions.TransferItemProperties(this,new_item);
9118 AddQuantity(-split_quantity_new, false, true);
9119 new_item.SetQuantity(split_quantity_new, false, true);
9120 }
9121 }
9122 }
9123 }
9124
9125 void SplitIntoStackMaxHandsClient(PlayerBase player)
9126 {
9127 if (g_Game.IsClient())
9128 {
9129 if (ScriptInputUserData.CanStoreInputUserData())
9130 {
9131 ScriptInputUserData ctx = new ScriptInputUserData;
9133 ctx.Write(3);
9134 ItemBase i1 = this; // @NOTE: workaround for correct serialization
9135 ctx.Write(i1);
9136 ItemBase destination_entity = this;
9137 ctx.Write(destination_entity);
9138 ctx.Write(true);
9139 ctx.Write(0);
9140 ctx.Send();
9141 }
9142 }
9143 else if (!g_Game.IsMultiplayer())
9144 {
9145 SplitIntoStackMaxHands(player);
9146 }
9147 }
9148
9149 void SplitIntoStackMaxHands(PlayerBase player)
9150 {
9151 float quantity = GetQuantity();
9152 float split_quantity_new;
9153 ref ItemBase new_item;
9154 if (player)
9155 {
9156 float stackable = GetTargetQuantityMax();
9157 if (quantity > stackable)
9158 split_quantity_new = stackable;
9159 else
9160 split_quantity_new = quantity;
9161
9162 if (ShouldSplitQuantity(split_quantity_new))
9163 {
9164 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
9165 new_item = ItemBase.Cast(in_hands);
9166 if (new_item)
9167 {
9168 new_item.SetResultOfSplit(true);
9169 MiscGameplayFunctions.TransferItemProperties(this,new_item);
9170 AddQuantity(-split_quantity_new, false, true);
9171 new_item.SetQuantity(split_quantity_new, false, true);
9172 }
9173 }
9174 }
9175 }
9176
9177 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
9178 {
9179 float quantity = GetQuantity();
9180 float split_quantity_new = Math.Floor(quantity * 0.5);
9181
9182 if (!ShouldSplitQuantity(split_quantity_new))
9183 return;
9184
9185 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
9186
9187 if (new_item)
9188 {
9189 if (new_item.GetQuantityMax() < split_quantity_new)
9190 {
9191 split_quantity_new = new_item.GetQuantityMax();
9192 }
9193
9194 new_item.SetResultOfSplit(true);
9195 MiscGameplayFunctions.TransferItemProperties(this, new_item);
9196
9197 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
9198 {
9199 AddQuantity(-1, false, true);
9200 new_item.SetQuantity(1, false, true);
9201 }
9202 else
9203 {
9204 AddQuantity(-split_quantity_new, false, true);
9205 new_item.SetQuantity(split_quantity_new, false, true);
9206 }
9207 }
9208 }
9209
9210 void SplitItem(PlayerBase player)
9211 {
9212 float quantity = GetQuantity();
9213 float split_quantity_new = Math.Floor(quantity / 2);
9214
9215 if (!ShouldSplitQuantity(split_quantity_new))
9216 return;
9217
9218 InventoryLocation invloc = new InventoryLocation;
9219 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
9220
9221 ItemBase new_item;
9222 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
9223
9224 if (new_item)
9225 {
9226 if (new_item.GetQuantityMax() < split_quantity_new)
9227 {
9228 split_quantity_new = new_item.GetQuantityMax();
9229 }
9230 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
9231 {
9232 AddQuantity(-1, false, true);
9233 new_item.SetQuantity(1, false, true);
9234 }
9235 else if (split_quantity_new > 1)
9236 {
9237 AddQuantity(-split_quantity_new, false, true);
9238 new_item.SetQuantity(split_quantity_new, false, true);
9239 }
9240 }
9241 }
9242
9244 void OnQuantityChanged(float delta)
9245 {
9246 SetWeightDirty();
9247 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
9248
9249 if (parent)
9250 parent.OnAttachmentQuantityChangedEx(this, delta);
9251
9252 if (IsLiquidContainer())
9253 {
9254 if (GetQuantityNormalized() <= 0.0)
9255 {
9257 }
9258 else if (GetLiquidType() == LIQUID_NONE)
9259 {
9260 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
9262 }
9263 }
9264 }
9265
9268 {
9269 // insert code here
9270 }
9271
9273 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
9274 {
9276 }
9277
9278 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
9279 {
9280 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
9281
9282 if (g_Game.IsServer())
9283 {
9284 if (newLevel == GameConstants.STATE_RUINED)
9285 {
9287 EntityAI parent = GetHierarchyParent();
9288 if (parent && parent.IsFireplace())
9289 {
9290 CargoBase cargo = GetInventory().GetCargo();
9291 if (cargo)
9292 {
9293 for (int i = 0; i < cargo.GetItemCount(); ++i)
9294 {
9295 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
9296 }
9297 }
9298 }
9299 }
9300
9301 if (IsResultOfSplit())
9302 {
9303 // reset the splitting result flag, return to normal item behavior
9304 SetResultOfSplit(false);
9305 return;
9306 }
9307
9308 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
9309 {
9310 SetCleanness(0);//unclean the item upon damage dealt
9311 }
9312 }
9313 }
9314
9315 // just the split? TODO: verify
9316 override void OnRightClick()
9317 {
9318 super.OnRightClick();
9319
9320 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !g_Game.GetPlayer().GetInventory().HasInventoryReservation(this,null))
9321 {
9322 if (g_Game.IsClient())
9323 {
9324 if (ScriptInputUserData.CanStoreInputUserData())
9325 {
9326 EntityAI root = GetHierarchyRoot();
9327 Man playerOwner = GetHierarchyRootPlayer();
9328 InventoryLocation dst = new InventoryLocation;
9329
9330 // 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
9331 if (!playerOwner && root && root == this)
9332 {
9334 }
9335 else
9336 {
9337 // 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
9338 GetInventory().GetCurrentInventoryLocation(dst);
9339 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
9340 {
9341 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
9342 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
9343 {
9345 }
9346 else
9347 {
9348 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
9349 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
9350 this shouldnt cause issues within this scope*/
9351 if (g_Game.GetPlayer().GetInventory().HasInventoryReservation(this, dst))
9352 {
9354 }
9355 else
9356 {
9357 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
9358 }
9359 }
9360 }
9361 }
9362
9363 ScriptInputUserData ctx = new ScriptInputUserData;
9365 ctx.Write(4);
9366 ItemBase thiz = this; // @NOTE: workaround for correct serialization
9367 ctx.Write(thiz);
9368 dst.WriteToContext(ctx);
9369 ctx.Write(true); // dummy
9370 ctx.Send();
9371 }
9372 }
9373 else if (!g_Game.IsMultiplayer())
9374 {
9375 SplitItem(PlayerBase.Cast(g_Game.GetPlayer()));
9376 }
9377 }
9378 }
9379
9380 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
9381 {
9382 if (root)
9383 {
9384 vector m4[4];
9385 root.GetTransform(m4);
9386 dst.SetGround(this, m4);
9387 }
9388 else
9389 {
9390 GetInventory().GetCurrentInventoryLocation(dst);
9391 }
9392 }
9393
9394 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
9395 {
9396 //TODO: delete check zero quantity check after fix double posts hands fsm events
9397 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
9398 return false;
9399
9400 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
9401 return false;
9402
9403 //can_this_be_combined = ConfigGetBool("canBeSplit");
9405 return false;
9406
9407
9408 Magazine mag = Magazine.Cast(this);
9409 if (mag)
9410 {
9411 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
9412 return false;
9413
9414 if (stack_max_limit)
9415 {
9416 Magazine other_mag = Magazine.Cast(other_item);
9417 if (other_item)
9418 {
9419 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
9420 return false;
9421 }
9422
9423 }
9424 }
9425 else
9426 {
9427 //TODO: delete check zero quantity check after fix double posts hands fsm events
9428 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
9429 return false;
9430
9431 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
9432 return false;
9433 }
9434
9435 PlayerBase player = null;
9436 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
9437 {
9438 if (player.GetInventory().HasAttachment(this))
9439 return false;
9440
9441 if (player.IsItemsToDelete())
9442 return false;
9443 }
9444
9445 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
9446 return false;
9447
9448 int slotID;
9449 string slotName;
9450 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
9451 return false;
9452
9453 return true;
9454 }
9455
9456 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
9457 {
9458 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
9459 }
9460
9461 bool IsResultOfSplit()
9462 {
9463 return m_IsResultOfSplit;
9464 }
9465
9466 void SetResultOfSplit(bool value)
9467 {
9468 m_IsResultOfSplit = value;
9469 }
9470
9471 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
9472 {
9473 return ComputeQuantityUsedEx(other_item, use_stack_max);
9474 }
9475
9476 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
9477 {
9478 float other_item_quantity = other_item.GetQuantity();
9479 float this_free_space;
9480
9481 float stack_max = GetQuantityMax();
9482
9483 this_free_space = stack_max - GetQuantity();
9484
9485 if (other_item_quantity > this_free_space)
9486 {
9487 return this_free_space;
9488 }
9489 else
9490 {
9491 return other_item_quantity;
9492 }
9493 }
9494
9495 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
9496 {
9497 CombineItems(ItemBase.Cast(entity2),use_stack_max);
9498 }
9499
9500 void CombineItems(ItemBase other_item, bool use_stack_max = true)
9501 {
9502 if (!CanBeCombined(other_item, false))
9503 return;
9504
9505 if (!IsMagazine() && other_item)
9506 {
9507 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
9508 if (quantity_used != 0)
9509 {
9510 float hp1 = GetHealth01("","");
9511 float hp2 = other_item.GetHealth01("","");
9512 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
9513 hpResult = hpResult / (GetQuantity() + quantity_used);
9514
9515 hpResult *= GetMaxHealth();
9516 Math.Round(hpResult);
9517 SetHealth("", "Health", hpResult);
9518
9519 AddQuantity(quantity_used);
9520 other_item.AddQuantity(-quantity_used);
9521 }
9522 }
9523 OnCombine(other_item);
9524 }
9525
9526 void OnCombine(ItemBase other_item)
9527 {
9528 #ifdef SERVER
9529 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
9530 GetHierarchyParent().IncreaseLifetimeUp();
9531 #endif
9532 };
9533
9534 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
9535 {
9536 PlayerBase p = PlayerBase.Cast(player);
9537
9538 array<int> recipesIds = p.m_Recipes;
9539 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
9540 if (moduleRecipesManager)
9541 {
9542 EntityAI itemInHands = player.GetEntityInHands();
9543 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
9544 }
9545
9546 for (int i = 0;i < recipesIds.Count(); i++)
9547 {
9548 int key = recipesIds.Get(i);
9549 string recipeName = moduleRecipesManager.GetRecipeName(key);
9550 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
9551 }
9552 }
9553
9554 // -------------------------------------------------------------------------
9555 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
9556 {
9557 super.GetDebugActions(outputList);
9558
9559 //quantity
9560 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
9561 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
9562 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
9563 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
9564 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9565
9566 //health
9567 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
9568 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
9569 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
9570 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9571 //temperature
9572 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
9573 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
9574 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
9575 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9576
9577 //wet
9578 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
9579 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
9580 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9581
9582 //liquidtype
9583 if (IsLiquidContainer())
9584 {
9585 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
9586 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
9587 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9588 }
9589
9590 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
9591 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9592
9593 // watch
9594 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
9595 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
9596 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9597
9598 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
9599
9600 InventoryLocation loc = new InventoryLocation();
9601 GetInventory().GetCurrentInventoryLocation(loc);
9602 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
9603 {
9604 if (Gizmo_IsSupported())
9605 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
9606 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
9607 }
9608
9609 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9610 }
9611
9612 // -------------------------------------------------------------------------
9613 // -------------------------------------------------------------------------
9614 // -------------------------------------------------------------------------
9615 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
9616 {
9617 super.OnAction(action_id, player, ctx);
9618
9619 if (g_Game.IsClient() || !g_Game.IsMultiplayer())
9620 {
9621 switch (action_id)
9622 {
9623 case EActions.GIZMO_OBJECT:
9624 if (GetGizmoApi())
9625 GetGizmoApi().SelectObject(this);
9626 return true;
9627 case EActions.GIZMO_PHYSICS:
9628 if (GetGizmoApi())
9629 GetGizmoApi().SelectPhysics(GetPhysics());
9630 return true;
9631 }
9632 }
9633
9634 if (g_Game.IsServer())
9635 {
9636 switch (action_id)
9637 {
9638 case EActions.DELETE:
9639 Delete();
9640 return true;
9641 }
9642 }
9643
9644 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
9645 {
9646 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
9647 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
9648 PlayerBase p = PlayerBase.Cast(player);
9649 if (EActions.RECIPES_RANGE_START < 1000)
9650 {
9651 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
9652 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
9653 }
9654 }
9655 #ifndef SERVER
9656 else if (action_id == EActions.WATCH_PLAYER)
9657 {
9658 PluginDeveloper.SetDeveloperItemClientEx(player);
9659 }
9660 #endif
9661 if (g_Game.IsServer())
9662 {
9663 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
9664 {
9665 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
9666 OnDebugButtonPressServer(id + 1);
9667 }
9668
9669 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
9670 {
9671 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
9672 InsertAgent(agent_id,100);
9673 }
9674
9675 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
9676 {
9677 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
9678 RemoveAgent(agent_id2);
9679 }
9680
9681 else if (action_id == EActions.ADD_QUANTITY)
9682 {
9683 if (IsMagazine())
9684 {
9685 Magazine mag = Magazine.Cast(this);
9686 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
9687 }
9688 else
9689 {
9690 AddQuantity(GetQuantityMax() * 0.2);
9691 }
9692
9693 if (m_EM)
9694 {
9695 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
9696 }
9697 //PrintVariables();
9698 }
9699
9700 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
9701 {
9702 if (IsMagazine())
9703 {
9704 Magazine mag2 = Magazine.Cast(this);
9705 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
9706 }
9707 else
9708 {
9709 AddQuantity(- GetQuantityMax() * 0.2);
9710 }
9711 if (m_EM)
9712 {
9713 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
9714 }
9715 //PrintVariables();
9716 }
9717
9718 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
9719 {
9720 SetQuantity(0);
9721
9722 if (m_EM)
9723 {
9724 m_EM.SetEnergy(0);
9725 }
9726 }
9727
9728 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
9729 {
9731
9732 if (m_EM)
9733 {
9734 m_EM.SetEnergy(m_EM.GetEnergyMax());
9735 }
9736 }
9737
9738 else if (action_id == EActions.ADD_HEALTH)
9739 {
9740 AddHealth("","",GetMaxHealth("","Health")/5);
9741 }
9742 else if (action_id == EActions.REMOVE_HEALTH)
9743 {
9744 AddHealth("","",-GetMaxHealth("","Health")/5);
9745 }
9746 else if (action_id == EActions.DESTROY_HEALTH)
9747 {
9748 SetHealth01("","",0);
9749 }
9750 else if (action_id == EActions.WATCH_ITEM)
9751 {
9753 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
9754 #ifdef DEVELOPER
9755 SetDebugDeveloper_item(this);
9756 #endif
9757 }
9758
9759 else if (action_id == EActions.ADD_TEMPERATURE)
9760 {
9761 AddTemperature(20);
9762 //PrintVariables();
9763 }
9764
9765 else if (action_id == EActions.REMOVE_TEMPERATURE)
9766 {
9767 AddTemperature(-20);
9768 //PrintVariables();
9769 }
9770
9771 else if (action_id == EActions.FLIP_FROZEN)
9772 {
9773 SetFrozen(!GetIsFrozen());
9774 //PrintVariables();
9775 }
9776
9777 else if (action_id == EActions.ADD_WETNESS)
9778 {
9779 AddWet(GetWetMax()/5);
9780 //PrintVariables();
9781 }
9782
9783 else if (action_id == EActions.REMOVE_WETNESS)
9784 {
9785 AddWet(-GetWetMax()/5);
9786 //PrintVariables();
9787 }
9788
9789 else if (action_id == EActions.LIQUIDTYPE_UP)
9790 {
9791 int curr_type = GetLiquidType();
9792 SetLiquidType(curr_type * 2);
9793 //AddWet(1);
9794 //PrintVariables();
9795 }
9796
9797 else if (action_id == EActions.LIQUIDTYPE_DOWN)
9798 {
9799 int curr_type2 = GetLiquidType();
9800 SetLiquidType(curr_type2 / 2);
9801 }
9802
9803 else if (action_id == EActions.MAKE_SPECIAL)
9804 {
9805 auto debugParams = DebugSpawnParams.WithPlayer(player);
9806 OnDebugSpawnEx(debugParams);
9807 }
9808
9809 }
9810
9811
9812 return false;
9813 }
9814
9815 // -------------------------------------------------------------------------
9816
9817
9820 void OnActivatedByTripWire();
9821
9823 void OnActivatedByItem(notnull ItemBase item);
9824
9825 //----------------------------------------------------------------
9826 //returns true if item is able to explode when put in fire
9827 bool CanExplodeInFire()
9828 {
9829 return false;
9830 }
9831
9832 //----------------------------------------------------------------
9833 bool CanEat()
9834 {
9835 return true;
9836 }
9837
9838 //----------------------------------------------------------------
9839 override bool IsIgnoredByConstruction()
9840 {
9841 return true;
9842 }
9843
9844 //----------------------------------------------------------------
9845 //has FoodStages in config?
9846 bool HasFoodStage()
9847 {
9848 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
9849 return g_Game.ConfigIsExisting(config_path);
9850 }
9851
9853 FoodStage GetFoodStage()
9854 {
9855 return null;
9856 }
9857
9858 bool CanBeCooked()
9859 {
9860 return false;
9861 }
9862
9863 bool CanBeCookedOnStick()
9864 {
9865 return false;
9866 }
9867
9869 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
9871
9872 //----------------------------------------------------------------
9873 bool CanRepair(ItemBase item_repair_kit)
9874 {
9875 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
9876 return module_repairing.CanRepair(this, item_repair_kit);
9877 }
9878
9879 //----------------------------------------------------------------
9880 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
9881 {
9882 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
9883 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
9884 }
9885
9886 //----------------------------------------------------------------
9887 int GetItemSize()
9888 {
9889 /*
9890 vector v_size = this.ConfigGetVector("itemSize");
9891 int v_size_x = v_size[0];
9892 int v_size_y = v_size[1];
9893 int size = v_size_x * v_size_y;
9894 return size;
9895 */
9896
9897 return 1;
9898 }
9899
9900 //----------------------------------------------------------------
9901 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
9902 bool CanBeMovedOverride()
9903 {
9904 return m_CanBeMovedOverride;
9905 }
9906
9907 //----------------------------------------------------------------
9908 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
9909 void SetCanBeMovedOverride(bool setting)
9910 {
9911 m_CanBeMovedOverride = setting;
9912 }
9913
9914 //----------------------------------------------------------------
9922 void MessageToOwnerStatus(string text)
9923 {
9924 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9925
9926 if (player)
9927 {
9928 player.MessageStatus(text);
9929 }
9930 }
9931
9932 //----------------------------------------------------------------
9940 void MessageToOwnerAction(string text)
9941 {
9942 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9943
9944 if (player)
9945 {
9946 player.MessageAction(text);
9947 }
9948 }
9949
9950 //----------------------------------------------------------------
9958 void MessageToOwnerFriendly(string text)
9959 {
9960 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9961
9962 if (player)
9963 {
9964 player.MessageFriendly(text);
9965 }
9966 }
9967
9968 //----------------------------------------------------------------
9976 void MessageToOwnerImportant(string text)
9977 {
9978 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9979
9980 if (player)
9981 {
9982 player.MessageImportant(text);
9983 }
9984 }
9985
9986 override bool IsItemBase()
9987 {
9988 return true;
9989 }
9990
9991 // Checks if item is of questioned kind
9992 override bool KindOf(string tag)
9993 {
9994 bool found = false;
9995 string item_name = this.GetType();
9996 ref TStringArray item_tag_array = new TStringArray;
9997 g_Game.ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
9998
9999 int array_size = item_tag_array.Count();
10000 for (int i = 0; i < array_size; i++)
10001 {
10002 if (item_tag_array.Get(i) == tag)
10003 {
10004 found = true;
10005 break;
10006 }
10007 }
10008 return found;
10009 }
10010
10011
10012 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
10013 {
10014 //Debug.Log("OnRPC called");
10015 super.OnRPC(sender, rpc_type,ctx);
10016
10017 //Play soundset for attachment locking (ActionLockAttachment.c)
10018 switch (rpc_type)
10019 {
10020 #ifndef SERVER
10021 case ERPCs.RPC_SOUND_LOCK_ATTACH:
10022 Param2<bool, string> p = new Param2<bool, string>(false, "");
10023
10024 if (!ctx.Read(p))
10025 return;
10026
10027 bool play = p.param1;
10028 string soundSet = p.param2;
10029
10030 if (play)
10031 {
10032 if (m_LockingSound)
10033 {
10035 {
10036 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
10037 }
10038 }
10039 else
10040 {
10041 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
10042 }
10043 }
10044 else
10045 {
10046 SEffectManager.DestroyEffect(m_LockingSound);
10047 }
10048
10049 break;
10050 #endif
10051
10052 }
10053
10054 if (GetWrittenNoteData())
10055 {
10056 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
10057 }
10058 }
10059
10060 //-----------------------------
10061 // VARIABLE MANIPULATION SYSTEM
10062 //-----------------------------
10063 int NameToID(string name)
10064 {
10065 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
10066 return plugin.GetID(name);
10067 }
10068
10069 string IDToName(int id)
10070 {
10071 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
10072 return plugin.GetName(id);
10073 }
10074
10076 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
10077 {
10078 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
10079 //read the flags
10080 int varFlags;
10081 if (!ctx.Read(varFlags))
10082 return;
10083
10084 if (varFlags & ItemVariableFlags.FLOAT)
10085 {
10086 ReadVarsFromCTX(ctx);
10087 }
10088 }
10089
10090 override void SerializeNumericalVars(array<float> floats_out)
10091 {
10092 //some variables handled on EntityAI level already!
10093 super.SerializeNumericalVars(floats_out);
10094
10095 // the order of serialization must be the same as the order of de-serialization
10096 //--------------------------------------------
10097 if (IsVariableSet(VARIABLE_QUANTITY))
10098 {
10099 floats_out.Insert(m_VarQuantity);
10100 }
10101 //--------------------------------------------
10102 if (IsVariableSet(VARIABLE_WET))
10103 {
10104 floats_out.Insert(m_VarWet);
10105 }
10106 //--------------------------------------------
10107 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
10108 {
10109 floats_out.Insert(m_VarLiquidType);
10110 }
10111 //--------------------------------------------
10112 if (IsVariableSet(VARIABLE_COLOR))
10113 {
10114 floats_out.Insert(m_ColorComponentR);
10115 floats_out.Insert(m_ColorComponentG);
10116 floats_out.Insert(m_ColorComponentB);
10117 floats_out.Insert(m_ColorComponentA);
10118 }
10119 //--------------------------------------------
10120 if (IsVariableSet(VARIABLE_CLEANNESS))
10121 {
10122 floats_out.Insert(m_Cleanness);
10123 }
10124 }
10125
10126 override void DeSerializeNumericalVars(array<float> floats)
10127 {
10128 //some variables handled on EntityAI level already!
10129 super.DeSerializeNumericalVars(floats);
10130
10131 // the order of serialization must be the same as the order of de-serialization
10132 int index = 0;
10133 int mask = Math.Round(floats.Get(index));
10134
10135 index++;
10136 //--------------------------------------------
10137 if (mask & VARIABLE_QUANTITY)
10138 {
10139 if (m_IsStoreLoad)
10140 {
10141 SetStoreLoadedQuantity(floats.Get(index));
10142 }
10143 else
10144 {
10145 float quantity = floats.Get(index);
10146 SetQuantity(quantity, true, false, false, false);
10147 }
10148 index++;
10149 }
10150 //--------------------------------------------
10151 if (mask & VARIABLE_WET)
10152 {
10153 float wet = floats.Get(index);
10154 SetWet(wet);
10155 index++;
10156 }
10157 //--------------------------------------------
10158 if (mask & VARIABLE_LIQUIDTYPE)
10159 {
10160 int liquidtype = Math.Round(floats.Get(index));
10161 SetLiquidType(liquidtype);
10162 index++;
10163 }
10164 //--------------------------------------------
10165 if (mask & VARIABLE_COLOR)
10166 {
10167 m_ColorComponentR = Math.Round(floats.Get(index));
10168 index++;
10169 m_ColorComponentG = Math.Round(floats.Get(index));
10170 index++;
10171 m_ColorComponentB = Math.Round(floats.Get(index));
10172 index++;
10173 m_ColorComponentA = Math.Round(floats.Get(index));
10174 index++;
10175 }
10176 //--------------------------------------------
10177 if (mask & VARIABLE_CLEANNESS)
10178 {
10179 int cleanness = Math.Round(floats.Get(index));
10180 SetCleanness(cleanness);
10181 index++;
10182 }
10183 }
10184
10185 override void WriteVarsToCTX(ParamsWriteContext ctx)
10186 {
10187 super.WriteVarsToCTX(ctx);
10188
10189 //--------------------------------------------
10190 if (IsVariableSet(VARIABLE_QUANTITY))
10191 {
10192 ctx.Write(GetQuantity());
10193 }
10194 //--------------------------------------------
10195 if (IsVariableSet(VARIABLE_WET))
10196 {
10197 ctx.Write(GetWet());
10198 }
10199 //--------------------------------------------
10200 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
10201 {
10202 ctx.Write(GetLiquidType());
10203 }
10204 //--------------------------------------------
10205 if (IsVariableSet(VARIABLE_COLOR))
10206 {
10207 int r,g,b,a;
10208 GetColor(r,g,b,a);
10209 ctx.Write(r);
10210 ctx.Write(g);
10211 ctx.Write(b);
10212 ctx.Write(a);
10213 }
10214 //--------------------------------------------
10215 if (IsVariableSet(VARIABLE_CLEANNESS))
10216 {
10217 ctx.Write(GetCleanness());
10218 }
10219 }
10220
10221 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
10222 {
10223 if (!super.ReadVarsFromCTX(ctx,version))
10224 return false;
10225
10226 int intValue;
10227 float value;
10228
10229 if (version < 140)
10230 {
10231 if (!ctx.Read(intValue))
10232 return false;
10233
10234 m_VariablesMask = intValue;
10235 }
10236
10237 if (m_VariablesMask & VARIABLE_QUANTITY)
10238 {
10239 if (!ctx.Read(value))
10240 return false;
10241
10242 if (IsStoreLoad())
10243 {
10245 }
10246 else
10247 {
10248 SetQuantity(value, true, false, false, false);
10249 }
10250 }
10251 //--------------------------------------------
10252 if (version < 140)
10253 {
10254 if (m_VariablesMask & VARIABLE_TEMPERATURE)
10255 {
10256 if (!ctx.Read(value))
10257 return false;
10258 SetTemperatureDirect(value);
10259 }
10260 }
10261 //--------------------------------------------
10262 if (m_VariablesMask & VARIABLE_WET)
10263 {
10264 if (!ctx.Read(value))
10265 return false;
10266 SetWet(value);
10267 }
10268 //--------------------------------------------
10269 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
10270 {
10271 if (!ctx.Read(intValue))
10272 return false;
10273 SetLiquidType(intValue);
10274 }
10275 //--------------------------------------------
10276 if (m_VariablesMask & VARIABLE_COLOR)
10277 {
10278 int r,g,b,a;
10279 if (!ctx.Read(r))
10280 return false;
10281 if (!ctx.Read(g))
10282 return false;
10283 if (!ctx.Read(b))
10284 return false;
10285 if (!ctx.Read(a))
10286 return false;
10287
10288 SetColor(r,g,b,a);
10289 }
10290 //--------------------------------------------
10291 if (m_VariablesMask & VARIABLE_CLEANNESS)
10292 {
10293 if (!ctx.Read(intValue))
10294 return false;
10295 SetCleanness(intValue);
10296 }
10297 //--------------------------------------------
10298 if (version >= 138 && version < 140)
10299 {
10300 if (m_VariablesMask & VARIABLE_TEMPERATURE)
10301 {
10302 if (!ctx.Read(intValue))
10303 return false;
10304 SetFrozen(intValue);
10305 }
10306 }
10307
10308 return true;
10309 }
10310
10311 //----------------------------------------------------------------
10312 override bool OnStoreLoad(ParamsReadContext ctx, int version)
10313 {
10314 m_IsStoreLoad = true;
10316 {
10317 m_FixDamageSystemInit = true;
10318 }
10319
10320 if (!super.OnStoreLoad(ctx, version))
10321 {
10322 m_IsStoreLoad = false;
10323 return false;
10324 }
10325
10326 if (version >= 114)
10327 {
10328 bool hasQuickBarIndexSaved;
10329
10330 if (!ctx.Read(hasQuickBarIndexSaved))
10331 {
10332 m_IsStoreLoad = false;
10333 return false;
10334 }
10335
10336 if (hasQuickBarIndexSaved)
10337 {
10338 int itmQBIndex;
10339
10340 //Load quickbar item bind
10341 if (!ctx.Read(itmQBIndex))
10342 {
10343 m_IsStoreLoad = false;
10344 return false;
10345 }
10346
10347 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
10348 if (itmQBIndex != -1 && parentPlayer)
10349 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
10350 }
10351 }
10352 else
10353 {
10354 // Backup of how it used to be
10355 PlayerBase player;
10356 int itemQBIndex;
10357 if (version == int.MAX)
10358 {
10359 if (!ctx.Read(itemQBIndex))
10360 {
10361 m_IsStoreLoad = false;
10362 return false;
10363 }
10364 }
10365 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
10366 {
10367 //Load quickbar item bind
10368 if (!ctx.Read(itemQBIndex))
10369 {
10370 m_IsStoreLoad = false;
10371 return false;
10372 }
10373 if (itemQBIndex != -1 && player)
10374 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
10375 }
10376 }
10377
10378 if (version < 140)
10379 {
10380 // variable management system
10381 if (!LoadVariables(ctx, version))
10382 {
10383 m_IsStoreLoad = false;
10384 return false;
10385 }
10386 }
10387
10388 //agent trasmission system
10389 if (!LoadAgents(ctx, version))
10390 {
10391 m_IsStoreLoad = false;
10392 return false;
10393 }
10394 if (version >= 132)
10395 {
10396 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
10397 if (raib)
10398 {
10399 if (!raib.OnStoreLoad(ctx,version))
10400 {
10401 m_IsStoreLoad = false;
10402 return false;
10403 }
10404 }
10405 }
10406
10407 m_IsStoreLoad = false;
10408 return true;
10409 }
10410
10411 //----------------------------------------------------------------
10412
10413 override void OnStoreSave(ParamsWriteContext ctx)
10414 {
10415 super.OnStoreSave(ctx);
10416
10417 PlayerBase player;
10418 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
10419 {
10420 ctx.Write(true); // Keep track of if we should actually read this in or not
10421 //Save quickbar item bind
10422 int itemQBIndex = -1;
10423 itemQBIndex = player.FindQuickBarEntityIndex(this);
10424 ctx.Write(itemQBIndex);
10425 }
10426 else
10427 {
10428 ctx.Write(false); // Keep track of if we should actually read this in or not
10429 }
10430
10431 SaveAgents(ctx);//agent trasmission system
10432
10433 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
10434 if (raib)
10435 {
10436 raib.OnStoreSave(ctx);
10437 }
10438 }
10439 //----------------------------------------------------------------
10440
10441 override void AfterStoreLoad()
10442 {
10443 super.AfterStoreLoad();
10444
10446 {
10448 }
10449
10450 if (GetStoreLoadedQuantity() != float.LOWEST)
10451 {
10453 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
10454 }
10455 }
10456
10457 override void EEOnAfterLoad()
10458 {
10459 super.EEOnAfterLoad();
10460
10462 {
10463 m_FixDamageSystemInit = false;
10464 }
10465
10468 }
10469
10470 bool CanBeDisinfected()
10471 {
10472 return false;
10473 }
10474
10475
10476 //----------------------------------------------------------------
10477 override void OnVariablesSynchronized()
10478 {
10479 if (m_Initialized)
10480 {
10481 #ifdef PLATFORM_CONSOLE
10482 //bruteforce it is
10483 if (IsSplitable())
10484 {
10485 UIScriptedMenu menu = g_Game.GetUIManager().FindMenu(MENU_INVENTORY);
10486 if (menu)
10487 {
10488 menu.Refresh();
10489 }
10490 }
10491 #endif
10492 }
10493
10495 {
10496 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
10497 m_WantPlayImpactSound = false;
10498 }
10499
10501 {
10502 SetWeightDirty();
10504 }
10505 if (m_VarWet != m_VarWetPrev)
10506 {
10509 }
10510
10511 if (m_SoundSyncPlay != 0)
10512 {
10515
10516 m_SoundSyncPlay = 0;
10517 m_SoundSyncSlotID = -1;
10518 }
10519 if (m_SoundSyncStop != 0)
10520 {
10522 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
10523 m_SoundSyncStop = 0;
10524 }
10525
10526 super.OnVariablesSynchronized();
10527 }
10528
10529 //------------------------- Quantity
10530 //----------------------------------------------------------------
10532 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
10533 {
10534 if (!IsServerCheck(allow_client))
10535 return false;
10536
10537 if (!HasQuantity())
10538 return false;
10539
10540 float min = GetQuantityMin();
10541 float max = GetQuantityMax();
10542
10543 if (value <= (min + 0.001))
10544 value = min;
10545
10546 if (value == min)
10547 {
10548 if (destroy_config)
10549 {
10550 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
10551 if (dstr)
10552 {
10553 m_VarQuantity = Math.Clamp(value, min, max);
10554 this.Delete();
10555 return true;
10556 }
10557 }
10558 else if (destroy_forced)
10559 {
10560 m_VarQuantity = Math.Clamp(value, min, max);
10561 this.Delete();
10562 return true;
10563 }
10564 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
10565 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
10566 }
10567
10568 float delta = m_VarQuantity;
10569 m_VarQuantity = Math.Clamp(value, min, max);
10570
10571 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
10572 {
10573 EntityAI parent = GetHierarchyRoot();
10574 InventoryLocation iLoc = new InventoryLocation();
10575 GetInventory().GetCurrentInventoryLocation(iLoc);
10576 if (iLoc && iLoc.IsValid() && delta != m_VarQuantity)
10577 {
10578 int iLocSlot = iLoc.GetSlot();
10579 if (delta < m_VarQuantity && iLoc.GetType() != InventoryLocationType.GROUND)
10580 {
10581 StartItemSoundServer(SoundConstants.ITEM_ATTACH, iLocSlot);
10582 }
10583 if (delta > m_VarQuantity && m_VarQuantity != 0 && !IsPrepareToDelete() && iLoc.GetType() == InventoryLocationType.ATTACHMENT)
10584 {
10585 StartItemSoundServer(SoundConstants.ITEM_DETACH, iLocSlot);
10586 }
10587 }
10588 }
10589
10590 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
10591 {
10592 delta = m_VarQuantity - delta;
10593
10594 if (delta)
10595 OnQuantityChanged(delta);
10596 }
10597
10598 SetVariableMask(VARIABLE_QUANTITY);
10599
10600 return false;
10601 }
10602
10603 //----------------------------------------------------------------
10605 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
10606 {
10607 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
10608 }
10609 //----------------------------------------------------------------
10610 void SetQuantityMax()
10611 {
10612 float max = GetQuantityMax();
10613 SetQuantity(max);
10614 }
10615
10616 override void SetQuantityToMinimum()
10617 {
10618 float min = GetQuantityMin();
10619 SetQuantity(min);
10620 }
10621 //----------------------------------------------------------------
10623 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
10624 {
10625 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
10626 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
10627 SetQuantity(result, destroy_config, destroy_forced);
10628 }
10629
10630 //----------------------------------------------------------------
10632 override float GetQuantityNormalized()
10633 {
10634 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
10635 }
10636
10638 {
10639 return GetQuantityNormalized();
10640 }
10641
10642 /*void SetAmmoNormalized(float value)
10643 {
10644 float value_clamped = Math.Clamp(value, 0, 1);
10645 Magazine this_mag = Magazine.Cast(this);
10646 int max_rounds = this_mag.GetAmmoMax();
10647 int result = value * max_rounds;//can the rounded if higher precision is required
10648 this_mag.SetAmmoCount(result);
10649 }*/
10650 //----------------------------------------------------------------
10651 override int GetQuantityMax()
10652 {
10653 int slot = -1;
10654 GameInventory inventory = GetInventory();
10655 if (inventory)
10656 {
10657 InventoryLocation il = new InventoryLocation;
10658 inventory.GetCurrentInventoryLocation(il);
10659 slot = il.GetSlot();
10660 }
10661
10662 return GetTargetQuantityMax(slot);
10663 }
10664
10665 override int GetTargetQuantityMax(int attSlotID = -1)
10666 {
10667 float quantity_max = 0;
10668
10669 if (IsSplitable()) //only stackable/splitable items can check for stack size
10670 {
10671 if (attSlotID != -1)
10672 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
10673
10674 if (quantity_max <= 0)
10675 quantity_max = m_VarStackMax;
10676 }
10677
10678 if (quantity_max <= 0)
10679 quantity_max = m_VarQuantityMax;
10680
10681 return quantity_max;
10682 }
10683 //----------------------------------------------------------------
10684 override int GetQuantityMin()
10685 {
10686 return m_VarQuantityMin;
10687 }
10688 //----------------------------------------------------------------
10689 int GetQuantityInit()
10690 {
10691 return m_VarQuantityInit;
10692 }
10693
10694 //----------------------------------------------------------------
10695 override bool HasQuantity()
10696 {
10697 return !(GetQuantityMax() - GetQuantityMin() == 0);
10698 }
10699
10700 override float GetQuantity()
10701 {
10702 return m_VarQuantity;
10703 }
10704
10705 bool IsFullQuantity()
10706 {
10707 return GetQuantity() >= GetQuantityMax();
10708 }
10709
10710 //Calculates weight of single item without attachments and cargo
10711 override float GetSingleInventoryItemWeightEx()
10712 {
10713 //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
10714 float weightEx = GetWeightEx();//overall weight of the item
10715 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
10716 return weightEx - special;
10717 }
10718
10719 // Obsolete, use GetSingleInventoryItemWeightEx() instead
10721 {
10723 }
10724
10725 override protected float GetWeightSpecialized(bool forceRecalc = false)
10726 {
10727 if (IsSplitable()) //quantity determines size of the stack
10728 {
10729 #ifdef DEVELOPER
10730 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
10731 {
10732 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
10733 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
10734 }
10735 #endif
10736
10737 return GetQuantity() * GetConfigWeightModified();
10738 }
10739 else if (HasEnergyManager())// items with energy manager
10740 {
10741 #ifdef DEVELOPER
10742 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
10743 {
10744 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
10745 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
10746 }
10747 #endif
10748 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
10749 }
10750 else//everything else
10751 {
10752 #ifdef DEVELOPER
10753 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
10754 {
10755 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
10756 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
10757 }
10758 #endif
10759 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
10760 }
10761 }
10762
10764 int GetNumberOfItems()
10765 {
10766 int item_count = 0;
10767 ItemBase item;
10768
10769 GameInventory inventory = GetInventory();
10770 CargoBase cargo = inventory.GetCargo();
10771 if (cargo != NULL)
10772 {
10773 item_count = cargo.GetItemCount();
10774 }
10775
10776 int nAttachments = inventory.AttachmentCount();
10777 for (int i = 0; i < nAttachments; ++i)
10778 {
10779 Class.CastTo(item, inventory.GetAttachmentFromIndex(i));
10780 if (item)
10781 item_count += item.GetNumberOfItems();
10782 }
10783 return item_count;
10784 }
10785
10787 float GetUnitWeight(bool include_wetness = true)
10788 {
10789 float weight = 0;
10790 float wetness = 1;
10791 if (include_wetness)
10792 wetness += GetWet();
10793 if (IsSplitable()) //quantity determines size of the stack
10794 {
10795 weight = wetness * m_ConfigWeight;
10796 }
10797 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
10798 {
10799 weight = 1;
10800 }
10801 return weight;
10802 }
10803
10804 //-----------------------------------------------------------------
10805
10806 override void ClearInventory()
10807 {
10808 GameInventory inventory = GetInventory();
10809 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && inventory)
10810 {
10811 array<EntityAI> items = new array<EntityAI>;
10812 inventory.EnumerateInventory(InventoryTraversalType.INORDER, items);
10813 for (int i = 0; i < items.Count(); ++i)
10814 {
10815 ItemBase item = ItemBase.Cast(items.Get(i));
10816 if (item)
10817 {
10818 g_Game.ObjectDelete(item);
10819 }
10820 }
10821 }
10822 }
10823
10824 //------------------------- Energy
10825
10826 //----------------------------------------------------------------
10827 float GetEnergy()
10828 {
10829 float energy = 0;
10830 if (HasEnergyManager())
10831 {
10832 energy = GetCompEM().GetEnergy();
10833 }
10834 return energy;
10835 }
10836
10837
10838 override void OnEnergyConsumed()
10839 {
10840 super.OnEnergyConsumed();
10841
10843 }
10844
10845 override void OnEnergyAdded()
10846 {
10847 super.OnEnergyAdded();
10848
10850 }
10851
10852 // Converts energy (from Energy Manager) to quantity, if enabled.
10854 {
10855 if (g_Game.IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
10856 {
10857 if (HasQuantity())
10858 {
10859 float energy_0to1 = GetCompEM().GetEnergy0To1();
10860 SetQuantityNormalized(energy_0to1);
10861 }
10862 }
10863 }
10864
10865 //----------------------------------------------------------------
10866 float GetHeatIsolationInit()
10867 {
10868 return ConfigGetFloat("heatIsolation");
10869 }
10870
10871 float GetHeatIsolation()
10872 {
10873 return m_HeatIsolation;
10874 }
10875
10876 float GetDryingIncrement(string pIncrementName)
10877 {
10878 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
10879 if (g_Game.ConfigIsExisting(paramPath))
10880 return g_Game.ConfigGetFloat(paramPath);
10881
10882 return 0.0;
10883 }
10884
10885 float GetSoakingIncrement(string pIncrementName)
10886 {
10887 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
10888 if (g_Game.ConfigIsExisting(paramPath))
10889 return g_Game.ConfigGetFloat(paramPath);
10890
10891 return 0.0;
10892 }
10893 //----------------------------------------------------------------
10894 override void SetWet(float value, bool allow_client = false)
10895 {
10896 if (!IsServerCheck(allow_client))
10897 return;
10898
10899 float min = GetWetMin();
10900 float max = GetWetMax();
10901
10902 float previousValue = m_VarWet;
10903
10904 m_VarWet = Math.Clamp(value, min, max);
10905
10906 if (previousValue != m_VarWet)
10907 {
10908 SetVariableMask(VARIABLE_WET);
10909 OnWetChanged(m_VarWet, previousValue);
10910 }
10911 }
10912 //----------------------------------------------------------------
10913 override void AddWet(float value)
10914 {
10915 SetWet(GetWet() + value);
10916 }
10917 //----------------------------------------------------------------
10918 override void SetWetMax()
10919 {
10921 }
10922 //----------------------------------------------------------------
10923 override float GetWet()
10924 {
10925 return m_VarWet;
10926 }
10927 //----------------------------------------------------------------
10928 override float GetWetMax()
10929 {
10930 return m_VarWetMax;
10931 }
10932 //----------------------------------------------------------------
10933 override float GetWetMin()
10934 {
10935 return m_VarWetMin;
10936 }
10937 //----------------------------------------------------------------
10938 override float GetWetInit()
10939 {
10940 return m_VarWetInit;
10941 }
10942 //----------------------------------------------------------------
10943 override void OnWetChanged(float newVal, float oldVal)
10944 {
10945 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
10946 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
10947 if (newLevel != oldLevel)
10948 {
10949 OnWetLevelChanged(newLevel,oldLevel);
10950 }
10951 }
10952
10953 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
10954 {
10955 SetWeightDirty();
10956 }
10957
10958 override EWetnessLevel GetWetLevel()
10959 {
10960 return GetWetLevelInternal(m_VarWet);
10961 }
10962
10963 //----------------------------------------------------------------
10964
10965 override void SetStoreLoad(bool value)
10966 {
10967 m_IsStoreLoad = value;
10968 }
10969
10970 override bool IsStoreLoad()
10971 {
10972 return m_IsStoreLoad;
10973 }
10974
10975 override void SetStoreLoadedQuantity(float value)
10976 {
10977 m_StoreLoadedQuantity = value;
10978 }
10979
10980 override float GetStoreLoadedQuantity()
10981 {
10982 return m_StoreLoadedQuantity;
10983 }
10984
10985 //----------------------------------------------------------------
10986
10987 float GetItemModelLength()
10988 {
10989 if (ConfigIsExisting("itemModelLength"))
10990 {
10991 return ConfigGetFloat("itemModelLength");
10992 }
10993 return 0;
10994 }
10995
10996 float GetItemAttachOffset()
10997 {
10998 if (ConfigIsExisting("itemAttachOffset"))
10999 {
11000 return ConfigGetFloat("itemAttachOffset");
11001 }
11002 return 0;
11003 }
11004
11005 override void SetCleanness(int value, bool allow_client = false)
11006 {
11007 if (!IsServerCheck(allow_client))
11008 return;
11009
11010 int previousValue = m_Cleanness;
11011
11012 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
11013
11014 if (previousValue != m_Cleanness)
11015 SetVariableMask(VARIABLE_CLEANNESS);
11016 }
11017
11018 override int GetCleanness()
11019 {
11020 return m_Cleanness;
11021 }
11022
11024 {
11025 return true;
11026 }
11027
11028 //----------------------------------------------------------------
11029 // ATTACHMENT LOCKING
11030 // Getters relevant to generic ActionLockAttachment
11031 int GetLockType()
11032 {
11033 return m_LockType;
11034 }
11035
11036 string GetLockSoundSet()
11037 {
11038 return m_LockSoundSet;
11039 }
11040
11041 //----------------------------------------------------------------
11042 //------------------------- Color
11043 // sets items color variable given color components
11044 override void SetColor(int r, int g, int b, int a)
11045 {
11050 SetVariableMask(VARIABLE_COLOR);
11051 }
11053 override void GetColor(out int r,out int g,out int b,out int a)
11054 {
11059 }
11060
11061 bool IsColorSet()
11062 {
11063 return IsVariableSet(VARIABLE_COLOR);
11064 }
11065
11067 string GetColorString()
11068 {
11069 int r,g,b,a;
11070 GetColor(r,g,b,a);
11071 r = r/255;
11072 g = g/255;
11073 b = b/255;
11074 a = a/255;
11075 return MiscGameplayFunctions.GetColorString(r, g, b, a);
11076 }
11077 //----------------------------------------------------------------
11078 //------------------------- LiquidType
11079
11080 override void SetLiquidType(int value, bool allow_client = false)
11081 {
11082 if (!IsServerCheck(allow_client))
11083 return;
11084
11085 int old = m_VarLiquidType;
11086 m_VarLiquidType = value;
11087 OnLiquidTypeChanged(old,value);
11088 SetVariableMask(VARIABLE_LIQUIDTYPE);
11089 }
11090
11091 int GetLiquidTypeInit()
11092 {
11093 return ConfigGetInt("varLiquidTypeInit");
11094 }
11095
11096 override int GetLiquidType()
11097 {
11098 return m_VarLiquidType;
11099 }
11100
11101 protected void OnLiquidTypeChanged(int oldType, int newType)
11102 {
11103 if (newType == LIQUID_NONE && GetIsFrozen())
11104 SetFrozen(false);
11105 }
11106
11108 void UpdateQuickbarShortcutVisibility(PlayerBase player)
11109 {
11110 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
11111 }
11112
11113 // -------------------------------------------------------------------------
11115 void OnInventoryEnter(Man player)
11116 {
11117 PlayerBase nplayer;
11118 if (PlayerBase.CastTo(nplayer, player))
11119 {
11120 m_CanPlayImpactSound = true;
11121 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
11122 }
11123 }
11124
11125 // -------------------------------------------------------------------------
11127 void OnInventoryExit(Man player)
11128 {
11129 PlayerBase nplayer;
11130 if (PlayerBase.CastTo(nplayer,player))
11131 {
11132 nplayer.SetEnableQuickBarEntityShortcut(this, false);
11133 }
11134
11135 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
11136
11137 if (HasEnergyManager())
11138 {
11139 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
11140 }
11141 }
11142
11143 // ADVANCED PLACEMENT EVENTS
11144 override void OnPlacementStarted(Man player)
11145 {
11146 super.OnPlacementStarted(player);
11147
11148 SetTakeable(false);
11149 }
11150
11151 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
11152 {
11153 if (m_AdminLog)
11154 {
11155 m_AdminLog.OnPlacementComplete(player, this);
11156 }
11157
11158 super.OnPlacementComplete(player, position, orientation);
11159 }
11160
11161 //-----------------------------
11162 // AGENT SYSTEM
11163 //-----------------------------
11164 //--------------------------------------------------------------------------
11165 bool ContainsAgent(int agent_id)
11166 {
11167 if (agent_id & m_AttachedAgents)
11168 {
11169 return true;
11170 }
11171 else
11172 {
11173 return false;
11174 }
11175 }
11176
11177 //--------------------------------------------------------------------------
11178 override void RemoveAgent(int agent_id)
11179 {
11180 if (ContainsAgent(agent_id))
11181 {
11182 m_AttachedAgents = ~agent_id & m_AttachedAgents;
11183 }
11184 }
11185
11186 //--------------------------------------------------------------------------
11187 override void RemoveAllAgents()
11188 {
11189 m_AttachedAgents = 0;
11190 }
11191 //--------------------------------------------------------------------------
11192 override void RemoveAllAgentsExcept(int agent_to_keep)
11193 {
11194 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
11195 }
11196 // -------------------------------------------------------------------------
11197 override void InsertAgent(int agent, float count = 1)
11198 {
11199 if (count < 1)
11200 return;
11201 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
11203 }
11204
11206 void TransferAgents(int agents)
11207 {
11209 }
11210
11211 // -------------------------------------------------------------------------
11212 override int GetAgents()
11213 {
11214 return m_AttachedAgents;
11215 }
11216 //----------------------------------------------------------------------
11217
11218 /*int GetContaminationType()
11219 {
11220 int contamination_type;
11221
11222 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
11223 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
11224 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
11225 const int DIRTY_MASK = eAgents.WOUND_AGENT;
11226
11227 Edible_Base edible = Edible_Base.Cast(this);
11228 int agents = GetAgents();
11229 if (edible)
11230 {
11231 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
11232 if (profile)
11233 {
11234 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
11235 }
11236 }
11237 if (agents & CONTAMINATED_MASK)
11238 {
11239 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
11240 }
11241 if (agents & POISONED_MASK)
11242 {
11243 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
11244 }
11245 if (agents & NERVE_GAS_MASK)
11246 {
11247 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
11248 }
11249 if (agents & DIRTY_MASK)
11250 {
11251 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
11252 }
11253
11254 return agents;
11255 }*/
11256
11257 // -------------------------------------------------------------------------
11258 bool LoadAgents(ParamsReadContext ctx, int version)
11259 {
11260 if (!ctx.Read(m_AttachedAgents))
11261 return false;
11262 return true;
11263 }
11264 // -------------------------------------------------------------------------
11266 {
11267
11269 }
11270 // -------------------------------------------------------------------------
11271
11273 override void CheckForRoofLimited(float timeTresholdMS = 3000)
11274 {
11275 super.CheckForRoofLimited(timeTresholdMS);
11276
11277 float time = g_Game.GetTime();
11278 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
11279 {
11280 m_PreviousRoofTestTime = time;
11281 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
11282 }
11283 }
11284
11285 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
11286 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
11287 {
11288 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
11289 {
11290 return 0;
11291 }
11292
11293 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
11294 {
11295 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
11296 if (filter)
11297 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
11298 else
11299 return 0;//otherwise return 0 when no filter attached
11300 }
11301
11302 string subclassPath, entryName;
11303
11304 switch (type)
11305 {
11306 case DEF_BIOLOGICAL:
11307 entryName = "biological";
11308 break;
11309 case DEF_CHEMICAL:
11310 entryName = "chemical";
11311 break;
11312 default:
11313 entryName = "biological";
11314 break;
11315 }
11316
11317 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
11318
11319 return g_Game.ConfigGetFloat(subclassPath + entryName);
11320 }
11321
11322
11323
11325 override void EEOnCECreate()
11326 {
11327 if (!IsMagazine())
11329
11331 }
11332
11333
11334 //-------------------------
11335 // OPEN/CLOSE USER ACTIONS
11336 //-------------------------
11338 void Open();
11339 void Close();
11340 bool IsOpen()
11341 {
11342 return true;
11343 }
11344
11345 override bool CanDisplayCargo()
11346 {
11347 return IsOpen();
11348 }
11349
11350
11351 // ------------------------------------------------------------
11352 // CONDITIONS
11353 // ------------------------------------------------------------
11354 override bool CanPutInCargo(EntityAI parent)
11355 {
11356 if (parent)
11357 {
11358 if (parent.IsInherited(DayZInfected))
11359 return true;
11360
11361 if (!parent.IsRuined())
11362 return true;
11363 }
11364
11365 return true;
11366 }
11367
11368 override bool CanPutAsAttachment(EntityAI parent)
11369 {
11370 if (!super.CanPutAsAttachment(parent))
11371 {
11372 return false;
11373 }
11374
11375 if (!IsRuined() && !parent.IsRuined())
11376 {
11377 return true;
11378 }
11379
11380 return false;
11381 }
11382
11383 override bool CanReceiveItemIntoCargo(EntityAI item)
11384 {
11385 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
11386 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
11387 // return false;
11388
11389 return super.CanReceiveItemIntoCargo(item);
11390 }
11391
11392 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
11393 {
11394 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
11395 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
11396 // return false;
11397
11398 GameInventory attachmentInv = attachment.GetInventory();
11399 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
11400 {
11401 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
11402 return false;
11403 }
11404
11405 InventoryLocation loc = new InventoryLocation();
11406 attachment.GetInventory().GetCurrentInventoryLocation(loc);
11407 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
11408 return false;
11409
11410 return super.CanReceiveAttachment(attachment, slotId);
11411 }
11412
11413 override bool CanReleaseAttachment(EntityAI attachment)
11414 {
11415 if (!super.CanReleaseAttachment(attachment))
11416 return false;
11417
11418 return GetInventory().AreChildrenAccessible();
11419 }
11420
11421 /*override bool CanLoadAttachment(EntityAI attachment)
11422 {
11423 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
11424 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
11425 // return false;
11426
11427 GameInventory attachmentInv = attachment.GetInventory();
11428 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
11429 {
11430 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
11431 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
11432
11433 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
11434 return false;
11435 }
11436
11437 return super.CanLoadAttachment(attachment);
11438 }*/
11439
11440 // Plays muzzle flash particle effects
11441 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11442 {
11443 int id = muzzle_owner.GetMuzzleID();
11444 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
11445
11446 if (WPOF_array)
11447 {
11448 for (int i = 0; i < WPOF_array.Count(); i++)
11449 {
11450 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
11451
11452 if (WPOF)
11453 {
11454 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
11455 }
11456 }
11457 }
11458 }
11459
11460 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
11461 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11462 {
11463 int id = muzzle_owner.GetMuzzleID();
11464 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
11465
11466 if (WPOBE_array)
11467 {
11468 for (int i = 0; i < WPOBE_array.Count(); i++)
11469 {
11470 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
11471
11472 if (WPOBE)
11473 {
11474 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
11475 }
11476 }
11477 }
11478 }
11479
11480 // Plays all weapon overheating particles
11481 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11482 {
11483 int id = muzzle_owner.GetMuzzleID();
11484 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
11485
11486 if (WPOOH_array)
11487 {
11488 for (int i = 0; i < WPOOH_array.Count(); i++)
11489 {
11490 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
11491
11492 if (WPOOH)
11493 {
11494 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
11495 }
11496 }
11497 }
11498 }
11499
11500 // Updates all weapon overheating particles
11501 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11502 {
11503 int id = muzzle_owner.GetMuzzleID();
11504 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
11505
11506 if (WPOOH_array)
11507 {
11508 for (int i = 0; i < WPOOH_array.Count(); i++)
11509 {
11510 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
11511
11512 if (WPOOH)
11513 {
11514 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
11515 }
11516 }
11517 }
11518 }
11519
11520 // Stops overheating particles
11521 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11522 {
11523 int id = muzzle_owner.GetMuzzleID();
11524 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
11525
11526 if (WPOOH_array)
11527 {
11528 for (int i = 0; i < WPOOH_array.Count(); i++)
11529 {
11530 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
11531
11532 if (WPOOH)
11533 {
11534 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
11535 }
11536 }
11537 }
11538 }
11539
11540 //----------------------------------------------------------------
11541 //Item Behaviour - unified approach
11542 override bool IsHeavyBehaviour()
11543 {
11544 if (m_ItemBehaviour == 0)
11545 {
11546 return true;
11547 }
11548
11549 return false;
11550 }
11551
11552 override bool IsOneHandedBehaviour()
11553 {
11554 if (m_ItemBehaviour == 1)
11555 {
11556 return true;
11557 }
11558
11559 return false;
11560 }
11561
11562 override bool IsTwoHandedBehaviour()
11563 {
11564 if (m_ItemBehaviour == 2)
11565 {
11566 return true;
11567 }
11568
11569 return false;
11570 }
11571
11572 bool IsDeployable()
11573 {
11574 return false;
11575 }
11576
11578 float GetDeployTime()
11579 {
11580 return UATimeSpent.DEFAULT_DEPLOY;
11581 }
11582
11583
11584 //----------------------------------------------------------------
11585 // Item Targeting (User Actions)
11586 override void SetTakeable(bool pState)
11587 {
11588 m_IsTakeable = pState;
11589 SetSynchDirty();
11590 }
11591
11592 override bool IsTakeable()
11593 {
11594 return m_IsTakeable;
11595 }
11596
11597 // For cases where we want to show object widget which cant be taken to hands
11599 {
11600 return false;
11601 }
11602
11604 protected void PreLoadSoundAttachmentType()
11605 {
11606 string att_type = "None";
11607
11608 if (ConfigIsExisting("soundAttType"))
11609 {
11610 att_type = ConfigGetString("soundAttType");
11611 }
11612
11613 m_SoundAttType = att_type;
11614 }
11615
11616 override string GetAttachmentSoundType()
11617 {
11618 return m_SoundAttType;
11619 }
11620
11621 //----------------------------------------------------------------
11622 //SOUNDS - ItemSoundHandler
11623 //----------------------------------------------------------------
11624
11625 string GetPlaceSoundset(); // played when deploy starts
11626 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
11627 string GetDeploySoundset(); // played when deploy sucessfully finishes
11628 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
11629 string GetFoldSoundset(); // played when fold sucessfully finishes
11630
11632 {
11633 if (!m_ItemSoundHandler)
11635
11636 return m_ItemSoundHandler;
11637 }
11638
11639 // override to initialize sounds
11640 protected void InitItemSounds()
11641 {
11642 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty && !GetInventoryItemType().SetDetachSoundEvent() && !GetInventoryItemType().SetAttachSoundEvent())
11643 return;
11644
11646
11647 if (GetPlaceSoundset() != string.Empty)
11648 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
11649
11650 if (GetDeploySoundset() != string.Empty)
11651 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
11652
11653 SoundParameters params = new SoundParameters();
11654 params.m_Loop = true;
11655 if (GetLoopDeploySoundset() != string.Empty)
11656 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
11657 }
11658
11659 // Start sound using ItemSoundHandler
11660 void StartItemSoundServer(int id, int slotId)
11661 {
11662 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
11663 {
11664 m_SoundSyncSlotID = slotId;
11665 m_SoundSyncPlay = id;
11666
11667 SetSynchDirty();
11668
11669 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
11670 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStartItemSoundServer, 100);
11671 }
11672 }
11673
11674 void StartItemSoundServer(int id)
11675 {
11676 StartItemSoundServer(id, InventorySlots.INVALID);
11677 }
11678
11679 // Stop sound using ItemSoundHandler
11680 void StopItemSoundServer(int id)
11681 {
11682 if (!g_Game.IsServer())
11683 return;
11684
11685 m_SoundSyncStop = id;
11686 SetSynchDirty();
11687
11688 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
11689 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStopItemSoundServer, 100);
11690 }
11691
11692 protected void ClearStartItemSoundServer()
11693 {
11694 m_SoundSyncPlay = 0;
11695 m_SoundSyncSlotID = InventorySlots.INVALID;
11696 }
11697
11698 protected void ClearStopItemSoundServer()
11699 {
11700 m_SoundSyncStop = 0;
11701 }
11702
11703 void OnApply(PlayerBase player);
11704
11706 {
11707 return 1.0;
11708 };
11709 //returns applicable selection
11710 array<string> GetHeadHidingSelection()
11711 {
11713 }
11714
11716 {
11718 }
11719
11720 WrittenNoteData GetWrittenNoteData() {};
11721
11723 {
11724 SetDynamicPhysicsLifeTime(0.01);
11725 m_ItemBeingDroppedPhys = false;
11726 }
11727
11729 {
11730 array<string> zone_names = new array<string>;
11731 GetDamageZones(zone_names);
11732 for (int i = 0; i < zone_names.Count(); i++)
11733 {
11734 SetHealthMax(zone_names.Get(i),"Health");
11735 }
11736 SetHealthMax("","Health");
11737 }
11738
11740 void SetZoneDamageCEInit()
11741 {
11742 float global_health = GetHealth01("","Health");
11743 array<string> zones = new array<string>;
11744 GetDamageZones(zones);
11745 //set damage of all zones to match global health level
11746 for (int i = 0; i < zones.Count(); i++)
11747 {
11748 SetHealth01(zones.Get(i),"Health",global_health);
11749 }
11750 }
11751
11753 bool IsCoverFaceForShave(string slot_name)
11754 {
11755 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
11756 }
11757
11758 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
11759 {
11760 if (!hasRootAsPlayer)
11761 {
11762 if (refParentIB)
11763 {
11764 // parent is wet
11765 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
11766 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
11767 // parent has liquid inside
11768 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
11769 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
11770 // drying
11771 else if (m_VarWet > m_VarWetMin)
11772 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
11773 }
11774 else
11775 {
11776 // drying on ground or inside non-itembase (car, ...)
11777 if (m_VarWet > m_VarWetMin)
11778 AddWet(-1 * delta * GetDryingIncrement("ground"));
11779 }
11780 }
11781 }
11782
11783 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
11784 {
11786 {
11787 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
11788 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
11789 {
11790 float heatPermCoef = 1.0;
11791 EntityAI ent = this;
11792 while (ent)
11793 {
11794 heatPermCoef *= ent.GetHeatPermeabilityCoef();
11795 ent = ent.GetHierarchyParent();
11796 }
11797
11798 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
11799 }
11800 }
11801 }
11802
11803 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
11804 {
11805 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
11806 EntityAI parent = GetHierarchyParent();
11807 if (!parent)
11808 {
11809 hasParent = false;
11810 hasRootAsPlayer = false;
11811 }
11812 else
11813 {
11814 hasParent = true;
11815 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
11816 refParentIB = ItemBase.Cast(parent);
11817 }
11818 }
11819
11820 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
11821 {
11822 // this is stub, implemented on Edible_Base
11823 }
11824
11825 bool CanDecay()
11826 {
11827 // return true used on selected food clases so they can decay
11828 return false;
11829 }
11830
11831 protected bool CanProcessDecay()
11832 {
11833 // this is stub, implemented on Edible_Base class
11834 // used to determine whether it is still necessary for the food to decay
11835 return false;
11836 }
11837
11838 protected bool CanHaveWetness()
11839 {
11840 // return true used on selected items that have a wetness effect
11841 return false;
11842 }
11843
11845 bool CanBeConsumed(ConsumeConditionData data = null)
11846 {
11847 return !GetIsFrozen() && IsOpen();
11848 }
11849
11850 override void ProcessVariables()
11851 {
11852 bool hasParent = false, hasRootAsPlayer = false;
11853 ItemBase refParentIB;
11854
11855 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
11856 bool foodDecay = g_Game.IsFoodDecayEnabled();
11857
11858 if (wwtu || foodDecay)
11859 {
11860 bool processWetness = wwtu && CanHaveWetness();
11861 bool processTemperature = wwtu && CanHaveTemperature();
11862 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
11863
11864 if (processWetness || processTemperature || processDecay)
11865 {
11866 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
11867
11868 if (processWetness)
11869 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
11870
11871 if (processTemperature)
11872 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
11873
11874 if (processDecay)
11875 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
11876 }
11877 }
11878 }
11879
11882 {
11883 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
11884 }
11885
11886 override float GetTemperatureFreezeThreshold()
11887 {
11889 return Liquid.GetFreezeThreshold(GetLiquidType());
11890
11891 return super.GetTemperatureFreezeThreshold();
11892 }
11893
11894 override float GetTemperatureThawThreshold()
11895 {
11897 return Liquid.GetThawThreshold(GetLiquidType());
11898
11899 return super.GetTemperatureThawThreshold();
11900 }
11901
11902 override float GetItemOverheatThreshold()
11903 {
11905 return Liquid.GetBoilThreshold(GetLiquidType());
11906
11907 return super.GetItemOverheatThreshold();
11908 }
11909
11910 override float GetTemperatureFreezeTime()
11911 {
11912 if (HasQuantity())
11913 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
11914
11915 return super.GetTemperatureFreezeTime();
11916 }
11917
11918 override float GetTemperatureThawTime()
11919 {
11920 if (HasQuantity())
11921 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
11922
11923 return super.GetTemperatureThawTime();
11924 }
11925
11927 void AffectLiquidContainerOnFill(int liquid_type, float amount);
11929 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
11930
11931 bool IsCargoException4x3(EntityAI item)
11932 {
11933 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
11934 }
11935
11937 {
11938 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
11939 }
11940
11942 void AddLightSourceItem(ItemBase lightsource)
11943 {
11944 m_LightSourceItem = lightsource;
11945 }
11946
11948 {
11949 m_LightSourceItem = null;
11950 }
11951
11953 {
11954 return m_LightSourceItem;
11955 }
11956
11958 array<int> GetValidFinishers()
11959 {
11960 return null;
11961 }
11962
11964 bool GetActionWidgetOverride(out typename name)
11965 {
11966 return false;
11967 }
11968
11969 bool PairWithDevice(notnull ItemBase otherDevice)
11970 {
11971 if (g_Game.IsServer())
11972 {
11973 ItemBase explosive = otherDevice;
11975 if (!trg)
11976 {
11977 trg = RemoteDetonatorTrigger.Cast(otherDevice);
11978 explosive = this;
11979 }
11980
11981 explosive.PairRemote(trg);
11982 trg.SetControlledDevice(explosive);
11983
11984 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
11985 trg.SetPersistentPairID(persistentID);
11986 explosive.SetPersistentPairID(persistentID);
11987
11988 return true;
11989 }
11990 return false;
11991 }
11992
11994 float GetBaitEffectivity()
11995 {
11996 float ret = 1.0;
11997 if (HasQuantity())
11998 ret *= GetQuantityNormalized();
11999 ret *= GetHealth01();
12000
12001 return ret;
12002 }
12003
12004 #ifdef DEVELOPER
12005 override void SetDebugItem()
12006 {
12007 super.SetDebugItem();
12008 _itemBase = this;
12009 }
12010
12011 override string GetDebugText()
12012 {
12013 string text = super.GetDebugText();
12014
12015 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
12016 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
12017
12018 return text;
12019 }
12020 #endif
12021
12022 bool CanBeUsedForSuicide()
12023 {
12024 return true;
12025 }
12026
12028 //DEPRECATED BELOW
12030 // Backwards compatibility
12031 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
12032 {
12033 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
12034 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
12035 }
12036
12037 // replaced by ItemSoundHandler
12038 protected EffectSound m_SoundDeployFinish;
12039 protected EffectSound m_SoundPlace;
12040 protected EffectSound m_DeployLoopSoundEx;
12041 protected EffectSound m_SoundDeploy;
12042 bool m_IsPlaceSound;
12043 bool m_IsDeploySound;
12045
12046 string GetDeployFinishSoundset();
12047 void PlayDeploySound();
12048 void PlayDeployFinishSound();
12049 void PlayPlaceSound();
12050 void PlayDeployLoopSoundEx();
12051 void StopDeployLoopSoundEx();
12052 void SoundSynchRemoteReset();
12053 void SoundSynchRemote();
12054 bool UsesGlobalDeploy(){return false;}
12055 bool CanPlayDeployLoopSound(){return false;}
12057 bool IsPlaceSound(){return m_IsPlaceSound;}
12058 bool IsDeploySound(){return m_IsDeploySound;}
12059 void SetIsPlaceSound(bool is_place_sound);
12060 void SetIsDeploySound(bool is_deploy_sound);
12061
12062 [Obsolete("Use ItemSoundHandler instead")]
12064 void PlayAttachSound(string slot_type)
12065 {
12066 if (!g_Game.IsDedicatedServer())
12067 {
12068 if (ConfigIsExisting("attachSoundSet"))
12069 {
12070 string cfg_path = "";
12071 string soundset = "";
12072 string type_name = GetType();
12073
12074 TStringArray cfg_soundset_array = new TStringArray;
12075 TStringArray cfg_slot_array = new TStringArray;
12076 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
12077 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
12078
12079 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
12080 {
12081 for (int i = 0; i < cfg_soundset_array.Count(); i++)
12082 {
12083 if (cfg_slot_array[i] == slot_type)
12084 {
12085 soundset = cfg_soundset_array[i];
12086 break;
12087 }
12088 }
12089 }
12090
12091 if (soundset != "")
12092 {
12093 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
12094 sound.SetAutodestroy(true);
12095 }
12096 }
12097 }
12098 }
12099
12100 void PlayDetachSound(string slot_type) {}
12101}
12102
12103EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
12104{
12105 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
12106 if (entity)
12107 {
12108 bool is_item = entity.IsInherited(ItemBase);
12109 if (is_item && full_quantity)
12110 {
12111 ItemBase item = ItemBase.Cast(entity);
12112 item.SetQuantity(item.GetQuantityInit());
12113 }
12114 }
12115 else
12116 {
12117 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
12118 return NULL;
12119 }
12120 return entity;
12121}
12122
12123void SetupSpawnedItem(ItemBase item, float health, float quantity)
12124{
12125 if (item)
12126 {
12127 if (health > 0)
12128 item.SetHealth("", "", health);
12129
12130 if (item.CanHaveTemperature())
12131 {
12132 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
12133 if (item.CanFreeze())
12134 item.SetFrozen(false);
12135 }
12136
12137 if (item.HasEnergyManager())
12138 {
12139 if (quantity >= 0)
12140 {
12141 item.GetCompEM().SetEnergy0To1(quantity);
12142 }
12143 else
12144 {
12145 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
12146 }
12147 }
12148 else if (item.IsMagazine())
12149 {
12150 Magazine mag = Magazine.Cast(item);
12151 if (quantity >= 0)
12152 {
12153 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
12154 }
12155 else
12156 {
12157 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
12158 }
12159
12160 }
12161 else
12162 {
12163 if (quantity >= 0)
12164 {
12165 item.SetQuantityNormalized(quantity, false);
12166 }
12167 else
12168 {
12169 item.SetQuantity(Math.AbsFloat(quantity));
12170 }
12171
12172 }
12173 }
12174}
12175
12176#ifdef DEVELOPER
12177ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
12178#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()