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

◆ ItemBase()

void SpawnItemOnLocation::ItemBase ( )
private

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

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