mirror of
https://github.com/islehorse/HISP.git
synced 2025-04-19 19:29:15 +12:00
Implement workshops and fix more quest weirdnes.
This commit is contained in:
parent
cb00f79d48
commit
d5762c3b07
9 changed files with 352 additions and 112 deletions
|
@ -31,7 +31,7 @@ namespace HISP.Game.Chat
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (args[0] == "MONEY")
|
||||
else if (args[0] == "MONEY")
|
||||
{
|
||||
int money = 0;
|
||||
try
|
||||
|
@ -44,7 +44,7 @@ namespace HISP.Game.Chat
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (args[0] == "QUEST")
|
||||
else if (args[0] == "QUEST")
|
||||
{
|
||||
int questId = 0;
|
||||
try
|
||||
|
@ -57,7 +57,10 @@ namespace HISP.Game.Chat
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
byte[] chatPacket = PacketBuilder.CreateChat(Messages.FormatAdminCommandCompleteMessage(message.Substring(1)), PacketBuilder.CHAT_BOTTOM_LEFT);
|
||||
user.LoggedinClient.SendPacket(chatPacket);
|
||||
return true;
|
||||
|
@ -220,6 +223,31 @@ namespace HISP.Game.Chat
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if(args[0] == "AREA")
|
||||
{
|
||||
if (args.Length < 2)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
string area = string.Join(" ", args, 1, args.Length - 1);
|
||||
bool teleported = false;
|
||||
foreach(World.Waypoint waypnt in World.Waypoints)
|
||||
{
|
||||
if(waypnt.Name.ToLower().StartsWith(area.ToLower()))
|
||||
{
|
||||
user.Teleport(waypnt.PosX, waypnt.PosY);
|
||||
teleported = true;
|
||||
}
|
||||
}
|
||||
if(!teleported)
|
||||
return false;
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(args[0].Contains(","))
|
||||
{
|
||||
try
|
||||
|
|
|
@ -217,6 +217,17 @@ namespace HISP.Game
|
|||
public static string TackViewSetFormat;
|
||||
public static string TackSetPeiceFormat;
|
||||
|
||||
// Workshop
|
||||
public static string WorkshopCraftEntryFormat;
|
||||
public static string WorkshopRequiresFormat;
|
||||
public static string WorkshopRequireEntryFormat;
|
||||
public static string WorkshopAnd;
|
||||
|
||||
public static string WorkshopNoRoomInInventory;
|
||||
public static string WorkshopMissingRequiredItem;
|
||||
public static string WorkshopCraftingSuccess;
|
||||
public static string WorkshopCannotAfford;
|
||||
|
||||
// Horse
|
||||
public static string BreedViewerMaximumStats;
|
||||
public static string AdvancedStatFormat;
|
||||
|
@ -569,6 +580,19 @@ namespace HISP.Game
|
|||
// Click
|
||||
public static string NothingInterestingHere;
|
||||
|
||||
public static string FormatWorkshopCraftEntry(int iconId, string itemName, int price, int itemId, int craftId)
|
||||
{
|
||||
return WorkshopCraftEntryFormat.Replace("%ICONID%", iconId.ToString()).Replace("%ITEMNAME%", itemName).Replace("%PRICE%", price.ToString("N0")).Replace("%ITEMID%", itemId.ToString()).Replace("%CRAFTID%", craftId.ToString());
|
||||
}
|
||||
public static string FormatWorkshopRequirements(string requiresTxt)
|
||||
{
|
||||
return WorkshopRequiresFormat.Replace("%REQUIRES%", requiresTxt);
|
||||
}
|
||||
public static string FormatWorkshopRequireEntry(int requiredCount, string itemNamePlural)
|
||||
{
|
||||
return WorkshopRequireEntryFormat.Replace("%REQCOUNT%", requiredCount.ToString("N0")).Replace("%ITEMNAME%", itemNamePlural);
|
||||
}
|
||||
|
||||
public static string FormatDrawingRoomSaved(int slot)
|
||||
{
|
||||
return DrawingContentsSavedInSlotFormat.Replace("%SLOT%", slot.ToString("N0"));
|
||||
|
|
|
@ -1018,6 +1018,33 @@ namespace HISP.Game
|
|||
return message;
|
||||
}
|
||||
|
||||
private static string buildWorkshop(User user)
|
||||
{
|
||||
Workshop shop = Workshop.GetWorkshopAt(user.X, user.Y);
|
||||
string message = "";
|
||||
foreach(Workshop.CraftableItem craft in shop.CraftableItems)
|
||||
{
|
||||
Item.ItemInformation itmInfo = Item.GetItemById(craft.GiveItemId);
|
||||
message += Messages.FormatWorkshopCraftEntry(itmInfo.IconId, itmInfo.Name, craft.MoneyCost, itmInfo.Id, craft.Id);
|
||||
// Get requirements
|
||||
List<string> Requirements = new List<string>();
|
||||
foreach(Workshop.RequiredItem reqItem in craft.RequiredItems)
|
||||
{
|
||||
|
||||
Item.ItemInformation requiredItemInfo = Item.GetItemById(reqItem.RequiredItemId);
|
||||
string requirementTxt;
|
||||
if (reqItem.RequiredItemCount <= 1)
|
||||
requirementTxt = Messages.FormatWorkshopRequireEntry(reqItem.RequiredItemCount, requiredItemInfo.Name);
|
||||
else
|
||||
requirementTxt = Messages.FormatWorkshopRequireEntry(reqItem.RequiredItemCount, requiredItemInfo.PluralName);
|
||||
Requirements.Add(requirementTxt);
|
||||
}
|
||||
message += Messages.FormatWorkshopRequirements(string.Join(Messages.WorkshopAnd, Requirements.ToArray()));
|
||||
}
|
||||
message += Messages.ExitThisPlace;
|
||||
message += Messages.MetaTerminator;
|
||||
return message;
|
||||
}
|
||||
private static string buildVet(Vet vet, User user)
|
||||
{
|
||||
string message = "";
|
||||
|
@ -1127,6 +1154,10 @@ namespace HISP.Game
|
|||
{
|
||||
message += buildPond(user);
|
||||
}
|
||||
if(TileCode == "WORKSHOP")
|
||||
{
|
||||
message += buildWorkshop(user);
|
||||
}
|
||||
if(TileCode == "MUDHOLE")
|
||||
{
|
||||
message += buildMudHole(user);
|
||||
|
@ -1535,24 +1566,26 @@ namespace HISP.Game
|
|||
if (chatpoint.ActivateQuestId != 0)
|
||||
{
|
||||
Quest.QuestEntry quest = Quest.GetQuestById(chatpoint.ActivateQuestId);
|
||||
if (Quest.ActivateQuest(user, quest, true))
|
||||
|
||||
Quest.QuestResult result = Quest.ActivateQuest(user, quest, true);
|
||||
if (result.QuestCompleted)
|
||||
{
|
||||
user.MetaPriority = true;
|
||||
if (quest.SetNpcChatpoint != -1)
|
||||
Npc.SetDefaultChatpoint(user, npc, quest.SetNpcChatpoint);
|
||||
if (quest.GotoNpcChatpoint != -1)
|
||||
chatpoint = Npc.GetNpcChatpoint(npc,quest.GotoNpcChatpoint);
|
||||
if (quest.SuccessNpcChat != null)
|
||||
chatpoint.ChatText = quest.SuccessNpcChat;
|
||||
if (result.SetChatpoint != -1)
|
||||
Npc.SetDefaultChatpoint(user, npc, result.SetChatpoint);
|
||||
if (result.GotoChatpoint != -1)
|
||||
chatpoint = Npc.GetNpcChatpoint(npc, result.GotoChatpoint);
|
||||
if (result.NpcChat != null)
|
||||
chatpoint.ChatText = result.NpcChat;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (quest.GotoNpcChatpoint != -1)
|
||||
chatpoint = Npc.GetNpcChatpoint(npc, quest.GotoNpcChatpoint);
|
||||
if (quest.FailNpcChat != null)
|
||||
chatpoint.ChatText = quest.FailNpcChat;
|
||||
if (result.GotoChatpoint != -1)
|
||||
chatpoint = Npc.GetNpcChatpoint(npc, result.GotoChatpoint);
|
||||
if (result.NpcChat != null)
|
||||
chatpoint.ChatText = result.NpcChat;
|
||||
|
||||
if (quest.HideReplyOnFail)
|
||||
if (result.HideRepliesOnFail)
|
||||
hideReplys = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,23 @@ namespace HISP.Game
|
|||
return sortedQuests.ToArray();
|
||||
}
|
||||
|
||||
public class QuestResult
|
||||
{
|
||||
public QuestResult()
|
||||
{
|
||||
NpcChat = null;
|
||||
SetChatpoint = -1;
|
||||
GotoChatpoint = -1;
|
||||
HideRepliesOnFail = false;
|
||||
QuestCompleted = false;
|
||||
}
|
||||
public string NpcChat;
|
||||
public int SetChatpoint;
|
||||
public int GotoChatpoint;
|
||||
public bool HideRepliesOnFail;
|
||||
public bool QuestCompleted;
|
||||
}
|
||||
|
||||
public static bool CanComplete(User user, QuestEntry quest)
|
||||
{
|
||||
if (quest.Tracked)
|
||||
|
@ -153,8 +170,10 @@ namespace HISP.Game
|
|||
return true;
|
||||
}
|
||||
|
||||
public static bool CompleteQuest(User user, QuestEntry quest, bool npcActivation = false)
|
||||
public static QuestResult CompleteQuest(User user, QuestEntry quest, bool npcActivation = false, QuestResult res=null)
|
||||
{
|
||||
if(res == null)
|
||||
res = new QuestResult();
|
||||
// Take Items
|
||||
foreach (QuestItemInfo itemInfo in quest.ItemsRequired)
|
||||
{
|
||||
|
@ -181,12 +200,24 @@ namespace HISP.Game
|
|||
// Give quest points
|
||||
user.QuestPoints += quest.QuestPointsEarned;
|
||||
|
||||
|
||||
res.QuestCompleted = true;
|
||||
if (npcActivation)
|
||||
{
|
||||
if (quest.SuccessNpcChat != null)
|
||||
res.NpcChat = quest.SuccessNpcChat;
|
||||
|
||||
if(quest.SetNpcChatpoint != -1)
|
||||
res.SetChatpoint = quest.SetNpcChatpoint;
|
||||
|
||||
if(quest.GotoNpcChatpoint != -1)
|
||||
res.GotoChatpoint = quest.GotoNpcChatpoint;
|
||||
}
|
||||
|
||||
if (quest.Tracked)
|
||||
user.Quests.TrackQuest(quest.Id);
|
||||
|
||||
if (quest.ChainedQuestId != 0)
|
||||
ActivateQuest(user, Quest.GetQuestById(quest.ChainedQuestId), npcActivation);
|
||||
res = ActivateQuest(user, Quest.GetQuestById(quest.ChainedQuestId), npcActivation, res);
|
||||
|
||||
if (quest.SuccessMessage != null)
|
||||
{
|
||||
|
@ -203,9 +234,6 @@ namespace HISP.Game
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Check if award unlocked
|
||||
int questPointsPercent = Convert.ToInt32(Math.Floor(((decimal)user.QuestPoints / (decimal)GetTotalQuestPoints()) * (decimal)100.0));
|
||||
if (questPointsPercent >= 25)
|
||||
|
@ -224,10 +252,23 @@ namespace HISP.Game
|
|||
user.LoggedinClient.SendPacket(swfLoadPacket);
|
||||
}
|
||||
|
||||
return true;
|
||||
return res;
|
||||
}
|
||||
public static bool FailQuest(User user, QuestEntry quest, bool npcActivation = false)
|
||||
public static QuestResult FailQuest(User user, QuestEntry quest, bool npcActivation = false, QuestResult res=null)
|
||||
{
|
||||
if(res == null)
|
||||
res = new QuestResult();
|
||||
res.QuestCompleted = false;
|
||||
|
||||
if(npcActivation)
|
||||
{
|
||||
if(quest.GotoNpcChatpoint != -1)
|
||||
res.GotoChatpoint = quest.GotoNpcChatpoint;
|
||||
if(quest.HideReplyOnFail != false)
|
||||
res.HideRepliesOnFail = quest.HideReplyOnFail;
|
||||
if(res.SetChatpoint != -1)
|
||||
res.SetChatpoint = quest.SetNpcChatpoint;
|
||||
}
|
||||
if (quest.FailNpcChat != null)
|
||||
{
|
||||
if (!npcActivation)
|
||||
|
@ -235,19 +276,24 @@ namespace HISP.Game
|
|||
byte[] ChatPacket = PacketBuilder.CreateChat(quest.FailNpcChat, PacketBuilder.CHAT_BOTTOM_RIGHT);
|
||||
user.LoggedinClient.SendPacket(ChatPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(quest.FailNpcChat != null)
|
||||
res.NpcChat = quest.FailNpcChat;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
public static bool ActivateQuest(User user, QuestEntry quest, bool npcActivation = false)
|
||||
public static QuestResult ActivateQuest(User user, QuestEntry quest, bool npcActivation = false, QuestResult res=null)
|
||||
{
|
||||
|
||||
if (CanComplete(user, quest))
|
||||
{
|
||||
return CompleteQuest(user, quest, npcActivation);
|
||||
return CompleteQuest(user, quest, npcActivation, res);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FailQuest(user, quest, npcActivation);
|
||||
return FailQuest(user, quest, npcActivation, res);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,30 @@ namespace HISP.Game.Services
|
|||
|
||||
public static List<Workshop> Workshops = new List<Workshop>();
|
||||
|
||||
public static Workshop GetWorkshopAt(int x, int y)
|
||||
{
|
||||
foreach(Workshop wkShop in Workshops)
|
||||
{
|
||||
if(wkShop.X == x && wkShop.Y == y)
|
||||
{
|
||||
return wkShop;
|
||||
}
|
||||
}
|
||||
throw new KeyNotFoundException("No workshop found.");
|
||||
}
|
||||
|
||||
public static bool CraftIdExists(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetCraftId(id);
|
||||
return true;
|
||||
}
|
||||
catch(KeyNotFoundException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static CraftableItem GetCraftId(int id)
|
||||
{
|
||||
foreach(Workshop wkShop in Workshops)
|
||||
|
|
|
@ -560,11 +560,11 @@ namespace HISP.Server
|
|||
craftableItem.GiveItemId = gameData.workshop[i].craftable_items[ii].give_item;
|
||||
craftableItem.MoneyCost = gameData.workshop[i].craftable_items[ii].money_cost;
|
||||
int totalItemsRequired = gameData.workshop[i].craftable_items[ii].required_items.Count;
|
||||
for(int iii = 0; iii < 0; iii++)
|
||||
for(int iii = 0; iii < totalItemsRequired; iii++)
|
||||
{
|
||||
Workshop.RequiredItem requiredItem = new Workshop.RequiredItem();
|
||||
requiredItem.RequiredItemId = totalItemsRequired = gameData.workshop[i].craftable_items[ii].required_items[iii].req_item;
|
||||
requiredItem.RequiredItemId = totalItemsRequired = gameData.workshop[i].craftable_items[ii].required_items[iii].req_quantity;
|
||||
requiredItem.RequiredItemId = gameData.workshop[i].craftable_items[ii].required_items[iii].req_item;
|
||||
requiredItem.RequiredItemCount = gameData.workshop[i].craftable_items[ii].required_items[iii].req_quantity;
|
||||
craftableItem.RequiredItems.Add(requiredItem);
|
||||
}
|
||||
wkShop.CraftableItems.Add(craftableItem);
|
||||
|
@ -761,6 +761,17 @@ namespace HISP.Server
|
|||
Messages.BankDepositedMoneyFormat = gameData.messages.bank.deposit_format;
|
||||
Messages.BankWithdrewMoneyFormat = gameData.messages.bank.withdraw_format;
|
||||
|
||||
// Workshop
|
||||
Messages.WorkshopCraftEntryFormat = gameData.messages.meta.workshop.craft_entry;
|
||||
Messages.WorkshopRequiresFormat = gameData.messages.meta.workshop.requires;
|
||||
Messages.WorkshopRequireEntryFormat = gameData.messages.meta.workshop.require;
|
||||
Messages.WorkshopAnd = gameData.messages.meta.workshop.and;
|
||||
|
||||
Messages.WorkshopNoRoomInInventory = gameData.messages.meta.workshop.no_room;
|
||||
Messages.WorkshopMissingRequiredItem = gameData.messages.meta.workshop.missing_item;
|
||||
Messages.WorkshopCraftingSuccess = gameData.messages.meta.workshop.craft_success;
|
||||
Messages.WorkshopCannotAfford = gameData.messages.meta.workshop.no_money;
|
||||
|
||||
// Horses
|
||||
Messages.AdvancedStatFormat = gameData.messages.meta.horse.stat_format;
|
||||
Messages.BasicStatFormat = gameData.messages.meta.horse.basic_stat_format;
|
||||
|
|
|
@ -3390,6 +3390,75 @@ namespace HISP.Server
|
|||
byte[] ChatPacket = PacketBuilder.CreateChat(Messages.BinocularsNothing, PacketBuilder.CHAT_BOTTOM_RIGHT);
|
||||
sender.SendPacket(ChatPacket);
|
||||
}
|
||||
break;
|
||||
case PacketBuilder.ITEM_CRAFT:
|
||||
packetStr = Encoding.UTF8.GetString(packet);
|
||||
string craftIdStr = packetStr.Substring(2, packet.Length - 2);
|
||||
int craftId = 0;
|
||||
// Prevent crashing on non-int string.
|
||||
try
|
||||
{
|
||||
craftId = Int32.Parse(craftIdStr);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to craft using craft id NaN.");
|
||||
return;
|
||||
}
|
||||
if(Workshop.CraftIdExists(craftId))
|
||||
{
|
||||
Workshop.CraftableItem itm = Workshop.GetCraftId(craftId);
|
||||
if(itm.MoneyCost <= sender.LoggedinUser.Money) // Check money
|
||||
{
|
||||
foreach(Workshop.RequiredItem reqItem in itm.RequiredItems)
|
||||
{
|
||||
if (sender.LoggedinUser.Inventory.HasItemId(reqItem.RequiredItemId))
|
||||
{
|
||||
if (sender.LoggedinUser.Inventory.GetItemByItemId(reqItem.RequiredItemId).ItemInstances.Count < reqItem.RequiredItemCount)
|
||||
goto failMissingItem;
|
||||
}
|
||||
else
|
||||
goto failMissingItem;
|
||||
}
|
||||
|
||||
// Finally create the items
|
||||
try
|
||||
{
|
||||
sender.LoggedinUser.Inventory.Add(new ItemInstance(itm.GiveItemId));
|
||||
}
|
||||
catch(InventoryException)
|
||||
{
|
||||
byte[] inventoryFullMessage = PacketBuilder.CreateChat(Messages.WorkshopNoRoomInInventory, PacketBuilder.CHAT_BOTTOM_RIGHT);
|
||||
sender.SendPacket(inventoryFullMessage);
|
||||
break;
|
||||
}
|
||||
sender.LoggedinUser.Money -= itm.MoneyCost;
|
||||
|
||||
// Remove the required items..
|
||||
foreach(Workshop.RequiredItem reqItem in itm.RequiredItems)
|
||||
for(int i = 0; i < reqItem.RequiredItemCount; i++)
|
||||
sender.LoggedinUser.Inventory.Remove(sender.LoggedinUser.Inventory.GetItemByItemId(reqItem.RequiredItemId).ItemInstances[0]);
|
||||
|
||||
byte[] itemCraftSuccess = PacketBuilder.CreateChat(Messages.WorkshopCraftingSuccess, PacketBuilder.CHAT_BOTTOM_RIGHT);
|
||||
sender.SendPacket(itemCraftSuccess);
|
||||
break;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] cantAffordMessage = PacketBuilder.CreateChat(Messages.WorkshopCannotAfford, PacketBuilder.CHAT_BOTTOM_RIGHT);
|
||||
sender.SendPacket(cantAffordMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
failMissingItem:
|
||||
{
|
||||
byte[] missingItemMessage = PacketBuilder.CreateChat(Messages.WorkshopMissingRequiredItem, PacketBuilder.CHAT_BOTTOM_RIGHT);
|
||||
sender.SendPacket(missingItemMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case PacketBuilder.ITEM_SELL: // Handles selling an item.
|
||||
int totalSold = 1;
|
||||
|
|
|
@ -137,6 +137,7 @@ namespace HISP.Server
|
|||
public const byte ITEM_DRINK = 0x52;
|
||||
public const byte ITEM_BINOCULARS = 0x5C;
|
||||
public const byte ITEM_MAGNIFYING = 0x5D;
|
||||
public const byte ITEM_CRAFT = 0x64;
|
||||
public const byte ITEM_RAKE = 0x5B;
|
||||
public const byte ITEM_SHOVEL = 0x5A;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue