From 11b2621ce79b325ec7d9778246a6fe29ad2f09fe Mon Sep 17 00:00:00 2001 From: SilicaAndPina Date: Wed, 13 Jan 2021 20:01:55 +1300 Subject: [PATCH] implement horse feeding --- DataCollection/gamedata.json | 10 +- .../Horse Isle Server/Game/Messages.cs | 21 ++- .../Horse Isle Server/Game/Meta.cs | 21 ++- .../Horse Isle Server/Server/Database.cs | 141 ++++++++++++++++++ .../Horse Isle Server/Server/GameDataJson.cs | 9 +- .../Horse Isle Server/Server/GameServer.cs | 140 ++++++++++++++++- .../Horse Isle Server/Server/PacketBuilder.cs | 2 + 7 files changed, 338 insertions(+), 6 deletions(-) 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;