diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index d9f9aae..435cf88 100644
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -8,9 +8,19 @@
"profile_save":"Your profile changes were saved.",
"buddy_request":"Attempting to Add Buddy. The other player must click ADD BUDDY as well. (Many players reserve this for just a couple players so don't feel insulted if they do not).",
"drawing_notice":"Drawing not sent to other players when you are not a subscriber.",
- "grab_message":"You grabbed an object off the ground.",
- "grab_all_message":"You grabbed all objects off the ground.",
- "dropped_item_message":"You dropped an item on the ground.",
+ "dropped_items":{
+ "grab_message":"You grabbed an object off the ground.",
+ "grab_all_message":"You grabbed all objects off the ground.",
+ "dropped_item_message":"You dropped an item on the ground.",
+ "grab_but_inv_full":"Your inventory is full! Cannot grab items."
+ },
+ "shop":{
+ "cant_afford_1":"You cannot afford that item!",
+ "cant_afford_5":"You cannot afford 5 of that item!",
+ "cant_afford_25":"You cannot afford 25 of that item!",
+ "brought_1_but_inv_full":"Your inventory is full! Cannot buy that item.",
+ "brought_1":"You bought a %ITEM% for $%PRICE%."
+ },
"tools":{
"binoculars":"You search high and low all around, but find nothing interesting.",
"magnify":"You look all over at all the tiny details, but alas, nothing interesting.",
@@ -48,7 +58,6 @@
"area_format":" in %AREA%",
"location_format":" You are%META% ",
"tile_format":"%TILENAME%",
-
"transport_format":"^LTransport via %METHOD% to %PLACE%^R1^I%ICON%^T4Trip Costs $%COST% one way. ^B1M%XY%^BY%ID%",
"exit_this_place":"^X",
"end_of_meta":"^Z",
@@ -72,6 +81,9 @@
"npc_talk_button":"^BA%ID%"
},
"inventory":{
+ "full_inventory_grab":"Your inventory is full! Cannot grab items.",
+ "full_inventory_buy":"Your inventory is full! Cannot grab items.",
+
"header_format":"^ATYour Inventory^HYou are carrying the following %ITEMCOUNT% different items: (%MAXITEMS% max)",
"item_entry":"^I%ICONID%^T4(%COUNT%) %TITLE%",
"shop_entry":"^I%ICONID%^T4(%COUNT%) %TITLE% $%PRICE%",
@@ -87,6 +99,7 @@
"buy_25_button":"^B4B2%ITEMID%",
"sell_button":"^B4S%RANDOMID%",
"sell_all_button":"^B4A%ITEMID%",
+
},
"dropped_items":{
"nothing_message":"^LYou see nothing on the ground of interest.^R1",
diff --git a/Horse Isle Server/Horse Isle Server/Game/Messages.cs b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
index 14d6fac..043c7be 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Messages.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Messages.cs
@@ -67,6 +67,7 @@ namespace HISP.Game
public static string GrabAllItemsButton;
public static string GrabAllItemsMessage;
public static string GrabbedItemMessage;
+ public static string GrabbedItemButInventoryFull;
public static string GrabbedAllObjectsMessage;
public static string DroppedAnItemMessage;
public static string ItemInformationFormat;
@@ -97,6 +98,13 @@ namespace HISP.Game
public static string ThingsIAmSelling;
public static string ThingsYouSellMe;
public static string InfinitySign;
+ public static string CantAfford1;
+ public static string CantAfford5;
+ public static string CantAfford25;
+ public static string Brought1Format;
+ public static string Brought1ButInventoryFull;
+ public static string Brought5;
+ public static string Brought25;
// Npc
public static string NpcStartChatFormat;
@@ -139,7 +147,10 @@ namespace HISP.Game
public static string BallonCutscene;
-
+ public static string FormatBuyMessage(string itemName, int price)
+ {
+ return Brought1Format.Replace("%ITEM%", itemName).Replace("%PRICE%", price.ToString());
+ }
public static string FormatShopEntry(int iconid, string count, string name, int price)
{
return ShopEntryFormat.Replace("%ICONID%", iconid.ToString()).Replace("%COUNT%", count).Replace("%TITLE%", name).Replace("%PRICE%", price.ToString());
diff --git a/Horse Isle Server/Horse Isle Server/Game/Quest.cs b/Horse Isle Server/Horse Isle Server/Game/Quest.cs
index 55d435f..7f2001e 100644
--- a/Horse Isle Server/Horse Isle Server/Game/Quest.cs
+++ b/Horse Isle Server/Horse Isle Server/Game/Quest.cs
@@ -135,7 +135,7 @@ namespace HISP.Game
for (int i = 0; i < itemInfo.Quantity; i++)
{
ItemInstance itm = new ItemInstance(itemInfo.ItemId);
- user.Inventory.Add(itm);
+ user.Inventory.AddIgnoringFull(itm);
}
}
if (quest.WarpX != 0 && quest.WarpY != 0)
diff --git a/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj b/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
index cc8fe85..9313cdd 100644
--- a/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
+++ b/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
@@ -72,6 +72,7 @@
+
diff --git a/Horse Isle Server/Horse Isle Server/Player/PlayerInventory.cs b/Horse Isle Server/Horse Isle Server/Player/PlayerInventory.cs
index 51ea7fd..24f47ad 100644
--- a/Horse Isle Server/Horse Isle Server/Player/PlayerInventory.cs
+++ b/Horse Isle Server/Horse Isle Server/Player/PlayerInventory.cs
@@ -5,8 +5,11 @@ using HISP.Server;
namespace HISP.Player
{
+
class PlayerInventory : IInventory
{
+
+
public User BaseUser;
private List inventoryItems;
public PlayerInventory(User forUser)
@@ -143,8 +146,27 @@ namespace HISP.Player
throw new KeyNotFoundException("random id: " + randomId + " not found in inventory");
}
+ public void AddIgnoringFull(ItemInstance item)
+ {
+ addItem(item, true);
+ }
public void Add(ItemInstance item)
{
+ // Check if has max allready
+ if(HasItemId(item.ItemId))
+ {
+ InventoryItem items = GetItemByItemId(item.ItemId);
+ if (items.ItemInstances.Count >= ConfigReader.MAX_STACK)
+ {
+ throw new InventoryMaxStackException();
+ }
+ else if (Count >= Messages.DefaultInventoryMax)
+ {
+ throw new InventoryFullException();
+ }
+ }
+
+
addItem(item, true);
}
}
diff --git a/Horse Isle Server/Horse Isle Server/Server/ConfigReader.cs b/Horse Isle Server/Horse Isle Server/Server/ConfigReader.cs
index f7fef64..b0e79ea 100644
--- a/Horse Isle Server/Horse Isle Server/Server/ConfigReader.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/ConfigReader.cs
@@ -24,6 +24,8 @@ namespace HISP.Server
public static bool BadWords;
public static bool DoCorrections;
+ public const int MAX_STACK = 40;
+
private static string ConfigurationFileName = "server.properties";
public static void OpenConfig()
{
diff --git a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
index 87c135b..7f138c9 100644
--- a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs
@@ -598,7 +598,18 @@ namespace HISP.Server
try
{
DroppedItems.DroppedItem item = DroppedItems.GetDroppedItemById(randomId);
- sender.LoggedinUser.Inventory.Add(item.instance);
+ try
+ {
+ sender.LoggedinUser.Inventory.Add(item.instance);
+ }
+ catch (InventoryException)
+ {
+ byte[] inventoryFullMessage = PacketBuilder.CreateChat(Messages.GrabbedItemButInventoryFull, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(inventoryFullMessage);
+ break;
+ }
+
+
DroppedItems.RemoveDroppedItem(item);
UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y);
@@ -679,6 +690,67 @@ namespace HISP.Server
sender.SendPacket(ChatPacket);
}
break;
+ case PacketBuilder.ITEM_BUY: // Handles buying an item.
+ packetStr = Encoding.UTF8.GetString(packet);
+ string itemIdStr = packetStr.Substring(2, packet.Length - 2);
+ int itemId = 0;
+ // Prevent crashing on non-int string.
+ try
+ {
+ itemId = Int32.Parse(itemIdStr);
+ }
+ catch (InvalidOperationException)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid object buy packet.");
+ return;
+ }
+
+ Item.ItemInformation itemInfo = Item.GetItemById(itemId);
+ Shop shop = sender.LoggedinUser.LastShoppedAt;
+ if(shop != null)
+ {
+ int buyCost = shop.CalculateBuyCost(itemInfo);
+ if (sender.LoggedinUser.Money < buyCost)
+ {
+ byte[] cantAffordMessage = PacketBuilder.CreateChat(Messages.CantAfford1, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(cantAffordMessage);
+ break;
+ }
+ sender.LoggedinUser.Money -= buyCost;
+ if (shop.Inventory.HasItemId(itemId))
+ {
+ ItemInstance itemInstance = shop.Inventory.GetItemByItemId(itemId).ItemInstances[0];
+
+ try
+ {
+ sender.LoggedinUser.Inventory.Add(itemInstance);
+ }
+ catch(InventoryException)
+ {
+ byte[] inventoryFullMessage = PacketBuilder.CreateChat(Messages.Brought1ButInventoryFull, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(inventoryFullMessage);
+ break;
+ }
+
+ shop.Inventory.Remove(itemInstance);
+ UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y);
+ // Send chat message to client.
+ byte[] broughtItemMessage = PacketBuilder.CreateChat(Messages.FormatBuyMessage(itemInfo.Name,buyCost), PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(broughtItemMessage);
+
+ }
+ else
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to buy a item that was not for sale.");
+ }
+ }
+ else
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to buy an item while not in a store.");
+ }
+
+ break;
+
case PacketBuilder.INFORMATION:
packetStr = Encoding.UTF8.GetString(packet);
randomIdStr = packetStr.Substring(3, packet.Length - 3);
@@ -696,7 +768,7 @@ namespace HISP.Server
if (packet[2] == PacketBuilder.ITEM_INFORMATON)
{
- int itemId = -1;
+ itemId = -1;
if (sender.LoggedinUser.Inventory.HasItem(randomId))
itemId = sender.LoggedinUser.Inventory.GetItemByRandomid(randomId).ItemId;
else if (DroppedItems.IsDroppedItemExist(randomId))
diff --git a/Horse Isle Server/Horse Isle Server/Server/Gamedata.cs b/Horse Isle Server/Horse Isle Server/Server/Gamedata.cs
index 06655f5..01ec2b6 100644
--- a/Horse Isle Server/Horse Isle Server/Server/Gamedata.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/Gamedata.cs
@@ -418,8 +418,12 @@ namespace HISP.Server
Messages.GrabItemFormat = gameData.messages.meta.dropped_items.item_format;
Messages.ItemInformationFormat = gameData.messages.meta.dropped_items.item_information_format;
Messages.GrabAllItemsButton = gameData.messages.meta.dropped_items.grab_all;
- Messages.DroppedAnItemMessage = gameData.messages.dropped_item_message;
- Messages.GrabbedAllObjectsMessage = gameData.messages.grab_all_message;
+ Messages.DroppedAnItemMessage = gameData.messages.dropped_items.dropped_item_message;
+ Messages.GrabbedAllObjectsMessage = gameData.messages.dropped_items.grab_all_message;
+ Messages.GrabbedItemMessage = gameData.messages.dropped_items.grab_message;
+ Messages.GrabAllItemsMessage = gameData.messages.dropped_items.grab_all_message;
+
+ Messages.GrabbedItemButInventoryFull = gameData.messages.dropped_items.grab_but_inv_full;
// Tools
Messages.BinocularsNothing = gameData.messages.tools.binoculars;
@@ -432,6 +436,13 @@ namespace HISP.Server
Messages.ThingsYouSellMe = gameData.messages.meta.shop.sell_me;
Messages.InfinitySign = gameData.messages.meta.shop.infinity;
+ Messages.CantAfford1 = gameData.messages.shop.cant_afford_1;
+ Messages.CantAfford5 = gameData.messages.shop.cant_afford_5;
+ Messages.CantAfford25 = gameData.messages.shop.cant_afford_25;
+ Messages.Brought1Format = gameData.messages.shop.brought_1;
+
+ Messages.Brought1ButInventoryFull = gameData.messages.shop.brought_1_but_inv_full;
+
// Meta Format
Messages.LocationFormat = gameData.messages.meta.location_format;
@@ -446,8 +457,6 @@ namespace HISP.Server
Messages.LongFullLine = gameData.messages.meta.long_full_line;
Messages.MetaTerminator = gameData.messages.meta.end_of_meta;
- Messages.GrabbedItemMessage = gameData.messages.grab_message;
- Messages.GrabAllItemsMessage = gameData.messages.grab_all_message;
Messages.NearbyPlayers = gameData.messages.meta.nearby.players_nearby;
Messages.North = gameData.messages.meta.nearby.north;
diff --git a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
index 6e1440a..8442402 100644
--- a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
+++ b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs
@@ -67,6 +67,7 @@ namespace HISP.Server
public const byte ITEM_DROP = 0x1E;
public const byte ITEM_PICKUP = 0x14;
+ public const byte ITEM_BUY = 0x33;
public const byte ITEM_BINOCULARS = 0x5C;
public const byte ITEM_MAGNIFYING = 0x5D;
public const byte ITEM_RAKE = 0x5B;