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

◆ GetDamageSystemVersionChange()

override int GetDamageSystemVersionChange ( )
private

Re-sets DamageSystem changes.

Возвращает
storage version on which the config changes occured (default -1, to be overriden!)
Заметки
Significant changes to DamageSystem in item configs have to be re-set by increasing the storage version and overriding this method. Default return is -1 (does nothing).

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

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