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

◆ OnQuantityChanged()

void SpawnItemOnLocation::OnQuantityChanged ( float delta)
protected

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

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

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

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