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(); }
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(); }
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 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); }
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; }