From 9f592fb51b950f425e666528a5f47437c161f00b Mon Sep 17 00:00:00 2001
From: SilicaAndPina <earsyum@gmail.com>
Date: Thu, 11 Feb 2021 02:31:16 +1300
Subject: [PATCH] Add ranches.

---
 DataCollection/gamedata.json                  |  16 +-
 .../Game/Inventory/HorseInventory.cs          |  12 +-
 .../Game/Inventory/PlayerInventory.cs         |   2 +-
 Horse Isle Server/HorseIsleServer/Game/Map.cs |   7 +-
 .../HorseIsleServer/Game/Messages.cs          |  31 +-
 .../HorseIsleServer/Game/Meta.cs              | 126 ++++-
 .../HorseIsleServer/Game/Ranch.cs             | 267 +++++++----
 .../HorseIsleServer/Game/World.cs             |  19 +
 .../HorseIsleServer/Player/User.cs            |  68 +++
 .../HorseIsleServer/Server/Database.cs        |  31 ++
 .../HorseIsleServer/Server/GameClient.cs      |   3 +
 .../HorseIsleServer/Server/GameDataJson.cs    |  40 +-
 .../HorseIsleServer/Server/GameServer.cs      | 443 +++++++++++++++++-
 .../HorseIsleServer/Server/PacketBuilder.cs   |  12 +
 14 files changed, 918 insertions(+), 159 deletions(-)

diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index 9313a95..f6e1109 100755
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -148,6 +148,8 @@
 			"unowned_ranch":"<B>This is an unowned ranch.</B><BR>It is available for purchase for $%PRICE%<BR>",
 			"you_could_purchase_this":"^T6You could purchase this ranch:^B6P^R1",
 			"ranch_already_owned":"<B>You already own a ranch, however.</B>",
+			"sub_only":"<B>Only Horse Isle subscribers may purchase a ranch however.</B>",
+			"ranch_desc_others":"<BR>^H%DESCRIPTION%<BR>"
 			
 			"unowned_ranch_click":"Unowned Ranch",
 			"click_message":"%USERNAME%'s %TITLE%",
@@ -160,8 +162,11 @@
 			"saved_ranch":"Saved Ranch Description.",
 			"default_title":"Ranch",
 			"edit_description":"^PLRanch Title:|%RANCHTITLE%^LYour Ranch Description:^R1^PB160|%RANCHDESC%^PS11|SAVE DESCRIPTION",
-			"your_ranch_meta":"<B>%USERANME%'s %TITLE%</B>",
+			"your_ranch_meta":"<B>%USERNAME%'s %TITLE%</B>",
 			"view_desc":"^H<B>YOUR RANCH DESCRIPTION:</B><BR>%DESCRIPTION%<BR>^T5Edit Your Ranch Description^D27|DESCRIPTION^R1",
+			
+			"sell_confirm":"^T6Are you SURE you want to sell your ranch?^B6S^R1",
+			"sell_done":"You sold your ranch for $%PRICE%!",
 			"build":{
 				"build_on_this_spot":"You can build one of the following buildings on this spot:",
 				"build_format":"^T6Build a %BUILDINGNAME% for $%PRICE%^B6L%BUILDINGID%^B6B%BUILDINGID%^R1",
@@ -176,20 +181,20 @@
 			"upgrade":{
 				"upgrade_message":"Ranch Upgraded.",
 				"cannot_afford":"You cannot afford this upgrade!",
-				"upgrade_meta":"You currently have a <B>%UPGRADENAME%</B>.<BR>Details: %UPGRADEDESC%<BR>%YOUCOULDUPGRADE%^R1^LYou could also sell your ranch: (75% of total invested)^R1^T6SELL your ranch for $%SELLPRICE%^D60|SELL^R1",	
-				"you_could_upgrade":"<BR>You could upgrade to a:^T6%NEXTUPGRADE% for $%COST%^B6U"
+				"upgrade_meta":"You currently have a <B>%UPGRADENAME%</B>.<BR>Details: %UPGRADEDESC%<BR>%YOUCOULDUPGRADE%^LYou could also sell your ranch: (75% of total invested)^R1^T6SELL your ranch for $%SELLPRICE%^D60|SELL^R1",	
+				"you_could_upgrade":"<BR>You could upgrade to a:^T6%NEXTUPGRADE% for $%COST%^B6U^R1"
 			},
 			"special":{
 				"rest_here":"<BR>You have a building here to rest in. You are now fully rested.",
-				"grain_silo":"<BR>You have a Grain Silo.  All of your horses have just been fully fed.", 
 				"barn":"<BR>You have %COUNT% Barn(s). This provides for %AMOUNT% extra horses.",
 				"big_barn":".<BR>You have %COUNT% Big Barn(s). This provides for %AMOUNT% extra horses",
 				"gold_barn":"<BR>You have %COUNT% Gold Barn(s). This provides for %AMOUNT% extra horses.",
 				"water_well":"<BR>You have a Water Well here.  You and all of your horses have just been watered.",
+				"grain_silo":"<BR>You have a Grain Silo.  All of your horses have just been fully fed.", 
+				"vegatable_garden":"<BR>You have a Vegetable Garden.  You have just fully eaten.",
 				"windmills":"<BR>You have %COUNT% Windmill(s) earning you $%AMOUNT% every 12 game hours.",
 				"wagon":"<BR>^T6Your Wagon can take you to the nearest station.^D7|STATION^R1^H",
 				"training_pen":"<BR>^T6You can train all your horses via the Pen^D13|TRAIN ALL^R1^H",
-				"vegatable_garden":"<BR>You have a Vegetable Garden.  You have just fully eaten.",
 				"train_all":"You attempt to train all of your horses:",
 				"train_success":"<BR>Training <B>%HORSENAME%</B>: +1SP +1ST +1CO +1AG +1EN +1exp",
 				"train_cant_train":"<B>%HORSENAME%</B>: Horse needs to rest %TIME% game minutes.",
@@ -7799,7 +7804,6 @@
 	 }
  },
  "item":{
-	"max_carryable":40,
 	"special":{
 		"present":135,
 		"mail_message":183,
diff --git a/Horse Isle Server/HorseIsleServer/Game/Inventory/HorseInventory.cs b/Horse Isle Server/HorseIsleServer/Game/Inventory/HorseInventory.cs
index 3591599..0f23d87 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Inventory/HorseInventory.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Inventory/HorseInventory.cs	
@@ -17,16 +17,6 @@ namespace HISP.Game.Inventory
             }
         }
 
-        public int MaxHorses
-        { 
-            get
-            {
-                if (baseUser.Subscribed)
-                    return 11;
-
-                return 7; // will change when ranches are implemented.
-            }
-        }
         public HorseInventory(User user)
         {
             baseUser = user;
@@ -35,7 +25,7 @@ namespace HISP.Game.Inventory
 
         public void AddHorse(HorseInstance horse, bool addToDb=true)
         {
-            if (HorseList.Length + 1 > MaxHorses)
+            if (HorseList.Length + 1 > baseUser.MaxHorses)
                 throw new InventoryFullException();
 
             horse.Owner = baseUser.Id;
diff --git a/Horse Isle Server/HorseIsleServer/Game/Inventory/PlayerInventory.cs b/Horse Isle Server/HorseIsleServer/Game/Inventory/PlayerInventory.cs
index d9373ab..ed77f84 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Inventory/PlayerInventory.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Inventory/PlayerInventory.cs	
@@ -162,7 +162,7 @@ namespace HISP.Game.Inventory
                     throw new InventoryMaxStackException();
                 }
             }
-            else if (Count >= Messages.DefaultInventoryMax)
+            else if (Count >= BaseUser.MaxItems)
             {
                 throw new InventoryFullException();
             }
diff --git a/Horse Isle Server/HorseIsleServer/Game/Map.cs b/Horse Isle Server/HorseIsleServer/Game/Map.cs
index 83917ab..4fe9e8a 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Map.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Map.cs	
@@ -39,7 +39,12 @@ namespace HISP.Game
             else if (overlay && Treasure.IsTilePotOfGold(x, y))
                 return 186; // Pot of Gold tile.
             else if (overlay && Ranch.IsRanchHere(x, y))
-                return 170 + Ranch.GetRanchAt(x, y).UpgradedLevel; // Ranch Tile + Upgraded amount
+            {
+                int upgradeLevel = Ranch.GetRanchAt(x, y).UpgradedLevel;
+                if (upgradeLevel > 7)
+                    upgradeLevel = 7;
+                return 170 + upgradeLevel;
+            }
             else if (overlay)
                 return oMapData[pos];
             else if (!overlay)
diff --git a/Horse Isle Server/HorseIsleServer/Game/Messages.cs b/Horse Isle Server/HorseIsleServer/Game/Messages.cs
index ec4c34d..afb19e8 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Messages.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Messages.cs	
@@ -8,7 +8,6 @@ namespace HISP.Game
     public class Messages
     {
         public static int RequiredChatViolations;
-        public static int DefaultInventoryMax;
 
         // Mod isle
         public static string ModIsleMessage;
@@ -17,6 +16,8 @@ namespace HISP.Game
         public static string RanchUnownedRanchFormat;
         public static string RanchYouCouldPurchaseThisRanch;
         public static string RanchYouAllreadyOwnARanch;
+        public static string RanchSubscribersOnly;
+        public static string RanchDescriptionOthersFormat;
         public static string RanchUnownedRanchClicked;
         public static string RanchClickMessageFormat;
 
@@ -29,8 +30,11 @@ namespace HISP.Game
         public static string RanchDefaultRanchTitle;
 
         public static string RanchEditDescriptionMetaFormat;
-        public static string RanchYourRanchMetaFormat;
-        public static string RanchDescriptionFormat;
+        public static string RanchTitleFormat;
+        public static string RanchYourDescriptionFormat;
+
+        public static string RanchSellAreYouSure;
+        public static string RanchSoldFormat;
 
         // Ranch: Build.
         public static string RanchCanBuildOneOfTheFollowingInThisSpot;
@@ -654,8 +658,15 @@ namespace HISP.Game
 
         // Click
         public static string NothingInterestingHere;
-
-        public static string FormatUnownedRanchMeta(int price)
+        public static string FormatRanchDescOthers(string description)
+        {
+            return RanchDescriptionOthersFormat.Replace("%DESCRIPTION%", description);
+        }
+        public static string FormatRanchSoldMessage(int price)
+        {
+            return RanchSoldFormat.Replace("%PRICE%", price.ToString("N0"));
+        }
+        public static string FormatRanchUnownedMeta(int price)
         {
             return RanchUnownedRanchFormat.Replace("%PRICE%", price.ToString("N0"));
         }
@@ -673,11 +684,11 @@ namespace HISP.Game
         }
         public static string FormatRanchTitle(string username, string title)
         {
-            return RanchYourRanchMetaFormat.Replace("%USERNAME%", username).Replace("%TITLE%", title);
+            return RanchTitleFormat.Replace("%USERNAME%", username).Replace("%TITLE%", title);
         }
-        public static string FormatRanchDescription(string description)
+        public static string FormatRanchYoursDescription(string description)
         {
-            return RanchDescriptionFormat.Replace("%DESCRIPTION%", description);
+            return RanchYourDescriptionFormat.Replace("%DESCRIPTION%", description);
         }
         public static string FormatBuildingEntry(string name, int price, int buildingId)
         {
@@ -687,9 +698,9 @@ namespace HISP.Game
         {
             return RanchBuildingInformationFormat.Replace("%BUILDINGNAME%", name).Replace("%BUILINGDESCRIPTION%", description);
         }
-        public static string FormatBuildingPlaced(string name, int buildingId, int price)
+        public static string FormatBuildingAlreadyPlaced(string name, int buildingId, int price)
         {
-            return RanchBuildingAlreadyHere.Replace("%BUILDINGNAME%", name).Replace("%BUILDINGID%", buildingId.ToString()).Replace("%PRICE%", price.ToString());
+            return RanchBuildingAlreadyHere.Replace("%BUILDINGNAME%", name).Replace("%BUILDINGID%", buildingId.ToString()).Replace("%PRICE%", price.ToString("N0"));
         }
         public static string FormatBuildingTornDown(int price)
         {
diff --git a/Horse Isle Server/HorseIsleServer/Game/Meta.cs b/Horse Isle Server/HorseIsleServer/Game/Meta.cs
index acce415..122dba0 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Meta.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Meta.cs	
@@ -1024,8 +1024,67 @@ namespace HISP.Game
 
             return message;
         }
+        public static string BuildRanchEdit(Ranch ranch)
+        {
+            return Messages.FormatRanchEditDescriptonMeta(ranch.Title, ranch.Description) + Messages.BackToMap + Messages.MetaTerminator;
+        }
+        public static string BuildRanchSellConfirmation()
+        {
+            return Messages.RanchSellAreYouSure + Messages.BackToMap + Messages.MetaTerminator;
+        }
+        public static string BuildRanchUpgrade(Ranch ranch)
+        {
+            string message = "";
+            Ranch.RanchUpgrade currentUpgrade = ranch.GetRanchUpgrade();
+            bool canUpgrade = Ranch.RanchUpgrade.RanchUpgradeExists(currentUpgrade.Id + 1);
+            
+            string upgrade = "";
+            if(canUpgrade)
+            {
+                Ranch.RanchUpgrade nextUpgrade = Ranch.RanchUpgrade.GetRanchUpgradeById(currentUpgrade.Id + 1);
+                upgrade = Messages.FormatNextUpgrade(nextUpgrade.Title, nextUpgrade.Cost);
+            }
+            message += Messages.FormatCurrentUpgrade(currentUpgrade.Title, currentUpgrade.Description, upgrade, ranch.GetSellPrice());
+            message += Messages.BackToMap;
+            return message;
+        }
+        public static string BuildRanchBuildingsAvalible(Ranch ranch, int slot)
+        {
+            string message = "";
+            if(ranch.GetBuilding(slot-1) != null)
+            {
+                Ranch.RanchBuilding building = ranch.GetBuilding(slot - 1);
+                message += Messages.FormatBuildingAlreadyPlaced(building.Title, building.Id, building.GetTeardownPrice());
+            }
+            else
+            {
+                message += Messages.RanchCanBuildOneOfTheFollowingInThisSpot;
+                foreach (Ranch.RanchBuilding building in Ranch.RanchBuilding.RanchBuildings)
+                {
+                    message += Messages.FormatBuildingEntry(building.Title, building.Cost, building.Id);
+                }
+            }
+
+            message += Messages.BackToMap;
+            return message;
+        }
+        public static string BuildRanchBuilding(Ranch ranch, Ranch.RanchUpgrade upgrade)
+        {
+            string message = "";
+            message += Messages.FormatViewBuilding(upgrade.Title, upgrade.Description);
+            message += Messages.BackToMap;
+            return message;
+        }
+        public static string BuildRanchBuilding(Ranch ranch, Ranch.RanchBuilding upgrade)
+        {
+            string message = "";
+            message += Messages.FormatViewBuilding(upgrade.Title, upgrade.Description);
+            message += Messages.BackToMap;
+            return message;
+        }
         private static string buildRanch(User user, int ranchId)
         {
+            
             string message = "";
             Ranch ranch = Ranch.GetRanchById(ranchId);
             bool mine = (ranch.OwnerId == user.Id);
@@ -1036,17 +1095,77 @@ namespace HISP.Game
 
             if (mine) // This is My DS.
             {
+                user.DoRanchActions();
+
+                string title = ranch.Title;
+                if (title == "" || title == null)
+                    title = Messages.RanchDefaultRanchTitle;
+                message += Messages.FormatRanchTitle(Database.GetUsername(ranch.OwnerId), title);
+                message += Messages.BuildingRestHere;
+
+                int numbBarns = ranch.GetBuildingCount(1);
+                int numbWaterWell = ranch.GetBuildingCount(2);
+                int numbGrainSilo = ranch.GetBuildingCount(3);
+                int numbTrainingPen = ranch.GetBuildingCount(6);
+                int numbWagon = ranch.GetBuildingCount(7);
+                int numbWindmill = ranch.GetBuildingCount(8);
+                int numbGarden = ranch.GetBuildingCount(9);
+                int numbBigBarn = ranch.GetBuildingCount(10);
+                int numbGoldBarn = ranch.GetBuildingCount(11);
                 
+
+                if (numbBarns > 0)
+                    message += Messages.FormatBuildingBarn(numbBarns, numbBarns * 4);
+                if (numbBigBarn > 0)
+                    message += Messages.FormatBuildingBarn(numbBigBarn, numbBigBarn * 8);
+                if (numbGoldBarn > 0)
+                    message += Messages.FormatBuildingBarn(numbGoldBarn, numbGoldBarn * 12);
+                if (numbBarns > 0 || numbBigBarn > 0 || numbGoldBarn > 0)
+                    message += Messages.RanchHorsesFullyRested;
+                if (numbWaterWell > 0)
+                    message += Messages.BuildingWaterWell;
+                if (numbGrainSilo > 0)
+                    message += Messages.BuildingGrainSilo;
+                if (numbWindmill > 0)
+                    message += Messages.FormatBuildingWindmill(numbWindmill, 5000 * numbWindmill);
+                if (numbGarden > 0)
+                    message += Messages.BuildingVegatableGarden;
+                if (numbWagon > 0)
+                    message += Messages.BuildingWagon;
+                if (numbTrainingPen > 0)
+                    message += Messages.BuildingTrainingPen;
+
+                message += Messages.FormatRanchYoursDescription(ranch.Description);
             }
             else if(ranch.OwnerId == -1) // No mans sky
             {
 
+                message += Messages.FormatRanchUnownedMeta(ranch.Value);
+                if (user.OwnedRanch == null)
+                {
+                    if (user.Subscribed)
+                        message += Messages.RanchYouCouldPurchaseThisRanch;
+                    else
+                        message += Messages.RanchSubscribersOnly;
+                }
+                else
+                {
+                    message += Messages.RanchYouAllreadyOwnARanch;
+                }
             }
             else
             {
+                string title = ranch.Title;
+                if (title == "" || title == null)
+                    title = Messages.RanchDefaultRanchTitle;
 
+                message += Messages.FormatRanchTitle(Database.GetUsername(ranch.OwnerId), title);
+                message += Messages.FormatRanchDescOthers(ranch.Description);
             }
 
+            message += Messages.ExitThisPlace;
+            message += Messages.MetaTerminator;
+
             return message;
         }
         private static string buildWorkshop(User user)
@@ -1290,8 +1409,7 @@ namespace HISP.Game
         }
         public static string BuildHorseInventory(User user)
         {
-            // TODO: calculate max number based on ranch barns owned.
-            string message = Messages.FormatHorseHeader(user.HorseInventory.MaxHorses, user.HorseInventory.HorseList.Length);
+            string message = Messages.FormatHorseHeader(user.MaxHorses, user.HorseInventory.HorseList.Length);
 
             message += buildHorseList(user);
             message += Messages.ViewBaiscStats;
@@ -1322,7 +1440,7 @@ namespace HISP.Game
         public static string BuildInventoryInfo(PlayerInventory inv)
         {
             string message = "";
-            message += Messages.FormatPlayerInventoryHeaderMeta(inv.Count, Messages.DefaultInventoryMax);
+            message += Messages.FormatPlayerInventoryHeaderMeta(inv.Count, inv.BaseUser.MaxItems);
             InventoryItem[] items = inv.GetItemList();
             foreach(InventoryItem item in items)
             {
@@ -1335,7 +1453,7 @@ namespace HISP.Game
                 message += Messages.FormatPlayerInventoryItemMeta(itemInfo.IconId, item.ItemInstances.Count, title);
 
                 int randomId = item.ItemInstances[0].RandomId;
-                if (itemInfo.Type != "QUEST" && itemInfo.Type != "TEXT" && World.CanDropItems(inv.BaseUser.X, inv.BaseUser.Y))
+                if (itemInfo.Type != "QUEST" && itemInfo.Type != "TEXT" &&  !(itemInfo.Id == Item.Present || itemInfo.Id == Item.DorothyShoes || itemInfo.Id == Item.Telescope) && World.CanDropItems(inv.BaseUser.X, inv.BaseUser.Y))
                     message += Messages.FormatItemDropButton(randomId);
 
                 if (itemInfo.Id == Item.Present || itemInfo.Id == Item.DorothyShoes || itemInfo.Id == Item.Telescope)
diff --git a/Horse Isle Server/HorseIsleServer/Game/Ranch.cs b/Horse Isle Server/HorseIsleServer/Game/Ranch.cs
index 66de29d..0fe631f 100644
--- a/Horse Isle Server/HorseIsleServer/Game/Ranch.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Ranch.cs	
@@ -1,4 +1,8 @@
-using HISP.Server;
+using HISP.Game.Inventory;
+using HISP.Game.Items;
+using HISP.Player;
+using HISP.Server;
+using System;
 using System.Collections.Generic;
 
 namespace HISP.Game
@@ -59,6 +63,11 @@ namespace HISP.Game
                 }
                 throw new KeyNotFoundException("No ranch found.");
             }
+
+            public int GetTeardownPrice()
+            {
+                return (int)Math.Round((float)this.Cost / (100 / 35.0));
+            }
         }
         public static List<Ranch> Ranches = new List<Ranch>();
 
@@ -73,39 +82,81 @@ namespace HISP.Game
         private string title;
         private string description;
 
+        public int GetSellPrice()
+        {
+            return (int)Math.Round((float)this.InvestedMoney / (100 / 75.0));
+        }
+        private void removeDorothyShoes(int Id)
+        {
+            if (Id == -1)
+                return;
+            
+            if(GameServer.IsUserOnline(Id))
+            {
+                User user = GameServer.GetUserById(Id);
+                user.OwnedRanch = null;
+                InventoryItem items = user.Inventory.GetItemByItemId(Item.DorothyShoes);
+                foreach (ItemInstance itm in items.ItemInstances.ToArray())
+                {
+                    user.Inventory.Remove(itm);
+                }
+            }
+            else
+            {
+                Database.RemoveAllItemTypesFromPlayerInventory(this.Id, Item.DorothyShoes);
+            }
+            
+        }
+        
+        private void deleteRanch()
+        {
+            Database.DeleteRanchOwner(this.Id);
+            removeDorothyShoes(this.ownerId);
+            resetRanch();
+        }
+        private void resetRanch()
+        {
+            title = "";
+            description = "";
+            investedMoney = 0;
+            upgradedLevel = 0;
+            ownerId = -1;
+            for (int i = 0; i < 16; i++)
+                buildings[i] = null;
+        }
         public int OwnerId
         {
             get
             {
+                if(ownerId != -1)
+                {
+                    if (!Database.IsUserSubscribed(ownerId) && !Database.IsUserAdmin(ownerId))
+                        deleteRanch();
+                }
                 return ownerId;
+                
             }
             set
             {
-
-                ownerId = value;
-
                 if (value == -1)
                 {
-                    Database.DeleteRanchOwner(this.Id);
+                    deleteRanch();
                 }
                 else
                 {
                     if(Database.IsRanchOwned(this.Id))
                     {
                         Database.SetRanchOwner(this.Id, ownerId);
+                        removeDorothyShoes(ownerId);
                     }
                     else
                     {
-                        title = "";
-                        description = "";
-                        investedMoney = 0;
-                        upgradedLevel = 0;
-                        for (int i = 0; i < 16; i++)
-                            buildings[i] = null;
-
-                        Database.AddRanch(this.Id, OwnerId, "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+                        resetRanch();
+                        Database.AddRanch(this.Id, value, "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
                     }
                 }
+
+                ownerId = value;
             }
         }
 
@@ -129,8 +180,8 @@ namespace HISP.Game
             }
             set
             {
-                investedMoney = 0;
-                Database.SetRanchUpgradeLevel(Id, value);
+                investedMoney = value;
+                Database.SetRanchInvestment(Id, value);
             }
         }
         public string Title
@@ -160,89 +211,101 @@ namespace HISP.Game
         
 
         private RanchBuilding[] buildings = new RanchBuilding[16];
-
-        public RanchBuilding[] Buildings
+        public int GetBuildingCount(int buildingId)
         {
-            get
+            int count = 0;
+            foreach(RanchBuilding building in buildings)
             {
-                return buildings;
-            }
-            set
-            {
-                buildings = value;
-                if (buildings[0] != null)
-                    Database.SetRanchBuilding1(this.Id, buildings[0].Id);
-                else
-                    Database.SetRanchBuilding1(this.Id, 0);
-                if (buildings[1] != null)
-                    Database.SetRanchBuilding2(this.Id, buildings[1].Id);
-                else
-                    Database.SetRanchBuilding2(this.Id, 0);
-                if (buildings[2] != null)
-                    Database.SetRanchBuilding3(this.Id, buildings[2].Id);
-                else
-                    Database.SetRanchBuilding3(this.Id, 0);
-                if (buildings[3] != null)
-                    Database.SetRanchBuilding4(this.Id, buildings[3].Id);
-                else
-                    Database.SetRanchBuilding4(this.Id, 0);
-                if (buildings[4] != null)
-                    Database.SetRanchBuilding5(this.Id, buildings[4].Id);
-                else
-                    Database.SetRanchBuilding5(this.Id, 0);
-                if (buildings[5] != null)
-                    Database.SetRanchBuilding6(this.Id, buildings[5].Id);
-                else
-                    Database.SetRanchBuilding6(this.Id, 0);
-                if (buildings[6] != null)
-                    Database.SetRanchBuilding7(this.Id, buildings[6].Id);
-                else
-                    Database.SetRanchBuilding7(this.Id, 0);
-                if (buildings[7] != null)
-                    Database.SetRanchBuilding8(this.Id, buildings[7].Id);
-                else
-                    Database.SetRanchBuilding8(this.Id, 0);
-                if (buildings[8] != null)
-                    Database.SetRanchBuilding9(this.Id, buildings[8].Id);
-                else
-                    Database.SetRanchBuilding9(this.Id, 0);
-                if (buildings[9] != null)
-                    Database.SetRanchBuilding10(this.Id, buildings[9].Id);
-                else
-                    Database.SetRanchBuilding10(this.Id, 0);
-                if (buildings[10] != null)
-                    Database.SetRanchBuilding11(this.Id, buildings[10].Id);
-                else
-                    Database.SetRanchBuilding11(this.Id, 0);
-                if (buildings[11] != null)
-                    Database.SetRanchBuilding12(this.Id, buildings[11].Id);
-                else
-                    Database.SetRanchBuilding12(this.Id, 0);
-                if (buildings[12] != null)
-                    Database.SetRanchBuilding13(this.Id, buildings[12].Id);
-                else
-                    Database.SetRanchBuilding13(this.Id, 0);
-                if (buildings[13] != null)
-                    Database.SetRanchBuilding14(this.Id, buildings[13].Id);
-                else
-                    Database.SetRanchBuilding14(this.Id, 0);
-                if (buildings[14] != null)
-                    Database.SetRanchBuilding15(this.Id, buildings[14].Id);
-                else
-                    Database.SetRanchBuilding15(this.Id, 0);
-                if (buildings[15] != null)
-                    Database.SetRanchBuilding16(this.Id, buildings[15].Id);
-                else
-                    Database.SetRanchBuilding16(this.Id, 0);
+                if(building != null)
+                    if (building.Id == buildingId)
+                        count++;
             }
+            return count;
         }
+        private void updateBuildings()
+        {
+            if (buildings[0] != null)
+                Database.SetRanchBuilding1(this.Id, buildings[0].Id);
+            else
+                Database.SetRanchBuilding1(this.Id, 0);
+            if (buildings[1] != null)
+                Database.SetRanchBuilding2(this.Id, buildings[1].Id);
+            else
+                Database.SetRanchBuilding2(this.Id, 0);
+            if (buildings[2] != null)
+                Database.SetRanchBuilding3(this.Id, buildings[2].Id);
+            else
+                Database.SetRanchBuilding3(this.Id, 0);
+            if (buildings[3] != null)
+                Database.SetRanchBuilding4(this.Id, buildings[3].Id);
+            else
+                Database.SetRanchBuilding4(this.Id, 0);
+            if (buildings[4] != null)
+                Database.SetRanchBuilding5(this.Id, buildings[4].Id);
+            else
+                Database.SetRanchBuilding5(this.Id, 0);
+            if (buildings[5] != null)
+                Database.SetRanchBuilding6(this.Id, buildings[5].Id);
+            else
+                Database.SetRanchBuilding6(this.Id, 0);
+            if (buildings[6] != null)
+                Database.SetRanchBuilding7(this.Id, buildings[6].Id);
+            else
+                Database.SetRanchBuilding7(this.Id, 0);
+            if (buildings[7] != null)
+                Database.SetRanchBuilding8(this.Id, buildings[7].Id);
+            else
+                Database.SetRanchBuilding8(this.Id, 0);
+            if (buildings[8] != null)
+                Database.SetRanchBuilding9(this.Id, buildings[8].Id);
+            else
+                Database.SetRanchBuilding9(this.Id, 0);
+            if (buildings[9] != null)
+                Database.SetRanchBuilding10(this.Id, buildings[9].Id);
+            else
+                Database.SetRanchBuilding10(this.Id, 0);
+            if (buildings[10] != null)
+                Database.SetRanchBuilding11(this.Id, buildings[10].Id);
+            else
+                Database.SetRanchBuilding11(this.Id, 0);
+            if (buildings[11] != null)
+                Database.SetRanchBuilding12(this.Id, buildings[11].Id);
+            else
+                Database.SetRanchBuilding12(this.Id, 0);
+            if (buildings[12] != null)
+                Database.SetRanchBuilding13(this.Id, buildings[12].Id);
+            else
+                Database.SetRanchBuilding13(this.Id, 0);
+            if (buildings[13] != null)
+                Database.SetRanchBuilding14(this.Id, buildings[13].Id);
+            else
+                Database.SetRanchBuilding14(this.Id, 0);
+            if (buildings[14] != null)
+                Database.SetRanchBuilding15(this.Id, buildings[14].Id);
+            else
+                Database.SetRanchBuilding15(this.Id, 0);
+            if (buildings[15] != null)
+                Database.SetRanchBuilding16(this.Id, buildings[15].Id);
+            else
+                Database.SetRanchBuilding16(this.Id, 0);
+        }
+        public RanchBuilding GetBuilding(int buildingId)
+        {
+            return buildings[buildingId];
+        }
+        public void SetBuilding(int buildingId, RanchBuilding value)
+        {
+            buildings[buildingId] = value;
+            updateBuildings();
+        }
+
 
         public string GetSwf(bool mine)
         {
-            string swf  = "ranchviewer.swf?H=" + upgradedLevel+1.ToString();
+            string swf  = "ranchviewer.swf?H=" + (upgradedLevel+1).ToString();
             for(int i = 0; i < buildings.Length; i++)
             {
-                swf += "&B" + i.ToString() + "=";
+                swf += "&B" + (i+1).ToString() + "=";
                 if (buildings[i] != null)
                 {
                     swf += buildings[i].Id.ToString();
@@ -260,20 +323,20 @@ namespace HISP.Game
             Y = y;
             Id = id;
             Value = value;
-            Title = "";
-            Description = "";
-            UpgradedLevel = 0;
-            OwnerId = -1;
-            InvestedMoney = 0;
+            title = "";
+            description = "";
+            upgradedLevel = 0;
+            ownerId = -1;
+            investedMoney = 0;
             for (int i = 0; i < 16; i++)
                 buildings[i] = null;
-
-            if (Database.IsRanchOwned(id))
+            bool owned = Database.IsRanchOwned(id);
+            if (owned)
             {
-                UpgradedLevel = Database.GetRanchUpgradeLevel(id);
-                Title = Database.GetRanchTitle(id);
-                Description = Database.GetRanchDescription(id);
-                OwnerId = Database.GetRanchOwner(id);
+                upgradedLevel = Database.GetRanchUpgradeLevel(id);
+                title = Database.GetRanchTitle(id);
+                description = Database.GetRanchDescription(id);
+                ownerId = Database.GetRanchOwner(id);
                 int b1 = Database.GetRanchBuilding1(id);
                 int b2 = Database.GetRanchBuilding2(id);
                 int b3 = Database.GetRanchBuilding3(id);
@@ -329,6 +392,10 @@ namespace HISP.Game
             }
         }
 
+        public RanchUpgrade GetRanchUpgrade()
+        {
+            return RanchUpgrade.GetRanchUpgradeById(this.upgradedLevel + 1);
+        }
         public static bool IsRanchHere(int x, int y)
         {
             foreach (Ranch ranch in Ranches)
diff --git a/Horse Isle Server/HorseIsleServer/Game/World.cs b/Horse Isle Server/HorseIsleServer/Game/World.cs
index 54d9f3f..0b13fda 100755
--- a/Horse Isle Server/HorseIsleServer/Game/World.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/World.cs	
@@ -196,6 +196,25 @@ namespace HISP.Game
             // Periodically write time to database:
             if (ServerTime.Minutes % 10 == 0) // every 10-in-game minutes)
                 Database.SetServerTime(ServerTime.Minutes, ServerTime.Days, ServerTime.Years);
+            
+            // Ranch Windmill Payments
+            if(hours % 12 == 0)
+            {
+                Logger.DebugPrint("Paying windmill owners . . . ");
+                foreach (Ranch ranch in Ranch.Ranches)
+                {
+                    int ranchOwner = ranch.OwnerId;
+                    if (ranchOwner != -1)
+                    {
+                        int moneyToAdd = 5000 * ranch.GetBuildingCount(8); // Windmill
+                        if (GameServer.IsUserOnline(ranchOwner))
+                            GameServer.GetUserById(ranchOwner).Money += moneyToAdd;
+                        else
+                            Database.SetPlayerMoney(Database.GetPlayerMoney(ranchOwner) + moneyToAdd, ranchOwner);
+                    }
+                }
+            }
+
 
             if (hours == 24) // 1 day
             {
diff --git a/Horse Isle Server/HorseIsleServer/Player/User.cs b/Horse Isle Server/HorseIsleServer/Player/User.cs
index f723a62..8fb6bf1 100755
--- a/Horse Isle Server/HorseIsleServer/Player/User.cs	
+++ b/Horse Isle Server/HorseIsleServer/Player/User.cs	
@@ -37,6 +37,42 @@ namespace HISP.Player
 
         public bool Idle;
         public int Facing;
+        public int MaxItems
+        {
+            get
+            {
+                int baseValue = 40;
+                if (Subscribed)
+                {
+                    if (OwnedRanch != null)
+                    {
+                        baseValue += 20 * OwnedRanch.GetBuildingCount(4); // Shed
+                        if (baseValue > 80) // 2 sheds max!
+                            baseValue = 80;
+                    }
+                }
+                return baseValue;
+            }
+        }
+        public int MaxHorses
+        {
+            get
+            {
+                if (Subscribed)
+                {
+                    int baseValue = 11;
+                    if(OwnedRanch != null)
+                    {
+                        baseValue += OwnedRanch.GetBuildingCount(1) * 4; // Barn
+                        baseValue += OwnedRanch.GetBuildingCount(10) * 8; // Big Barn
+                        baseValue += OwnedRanch.GetBuildingCount(11) * 12; // Gold Barn
+                    }
+                    return baseValue;
+                }
+
+                return 7; // will change when ranches are implemented.
+            }
+        }
         public Mailbox MailBox;
         public Friends Friends;
         public string Password; // For chat filter.
@@ -56,6 +92,7 @@ namespace HISP.Player
         public int CapturingHorseId;
         public DateTime LoginTime;
         public string LastSeenWeather;
+        public int LastClickedRanchBuilding = 0;
 
         public string GetWeatherSeen()
         {
@@ -67,6 +104,37 @@ namespace HISP.Player
             LastSeenWeather = weather;
             return weather;
         }
+        public void DoRanchActions()
+        {
+            if(OwnedRanch != null)
+            {
+                Tiredness = 1000; // All ranches fully rest you.
+                
+                if(OwnedRanch.GetBuildingCount(2) > 0)
+                {
+                    Thirst = 1000;
+                    foreach (HorseInstance horse in HorseInventory.HorseList)
+                        horse.BasicStats.Thirst = 1000;
+                }
+
+                if (OwnedRanch.GetBuildingCount(3) > 0)
+                {
+                    foreach (HorseInstance horse in HorseInventory.HorseList)
+                        horse.BasicStats.Hunger = 1000;
+                }
+                if(OwnedRanch.GetBuildingCount(9) > 0)
+                {
+                    Hunger = 1000;
+                }
+                if( (OwnedRanch.GetBuildingCount(1) > 0)|| (OwnedRanch.GetBuildingCount(10) > 0) || (OwnedRanch.GetBuildingCount(11) > 0))
+                {
+
+                    foreach (HorseInstance horse in HorseInventory.HorseList)
+                        horse.BasicStats.Tiredness = 1000;
+                }
+
+            }
+        }
         public DateTime SubscribedUntil
         {
             get
diff --git a/Horse Isle Server/HorseIsleServer/Server/Database.cs b/Horse Isle Server/HorseIsleServer/Server/Database.cs
index d759caa..900c4b4 100755
--- a/Horse Isle Server/HorseIsleServer/Server/Database.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/Database.cs	
@@ -3208,6 +3208,22 @@ namespace HISP.Server
                 return subscribedUntil;
             }
         }
+        public static bool IsUserAdmin(int playerId)
+        {
+            using (MySqlConnection db = new MySqlConnection(ConnectionString))
+            {
+                db.Open();
+                MySqlCommand sqlCommand = db.CreateCommand();
+
+                sqlCommand.CommandText = "SELECT Admin FROM Users WHERE Id=@playerId";
+                sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+                sqlCommand.Prepare();
+                bool admin = sqlCommand.ExecuteScalar().ToString() == "YES";
+                sqlCommand.Dispose();
+
+                return admin;
+            }
+        }
         public static bool IsUserSubscribed(int playerId)
         {
             using (MySqlConnection db = new MySqlConnection(ConnectionString))
@@ -3365,6 +3381,21 @@ namespace HISP.Server
             }
         }
 
+        public static void RemoveAllItemTypesFromPlayerInventory(int playerId, int itemId)
+        {
+            using (MySqlConnection db = new MySqlConnection(ConnectionString))
+            {
+                db.Open();
+                MySqlCommand sqlCommand = db.CreateCommand();
+
+                sqlCommand.CommandText = "DELETE FROM Inventory WHERE (PlayerId=@playerId AND ItemID=@itemId)";
+                sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+                sqlCommand.Parameters.AddWithValue("@itemId", itemId);
+                sqlCommand.Prepare();
+                sqlCommand.ExecuteNonQuery();
+                sqlCommand.Dispose();
+            }
+        }
         public static void RemoveItemFromInventory(int playerId, ItemInstance instance)
         {
             using (MySqlConnection db = new MySqlConnection(ConnectionString))
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameClient.cs b/Horse Isle Server/HorseIsleServer/Server/GameClient.cs
index 6389a0b..439105f 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameClient.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/GameClient.cs	
@@ -292,6 +292,9 @@ namespace HISP.Server
                     case PacketBuilder.PACKET_WISH:
                         GameServer.OnWish(this, Packet);
                         break;
+                    case PacketBuilder.PACKET_RANCH:
+                        GameServer.OnRanchPacket(this, Packet);
+                        break;
                     default:
                         Logger.ErrorPrint("Unimplemented Packet: " + BitConverter.ToString(Packet).Replace('-', ' '));
                         break;
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
index 84db6c3..699d59c 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs	
@@ -575,19 +575,6 @@ namespace HISP.Server
                 Workshop.Workshops.Add(wkShop);
                 Logger.DebugPrint("Registered Workshop at X: " + wkShop.X + " Y: " + wkShop.Y);
 
-            }
-            // Register Ranches
-            int totalRanchLocations = gameData.ranch.ranch_locations.Count;
-            for (int i = 0; i < totalRanchLocations; i++)
-            {
-                int x = gameData.ranch.ranch_locations[i].x;
-                int y = gameData.ranch.ranch_locations[i].y;
-                int id = gameData.ranch.ranch_locations[i].id;
-                int value = gameData.ranch.ranch_locations[i].value;
-                Ranch ranch = new Ranch(x, y, id, value);
-                Ranch.Ranches.Add(ranch);
-                Logger.DebugPrint("Registered Ranch at X: " + ranch.X + " Y: " + ranch.Y);
-
             }
             // Register Ranch Buildings
             int totalRanchBuildings = gameData.ranch.ranch_buildings.buildings.Count;
@@ -630,6 +617,19 @@ namespace HISP.Server
                 Ranch.RanchUpgrade.RanchUpgrades.Add(upgrade);
                 Logger.DebugPrint("Registered Ranch Upgrade: " + upgrade.Title);
 
+            }
+            // Register Ranches
+            int totalRanchLocations = gameData.ranch.ranch_locations.Count;
+            for (int i = 0; i < totalRanchLocations; i++)
+            {
+                int x = gameData.ranch.ranch_locations[i].x;
+                int y = gameData.ranch.ranch_locations[i].y;
+                int id = gameData.ranch.ranch_locations[i].id;
+                int value = gameData.ranch.ranch_locations[i].value;
+                Ranch ranch = new Ranch(x, y, id, value);
+                Ranch.Ranches.Add(ranch);
+                Logger.DebugPrint("Registered Ranch id " + id + " at X: " + ranch.X + " Y: " + ranch.Y);
+
             }
             // Register Riddles
             int totalRiddles = gameData.riddle_room.Count;
@@ -670,7 +670,8 @@ namespace HISP.Server
             Messages.RanchUnownedRanchFormat = gameData.messages.meta.ranch.unowned_ranch;
             Messages.RanchYouCouldPurchaseThisRanch = gameData.messages.meta.ranch.you_could_purchase_this;
             Messages.RanchYouAllreadyOwnARanch = gameData.messages.meta.ranch.ranch_already_owned;
-
+            Messages.RanchSubscribersOnly = gameData.messages.meta.ranch.sub_only;
+            Messages.RanchDescriptionOthersFormat = gameData.meta.ranch.ranch_desc_others;
             Messages.RanchUnownedRanchClicked = gameData.messages.meta.ranch.unowned_ranch_click;
             Messages.RanchClickMessageFormat = gameData.messages.meta.ranch.click_message;
 
@@ -682,8 +683,11 @@ namespace HISP.Server
             Messages.RanchSavedRanchDescripton = gameData.messages.meta.ranch.saved_ranch;
             Messages.RanchDefaultRanchTitle = gameData.messages.meta.ranch.default_title;
             Messages.RanchEditDescriptionMetaFormat = gameData.messages.meta.ranch.edit_description;
-            Messages.RanchYourRanchMetaFormat = gameData.messages.meta.ranch.your_ranch_meta;
-            Messages.RanchDescriptionFormat = gameData.messages.meta.ranch.view_desc;
+            Messages.RanchTitleFormat = gameData.messages.meta.ranch.your_ranch_meta;
+            Messages.RanchYourDescriptionFormat = gameData.messages.meta.ranch.view_desc;
+
+            Messages.RanchSellAreYouSure = gameData.messages.meta.ranch.sell_confirm;
+            Messages.RanchSoldFormat = gameData.messages.meta.ranch.sell_done;
 
             // Ranch : Breed
 
@@ -1306,10 +1310,6 @@ namespace HISP.Server
             GameServer.IdleWarning = gameData.messages.disconnect.client_timeout.warn_after;
             GameServer.IdleTimeout = gameData.messages.disconnect.client_timeout.kick_after;
 
-            // Inventory
-
-            Messages.DefaultInventoryMax = gameData.item.max_carryable;
-
             // Competition Gear
 
             Messages.EquipCompetitionGearFormat = gameData.messages.equips.equip_competition_gear_format;
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
index dfb99ab..7ac9e27 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs	
@@ -1166,7 +1166,25 @@ namespace HISP.Server
                                 break;
                             }
                             break;
-
+                        case 11: // Ranch Description Edit
+                            if (dynamicInput.Length >= 2)
+                            {
+                                string title = dynamicInput[1];
+                                string desc = dynamicInput[2];
+                                if(sender.LoggedinUser.OwnedRanch != null)
+                                {
+                                    sender.LoggedinUser.OwnedRanch.Title = title;
+                                    sender.LoggedinUser.OwnedRanch.Description = desc;
+                                }
+                                byte[] descriptionEditedMessage = PacketBuilder.CreateChat(Messages.RanchSavedRanchDescripton, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                                sender.SendPacket(descriptionEditedMessage);
+                            }
+                            else
+                            {
+                                Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to send a invalid dynamic input (ranch description, wrong size)");
+                                break;
+                            }
+                            break;
                         case 12: // Abuse Report
                             if (dynamicInput.Length >= 2)
                             {
@@ -1386,6 +1404,14 @@ namespace HISP.Server
                     metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildAwardList(sender.LoggedinUser));
                     sender.SendPacket(metaPacket);
                     break;
+                case "27": // Ranch Edit
+                    if(sender.LoggedinUser.OwnedRanch != null)
+                    {
+                        sender.LoggedinUser.MetaPriority = true;
+                        metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildRanchEdit(sender.LoggedinUser.OwnedRanch));
+                        sender.SendPacket(metaPacket);
+                    }
+                    break;
                 case "35": // Buddy List
                     sender.LoggedinUser.MetaPriority = true;
                     metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildBuddyList(sender.LoggedinUser));
@@ -1440,6 +1466,11 @@ namespace HISP.Server
                     metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildMiscStats(sender.LoggedinUser));
                     sender.SendPacket(metaPacket);
                     break;
+                case "60": // Ranch Sell
+                    sender.LoggedinUser.MetaPriority = true;
+                    metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildRanchSellConfirmation());
+                    sender.SendPacket(metaPacket);
+                    break;
                 case "28c1": // Abuse Report
                     sender.LoggedinUser.MetaPriority = true;
                     metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildAbuseReportPage());
@@ -2107,8 +2138,6 @@ namespace HISP.Server
             {
                 sender.LoggedinUser.MetaPriority = true;
                 string profilePage = sender.LoggedinUser.ProfilePage;
-                profilePage = profilePage.Replace("<", "[");
-                profilePage = profilePage.Replace(">", "]");
                 byte[] profilePacket = PacketBuilder.CreateProfilePacket(profilePage);
                 sender.SendPacket(profilePacket);
             }
@@ -2889,6 +2918,346 @@ namespace HISP.Server
             }
 
          
+        }
+        public static void OnRanchPacket(GameClient sender, byte[] packet)
+        {
+            if (!sender.LoggedIn)
+            {
+                Logger.ErrorPrint(sender.RemoteIp + " Sent ranch packet when not logged in.");
+                return;
+            }
+            if (packet.Length < 4)
+            {
+                Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid ranch packet.");
+                return;
+            }
+            string packetStr = Encoding.UTF8.GetString(packet);
+            byte method = packet[1];
+
+            if (method == PacketBuilder.RANCH_INFO)
+            {
+                string buildingIdStr = packetStr.Substring(2, packetStr.Length - 4);
+                int buildingId = 0;
+                try
+                {
+                    buildingId = int.Parse(buildingIdStr);
+                }
+                catch (FormatException)
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to get info for building id NaN");
+                    return;
+                }
+                if (Ranch.RanchBuilding.RanchBuildingExists(buildingId))
+                {
+                    Ranch.RanchBuilding building = Ranch.RanchBuilding.GetRanchBuildingById(buildingId);
+
+                    byte[] ranchBuild = PacketBuilder.CreateChat(Messages.FormatBuildingInformaton(building.Title, building.Description), PacketBuilder.CHAT_BOTTOM_RIGHT);
+                    sender.SendPacket(ranchBuild);
+
+                    return;
+                }
+                else
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to get info for building id that didnt exist.");
+                    return;
+                }
+            }
+            else if (method == PacketBuilder.RANCH_SELL)
+            {
+                string NanSTR = packetStr.Substring(2, packetStr.Length - 4);
+                if (NanSTR == "NaN")
+                {
+                    if (sender.LoggedinUser.OwnedRanch == null)
+                    {
+                        Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to sell there ranch when they didnt own one.");
+                        return;
+                    }
+                    int sellPrice = sender.LoggedinUser.OwnedRanch.GetSellPrice();
+                    sender.LoggedinUser.Money += sellPrice;
+                    byte[] sellPacket = PacketBuilder.CreateChat(Messages.FormatRanchSoldMessage(sellPrice), PacketBuilder.CHAT_BOTTOM_RIGHT);
+                    sender.LoggedinUser.OwnedRanch.OwnerId = -1;
+                    sender.SendPacket(sellPacket);
+
+                    // Change map sprite.
+                    User[] users = GetUsersAt(sender.LoggedinUser.X, sender.LoggedinUser.Y, true, true);
+                    foreach (User user in users)
+                    {
+                        byte[] MovementPacket = PacketBuilder.CreateMovementPacket(user.X, user.Y, user.CharacterId, user.Facing, PacketBuilder.DIRECTION_TELEPORT, true);
+                        user.LoggedinClient.SendPacket(MovementPacket);
+                    }
+                    UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y, true);
+                }
+                else
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to sell there ranch without sending NaN.");
+                    return;
+                }
+            }
+            else if (method == PacketBuilder.RANCH_UPGRADE)
+            {
+                string NanSTR = packetStr.Substring(2, packetStr.Length - 4);
+                if (NanSTR == "NaN")
+                {
+                    if (sender.LoggedinUser.OwnedRanch != null)
+                    {
+                        Ranch.RanchUpgrade currentUpgrade = sender.LoggedinUser.OwnedRanch.GetRanchUpgrade();
+
+                        if (!Ranch.RanchUpgrade.RanchUpgradeExists(currentUpgrade.Id + 1))
+                        {
+                            Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to upgrade there ranch when it was max upgrade.");
+                            return;
+                        }
+
+                        Ranch.RanchUpgrade nextUpgrade = Ranch.RanchUpgrade.GetRanchUpgradeById(currentUpgrade.Id + 1);
+                        if (sender.LoggedinUser.Money >= nextUpgrade.Cost)
+                        {
+                            sender.LoggedinUser.Money -= nextUpgrade.Cost;
+                            sender.LoggedinUser.OwnedRanch.InvestedMoney += nextUpgrade.Cost;
+                            sender.LoggedinUser.OwnedRanch.UpgradedLevel++;
+
+                            byte[] upgraded = PacketBuilder.CreateChat(Messages.UpgradedMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(upgraded);
+
+                            // Change map sprite.
+                            User[] users = GetUsersAt(sender.LoggedinUser.X, sender.LoggedinUser.Y, true, true);
+                            foreach (User user in users)
+                            {
+                                byte[] MovementPacket = PacketBuilder.CreateMovementPacket(user.X, user.Y, user.CharacterId, user.Facing, PacketBuilder.DIRECTION_TELEPORT, true);
+                                user.LoggedinClient.SendPacket(MovementPacket);
+                            }
+                            UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y, true);
+                        }
+                        else
+                        {
+                            byte[] cantAfford = PacketBuilder.CreateChat(Messages.UpgradeCannotAfford, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(cantAfford);
+                        }
+                    }
+                    else
+                    {
+                        Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to upgrade there ranch when they didnt own one.");
+                    }
+                }
+                else
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to upgrade there ranch without sending NaN.");
+                    return;
+                }
+            }
+            else if (method == PacketBuilder.RANCH_REMOVE)
+            {
+                string buildingIdStr = packetStr.Substring(2, packetStr.Length - 4);
+                int buildingId = 0;
+                try
+                {
+                    buildingId = int.Parse(buildingIdStr);
+                }
+                catch (FormatException)
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to get info for building id NaN");
+                    return;
+                }
+                if (Ranch.RanchBuilding.RanchBuildingExists(buildingId))
+                {
+                    Ranch.RanchBuilding building = Ranch.RanchBuilding.GetRanchBuildingById(buildingId);
+                    int ranchBuild = sender.LoggedinUser.LastClickedRanchBuilding;
+                    if (ranchBuild == 0)
+                        return;
+                    if (sender.LoggedinUser.OwnedRanch != null)
+                    {
+                        if (ranchBuild > sender.LoggedinUser.OwnedRanch.GetRanchUpgrade().Limit)
+                        {
+                            Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to remove more buildings than the limit.");
+                            return;
+                        }
+                        Ranch.RanchBuilding ranchBuilding = sender.LoggedinUser.OwnedRanch.GetBuilding(ranchBuild - 1);
+                        if (ranchBuilding.Id == buildingId)
+                        {
+                            sender.LoggedinUser.OwnedRanch.SetBuilding(ranchBuild - 1, null);
+                            sender.LoggedinUser.Money += ranchBuilding.GetTeardownPrice();
+                            sender.LoggedinUser.OwnedRanch.InvestedMoney -= building.Cost;
+                            byte[] chatPacket = PacketBuilder.CreateChat(Messages.FormatBuildingTornDown(ranchBuilding.GetTeardownPrice()), PacketBuilder.CHAT_BOTTOM_RIGHT);
+
+                            sender.SendPacket(chatPacket);
+                            UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y, true);
+                            return;
+                        }
+                        else
+                        {
+                            Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to remove bulidingid: " + buildingId + " from building slot " + ranchBuild + " but the building was not found there.");
+                        }
+
+                    }
+                    Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to remove in a ranch when they dont own one.");
+                    return;
+                }
+                else
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to get info for building id that didnt exist.");
+                    return;
+                }
+            }
+            else if (method == PacketBuilder.RANCH_BUILD)
+            {
+                string buildingIdStr = packetStr.Substring(2, packetStr.Length - 4);
+                int buildingId = 0;
+                try
+                {
+                    buildingId = int.Parse(buildingIdStr);
+                }
+                catch (FormatException)
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to get info for building id NaN");
+                    return;
+                }
+                if (Ranch.RanchBuilding.RanchBuildingExists(buildingId))
+                {
+                    Ranch.RanchBuilding building = Ranch.RanchBuilding.GetRanchBuildingById(buildingId);
+                    int ranchBuild = sender.LoggedinUser.LastClickedRanchBuilding;
+                    if (ranchBuild == 0)
+                        return;
+                    if (sender.LoggedinUser.OwnedRanch != null)
+                    {
+                        if (ranchBuild > sender.LoggedinUser.OwnedRanch.GetRanchUpgrade().Limit)
+                        {
+                            Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to build more buildings than the limit.");
+                            return;
+                        }
+
+                        if (sender.LoggedinUser.Money >= building.Cost)
+                        {
+                            sender.LoggedinUser.OwnedRanch.SetBuilding(ranchBuild - 1, building);
+                            sender.LoggedinUser.OwnedRanch.InvestedMoney += building.Cost;
+                            sender.LoggedinUser.Money -= building.Cost;
+                            byte[] chatPacket = PacketBuilder.CreateChat(Messages.RanchBuildingComplete, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(chatPacket);
+                            UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y, true);
+                            return;
+
+                        }
+                        else
+                        {
+                            byte[] chatPacket = PacketBuilder.CreateChat(Messages.RanchCantAffordThisBuilding, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(chatPacket);
+                            return;
+                        }
+                    }
+                    Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to build in a ranch when they dont own one.");
+                    return;
+                }
+                else
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to get info for building id that didnt exist.");
+                    return;
+                }
+            }
+            else if (method == PacketBuilder.RANCH_BUY)
+            {
+                string nan = packetStr.Substring(2, packetStr.Length - 4);
+                if (nan == "NaN")
+                {
+                    if (Ranch.IsRanchHere(sender.LoggedinUser.X, sender.LoggedinUser.Y))
+                    {
+                        Ranch ranch = Ranch.GetRanchAt(sender.LoggedinUser.X, sender.LoggedinUser.Y);
+                        if (sender.LoggedinUser.Money >= ranch.Value)
+                        {
+                            byte[] broughtRanch = PacketBuilder.CreateChat(Messages.FormatRanchBroughtMessage(ranch.Value), PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(broughtRanch);
+                            sender.LoggedinUser.Money -= ranch.Value;
+                            ranch.OwnerId = sender.LoggedinUser.Id;
+                            ranch.InvestedMoney += ranch.Value;
+                            sender.LoggedinUser.OwnedRanch = ranch;
+                            sender.LoggedinUser.Inventory.AddIgnoringFull(new ItemInstance(Item.DorothyShoes));
+                            UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y, true);
+
+                        }
+                        else
+                        {
+                            byte[] cantAfford = PacketBuilder.CreateChat(Messages.RanchCantAffordRanch, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(cantAfford);
+                        }
+                    }
+                    else
+                    {
+                        Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to buy a non existant ranch.");
+                        return;
+                    }
+                }
+                else
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent RANCH_BUY without \"NaN\".");
+                    return;
+                }
+            }
+            else if (method == PacketBuilder.RANCH_CLICK)
+            {
+                if (packet.Length < 6)
+                {
+                    Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid ranch click packet.");
+                    return;
+                }
+                byte action = packet[2];
+                if (action == PacketBuilder.RANCH_CLICK_BUILD)
+                {
+                    if (Ranch.IsRanchHere(sender.LoggedinUser.X, sender.LoggedinUser.Y))
+                    {
+                        Ranch ranch = Ranch.GetRanchAt(sender.LoggedinUser.X, sender.LoggedinUser.Y);
+                        if (sender.LoggedinUser.OwnedRanch != null)
+                        {
+                            if (sender.LoggedinUser.OwnedRanch.Id == ranch.Id)
+                            {
+                                int buildSlot = packet[3] - 40;
+                                sender.LoggedinUser.LastClickedRanchBuilding = buildSlot;
+
+                                if (buildSlot == 0)
+                                {
+                                    byte[] buildingsAvalible = PacketBuilder.CreateMetaPacket(Meta.BuildRanchUpgrade(ranch));
+                                    sender.SendPacket(buildingsAvalible);
+
+                                }
+                                else
+                                {
+                                    byte[] buildingsAvalible = PacketBuilder.CreateMetaPacket(Meta.BuildRanchBuildingsAvalible(ranch, buildSlot));
+                                    sender.SendPacket(buildingsAvalible);
+                                }
+
+
+                                return;
+                            }
+                        }
+                    }
+
+                    Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to build in a ranch they didnt own.");
+                    return;
+                }
+                else if (action == PacketBuilder.RANCH_CLICK_NORM)
+                {
+                    if (Ranch.IsRanchHere(sender.LoggedinUser.X, sender.LoggedinUser.Y))
+                    {
+                        Ranch ranch = Ranch.GetRanchAt(sender.LoggedinUser.X, sender.LoggedinUser.Y);
+                        int buildSlot = packet[3] - 40;
+                        if (buildSlot == 0) // Main Building
+                        {
+                            byte[] upgradeDescription = PacketBuilder.CreateMetaPacket(Meta.BuildRanchBuilding(ranch, ranch.GetRanchUpgrade()));
+                            sender.SendPacket(upgradeDescription);
+                        }
+                        else // Other Building
+                        {
+                            byte[] buildingDescription = PacketBuilder.CreateMetaPacket(Meta.BuildRanchBuilding(ranch, ranch.GetBuilding(buildSlot - 1)));
+                            sender.SendPacket(buildingDescription);
+                        }
+                        return;
+                    }
+                    else
+                    {
+                        Logger.ErrorPrint(sender.LoggedinUser.Username + " sent an Unknown ranch packet " + BitConverter.ToString(packet).Replace("-", " "));
+                    }
+                }
+            }
+            else
+            {
+                Logger.ErrorPrint(sender.LoggedinUser.Username + " sent an Unknown ranch packet " + BitConverter.ToString(packet).Replace("-", " "));
+            }
         }
         public static void OnChatPacket(GameClient sender, byte[] packet)
         {
@@ -3015,6 +3384,21 @@ namespace HISP.Server
                     if (tile.Title != null)
                         returnedMsg = tile.Title;
                 }
+                if(Ranch.IsRanchHere(x, y))
+                {
+                    Ranch ranch = Ranch.GetRanchAt(x, y);
+                    if(ranch.OwnerId == -1)
+                    {
+                        returnedMsg = Messages.RanchUnownedRanchClicked;
+                    }
+                    else
+                    {
+                        string title = ranch.Title;
+                        if (title == null || title == "")
+                            title = Messages.RanchDefaultRanchTitle;
+                        returnedMsg = Messages.FormatRanchClickMessage(Database.GetUsername(ranch.OwnerId), title);
+                    }
+                }
 
                 byte[] tileInfoPacket = PacketBuilder.CreateClickTileInfoPacket(returnedMsg);
                 sender.SendPacket(tileInfoPacket);
@@ -3220,6 +3604,53 @@ namespace HISP.Server
                         sender.SendPacket(itemRemovedMessage);
                     }
                     
+                    break;
+                case PacketBuilder.ITEM_USE:
+                    packetStr = Encoding.UTF8.GetString(packet);
+                    randomIdStr = packetStr.Substring(2, packet.Length - 2);
+                    randomId = 0;
+
+                    try
+                    {
+                        randomId = Int32.Parse(randomIdStr);
+                    }
+                    catch (FormatException)
+                    {
+                        Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid object interaction packet.");
+                        return;
+                    }
+                    if (sender.LoggedinUser.Inventory.HasItem(randomId))
+                    {
+                        InventoryItem itm = sender.LoggedinUser.Inventory.GetItemByRandomid(randomId);
+                        if(itm.ItemId == Item.DorothyShoes)
+                        {
+                            if(World.InIsle(sender.LoggedinUser.X, sender.LoggedinUser.Y))
+                            {
+                                World.Isle isle = World.GetIsle(sender.LoggedinUser.X, sender.LoggedinUser.Y);
+                                if(isle.Name == "Prison Isle")
+                                {
+                                    byte[] dontWorkHere = PacketBuilder.CreateChat(Messages.RanchDorothyShoesPrisonIsleMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                                    sender.SendPacket(dontWorkHere);
+                                    break;
+                                }
+                            }
+
+                            if(sender.LoggedinUser.OwnedRanch == null) // How????
+                            {
+                                Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to use Dorothy Shoes when they did *NOT* own a ranch.");
+                                sender.LoggedinUser.Inventory.Remove(itm.ItemInstances[0]);
+                                break;
+                            }
+                            byte[] noPlaceLIke127001 = PacketBuilder.CreateChat(Messages.RanchDorothyShoesMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(noPlaceLIke127001);
+
+                            sender.LoggedinUser.Teleport(sender.LoggedinUser.OwnedRanch.X, sender.LoggedinUser.OwnedRanch.Y);
+                        }
+                        else
+                        {
+                            Logger.ErrorPrint(sender.LoggedinUser.Username + "Tried to use item with undefined action- ID: " + itm.ItemId);
+                        }
+                    }
                     break;
                 case PacketBuilder.ITEM_WEAR:
                     packetStr = Encoding.UTF8.GetString(packet);
@@ -3772,7 +4203,7 @@ namespace HISP.Server
                                 }
 
                             }
-                            else if(sender.LoggedinUser.Inventory.Count + 1 > Messages.DefaultInventoryMax)
+                            else if(sender.LoggedinUser.Inventory.Count + 1 > sender.LoggedinUser.MaxItems)
                             {
                                 goto showError;
                             }
@@ -4372,13 +4803,13 @@ namespace HISP.Server
 
 
         }
-        public static void UpdateAreaForAll(int x, int y)
+        public static void UpdateAreaForAll(int x, int y, bool ignoreMetaPrio=false)
         {
             foreach(GameClient client in ConnectedClients)
             {
                 if (client.LoggedIn)
                     if (client.LoggedinUser.X == x && client.LoggedinUser.Y == y)
-                        if(!client.LoggedinUser.MetaPriority)
+                        if(!client.LoggedinUser.MetaPriority || ignoreMetaPrio)
                             UpdateArea(client);
             }
         }
diff --git a/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs b/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs
index 1f631cb..37179ec 100755
--- a/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs	
@@ -21,6 +21,7 @@ namespace HISP.Server
         public const byte PACKET_USERINFO = 0x81;
         public const byte PACKET_WORLD = 0x7A;
         public const byte PACKET_BASE_STATS = 0x7B;
+        public const byte PACKET_RANCH = 0x23;
         public const byte PACKET_SWF_CUTSCENE = 0x29;
         public const byte PACKET_SWF_MODULE_FORCE = 0x28;
         public const byte PACKET_SWF_MODULE_GENTLE = 0x2A;
@@ -46,6 +47,16 @@ namespace HISP.Server
         public const byte PACKET_WISH = 0x2C;
         public const byte PACKET_SWFMODULE = 0x50;
 
+        public const byte RANCH_BUY = 0x14;
+        public const byte RANCH_INFO = 0x16;
+        public const byte RANCH_CLICK = 0x17;
+        public const byte RANCH_UPGRADE = 0x18;
+        public const byte RANCH_SELL = 0x15;
+        public const byte RANCH_BUILD = 0x19;
+        public const byte RANCH_REMOVE = 0x1A;
+        public const byte RANCH_CLICK_NORM = 0x14;
+        public const byte RANCH_CLICK_BUILD = 0x15;
+
         public const byte HORSE_LIST = 0x0A;
         public const byte HORSE_LOOK = 0x14;
         public const byte HORSE_FEED = 0x15;
@@ -138,6 +149,7 @@ namespace HISP.Server
         public const byte ITEM_BINOCULARS = 0x5C;
         public const byte ITEM_MAGNIFYING = 0x5D;
         public const byte ITEM_CRAFT = 0x64;
+        public const byte ITEM_USE = 0x5F;
         public const byte ITEM_RAKE = 0x5B;
         public const byte ITEM_SHOVEL = 0x5A;