293 lines
No EOL
13 KiB
C#
293 lines
No EOL
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Qmmands;
|
|
using WingsAPI.Game.Extensions.Quests;
|
|
using WingsEmu.Commands.Checks;
|
|
using WingsEmu.Commands.Entities;
|
|
using WingsEmu.DTOs.Account;
|
|
using WingsEmu.DTOs.Quests;
|
|
using WingsEmu.Game.Extensions;
|
|
using WingsEmu.Game.Networking;
|
|
using WingsEmu.Game.Quests;
|
|
using WingsEmu.Game.Quests.Event;
|
|
using WingsEmu.Packets.Enums.Chat;
|
|
|
|
namespace Plugin.QuestImpl
|
|
{
|
|
[Name("Quests")]
|
|
[Group("quests", "quest")]
|
|
[Description("Module related to Quest commands.")]
|
|
[RequireAuthority(AuthorityType.SuperGameMaster)]
|
|
public class QuestModule : SaltyModuleBase
|
|
{
|
|
private readonly IQuestFactory _questFactory;
|
|
private readonly IQuestManager _questManager;
|
|
|
|
public QuestModule(IQuestManager questManager, IQuestFactory questFactory)
|
|
{
|
|
_questManager = questManager;
|
|
_questFactory = questFactory;
|
|
}
|
|
|
|
[Command("add")]
|
|
[Description("Add the quest linked to a given ID")]
|
|
public async Task<SaltyCommandResult> AddQuest(int questId, string questSlotTypeName)
|
|
{
|
|
if (!Enum.TryParse(questSlotTypeName, out QuestSlotType questSlotType))
|
|
{
|
|
return new SaltyCommandResult(false, "Wrong quest slot type");
|
|
}
|
|
|
|
QuestDto quest = _questManager.GetQuestById(questId);
|
|
if (quest == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Quest null");
|
|
}
|
|
|
|
Context.Player.PlayerEntity.AddActiveQuest(_questFactory.NewQuest(Context.Player.PlayerEntity.Id, questId, questSlotType));
|
|
Context.Player.RefreshQuestList(_questManager, quest.Id);
|
|
Context.Player.SendTargetQuest(quest.TargetMapX, quest.TargetMapY, quest.TargetMapId, quest.Id);
|
|
return new SaltyCommandResult(true, "Quest added!");
|
|
}
|
|
|
|
[Command("give")]
|
|
[Description("Gives the quest to a character on a slot (general, main, secondary)")]
|
|
public async Task<SaltyCommandResult> AddQuest(IClientSession session, int questId, string questSlotTypeName)
|
|
{
|
|
if (!Enum.TryParse(questSlotTypeName, out QuestSlotType questSlotType))
|
|
{
|
|
return new SaltyCommandResult(false, "Wrong quest slot type");
|
|
}
|
|
|
|
QuestDto quest = _questManager.GetQuestById(questId);
|
|
if (quest == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Quest null");
|
|
}
|
|
|
|
if (session == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Player null");
|
|
}
|
|
|
|
session.PlayerEntity.AddActiveQuest(_questFactory.NewQuest(session.PlayerEntity.Id, questId, questSlotType));
|
|
session.RefreshQuestList(_questManager, quest.Id);
|
|
session.SendTargetQuest(quest.TargetMapX, quest.TargetMapY, quest.TargetMapId, quest.Id);
|
|
return new SaltyCommandResult(true, "Quest added!");
|
|
}
|
|
|
|
[Command("getscripts")]
|
|
[Description("Get the scripts completed by the player")]
|
|
public async Task<SaltyCommandResult> GetPlayerCompletedScripts(IClientSession session)
|
|
{
|
|
if (session == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Player null");
|
|
}
|
|
|
|
foreach (CompletedScriptsDto completedScriptsDto in session.PlayerEntity.GetCompletedScripts())
|
|
{
|
|
Context.Player.SendChatMessage($"script {completedScriptsDto.ScriptId} {completedScriptsDto.ScriptIndex}", ChatMessageColorType.Yellow);
|
|
}
|
|
|
|
return new SaltyCommandResult(true);
|
|
}
|
|
|
|
[Command("completescripts", "cs")]
|
|
[Description("Forces the script completion, removing any MAIN quest running and any completed script after the specified, and sends the next one.")]
|
|
public async Task<SaltyCommandResult> ForceCompleteScripts(IClientSession session, int scriptId, int scriptIndex)
|
|
{
|
|
if (session == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Player null");
|
|
}
|
|
|
|
TutorialDto tutorialDto = _questManager.GetScriptTutorialByIndex(scriptId, scriptIndex);
|
|
if (tutorialDto == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Script null");
|
|
}
|
|
|
|
IReadOnlyCollection<TutorialDto> scripts = _questManager.GetScriptsTutorialUntilIndex(scriptId, scriptIndex);
|
|
IEnumerable<CompletedScriptsDto> playerCompletedScripts = session.PlayerEntity.GetCompletedScripts();
|
|
|
|
foreach (TutorialDto script in scripts)
|
|
{
|
|
session.PlayerEntity.SaveScript(script.ScriptId, script.ScriptIndex, script.Type, DateTime.UtcNow);
|
|
if (script.Type == TutorialActionType.WAIT_FOR_QUEST_COMPLETION)
|
|
{
|
|
session.PlayerEntity.AddCompletedQuest(_questFactory.NewQuest(session.PlayerEntity.Id, script.Data, QuestSlotType.MAIN));
|
|
}
|
|
}
|
|
|
|
foreach (CompletedScriptsDto completedScript in playerCompletedScripts)
|
|
{
|
|
if (completedScript.ScriptId < scriptId || completedScript.ScriptId == scriptId && completedScript.ScriptIndex <= scriptIndex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
session.PlayerEntity.RemoveCompletedScript(completedScript.ScriptId, completedScript.ScriptIndex);
|
|
|
|
TutorialDto script = _questManager.GetScriptTutorialByIndex(completedScript.ScriptId, completedScript.ScriptIndex);
|
|
if (script.Type == TutorialActionType.WAIT_FOR_QUEST_COMPLETION)
|
|
{
|
|
session.PlayerEntity.RemoveCompletedQuest(script.Data);
|
|
}
|
|
}
|
|
|
|
TutorialDto nextScript = _questManager.GetScriptTutorialById(scripts.Last().Id + 1);
|
|
if (nextScript == null)
|
|
{
|
|
return new SaltyCommandResult(true, "That was the last script,");
|
|
}
|
|
|
|
CharacterQuest characterQuest = session.GetQuestBySlot(5);
|
|
if (characterQuest != null) // Remove a MAIN quest if there is any
|
|
{
|
|
session.DeleteQuestTarget(characterQuest);
|
|
session.PlayerEntity.RemoveActiveQuest(characterQuest.QuestId);
|
|
session.RefreshQuestList(_questManager, null);
|
|
}
|
|
|
|
if (nextScript.Type == TutorialActionType.WAIT_FOR_QUEST_COMPLETION && session.PlayerEntity.HasQuestWithId(nextScript.Data))
|
|
{
|
|
QuestDto quest = _questManager.GetQuestById(nextScript.Data);
|
|
session.PlayerEntity.AddActiveQuest(_questFactory.NewQuest(session.PlayerEntity.Id, nextScript.Data, QuestSlotType.MAIN));
|
|
session.RefreshQuestList(_questManager, quest.Id);
|
|
session.SendTargetQuest(quest.TargetMapX, quest.TargetMapY, quest.TargetMapId, quest.Id);
|
|
}
|
|
|
|
session.SendScriptPacket(nextScript.ScriptId, nextScript.ScriptIndex);
|
|
|
|
return new SaltyCommandResult(true, "Scripts completed");
|
|
}
|
|
|
|
[Command("remove")]
|
|
[Description("Remove the quest linked to a given ID")]
|
|
public async Task<SaltyCommandResult> RemoveQuest(int questId)
|
|
{
|
|
CharacterQuest quest = Context.Player.PlayerEntity.GetQuestById(questId);
|
|
if (quest == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Quest null");
|
|
}
|
|
|
|
Context.Player.DeleteQuestTarget(quest);
|
|
Context.Player.PlayerEntity.RemoveActiveQuest(quest.QuestId);
|
|
Context.Player.RefreshQuestList(_questManager, null);
|
|
return new SaltyCommandResult(true, "Quest removed!");
|
|
}
|
|
|
|
[Command("remove")]
|
|
[Description("Remove the quest linked to a given ID of a character")]
|
|
public async Task<SaltyCommandResult> RemoveQuest(IClientSession session, int questId)
|
|
{
|
|
if (session == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Player null");
|
|
}
|
|
|
|
CharacterQuest quest = session.PlayerEntity.GetQuestById(questId);
|
|
if (quest == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Quest null");
|
|
}
|
|
|
|
session.DeleteQuestTarget(quest);
|
|
session.PlayerEntity.RemoveActiveQuest(quest.QuestId);
|
|
session.RefreshQuestList(_questManager, null);
|
|
return new SaltyCommandResult(true, "Quest removed!");
|
|
}
|
|
|
|
[Command("showinfo")]
|
|
[Description("Show info related to a player quests")]
|
|
public async Task<SaltyCommandResult> ShowInfo(IClientSession session)
|
|
{
|
|
if (session == null)
|
|
{
|
|
return new SaltyCommandResult(false, "Player null");
|
|
}
|
|
|
|
Context.Player.SendChatMessage($"== Active quests from {session.PlayerEntity.Name} ==", ChatMessageColorType.Yellow);
|
|
foreach (CharacterQuest quest in session.PlayerEntity.GetCurrentQuests())
|
|
{
|
|
Context.Player.SendChatMessage($"- Quest VNUM: {quest.QuestId}; Slot: {quest.SlotType}; Type: {quest.Quest.QuestType}", ChatMessageColorType.Yellow);
|
|
foreach (QuestObjectiveDto objective in quest.Quest.Objectives)
|
|
{
|
|
CharacterQuestObjectiveDto questObjectiveDto = quest.ObjectiveAmount[objective.ObjectiveIndex];
|
|
Context.Player.SendChatMessage($"ObjectiveIndex: {objective.ObjectiveIndex}; CompletedAmount: {questObjectiveDto.CurrentAmount}", ChatMessageColorType.Yellow);
|
|
}
|
|
}
|
|
|
|
return new SaltyCommandResult(true, "Scripts showed");
|
|
}
|
|
|
|
[Command("showinfo")]
|
|
[Description("Show info related to your quests")]
|
|
public async Task<SaltyCommandResult> ShowInfo()
|
|
{
|
|
Context.Player.SendChatMessage($"== Active quests from {Context.Player.PlayerEntity.Name} ==", ChatMessageColorType.Yellow);
|
|
foreach (CharacterQuest quest in Context.Player.PlayerEntity.GetCurrentQuests())
|
|
{
|
|
Context.Player.SendChatMessage($"- Quest VNUM: {quest.QuestId}; Slot: {quest.SlotType}; Type: {quest.Quest.QuestType}", ChatMessageColorType.Yellow);
|
|
foreach (QuestObjectiveDto objective in quest.Quest.Objectives)
|
|
{
|
|
CharacterQuestObjectiveDto questObjectiveDto = quest.ObjectiveAmount[objective.ObjectiveIndex];
|
|
Context.Player.SendChatMessage($"ObjectiveIndex: {objective.ObjectiveIndex}; CompletedAmount: {questObjectiveDto.CurrentAmount}", ChatMessageColorType.Yellow);
|
|
}
|
|
}
|
|
|
|
return new SaltyCommandResult(true);
|
|
}
|
|
|
|
[Command("clear")]
|
|
[Description("Clear all quests")]
|
|
public async Task<SaltyCommandResult> ClearAllQuests()
|
|
{
|
|
foreach (CharacterQuest quest in Context.Player.PlayerEntity.GetCurrentQuests())
|
|
{
|
|
Context.Player.PlayerEntity.RemoveActiveQuest(quest.QuestId);
|
|
Context.Player.DeleteQuestTarget(quest);
|
|
}
|
|
|
|
Context.Player.RefreshQuestList(_questManager, null);
|
|
return new SaltyCommandResult(true);
|
|
}
|
|
|
|
[Command("refresh-dq", "refreshdailyquests", "rdq")]
|
|
[Description("Refresh your daily minigame points.")]
|
|
public async Task<SaltyCommandResult> RefreshDailyQuests([Description("Force refresh")] bool force = false)
|
|
{
|
|
Context.Player.EmitEvent(new QuestDailyRefreshEvent { Force = force });
|
|
return new SaltyCommandResult(true, "Daily quests refreshed!");
|
|
}
|
|
|
|
[Command("set-soundflowers")]
|
|
[Description("Gives the player X amount of unstarted soundflower quests")]
|
|
public async Task<SaltyCommandResult> GiveSoundFlowers(IClientSession session, int amount)
|
|
{
|
|
IReadOnlyCollection<CharacterQuest> generalQuests = session.PlayerEntity.GetCurrentQuests().Where(s => s.SlotType == QuestSlotType.MAIN).ToList();
|
|
if (generalQuests.Count + amount > 5)
|
|
{
|
|
return new SaltyCommandResult(false, "You can't have more than 5 GENERAL quests active!");
|
|
}
|
|
|
|
int currentSoundFlowers = session.PlayerEntity.GetPendingSoundFlowerQuests();
|
|
for (int i = 0; i < currentSoundFlowers; i++)
|
|
{
|
|
session.PlayerEntity.DecreasePendingSoundFlowerQuests();
|
|
}
|
|
|
|
for (int i = 0; i < amount; i++)
|
|
{
|
|
session.PlayerEntity.IncreasePendingSoundFlowerQuests();
|
|
}
|
|
|
|
session.RefreshQuestList(_questManager, null);
|
|
return new SaltyCommandResult(true, "Sound flower quests added!");
|
|
}
|
|
}
|
|
} |