diff --git a/src/ZoneServer/Commands/ChatCommands.Handlers.cs b/src/ZoneServer/Commands/ChatCommands.Handlers.cs index afaa14302..aa5e6ba8d 100644 --- a/src/ZoneServer/Commands/ChatCommands.Handlers.cs +++ b/src/ZoneServer/Commands/ChatCommands.Handlers.cs @@ -21,6 +21,7 @@ using Yggdrasil.Network.Communication; using Yggdrasil.Util; using Yggdrasil.Util.Commands; +using Melia.Shared.Game.Properties; namespace Melia.Zone.Commands { @@ -42,6 +43,8 @@ public ChatCommands() this.Add("readcollection", "", "", this.HandleReadCollection); this.Add("buyabilpoint", "", "", this.HandleBuyAbilPoint); this.Add("intewarpByToken", "", "", this.HandleTokenWarp); + this.Add("pethire", "", "", this.HandlePetHire); + this.Add("petstat", "", "", this.HandlePetStat); // Custom Client Commands this.Add("buyshop", "", "", this.HandleBuyShop); @@ -290,6 +293,118 @@ private CommandResult HandleJump(Character sender, Character target, string mess return CommandResult.Okay; } + /// + /// Official slash command to hire a pet + /// + /// /pethire 3 Pet + /// + /// + /// + /// + /// + /// + private CommandResult HandlePetHire(Character sender, Character target, string message, string command, Arguments args) + { + // Since this command is sent via UI interactions, we'll not + // use any automated command result messages, but we'll leave + // debug messages for now, in case of unexpected values. + if (args.Count < 2) + { + Log.Debug("HandlePetHire: Invalid call by user '{0}': {1}", sender.Username, command); + return CommandResult.Okay; + } + + if (sender.Companions.HasCompanions) + return CommandResult.Okay; + + if (!int.TryParse(args.Get(0), out var petShopId)) + return CommandResult.InvalidArgument; + + if (!ZoneServer.Instance.Data.CompanionDb.TryFind(petShopId, out var data)) + return CommandResult.InvalidArgument; + + if (!ZoneServer.Instance.Data.MonsterDb.TryFind(data.ClassName, out var monData)) + return CommandResult.InvalidArgument; + + var targetNpcName = "Companion Trader"; + var currentNpcName = sender.Connection.CurrentDialog?.Npc.Name; + + if (string.IsNullOrEmpty(currentNpcName) || !currentNpcName.Contains(targetNpcName)) + return CommandResult.InvalidArgument; + + //TODO: Decide if we sell pets that don't have a price defined. + if (data.Price == 0) + return CommandResult.Okay; + + if (sender.Inventory.CountItem(ItemId.Silver) < data.Price) + { + sender.SystemMessage("OwnerDontHaveSilver"); + return CommandResult.Okay; + } + + if (sender.Inventory.Remove(ItemId.Silver, data.Price) != InventoryResult.Success) + return CommandResult.Fail; + + var companion = new Companion(sender, monData.Id); + if (args.Count > 1) + companion.Name = args.Get(1); + + sender.Companions.CreateCompanion(companion); + + return CommandResult.Okay; + } + + /// + /// Official slash command to raise pet stats + /// + /// /petstat 528525790635969 MHP 1 + /// + /// + /// + /// + /// + /// + private CommandResult HandlePetStat(Character sender, Character target, string message, string command, Arguments args) + { + // Since this command is sent via UI interactions, we'll not + // use any automated command result messages, but we'll leave + // debug messages for now, in case of unexpected values. + if (args.Count < 2) + { + Log.Debug("HandlePetStat: Invalid call by user '{0}': {1}", sender.Username, command); + return CommandResult.Okay; + } + + if (!sender.Companions.HasCompanions) + return CommandResult.Okay; + + if (long.TryParse(args.Get(0), out var companionObjectId)) + { + var companion = sender.Companions.GetCompanion(companionObjectId); + var propertyName = "Monster_Stat_" + args.Get(1); + + if (companion != null && PropertyTable.Exists("Monster", propertyName) + && int.TryParse(args.Get(2), out var modifierValue)) + { + var baseCost = propertyName == PropertyName.Stat_DEF ? 600 : 300; + var totalCost = 0; + var currentValue = companion.Properties.GetFloat(propertyName) - 1; + + for (var i = currentValue; i < (currentValue + modifierValue); i++) + totalCost += (int)Math.Floor(baseCost * Math.Pow(1.08, i)); + + if (sender.Inventory.CountItem(ItemId.Silver) >= totalCost) + { + sender.Inventory.Remove(ItemId.Silver, totalCost); + companion.Properties.Modify(propertyName, modifierValue); + Send.ZC_OBJECT_PROPERTY(sender.Connection, companion); + } + } + } + + return CommandResult.Okay; + } + /// /// Warps target to the specified map. /// diff --git a/system/conf/commands.conf b/system/conf/commands.conf index a120bf632..da625af8e 100644 --- a/system/conf/commands.conf +++ b/system/conf/commands.conf @@ -35,6 +35,8 @@ readcollection : 0,-1 buyabilpoint : 0,-1 learnpcabil : 0,-1 intewarpByToken : 0,-1 +pethire : 0,-1 +petstat : 0,-1 // Custom client commands // These commands are used by our internal custom scripts to communicate