/// <summary> /// Graze food add method. /// This style is not supported in GrazeFoodStoreType /// </summary> /// <param name="ResourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="ActivityName"></param> /// <param name="Reason"></param> public void Add(object ResourceAmount, string ActivityName, string Reason) { // expecting a GrazeFoodStoreResource (PastureManage) or FoodResourcePacket (CropManage) if (!(ResourceAmount.GetType() == typeof(GrazeFoodStorePool) | ResourceAmount.GetType() != typeof(FoodResourcePacket))) { throw new Exception(String.Format("ResourceAmount object of type {0} is not supported in Add method in {1}", ResourceAmount.GetType().ToString(), this.Name)); } GrazeFoodStorePool pool; if (ResourceAmount.GetType() == typeof(GrazeFoodStorePool)) { pool = ResourceAmount as GrazeFoodStorePool; } else { pool = new GrazeFoodStorePool(); FoodResourcePacket packet = ResourceAmount as FoodResourcePacket; pool.Set(packet.Amount); pool.Nitrogen = packet.PercentN; pool.DMD = packet.DMD; } if (pool.Amount > 0) { // allow decaying or no pools currently available if (PastureDecays | Pools.Count() == 0) { Pools.Insert(0, pool); } else { Pools[0].Add(pool); } // update biomass available biomassAddedThisYear += pool.Amount; ResourceTransaction details = new ResourceTransaction(); details.Credit = pool.Amount; details.Activity = ActivityName; details.Reason = Reason; details.ResourceType = this.Name; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
// event handler for gathering resources public void OnTick(object sender, TimeTickSystem.OnTickEventArgs e) { //Debug.Log(String.Format("event handler called {0}", e.tick)); // TODO: See if using OnTick5 makes sense if (e.tick % resourceTicks == 0) { Debug.Log(GetWorkerStatusString()); // send resources to store ResourceTransaction transaction = GeneratePayOutTransaction(); Debug.Log(transaction.FormattedStatusString()); SendResourcesToStore(transaction); } }
/// <summary> /// Add to food store /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { HumanFoodStorePool pool; switch (resourceAmount.GetType().Name) { case "HumanFoodStorePool": pool = resourceAmount as HumanFoodStorePool; break; case "Double": pool = new HumanFoodStorePool((double)resourceAmount, 0); break; default: // expecting a HumanFoodStorePool or Double throw new Exception(String.Format("ResourceAmount object of type {0} is not supported in Add method in {1}", resourceAmount.GetType().ToString(), this.Name)); } if (pool.Amount > 0) { HumanFoodStorePool poolOfAge = Pools.Where(a => a.Age == pool.Age).FirstOrDefault(); if (poolOfAge is null) { Pools.Insert(0, pool); } else { poolOfAge.Add(pool.Amount); } ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Gain, Amount = pool.Amount, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this }; base.LastGain = pool.Amount; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
/// <summary> /// Add to food store /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { if (resourceAmount.GetType().ToString() != "System.Double") { throw new Exception(String.Format("ResourceAmount object of type [{0}] is not supported. Add method in [r={1}]", resourceAmount.GetType().ToString(), this.GetType().ToString())); } double addAmount = (double)resourceAmount; double amountAdded = addAmount; if (this.areaAvailable + addAmount > this.UsableArea) { amountAdded = this.UsableArea - this.areaAvailable; string message = "Tried to add more available land to [r=" + this.Name + "] than exists."; Summary.WriteWarning(this, message); this.areaAvailable = this.UsableArea; } else { this.areaAvailable += addAmount; } ResourceTransaction details = new ResourceTransaction { Style = TransactionStyle.Gain, Amount = amountAdded, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this }; LastGain = amountAdded; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); if (category != "Initialise") { UpdateLandAllocatedList(activity, amountAdded, true); // adjust activity using all remaining land as well. if (ActivityRequestingRemainingLand != null && ActivityRequestingRemainingLand != activity) { UpdateLandAllocatedList(ActivityRequestingRemainingLand, amountAdded, true); } } }
public ResourceTransaction GeneratePayOutTransaction() { ResourceTransaction transaction = ResourceTransactionFactory.Create(); foreach (var workerMapEntry in workerCounts) { ResourceType type = workerMapEntry.Key; int numWorkers = workerMapEntry.Value; ResourceCost cost = ResourceCostFactory.Create(workerMapEntry.Key, numWorkers * resourcesGeneratedPerWorker); transaction.AddResourceCost(cost); } return(transaction); }
/// <summary> /// Add to food store /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { HumanFoodStorePool pool; switch (resourceAmount) { case HumanFoodStorePool _: pool = resourceAmount as HumanFoodStorePool; break; case double _: pool = new HumanFoodStorePool((double)resourceAmount, 0); break; default: throw new Exception($"ResourceAmount object of type [{resourceAmount.GetType().Name}] is not supported in [r={Name}]"); } if (pool.Amount > 0) { HumanFoodStorePool poolOfAge = Pools.Where(a => a.Age == pool.Age).FirstOrDefault(); if (poolOfAge is null) { Pools.Insert(0, pool); } else { poolOfAge.Add(pool.Amount); } ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Gain, Amount = pool.Amount, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this }; base.LastGain = pool.Amount; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
public override bool Execute() { Debug.Log("build command executing"); // Get required data on building BuildPlotController buildPlotController = GetBuildPlotController(); buildingModel = BuildingModelFactory.Create(buildingType); ResourceTransaction transaction = buildingModel.buildCost; // Check if constructing the building is possible // Building has already been constructed in another plot if (buildPlotController.IsBuilt(buildingType)) { Debug.LogError(string.Format("Error: there is already a {0} on another plot.", buildingType)); GetGameLogController().Log(string.Format("Error: there is already a {0} on another plot.", buildingType)); //abort return(false); } // Plot isn't empty if (!buildPlotController.IsBuildable(buildPlotLocation)) { Debug.LogError(string.Format("Error: there is already a building on {0}", buildPlotLocation)); GetGameLogController().Log(string.Format("Error: there is already a building on {0}", buildPlotLocation)); // abort return(false); } // transaction fails if (!PayOutTransaction(transaction)) { // abort GetGameLogController().Log(string.Format("Error: not enough resources to construct {0}", buildingType)); return(false); } // Success -> Build buildPlotController.Build(buildPlotLocation, buildingType, buildingModel); return(true); }
/// <summary> /// Add to food store /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { double addAmount; double nAdded; switch (resourceAmount.GetType().ToString()) { case "System.Double": addAmount = (double)resourceAmount; nAdded = Nitrogen; break; case "Models.CLEM.Resources.FoodResourcePacket": addAmount = ((FoodResourcePacket)resourceAmount).Amount; nAdded = ((FoodResourcePacket)resourceAmount).PercentN; break; default: throw new Exception(String.Format("ResourceAmount object of type {0} is not supported Add method in {1}", resourceAmount.GetType().ToString(), this.Name)); } if (addAmount > 0) { // update N based on new input added CurrentStoreNitrogen = ((CurrentStoreNitrogen * Amount) + (nAdded * addAmount)) / (Amount + addAmount); this.amount += addAmount; ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Gain, Amount = addAmount, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this }; LastTransaction = details; LastGain = addAmount; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
/// <summary> /// Remove from human food store /// </summary> /// <param name="request">Resource request class with details.</param> public new void Remove(ResourceRequest request) { if (request.Required == 0) { return; } double amountRequired = request.Required; foreach (HumanFoodStorePool pool in Pools.OrderByDescending(a => a.Age)) { // take min of amount in pool, remaining intake needed double amountToRemove = Math.Min(pool.Amount, amountRequired); amountRequired -= amountToRemove; // remove resource from pool pool.Remove(amountToRemove, request.ActivityModel, "Consumed"); if (amountRequired <= 0) { break; } } double amountRemoved = request.Required - amountRequired; // avoid taking too much amountRemoved = Math.Min(this.Amount, amountRemoved); request.Provided = amountRemoved; ResourceTransaction details = new ResourceTransaction { ResourceType = this, Loss = amountRemoved, Activity = request.ActivityModel, Reason = request.Reason }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); }
// BOOL! public bool PayOutTransaction(ResourceTransaction transaction) { bool success = false; if (resourceStoreMap.IsTransactionPossible(transaction)) { resourceStoreMap.PayOutTransaction(transaction); success = true; UpdateResourceStoreViews(); } else { Debug.LogError("Transaction rejected, not enough resources"); } return(success); }
/// <summary> /// Add to food store /// </summary> /// <param name="AddAmount">Amount to add to resource</param> /// <param name="ActivityName">Name of activity adding resource</param> /// <param name="UserName">Name of individual radding resource</param> public void Add(double AddAmount, string ActivityName, string UserName) { this.availableDays = this.availableDays + AddAmount; ResourceTransaction details = new ResourceTransaction(); details.Credit = AddAmount; details.Activity = ActivityName; details.Reason = UserName; details.ResourceType = this.Name; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); }
/// <summary> /// Remove from finance type store /// </summary> /// <param name="request">Resource request class with details.</param> public new void Remove(ResourceRequest request) { if (request.Required == 0) { return; } // if this request aims to trade with a market see if we need to set up details for the first time if (request.MarketTransactionMultiplier > 0) { FindEquivalentMarketStore(); } // avoid taking too much double amountRemoved = request.Required; amountRemoved = Math.Min(this.Amount, amountRemoved); this.amount -= amountRemoved; // send to market if needed if (request.MarketTransactionMultiplier > 0 && EquivalentMarketStore != null) { (EquivalentMarketStore as ProductStoreType).Add(amountRemoved * request.MarketTransactionMultiplier, request.ActivityModel, this.NameWithParent, "Farm sales"); } request.Provided = amountRemoved; if (amountRemoved > 0) { ResourceTransaction details = new ResourceTransaction { ResourceType = this, Style = TransactionStyle.Loss, Amount = amountRemoved, Activity = request.ActivityModel, Category = request.Category, RelatesToResource = request.RelatesToResource }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
/// <summary> /// Graze food add method. /// This style is not supported in GrazeFoodStoreType /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { // expecting a GrazeFoodStoreResource (PastureManage) or FoodResourcePacket (CropManage) if (!(resourceAmount.GetType() == typeof(GrazeFoodStorePool) || resourceAmount.GetType() != typeof(FoodResourcePacket))) { throw new Exception(String.Format("ResourceAmount object of type {0} is not supported in Add method in {1}", resourceAmount.GetType().ToString(), this.Name)); } GrazeFoodStorePool pool; if (resourceAmount.GetType() == typeof(GrazeFoodStorePool)) { pool = resourceAmount as GrazeFoodStorePool; } else { pool = new GrazeFoodStorePool(); FoodResourcePacket packet = resourceAmount as FoodResourcePacket; pool.Set(packet.Amount); pool.Nitrogen = packet.PercentN; pool.DMD = packet.DMD; } if (pool.Amount > 0) { ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Gain, Amount = pool.Amount, Activity = activity, Category = category, RelatesToResource = relatesToResource, ResourceType = this }; LastGain = pool.Amount; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
/// <summary> /// Remove from finance type store /// </summary> /// <param name="request">Resource request class with details.</param> public new void Remove(ResourceRequest request) { if (request.Required == 0) { return; } // if this request aims to trade with a market see if we need to set up details for the first time if (request.MarketTransactionMultiplier > 0) { FindEquivalentMarketStore(); } // avoid taking too much double amountRemoved = request.Required; amountRemoved = Math.Min(this.Amount, amountRemoved); this.amount -= amountRemoved; // send to market if needed if (request.MarketTransactionMultiplier > 0 && equivalentMarketStore != null) { (equivalentMarketStore as EquipmentType).Add(amountRemoved * request.MarketTransactionMultiplier, request.ActivityModel, "Farm sales"); } request.Provided = amountRemoved; ResourceTransaction details = new ResourceTransaction { ResourceType = this, Loss = amountRemoved, Activity = request.ActivityModel, Reason = request.Reason }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); }
/// <summary> /// Add money to account /// </summary> /// <param name="AddAmount"></param> /// <param name="ActivityName"></param> /// <param name="UserName"></param> public void Add(double AddAmount, string ActivityName, string UserName) { if (AddAmount > 0) { AddAmount = Math.Round(AddAmount, 2, MidpointRounding.ToEven); amount += AddAmount; ResourceTransaction details = new ResourceTransaction(); details.Credit = AddAmount; details.Activity = ActivityName; details.Reason = UserName; details.ResourceType = this.Name; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
/// <summary> /// Remove from finance type store /// </summary> /// <param name="request">Resource request class with details.</param> public new void Remove(ResourceRequest request) { if (request.Required == 0) { return; } double amountRemoved = Math.Round(request.Required, 2, MidpointRounding.ToEven); // more than positive balance can be taken if withdrawal limit set to false if (this.EnforceWithdrawalLimit) { amountRemoved = Math.Min(amountRemoved, FundsAvailable); } // avoid taking too much //amountRemoved = Math.Min(this.Amount, amountRemoved); if (amountRemoved == 0) { return; } this.amount -= amountRemoved; request.Provided = amountRemoved; ResourceTransaction details = new ResourceTransaction { ResourceType = this, Loss = amountRemoved, Activity = request.ActivityModel, Reason = request.Reason }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); }
/// <summary> /// Remove money from account /// </summary> /// <param name="RemoveAmount"></param> /// <param name="ActivityName"></param> /// <param name="UserName"></param> public double Remove(double RemoveAmount, string ActivityName, string UserName) { if (RemoveAmount > 0) { RemoveAmount = Math.Round(RemoveAmount, 2, MidpointRounding.ToEven); amount -= RemoveAmount; ResourceTransaction details = new ResourceTransaction(); details.ResourceType = this.Name; details.Debit = RemoveAmount * -1; details.Activity = ActivityName; details.Reason = UserName; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } return(RemoveAmount); }
/// <summary> /// Add to food store /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="reason">Name of individual adding resource</param> public new void Add(object resourceAmount, CLEMModel activity, string reason) { double addAmount = 0; double nAdded = 0; switch (resourceAmount.GetType().ToString()) { case "System.Double": addAmount = (double)resourceAmount; nAdded = Nitrogen; break; case "Models.CLEM.Resources.FoodResourcePacket": addAmount = ((FoodResourcePacket)resourceAmount).Amount; nAdded = ((FoodResourcePacket)resourceAmount).PercentN; break; default: throw new Exception(String.Format("ResourceAmount object of type {0} is not supported Add method in {1}", resourceAmount.GetType().ToString(), this.Name)); } // update N based on new input added CurrentStoreNitrogen = ((Nitrogen / 100 * Amount) + (nAdded / 100 * addAmount)) / (Amount + addAmount) * 100; this.amount = this.amount + addAmount; ResourceTransaction details = new ResourceTransaction(); details.Gain = addAmount; details.Activity = activity.Name; details.ActivityType = activity.GetType().Name; details.Reason = reason; details.ResourceType = this.Name; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); }
/// <summary> /// Add product to store /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { double addAmount; switch (resourceAmount) { case FoodResourcePacket _: addAmount = (resourceAmount as FoodResourcePacket).Amount; break; case double _: addAmount = (double)resourceAmount; break; default: throw new Exception($"ResourceAmount object of type [{resourceAmount.GetType().Name}] is not supported in [r={Name}]"); } if (addAmount > 0) { amount += addAmount; ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Gain, Amount = addAmount, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this }; base.LastGain = addAmount; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
/// <summary> /// Add product to store /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { double addAmount; if (resourceAmount.GetType().Name == "FoodResourcePacket") { addAmount = (resourceAmount as FoodResourcePacket).Amount; } else if (resourceAmount.GetType().ToString() == "System.Double") { addAmount = (double)resourceAmount; } else { throw new Exception(String.Format("ResourceAmount object of type [{0}] is not supported in [r={1}]", resourceAmount.GetType().ToString(), this.Name)); } if (addAmount > 0) { amount += addAmount; ResourceTransaction details = new ResourceTransaction { Style = TransactionStyle.Gain, Amount = addAmount, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this }; base.LastGain = addAmount; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
/// <summary> /// Remove from animal food store /// </summary> /// <param name="request">Resource request class with details.</param> public new void Remove(ResourceRequest request) { if (request.Required == 0) { return; } double amountRemoved = request.Required; // avoid taking too much amountRemoved = Math.Min(this.amount, amountRemoved); this.amount -= amountRemoved; FoodResourcePacket additionalDetails = new FoodResourcePacket { DMD = this.DMD, PercentN = this.CurrentStoreNitrogen }; request.AdditionalDetails = additionalDetails; request.Provided = amountRemoved; ResourceTransaction details = new ResourceTransaction { ResourceType = this, Loss = amountRemoved, Activity = request.ActivityModel, Reason = request.Reason }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); return; }
/// <summary> /// Remove from labour store /// </summary> /// <param name="request">Resource request class with details.</param> public new void Remove(ResourceRequest request) { if (request.Required == 0) { return; } if (this.Individuals > 1) { throw new NotImplementedException("Cannot currently use labour transactions while using cohort-based style labour"); } double amountRemoved = request.Required; // avoid taking too much amountRemoved = Math.Min(this.AvailableDays, amountRemoved); this.AvailableDays -= amountRemoved; request.Provided = amountRemoved; LastActivityRequestID = request.ActivityID; ResourceTransaction details = new ResourceTransaction { ResourceType = this, TransactionType = TransactionType.Loss, Amount = amountRemoved, Activity = request.ActivityModel, Category = request.Category, RelatesToResource = request.RelatesToResource }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); return; }
public bool IsTransactionPossible(ResourceTransaction transaction) { foreach (ResourceCost cost in transaction.resourceCosts) { ResourceType type = cost.type; if (!resourceStores.ContainsKey(type)) { // error -> no resource store of that type Debug.LogError(string.Format("Wrong Resource Type ({0})", type)); return(false); } if (!resourceStores[type].CheckPayOutPossible(cost)) { // error -> not enough resources Debug.LogError(string.Format("not enough {0}", type)); return(false); } } return(true); }
/// <summary> /// Add to labour store of this type /// </summary> /// <param name="ResourceAmount"></param> /// <param name="ActivityName"></param> /// <param name="Reason"></param> public void Add(object ResourceAmount, string ActivityName, string Reason) { if (ResourceAmount.GetType().ToString() != "System.Double") { throw new Exception(String.Format("ResourceAmount object of type {0} is not supported Add method in {1}", ResourceAmount.GetType().ToString(), this.Name)); } double addAmount = (double)ResourceAmount; this.availableDays = this.availableDays + addAmount; ResourceTransaction details = new ResourceTransaction(); details.Credit = addAmount; details.Activity = ActivityName; details.Reason = Reason; details.ResourceType = this.Name; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); }
/// <inheritdoc/> public new void Remove(ResourceRequest request) { // grazing or feeding from store treated the same way // grazing does not access pools by breed by gets all it needs of this quality common pasture // common pasture quality can be linked to a real pasture or foodstore and this has already been done. FoodResourcePacket additionalDetails = new FoodResourcePacket { PercentN = this.Nitrogen, DMD = this.dryMatterDigestibility, Amount = request.Required }; request.AdditionalDetails = additionalDetails; // other non grazing activities requesting common land pasture request.Provided = request.Required; // report ResourceTransaction details = new ResourceTransaction { ResourceType = this, TransactionType = TransactionType.Loss, Amount = request.Provided, Activity = request.ActivityModel, Category = request.Category, RelatesToResource = request.RelatesToResource }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); }
/// <summary> /// Add individuals to type based on cohort /// </summary> /// <param name="addIndividuals">OtherAnimalsTypeCohort Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object addIndividuals, CLEMModel activity, string relatesToResource, string category) { OtherAnimalsTypeCohort cohortToAdd = addIndividuals as OtherAnimalsTypeCohort; OtherAnimalsTypeCohort cohortexists = Cohorts.Where(a => a.Age == cohortToAdd.Age && a.Sex == cohortToAdd.Sex).FirstOrDefault(); if (cohortexists == null) { // add new Cohorts.Add(cohortToAdd); } else { cohortexists.Number += cohortToAdd.Number; } LastCohortChanged = cohortToAdd; ResourceTransaction details = new ResourceTransaction { TransactionType = TransactionType.Gain, Amount = cohortToAdd.Number, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this, ExtraInformation = cohortToAdd }; LastTransaction = details; LastGain = cohortToAdd.Number; TransactionEventArgs eargs = new TransactionEventArgs { Transaction = LastTransaction }; OnTransactionOccurred(eargs); }
/// <summary> /// /// </summary> /// <param name="request"></param> public new void Remove(ResourceRequest request) { // handles grazing by breed from this pasture pools based on breed pool limits if (request.AdditionalDetails != null && request.AdditionalDetails.GetType() == typeof(RuminantActivityGrazePastureHerd)) { RuminantActivityGrazePastureHerd thisBreed = request.AdditionalDetails as RuminantActivityGrazePastureHerd; // take from pools as specified for the breed double amountRequired = request.Required; thisBreed.DMD = 0; thisBreed.N = 0; // first take from pools foreach (GrazeBreedPoolLimit pool in thisBreed.PoolFeedLimits) { // take min of amount in pool, intake*limiter, remaining intake needed double amountToRemove = Math.Min(request.Required * pool.Limit, Math.Min(pool.Pool.Amount, amountRequired)); // update DMD and N based on pool utilised thisBreed.DMD += pool.Pool.DMD * amountToRemove; thisBreed.N += pool.Pool.Nitrogen * amountToRemove; amountRequired -= amountToRemove; // remove resource from pool pool.Pool.Remove(amountToRemove, thisBreed, "Graze"); if (amountRequired <= 0) { break; } } // if forage still limiting and second take allowed (enforce strict limits is false) if (amountRequired > 0 & !thisBreed.RuminantTypeModel.StrictFeedingLimits) { // allow second take for the limited pools double forage = thisBreed.PoolFeedLimits.Sum(a => a.Pool.Amount); // this will only be the previously limited pools double amountTakenDuringSecondTake = 0; foreach (GrazeBreedPoolLimit pool in thisBreed.PoolFeedLimits.Where(a => a.Limit < 1)) { //if still not enough take all double amountToRemove = 0; if (amountRequired >= forage) { // take as a proportion of the pool to total forage remaining amountToRemove = pool.Pool.Amount / forage * amountRequired; } else { amountToRemove = pool.Pool.Amount; } // update DMD and N based on pool utilised thisBreed.DMD += pool.Pool.DMD * amountToRemove; thisBreed.N += pool.Pool.Nitrogen * amountToRemove; amountTakenDuringSecondTake += amountToRemove; // remove resource from pool pool.Pool.Remove(amountToRemove, thisBreed, "Graze"); } amountRequired -= amountTakenDuringSecondTake; } request.Provided = request.Required - amountRequired; // adjust DMD and N of biomass consumed thisBreed.DMD /= request.Provided; thisBreed.N /= request.Provided; //if graze activity biomassConsumed += request.Provided; // report ResourceTransaction details = new ResourceTransaction { ResourceType = this, Style = TransactionStyle.Loss, Amount = request.Provided, Activity = request.ActivityModel, Category = request.Category, RelatesToResource = request.RelatesToResource }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } else if (request.AdditionalDetails != null && request.AdditionalDetails.GetType() == typeof(PastureActivityCutAndCarry)) { // take from pools by cut and carry double amountRequired = request.Required; double amountCollected = 0; double dryMatterDigestibility = 0; double nitrogen = 0; // take proportionally from all pools. double useproportion = Math.Min(1.0, amountRequired / Pools.Sum(a => a.Amount)); // if less than pools then take required as proportion of pools foreach (GrazeFoodStorePool pool in Pools) { double amountToRemove = pool.Amount * useproportion; amountCollected += amountToRemove; dryMatterDigestibility += pool.DMD * amountToRemove; nitrogen += pool.Nitrogen * amountToRemove; pool.Remove(amountToRemove, this, "Cut and Carry"); } request.Provided = amountCollected; // adjust DMD and N of biomass consumed dryMatterDigestibility /= request.Provided; nitrogen /= request.Provided; // report ResourceTransaction details = new ResourceTransaction { ResourceType = this, Style = TransactionStyle.Loss, Amount = request.Provided, Activity = request.ActivityModel, Category = request.Category, RelatesToResource = request.RelatesToResource }; LastTransaction = details; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } else { // Need to add new section here to allow non grazing activity to remove resources from pasture. throw new Exception("Removing resources from native food store can only be performed by a grazing and cut and carry activities at this stage"); } }
/// <summary> /// Graze food add method. /// This style is not supported in GrazeFoodStoreType /// </summary> /// <param name="resourceAmount">Object to add. This object can be double or contain additional information (e.g. Nitrogen) of food being added</param> /// <param name="activity">Name of activity adding resource</param> /// <param name="relatesToResource"></param> /// <param name="category"></param> public new void Add(object resourceAmount, CLEMModel activity, string relatesToResource, string category) { GrazeFoodStorePool pool; switch (resourceAmount.GetType().Name) { case "GrazeFoodStorePool": pool = resourceAmount as GrazeFoodStorePool; // adjust N content only if new growth (age = 0) based on yield limits and month range defined in GrazeFoodStoreFertilityLimiter if present if (pool.Age == 0 && !(grazeFoodStoreFertilityLimiter is null)) { double reduction = grazeFoodStoreFertilityLimiter.GetProportionNitrogenLimited(pool.Amount / Manager.Area); pool.Nitrogen = Math.Max(MinimumNitrogen, pool.Nitrogen * reduction); } break; case "FoodResourcePacket": pool = new GrazeFoodStorePool(); FoodResourcePacket packet = resourceAmount as FoodResourcePacket; pool.Set(packet.Amount); pool.Nitrogen = packet.PercentN; pool.DMD = packet.DMD; break; case "Double": pool = new GrazeFoodStorePool(); pool.Set((double)resourceAmount); pool.Nitrogen = this.Nitrogen; pool.DMD = this.EstimateDMD(this.Nitrogen); break; default: // expecting a GrazeFoodStoreResource (PastureManage) or FoodResourcePacket (CropManage) or Double from G-Range throw new Exception(String.Format("ResourceAmount object of type {0} is not supported in Add method in {1}", resourceAmount.GetType().ToString(), this.Name)); } if (pool.Amount > 0) { // allow decaying or no pools currently available if (PastureDecays || Pools.Count() == 0) { Pools.Insert(0, pool); } else { Pools[0].Add(pool); } // update biomass available if (!category.StartsWith("Initialise")) { // do not update if this is ian initialisation pool biomassAddedThisYear += pool.Amount; } ResourceTransaction details = new ResourceTransaction { Style = TransactionStyle.Gain, Amount = pool.Amount, Activity = activity, RelatesToResource = relatesToResource, Category = category, ResourceType = this }; LastTransaction = details; LastGain = pool.Amount; TransactionEventArgs te = new TransactionEventArgs() { Transaction = details }; OnTransactionOccurred(te); } }
// Utility method for making transactions (avoiding code duplication) protected bool PayOutTransaction(ResourceTransaction transaction) { ResourceController resourceController = GetResourceController(); return(resourceController.PayOutTransaction(transaction)); }
public ResourceTransactionEvent(Guid playerId, ResourceTransaction resourceTransaction) : base(playerId) { this.ResourceTransactions = new ResourceTransactionList(); this.ResourceTransactions.Add(resourceTransaction); }