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

◆ OnAttachmentQuantityChanged()

void SpawnItemOnLocation::OnAttachmentQuantityChanged ( ItemBase item)
protected

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

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

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

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