From 37faab1a6d372fb53729486cc591ad5844cfc40e Mon Sep 17 00:00:00 2001
From: SilicaAndPina <earsyum@gmail.com>
Date: Fri, 19 Feb 2021 00:45:47 +1300
Subject: [PATCH] Add HORSELEASER ....

---
 DataCollection/gamedata.json                  | 146 +++++++++++++++++-
 .../Game/Horse/HorseInstance.cs               |  24 ++-
 .../HorseIsleServer/Game/Horse/Leaser.cs      | 121 +++++++++++++++
 .../HorseIsleServer/Game/Messages.cs          |  26 ++++
 .../HorseIsleServer/Game/Meta.cs              | 132 ++++++++++------
 .../HorseIsleServer/Server/Database.cs        | 104 +++++++++++--
 .../HorseIsleServer/Server/GameClient.cs      |  76 +++++++++
 .../HorseIsleServer/Server/GameDataJson.cs    |  67 ++++++++
 .../HorseIsleServer/Server/GameServer.cs      |  91 ++++++++---
 9 files changed, 709 insertions(+), 78 deletions(-)
 create mode 100644 Horse Isle Server/HorseIsleServer/Game/Horse/Leaser.cs

diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index 8572670..51e98bc 100755
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -59,6 +59,14 @@
 	"incorrect_password":"Incorrect.  You will have to find the correct answer somewhere...",
 	"player_here":"%USERNAME% here",
 	"no_telescope":"You do not have a telescope to use! You try making circles with your hands and placing them in front of one eye,  but it is of minimal aid...",
+	"horse_leaser":{
+		"cant_afford":"You cannot afford the lease fee.",
+		"temporary_horse_added":"New temporary horse added to your horse list.",
+		"horses_full":"You cannot manage any more horses.",
+		"returned_to_uniter":"The %HORSENAME%'s time with you has ended. You were taken back to the Uniter.",
+		"returned_to_uniter_pegasus":"The Pegasus' time with you has ended. You were taken back to the Uniter.",
+		"returned_to_owner":"Your leased horse %HORSENAME% has been returned to the owner."
+	},
 	"treasure":{
 		"pirate_treasure":"Wow!  You found buried treasure worth $%PRIZE%! Gotta love those pirates!",
 		"pot_of_gold":"YEA!  You found the fabled pot of gold at the end of the rainbow! It was worth $%PRIZE%!"
@@ -560,6 +568,7 @@
 				
 				"trainable_in":" Trainable again in %TIME%m.<BR>",
 				"currently_trainable":" Currently trainable.<BR>",
+				"leased_horse":"It is a <B>Leased</B> Horse, with %TIME% real minutes remaining.<BR>",
 				
 				"dismount_button":"^B3N%ID%",
 				"mount_button":"^B3O%ID%",
@@ -550131,5 +550140,140 @@
 		{"arena_id":9,"arena_type":"DRAFT","entry_cost":10000,"race_every":60,"slots":6,"timeout":2},
 		{"arena_id":10,"arena_type":"BEGINNERJUMPING","entry_cost":500,"race_every":60,"slots":6,"timeout":2},
 		{"arena_id":11,"arena_type":"BEGINNERJUMPING","entry_cost":500,"race_every":60,"slots":6,"timeout":2}
-  ]
+  ],
+ "leaser":[
+		{
+			"lease_id":1, 
+			"button_id":"57c1",
+			"info":"^HA very special creature, the Unicorn, can temporarily travel with you for 1 game day (2 hours) for $200,000.^T62hr Unicorn teamup for $200,000^D57c1|TEAM UP^R1",
+			"on_lease":"^ATNew Temporary Unicorn Teamup!^HYou can ride the unicorn without tack. Use the chat command !WARP <I>LOCATION or PLAYERNAME</I> to ask the unicorn to warp you places!<BR>When the time is up, it will be removed from your horses list",
+			"price":200000,
+			"minutes":120,
+			"horse":{
+				"breed":63,
+				"name":"Unicorn",
+				"exp":1000,
+				"color":"white",
+				"gender":"stallion",
+				"hands":66,
+				"basic_stats":{"health":1000,"hunger":1000,"thirst":1000,"mood":500,"energy":1000,"groom":200,"shoes":0}, 
+				"tack":{"saddle":null,"saddle_pad":null, "bridle":null},
+				"advanced_stats":{"speed":0,"strength":0,"conformation":0,"agility":0,"endurance":0,"inteligence":0,"personality":0}
+			}
+		},
+		{
+			"lease_id":1, 
+			"button_id":"57c5",
+			"info":"^HA very special creature, the Unicorn, can temporarily travel with you for 2 game days (4 hours) for $1,000,000.^T64hr Unicorn teamup for $1,000,000^D57c5|TEAM UP^R1",
+			"on_lease":"^ATNew Temporary Unicorn Teamup!^HYou can ride the unicorn without tack. Use the chat command !WARP <I>LOCATION or PLAYERNAME</I> to ask the unicorn to warp you places!<BR>When the time is up, it will be removed from your horses list",
+			"price":1000000,
+			"minutes":240,
+			"horse":{
+				"breed":63,
+				"name":"Unicorn",
+				"exp":1000,
+				"color":"white",
+				"gender":"stallion",
+				"hands":66,
+				"basic_stats":{"health":1000,"hunger":1000,"thirst":1000,"mood":500,"energy":1000,"groom":200,"shoes":0}, 
+				"tack":{"saddle":null,"saddle_pad":null, "bridle":null},
+				"advanced_stats":{"speed":0,"strength":0,"conformation":0,"agility":0,"endurance":0,"inteligence":0,"personality":0}
+			}
+		},
+		{
+			"lease_id":2, 
+			"button_id":"57c2",
+			"info":"^HA very special creature, the Pegasus, can temporarily travel with you for 1 game day (2 hours) for $200,000.^T62hr Pegasus teamup for $200,000^D57c2|TEAM UP^R1",
+			"on_lease":"^ATNew Temporary Pegasus Teamup!^HYou can ride the Pegasus without tack, it can fly over any terrain including water! Enjoy!<BR>When the time is up, it will be removed from your horses list.",
+			"price":200000,
+			"minutes":120,
+			"horse":{
+				"breed":64,
+				"name":"Pegasus",
+				"exp":1000,
+				"color":"white",
+				"gender":"stallion",
+				"hands":65,
+				"basic_stats":{"health":1000,"hunger":1000,"thirst":1000,"mood":500,"energy":1000,"groom":200,"shoes":0}, 
+				"tack":{"saddle":null,"saddle_pad":null, "bridle":null},
+				"advanced_stats":{"speed":0,"strength":0,"conformation":0,"agility":0,"endurance":0,"inteligence":0,"personality":0}
+			}
+		},
+		{
+			"lease_id":2, 
+			"button_id":"57c6",
+			"info":"^HA very special creature, the Pegasus, can temporarily travel with you for 2 game days (4 hours) for $1,000,000.^T64hr Pegasus teamup for $1,000,000^D57c6|TEAM UP^R1",
+			"on_lease":"^ATNew Temporary Pegasus Teamup!^HYou can ride the Pegasus without tack, it can fly over any terrain including water! Enjoy!<BR>When the time is up, it will be removed from your horses list.",
+			"price":1000000,
+			"minutes":240,
+			"horse":{
+				"breed":64,
+				"name":"Pegasus",
+				"exp":1000,
+				"color":"white",
+				"gender":"stallion",
+				"hands":65,
+				"basic_stats":{"health":1000,"hunger":1000,"thirst":1000,"mood":500,"energy":1000,"groom":200,"shoes":0}, 
+				"tack":{"saddle":null,"saddle_pad":null, "bridle":null},
+				"advanced_stats":{"speed":0,"strength":0,"conformation":0,"agility":0,"endurance":0,"inteligence":0,"personality":0}
+			}
+		},
+		{
+			"lease_id":3, 
+			"button_id":"57c3",
+			"info":"^HA tacked, trusty Fell Pony that can temporarily travel with you for 1 game day (2 hours) for $250. Leased horses have limited options. They cannot enter arena events, or minigames, but they come fully tacked for riding!^T62hr Fell Pony lease for $250^D57c3|LEASE^R1",
+			"on_lease":"^ATNew Temporary Horse!^HEnjoy your temporary horse!<BR>When the time is up, it will be removed from your horses list.",
+			"price":250,
+			"minutes":120,
+			"horse":{
+				"breed":16,
+				"name":"Fell Pony",
+				"exp":50,
+				"color":"bay",
+				"gender":"stallion",
+				"hands":53,
+				"basic_stats":{"health":1000,"hunger":1000,"thirst":1000,"mood":500,"energy":1000,"groom":200,"shoes":0}, 
+				"tack":{"saddle":35,"saddle_pad":37, "bridle":36},
+				"advanced_stats":{"speed":0,"strength":0,"conformation":0,"agility":0,"endurance":0,"inteligence":0,"personality":0}
+			}
+		},
+		{
+			"lease_id":4, 
+			"button_id":"57c4",
+			"info":"^HA tacked trusty American Mustang that can temporarily travel with you for 1 game day (2 hours) for $500. Leased horses have limited options. They cannot enter arena events, or minigames, but they come fully tacked for riding!^T62hr American Mustang lease for $500^D57c4|LEASE^R1",
+			"on_lease":"^ATNew Temporary Horse!^HEnjoy your temporary horse!<BR>When the time is up, it will be removed from your horses list.",
+			"price":500,
+			"minutes":120,
+			"horse":{
+				"breed":29,
+				"name":"American Mustang",
+				"color":"palomino",
+				"gender":"stallion",
+				"exp":50,
+				"hands":59,
+				"basic_stats":{"health":1000,"hunger":1000,"thirst":1000,"mood":500,"energy":1000,"groom":200,"shoes":0}, 
+				"tack":{"saddle":272,"saddle_pad":273, "bridle":274},
+				"advanced_stats":{"speed":0,"strength":0,"conformation":0,"agility":0,"endurance":0,"inteligence":0,"personality":0}
+			}
+		},
+		{
+			"lease_id":5,
+			"button_id":"57c7",
+			"info":"^HAn amazing creature, the UniPeg, can temporarily travel with you for 2 game days (4 hours) for $4,000,000.^T64hr UniPeg teamup for $4,000,000^D57c7|TEAM UP^R1",
+			"on_lease":"^ATNew Temporary UniPeg Teamup!^HYou can ride the UniPeg without tack. Use the chat command !WARP <I>LOCATION or PLAYERNAME</I> to ask the UniPeg to warp you places! It can also fly over any terrain including water! Enjoy!<BR>When the time is up, it will be removed from your horses list",
+			"price":4000000,
+			"minutes":240,
+			"horse":{
+				"breed":170,
+				"name":"UniPeg",
+				"color":"white",
+				"gender":"stallion",
+				"exp":1000,
+				"hands":70,
+				"basic_stats":{"health":1000,"hunger":1000,"thirst":1000,"mood":500,"energy":1000,"groom":200,"shoes":0}, 
+				"tack":{"saddle":null,"saddle_pad":null, "bridle":null},
+				"advanced_stats":{"speed":0,"strength":0,"conformation":0,"agility":0,"endurance":0,"inteligence":0,"personality":0}
+			}
+		}
+ ]
 }
diff --git a/Horse Isle Server/HorseIsleServer/Game/Horse/HorseInstance.cs b/Horse Isle Server/HorseIsleServer/Game/Horse/HorseInstance.cs
index 438157d..7dc6b09 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Horse/HorseInstance.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Horse/HorseInstance.cs	
@@ -6,7 +6,7 @@ namespace HISP.Game.Horse
 {
     public class HorseInstance
     {
-        public HorseInstance(HorseInfo.Breed breed, int randomId = -1, string loadName=null, string loadDescription = "", int loadSpoiled=0, string loadCategory="KEEPER", int loadMagicUsed=0, int loadAutoSell=0)
+        public HorseInstance(HorseInfo.Breed breed, int randomId = -1, string loadName=null, string loadDescription = "", int loadSpoiled=0, string loadCategory="KEEPER", int loadMagicUsed=0, int loadAutoSell=0, int leaseTimer=0)
         {
             RandomId = RandomID.NextRandomId(randomId);
             Owner = 0;
@@ -36,9 +36,9 @@ namespace HISP.Game.Horse
                 name = loadName;
             }
             if(GameServer.RandomNumberGenerator.Next(0, 100) > 50)
-                Sex = breed.GenderTypes()[1];
+                Gender = breed.GenderTypes()[1];
             else
-                Sex = breed.GenderTypes()[0];
+                Gender = breed.GenderTypes()[0];
 
             description = loadDescription;
             Breed = breed;
@@ -55,13 +55,24 @@ namespace HISP.Game.Horse
             category = loadCategory;
             spoiled = loadSpoiled;
             magicUsed = loadMagicUsed;
-            RanchId = 0;
+            leaseTime = leaseTimer;
             Leaser = 0;
         }
-        public int RanchId;
         public int Leaser;
         public int RandomId;
         public int Owner;
+        public int LeaseTime
+        {
+            get
+            {
+                return leaseTime;
+            }
+            set
+            {
+                leaseTime = value;
+                Database.SetLeaseTime(this.RandomId, leaseTime);
+            }
+        }
         public string Name
         {
             get
@@ -86,7 +97,7 @@ namespace HISP.Game.Horse
                 Database.SetHorseDescription(this.RandomId, description);
             }
         }
-        public string Sex;
+        public string Gender;
         public string Color;
         public int TrainTimer
         {
@@ -159,6 +170,7 @@ namespace HISP.Game.Horse
         private string name;
         private string description;
         private int spoiled;
+        private int leaseTime;
         private int magicUsed;
         private int autosell;
         private string category;
diff --git a/Horse Isle Server/HorseIsleServer/Game/Horse/Leaser.cs b/Horse Isle Server/HorseIsleServer/Game/Horse/Leaser.cs
new file mode 100644
index 0000000..a905693
--- /dev/null
+++ b/Horse Isle Server/HorseIsleServer/Game/Horse/Leaser.cs	
@@ -0,0 +1,121 @@
+using HISP.Game.Items;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HISP.Game.Horse
+{
+    public class Leaser
+    {
+        public static List<Leaser> HorseLeasers = new List<Leaser>();
+        public Leaser(int breedId, int saddle, int saddlePad, int bridle)
+        {
+            Breed = HorseInfo.GetBreedById(breedId);
+
+            if (saddle != -1)
+                Saddle = Item.GetItemById(saddle);
+            if (saddlePad != -1)
+                SaddlePad = Item.GetItemById(saddlePad);
+            if (bridle != -1)
+                Bridle = Item.GetItemById(bridle);
+
+
+        }
+
+
+        public int LeaseId;
+        public string ButtonId;
+        public string Info;
+        public string OnLeaseText;
+        public int Price;
+        public int Minutes;
+
+        // Horse
+
+        public HorseInfo.Breed Breed;
+        public string HorseName;
+        public string Color;
+        public string Gender;
+
+        public int Health;
+        public int Shoes;
+        public int Hunger;
+        public int Thirst;
+        public int Mood;
+        public int Groom;
+        public int Tiredness;
+        public int Experience;
+
+        public Item.ItemInformation Saddle = null;
+        public Item.ItemInformation SaddlePad = null;
+        public Item.ItemInformation Bridle = null;
+
+        public int Speed;
+        public int Strength;
+        public int Conformation;
+        public int Agility;
+        public int Inteligence;
+        public int Endurance;
+        public int Personality;
+        public int Height;
+
+        public HorseInstance GenerateLeaseHorse()
+        {
+            HorseInstance instance = new HorseInstance(this.Breed, -1, null, "", 0, "LEASED", 0, 0, this.Minutes);
+            instance.Name = this.HorseName;
+            instance.Color = this.Color;
+            instance.Gender = this.Gender;
+            instance.Leaser = this.LeaseId;
+
+            instance.BasicStats = new HorseInfo.BasicStats(instance, Health, Shoes, Hunger, Thirst, Mood, Groom, Tiredness, Experience);
+            instance.AdvancedStats = new HorseInfo.AdvancedStats(instance, Speed, Strength, Conformation, Agility, Inteligence, Endurance, Personality, Height);
+
+            instance.Equipment.Saddle = this.Saddle;
+            instance.Equipment.SaddlePad = this.SaddlePad;
+            instance.Equipment.Bridle = this.Bridle;
+
+            return instance;
+        }
+
+        public static bool LeaserButtonIdExists(string bid)
+        {
+            foreach (Leaser leaser in HorseLeasers)
+            {
+                if (leaser.ButtonId == bid)
+                {
+                    return true;
+                }
+            }
+            return false; 
+        }
+
+        public static Leaser GetLeaserByButtonId(string bid)
+        {
+            foreach(Leaser leaser in HorseLeasers)
+            {
+                if(leaser.ButtonId == bid)
+                {
+                    return leaser;
+                }
+            }
+            throw new KeyNotFoundException("No leaser with button id: " + bid + " found.");
+        }
+
+        public static Leaser[] GetLeasersById(int id)
+        {
+            List<Leaser> leasers = new List<Leaser>();
+
+            foreach (Leaser leaser in HorseLeasers)
+            {
+                if (leaser.LeaseId == id)
+                {
+                    leasers.Add(leaser);
+                }
+            }
+            return leasers.ToArray();
+        }
+
+    }
+}
diff --git a/Horse Isle Server/HorseIsleServer/Game/Messages.cs b/Horse Isle Server/HorseIsleServer/Game/Messages.cs
index b8a104e..9f6079d 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Messages.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Messages.cs	
@@ -19,6 +19,16 @@ namespace HISP.Game
         // Hammock
         public static string HammockText;
 
+        // Horse Leaser
+        public static string HorseLeaserCantAffordMessage;
+        public static string HorseLeaserTemporaryHorseAdded;
+        public static string HorseLeaserHorsesFull;
+
+        public static string HorseLeaserReturnedToUniterPegasus;
+
+        public static string HorseLeaserReturnedToUniterFormat;
+        public static string HorseLeaserReturnedToOwnerFormat;
+
         // Horse Games
         public static string HorseGamesSelectHorse;
         public static string HorseGamesHorseEntryFormat;
@@ -451,6 +461,8 @@ namespace HISP.Game
         public static string HorseTrainableInFormat;
         public static string HorseIsTrainable;
 
+        public static string HorseLeasedRemainingTimeFormat;
+
         public static string HorseCannotMountUntilTackedMessage;
         public static string HorseDismountedBecauseNotTackedMessageFormat;
         public static string HorseMountButtonFormat;
@@ -842,6 +854,16 @@ namespace HISP.Game
 
         // Click
         public static string NothingInterestingHere;
+
+        public static string FormatHorseReturnedToOwner(string horseName)
+        {
+            return HorseLeaserReturnedToOwnerFormat.Replace("%HORSENAME%", horseName);
+        }
+        public static string FormatHorseReturnedToUniter(string horseName)
+        {
+            return HorseLeaserReturnedToUniterFormat.Replace("%HORSENAME%", horseName);
+        }
+
         public static string FormatArenaCompetingHorseEntry(string userName, string horseName, int horseRandomId)
         {
             return ArenaCompetingHorseFormat.Replace("%USERNAME%", userName).Replace("%HORSENAME%", horseName).Replace("%HORSERANDOMID%", horseRandomId.ToString());
@@ -1482,6 +1504,10 @@ namespace HISP.Game
         {
             return HorseTrainableInFormat.Replace("%TIME%", minutes.ToString());
         }
+        public static string FormatHorseIsLeased(int minutes)
+        {
+            return HorseLeasedRemainingTimeFormat.Replace("%TIME%", minutes.ToString());
+        }
 
         public static string FormatDisMountButton(int randomId)
         {
diff --git a/Horse Isle Server/HorseIsleServer/Game/Meta.cs b/Horse Isle Server/HorseIsleServer/Game/Meta.cs
index f099fc1..077d831 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Meta.cs	
+++ b/Horse Isle Server/HorseIsleServer/Game/Meta.cs	
@@ -1801,7 +1801,7 @@ namespace HISP.Game
             string message = Messages.HorseAllBasicStats;
             foreach(HorseInstance horse in user.HorseInventory.HorseList)
             {
-                message += Messages.FormaHorseAllBasicStatsEntry(horse.Name, horse.Color, horse.Breed.Name, horse.Sex, horse.BasicStats.Experience);
+                message += Messages.FormaHorseAllBasicStatsEntry(horse.Name, horse.Color, horse.Breed.Name, horse.Gender, horse.BasicStats.Experience);
                 message += Messages.FormatHorseBasicStat(horse.BasicStats.Health, horse.BasicStats.Hunger, horse.BasicStats.Thirst, horse.BasicStats.Mood, horse.BasicStats.Tiredness, horse.BasicStats.Groom, horse.BasicStats.Shoes);
             }
             message += Messages.BackToMap;
@@ -1825,15 +1825,21 @@ namespace HISP.Game
                 message += Messages.FormatHorseNameOthers(horse.Name);
 
             message += Messages.FormatHorseDescription(horse.Description);
-            message += Messages.FormatHorseHandsHigh(horse.Color, horse.Breed.Name, horse.Sex, HorseInfo.CalculateHands(horse.AdvancedStats.Height, false));
+            message += Messages.FormatHorseHandsHigh(horse.Color, horse.Breed.Name, horse.Gender, HorseInfo.CalculateHands(horse.AdvancedStats.Height, false));
             message += Messages.FormatHorseExperience(horse.BasicStats.Experience);
             
+
             if (horse.TrainTimer > 0)
                 message += Messages.FormatTrainableIn(horse.TrainTimer);
             else
                 message += Messages.HorseIsTrainable;
+            
+            if(horse.Leaser != 0)
+            {
+                message += Messages.FormatHorseIsLeased(horse.LeaseTime);
+            }
 
-            if(isMyHorse)
+            if (isMyHorse)
             {
                 if (user.CurrentlyRidingHorse == null)
                     message += Messages.FormatMountButton(horse.RandomId);
@@ -1842,33 +1848,45 @@ namespace HISP.Game
 
 
                 message += Messages.FormatFeedButton(horse.RandomId);
-                message += Messages.FormatTackButton(horse.RandomId);
-                message += Messages.FormatPetButton(horse.RandomId);
-                message += Messages.FormatProfileButton(horse.RandomId);
-
-                if (horse.Equipment.Saddle == null && horse.Equipment.SaddlePad == null && horse.Equipment.Bridle == null && horse.Equipment.Companion == null)
+                if (horse.Leaser == 0)
                 {
-                    string autoSellMessage = Messages.HorseNoAutoSell;
-                    if (horse.AutoSell > 0)
-                        autoSellMessage = Messages.FormatAutoSellPrice(horse.AutoSell);
-                    message += Messages.FormatAutoSell(autoSellMessage);
-                    if (horse.AutoSell > 0)
-                        message += Messages.HorseChangeAutoSell;
+                    message += Messages.FormatTackButton(horse.RandomId);
+                }
+                message += Messages.FormatPetButton(horse.RandomId);
+                if (horse.Leaser == 0)
+                {
+                    message += Messages.FormatProfileButton(horse.RandomId);
+
+                    if (horse.Equipment.Saddle == null && horse.Equipment.SaddlePad == null && horse.Equipment.Bridle == null && horse.Equipment.Companion == null)
+                    {
+                        string autoSellMessage = Messages.HorseNoAutoSell;
+                        if (horse.AutoSell > 0)
+                            autoSellMessage = Messages.FormatAutoSellPrice(horse.AutoSell);
+                        message += Messages.FormatAutoSell(autoSellMessage);
+                        if (horse.AutoSell > 0)
+                            message += Messages.HorseChangeAutoSell;
+                        else
+                            message += Messages.HorseSetAutoSell;
+                    }
                     else
-                        message += Messages.HorseSetAutoSell;
+                    {
+                        message += Messages.HorseCantAutoSellTacked;
+                    }
                 }
                 else
                 {
-                    message += Messages.HorseCantAutoSellTacked;
+                    message += "^R1";
                 }
             }
 
 
-
-            if(isMyHorse)
-                message += Messages.FormatHorseCategory(horse.Category, Messages.HorseMarkAsCategory);
-            else
-                message += Messages.FormatHorseCategory(horse.Category, "");
+            if (horse.Leaser == 0)
+            {
+                if (isMyHorse)
+                    message += Messages.FormatHorseCategory(horse.Category, Messages.HorseMarkAsCategory);
+                else
+                    message += Messages.FormatHorseCategory(horse.Category, "");
+            }
 
             message += Messages.HorseStats;
 
@@ -1884,15 +1902,18 @@ namespace HISP.Game
             if (horse.Equipment.Bridle != null)
                 message += Messages.FormatHorseTackEntry(horse.Equipment.Bridle.IconId, horse.Equipment.Bridle.Name, horse.Equipment.Bridle.Id);
 
-            message += Messages.HorseCompanion;
-            if (horse.Equipment.Companion != null)
-                if(isMyHorse)
-                    message += Messages.FormatHorseCompanionEntry(horse.Equipment.Companion.IconId, horse.Equipment.Companion.Name, Messages.HorseCompanionChangeButton, horse.Equipment.Companion.Id);
+            if(horse.Leaser == 0)
+            {
+                message += Messages.HorseCompanion;
+                if (horse.Equipment.Companion != null)
+                    if (isMyHorse)
+                        message += Messages.FormatHorseCompanionEntry(horse.Equipment.Companion.IconId, horse.Equipment.Companion.Name, Messages.HorseCompanionChangeButton, horse.Equipment.Companion.Id);
+                    else
+                        message += Messages.FormatHorseCompanionEntry(horse.Equipment.Companion.IconId, horse.Equipment.Companion.Name, "", horse.Equipment.Companion.Id);
                 else
-                    message += Messages.FormatHorseCompanionEntry(horse.Equipment.Companion.IconId, horse.Equipment.Companion.Name, "", horse.Equipment.Companion.Id);
-            else
-                if(isMyHorse)
+                    if (isMyHorse)
                     message += Messages.HorseNoCompanion;
+            }
 
             message += Messages.FormatHorseAdvancedStats(horse.Spoiled, horse.MagicUsed);
 
@@ -1916,23 +1937,25 @@ namespace HISP.Game
             message += Messages.FormatHorseHeight(Convert.ToInt32(Math.Floor(HorseInfo.CalculateHands(horse.Breed.BaseStats.MinHeight,false))), Convert.ToInt32(Math.Floor(HorseInfo.CalculateHands(horse.Breed.BaseStats.MaxHeight,false))));
             
             message += Messages.FormatPossibleColors(horse.Breed.Colors);
-
-            if(isMyHorse)
+            if (horse.Leaser == 0)
             {
-                bool canRelease = true;
-                if (World.InTown(user.X, user.Y))
-                    canRelease = false;
-
-
-                if (World.InSpecialTile(user.X, user.Y))
+                if (isMyHorse)
                 {
-                    World.SpecialTile tile = World.GetSpecialTile(user.X, user.Y);
-                    if (tile.Code != null)
+                    bool canRelease = true;
+                    if (World.InTown(user.X, user.Y))
                         canRelease = false;
-                }
 
-                if (canRelease)
-                    message += Messages.FormatHorseReleaseButton(horse.Breed.Type.ToUpper());
+
+                    if (World.InSpecialTile(user.X, user.Y))
+                    {
+                        World.SpecialTile tile = World.GetSpecialTile(user.X, user.Y);
+                        if (tile.Code != null)
+                            canRelease = false;
+                    }
+
+                    if (canRelease)
+                        message += Messages.FormatHorseReleaseButton(horse.Breed.Type.ToUpper());
+                }
             }
 
 
@@ -1962,7 +1985,7 @@ namespace HISP.Game
                 HorseInfo.StatCalculator inteligenceStat = new HorseInfo.StatCalculator(horse, HorseInfo.StatType.INTELIGENCE);
                 HorseInfo.StatCalculator personalityStat = new HorseInfo.StatCalculator(horse, HorseInfo.StatType.PERSONALITY);
 
-                message += Messages.FormatAllStatsEntry(horse.Name, horse.Color, horse.Breed.Name, horse.Sex, horse.BasicStats.Experience);
+                message += Messages.FormatAllStatsEntry(horse.Name, horse.Color, horse.Breed.Name, horse.Gender, horse.BasicStats.Experience);
                 message += Messages.FormatCompactedBasicStats(horse.BasicStats.Health, horse.BasicStats.Hunger, horse.BasicStats.Thirst, horse.BasicStats.Mood, horse.BasicStats.Tiredness, horse.BasicStats.Groom, horse.BasicStats.Shoes);
                 message += Messages.FormatCompactedAdvancedStats(speedStat.Total, strengthStat.Total, conformationStat.Total, agilityStat.Total, enduranceStat.Total, inteligenceStat.Total, personalityStat.Total);
             }
@@ -2079,7 +2102,7 @@ namespace HISP.Game
         }
         public static string BuildPawneerOrderFound(HorseInstance instance)
         {
-            string message = Messages.FormatPawneerOrderHorseFound(instance.Breed.Name, instance.Color, instance.Sex, instance.AdvancedStats.Height, instance.AdvancedStats.Personality, instance.AdvancedStats.Inteligence);
+            string message = Messages.FormatPawneerOrderHorseFound(instance.Breed.Name, instance.Color, instance.Gender, instance.AdvancedStats.Height, instance.AdvancedStats.Personality, instance.AdvancedStats.Inteligence);
             message += Messages.BackToMap;
             message += Messages.MetaTerminator;
             return message;
@@ -2206,6 +2229,25 @@ namespace HISP.Game
             message += Messages.MetaTerminator;
             return message;
         }
+        public static string BuildLeaserOnLeaseInfo(Leaser leaser)
+        {
+            string mesasge = "";
+            mesasge += leaser.OnLeaseText;
+            mesasge += Messages.BackToMap;
+            mesasge += Messages.MetaTerminator;
+            return mesasge;
+        }
+        private static string buildLeaser(User user, Leaser[] leasers)
+        {
+            string message = "";
+            foreach(Leaser leaser in leasers)
+            {
+                message += leaser.Info;
+            }
+            message += Messages.ExitThisPlace;
+            message += Messages.MetaTerminator;
+            return message;
+        }
         public static string BuildComposeMailMenu()
         {
             string message = Messages.CityHallMailSendMeta;
@@ -2394,6 +2436,10 @@ namespace HISP.Game
                 {
                     message += buildTrainer(user, Trainer.GetTrainerById(int.Parse(TileArg)));
                 }
+                if(TileCode == "HORSELEASER")
+                {
+                    message += buildLeaser(user, Leaser.GetLeasersById(int.Parse(TileArg)));
+                }
                 if (TileCode == "LIBRARY")
                 {
                     message += buildLibary();
diff --git a/Horse Isle Server/HorseIsleServer/Server/Database.cs b/Horse Isle Server/HorseIsleServer/Server/Database.cs
index 521d949..3eaeca2 100755
--- a/Horse Isle Server/HorseIsleServer/Server/Database.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/Database.cs	
@@ -41,7 +41,7 @@ namespace HISP.Server
                 string PoetryRooms = "CREATE TABLE PoetryRooms(poetId INT, X INT, Y INT, roomId INT)";
                 string SavedDrawings = "CREATE TABLE SavedDrawings(playerId INT, Drawing1 TEXT(65535), Drawing2 TEXT(65535), Drawing3 TEXT(65535))";
                 string DrawingRooms = "CREATE TABLE DrawingRooms(roomId INT, Drawing TEXT(65535))";
-                string Horses = "CREATE TABLE Horses(randomId INT, ownerId INT, ranchId INT, leaser INT, breed INT, name TEXT(128), description TEXT(1028), sex TEXT(128), color TEXT(128), health INT, shoes INT, hunger INT, thirst INT, mood INT, groom INT, tiredness INT, experience INT, speed INT, strength INT, conformation INT, agility INT, endurance INT, inteligence INT, personality INT, height INT, saddle INT, saddlepad INT, bridle INT, companion INT, autoSell INT, trainTimer INT, category TEXT(128), spoiled INT, magicUsed INT)";
+                string Horses = "CREATE TABLE Horses(randomId INT, ownerId INT, leaseTime INT, leaser INT, breed INT, name TEXT(128), description TEXT(1028), sex TEXT(128), color TEXT(128), health INT, shoes INT, hunger INT, thirst INT, mood INT, groom INT, tiredness INT, experience INT, speed INT, strength INT, conformation INT, agility INT, endurance INT, inteligence INT, personality INT, height INT, saddle INT, saddlepad INT, bridle INT, companion INT, autoSell INT, trainTimer INT, category TEXT(128), spoiled INT, magicUsed INT)";
                 string WildHorse = "CREATE TABLE WildHorse(randomId INT, originalOwner INT, breed INT, x INT, y INT, name TEXT(128), description TEXT(1028), sex TEXT(128), color TEXT(128), health INT, shoes INT, hunger INT, thirst INT, mood INT, groom INT, tiredness INT, experience INT, speed INT, strength INT, conformation INT, agility INT, endurance INT, inteligence INT, personality INT, height INT, saddle INT, saddlepad INT, bridle INT, companion INT, timeout INT, autoSell INT, trainTimer INT, category TEXT(128), spoiled INT, magicUsed INT)";
                 string LastPlayer = "CREATE TABLE LastPlayer(roomId TEXT(1028), playerId INT)";
                 string TrackingStats = "CREATE TABLE Tracking(playerId INT, what TEXT(128), count INT)";
@@ -1367,16 +1367,16 @@ namespace HISP.Server
             {
                 db.Open();
                 MySqlCommand sqlCommand = db.CreateCommand();
-                sqlCommand.CommandText = "INSERT INTO Horses VALUES(@randomId,@originalOwner,@ranch,@leaser,@breed,@name,@description,@sex,@color,@health,@shoes,@hunger,@thirst,@mood,@groom,@tiredness,@experience,@speed,@strength,@conformation,@agility,@endurance,@inteligence,@personality,@height,@saddle,@saddlepad,@bridle,@companion,@autosell,@training,@category,@spoiled,@magicused)";
+                sqlCommand.CommandText = "INSERT INTO Horses VALUES(@randomId,@originalOwner,@leaseTime,@leaser,@breed,@name,@description,@sex,@color,@health,@shoes,@hunger,@thirst,@mood,@groom,@tiredness,@experience,@speed,@strength,@conformation,@agility,@endurance,@inteligence,@personality,@height,@saddle,@saddlepad,@bridle,@companion,@autosell,@training,@category,@spoiled,@magicused)";
 
                 sqlCommand.Parameters.AddWithValue("@randomId", horse.RandomId);
                 sqlCommand.Parameters.AddWithValue("@originalOwner", horse.Owner);
-                sqlCommand.Parameters.AddWithValue("@ranch", horse.RanchId);
+                sqlCommand.Parameters.AddWithValue("@leaseTime", horse.LeaseTime);
                 sqlCommand.Parameters.AddWithValue("@leaser", horse.Leaser);
                 sqlCommand.Parameters.AddWithValue("@breed", horse.Breed.Id);
                 sqlCommand.Parameters.AddWithValue("@name", horse.Name);
                 sqlCommand.Parameters.AddWithValue("@description", horse.Description);
-                sqlCommand.Parameters.AddWithValue("@sex", horse.Sex);
+                sqlCommand.Parameters.AddWithValue("@sex", horse.Gender);
                 sqlCommand.Parameters.AddWithValue("@color", horse.Color);
 
                 sqlCommand.Parameters.AddWithValue("@health", horse.BasicStats.Health);
@@ -1447,13 +1447,12 @@ namespace HISP.Server
             string category = reader.GetString(31);
             int magicUsed = reader.GetInt32(33);
             int autosell = reader.GetInt32(29);
+            int leaseTime = reader.GetInt32(2);
 
-
-            HorseInstance inst = new HorseInstance(horseBreed, randomId, name, description, spoiled, category, magicUsed, autosell);
+            HorseInstance inst = new HorseInstance(horseBreed, randomId, name, description, spoiled, category, magicUsed, autosell, leaseTime);
             inst.Owner = reader.GetInt32(1);
-            inst.RanchId = reader.GetInt32(2);
             inst.Leaser = reader.GetInt32(3);
-            inst.Sex = reader.GetString(7);
+            inst.Gender = reader.GetString(7);
             inst.Color = reader.GetString(8);
 
 
@@ -1583,7 +1582,7 @@ namespace HISP.Server
                 sqlCommand.Parameters.AddWithValue("@y", horse.Y);
                 sqlCommand.Parameters.AddWithValue("@name", horse.Instance.Name);
                 sqlCommand.Parameters.AddWithValue("@description", horse.Instance.Description);
-                sqlCommand.Parameters.AddWithValue("@sex", horse.Instance.Sex);
+                sqlCommand.Parameters.AddWithValue("@sex", horse.Instance.Gender);
                 sqlCommand.Parameters.AddWithValue("@color", horse.Instance.Color);
 
                 sqlCommand.Parameters.AddWithValue("@health", horse.Instance.BasicStats.Health);
@@ -1664,7 +1663,7 @@ namespace HISP.Server
                     inst.Owner = reader.GetInt32(1);
                     inst.Name = reader.GetString(5);
                     inst.Description = reader.GetString(6);
-                    inst.Sex = reader.GetString(7);
+                    inst.Gender = reader.GetString(7);
                     inst.Color = reader.GetString(8);
 
                     inst.BasicStats.Health = reader.GetInt32(9);
@@ -2295,6 +2294,20 @@ namespace HISP.Server
                 sqlCommand.Dispose();
             }
         }
+        public static void SetLeaseTime(int horseRandomId, int leaseTime)
+        {
+            using (MySqlConnection db = new MySqlConnection(ConnectionString))
+            {
+                db.Open();
+                MySqlCommand sqlCommand = db.CreateCommand();
+                sqlCommand.CommandText = "UPDATE Horses SET leaseTime=@leaseTime WHERE randomId=@randomId";
+                sqlCommand.Parameters.AddWithValue("@leaseTime", leaseTime);
+                sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+                sqlCommand.Prepare();
+                sqlCommand.ExecuteNonQuery();
+                sqlCommand.Dispose();
+            }
+        }
 
         public static void SetHorseName(int horseRandomId, string Name)
         {
@@ -4754,7 +4767,78 @@ namespace HISP.Server
             }
         }
 
+        public static void DeleteExpiredLeasedHorsesForOfflinePlayers()
+        {
+            using (MySqlConnection db = new MySqlConnection(ConnectionString))
+            {
+                db.Open();
+                MySqlCommand sqlCommand = db.CreateCommand();
+                sqlCommand.CommandText = "DELETE FROM Horses WHERE ownerId NOT IN (SELECT playerId FROM onlineusers) AND leaseTime <= 0 AND leaser > 0";
+                sqlCommand.Prepare();
+                sqlCommand.ExecuteNonQuery();
 
+                sqlCommand.Dispose();
+                return;
+            }
+        }
+        public static void TpOfflinePlayersBackToUniterForOfflinePlayers()
+        {
+            using (MySqlConnection db = new MySqlConnection(ConnectionString))
+            {
+                db.Open();
+
+                MySqlCommand sqlCommand = db.CreateCommand();
+                sqlCommand.CommandText = "SELECT ownerId, breed, leaser FROM Horses WHERE ownerId NOT IN (SELECT playerId FROM onlineusers) AND leaseTime <= 0 AND leaser > 0";
+                sqlCommand.Prepare();
+                MySqlDataReader reader = sqlCommand.ExecuteReader();
+
+                while(reader.Read())
+                {
+                    int playerId = reader.GetInt32(0);
+                    string horseType = HorseInfo.GetBreedById(reader.GetInt32(1)).Type;
+                    int leaserId = reader.GetInt32(2);
+
+                    if(horseType == "pegasus" || horseType == "unicorn")
+                    {
+                        foreach(World.SpecialTile tile in World.SpecialTiles)
+                        {
+                            if (tile.Code == null)
+                                continue;
+                            if(tile.Code.StartsWith("HORSELEASER-"))
+                            {
+                                int id = int.Parse(tile.Code.Split("-")[1]);
+                                if(leaserId == id)
+                                {
+                                    SetPlayerX(tile.X, playerId);
+                                    SetPlayerY(tile.Y, playerId);
+                                }
+                            }
+                        }
+                    }
+
+
+                }
+
+                sqlCommand.Dispose();
+                return;
+            }
+        }
+
+        public static void DecrementHorseLeaseTimeForOfflinePlayers()
+        {
+            using (MySqlConnection db = new MySqlConnection(ConnectionString))
+            {
+                db.Open();
+                MySqlCommand sqlCommand = db.CreateCommand();
+                sqlCommand.CommandText = "UPDATE Horses SET leaseTime = leaseTime - 1 WHERE ownerId NOT IN (SELECT playerId FROM onlineusers) AND leaseTime > 0 AND leaser > 0";
+                sqlCommand.Prepare();
+                sqlCommand.ExecuteNonQuery();
+
+                sqlCommand.Dispose();
+                return;
+            }
+            
+        }
         public static void IncPlayerTirednessForOfflineUsers()
         {
             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 3c77562..b993677 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameClient.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/GameClient.cs	
@@ -71,6 +71,82 @@ namespace HISP.Server
                         horse.BasicStats.Tiredness--;
                     }
 
+                    if(horse.Leaser > 0)
+                    {
+                        horse.LeaseTime--;
+
+                        if (horse.LeaseTime <= 0)
+                        {
+                            int tpX = 0;
+                            int tpY = 0;
+                            if(horse.Breed.Type == "unicorn" || horse.Breed.Type == "pegasus")
+                            {
+                                foreach (World.SpecialTile tile in World.SpecialTiles)
+                                {
+                                    if (tile.Code == null)
+                                        continue;
+
+                                    if (tile.Code.StartsWith("HORSELEASER-"))
+                                    {
+                                        int id = int.Parse(tile.Code.Split("-")[1]);
+                                        if (horse.Leaser == id)
+                                        {
+                                            string msg = Messages.FormatHorseReturnedToUniter(horse.Breed.Name);
+                                            if (horse.Breed.Type == "pegasus")
+                                                msg = Messages.HorseLeaserReturnedToUniterPegasus;
+
+                                            byte[] youWereTeleportedToUniter = PacketBuilder.CreateChat(msg, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                                            SendPacket(youWereTeleportedToUniter);
+
+                                            tpX = tile.X;
+                                            tpY = tile.Y;
+
+                                            if(tile.ExitX != 0 && tile.ExitY != 0)
+                                            {
+                                                tpX = tile.ExitX;
+                                                tpY = tile.ExitY;
+                                            }
+                                            else
+                                            {
+                                                tpY++;
+                                            }
+
+                                        }
+                                    }
+                                }
+                                
+                            }
+
+                            byte[] horseReturned = PacketBuilder.CreateChat(Messages.FormatHorseReturnedToOwner(horse.Name), PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            SendPacket(horseReturned);
+
+                            if(tpX != 0 && tpY != 0)
+                                LoggedinUser.Teleport(tpX, tpY);
+
+
+                            if (LoggedinUser.CurrentlyRidingHorse != null)
+                            {
+                                if(LoggedinUser.CurrentlyRidingHorse.RandomId == horse.RandomId)
+                                {
+                                    GameServer.StopRidingHorse(this);
+                                }
+                                
+                             }
+
+                            if(LoggedinUser.LastViewedHorse != null)
+                            {
+                                if(LoggedinUser.LastViewedHorse.RandomId == horse.RandomId)
+                                {
+                                    LoggedinUser.LastViewedHorse = null;
+                                }
+                            }    
+
+
+                             LoggedinUser.HorseInventory.DeleteHorse(horse);
+                        }
+
+                        
+                    }
 
                 }
 
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
index 61a4b8f..19c2204 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs	
@@ -708,6 +708,8 @@ namespace HISP.Server
                 BBCode code = new BBCode(tag, meta);
                 Logger.DebugPrint("Registered BBCODE: " + code.Tag + " to " + code.MetaTranslation);
             }
+
+            // Register Training Pens
             int totalTrainingPens = gameData.training_pens.Count;
             for (int i = 0; i < totalTrainingPens; i++)
             {
@@ -723,6 +725,8 @@ namespace HISP.Server
                 Trainer.Trainers.Add(trainer);
                 Logger.DebugPrint("Registered Training Pen: " + trainer.Id + " for " + trainer.ImprovesStat);
             }
+
+            // Register Arenas
             int totalArenas = gameData.arena.Count;
             for(int i = 0; i < totalArenas; i++)
             {
@@ -736,6 +740,58 @@ namespace HISP.Server
                 Arena arena = new Arena(arenaId, arenaType, arenaEntryCost, raceEvery, slots, timeout);
                 Logger.DebugPrint("Registered Arena: " + arena.Id.ToString()+" as " + arena.Type);
             }
+            // Register Leaser
+            int totalLeasers = gameData.leaser.Count;
+            for (int i = 0; i < totalLeasers; i++)
+            {
+                int breedId = gameData.leaser[i].horse.breed;
+
+                int saddle = -1;
+                int saddlePad = -1;
+                int bridle = -1;
+
+                if (gameData.leaser[i].horse.tack.saddle != null)
+                    saddle = gameData.leaser[i].horse.tack.saddle;
+
+                if (gameData.leaser[i].horse.tack.saddle_pad != null)
+                    saddlePad = gameData.leaser[i].horse.tack.saddle_pad;
+
+                if (gameData.leaser[i].horse.tack.bridle != null)
+                    bridle = gameData.leaser[i].horse.tack.bridle;
+
+                Leaser leaser = new Leaser(breedId, saddle, saddlePad, bridle);
+                leaser.LeaseId = gameData.leaser[i].lease_id;
+                leaser.ButtonId = gameData.leaser[i].button_id;
+                leaser.Info = gameData.leaser[i].info;
+                leaser.OnLeaseText = gameData.leaser[i].on_lease;
+                leaser.Price = gameData.leaser[i].price;
+                leaser.Minutes = gameData.leaser[i].minutes;
+
+                leaser.Color = gameData.leaser[i].horse.color;
+                leaser.Gender = gameData.leaser[i].horse.gender;
+                leaser.Height = gameData.leaser[i].horse.hands;
+                leaser.Experience = gameData.leaser[i].horse.exp;
+                leaser.HorseName = gameData.leaser[i].horse.name; 
+
+                leaser.Health = gameData.leaser[i].horse.basic_stats.health;
+                leaser.Hunger = gameData.leaser[i].horse.basic_stats.hunger;
+                leaser.Thirst = gameData.leaser[i].horse.basic_stats.thirst;
+                leaser.Mood = gameData.leaser[i].horse.basic_stats.mood;
+                leaser.Tiredness = gameData.leaser[i].horse.basic_stats.energy;
+                leaser.Groom = gameData.leaser[i].horse.basic_stats.groom;
+                leaser.Shoes = gameData.leaser[i].horse.basic_stats.shoes;
+
+                leaser.Speed = gameData.leaser[i].horse.advanced_stats.speed;
+                leaser.Strength = gameData.leaser[i].horse.advanced_stats.strength;
+                leaser.Conformation = gameData.leaser[i].horse.advanced_stats.conformation;
+                leaser.Agility = gameData.leaser[i].horse.advanced_stats.agility;
+                leaser.Endurance = gameData.leaser[i].horse.advanced_stats.endurance;
+                leaser.Inteligence = gameData.leaser[i].horse.advanced_stats.inteligence;
+                leaser.Personality = gameData.leaser[i].horse.advanced_stats.personality;
+
+                Leaser.HorseLeasers.Add(leaser);
+                Logger.DebugPrint("Registered Leaser: " + leaser.LeaseId.ToString() + " For a " + leaser.HorseName);
+            }
 
             HorseInfo.HorseNames = gameData.horses.names.ToObject<string[]>();
 
@@ -762,6 +818,16 @@ namespace HISP.Server
             // Hammock Text
             Messages.HammockText = gameData.messages.meta.hammock;
 
+            // Horse Leaser
+            Messages.HorseLeaserCantAffordMessage = gameData.messages.horse_leaser.cant_afford;
+            Messages.HorseLeaserTemporaryHorseAdded = gameData.messages.horse_leaser.temporary_horse_added;
+            Messages.HorseLeaserHorsesFull = gameData.messages.horse_leaser.horses_full;
+
+            Messages.HorseLeaserReturnedToUniterPegasus = gameData.messages.horse_leaser.returned_to_uniter_pegasus;
+
+            Messages.HorseLeaserReturnedToUniterFormat = gameData.messages.horse_leaser.returned_to_uniter;
+            Messages.HorseLeaserReturnedToOwnerFormat = gameData.messages.horse_leaser.returned_to_owner;
+
             // Competitions
             Messages.ArenaResultsMessage = gameData.messages.meta.arena.results;
             Messages.ArenaPlacingFormat = gameData.messages.meta.arena.placing;
@@ -1200,6 +1266,7 @@ namespace HISP.Server
             
             Messages.HorseTrainableInFormat = gameData.messages.meta.horse.horse_inventory.trainable_in;
             Messages.HorseIsTrainable = gameData.messages.meta.horse.horse_inventory.currently_trainable;
+            Messages.HorseLeasedRemainingTimeFormat = gameData.messages.meta.horse.horse_inventory.leased_horse;
 
             Messages.HorseCannotMountUntilTackedMessage = gameData.messages.meta.horse.cannot_mount_tacked;
             Messages.HorseDismountedBecauseNotTackedMessageFormat = gameData.messages.meta.horse.dismount_because_tack;
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
index 229d96e..6167f49 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs	
+++ b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs	
@@ -111,22 +111,10 @@ namespace HISP.Server
                 }
             }
 
-            foreach(GameClient client in ConnectedClients)
-                if (client.LoggedIn)
-                {
-                    if (!client.LoggedinUser.MetaPriority)
-                        Update(client);
-                    byte[] BaseStatsPacketData = PacketBuilder.CreatePlayerData(client.LoggedinUser.Money, GameServer.GetNumberOfPlayers(), client.LoggedinUser.MailBox.UnreadMailCount);
-                    client.SendPacket(BaseStatsPacketData);
 
-                    UpdateWorld(client);
-                    UpdatePlayer(client);
-                }
-  
 
-            Database.IncPlayerTirednessForOfflineUsers();
 
-            if(totalMinutesElapsed % 60 == 0)
+            if (totalMinutesElapsed % 60 == 0)
             {
                 foreach (HorseInstance horse in Database.GetMostSpoiledHorses())
                 {
@@ -144,6 +132,32 @@ namespace HISP.Server
                 DroppedItems.GenerateItems();
             }
 
+
+            foreach (GameClient client in ConnectedClients)
+            {
+                if (client.LoggedIn)
+                {
+                    if (!client.LoggedinUser.MetaPriority)
+                        Update(client);
+                    byte[] BaseStatsPacketData = PacketBuilder.CreatePlayerData(client.LoggedinUser.Money, GameServer.GetNumberOfPlayers(), client.LoggedinUser.MailBox.UnreadMailCount);
+                    client.SendPacket(BaseStatsPacketData);
+
+                    UpdateWorld(client);
+                    UpdatePlayer(client);
+                }
+            }
+
+
+
+            Database.IncPlayerTirednessForOfflineUsers();
+
+            // Offline player handling w sql magic...
+
+            Database.DecrementHorseLeaseTimeForOfflinePlayers();
+            Database.TpOfflinePlayersBackToUniterForOfflinePlayers();
+            Database.DeleteExpiredLeasedHorsesForOfflinePlayers();
+
+
             WildHorse.Update();
             Npc.WanderNpcs();
             minuteTimer.Change(oneMinute, oneMinute);
@@ -2323,7 +2337,7 @@ namespace HISP.Server
 
                                     HorseInstance horseInstance = new HorseInstance(sender.LoggedinUser.PawneerOrderBreed);
                                     horseInstance.Color = sender.LoggedinUser.PawneerOrderColor;
-                                    horseInstance.Sex = sender.LoggedinUser.PawneerOrderGender;
+                                    horseInstance.Gender = sender.LoggedinUser.PawneerOrderGender;
                                     horseInstance.Name = "Pawneer Order";
 
                                     sender.LoggedinUser.Inventory.Remove(sender.LoggedinUser.Inventory.GetItemByItemId(Item.PawneerOrder).ItemInstances[0]);
@@ -2449,6 +2463,43 @@ namespace HISP.Server
                         }
                         break;
                     }
+
+                    if(Leaser.LeaserButtonIdExists(buttonIdStr))
+                    {
+                        Leaser horseLeaser = Leaser.GetLeaserByButtonId(buttonIdStr);
+
+                        if(sender.LoggedinUser.Money >= horseLeaser.Price)
+                        {
+                            if(sender.LoggedinUser.HorseInventory.HorseList.Length + 1 > sender.LoggedinUser.MaxHorses)
+                            {
+                                byte[] cantManageHorses = PacketBuilder.CreateChat(Messages.HorseLeaserHorsesFull, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                                sender.SendPacket(cantManageHorses);
+                                break;
+                            }
+                            else
+                            {
+                                sender.LoggedinUser.MetaPriority = true;
+                                sender.LoggedinUser.Money -= horseLeaser.Price;
+
+                                sender.LoggedinUser.HorseInventory.AddHorse(horseLeaser.GenerateLeaseHorse());
+
+                                byte[] addedHorseMeta = PacketBuilder.CreateMetaPacket(Meta.BuildLeaserOnLeaseInfo(horseLeaser));
+                                sender.SendPacket(addedHorseMeta);
+
+                                byte[] addedNewTempHorseMessage = PacketBuilder.CreateChat(Messages.HorseLeaserTemporaryHorseAdded, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                                sender.SendPacket(addedNewTempHorseMessage);
+                                break;
+
+                            }
+                        }
+                        else
+                        {
+                            byte[] cantAffordLease = PacketBuilder.CreateChat(Messages.HorseLeaserCantAffordMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                            sender.SendPacket(cantAffordLease);
+                            break;
+                        }
+                        
+                    }
                     if(AbuseReport.DoesReasonExist(buttonIdStr))
                     {
                         sender.LoggedinUser.MetaPriority = true;
@@ -6010,13 +6061,17 @@ namespace HISP.Server
         {
             HorseInstance horseMountInst = sender.LoggedinUser.HorseInventory.GetHorseById(horseRandomId);
 
-            if (horseMountInst.Equipment.Saddle == null || horseMountInst.Equipment.SaddlePad == null || horseMountInst.Equipment.Bridle == null)
+            if (horseMountInst.Breed.Type != "unicorn" && horseMountInst.Breed.Type != "pegasus")
             {
-                byte[] horseNotTackedMessage = PacketBuilder.CreateChat(Messages.HorseCannotMountUntilTackedMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
-                sender.SendPacket(horseNotTackedMessage);
-                return;
+                if (horseMountInst.Equipment.Saddle == null || horseMountInst.Equipment.SaddlePad == null || horseMountInst.Equipment.Bridle == null)
+                {
+                    byte[] horseNotTackedMessage = PacketBuilder.CreateChat(Messages.HorseCannotMountUntilTackedMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
+                    sender.SendPacket(horseNotTackedMessage);
+                    return;
+                }
             }
 
+
             string ridingHorseMessage = Messages.FormatHorseRidingMessage(horseMountInst.Name);
             byte[] ridingHorseMessagePacket = PacketBuilder.CreateChat(ridingHorseMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
             sender.SendPacket(ridingHorseMessagePacket);