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

◆ OnAttachmentQuantityChanged()

void SpawnItemOnLocation::OnAttachmentQuantityChanged ( ItemBase item)
protected

Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChanged(item); first when overriding this event.

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

6893{
6894 override bool CanPutAsAttachment(EntityAI parent)
6895 {
6896 return true;
6897 }
6898};
6899
6900//const bool QUANTITY_DEBUG_REMOVE_ME = false;
6901
6902class ItemBase extends InventoryItem
6903{
6907
6909
6910 static int m_DebugActionsMask;
6912 // ============================================
6913 // Variable Manipulation System
6914 // ============================================
6915 // Quantity
6916
6917 float m_VarQuantity;
6918 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
6920 int m_VarQuantityMin;
6921 int m_VarQuantityMax;
6922 int m_Count;
6923 float m_VarStackMax;
6924 float m_StoreLoadedQuantity = float.LOWEST;
6925 // Wet
6926 float m_VarWet;
6927 float m_VarWetPrev;//for client to know wetness changed during synchronization
6928 float m_VarWetInit;
6929 float m_VarWetMin;
6930 float m_VarWetMax;
6931 // Cleanness
6932 int m_Cleanness;
6933 int m_CleannessInit;
6934 int m_CleannessMin;
6935 int m_CleannessMax;
6936 // impact sounds
6938 bool m_CanPlayImpactSound = true;
6939 float m_ImpactSpeed;
6941 //
6942 float m_HeatIsolation;
6943 float m_ItemModelLength;
6944 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
6946 int m_VarLiquidType;
6947 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
6948 int m_QuickBarBonus;
6949 bool m_IsBeingPlaced;
6950 bool m_IsHologram;
6951 bool m_IsTakeable;
6952 bool m_ThrowItemOnDrop;
6955 bool m_FixDamageSystemInit = false; //can be changed on storage version check
6956 bool can_this_be_combined; //Check if item can be combined
6957 bool m_CanThisBeSplit; //Check if item can be split
6958 bool m_IsStoreLoad = false;
6959 bool m_CanShowQuantity;
6960 bool m_HasQuantityBar;
6961 protected bool m_CanBeDigged;
6962 protected bool m_IsResultOfSplit
6963
6964 string m_SoundAttType;
6965 // items color variables
6970 //-------------------------------------------------------
6971
6972 // light source managing
6974
6978
6979 //==============================================
6980 // agent system
6981 private int m_AttachedAgents;
6982
6984 void TransferModifiers(PlayerBase reciever);
6985
6986
6987 // Weapons & suppressors particle effects
6992 static int m_LastRegisteredWeaponID = 0;
6993
6994 // Overheating effects
6996 float m_OverheatingShots;
6997 ref Timer m_CheckOverheating;
6998 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
6999 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
7000 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
7001 ref array <ref OverheatingParticle> m_OverheatingParticles;
7002
7004 protected bool m_HideSelectionsBySlot;
7005
7006 // Admin Log
7007 PluginAdminLog m_AdminLog;
7008
7009 // misc
7010 ref Timer m_PhysDropTimer;
7011
7012 // Attachment Locking variables
7013 ref array<int> m_CompatibleLocks;
7014 protected int m_LockType;
7015 protected ref EffectSound m_LockingSound;
7016 protected string m_LockSoundSet;
7017
7018 // ItemSoundHandler
7019 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
7020 protected int m_SoundSyncPlay; // id for sound to play
7021 protected int m_SoundSyncStop; // id for sound to stop
7023
7024 //temperature
7025 private float m_TemperaturePerQuantityWeight;
7026
7027 // -------------------------------------------------------------------------
7028 void ItemBase()
7029 {
7030 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
7034
7035 if (!GetGame().IsDedicatedServer())
7036 {
7037 if (HasMuzzle())
7038 {
7040
7042 {
7044 }
7045 }
7046
7048 m_ActionsInitialize = false;
7049 }
7050
7051 m_OldLocation = null;
7052
7053 if (GetGame().IsServer())
7054 {
7055 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
7056 }
7057
7058 if (ConfigIsExisting("headSelectionsToHide"))
7059 {
7061 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
7062 }
7063
7064 m_HideSelectionsBySlot = false;
7065 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
7066 {
7067 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
7068 }
7069
7070 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
7071
7072 m_IsResultOfSplit = false;
7073
7075 }
7076
7077 override void InitItemVariables()
7078 {
7079 super.InitItemVariables();
7080
7081 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
7082 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
7083 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
7084 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
7085 m_VarStackMax = ConfigGetFloat("varStackMax");
7086 m_Count = ConfigGetInt("count");
7087
7088 m_CanShowQuantity = ConfigGetBool("quantityShow");
7089 m_HasQuantityBar = ConfigGetBool("quantityBar");
7090
7091 m_CleannessInit = ConfigGetInt("varCleannessInit");
7093 m_CleannessMin = ConfigGetInt("varCleannessMin");
7094 m_CleannessMax = ConfigGetInt("varCleannessMax");
7095
7096 m_WantPlayImpactSound = false;
7097 m_ImpactSpeed = 0.0;
7098
7099 m_VarWetInit = ConfigGetFloat("varWetInit");
7101 m_VarWetMin = ConfigGetFloat("varWetMin");
7102 m_VarWetMax = ConfigGetFloat("varWetMax");
7103
7104 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
7105 if (IsLiquidContainer() && GetQuantity() != 0)
7107 m_IsBeingPlaced = false;
7108 m_IsHologram = false;
7109 m_IsTakeable = true;
7110 m_CanBeMovedOverride = false;
7114 m_CanBeDigged = ConfigGetBool("canBeDigged");
7115
7116 m_CompatibleLocks = new array<int>();
7117 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
7118 m_LockType = ConfigGetInt("lockType");
7119
7120 //Define if item can be split and set ability to be combined accordingly
7121 m_CanThisBeSplit = false;
7122 can_this_be_combined = false;
7123 if (ConfigIsExisting("canBeSplit"))
7124 {
7125 can_this_be_combined = ConfigGetBool("canBeSplit");
7127 }
7128
7129 m_ItemBehaviour = -1;
7130 if (ConfigIsExisting("itemBehaviour"))
7131 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
7132
7133 //RegisterNetSyncVariableInt("m_VariablesMask");
7134 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7135 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
7136 RegisterNetSyncVariableInt("m_VarLiquidType");
7137 RegisterNetSyncVariableInt("m_Cleanness",0,1);
7138
7139 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
7140 RegisterNetSyncVariableFloat("m_ImpactSpeed");
7141 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
7142
7143 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
7144 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
7145 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
7146 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
7147
7148 RegisterNetSyncVariableBool("m_IsBeingPlaced");
7149 RegisterNetSyncVariableBool("m_IsTakeable");
7150 RegisterNetSyncVariableBool("m_IsHologram");
7151
7152 InitItemSounds();
7154 {
7155 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
7156 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
7157 }
7158
7159 m_LockSoundSet = ConfigGetString("lockSoundSet");
7160
7162 if (ConfigIsExisting("temperaturePerQuantityWeight"))
7163 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
7164
7165 }
7166
7167 override int GetQuickBarBonus()
7168 {
7169 return m_QuickBarBonus;
7170 }
7171
7172 void InitializeActions()
7173 {
7175 if (!m_InputActionMap)
7176 {
7178 m_InputActionMap = iam;
7179 SetActions();
7181 }
7182 }
7183
7184 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
7185 {
7187 {
7188 m_ActionsInitialize = true;
7190 }
7191
7192 actions = m_InputActionMap.Get(action_input_type);
7193 }
7194
7195 void SetActions()
7196 {
7197 AddAction(ActionTakeItem);
7198 AddAction(ActionTakeItemToHands);
7199 AddAction(ActionWorldCraft);
7201 AddAction(ActionAttachWithSwitch);
7202 }
7203
7204 void SetActionAnimOverrides(); // Override action animation for specific item
7205
7206 void AddAction(typename actionName)
7207 {
7208 ActionBase action = ActionManagerBase.GetAction(actionName);
7209
7210 if (!action)
7211 {
7212 Debug.LogError("Action " + actionName + " dosn't exist!");
7213 return;
7214 }
7215
7216 typename ai = action.GetInputType();
7217 if (!ai)
7218 {
7219 m_ActionsInitialize = false;
7220 return;
7221 }
7222
7223 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
7224 if (!action_array)
7225 {
7226 action_array = new array<ActionBase_Basic>;
7227 m_InputActionMap.Insert(ai, action_array);
7228 }
7229 if (LogManager.IsActionLogEnable())
7230 {
7231 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
7232 }
7233
7234 if (action_array.Find(action) != -1)
7235 {
7236 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
7237 }
7238 else
7239 {
7240 action_array.Insert(action);
7241 }
7242 }
7243
7244 void RemoveAction(typename actionName)
7245 {
7246 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
7247 ActionBase action = player.GetActionManager().GetAction(actionName);
7248 typename ai = action.GetInputType();
7249 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
7250
7251 if (action_array)
7252 {
7253 action_array.RemoveItem(action);
7254 }
7255 }
7256
7257 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
7258 // Set -1 for params which should stay in default state
7259 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
7260 {
7261 ActionOverrideData overrideData = new ActionOverrideData();
7262 overrideData.m_CommandUID = commandUID;
7263 overrideData.m_CommandUIDProne = commandUIDProne;
7264 overrideData.m_StanceMask = stanceMask;
7265
7266 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
7267 if (!actionMap) // create new map of action > overidables map
7268 {
7269 actionMap = new TActionAnimOverrideMap();
7270 m_ItemActionOverrides.Insert(action, actionMap);
7271 }
7272
7273 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
7274
7275 }
7276
7277 void OnItemInHandsPlayerSwimStart(PlayerBase player);
7278
7279 ScriptedLightBase GetLight();
7280
7281 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
7282 void LoadParticleConfigOnFire(int id)
7283 {
7284 if (!m_OnFireEffect)
7286
7289
7290 string config_to_search = "CfgVehicles";
7291 string muzzle_owner_config;
7292
7293 if (!m_OnFireEffect.Contains(id))
7294 {
7295 if (IsInherited(Weapon))
7296 config_to_search = "CfgWeapons";
7297
7298 muzzle_owner_config = config_to_search + " " + GetType() + " ";
7299
7300 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
7301
7302 int config_OnFire_subclass_count = GetGame().ConfigGetChildrenCount(config_OnFire_class);
7303
7304 if (config_OnFire_subclass_count > 0)
7305 {
7306 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
7307
7308 for (int i = 0; i < config_OnFire_subclass_count; i++)
7309 {
7310 string particle_class = "";
7311 GetGame().ConfigGetChildName(config_OnFire_class, i, particle_class);
7312 string config_OnFire_entry = config_OnFire_class + particle_class;
7313 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
7314 WPOF_array.Insert(WPOF);
7315 }
7316
7317
7318 m_OnFireEffect.Insert(id, WPOF_array);
7319 }
7320 }
7321
7322 if (!m_OnBulletCasingEjectEffect.Contains(id))
7323 {
7324 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
7325 muzzle_owner_config = config_to_search + " " + GetType() + " ";
7326
7327 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
7328
7329 int config_OnBulletCasingEject_count = GetGame().ConfigGetChildrenCount(config_OnBulletCasingEject_class);
7330
7331 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
7332 {
7333 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
7334
7335 for (i = 0; i < config_OnBulletCasingEject_count; i++)
7336 {
7337 string particle_class2 = "";
7338 GetGame().ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
7339 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
7340 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
7341 WPOBE_array.Insert(WPOBE);
7342 }
7343
7344
7345 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
7346 }
7347 }
7348 }
7349
7350 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
7352 {
7355
7356 if (!m_OnOverheatingEffect.Contains(id))
7357 {
7358 string config_to_search = "CfgVehicles";
7359
7360 if (IsInherited(Weapon))
7361 config_to_search = "CfgWeapons";
7362
7363 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
7364 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
7365
7366 if (GetGame().ConfigIsExisting(config_OnOverheating_class))
7367 {
7368
7369 m_ShotsToStartOverheating = GetGame().ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
7370
7372 {
7373 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
7374 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
7375 Error(error);
7376 return;
7377 }
7378
7379 m_OverheatingDecayInterval = GetGame().ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
7380 m_MaxOverheatingValue = GetGame().ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
7381
7382
7383
7384 int config_OnOverheating_subclass_count = GetGame().ConfigGetChildrenCount(config_OnOverheating_class);
7385 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
7386
7387 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
7388 {
7389 string particle_class = "";
7390 GetGame().ConfigGetChildName(config_OnOverheating_class, i, particle_class);
7391 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
7392 int entry_type = GetGame().ConfigGetType(config_OnOverheating_entry);
7393
7394 if (entry_type == CT_CLASS)
7395 {
7396 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
7397 WPOOH_array.Insert(WPOF);
7398 }
7399 }
7400
7401
7402 m_OnOverheatingEffect.Insert(id, WPOOH_array);
7403 }
7404 }
7405 }
7406
7407 float GetOverheatingValue()
7408 {
7409 return m_OverheatingShots;
7410 }
7411
7412 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
7413 {
7414 if (m_MaxOverheatingValue > 0)
7415 {
7417
7418 if (!m_CheckOverheating)
7420
7422 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
7423
7424 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7425 }
7426 }
7427
7428 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7429 {
7431 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7432
7434 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7435
7437 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7438
7440 {
7442 }
7443 }
7444
7446 {
7448 }
7449
7450 void OnOverheatingDecay()
7451 {
7452 if (m_MaxOverheatingValue > 0)
7453 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
7454 else
7456
7457 if (m_OverheatingShots <= 0)
7458 {
7461 }
7462 else
7463 {
7464 if (!m_CheckOverheating)
7466
7468 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
7469 }
7470
7471 CheckOverheating(this, "", this);
7472 }
7473
7474 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7475 {
7477 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
7478 }
7479
7480 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7481 {
7483 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
7485 }
7486
7487 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
7488 {
7490 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
7491 }
7492
7493 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
7494 {
7496 m_OverheatingParticles = new array<ref OverheatingParticle>;
7497
7498 OverheatingParticle OP = new OverheatingParticle();
7499 OP.RegisterParticle(p);
7500 OP.SetOverheatingLimitMin(min_heat_coef);
7501 OP.SetOverheatingLimitMax(max_heat_coef);
7502 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
7503
7504 m_OverheatingParticles.Insert(OP);
7505 }
7506
7507 float GetOverheatingCoef()
7508 {
7509 if (m_MaxOverheatingValue > 0)
7511
7512 return -1;
7513 }
7514
7516 {
7518 {
7519 float overheat_coef = GetOverheatingCoef();
7520 int count = m_OverheatingParticles.Count();
7521
7522 for (int i = count; i > 0; --i)
7523 {
7524 int id = i - 1;
7525 OverheatingParticle OP = m_OverheatingParticles.Get(id);
7526 Particle p = OP.GetParticle();
7527
7528 float overheat_min = OP.GetOverheatingLimitMin();
7529 float overheat_max = OP.GetOverheatingLimitMax();
7530
7531 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
7532 {
7533 if (p)
7534 {
7535 p.Stop();
7536 OP.RegisterParticle(null);
7537 }
7538 }
7539 }
7540 }
7541 }
7542
7544 {
7546 {
7547 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
7548 {
7549 int id = i - 1;
7550 OverheatingParticle OP = m_OverheatingParticles.Get(id);
7551
7552 if (OP)
7553 {
7554 Particle p = OP.GetParticle();
7555
7556 if (p)
7557 {
7558 p.Stop();
7559 }
7560
7561 delete OP;
7562 }
7563 }
7564
7565 m_OverheatingParticles.Clear();
7567 }
7568 }
7569
7571 float GetInfectionChance(int system = 0, Param param = null)
7572 {
7573 return 0.0;
7574 }
7575
7576
7577 float GetDisinfectQuantity(int system = 0, Param param1 = null)
7578 {
7579 return 250;//default value
7580 }
7581
7582 float GetFilterDamageRatio()
7583 {
7584 return 0;
7585 }
7586
7588 bool HasMuzzle()
7589 {
7590 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
7591 return true;
7592
7593 return false;
7594 }
7595
7597 int GetMuzzleID()
7598 {
7599 if (!m_WeaponTypeToID)
7601
7602 if (m_WeaponTypeToID.Contains(GetType()))
7603 {
7604 return m_WeaponTypeToID.Get(GetType());
7605 }
7606 else
7607 {
7608 // Register new weapon ID
7610 }
7611
7613 }
7614
7621 {
7622 return -1;
7623 }
7624
7625
7626
7627 // -------------------------------------------------------------------------
7628 void ~ItemBase()
7629 {
7630 if (GetGame() && GetGame().GetPlayer() && (!GetGame().IsDedicatedServer()))
7631 {
7632 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
7633 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
7634
7635 if (r_index >= 0)
7636 {
7637 InventoryLocation r_il = new InventoryLocation;
7638 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
7639
7640 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
7641 int r_type = r_il.GetType();
7642 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
7643 {
7644 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7645 }
7646 else if (r_type == InventoryLocationType.ATTACHMENT)
7647 {
7648 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7649 }
7650
7651 }
7652
7653 player.GetHumanInventory().ClearUserReservedLocation(this);
7654 }
7655
7656 if (m_LockingSound)
7657 SEffectManager.DestroyEffect(m_LockingSound);
7658 }
7659
7660
7661
7662 // -------------------------------------------------------------------------
7663 static int GetDebugActionsMask()
7664 {
7665 return ItemBase.m_DebugActionsMask;
7666 }
7667
7668 static bool HasDebugActionsMask(int mask)
7669 {
7670 return ItemBase.m_DebugActionsMask & mask;
7671 }
7672
7673 static void SetDebugActionsMask(int mask)
7674 {
7675 ItemBase.m_DebugActionsMask = mask;
7676 }
7677
7678 static void AddDebugActionsMask(int mask)
7679 {
7680 ItemBase.m_DebugActionsMask |= mask;
7681 }
7682
7683 static void RemoveDebugActionsMask(int mask)
7684 {
7685 ItemBase.m_DebugActionsMask &= ~mask;
7686 }
7687
7688 static void ToggleDebugActionsMask(int mask)
7689 {
7690 if (HasDebugActionsMask(mask))
7691 {
7693 }
7694 else
7695 {
7696 AddDebugActionsMask(mask);
7697 }
7698 }
7699
7700 // -------------------------------------------------------------------------
7701 void SetCEBasedQuantity()
7702 {
7703 if (GetEconomyProfile())
7704 {
7705 float q_max = GetEconomyProfile().GetQuantityMax();
7706 if (q_max > 0)
7707 {
7708 float q_min = GetEconomyProfile().GetQuantityMin();
7709 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
7710
7711 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
7712 {
7713 ComponentEnergyManager comp = GetCompEM();
7714 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
7715 {
7716 comp.SetEnergy0To1(quantity_randomized);
7717 }
7718 }
7719 else if (HasQuantity())
7720 {
7721 SetQuantityNormalized(quantity_randomized, false);
7722 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
7723 }
7724
7725 }
7726 }
7727 }
7728
7730 void LockToParent()
7731 {
7732 EntityAI parent = GetHierarchyParent();
7733
7734 if (parent)
7735 {
7736 InventoryLocation inventory_location_to_lock = new InventoryLocation;
7737 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
7738 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
7739 }
7740 }
7741
7743 void UnlockFromParent()
7744 {
7745 EntityAI parent = GetHierarchyParent();
7746
7747 if (parent)
7748 {
7749 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
7750 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
7751 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
7752 }
7753 }
7754
7755 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
7756 {
7757 /*
7758 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
7759 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, GetGame().GetPlayer());
7760 */
7761 ItemBase item2 = ItemBase.Cast(entity2);
7762
7763 if (GetGame().IsClient())
7764 {
7765 if (ScriptInputUserData.CanStoreInputUserData())
7766 {
7767 ScriptInputUserData ctx = new ScriptInputUserData;
7769 ctx.Write(-1);
7770 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7771 ctx.Write(i1);
7772 ctx.Write(item2);
7773 ctx.Write(use_stack_max);
7774 ctx.Write(-1);
7775 ctx.Send();
7776
7777 if (IsCombineAll(item2, use_stack_max))
7778 {
7779 GetGame().GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
7780 }
7781 }
7782 }
7783 else if (!GetGame().IsMultiplayer())
7784 {
7785 CombineItems(item2, use_stack_max);
7786 }
7787 }
7788
7789 bool IsLiquidPresent()
7790 {
7791 return (GetLiquidType() != 0 && HasQuantity());
7792 }
7793
7794 bool IsLiquidContainer()
7795 {
7796 return m_LiquidContainerMask != 0;
7797 }
7798
7800 {
7801 return m_LiquidContainerMask;
7802 }
7803
7804 bool IsBloodContainer()
7805 {
7806 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
7807 return false;
7808 }
7809
7810 bool IsNVG()
7811 {
7812 return false;
7813 }
7814
7817 bool IsExplosive()
7818 {
7819 return false;
7820 }
7821
7823 {
7824 return "";
7825 }
7826
7828
7829 bool IsLightSource()
7830 {
7831 return false;
7832 }
7833
7835 {
7836 return true;
7837 }
7838
7839 //--- ACTION CONDITIONS
7840 //direction
7841 bool IsFacingPlayer(PlayerBase player, string selection)
7842 {
7843 return true;
7844 }
7845
7846 bool IsPlayerInside(PlayerBase player, string selection)
7847 {
7848 return true;
7849 }
7850
7851 override bool CanObstruct()
7852 {
7853 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7854 return !player || !IsPlayerInside(player, "");
7855 }
7856
7857 override bool IsBeingPlaced()
7858 {
7859 return m_IsBeingPlaced;
7860 }
7861
7862 void SetIsBeingPlaced(bool is_being_placed)
7863 {
7864 m_IsBeingPlaced = is_being_placed;
7865 if (!is_being_placed)
7867 SetSynchDirty();
7868 }
7869
7870 //server-side
7871 void OnEndPlacement() {}
7872
7873 override bool IsHologram()
7874 {
7875 return m_IsHologram;
7876 }
7877
7878 bool CanBeDigged()
7879 {
7880 return m_CanBeDigged;
7881 }
7882
7884 {
7885 return 1;
7886 }
7887
7888 bool CanMakeGardenplot()
7889 {
7890 return false;
7891 }
7892
7893 void SetIsHologram(bool is_hologram)
7894 {
7895 m_IsHologram = is_hologram;
7896 SetSynchDirty();
7897 }
7898 /*
7899 protected float GetNutritionalEnergy()
7900 {
7901 Edible_Base edible = Edible_Base.Cast(this);
7902 return edible.GetFoodEnergy();
7903 }
7904
7905 protected float GetNutritionalWaterContent()
7906 {
7907 Edible_Base edible = Edible_Base.Cast(this);
7908 return edible.GetFoodWater();
7909 }
7910
7911 protected float GetNutritionalIndex()
7912 {
7913 Edible_Base edible = Edible_Base.Cast(this);
7914 return edible.GetFoodNutritionalIndex();
7915 }
7916
7917 protected float GetNutritionalFullnessIndex()
7918 {
7919 Edible_Base edible = Edible_Base.Cast(this);
7920 return edible.GetFoodTotalVolume();
7921 }
7922
7923 protected float GetNutritionalToxicity()
7924 {
7925 Edible_Base edible = Edible_Base.Cast(this);
7926 return edible.GetFoodToxicity();
7927
7928 }
7929 */
7930
7931
7932 // -------------------------------------------------------------------------
7933 override void OnMovedInsideCargo(EntityAI container)
7934 {
7935 super.OnMovedInsideCargo(container);
7936
7937 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
7938 }
7939
7940 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
7941 {
7942 super.EEItemLocationChanged(oldLoc,newLoc);
7943
7944 PlayerBase new_player = null;
7945 PlayerBase old_player = null;
7946
7947 if (newLoc.GetParent())
7948 new_player = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
7949
7950 if (oldLoc.GetParent())
7951 old_player = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
7952
7953 if (old_player && oldLoc.GetType() == InventoryLocationType.HANDS)
7954 {
7955 int r_index = old_player.GetHumanInventory().FindUserReservedLocationIndex(this);
7956
7957 if (r_index >= 0)
7958 {
7959 InventoryLocation r_il = new InventoryLocation;
7960 old_player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
7961
7962 old_player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
7963 int r_type = r_il.GetType();
7964 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
7965 {
7966 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7967 }
7968 else if (r_type == InventoryLocationType.ATTACHMENT)
7969 {
7970 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7971 }
7972
7973 }
7974 }
7975
7976 if (newLoc.GetType() == InventoryLocationType.HANDS)
7977 {
7978 if (new_player)
7979 new_player.ForceStandUpForHeavyItems(newLoc.GetItem());
7980
7981 if (new_player == old_player)
7982 {
7983
7984 if (oldLoc.GetParent() && new_player.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
7985 {
7986 if (oldLoc.GetType() == InventoryLocationType.CARGO)
7987 {
7988 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
7989 {
7990 new_player.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
7991 }
7992 }
7993 else
7994 {
7995 new_player.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
7996 }
7997 }
7998
7999 if (new_player.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
8000 {
8001 int type = oldLoc.GetType();
8002 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
8003 {
8004 oldLoc.GetParent().GetOnSetLock().Invoke(this);
8005 }
8006 else if (type == InventoryLocationType.ATTACHMENT)
8007 {
8008 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
8009 }
8010 }
8011 if (!m_OldLocation)
8012 {
8013 m_OldLocation = new InventoryLocation;
8014 }
8015 m_OldLocation.Copy(oldLoc);
8016 }
8017 else
8018 {
8019 if (m_OldLocation)
8020 {
8021 m_OldLocation.Reset();
8022 }
8023 }
8024
8026 }
8027 else
8028 {
8029 if (new_player)
8030 {
8031 int res_index = new_player.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
8032 if (res_index >= 0)
8033 {
8034 InventoryLocation il = new InventoryLocation;
8035 new_player.GetHumanInventory().GetUserReservedLocation(res_index,il);
8036 ItemBase it = ItemBase.Cast(il.GetItem());
8037 new_player.GetHumanInventory().ClearUserReservedLocationAtIndex(res_index);
8038 int rel_type = il.GetType();
8039 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
8040 {
8041 il.GetParent().GetOnReleaseLock().Invoke(it);
8042 }
8043 else if (rel_type == InventoryLocationType.ATTACHMENT)
8044 {
8045 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
8046 }
8047 //it.GetOnReleaseLock().Invoke(it);
8048 }
8049 }
8050 else if (old_player && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
8051 {
8052 //ThrowPhysically(old_player, vector.Zero);
8053 m_ThrowItemOnDrop = false;
8054 }
8055
8056 if (m_OldLocation)
8057 {
8058 m_OldLocation.Reset();
8059 }
8060 }
8061 }
8062
8063 override void EOnContact(IEntity other, Contact extra)
8064 {
8066 {
8067 int liquidType = -1;
8068 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
8069 if (impactSpeed > 0.0)
8070 {
8071 m_ImpactSpeed = impactSpeed;
8072 #ifndef SERVER
8073 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
8074 #else
8075 m_WantPlayImpactSound = true;
8076 SetSynchDirty();
8077 #endif
8078 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
8079 }
8080 }
8081
8082 #ifdef SERVER
8083 if (GetCompEM() && GetCompEM().IsPlugged())
8084 {
8085 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
8086 GetCompEM().UnplugThis();
8087 }
8088 #endif
8089 }
8090
8091 void RefreshPhysics();
8092
8093 override void OnCreatePhysics()
8094 {
8096 }
8097
8098 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
8099 {
8100
8101 }
8102 // -------------------------------------------------------------------------
8103 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
8104 {
8105 super.OnItemLocationChanged(old_owner, new_owner);
8106
8107 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
8108 PlayerBase playerNew = PlayerBase.Cast(new_owner);
8109
8110 if (!relatedPlayer && playerNew)
8111 relatedPlayer = playerNew;
8112
8113 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
8114 {
8115 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
8116 if (actionMgr)
8117 {
8118 ActionBase currentAction = actionMgr.GetRunningAction();
8119 if (currentAction)
8120 currentAction.OnItemLocationChanged(this);
8121 }
8122 }
8123
8124 Man ownerPlayerOld = null;
8125 Man ownerPlayerNew = null;
8126
8127 if (old_owner)
8128 {
8129 if (old_owner.IsMan())
8130 {
8131 ownerPlayerOld = Man.Cast(old_owner);
8132 }
8133 else
8134 {
8135 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
8136 }
8137 }
8138 else
8139 {
8140 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
8141 {
8142 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
8143
8144 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
8145 {
8146 GetCompEM().UnplugThis();
8147 }
8148 }
8149 }
8150
8151 if (new_owner)
8152 {
8153 if (new_owner.IsMan())
8154 {
8155 ownerPlayerNew = Man.Cast(new_owner);
8156 }
8157 else
8158 {
8159 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
8160 }
8161 }
8162
8163 if (ownerPlayerOld != ownerPlayerNew)
8164 {
8165 if (ownerPlayerOld)
8166 {
8167 array<EntityAI> subItemsExit = new array<EntityAI>;
8168 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
8169 for (int i = 0; i < subItemsExit.Count(); i++)
8170 {
8171 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
8172 itemExit.OnInventoryExit(ownerPlayerOld);
8173 }
8174 }
8175
8176 if (ownerPlayerNew)
8177 {
8178 array<EntityAI> subItemsEnter = new array<EntityAI>;
8179 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
8180 for (int j = 0; j < subItemsEnter.Count(); j++)
8181 {
8182 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
8183 itemEnter.OnInventoryEnter(ownerPlayerNew);
8184 }
8185 }
8186 }
8187 else if (ownerPlayerNew != null)
8188 {
8189 PlayerBase nplayer;
8190 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
8191 {
8192 array<EntityAI> subItemsUpdate = new array<EntityAI>;
8193 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
8194 for (int k = 0; k < subItemsUpdate.Count(); k++)
8195 {
8196 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
8197 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
8198 }
8199 }
8200 }
8201
8202 if (old_owner)
8203 old_owner.OnChildItemRemoved(this);
8204 if (new_owner)
8205 new_owner.OnChildItemReceived(this);
8206 }
8207
8208 // -------------------------------------------------------------------------------
8209 override void EEDelete(EntityAI parent)
8210 {
8211 super.EEDelete(parent);
8212 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
8213 if (player)
8214 {
8215 OnInventoryExit(player);
8216
8217 if (player.IsAlive())
8218 {
8219 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
8220 if (r_index >= 0)
8221 {
8222 InventoryLocation r_il = new InventoryLocation;
8223 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
8224
8225 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
8226 int r_type = r_il.GetType();
8227 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
8228 {
8229 r_il.GetParent().GetOnReleaseLock().Invoke(this);
8230 }
8231 else if (r_type == InventoryLocationType.ATTACHMENT)
8232 {
8233 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
8234 }
8235
8236 }
8237
8238 player.RemoveQuickBarEntityShortcut(this);
8239 }
8240 }
8241 }
8242 // -------------------------------------------------------------------------------
8243 override void EEKilled(Object killer)
8244 {
8245 super.EEKilled(killer);
8246
8248 if (killer && killer.IsFireplace() && CanExplodeInFire())
8249 {
8250 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
8251 {
8252 if (IsMagazine())
8253 {
8254 if (Magazine.Cast(this).GetAmmoCount() > 0)
8255 {
8256 ExplodeAmmo();
8257 }
8258 }
8259 else
8260 {
8261 Explode(DamageType.EXPLOSION);
8262 }
8263 }
8264 }
8265 }
8266
8267 override void OnWasAttached(EntityAI parent, int slot_id)
8268 {
8269 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
8270
8271 super.OnWasAttached(parent, slot_id);
8272
8273 if (HasQuantity())
8274 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
8275
8276 PlayAttachSound(InventorySlots.GetSlotName(slot_id));
8277 }
8278
8279 override void OnWasDetached(EntityAI parent, int slot_id)
8280 {
8281 super.OnWasDetached(parent, slot_id);
8282
8283 if (HasQuantity())
8284 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
8285 }
8286
8287 override string ChangeIntoOnAttach(string slot)
8288 {
8289 int idx;
8290 TStringArray inventory_slots = new TStringArray;
8291 TStringArray attach_types = new TStringArray;
8292
8293 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
8294 if (inventory_slots.Count() < 1) //is string
8295 {
8296 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
8297 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
8298 }
8299 else //is array
8300 {
8301 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
8302 }
8303
8304 idx = inventory_slots.Find(slot);
8305 if (idx < 0)
8306 return "";
8307
8308 return attach_types.Get(idx);
8309 }
8310
8311 override string ChangeIntoOnDetach()
8312 {
8313 int idx = -1;
8314 string slot;
8315
8316 TStringArray inventory_slots = new TStringArray;
8317 TStringArray detach_types = new TStringArray;
8318
8319 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
8320 if (inventory_slots.Count() < 1) //is string
8321 {
8322 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
8323 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
8324 }
8325 else //is array
8326 {
8327 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
8328 if (detach_types.Count() < 1)
8329 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
8330 }
8331
8332 for (int i = 0; i < inventory_slots.Count(); i++)
8333 {
8334 slot = inventory_slots.Get(i);
8335 }
8336
8337 if (slot != "")
8338 {
8339 if (detach_types.Count() == 1)
8340 idx = 0;
8341 else
8342 idx = inventory_slots.Find(slot);
8343 }
8344 if (idx < 0)
8345 return "";
8346
8347 return detach_types.Get(idx);
8348 }
8349
8350 void ExplodeAmmo()
8351 {
8352 //timer
8353 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
8354
8355 //min/max time
8356 float min_time = 1;
8357 float max_time = 3;
8358 float delay = Math.RandomFloat(min_time, max_time);
8359
8360 explode_timer.Run(delay, this, "DoAmmoExplosion");
8361 }
8362
8363 void DoAmmoExplosion()
8364 {
8365 Magazine magazine = Magazine.Cast(this);
8366 int pop_sounds_count = 6;
8367 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
8368
8369 //play sound
8370 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
8371 string sound_name = pop_sounds[ sound_idx ];
8372 GetGame().CreateSoundOnObject(this, sound_name, 20, false);
8373
8374 //remove ammo count
8375 magazine.ServerAddAmmoCount(-1);
8376
8377 //if condition then repeat -> ExplodeAmmo
8378 float min_temp_to_explode = 100; //min temperature for item to explode
8379
8380 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
8381 {
8382 ExplodeAmmo();
8383 }
8384 }
8385
8386 // -------------------------------------------------------------------------------
8387 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
8388 {
8389 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
8390
8391 const int CHANCE_DAMAGE_CARGO = 4;
8392 const int CHANCE_DAMAGE_ATTACHMENT = 1;
8393 const int CHANCE_DAMAGE_NOTHING = 2;
8394
8395 if (IsClothing() || IsContainer() || IsItemTent())
8396 {
8397 float dmg = damageResult.GetDamage("","Health") * -0.5;
8398 int chances;
8399 int rnd;
8400
8401 if (GetInventory().GetCargo())
8402 {
8403 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
8404 rnd = Math.RandomInt(0,chances);
8405
8406 if (rnd < CHANCE_DAMAGE_CARGO)
8407 {
8408 DamageItemInCargo(dmg);
8409 }
8410 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
8411 {
8413 }
8414 }
8415 else
8416 {
8417 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
8418 rnd = Math.RandomInt(0,chances);
8419
8420 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
8421 {
8423 }
8424 }
8425 }
8426 }
8427
8428 bool DamageItemInCargo(float damage)
8429 {
8430 if (GetInventory().GetCargo())
8431 {
8432 int item_count = GetInventory().GetCargo().GetItemCount();
8433 if (item_count > 0)
8434 {
8435 int random_pick = Math.RandomInt(0, item_count);
8436 ItemBase item = ItemBase.Cast(GetInventory().GetCargo().GetItem(random_pick));
8437 if (!item.IsExplosive())
8438 {
8439 item.AddHealth("","",damage);
8440 return true;
8441 }
8442 }
8443 }
8444 return false;
8445 }
8446
8447 bool DamageItemAttachments(float damage)
8448 {
8449 int attachment_count = GetInventory().AttachmentCount();
8450 if (attachment_count > 0)
8451 {
8452 int random_pick = Math.RandomInt(0, attachment_count);
8453 ItemBase attachment = ItemBase.Cast(GetInventory().GetAttachmentFromIndex(random_pick));
8454 if (!attachment.IsExplosive())
8455 {
8456 attachment.AddHealth("","",damage);
8457 return true;
8458 }
8459 }
8460 return false;
8461 }
8462
8463 override bool IsSplitable()
8464 {
8465 return m_CanThisBeSplit;
8466 }
8467 //----------------
8468 override bool CanBeSplit()
8469 {
8470 if (IsSplitable() && (GetQuantity() > 1))
8471 return GetInventory().CanRemoveEntity();
8472
8473 return false;
8474 }
8475
8476 protected bool ShouldSplitQuantity(float quantity)
8477 {
8478 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
8479 if (!IsSplitable())
8480 return false;
8481
8482 // nothing to split?
8483 if (GetQuantity() <= 1)
8484 return false;
8485
8486 // check if we should re-use the item instead of creating a new copy?
8487 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
8488 int delta = GetQuantity() - quantity;
8489 if (delta == 0)
8490 return false;
8491
8492 // valid to split
8493 return true;
8494 }
8495
8496 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
8497 {
8498 if (GetGame().IsClient())
8499 {
8500 if (ScriptInputUserData.CanStoreInputUserData())
8501 {
8502 ScriptInputUserData ctx = new ScriptInputUserData;
8504 ctx.Write(1);
8505 ItemBase i1 = this; // @NOTE: workaround for correct serialization
8506 ctx.Write(i1);
8507 ctx.Write(destination_entity);
8508 ctx.Write(true);
8509 ctx.Write(slot_id);
8510 ctx.Send();
8511 }
8512 }
8513 else if (!GetGame().IsMultiplayer())
8514 {
8515 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(GetGame().GetPlayer()));
8516 }
8517 }
8518
8519 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
8520 {
8521 float split_quantity_new;
8522 ItemBase new_item;
8523 float quantity = GetQuantity();
8524 float stack_max = GetTargetQuantityMax(slot_id);
8525 InventoryLocation loc = new InventoryLocation;
8526
8527 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
8528 {
8529 if (stack_max <= GetQuantity())
8530 split_quantity_new = stack_max;
8531 else
8532 split_quantity_new = GetQuantity();
8533
8534 if (ShouldSplitQuantity(split_quantity_new))
8535 {
8536 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
8537 if (new_item)
8538 {
8539 new_item.SetResultOfSplit(true);
8540 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8541 AddQuantity(-split_quantity_new, false, true);
8542 new_item.SetQuantity(split_quantity_new, false, true);
8543 }
8544 }
8545 }
8546 else if (destination_entity && slot_id == -1)
8547 {
8548 if (quantity > stack_max)
8549 split_quantity_new = stack_max;
8550 else
8551 split_quantity_new = quantity;
8552
8553 if (ShouldSplitQuantity(split_quantity_new))
8554 {
8555 if (destination_entity.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
8556 {
8557 Object o = destination_entity.GetInventory().LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
8558 new_item = ItemBase.Cast(o);
8559 }
8560
8561 if (new_item)
8562 {
8563 new_item.SetResultOfSplit(true);
8564 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8565 AddQuantity(-split_quantity_new, false, true);
8566 new_item.SetQuantity(split_quantity_new, false, true);
8567 }
8568 }
8569 }
8570 else
8571 {
8572 if (stack_max != 0)
8573 {
8574 if (stack_max < GetQuantity())
8575 {
8576 split_quantity_new = GetQuantity() - stack_max;
8577 }
8578
8579 if (split_quantity_new == 0)
8580 {
8581 if (!GetGame().IsMultiplayer())
8582 player.PhysicalPredictiveDropItem(this);
8583 else
8584 player.ServerDropEntity(this);
8585 return;
8586 }
8587
8588 if (ShouldSplitQuantity(split_quantity_new))
8589 {
8590 new_item = ItemBase.Cast(GetGame().CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
8591
8592 if (new_item)
8593 {
8594 new_item.SetResultOfSplit(true);
8595 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8596 SetQuantity(split_quantity_new, false, true);
8597 new_item.SetQuantity(stack_max, false, true);
8598 new_item.PlaceOnSurface();
8599 }
8600 }
8601 }
8602 }
8603 }
8604
8605 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
8606 {
8607 float split_quantity_new;
8608 ItemBase new_item;
8609 float quantity = GetQuantity();
8610 float stack_max = GetTargetQuantityMax(slot_id);
8611 InventoryLocation loc = new InventoryLocation;
8612
8613 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
8614 {
8615 if (stack_max <= GetQuantity())
8616 split_quantity_new = stack_max;
8617 else
8618 split_quantity_new = GetQuantity();
8619
8620 if (ShouldSplitQuantity(split_quantity_new))
8621 {
8622 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
8623 if (new_item)
8624 {
8625 new_item.SetResultOfSplit(true);
8626 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8627 AddQuantity(-split_quantity_new, false, true);
8628 new_item.SetQuantity(split_quantity_new, false, true);
8629 }
8630 }
8631 }
8632 else if (destination_entity && slot_id == -1)
8633 {
8634 if (quantity > stack_max)
8635 split_quantity_new = stack_max;
8636 else
8637 split_quantity_new = quantity;
8638
8639 if (ShouldSplitQuantity(split_quantity_new))
8640 {
8641 if (destination_entity.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
8642 {
8643 Object o = destination_entity.GetInventory().LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
8644 new_item = ItemBase.Cast(o);
8645 }
8646
8647 if (new_item)
8648 {
8649 new_item.SetResultOfSplit(true);
8650 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8651 AddQuantity(-split_quantity_new, false, true);
8652 new_item.SetQuantity(split_quantity_new, false, true);
8653 }
8654 }
8655 }
8656 else
8657 {
8658 if (stack_max != 0)
8659 {
8660 if (stack_max < GetQuantity())
8661 {
8662 split_quantity_new = GetQuantity() - stack_max;
8663 }
8664
8665 if (ShouldSplitQuantity(split_quantity_new))
8666 {
8667 new_item = ItemBase.Cast(GetGame().CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
8668
8669 if (new_item)
8670 {
8671 new_item.SetResultOfSplit(true);
8672 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8673 SetQuantity(split_quantity_new, false, true);
8674 new_item.SetQuantity(stack_max, false, true);
8675 new_item.PlaceOnSurface();
8676 }
8677 }
8678 }
8679 }
8680 }
8681
8682 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
8683 {
8684 if (GetGame().IsClient())
8685 {
8686 if (ScriptInputUserData.CanStoreInputUserData())
8687 {
8688 ScriptInputUserData ctx = new ScriptInputUserData;
8690 ctx.Write(4);
8691 ItemBase thiz = this; // @NOTE: workaround for correct serialization
8692 ctx.Write(thiz);
8693 dst.WriteToContext(ctx);
8694 ctx.Send();
8695 }
8696 }
8697 else if (!GetGame().IsMultiplayer())
8698 {
8700 }
8701 }
8702
8703 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
8704 {
8705 if (GetGame().IsClient())
8706 {
8707 if (ScriptInputUserData.CanStoreInputUserData())
8708 {
8709 ScriptInputUserData ctx = new ScriptInputUserData;
8711 ctx.Write(2);
8712 ItemBase dummy = this; // @NOTE: workaround for correct serialization
8713 ctx.Write(dummy);
8714 ctx.Write(destination_entity);
8715 ctx.Write(true);
8716 ctx.Write(idx);
8717 ctx.Write(row);
8718 ctx.Write(col);
8719 ctx.Send();
8720 }
8721 }
8722 else if (!GetGame().IsMultiplayer())
8723 {
8724 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
8725 }
8726 }
8727
8728 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
8729 {
8731 }
8732
8733 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
8734 {
8735 float quantity = GetQuantity();
8736 float split_quantity_new;
8737 ItemBase new_item;
8738 if (dst.IsValid())
8739 {
8740 int slot_id = dst.GetSlot();
8741 float stack_max = GetTargetQuantityMax(slot_id);
8742
8743 if (quantity > stack_max)
8744 split_quantity_new = stack_max;
8745 else
8746 split_quantity_new = quantity;
8747
8748 if (ShouldSplitQuantity(split_quantity_new))
8749 {
8750 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
8751
8752 if (new_item)
8753 {
8754 new_item.SetResultOfSplit(true);
8755 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8756 AddQuantity(-split_quantity_new, false, true);
8757 new_item.SetQuantity(split_quantity_new, false, true);
8758 }
8759
8760 return new_item;
8761 }
8762 }
8763
8764 return null;
8765 }
8766
8767 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
8768 {
8769 float quantity = GetQuantity();
8770 float split_quantity_new;
8771 ItemBase new_item;
8772 if (destination_entity)
8773 {
8774 float stackable = GetTargetQuantityMax();
8775 if (quantity > stackable)
8776 split_quantity_new = stackable;
8777 else
8778 split_quantity_new = quantity;
8779
8780 if (ShouldSplitQuantity(split_quantity_new))
8781 {
8782 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
8783 if (new_item)
8784 {
8785 new_item.SetResultOfSplit(true);
8786 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8787 AddQuantity(-split_quantity_new, false, true);
8788 new_item.SetQuantity(split_quantity_new, false, true);
8789 }
8790 }
8791 }
8792 }
8793
8794 void SplitIntoStackMaxHandsClient(PlayerBase player)
8795 {
8796 if (GetGame().IsClient())
8797 {
8798 if (ScriptInputUserData.CanStoreInputUserData())
8799 {
8800 ScriptInputUserData ctx = new ScriptInputUserData;
8802 ctx.Write(3);
8803 ItemBase i1 = this; // @NOTE: workaround for correct serialization
8804 ctx.Write(i1);
8805 ItemBase destination_entity = this;
8806 ctx.Write(destination_entity);
8807 ctx.Write(true);
8808 ctx.Write(0);
8809 ctx.Send();
8810 }
8811 }
8812 else if (!GetGame().IsMultiplayer())
8813 {
8814 SplitIntoStackMaxHands(player);
8815 }
8816 }
8817
8818 void SplitIntoStackMaxHands(PlayerBase player)
8819 {
8820 float quantity = GetQuantity();
8821 float split_quantity_new;
8822 ref ItemBase new_item;
8823 if (player)
8824 {
8825 float stackable = GetTargetQuantityMax();
8826 if (quantity > stackable)
8827 split_quantity_new = stackable;
8828 else
8829 split_quantity_new = quantity;
8830
8831 if (ShouldSplitQuantity(split_quantity_new))
8832 {
8833 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
8834 new_item = ItemBase.Cast(in_hands);
8835 if (new_item)
8836 {
8837 new_item.SetResultOfSplit(true);
8838 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8839 AddQuantity(-split_quantity_new, false, true);
8840 new_item.SetQuantity(split_quantity_new, false, true);
8841 }
8842 }
8843 }
8844 }
8845
8846 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
8847 {
8848 float quantity = GetQuantity();
8849 float split_quantity_new = Math.Floor(quantity * 0.5);
8850
8851 if (!ShouldSplitQuantity(split_quantity_new))
8852 return;
8853
8854 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
8855
8856 if (new_item)
8857 {
8858 if (new_item.GetQuantityMax() < split_quantity_new)
8859 {
8860 split_quantity_new = new_item.GetQuantityMax();
8861 }
8862
8863 new_item.SetResultOfSplit(true);
8864 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8865
8866 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
8867 {
8868 AddQuantity(-1, false, true);
8869 new_item.SetQuantity(1, false, true);
8870 }
8871 else
8872 {
8873 AddQuantity(-split_quantity_new, false, true);
8874 new_item.SetQuantity(split_quantity_new, false, true);
8875 }
8876 }
8877 }
8878
8879 void SplitItem(PlayerBase player)
8880 {
8881 float quantity = GetQuantity();
8882 float split_quantity_new = Math.Floor(quantity / 2);
8883
8884 if (!ShouldSplitQuantity(split_quantity_new))
8885 return;
8886
8887 InventoryLocation invloc = new InventoryLocation;
8888 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
8889
8890 ItemBase new_item;
8891 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
8892
8893 if (new_item)
8894 {
8895 if (new_item.GetQuantityMax() < split_quantity_new)
8896 {
8897 split_quantity_new = new_item.GetQuantityMax();
8898 }
8899 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
8900 {
8901 AddQuantity(-1, false, true);
8902 new_item.SetQuantity(1, false, true);
8903 }
8904 else if (split_quantity_new > 1)
8905 {
8906 AddQuantity(-split_quantity_new, false, true);
8907 new_item.SetQuantity(split_quantity_new, false, true);
8908 }
8909 }
8910 }
8911
8913 void OnQuantityChanged(float delta)
8914 {
8915 SetWeightDirty();
8916 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
8917
8918 if (parent)
8919 parent.OnAttachmentQuantityChangedEx(this, delta);
8920
8921 if (IsLiquidContainer())
8922 {
8923 if (GetQuantityNormalized() <= 0.0)
8924 {
8926 }
8927 else if (GetLiquidType() == LIQUID_NONE)
8928 {
8929 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
8931 }
8932 }
8933
8934 }
8935
8938 {
8939 // insert code here
8940 }
8941
8943 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
8944 {
8946 }
8947
8948 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
8949 {
8950 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
8951
8952 if (GetGame().IsServer())
8953 {
8954 if (newLevel == GameConstants.STATE_RUINED)
8955 {
8957 EntityAI parent = GetHierarchyParent();
8958 if (parent && parent.IsFireplace())
8959 {
8960 CargoBase cargo = GetInventory().GetCargo();
8961 if (cargo)
8962 {
8963 for (int i = 0; i < cargo.GetItemCount(); ++i)
8964 {
8965 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
8966 }
8967 }
8968 }
8969 }
8970
8971 if (IsResultOfSplit())
8972 {
8973 // reset the splitting result flag, return to normal item behavior
8974 SetResultOfSplit(false);
8975 return;
8976 }
8977
8978 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
8979 {
8980 SetCleanness(0);//unclean the item upon damage dealt
8981 }
8982 }
8983 }
8984
8985 // just the split? TODO: verify
8986 override void OnRightClick()
8987 {
8988 super.OnRightClick();
8989
8990 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !GetGame().GetPlayer().GetInventory().HasInventoryReservation(this,null))
8991 {
8992 if (GetGame().IsClient())
8993 {
8994 if (ScriptInputUserData.CanStoreInputUserData())
8995 {
8996 EntityAI root = GetHierarchyRoot();
8997 Man playerOwner = GetHierarchyRootPlayer();
8998 InventoryLocation dst = new InventoryLocation;
8999
9000 // 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
9001 if (!playerOwner && root && root == this)
9002 {
9004 }
9005 else
9006 {
9007 // 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
9008 GetInventory().GetCurrentInventoryLocation(dst);
9009 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
9010 {
9011 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
9012 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
9013 {
9015 }
9016 else
9017 {
9018 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
9019 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
9020 this shouldnt cause issues within this scope*/
9021 if (GetGame().GetPlayer().GetInventory().HasInventoryReservation(this, dst))
9022 {
9024 }
9025 else
9026 {
9027 GetGame().GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
9028 }
9029 }
9030 }
9031 }
9032
9033 ScriptInputUserData ctx = new ScriptInputUserData;
9035 ctx.Write(4);
9036 ItemBase thiz = this; // @NOTE: workaround for correct serialization
9037 ctx.Write(thiz);
9038 dst.WriteToContext(ctx);
9039 ctx.Write(true); // dummy
9040 ctx.Send();
9041 }
9042 }
9043 else if (!GetGame().IsMultiplayer())
9044 {
9045 SplitItem(PlayerBase.Cast(GetGame().GetPlayer()));
9046 }
9047 }
9048 }
9049
9050 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
9051 {
9052 if (root)
9053 {
9054 vector m4[4];
9055 root.GetTransform(m4);
9056 dst.SetGround(this, m4);
9057 }
9058 else
9059 {
9060 GetInventory().GetCurrentInventoryLocation(dst);
9061 }
9062 }
9063
9064 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
9065 {
9066 //TODO: delete check zero quantity check after fix double posts hands fsm events
9067 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
9068 return false;
9069
9070 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
9071 return false;
9072
9073 //can_this_be_combined = ConfigGetBool("canBeSplit");
9075 return false;
9076
9077
9078 Magazine mag = Magazine.Cast(this);
9079 if (mag)
9080 {
9081 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
9082 return false;
9083
9084 if (stack_max_limit)
9085 {
9086 Magazine other_mag = Magazine.Cast(other_item);
9087 if (other_item)
9088 {
9089 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
9090 return false;
9091 }
9092
9093 }
9094 }
9095 else
9096 {
9097 //TODO: delete check zero quantity check after fix double posts hands fsm events
9098 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
9099 return false;
9100
9101 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
9102 return false;
9103 }
9104
9105 PlayerBase player = null;
9106 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
9107 {
9108 if (player.GetInventory().HasAttachment(this))
9109 return false;
9110
9111 if (player.IsItemsToDelete())
9112 return false;
9113 }
9114
9115 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
9116 return false;
9117
9118 int slotID;
9119 string slotName;
9120 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
9121 return false;
9122
9123 return true;
9124 }
9125
9126 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
9127 {
9128 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
9129 }
9130
9131 bool IsResultOfSplit()
9132 {
9133 return m_IsResultOfSplit;
9134 }
9135
9136 void SetResultOfSplit(bool value)
9137 {
9138 m_IsResultOfSplit = value;
9139 }
9140
9141 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
9142 {
9143 return ComputeQuantityUsedEx(other_item, use_stack_max);
9144 }
9145
9146 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
9147 {
9148 float other_item_quantity = other_item.GetQuantity();
9149 float this_free_space;
9150
9151 float stack_max = GetQuantityMax();
9152
9153 this_free_space = stack_max - GetQuantity();
9154
9155 if (other_item_quantity > this_free_space)
9156 {
9157 return this_free_space;
9158 }
9159 else
9160 {
9161 return other_item_quantity;
9162 }
9163 }
9164
9165 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
9166 {
9167 CombineItems(ItemBase.Cast(entity2),use_stack_max);
9168 }
9169
9170 void CombineItems(ItemBase other_item, bool use_stack_max = true)
9171 {
9172 if (!CanBeCombined(other_item, false))
9173 return;
9174
9175 if (!IsMagazine() && other_item)
9176 {
9177 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
9178 if (quantity_used != 0)
9179 {
9180 float hp1 = GetHealth01("","");
9181 float hp2 = other_item.GetHealth01("","");
9182 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
9183 hpResult = hpResult / (GetQuantity() + quantity_used);
9184
9185 hpResult *= GetMaxHealth();
9186 Math.Round(hpResult);
9187 SetHealth("", "Health", hpResult);
9188
9189 AddQuantity(quantity_used);
9190 other_item.AddQuantity(-quantity_used);
9191 }
9192 }
9193 OnCombine(other_item);
9194 }
9195
9196 void OnCombine(ItemBase other_item)
9197 {
9198 #ifdef SERVER
9199 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
9200 GetHierarchyParent().IncreaseLifetimeUp();
9201 #endif
9202 };
9203
9204 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
9205 {
9206 PlayerBase p = PlayerBase.Cast(player);
9207
9208 array<int> recipesIds = p.m_Recipes;
9209 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
9210 if (moduleRecipesManager)
9211 {
9212 EntityAI itemInHands = player.GetHumanInventory().GetEntityInHands();
9213 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
9214 }
9215
9216 for (int i = 0;i < recipesIds.Count(); i++)
9217 {
9218 int key = recipesIds.Get(i);
9219 string recipeName = moduleRecipesManager.GetRecipeName(key);
9220 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
9221 }
9222 }
9223
9224 // -------------------------------------------------------------------------
9225 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
9226 {
9227 super.GetDebugActions(outputList);
9228
9229 //quantity
9230 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
9231 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
9232 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
9233 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
9234 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9235
9236 //health
9237 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
9238 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
9239 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
9240 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9241 //temperature
9242 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
9243 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
9244 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
9245 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9246
9247 //wet
9248 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
9249 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
9250 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9251
9252 //liquidtype
9253 if (IsLiquidContainer())
9254 {
9255 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
9256 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
9257 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9258 }
9259
9260 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
9261 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9262
9263 // watch
9264 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
9265 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
9266 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9267
9268 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
9269
9270 InventoryLocation loc = new InventoryLocation();
9271 GetInventory().GetCurrentInventoryLocation(loc);
9272 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
9273 {
9274 if (Gizmo_IsSupported())
9275 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
9276 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
9277 }
9278
9279 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
9280 }
9281
9282 // -------------------------------------------------------------------------
9283 // -------------------------------------------------------------------------
9284 // -------------------------------------------------------------------------
9285 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
9286 {
9287 super.OnAction(action_id, player, ctx);
9288
9289 if (GetGame().IsClient() || !GetGame().IsMultiplayer())
9290 {
9291 switch (action_id)
9292 {
9293 case EActions.GIZMO_OBJECT:
9294 GetGame().GizmoSelectObject(this);
9295 return true;
9296 case EActions.GIZMO_PHYSICS:
9297 GetGame().GizmoSelectPhysics(GetPhysics());
9298 return true;
9299 }
9300 }
9301
9302 if (GetGame().IsServer())
9303 {
9304 switch (action_id)
9305 {
9306 case EActions.DELETE:
9307 Delete();
9308 return true;
9309 }
9310 }
9311
9312 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
9313 {
9314 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
9315 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
9316 PlayerBase p = PlayerBase.Cast(player);
9317 if (EActions.RECIPES_RANGE_START < 1000)
9318 {
9319 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
9320 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
9321 }
9322 }
9323 #ifndef SERVER
9324 else if (action_id == EActions.WATCH_PLAYER)
9325 {
9326 PluginDeveloper.SetDeveloperItemClientEx(player);
9327 }
9328 #endif
9329 if (GetGame().IsServer())
9330 {
9331 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
9332 {
9333 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
9334 OnDebugButtonPressServer(id + 1);
9335 }
9336
9337 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
9338 {
9339 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
9340 InsertAgent(agent_id,100);
9341 }
9342
9343 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
9344 {
9345 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
9346 RemoveAgent(agent_id2);
9347 }
9348
9349 else if (action_id == EActions.ADD_QUANTITY)
9350 {
9351 if (IsMagazine())
9352 {
9353 Magazine mag = Magazine.Cast(this);
9354 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
9355 }
9356 else
9357 {
9358 AddQuantity(GetQuantityMax() * 0.2);
9359 }
9360
9361 if (m_EM)
9362 {
9363 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
9364 }
9365 //PrintVariables();
9366 }
9367
9368 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
9369 {
9370 if (IsMagazine())
9371 {
9372 Magazine mag2 = Magazine.Cast(this);
9373 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
9374 }
9375 else
9376 {
9377 AddQuantity(- GetQuantityMax() * 0.2);
9378 }
9379 if (m_EM)
9380 {
9381 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
9382 }
9383 //PrintVariables();
9384 }
9385
9386 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
9387 {
9388 SetQuantity(0);
9389
9390 if (m_EM)
9391 {
9392 m_EM.SetEnergy(0);
9393 }
9394 }
9395
9396 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
9397 {
9399
9400 if (m_EM)
9401 {
9402 m_EM.SetEnergy(m_EM.GetEnergyMax());
9403 }
9404 }
9405
9406 else if (action_id == EActions.ADD_HEALTH)
9407 {
9408 AddHealth("","",GetMaxHealth("","Health")/5);
9409 }
9410 else if (action_id == EActions.REMOVE_HEALTH)
9411 {
9412 AddHealth("","",-GetMaxHealth("","Health")/5);
9413 }
9414 else if (action_id == EActions.DESTROY_HEALTH)
9415 {
9416 SetHealth01("","",0);
9417 }
9418 else if (action_id == EActions.WATCH_ITEM)
9419 {
9421 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
9422 #ifdef DEVELOPER
9423 SetDebugDeveloper_item(this);
9424 #endif
9425 }
9426
9427 else if (action_id == EActions.ADD_TEMPERATURE)
9428 {
9429 AddTemperature(20);
9430 //PrintVariables();
9431 }
9432
9433 else if (action_id == EActions.REMOVE_TEMPERATURE)
9434 {
9435 AddTemperature(-20);
9436 //PrintVariables();
9437 }
9438
9439 else if (action_id == EActions.FLIP_FROZEN)
9440 {
9441 SetFrozen(!GetIsFrozen());
9442 //PrintVariables();
9443 }
9444
9445 else if (action_id == EActions.ADD_WETNESS)
9446 {
9447 AddWet(GetWetMax()/5);
9448 //PrintVariables();
9449 }
9450
9451 else if (action_id == EActions.REMOVE_WETNESS)
9452 {
9453 AddWet(-GetWetMax()/5);
9454 //PrintVariables();
9455 }
9456
9457 else if (action_id == EActions.LIQUIDTYPE_UP)
9458 {
9459 int curr_type = GetLiquidType();
9460 SetLiquidType(curr_type * 2);
9461 //AddWet(1);
9462 //PrintVariables();
9463 }
9464
9465 else if (action_id == EActions.LIQUIDTYPE_DOWN)
9466 {
9467 int curr_type2 = GetLiquidType();
9468 SetLiquidType(curr_type2 / 2);
9469 }
9470
9471 else if (action_id == EActions.MAKE_SPECIAL)
9472 {
9473 auto debugParams = DebugSpawnParams.WithPlayer(player);
9474 OnDebugSpawnEx(debugParams);
9475 }
9476
9477 }
9478
9479
9480 return false;
9481 }
9482
9483 // -------------------------------------------------------------------------
9484
9485
9488 void OnActivatedByTripWire();
9489
9491 void OnActivatedByItem(notnull ItemBase item);
9492
9493 //----------------------------------------------------------------
9494 //returns true if item is able to explode when put in fire
9495 bool CanExplodeInFire()
9496 {
9497 return false;
9498 }
9499
9500 //----------------------------------------------------------------
9501 bool CanEat()
9502 {
9503 return true;
9504 }
9505
9506 //----------------------------------------------------------------
9507 override bool IsIgnoredByConstruction()
9508 {
9509 return true;
9510 }
9511
9512 //----------------------------------------------------------------
9513 //has FoodStages in config?
9514 bool HasFoodStage()
9515 {
9516 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
9517 return GetGame().ConfigIsExisting(config_path);
9518 }
9519
9521 FoodStage GetFoodStage()
9522 {
9523 return null;
9524 }
9525
9526 bool CanBeCooked()
9527 {
9528 return false;
9529 }
9530
9531 bool CanBeCookedOnStick()
9532 {
9533 return false;
9534 }
9535
9537 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
9539
9540 //----------------------------------------------------------------
9541 bool CanRepair(ItemBase item_repair_kit)
9542 {
9543 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
9544 return module_repairing.CanRepair(this, item_repair_kit);
9545 }
9546
9547 //----------------------------------------------------------------
9548 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
9549 {
9550 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
9551 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
9552 }
9553
9554 //----------------------------------------------------------------
9555 int GetItemSize()
9556 {
9557 /*
9558 vector v_size = this.ConfigGetVector("itemSize");
9559 int v_size_x = v_size[0];
9560 int v_size_y = v_size[1];
9561 int size = v_size_x * v_size_y;
9562 return size;
9563 */
9564
9565 return 1;
9566 }
9567
9568 //----------------------------------------------------------------
9569 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
9570 bool CanBeMovedOverride()
9571 {
9572 return m_CanBeMovedOverride;
9573 }
9574
9575 //----------------------------------------------------------------
9576 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
9577 void SetCanBeMovedOverride(bool setting)
9578 {
9579 m_CanBeMovedOverride = setting;
9580 }
9581
9582 //----------------------------------------------------------------
9590 void MessageToOwnerStatus(string text)
9591 {
9592 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9593
9594 if (player)
9595 {
9596 player.MessageStatus(text);
9597 }
9598 }
9599
9600 //----------------------------------------------------------------
9608 void MessageToOwnerAction(string text)
9609 {
9610 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9611
9612 if (player)
9613 {
9614 player.MessageAction(text);
9615 }
9616 }
9617
9618 //----------------------------------------------------------------
9626 void MessageToOwnerFriendly(string text)
9627 {
9628 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9629
9630 if (player)
9631 {
9632 player.MessageFriendly(text);
9633 }
9634 }
9635
9636 //----------------------------------------------------------------
9644 void MessageToOwnerImportant(string text)
9645 {
9646 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
9647
9648 if (player)
9649 {
9650 player.MessageImportant(text);
9651 }
9652 }
9653
9654 override bool IsItemBase()
9655 {
9656 return true;
9657 }
9658
9659 // Checks if item is of questioned kind
9660 override bool KindOf(string tag)
9661 {
9662 bool found = false;
9663 string item_name = this.GetType();
9664 ref TStringArray item_tag_array = new TStringArray;
9665 GetGame().ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
9666
9667 int array_size = item_tag_array.Count();
9668 for (int i = 0; i < array_size; i++)
9669 {
9670 if (item_tag_array.Get(i) == tag)
9671 {
9672 found = true;
9673 break;
9674 }
9675 }
9676 return found;
9677 }
9678
9679
9680 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
9681 {
9682 //Debug.Log("OnRPC called");
9683 super.OnRPC(sender, rpc_type,ctx);
9684
9685 //Play soundset for attachment locking (ActionLockAttachment.c)
9686 switch (rpc_type)
9687 {
9688 #ifndef SERVER
9689 case ERPCs.RPC_SOUND_LOCK_ATTACH:
9690 Param2<bool, string> p = new Param2<bool, string>(false, "");
9691
9692 if (!ctx.Read(p))
9693 return;
9694
9695 bool play = p.param1;
9696 string soundSet = p.param2;
9697
9698 if (play)
9699 {
9700 if (m_LockingSound)
9701 {
9703 {
9704 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
9705 }
9706 }
9707 else
9708 {
9709 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
9710 }
9711 }
9712 else
9713 {
9714 SEffectManager.DestroyEffect(m_LockingSound);
9715 }
9716
9717 break;
9718 #endif
9719
9720 }
9721
9722 if (GetWrittenNoteData())
9723 {
9724 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
9725 }
9726 }
9727
9728 //-----------------------------
9729 // VARIABLE MANIPULATION SYSTEM
9730 //-----------------------------
9731 int NameToID(string name)
9732 {
9733 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
9734 return plugin.GetID(name);
9735 }
9736
9737 string IDToName(int id)
9738 {
9739 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
9740 return plugin.GetName(id);
9741 }
9742
9744 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
9745 {
9746 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
9747 //read the flags
9748 int varFlags;
9749 if (!ctx.Read(varFlags))
9750 return;
9751
9752 if (varFlags & ItemVariableFlags.FLOAT)
9753 {
9754 ReadVarsFromCTX(ctx);
9755 }
9756 }
9757
9758 override void SerializeNumericalVars(array<float> floats_out)
9759 {
9760 //some variables handled on EntityAI level already!
9761 super.SerializeNumericalVars(floats_out);
9762
9763 // the order of serialization must be the same as the order of de-serialization
9764 //--------------------------------------------
9765 if (IsVariableSet(VARIABLE_QUANTITY))
9766 {
9767 floats_out.Insert(m_VarQuantity);
9768 }
9769 //--------------------------------------------
9770 if (IsVariableSet(VARIABLE_WET))
9771 {
9772 floats_out.Insert(m_VarWet);
9773 }
9774 //--------------------------------------------
9775 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
9776 {
9777 floats_out.Insert(m_VarLiquidType);
9778 }
9779 //--------------------------------------------
9780 if (IsVariableSet(VARIABLE_COLOR))
9781 {
9782 floats_out.Insert(m_ColorComponentR);
9783 floats_out.Insert(m_ColorComponentG);
9784 floats_out.Insert(m_ColorComponentB);
9785 floats_out.Insert(m_ColorComponentA);
9786 }
9787 //--------------------------------------------
9788 if (IsVariableSet(VARIABLE_CLEANNESS))
9789 {
9790 floats_out.Insert(m_Cleanness);
9791 }
9792 }
9793
9794 override void DeSerializeNumericalVars(array<float> floats)
9795 {
9796 //some variables handled on EntityAI level already!
9797 super.DeSerializeNumericalVars(floats);
9798
9799 // the order of serialization must be the same as the order of de-serialization
9800 int index = 0;
9801 int mask = Math.Round(floats.Get(index));
9802
9803 index++;
9804 //--------------------------------------------
9805 if (mask & VARIABLE_QUANTITY)
9806 {
9807 if (m_IsStoreLoad)
9808 {
9809 SetStoreLoadedQuantity(floats.Get(index));
9810 }
9811 else
9812 {
9813 float quantity = floats.Get(index);
9814 SetQuantity(quantity, true, false, false, false);
9815 }
9816 index++;
9817 }
9818 //--------------------------------------------
9819 if (mask & VARIABLE_WET)
9820 {
9821 float wet = floats.Get(index);
9822 SetWet(wet);
9823 index++;
9824 }
9825 //--------------------------------------------
9826 if (mask & VARIABLE_LIQUIDTYPE)
9827 {
9828 int liquidtype = Math.Round(floats.Get(index));
9829 SetLiquidType(liquidtype);
9830 index++;
9831 }
9832 //--------------------------------------------
9833 if (mask & VARIABLE_COLOR)
9834 {
9835 m_ColorComponentR = Math.Round(floats.Get(index));
9836 index++;
9837 m_ColorComponentG = Math.Round(floats.Get(index));
9838 index++;
9839 m_ColorComponentB = Math.Round(floats.Get(index));
9840 index++;
9841 m_ColorComponentA = Math.Round(floats.Get(index));
9842 index++;
9843 }
9844 //--------------------------------------------
9845 if (mask & VARIABLE_CLEANNESS)
9846 {
9847 int cleanness = Math.Round(floats.Get(index));
9848 SetCleanness(cleanness);
9849 index++;
9850 }
9851 }
9852
9853 override void WriteVarsToCTX(ParamsWriteContext ctx)
9854 {
9855 super.WriteVarsToCTX(ctx);
9856
9857 //--------------------------------------------
9858 if (IsVariableSet(VARIABLE_QUANTITY))
9859 {
9860 ctx.Write(GetQuantity());
9861 }
9862 //--------------------------------------------
9863 if (IsVariableSet(VARIABLE_WET))
9864 {
9865 ctx.Write(GetWet());
9866 }
9867 //--------------------------------------------
9868 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
9869 {
9870 ctx.Write(GetLiquidType());
9871 }
9872 //--------------------------------------------
9873 if (IsVariableSet(VARIABLE_COLOR))
9874 {
9875 int r,g,b,a;
9876 GetColor(r,g,b,a);
9877 ctx.Write(r);
9878 ctx.Write(g);
9879 ctx.Write(b);
9880 ctx.Write(a);
9881 }
9882 //--------------------------------------------
9883 if (IsVariableSet(VARIABLE_CLEANNESS))
9884 {
9885 ctx.Write(GetCleanness());
9886 }
9887 }
9888
9889 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
9890 {
9891 if (!super.ReadVarsFromCTX(ctx,version))
9892 return false;
9893
9894 int intValue;
9895 float value;
9896
9897 if (version < 140)
9898 {
9899 if (!ctx.Read(intValue))
9900 return false;
9901
9902 m_VariablesMask = intValue;
9903 }
9904
9905 if (m_VariablesMask & VARIABLE_QUANTITY)
9906 {
9907 if (!ctx.Read(value))
9908 return false;
9909
9910 if (IsStoreLoad())
9911 {
9913 }
9914 else
9915 {
9916 SetQuantity(value, true, false, false, false);
9917 }
9918 }
9919 //--------------------------------------------
9920 if (version < 140)
9921 {
9922 if (m_VariablesMask & VARIABLE_TEMPERATURE)
9923 {
9924 if (!ctx.Read(value))
9925 return false;
9926 SetTemperatureDirect(value);
9927 }
9928 }
9929 //--------------------------------------------
9930 if (m_VariablesMask & VARIABLE_WET)
9931 {
9932 if (!ctx.Read(value))
9933 return false;
9934 SetWet(value);
9935 }
9936 //--------------------------------------------
9937 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
9938 {
9939 if (!ctx.Read(intValue))
9940 return false;
9941 SetLiquidType(intValue);
9942 }
9943 //--------------------------------------------
9944 if (m_VariablesMask & VARIABLE_COLOR)
9945 {
9946 int r,g,b,a;
9947 if (!ctx.Read(r))
9948 return false;
9949 if (!ctx.Read(g))
9950 return false;
9951 if (!ctx.Read(b))
9952 return false;
9953 if (!ctx.Read(a))
9954 return false;
9955
9956 SetColor(r,g,b,a);
9957 }
9958 //--------------------------------------------
9959 if (m_VariablesMask & VARIABLE_CLEANNESS)
9960 {
9961 if (!ctx.Read(intValue))
9962 return false;
9963 SetCleanness(intValue);
9964 }
9965 //--------------------------------------------
9966 if (version >= 138 && version < 140)
9967 {
9968 if (m_VariablesMask & VARIABLE_TEMPERATURE)
9969 {
9970 if (!ctx.Read(intValue))
9971 return false;
9972 SetFrozen(intValue);
9973 }
9974 }
9975
9976 return true;
9977 }
9978
9979 //----------------------------------------------------------------
9980 override bool OnStoreLoad(ParamsReadContext ctx, int version)
9981 {
9982 m_IsStoreLoad = true;
9984 {
9985 m_FixDamageSystemInit = true;
9986 }
9987
9988 if (!super.OnStoreLoad(ctx, version))
9989 {
9990 m_IsStoreLoad = false;
9991 return false;
9992 }
9993
9994 if (version >= 114)
9995 {
9996 bool hasQuickBarIndexSaved;
9997
9998 if (!ctx.Read(hasQuickBarIndexSaved))
9999 {
10000 m_IsStoreLoad = false;
10001 return false;
10002 }
10003
10004 if (hasQuickBarIndexSaved)
10005 {
10006 int itmQBIndex;
10007
10008 //Load quickbar item bind
10009 if (!ctx.Read(itmQBIndex))
10010 {
10011 m_IsStoreLoad = false;
10012 return false;
10013 }
10014
10015 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
10016 if (itmQBIndex != -1 && parentPlayer)
10017 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
10018 }
10019 }
10020 else
10021 {
10022 // Backup of how it used to be
10023 PlayerBase player;
10024 int itemQBIndex;
10025 if (version == int.MAX)
10026 {
10027 if (!ctx.Read(itemQBIndex))
10028 {
10029 m_IsStoreLoad = false;
10030 return false;
10031 }
10032 }
10033 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
10034 {
10035 //Load quickbar item bind
10036 if (!ctx.Read(itemQBIndex))
10037 {
10038 m_IsStoreLoad = false;
10039 return false;
10040 }
10041 if (itemQBIndex != -1 && player)
10042 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
10043 }
10044 }
10045
10046 if (version < 140)
10047 {
10048 // variable management system
10049 if (!LoadVariables(ctx, version))
10050 {
10051 m_IsStoreLoad = false;
10052 return false;
10053 }
10054 }
10055
10056 //agent trasmission system
10057 if (!LoadAgents(ctx, version))
10058 {
10059 m_IsStoreLoad = false;
10060 return false;
10061 }
10062 if (version >= 132)
10063 {
10064 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
10065 if (raib)
10066 {
10067 if (!raib.OnStoreLoad(ctx,version))
10068 {
10069 m_IsStoreLoad = false;
10070 return false;
10071 }
10072 }
10073 }
10074
10075 m_IsStoreLoad = false;
10076 return true;
10077 }
10078
10079 //----------------------------------------------------------------
10080
10081 override void OnStoreSave(ParamsWriteContext ctx)
10082 {
10083 super.OnStoreSave(ctx);
10084
10085 PlayerBase player;
10086 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
10087 {
10088 ctx.Write(true); // Keep track of if we should actually read this in or not
10089 //Save quickbar item bind
10090 int itemQBIndex = -1;
10091 itemQBIndex = player.FindQuickBarEntityIndex(this);
10092 ctx.Write(itemQBIndex);
10093 }
10094 else
10095 {
10096 ctx.Write(false); // Keep track of if we should actually read this in or not
10097 }
10098
10099 SaveAgents(ctx);//agent trasmission system
10100
10101 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
10102 if (raib)
10103 {
10104 raib.OnStoreSave(ctx);
10105 }
10106 }
10107 //----------------------------------------------------------------
10108
10109 override void AfterStoreLoad()
10110 {
10111 super.AfterStoreLoad();
10112
10114 {
10116 }
10117
10118 if (GetStoreLoadedQuantity() != float.LOWEST)
10119 {
10121 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
10122 }
10123 }
10124
10125 override void EEOnAfterLoad()
10126 {
10127 super.EEOnAfterLoad();
10128
10130 {
10131 m_FixDamageSystemInit = false;
10132 }
10133
10136 }
10137
10138 bool CanBeDisinfected()
10139 {
10140 return false;
10141 }
10142
10143
10144 //----------------------------------------------------------------
10145 override void OnVariablesSynchronized()
10146 {
10147 if (m_Initialized)
10148 {
10149 #ifdef PLATFORM_CONSOLE
10150 //bruteforce it is
10151 if (IsSplitable())
10152 {
10153 UIScriptedMenu menu = GetGame().GetUIManager().FindMenu(MENU_INVENTORY);
10154 if (menu)
10155 {
10156 menu.Refresh();
10157 }
10158 }
10159 #endif
10160 }
10161
10163 {
10164 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
10165 m_WantPlayImpactSound = false;
10166 }
10167
10169 {
10170 SetWeightDirty();
10172 }
10173 if (m_VarWet != m_VarWetPrev)
10174 {
10177 }
10178
10179 if (m_SoundSyncPlay != 0)
10180 {
10181 m_ItemSoundHandler.PlayItemSoundClient(m_SoundSyncPlay);
10182 m_SoundSyncPlay = 0;
10183 }
10184 if (m_SoundSyncStop != 0)
10185 {
10186 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
10187 m_SoundSyncStop = 0;
10188 }
10189
10190 super.OnVariablesSynchronized();
10191 }
10192
10193 //------------------------- Quantity
10194 //----------------------------------------------------------------
10196 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
10197 {
10198 if (!IsServerCheck(allow_client))
10199 return false;
10200
10201 if (!HasQuantity())
10202 return false;
10203
10204 float min = GetQuantityMin();
10205 float max = GetQuantityMax();
10206
10207 if (value <= (min + 0.001))
10208 value = min;
10209
10210 if (value == min)
10211 {
10212 if (destroy_config)
10213 {
10214 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
10215 if (dstr)
10216 {
10217 m_VarQuantity = Math.Clamp(value, min, max);
10218 this.Delete();
10219 return true;
10220 }
10221 }
10222 else if (destroy_forced)
10223 {
10224 m_VarQuantity = Math.Clamp(value, min, max);
10225 this.Delete();
10226 return true;
10227 }
10228 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
10229 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
10230 }
10231
10232 float delta = m_VarQuantity;
10233 m_VarQuantity = Math.Clamp(value, min, max);
10234
10235 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
10236 {
10237 delta = m_VarQuantity - delta;
10238
10239 if (delta)
10240 OnQuantityChanged(delta);
10241 }
10242
10243 SetVariableMask(VARIABLE_QUANTITY);
10244
10245 return false;
10246 }
10247
10248 //----------------------------------------------------------------
10250 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
10251 {
10252 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
10253 }
10254 //----------------------------------------------------------------
10255 void SetQuantityMax()
10256 {
10257 float max = GetQuantityMax();
10258 SetQuantity(max);
10259 }
10260
10261 override void SetQuantityToMinimum()
10262 {
10263 float min = GetQuantityMin();
10264 SetQuantity(min);
10265 }
10266 //----------------------------------------------------------------
10268 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
10269 {
10270 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
10271 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
10272 SetQuantity(result, destroy_config, destroy_forced);
10273 }
10274
10275 //----------------------------------------------------------------
10277 override float GetQuantityNormalized()
10278 {
10279 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
10280 }
10281
10283 {
10284 return GetQuantityNormalized();
10285 }
10286
10287 /*void SetAmmoNormalized(float value)
10288 {
10289 float value_clamped = Math.Clamp(value, 0, 1);
10290 Magazine this_mag = Magazine.Cast(this);
10291 int max_rounds = this_mag.GetAmmoMax();
10292 int result = value * max_rounds;//can the rounded if higher precision is required
10293 this_mag.SetAmmoCount(result);
10294 }*/
10295 //----------------------------------------------------------------
10296 override int GetQuantityMax()
10297 {
10298 int slot = -1;
10299 if (GetInventory())
10300 {
10301 InventoryLocation il = new InventoryLocation;
10302 GetInventory().GetCurrentInventoryLocation(il);
10303 slot = il.GetSlot();
10304 }
10305
10306 return GetTargetQuantityMax(slot);
10307 }
10308
10309 override int GetTargetQuantityMax(int attSlotID = -1)
10310 {
10311 float quantity_max = 0;
10312
10313 if (IsSplitable()) //only stackable/splitable items can check for stack size
10314 {
10315 if (attSlotID != -1)
10316 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
10317
10318 if (quantity_max <= 0)
10319 quantity_max = m_VarStackMax;
10320 }
10321
10322 if (quantity_max <= 0)
10323 quantity_max = m_VarQuantityMax;
10324
10325 return quantity_max;
10326 }
10327 //----------------------------------------------------------------
10328 override int GetQuantityMin()
10329 {
10330 return m_VarQuantityMin;
10331 }
10332 //----------------------------------------------------------------
10333 int GetQuantityInit()
10334 {
10335 return m_VarQuantityInit;
10336 }
10337
10338 //----------------------------------------------------------------
10339 override bool HasQuantity()
10340 {
10341 return !(GetQuantityMax() - GetQuantityMin() == 0);
10342 }
10343
10344 override float GetQuantity()
10345 {
10346 return m_VarQuantity;
10347 }
10348
10349 bool IsFullQuantity()
10350 {
10351 return GetQuantity() >= GetQuantityMax();
10352 }
10353
10354 //Calculates weight of single item without attachments and cargo
10355 override float GetSingleInventoryItemWeightEx()
10356 {
10357 //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
10358 float weightEx = GetWeightEx();//overall weight of the item
10359 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
10360 return weightEx - special;
10361 }
10362
10363 // Obsolete, use GetSingleInventoryItemWeightEx() instead
10365 {
10367 }
10368
10369 override protected float GetWeightSpecialized(bool forceRecalc = false)
10370 {
10371 if (IsSplitable()) //quantity determines size of the stack
10372 {
10373 #ifdef DEVELOPER
10374 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
10375 {
10376 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
10377 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
10378 }
10379 #endif
10380
10381 return GetQuantity() * GetConfigWeightModified();
10382 }
10383 else if (HasEnergyManager())// items with energy manager
10384 {
10385 #ifdef DEVELOPER
10386 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
10387 {
10388 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
10389 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
10390 }
10391 #endif
10392 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
10393 }
10394 else//everything else
10395 {
10396 #ifdef DEVELOPER
10397 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
10398 {
10399 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
10400 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
10401 }
10402 #endif
10403 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
10404 }
10405 }
10406
10408 int GetNumberOfItems()
10409 {
10410 int item_count = 0;
10411 ItemBase item;
10412
10413 if (GetInventory().GetCargo() != NULL)
10414 {
10415 item_count = GetInventory().GetCargo().GetItemCount();
10416 }
10417
10418 for (int i = 0; i < GetInventory().AttachmentCount(); i++)
10419 {
10420 Class.CastTo(item,GetInventory().GetAttachmentFromIndex(i));
10421 if (item)
10422 item_count += item.GetNumberOfItems();
10423 }
10424 return item_count;
10425 }
10426
10428 float GetUnitWeight(bool include_wetness = true)
10429 {
10430 float weight = 0;
10431 float wetness = 1;
10432 if (include_wetness)
10433 wetness += GetWet();
10434 if (IsSplitable()) //quantity determines size of the stack
10435 {
10436 weight = wetness * m_ConfigWeight;
10437 }
10438 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
10439 {
10440 weight = 1;
10441 }
10442 return weight;
10443 }
10444
10445 //-----------------------------------------------------------------
10446
10447 override void ClearInventory()
10448 {
10449 if ((GetGame().IsServer() || !GetGame().IsMultiplayer()) && GetInventory())
10450 {
10451 GameInventory inv = GetInventory();
10452 array<EntityAI> items = new array<EntityAI>;
10453 inv.EnumerateInventory(InventoryTraversalType.INORDER, items);
10454 for (int i = 0; i < items.Count(); i++)
10455 {
10456 ItemBase item = ItemBase.Cast(items.Get(i));
10457 if (item)
10458 {
10459 GetGame().ObjectDelete(item);
10460 }
10461 }
10462 }
10463 }
10464
10465 //------------------------- Energy
10466
10467 //----------------------------------------------------------------
10468 float GetEnergy()
10469 {
10470 float energy = 0;
10471 if (HasEnergyManager())
10472 {
10473 energy = GetCompEM().GetEnergy();
10474 }
10475 return energy;
10476 }
10477
10478
10479 override void OnEnergyConsumed()
10480 {
10481 super.OnEnergyConsumed();
10482
10484 }
10485
10486 override void OnEnergyAdded()
10487 {
10488 super.OnEnergyAdded();
10489
10491 }
10492
10493 // Converts energy (from Energy Manager) to quantity, if enabled.
10495 {
10496 if (GetGame().IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
10497 {
10498 if (HasQuantity())
10499 {
10500 float energy_0to1 = GetCompEM().GetEnergy0To1();
10501 SetQuantityNormalized(energy_0to1);
10502 }
10503 }
10504 }
10505
10506 //----------------------------------------------------------------
10507 float GetHeatIsolationInit()
10508 {
10509 return ConfigGetFloat("heatIsolation");
10510 }
10511
10512 float GetHeatIsolation()
10513 {
10514 return m_HeatIsolation;
10515 }
10516
10517 float GetDryingIncrement(string pIncrementName)
10518 {
10519 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
10520 if (GetGame().ConfigIsExisting(paramPath))
10521 return GetGame().ConfigGetFloat(paramPath);
10522
10523 return 0.0;
10524 }
10525
10526 float GetSoakingIncrement(string pIncrementName)
10527 {
10528 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
10529 if (GetGame().ConfigIsExisting(paramPath))
10530 return GetGame().ConfigGetFloat(paramPath);
10531
10532 return 0.0;
10533 }
10534 //----------------------------------------------------------------
10535 override void SetWet(float value, bool allow_client = false)
10536 {
10537 if (!IsServerCheck(allow_client))
10538 return;
10539
10540 float min = GetWetMin();
10541 float max = GetWetMax();
10542
10543 float previousValue = m_VarWet;
10544
10545 m_VarWet = Math.Clamp(value, min, max);
10546
10547 if (previousValue != m_VarWet)
10548 {
10549 SetVariableMask(VARIABLE_WET);
10550 OnWetChanged(m_VarWet, previousValue);
10551 }
10552 }
10553 //----------------------------------------------------------------
10554 override void AddWet(float value)
10555 {
10556 SetWet(GetWet() + value);
10557 }
10558 //----------------------------------------------------------------
10559 override void SetWetMax()
10560 {
10562 }
10563 //----------------------------------------------------------------
10564 override float GetWet()
10565 {
10566 return m_VarWet;
10567 }
10568 //----------------------------------------------------------------
10569 override float GetWetMax()
10570 {
10571 return m_VarWetMax;
10572 }
10573 //----------------------------------------------------------------
10574 override float GetWetMin()
10575 {
10576 return m_VarWetMin;
10577 }
10578 //----------------------------------------------------------------
10579 override float GetWetInit()
10580 {
10581 return m_VarWetInit;
10582 }
10583 //----------------------------------------------------------------
10584 override void OnWetChanged(float newVal, float oldVal)
10585 {
10586 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
10587 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
10588 if (newLevel != oldLevel)
10589 {
10590 OnWetLevelChanged(newLevel,oldLevel);
10591 }
10592 }
10593
10594 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
10595 {
10596 SetWeightDirty();
10597 }
10598
10599 override EWetnessLevel GetWetLevel()
10600 {
10601 return GetWetLevelInternal(m_VarWet);
10602 }
10603
10604 //----------------------------------------------------------------
10605
10606 override void SetStoreLoad(bool value)
10607 {
10608 m_IsStoreLoad = value;
10609 }
10610
10611 override bool IsStoreLoad()
10612 {
10613 return m_IsStoreLoad;
10614 }
10615
10616 override void SetStoreLoadedQuantity(float value)
10617 {
10618 m_StoreLoadedQuantity = value;
10619 }
10620
10621 override float GetStoreLoadedQuantity()
10622 {
10623 return m_StoreLoadedQuantity;
10624 }
10625
10626 //----------------------------------------------------------------
10627
10628 float GetItemModelLength()
10629 {
10630 if (ConfigIsExisting("itemModelLength"))
10631 {
10632 return ConfigGetFloat("itemModelLength");
10633 }
10634 return 0;
10635 }
10636
10637 float GetItemAttachOffset()
10638 {
10639 if (ConfigIsExisting("itemAttachOffset"))
10640 {
10641 return ConfigGetFloat("itemAttachOffset");
10642 }
10643 return 0;
10644 }
10645
10646 override void SetCleanness(int value, bool allow_client = false)
10647 {
10648 if (!IsServerCheck(allow_client))
10649 return;
10650
10651 int previousValue = m_Cleanness;
10652
10653 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
10654
10655 if (previousValue != m_Cleanness)
10656 SetVariableMask(VARIABLE_CLEANNESS);
10657 }
10658
10659 override int GetCleanness()
10660 {
10661 return m_Cleanness;
10662 }
10663
10665 {
10666 return true;
10667 }
10668
10669 //----------------------------------------------------------------
10670 // ATTACHMENT LOCKING
10671 // Getters relevant to generic ActionLockAttachment
10672 int GetLockType()
10673 {
10674 return m_LockType;
10675 }
10676
10677 string GetLockSoundSet()
10678 {
10679 return m_LockSoundSet;
10680 }
10681
10682 //----------------------------------------------------------------
10683 //------------------------- Color
10684 // sets items color variable given color components
10685 override void SetColor(int r, int g, int b, int a)
10686 {
10691 SetVariableMask(VARIABLE_COLOR);
10692 }
10694 override void GetColor(out int r,out int g,out int b,out int a)
10695 {
10700 }
10701
10702 bool IsColorSet()
10703 {
10704 return IsVariableSet(VARIABLE_COLOR);
10705 }
10706
10708 string GetColorString()
10709 {
10710 int r,g,b,a;
10711 GetColor(r,g,b,a);
10712 r = r/255;
10713 g = g/255;
10714 b = b/255;
10715 a = a/255;
10716 return MiscGameplayFunctions.GetColorString(r, g, b, a);
10717 }
10718 //----------------------------------------------------------------
10719 //------------------------- LiquidType
10720
10721 override void SetLiquidType(int value, bool allow_client = false)
10722 {
10723 if (!IsServerCheck(allow_client))
10724 return;
10725
10726 int old = m_VarLiquidType;
10727 m_VarLiquidType = value;
10728 OnLiquidTypeChanged(old,value);
10729 SetVariableMask(VARIABLE_LIQUIDTYPE);
10730 }
10731
10732 int GetLiquidTypeInit()
10733 {
10734 return ConfigGetInt("varLiquidTypeInit");
10735 }
10736
10737 override int GetLiquidType()
10738 {
10739 return m_VarLiquidType;
10740 }
10741
10742 protected void OnLiquidTypeChanged(int oldType, int newType)
10743 {
10744 if (newType == LIQUID_NONE && GetIsFrozen())
10745 SetFrozen(false);
10746 }
10747
10749 void UpdateQuickbarShortcutVisibility(PlayerBase player)
10750 {
10751 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
10752 }
10753
10754 // -------------------------------------------------------------------------
10756 void OnInventoryEnter(Man player)
10757 {
10758 PlayerBase nplayer;
10759 if (PlayerBase.CastTo(nplayer, player))
10760 {
10761 m_CanPlayImpactSound = true;
10762 //nplayer.OnItemInventoryEnter(this);
10763 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
10764 }
10765 }
10766
10767 // -------------------------------------------------------------------------
10769 void OnInventoryExit(Man player)
10770 {
10771 PlayerBase nplayer;
10772 if (PlayerBase.CastTo(nplayer,player))
10773 {
10774 //nplayer.OnItemInventoryExit(this);
10775 nplayer.SetEnableQuickBarEntityShortcut(this,false);
10776
10777 }
10778
10779 //if (!GetGame().IsDedicatedServer())
10780 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
10781
10782
10783 if (HasEnergyManager())
10784 {
10785 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
10786 }
10787 }
10788
10789 // ADVANCED PLACEMENT EVENTS
10790 override void OnPlacementStarted(Man player)
10791 {
10792 super.OnPlacementStarted(player);
10793
10794 SetTakeable(false);
10795 }
10796
10797 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
10798 {
10799 if (m_AdminLog)
10800 {
10801 m_AdminLog.OnPlacementComplete(player, this);
10802 }
10803
10804 super.OnPlacementComplete(player, position, orientation);
10805 }
10806
10807 //-----------------------------
10808 // AGENT SYSTEM
10809 //-----------------------------
10810 //--------------------------------------------------------------------------
10811 bool ContainsAgent(int agent_id)
10812 {
10813 if (agent_id & m_AttachedAgents)
10814 {
10815 return true;
10816 }
10817 else
10818 {
10819 return false;
10820 }
10821 }
10822
10823 //--------------------------------------------------------------------------
10824 override void RemoveAgent(int agent_id)
10825 {
10826 if (ContainsAgent(agent_id))
10827 {
10828 m_AttachedAgents = ~agent_id & m_AttachedAgents;
10829 }
10830 }
10831
10832 //--------------------------------------------------------------------------
10833 override void RemoveAllAgents()
10834 {
10835 m_AttachedAgents = 0;
10836 }
10837 //--------------------------------------------------------------------------
10838 override void RemoveAllAgentsExcept(int agent_to_keep)
10839 {
10840 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
10841 }
10842 // -------------------------------------------------------------------------
10843 override void InsertAgent(int agent, float count = 1)
10844 {
10845 if (count < 1)
10846 return;
10847 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
10849 }
10850
10852 void TransferAgents(int agents)
10853 {
10855 }
10856
10857 // -------------------------------------------------------------------------
10858 override int GetAgents()
10859 {
10860 return m_AttachedAgents;
10861 }
10862 //----------------------------------------------------------------------
10863
10864 /*int GetContaminationType()
10865 {
10866 int contamination_type;
10867
10868 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
10869 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
10870 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
10871 const int DIRTY_MASK = eAgents.WOUND_AGENT;
10872
10873 Edible_Base edible = Edible_Base.Cast(this);
10874 int agents = GetAgents();
10875 if (edible)
10876 {
10877 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
10878 if (profile)
10879 {
10880 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
10881 }
10882 }
10883 if (agents & CONTAMINATED_MASK)
10884 {
10885 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
10886 }
10887 if (agents & POISONED_MASK)
10888 {
10889 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
10890 }
10891 if (agents & NERVE_GAS_MASK)
10892 {
10893 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
10894 }
10895 if (agents & DIRTY_MASK)
10896 {
10897 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
10898 }
10899
10900 return agents;
10901 }*/
10902
10903 // -------------------------------------------------------------------------
10904 bool LoadAgents(ParamsReadContext ctx, int version)
10905 {
10906 if (!ctx.Read(m_AttachedAgents))
10907 return false;
10908 return true;
10909 }
10910 // -------------------------------------------------------------------------
10912 {
10913
10915 }
10916 // -------------------------------------------------------------------------
10917
10919 override void CheckForRoofLimited(float timeTresholdMS = 3000)
10920 {
10921 super.CheckForRoofLimited(timeTresholdMS);
10922
10923 float time = GetGame().GetTime();
10924 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
10925 {
10926 m_PreviousRoofTestTime = time;
10927 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
10928 }
10929 }
10930
10931 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
10932 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
10933 {
10934 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
10935 {
10936 return 0;
10937 }
10938
10939 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
10940 {
10941 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
10942 if (filter)
10943 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
10944 else
10945 return 0;//otherwise return 0 when no filter attached
10946 }
10947
10948 string subclassPath, entryName;
10949
10950 switch (type)
10951 {
10952 case DEF_BIOLOGICAL:
10953 entryName = "biological";
10954 break;
10955 case DEF_CHEMICAL:
10956 entryName = "chemical";
10957 break;
10958 default:
10959 entryName = "biological";
10960 break;
10961 }
10962
10963 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
10964
10965 return GetGame().ConfigGetFloat(subclassPath + entryName);
10966 }
10967
10968
10969
10971 override void EEOnCECreate()
10972 {
10973 if (!IsMagazine())
10975
10977 }
10978
10979
10980 //-------------------------
10981 // OPEN/CLOSE USER ACTIONS
10982 //-------------------------
10984 void Open();
10985 void Close();
10986 bool IsOpen()
10987 {
10988 return true;
10989 }
10990
10991 override bool CanDisplayCargo()
10992 {
10993 return IsOpen();
10994 }
10995
10996
10997 // ------------------------------------------------------------
10998 // CONDITIONS
10999 // ------------------------------------------------------------
11000 override bool CanPutInCargo(EntityAI parent)
11001 {
11002 if (parent)
11003 {
11004 if (parent.IsInherited(DayZInfected))
11005 return true;
11006
11007 if (!parent.IsRuined())
11008 return true;
11009 }
11010
11011 return true;
11012 }
11013
11014 override bool CanPutAsAttachment(EntityAI parent)
11015 {
11016 if (!super.CanPutAsAttachment(parent))
11017 {
11018 return false;
11019 }
11020
11021 if (!IsRuined() && !parent.IsRuined())
11022 {
11023 return true;
11024 }
11025
11026 return false;
11027 }
11028
11029 override bool CanReceiveItemIntoCargo(EntityAI item)
11030 {
11031 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
11032 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
11033 // return false;
11034
11035 return super.CanReceiveItemIntoCargo(item);
11036 }
11037
11038 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
11039 {
11040 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
11041 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
11042 // return false;
11043
11044 GameInventory attachmentInv = attachment.GetInventory();
11045 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
11046 {
11047 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
11048 return false;
11049 }
11050
11051 InventoryLocation loc = new InventoryLocation();
11052 attachment.GetInventory().GetCurrentInventoryLocation(loc);
11053 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
11054 return false;
11055
11056 return super.CanReceiveAttachment(attachment, slotId);
11057 }
11058
11059 override bool CanReleaseAttachment(EntityAI attachment)
11060 {
11061 if (!super.CanReleaseAttachment(attachment))
11062 return false;
11063
11064 return GetInventory().AreChildrenAccessible();
11065 }
11066
11067 /*override bool CanLoadAttachment(EntityAI attachment)
11068 {
11069 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
11070 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
11071 // return false;
11072
11073 GameInventory attachmentInv = attachment.GetInventory();
11074 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
11075 {
11076 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
11077 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
11078
11079 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
11080 return false;
11081 }
11082
11083 return super.CanLoadAttachment(attachment);
11084 }*/
11085
11086 // Plays muzzle flash particle effects
11087 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11088 {
11089 int id = muzzle_owner.GetMuzzleID();
11090 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
11091
11092 if (WPOF_array)
11093 {
11094 for (int i = 0; i < WPOF_array.Count(); i++)
11095 {
11096 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
11097
11098 if (WPOF)
11099 {
11100 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
11101 }
11102 }
11103 }
11104 }
11105
11106 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
11107 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11108 {
11109 int id = muzzle_owner.GetMuzzleID();
11110 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
11111
11112 if (WPOBE_array)
11113 {
11114 for (int i = 0; i < WPOBE_array.Count(); i++)
11115 {
11116 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
11117
11118 if (WPOBE)
11119 {
11120 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
11121 }
11122 }
11123 }
11124 }
11125
11126 // Plays all weapon overheating particles
11127 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11128 {
11129 int id = muzzle_owner.GetMuzzleID();
11130 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
11131
11132 if (WPOOH_array)
11133 {
11134 for (int i = 0; i < WPOOH_array.Count(); i++)
11135 {
11136 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
11137
11138 if (WPOOH)
11139 {
11140 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
11141 }
11142 }
11143 }
11144 }
11145
11146 // Updates all weapon overheating particles
11147 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11148 {
11149 int id = muzzle_owner.GetMuzzleID();
11150 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
11151
11152 if (WPOOH_array)
11153 {
11154 for (int i = 0; i < WPOOH_array.Count(); i++)
11155 {
11156 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
11157
11158 if (WPOOH)
11159 {
11160 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
11161 }
11162 }
11163 }
11164 }
11165
11166 // Stops overheating particles
11167 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
11168 {
11169 int id = muzzle_owner.GetMuzzleID();
11170 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
11171
11172 if (WPOOH_array)
11173 {
11174 for (int i = 0; i < WPOOH_array.Count(); i++)
11175 {
11176 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
11177
11178 if (WPOOH)
11179 {
11180 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
11181 }
11182 }
11183 }
11184 }
11185
11186 //----------------------------------------------------------------
11187 //Item Behaviour - unified approach
11188 override bool IsHeavyBehaviour()
11189 {
11190 if (m_ItemBehaviour == 0)
11191 {
11192 return true;
11193 }
11194
11195 return false;
11196 }
11197
11198 override bool IsOneHandedBehaviour()
11199 {
11200 if (m_ItemBehaviour == 1)
11201 {
11202 return true;
11203 }
11204
11205 return false;
11206 }
11207
11208 override bool IsTwoHandedBehaviour()
11209 {
11210 if (m_ItemBehaviour == 2)
11211 {
11212 return true;
11213 }
11214
11215 return false;
11216 }
11217
11218 bool IsDeployable()
11219 {
11220 return false;
11221 }
11222
11224 float GetDeployTime()
11225 {
11226 return UATimeSpent.DEFAULT_DEPLOY;
11227 }
11228
11229
11230 //----------------------------------------------------------------
11231 // Item Targeting (User Actions)
11232 override void SetTakeable(bool pState)
11233 {
11234 m_IsTakeable = pState;
11235 SetSynchDirty();
11236 }
11237
11238 override bool IsTakeable()
11239 {
11240 return m_IsTakeable;
11241 }
11242
11243 // For cases where we want to show object widget which cant be taken to hands
11245 {
11246 return false;
11247 }
11248
11250 protected void PreLoadSoundAttachmentType()
11251 {
11252 string att_type = "None";
11253
11254 if (ConfigIsExisting("soundAttType"))
11255 {
11256 att_type = ConfigGetString("soundAttType");
11257 }
11258
11259 m_SoundAttType = att_type;
11260 }
11261
11262 override string GetAttachmentSoundType()
11263 {
11264 return m_SoundAttType;
11265 }
11266
11267 //----------------------------------------------------------------
11268 //SOUNDS - ItemSoundHandler
11269 //----------------------------------------------------------------
11270
11271 string GetPlaceSoundset(); // played when deploy starts
11272 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
11273 string GetDeploySoundset(); // played when deploy sucessfully finishes
11274 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
11275 string GetFoldSoundset(); // played when fold sucessfully finishes
11276
11278 {
11279 if (!m_ItemSoundHandler)
11281
11282 return m_ItemSoundHandler;
11283 }
11284
11285 // override to initialize sounds
11286 protected void InitItemSounds()
11287 {
11288 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty)
11289 return;
11290
11292
11293 if (GetPlaceSoundset() != string.Empty)
11294 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
11295
11296 if (GetDeploySoundset() != string.Empty)
11297 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
11298
11299 SoundParameters params = new SoundParameters();
11300 params.m_Loop = true;
11301 if (GetLoopDeploySoundset() != string.Empty)
11302 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
11303 }
11304
11305 // Start sound using ItemSoundHandler
11306 void StartItemSoundServer(int id)
11307 {
11308 if (!GetGame().IsServer())
11309 return;
11310
11311 m_SoundSyncPlay = id;
11312 SetSynchDirty();
11313
11314 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
11316 }
11317
11318 // Stop sound using ItemSoundHandler
11319 void StopItemSoundServer(int id)
11320 {
11321 if (!GetGame().IsServer())
11322 return;
11323
11324 m_SoundSyncStop = id;
11325 SetSynchDirty();
11326
11327 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
11329 }
11330
11331 protected void ClearStartItemSoundServer()
11332 {
11333 m_SoundSyncPlay = 0;
11334 }
11335
11336 protected void ClearStopItemSoundServer()
11337 {
11338 m_SoundSyncStop = 0;
11339 }
11340
11342 void PlayAttachSound(string slot_type)
11343 {
11344 if (!GetGame().IsDedicatedServer())
11345 {
11346 if (ConfigIsExisting("attachSoundSet"))
11347 {
11348 string cfg_path = "";
11349 string soundset = "";
11350 string type_name = GetType();
11351
11352 TStringArray cfg_soundset_array = new TStringArray;
11353 TStringArray cfg_slot_array = new TStringArray;
11354 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
11355 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
11356
11357 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
11358 {
11359 for (int i = 0; i < cfg_soundset_array.Count(); i++)
11360 {
11361 if (cfg_slot_array[i] == slot_type)
11362 {
11363 soundset = cfg_soundset_array[i];
11364 break;
11365 }
11366 }
11367 }
11368
11369 if (soundset != "")
11370 {
11371 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
11372 sound.SetAutodestroy(true);
11373 }
11374 }
11375 }
11376 }
11377
11378 void PlayDetachSound(string slot_type)
11379 {
11380 //TODO - evaluate if needed and devise universal config structure if so
11381 }
11382
11383 void OnApply(PlayerBase player);
11384
11386 {
11387 return 1.0;
11388 };
11389 //returns applicable selection
11390 array<string> GetHeadHidingSelection()
11391 {
11393 }
11394
11396 {
11398 }
11399
11400 WrittenNoteData GetWrittenNoteData() {};
11401
11403 {
11404 SetDynamicPhysicsLifeTime(0.01);
11405 m_ItemBeingDroppedPhys = false;
11406 }
11407
11409 {
11410 array<string> zone_names = new array<string>;
11411 GetDamageZones(zone_names);
11412 for (int i = 0; i < zone_names.Count(); i++)
11413 {
11414 SetHealthMax(zone_names.Get(i),"Health");
11415 }
11416 SetHealthMax("","Health");
11417 }
11418
11420 void SetZoneDamageCEInit()
11421 {
11422 float global_health = GetHealth01("","Health");
11423 array<string> zones = new array<string>;
11424 GetDamageZones(zones);
11425 //set damage of all zones to match global health level
11426 for (int i = 0; i < zones.Count(); i++)
11427 {
11428 SetHealth01(zones.Get(i),"Health",global_health);
11429 }
11430 }
11431
11433 bool IsCoverFaceForShave(string slot_name)
11434 {
11435 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
11436 }
11437
11438 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
11439 {
11440 if (!hasRootAsPlayer)
11441 {
11442 if (refParentIB)
11443 {
11444 // parent is wet
11445 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
11446 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
11447 // parent has liquid inside
11448 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
11449 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
11450 // drying
11451 else if (m_VarWet > m_VarWetMin)
11452 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
11453 }
11454 else
11455 {
11456 // drying on ground or inside non-itembase (car, ...)
11457 if (m_VarWet > m_VarWetMin)
11458 AddWet(-1 * delta * GetDryingIncrement("ground"));
11459 }
11460 }
11461 }
11462
11463 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
11464 {
11466 {
11467 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
11468 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
11469 {
11470 float heatPermCoef = 1.0;
11471 EntityAI ent = this;
11472 while (ent)
11473 {
11474 heatPermCoef *= ent.GetHeatPermeabilityCoef();
11475 ent = ent.GetHierarchyParent();
11476 }
11477
11478 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
11479 }
11480 }
11481 }
11482
11483 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
11484 {
11485 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
11486 EntityAI parent = GetHierarchyParent();
11487 if (!parent)
11488 {
11489 hasParent = false;
11490 hasRootAsPlayer = false;
11491 }
11492 else
11493 {
11494 hasParent = true;
11495 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
11496 refParentIB = ItemBase.Cast(parent);
11497 }
11498 }
11499
11500 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
11501 {
11502 // this is stub, implemented on Edible_Base
11503 }
11504
11505 bool CanDecay()
11506 {
11507 // return true used on selected food clases so they can decay
11508 return false;
11509 }
11510
11511 protected bool CanProcessDecay()
11512 {
11513 // this is stub, implemented on Edible_Base class
11514 // used to determine whether it is still necessary for the food to decay
11515 return false;
11516 }
11517
11518 protected bool CanHaveWetness()
11519 {
11520 // return true used on selected items that have a wetness effect
11521 return false;
11522 }
11523
11525 bool CanBeConsumed(ConsumeConditionData data = null)
11526 {
11527 return !GetIsFrozen() && IsOpen();
11528 }
11529
11530 override void ProcessVariables()
11531 {
11532 bool hasParent = false, hasRootAsPlayer = false;
11533 ItemBase refParentIB;
11534
11535 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
11536 bool foodDecay = g_Game.IsFoodDecayEnabled();
11537
11538 if (wwtu || foodDecay)
11539 {
11540 bool processWetness = wwtu && CanHaveWetness();
11541 bool processTemperature = wwtu && CanHaveTemperature();
11542 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
11543
11544 if (processWetness || processTemperature || processDecay)
11545 {
11546 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
11547
11548 if (processWetness)
11549 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
11550
11551 if (processTemperature)
11552 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
11553
11554 if (processDecay)
11555 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
11556 }
11557 }
11558 }
11559
11562 {
11563 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
11564 }
11565
11566 override float GetTemperatureFreezeThreshold()
11567 {
11569 return Liquid.GetFreezeThreshold(GetLiquidType());
11570
11571 return super.GetTemperatureFreezeThreshold();
11572 }
11573
11574 override float GetTemperatureThawThreshold()
11575 {
11577 return Liquid.GetThawThreshold(GetLiquidType());
11578
11579 return super.GetTemperatureThawThreshold();
11580 }
11581
11582 override float GetItemOverheatThreshold()
11583 {
11585 return Liquid.GetBoilThreshold(GetLiquidType());
11586
11587 return super.GetItemOverheatThreshold();
11588 }
11589
11590 override float GetTemperatureFreezeTime()
11591 {
11592 if (HasQuantity())
11593 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
11594
11595 return super.GetTemperatureFreezeTime();
11596 }
11597
11598 override float GetTemperatureThawTime()
11599 {
11600 if (HasQuantity())
11601 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
11602
11603 return super.GetTemperatureThawTime();
11604 }
11605
11607 void AffectLiquidContainerOnFill(int liquid_type, float amount);
11609 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
11610
11611 bool IsCargoException4x3(EntityAI item)
11612 {
11613 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
11614 }
11615
11617 {
11618 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
11619 }
11620
11622 void AddLightSourceItem(ItemBase lightsource)
11623 {
11624 m_LightSourceItem = lightsource;
11625 }
11626
11628 {
11629 m_LightSourceItem = null;
11630 }
11631
11633 {
11634 return m_LightSourceItem;
11635 }
11636
11638 array<int> GetValidFinishers()
11639 {
11640 return null;
11641 }
11642
11644 bool GetActionWidgetOverride(out typename name)
11645 {
11646 return false;
11647 }
11648
11649 bool PairWithDevice(notnull ItemBase otherDevice)
11650 {
11651 if (GetGame().IsServer())
11652 {
11653 ItemBase explosive = otherDevice;
11655 if (!trg)
11656 {
11657 trg = RemoteDetonatorTrigger.Cast(otherDevice);
11658 explosive = this;
11659 }
11660
11661 explosive.PairRemote(trg);
11662 trg.SetControlledDevice(explosive);
11663
11664 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
11665 trg.SetPersistentPairID(persistentID);
11666 explosive.SetPersistentPairID(persistentID);
11667
11668 return true;
11669 }
11670 return false;
11671 }
11672
11674 float GetBaitEffectivity()
11675 {
11676 float ret = 1.0;
11677 if (HasQuantity())
11678 ret *= GetQuantityNormalized();
11679 ret *= GetHealth01();
11680
11681 return ret;
11682 }
11683
11684 #ifdef DEVELOPER
11685 override void SetDebugItem()
11686 {
11687 super.SetDebugItem();
11688 _itemBase = this;
11689 }
11690
11691 override string GetDebugText()
11692 {
11693 string text = super.GetDebugText();
11694
11695 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
11696 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
11697
11698 return text;
11699 }
11700 #endif
11701
11702 bool CanBeUsedForSuicide()
11703 {
11704 return true;
11705 }
11706
11708 //DEPRECATED BELOW
11710 // Backwards compatibility
11711 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
11712 {
11713 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
11714 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
11715 }
11716
11717 // replaced by ItemSoundHandler
11718 protected EffectSound m_SoundDeployFinish;
11719 protected EffectSound m_SoundPlace;
11720 protected EffectSound m_DeployLoopSoundEx;
11721 protected EffectSound m_SoundDeploy;
11722 bool m_IsPlaceSound;
11723 bool m_IsDeploySound;
11725
11726 string GetDeployFinishSoundset();
11727 void PlayDeploySound();
11728 void PlayDeployFinishSound();
11729 void PlayPlaceSound();
11730 void PlayDeployLoopSoundEx();
11731 void StopDeployLoopSoundEx();
11732 void SoundSynchRemoteReset();
11733 void SoundSynchRemote();
11734 bool UsesGlobalDeploy(){return false;}
11735 bool CanPlayDeployLoopSound(){return false;}
11737 bool IsPlaceSound(){return m_IsPlaceSound;}
11738 bool IsDeploySound(){return m_IsDeploySound;}
11739 void SetIsPlaceSound(bool is_place_sound);
11740 void SetIsDeploySound(bool is_deploy_sound);
11741}
11742
11743EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
11744{
11745 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
11746 if (entity)
11747 {
11748 bool is_item = entity.IsInherited(ItemBase);
11749 if (is_item && full_quantity)
11750 {
11751 ItemBase item = ItemBase.Cast(entity);
11752 item.SetQuantity(item.GetQuantityInit());
11753 }
11754 }
11755 else
11756 {
11757 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
11758 return NULL;
11759 }
11760 return entity;
11761}
11762
11763void SetupSpawnedItem(ItemBase item, float health, float quantity)
11764{
11765 if (item)
11766 {
11767 if (health > 0)
11768 item.SetHealth("", "", health);
11769
11770 if (item.CanHaveTemperature())
11771 {
11772 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
11773 if (item.CanFreeze())
11774 item.SetFrozen(false);
11775 }
11776
11777 if (item.HasEnergyManager())
11778 {
11779 if (quantity >= 0)
11780 {
11781 item.GetCompEM().SetEnergy0To1(quantity);
11782 }
11783 else
11784 {
11785 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
11786 }
11787 }
11788 else if (item.IsMagazine())
11789 {
11790 Magazine mag = Magazine.Cast(item);
11791 if (quantity >= 0)
11792 {
11793 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
11794 }
11795 else
11796 {
11797 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
11798 }
11799
11800 }
11801 else
11802 {
11803 if (quantity >= 0)
11804 {
11805 item.SetQuantityNormalized(quantity, false);
11806 }
11807 else
11808 {
11809 item.SetQuantity(Math.AbsFloat(quantity));
11810 }
11811
11812 }
11813 }
11814}
11815
11816#ifdef DEVELOPER
11817ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
11818#endif
Param4< int, int, string, int > TSelectableActionInfoWithColor
Определения 3_Game/Entities/EntityAI.c:97
Param3 TSelectableActionInfo
EWetnessLevel
Определения 3_Game/Entities/EntityAI.c:2
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:14
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
int GetLiquidType()
Определения CCTWaterSurface.c:129
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:3868
DayZGame GetDayZGame()
Определения DayZGame.c:3870
EActions
Определения EActions.c:2
ERPCs
Определения ERPCs.c:2
PluginAdminLog m_AdminLog
Определения EmoteManager.c:142
const int MAX
Определения EnConvert.c:27
float GetTemperature()
Определения Environment.c:497
override bool IsExplosive()
Определения ExplosivesBase.c:59
override bool CanHaveTemperature()
Определения FireplaceBase.c:559
class GP5GasMask extends MaskBase ItemBase
Empty
Определения Hand_States.c:14
FindInventoryLocationType
flags for searching locations in inventory
Определения InventoryLocation.c:17
InventoryLocationType
types of Inventory Location
Определения InventoryLocation.c:4
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
bool DamageItemInCargo(float damage)
Определения ItemBase.c:6380
static bool HasDebugActionsMask(int mask)
Определения ItemBase.c:5620
bool HidesSelectionBySlot()
Определения ItemBase.c:9347
float m_VarWetMin
Определения ItemBase.c:4881
void SplitItem(PlayerBase player)
Определения ItemBase.c:6831
void CopyScriptPropertiesFrom(EntityAI oldItem)
Определения ItemBase.c:9568
override void InsertAgent(int agent, float count=1)
Определения ItemBase.c:8795
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:8229
static void SetDebugActionsMask(int mask)
Определения ItemBase.c:5625
void SetIsDeploySound(bool is_deploy_sound)
bool IsOpen()
Определения ItemBase.c:8938
void SplitItemToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6798
override bool IsHeavyBehaviour()
Определения ItemBase.c:9140
override void SetWetMax()
Определения ItemBase.c:8511
bool IsCoverFaceForShave(string slot_name)
DEPRECATED in use, but returns correct values nontheless. Check performed elsewhere.
Определения ItemBase.c:9385
void ClearStartItemSoundServer()
Определения ItemBase.c:9283
float m_VarWet
Определения ItemBase.c:4878
void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9415
map< typename, ref ActionOverrideData > TActionAnimOverrideMap
Определения ItemBase.c:2
override void RemoveAllAgentsExcept(int agent_to_keep)
Определения ItemBase.c:8790
static ref map< int, ref array< ref WeaponParticlesOnBulletCasingEject > > m_OnBulletCasingEjectEffect
Определения ItemBase.c:4941
bool CanBeMovedOverride()
Определения ItemBase.c:7522
override void SetWet(float value, bool allow_client=false)
Определения ItemBase.c:8487
ref TIntArray m_SingleUseActions
Определения ItemBase.c:4927
override void ProcessVariables()
Определения ItemBase.c:9482
ref TStringArray m_HeadHidingSelections
Определения ItemBase.c:4955
float GetWeightSpecialized(bool forceRecalc=false)
Определения ItemBase.c:8321
bool LoadAgents(ParamsReadContext ctx, int version)
Определения ItemBase.c:8856
void UpdateQuickbarShortcutVisibility(PlayerBase player)
To be called on moving item within character's inventory; 'player' should never be null.
Определения ItemBase.c:8701
void OverrideActionAnimation(typename action, int commandUID, int stanceMask=-1, int commandUIDProne=-1)
Определения ItemBase.c:5211
ref array< ref OverheatingParticle > m_OverheatingParticles
Определения ItemBase.c:4953
override float GetTemperatureFreezeThreshold()
Определения ItemBase.c:9518
bool m_IsSoundSynchRemote
Определения ItemBase.c:9676
float m_OverheatingShots
Определения ItemBase.c:4948
void StopItemSoundServer(int id)
Определения ItemBase.c:9271
static void ToggleDebugActionsMask(int mask)
Определения ItemBase.c:5640
void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:5364
override float GetTemperatureFreezeTime()
Определения ItemBase.c:9542
ref array< int > m_CompatibleLocks
Определения ItemBase.c:4965
bool CanBeCooked()
Определения ItemBase.c:7478
override void CombineItemsClient(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:5707
float m_TemperaturePerQuantityWeight
Определения ItemBase.c:4977
bool m_RecipesInitialized
Определения ItemBase.c:4863
void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
Определения ItemBase.c:6471
override float GetTemperatureThawThreshold()
Определения ItemBase.c:9526
override void OnEnergyConsumed()
Определения ItemBase.c:8431
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:8360
override EWetnessLevel GetWetLevel()
Определения ItemBase.c:8551
float GetSingleInventoryItemWeight()
Определения ItemBase.c:8316
ref TIntArray m_InteractActions
Определения ItemBase.c:4929
void MessageToOwnerStatus(string text)
Send message to owner player in grey color.
Определения ItemBase.c:7542
float m_VarQuantity
Определения ItemBase.c:4869
bool CanPlayDeployLoopSound()
Определения ItemBase.c:9687
override float GetWetMax()
Определения ItemBase.c:8521
bool CanBeUsedForSuicide()
Определения ItemBase.c:9654
override void CombineItemsEx(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:7117
void OnItemInHandsPlayerSwimStart(PlayerBase player)
void SetIsHologram(bool is_hologram)
Определения ItemBase.c:5845
void OnSyncVariables(ParamsReadContext ctx)
DEPRECATED (most likely)
Определения ItemBase.c:7696
void StartItemSoundServer(int id)
Определения ItemBase.c:9258
void DoAmmoExplosion()
Определения ItemBase.c:6315
static ref map< int, ref array< ref WeaponParticlesOnFire > > m_OnFireEffect
Определения ItemBase.c:4940
void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6655
int GetItemSize()
Определения ItemBase.c:7507
bool m_CanBeMovedOverride
Определения ItemBase.c:4906
override string ChangeIntoOnAttach(string slot)
Определения ItemBase.c:6239
void UpdateOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5432
bool CanDecay()
Определения ItemBase.c:9457
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:8202
void SetQuantityMax()
Определения ItemBase.c:8207
override float GetQuantity()
Определения ItemBase.c:8296
int m_ColorComponentR
Определения ItemBase.c:4918
int m_ShotsToStartOverheating
Определения ItemBase.c:4950
override void OnWetChanged(float newVal, float oldVal)
Определения ItemBase.c:8536
void StopOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5439
static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9039
void OnOverheatingDecay()
Определения ItemBase.c:5402
float GetDryingIncrement(string pIncrementName)
Определения ItemBase.c:8469
void SoundSynchRemoteReset()
int m_Cleanness
Определения ItemBase.c:4884
bool HasMuzzle()
Returns true if this item has a muzzle (weapons, suppressors)
Определения ItemBase.c:5540
bool UsesGlobalDeploy()
Определения ItemBase.c:9686
int m_ItemBehaviour
Определения ItemBase.c:4899
override bool CanReleaseAttachment(EntityAI attachment)
Определения ItemBase.c:9011
float m_HeatIsolation
Определения ItemBase.c:4894
float m_VarWetInit
Определения ItemBase.c:4880
override void OnMovedInsideCargo(EntityAI container)
Определения ItemBase.c:5885
void SetCEBasedQuantity()
Определения ItemBase.c:5653
bool m_CanPlayImpactSound
Определения ItemBase.c:4890
override string GetAttachmentSoundType()
Определения ItemBase.c:9214
float GetOverheatingCoef()
Определения ItemBase.c:5459
array< string > GetHeadHidingSelection()
Определения ItemBase.c:9342
void PlayAttachSound(string slot_type)
Plays sound on item attach. Be advised, the config structure may slightly change in 1....
Определения ItemBase.c:9294
override bool IsStoreLoad()
Определения ItemBase.c:8563
int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7093
bool IsLightSource()
Определения ItemBase.c:5781
bool m_HasQuantityBar
Определения ItemBase.c:4912
void SetResultOfSplit(bool value)
Определения ItemBase.c:7088
void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6719
void OnAttachmentQuantityChanged(ItemBase item)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6889
void UpdateAllOverheatingParticles()
Определения ItemBase.c:5467
float GetSoakingIncrement(string pIncrementName)
Определения ItemBase.c:8478
static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9119
override float GetStoreLoadedQuantity()
Определения ItemBase.c:8573
int m_LockType
Определения ItemBase.c:4966
const int ITEM_SOUNDS_MAX
Определения ItemBase.c:4971
bool m_CanBeDigged
Определения ItemBase.c:4913
float m_ItemAttachOffset
Определения ItemBase.c:4896
float GetItemModelLength()
Определения ItemBase.c:8580
bool m_ThrowItemOnDrop
Определения ItemBase.c:4904
override bool ReadVarsFromCTX(ParamsReadContext ctx, int version=-1)
Определения ItemBase.c:7841
override void CheckForRoofLimited(float timeTresholdMS=3000)
Roof check for entity, limited by time (anti-spam solution)
Определения ItemBase.c:8871
void Close()
float GetHeatIsolation()
Определения ItemBase.c:8464
void CombineItems(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7122
void TransferModifiers(PlayerBase reciever)
appears to be deprecated, legacy code
float GetTemperaturePerQuantityWeight()
Used in heat comfort calculations only!
Определения ItemBase.c:9513
bool CanHaveWetness()
Определения ItemBase.c:9470
int m_CleannessMin
Определения ItemBase.c:4886
void TransferAgents(int agents)
transfer agents from another item
Определения ItemBase.c:8804
string IDToName(int id)
Определения ItemBase.c:7689
bool CanBeConsumed(ConsumeConditionData data=null)
Items cannot be consumed if frozen by default. Override for exceptions.
Определения ItemBase.c:9477
float GetHeatIsolationInit()
Определения ItemBase.c:8459
void PlayPlaceSound()
void SetCanBeMovedOverride(bool setting)
Определения ItemBase.c:7529
override bool HasQuantity()
Определения ItemBase.c:8291
float m_VarWetPrev
Определения ItemBase.c:4879
int m_SoundSyncStop
Определения ItemBase.c:4973
bool IsCargoException4x3(EntityAI item)
Определения ItemBase.c:9563
ref TIntArray m_ContinuousActions
Определения ItemBase.c:4928
int GetMuzzleID()
Returns global muzzle ID. If not found, then it gets automatically registered.
Определения ItemBase.c:5549
void LoadParticleConfigOnFire(int id)
Определения ItemBase.c:5234
int m_VarLiquidType
Определения ItemBase.c:4898
int m_QuickBarBonus
Определения ItemBase.c:4900
void PreLoadSoundAttachmentType()
Attachment Sound Type getting from config file.
Определения ItemBase.c:9202
override float GetWetInit()
Определения ItemBase.c:8531
int m_ImpactSoundSurfaceHash
Определения ItemBase.c:4892
int m_SoundSyncPlay
Определения ItemBase.c:4972
int m_MaxOverheatingValue
Определения ItemBase.c:4951
void SetupSpawnedItem(ItemBase item, float health, float quantity)
Определения ItemBase.c:4875
bool m_IsTakeable
Определения ItemBase.c:4903
bool ShouldSplitQuantity(float quantity)
Определения ItemBase.c:6428
static ref map< string, int > m_WeaponTypeToID
Определения ItemBase.c:4943
string GetLockSoundSet()
Определения ItemBase.c:8629
string GetColorString()
Returns item's PROCEDURAL color as formated string, i.e. "#(argb,8,8,3)color(0.15,...
Определения ItemBase.c:8660
array< int > GetValidFinishers()
returns an array of possible finishers
Определения ItemBase.c:9590
void OnAttachmentQuantityChangedEx(ItemBase item, float delta)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6895
class ItemBase extends InventoryItem SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
Определения ItemBase.c:4855
ItemSoundHandler GetItemSoundHandler()
Определения ItemBase.c:9229
override int GetQuantityMin()
Определения ItemBase.c:8280
void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
Определения ItemBase.c:6634
override int GetQuickBarBonus()
Определения ItemBase.c:5119
override void SetTakeable(bool pState)
Определения ItemBase.c:9184
float m_OverheatingDecayInterval
Определения ItemBase.c:4952
void SetIsPlaceSound(bool is_place_sound)
override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6448
void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
Определения ItemBase.c:9435
bool CanProcessDecay()
Определения ItemBase.c:9463
void RemoveAudioVisualsOnClient()
Определения Bottle_Base.c:151
void SoundSynchRemote()
static void AddDebugActionsMask(int mask)
Определения ItemBase.c:5630
void PlayDeployLoopSoundEx()
void RemoveLightSourceItem()
Определения ItemBase.c:9579
bool CanRepair(ItemBase item_repair_kit)
Определения ItemBase.c:7493
bool can_this_be_combined
Определения ItemBase.c:4908
EffectSound m_SoundDeploy
Определения ItemBase.c:9673
int m_Count
Определения ItemBase.c:4874
float GetBaitEffectivity()
generic effectivity as a bait for animal catching
Определения ItemBase.c:9626
float GetDeployTime()
how long it takes to deploy this item in seconds
Определения ItemBase.c:9176
override bool IsSplitable()
Определения ItemBase.c:6415
bool DamageItemAttachments(float damage)
Определения ItemBase.c:6399
override void WriteVarsToCTX(ParamsWriteContext ctx)
Определения ItemBase.c:7805
void ConvertEnergyToQuantity()
Определения ItemBase.c:8446
override void RemoveAllAgents()
Определения ItemBase.c:8785
override void SetQuantityToMinimum()
Определения ItemBase.c:8213
bool m_WantPlayImpactSound
Определения ItemBase.c:4889
override float GetTemperatureThawTime()
Определения ItemBase.c:9550
ref map< int, ref array< ref WeaponParticlesOnOverheating > > m_OnOverheatingEffect
Определения ItemBase.c:4942
int m_ColorComponentG
Определения ItemBase.c:4919
float m_StoreLoadedQuantity
Определения ItemBase.c:4876
void MessageToOwnerAction(string text)
Send message to owner player in yellow color.
Определения ItemBase.c:7560
int m_ColorComponentA
Определения ItemBase.c:4921
int m_VarQuantityInit
Определения ItemBase.c:4871
float GetFilterDamageRatio()
Определения ItemBase.c:5534
override void SetLiquidType(int value, bool allow_client=false)
Определения ItemBase.c:8673
void OnQuantityChanged(float delta)
Called on server side when this item's quantity is changed. Call super.OnQuantityChanged(); first whe...
Определения ItemBase.c:6865
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:8220
bool m_HideSelectionsBySlot
Определения ItemBase.c:4956
bool IsOverheatingEffectActive()
Определения ItemBase.c:5397
void SetIsBeingPlaced(bool is_being_placed)
Определения ItemBase.c:5814
int GetLiquidContainerMask()
Определения ItemBase.c:5751
void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
Определения ItemBase.c:7002
ref Timer m_CheckOverheating
Определения ItemBase.c:4949
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:5445
float GetEnergy()
Определения ItemBase.c:8420
bool CanBeDigged()
Определения ItemBase.c:5830
bool GetActionWidgetOverride(out typename name)
If we need a different (handheld)item action widget displayed, the logic goes in here.
Определения ItemBase.c:9596
bool IsNVG()
Определения ItemBase.c:5762
float GetUnitWeight(bool include_wetness=true)
Obsolete, use GetWeightEx instead.
Определения ItemBase.c:8380
void SetZoneDamageCEInit()
Sets zone damages to match randomized global health set by CE (CE spawn only)
Определения ItemBase.c:9372
bool m_IsDeploySound
Определения ItemBase.c:9675
bool CanEat()
Определения ItemBase.c:7453
static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9079
override bool IsOneHandedBehaviour()
Определения ItemBase.c:9150
void AddLightSourceItem(ItemBase lightsource)
Adds a light source child.
Определения ItemBase.c:9574
bool IsLiquidContainer()
Определения ItemBase.c:5746
FoodStage GetFoodStage()
overridden on Edible_Base; so we don't have to parse configs all the time
Определения ItemBase.c:7473
override float GetSingleInventoryItemWeightEx()
Определения ItemBase.c:8307
void SaveAgents(ParamsWriteContext ctx)
Определения ItemBase.c:8863
override int GetTargetQuantityMax(int attSlotID=-1)
Определения ItemBase.c:8261
int m_CleannessInit
Определения ItemBase.c:4885
float GetDisinfectQuantity(int system=0, Param param1=null)
Определения ItemBase.c:5529
override int GetAgents()
Определения ItemBase.c:8810
int m_VarQuantityMax
Определения ItemBase.c:4873
override bool IsHologram()
Определения ItemBase.c:5825
float GetItemAttachOffset()
Определения ItemBase.c:8589
bool IsPlaceSound()
Определения ItemBase.c:9689
static int GetDebugActionsMask()
Определения ItemBase.c:5615
void ProcessDecay(float delta, bool hasRootAsPlayer)
Определения ItemBase.c:9452
override bool IsItemBase()
Определения ItemBase.c:7606
void PlayDeploySound()
override bool IsTwoHandedBehaviour()
Определения ItemBase.c:9160
void ExplodeAmmo()
Определения ItemBase.c:6302
bool IsCombineAll(ItemBase other_item, bool use_stack_max=false)
Определения ItemBase.c:7078
float GetProtectionLevel(int type, bool consider_filter=false, int system=0)
Определения ItemBase.c:8884
static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9059
override void OnEnergyAdded()
Определения ItemBase.c:8438
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:5774
EffectSound m_DeployLoopSoundEx
Определения ItemBase.c:9672
override void DeSerializeNumericalVars(array< float > floats)
Определения ItemBase.c:7746
void StopItemDynamicPhysics()
Определения ItemBase.c:9354
bool HasFoodStage()
Определения ItemBase.c:7466
override void SetStoreLoad(bool value)
Определения ItemBase.c:8558
float GetOverheatingValue()
Определения ItemBase.c:5359
bool ContainsAgent(int agent_id)
Определения ItemBase.c:8763
override void AddWet(float value)
Определения ItemBase.c:8506
bool IsLiquidPresent()
Определения ItemBase.c:5741
bool IsFullQuantity()
Определения ItemBase.c:8301
override void EOnContact(IEntity other, Contact extra)
Определения ItemBase.c:6015
void SplitIntoStackMaxHands(PlayerBase player)
Определения ItemBase.c:6770
void SplitIntoStackMaxHandsClient(PlayerBase player)
Определения ItemBase.c:6746
int m_CleannessMax
Определения ItemBase.c:4887
float m_VarStackMax
Определения ItemBase.c:4875
ref Timer m_PhysDropTimer
Определения ItemBase.c:4962
void MessageToOwnerFriendly(string text)
Send message to owner player in green color.
Определения ItemBase.c:7578
override void SetStoreLoadedQuantity(float value)
Определения ItemBase.c:8568
bool m_IsResultOfSplit string m_SoundAttType
distinguish if item has been created as new or it came from splitting (server only flag)
Определения ItemBase.c:4916
void CheckOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5380
void UnlockFromParent()
Unlocks this item from its attachment slot of its parent.
Определения ItemBase.c:5695
bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
Определения ItemBase.c:7500
void OnLiquidTypeChanged(int oldType, int newType)
Определения ItemBase.c:8694
void StartOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5426
void PlayDeployFinishSound()
bool AllowFoodConsumption()
Определения ItemBase.c:8616
bool m_IsOverheatingEffectActive
Определения ItemBase.c:4947
int m_LiquidContainerMask
Определения ItemBase.c:4897
void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9390
override int GetCleanness()
Определения ItemBase.c:8611
bool PairWithDevice(notnull ItemBase otherDevice)
Определения ItemBase.c:9601
bool IsDeploySound()
Определения ItemBase.c:9690
static void RemoveDebugActionsMask(int mask)
Определения ItemBase.c:5635
static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9099
int m_VarQuantityMin
Определения ItemBase.c:4872
void PerformDamageSystemReinit()
Определения ItemBase.c:9360
override void ClearInventory()
Определения ItemBase.c:8399
static int m_LastRegisteredWeaponID
Определения ItemBase.c:4944
ItemBase GetLightSourceItem()
Определения ItemBase.c:9584
void MessageToOwnerImportant(string text)
Send message to owner player in red color.
Определения ItemBase.c:7596
override float GetItemOverheatThreshold()
Определения ItemBase.c:9534
void StopDeployLoopSoundEx()
bool m_CanThisBeSplit
Определения ItemBase.c:4909
override void SerializeNumericalVars(array< float > floats_out)
Определения ItemBase.c:7710
ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
Определения ItemBase.c:6685
float m_ItemModelLength
Определения ItemBase.c:4895
bool m_IsHologram
Определения ItemBase.c:4902
static int m_DebugActionsMask
Определения ItemBase.c:4862
void KillAllOverheatingParticles()
Определения ItemBase.c:5495
bool CanBeCookedOnStick()
Определения ItemBase.c:7483
override int GetQuantityMax()
Определения ItemBase.c:8248
void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
Определения ItemBase.c:7156
void OnActivatedByTripWire()
bool IsColorSet()
Определения ItemBase.c:8654
override void RemoveAgent(int agent_id)
Определения ItemBase.c:8776
bool m_ItemBeingDroppedPhys
Определения ItemBase.c:4905
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:8966
void PlayDetachSound(string slot_type)
Определения ItemBase.c:9330
static ref map< typename, ref TInputActionMap > m_ItemTypeActionsMap
Определения ItemBase.c:4856
void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9663
override bool IsBeingPlaced()
Определения ItemBase.c:5809
int GetQuantityInit()
Определения ItemBase.c:8285
float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7098
bool IsResultOfSplit()
Определения ItemBase.c:7083
bool m_FixDamageSystemInit
Определения ItemBase.c:4907
float m_ImpactSpeed
Определения ItemBase.c:4891
bool m_IsStoreLoad
Определения ItemBase.c:4910
int GetLiquidTypeInit()
Определения ItemBase.c:8684
string GetDeployFinishSoundset()
ItemBase m_LightSourceItem
Определения ItemBase.c:4925
void LockToParent()
Locks this item in it's current attachment slot of its parent. This makes the "locked" icon visible i...
Определения ItemBase.c:5682
override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6557
int m_AttachedAgents
Определения ItemBase.c:4933
string m_LockSoundSet
Определения ItemBase.c:4968
void LoadParticleConfigOnOverheating(int id)
Определения ItemBase.c:5303
float m_VarQuantityPrev
Определения ItemBase.c:4870
bool IsSoundSynchRemote()
Определения ItemBase.c:9688
bool m_CanShowQuantity
Определения ItemBase.c:4911
override void OnRightClick()
Определения ItemBase.c:6938
int m_ColorComponentB
Определения ItemBase.c:4920
static ref map< typename, ref TActionAnimOverrideMap > m_ItemActionOverrides
Определения ItemBase.c:4858
bool IsActionTargetVisible()
Определения ItemBase.c:9196
override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения ItemBase.c:6050
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Определения ItemBase.c:6339
bool m_IsBeingPlaced
Определения ItemBase.c:4901
int NameToID(string name)
Определения ItemBase.c:7683
void ~ItemBase()
Определения ItemBase.c:5580
override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
Определения ItemBase.c:8546
void ClearStopItemSoundServer()
Определения ItemBase.c:9288
override string ChangeIntoOnDetach()
Определения ItemBase.c:6263
float m_VarWetMax
Определения ItemBase.c:4882
void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6680
int GetLockType()
Определения ItemBase.c:8624
EffectSound m_SoundDeployFinish
Определения ItemBase.c:9670
override float GetWet()
Определения ItemBase.c:8516
EffectSound m_SoundPlace
Определения ItemBase.c:9671
float GetQuantityNormalizedScripted()
Определения ItemBase.c:8234
override void SetCleanness(int value, bool allow_client=false)
Определения ItemBase.c:8598
bool m_IsPlaceSound
Определения ItemBase.c:9674
override float GetWetMin()
Определения ItemBase.c:8526
ref ItemSoundHandler m_ItemSoundHandler
Определения ItemBase.c:4974
override bool KindOf(string tag)
Определения ItemBase.c:7612
void ItemSoundHandler(ItemBase parent)
Определения ItemSoundHandler.c:31
string Type
Определения JsonDataContaminatedArea.c:11
EffectSound m_LockingSound
Определения Land_Underground_Entrance.c:321
string GetDebugText()
Определения ModifierBase.c:71
PlayerBase GetPlayer()
Определения ModifierBase.c:51
@ LOWEST
Определения PPEConstants.c:54
void PluginItemDiagnostic()
Определения PluginItemDiagnostic.c:74
PluginBase GetPlugin(typename plugin_type)
Определения PluginManager.c:316
EntityAI GetItem()
Определения RadialQuickbarMenu.c:37
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
void Debug()
Определения UniversalTemperatureSource.c:349
int GetID()
Определения ActionBase.c:1360
void OnItemLocationChanged(ItemBase item)
Определения ActionBase.c:998
GetInputType()
Определения ActionBase.c:215
int m_StanceMask
Определения ActionBase.c:25
int m_CommandUIDProne
Определения ActionBase.c:24
int m_CommandUID
Определения ActionBase.c:23
void OnItemAttachedAtPlayer(EntityAI item, string slot_name)
Определения AnalyticsManagerClient.c:77
proto native UIManager GetUIManager()
proto bool ConfigGetChildName(string path, int index, out string name)
Get name of subclass in config class on path.
proto native float ConfigGetFloat(string path)
Get float value from config on path.
override ScriptCallQueue GetCallQueue(int call_category)
Определения DayZGame.c:1187
proto native void GizmoSelectObject(Object object)
proto native bool ConfigIsExisting(string path)
proto native void ConfigGetTextArray(string path, out TStringArray values)
Get array of strings from config on path.
proto native DayZPlayer GetPlayer()
proto native void GizmoSelectPhysics(Physics physics)
proto int GetTime()
returns mission time in milliseconds
proto native int ConfigGetType(string path)
Returns type of config value.
AnalyticsManagerClient GetAnalyticsClient()
Определения Global/game.c:1568
proto native int ConfigGetChildrenCount(string path)
Get count of subclasses in config class on path.
proto native SoundOnVehicle CreateSoundOnObject(Object source, string sound_name, float distance, bool looped, bool create_local=false)
proto native void ObjectDelete(Object obj)
proto native int GetItemCount()
proto native EntityAI GetItem(int index)
float GetEnergyAtSpawn()
Определения ComponentEnergyManager.c:1280
void SetEnergy0To1(float energy01)
Energy manager: Sets stored energy for this device between 0 and MAX based on relative input value be...
Определения ComponentEnergyManager.c:541
float GetEnergyMaxPristine()
Energy manager: Returns the maximum amount of energy this device can store. It's damage is NOT taken ...
Определения ComponentEnergyManager.c:1275
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/Entities/Man.c:44
proto native bool EnumerateInventory(InventoryTraversalType tt, out array< EntityAI > items)
enumerate inventory using traversal type and filling items array
proto native CargoBase GetCargo()
cargo
Определения ItemBase.c:15
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:469
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:29
override bool CanDisplayCargo()
Определения UndergroundStash.c:24
override void OnInventoryEnter(Man player)
Определения BarbedWire.c:203
override string GetFoldSoundset()
Определения BaseBuildingBase.c:108
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:6
override bool CanReceiveItemIntoCargo(EntityAI item)
Определения TentBase.c:913
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 void SetActions()
override string GetLoopFoldSoundset()
Определения BaseBuildingBase.c:113
override bool CanMakeGardenplot()
Определения FieldShovel.c:3
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
Определения PowerGenerator.c:412
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:424
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 IsClothing()
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
Определения 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 void Remove(func fn)
remove specific call from queue
proto void CallLater(func fn, int delay=0, bool repeat=false, 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)
adds call into the queue with given parameters and arguments (arguments are held in memory until the ...
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:64
proto native float GetDamage(string zoneName, string healthType)
UIScriptedMenu FindMenu(int id)
Returns menu with specific ID if it is open (see MenuID)
Определения UIManager.c:160
override void Refresh()
Определения ChatInputMenu.c:70
void SetCalcDetails(string details)
Определения 3_Game/tools/Debug.c:816
void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения WrittenNoteData.c:13
const float LOWEST
Определения EnConvert.c:100
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
proto native CGame GetGame()
Serializer ParamsWriteContext
Определения gameplay.c:16
const int DEF_BIOLOGICAL
Определения 3_Game/constants.c:512
const int DEF_CHEMICAL
Определения 3_Game/constants.c:513
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:709
array< int > TIntArray
Определения EnScript.c:711
EntityEvent
Entity events for event-mask, or throwing event from code.
Определения EnEntity.c:45
static const float ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE
Определения 3_Game/constants.c:808
const int VARIABLE_LIQUIDTYPE
Определения 3_Game/constants.c:632
const int VARIABLE_CLEANNESS
Определения 3_Game/constants.c:635
const int VARIABLE_COLOR
Определения 3_Game/constants.c:634
const int VARIABLE_TEMPERATURE
Определения 3_Game/constants.c:630
const int VARIABLE_QUANTITY
Определения 3_Game/constants.c:628
const int VARIABLE_WET
Определения 3_Game/constants.c:631
const int LIQUID_NONE
Определения 3_Game/constants.c:529
static proto float AbsFloat(float f)
Returns absolute value.
const int MENU_INVENTORY
Определения 3_Game/constants.c:180
proto native bool dBodyIsDynamic(notnull IEntity ent)
const int SAT_CRAFTING
Определения 3_Game/constants.c:453
const int SAT_DEBUG_ACTION
Определения 3_Game/constants.c:454
class JsonUndergroundAreaTriggerData GetPosition
Определения UndergroundAreaLoader.c:9
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/tools/tools.c:10
const int CALL_CATEGORY_SYSTEM
Определения 3_Game/tools/tools.c:8
proto native int GetColor()

Используется в InventoryItem::OnAttachmentQuantityChangedEx().