diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index e727e80..4e467cb 100644
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -145,7 +145,8 @@
"horse_format":"^I252^T7#%NUMB%: %NAME% (%BREED%) ^B3L%ID%^R1",
"view_basic_stats":"^T6View all of basic stats together:^D33|BASIC STATS^R1",
"view_advanced_stats":"^T6View all advanced stats together:^D34|ALL STATS^R1",
-
+ "equip_tack_message":"You put the %NAME% on %HORSENAME%.",
+ "unequip_tack_message":"You removed the tack off %HORSENAME%.",
"horse_inventory":{
"your_horse_format":"Your horse: %NAME%:
",
"released_by_format":" Released by %USERNAME%:Released by %USERNAME%:",
diff --git a/Horse Isle Server/Horse Isle Server/Game/Messages.cs b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
index b6936eb..7226d62 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Messages.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
@@ -212,10 +212,14 @@ namespace HISP.Game
public static string HorseOthers;
+ public static string HorseEquipTackMessageFormat;
+ public static string HorseUnEquipTackMessageFormat;
+
+
// Tack horse menu
- public static string HorseTackedAsFollows;
+ public static string HorseTackedAsFollowsFormat;
public static string HorseUnEquipSaddleFormat;
- public static string HorseUnEquipSadlePadFormat;
+ public static string HorseUnEquipSaddlePadFormat;
public static string HorseUnEquipBridleFormat;
public static string HorseTackInInventory;
public static string HorseEquipFormat;
@@ -412,6 +416,38 @@ namespace HISP.Game
// Click
public static string NothingInterestingHere;
+ public static string FormatEquipTackMessage(string itemName, string horseName)
+ {
+ return HorseEquipTackMessageFormat.Replace("%NAME%", itemName).Replace("%HORSENAME%", horseName);
+ }
+ public static string FormatUnEquipTackMessage(string horseName)
+ {
+ return HorseUnEquipTackMessageFormat.Replace("%HORSENAME%", horseName);
+ }
+
+ public static string FormatTackedAsFollowedMessage(string name)
+ {
+ return HorseTackedAsFollowsFormat.Replace("%NAME%", name);
+ }
+ public static string FormatUnEquipSaddle(int iconId, string name)
+ {
+ return HorseUnEquipSaddleFormat.Replace("%NAME%", name).Replace("%ICONID%", iconId.ToString());
+ }
+ public static string FormatUnEquipSaddlePad(int iconId, string name)
+ {
+ return HorseUnEquipSaddlePadFormat.Replace("%NAME%", name).Replace("%ICONID%", iconId.ToString());
+ }
+ public static string FormatUnEquipBridle(int iconId, string name)
+ {
+ return HorseUnEquipBridleFormat.Replace("%NAME%", name).Replace("%ICONID%", iconId.ToString());
+ }
+ public static string FormatHorseEquip(int iconId, int count, string name, int id)
+ {
+ return HorseEquipFormat.Replace("%ICONID%", iconId.ToString()).Replace("%COUNT%", count.ToString()).Replace("%NAME%", name).Replace("%ID%", id.ToString());
+ }
+
+
+
public static string FormatHorseName(string name)
{
return HorseNameFormat.Replace("%NAME%", name);
diff --git a/Horse Isle Server/Horse Isle Server/Game/Meta.cs b/Horse Isle Server/Horse Isle Server/Game/Meta.cs
index 3d8427b..bdfca82 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Meta.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Meta.cs
@@ -1189,6 +1189,29 @@ namespace HISP.Game
return message;
}
+
+ public static string BuildTackMenu(HorseInstance horse, User user)
+ {
+ string message = Messages.FormatTackedAsFollowedMessage(horse.Name);
+ if(horse.Equipment.Saddle != null)
+ message += Messages.FormatUnEquipSaddle(horse.Equipment.Saddle.IconId, horse.Equipment.Saddle.Name);
+ if (horse.Equipment.SaddlePad != null)
+ message += Messages.FormatUnEquipSaddlePad(horse.Equipment.SaddlePad.IconId, horse.Equipment.SaddlePad.Name);
+ if (horse.Equipment.Bridle != null)
+ message += Messages.FormatUnEquipBridle(horse.Equipment.Bridle.IconId, horse.Equipment.Bridle.Name);
+ message += Messages.HorseTackInInventory;
+ foreach(InventoryItem item in user.Inventory.GetItemList())
+ {
+ Item.ItemInformation itemInfo = item.ItemInstances[0].GetItemInfo();
+ if (itemInfo.Type == "TACK")
+ {
+ message += Messages.FormatHorseEquip(itemInfo.IconId, item.ItemInstances.Count, itemInfo.Name, itemInfo.Id);
+ }
+ }
+
+ message += Messages.HorseBackTo;
+ return message;
+ }
public static string BuildChatpoint(User user, Npc.NpcEntry npc, Npc.NpcChat chatpoint)
{
bool hideReplys = false;
diff --git a/Horse Isle Server/Horse Isle Server/Game/Services/Shop.cs b/Horse Isle Server/Horse Isle Server/Game/Services/Shop.cs
index 08733d0..8ece16c 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Services/Shop.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Services/Shop.cs
@@ -32,11 +32,11 @@ namespace HISP.Game.Services
public int CalculateBuyCost(Item.ItemInformation item)
{
- return (int)Math.Floor((float)item.SellPrice * (100.0 / (float)BuyPricePercentage));
+ return (int)Math.Round((float)item.SellPrice * (100.0 / (float)BuyPricePercentage));
}
public int CalculateSellCost(Item.ItemInformation item)
{
- return (int)Math.Floor((float)item.SellPrice * (100.0 / (float)SellPricePercentage));
+ return (int)Math.Round((float)item.SellPrice * (100.0 / (float)SellPricePercentage));
}
public bool CanSell(Item.ItemInformation item)
diff --git a/Horse Isle Server/Horse Isle Server/Player/User.cs b/Horse Isle Server/Horse Isle Server/Player/User.cs
index 3ac5d99..7f55d38 100644
--- a/Horse Isle Server/Horse Isle Server/Player/User.cs
+++ b/Horse Isle Server/Horse Isle Server/Player/User.cs
@@ -5,6 +5,7 @@ using HISP.Server;
using HISP.Player.Equips;
using HISP.Game.Services;
using HISP.Game.Inventory;
+using HISP.Game.Horse;
namespace HISP.Player
{
@@ -43,6 +44,7 @@ namespace HISP.Player
public Shop LastShoppedAt;
public Inn LastVisitedInn;
public HorseInventory HorseInventory;
+ public HorseInstance LastViewedHorse;
public PlayerQuests Quests;
public Highscore Highscores;
public Award Awards;
diff --git a/Horse Isle Server/Horse Isle Server/Server/Database.cs b/Horse Isle Server/Horse Isle Server/Server/Database.cs
index d9ea1d3..218d682 100644
--- a/Horse Isle Server/Horse Isle Server/Server/Database.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/Database.cs
@@ -884,6 +884,52 @@ namespace HISP.Server
}
}
+ public static void SetSaddle(int horseRandomId, int saddleItemId)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET saddle=@saddle WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@saddle", saddleItemId);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+
+ public static void SetSaddlePad(int horseRandomId, int saddlePadItemId)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET saddlepad=@saddlepad WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@saddlepad", saddlePadItemId);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+
+ public static void SetBridle(int horseRandomId, int bridleItemId)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET bridle=@bridle WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@bridle", bridleItemId);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+
+
public static void SetWorldWeather(string Weather)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
diff --git a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
index d1d74c9..7856a5e 100644
--- a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
@@ -647,6 +647,18 @@ namespace HISP.Server
Messages.HorseReleaseButton = gameData.messages.meta.horse.horse_inventory.release_horse;
Messages.HorseOthers = gameData.messages.meta.horse.horse_inventory.other_horses;
+ Messages.HorseEquipTackMessageFormat = gameData.messages.meta.horse.equip_tack_message;
+ Messages.HorseUnEquipTackMessageFormat = gameData.messages.meta.horse.unequip_tack_message;
+
+ // Tack menu (horses)
+ Messages.HorseTackedAsFollowsFormat = gameData.messages.meta.horse.tack_menu.tacked_as_follows;
+ Messages.HorseUnEquipSaddleFormat = gameData.messages.meta.horse.tack_menu.dequip_saddle;
+ Messages.HorseUnEquipSaddlePadFormat = gameData.messages.meta.horse.tack_menu.dequip_saddle_pad;
+ 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;
+
// Libary
Messages.LibaryMainMenu = gameData.messages.meta.libary.main_menu;
diff --git a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
index a704d15..3bebb34 100644
--- a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
@@ -104,7 +104,8 @@ namespace HISP.Server
byte[] metaTags = PacketBuilder.CreateMetaPacket(Meta.BuildHorseInventory(sender.LoggedinUser));
sender.SendPacket(metaTags);
break;
- case PacketBuilder.HORSE_MOUNT:
+ case PacketBuilder.HORSE_TACK:
+
int randomId = 0;
string packetStr = Encoding.UTF8.GetString(packet);
string randomIdStr = packetStr.Substring(2, packetStr.Length - 4);
@@ -112,6 +113,113 @@ 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.BuildTackMenu(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_TACK_EQUIP:
+
+ int itemId = 0;
+ packetStr = Encoding.UTF8.GetString(packet);
+ string itemIdStr = packetStr.Substring(2, packetStr.Length - 4);
+ try
+ {
+ itemId = int.Parse(itemIdStr);
+ }
+ catch (Exception)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid randomid to horse interaction packet ");
+ break;
+ }
+ if(Item.ItemIdExist(itemId))
+ {
+ if(sender.LoggedinUser.LastViewedHorse != null)
+ {
+ if(sender.LoggedinUser.Inventory.HasItemId(itemId))
+ {
+ Item.ItemInformation itemInfo = Item.GetItemById(itemId);
+ if (itemInfo.Type == "TACK")
+ {
+ switch (itemInfo.MiscFlags[0])
+ {
+ case 1: // Saddle
+ if(sender.LoggedinUser.LastViewedHorse.Equipment.Saddle != null)
+ sender.LoggedinUser.Inventory.AddIgnoringFull(new ItemInstance(sender.LoggedinUser.LastViewedHorse.Equipment.Saddle.Id));
+ Database.SetSaddle(sender.LoggedinUser.LastViewedHorse.RandomId, itemInfo.Id);
+ sender.LoggedinUser.LastViewedHorse.Equipment.Saddle = itemInfo;
+ break;
+ case 2: // Saddle Pad
+ if (sender.LoggedinUser.LastViewedHorse.Equipment.SaddlePad != null)
+ sender.LoggedinUser.Inventory.AddIgnoringFull(new ItemInstance(sender.LoggedinUser.LastViewedHorse.Equipment.SaddlePad.Id));
+ Database.SetSaddlePad(sender.LoggedinUser.LastViewedHorse.RandomId, itemInfo.Id);
+ sender.LoggedinUser.LastViewedHorse.Equipment.SaddlePad = itemInfo;
+ break;
+ case 3: // Bridle
+ if (sender.LoggedinUser.LastViewedHorse.Equipment.Bridle != null)
+ sender.LoggedinUser.Inventory.AddIgnoringFull(new ItemInstance(sender.LoggedinUser.LastViewedHorse.Equipment.Bridle.Id));
+ Database.SetBridle(sender.LoggedinUser.LastViewedHorse.RandomId, itemInfo.Id);
+ sender.LoggedinUser.LastViewedHorse.Equipment.Bridle = itemInfo;
+ break;
+ }
+
+ sender.LoggedinUser.MetaPriority = true;
+ byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildTackMenu(sender.LoggedinUser.LastViewedHorse, sender.LoggedinUser));
+ sender.SendPacket(metaPacket);
+
+ sender.LoggedinUser.Inventory.Remove(sender.LoggedinUser.Inventory.GetItemByItemId(itemId).ItemInstances[0]); // Remove item from inventory.
+ byte[] equipMsgPacket = PacketBuilder.CreateChat(Messages.FormatEquipTackMessage(itemInfo.Name, sender.LoggedinUser.LastViewedHorse.Name), PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(equipMsgPacket);
+
+ }
+ else
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to equip a tack item to a hrose but that item was not of type \"TACK\".");
+ }
+ }
+ else
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " tried to equip tack he doesnt have");
+ break;
+ }
+ }
+ else
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to equip tack to a horse when not viewing one.");
+ break;
+ }
+ }
+ else
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " tried to equip tack he doesnt exist");
+ break;
+ }
+
+ break;
+ case PacketBuilder.HORSE_MOUNT:
+ randomId = 0;
+ packetStr = Encoding.UTF8.GetString(packet);
+ randomIdStr = packetStr.Substring(2, packetStr.Length - 4);
+ try
+ {
+ randomId = int.Parse(randomIdStr);
+
}
catch (Exception)
{
@@ -126,11 +234,9 @@ namespace HISP.Server
}
else
{
- Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to mont at a non existant horse.");
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to mount at a non existant horse.");
break;
}
-
- break;
case PacketBuilder.HORSE_LOOK:
randomId = 0;
packetStr = Encoding.UTF8.GetString(packet);
@@ -147,16 +253,8 @@ namespace HISP.Server
}
if(sender.LoggedinUser.HorseInventory.HorseIdExist(randomId))
{
- int TileID = Map.GetTileId(sender.LoggedinUser.X, sender.LoggedinUser.Y, false);
- string type = Map.TerrainTiles[TileID - 1].Type;
HorseInstance horseInst = sender.LoggedinUser.HorseInventory.GetHorseById(randomId);
- byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseInformation(horseInst, sender.LoggedinUser));
- sender.SendPacket(metaPacket);
-
- string loadSwf = HorseInfo.BreedViewerSwf(horseInst, type);
- byte[] swfPacket = PacketBuilder.CreateSwfModulePacket(loadSwf, PacketBuilder.PACKET_SWF_MODULE_FORCE);
- sender.SendPacket(swfPacket);
-
+ UpdateHorseMenu(sender, horseInst);
}
else
{
@@ -476,6 +574,10 @@ namespace HISP.Server
byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildQuestLog(sender.LoggedinUser));
sender.SendPacket(metaPacket);
break;
+ case "5":
+ if (sender.LoggedinUser.LastViewedHorse != null)
+ UpdateHorseMenu(sender, sender.LoggedinUser.LastViewedHorse);
+ break;
case "21": // Private Notes
sender.LoggedinUser.MetaPriority = true;
metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildPrivateNotes(sender.LoggedinUser));
@@ -574,7 +676,7 @@ namespace HISP.Server
break;
}
- Logger.ErrorPrint("Dynamic button #" + buttonIdStr + " unknown...");
+ Logger.ErrorPrint("Dynamic button #" + buttonIdStr + " unknown... Packet Dump: "+BitConverter.ToString(packet).Replace("-", " "));
break;
}
}
@@ -2810,6 +2912,20 @@ namespace HISP.Server
UpdateUserInfo(client.LoggedinUser);
}
+
+ public static void UpdateHorseMenu(GameClient forClient, HorseInstance horseInst)
+ {
+ int TileID = Map.GetTileId(forClient.LoggedinUser.X, forClient.LoggedinUser.Y, false);
+ string type = Map.TerrainTiles[TileID - 1].Type;
+ forClient.LoggedinUser.LastViewedHorse = horseInst;
+ forClient.LoggedinUser.MetaPriority = true;
+ byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseInformation(horseInst, forClient.LoggedinUser));
+ forClient.SendPacket(metaPacket);
+
+ string loadSwf = HorseInfo.BreedViewerSwf(horseInst, type);
+ byte[] swfPacket = PacketBuilder.CreateSwfModulePacket(loadSwf, PacketBuilder.PACKET_SWF_MODULE_FORCE);
+ forClient.SendPacket(swfPacket);
+ }
public static void UpdateInventory(GameClient forClient)
{
if (!forClient.LoggedIn)
diff --git a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
index 28e47bd..9b437d4 100644
--- a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
@@ -48,6 +48,9 @@ namespace HISP.Server
public const byte HORSE_LIST = 0x0A;
public const byte HORSE_LOOK = 0x14;
public const byte HORSE_TRY_CAPTURE = 0x1C;
+ public const byte HORSE_TACK = 0x16;
+ public const byte HORSE_TACK_EQUIP = 0x3C;
+ public const byte HORSE_TACK_UNEQUIP = 0x3D;
public const byte HORSE_MOUNT = 0x46;
public const byte HORSE_ESCAPE = 0x1E;
public const byte HORSE_CAUGHT = 0x1D;