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

◆ OnAttachmentQuantityChangedEx()

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

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

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

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