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

◆ OnAttachmentQuantityChangedEx()

void SpawnItemOnLocation::OnAttachmentQuantityChangedEx ( ItemBase item,
float delta )
protected

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

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

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