diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index 26edd4a..0f5b4fb 100644
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -131,6 +131,7 @@
"venus_flytrap_format":"The Giant Venus Flytrap chomped at you!
OUCH!!
It chomped your pocket, taking $%MONEY% with it!!",
"password_input":"
^PLReply:|^PS14|ANSWER^R1",
"last_poet":"^R1^LLast Player Poet:%USERNAME% ^R1",
+
"horse":{
"stat_format":"%BASE%;%COMPAINON%;%TACK%;%MAX%;",
"basic_stat_format":"^AB%HEALTH%;%HUNGER%;%THIRST%;%MOOD%;%ENERGY%;%GROOM%;%SHOES%;^H",
@@ -149,6 +150,14 @@
"riding_message":"You are now riding %HORSENAME%!",
"stop_riding_message":"You are now not riding a horse!",
"unequip_tack_message":"You removed the tack off %HORSENAME%.",
+ "back_to_horse":"^R1^D5|BACK TO HORSE^R1",
+ "feed_horse":{
+ "horse_neigh":"Your horse neighs a thank you!",
+ "horse_could_not_finish":"The horse could not finish it all. Some was wasted.",
+ "current_status":"%HORSENAME%'s current stats:",
+ "holding_horse_feed":"
You are currently carrying the following horse feed:
",
+ "horsefeed_format":"^I%ICONID%^T3[ %COUNT% ] %NAME%^B3I%RANDOMID%^R1"
+ },
"horse_inventory":{
"your_horse_format":"Your horse: %NAME%:
",
"released_by_format":" Released by %USERNAME%:Released by %USERNAME%:",
@@ -194,7 +203,6 @@
"dequip_bridle":"^I%ICONID%^T5%NAME%^B3M3^R1",
"you_have_following_tack":"^LYou have the following tack in your inventory:^R1",
"equip_tack":"^I%ICONID%^T5[ %COUNT% ] %NAME%^B3K%ID%^R1",
- "back_to_horse":"^R1^D5|BACK TO HORSE^R1"
},
},
"libary":{
diff --git a/Horse Isle Server/Horse Isle Server/Game/Messages.cs b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
index 26a58bb..d19c72b 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Messages.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
@@ -217,6 +217,14 @@ namespace HISP.Game
public static string HorseUnEquipTackMessageFormat;
public static string HorseStopRidingMessage;
+
+ // Horse Feed Menu
+ public static string HorseCurrentStatusFormat;
+ public static string HorseHoldingHorseFeed;
+ public static string HorsefeedFormat;
+ public static string HorseNeighsThanks;
+ public static string HorseCouldNotFinish;
+
// Tack horse menu
public static string HorseTackedAsFollowsFormat;
public static string HorseUnEquipSaddleFormat;
@@ -224,7 +232,7 @@ namespace HISP.Game
public static string HorseUnEquipBridleFormat;
public static string HorseTackInInventory;
public static string HorseEquipFormat;
- public static string HorseBackTo;
+ public static string BackToHorse;
// Consume
@@ -417,6 +425,17 @@ namespace HISP.Game
// Click
public static string NothingInterestingHere;
+
+ public static string FormatHorseCurrentStatus(string name)
+ {
+ return HorseCurrentStatusFormat.Replace("%HORSENAME%", name);
+ }
+
+ public static string FormatHorseFeedEntry(int icon, int count, string name, int randomId)
+ {
+ return HorsefeedFormat.Replace("%ICONID%", icon.ToString()).Replace("%COUNT%", count.ToString("N0")).Replace("%NAME%", name).Replace("%RANDOMID%", randomId.ToString());
+ }
+
public static string FormatHorseRidingMessage(string name)
{
return HorseRidingMessageFormat.Replace("%HORSENAME%", name);
diff --git a/Horse Isle Server/Horse Isle Server/Game/Meta.cs b/Horse Isle Server/Horse Isle Server/Game/Meta.cs
index a1996f4..f6aa668 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Meta.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Meta.cs
@@ -971,6 +971,25 @@ namespace HISP.Game
message += Messages.MetaTerminator;
return message;
}
+ public static string BuildHorseFeedMenu(HorseInstance horse, User user)
+ {
+ string message = "";
+ message += Messages.FormatHorseCurrentStatus(horse.Name);
+ message += Messages.FormatHorseBasicStat(horse.BasicStats.Health, horse.BasicStats.Hunger, horse.BasicStats.Thirst, horse.BasicStats.Mood, 1000, horse.BasicStats.Groom, horse.BasicStats.Groom);
+ message += Messages.HorseHoldingHorseFeed;
+ foreach(InventoryItem item in user.Inventory.GetItemList())
+ {
+ Item.ItemInformation itemInfo = item.ItemInstances[0].GetItemInfo();
+ if(itemInfo.Type == "HORSEFOOD")
+ {
+ message += Messages.FormatHorseFeedEntry(itemInfo.IconId, item.ItemInstances.Count, itemInfo.Name, item.ItemInstances[0].RandomId);
+ }
+
+ }
+ message += Messages.BackToHorse;
+ return message;
+ }
+
public static string BuildHorseInformation(HorseInstance horse, User user)
{
string message = "";
@@ -1226,7 +1245,7 @@ namespace HISP.Game
}
}
- message += Messages.HorseBackTo;
+ message += Messages.BackToHorse;
return message;
}
public static string BuildChatpoint(User user, Npc.NpcEntry npc, Npc.NpcChat chatpoint)
diff --git a/Horse Isle Server/Horse Isle Server/Server/Database.cs b/Horse Isle Server/Horse Isle Server/Server/Database.cs
index 1e4235c..24a79d2 100644
--- a/Horse Isle Server/Horse Isle Server/Server/Database.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/Database.cs
@@ -883,6 +883,147 @@ namespace HISP.Server
return Weather;
}
}
+ public static void SetHorseTiredness(int horseRandomId, int Tiredness)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET tiredness=@tiredness WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@tiredness", Tiredness);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorsePersonality(int horseRandomId, int Personality)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET personality=@personality WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@personality", Personality);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorseSpoiled(int horseRandomId, int Spoiled)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET spoiled=@spoiled WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@spoiled", Spoiled);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorseHeight(int horseRandomId, int Height)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET height=@height WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@height", Height);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorseInteligence(int horseRandomId, int Inteligence)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET inteligence=@inteligence WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@inteligence", Inteligence);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorseMood(int horseRandomId, int Mood)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET mood=@mood WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@mood", Mood);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorseGroom(int horseRandomId, int Groom)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET groom=@groom WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@groom", Groom);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+
+ public static void SetHorseHunger(int horseRandomId, int Hunger)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET hunger=@hunger WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@hunger", Hunger);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorseThirst(int horseRandomId, int Thirst)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET thirst=@thirst WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@thirst", Thirst);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+ public static void SetHorseHealth(int horseRandomId, int Health)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET health=@health WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@health", Health);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
public static void SetSaddle(int horseRandomId, int saddleItemId)
{
diff --git a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
index 0b299ca..450c0b5 100644
--- a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
@@ -652,6 +652,13 @@ namespace HISP.Server
Messages.HorseUnEquipTackMessageFormat = gameData.messages.meta.horse.unequip_tack_message;
Messages.HorseStopRidingMessage = gameData.messages.meta.horse.stop_riding_message;
+ // Horse Feed Menu
+ Messages.HorseCurrentStatusFormat = gameData.messages.meta.horse.feed_horse.current_status;
+ Messages.HorseHoldingHorseFeed = gameData.messages.meta.horse.feed_horse.holding_horse_feed;
+ Messages.HorsefeedFormat = gameData.messages.meta.horse.feed_horse.horsefeed_format;
+ Messages.HorseNeighsThanks = gameData.messages.meta.horse.feed_horse.horse_neigh;
+ Messages.HorseCouldNotFinish = gameData.messages.meta.horse.feed_horse.horse_could_not_finish;
+
// Tack menu (horses)
Messages.HorseTackedAsFollowsFormat = gameData.messages.meta.horse.tack_menu.tacked_as_follows;
Messages.HorseUnEquipSaddleFormat = gameData.messages.meta.horse.tack_menu.dequip_saddle;
@@ -659,7 +666,7 @@ namespace HISP.Server
Messages.HorseUnEquipBridleFormat = gameData.messages.meta.horse.tack_menu.dequip_bridle;
Messages.HorseTackInInventory = gameData.messages.meta.horse.tack_menu.you_have_following_tack;
Messages.HorseEquipFormat = gameData.messages.meta.horse.tack_menu.equip_tack;
- Messages.HorseBackTo = gameData.messages.meta.horse.tack_menu.back_to_horse;
+ Messages.BackToHorse = gameData.messages.meta.horse.back_to_horse;
// Libary
diff --git a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
index 7b69e78..c43ae4f 100644
--- a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
@@ -104,8 +104,7 @@ namespace HISP.Server
byte[] metaTags = PacketBuilder.CreateMetaPacket(Meta.BuildHorseInventory(sender.LoggedinUser));
sender.SendPacket(metaTags);
break;
- case PacketBuilder.HORSE_TACK:
-
+ case PacketBuilder.HORSE_FEED:
int randomId = 0;
string packetStr = Encoding.UTF8.GetString(packet);
string randomIdStr = packetStr.Substring(2, packetStr.Length - 4);
@@ -113,6 +112,143 @@ namespace HISP.Server
{
randomId = int.Parse(randomIdStr);
+ }
+ catch (Exception)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid randomid to horse interaction packet ");
+ break;
+ }
+ if (sender.LoggedinUser.HorseInventory.HorseIdExist(randomId))
+ {
+ HorseInstance horseInst = sender.LoggedinUser.HorseInventory.GetHorseById(randomId);
+
+ sender.LoggedinUser.LastViewedHorse = horseInst;
+ sender.LoggedinUser.MetaPriority = true;
+ byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseFeedMenu(horseInst, sender.LoggedinUser));
+ sender.SendPacket(metaPacket);
+ break;
+ }
+ else
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to tack at a non existant horse.");
+ break;
+ }
+ case PacketBuilder.HORSE_GIVE_FEED:
+ randomId = 0;
+ packetStr = Encoding.UTF8.GetString(packet);
+ randomIdStr = packetStr.Substring(2, packetStr.Length - 4);
+ try
+ {
+ randomId = int.Parse(randomIdStr);
+
+ }
+ catch (Exception)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid randomid to horse interaction packet ");
+ break;
+ }
+ if(sender.LoggedinUser.LastViewedHorse == null)
+ {
+ Logger.InfoPrint(sender.LoggedinUser.Username + " Tried to feed a non existant horse.");
+ break;
+ }
+ if (sender.LoggedinUser.Inventory.HasItem(randomId))
+ {
+ InventoryItem item = sender.LoggedinUser.Inventory.GetItemByRandomid(randomId);
+ Item.ItemInformation itemInfo = item.ItemInstances[0].GetItemInfo();
+ HorseInstance horseInstance = sender.LoggedinUser.LastViewedHorse;
+ bool tooMuch = false;
+ if (itemInfo.Type == "HORSEFOOD")
+ {
+ foreach(Item.Effects effect in itemInfo.Effects)
+ {
+ switch(effect.EffectsWhat)
+ {
+ case "HUNGER":
+ horseInstance.BasicStats.Hunger += effect.EffectAmount;
+ if (horseInstance.BasicStats.Hunger > 1000)
+ {
+ horseInstance.BasicStats.Hunger = 1000;
+ tooMuch = true;
+ }
+ Database.SetHorseHunger(horseInstance.RandomId, horseInstance.BasicStats.Hunger);
+ break;
+ case "THIRST":
+ horseInstance.BasicStats.Thirst += effect.EffectAmount;
+ if (horseInstance.BasicStats.Thirst > 1000)
+ {
+ horseInstance.BasicStats.Thirst = 1000;
+ tooMuch = true;
+ }
+ Database.SetHorseThirst(horseInstance.RandomId, horseInstance.BasicStats.Thirst);
+ break;
+ case "MOOD":
+ horseInstance.BasicStats.Mood += effect.EffectAmount;
+ if (horseInstance.BasicStats.Mood > 1000)
+ {
+ horseInstance.BasicStats.Mood = 1000;
+ tooMuch = true;
+ }
+ Database.SetHorseMood(horseInstance.RandomId, horseInstance.BasicStats.Mood);
+ break;
+ case "TIREDNESS":
+ horseInstance.BasicStats.Tiredness += effect.EffectAmount;
+ if (horseInstance.BasicStats.Tiredness > 1000)
+ {
+ horseInstance.BasicStats.Tiredness = 1000;
+ tooMuch = true;
+ }
+ Database.SetHorseTiredness(horseInstance.RandomId, horseInstance.BasicStats.Tiredness);
+ break;
+ case "INTELLIGENCEOFFSET":
+ horseInstance.AdvancedStats.Inteligence += effect.EffectAmount;
+ Database.SetHorseInteligence(horseInstance.RandomId, horseInstance.AdvancedStats.Inteligence);
+ break;
+ case "PERSONALITYOFFSET":
+ horseInstance.AdvancedStats.Personality += effect.EffectAmount;
+ Database.SetHorsePersonality(horseInstance.RandomId, horseInstance.AdvancedStats.Personality);
+ break;
+ case "SPOILED":
+ horseInstance.Spoiled += effect.EffectAmount;
+ Database.SetHorseSpoiled(horseInstance.RandomId, horseInstance.Spoiled);
+ break;
+ }
+ }
+ sender.LoggedinUser.Inventory.Remove(item.ItemInstances[0]);
+
+ byte[] horseNeighThanksPacket = PacketBuilder.CreateChat(Messages.HorseNeighsThanks, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(horseNeighThanksPacket);
+
+ if (tooMuch)
+ {
+ byte[] horseCouldntFinishItAll = PacketBuilder.CreateChat(Messages.HorseCouldNotFinish, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(horseCouldntFinishItAll);
+ }
+
+ sender.LoggedinUser.MetaPriority = true;
+ byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseFeedMenu(sender.LoggedinUser.LastViewedHorse, sender.LoggedinUser));
+ sender.SendPacket(metaPacket);
+ break;
+ }
+ else
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + "Tried to feed a horse a non-HORSEFOOD item.");
+ }
+ break;
+ }
+ else
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to feed a non existant item to a horse.");
+ break;
+ }
+ case PacketBuilder.HORSE_TACK:
+ randomId = 0;
+ packetStr = Encoding.UTF8.GetString(packet);
+ randomIdStr = packetStr.Substring(2, packetStr.Length - 4);
+ try
+ {
+ randomId = int.Parse(randomIdStr);
+
}
catch (Exception)
{
diff --git a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
index 30e8fd1..47e412b 100644
--- a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
@@ -48,8 +48,10 @@ namespace HISP.Server
public const byte HORSE_LIST = 0x0A;
public const byte HORSE_LOOK = 0x14;
+ public const byte HORSE_FEED = 0x15;
public const byte HORSE_TRY_CAPTURE = 0x1C;
public const byte HORSE_TACK = 0x16;
+ public const byte HORSE_GIVE_FEED = 0x1B;
public const byte HORSE_TACK_EQUIP = 0x3C;
public const byte HORSE_TACK_UNEQUIP = 0x3D;
public const byte HORSE_MOUNT = 0x46;