From 298fb1f59a126feb92f656e46bdb99bec3078b8a Mon Sep 17 00:00:00 2001 From: Waverunner Date: Mon, 25 Aug 2014 17:44:22 -0400 Subject: [PATCH] Added quest completion window, Changed sui service to not need conversation npcs to need conversation radial attached, Changed goToLocation event to check all of players quests instead of active one --- scripts/commands/completequest.py | 25 +++++++++ .../{ => quests/tatooine}/majolnir.py | 5 +- scripts/object/mobile/majolnir.py | 2 +- scripts/quests/events/go_to_location.py | 4 +- .../events/signals/giveCustomizationKit.py | 2 - .../item_content_veh_custom_kit_02_02.py | 4 ++ src/protocol/swg/ObjControllerMessage.java | 1 + .../ShowQuestCompletionWindow.java | 56 +++++++++++++++++++ src/resources/quest/Quest.java | 5 ++ src/services/ConversationService.java | 1 + src/services/quest/QuestService.java | 23 ++++---- src/services/sui/SUIService.java | 11 +++- 12 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 scripts/commands/completequest.py rename scripts/conversation/{ => quests/tatooine}/majolnir.py (95%) create mode 100644 scripts/quests/rewards/item_content_veh_custom_kit_02_02.py create mode 100644 src/protocol/swg/objectControllerObjects/ShowQuestCompletionWindow.java diff --git a/scripts/commands/completequest.py b/scripts/commands/completequest.py new file mode 100644 index 00000000..1eeea046 --- /dev/null +++ b/scripts/commands/completequest.py @@ -0,0 +1,25 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + + if actor is None: + return + + player = actor.getPlayerObject() + + if player is None: + return + + quest = player.getQuest(int(commandString)) + + if quest is None: + return + + if (quest.getActiveTask() != (core.questService.getQuestData(quest.getName()).getTasks().size() - 1)): + return + + core.questService.completeQuest(player, quest) + return \ No newline at end of file diff --git a/scripts/conversation/majolnir.py b/scripts/conversation/quests/tatooine/majolnir.py similarity index 95% rename from scripts/conversation/majolnir.py rename to scripts/conversation/quests/tatooine/majolnir.py index 91431d53..469f4efb 100644 --- a/scripts/conversation/majolnir.py +++ b/scripts/conversation/quests/tatooine/majolnir.py @@ -7,8 +7,7 @@ import sys def startConversation(core, actor, npc): convSvc = core.conversationService player = actor.getPlayerObject() - - print ('conversation') + if player is None: return @@ -18,7 +17,7 @@ def startConversation(core, actor, npc): endConversation(core, actor, npc) return - if quest.isComplete(): + if quest.isCompleted(): core.conversationService.sendStopConversation(actor, npc, 'conversation/tatooine_eisley_majolnir', 's_24') return diff --git a/scripts/object/mobile/majolnir.py b/scripts/object/mobile/majolnir.py index d80c08c5..68dc2c93 100644 --- a/scripts/object/mobile/majolnir.py +++ b/scripts/object/mobile/majolnir.py @@ -1,5 +1,5 @@ import sys def setup(core, object): - object.setAttachment('conversationFile', 'majolnir') + object.setAttachment('conversationFile', 'quests/tatooine/majolnir') return \ No newline at end of file diff --git a/scripts/quests/events/go_to_location.py b/scripts/quests/events/go_to_location.py index 396505a0..d5e3b141 100644 --- a/scripts/quests/events/go_to_location.py +++ b/scripts/quests/events/go_to_location.py @@ -7,10 +7,10 @@ def run(core, activator, collidable): player = activator.getPlayerObject() - if player.getActiveQuestName() != collidable.getAttachedQuest(): + if player.getQuest(collidable.getAttachedQuest()) == None: return - quest = player.getQuest(player.getActiveQuest()) + quest = player.getQuest(collidable.getAttachedQuest()) if quest.isCompleted(): return diff --git a/scripts/quests/events/signals/giveCustomizationKit.py b/scripts/quests/events/signals/giveCustomizationKit.py index 94611f89..2c219af1 100644 --- a/scripts/quests/events/signals/giveCustomizationKit.py +++ b/scripts/quests/events/signals/giveCustomizationKit.py @@ -2,10 +2,8 @@ def setup(core): return def wait(core, actor): - print ('waiting') return def activate(core, actor, quest): - print ('Activate!!') core.questService.completeActiveTask(actor, quest) return \ No newline at end of file diff --git a/scripts/quests/rewards/item_content_veh_custom_kit_02_02.py b/scripts/quests/rewards/item_content_veh_custom_kit_02_02.py new file mode 100644 index 00000000..73c2b4d8 --- /dev/null +++ b/scripts/quests/rewards/item_content_veh_custom_kit_02_02.py @@ -0,0 +1,4 @@ +import sys + +def run(): + return "object/tangible/item/shared_vehicle_customization.iff" \ No newline at end of file diff --git a/src/protocol/swg/ObjControllerMessage.java b/src/protocol/swg/ObjControllerMessage.java index d9d66a97..580318e0 100644 --- a/src/protocol/swg/ObjControllerMessage.java +++ b/src/protocol/swg/ObjControllerMessage.java @@ -81,6 +81,7 @@ public class ObjControllerMessage extends SWGMessage { public static final int QUEST_TASK_COUNTER = 0x0441; public static final int QUEST_TASK_TIMER = 0x0444; public static final int FORCE_ACTIVATE_QUEST = 0x04BE; + public static final int SHOW_QUEST_COMPLETION_WINDOW = 0x04B8; public ObjControllerMessage() { diff --git a/src/protocol/swg/objectControllerObjects/ShowQuestCompletionWindow.java b/src/protocol/swg/objectControllerObjects/ShowQuestCompletionWindow.java new file mode 100644 index 00000000..6078f56d --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ShowQuestCompletionWindow.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; +import engine.resources.objects.Baseline; + +public class ShowQuestCompletionWindow extends ObjControllerObject { + + private long objectId; + private int questCrc; + + public ShowQuestCompletionWindow(long objectId, int questCrc) { + this.objectId = objectId; + this.questCrc = questCrc; + } + + @Override + public void deserialize(IoBuffer data) { + } + + @Override + public IoBuffer serialize() { + IoBuffer buffer = Baseline.createBuffer(20); + + buffer.putInt(ObjControllerMessage.SHOW_QUEST_COMPLETION_WINDOW); + buffer.putLong(objectId); + buffer.putInt(0); + + buffer.putInt(questCrc); + + return buffer.flip(); + } + +} diff --git a/src/resources/quest/Quest.java b/src/resources/quest/Quest.java index 2e346183..73549238 100644 --- a/src/resources/quest/Quest.java +++ b/src/resources/quest/Quest.java @@ -133,6 +133,11 @@ public class Quest extends Delta implements Serializable { //System.out.println("Active step was "+ (activeStep - 1) + " and is now " + activeStep ); } + public void complete() { + completedStepBitmask.set(activeStep); + activeStepBitmask.clear(); + } + public ScheduledFuture getTimer() { return timer; } diff --git a/src/services/ConversationService.java b/src/services/ConversationService.java index 29dd18ec..d3418d7c 100644 --- a/src/services/ConversationService.java +++ b/src/services/ConversationService.java @@ -60,6 +60,7 @@ public class ConversationService implements INetworkDispatch { core.simulationService.faceTarget(npc, player); player.setConversingNpc(npc); + // TODO: Come up with a way for not needing to send the StartConversation packet, some only sent the end conversation packet to show the chat bubble sendStartConversation(player, npc); core.scriptService.callScript("scripts/conversation/", (String) npc.getAttachment("conversationFile"), "startConversation", core, player, npc); } diff --git a/src/services/quest/QuestService.java b/src/services/quest/QuestService.java index dec1e873..094e2b8a 100644 --- a/src/services/quest/QuestService.java +++ b/src/services/quest/QuestService.java @@ -49,11 +49,11 @@ import protocol.swg.objectControllerObjects.ForceActivateQuest; import protocol.swg.objectControllerObjects.QuestTaskCounterMessage; import protocol.swg.objectControllerObjects.QuestTaskTimerMessage; import protocol.swg.objectControllerObjects.ShowLootBox; +import protocol.swg.objectControllerObjects.ShowQuestCompletionWindow; import resources.common.Console; import resources.common.ObjControllerOpcodes; import resources.common.OutOfBand; import resources.common.ProsePackage; -import resources.common.collidables.CollidableCircle; import resources.common.collidables.QuestCollidable; import resources.datatables.DisplayType; import resources.objects.SWGMap; @@ -262,16 +262,19 @@ public class QuestService implements INetworkDispatch { quest.getTimer().cancel(true); if (activeStep + 1 >= qData.getTasks().size()) { - QuestList listItem = questRewardMap.get(quest.getName()); + //QuestList listItem = questRewardMap.get(quest.getName()); - if (listItem.isCompleteWhenTasksComplete()) + quest.setCompleted(true); + + if (!task.isGrantQuestOnCompleteShowSystemMessage()) { completeQuest(player, quest); // Force complete packet sent if the quest isn't auto completed (window shows up, typical for exclusive reward items) - /*else - sendQuestCompleteWindow(quester, quest.getName());*/ + player.getContainer().getClient().getSession().write(player.getBaseline(8).createDelta(7)); + } else + sendQuestCompleteWindow(quester, quest.getCrc()); if (task.getGrantQuestOnComplete() != null && !task.getGrantQuestOnComplete().equals("")) activateQuest(quester, task.getGrantQuestOnComplete()); - + return; } @@ -318,9 +321,8 @@ public class QuestService implements INetworkDispatch { CreatureObject creo = (CreatureObject) player.getContainer(); - if (!quest.isCompleted()) { + if (!quest.isCompleted()) quest.setCompleted(true); - } QuestList info = getQuestList(quest.getName()); @@ -402,8 +404,9 @@ public class QuestService implements INetworkDispatch { } - public void sendQuestCompleteWindow(CreatureObject reciever, String questName) { - + public void sendQuestCompleteWindow(CreatureObject reciever, int questCrc) { + ObjControllerMessage objController = new ObjControllerMessage(0x0B, new ShowQuestCompletionWindow(reciever.getObjectID(), questCrc)); + reciever.getClient().getSession().write(objController.serialize()); } public String getQuestItemRadialName(CreatureObject quester, String template) { diff --git a/src/services/sui/SUIService.java b/src/services/sui/SUIService.java index 0165c5d1..9745276b 100644 --- a/src/services/sui/SUIService.java +++ b/src/services/sui/SUIService.java @@ -150,12 +150,17 @@ public class SUIService implements INetworkDispatch { return; } + if (target.getAttachment("conversationFile") != null) { + core.scriptService.callScript("scripts/radial/", "object/conversation", "createRadial", core, owner, target, request.getRadialOptions()); + sendRadial(owner, target, request.getRadialOptions(), request.getRadialCount()); + return; + } + core.scriptService.callScript("scripts/radial/", getRadialFilename(target), "createRadial", core, owner, target, request.getRadialOptions()); if(getRadialFilename(target).equals("default")) return; sendRadial(owner, target, request.getRadialOptions(), request.getRadialCount()); - } }); @@ -191,6 +196,10 @@ public class SUIService implements INetworkDispatch { return; } + if (target.getAttachment("conversationFile") != null) { + core.scriptService.callScript("scripts/radial/", "object/conversation", "handleSelection", core, owner, target, objMenuSelect.getSelection()); + return; + } core.scriptService.callScript("scripts/radial/", getRadialFilename(target), "handleSelection", core, owner, target, objMenuSelect.getSelection()); }