/// <summary> /// Gets the current work items being produced in /// the supplied production item /// </summary> /// <param name="player"></param> /// <param name="stage"></param> public List<WorkInProgress> GetCurrentWorkItemsForProductionItem(GamePlayer player, BuildableItemEnum productionItem) { List<WorkInProgress> workItems = new List<WorkInProgress>(); foreach (WorkInProgress workInProgress in player.WorkInProgress) { ConsumableItem item = BuildableItems[workInProgress.Quantity.ItemCode] as ConsumableItem; if (item != null) { if (item.ProducedWith == productionItem) { workItems.Add(workInProgress); } } } return workItems; }
/// <summary> /// Returns the production amount for an item /// </summary> /// <param name="player"></param> /// <param name="location"></param> /// <param name="level"></param> /// <param name="itemCode"></param> /// <returns></returns> public int GetProductionQuantityForItem(GamePlayer player, int location, int level, BuildableItemEnum itemCode) { BuildableItem buildableItem = BuildableItems[itemCode]; ConsumableItem consumable = buildableItem as ConsumableItem; if (consumable != null) { ConsumableItemStat stat = consumable.ConsumableStats[level]; if (stat != null) { return stat.ProductionQuantity; } } return 1; }
/// <summary> /// Starts a player doing delayed work if all conditions pass. /// </summary> /// <param name="player"></param> /// <param name="code"></param> public WorkInProgress StartWork(GamePlayer player, int location, int level, BuildableItemEnum itemCode) { bool canDoWork = TryBuildItem(player, location, level, itemCode); if (!canDoWork) { return null; } DeductResources(player, location, level, itemCode); BuildableItem buildableItem = BuildableItems[itemCode]; BuildableItemStat stat = buildableItem.Stats[level]; WorkInProgress wip = new WorkInProgress { Quantity = new ItemQuantity { ItemCode = itemCode, UnStoredQuantity = GetProductionQuantityForItem(player, location, level, itemCode) }, FinishTime = DateTime.UtcNow.AddSeconds(stat.BuildSeconds) }; player.WorkInProgress.Add(wip); if (WorkStarted != null) { OnWorkStarted(new GamePlayerLogicEventArgs(player, wip)); } WorkItem workItem = buildableItem as WorkItem; if (workItem != null) { FinishWork(player, DateTime.UtcNow); } player.StateChanged = true; return wip; }
/// <summary> /// Deducts the resources required to build an item from the player /// </summary> /// <param name="player"></param> /// <param name="itemCode"></param> public void DeductResources(GamePlayer player, int location, int level, BuildableItemEnum itemCode) { BuildableItem buildableItem = BuildableItems[itemCode]; BuildableItemStat stat = buildableItem.Stats[level]; if (stat.RequiredItems != null) { foreach (ItemQuantity requiredItem in stat.RequiredItems) { RemoveItem(player, location, requiredItem); } } ModifyCoins(player, -stat.CoinCost); ModifyCoupons(player, -stat.CouponCost); player.StateChanged = true; }
/// <summary> /// Returns true if the player can build the item, throws an exception otherwise /// </summary> /// <returns></returns> public bool TryBuildItem(GamePlayer player, int location, int level, BuildableItemEnum itemCode) { ErrorCode error = CanBuildItem(player, location, level, itemCode); if (error != ErrorCode.ERROR_OK) { Trace.TraceError(error.ToString()); throw new ArgumentException(error.ToString()); } return true; }
/// <summary> /// Returns ErrorCode.OK if the player can build the item, /// an error code otherwise /// </summary> /// <param name="player"></param> /// <param name="item"></param> /// <returns></returns> public ErrorCode CanBuildItem(GamePlayer player, int location, int level, BuildableItemEnum itemCode) { if (!BuildableItems.ContainsKey(itemCode)) { return ErrorCode.START_WORK_INVALID_ITEM; } BuildableItem buildabelItem = BuildableItems[itemCode]; if (level < 0 || level > buildabelItem.Stats.Count) { return ErrorCode.START_WORK_INVALID_LEVEL; } BuildableItemStat stat = buildabelItem.Stats[level]; if (player.Level < stat.RequiredLevel) { return ErrorCode.START_WORK_ITEM_NOT_AVAILABLE; } if (stat.CoinCost > player.Coins) { return ErrorCode.START_WORK_INSUFFICIENT_COINS; } if (stat.CouponCost > player.Coupons) { return ErrorCode.START_WORK_INSUFFICIENT_COUPONS; } if (location < 0 || location > player.Locations.Count) { return ErrorCode.START_WORK_INVALID_LOCATION; } BusinessLocation businessLocation = player.Locations[location]; LocationStorage storage = businessLocation.Storage; if (stat.RequiredItems != null) { foreach (ItemQuantity itemQuantity in stat.RequiredItems) { if (!storage.Items.ContainsKey(itemQuantity.ItemCode)) { return ErrorCode.START_WORK_INVALID_INGREDIENTS; } if (storage.Items[itemQuantity.ItemCode].StoredQuantity < itemQuantity.StoredQuantity) { return ErrorCode.START_WORK_INSUFFICIENT_INGREDIENTS; } } } if (!DoesPlayerHaveProductionCapacity(player, location, level, itemCode)) { return ErrorCode.START_WORK_NO_PRODUCTION_CAPACITY; } if (!DoesPlayeraHaveStorageCapacity(player, location, level, itemCode)) { return ErrorCode.START_WORK_NO_STORAGE_CAPACITY; } WorkItem workItem = buildabelItem as WorkItem; if (workItem != null) { if (!storage.Items.ContainsKey(itemCode)) { return ErrorCode.START_WORK_INSUFFICIENT_NEGATIVE; } if (storage.Items[itemCode].UnStoredQuantity < GetProductionQuantityForItem(player, location, level, itemCode)) { return ErrorCode.START_WORK_INSUFFICIENT_NEGATIVE; } } else { ConsumableItem consumable = buildabelItem as ConsumableItem; if (consumable == null) { ItemQuantity inStorage = storage.Items[itemCode]; if (inStorage.UnStoredQuantity > 0 && inStorage.Level >= level) { return ErrorCode.START_WORK_MULTIPLE_NON_CONSUMABLE; } } } return ErrorCode.ERROR_OK; }
/// <summary> /// Returns true if the player has storage capacity for the item, false otherwise /// </summary> /// <param name="player"></param> /// <param name="itemCode"></param> /// <returns></returns> public bool DoesPlayeraHaveStorageCapacity(GamePlayer player, int location, int level, BuildableItemEnum itemCode) { ConsumableItem consumable = BuildableItems[itemCode] as ConsumableItem; if (consumable == null) { return true; } BusinessLocation businessLocation = player.Locations[location]; LocationStorage storage = businessLocation.Storage; if (!storage.Items.ContainsKey(consumable.StoredIn)) { return false; } int itemsInStorage = 0; foreach (ItemQuantity iq in storage.Items.Values) { ConsumableItem csi = BuildableItems[iq.ItemCode] as ConsumableItem; if (csi == null) { continue; } if (csi.StoredIn == consumable.StoredIn) { itemsInStorage += iq.StoredQuantity; } } StorageItem storageItem = BuildableItems[consumable.StoredIn] as StorageItem; int storageItemLevel = storage.Items[storageItem.ItemCode].Level; StorageItemStat storageStat = storageItem.StorageStats[storageItemLevel]; return itemsInStorage + GetProductionQuantityForItem(player, location, level, itemCode) < storageStat.Capacity; }
/// <summary> /// Returns true if the player has the capacity to start hhe item. /// </summary> /// <param name="player"></param> /// <param name="itemCode"></param> /// <returns></returns> public bool DoesPlayerHaveProductionCapacity(GamePlayer player, int location, int level, BuildableItemEnum itemCode) { ConsumableItem consumable = BuildableItems[itemCode] as ConsumableItem; if (consumable == null) { return true; } BusinessLocation businessLocation = player.Locations[location]; LocationStorage storage = businessLocation.Storage; if (!storage.Items.ContainsKey(consumable.ProducedWith) || storage.Items[consumable.ProducedWith].UnStoredQuantity == 0) { return false; } int inUse = 0; foreach (WorkInProgress wi in player.WorkInProgress) { ConsumableItem cip = BuildableItems[wi.Quantity.ItemCode] as ConsumableItem; if (cip == null) { continue; } if (cip.ProducedWith == consumable.ProducedWith) { inUse++; } } ProductionItem productionItem = BuildableItems[consumable.ProducedWith] as ProductionItem; int productionItemLevel = storage.Items[productionItem.ItemCode].Level; ProductionItemStat productionStat = productionItem.ProductionStats[productionItemLevel]; return inUse < productionStat.Capacity; }