diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/quest/QuestService.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/quest/QuestService.java index 730324eee..ccac90562 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/player/quest/QuestService.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/quest/QuestService.java @@ -35,6 +35,7 @@ import com.projectswg.common.network.packets.swg.zone.CommPlayerMessage; import com.projectswg.common.network.packets.swg.zone.PlayMusicMessage; import com.projectswg.common.network.packets.swg.zone.chat.ChatSystemMessage; import com.projectswg.common.network.packets.swg.zone.object_controller.quest.QuestCompletedMessage; +import com.projectswg.common.network.packets.swg.zone.object_controller.quest.QuestTaskCounterMessage; import com.projectswg.holocore.intents.gameplay.combat.CreatureKilledIntent; import com.projectswg.holocore.intents.gameplay.player.quest.AbandonQuestIntent; import com.projectswg.holocore.intents.gameplay.player.quest.AdvanceQuestIntent; @@ -197,12 +198,12 @@ public class QuestService extends Service { int max = activeTaskListInfo.getCount(); int counter = playerObject.incrementQuestCounter(questName); int remaining = max - counter; - + int task = activeTaskListInfo.getIndex(); StandardLog.onPlayerTrace(this, owner, "%d remaining kills required on quest %s", remaining, questName); + + incrementKillCount(questName, task, owner, counter, max); - if (remaining > 0) { - incrementKillCount(owner, remaining); - } else { + if (remaining <= 0) { advanceQuest(questName, owner, activeTaskListInfos); } } @@ -219,11 +220,11 @@ public class QuestService extends Service { return Objects.equals(targetServerTemplate, stfName); } - private void incrementKillCount(Player player, int remaining) { + private void incrementKillCount(String questName, int task, Player player, int counter, int max) { + player.sendPacket(new QuestTaskCounterMessage(player.getCreatureObject().getObjectId(), questName, task, "@quest/groundquests:destroy_counter", counter, max)); + int remaining = max - counter; ProsePackage prose = new ProsePackage(new StringId("quest/groundquests", "destroy_multiple_success"), "DI", remaining); SystemMessageIntent.broadcastPersonal(player, prose); - - player.sendPacket(new PlayMusicMessage(0, "sound/ui_npe2_quest_counter.snd", 1, false)); } private void handleTaskEvents(Player player, String questName, Collection currentTasks) { @@ -253,10 +254,21 @@ public class QuestService extends Service { handleShowMessageBox(player, questName, playerObject, currentTask); break; } + case "quest.task.ground.destroy_multi": { + handleDestroyMulti(player, questName, currentTask); + break; + } } } } + private static void handleDestroyMulti(Player player, String questName, QuestLoader.QuestTaskInfo currentTask) { + int task = currentTask.getIndex(); + int max = currentTask.getCount(); + int counter = 0; + player.sendPacket(new QuestTaskCounterMessage(player.getCreatureObject().getObjectId(), questName, task, "@quest/groundquests:destroy_counter", counter, max)); + } + private void handleShowMessageBox(Player player, String questName, PlayerObject playerObject, QuestLoader.QuestTaskInfo currentTask) { String messageBoxTitle = currentTask.getMessageBoxTitle(); String messageBoxText = currentTask.getMessageBoxText(); diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/world/weather/EnvironmentService.kt b/src/main/java/com/projectswg/holocore/services/gameplay/world/weather/EnvironmentService.kt index 48335eac5..86fbe1243 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/world/weather/EnvironmentService.kt +++ b/src/main/java/com/projectswg/holocore/services/gameplay/world/weather/EnvironmentService.kt @@ -84,7 +84,7 @@ class EnvironmentService : Service() { } private fun updateTime() { - NotifyPlayersPacketIntent(ServerTimeMessage(ProjectSWG.getGalacticTime())).broadcast() + NotifyPlayersPacketIntent(ServerTimeMessage(ProjectSWG.galacticTime)).broadcast() } private fun maybeUpdateWeather(terrain: Terrain) { diff --git a/src/test/java/com/projectswg/holocore/services/gameplay/player/quest/QuestTaskTypeTest.kt b/src/test/java/com/projectswg/holocore/services/gameplay/player/quest/QuestTaskTypeTest.kt index 42734055c..ef17686c8 100644 --- a/src/test/java/com/projectswg/holocore/services/gameplay/player/quest/QuestTaskTypeTest.kt +++ b/src/test/java/com/projectswg/holocore/services/gameplay/player/quest/QuestTaskTypeTest.kt @@ -26,18 +26,32 @@ ***********************************************************************************/ package com.projectswg.holocore.services.gameplay.player.quest +import com.projectswg.common.data.location.Location import com.projectswg.common.network.packets.swg.login.creation.ClientCreateCharacter import com.projectswg.common.network.packets.swg.zone.CommPlayerMessage +import com.projectswg.common.network.packets.swg.zone.object_controller.quest.QuestCompletedMessage +import com.projectswg.common.network.packets.swg.zone.object_controller.quest.QuestTaskCounterMessage import com.projectswg.common.network.packets.swg.zone.server_ui.SuiCreatePageMessage +import com.projectswg.holocore.intents.gameplay.combat.RequestCreatureDeathIntent import com.projectswg.holocore.intents.gameplay.player.quest.GrantQuestIntent import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader +import com.projectswg.holocore.resources.support.data.server_info.loader.npc.NpcStaticSpawnLoader import com.projectswg.holocore.resources.support.global.player.AccessLevel import com.projectswg.holocore.resources.support.global.zone.creation.CharacterCreation import com.projectswg.holocore.resources.support.global.zone.sui.SuiMessageBox +import com.projectswg.holocore.resources.support.npc.spawn.NPCCreator +import com.projectswg.holocore.resources.support.npc.spawn.SimpleSpawnInfo +import com.projectswg.holocore.resources.support.npc.spawn.Spawner +import com.projectswg.holocore.resources.support.objects.ObjectCreator +import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureDifficulty +import com.projectswg.holocore.resources.support.objects.swg.custom.AIObject +import com.projectswg.holocore.services.gameplay.combat.CombatDeathblowService +import com.projectswg.holocore.services.gameplay.player.experience.skills.SkillService import com.projectswg.holocore.services.support.global.zone.sui.SuiService import com.projectswg.holocore.test.resources.GenericPlayer import com.projectswg.holocore.test.runners.TestRunnerSynchronousIntents -import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test @@ -48,6 +62,8 @@ class QuestTaskTypeTest : TestRunnerSynchronousIntents() { fun setUp() { registerService(QuestService()) registerService(SuiService()) + registerService(SkillService()) + registerService(CombatDeathblowService()) } @Test @@ -55,7 +71,7 @@ class QuestTaskTypeTest : TestRunnerSynchronousIntents() { fun showMessageBox() { val player = createPlayer() - GrantQuestIntent.broadcast(player, "quest/c_newbie_start") // This quest immediately wants to display a SUI message box + GrantQuestIntent.broadcast(player, "quest/c_newbie_start") // This quest immediately wants to display a SUI message box val suiCreatePageMessage = player.waitForNextPacket(SuiCreatePageMessage::class.java) assertNotNull(suiCreatePageMessage) @@ -74,6 +90,42 @@ class QuestTaskTypeTest : TestRunnerSynchronousIntents() { assertEquals(CommPlayerMessage::class, commPlayerMessage!!::class) } + @Test + @DisplayName("quest.task.ground.destroy_multi") + fun destroyMulti() { + val player = createPlayer() + GrantQuestIntent.broadcast(player, "quest/test_destroy_multiple") + val declareRequiredKillCount = player.waitForNextPacket(QuestTaskCounterMessage::class.java) + assertNotNull(declareRequiredKillCount, "Failed to receive initial required kill count in time") + val womprats = spawnNPCs("creature_womprat", player.creatureObject.location, 3) + + womprats.forEach { womprat -> + RequestCreatureDeathIntent.broadcast(player.creatureObject, womprat) + val killCountUpdate = player.waitForNextPacket(QuestTaskCounterMessage::class.java) + assertNotNull(killCountUpdate, "Failed to receive kill count update in time") + } + + val questCompletedMessage = player.waitForNextPacket(QuestCompletedMessage::class.java) + assertNotNull(questCompletedMessage, "Failed to receive QuestCompletedMessage in time") + } + + private fun spawnNPCs(npcId: String, location: Location, amount: Int): Collection { + val egg = ObjectCreator.createObjectFromTemplate("object/tangible/ground_spawning/shared_patrol_spawner.iff") + egg.moveToContainer(null, location) + + val spawnInfo = SimpleSpawnInfo.builder() + .withNpcId(npcId) + .withDifficulty(CreatureDifficulty.NORMAL) + .withMinLevel(1) + .withMaxLevel(1) + .withLocation(location) + .withAmount(amount) + .withSpawnerFlag(NpcStaticSpawnLoader.SpawnerFlag.ATTACKABLE) + .build() + + return NPCCreator.createAllNPCs(Spawner(spawnInfo, egg)) + } + private fun createPlayer(): GenericPlayer { val player = GenericPlayer() val clientCreateCharacter = ClientCreateCharacter()