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

◆ OnAction()

override bool SpawnItemOnLocation::OnAction ( int action_id,
Man player,
ParamsReadContext ctx )
protected

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

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