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

◆ RemoveAction()

void SpawnItemOnLocation::RemoveAction ( typename actionName )
private

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

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