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;