diff --git a/Classes/Base/Dealer.cs b/Classes/BaseTypes/Dealer.cs
similarity index 100%
rename from Classes/Base/Dealer.cs
rename to Classes/BaseTypes/Dealer.cs
diff --git a/Classes/BaseTypes/NotifyBase.cs b/Classes/BaseTypes/NotifyBase.cs
new file mode 100644
index 00000000..4c2aaa70
--- /dev/null
+++ b/Classes/BaseTypes/NotifyBase.cs
@@ -0,0 +1,66 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace Los.Santos.Dope.Wars.Classes.BaseTypes;
+
+///
+/// The class.
+///
+/// The class implements the following interfaces:
+///
+/// - The members of the interface.
+/// - The members of the interface.
+///
+///
+///
+public abstract class NotifyBase : INotifyPropertyChanged, INotifyPropertyChanging
+{
+ ///
+ /// Sets a new value for a property and notifies about the change.
+ ///
+ ///
+ /// Will throw an exception of type if is .
+ ///
+ ///
+ /// The referenced field.
+ /// The new value for the property.
+ /// The property name.
+ ///
+ protected void SetProperty(ref T field, T newValue, [CallerMemberName] string? propertyName = null)
+ {
+ if (propertyName is null)
+ throw new ArgumentNullException(nameof(propertyName));
+
+ if (!Equals(field, newValue))
+ {
+ RaisePropertyChanging(propertyName);
+ field = newValue;
+ RaisePropertyChanged(propertyName);
+ }
+ }
+
+ ///
+ public event PropertyChangedEventHandler? PropertyChanged;
+ ///
+ public event PropertyChangingEventHandler? PropertyChanging;
+
+ ///
+ /// The method is used to raise the 'property changed' event.
+ ///
+ ///
+ /// The calling member's name will be used as the parameter.
+ ///
+ /// The name of the property, can be .
+ protected virtual void RaisePropertyChanged([CallerMemberName] string? propertyName = null) =>
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+
+ ///
+ /// The method is used to raise the 'property changing' event.
+ ///
+ ///
+ /// The calling member's name will be used as the parameter.
+ ///
+ /// The name of the property, can be .
+ protected virtual void RaisePropertyChanging([CallerMemberName] string? propertyName = null) =>
+ PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName));
+}
diff --git a/Classes/Base/Pedestrian.cs b/Classes/BaseTypes/Pedestrian.cs
similarity index 100%
rename from Classes/Base/Pedestrian.cs
rename to Classes/BaseTypes/Pedestrian.cs
diff --git a/Classes/Base/PlayerProperty.cs b/Classes/BaseTypes/PlayerProperty.cs
similarity index 100%
rename from Classes/Base/PlayerProperty.cs
rename to Classes/BaseTypes/PlayerProperty.cs
diff --git a/Classes/Base/Stash.cs b/Classes/BaseTypes/Stash.cs
similarity index 100%
rename from Classes/Base/Stash.cs
rename to Classes/BaseTypes/Stash.cs
diff --git a/Classes/Drug.cs b/Classes/Drug.cs
index e2db08f1..b786d068 100644
--- a/Classes/Drug.cs
+++ b/Classes/Drug.cs
@@ -1,4 +1,6 @@
-using System.Xml.Serialization;
+using Los.Santos.Dope.Wars.Classes.BaseTypes;
+using System.ComponentModel;
+using System.Xml.Serialization;
namespace Los.Santos.Dope.Wars.Classes;
@@ -6,44 +8,15 @@ namespace Los.Santos.Dope.Wars.Classes;
/// The class is the root element for the drug class.
///
[XmlRoot(ElementName = nameof(Drug), IsNullable = false)]
-public class Drug
+public class Drug : NotifyBase
{
#region fields
- private int _quantity;
+ private int quantity;
#endregion
#region ctor
///
- /// Empty constructor for
- ///
- public Drug()
- {
- Name = string.Empty;
- Description = string.Empty;
- CurrentPrice = default;
- AveragePrice = default;
- PurchasePrice = default;
- Quantity = default;
- }
-
- ///
- /// The constructor for
- ///
- ///
- ///
- ///
- public Drug(Enums.DrugType drugType, string description, int marketValue)
- {
- Name = drugType.GetName();
- Description = description;
- CurrentPrice = default;
- AveragePrice = marketValue;
- PurchasePrice = default;
- Quantity = default;
- }
-
- ///
- /// The constructor for
+ /// Initializes a new instance of the class.
///
///
///
@@ -56,54 +29,65 @@ public Drug(string drugName, string description, int marketValue)
AveragePrice = marketValue;
PurchasePrice = default;
Quantity = default;
+ PropertyChanged += OnDrugPropertyChanged;
}
#endregion
#region properties
///
- /// The property
+ /// The property is the name of the drug.
///
[XmlText]
public string Name { get; set; }
///
- /// The property
+ /// The property is the description of the drug.
///
[XmlIgnore]
public string Description { get; set; }
///
- /// The property
+ /// The property is the current price of the drug.
///
[XmlIgnore]
public int CurrentPrice { get; set; }
///
- /// The property
+ /// The property is the normal market price of the drug.
///
[XmlIgnore]
public int AveragePrice { get; set; }
///
- /// The property
+ /// The property is the price the drug has been purchased.
///
[XmlAttribute(AttributeName = nameof(PurchasePrice))]
public int PurchasePrice { get; set; }
///
- /// The property, if the quantity gets set to 0 the property goes 0 too
+ /// The property is the amount of the drug.
///
[XmlAttribute(AttributeName = nameof(Quantity))]
- public int Quantity
+ public int Quantity { get => quantity; set => SetProperty(ref quantity, value); }
+ #endregion
+
+ #region private methods
+ ///
+ /// The event trigger method if a property that notifies has changed.
+ ///
+ ///
+ ///
+ private void OnDrugPropertyChanged(object sender, PropertyChangedEventArgs e)
{
- get => _quantity;
- set
+ if (sender is not Drug drug)
+ return;
+ if (e is null)
+ return;
+
+ if (Equals(e.PropertyName, nameof(drug.Quantity)))
{
- _quantity = value;
- if (value.Equals(0))
- {
- PurchasePrice = value;
- }
+ if (Equals(drug.Quantity, 0))
+ drug.PurchasePrice = Quantity;
}
}
#endregion
diff --git a/Classes/PlayerStash.cs b/Classes/PlayerStash.cs
index 21f92954..1ac4e692 100644
--- a/Classes/PlayerStash.cs
+++ b/Classes/PlayerStash.cs
@@ -5,58 +5,55 @@
namespace Los.Santos.Dope.Wars.Classes;
///
-/// The class for player types, inherits from
+/// The class.
///
+///
+/// Inherits from the base class.
+/// Implements the members of the interface.
+///
public class PlayerStash : Stash, IPlayerStash
{
- #region ctor
///
- /// The standard constructor for the class
+ /// Initializes a new instance of the class.
///
- public PlayerStash()
- {
- Drugs = new();
- }
- #endregion
+ public PlayerStash() => Drugs = new();
#region IPlayerStash members
- ///
+ ///
public void BuyDrug(string drugName, int drugQuantity, int drugPrice)
{
- Drug drug = Drugs.Where(x => x.Name.Equals(drugName, StringComparison.Ordinal)).SingleOrDefault();
-
- if (drug.Quantity.Equals(0))
- drug.PurchasePrice = drugPrice;
- else
- drug.PurchasePrice = ((drug.Quantity * drug.PurchasePrice) + (drugQuantity * drugPrice)) / (drug.Quantity + drugQuantity);
-
+ CalculateNewPurchasePrice(drugName, drugQuantity, drugPrice);
AddToStash(drugName, drugQuantity);
-
Game.Player.Money -= drugPrice * drugQuantity;
}
- ///
+
+ ///
public void MoveIntoInventory(string drugName, int drugQuantity, int drugPrice)
{
- Drug drug = Drugs.Where(x => x.Name.Equals(drugName, StringComparison.Ordinal)).SingleOrDefault();
-
- if (drug.Quantity.Equals(0))
- drug.PurchasePrice = drugPrice;
- else
- drug.PurchasePrice = ((drug.Quantity * drug.PurchasePrice) + (drugQuantity * drugPrice)) / (drug.Quantity + drugQuantity);
-
+ CalculateNewPurchasePrice(drugName, drugQuantity, drugPrice);
AddToStash(drugName, drugQuantity);
}
- ///
+ ///
public void SellDrug(string drugName, int drugQuantity, int drugPrice)
{
RemoveFromStash(drugName, drugQuantity);
-
Game.Player.Money += drugPrice * drugQuantity;
}
- ///
- public void TakeFromInventory(string drugName, int drugQuantity)
- {
+ ///
+ public void TakeFromInventory(string drugName, int drugQuantity) =>
RemoveFromStash(drugName, drugQuantity);
- }
#endregion
+
+ ///
+ /// The method calculaties the new purchase price, when adding drug into the player stash.
+ ///
+ /// The name of the drug.
+ /// The quantity / amount of the drug.
+ /// The current price of the drug.
+ private void CalculateNewPurchasePrice(string drugName, int drugQuantity, int drugPrice)
+ {
+ Drug drug = Drugs.Where(x => x.Name.Equals(drugName, StringComparison.Ordinal)).Single();
+ drug.PurchasePrice = drug.Quantity.Equals(0) ? drugPrice
+ : ((drug.Quantity * drug.PurchasePrice) + (drugQuantity * drugPrice)) / (drug.Quantity + drugQuantity);
+ }
}
diff --git a/Interfaces/IPlayerStash.cs b/Interfaces/IPlayerStash.cs
index 1feeef36..bb537b54 100644
--- a/Interfaces/IPlayerStash.cs
+++ b/Interfaces/IPlayerStash.cs
@@ -1,38 +1,38 @@
namespace Los.Santos.Dope.Wars.Interfaces;
///
-/// The interface, provides methods specifically for the player
+/// The interface, provides th epublic methods for the player stash.
///
public interface IPlayerStash
{
///
- /// The method is used to manipulate the player stash
+ /// The method is used to manipulate the player stash by adding drugs through a buy transaction.
///
- ///
- ///
- ///
+ /// The name of the drug.
+ /// The quantity / amount of the drug.
+ /// The current price of the drug.
void BuyDrug(string drugName, int drugQuantity, int drugPrice);
///
- /// The method is used to manipulate the player stash
+ /// The method is used to manipulate the player stash by adding drugs through a sell transaction.
///
- ///
- ///
- ///
+ /// The name of the drug.
+ /// The quantity / amount of the drug.
+ /// The current price of the drug.
void SellDrug(string drugName, int drugQuantity, int drugPrice);
///
- /// The method is used to make transfers into player inventories
+ /// The method is used to make transfers into player inventories by adding drug into a inventory.
///
- ///
- ///
- ///
+ /// The name of the drug.
+ /// The quantity / amount of the drug.
+ /// The current price of the drug.
void MoveIntoInventory(string drugName, int drugQuantity, int drugPrice);
///
- /// The method is used to make transfers from player inventories
+ /// The method is used to make transfers into player inventories by removing drug from a inventory.
///
- ///
- ///
+ /// The name of the drug.
+ /// The quantity / amount of the drug.
void TakeFromInventory(string drugName, int drugQuantity);
}
diff --git a/Persistence/State/PlayerStats.cs b/Persistence/State/PlayerStats.cs
index e395b5b4..cc1a2203 100644
--- a/Persistence/State/PlayerStats.cs
+++ b/Persistence/State/PlayerStats.cs
@@ -1,6 +1,6 @@
using Los.Santos.Dope.Wars.Classes;
+using Los.Santos.Dope.Wars.Classes.BaseTypes;
using System.ComponentModel;
-using System.Runtime.CompilerServices;
using System.Xml.Serialization;
namespace Los.Santos.Dope.Wars.Persistence.State;
@@ -9,11 +9,11 @@ namespace Los.Santos.Dope.Wars.Persistence.State;
/// The class is the root element for each character.
///
[XmlRoot(ElementName = nameof(PlayerStats), IsNullable = false)]
-public class PlayerStats : INotifyPropertyChanged
+public class PlayerStats : NotifyBase
{
#region fields
private int currentLevel;
-
+ private int currentExperience;
#endregion
#region ctor
@@ -30,77 +30,68 @@ public PlayerStats()
Stash.Init();
Reward = new();
Warehouse = new();
+ PropertyChanged += OnPlayerStatsPropertyChanged;
}
#endregion
#region properties
///
- /// The property, money spend for buying drugs
+ /// The property, money spend for buying drugs.
///
[XmlAttribute(AttributeName = nameof(SpentMoney))]
public int SpentMoney { get; set; }
///
- /// The property, money earned from selling drugs
+ /// The property, money earned from selling drugs.
///
[XmlAttribute(AttributeName = nameof(EarnedMoney))]
public int EarnedMoney { get; set; }
///
- /// The property, increases depending on experience gain
+ /// The property, increases depending on experience gain.
///
[XmlAttribute(AttributeName = nameof(CurrentLevel))]
- public int CurrentLevel
- {
- get => currentLevel;
- set
- {
- if (value != currentLevel)
- {
- currentLevel = value;
- OnPropertyChanged();
- }
- }
- }
+ public int CurrentLevel { get => currentLevel; set => SetProperty(ref currentLevel, value); }
///
/// The property
///
[XmlAttribute(AttributeName = nameof(CurrentExperience))]
- public int CurrentExperience { get; set; }
+ public int CurrentExperience { get => currentExperience; set => SetProperty(ref currentExperience, value); }
///
- /// The property, calculated not serialized
+ /// The property, calculated depending on the current level, not serialized.
///
[XmlIgnore]
- public int NextLevelExperience { get => GetNextLevelExpPoints(); }
+ public int NextLevelExperience => GetNextLevelExpPoints();
///
- /// The property, increases/decreasing depending on the amount of drugs the player has
+ /// The property, increases/decreasing depending on the amount of drugs the player has.
///
[XmlAttribute(AttributeName = nameof(CurrentBagSize))]
- public int CurrentBagSize { get => GetCurrentBagSize(); }
+ public int CurrentBagSize => GetCurrentBagSize();
///
- /// The property, increases depending on level gain
+ /// The property, increases depending on level gain.
///
+ // TODO: The maximum player bag size is still hard coded here ...
[XmlAttribute(AttributeName = nameof(MaxBagSize))]
- public int MaxBagSize { get => CurrentLevel * 50; }
+ public int MaxBagSize => CurrentLevel * 50;
///
- /// The property, holds the bought player drugs and drug money for trading
+ /// The property, holds the bought and otherwise acquired drugs for trading.
///
[XmlElement(ElementName = nameof(Stash), IsNullable = false)]
public PlayerStash Stash { get; set; }
///
- /// The property, holds the information about achieved rewards
+ /// The property, holds the information about achieved rewards.
///
[XmlElement(ElementName = nameof(Reward), IsNullable = false)]
public Reward Reward { get; set; }
///
- /// The property, holds the warehouse information
+ /// The property, holds the warehouse information.
///
[XmlElement(ElementName = nameof(Warehouse), IsNullable = false)]
public Warehouse Warehouse { get; set; }
@@ -108,22 +99,17 @@ public int CurrentLevel
#region public members
///
- /// bad implementation for now ...
+ /// The Method adds the desired experience points to the current experience.
///
- ///
- public void AddExperiencePoints(int points)
- {
- CurrentExperience += points;
- while (GetNextLevelExpPoints() < CurrentExperience)
- CurrentLevel++;
- }
+ /// The experience points to add to the current experience.
+ public void AddExperiencePoints(int points) => CurrentExperience += points;
#endregion
#region private members
///
- /// Returns the need experience points fo the next level
+ /// The method calculates the experience points needed for the next level up.
///
- ///
+ /// The needed experience points.
private int GetNextLevelExpPoints() => (int)Math.Pow(CurrentLevel + 1, 2.5) * 1000;
///
@@ -135,6 +121,7 @@ public void AddExperiencePoints(int points)
/// The current bag size.
private int GetCurrentBagSize()
{
+ // TODO: this needs to be redone / refac ... think this is a bad implementation.
int bagSize = default;
if (Stash.Drugs.Count.Equals(0))
return bagSize;
@@ -142,20 +129,22 @@ private int GetCurrentBagSize()
bagSize += drug.Quantity;
return bagSize;
}
- #endregion
-
- #region INotifyPropertyChanged interface members
- ///
- public event PropertyChangedEventHandler? PropertyChanged;
///
- /// The method for the event trigger.
+ /// The event trigger method if a property that notifies has changed.
///
- ///
- /// It should not be necessary to set the 'propertyName' parameter.
- ///
- /// The name of the propery which has changed.
- private protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ ///
+ ///
+ private void OnPlayerStatsPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e is null)
+ return;
+
+ if (Equals(e.PropertyName, nameof(CurrentExperience)))
+ {
+ if (GetNextLevelExpPoints() < CurrentExperience)
+ CurrentLevel++;
+ }
+ }
#endregion
}