public override void UndoUseWater(AbstractGameAsset a) { if (!a.CanBeAllocatedWater) { throw new WaterWarsGameLogicException( string.Format( "Attempt made to undo allocate water on asset {0} but this asset type does not allow water allocation", a.Name)); } if (!a.IsBuilt) { throw new WaterWarsGameLogicException( "{0} tried to undo allocate water on asset {1} but it is only partially built", a.OwnerName, a.Name); } Player p = a.Field.BuyPoint.DevelopmentRightsOwner; BuyPoint bp = a.Field.BuyPoint; m_log.InfoFormat( "[WATER WARS]: {0} undoing use of {1} on {2} at {3} in {4}", p.Name, WaterWarsUtils.GetWaterUnitsText(a.WaterAllocated), a.Name, bp.Name, bp.Location.RegionName); m_controller.WaterAllocator.ChangeAllocation(a, p, 0); m_controller.EventManager.TriggerWaterUsed(a, p, 0); a.TriggerChanged(); bp.TriggerChanged(); p.TriggerChanged(); UpdateHudStatus(p); }
public override void UpgradeGameAsset(Player p, AbstractGameAsset ga, int newLevel) { BuyPoint bp = ga.Field.BuyPoint; if (!ga.IsBuilt) { throw new WaterWarsGameLogicException( "{0} tried to upgrade {1} at {2} in {3} but the asset is only partially built", p.Name, ga.Name, bp.Name, bp.Location.RegionName); } if (newLevel <= ga.Level) { throw new WaterWarsGameLogicException( "{0} tried to upgrade {1} to level {2} but asset is already at level {3}", p, ga, newLevel, ga.Level); } if (newLevel > ga.MaxLevel) { throw new WaterWarsGameLogicException( "{0} tried to upgrade {1} to level {2} but max level of asset is {3}", p, ga, newLevel, ga.MaxLevel); } int price = ga.ConstructionCosts[newLevel] - ga.ConstructionCosts[ga.Level]; if (p.Money < price) { throw new WaterWarsGameLogicException( "{0} has {1}, not enough to upgrade {2} to level {3} which costs {4}", p, p.Money, ga, newLevel, price); } m_log.InfoFormat( "[WATER WARS]: {0} upgrading {1} on {2} in {3} to level {4}", p.Name, ga.Name, bp.Name, bp.Location.RegionName, newLevel); // Perform the transaction p.Money -= price; int oldLevel = ga.Level; ga.Level = newLevel; ga.Name = string.Format("{0} ({1})", ga.InitialNames[ga.Level], ga.Field.Name); ga.RevenueThisTurn = m_controller.EconomicDistributor.Allocate(ga.Game.EconomicActivity, ga); m_controller.EventManager.TriggerGameAssetUpgraded(ga, oldLevel); bp.TriggerChanged(); p.TriggerChanged(); ga.TriggerChanged(); UpdateHudStatus(p); }
protected void TakeWater(AbstractGameAsset a, Player p, int waterRequired) { m_log.InfoFormat( "[WATER WARS]: Allocating {0} water to {1} owned by {2}", waterRequired, a.Name, a.Field.BuyPoint.DevelopmentRightsOwner); int totalWaterTaken = 0; if (a.Field.BuyPoint.WaterRightsOwner == p) { int waterTaken = Math.Min(a.Field.BuyPoint.WaterAvailable, waterRequired); a.Field.BuyPoint.WaterAvailable -= waterTaken; waterRequired -= waterTaken; totalWaterTaken += waterTaken; } // We need to pull in water from other places. if (waterRequired > 0) { lock (p.WaterRightsOwned) { Dictionary <UUID, BuyPoint> otherRights = new Dictionary <UUID, BuyPoint>(p.WaterRightsOwned); otherRights.Remove(a.Field.BuyPoint.Uuid); while (waterRequired > 0) { BuyPoint waterMaxBp = BuyPoint.None; foreach (BuyPoint bp in otherRights.Values) { if (bp.WaterAvailable > waterMaxBp.WaterAvailable) { waterMaxBp = bp; } } m_log.InfoFormat( "[WATER WARS]: ParcelOrientedAllocator determined buy point {0} has max water of {1}", waterMaxBp.Name, waterMaxBp.WaterAvailable); int waterTaken = Math.Min(waterMaxBp.WaterAvailable, waterRequired); waterMaxBp.WaterAvailable -= waterTaken; waterRequired -= waterTaken; totalWaterTaken += waterTaken; } } } a.WaterAllocated += totalWaterTaken; //p.Water -= a.WaterUsage; a.TriggerChanged(); }
protected void GiveBackWater(AbstractGameAsset a, Player p, int waterToReturn) { m_log.InfoFormat( "[WATER WARS]: Deallocating {0} water from {1} owned by {2}", waterToReturn, a.Name, a.Field.BuyPoint.DevelopmentRightsOwner); BuyPoint assetBp = a.Field.BuyPoint; // If the asset owner has no water rights anywhere then the water is simply lost. if (assetBp.DevelopmentRightsOwner.WaterRightsOwned.Count == 0) { return; } // If the asset sits in a parcel for which the owner also owns water rights, then just return the water // there if (assetBp.DevelopmentRightsOwner == assetBp.WaterRightsOwner) { assetBp.WaterAvailable += waterToReturn; a.WaterAllocated -= waterToReturn; } else { lock (p.WaterRightsOwned) { int waterForEach = (int)Math.Ceiling(waterToReturn / (double)p.WaterRightsOwned.Count); a.WaterAllocated -= waterToReturn; foreach (BuyPoint bp in p.WaterRightsOwned.Values) { int water = Math.Min(waterForEach, waterToReturn); bp.WaterAvailable += water; waterToReturn -= water; if (waterToReturn <= 0) { break; } } } } a.TriggerChanged(); }
public override void SellGameAssetToEconomy(AbstractGameAsset ga) { if (!ga.CanBeSoldToEconomy) { throw new WaterWarsGameLogicException( "{0} tried to sell asset {1} on {2} in {3} to the economy but it is not of the appropriate type", ga.OwnerName, ga.Name, ga.Field.BuyPoint.Name, ga.Field.BuyPoint.Location.RegionName); } if (!ga.IsBuilt) { throw new WaterWarsGameLogicException( "{0} tried to sell asset {1} on {2} in {3} to the economy but it is only partially built", ga.OwnerName, ga.Name, ga.Field.BuyPoint.Name, ga.Field.BuyPoint.Location.RegionName); } Player owner = ga.Field.Owner; BuyPoint bp = ga.Field.BuyPoint; if (ga.WaterUsage > owner.WaterEntitlement) { throw new WaterWarsGameLogicException( "Game asset {0} on parcel {1} in {2} cannot be sold to the market since this requires water rights of {3} whereas {4} has only {5} available", ga.Name, bp.Name, bp.Location.RegionName, owner.Name, owner.WaterEntitlement); } m_log.InfoFormat( "[WATER WARS]: {0} selling {1} on {2} in {3} to economy", owner.Name, ga.Name, bp.Name, bp.Location.RegionName); int revenue = ga.MarketPrice; owner.Money += revenue; owner.BuildRevenueThisTurn += revenue; owner.WaterEntitlement -= ga.WaterUsage; ga.IsSoldToEconomy = true; ga.Field.Owner = m_controller.Game.Economy; ga.TriggerChanged(); bp.TriggerChanged(); owner.TriggerChanged(); m_controller.EventManager.TriggerGameAssetSoldToEconomy(ga, owner, revenue); }
public override AbstractGameAsset ContinueBuildingGameAsset(AbstractGameAsset ga) { BuyPoint bp = ga.Field.BuyPoint; if (ga.IsBuilt) { throw new WaterWarsGameLogicException( "{0} tried to continue building game asset {1} on {2} in {3} but this is already fully built", bp.DevelopmentRightsOwner.Name, ga.Name, bp.Name, bp.Location.RegionName); } Player p = bp.DevelopmentRightsOwner; int price = ga.ConstructionCostPerBuildStep; if (p.Money < price) { // TODO: Signal this to the player in-world in some way throw new WaterWarsGameLogicException( "[WATER WARS]: Player {0} has {1}, not enough to build the next phase of {2} in {3} at {4} costing {5}", p, p.Money, ga.Name, bp.Name, bp.Location.RegionName, price); } p.Money -= price; p.BuildCostsThisTurn += price; ga.StepsBuilt++; ga.StepBuiltThisTurn = true; m_controller.EventManager.TriggerGameAssetBuildContinued(ga); if (ga.IsBuilt) { m_controller.EventManager.TriggerGameAssetBuildCompleted(ga); } ga.TriggerChanged(); p.TriggerChanged(); bp.TriggerChanged(); UpdateHudStatus(p); return(ga); }
public override void UseWater(AbstractGameAsset a, Player p, int amount) { BuyPoint bp = a.Field.BuyPoint; if (bp.DevelopmentRightsOwner != p) { throw new WaterWarsGameLogicException( "{0} tried to allocate water on asset {1} but development rights are owned by {2}", p, a, bp.DevelopmentRightsOwner); } if (!a.CanBeAllocatedWater) { throw new WaterWarsGameLogicException( "{0} tried to allocate water on asset {1} but this asset type does not allow water allocation", p.Name, a.Name); } if (!a.IsBuilt) { throw new WaterWarsGameLogicException( "{0} tried to allocate water on asset {1} but it is only partially built", p.Name, a.Name); } m_log.InfoFormat( "[WATER WARS]: {0} using {1} on {2} at {3} in {4}", p.Name, WaterWarsUtils.GetWaterUnitsText(amount), a.Name, bp.Name, bp.Location.RegionName); m_controller.WaterAllocator.ChangeAllocation(a, p, amount); m_controller.EventManager.TriggerWaterUsed(a, p, amount); a.TriggerChanged(); bp.TriggerChanged(); p.TriggerChanged(); UpdateHudStatus(p); }