diff --git a/EXILED/Exiled.API/Features/Items/Firearm.cs b/EXILED/Exiled.API/Features/Items/Firearm.cs index 9be7967728..76216619cc 100644 --- a/EXILED/Exiled.API/Features/Items/Firearm.cs +++ b/EXILED/Exiled.API/Features/Items/Firearm.cs @@ -162,11 +162,6 @@ public int BarrelAmmo } } - /// - /// Gets the total amount of ammo in the firearm. - /// - public int TotalAmmo => Base.GetTotalStoredAmmo(); - /// /// Gets or sets the max ammo for this firearm. /// @@ -194,12 +189,96 @@ public int MaxBarrelAmmo } /// - /// Gets the total amount of ammo in the firearm. + /// Gets or sets the maximum amount of ammo in the firearm. + /// + [Obsolete("Use MaxAmmo instead.")] + public int TotalMaxAmmo + { + get => MaxAmmo; + set => MaxAmmo = value; + } + + /// + /// Gets or sets the amount of ammo in the firearm. + /// + [Obsolete("Use Ammo instead.")] + public int TotalAmmo + { + get => Ammo; + set => Ammo = value; + } + + /// + /// Gets or sets the maximum amount of ammo in the firearm. + /// + public int MaxAmmo + { + get => Base.GetTotalMaxAmmo(); + set + { + int difference = value - MaxAmmo; + PrimaryMagazine.MaxAmmo = Mathf.Clamp(PrimaryMagazine.MaxAmmo + difference, 0, byte.MaxValue); + } + } + + /// + /// Gets or sets the amount of ammo in the firearm. /// - public int TotalMaxAmmo => Base.GetTotalMaxAmmo(); + public int Ammo + { + get => Base.GetTotalStoredAmmo(); + set + { + // Magazines that contain most of the ammo and can be reloaded + PrimaryMagazine primaryContainer = PrimaryMagazine; + + // Barrels that may contain some ammo in them + var automaticActionBarrel = BarrelMagazine as AutomaticBarrelMagazine; + + // Other type of barrels that also contain ammo but don't have AmmoStored setter + var pumpActionBarrel = BarrelMagazine as PumpBarrelMagazine; + + value = Mathf.Clamp(value, 0, Base is ParticleDisruptor ? 254 : byte.MaxValue); + + // Set everything to 0 + if (primaryContainer is not null) + { + primaryContainer.Ammo = 0; + } + + if (automaticActionBarrel is not null) + { + automaticActionBarrel.Ammo = 0; + } + else if (pumpActionBarrel is not null) + { + pumpActionBarrel.CockedAmmo = 0; + pumpActionBarrel.Ammo = 0; + } + + if (value == 0) + return; + + // Distribute the ammo between containers + if (primaryContainer is not null) + { + var addedAmmo = Mathf.Clamp(byte.MaxValue - primaryContainer.Ammo, 0, value); + primaryContainer.Ammo = addedAmmo; + } + else if (pumpActionBarrel is not null) + { + var addedAmmo = Mathf.Clamp(byte.MaxValue - pumpActionBarrel.Ammo, 0, value); + pumpActionBarrel.Ammo = addedAmmo; + } + + // Reload action modules + pumpActionBarrel?.PumpBarrel.Pump(); + automaticActionBarrel?.AutomaticBarrel.ServerCycleAction(); + } + } /// - /// Gets or sets a ammo drain per shoot. + /// Gets or sets the ammo drain per shoot. /// /// /// Always by default. @@ -225,7 +304,7 @@ public int MaxBarrelAmmo /// /// Gets a value indicating whether the firearm is being aimed. /// - public bool Aiming => Base.TryGetModule(out LinearAdsModule module) && module.AdsTarget; + public bool Aiming => Base.TryGetModule(out IAdsModule module) && module.AdsTarget; /// /// Gets a value indicating whether the firearm's flashlight module is enabled. @@ -297,6 +376,178 @@ public RecoilSettings Recoil public static Firearm Create(FirearmType type) => type is not FirearmType.None ? (Firearm)Create(type.GetItemType()) : null; + /// + /// Adds or replaces an existing preference to the . + /// + /// The of which must be added. + /// The to add. + /// The [] to add. + public static void AddPreference(Player player, FirearmType itemType, AttachmentIdentifier[] attachments) + { + foreach (KeyValuePair> kvp in PlayerPreferences) + { + if (kvp.Key != player) + continue; + + if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) + dictionary[itemType.GetItemType()] = attachments.GetAttachmentsCode(); + } + } + + /// + /// Adds or replaces an existing preference to the . + /// + /// The of which must be added. + /// The of and [] to add. + public static void AddPreference(Player player, KeyValuePair preference) => AddPreference(player, preference.Key, preference.Value); + + /// + /// Adds or replaces an existing preference to the . + /// + /// The of which must be added. + /// The of and [] to add. + public static void AddPreference(Player player, Dictionary preference) + { + foreach (KeyValuePair kvp in preference) + AddPreference(player, kvp); + } + + /// + /// Adds or replaces an existing preference to the . + /// + /// The of of which must be added. + /// The to add. + /// The [] to add. + public static void AddPreference(IEnumerable players, FirearmType type, AttachmentIdentifier[] attachments) + { + foreach (Player player in players) + AddPreference(player, type, attachments); + } + + /// + /// Adds or replaces an existing preference to the . + /// + /// The of of which must be added. + /// The of and [] to add. + public static void AddPreference(IEnumerable players, KeyValuePair preference) + { + foreach (Player player in players) + AddPreference(player, preference.Key, preference.Value); + } + + /// + /// Adds or replaces an existing preference to the . + /// + /// The of of which must be added. + /// The of and [] to add. + public static void AddPreference(IEnumerable players, Dictionary preference) + { + foreach ((Player player, KeyValuePair kvp) in players.SelectMany(player => preference.Select(kvp => (player, kvp)))) + AddPreference(player, kvp); + } + + /// + /// Removes a preference from the if it already exists. + /// + /// The of which must be removed. + /// The to remove. + public static void RemovePreference(Player player, FirearmType type) + { + foreach (KeyValuePair> kvp in PlayerPreferences) + { + if (kvp.Key != player) + continue; + + if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) + dictionary[type.GetItemType()] = type.GetBaseCode(); + } + } + + /// + /// Removes a preference from the if it already exists. + /// + /// The of of which must be removed. + /// The to remove. + public static void RemovePreference(IEnumerable players, FirearmType type) + { + foreach (Player player in players) + RemovePreference(player, type); + } + + /// + /// Removes a preference from the if it already exists. + /// + /// The of which must be removed. + /// The of to remove. + public static void RemovePreference(Player player, IEnumerable types) + { + foreach (FirearmType itemType in types) + RemovePreference(player, itemType); + } + + /// + /// Removes a preference from the if it already exists. + /// + /// The of of which must be removed. + /// The of to remove. + public static void RemovePreference(IEnumerable players, IEnumerable types) + { + foreach ((Player player, FirearmType firearmType) in players.SelectMany(player => types.Select(itemType => (player, itemType)))) + RemovePreference(player, firearmType); + } + + /// + /// Clears all the existing preferences from . + /// + /// The of which must be cleared. + public static void ClearPreferences(Player player) + { + if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) + { + foreach (KeyValuePair kvp in dictionary) + dictionary[kvp.Key] = kvp.Key.GetFirearmType().GetBaseCode(); + } + } + + /// + /// Clears all the existing preferences from . + /// + /// The of of which must be cleared. + public static void ClearPreferences(IEnumerable players) + { + foreach (Player player in players) + ClearPreferences(player); + } + + /// + /// Clears all the existing preferences from . + /// + public static void ClearPreferences() + { + foreach (Player player in Player.List) + ClearPreferences(player); + } + + /// + /// Tries to get a specific module of the . + /// + /// The type of the module to get. + /// Module if found, otherwise . + /// Whether to ignore submodules. + /// A value indicating whether the module was found. + /// + /// Modules are a part of the new firearm system. They define the behaviour of a firearm. + /// They are magazines that store ammo, barrels that shoot, and even recoil patterns. + /// By altering their settings it is possible to do almost anything with a given weapon. + /// + /// + /// + /// + /// + /// + public bool TryGetModule(out T module, bool ignoreSubmodules = true) + => Base.TryGetModule(out module, ignoreSubmodules); + /// /// Adds a to the firearm. /// @@ -496,156 +747,25 @@ public bool TryGetAttachment(AttachmentName attachmentName, out Attachment firea } /// - /// Adds or replaces an existing preference to the . - /// - /// The of which must be added. - /// The to add. - /// The [] to add. - public void AddPreference(Player player, FirearmType itemType, AttachmentIdentifier[] attachments) - { - foreach (KeyValuePair> kvp in PlayerPreferences) - { - if (kvp.Key != player) - continue; - - if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) - dictionary[itemType.GetItemType()] = attachments.GetAttachmentsCode(); - } - } - - /// - /// Adds or replaces an existing preference to the . - /// - /// The of which must be added. - /// The of and [] to add. - public void AddPreference(Player player, KeyValuePair preference) => AddPreference(player, preference.Key, preference.Value); - - /// - /// Adds or replaces an existing preference to the . + /// Gets stats of the attachments of the firearm. /// - /// The of which must be added. - /// The of and [] to add. - public void AddPreference(Player player, Dictionary preference) - { - foreach (KeyValuePair kvp in preference) - AddPreference(player, kvp); - } + /// The to get. + /// The value of the specified parameter. + public float GetAttachmentsValue(AttachmentParam parameter) => Base.AttachmentsValue(parameter); /// - /// Adds or replaces an existing preference to the . + /// Checks if the firearm has a specific advantage. /// - /// The of of which must be added. - /// The to add. - /// The [] to add. - public void AddPreference(IEnumerable players, FirearmType type, AttachmentIdentifier[] attachments) - { - foreach (Player player in players) - AddPreference(player, type, attachments); - } + /// The to check. + /// A value indicating whether the firearm has the specified advantage. + public bool HasAdvantage(AttachmentDescriptiveAdvantages flag) => Base.HasAdvantageFlag(flag); /// - /// Adds or replaces an existing preference to the . + /// Checks if the firearm has a specific downside. /// - /// The of of which must be added. - /// The of and [] to add. - public void AddPreference(IEnumerable players, KeyValuePair preference) - { - foreach (Player player in players) - AddPreference(player, preference.Key, preference.Value); - } - - /// - /// Adds or replaces an existing preference to the . - /// - /// The of of which must be added. - /// The of and [] to add. - public void AddPreference(IEnumerable players, Dictionary preference) - { - foreach ((Player player, KeyValuePair kvp) in players.SelectMany(player => preference.Select(kvp => (player, kvp)))) - AddPreference(player, kvp); - } - - /// - /// Removes a preference from the if it already exists. - /// - /// The of which must be removed. - /// The to remove. - public void RemovePreference(Player player, FirearmType type) - { - foreach (KeyValuePair> kvp in PlayerPreferences) - { - if (kvp.Key != player) - continue; - - if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) - dictionary[type.GetItemType()] = type.GetBaseCode(); - } - } - - /// - /// Removes a preference from the if it already exists. - /// - /// The of of which must be removed. - /// The to remove. - public void RemovePreference(IEnumerable players, FirearmType type) - { - foreach (Player player in players) - RemovePreference(player, type); - } - - /// - /// Removes a preference from the if it already exists. - /// - /// The of which must be removed. - /// The of to remove. - public void RemovePreference(Player player, IEnumerable types) - { - foreach (FirearmType itemType in types) - RemovePreference(player, itemType); - } - - /// - /// Removes a preference from the if it already exists. - /// - /// The of of which must be removed. - /// The of to remove. - public void RemovePreference(IEnumerable players, IEnumerable types) - { - foreach ((Player player, FirearmType firearmType) in players.SelectMany(player => types.Select(itemType => (player, itemType)))) - RemovePreference(player, firearmType); - } - - /// - /// Clears all the existing preferences from . - /// - /// The of which must be cleared. - public void ClearPreferences(Player player) - { - if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) - { - foreach (KeyValuePair kvp in dictionary) - dictionary[kvp.Key] = kvp.Key.GetFirearmType().GetBaseCode(); - } - } - - /// - /// Clears all the existing preferences from . - /// - /// The of of which must be cleared. - public void ClearPreferences(IEnumerable players) - { - foreach (Player player in players) - ClearPreferences(player); - } - - /// - /// Clears all the existing preferences from . - /// - public void ClearPreferences() - { - foreach (Player player in Player.List) - ClearPreferences(player); - } + /// The to check. + /// A value indicating whether the firearm has the specified downside. + public bool HasDownside(AttachmentDescriptiveDownsides flag) => Base.HasDownsideFlag(flag); /// /// Reloads current . @@ -667,9 +787,7 @@ public void Reload() /// New object. public override Item Clone() { - Firearm cloneableItem = new(Type) - { - }; + Firearm cloneableItem = new(Type); // TODO Not finish /*