Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        protected override void PostStartState()
        {
            // Perform economic activity
            Game.EconomicActivity = m_controller.EconomicGenerator.Generate(Game);

            lock (Game.GameAssets)
            {
                Dictionary <AbstractGameAsset, int> allocation
                    = m_controller.EconomicDistributor.Allocate(Game.EconomicActivity, Game.GameAssets.Values);

                foreach (AbstractGameAsset ga in allocation.Keys)
                {
                    // Messy.  This will need to come out as a separate Dictionary of market prices from the allocator
                    // or perhaps another source (MarketPricer?)
                    if (ga.Type == AbstractGameAssetType.Houses)
                    {
                        ga.MarketPrice = allocation[ga];
                    }
                    else
                    {
                        ga.RevenueThisTurn = allocation[ga];
                    }
                }
            }

            // Perform water activity
            RainfallTotal = m_controller.RainfallGenerator.Generate(Game);

            m_controller.EventManager.TriggerWaterGenerated(RainfallTotal);

            m_log.InfoFormat(
                "[WATER WARS]: Generated {0} over {1} parcels",
                WaterWarsUtils.GetWaterUnitsText(RainfallTotal), Game.BuyPoints.Count);

            List <Player> players;

            lock (Game.Players)
                players = Game.Players.Values.ToList();

            Dictionary <Player, int> waterAllocated
                = m_controller.WaterDistributor.Allocate(RainfallTotal, players, Game.BuyPoints.Values);

            foreach (Player p in waterAllocated.Keys)
            {
                p.WaterReceived = waterAllocated[p];
                p.Water        += p.WaterReceived;

                m_log.InfoFormat(
                    "[WATER WARS]: Allocated {0} to {1}", WaterWarsUtils.GetWaterUnitsText(p.WaterReceived), p.Name);

                m_controller.EventManager.TriggerWaterAllocated(p, p.WaterReceived);

                // We'll leave it up to the following Water State (or possibly Reset State) to trigger the general
                // player data change event
//                p.TriggerChanged();
            }

            EndState(new WaterStageState(m_controller));
        }
Esempio n. 3
0
 protected void UpdateLabel()
 {
     if (m_controller.Game.State == GameStateType.Build)
     {
         LabelBehaviour.Text = string.Format("Rights owned\n{0}", WaterWarsUtils.GetWaterUnitsText(m_waterEntitlement));
     }
     else
     {
         LabelBehaviour.Text = string.Format("Available for use\n{0}", WaterWarsUtils.GetWaterUnitsText(m_water));
     }
 }
Esempio n. 4
0
        public override void GiveWaterRights(Player p, int amount)
        {
            m_log.InfoFormat("[WATER WARS]: Giving rights to {0} to {1}", WaterWarsUtils.GetWaterUnitsText(amount), p.Name);

            p.WaterEntitlement += amount;

            m_controller.EventManager.TriggerWaterRightsGiven(p, amount);

            p.TriggerChanged();

            // FIXME: Should be done via event subscription.
            UpdateHudStatus(p);
        }
        protected void AskBuyer()
        {
            SendDialog(
                m_buyer,
                string.Format(
                    "Would you like to buy the rights to {0} from {1} for {2}{3}?",
                    WaterWarsUtils.GetWaterUnitsText(m_amount), m_seller.Name, WaterWarsConstants.MONEY_UNIT, m_salePrice),
                YES_NO_OPTIONS, ProcessBuyer);

            SendAlert(
                m_seller,
                string.Format(
                    "Offer to sell rights for {0} to {1} for {2}{3} has been sent",
                    WaterWarsUtils.GetWaterUnitsText(m_amount), m_buyer.Name, WaterWarsConstants.MONEY_UNIT, m_salePrice));
        }
Esempio n. 6
0
        protected Hashtable HandleBuyPointChange(string rawBpId, Hashtable request)
        {
            JObject json = GetJsonFromPost(request);

            string name         = (string)json.SelectToken("Name");
            bool   changingName = name != null;

            string rawDevelopmentRightsBuyerId = (string)json.SelectToken("DevelopmentRightsOwner.Uuid.Guid");
            bool   buyingDevelopmentRights     = rawDevelopmentRightsBuyerId != null;

            string rawWaterRightsBuyerId = (string)json.SelectToken("WaterRightsOwner.Uuid.Guid");
            bool   buyingWaterRights     = rawWaterRightsBuyerId != null;

            int?developmentRightsPrice = (int?)json.SelectToken("DevelopmentRightsPrice");
            int?waterRightsPrice       = (int?)json.SelectToken("WaterRightsPrice");
            int?combinedRightsPrice    = (int?)json.SelectToken("CombinedPrice");

//            m_log.InfoFormat(
//                "rawBpId [{0}], buyingDevelopmentRights [{1}], buyingWaterRights [{2}]",
//                rawBpId, buyingDevelopmentRights, buyingWaterRights);

            UUID     bpId = WaterWarsUtils.ParseRawId(rawBpId);
            BuyPoint bp   = null;

            m_controller.Game.BuyPoints.TryGetValue(bpId, out bp);

            if (changingName)
            {
                return(HandleChangeName(bp, name));
            }
            else if (buyingDevelopmentRights || buyingWaterRights)
            {
                return(HandleBuyRights(
                           bp, buyingDevelopmentRights, buyingWaterRights,
                           rawDevelopmentRightsBuyerId, rawWaterRightsBuyerId,
                           developmentRightsPrice, waterRightsPrice, combinedRightsPrice, request));
            }

            // TODO: Deal with error situations: uuid not valid, no such buy point, not enough money, etc.

            Hashtable reply = new Hashtable();

            reply["int_response_code"]   = 200; // 200 OK
            reply["str_response_string"] = "hoorah";
            reply["content_type"]        = "text/plain";

            return(reply);
        }
        protected void ProcessBuyer(OSChatMessage chat)
        {
            m_log.InfoFormat(
                "[WATER WARS]: Processing reply {0} for {1} selling to {2}", chat.Message, m_seller, m_buyer);

            bool accepted = false;

            if (YES_OPTION == chat.Message)
            {
                if (m_buyer.Money >= m_salePrice)
                {
                    accepted = true;
                }
                else
                {
                    SendAlert(m_buyer, "You don't have enough money to accept that offer!");
                }
            }

            if (accepted)
            {
                m_controller.State.SellWaterRights(m_buyer, m_seller, m_amount, m_salePrice);

                SendAlert(
                    m_seller,
                    string.Format(
                        "You successfully sold rights to {0} to {1} for {2}{3}",
                        WaterWarsUtils.GetWaterUnitsText(m_amount), m_buyer.Name, WaterWarsConstants.MONEY_UNIT, m_salePrice));

                SendAlert(
                    m_buyer,
                    string.Format(
                        "You successfully bought the rights to {0} from {1} for {2}{3}",
                        WaterWarsUtils.GetWaterUnitsText(m_amount), m_seller.Name, WaterWarsConstants.MONEY_UNIT, m_salePrice));
            }
            else
            {
                m_controller.EventManager.TriggerWaterRightsSold(m_buyer, m_seller, m_amount, m_salePrice, false);

                SendAlert(
                    m_seller,
                    string.Format(
                        "{0} declined your offer to sell them rights to {1} for {2}{3}",
                        m_buyer.Name, WaterWarsUtils.GetWaterUnitsText(m_amount), WaterWarsConstants.MONEY_UNIT, m_salePrice));
            }
        }
Esempio n. 8
0
        protected Hashtable HandleLogin(UUID playerId, Hashtable request)
        {
            Hashtable reply = new Hashtable();

            // We have to give some response string otherwise the return code crashes
            reply["str_response_string"] = "";

            UUID loginToken = UUID.Zero;

            lock (m_loginTokens)
                m_loginTokens.TryGetValue(playerId, out loginToken);

            bool passed = false;

            if (!WaterWarsConstants.IS_WEBSERVICE_SECURITY_ON)
            {
                passed = true;
            }
            else
            {
                UUID submittedLoginToken = WaterWarsUtils.ParseRawId((string)request["loginToken"]);

                if (loginToken == submittedLoginToken)
                {
                    passed = true;
                }
            }

            if (passed)
            {
                reply["int_response_code"] = 200;

                lock (m_loginTokens)
                    m_loginTokens.Remove(playerId);

                // TODO: Establish the second authorization token
            }
            else
            {
                reply["int_response_code"] = 401;
            }

            return(reply);
        }
Esempio n. 9
0
        public override void SellWaterRights(Player buyer, Player seller, int amount, int salePrice)
        {
            if (buyer.Money < salePrice)
            {
                throw new WaterWarsGameLogicException(
                          string.Format(
                              "Player {0} tried to buy {1} water rights from {2} for {3} but they only have {4}",
                              buyer, amount, seller, salePrice, buyer.Money));
            }

            if (seller.WaterEntitlement < amount)
            {
                throw new WaterWarsGameLogicException(
                          string.Format(
                              "Player {0} tried to sell {1} water rights to {2} but they only have {3}",
                              seller, amount, buyer, WaterWarsUtils.GetWaterUnitsText(seller.WaterEntitlement)));
            }

            m_log.InfoFormat(
                "[WATER WARS]: Player {0} selling {1} water rights to {2} for {3}",
                seller, amount, buyer, salePrice);

            buyer.Money -= salePrice;
            buyer.WaterRightsCostsThisTurn += salePrice;
            seller.Money += salePrice;
            seller.WaterRightsRevenueThisTurn += salePrice;
            buyer.WaterEntitlement            += amount;
            seller.WaterEntitlement           -= amount;

            m_controller.EventManager.TriggerWaterRightsSold(buyer, seller, amount, salePrice, true);

            buyer.TriggerChanged();
            seller.TriggerChanged();

            // FIXME: Should be done via event subscription.
            UpdateHudStatus(buyer);
            UpdateHudStatus(seller);

            m_controller.Events.PostToAll(
                string.Format(SELL_WATER_RIGHTS_CRAWL_MSG, seller.Name, WaterWarsUtils.GetWaterUnitsText(amount), buyer.Name),
                EventLevel.Crawl);
        }
Esempio n. 10
0
        public override void SellWater(Player seller, Player buyer, int water, int price)
        {
            if (seller.Water < water)
            {
                throw new WaterWarsGameLogicException(
                          string.Format(
                              "{0} only has {1} but is trying to sell {2} to {3}",
                              seller, WaterWarsUtils.GetWaterUnitsText(seller.Water), WaterWarsUtils.GetWaterUnitsText(water), buyer));
            }

            if (buyer.Money < price)
            {
                throw new WaterWarsGameLogicException(
                          string.Format(
                              "{0} only has {1} but {2} is trying to sell them water for {3}",
                              buyer, buyer.Money, seller, price));
            }

            m_log.InfoFormat(
                "[WATER WARS]: {0} selling {1} to {2} for {3}",
                seller.Name, WaterWarsUtils.GetWaterUnitsText(water), buyer.Name, price);

            seller.Money                += price;
            buyer.Money                 -= price;
            buyer.WaterCostsThisTurn    += price;
            seller.WaterRevenueThisTurn += price;
            seller.Water                -= water;
            buyer.Water                 += water;

            m_controller.EventManager.TriggerWaterSold(buyer, seller, water, price, true);
            buyer.TriggerChanged();
            seller.TriggerChanged();

            UpdateHudStatus(seller);
            UpdateHudStatus(buyer);

            m_controller.Events.PostToAll(
                string.Format(
                    SELL_WATER_CRAWL_MSG, seller.Name, WaterWarsUtils.GetWaterUnitsText(water), buyer.Name),
                EventLevel.Crawl);
        }
Esempio n. 11
0
        public override void RegisterBuyPoint(BuyPoint bp)
        {
            Vector3 swPoint, nePoint;

            WaterWarsUtils.FindSquareParcelCorners(bp.Location.Parcel, out swPoint, out nePoint);

            if (!Game.BuyPoints.ContainsKey(bp.Uuid))
            {
                m_log.InfoFormat(
                    "[WATER WARS]: Registering buy point {0} named {1} at {2} in parcel {3} ({4},{5})",
                    bp.Uuid, bp.Name, bp.Location.LocalPosition, bp.Location.Parcel.LandData.Name, swPoint, nePoint);
                Game.BuyPoints[bp.Uuid] = bp;
            }
            else
            {
                m_log.WarnFormat(
                    "[WATER WARS]: Attempt to register duplicate buy point {0} named {1} at {2} in parcel {3} ({4},{5})",
                    bp.Uuid, bp.Name, bp.Location.LocalPosition, bp.Location.Parcel.LandData.Name, swPoint, nePoint);
            }

            m_controller.EventManager.TriggerBuyPointRegistered(bp);
        }
Esempio n. 12
0
        protected override void StartState()
        {
            base.StartState();

            // We do not provide a forecast for the next water phase during the current water phase.
            Game.Forecast.Economic = null;
            Game.Forecast.Water    = "Available next build phase";

            List <Player> players;

            lock (Game.Players)
                players = Game.Players.Values.ToList();

            foreach (Player p in players)
            {
                m_controller.Events.Post(
                    p,
                    string.Format(FEED_RAINFALL_MSG, WaterWarsUtils.GetWaterUnitsText(p.WaterReceived)),
                    EventLevel.Alert);
            }

            UpdateAllStatus();
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        /// <summary>
        /// Change the specialization presentation of this buy point view
        /// </summary>
        /// <param name="assetType"></param>
        /// <param name="fields">Fields for which field views need to be created</param>
        public Dictionary <UUID, FieldView> ChangeSpecialization(AbstractGameAssetType assetType, List <Field> fields)
        {
            Dictionary <UUID, FieldView> fvs = new Dictionary <UUID, FieldView>();

            string morphItemName = m_veSceneObjectNames[assetType];

            ChangeSceneObject(m_itemStoreView, morphItemName);
            m_bp.Name = morphItemName;

            if (assetType != AbstractGameAssetType.None)
            {
                Vector3 p1, p2;
                WaterWarsUtils.FindSquareParcelCorners(m_bp.Location.Parcel, out p1, out p2);

//                m_log.InfoFormat("[WATER WARS]: Found corners of parcel at ({0}),({1})", p1, p2);

                int shortDimension = (int)Math.Floor(Math.Sqrt(fields.Count));
                int longDimension  = (int)Math.Ceiling((float)fields.Count / shortDimension);
//                m_log.InfoFormat("[WATER WARS]: Would space as [{0}][{1}]", shortDimension, longDimension);

                // XXX: For now, we're always going to short space the fields on the x axis
                // This shouldn't be a problem if all our regions are square but might start to look a bit odd if they
                // were different rectangular sizes

                // Adjust dimensions to leave a gap around the edges for the buypoint
                p1.X += 5;
                p1.Y += 5;
                p2.X -= 5;
                p2.Y -= 5;

                float xSpacing = (p2.X - p1.X) / (float)shortDimension;
                float ySpacing = (p2.Y - p1.Y) / (float)longDimension;

                List <Vector3> placementPoints = new List <Vector3>();

//                for (int y = y1; y < y2; y += ySpacing)
//                {
//                    for (float x = x1; x < x2; x += xSpacing)
//                    {
//                        placementPoints.Add(new Vector3(x, y, (float)heightHere + 0.1f));
//                    }
//                }

                for (int y = 0; y < longDimension; y++)
                {
                    for (float x = 0; x < shortDimension; x++)
                    {
                        Vector3 spacing = new Vector3(x * xSpacing, y * ySpacing, 2f);
                        placementPoints.Add(p1 + spacing);
                    }
                }

                m_fieldViewScale = new Vector3(xSpacing, ySpacing, 0.1f);
                Vector3 placementAdjustment = new Vector3(xSpacing / 2, ySpacing / 2, 0);

                int i = 0;
                foreach (Vector3 v in placementPoints)
                {
                    FieldView fv = CreateFieldView(fields[i++], v + placementAdjustment);
                    fvs.Add(fv.RootPart.UUID, fv);
                }
            }
            else
            {
                lock (m_fieldViews)
                {
                    foreach (FieldView fv in m_fieldViews.Values)
                    {
                        fv.Close();
                    }

                    m_fieldViews.Clear();
                }
            }

            return(fvs);
        }
Esempio n. 15
0
        protected Hashtable HandleBuyRights(
            BuyPoint bp, bool buyingDevelopmentRights, bool buyingWaterRights,
            string rawDevelopmentRightsBuyerId, string rawWaterRightsBuyerId,
            int?developmentRightsPrice, int?waterRightsPrice, int?combinedRightsPrice, Hashtable request)
        {
            if (bp.DevelopmentRightsOwner == Player.None)
            {
                m_controller.Resolver.BuyLandRights(bp.Uuid.ToString(), rawDevelopmentRightsBuyerId);
            }
            else
            {
                UUID developmentRightsBuyerId = UUID.Zero;
                if (rawDevelopmentRightsBuyerId != null)
                {
                    developmentRightsBuyerId = WaterWarsUtils.ParseRawId(rawDevelopmentRightsBuyerId);
                }

                UUID waterRightsBuyerId = UUID.Zero;
                if (rawWaterRightsBuyerId != null)
                {
                    waterRightsBuyerId = WaterWarsUtils.ParseRawId(rawWaterRightsBuyerId);
                }

                // TODO: Do player ownership checks later when we have access to this via security

                if (buyingDevelopmentRights && buyingWaterRights)
                {
                    if (null == combinedRightsPrice)
                    {
                        throw new Exception(
                                  string.Format("No combined rights price specified for sale of {0} rights", bp));
                    }

                    m_controller.Resolver.SellRights(
                        bp, developmentRightsBuyerId, RightsType.Combined, (int)combinedRightsPrice);
                }
                else if (buyingDevelopmentRights)
                {
                    if (null == developmentRightsPrice)
                    {
                        throw new Exception(
                                  string.Format("No development rights price specified for sale of {0} rights", bp));
                    }

                    m_controller.Resolver.SellRights(
                        bp, developmentRightsBuyerId, RightsType.Development, (int)developmentRightsPrice);
                }
                else if (buyingWaterRights)
                {
                    if (null == waterRightsPrice)
                    {
                        throw new Exception(
                                  string.Format("No water rights price specified for sale of {0} rights", bp));
                    }

                    m_controller.Resolver.SellRights(
                        bp, waterRightsBuyerId, RightsType.Water, (int)waterRightsPrice);
                }
            }

            // TODO: Deal with error situations: uuid not valid, no such buy point, not enough money, etc.

            Hashtable reply = new Hashtable();

            reply["int_response_code"]   = 200; // 200 OK
            reply["str_response_string"] = "hoorah";
            reply["content_type"]        = "text/plain";

            return(reply);
        }
Esempio n. 16
0
        protected override void PostStartState()
        {
            Dictionary <Player, int>    eotRevenues = CalculateOperatingRevenue();
            Dictionary <Player, int>    eotCosts    = CalculateMaintenanceCosts();
            Dictionary <Player, string> eotMessages = new Dictionary <Player, string>();

            foreach (Player p in Game.Players.Values)
            {
                // Right now we also want to reset all water the player has in hand.
                // TODO: This should be a separate rule
                p.Water = 0;

                p.Money += eotRevenues[p];
                p.Money -= eotCosts[p];
                p.Money -= p.CostOfLiving;

                m_controller.EventManager.TriggerRevenueReceived(p, eotRevenues[p], eotCosts[p], p.CostOfLiving);

                p.RecordHistory();

                int revenue = 0, costs = 0, capitalRevenue = 0, capitalCosts = 0;

                // Common financial components
                revenue        = p.WaterRevenueThisTurn;
                costs          = p.MaintenanceCosts + p.WaterCostsThisTurn + p.CostOfLiving;
                capitalRevenue = p.LandRevenueThisTurn + p.WaterRightsRevenueThisTurn;
                capitalCosts   = p.LandCostsThisTurn + p.WaterRightsCostsThisTurn;

                if (p.Role.Type == RoleType.Farmer)
                {
                    revenue += p.ProjectedRevenueFromProducts;
                    costs   += p.BuildCostsThisTurn;
                }
                else if (p.Role.Type == RoleType.Developer)
                {
                    revenue += p.BuildRevenueThisTurn;
                    costs   += p.BuildCostsThisTurn;
                }
                else if (p.Role.Type == RoleType.Manufacturer)
                {
                    revenue      += p.ProjectedRevenueFromProducts;
                    capitalCosts += p.BuildCostsThisTurn;
                }

                int    profit             = revenue - costs;
                string profitText         = WaterWarsUtils.GetMoneyUnitsText(profit);
                string revenueText        = WaterWarsUtils.GetMoneyUnitsText(revenue);
                string costsText          = WaterWarsUtils.GetMoneyUnitsText(costs);
                string capitalRevenueText = WaterWarsUtils.GetMoneyUnitsText(capitalRevenue);
                string capitalCostsText   = WaterWarsUtils.GetMoneyUnitsText(capitalCosts);

                m_log.InfoFormat(
                    "[WATER WARS]: {0} made {1} ({2} revenue - {3} costs) this turn, excluding {4} capital revenue, {5} capital costs",
                    p.Name, profitText, revenueText, costsText, capitalRevenueText, capitalCostsText);

                string msg = string.Format(REVENUE_AND_COST_MSG, profitText) + "\n";
//                string msg = string.Format(
//                    REVENUE_AND_COST_MSG, profitText, revenueText, costsText, capitalCostsText) + "\n";

                if (m_controller.Game.IsLastRound)
                {
                    msg += GAME_ENDED_STATUS_MSG;
                }
                else
                {
                    msg += BuildStageState.BUILD_PHASE_STARTING_MSG;
                }

                eotMessages[p] = msg;
            }

            // Do these actions after recording history so that project revenues (based on ga allocations) are correct
            List <AbstractGameAsset> assetsRemoved = AgeGameAssets();

            foreach (Player p in Game.Players.Values)
            {
                m_controller.Events.Post(p, eotMessages[p], EventLevel.All);
            }

            ResetPerTurnProperties();

            m_controller.EventManager.TriggerRevenueStageEnded(assetsRemoved);

            if (!m_controller.RoundManager.EndRound())
            {
                m_controller.GameDateManager.AdvanceDate();
                EndState(new BuildStageState(m_controller));
            }
            else
            {
                EndState(new GameEndedState(m_controller));
            }
        }