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

◆ GetDebugActions()

override void SpawnItemOnLocation::GetDebugActions ( out TSelectableActionInfoArrayEx outputList)
protected

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

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