add horse catching minigame,

This commit is contained in:
SilicaAndPina 2021-01-05 20:09:12 +13:00
parent 9650e8e0b5
commit 062a24a4ed
11 changed files with 308 additions and 6 deletions

View file

@ -131,7 +131,12 @@
"password_input":"<BR>^PLReply:|^PS14|ANSWER^R1",
"last_poet":"^R1^LLast Player Poet:%USERNAME% ^R1",
"horse":{
"stat_format":"%BASE%;%COMPAINON%;%TACK%;%MAX%;"
"stat_format":"%BASE%;%COMPAINON%;%TACK%;%MAX%;",
"horses_here":"<B>HORSES HERE:</B><BR>",
"wild_horse":"^I252^T6%NAME%, It's a %BREED%^B3U%RANDOMID%^R1",
"horse_timer":"You have 60 seconds to capture the horse. Good luck!",
"horse_escaped":"The Horse Evaded Capture.",
"hore_caught":"You Captured the Horse!"
},
"libary":{
"main_menu":"Welcome to the Library! You can research different subjects.<BR>^T2Search Residents: ^D30|SEARCH NPC^R1^T2Search Ranches: ^D31|SEARCH RANCH^R1^T2Research Horses: ^D4|VIEW BREEDS^R1^T2Research Tack: ^D9|VIEW TACK^R1^T2Research Companions: ^D10|VIEW COMPANIONS^R1^T2Research Mini-Games: ^D12|VIEW MINIGAMES^R1^T2Research Locations: ^D22|VIEW LOCATIONS^R1^T2Research Awards: ^D23|VIEW AWARDS^R1^T2Read Books: ^D38|READ BOOKS^R1",

View file

@ -1,4 +1,5 @@
using HISP.Server;
using HISP.Player;
using HISP.Server;
using System;
using System.Collections.Generic;
using System.Linq;
@ -79,11 +80,44 @@ namespace HISP.Game.Horse
}
}
}
else
{
x = MapX;
y = MapY;
}
wildHorses.Add(this);
if(addToDatabase)
Database.AddWildHorse(this);
}
public void Escape()
{
while(true)
{
int tryX = X + GameServer.RandomNumberGenerator.Next(-15, 15);
int tryY = Y + GameServer.RandomNumberGenerator.Next(-15, 15);
// Horses cannot be in towns.
if (World.InTown(tryX, tryY))
continue;
if (World.InSpecialTile(tryX, tryY))
continue;
if (Map.CheckPassable(tryX, tryY))
{
X = tryX;
Y = tryY;
break;
}
}
}
public void Capture(User forUser)
{
Despawn(this);
}
private static List<WildHorse> wildHorses = new List<WildHorse>();
public static WildHorse[] WildHorses
{
@ -115,6 +149,56 @@ namespace HISP.Game.Horse
Database.LoadWildHorses();
GenerateHorses();
}
public static WildHorse[] GetHorsesAt(int x, int y)
{
List<WildHorse> horses = new List<WildHorse>();
foreach (WildHorse wildHorse in WildHorses)
{
if (wildHorse.X == x && wildHorse.Y == y)
horses.Add(wildHorse);
}
return horses.ToArray();
}
public static bool DoesHorseExist(int randomId)
{
foreach (WildHorse wildHorse in WildHorses)
{
if (wildHorse.Instance.RandomId == randomId)
return true;
}
return false;
}
public static WildHorse GetHorseById(int randomId)
{
foreach(WildHorse wildHorse in WildHorses)
{
if (wildHorse.Instance.RandomId == randomId)
return wildHorse;
}
throw new KeyNotFoundException("No horse with id: " + randomId + " was found.");
}
public static void Despawn(WildHorse horse)
{
Database.RemoveWildHorse(horse.Instance.RandomId);
wildHorses.Remove(horse);
}
public static void Update()
{
foreach(WildHorse wildHorse in WildHorses)
{
wildHorse.Timeout -= 1;
if (wildHorse.Timeout <= 0)
Despawn(wildHorse);
}
if(WildHorses.Length < 40)
{
GenerateHorses();
}
}
public HorseInstance Instance;
public int X
{
@ -124,6 +208,7 @@ namespace HISP.Game.Horse
}
set
{
Database.SetWildHorseX(this.Instance.RandomId, value);
x = value;
}
}
@ -135,6 +220,7 @@ namespace HISP.Game.Horse
}
set
{
Database.SetWildHorseY(this.Instance.RandomId, value);
y = value;
}
}
@ -146,6 +232,7 @@ namespace HISP.Game.Horse
}
set
{
Database.SetWildHorseTimeout(this.Instance.RandomId, value);
timeout = value;
}
}

View file

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HISP.Game.Inventory
{
class HorseInventory
{
}
}

View file

@ -164,6 +164,11 @@ namespace HISP.Game
// Horse
public static string BreedViewerMaximumStats;
public static string StatFormat;
public static string HorsesHere;
public static string WildHorseFormat;
public static string HorseCaptureTimer;
public static string YouCapturedTheHorse;
public static string HorseEvadedCapture;
// Consume
@ -355,6 +360,11 @@ namespace HISP.Game
// Click
public static string NothingInterestingHere;
public static string FormatWildHorse(string name, string breed, int randomId)
{
return WildHorseFormat.Replace("%NAME%", name).Replace("%BREED%", breed).Replace("%RANDOMID%", randomId.ToString());
}
public static string FormatHorseBreedPreview(string name, string description)
{
return BreedViewerFormat.Replace("%NAME%", name).Replace("%DESCRIPTION%", description);

View file

@ -434,7 +434,20 @@ namespace HISP.Game
return message;
}
public static string BuildHorseList(User user)
{
string message = "";
WildHorse[] horses = WildHorse.GetHorsesAt(user.X, user.Y);
if(horses.Length > 0)
{
message = Messages.HorsesHere;
foreach(WildHorse horse in horses)
{
message += Messages.FormatWildHorse(horse.Instance.Name, horse.Instance.Breed.Name, horse.Instance.RandomId);
}
}
return message;
}
public static string BuildAwardList(User user)
{
string message = Messages.AwardHeader;
@ -835,9 +848,23 @@ namespace HISP.Game
return message;
}
public static string BuildHorseEscapedMessage()
{
string message = Messages.HorseEvadedCapture;
message += Messages.BackToMap;
message += Messages.MetaTerminator;
return message;
}
public static string BuildHorseCaughtMessage()
{
string message = Messages.YouCapturedTheHorse;
message += Messages.BackToMap;
message += Messages.MetaTerminator;
return message;
}
public static string BuildAbuseReportPage()
{
@ -960,7 +987,7 @@ namespace HISP.Game
{
string message = "";
message += buildLocationString(x, y);
message += BuildHorseList(user);
message += buildNpc(user, x, y);

View file

@ -5,6 +5,7 @@ using HISP.Server;
using HISP.Player.Equips;
using HISP.Game.Services;
using HISP.Game.Inventory;
using HISP.Game.Horse;
namespace HISP.Player
{
@ -45,6 +46,7 @@ namespace HISP.Player
public PlayerQuests Quests;
public Highscore Highscores;
public Award Awards;
public int CapturingHorseId;
public DateTime LoginTime;
public DateTime SubscribedUntil

View file

@ -34,11 +34,26 @@ namespace HISP.Server
string Leaderboards = "CREATE TABLE Leaderboards(playerId INT, minigame TEXT(128), wins INT, looses INT, timesplayed INT, score INT, type TEXT(128))";
string NpcStartPoint = "CREATE TABLE NpcStartPoint(playerId INT, npcId INT, chatpointId INT)";
string PoetryRooms = "CREATE TABLE PoetryRooms(poetId INT, X INT, Y INT, roomId INT)";
string Horses = "CREATE TABLE Horses(randomId INT, originalOwner INT, breed INT, name TEXT(128), description TEXT(1028), sex TEXT(128), color TEXT(128), health INT, shoes INT, hunger INT, thirst INT, mood INT, groom INT, tiredness INT, experience INT, speed INT, strength INT, conformation INT, agility INT, endurance INT, inteligence INT, personality INT, height INT, saddle INT, saddlepad INT, bridle INT, companion INT, autoSell INT, category TEXT(128), spoiled INT, magicUsed INT)"
string WildHorse = "CREATE TABLE WildHorse(randomId INT, originalOwner INT, breed INT, x INT, y INT, name TEXT(128), description TEXT(1028), sex TEXT(128), color TEXT(128), health INT, shoes INT, hunger INT, thirst INT, mood INT, groom INT, tiredness INT, experience INT, speed INT, strength INT, conformation INT, agility INT, endurance INT, inteligence INT, personality INT, height INT, saddle INT, saddlepad INT, bridle INT, companion INT, timeout INT, autoSell INT, category TEXT(128), spoiled INT, magicUsed INT)";
string LastPlayer = "CREATE TABLE LastPlayer(roomId TEXT(1028), playerId INT)";
string DeleteOnlineUsers = "DELETE FROM OnlineUsers";
try
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = Horses;
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
catch (Exception e)
{
Logger.WarnPrint(e.Message);
};
try
{
@ -325,6 +340,58 @@ namespace HISP.Server
}
}
public static void SetWildHorseX(int randomId, int x)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE WildHorse SET x=@x WHERE randomId=@randomId";
sqlCommand.Parameters.AddWithValue("@randomId", randomId);
sqlCommand.Parameters.AddWithValue("@x", x);
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
}
public static void SetWildHorseTimeout(int randomId, int timeout)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE WildHorse SET timeout=@timeout WHERE randomId=@randomId";
sqlCommand.Parameters.AddWithValue("@randomId", randomId);
sqlCommand.Parameters.AddWithValue("@timeout", timeout);
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
}
public static void RemoveWildHorse(int randomId)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "DELETE FROM WildHorse WHERE randomId=@randomId";
sqlCommand.Parameters.AddWithValue("@randomId", randomId);
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
}
public static void SetWildHorseY(int randomId, int x)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE WildHorse SET y=@y WHERE randomId=@randomId";
sqlCommand.Parameters.AddWithValue("@randomId", randomId);
sqlCommand.Parameters.AddWithValue("@y", x);
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
}
public static void AddWildHorse(WildHorse horse)
{

View file

@ -245,6 +245,9 @@ namespace HISP.Server
case PacketBuilder.PACKET_SWFMODULE:
GameServer.OnSwfModuleCommunication(this, Packet);
break;
case PacketBuilder.PACKET_HORSE:
GameServer.OnHorseInteraction(this, Packet);
break;
case PacketBuilder.PACKET_WISH:
GameServer.OnWish(this, Packet);
break;

View file

@ -589,7 +589,11 @@ namespace HISP.Server
// Horses
Messages.StatFormat = gameData.messages.meta.horse.stat_format;
Messages.HorsesHere = gameData.messages.meta.horse.horses_here;
Messages.WildHorseFormat = gameData.messages.meta.horse.wild_horse;
Messages.HorseCaptureTimer = gameData.messages.meta.horse.horse_timer;
Messages.YouCapturedTheHorse = gameData.messages.meta.horse.hore_caught;
Messages.HorseEvadedCapture = gameData.messages.meta.horse.horse_escaped;
// Libary
Messages.LibaryMainMenu = gameData.messages.meta.libary.main_menu;

View file

@ -64,7 +64,7 @@ namespace HISP.Server
Database.IncPlayerTirednessForOfflineUsers();
DroppedItems.Update();
WildHorse.GenerateHorses();
WildHorse.Update();
minuteTimer.Change(oneMinute, oneMinute);
}
@ -81,6 +81,86 @@ namespace HISP.Server
sender.SendPacket(crossDomainPolicyResponse);
}
public static void OnHorseInteraction(GameClient sender, byte[] packet)
{
if (!sender.LoggedIn)
{
Logger.ErrorPrint(sender.RemoteIp + " Sent horse interaction when not logged in.");
return;
}
if(packet.Length < 4)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid sized horse interaction packet.");
return;
}
byte method = packet[1];
switch(method)
{
case PacketBuilder.HORSE_ESCAPE:
if(WildHorse.DoesHorseExist(sender.LoggedinUser.CapturingHorseId))
{
WildHorse capturing = WildHorse.GetHorseById(sender.LoggedinUser.CapturingHorseId);
capturing.Escape();
Logger.InfoPrint(sender.LoggedinUser.Username + " Failed to capture: " + capturing.Instance.Breed.Name + " new location: " + capturing.X + ", " + capturing.Y);
sender.LoggedinUser.MetaPriority = true;
byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseEscapedMessage());
sender.SendPacket(metaPacket);
UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y);
}
break;
case PacketBuilder.HORSE_CAUGHT:
if (WildHorse.DoesHorseExist(sender.LoggedinUser.CapturingHorseId))
{
WildHorse capturing = WildHorse.GetHorseById(sender.LoggedinUser.CapturingHorseId);
capturing.Capture(sender.LoggedinUser);
Logger.InfoPrint(sender.LoggedinUser.Username + " Captured a: " + capturing.Instance.Breed.Name + " new location: " + capturing.X + ", " + capturing.Y);
sender.LoggedinUser.MetaPriority = true;
byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildHorseCaughtMessage());
sender.SendPacket(metaPacket);
UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y);
}
break;
case PacketBuilder.HORSE_TRY_CAPTURE:
int randomId = 0;
string packetStr = Encoding.UTF8.GetString(packet);
string 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 ");
return;
}
if (!WildHorse.DoesHorseExist(randomId))
{
Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to catch a horse that doesnt exist.");
return;
}
sender.LoggedinUser.CapturingHorseId = randomId;
byte[] chatPacket = PacketBuilder.CreateChat(Messages.HorseCaptureTimer, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(chatPacket);
byte[] swfModulePacket = PacketBuilder.CreateSwfModulePacket("catchhorse", PacketBuilder.PACKET_SWF_MODULE_FORCE);
sender.SendPacket(swfModulePacket);
break;
default:
Logger.DebugPrint("Unknown horse packet: " + BitConverter.ToString(packet).Replace("-", " "));
break;
}
}
public static void OnDynamicInputReceived(GameClient sender, byte[] packet)
{
if (!sender.LoggedIn)

View file

@ -24,6 +24,7 @@ namespace HISP.Server
public const byte PACKET_SWF_MODULE_FORCE = 0x28;
public const byte PACKET_SWF_MODULE_GENTLE = 0x2A;
public const byte PACKET_PLACE_INFO = 0x1E;
public const byte PACKET_HORSE = 0x19;
public const byte PACKET_AREA_DEFS = 0x79;
public const byte PACKET_ITEM_INTERACTION = 0x1E;
public const byte PACKET_ANNOUNCEMENT = 0x7E;
@ -44,6 +45,10 @@ namespace HISP.Server
public const byte PACKET_WISH = 0x2C;
public const byte PACKET_SWFMODULE = 0x50;
public const byte HORSE_TRY_CAPTURE = 0x1C;
public const byte HORSE_ESCAPE = 0x1E;
public const byte HORSE_CAUGHT = 0x1D;
public const byte SWFMODULE_BRICKPOET = 0x5A;
public const byte BRICKPOET_LIST_ALL = 0x14;