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

◆ GetActions()

override void SpawnItemOnLocation::GetActions ( typename action_input_type ,
out array< ActionBase_Basic > actions )
private

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

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