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

◆ SetActions()

void SpawnItemOnLocation::SetActions ( )
private

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

5212{
5213 override bool CanPutAsAttachment(EntityAI parent)
5214 {
5215 return true;
5216 }
5217};
5218
5220{
5221
5222};
5223
5224//const bool QUANTITY_DEBUG_REMOVE_ME = false;
5225
5226class ItemBase extends InventoryItem
5227{
5231
5233
5234 static int m_DebugActionsMask;
5236 // ============================================
5237 // Variable Manipulation System
5238 // ============================================
5239 // Quantity
5240
5241 float m_VarQuantity;
5242 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
5244 int m_VarQuantityMin;
5245 int m_VarQuantityMax;
5246 int m_Count;
5247 float m_VarStackMax;
5248 float m_StoreLoadedQuantity = float.LOWEST;
5249 // Wet
5250 float m_VarWet;
5251 float m_VarWetPrev;//for client to know wetness changed during synchronization
5252 float m_VarWetInit;
5253 float m_VarWetMin;
5254 float m_VarWetMax;
5255 // Cleanness
5256 int m_Cleanness;
5257 int m_CleannessInit;
5258 int m_CleannessMin;
5259 int m_CleannessMax;
5260 // impact sounds
5262 bool m_CanPlayImpactSound = true;
5263 float m_ImpactSpeed;
5265 //
5266 float m_HeatIsolation;
5267 float m_ItemModelLength;
5268 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
5270 int m_VarLiquidType;
5271 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
5272 int m_QuickBarBonus;
5273 bool m_IsBeingPlaced;
5274 bool m_IsHologram;
5275 bool m_IsTakeable;
5276 bool m_ThrowItemOnDrop;
5279 bool m_FixDamageSystemInit = false; //can be changed on storage version check
5280 bool can_this_be_combined; //Check if item can be combined
5281 bool m_CanThisBeSplit; //Check if item can be split
5282 bool m_IsStoreLoad = false;
5283 bool m_CanShowQuantity;
5284 bool m_HasQuantityBar;
5285 protected bool m_CanBeDigged;
5286 protected bool m_IsResultOfSplit
5287
5288 string m_SoundAttType;
5289 // items color variables
5294 //-------------------------------------------------------
5295
5296 // light source managing
5298
5302
5303 //==============================================
5304 // agent system
5305 private int m_AttachedAgents;
5306
5308 void TransferModifiers(PlayerBase reciever);
5309
5310
5311 // Weapons & suppressors particle effects
5315 ref static map<string, int> m_WeaponTypeToID;
5316 static int m_LastRegisteredWeaponID = 0;
5317
5318 // Overheating effects
5320 float m_OverheatingShots;
5321 ref Timer m_CheckOverheating;
5322 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
5323 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
5324 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
5325 ref array <ref OverheatingParticle> m_OverheatingParticles;
5326
5328 protected bool m_HideSelectionsBySlot;
5329
5330 // Admin Log
5331 PluginAdminLog m_AdminLog;
5332
5333 // misc
5334 ref Timer m_PhysDropTimer;
5335
5336 // Attachment Locking variables
5337 ref array<int> m_CompatibleLocks;
5338 protected int m_LockType;
5339 protected ref EffectSound m_LockingSound;
5340 protected string m_LockSoundSet;
5341
5342 // ItemSoundHandler variables
5343 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
5344 protected int m_SoundSyncPlay; // id for sound to play
5345 protected int m_SoundSyncStop; // id for sound to stop
5346 protected int m_SoundSyncSlotID = InventorySlots.INVALID; // slot id for attach/detach sound based on slot
5347
5349
5350 //temperature
5351 private float m_TemperaturePerQuantityWeight;
5352
5353 // -------------------------------------------------------------------------
5354 void ItemBase()
5355 {
5356 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
5360
5361 if (!g_Game.IsDedicatedServer())
5362 {
5363 if (HasMuzzle())
5364 {
5366
5368 {
5370 }
5371 }
5372
5374 m_ActionsInitialize = false;
5375 }
5376
5377 m_OldLocation = null;
5378
5379 if (g_Game.IsServer())
5380 {
5381 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
5382 }
5383
5384 if (ConfigIsExisting("headSelectionsToHide"))
5385 {
5387 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
5388 }
5389
5390 m_HideSelectionsBySlot = false;
5391 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
5392 {
5393 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
5394 }
5395
5396 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
5397
5398 m_IsResultOfSplit = false;
5399
5401 }
5402
5403 override void InitItemVariables()
5404 {
5405 super.InitItemVariables();
5406
5407 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
5408 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
5409 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
5410 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
5411 m_VarStackMax = ConfigGetFloat("varStackMax");
5412 m_Count = ConfigGetInt("count");
5413
5414 m_CanShowQuantity = ConfigGetBool("quantityShow");
5415 m_HasQuantityBar = ConfigGetBool("quantityBar");
5416
5417 m_CleannessInit = ConfigGetInt("varCleannessInit");
5419 m_CleannessMin = ConfigGetInt("varCleannessMin");
5420 m_CleannessMax = ConfigGetInt("varCleannessMax");
5421
5422 m_WantPlayImpactSound = false;
5423 m_ImpactSpeed = 0.0;
5424
5425 m_VarWetInit = ConfigGetFloat("varWetInit");
5427 m_VarWetMin = ConfigGetFloat("varWetMin");
5428 m_VarWetMax = ConfigGetFloat("varWetMax");
5429
5430 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
5431 if (IsLiquidContainer() && GetQuantity() != 0)
5433 m_IsBeingPlaced = false;
5434 m_IsHologram = false;
5435 m_IsTakeable = true;
5436 m_CanBeMovedOverride = false;
5440 m_CanBeDigged = ConfigGetBool("canBeDigged");
5441
5442 m_CompatibleLocks = new array<int>();
5443 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
5444 m_LockType = ConfigGetInt("lockType");
5445
5446 //Define if item can be split and set ability to be combined accordingly
5447 m_CanThisBeSplit = false;
5448 can_this_be_combined = false;
5449 if (ConfigIsExisting("canBeSplit"))
5450 {
5451 can_this_be_combined = ConfigGetBool("canBeSplit");
5453 }
5454
5455 m_ItemBehaviour = -1;
5456 if (ConfigIsExisting("itemBehaviour"))
5457 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
5458
5459 //RegisterNetSyncVariableInt("m_VariablesMask");
5460 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
5461 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
5462 RegisterNetSyncVariableInt("m_VarLiquidType");
5463 RegisterNetSyncVariableInt("m_Cleanness",0,1);
5464
5465 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
5466 RegisterNetSyncVariableFloat("m_ImpactSpeed");
5467 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
5468
5469 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
5470 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
5471 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
5472 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
5473
5474 RegisterNetSyncVariableBool("m_IsBeingPlaced");
5475 RegisterNetSyncVariableBool("m_IsTakeable");
5476 RegisterNetSyncVariableBool("m_IsHologram");
5477
5480 {
5481 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
5482 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
5483 RegisterNetSyncVariableInt("m_SoundSyncSlotID", int.MIN, int.MAX);
5484 }
5485
5486 m_LockSoundSet = ConfigGetString("lockSoundSet");
5487
5489 if (ConfigIsExisting("temperaturePerQuantityWeight"))
5490 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
5491
5492 m_SoundSyncSlotID = -1;
5493 }
5494
5495 override int GetQuickBarBonus()
5496 {
5497 return m_QuickBarBonus;
5498 }
5499
5500 void InitializeActions()
5501 {
5503 if (!m_InputActionMap)
5504 {
5506 m_InputActionMap = iam;
5507 SetActions();
5509 }
5510 }
5511
5512 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
5513 {
5515 {
5516 m_ActionsInitialize = true;
5518 }
5519
5520 actions = m_InputActionMap.Get(action_input_type);
5521 }
5522
5523 void SetActions()
5524 {
5525 AddAction(ActionTakeItem);
5526 AddAction(ActionTakeItemToHands);
5527 AddAction(ActionWorldCraft);
5529 AddAction(ActionAttachWithSwitch);
5530 }
5531
5532 void SetActionAnimOverrides(); // Override action animation for specific item
5533
5534 void AddAction(typename actionName)
5535 {
5536 ActionBase action = ActionManagerBase.GetAction(actionName);
5537
5538 if (!action)
5539 {
5540 Debug.LogError("Action " + actionName + " dosn't exist!");
5541 return;
5542 }
5543
5544 typename ai = action.GetInputType();
5545 if (!ai)
5546 {
5547 m_ActionsInitialize = false;
5548 return;
5549 }
5550
5551 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
5552 if (!action_array)
5553 {
5554 action_array = new array<ActionBase_Basic>;
5555 m_InputActionMap.Insert(ai, action_array);
5556 }
5557 if (LogManager.IsActionLogEnable())
5558 {
5559 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
5560 }
5561
5562 if (action_array.Find(action) != -1)
5563 {
5564 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
5565 }
5566 else
5567 {
5568 action_array.Insert(action);
5569 }
5570 }
5571
5572 void RemoveAction(typename actionName)
5573 {
5574 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
5575 ActionBase action = player.GetActionManager().GetAction(actionName);
5576 typename ai = action.GetInputType();
5577 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
5578
5579 if (action_array)
5580 {
5581 action_array.RemoveItem(action);
5582 }
5583 }
5584
5585 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
5586 // Set -1 for params which should stay in default state
5587 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
5588 {
5589 ActionOverrideData overrideData = new ActionOverrideData();
5590 overrideData.m_CommandUID = commandUID;
5591 overrideData.m_CommandUIDProne = commandUIDProne;
5592 overrideData.m_StanceMask = stanceMask;
5593
5594 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
5595 if (!actionMap) // create new map of action > overidables map
5596 {
5597 actionMap = new TActionAnimOverrideMap();
5598 m_ItemActionOverrides.Insert(action, actionMap);
5599 }
5600
5601 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
5602
5603 }
5604
5605 void OnItemInHandsPlayerSwimStart(PlayerBase player);
5606
5607 ScriptedLightBase GetLight();
5608
5609 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
5610 void LoadParticleConfigOnFire(int id)
5611 {
5612 if (!m_OnFireEffect)
5614
5617
5618 string config_to_search = "CfgVehicles";
5619 string muzzle_owner_config;
5620
5621 if (!m_OnFireEffect.Contains(id))
5622 {
5623 if (IsInherited(Weapon))
5624 config_to_search = "CfgWeapons";
5625
5626 muzzle_owner_config = config_to_search + " " + GetType() + " ";
5627
5628 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
5629
5630 int config_OnFire_subclass_count = g_Game.ConfigGetChildrenCount(config_OnFire_class);
5631
5632 if (config_OnFire_subclass_count > 0)
5633 {
5634 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
5635
5636 for (int i = 0; i < config_OnFire_subclass_count; i++)
5637 {
5638 string particle_class = "";
5639 g_Game.ConfigGetChildName(config_OnFire_class, i, particle_class);
5640 string config_OnFire_entry = config_OnFire_class + particle_class;
5641 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
5642 WPOF_array.Insert(WPOF);
5643 }
5644
5645
5646 m_OnFireEffect.Insert(id, WPOF_array);
5647 }
5648 }
5649
5650 if (!m_OnBulletCasingEjectEffect.Contains(id))
5651 {
5652 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
5653 muzzle_owner_config = config_to_search + " " + GetType() + " ";
5654
5655 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
5656
5657 int config_OnBulletCasingEject_count = g_Game.ConfigGetChildrenCount(config_OnBulletCasingEject_class);
5658
5659 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
5660 {
5661 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
5662
5663 for (i = 0; i < config_OnBulletCasingEject_count; i++)
5664 {
5665 string particle_class2 = "";
5666 g_Game.ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
5667 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
5668 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
5669 WPOBE_array.Insert(WPOBE);
5670 }
5671
5672
5673 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
5674 }
5675 }
5676 }
5677
5678 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
5680 {
5683
5684 if (!m_OnOverheatingEffect.Contains(id))
5685 {
5686 string config_to_search = "CfgVehicles";
5687
5688 if (IsInherited(Weapon))
5689 config_to_search = "CfgWeapons";
5690
5691 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
5692 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
5693
5694 if (g_Game.ConfigIsExisting(config_OnOverheating_class))
5695 {
5696
5697 m_ShotsToStartOverheating = g_Game.ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
5698
5700 {
5701 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
5702 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
5703 Error(error);
5704 return;
5705 }
5706
5707 m_OverheatingDecayInterval = g_Game.ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
5708 m_MaxOverheatingValue = g_Game.ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
5709
5710
5711
5712 int config_OnOverheating_subclass_count = g_Game.ConfigGetChildrenCount(config_OnOverheating_class);
5713 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
5714
5715 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
5716 {
5717 string particle_class = "";
5718 g_Game.ConfigGetChildName(config_OnOverheating_class, i, particle_class);
5719 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
5720 int entry_type = g_Game.ConfigGetType(config_OnOverheating_entry);
5721
5722 if (entry_type == CT_CLASS)
5723 {
5724 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
5725 WPOOH_array.Insert(WPOF);
5726 }
5727 }
5728
5729
5730 m_OnOverheatingEffect.Insert(id, WPOOH_array);
5731 }
5732 }
5733 }
5734
5735 float GetOverheatingValue()
5736 {
5737 return m_OverheatingShots;
5738 }
5739
5740 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
5741 {
5742 if (m_MaxOverheatingValue > 0)
5743 {
5745
5746 if (!m_CheckOverheating)
5748
5750 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
5751
5752 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
5753 }
5754 }
5755
5756 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
5757 {
5759 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
5760
5762 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
5763
5765 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
5766
5768 {
5770 }
5771 }
5772
5774 {
5776 }
5777
5778 void OnOverheatingDecay()
5779 {
5780 if (m_MaxOverheatingValue > 0)
5781 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
5782 else
5784
5785 if (m_OverheatingShots <= 0)
5786 {
5789 }
5790 else
5791 {
5792 if (!m_CheckOverheating)
5794
5796 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
5797 }
5798
5799 CheckOverheating(this, "", this);
5800 }
5801
5802 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
5803 {
5805 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
5806 }
5807
5808 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
5809 {
5811 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
5813 }
5814
5815 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
5816 {
5818 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
5819 }
5820
5821 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
5822 {
5824 m_OverheatingParticles = new array<ref OverheatingParticle>;
5825
5826 OverheatingParticle OP = new OverheatingParticle();
5827 OP.RegisterParticle(p);
5828 OP.SetOverheatingLimitMin(min_heat_coef);
5829 OP.SetOverheatingLimitMax(max_heat_coef);
5830 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
5831
5832 m_OverheatingParticles.Insert(OP);
5833 }
5834
5835 float GetOverheatingCoef()
5836 {
5837 if (m_MaxOverheatingValue > 0)
5839
5840 return -1;
5841 }
5842
5844 {
5846 {
5847 float overheat_coef = GetOverheatingCoef();
5848 int count = m_OverheatingParticles.Count();
5849
5850 for (int i = count; i > 0; --i)
5851 {
5852 int id = i - 1;
5853 OverheatingParticle OP = m_OverheatingParticles.Get(id);
5854 Particle p = OP.GetParticle();
5855
5856 float overheat_min = OP.GetOverheatingLimitMin();
5857 float overheat_max = OP.GetOverheatingLimitMax();
5858
5859 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
5860 {
5861 if (p)
5862 {
5863 p.Stop();
5864 OP.RegisterParticle(null);
5865 }
5866 }
5867 }
5868 }
5869 }
5870
5872 {
5874 {
5875 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
5876 {
5877 int id = i - 1;
5878 OverheatingParticle OP = m_OverheatingParticles.Get(id);
5879
5880 if (OP)
5881 {
5882 Particle p = OP.GetParticle();
5883
5884 if (p)
5885 {
5886 p.Stop();
5887 }
5888
5889 delete OP;
5890 }
5891 }
5892
5893 m_OverheatingParticles.Clear();
5895 }
5896 }
5897
5899 float GetInfectionChance(int system = 0, Param param = null)
5900 {
5901 return 0.0;
5902 }
5903
5904
5905 float GetDisinfectQuantity(int system = 0, Param param1 = null)
5906 {
5907 return 250;//default value
5908 }
5909
5910 float GetFilterDamageRatio()
5911 {
5912 return 0;
5913 }
5914
5916 bool HasMuzzle()
5917 {
5918 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
5919 return true;
5920
5921 return false;
5922 }
5923
5925 int GetMuzzleID()
5926 {
5927 if (!m_WeaponTypeToID)
5928 m_WeaponTypeToID = new map<string, int>;
5929
5930 if (m_WeaponTypeToID.Contains(GetType()))
5931 {
5932 return m_WeaponTypeToID.Get(GetType());
5933 }
5934 else
5935 {
5936 // Register new weapon ID
5938 }
5939
5941 }
5942
5949 {
5950 return -1;
5951 }
5952
5953
5954
5955 // -------------------------------------------------------------------------
5956 void ~ItemBase()
5957 {
5958 if (g_Game && g_Game.GetPlayer() && (!g_Game.IsDedicatedServer()))
5959 {
5960 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
5961 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
5962
5963 if (r_index >= 0)
5964 {
5965 InventoryLocation r_il = new InventoryLocation;
5966 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
5967
5968 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
5969 int r_type = r_il.GetType();
5970 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
5971 {
5972 r_il.GetParent().GetOnReleaseLock().Invoke(this);
5973 }
5974 else if (r_type == InventoryLocationType.ATTACHMENT)
5975 {
5976 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
5977 }
5978
5979 }
5980
5981 player.GetHumanInventory().ClearUserReservedLocation(this);
5982 }
5983
5984 if (m_LockingSound)
5985 SEffectManager.DestroyEffect(m_LockingSound);
5986 }
5987
5988
5989
5990 // -------------------------------------------------------------------------
5991 static int GetDebugActionsMask()
5992 {
5993 return ItemBase.m_DebugActionsMask;
5994 }
5995
5996 static bool HasDebugActionsMask(int mask)
5997 {
5998 return ItemBase.m_DebugActionsMask & mask;
5999 }
6000
6001 static void SetDebugActionsMask(int mask)
6002 {
6003 ItemBase.m_DebugActionsMask = mask;
6004 }
6005
6006 static void AddDebugActionsMask(int mask)
6007 {
6008 ItemBase.m_DebugActionsMask |= mask;
6009 }
6010
6011 static void RemoveDebugActionsMask(int mask)
6012 {
6013 ItemBase.m_DebugActionsMask &= ~mask;
6014 }
6015
6016 static void ToggleDebugActionsMask(int mask)
6017 {
6018 if (HasDebugActionsMask(mask))
6019 {
6021 }
6022 else
6023 {
6024 AddDebugActionsMask(mask);
6025 }
6026 }
6027
6028 // -------------------------------------------------------------------------
6029 void SetCEBasedQuantity()
6030 {
6031 if (GetEconomyProfile())
6032 {
6033 float q_max = GetEconomyProfile().GetQuantityMax();
6034 if (q_max > 0)
6035 {
6036 float q_min = GetEconomyProfile().GetQuantityMin();
6037 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
6038
6039 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
6040 {
6041 ComponentEnergyManager comp = GetCompEM();
6042 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
6043 {
6044 comp.SetEnergy0To1(quantity_randomized);
6045 }
6046 }
6047 else if (HasQuantity())
6048 {
6049 SetQuantityNormalized(quantity_randomized, false);
6050 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
6051 }
6052
6053 }
6054 }
6055 }
6056
6058 void LockToParent()
6059 {
6060 EntityAI parent = GetHierarchyParent();
6061
6062 if (parent)
6063 {
6064 InventoryLocation inventory_location_to_lock = new InventoryLocation;
6065 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
6066 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
6067 }
6068 }
6069
6071 void UnlockFromParent()
6072 {
6073 EntityAI parent = GetHierarchyParent();
6074
6075 if (parent)
6076 {
6077 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
6078 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
6079 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
6080 }
6081 }
6082
6083 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
6084 {
6085 /*
6086 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
6087 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, g_Game.GetPlayer());
6088 */
6089 ItemBase item2 = ItemBase.Cast(entity2);
6090
6091 if (g_Game.IsClient())
6092 {
6093 if (ScriptInputUserData.CanStoreInputUserData())
6094 {
6095 ScriptInputUserData ctx = new ScriptInputUserData;
6097 ctx.Write(-1);
6098 ItemBase i1 = this; // @NOTE: workaround for correct serialization
6099 ctx.Write(i1);
6100 ctx.Write(item2);
6101 ctx.Write(use_stack_max);
6102 ctx.Write(-1);
6103 ctx.Send();
6104
6105 if (IsCombineAll(item2, use_stack_max))
6106 {
6107 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
6108 }
6109 }
6110 }
6111 else if (!g_Game.IsMultiplayer())
6112 {
6113 CombineItems(item2, use_stack_max);
6114 }
6115 }
6116
6117 bool IsLiquidPresent()
6118 {
6119 return (GetLiquidType() != 0 && HasQuantity());
6120 }
6121
6122 bool IsLiquidContainer()
6123 {
6124 return m_LiquidContainerMask != 0;
6125 }
6126
6128 {
6129 return m_LiquidContainerMask;
6130 }
6131
6132 bool IsBloodContainer()
6133 {
6134 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
6135 return false;
6136 }
6137
6138 bool IsNVG()
6139 {
6140 return false;
6141 }
6142
6145 bool IsExplosive()
6146 {
6147 return false;
6148 }
6149
6151 {
6152 return "";
6153 }
6154
6156
6157 bool IsLightSource()
6158 {
6159 return false;
6160 }
6161
6163 {
6164 return true;
6165 }
6166
6167 //--- ACTION CONDITIONS
6168 //direction
6169 bool IsFacingPlayer(PlayerBase player, string selection)
6170 {
6171 return true;
6172 }
6173
6174 bool IsPlayerInside(PlayerBase player, string selection)
6175 {
6176 return true;
6177 }
6178
6179 override bool CanObstruct()
6180 {
6181 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
6182 return !player || !IsPlayerInside(player, "");
6183 }
6184
6185 override bool IsBeingPlaced()
6186 {
6187 return m_IsBeingPlaced;
6188 }
6189
6190 void SetIsBeingPlaced(bool is_being_placed)
6191 {
6192 m_IsBeingPlaced = is_being_placed;
6193 if (!is_being_placed)
6195 SetSynchDirty();
6196 }
6197
6198 //server-side
6199 void OnEndPlacement() {}
6200
6201 override bool IsHologram()
6202 {
6203 return m_IsHologram;
6204 }
6205
6206 bool CanBeDigged()
6207 {
6208 return m_CanBeDigged;
6209 }
6210
6212 {
6213 return 1;
6214 }
6215
6216 bool CanMakeGardenplot()
6217 {
6218 return false;
6219 }
6220
6221 void SetIsHologram(bool is_hologram)
6222 {
6223 m_IsHologram = is_hologram;
6224 SetSynchDirty();
6225 }
6226 /*
6227 protected float GetNutritionalEnergy()
6228 {
6229 Edible_Base edible = Edible_Base.Cast(this);
6230 return edible.GetFoodEnergy();
6231 }
6232
6233 protected float GetNutritionalWaterContent()
6234 {
6235 Edible_Base edible = Edible_Base.Cast(this);
6236 return edible.GetFoodWater();
6237 }
6238
6239 protected float GetNutritionalIndex()
6240 {
6241 Edible_Base edible = Edible_Base.Cast(this);
6242 return edible.GetFoodNutritionalIndex();
6243 }
6244
6245 protected float GetNutritionalFullnessIndex()
6246 {
6247 Edible_Base edible = Edible_Base.Cast(this);
6248 return edible.GetFoodTotalVolume();
6249 }
6250
6251 protected float GetNutritionalToxicity()
6252 {
6253 Edible_Base edible = Edible_Base.Cast(this);
6254 return edible.GetFoodToxicity();
6255
6256 }
6257 */
6258
6259
6260 // -------------------------------------------------------------------------
6261 override void OnMovedInsideCargo(EntityAI container)
6262 {
6263 super.OnMovedInsideCargo(container);
6264
6265 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
6266 }
6267
6268 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
6269 {
6270 super.EEItemLocationChanged(oldLoc, newLoc);
6271
6272 PlayerBase newPlayer = null;
6273 PlayerBase oldPlayer = null;
6274
6275 if (newLoc.GetParent())
6276 newPlayer = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
6277
6278 if (oldLoc.GetParent())
6279 oldPlayer = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
6280
6281 if (oldPlayer && oldLoc.GetType() == InventoryLocationType.HANDS)
6282 {
6283 int rIndex = oldPlayer.GetHumanInventory().FindUserReservedLocationIndex(this);
6284
6285 if (rIndex >= 0)
6286 {
6287 InventoryLocation rIl = new InventoryLocation;
6288 oldPlayer.GetHumanInventory().GetUserReservedLocation(rIndex, rIl);
6289
6290 oldPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(rIndex);
6291 int rType = rIl.GetType();
6292 if (rType == InventoryLocationType.CARGO || rType == InventoryLocationType.PROXYCARGO)
6293 {
6294 rIl.GetParent().GetOnReleaseLock().Invoke(this);
6295 }
6296 else if (rType == InventoryLocationType.ATTACHMENT)
6297 {
6298 rIl.GetParent().GetOnAttachmentReleaseLock().Invoke(this, rIl.GetSlot());
6299 }
6300
6301 }
6302 }
6303
6304 if (newLoc.GetType() == InventoryLocationType.HANDS && oldLoc.GetType() != InventoryLocationType.TEMP)
6305 {
6306 if (newPlayer)
6307 newPlayer.ForceStandUpForHeavyItems(newLoc.GetItem());
6308
6309 if (newPlayer == oldPlayer)
6310 {
6311 if (oldLoc.GetParent() && newPlayer.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
6312 {
6313 if (oldLoc.GetType() == InventoryLocationType.CARGO)
6314 {
6315 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
6316 {
6317 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
6318 }
6319 }
6320 else
6321 {
6322 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
6323 }
6324 }
6325
6326 if (newPlayer.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
6327 {
6328 int type = oldLoc.GetType();
6329 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
6330 {
6331 oldLoc.GetParent().GetOnSetLock().Invoke(this);
6332 }
6333 else if (type == InventoryLocationType.ATTACHMENT)
6334 {
6335 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
6336 }
6337 }
6338 if (!m_OldLocation)
6339 {
6340 m_OldLocation = new InventoryLocation;
6341 }
6342 m_OldLocation.Copy(oldLoc);
6343 }
6344 else
6345 {
6346 if (m_OldLocation)
6347 {
6348 m_OldLocation.Reset();
6349 }
6350 }
6351
6352 g_Game.GetAnalyticsClient().OnItemAttachedAtPlayer(this,"Hands");
6353 }
6354 else
6355 {
6356 if (newPlayer)
6357 {
6358 int resIndex = newPlayer.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
6359 if (resIndex >= 0)
6360 {
6361 InventoryLocation il = new InventoryLocation;
6362 newPlayer.GetHumanInventory().GetUserReservedLocation(resIndex, il);
6363 ItemBase it = ItemBase.Cast(il.GetItem());
6364 newPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(resIndex);
6365 int rel_type = il.GetType();
6366 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
6367 {
6368 il.GetParent().GetOnReleaseLock().Invoke(it);
6369 }
6370 else if (rel_type == InventoryLocationType.ATTACHMENT)
6371 {
6372 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
6373 }
6374 //it.GetOnReleaseLock().Invoke(it);
6375 }
6376 }
6377 else if (oldPlayer && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
6378 {
6379 //ThrowPhysically(oldPlayer, vector.Zero);
6380 m_ThrowItemOnDrop = false;
6381 }
6382
6383 if (m_OldLocation)
6384 {
6385 m_OldLocation.Reset();
6386 }
6387 }
6388
6389 if (oldLoc.GetType() == InventoryLocationType.TEMP)
6390 {
6391 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Remove(oldLoc.GetItem());
6392 }
6393
6394 if (newLoc.GetType() == InventoryLocationType.TEMP)
6395 {
6396 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Add(oldLoc.GetItem());
6397 }
6398 }
6399
6400 override void EOnContact(IEntity other, Contact extra)
6401 {
6403 {
6404 int liquidType = -1;
6405 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
6406 if (impactSpeed > 0.0)
6407 {
6408 m_ImpactSpeed = impactSpeed;
6409 #ifndef SERVER
6410 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
6411 #else
6412 m_WantPlayImpactSound = true;
6413 SetSynchDirty();
6414 #endif
6415 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
6416 }
6417 }
6418
6419 #ifdef SERVER
6420 if (GetCompEM() && GetCompEM().IsPlugged())
6421 {
6422 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
6423 GetCompEM().UnplugThis();
6424 }
6425 #endif
6426 }
6427
6428 void RefreshPhysics();
6429
6430 override void OnCreatePhysics()
6431 {
6433 }
6434
6435 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
6436 {
6437
6438 }
6439 // -------------------------------------------------------------------------
6440 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
6441 {
6442 super.OnItemLocationChanged(old_owner, new_owner);
6443
6444 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
6445 PlayerBase playerNew = PlayerBase.Cast(new_owner);
6446
6447 if (!relatedPlayer && playerNew)
6448 relatedPlayer = playerNew;
6449
6450 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
6451 {
6452 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
6453 if (actionMgr)
6454 {
6455 ActionBase currentAction = actionMgr.GetRunningAction();
6456 if (currentAction)
6457 currentAction.OnItemLocationChanged(this);
6458 }
6459 }
6460
6461 Man ownerPlayerOld = null;
6462 Man ownerPlayerNew = null;
6463
6464 if (old_owner)
6465 {
6466 if (old_owner.IsMan())
6467 {
6468 ownerPlayerOld = Man.Cast(old_owner);
6469 }
6470 else
6471 {
6472 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
6473 }
6474 }
6475 else
6476 {
6477 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
6478 {
6479 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
6480
6481 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
6482 {
6483 GetCompEM().UnplugThis();
6484 }
6485 }
6486 }
6487
6488 if (new_owner)
6489 {
6490 if (new_owner.IsMan())
6491 {
6492 ownerPlayerNew = Man.Cast(new_owner);
6493 }
6494 else
6495 {
6496 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
6497 }
6498 }
6499
6500 if (ownerPlayerOld != ownerPlayerNew)
6501 {
6502 if (ownerPlayerOld)
6503 {
6504 array<EntityAI> subItemsExit = new array<EntityAI>;
6505 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
6506 for (int i = 0; i < subItemsExit.Count(); i++)
6507 {
6508 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
6509 itemExit.OnInventoryExit(ownerPlayerOld);
6510 }
6511 }
6512
6513 if (ownerPlayerNew)
6514 {
6515 array<EntityAI> subItemsEnter = new array<EntityAI>;
6516 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
6517 for (int j = 0; j < subItemsEnter.Count(); j++)
6518 {
6519 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
6520 itemEnter.OnInventoryEnter(ownerPlayerNew);
6521 }
6522 }
6523 }
6524 else if (ownerPlayerNew != null)
6525 {
6526 PlayerBase nplayer;
6527 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
6528 {
6529 array<EntityAI> subItemsUpdate = new array<EntityAI>;
6530 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
6531 for (int k = 0; k < subItemsUpdate.Count(); k++)
6532 {
6533 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
6534 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
6535 }
6536 }
6537 }
6538
6539 if (old_owner)
6540 old_owner.OnChildItemRemoved(this);
6541 if (new_owner)
6542 new_owner.OnChildItemReceived(this);
6543 }
6544
6545 // -------------------------------------------------------------------------------
6546 override void EEDelete(EntityAI parent)
6547 {
6548 super.EEDelete(parent);
6549 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
6550 if (player)
6551 {
6552 OnInventoryExit(player);
6553
6554 if (player.IsAlive())
6555 {
6556 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
6557 if (r_index >= 0)
6558 {
6559 InventoryLocation r_il = new InventoryLocation;
6560 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
6561
6562 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
6563 int r_type = r_il.GetType();
6564 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
6565 {
6566 r_il.GetParent().GetOnReleaseLock().Invoke(this);
6567 }
6568 else if (r_type == InventoryLocationType.ATTACHMENT)
6569 {
6570 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
6571 }
6572
6573 }
6574
6575 player.RemoveQuickBarEntityShortcut(this);
6576 }
6577 }
6578 }
6579 // -------------------------------------------------------------------------------
6580 override void EEKilled(Object killer)
6581 {
6582 super.EEKilled(killer);
6583
6585 if (killer && killer.IsFireplace() && CanExplodeInFire())
6586 {
6587 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
6588 {
6589 if (IsMagazine())
6590 {
6591 if (Magazine.Cast(this).GetAmmoCount() > 0)
6592 {
6593 ExplodeAmmo();
6594 }
6595 }
6596 else
6597 {
6598 Explode(DamageType.EXPLOSION);
6599 }
6600 }
6601 }
6602 }
6603
6604 override void OnWasAttached(EntityAI parent, int slot_id)
6605 {
6606 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
6607
6608 super.OnWasAttached(parent, slot_id);
6609
6610 if (HasQuantity())
6611 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
6612
6613 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
6614 StartItemSoundServer(SoundConstants.ITEM_ATTACH, slot_id);
6615 }
6616
6617 override void OnWasDetached(EntityAI parent, int slot_id)
6618 {
6619 super.OnWasDetached(parent, slot_id);
6620
6621 if (HasQuantity())
6622 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
6623
6624 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
6625 StartItemSoundServer(SoundConstants.ITEM_DETACH, slot_id);
6626 }
6627
6628 override string ChangeIntoOnAttach(string slot)
6629 {
6630 int idx;
6631 TStringArray inventory_slots = new TStringArray;
6632 TStringArray attach_types = new TStringArray;
6633
6634 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
6635 if (inventory_slots.Count() < 1) //is string
6636 {
6637 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
6638 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
6639 }
6640 else //is array
6641 {
6642 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
6643 }
6644
6645 idx = inventory_slots.Find(slot);
6646 if (idx < 0)
6647 return "";
6648
6649 return attach_types.Get(idx);
6650 }
6651
6652 override string ChangeIntoOnDetach()
6653 {
6654 int idx = -1;
6655 string slot;
6656
6657 TStringArray inventory_slots = new TStringArray;
6658 TStringArray detach_types = new TStringArray;
6659
6660 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
6661 if (inventory_slots.Count() < 1) //is string
6662 {
6663 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
6664 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
6665 }
6666 else //is array
6667 {
6668 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
6669 if (detach_types.Count() < 1)
6670 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
6671 }
6672
6673 for (int i = 0; i < inventory_slots.Count(); i++)
6674 {
6675 slot = inventory_slots.Get(i);
6676 }
6677
6678 if (slot != "")
6679 {
6680 if (detach_types.Count() == 1)
6681 idx = 0;
6682 else
6683 idx = inventory_slots.Find(slot);
6684 }
6685 if (idx < 0)
6686 return "";
6687
6688 return detach_types.Get(idx);
6689 }
6690
6691 void ExplodeAmmo()
6692 {
6693 //timer
6694 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
6695
6696 //min/max time
6697 float min_time = 1;
6698 float max_time = 3;
6699 float delay = Math.RandomFloat(min_time, max_time);
6700
6701 explode_timer.Run(delay, this, "DoAmmoExplosion");
6702 }
6703
6704 void DoAmmoExplosion()
6705 {
6706 Magazine magazine = Magazine.Cast(this);
6707 int pop_sounds_count = 6;
6708 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
6709
6710 //play sound
6711 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
6712 string sound_name = pop_sounds[ sound_idx ];
6713 g_Game.CreateSoundOnObject(this, sound_name, 20, false);
6714
6715 //remove ammo count
6716 magazine.ServerAddAmmoCount(-1);
6717
6718 //if condition then repeat -> ExplodeAmmo
6719 float min_temp_to_explode = 100; //min temperature for item to explode
6720
6721 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
6722 {
6723 ExplodeAmmo();
6724 }
6725 }
6726
6727 // -------------------------------------------------------------------------------
6728 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
6729 {
6730 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
6731
6732 const int CHANCE_DAMAGE_CARGO = 4;
6733 const int CHANCE_DAMAGE_ATTACHMENT = 1;
6734 const int CHANCE_DAMAGE_NOTHING = 2;
6735
6736 if (IsClothing() || IsContainer() || IsItemTent())
6737 {
6738 float dmg = damageResult.GetDamage("","Health") * -0.5;
6739 int chances;
6740 int rnd;
6741
6742 if (GetInventory().GetCargo())
6743 {
6744 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
6745 rnd = Math.RandomInt(0,chances);
6746
6747 if (rnd < CHANCE_DAMAGE_CARGO)
6748 {
6749 DamageItemInCargo(dmg);
6750 }
6751 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
6752 {
6754 }
6755 }
6756 else
6757 {
6758 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
6759 rnd = Math.RandomInt(0,chances);
6760
6761 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
6762 {
6764 }
6765 }
6766 }
6767 }
6768
6769 bool DamageItemInCargo(float damage)
6770 {
6771 CargoBase cargo = GetInventory().GetCargo();
6772 if (cargo)
6773 {
6774 int item_count = cargo.GetItemCount();
6775 if (item_count > 0)
6776 {
6777 int random_pick = Math.RandomInt(0, item_count);
6778 ItemBase item = ItemBase.Cast(cargo.GetItem(random_pick));
6779 if (!item.IsExplosive())
6780 {
6781 item.AddHealth("","",damage);
6782 return true;
6783 }
6784 }
6785 }
6786 return false;
6787 }
6788
6789 bool DamageItemAttachments(float damage)
6790 {
6791 GameInventory inventory = GetInventory();
6792 int attachment_count = inventory.AttachmentCount();
6793 if (attachment_count > 0)
6794 {
6795 int random_pick = Math.RandomInt(0, attachment_count);
6796 ItemBase attachment = ItemBase.Cast(inventory.GetAttachmentFromIndex(random_pick));
6797 if (!attachment.IsExplosive())
6798 {
6799 attachment.AddHealth("","",damage);
6800 return true;
6801 }
6802 }
6803 return false;
6804 }
6805
6806 override bool IsSplitable()
6807 {
6808 return m_CanThisBeSplit;
6809 }
6810 //----------------
6811 override bool CanBeSplit()
6812 {
6813 if (IsSplitable() && (GetQuantity() > 1))
6814 return GetInventory().CanRemoveEntity();
6815
6816 return false;
6817 }
6818
6819 protected bool ShouldSplitQuantity(float quantity)
6820 {
6821 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
6822 if (!IsSplitable())
6823 return false;
6824
6825 // nothing to split?
6826 if (GetQuantity() <= 1)
6827 return false;
6828
6829 // check if we should re-use the item instead of creating a new copy?
6830 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
6831 int delta = GetQuantity() - quantity;
6832 if (delta == 0)
6833 return false;
6834
6835 // valid to split
6836 return true;
6837 }
6838
6839 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
6840 {
6841 if (g_Game.IsClient())
6842 {
6843 if (ScriptInputUserData.CanStoreInputUserData())
6844 {
6845 ScriptInputUserData ctx = new ScriptInputUserData;
6847 ctx.Write(1);
6848 ItemBase i1 = this; // @NOTE: workaround for correct serialization
6849 ctx.Write(i1);
6850 ctx.Write(destination_entity);
6851 ctx.Write(true);
6852 ctx.Write(slot_id);
6853 ctx.Send();
6854 }
6855 }
6856 else if (!g_Game.IsMultiplayer())
6857 {
6858 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(g_Game.GetPlayer()));
6859 }
6860 }
6861
6862 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
6863 {
6864 float split_quantity_new;
6865 ItemBase new_item;
6866 float quantity = GetQuantity();
6867 float stack_max = GetTargetQuantityMax(slot_id);
6868 InventoryLocation loc = new InventoryLocation;
6869
6870 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
6871 {
6872 if (stack_max <= GetQuantity())
6873 split_quantity_new = stack_max;
6874 else
6875 split_quantity_new = GetQuantity();
6876
6877 if (ShouldSplitQuantity(split_quantity_new))
6878 {
6879 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
6880 if (new_item)
6881 {
6882 new_item.SetResultOfSplit(true);
6883 MiscGameplayFunctions.TransferItemProperties(this, new_item);
6884 AddQuantity(-split_quantity_new, false, true);
6885 new_item.SetQuantity(split_quantity_new, false, true);
6886 }
6887 }
6888 }
6889 else if (destination_entity && slot_id == -1)
6890 {
6891 if (quantity > stack_max)
6892 split_quantity_new = stack_max;
6893 else
6894 split_quantity_new = quantity;
6895
6896 if (ShouldSplitQuantity(split_quantity_new))
6897 {
6898 GameInventory destinationInventory = destination_entity.GetInventory();
6899 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
6900 {
6901 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
6902 new_item = ItemBase.Cast(o);
6903 }
6904
6905 if (new_item)
6906 {
6907 new_item.SetResultOfSplit(true);
6908 MiscGameplayFunctions.TransferItemProperties(this, new_item);
6909 AddQuantity(-split_quantity_new, false, true);
6910 new_item.SetQuantity(split_quantity_new, false, true);
6911 }
6912 }
6913 }
6914 else
6915 {
6916 if (stack_max != 0)
6917 {
6918 if (stack_max < GetQuantity())
6919 {
6920 split_quantity_new = GetQuantity() - stack_max;
6921 }
6922
6923 if (split_quantity_new == 0)
6924 {
6925 if (!g_Game.IsMultiplayer())
6926 player.PhysicalPredictiveDropItem(this);
6927 else
6928 player.ServerDropEntity(this);
6929 return;
6930 }
6931
6932 if (ShouldSplitQuantity(split_quantity_new))
6933 {
6934 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
6935
6936 if (new_item)
6937 {
6938 new_item.SetResultOfSplit(true);
6939 MiscGameplayFunctions.TransferItemProperties(this, new_item);
6940 SetQuantity(split_quantity_new, false, true);
6941 new_item.SetQuantity(stack_max, false, true);
6942 new_item.PlaceOnSurface();
6943 }
6944 }
6945 }
6946 }
6947 }
6948
6949 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
6950 {
6951 float split_quantity_new;
6952 ItemBase new_item;
6953 float quantity = GetQuantity();
6954 float stack_max = GetTargetQuantityMax(slot_id);
6955 InventoryLocation loc = new InventoryLocation;
6956
6957 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
6958 {
6959 if (stack_max <= GetQuantity())
6960 split_quantity_new = stack_max;
6961 else
6962 split_quantity_new = GetQuantity();
6963
6964 if (ShouldSplitQuantity(split_quantity_new))
6965 {
6966 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
6967 if (new_item)
6968 {
6969 new_item.SetResultOfSplit(true);
6970 MiscGameplayFunctions.TransferItemProperties(this, new_item);
6971 AddQuantity(-split_quantity_new, false, true);
6972 new_item.SetQuantity(split_quantity_new, false, true);
6973 }
6974 }
6975 }
6976 else if (destination_entity && slot_id == -1)
6977 {
6978 if (quantity > stack_max)
6979 split_quantity_new = stack_max;
6980 else
6981 split_quantity_new = quantity;
6982
6983 if (ShouldSplitQuantity(split_quantity_new))
6984 {
6985 GameInventory destinationInventory = destination_entity.GetInventory();
6986 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
6987 {
6988 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
6989 new_item = ItemBase.Cast(o);
6990 }
6991
6992 if (new_item)
6993 {
6994 new_item.SetResultOfSplit(true);
6995 MiscGameplayFunctions.TransferItemProperties(this, new_item);
6996 AddQuantity(-split_quantity_new, false, true);
6997 new_item.SetQuantity(split_quantity_new, false, true);
6998 }
6999 }
7000 }
7001 else
7002 {
7003 if (stack_max != 0)
7004 {
7005 if (stack_max < GetQuantity())
7006 {
7007 split_quantity_new = GetQuantity() - stack_max;
7008 }
7009
7010 if (ShouldSplitQuantity(split_quantity_new))
7011 {
7012 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7013
7014 if (new_item)
7015 {
7016 new_item.SetResultOfSplit(true);
7017 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7018 SetQuantity(split_quantity_new, false, true);
7019 new_item.SetQuantity(stack_max, false, true);
7020 new_item.PlaceOnSurface();
7021 }
7022 }
7023 }
7024 }
7025 }
7026
7027 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
7028 {
7029 if (g_Game.IsClient())
7030 {
7031 if (ScriptInputUserData.CanStoreInputUserData())
7032 {
7033 ScriptInputUserData ctx = new ScriptInputUserData;
7035 ctx.Write(4);
7036 ItemBase thiz = this; // @NOTE: workaround for correct serialization
7037 ctx.Write(thiz);
7038 dst.WriteToContext(ctx);
7039 ctx.Send();
7040 }
7041 }
7042 else if (!g_Game.IsMultiplayer())
7043 {
7045 }
7046 }
7047
7048 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
7049 {
7050 if (g_Game.IsClient())
7051 {
7052 if (ScriptInputUserData.CanStoreInputUserData())
7053 {
7054 ScriptInputUserData ctx = new ScriptInputUserData;
7056 ctx.Write(2);
7057 ItemBase dummy = this; // @NOTE: workaround for correct serialization
7058 ctx.Write(dummy);
7059 ctx.Write(destination_entity);
7060 ctx.Write(true);
7061 ctx.Write(idx);
7062 ctx.Write(row);
7063 ctx.Write(col);
7064 ctx.Send();
7065 }
7066 }
7067 else if (!g_Game.IsMultiplayer())
7068 {
7069 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
7070 }
7071 }
7072
7073 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
7074 {
7076 }
7077
7078 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
7079 {
7080 float quantity = GetQuantity();
7081 float split_quantity_new;
7082 ItemBase new_item;
7083 if (dst.IsValid())
7084 {
7085 int slot_id = dst.GetSlot();
7086 float stack_max = GetTargetQuantityMax(slot_id);
7087
7088 if (quantity > stack_max)
7089 split_quantity_new = stack_max;
7090 else
7091 split_quantity_new = quantity;
7092
7093 if (ShouldSplitQuantity(split_quantity_new))
7094 {
7095 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
7096
7097 if (new_item)
7098 {
7099 new_item.SetResultOfSplit(true);
7100 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7101 AddQuantity(-split_quantity_new, false, true);
7102 new_item.SetQuantity(split_quantity_new, false, true);
7103 }
7104
7105 return new_item;
7106 }
7107 }
7108
7109 return null;
7110 }
7111
7112 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
7113 {
7114 float quantity = GetQuantity();
7115 float split_quantity_new;
7116 ItemBase new_item;
7117 if (destination_entity)
7118 {
7119 float stackable = GetTargetQuantityMax();
7120 if (quantity > stackable)
7121 split_quantity_new = stackable;
7122 else
7123 split_quantity_new = quantity;
7124
7125 if (ShouldSplitQuantity(split_quantity_new))
7126 {
7127 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
7128 if (new_item)
7129 {
7130 new_item.SetResultOfSplit(true);
7131 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7132 AddQuantity(-split_quantity_new, false, true);
7133 new_item.SetQuantity(split_quantity_new, false, true);
7134 }
7135 }
7136 }
7137 }
7138
7139 void SplitIntoStackMaxHandsClient(PlayerBase player)
7140 {
7141 if (g_Game.IsClient())
7142 {
7143 if (ScriptInputUserData.CanStoreInputUserData())
7144 {
7145 ScriptInputUserData ctx = new ScriptInputUserData;
7147 ctx.Write(3);
7148 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7149 ctx.Write(i1);
7150 ItemBase destination_entity = this;
7151 ctx.Write(destination_entity);
7152 ctx.Write(true);
7153 ctx.Write(0);
7154 ctx.Send();
7155 }
7156 }
7157 else if (!g_Game.IsMultiplayer())
7158 {
7159 SplitIntoStackMaxHands(player);
7160 }
7161 }
7162
7163 void SplitIntoStackMaxHands(PlayerBase player)
7164 {
7165 float quantity = GetQuantity();
7166 float split_quantity_new;
7167 ref ItemBase new_item;
7168 if (player)
7169 {
7170 float stackable = GetTargetQuantityMax();
7171 if (quantity > stackable)
7172 split_quantity_new = stackable;
7173 else
7174 split_quantity_new = quantity;
7175
7176 if (ShouldSplitQuantity(split_quantity_new))
7177 {
7178 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
7179 new_item = ItemBase.Cast(in_hands);
7180 if (new_item)
7181 {
7182 new_item.SetResultOfSplit(true);
7183 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7184 AddQuantity(-split_quantity_new, false, true);
7185 new_item.SetQuantity(split_quantity_new, false, true);
7186 }
7187 }
7188 }
7189 }
7190
7191 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
7192 {
7193 float quantity = GetQuantity();
7194 float split_quantity_new = Math.Floor(quantity * 0.5);
7195
7196 if (!ShouldSplitQuantity(split_quantity_new))
7197 return;
7198
7199 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
7200
7201 if (new_item)
7202 {
7203 if (new_item.GetQuantityMax() < split_quantity_new)
7204 {
7205 split_quantity_new = new_item.GetQuantityMax();
7206 }
7207
7208 new_item.SetResultOfSplit(true);
7209 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7210
7211 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
7212 {
7213 AddQuantity(-1, false, true);
7214 new_item.SetQuantity(1, false, true);
7215 }
7216 else
7217 {
7218 AddQuantity(-split_quantity_new, false, true);
7219 new_item.SetQuantity(split_quantity_new, false, true);
7220 }
7221 }
7222 }
7223
7224 void SplitItem(PlayerBase player)
7225 {
7226 float quantity = GetQuantity();
7227 float split_quantity_new = Math.Floor(quantity / 2);
7228
7229 if (!ShouldSplitQuantity(split_quantity_new))
7230 return;
7231
7232 InventoryLocation invloc = new InventoryLocation;
7233 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
7234
7235 ItemBase new_item;
7236 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
7237
7238 if (new_item)
7239 {
7240 if (new_item.GetQuantityMax() < split_quantity_new)
7241 {
7242 split_quantity_new = new_item.GetQuantityMax();
7243 }
7244 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
7245 {
7246 AddQuantity(-1, false, true);
7247 new_item.SetQuantity(1, false, true);
7248 }
7249 else if (split_quantity_new > 1)
7250 {
7251 AddQuantity(-split_quantity_new, false, true);
7252 new_item.SetQuantity(split_quantity_new, false, true);
7253 }
7254 }
7255 }
7256
7258 void OnQuantityChanged(float delta)
7259 {
7260 SetWeightDirty();
7261 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
7262
7263 if (parent)
7264 parent.OnAttachmentQuantityChangedEx(this, delta);
7265
7266 if (IsLiquidContainer())
7267 {
7268 if (GetQuantityNormalized() <= 0.0)
7269 {
7271 }
7272 else if (GetLiquidType() == LIQUID_NONE)
7273 {
7274 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
7276 }
7277 }
7278 }
7279
7282 {
7283 // insert code here
7284 }
7285
7287 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
7288 {
7290 }
7291
7292 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
7293 {
7294 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
7295
7296 if (g_Game.IsServer())
7297 {
7298 if (newLevel == GameConstants.STATE_RUINED)
7299 {
7301 EntityAI parent = GetHierarchyParent();
7302 if (parent && parent.IsFireplace())
7303 {
7304 CargoBase cargo = GetInventory().GetCargo();
7305 if (cargo)
7306 {
7307 for (int i = 0; i < cargo.GetItemCount(); ++i)
7308 {
7309 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
7310 }
7311 }
7312 }
7313 }
7314
7315 if (IsResultOfSplit())
7316 {
7317 // reset the splitting result flag, return to normal item behavior
7318 SetResultOfSplit(false);
7319 return;
7320 }
7321
7322 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
7323 {
7324 SetCleanness(0);//unclean the item upon damage dealt
7325 }
7326 }
7327 }
7328
7329 // just the split? TODO: verify
7330 override void OnRightClick()
7331 {
7332 super.OnRightClick();
7333
7334 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !g_Game.GetPlayer().GetInventory().HasInventoryReservation(this,null))
7335 {
7336 if (g_Game.IsClient())
7337 {
7338 if (ScriptInputUserData.CanStoreInputUserData())
7339 {
7340 EntityAI root = GetHierarchyRoot();
7341 Man playerOwner = GetHierarchyRootPlayer();
7342 InventoryLocation dst = new InventoryLocation;
7343
7344 // 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
7345 if (!playerOwner && root && root == this)
7346 {
7348 }
7349 else
7350 {
7351 // 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
7352 GetInventory().GetCurrentInventoryLocation(dst);
7353 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
7354 {
7355 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7356 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
7357 {
7359 }
7360 else
7361 {
7362 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
7363 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
7364 this shouldnt cause issues within this scope*/
7365 if (g_Game.GetPlayer().GetInventory().HasInventoryReservation(this, dst))
7366 {
7368 }
7369 else
7370 {
7371 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
7372 }
7373 }
7374 }
7375 }
7376
7377 ScriptInputUserData ctx = new ScriptInputUserData;
7379 ctx.Write(4);
7380 ItemBase thiz = this; // @NOTE: workaround for correct serialization
7381 ctx.Write(thiz);
7382 dst.WriteToContext(ctx);
7383 ctx.Write(true); // dummy
7384 ctx.Send();
7385 }
7386 }
7387 else if (!g_Game.IsMultiplayer())
7388 {
7389 SplitItem(PlayerBase.Cast(g_Game.GetPlayer()));
7390 }
7391 }
7392 }
7393
7394 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
7395 {
7396 if (root)
7397 {
7398 vector m4[4];
7399 root.GetTransform(m4);
7400 dst.SetGround(this, m4);
7401 }
7402 else
7403 {
7404 GetInventory().GetCurrentInventoryLocation(dst);
7405 }
7406 }
7407
7408 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
7409 {
7410 //TODO: delete check zero quantity check after fix double posts hands fsm events
7411 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
7412 return false;
7413
7414 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
7415 return false;
7416
7417 //can_this_be_combined = ConfigGetBool("canBeSplit");
7419 return false;
7420
7421
7422 Magazine mag = Magazine.Cast(this);
7423 if (mag)
7424 {
7425 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
7426 return false;
7427
7428 if (stack_max_limit)
7429 {
7430 Magazine other_mag = Magazine.Cast(other_item);
7431 if (other_item)
7432 {
7433 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
7434 return false;
7435 }
7436
7437 }
7438 }
7439 else
7440 {
7441 //TODO: delete check zero quantity check after fix double posts hands fsm events
7442 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
7443 return false;
7444
7445 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
7446 return false;
7447 }
7448
7449 PlayerBase player = null;
7450 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
7451 {
7452 if (player.GetInventory().HasAttachment(this))
7453 return false;
7454
7455 if (player.IsItemsToDelete())
7456 return false;
7457 }
7458
7459 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
7460 return false;
7461
7462 int slotID;
7463 string slotName;
7464 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
7465 return false;
7466
7467 return true;
7468 }
7469
7470 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
7471 {
7472 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
7473 }
7474
7475 bool IsResultOfSplit()
7476 {
7477 return m_IsResultOfSplit;
7478 }
7479
7480 void SetResultOfSplit(bool value)
7481 {
7482 m_IsResultOfSplit = value;
7483 }
7484
7485 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
7486 {
7487 return ComputeQuantityUsedEx(other_item, use_stack_max);
7488 }
7489
7490 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
7491 {
7492 float other_item_quantity = other_item.GetQuantity();
7493 float this_free_space;
7494
7495 float stack_max = GetQuantityMax();
7496
7497 this_free_space = stack_max - GetQuantity();
7498
7499 if (other_item_quantity > this_free_space)
7500 {
7501 return this_free_space;
7502 }
7503 else
7504 {
7505 return other_item_quantity;
7506 }
7507 }
7508
7509 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
7510 {
7511 CombineItems(ItemBase.Cast(entity2),use_stack_max);
7512 }
7513
7514 void CombineItems(ItemBase other_item, bool use_stack_max = true)
7515 {
7516 if (!CanBeCombined(other_item, false))
7517 return;
7518
7519 if (!IsMagazine() && other_item)
7520 {
7521 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
7522 if (quantity_used != 0)
7523 {
7524 float hp1 = GetHealth01("","");
7525 float hp2 = other_item.GetHealth01("","");
7526 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
7527 hpResult = hpResult / (GetQuantity() + quantity_used);
7528
7529 hpResult *= GetMaxHealth();
7530 Math.Round(hpResult);
7531 SetHealth("", "Health", hpResult);
7532
7533 AddQuantity(quantity_used);
7534 other_item.AddQuantity(-quantity_used);
7535 }
7536 }
7537 OnCombine(other_item);
7538 }
7539
7540 void OnCombine(ItemBase other_item)
7541 {
7542 #ifdef SERVER
7543 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
7544 GetHierarchyParent().IncreaseLifetimeUp();
7545 #endif
7546 };
7547
7548 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
7549 {
7550 PlayerBase p = PlayerBase.Cast(player);
7551
7552 array<int> recipesIds = p.m_Recipes;
7553 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
7554 if (moduleRecipesManager)
7555 {
7556 EntityAI itemInHands = player.GetEntityInHands();
7557 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
7558 }
7559
7560 for (int i = 0;i < recipesIds.Count(); i++)
7561 {
7562 int key = recipesIds.Get(i);
7563 string recipeName = moduleRecipesManager.GetRecipeName(key);
7564 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
7565 }
7566 }
7567
7568 // -------------------------------------------------------------------------
7569 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
7570 {
7571 super.GetDebugActions(outputList);
7572
7573 //quantity
7574 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
7575 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
7576 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
7577 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
7578 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7579
7580 //health
7581 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
7582 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
7583 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
7584 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7585 //temperature
7586 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
7587 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
7588 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
7589 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7590
7591 //wet
7592 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
7593 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
7594 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7595
7596 //liquidtype
7597 if (IsLiquidContainer())
7598 {
7599 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
7600 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
7601 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7602 }
7603
7604 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
7605 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7606
7607 // watch
7608 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
7609 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
7610 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7611
7612 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
7613
7614 InventoryLocation loc = new InventoryLocation();
7615 GetInventory().GetCurrentInventoryLocation(loc);
7616 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
7617 {
7618 if (Gizmo_IsSupported())
7619 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
7620 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
7621 }
7622
7623 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7624 }
7625
7626 // -------------------------------------------------------------------------
7627 // -------------------------------------------------------------------------
7628 // -------------------------------------------------------------------------
7629 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
7630 {
7631 super.OnAction(action_id, player, ctx);
7632
7633 if (g_Game.IsClient() || !g_Game.IsMultiplayer())
7634 {
7635 switch (action_id)
7636 {
7637 case EActions.GIZMO_OBJECT:
7638 if (GetGizmoApi())
7639 GetGizmoApi().SelectObject(this);
7640 return true;
7641 case EActions.GIZMO_PHYSICS:
7642 if (GetGizmoApi())
7643 GetGizmoApi().SelectPhysics(GetPhysics());
7644 return true;
7645 }
7646 }
7647
7648 if (g_Game.IsServer())
7649 {
7650 switch (action_id)
7651 {
7652 case EActions.DELETE:
7653 Delete();
7654 return true;
7655 }
7656 }
7657
7658 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
7659 {
7660 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
7661 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
7662 PlayerBase p = PlayerBase.Cast(player);
7663 if (EActions.RECIPES_RANGE_START < 1000)
7664 {
7665 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
7666 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
7667 }
7668 }
7669 #ifndef SERVER
7670 else if (action_id == EActions.WATCH_PLAYER)
7671 {
7672 PluginDeveloper.SetDeveloperItemClientEx(player);
7673 }
7674 #endif
7675 if (g_Game.IsServer())
7676 {
7677 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
7678 {
7679 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
7680 OnDebugButtonPressServer(id + 1);
7681 }
7682
7683 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
7684 {
7685 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
7686 InsertAgent(agent_id,100);
7687 }
7688
7689 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
7690 {
7691 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
7692 RemoveAgent(agent_id2);
7693 }
7694
7695 else if (action_id == EActions.ADD_QUANTITY)
7696 {
7697 if (IsMagazine())
7698 {
7699 Magazine mag = Magazine.Cast(this);
7700 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
7701 }
7702 else
7703 {
7704 AddQuantity(GetQuantityMax() * 0.2);
7705 }
7706
7707 if (m_EM)
7708 {
7709 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
7710 }
7711 //PrintVariables();
7712 }
7713
7714 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
7715 {
7716 if (IsMagazine())
7717 {
7718 Magazine mag2 = Magazine.Cast(this);
7719 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
7720 }
7721 else
7722 {
7723 AddQuantity(- GetQuantityMax() * 0.2);
7724 }
7725 if (m_EM)
7726 {
7727 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
7728 }
7729 //PrintVariables();
7730 }
7731
7732 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
7733 {
7734 SetQuantity(0);
7735
7736 if (m_EM)
7737 {
7738 m_EM.SetEnergy(0);
7739 }
7740 }
7741
7742 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
7743 {
7745
7746 if (m_EM)
7747 {
7748 m_EM.SetEnergy(m_EM.GetEnergyMax());
7749 }
7750 }
7751
7752 else if (action_id == EActions.ADD_HEALTH)
7753 {
7754 AddHealth("","",GetMaxHealth("","Health")/5);
7755 }
7756 else if (action_id == EActions.REMOVE_HEALTH)
7757 {
7758 AddHealth("","",-GetMaxHealth("","Health")/5);
7759 }
7760 else if (action_id == EActions.DESTROY_HEALTH)
7761 {
7762 SetHealth01("","",0);
7763 }
7764 else if (action_id == EActions.WATCH_ITEM)
7765 {
7767 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
7768 #ifdef DEVELOPER
7769 SetDebugDeveloper_item(this);
7770 #endif
7771 }
7772
7773 else if (action_id == EActions.ADD_TEMPERATURE)
7774 {
7775 AddTemperature(20);
7776 //PrintVariables();
7777 }
7778
7779 else if (action_id == EActions.REMOVE_TEMPERATURE)
7780 {
7781 AddTemperature(-20);
7782 //PrintVariables();
7783 }
7784
7785 else if (action_id == EActions.FLIP_FROZEN)
7786 {
7787 SetFrozen(!GetIsFrozen());
7788 //PrintVariables();
7789 }
7790
7791 else if (action_id == EActions.ADD_WETNESS)
7792 {
7793 AddWet(GetWetMax()/5);
7794 //PrintVariables();
7795 }
7796
7797 else if (action_id == EActions.REMOVE_WETNESS)
7798 {
7799 AddWet(-GetWetMax()/5);
7800 //PrintVariables();
7801 }
7802
7803 else if (action_id == EActions.LIQUIDTYPE_UP)
7804 {
7805 int curr_type = GetLiquidType();
7806 SetLiquidType(curr_type * 2);
7807 //AddWet(1);
7808 //PrintVariables();
7809 }
7810
7811 else if (action_id == EActions.LIQUIDTYPE_DOWN)
7812 {
7813 int curr_type2 = GetLiquidType();
7814 SetLiquidType(curr_type2 / 2);
7815 }
7816
7817 else if (action_id == EActions.MAKE_SPECIAL)
7818 {
7819 auto debugParams = DebugSpawnParams.WithPlayer(player);
7820 OnDebugSpawnEx(debugParams);
7821 }
7822
7823 }
7824
7825
7826 return false;
7827 }
7828
7829 // -------------------------------------------------------------------------
7830
7831
7834 void OnActivatedByTripWire();
7835
7837 void OnActivatedByItem(notnull ItemBase item);
7838
7839 //----------------------------------------------------------------
7840 //returns true if item is able to explode when put in fire
7841 bool CanExplodeInFire()
7842 {
7843 return false;
7844 }
7845
7846 //----------------------------------------------------------------
7847 bool CanEat()
7848 {
7849 return true;
7850 }
7851
7852 //----------------------------------------------------------------
7853 override bool IsIgnoredByConstruction()
7854 {
7855 return true;
7856 }
7857
7858 //----------------------------------------------------------------
7859 //has FoodStages in config?
7860 bool HasFoodStage()
7861 {
7862 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
7863 return g_Game.ConfigIsExisting(config_path);
7864 }
7865
7867 FoodStage GetFoodStage()
7868 {
7869 return null;
7870 }
7871
7872 bool CanBeCooked()
7873 {
7874 return false;
7875 }
7876
7877 bool CanBeCookedOnStick()
7878 {
7879 return false;
7880 }
7881
7883 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
7885
7886 //----------------------------------------------------------------
7887 bool CanRepair(ItemBase item_repair_kit)
7888 {
7889 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
7890 return module_repairing.CanRepair(this, item_repair_kit);
7891 }
7892
7893 //----------------------------------------------------------------
7894 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
7895 {
7896 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
7897 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
7898 }
7899
7900 //----------------------------------------------------------------
7901 int GetItemSize()
7902 {
7903 /*
7904 vector v_size = this.ConfigGetVector("itemSize");
7905 int v_size_x = v_size[0];
7906 int v_size_y = v_size[1];
7907 int size = v_size_x * v_size_y;
7908 return size;
7909 */
7910
7911 return 1;
7912 }
7913
7914 //----------------------------------------------------------------
7915 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
7916 bool CanBeMovedOverride()
7917 {
7918 return m_CanBeMovedOverride;
7919 }
7920
7921 //----------------------------------------------------------------
7922 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
7923 void SetCanBeMovedOverride(bool setting)
7924 {
7925 m_CanBeMovedOverride = setting;
7926 }
7927
7928 //----------------------------------------------------------------
7936 void MessageToOwnerStatus(string text)
7937 {
7938 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
7939
7940 if (player)
7941 {
7942 player.MessageStatus(text);
7943 }
7944 }
7945
7946 //----------------------------------------------------------------
7954 void MessageToOwnerAction(string text)
7955 {
7956 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
7957
7958 if (player)
7959 {
7960 player.MessageAction(text);
7961 }
7962 }
7963
7964 //----------------------------------------------------------------
7972 void MessageToOwnerFriendly(string text)
7973 {
7974 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
7975
7976 if (player)
7977 {
7978 player.MessageFriendly(text);
7979 }
7980 }
7981
7982 //----------------------------------------------------------------
7990 void MessageToOwnerImportant(string text)
7991 {
7992 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
7993
7994 if (player)
7995 {
7996 player.MessageImportant(text);
7997 }
7998 }
7999
8000 override bool IsItemBase()
8001 {
8002 return true;
8003 }
8004
8005 // Checks if item is of questioned kind
8006 override bool KindOf(string tag)
8007 {
8008 bool found = false;
8009 string item_name = this.GetType();
8010 ref TStringArray item_tag_array = new TStringArray;
8011 g_Game.ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
8012
8013 int array_size = item_tag_array.Count();
8014 for (int i = 0; i < array_size; i++)
8015 {
8016 if (item_tag_array.Get(i) == tag)
8017 {
8018 found = true;
8019 break;
8020 }
8021 }
8022 return found;
8023 }
8024
8025
8026 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
8027 {
8028 //Debug.Log("OnRPC called");
8029 super.OnRPC(sender, rpc_type,ctx);
8030
8031 //Play soundset for attachment locking (ActionLockAttachment.c)
8032 switch (rpc_type)
8033 {
8034 #ifndef SERVER
8035 case ERPCs.RPC_SOUND_LOCK_ATTACH:
8036 Param2<bool, string> p = new Param2<bool, string>(false, "");
8037
8038 if (!ctx.Read(p))
8039 return;
8040
8041 bool play = p.param1;
8042 string soundSet = p.param2;
8043
8044 if (play)
8045 {
8046 if (m_LockingSound)
8047 {
8049 {
8050 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
8051 }
8052 }
8053 else
8054 {
8055 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
8056 }
8057 }
8058 else
8059 {
8060 SEffectManager.DestroyEffect(m_LockingSound);
8061 }
8062
8063 break;
8064 #endif
8065
8066 }
8067
8068 if (GetWrittenNoteData())
8069 {
8070 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
8071 }
8072 }
8073
8074 //-----------------------------
8075 // VARIABLE MANIPULATION SYSTEM
8076 //-----------------------------
8077 int NameToID(string name)
8078 {
8079 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
8080 return plugin.GetID(name);
8081 }
8082
8083 string IDToName(int id)
8084 {
8085 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
8086 return plugin.GetName(id);
8087 }
8088
8090 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
8091 {
8092 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
8093 //read the flags
8094 int varFlags;
8095 if (!ctx.Read(varFlags))
8096 return;
8097
8098 if (varFlags & ItemVariableFlags.FLOAT)
8099 {
8100 ReadVarsFromCTX(ctx);
8101 }
8102 }
8103
8104 override void SerializeNumericalVars(array<float> floats_out)
8105 {
8106 //some variables handled on EntityAI level already!
8107 super.SerializeNumericalVars(floats_out);
8108
8109 // the order of serialization must be the same as the order of de-serialization
8110 //--------------------------------------------
8111 if (IsVariableSet(VARIABLE_QUANTITY))
8112 {
8113 floats_out.Insert(m_VarQuantity);
8114 }
8115 //--------------------------------------------
8116 if (IsVariableSet(VARIABLE_WET))
8117 {
8118 floats_out.Insert(m_VarWet);
8119 }
8120 //--------------------------------------------
8121 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
8122 {
8123 floats_out.Insert(m_VarLiquidType);
8124 }
8125 //--------------------------------------------
8126 if (IsVariableSet(VARIABLE_COLOR))
8127 {
8128 floats_out.Insert(m_ColorComponentR);
8129 floats_out.Insert(m_ColorComponentG);
8130 floats_out.Insert(m_ColorComponentB);
8131 floats_out.Insert(m_ColorComponentA);
8132 }
8133 //--------------------------------------------
8134 if (IsVariableSet(VARIABLE_CLEANNESS))
8135 {
8136 floats_out.Insert(m_Cleanness);
8137 }
8138 }
8139
8140 override void DeSerializeNumericalVars(array<float> floats)
8141 {
8142 //some variables handled on EntityAI level already!
8143 super.DeSerializeNumericalVars(floats);
8144
8145 // the order of serialization must be the same as the order of de-serialization
8146 int index = 0;
8147 int mask = Math.Round(floats.Get(index));
8148
8149 index++;
8150 //--------------------------------------------
8151 if (mask & VARIABLE_QUANTITY)
8152 {
8153 if (m_IsStoreLoad)
8154 {
8155 SetStoreLoadedQuantity(floats.Get(index));
8156 }
8157 else
8158 {
8159 float quantity = floats.Get(index);
8160 SetQuantity(quantity, true, false, false, false);
8161 }
8162 index++;
8163 }
8164 //--------------------------------------------
8165 if (mask & VARIABLE_WET)
8166 {
8167 float wet = floats.Get(index);
8168 SetWet(wet);
8169 index++;
8170 }
8171 //--------------------------------------------
8172 if (mask & VARIABLE_LIQUIDTYPE)
8173 {
8174 int liquidtype = Math.Round(floats.Get(index));
8175 SetLiquidType(liquidtype);
8176 index++;
8177 }
8178 //--------------------------------------------
8179 if (mask & VARIABLE_COLOR)
8180 {
8181 m_ColorComponentR = Math.Round(floats.Get(index));
8182 index++;
8183 m_ColorComponentG = Math.Round(floats.Get(index));
8184 index++;
8185 m_ColorComponentB = Math.Round(floats.Get(index));
8186 index++;
8187 m_ColorComponentA = Math.Round(floats.Get(index));
8188 index++;
8189 }
8190 //--------------------------------------------
8191 if (mask & VARIABLE_CLEANNESS)
8192 {
8193 int cleanness = Math.Round(floats.Get(index));
8194 SetCleanness(cleanness);
8195 index++;
8196 }
8197 }
8198
8199 override void WriteVarsToCTX(ParamsWriteContext ctx)
8200 {
8201 super.WriteVarsToCTX(ctx);
8202
8203 //--------------------------------------------
8204 if (IsVariableSet(VARIABLE_QUANTITY))
8205 {
8206 ctx.Write(GetQuantity());
8207 }
8208 //--------------------------------------------
8209 if (IsVariableSet(VARIABLE_WET))
8210 {
8211 ctx.Write(GetWet());
8212 }
8213 //--------------------------------------------
8214 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
8215 {
8216 ctx.Write(GetLiquidType());
8217 }
8218 //--------------------------------------------
8219 if (IsVariableSet(VARIABLE_COLOR))
8220 {
8221 int r,g,b,a;
8222 GetColor(r,g,b,a);
8223 ctx.Write(r);
8224 ctx.Write(g);
8225 ctx.Write(b);
8226 ctx.Write(a);
8227 }
8228 //--------------------------------------------
8229 if (IsVariableSet(VARIABLE_CLEANNESS))
8230 {
8231 ctx.Write(GetCleanness());
8232 }
8233 }
8234
8235 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
8236 {
8237 if (!super.ReadVarsFromCTX(ctx,version))
8238 return false;
8239
8240 int intValue;
8241 float value;
8242
8243 if (version < 140)
8244 {
8245 if (!ctx.Read(intValue))
8246 return false;
8247
8248 m_VariablesMask = intValue;
8249 }
8250
8251 if (m_VariablesMask & VARIABLE_QUANTITY)
8252 {
8253 if (!ctx.Read(value))
8254 return false;
8255
8256 if (IsStoreLoad())
8257 {
8259 }
8260 else
8261 {
8262 SetQuantity(value, true, false, false, false);
8263 }
8264 }
8265 //--------------------------------------------
8266 if (version < 140)
8267 {
8268 if (m_VariablesMask & VARIABLE_TEMPERATURE)
8269 {
8270 if (!ctx.Read(value))
8271 return false;
8272 SetTemperatureDirect(value);
8273 }
8274 }
8275 //--------------------------------------------
8276 if (m_VariablesMask & VARIABLE_WET)
8277 {
8278 if (!ctx.Read(value))
8279 return false;
8280 SetWet(value);
8281 }
8282 //--------------------------------------------
8283 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
8284 {
8285 if (!ctx.Read(intValue))
8286 return false;
8287 SetLiquidType(intValue);
8288 }
8289 //--------------------------------------------
8290 if (m_VariablesMask & VARIABLE_COLOR)
8291 {
8292 int r,g,b,a;
8293 if (!ctx.Read(r))
8294 return false;
8295 if (!ctx.Read(g))
8296 return false;
8297 if (!ctx.Read(b))
8298 return false;
8299 if (!ctx.Read(a))
8300 return false;
8301
8302 SetColor(r,g,b,a);
8303 }
8304 //--------------------------------------------
8305 if (m_VariablesMask & VARIABLE_CLEANNESS)
8306 {
8307 if (!ctx.Read(intValue))
8308 return false;
8309 SetCleanness(intValue);
8310 }
8311 //--------------------------------------------
8312 if (version >= 138 && version < 140)
8313 {
8314 if (m_VariablesMask & VARIABLE_TEMPERATURE)
8315 {
8316 if (!ctx.Read(intValue))
8317 return false;
8318 SetFrozen(intValue);
8319 }
8320 }
8321
8322 return true;
8323 }
8324
8325 //----------------------------------------------------------------
8326 override bool OnStoreLoad(ParamsReadContext ctx, int version)
8327 {
8328 m_IsStoreLoad = true;
8330 {
8331 m_FixDamageSystemInit = true;
8332 }
8333
8334 if (!super.OnStoreLoad(ctx, version))
8335 {
8336 m_IsStoreLoad = false;
8337 return false;
8338 }
8339
8340 if (version >= 114)
8341 {
8342 bool hasQuickBarIndexSaved;
8343
8344 if (!ctx.Read(hasQuickBarIndexSaved))
8345 {
8346 m_IsStoreLoad = false;
8347 return false;
8348 }
8349
8350 if (hasQuickBarIndexSaved)
8351 {
8352 int itmQBIndex;
8353
8354 //Load quickbar item bind
8355 if (!ctx.Read(itmQBIndex))
8356 {
8357 m_IsStoreLoad = false;
8358 return false;
8359 }
8360
8361 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
8362 if (itmQBIndex != -1 && parentPlayer)
8363 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
8364 }
8365 }
8366 else
8367 {
8368 // Backup of how it used to be
8369 PlayerBase player;
8370 int itemQBIndex;
8371 if (version == int.MAX)
8372 {
8373 if (!ctx.Read(itemQBIndex))
8374 {
8375 m_IsStoreLoad = false;
8376 return false;
8377 }
8378 }
8379 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
8380 {
8381 //Load quickbar item bind
8382 if (!ctx.Read(itemQBIndex))
8383 {
8384 m_IsStoreLoad = false;
8385 return false;
8386 }
8387 if (itemQBIndex != -1 && player)
8388 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
8389 }
8390 }
8391
8392 if (version < 140)
8393 {
8394 // variable management system
8395 if (!LoadVariables(ctx, version))
8396 {
8397 m_IsStoreLoad = false;
8398 return false;
8399 }
8400 }
8401
8402 //agent trasmission system
8403 if (!LoadAgents(ctx, version))
8404 {
8405 m_IsStoreLoad = false;
8406 return false;
8407 }
8408 if (version >= 132)
8409 {
8410 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
8411 if (raib)
8412 {
8413 if (!raib.OnStoreLoad(ctx,version))
8414 {
8415 m_IsStoreLoad = false;
8416 return false;
8417 }
8418 }
8419 }
8420
8421 m_IsStoreLoad = false;
8422 return true;
8423 }
8424
8425 //----------------------------------------------------------------
8426
8427 override void OnStoreSave(ParamsWriteContext ctx)
8428 {
8429 super.OnStoreSave(ctx);
8430
8431 PlayerBase player;
8432 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
8433 {
8434 ctx.Write(true); // Keep track of if we should actually read this in or not
8435 //Save quickbar item bind
8436 int itemQBIndex = -1;
8437 itemQBIndex = player.FindQuickBarEntityIndex(this);
8438 ctx.Write(itemQBIndex);
8439 }
8440 else
8441 {
8442 ctx.Write(false); // Keep track of if we should actually read this in or not
8443 }
8444
8445 SaveAgents(ctx);//agent trasmission system
8446
8447 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
8448 if (raib)
8449 {
8450 raib.OnStoreSave(ctx);
8451 }
8452 }
8453 //----------------------------------------------------------------
8454
8455 override void AfterStoreLoad()
8456 {
8457 super.AfterStoreLoad();
8458
8460 {
8462 }
8463
8464 if (GetStoreLoadedQuantity() != float.LOWEST)
8465 {
8467 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
8468 }
8469 }
8470
8471 override void EEOnAfterLoad()
8472 {
8473 super.EEOnAfterLoad();
8474
8476 {
8477 m_FixDamageSystemInit = false;
8478 }
8479
8482 }
8483
8484 bool CanBeDisinfected()
8485 {
8486 return false;
8487 }
8488
8489
8490 //----------------------------------------------------------------
8491 override void OnVariablesSynchronized()
8492 {
8493 if (m_Initialized)
8494 {
8495 #ifdef PLATFORM_CONSOLE
8496 //bruteforce it is
8497 if (IsSplitable())
8498 {
8499 UIScriptedMenu menu = g_Game.GetUIManager().FindMenu(MENU_INVENTORY);
8500 if (menu)
8501 {
8502 menu.Refresh();
8503 }
8504 }
8505 #endif
8506 }
8507
8509 {
8510 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
8511 m_WantPlayImpactSound = false;
8512 }
8513
8515 {
8516 SetWeightDirty();
8518 }
8519 if (m_VarWet != m_VarWetPrev)
8520 {
8523 }
8524
8525 if (m_SoundSyncPlay != 0)
8526 {
8529
8530 m_SoundSyncPlay = 0;
8531 m_SoundSyncSlotID = -1;
8532 }
8533 if (m_SoundSyncStop != 0)
8534 {
8536 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
8537 m_SoundSyncStop = 0;
8538 }
8539
8540 super.OnVariablesSynchronized();
8541 }
8542
8543 //------------------------- Quantity
8544 //----------------------------------------------------------------
8546 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
8547 {
8548 if (!IsServerCheck(allow_client))
8549 return false;
8550
8551 if (!HasQuantity())
8552 return false;
8553
8554 float min = GetQuantityMin();
8555 float max = GetQuantityMax();
8556
8557 if (value <= (min + 0.001))
8558 value = min;
8559
8560 if (value == min)
8561 {
8562 if (destroy_config)
8563 {
8564 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
8565 if (dstr)
8566 {
8567 m_VarQuantity = Math.Clamp(value, min, max);
8568 this.Delete();
8569 return true;
8570 }
8571 }
8572 else if (destroy_forced)
8573 {
8574 m_VarQuantity = Math.Clamp(value, min, max);
8575 this.Delete();
8576 return true;
8577 }
8578 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
8579 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
8580 }
8581
8582 float delta = m_VarQuantity;
8583 m_VarQuantity = Math.Clamp(value, min, max);
8584
8585 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
8586 {
8587 EntityAI parent = GetHierarchyRoot();
8588 InventoryLocation iLoc = new InventoryLocation();
8589 GetInventory().GetCurrentInventoryLocation(iLoc);
8590 if (iLoc && iLoc.IsValid() && delta != m_VarQuantity)
8591 {
8592 int iLocSlot = iLoc.GetSlot();
8593 if (delta < m_VarQuantity && iLoc.GetType() != InventoryLocationType.GROUND)
8594 {
8595 StartItemSoundServer(SoundConstants.ITEM_ATTACH, iLocSlot);
8596 }
8597 if (delta > m_VarQuantity && m_VarQuantity != 0 && !IsPrepareToDelete() && iLoc.GetType() == InventoryLocationType.ATTACHMENT)
8598 {
8599 StartItemSoundServer(SoundConstants.ITEM_DETACH, iLocSlot);
8600 }
8601 }
8602 }
8603
8604 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
8605 {
8606 delta = m_VarQuantity - delta;
8607
8608 if (delta)
8609 OnQuantityChanged(delta);
8610 }
8611
8612 SetVariableMask(VARIABLE_QUANTITY);
8613
8614 return false;
8615 }
8616
8617 //----------------------------------------------------------------
8619 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
8620 {
8621 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
8622 }
8623 //----------------------------------------------------------------
8624 void SetQuantityMax()
8625 {
8626 float max = GetQuantityMax();
8627 SetQuantity(max);
8628 }
8629
8630 override void SetQuantityToMinimum()
8631 {
8632 float min = GetQuantityMin();
8633 SetQuantity(min);
8634 }
8635 //----------------------------------------------------------------
8637 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
8638 {
8639 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
8640 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
8641 SetQuantity(result, destroy_config, destroy_forced);
8642 }
8643
8644 //----------------------------------------------------------------
8646 override float GetQuantityNormalized()
8647 {
8648 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
8649 }
8650
8652 {
8653 return GetQuantityNormalized();
8654 }
8655
8656 /*void SetAmmoNormalized(float value)
8657 {
8658 float value_clamped = Math.Clamp(value, 0, 1);
8659 Magazine this_mag = Magazine.Cast(this);
8660 int max_rounds = this_mag.GetAmmoMax();
8661 int result = value * max_rounds;//can the rounded if higher precision is required
8662 this_mag.SetAmmoCount(result);
8663 }*/
8664 //----------------------------------------------------------------
8665 override int GetQuantityMax()
8666 {
8667 int slot = -1;
8668 GameInventory inventory = GetInventory();
8669 if (inventory)
8670 {
8671 InventoryLocation il = new InventoryLocation;
8672 inventory.GetCurrentInventoryLocation(il);
8673 slot = il.GetSlot();
8674 }
8675
8676 return GetTargetQuantityMax(slot);
8677 }
8678
8679 override int GetTargetQuantityMax(int attSlotID = -1)
8680 {
8681 float quantity_max = 0;
8682
8683 if (IsSplitable()) //only stackable/splitable items can check for stack size
8684 {
8685 if (attSlotID != -1)
8686 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
8687
8688 if (quantity_max <= 0)
8689 quantity_max = m_VarStackMax;
8690 }
8691
8692 if (quantity_max <= 0)
8693 quantity_max = m_VarQuantityMax;
8694
8695 return quantity_max;
8696 }
8697 //----------------------------------------------------------------
8698 override int GetQuantityMin()
8699 {
8700 return m_VarQuantityMin;
8701 }
8702 //----------------------------------------------------------------
8703 int GetQuantityInit()
8704 {
8705 return m_VarQuantityInit;
8706 }
8707
8708 //----------------------------------------------------------------
8709 override bool HasQuantity()
8710 {
8711 return !(GetQuantityMax() - GetQuantityMin() == 0);
8712 }
8713
8714 override float GetQuantity()
8715 {
8716 return m_VarQuantity;
8717 }
8718
8719 bool IsFullQuantity()
8720 {
8721 return GetQuantity() >= GetQuantityMax();
8722 }
8723
8724 //Calculates weight of single item without attachments and cargo
8725 override float GetSingleInventoryItemWeightEx()
8726 {
8727 //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
8728 float weightEx = GetWeightEx();//overall weight of the item
8729 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
8730 return weightEx - special;
8731 }
8732
8733 // Obsolete, use GetSingleInventoryItemWeightEx() instead
8735 {
8737 }
8738
8739 override protected float GetWeightSpecialized(bool forceRecalc = false)
8740 {
8741 if (IsSplitable()) //quantity determines size of the stack
8742 {
8743 #ifdef DEVELOPER
8744 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
8745 {
8746 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
8747 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
8748 }
8749 #endif
8750
8751 return GetQuantity() * GetConfigWeightModified();
8752 }
8753 else if (HasEnergyManager())// items with energy manager
8754 {
8755 #ifdef DEVELOPER
8756 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
8757 {
8758 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
8759 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
8760 }
8761 #endif
8762 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
8763 }
8764 else//everything else
8765 {
8766 #ifdef DEVELOPER
8767 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
8768 {
8769 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
8770 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
8771 }
8772 #endif
8773 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
8774 }
8775 }
8776
8778 int GetNumberOfItems()
8779 {
8780 int item_count = 0;
8781 ItemBase item;
8782
8783 GameInventory inventory = GetInventory();
8784 CargoBase cargo = inventory.GetCargo();
8785 if (cargo != NULL)
8786 {
8787 item_count = cargo.GetItemCount();
8788 }
8789
8790 int nAttachments = inventory.AttachmentCount();
8791 for (int i = 0; i < nAttachments; ++i)
8792 {
8793 Class.CastTo(item, inventory.GetAttachmentFromIndex(i));
8794 if (item)
8795 item_count += item.GetNumberOfItems();
8796 }
8797 return item_count;
8798 }
8799
8801 float GetUnitWeight(bool include_wetness = true)
8802 {
8803 float weight = 0;
8804 float wetness = 1;
8805 if (include_wetness)
8806 wetness += GetWet();
8807 if (IsSplitable()) //quantity determines size of the stack
8808 {
8809 weight = wetness * m_ConfigWeight;
8810 }
8811 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
8812 {
8813 weight = 1;
8814 }
8815 return weight;
8816 }
8817
8818 //-----------------------------------------------------------------
8819
8820 override void ClearInventory()
8821 {
8822 GameInventory inventory = GetInventory();
8823 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && inventory)
8824 {
8825 array<EntityAI> items = new array<EntityAI>;
8826 inventory.EnumerateInventory(InventoryTraversalType.INORDER, items);
8827 for (int i = 0; i < items.Count(); ++i)
8828 {
8829 ItemBase item = ItemBase.Cast(items.Get(i));
8830 if (item)
8831 {
8832 g_Game.ObjectDelete(item);
8833 }
8834 }
8835 }
8836 }
8837
8838 //------------------------- Energy
8839
8840 //----------------------------------------------------------------
8841 float GetEnergy()
8842 {
8843 float energy = 0;
8844 if (HasEnergyManager())
8845 {
8846 energy = GetCompEM().GetEnergy();
8847 }
8848 return energy;
8849 }
8850
8851
8852 override void OnEnergyConsumed()
8853 {
8854 super.OnEnergyConsumed();
8855
8857 }
8858
8859 override void OnEnergyAdded()
8860 {
8861 super.OnEnergyAdded();
8862
8864 }
8865
8866 // Converts energy (from Energy Manager) to quantity, if enabled.
8868 {
8869 if (g_Game.IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
8870 {
8871 if (HasQuantity())
8872 {
8873 float energy_0to1 = GetCompEM().GetEnergy0To1();
8874 SetQuantityNormalized(energy_0to1);
8875 }
8876 }
8877 }
8878
8879 //----------------------------------------------------------------
8880 float GetHeatIsolationInit()
8881 {
8882 return ConfigGetFloat("heatIsolation");
8883 }
8884
8885 float GetHeatIsolation()
8886 {
8887 return m_HeatIsolation;
8888 }
8889
8890 float GetDryingIncrement(string pIncrementName)
8891 {
8892 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
8893 if (g_Game.ConfigIsExisting(paramPath))
8894 return g_Game.ConfigGetFloat(paramPath);
8895
8896 return 0.0;
8897 }
8898
8899 float GetSoakingIncrement(string pIncrementName)
8900 {
8901 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
8902 if (g_Game.ConfigIsExisting(paramPath))
8903 return g_Game.ConfigGetFloat(paramPath);
8904
8905 return 0.0;
8906 }
8907 //----------------------------------------------------------------
8908 override void SetWet(float value, bool allow_client = false)
8909 {
8910 if (!IsServerCheck(allow_client))
8911 return;
8912
8913 float min = GetWetMin();
8914 float max = GetWetMax();
8915
8916 float previousValue = m_VarWet;
8917
8918 m_VarWet = Math.Clamp(value, min, max);
8919
8920 if (previousValue != m_VarWet)
8921 {
8922 SetVariableMask(VARIABLE_WET);
8923 OnWetChanged(m_VarWet, previousValue);
8924 }
8925 }
8926 //----------------------------------------------------------------
8927 override void AddWet(float value)
8928 {
8929 SetWet(GetWet() + value);
8930 }
8931 //----------------------------------------------------------------
8932 override void SetWetMax()
8933 {
8935 }
8936 //----------------------------------------------------------------
8937 override float GetWet()
8938 {
8939 return m_VarWet;
8940 }
8941 //----------------------------------------------------------------
8942 override float GetWetMax()
8943 {
8944 return m_VarWetMax;
8945 }
8946 //----------------------------------------------------------------
8947 override float GetWetMin()
8948 {
8949 return m_VarWetMin;
8950 }
8951 //----------------------------------------------------------------
8952 override float GetWetInit()
8953 {
8954 return m_VarWetInit;
8955 }
8956 //----------------------------------------------------------------
8957 override void OnWetChanged(float newVal, float oldVal)
8958 {
8959 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
8960 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
8961 if (newLevel != oldLevel)
8962 {
8963 OnWetLevelChanged(newLevel,oldLevel);
8964 }
8965 }
8966
8967 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
8968 {
8969 SetWeightDirty();
8970 }
8971
8972 override EWetnessLevel GetWetLevel()
8973 {
8974 return GetWetLevelInternal(m_VarWet);
8975 }
8976
8977 //----------------------------------------------------------------
8978
8979 override void SetStoreLoad(bool value)
8980 {
8981 m_IsStoreLoad = value;
8982 }
8983
8984 override bool IsStoreLoad()
8985 {
8986 return m_IsStoreLoad;
8987 }
8988
8989 override void SetStoreLoadedQuantity(float value)
8990 {
8991 m_StoreLoadedQuantity = value;
8992 }
8993
8994 override float GetStoreLoadedQuantity()
8995 {
8996 return m_StoreLoadedQuantity;
8997 }
8998
8999 //----------------------------------------------------------------
9000
9001 float GetItemModelLength()
9002 {
9003 if (ConfigIsExisting("itemModelLength"))
9004 {
9005 return ConfigGetFloat("itemModelLength");
9006 }
9007 return 0;
9008 }
9009
9010 float GetItemAttachOffset()
9011 {
9012 if (ConfigIsExisting("itemAttachOffset"))
9013 {
9014 return ConfigGetFloat("itemAttachOffset");
9015 }
9016 return 0;
9017 }
9018
9019 override void SetCleanness(int value, bool allow_client = false)
9020 {
9021 if (!IsServerCheck(allow_client))
9022 return;
9023
9024 int previousValue = m_Cleanness;
9025
9026 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
9027
9028 if (previousValue != m_Cleanness)
9029 SetVariableMask(VARIABLE_CLEANNESS);
9030 }
9031
9032 override int GetCleanness()
9033 {
9034 return m_Cleanness;
9035 }
9036
9038 {
9039 return true;
9040 }
9041
9042 //----------------------------------------------------------------
9043 // ATTACHMENT LOCKING
9044 // Getters relevant to generic ActionLockAttachment
9045 int GetLockType()
9046 {
9047 return m_LockType;
9048 }
9049
9050 string GetLockSoundSet()
9051 {
9052 return m_LockSoundSet;
9053 }
9054
9055 //----------------------------------------------------------------
9056 //------------------------- Color
9057 // sets items color variable given color components
9058 override void SetColor(int r, int g, int b, int a)
9059 {
9064 SetVariableMask(VARIABLE_COLOR);
9065 }
9067 override void GetColor(out int r,out int g,out int b,out int a)
9068 {
9073 }
9074
9075 bool IsColorSet()
9076 {
9077 return IsVariableSet(VARIABLE_COLOR);
9078 }
9079
9081 string GetColorString()
9082 {
9083 int r,g,b,a;
9084 GetColor(r,g,b,a);
9085 r = r/255;
9086 g = g/255;
9087 b = b/255;
9088 a = a/255;
9089 return MiscGameplayFunctions.GetColorString(r, g, b, a);
9090 }
9091 //----------------------------------------------------------------
9092 //------------------------- LiquidType
9093
9094 override void SetLiquidType(int value, bool allow_client = false)
9095 {
9096 if (!IsServerCheck(allow_client))
9097 return;
9098
9099 int old = m_VarLiquidType;
9100 m_VarLiquidType = value;
9101 OnLiquidTypeChanged(old,value);
9102 SetVariableMask(VARIABLE_LIQUIDTYPE);
9103 }
9104
9105 int GetLiquidTypeInit()
9106 {
9107 return ConfigGetInt("varLiquidTypeInit");
9108 }
9109
9110 override int GetLiquidType()
9111 {
9112 return m_VarLiquidType;
9113 }
9114
9115 protected void OnLiquidTypeChanged(int oldType, int newType)
9116 {
9117 if (newType == LIQUID_NONE && GetIsFrozen())
9118 SetFrozen(false);
9119 }
9120
9122 void UpdateQuickbarShortcutVisibility(PlayerBase player)
9123 {
9124 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
9125 }
9126
9127 // -------------------------------------------------------------------------
9129 void OnInventoryEnter(Man player)
9130 {
9131 PlayerBase nplayer;
9132 if (PlayerBase.CastTo(nplayer, player))
9133 {
9134 m_CanPlayImpactSound = true;
9135 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
9136 }
9137 }
9138
9139 // -------------------------------------------------------------------------
9141 void OnInventoryExit(Man player)
9142 {
9143 PlayerBase nplayer;
9144 if (PlayerBase.CastTo(nplayer,player))
9145 {
9146 nplayer.SetEnableQuickBarEntityShortcut(this, false);
9147 }
9148
9149 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
9150
9151 if (HasEnergyManager())
9152 {
9153 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
9154 }
9155 }
9156
9157 // ADVANCED PLACEMENT EVENTS
9158 override void OnPlacementStarted(Man player)
9159 {
9160 super.OnPlacementStarted(player);
9161
9162 SetTakeable(false);
9163 }
9164
9165 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
9166 {
9167 if (m_AdminLog)
9168 {
9169 m_AdminLog.OnPlacementComplete(player, this);
9170 }
9171
9172 super.OnPlacementComplete(player, position, orientation);
9173 }
9174
9175 //-----------------------------
9176 // AGENT SYSTEM
9177 //-----------------------------
9178 //--------------------------------------------------------------------------
9179 bool ContainsAgent(int agent_id)
9180 {
9181 if (agent_id & m_AttachedAgents)
9182 {
9183 return true;
9184 }
9185 else
9186 {
9187 return false;
9188 }
9189 }
9190
9191 //--------------------------------------------------------------------------
9192 override void RemoveAgent(int agent_id)
9193 {
9194 if (ContainsAgent(agent_id))
9195 {
9196 m_AttachedAgents = ~agent_id & m_AttachedAgents;
9197 }
9198 }
9199
9200 //--------------------------------------------------------------------------
9201 override void RemoveAllAgents()
9202 {
9203 m_AttachedAgents = 0;
9204 }
9205 //--------------------------------------------------------------------------
9206 override void RemoveAllAgentsExcept(int agent_to_keep)
9207 {
9208 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
9209 }
9210 // -------------------------------------------------------------------------
9211 override void InsertAgent(int agent, float count = 1)
9212 {
9213 if (count < 1)
9214 return;
9215 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
9217 }
9218
9220 void TransferAgents(int agents)
9221 {
9223 }
9224
9225 // -------------------------------------------------------------------------
9226 override int GetAgents()
9227 {
9228 return m_AttachedAgents;
9229 }
9230 //----------------------------------------------------------------------
9231
9232 /*int GetContaminationType()
9233 {
9234 int contamination_type;
9235
9236 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
9237 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
9238 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
9239 const int DIRTY_MASK = eAgents.WOUND_AGENT;
9240
9241 Edible_Base edible = Edible_Base.Cast(this);
9242 int agents = GetAgents();
9243 if (edible)
9244 {
9245 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
9246 if (profile)
9247 {
9248 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
9249 }
9250 }
9251 if (agents & CONTAMINATED_MASK)
9252 {
9253 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
9254 }
9255 if (agents & POISONED_MASK)
9256 {
9257 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
9258 }
9259 if (agents & NERVE_GAS_MASK)
9260 {
9261 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
9262 }
9263 if (agents & DIRTY_MASK)
9264 {
9265 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
9266 }
9267
9268 return agents;
9269 }*/
9270
9271 // -------------------------------------------------------------------------
9272 bool LoadAgents(ParamsReadContext ctx, int version)
9273 {
9274 if (!ctx.Read(m_AttachedAgents))
9275 return false;
9276 return true;
9277 }
9278 // -------------------------------------------------------------------------
9280 {
9281
9283 }
9284 // -------------------------------------------------------------------------
9285
9287 override void CheckForRoofLimited(float timeTresholdMS = 3000)
9288 {
9289 super.CheckForRoofLimited(timeTresholdMS);
9290
9291 float time = g_Game.GetTime();
9292 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
9293 {
9294 m_PreviousRoofTestTime = time;
9295 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
9296 }
9297 }
9298
9299 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
9300 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
9301 {
9302 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
9303 {
9304 return 0;
9305 }
9306
9307 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
9308 {
9309 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
9310 if (filter)
9311 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
9312 else
9313 return 0;//otherwise return 0 when no filter attached
9314 }
9315
9316 string subclassPath, entryName;
9317
9318 switch (type)
9319 {
9320 case DEF_BIOLOGICAL:
9321 entryName = "biological";
9322 break;
9323 case DEF_CHEMICAL:
9324 entryName = "chemical";
9325 break;
9326 default:
9327 entryName = "biological";
9328 break;
9329 }
9330
9331 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
9332
9333 return g_Game.ConfigGetFloat(subclassPath + entryName);
9334 }
9335
9336
9337
9339 override void EEOnCECreate()
9340 {
9341 if (!IsMagazine())
9343
9345 }
9346
9347
9348 //-------------------------
9349 // OPEN/CLOSE USER ACTIONS
9350 //-------------------------
9352 void Open();
9353 void Close();
9354 bool IsOpen()
9355 {
9356 return true;
9357 }
9358
9359 override bool CanDisplayCargo()
9360 {
9361 return IsOpen();
9362 }
9363
9364
9365 // ------------------------------------------------------------
9366 // CONDITIONS
9367 // ------------------------------------------------------------
9368 override bool CanPutInCargo(EntityAI parent)
9369 {
9370 if (parent)
9371 {
9372 if (parent.IsInherited(DayZInfected))
9373 return true;
9374
9375 if (!parent.IsRuined())
9376 return true;
9377 }
9378
9379 return true;
9380 }
9381
9382 override bool CanPutAsAttachment(EntityAI parent)
9383 {
9384 if (!super.CanPutAsAttachment(parent))
9385 {
9386 return false;
9387 }
9388
9389 if (!IsRuined() && !parent.IsRuined())
9390 {
9391 return true;
9392 }
9393
9394 return false;
9395 }
9396
9397 override bool CanReceiveItemIntoCargo(EntityAI item)
9398 {
9399 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9400 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9401 // return false;
9402
9403 return super.CanReceiveItemIntoCargo(item);
9404 }
9405
9406 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
9407 {
9408 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9409 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9410 // return false;
9411
9412 GameInventory attachmentInv = attachment.GetInventory();
9413 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
9414 {
9415 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
9416 return false;
9417 }
9418
9419 InventoryLocation loc = new InventoryLocation();
9420 attachment.GetInventory().GetCurrentInventoryLocation(loc);
9421 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
9422 return false;
9423
9424 return super.CanReceiveAttachment(attachment, slotId);
9425 }
9426
9427 override bool CanReleaseAttachment(EntityAI attachment)
9428 {
9429 if (!super.CanReleaseAttachment(attachment))
9430 return false;
9431
9432 return GetInventory().AreChildrenAccessible();
9433 }
9434
9435 /*override bool CanLoadAttachment(EntityAI attachment)
9436 {
9437 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9438 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9439 // return false;
9440
9441 GameInventory attachmentInv = attachment.GetInventory();
9442 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
9443 {
9444 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
9445 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
9446
9447 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
9448 return false;
9449 }
9450
9451 return super.CanLoadAttachment(attachment);
9452 }*/
9453
9454 // Plays muzzle flash particle effects
9455 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9456 {
9457 int id = muzzle_owner.GetMuzzleID();
9458 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
9459
9460 if (WPOF_array)
9461 {
9462 for (int i = 0; i < WPOF_array.Count(); i++)
9463 {
9464 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
9465
9466 if (WPOF)
9467 {
9468 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
9469 }
9470 }
9471 }
9472 }
9473
9474 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
9475 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9476 {
9477 int id = muzzle_owner.GetMuzzleID();
9478 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
9479
9480 if (WPOBE_array)
9481 {
9482 for (int i = 0; i < WPOBE_array.Count(); i++)
9483 {
9484 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
9485
9486 if (WPOBE)
9487 {
9488 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
9489 }
9490 }
9491 }
9492 }
9493
9494 // Plays all weapon overheating particles
9495 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9496 {
9497 int id = muzzle_owner.GetMuzzleID();
9498 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9499
9500 if (WPOOH_array)
9501 {
9502 for (int i = 0; i < WPOOH_array.Count(); i++)
9503 {
9504 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9505
9506 if (WPOOH)
9507 {
9508 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
9509 }
9510 }
9511 }
9512 }
9513
9514 // Updates all weapon overheating particles
9515 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9516 {
9517 int id = muzzle_owner.GetMuzzleID();
9518 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9519
9520 if (WPOOH_array)
9521 {
9522 for (int i = 0; i < WPOOH_array.Count(); i++)
9523 {
9524 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9525
9526 if (WPOOH)
9527 {
9528 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
9529 }
9530 }
9531 }
9532 }
9533
9534 // Stops overheating particles
9535 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9536 {
9537 int id = muzzle_owner.GetMuzzleID();
9538 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9539
9540 if (WPOOH_array)
9541 {
9542 for (int i = 0; i < WPOOH_array.Count(); i++)
9543 {
9544 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9545
9546 if (WPOOH)
9547 {
9548 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
9549 }
9550 }
9551 }
9552 }
9553
9554 //----------------------------------------------------------------
9555 //Item Behaviour - unified approach
9556 override bool IsHeavyBehaviour()
9557 {
9558 if (m_ItemBehaviour == 0)
9559 {
9560 return true;
9561 }
9562
9563 return false;
9564 }
9565
9566 override bool IsOneHandedBehaviour()
9567 {
9568 if (m_ItemBehaviour == 1)
9569 {
9570 return true;
9571 }
9572
9573 return false;
9574 }
9575
9576 override bool IsTwoHandedBehaviour()
9577 {
9578 if (m_ItemBehaviour == 2)
9579 {
9580 return true;
9581 }
9582
9583 return false;
9584 }
9585
9586 bool IsDeployable()
9587 {
9588 return false;
9589 }
9590
9592 float GetDeployTime()
9593 {
9594 return UATimeSpent.DEFAULT_DEPLOY;
9595 }
9596
9597
9598 //----------------------------------------------------------------
9599 // Item Targeting (User Actions)
9600 override void SetTakeable(bool pState)
9601 {
9602 m_IsTakeable = pState;
9603 SetSynchDirty();
9604 }
9605
9606 override bool IsTakeable()
9607 {
9608 return m_IsTakeable;
9609 }
9610
9611 // For cases where we want to show object widget which cant be taken to hands
9613 {
9614 return false;
9615 }
9616
9618 protected void PreLoadSoundAttachmentType()
9619 {
9620 string att_type = "None";
9621
9622 if (ConfigIsExisting("soundAttType"))
9623 {
9624 att_type = ConfigGetString("soundAttType");
9625 }
9626
9627 m_SoundAttType = att_type;
9628 }
9629
9630 override string GetAttachmentSoundType()
9631 {
9632 return m_SoundAttType;
9633 }
9634
9635 //----------------------------------------------------------------
9636 //SOUNDS - ItemSoundHandler
9637 //----------------------------------------------------------------
9638
9639 string GetPlaceSoundset(); // played when deploy starts
9640 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
9641 string GetDeploySoundset(); // played when deploy sucessfully finishes
9642 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
9643 string GetFoldSoundset(); // played when fold sucessfully finishes
9644
9646 {
9647 if (!m_ItemSoundHandler)
9649
9650 return m_ItemSoundHandler;
9651 }
9652
9653 // override to initialize sounds
9654 protected void InitItemSounds()
9655 {
9656 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty && !GetInventoryItemType().SetDetachSoundEvent() && !GetInventoryItemType().SetAttachSoundEvent())
9657 return;
9658
9660
9661 if (GetPlaceSoundset() != string.Empty)
9662 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
9663
9664 if (GetDeploySoundset() != string.Empty)
9665 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
9666
9667 SoundParameters params = new SoundParameters();
9668 params.m_Loop = true;
9669 if (GetLoopDeploySoundset() != string.Empty)
9670 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
9671 }
9672
9673 // Start sound using ItemSoundHandler
9674 void StartItemSoundServer(int id, int slotId)
9675 {
9676 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
9677 {
9678 m_SoundSyncSlotID = slotId;
9679 m_SoundSyncPlay = id;
9680
9681 SetSynchDirty();
9682
9683 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
9684 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStartItemSoundServer, 100);
9685 }
9686 }
9687
9688 void StartItemSoundServer(int id)
9689 {
9690 StartItemSoundServer(id, InventorySlots.INVALID);
9691 }
9692
9693 // Stop sound using ItemSoundHandler
9694 void StopItemSoundServer(int id)
9695 {
9696 if (!g_Game.IsServer())
9697 return;
9698
9699 m_SoundSyncStop = id;
9700 SetSynchDirty();
9701
9702 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
9703 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStopItemSoundServer, 100);
9704 }
9705
9706 protected void ClearStartItemSoundServer()
9707 {
9708 m_SoundSyncPlay = 0;
9709 m_SoundSyncSlotID = InventorySlots.INVALID;
9710 }
9711
9712 protected void ClearStopItemSoundServer()
9713 {
9714 m_SoundSyncStop = 0;
9715 }
9716
9717 void OnApply(PlayerBase player);
9718
9720 {
9721 return 1.0;
9722 };
9723 //returns applicable selection
9724 array<string> GetHeadHidingSelection()
9725 {
9727 }
9728
9730 {
9732 }
9733
9734 WrittenNoteData GetWrittenNoteData() {};
9735
9737 {
9738 SetDynamicPhysicsLifeTime(0.01);
9739 m_ItemBeingDroppedPhys = false;
9740 }
9741
9743 {
9744 array<string> zone_names = new array<string>;
9745 GetDamageZones(zone_names);
9746 for (int i = 0; i < zone_names.Count(); i++)
9747 {
9748 SetHealthMax(zone_names.Get(i),"Health");
9749 }
9750 SetHealthMax("","Health");
9751 }
9752
9754 void SetZoneDamageCEInit()
9755 {
9756 float global_health = GetHealth01("","Health");
9757 array<string> zones = new array<string>;
9758 GetDamageZones(zones);
9759 //set damage of all zones to match global health level
9760 for (int i = 0; i < zones.Count(); i++)
9761 {
9762 SetHealth01(zones.Get(i),"Health",global_health);
9763 }
9764 }
9765
9767 bool IsCoverFaceForShave(string slot_name)
9768 {
9769 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
9770 }
9771
9772 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
9773 {
9774 if (!hasRootAsPlayer)
9775 {
9776 if (refParentIB)
9777 {
9778 // parent is wet
9779 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
9780 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
9781 // parent has liquid inside
9782 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
9783 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
9784 // drying
9785 else if (m_VarWet > m_VarWetMin)
9786 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
9787 }
9788 else
9789 {
9790 // drying on ground or inside non-itembase (car, ...)
9791 if (m_VarWet > m_VarWetMin)
9792 AddWet(-1 * delta * GetDryingIncrement("ground"));
9793 }
9794 }
9795 }
9796
9797 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
9798 {
9800 {
9801 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
9802 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
9803 {
9804 float heatPermCoef = 1.0;
9805 EntityAI ent = this;
9806 while (ent)
9807 {
9808 heatPermCoef *= ent.GetHeatPermeabilityCoef();
9809 ent = ent.GetHierarchyParent();
9810 }
9811
9812 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
9813 }
9814 }
9815 }
9816
9817 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
9818 {
9819 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
9820 EntityAI parent = GetHierarchyParent();
9821 if (!parent)
9822 {
9823 hasParent = false;
9824 hasRootAsPlayer = false;
9825 }
9826 else
9827 {
9828 hasParent = true;
9829 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
9830 refParentIB = ItemBase.Cast(parent);
9831 }
9832 }
9833
9834 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
9835 {
9836 // this is stub, implemented on Edible_Base
9837 }
9838
9839 bool CanDecay()
9840 {
9841 // return true used on selected food clases so they can decay
9842 return false;
9843 }
9844
9845 protected bool CanProcessDecay()
9846 {
9847 // this is stub, implemented on Edible_Base class
9848 // used to determine whether it is still necessary for the food to decay
9849 return false;
9850 }
9851
9852 protected bool CanHaveWetness()
9853 {
9854 // return true used on selected items that have a wetness effect
9855 return false;
9856 }
9857
9859 bool CanBeConsumed(ConsumeConditionData data = null)
9860 {
9861 return !GetIsFrozen() && IsOpen();
9862 }
9863
9864 override void ProcessVariables()
9865 {
9866 bool hasParent = false, hasRootAsPlayer = false;
9867 ItemBase refParentIB;
9868
9869 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
9870 bool foodDecay = g_Game.IsFoodDecayEnabled();
9871
9872 if (wwtu || foodDecay)
9873 {
9874 bool processWetness = wwtu && CanHaveWetness();
9875 bool processTemperature = wwtu && CanHaveTemperature();
9876 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
9877
9878 if (processWetness || processTemperature || processDecay)
9879 {
9880 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
9881
9882 if (processWetness)
9883 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
9884
9885 if (processTemperature)
9886 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
9887
9888 if (processDecay)
9889 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
9890 }
9891 }
9892 }
9893
9896 {
9897 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
9898 }
9899
9900 override float GetTemperatureFreezeThreshold()
9901 {
9903 return Liquid.GetFreezeThreshold(GetLiquidType());
9904
9905 return super.GetTemperatureFreezeThreshold();
9906 }
9907
9908 override float GetTemperatureThawThreshold()
9909 {
9911 return Liquid.GetThawThreshold(GetLiquidType());
9912
9913 return super.GetTemperatureThawThreshold();
9914 }
9915
9916 override float GetItemOverheatThreshold()
9917 {
9919 return Liquid.GetBoilThreshold(GetLiquidType());
9920
9921 return super.GetItemOverheatThreshold();
9922 }
9923
9924 override float GetTemperatureFreezeTime()
9925 {
9926 if (HasQuantity())
9927 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
9928
9929 return super.GetTemperatureFreezeTime();
9930 }
9931
9932 override float GetTemperatureThawTime()
9933 {
9934 if (HasQuantity())
9935 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
9936
9937 return super.GetTemperatureThawTime();
9938 }
9939
9941 void AffectLiquidContainerOnFill(int liquid_type, float amount);
9943 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
9944
9945 bool IsCargoException4x3(EntityAI item)
9946 {
9947 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
9948 }
9949
9951 {
9952 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
9953 }
9954
9956 void AddLightSourceItem(ItemBase lightsource)
9957 {
9958 m_LightSourceItem = lightsource;
9959 }
9960
9962 {
9963 m_LightSourceItem = null;
9964 }
9965
9967 {
9968 return m_LightSourceItem;
9969 }
9970
9972 array<int> GetValidFinishers()
9973 {
9974 return null;
9975 }
9976
9978 bool GetActionWidgetOverride(out typename name)
9979 {
9980 return false;
9981 }
9982
9983 bool PairWithDevice(notnull ItemBase otherDevice)
9984 {
9985 if (g_Game.IsServer())
9986 {
9987 ItemBase explosive = otherDevice;
9989 if (!trg)
9990 {
9991 trg = RemoteDetonatorTrigger.Cast(otherDevice);
9992 explosive = this;
9993 }
9994
9995 explosive.PairRemote(trg);
9996 trg.SetControlledDevice(explosive);
9997
9998 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
9999 trg.SetPersistentPairID(persistentID);
10000 explosive.SetPersistentPairID(persistentID);
10001
10002 return true;
10003 }
10004 return false;
10005 }
10006
10008 float GetBaitEffectivity()
10009 {
10010 float ret = 1.0;
10011 if (HasQuantity())
10012 ret *= GetQuantityNormalized();
10013 ret *= GetHealth01();
10014
10015 return ret;
10016 }
10017
10018 #ifdef DEVELOPER
10019 override void SetDebugItem()
10020 {
10021 super.SetDebugItem();
10022 _itemBase = this;
10023 }
10024
10025 override string GetDebugText()
10026 {
10027 string text = super.GetDebugText();
10028
10029 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
10030 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
10031
10032 return text;
10033 }
10034 #endif
10035
10036 bool CanBeUsedForSuicide()
10037 {
10038 return true;
10039 }
10040
10042 //DEPRECATED BELOW
10044 // Backwards compatibility
10045 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10046 {
10047 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
10048 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
10049 }
10050
10051 // replaced by ItemSoundHandler
10052 protected EffectSound m_SoundDeployFinish;
10053 protected EffectSound m_SoundPlace;
10054 protected EffectSound m_DeployLoopSoundEx;
10055 protected EffectSound m_SoundDeploy;
10056 bool m_IsPlaceSound;
10057 bool m_IsDeploySound;
10059
10060 string GetDeployFinishSoundset();
10061 void PlayDeploySound();
10062 void PlayDeployFinishSound();
10063 void PlayPlaceSound();
10064 void PlayDeployLoopSoundEx();
10065 void StopDeployLoopSoundEx();
10066 void SoundSynchRemoteReset();
10067 void SoundSynchRemote();
10068 bool UsesGlobalDeploy(){return false;}
10069 bool CanPlayDeployLoopSound(){return false;}
10071 bool IsPlaceSound(){return m_IsPlaceSound;}
10072 bool IsDeploySound(){return m_IsDeploySound;}
10073 void SetIsPlaceSound(bool is_place_sound);
10074 void SetIsDeploySound(bool is_deploy_sound);
10075
10076 [Obsolete("Use ItemSoundHandler instead")]
10078 void PlayAttachSound(string slot_type)
10079 {
10080 if (!g_Game.IsDedicatedServer())
10081 {
10082 if (ConfigIsExisting("attachSoundSet"))
10083 {
10084 string cfg_path = "";
10085 string soundset = "";
10086 string type_name = GetType();
10087
10088 TStringArray cfg_soundset_array = new TStringArray;
10089 TStringArray cfg_slot_array = new TStringArray;
10090 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
10091 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
10092
10093 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
10094 {
10095 for (int i = 0; i < cfg_soundset_array.Count(); i++)
10096 {
10097 if (cfg_slot_array[i] == slot_type)
10098 {
10099 soundset = cfg_soundset_array[i];
10100 break;
10101 }
10102 }
10103 }
10104
10105 if (soundset != "")
10106 {
10107 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
10108 sound.SetAutodestroy(true);
10109 }
10110 }
10111 }
10112 }
10113
10114 void PlayDetachSound(string slot_type) {}
10115}
10116
10117EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
10118{
10119 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
10120 if (entity)
10121 {
10122 bool is_item = entity.IsInherited(ItemBase);
10123 if (is_item && full_quantity)
10124 {
10125 ItemBase item = ItemBase.Cast(entity);
10126 item.SetQuantity(item.GetQuantityInit());
10127 }
10128 }
10129 else
10130 {
10131 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
10132 return NULL;
10133 }
10134 return entity;
10135}
10136
10137void SetupSpawnedItem(ItemBase item, float health, float quantity)
10138{
10139 if (item)
10140 {
10141 if (health > 0)
10142 item.SetHealth("", "", health);
10143
10144 if (item.CanHaveTemperature())
10145 {
10146 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
10147 if (item.CanFreeze())
10148 item.SetFrozen(false);
10149 }
10150
10151 if (item.HasEnergyManager())
10152 {
10153 if (quantity >= 0)
10154 {
10155 item.GetCompEM().SetEnergy0To1(quantity);
10156 }
10157 else
10158 {
10159 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
10160 }
10161 }
10162 else if (item.IsMagazine())
10163 {
10164 Magazine mag = Magazine.Cast(item);
10165 if (quantity >= 0)
10166 {
10167 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
10168 }
10169 else
10170 {
10171 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
10172 }
10173
10174 }
10175 else
10176 {
10177 if (quantity >= 0)
10178 {
10179 item.SetQuantityNormalized(quantity, false);
10180 }
10181 else
10182 {
10183 item.SetQuantity(Math.AbsFloat(quantity));
10184 }
10185
10186 }
10187 }
10188}
10189
10190#ifdef DEVELOPER
10191ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
10192#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()