diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json index 0eec686..c17187f 100644 --- a/DataCollection/gamedata.json +++ b/DataCollection/gamedata.json @@ -51,6 +51,7 @@ "sec_code":{ "invalid_sec_code":"Data Code Error. You did not get the bonus. You should reconnect if you get this message again.", "item_earned":"You Earned a %ITEM%!", + "item_deleted":"You Lost an %ITEM%!", "money_earned":"You Earned $%MONEY%!", "highscore_beaten":"You just beat your best score! New high score: %SCORE%.", "best_time_beaten":"Your new best time: %TIME%." @@ -131,7 +132,23 @@ "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", - + "pond":{ + "header":"^LYou can go fishing at this pond!^R1", + "go_fishing":"^T6Go Fishing!^BMfishing^R5", + "no_fishing_pole":"^LBut you do not have a Fishing Pole!^R5", + "no_earth_worms":"^LBut you do not have any Earth Worms!^R5", + "drink_here":"^LYour horses can drink at this pond if you think it's safe.^R1", + "horse_drink_format":"^T7Your horse %HORSENAME%: thirst %THIRST%/%MAXTHIRST%^B3D%RANDOMID%^R1", + + "not_thirsty":"Your horse %HORSENAME% is not thirsty at all.", + "cant_drink_hp_low":"Your horse %HORSENAME% health is too poor. Don't want to risk drinking something nasty!", + "drank_full":"Your horse %HORSENAME% drank to its heart's content!", + "drank_something_bad":"OH NO! %HORSENAME% must have drank something bad! Its health is down." + }, + "mud_hole":{ + "no_horses":"Big muddy area here....Luckily you don't have any horses, because if you did they may have gotten dirty.", + "ruined_groom":"Big muddy area here....OH NO! Your horse '%HORSENAME%' rolled around in the mud, ruining its groom completely..", + }, "horse":{ "stat_format":"%BASE%;%COMPAINON%;%TACK%;%MAX%;", "basic_stat_format":"^AB%HEALTH%;%HUNGER%;%THIRST%;%MOOD%;%ENERGY%;%GROOM%;%SHOES%;", @@ -7617,7 +7634,9 @@ "pawneer_order":559, "telescope":182, "pitchfork":152, - "wishing_coin":50 + "wishing_coin":50, + "fishing_poll":146, + "earthworm":83 }, "throwable":[ {"id":144,"message":"blanketing wet snow on "}, diff --git a/Horse Isle Server/Horse Isle Server/Game/Horse/HorseInfo.cs b/Horse Isle Server/Horse Isle Server/Game/Horse/HorseInfo.cs index bbbc6f0..b2a14c3 100644 --- a/Horse Isle Server/Horse Isle Server/Game/Horse/HorseInfo.cs +++ b/Horse Isle Server/Horse Isle Server/Game/Horse/HorseInfo.cs @@ -397,7 +397,7 @@ namespace HISP.Game.Horse value = 1000; if (value < 0) value = 0; - hunger = value; + thirst = value; Database.SetHorseThirst(baseHorse.RandomId, value); } } diff --git a/Horse Isle Server/Horse Isle Server/Game/Item.cs b/Horse Isle Server/Horse Isle Server/Game/Item.cs index 41a969d..f681c7c 100644 --- a/Horse Isle Server/Horse Isle Server/Game/Item.cs +++ b/Horse Isle Server/Horse Isle Server/Game/Item.cs @@ -57,6 +57,8 @@ namespace HISP.Game public static int Telescope; public static int Pitchfork; public static int WishingCoin; + public static int FishingPole; + public static int Earthworm; public static ItemInformation[] GetAllWishableItems() { diff --git a/Horse Isle Server/Horse Isle Server/Game/Messages.cs b/Horse Isle Server/Horse Isle Server/Game/Messages.cs index 97cbcaa..7222a14 100644 --- a/Horse Isle Server/Horse Isle Server/Game/Messages.cs +++ b/Horse Isle Server/Horse Isle Server/Game/Messages.cs @@ -157,8 +157,26 @@ namespace HISP.Game public static string DroppedAnItemMessage; public static string ItemInformationFormat; + // Pond + public static string PondHeader; + public static string PondGoFishing; + public static string PondNoFishingPole; + public static string PondNoEarthWorms; + public static string PondDrinkHereIfSafe; + public static string PondHorseDrinkFormat; + + public static string PondNotThirstyFormat; + public static string PondDrinkFullFormat; + public static string PondCantDrinkHpLowFormat; + public static string PondDrinkOhNoesFormat; + + // Mud Hole + + public static string MudHoleNoHorses; + public static string MudHoleRuinedGroomFormat; // Competition Gear + public static string EquipCompetitionGearFormat; public static string RemoveCompetitionGear; @@ -369,6 +387,7 @@ namespace HISP.Game // Sec Codes public static string InvalidSecCodeError; public static string YouEarnedAnItemFormat; + public static string YouLostAnItemFormat; public static string YouEarnedMoneyFormat; public static string BeatHighscoreFormat; public static string BeatBestTimeFormat; @@ -469,8 +488,32 @@ namespace HISP.Game // Click public static string NothingInterestingHere; + + public static string FormatPondNotThirsty(string horseName) + { + return PondNotThirstyFormat.Replace("%HORSENAME%", horseName); + } + public static string FormatPondDrinkOhNoes(string horseName) + { + return PondDrinkOhNoesFormat.Replace("%HORSENAME%", horseName); + } + public static string FormatPondDrinkFull(string horseName) + { + return PondDrinkFullFormat.Replace("%HORSENAME%", horseName); + } + public static string FormatPondHpLowMessage(string horseName) + { + return PondCantDrinkHpLowFormat.Replace("%HORSENAME%", horseName); + } - + public static string FormatPondDrinkHorseFormat(string horseName, int thirst, int maxThirst, int randomId) + { + return PondHorseDrinkFormat.Replace("%HORSENAME%", horseName).Replace("%THIRST%", thirst.ToString()).Replace("%MAXTHIRST%", maxThirst.ToString()).Replace("%RANDOMID%", randomId.ToString()); + } + public static string FormatMudHoleGroomDestroyed(string horseName) + { + return MudHoleRuinedGroomFormat.Replace("%HORSENAME%", horseName); + } public static string FormatMiscStatsEntry(string statName, int value) { return StatMiscEntryFormat.Replace("%STAT%", statName).Replace("%COUNT%", value.ToString()); @@ -1004,6 +1047,10 @@ namespace HISP.Game return PlayerCommandFormat.Replace("%COMMAND%", command); } + public static string FormatYouLostAnItemMessage(string itemName) + { + return YouLostAnItemFormat.Replace("%ITEM%", itemName); + } public static string FormatYouEarnedAnItemMessage(string itemName) { return YouEarnedAnItemFormat.Replace("%ITEM%", itemName); diff --git a/Horse Isle Server/Horse Isle Server/Game/Meta.cs b/Horse Isle Server/Horse Isle Server/Game/Meta.cs index 0716bc6..8e6c6b2 100644 --- a/Horse Isle Server/Horse Isle Server/Game/Meta.cs +++ b/Horse Isle Server/Horse Isle Server/Game/Meta.cs @@ -731,6 +731,48 @@ namespace HISP.Game { return Messages.FountainMeta; } + private static string buildPond(User user) + { + string message = Messages.PondHeader; + if(!user.Inventory.HasItemId(Item.FishingPole)) + { + message += Messages.PondNoFishingPole; + } + else if(!user.Inventory.HasItemId(Item.Earthworm)) + { + message += Messages.PondNoEarthWorms; + } + else + { + message += Messages.PondGoFishing; + } + message += Messages.PondDrinkHereIfSafe; + foreach(HorseInstance horse in user.HorseInventory.HorseList) + { + message += Messages.FormatPondDrinkHorseFormat(horse.Name, horse.BasicStats.Thirst, 1000, horse.RandomId); + } + message += Messages.ExitThisPlace; + message += Messages.MetaTerminator; + return message; + } + private static string buildMudHole(User user) + { + string message = ""; + if(user.HorseInventory.HorseList.Length > 0) + { + int rngHorseIndex = GameServer.RandomNumberGenerator.Next(0, user.HorseInventory.HorseList.Length); + HorseInstance horse = user.HorseInventory.HorseList[rngHorseIndex]; + horse.BasicStats.Groom = 0; + message += Messages.FormatMudHoleGroomDestroyed(horse.Name); + } + else + { + message += Messages.MudHoleNoHorses; + } + message += Messages.ExitThisPlace; + message += Messages.MetaTerminator; + return message; + } private static string buildPassword() { return Messages.PasswordEntry + Messages.ExitThisPlace + Messages.MetaTerminator; @@ -773,6 +815,7 @@ namespace HISP.Game if (specialTile.Title != null && specialTile.Title != "") message += Messages.FormatTileName(specialTile.Title); + if (specialTile.Description != null && specialTile.Description != "") message += specialTile.Description; @@ -835,6 +878,14 @@ namespace HISP.Game { message += buildLibary(); } + if(TileCode == "POND") + { + message += buildPond(user); + } + if(TileCode == "MUDHOLE") + { + message += buildMudHole(user); + } if(TileCode == "MULTIROOM") { user.MetaPriority = false; // acturally want to track updates here >-< @@ -1066,7 +1117,7 @@ namespace HISP.Game else message += Messages.HorseIsTrainable; - if (user.Facing <= 5) + if (user.CurrentlyRidingHorse == null) message += Messages.FormatMountButton(horse.RandomId); else message += Messages.FormatDisMountButton(horse.RandomId); diff --git a/Horse Isle Server/Horse Isle Server/Server/GameClient.cs b/Horse Isle Server/Horse Isle Server/Server/GameClient.cs index 4f09980..ce036c0 100644 --- a/Horse Isle Server/Horse Isle Server/Server/GameClient.cs +++ b/Horse Isle Server/Horse Isle Server/Server/GameClient.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading; using HISP.Player; using HISP.Game; +using HISP.Game.Horse; namespace HISP.Server { @@ -52,20 +53,35 @@ namespace HISP.Server // From testing hunger seemed to go down fastest, then thirst, and finally tiredness. - if(totalMinutesElapsed % 1 == 0) + foreach(HorseInstance horse in LoggedinUser.HorseInventory.HorseList) { - LoggedinUser.Hunger -= 1; + if (totalMinutesElapsed % 2 == 0) + { + horse.BasicStats.Thirst--; + horse.BasicStats.Hunger--; + } + if (totalMinutesElapsed % 2 == 0 && (horse.BasicStats.Thirst <= 100 || horse.BasicStats.Thirst <= 100 || horse.BasicStats.Tiredness <= 100)) + horse.BasicStats.Health--; + + if (totalMinutesElapsed % 60 == 0) + { + horse.BasicStats.Mood--; + horse.BasicStats.Shoes--; + horse.BasicStats.Tiredness--; + } + + } + + if (totalMinutesElapsed % 1 == 0) + LoggedinUser.Thirst--; + if (totalMinutesElapsed % 5 == 0) - { - LoggedinUser.Thirst -= 1; - } + LoggedinUser.Hunger--; if (totalMinutesElapsed % 10 == 0) - { - LoggedinUser.Tiredness -= 1; - } + LoggedinUser.Tiredness--; } minuteTimer.Change(oneMinute, oneMinute); diff --git a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs index 204a33d..502b130 100644 --- a/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs +++ b/Horse Isle Server/Horse Isle Server/Server/GameDataJson.cs @@ -512,6 +512,8 @@ namespace HISP.Server Item.Telescope = gameData.item.special.telescope; Item.Pitchfork = gameData.item.special.pitchfork; Item.WishingCoin = gameData.item.special.wishing_coin; + Item.FishingPole = gameData.item.special.fishing_poll; + Item.Earthworm = gameData.item.special.earthworm; // New Users Messages.NewUserMessage = gameData.messages.new_user.starting_message; @@ -578,6 +580,23 @@ namespace HISP.Server Messages.StatMiscNoneRecorded = gameData.messages.meta.misc_stats.no_stats_recorded; Messages.StatMiscEntryFormat = gameData.messages.meta.misc_stats.stat_format; + // Pond + Messages.PondHeader = gameData.messages.meta.pond.header; + Messages.PondGoFishing = gameData.messages.meta.pond.go_fishing; + Messages.PondNoFishingPole = gameData.messages.meta.pond.no_fishing_pole; + Messages.PondDrinkHereIfSafe = gameData.messages.meta.pond.drink_here; + Messages.PondHorseDrinkFormat = gameData.messages.meta.pond.horse_drink_format; + Messages.PondNoEarthWorms = gameData.messages.meta.pond.no_earth_worms; + + Messages.PondDrinkFullFormat = gameData.messages.meta.pond.drank_full; + Messages.PondCantDrinkHpLowFormat = gameData.messages.meta.pond.cant_drink_hp_low; + Messages.PondDrinkOhNoesFormat = gameData.messages.meta.pond.drank_something_bad; + Messages.PondNotThirstyFormat = gameData.messages.meta.pond.not_thirsty; + + // Mud Hole + Messages.MudHoleNoHorses = gameData.messages.meta.mud_hole.no_horses; + Messages.MudHoleRuinedGroomFormat = gameData.messages.meta.mud_hole.ruined_groom; + // Movement Messages.RandomMovement = gameData.messages.random_movement; @@ -933,6 +952,7 @@ namespace HISP.Server Messages.InvalidSecCodeError = gameData.messages.sec_code.invalid_sec_code; Messages.YouEarnedAnItemFormat = gameData.messages.sec_code.item_earned; + Messages.YouLostAnItemFormat = gameData.messages.sec_code.item_deleted; Messages.YouEarnedMoneyFormat = gameData.messages.sec_code.money_earned; Messages.BeatHighscoreFormat = gameData.messages.sec_code.highscore_beaten; Messages.BeatBestTimeFormat = gameData.messages.sec_code.best_time_beaten; diff --git a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs index 9965ebe..e23821f 100644 --- a/Horse Isle Server/Horse Isle Server/Server/GameServer.cs +++ b/Horse Isle Server/Horse Isle Server/Server/GameServer.cs @@ -387,6 +387,69 @@ namespace HISP.Server Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to tack at a non existant horse."); break; } + case PacketBuilder.HORSE_DRINK: + if(World.InSpecialTile(sender.LoggedinUser.X, sender.LoggedinUser.Y)) + { + World.SpecialTile tile = World.GetSpecialTile(sender.LoggedinUser.X, sender.LoggedinUser.Y); + if(tile.Code != "POND") + { + Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to drink from a pond when not on one."); + break; + } + } + + 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.HorseInventory.HorseIdExist(randomId)) + { + HorseInstance horseInst = sender.LoggedinUser.HorseInventory.GetHorseById(randomId); + + if(horseInst.BasicStats.Health < 200) + { + byte[] hpToLow = PacketBuilder.CreateChat(Messages.FormatPondHpLowMessage(horseInst.Name), PacketBuilder.CHAT_BOTTOM_RIGHT); + sender.SendPacket(hpToLow); + break; + } + + if(horseInst.BasicStats.Thirst < 1000) + { + horseInst.BasicStats.Thirst = 1000; + byte[] drinkFull = PacketBuilder.CreateChat(Messages.FormatPondDrinkFull(horseInst.Name),PacketBuilder.CHAT_BOTTOM_RIGHT); + sender.SendPacket(drinkFull); + + if(RandomNumberGenerator.Next(0, 100) < 25) + { + horseInst.BasicStats.Health -= 200; + byte[] ohNoes = PacketBuilder.CreateChat(Messages.FormatPondDrinkOhNoes(horseInst.Name), PacketBuilder.CHAT_BOTTOM_RIGHT); + sender.SendPacket(ohNoes); + } + + UpdateArea(sender); + } + else + { + byte[] notThirsty = PacketBuilder.CreateChat(Messages.FormatPondNotThirsty(horseInst.Name), PacketBuilder.CHAT_BOTTOM_RIGHT); + sender.SendPacket(notThirsty); + break; + } + break; + } + else + { + Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to tack at a non existant horse."); + break; + } case PacketBuilder.HORSE_TACK_EQUIP: int itemId = 0; @@ -1777,7 +1840,7 @@ namespace HISP.Server } } - else if (method == PacketBuilder.SECCODE_ITEM) + else if (method == PacketBuilder.SECCODE_GIVE_ITEM) { byte[] ExpectedSecCode = sender.LoggedinUser.GenerateSecCode(); byte[] GotSecCode = new byte[4]; @@ -1827,6 +1890,59 @@ namespace HISP.Server return; } } + else if (method == PacketBuilder.SECCODE_DELETE_ITEM) + { + byte[] ExpectedSecCode = sender.LoggedinUser.GenerateSecCode(); + byte[] GotSecCode = new byte[4]; + Array.ConstrainedCopy(packet, 2, GotSecCode, 0, GotSecCode.Length); + Logger.DebugPrint(sender.LoggedinUser.Username + " Sent sec code: " + BitConverter.ToString(GotSecCode).Replace("-", " ")); + if (ExpectedSecCode.SequenceEqual(GotSecCode)) + { + if (packet.Length < 6) + { + Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent a seccode item request with invalid size"); + return; + } + string packetStr = Encoding.UTF8.GetString(packet); + string intStr = packetStr.Substring(6, packetStr.Length - 6 - 2); + int value = -1; + try + { + value = int.Parse(intStr); + } + catch (FormatException) + { + Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent correct sec code, but invalid value"); + return; + } + + + if (sender.LoggedinUser.Inventory.HasItemId(value)) + { + InventoryItem item = sender.LoggedinUser.Inventory.GetItemByItemId(value); + sender.LoggedinUser.Inventory.Remove(item.ItemInstances[0]); + + Item.ItemInformation itemInfo = Item.GetItemById(value); + byte[] lostItemMessage = PacketBuilder.CreateChat(Messages.FormatYouLostAnItemMessage(itemInfo.Name), PacketBuilder.CHAT_BOTTOM_RIGHT); + sender.SendPacket(lostItemMessage); + + UpdateArea(sender); + } + else + { + Logger.HackerPrint(sender.LoggedinUser.Username + " Sent correct sec code, but tried to delete an non existant item"); + return; + } + + } + else + { + byte[] errorMessage = PacketBuilder.CreateChat(Messages.InvalidSecCodeError, PacketBuilder.CHAT_BOTTOM_RIGHT); + sender.SendPacket(errorMessage); + Logger.HackerPrint(sender.LoggedinUser.Username + " Sent invalid sec code"); + return; + } + } else if (method == PacketBuilder.SECCODE_QUEST) { byte[] ExpectedSecCode = sender.LoggedinUser.GenerateSecCode(); @@ -1892,7 +2008,6 @@ namespace HISP.Server sender.SendPacket(metaTag); } - } public static void OnMovementPacket(GameClient sender, byte[] packet) { @@ -2081,6 +2196,7 @@ namespace HISP.Server sender.SendPacket(moveResponse); } + Update(sender); } public static void OnQuitPacket(GameClient sender, byte[] packet) @@ -2392,20 +2508,21 @@ namespace HISP.Server case PacketBuilder.ITEM_PICKUP_ALL: string chatMsg = Messages.GrabAllItemsMessage; DroppedItems.DroppedItem[] droppedItems = DroppedItems.GetItemsAt(sender.LoggedinUser.X, sender.LoggedinUser.Y); - foreach(DroppedItems.DroppedItem item in droppedItems) + + try { - try + foreach (DroppedItems.DroppedItem item in droppedItems) { sender.LoggedinUser.Inventory.Add(item.instance); + DroppedItems.RemoveDroppedItem(item); } - catch (InventoryException) - { - chatMsg = Messages.GrabbedAllItemsButInventoryFull; - break; - } - - DroppedItems.RemoveDroppedItem(item); } + catch (InventoryException) + { + chatMsg = Messages.GrabbedAllItemsButInventoryFull; + break; + } + UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y); byte[] chatMessage = PacketBuilder.CreateChat(chatMsg, PacketBuilder.CHAT_BOTTOM_RIGHT); diff --git a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs index 2235e85..49d97b9 100644 --- a/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs +++ b/Horse Isle Server/Horse Isle Server/Server/PacketBuilder.cs @@ -55,6 +55,7 @@ namespace HISP.Server public const byte HORSE_TRY_CAPTURE = 0x1C; public const byte HORSE_RELEASE = 0x19; public const byte HORSE_TACK = 0x16; + public const byte HORSE_DRINK = 0x2B; public const byte HORSE_GIVE_FEED = 0x1B; public const byte HORSE_TACK_EQUIP = 0x3C; public const byte HORSE_TACK_UNEQUIP = 0x3D; @@ -73,7 +74,8 @@ namespace HISP.Server public const byte WISH_WORLDPEACE = 0x33; public const byte SECCODE_QUEST = 0x32; - public const byte SECCODE_ITEM = 0x28; + public const byte SECCODE_GIVE_ITEM = 0x28; + public const byte SECCODE_DELETE_ITEM = 0x29; public const byte SECCODE_SCORE = 0x3D; public const byte SECCODE_TIME = 0x3E; public const byte SECCODE_MONEY = 0x1E;