diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index 0ec0cdf..c4290ad 100644
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -157,6 +157,15 @@
"pet_horse":"Your horse whinnies lightly. (+%MOOD% mood / -%TIREDNESS% tiredness)",
"pet_horse_too_happy":"Your horse is as happy as it can be now. Your horse whinnies lightly. (+%MOOD% mood / -%TIREDNESS% tiredness)",
"description_edit":"^PLHorse's Name:|%HORSENAME%^D11|GENERATE RANDOM HORSE NAME^R1^LDescription: (reset if you generate name)^R1^PB120|%DESCRIPTION%^PS5|SAVE CHANGES",
+ "tack_fail_autosell":"You cannot put tack on a horse with Auto-Sell set.",
+ "companion_menu":{
+ "menu_header":"%HORSENAME%'s current companion:
",
+ "companions_avalible":"^LYou have the following companions available:^R1",
+ "companion_entry":"^I%ICONID%^T5[ %COUNT% ] %NAME%^B3K%ID%^R1",
+ "selected_companion":"^I%ICONID%^T5%NAME%^B3M4^R1",
+ "companion_equip_message":"You gave %HORSENAME% a %ITEM% for a companion.",
+ "companion_remove_message":"You removed the companion from %HORSENAME%."
+ },
"auto_sell":{
"auto_sell_meta":"Auto-Selling a horse:
By setting this value, any other player can buy this horse from you at any time. If you have a Ranch, they can even buy the horse when you are offline! (Put the cost to 0 to stop it from being for auto-sale.)^PMAuto-Sell horse for:|%AUTOSELL%^PS10|SET COST",
"auto_sell_confirmed":"Setting up Auto-Sell for horse at $%MONEY%",
@@ -189,7 +198,9 @@
"no_auto_sell":"NO Auto-Sell",
"auto_sell_format":"Auto-Selling: $%MONEY%",
- "auto_sell":"^R1^T2[%AUTOSELL%]^D25|SET AUTO-SELL PRICE",
+ "change_auto_sell":"^D25|CHANGE AUTO-SELL",
+ "set_auto_sell":"^D25|SET AUTO-SELL PRICE",
+ "auto_sell":"^R1^T2[%AUTOSELL%]",
"cannot_auto_sell_tacked":"^R1^T8Cannot set Auto-Sell on a Horse with Tack",
"marked_as":"^R1^LHorse currently marked [%CATEGORY%]. Mark:^R1^D52c1|KEEPER^D52c2|TRAINING^D52c3|TRADING^D52c4|RETIRED^R1",
diff --git a/Horse Isle Server/Horse Isle Server/Game/Messages.cs b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
index 5435220..4d9ad4f 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Messages.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
@@ -227,6 +227,19 @@ namespace HISP.Game
public static string HorseAutoSellConfirmedFormat;
public static string HorseAutoSellRemoved;
+ public static string HorseChangeAutoSell;
+ public static string HorseSetAutoSell;
+
+ public static string HorseTackFailAutoSell;
+
+ // Horse compainion menu
+ public static string HorseCompanionMenuHeaderFormat;
+ public static string HorseCompnaionMenuCurrentCompanionFormat;
+ public static string HorseCompanionEntryFormat;
+ public static string HorseCompanionEquipMessageFormat;
+ public static string HorseCompanionRemoveMessageFormat;
+ public static string HorseCompanionMenuCurrentlyAvalibleCompanions;
+
// Horse Feed Menu
public static string HorseCurrentStatusFormat;
public static string HorseHoldingHorseFeed;
@@ -434,6 +447,26 @@ namespace HISP.Game
// Click
public static string NothingInterestingHere;
+ public static string FormatHorseCompanionRemoveMessage(string horseName)
+ {
+ return HorseCompanionRemoveMessageFormat.Replace("%HORSENAME%", horseName);
+ }
+ public static string FormatHorseCompanionEquipMessage(string horseName, string itemName)
+ {
+ return HorseCompanionEquipMessageFormat.Replace("%HORSENAME%", horseName).Replace("%ITEM%", itemName);
+ }
+ public static string FormatHorseCompanionSelected(int icon, string name)
+ {
+ return HorseCompnaionMenuCurrentCompanionFormat.Replace("%ICONID%", icon.ToString()).Replace("%NAME%", name);
+ }
+ public static string FormatHorseCompanionMenuHeader(string horseName)
+ {
+ return HorseCompanionMenuHeaderFormat.Replace("%HORSENAME%", horseName);
+ }
+ public static string FormatHorseCompanionOption(int icon, int count, string name, int id)
+ {
+ return HorseCompanionEntryFormat.Replace("%ICONID%", icon.ToString()).Replace("%COUNT%", count.ToString("N0")).Replace("%NAME%", name).Replace("%ID%", id.ToString());
+ }
public static string FormatAutoSellConfirmedMessage(int money)
{
@@ -917,23 +950,23 @@ namespace HISP.Game
}
public static string FormatSellMessage(string itemName, int price)
{
- return Sold1Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString());
+ return Sold1Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString("N0"));
}
public static string FormatSellAllMessage(string itemName, int price, int sellAmount)
{
- return SoldAllFormat.Replace("%AMOUNT%",sellAmount.ToString()).Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString());
+ return SoldAllFormat.Replace("%AMOUNT%",sellAmount.ToString()).Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString("N0"));
}
public static string FormatBuy25Message(string itemName, int price)
{
- return Brought25Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString());
+ return Brought25Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString("N0"));
}
public static string FormatBuy5Message(string itemName, int price)
{
- return Brought5Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString());
+ return Brought5Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString("N0"));
}
public static string FormatBuyMessage(string itemName, int price)
{
- return Brought1Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString());
+ return Brought1Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString("N0"));
}
public static string FormatShopEntry(int iconid, string count, string name, int price)
{
diff --git a/Horse Isle Server/Horse Isle Server/Game/Meta.cs b/Horse Isle Server/Horse Isle Server/Game/Meta.cs
index 4d0e3f5..5170aa0 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Meta.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Meta.cs
@@ -998,6 +998,25 @@ namespace HISP.Game
message += Messages.MetaTerminator;
return message;
}
+
+ public static string BuildHorseCompanionEquipMenu(HorseInstance horse, User user)
+ {
+ string message = "";
+ message += Messages.FormatHorseCompanionMenuHeader(horse.Name);
+ if (horse.Equipment.Companion != null)
+ message += Messages.FormatHorseCompanionSelected(horse.Equipment.Companion.IconId, horse.Equipment.Companion.Name);
+ message += Messages.HorseCompanionMenuCurrentlyAvalibleCompanions;
+ foreach (InventoryItem item in user.Inventory.GetItemList())
+ {
+ Item.ItemInformation itemInfo = item.ItemInstances[0].GetItemInfo();
+ if(itemInfo.Type == "COMPANION")
+ {
+ message += Messages.FormatHorseCompanionOption(itemInfo.IconId, item.ItemInstances.Count, itemInfo.Name, item.ItemId);
+ }
+ }
+ message += Messages.BackToHorse;
+ return message;
+ }
public static string BuildHorseDescriptionEditMeta(HorseInstance horse)
{
string message = Messages.FormatDescriptionEditMeta(horse.Name, horse.Description);
@@ -1027,12 +1046,16 @@ namespace HISP.Game
message += Messages.FormatPetButton(horse.RandomId);
message += Messages.FormatProfileButton(horse.RandomId);
- if (horse.Equipment.Saddle == null && horse.Equipment.SaddlePad == null && horse.Equipment.Bridle == null)
+ 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
{
diff --git a/Horse Isle Server/Horse Isle Server/Server/Database.cs b/Horse Isle Server/Horse Isle Server/Server/Database.cs
index f0376da..fa2ce07 100644
--- a/Horse Isle Server/Horse Isle Server/Server/Database.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/Database.cs
@@ -1247,6 +1247,20 @@ namespace HISP.Server
sqlCommand.Dispose();
}
}
+ public static void SetCompanion(int horseRandomId, int companionItemId)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET companion=@companion WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@companion", companionItemId);
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
public static void ClearSaddle(int horseRandomId)
{
@@ -1290,6 +1304,19 @@ namespace HISP.Server
}
}
+ public static void ClearCompanion(int horseRandomId)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "UPDATE Horses SET companion=NULL WHERE randomId=@randomId";
+ sqlCommand.Parameters.AddWithValue("@randomId", horseRandomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
public static void SetWorldWeather(string Weather)
{
diff --git a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
index b7e9e29..eefaa76 100644
--- a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs
@@ -661,10 +661,21 @@ namespace HISP.Server
Messages.HorseSetNewCategoryMessageFormat = gameData.messages.meta.horse.horse_set_new_category;
Messages.HorseAutoSellMenuFormat = gameData.messages.meta.horse.auto_sell.auto_sell_meta;
- Messages.HorseIsAutoSell = gameData.messages.meta.auto_sell.horse.is_auto_sell;
- Messages.HorseAutoSellConfirmedFormat = gameData.messages.meta.auto_sell.horse.auto_sell_confirmed;
- Messages.HorseAutoSellRemoved = gameData.messages.meta.auto_sell.horse.auto_sell_remove;
+ Messages.HorseIsAutoSell = gameData.messages.meta.horse.auto_sell.is_auto_sell;
+ Messages.HorseAutoSellConfirmedFormat = gameData.messages.meta.horse.auto_sell.auto_sell_confirmed;
+ Messages.HorseAutoSellRemoved = gameData.messages.meta.horse.auto_sell.auto_sell_remove;
+ Messages.HorseSetAutoSell = gameData.messages.meta.horse.horse_inventory.set_auto_sell;
+ Messages.HorseChangeAutoSell = gameData.messages.meta.horse.horse_inventory.change_auto_sell;
+ Messages.HorseTackFailAutoSell = gameData.messages.meta.horse.tack_fail_autosell;
+
+ // Horse companion menu
+ Messages.HorseCompanionMenuHeaderFormat = gameData.messages.meta.horse.companion_menu.menu_header;
+ Messages.HorseCompnaionMenuCurrentCompanionFormat = gameData.messages.meta.horse.companion_menu.selected_companion;
+ Messages.HorseCompanionEntryFormat = gameData.messages.meta.horse.companion_menu.companion_entry;
+ Messages.HorseCompanionEquipMessageFormat = gameData.messages.meta.horse.companion_menu.companion_equip_message;
+ Messages.HorseCompanionRemoveMessageFormat = gameData.messages.meta.horse.companion_menu.companion_remove_message;
+ Messages.HorseCompanionMenuCurrentlyAvalibleCompanions = gameData.messages.meta.horse.companion_menu.companions_avalible;
// Horse Feed Menu
Messages.HorseCurrentStatusFormat = gameData.messages.meta.horse.feed_horse.current_status;
diff --git a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
index 1d13e73..004b320 100644
--- a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
@@ -351,6 +351,13 @@ namespace HISP.Server
{
if(sender.LoggedinUser.LastViewedHorse != null)
{
+ if(sender.LoggedinUser.LastViewedHorse.AutoSell > 0)
+ {
+ byte[] failMessagePacket = PacketBuilder.CreateChat(Messages.HorseTackFailAutoSell, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(failMessagePacket);
+ break;
+ }
+
if(sender.LoggedinUser.Inventory.HasItemId(itemId))
{
Item.ItemInformation itemInfo = Item.GetItemById(itemId);
@@ -389,6 +396,22 @@ namespace HISP.Server
sender.SendPacket(equipMsgPacket);
}
+ else if(itemInfo.Type == "COMPANION")
+ {
+ if (sender.LoggedinUser.LastViewedHorse.Equipment.Companion != null)
+ sender.LoggedinUser.Inventory.AddIgnoringFull(new ItemInstance(sender.LoggedinUser.LastViewedHorse.Equipment.Companion.Id));
+ Database.SetCompanion(sender.LoggedinUser.LastViewedHorse.RandomId, itemInfo.Id);
+ sender.LoggedinUser.LastViewedHorse.Equipment.Companion = itemInfo;
+
+ sender.LoggedinUser.Inventory.Remove(sender.LoggedinUser.Inventory.GetItemByItemId(itemId).ItemInstances[0]); // Remove item from inventory.
+
+ sender.LoggedinUser.MetaPriority = true;
+ byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseCompanionEquipMenu(sender.LoggedinUser.LastViewedHorse, sender.LoggedinUser));
+ sender.SendPacket(metaPacket);
+
+ byte[] equipMsgPacket = PacketBuilder.CreateChat(Messages.FormatHorseCompanionEquipMessage(sender.LoggedinUser.LastViewedHorse.Name, itemInfo.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\".");
@@ -437,6 +460,12 @@ namespace HISP.Server
Database.ClearBridle(sender.LoggedinUser.LastViewedHorse.RandomId);
sender.LoggedinUser.LastViewedHorse.Equipment.Bridle = null;
break;
+ case 0x34: // Companion
+ if (sender.LoggedinUser.LastViewedHorse.Equipment.Companion != null)
+ sender.LoggedinUser.Inventory.AddIgnoringFull(new ItemInstance(sender.LoggedinUser.LastViewedHorse.Equipment.Companion.Id));
+ Database.ClearCompanion(sender.LoggedinUser.LastViewedHorse.RandomId);
+ sender.LoggedinUser.LastViewedHorse.Equipment.Companion = null;
+ goto companionRemove;
default:
Logger.ErrorPrint("Unknown equip slot: " + equipSlot.ToString("X"));
break;
@@ -447,6 +476,16 @@ namespace HISP.Server
sender.LoggedinUser.MetaPriority = true;
byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildTackMenu(sender.LoggedinUser.LastViewedHorse, sender.LoggedinUser));
sender.SendPacket(metaPacket);
+ break;
+ companionRemove:;
+ itemUnequipedMessage = PacketBuilder.CreateChat(Messages.FormatHorseCompanionRemoveMessage(sender.LoggedinUser.LastViewedHorse.Name), PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(itemUnequipedMessage);
+
+ sender.LoggedinUser.MetaPriority = true;
+ metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseCompanionEquipMenu(sender.LoggedinUser.LastViewedHorse, sender.LoggedinUser));
+ sender.SendPacket(metaPacket);
+ break;
+
}
else
{
@@ -988,10 +1027,19 @@ namespace HISP.Server
metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseList());
sender.SendPacket(metaPacket);
break;
- case "5":
+ case "5": // Back to horse
if (sender.LoggedinUser.LastViewedHorse != null)
UpdateHorseMenu(sender, sender.LoggedinUser.LastViewedHorse);
break;
+ case "6": // Equip companion
+ if (sender.LoggedinUser.LastViewedHorse != null)
+ {
+ sender.LoggedinUser.MetaPriority = true;
+ HorseInstance horseInstance = sender.LoggedinUser.LastViewedHorse;
+ metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseCompanionEquipMenu(horseInstance,sender.LoggedinUser));
+ sender.SendPacket(metaPacket);
+ }
+ break;
case "11": // Randomize horse name
if (sender.LoggedinUser.LastViewedHorse != null)
{