/// <summary> /// Executes the requested bake operation. /// </summary> /// <param name="player"></param> /// <param name="data"></param> public static void Bake(AgricolaPlayer player, ImmutableList <GameEventTrigger> eventTriggers, List <GameActionNotice> resultingNotices, ImmutableArray <ResourceConversionData> data) { if (data != null && data.Length > 0) { var bakeInput = new ResourceCache(Resource.Grain, 0); var bakeOutput = new ResourceCache(Resource.Food, 0); foreach (var bake in data) { var card = ((AgricolaGame)player.Game).GetCard(bake.Id); var resources = Curator.GetBakeOutput(player, bake.Id, bake.Count); if (resources != null) { player.AddResource(card.BakeProperties.InType, -bake.Count); player.AddResource(resources); bakeInput = bakeInput.updateCount(bake.Count); bakeOutput = bakeOutput.updateCount(resources.Count); } } resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.Bake.ToString(), new ConversionPredicate(bakeInput, bakeOutput))); var trigger = new BakeTrigger(bakeInput.Count); ProcessEventTrigger(player, trigger, resultingNotices); CheckTriggers(player, eventTriggers, resultingNotices); } }
/// <summary> /// Puts an occupation into player for the given player. After all custom event triggers are fired, /// a PlayOccupationTrigger will be fired. /// </summary> /// <param name="player">The player who owns the occupation</param> /// <param name="eventTriggers">Any triggers that should be fired when this occupation is played</param> /// <param name="resultingNotices">A list of notices that should be sent to players</param> /// <param name="data">The data for the occupation being played</param> public static void PlayOccupation(AgricolaPlayer player, ImmutableList <GameEventTrigger> eventTriggers, List <GameActionNotice> resultingNotices, OccupationActionData data) { var card = ((AgricolaGame)player.Game).GetCard(data.Id.Value); var cost = Curator.GetOccupationCost(player, data.ActionId, data.Id.Value); foreach (var resource in cost) { player.AddResource(resource.Type, -resource.Count); } player.PlayCard(data.Id.Value); foreach (var evnt in card.OnPlayEvents) { evnt.Execute(player, null, card, resultingNotices); } resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.PlayOccupation.ToString(), new IdPredicate(data.Id.Value))); CheckTriggers(player, eventTriggers, resultingNotices); var trigger = new PlayOccupationTrigger(card); ProcessEventTrigger(player, trigger, resultingNotices); }
/// <summary> /// Assigns a single resource to a player. /// This method triggers no events. /// </summary> /// <param name="player"></param> /// <param name="resource"></param> /// <param name="resultingNotices"></param> public static void AssignResource(AgricolaPlayer player, ResourceCache resource, List <GameActionNotice> resultingNotices) { player.AddResource(resource); var resourcePredicateFound = false; foreach (var predicates in resultingNotices.Where(x => ((string)x.Subject) == player.Name).Select(x => x.Predicates)) { if (predicates != null) { for (var i = 0; i < predicates.Count; i++) { var predicate = predicates[i]; if (predicate is ResourceCache) { resourcePredicateFound = true; var cache = (ResourceCache)predicate; if (cache.Type == resource.Type) { predicates[i] = cache.updateCount(resource.Count); return; } } } if (resourcePredicateFound) { predicates.Add(new ResourceCache(resource.Type, resource.Count)); return; } } } resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.Take.ToString(), new ResourceCache(resource.Type, resource.Count))); }
public static void Sow(AgricolaPlayer player, ImmutableArray <SowData> sowData, List <GameActionNotice> resultingNotices) { if (sowData.Length > 0) { var grains = 0; var vegetables = 0; foreach (var sow in sowData) { player.AddResource(sow.Type, -1); player.SowField(sow.Index, sow.Type); if (sow.Type == Resource.Grain) { grains++; } if (sow.Type == Resource.Vegetables) { vegetables++; } } var sowPredicates = new List <INoticePredicate>(); if (grains > 0) { sowPredicates.Add(new ResourceCache(Resource.Grain, grains)); } if (vegetables > 0) { sowPredicates.Add(new ResourceCache(Resource.Vegetables, vegetables)); } resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.Sow.ToString(), sowPredicates)); } }
public static void Cook(AgricolaPlayer player, ImmutableList <GameEventTrigger> eventTriggers, ResourceConversionData[] data, List <GameActionNotice> resultingNotices) { var availableConversions = Curator.GetAnytimeResourceConversions(player); var trigger = new ResourceConversionTrigger(); foreach (var conversion in data) { var conversionDefinition = availableConversions.Where(x => x.Id == conversion.Id && x.InType == conversion.InType && x.InAmount == conversion.InAmount && x.OutType == conversion.OutType).OrderByDescending(a => a.OutAmount).FirstOrDefault(); if (!conversionDefinition.InType.IsAnimal()) { var inputCache = new ResourceCache(conversionDefinition.InType, -conversion.Count); var outputCache = new ResourceCache(conversionDefinition.OutType, (conversion.Count / conversionDefinition.InAmount) * conversionDefinition.OutAmount); // Deduct the cost player.AddResource(inputCache); if (!conversionDefinition.OutType.IsAnimal()) { // Add the converted resources player.AddResource(outputCache); } else { ((AgricolaGame)player.Game).AddInterrupt(new AssignAnimalsAction(player, (AnimalResource)conversionDefinition.OutType, conversionDefinition.OutAmount, resultingNotices)); } inputCache = new ResourceCache(inputCache.Type, inputCache.Count * -1); resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.Converted.ToString(), new ConversionPredicate(inputCache, outputCache))); trigger.AddConvertedResources(ResourcesConvertedData.FromResourceConversion(conversionDefinition, conversion.Count / conversionDefinition.InAmount)); } } ProcessEventTrigger(player, trigger, resultingNotices); CheckTriggers(player, eventTriggers, resultingNotices); }
/// <summary> /// Applies the requested animal assignment data, cooking animals /// for food in the process /// </summary> /// <param name="player"></param> /// <param name="data"></param> public static void AssignAnimals(AgricolaPlayer player, AnimalCacheActionData data, List <GameActionNotice> resultingNotices) { player.AssignAnimals(data.Assignments); var cooking = false; foreach (var count in data.Cook.Values) { if (count > 0) { cooking = true; break; } } var freedAnimalsPredicates = new List <INoticePredicate>(); foreach (var animal in data.Free.Keys) { if (data.Free[animal] > 0) { freedAnimalsPredicates.Add(new ResourceCache((Resource)animal, data.Free[animal])); } } if (freedAnimalsPredicates.Count > 0) { resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.FreeAnimals.ToString(), freedAnimalsPredicates)); } if (cooking) { var conversions = Curator.GetHarvestFoodValues(player); var cookedAnimalPredicates = new List <INoticePredicate>(); foreach (var animal in data.Cook.Keys) { if (data.Cook[animal] > 0) { var definition = conversions.Where(x => x.InType.ToString() == animal.ToString()).OrderByDescending(x => x.OutAmount).First(); var inputCache = new ResourceCache((Resource)animal, data.Cook[animal]); var outputCache = new ResourceCache(Resource.Food, definition.OutAmount * data.Cook[animal]); player.AddResource(outputCache); cookedAnimalPredicates.Add(new ConversionPredicate(inputCache, outputCache)); } } if (cookedAnimalPredicates.Count > 0) { resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.Converted.ToString(), cookedAnimalPredicates)); } } }
public override GameAction OnExecute(AgricolaPlayer player, Data.GameActionData data) { base.OnExecute(player, data); var choiceData = (AnimalChoiceActionData)data; if (choiceData.Option == AnimalResource.Sheep) { player.AddResource(Resource.Food); } else if (choiceData.Option == AnimalResource.Cattle) { player.RemoveResource(Resource.Food); } ActionService.AssignAnimals(player, choiceData.AnimalData, ResultingNotices); return(this); }
/// <summary> /// Assigns a single resource to a player and triggers /// events. /// </summary> /// <param name="player"></param> /// <param name="cache"></param> /// <param name="eventTriggers">Triggers attached to the calling actions.</param> /// <param name="resultingNotices"></param> /// <param name="partOfMultiCache"></param> public static void AssignCacheResource(AgricolaPlayer player, ImmutableList <GameEventTrigger> eventTriggers, List <GameActionNotice> resultingNotices, ResourceCache cache, bool partOfMultiCache = false) { if (cache.Type.IsAnimal()) { //player.Game.AddInterrupt(new AssignAnimalsAction(player, cache, resultingNotices)); } else { player.AddResource(cache.Type, cache.Count); resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.Take.ToString(), new ResourceCache(cache.Type, cache.Count))); var resourceTrigger = new TakeCachedResourceTrigger(cache.Type); ProcessEventTrigger(player, resourceTrigger, resultingNotices); if (!partOfMultiCache) { var onlyResourceTrigger = new TakeSoleCachedResourceTrigger(cache.Type); ProcessEventTrigger(player, onlyResourceTrigger, resultingNotices); } CheckTriggers(player, eventTriggers, resultingNotices); } }
public static void BuyImprovement(AgricolaPlayer player, ImprovementActionData data, List <GameActionNotice> resultingNotices) { var improvementData = (ImprovementActionData)data; var card = ((AgricolaGame)player.Game).GetCard(improvementData.Id); var cost = Curator.GetCardCost(player, improvementData.Id, improvementData.PaymentOption); if (cost is ResourceCardCost) { var rcCost = (ResourceCardCost)cost; foreach (var resource in rcCost.Resources) { if (resource.Type.IsAnimal()) { player.RemoveAnimals((AnimalResource)resource.Type, resource.Count); } else { player.AddResource(resource.Type, -resource.Count); } } } else if (cost is ReturnCardCardCost) { var miCost = (ReturnCardCardCost)cost; var ownedCardIds = player.OwnedCardIds; foreach (var id in miCost.Ids) { if (ownedCardIds.Contains(id)) { ((AgricolaGame)player.Game).ReturnCard(player, id); break; } } } else if (!(cost is FreeCardCost)) { throw new NotImplementedException("Cost type not supported."); } // Apply the card if (card is MajorImprovement) { ((AgricolaGame)player.Game).AssignMajorImprovement(improvementData.Id, player); } else if (card is MinorImprovement) { if (((MinorImprovement)card).PassesLeft) { ((AgricolaGame)player.Game).PassCardLeft(player, (MinorImprovement)card); } else { player.PlayCard(card); } } resultingNotices.Add(new GameActionNotice(player.Name, NoticeVerb.PurchaseImprovement.ToString(), new IdPredicate(data.Id))); foreach (var evnt in card.OnPlayEvents) { evnt.Execute(player, null, card, resultingNotices); } }