Add support for the "Drop" button.

This commit is contained in:
SilicaAndPina 2020-10-25 23:42:22 +13:00
parent db8b3b6c54
commit c3497a6582
12 changed files with 269 additions and 32 deletions

View file

@ -9,7 +9,7 @@
"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.",
"toss_tomato":"You toss the Rotten Tomato high into the air! SMACK! It comes back down and hits you on the head, bright red chunks are covering you.",
"dropped_item_message":"You dropped an item on the ground.",
"transport":{
"not_enough_money":"You cannot afford this trip!",
"welcome_to_format":"Welcome to %PLACE%."
@ -53,7 +53,9 @@
"item_drop_button":"^B4D%RANDOMID%",
"item_info_button":"^B4LE%RANDOMID%",
"item_consume_button":"^B4E%RANDOMID%",
"item_throw_button":"^B4D%RANDOMID%"
"item_throw_button":"^B4T%RANDOMID%",
"item_use_button":"^B4UD%RANDOMID%",
"item_read_button":"^B4VL%RANDOMID%"
},
"dropped_items":{
"nothing_message":"^LYou see nothing on the ground of interest.^R1",
@ -273,14 +275,10 @@
"pm_sound":"PM"
}
},
"mod_splatterball_game":{
"hit_message":"SMACK!! %USERNAME% hit you with a Mod Splatterball, slimy goop exploded and dripped on you."
},
"water_balloon_game":{
"money_prize":20000,
"starting_amount":8,
"start_message":"<B>WATER BALLOON FIGHT:</B> You have just been given %AMOUNT% Water Balloons. Whoever gets hit the MOST in 5 minutes (60 game minutes) will win a prize (hits on yourself are not counted).",
"hit_message":"SMACK!! %USERNAME% hit you with a Water Balloon, soaking you.",
"winner_message":"<B>You are a Water Balloon winner!</B> Prize: $%PRIZE%",
"end_message_winner":"<B>WATER BALLOON FIGHT OVER:</B> Here were the winners:<BR>%USERNAME% was hit %AMOUNT% times."
},
@ -520,6 +518,22 @@
},
"item":{
"max_carryable":40,
"special":{
"present":135,
"mail_message":183,
"dorothy_shoes":260,
"pawneer_order":559,
"telescope":182,
"pitchfork":152
},
"throwable":[
{"id":144,"message":"blanketing wet snow on "},
{"id":333,"message":"bright red chunks are covering "},
{"id":334,"message":"soaking "},
{"id":639,"message":"twinkling magic on "},
{"id":640,"message":"lightly bouncing off "},
{"id":713,"message":"slimy goop exploded and dripped on "}
],
"item_list":[
{
"id": 1,

View file

@ -289,7 +289,7 @@ namespace Horse_Isle_Server
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "DELETE FROM Inventory WHERE (PlayerId=@id AND RandomId=@randomId)";
sqlCommand.CommandText = "DELETE FROM Inventory WHERE (PlayerId=@playerId AND RandomId=@randomId)";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Parameters.AddWithValue("@randomId", instance.RandomID);
sqlCommand.Prepare();

View file

@ -108,6 +108,16 @@ namespace Horse_Isle_Server
if(removedCount > 0)
epoch = new_epoch;
}
public static void AddItem(ItemInstance item, int x, int y)
{
DroppedItem droppedItem = new DroppedItem();
droppedItem.X = x;
droppedItem.Y = y;
droppedItem.DespawnTimer = 1500;
droppedItem.instance = item;
droppedItemsList.Add(droppedItem);
}
public static void GenerateItems()
{
int newItems = 0;

View file

@ -192,6 +192,21 @@ namespace Horse_Isle_Server
Item.Items.Add(item);
}
int totalThrowable = gameData.item.throwable.Count;
for(int i = 0; i < totalThrowable; i++)
{
Item.ThrowableItem throwableItem = new Item.ThrowableItem();
throwableItem.Id = gameData.item.throwable[i].id;
throwableItem.Message = gameData.item.throwable[i].message;
Item.ThrowableItems.Add(throwableItem);
}
Item.Present = gameData.item.special.present;
Item.MailMessage = gameData.item.special.mail_message;
Item.DorothyShoes = gameData.item.special.dorothy_shoes;
Item.PawneerOrder = gameData.item.special.pawneer_order;
Item.Telescope = gameData.item.special.telescope;
Item.Pitchfork = gameData.item.special.pitchfork;
// New Users
Messages.NewUserMessage = gameData.new_user.starting_message;
@ -242,6 +257,14 @@ namespace Horse_Isle_Server
Messages.PasswordNotice = gameData.messages.chat.password_included;
Messages.CapsNotice = gameData.messages.chat.caps_notice;
// Hardcoded messages
Messages.NothingMessage = gameData.messages.meta.dropped_items.nothing_message;
Messages.ItemsOnGroundMessage = gameData.messages.meta.dropped_items.items_message;
Messages.GrabItemFormat = gameData.messages.meta.dropped_items.item_format;
Messages.GrabAllItemsButton = gameData.messages.meta.dropped_items.grab_all;
Messages.DroppedAnItemMessage = gameData.messages.dropped_item_message;
// Meta Format
Messages.LocationFormat = gameData.messages.meta.location_format;
@ -256,10 +279,6 @@ namespace Horse_Isle_Server
Messages.LongFullLine = gameData.messages.meta.long_full_line;
Messages.MetaTerminator = gameData.messages.meta.end_of_meta;
Messages.NothingMessage = gameData.messages.meta.dropped_items.nothing_message;
Messages.ItemsOnGroundMessage = gameData.messages.meta.dropped_items.items_message;
Messages.GrabItemFormat = gameData.messages.meta.dropped_items.item_format;
Messages.GrabAllItemsButton = gameData.messages.meta.dropped_items.grab_all;
Messages.GrabbedItemMessage = gameData.messages.grab_message;
Messages.GrabAllItemsMessage = gameData.messages.grab_all_message;
@ -275,7 +294,12 @@ namespace Horse_Isle_Server
Messages.InventoryItemFormat = gameData.messages.meta.inventory.item_entry;
Messages.ItemInformationButton = gameData.messages.meta.inventory.item_info_button;
Messages.ItemDropItemButton = gameData.messages.meta.inventory.item_drop_button;
Messages.ItemDropButton = gameData.messages.meta.inventory.item_drop_button;
Messages.ItemThrowButton = gameData.messages.meta.inventory.item_throw_button;
Messages.ItemConsumeButton = gameData.messages.meta.inventory.item_consume_button;
Messages.ItemUseButton = gameData.messages.meta.inventory.item_use_button;
Messages.ItemReadButton = gameData.messages.meta.inventory.item_read_button;
// Map Data

View file

@ -9,6 +9,7 @@
<RootNamespace>Horse_Isle_Server</RootNamespace>
<AssemblyName>Horse Isle Server</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>8.0</LangVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>

View file

@ -22,7 +22,6 @@ namespace Horse_Isle_Server
void Add(ItemInstance item);
void Remove(ItemInstance item);
int Count
{
get;
@ -31,5 +30,13 @@ namespace Horse_Isle_Server
InventoryItem[] GetItemList();
bool HasItem(int randomId);
bool HasItemId(int itemId);
InventoryItem GetItemByItemId(int itemId);
InventoryItem GetItemByRandomid(int randomId);
}
}

View file

@ -43,8 +43,46 @@ namespace Horse_Isle_Server
}
public static List<ItemInformation> Items = new List<ItemInformation>();
public struct ThrowableItem
{
public int Id;
public string Message;
}
public static List<ItemInformation> Items = new List<ItemInformation>();
public static List<ThrowableItem> ThrowableItems = new List<ThrowableItem>();
public static int Present;
public static int MailMessage;
public static int DorothyShoes;
public static int PawneerOrder;
public static int Telescope;
public static int Pitchfork;
public static bool IsThrowable(int id)
{
foreach(ThrowableItem itm in ThrowableItems)
{
if(itm.Id == id)
{
return true;
}
}
return false;
}
public static ThrowableItem GetThrowableItem(int id)
{
foreach (ThrowableItem itm in ThrowableItems)
{
if (itm.Id == id)
{
return itm;
}
}
throw new KeyNotFoundException("id: " + id + " is not a throwable item.");
}
public static ItemInformation GetItemById(int id)
{
foreach(ItemInformation item in Items)

View file

@ -62,13 +62,18 @@ namespace Horse_Isle_Server
public static string GrabAllItemsMessage;
public static string GrabbedItemMessage;
public static string GrabbedAllObjectsMessage;
public static string DroppedAnItemMessage;
// Inventory
public static string InventoryItemFormat;
public static string InventoryHeaderFormat;
public static string ItemDropItemButton;
public static string ItemDropButton;
public static string ItemInformationButton;
public static string ItemConsumeButton;
public static string ItemThrowButton;
public static string ItemUseButton;
public static string ItemReadButton;
// Meta
public static string IsleFormat;
@ -115,16 +120,31 @@ namespace Horse_Isle_Server
return InventoryItemFormat.Replace("%ICONID%", iconid.ToString()).Replace("%COUNT%", count.ToString()).Replace("%TITLE%", name);
}
public static string FormatItemThrowButton(int randomid)
{
return ItemThrowButton.Replace("%RANDOMID%", randomid.ToString());
}
public static string FormatItemConsumeButton(int randomid)
{
return ItemConsumeButton.Replace("%RANDOMID%", randomid.ToString());
}
public static string FormatItemInformationButton(int randomid)
{
return ItemInformationButton.Replace("%RANDOMID%", randomid.ToString());
}
public static string FormatItemDropItemButton(int randomid)
public static string FormatItemDropButton(int randomid)
{
return ItemDropItemButton.Replace("%RANDOMID%", randomid.ToString());
return ItemDropButton.Replace("%RANDOMID%", randomid.ToString());
}
public static string FormatItemUseButton(int randomid)
{
return ItemUseButton.Replace("%RANDOMID%", randomid.ToString());
}
public static string FormatItemReadButton(int randomid)
{
return ItemReadButton.Replace("%RANDOMID%", randomid.ToString());
}
// Meta
public static string FormatTileName(string name)

View file

@ -154,14 +154,27 @@ namespace Horse_Isle_Server
message += Messages.FormatPlayerInventoryItemMeta(itemInfo.IconId, item.ItemInstances.Count, title);
int randomId = item.ItemInstances[0].RandomID;
int sortBy = itemInfo.SortBy;
if(sortBy == 2) // all items with sort 2 are throwable-
message += Messages.FormatItemDropItemButton(randomId);
if (itemInfo.Id == Item.Present || itemInfo.Id == Item.DorothyShoes || itemInfo.Id == Item.Telescope)
message += Messages.FormatItemUseButton(randomId);
if (itemInfo.Type == "TEXT")
message += Messages.FormatItemReadButton(randomId);
if (itemInfo.Type == "PLAYERFOOD")
message += Messages.FormatItemConsumeButton(randomId);
if (Item.IsThrowable(itemInfo.Id))
message += Messages.FormatItemThrowButton(randomId);
if(itemInfo.Type != "QUEST" || itemInfo.Type != "TEXT")
message += Messages.FormatItemDropButton(randomId);
message += Messages.FormatItemInformationButton(randomId);
message += "^R1";
}
message += Messages.BackToMap;
message += Messages.MetaTerminator;
Logger.DebugPrint(message);
return message;
}

View file

@ -33,8 +33,7 @@ namespace Horse_Isle_Server
public const byte PACKET_LEAVE = 0x7D;
public const byte PACKET_PLAYERINFO = 0x16;
public const byte PICKUP_OBJECT = 0x14;
public const byte PLAYERINFO_LEAVE = 0x16;
public const byte PLAYERINFO_UPDATE_OR_CREATE = 0x15;
@ -58,6 +57,9 @@ namespace Horse_Isle_Server
public const byte CHAT_BOTTOM_RIGHT = 0x15;
public const byte CHAT_DM_RIGHT = 0x16;
public const byte ITEM_DROP = 0x1E;
public const byte ITEM_PICKUP = 0x14;
public const byte LOGIN_INVALID_USER_PASS = 0x15;
public const byte LOGIN_SUCCESS = 0x14;

View file

@ -18,7 +18,7 @@ namespace Horse_Isle_Server
ItemInstance[] instances = Database.GetPlayerInventory(baseUser.Id).ToArray();
foreach(ItemInstance instance in instances)
{
Add(instance);
addItem(instance, false);
}
}
@ -29,10 +29,10 @@ namespace Horse_Isle_Server
return inventoryItems.Count;
}
}
public void Add(ItemInstance item)
private void addItem(ItemInstance item, bool addToDatabase)
{
Database.AddItemToInventory(baseUser.Id, item);
if (addToDatabase)
Database.AddItemToInventory(baseUser.Id, item);
foreach (InventoryItem invetoryItem in inventoryItems)
{
@ -50,11 +50,20 @@ namespace Horse_Isle_Server
inventoryItems.Add(inventoryItem);
}
public void Add(ItemInstance item)
{
addItem(item, true);
}
public InventoryItem[] GetItemList()
{
return inventoryItems.OrderBy(o => o.ItemInstances[0].GetItemInfo().SortBy).ToArray();
}
public void Remove(ItemInstance item)
{
@ -69,6 +78,10 @@ namespace Horse_Isle_Server
if(instance.RandomID == item.RandomID)
{
inventoryItem.ItemInstances.Remove(instance);
if (inventoryItem.ItemInstances.Count <= 0)
inventoryItems.Remove(inventoryItem);
return;
}
}
@ -78,5 +91,62 @@ namespace Horse_Isle_Server
Logger.ErrorPrint("Tried to remove item : " + item.RandomID + " from inventory when it was not in it");
}
public bool HasItem(int randomId)
{
InventoryItem[] items = GetItemList();
foreach(InventoryItem item in items)
{
ItemInstance[] instances = item.ItemInstances.ToArray();
foreach(ItemInstance instance in instances)
{
if (instance.RandomID == randomId)
return true;
}
}
return false;
}
public bool HasItemId(int itemId)
{
InventoryItem[] items = GetItemList();
foreach (InventoryItem item in items)
{
if (item.ItemId == itemId)
{
return true;
}
}
return false;
}
public InventoryItem GetItemByItemId(int itemId)
{
InventoryItem[] items = GetItemList();
foreach (InventoryItem item in items)
{
if (item.ItemId == itemId)
{
return item;
}
}
throw new KeyNotFoundException("id: " + itemId + " not found in inventory");
}
public InventoryItem GetItemByRandomid(int randomId)
{
InventoryItem[] items = GetItemList();
foreach (InventoryItem item in items)
{
ItemInstance[] instances = item.ItemInstances.ToArray();
foreach (ItemInstance instance in instances)
{
if (instance.RandomID == randomId)
return item;
}
}
throw new KeyNotFoundException("random id: " + randomId + " not found in inventory");
}
}
}

View file

@ -463,7 +463,7 @@ namespace Horse_Isle_Server
byte action = packet[1];
switch(action)
{
case PacketBuilder.PICKUP_OBJECT:
case PacketBuilder.ITEM_PICKUP:
string packetStr = Encoding.UTF8.GetString(packet);
string randomIdStr = packetStr.Substring(2, packet.Length - 2);
int randomId = 0;
@ -495,6 +495,40 @@ namespace Horse_Isle_Server
return;
}
break;
case PacketBuilder.ITEM_DROP:
packetStr = Encoding.UTF8.GetString(packet);
randomIdStr = packetStr.Substring(2, packet.Length - 2);
randomId = 0;
try
{
randomId = Int32.Parse(randomIdStr);
}
catch (InvalidOperationException)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid object interaction packet.");
return;
}
if(sender.LoggedinUser.Inventory.HasItem(randomId))
{
InventoryItem itm = sender.LoggedinUser.Inventory.GetItemByRandomid(randomId);
ItemInstance instance = itm.ItemInstances[0];
DroppedItems.AddItem(instance, sender.LoggedinUser.X, sender.LoggedinUser.Y);
sender.LoggedinUser.Inventory.Remove(instance);
byte[] chatPacket = PacketBuilder.CreateChat(Messages.DroppedAnItemMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(chatPacket);
UpdateInventory(sender);
}
else
{
Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to drop an item they did not have.");
}
break;
default:
Logger.WarnPrint(sender.LoggedinUser.Username + " Sent an unknown Item Interaction Packet type: " + action.ToString() + ", Packet Dump: " + BitConverter.ToString(packet).Replace('-', ' '));
break;
}
@ -514,8 +548,7 @@ namespace Horse_Isle_Server
return;
}
byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildInventoryInfo(sender.LoggedinUser.Inventory));
sender.SendPacket(metaPacket);
UpdateInventory(sender);
}
public static void OnLoginRequest(Client sender, byte[] packet)
{
@ -712,8 +745,13 @@ namespace Horse_Isle_Server
UpdateUserInfo(client.LoggedinUser);
}
public static void UpdateInventory(Client forClient)
{
if (!forClient.LoggedIn)
return;
byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildInventoryInfo(forClient.LoggedinUser.Inventory));
forClient.SendPacket(metaPacket);
}
public static void UpdateWorld(Client forClient)
{
if (!forClient.LoggedIn)