diff --git a/src/main/java/com/projectswg/holocore/resources/gameplay/crafting/resource/galactic/storage/GalacticResourceContainer.kt b/src/main/java/com/projectswg/holocore/resources/gameplay/crafting/resource/galactic/storage/GalacticResourceContainer.kt index 2bf6a1465..45e7d7ccd 100644 --- a/src/main/java/com/projectswg/holocore/resources/gameplay/crafting/resource/galactic/storage/GalacticResourceContainer.kt +++ b/src/main/java/com/projectswg/holocore/resources/gameplay/crafting/resource/galactic/storage/GalacticResourceContainer.kt @@ -1,29 +1,29 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * - * * + * Copyright (c) 2023 /// Project SWG /// www.projectswg.com * + * * * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * * Our goal is to create an emulator which will provide a server for players to * * continue playing a game similar to the one they used to play. We are basing * * it on the final publish of the game prior to end-game events. * - * * + * * * This file is part of Holocore. * - * * + * * * --------------------------------------------------------------------------------* - * * + * * * Holocore is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * + * * * Holocore 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 Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * - * along with Holocore. If not, see //www.gnu.org/licenses/>. * - */ + * along with Holocore. If not, see . * + ***********************************************************************************/ package com.projectswg.holocore.resources.gameplay.crafting.resource.galactic.storage import com.projectswg.common.data.location.Terrain @@ -43,7 +43,14 @@ object GalacticResourceContainer { private val galacticResourceMap = ConcurrentHashMap() private val galacticResourcesByName = ConcurrentHashMap() private val rawToGalactic = ConcurrentHashMap>() - + + fun clear() { + rawResourceMap.clear() + galacticResourceMap.clear() + galacticResourcesByName.clear() + rawToGalactic.clear() + } + val allResources: List get() = galacticResourceMap.values.toList() diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/CreatureHarvestingService.kt b/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/CreatureHarvestingService.kt index 2d35a3c36..f13c16ca9 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/CreatureHarvestingService.kt +++ b/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/CreatureHarvestingService.kt @@ -28,6 +28,7 @@ package com.projectswg.holocore.services.gameplay.crafting.resource import com.projectswg.common.data.encodables.oob.ProsePackage import com.projectswg.common.data.encodables.oob.StringId +import com.projectswg.holocore.intents.gameplay.player.experience.ExperienceIntent import com.projectswg.holocore.intents.support.global.chat.SystemMessageIntent import com.projectswg.holocore.resources.gameplay.crafting.resource.galactic.GalacticResource import com.projectswg.holocore.resources.gameplay.crafting.resource.galactic.storage.GalacticResourceContainer.getRawResource @@ -110,6 +111,8 @@ class CreatureHarvestingService : Service() { } } ResourceContainerHelper.giveResourcesToPlayer(amount, spawnedResource, player, eventHandler) + val experienceGained = player.creatureObject.level * 2 + ExperienceIntent(player.creatureObject, "scout", experienceGained).broadcast() } private fun randomizeResourceAmount(resourceInfo: NpcResourceInfo, creatureQuality: CreatureQuality, player: Player): Int { diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/ResourceService.java b/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/ResourceService.java index 625ef8a7d..6f0050242 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/ResourceService.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/crafting/resource/ResourceService.java @@ -60,6 +60,7 @@ public class ResourceService extends Service { @Override public boolean terminate() { + GalacticResourceContainer.INSTANCE.clear(); spawnerUpdater.stop(); spawner.terminate(); return super.terminate(); diff --git a/src/test/java/com/projectswg/holocore/services/gameplay/crafting/resource/CreatureHarvestingTest.kt b/src/test/java/com/projectswg/holocore/services/gameplay/crafting/resource/CreatureHarvestingTest.kt new file mode 100644 index 000000000..bcfe907c6 --- /dev/null +++ b/src/test/java/com/projectswg/holocore/services/gameplay/crafting/resource/CreatureHarvestingTest.kt @@ -0,0 +1,130 @@ +/*********************************************************************************** + * Copyright (c) 2023 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create an emulator which will provide a server for players to * + * continue playing a game similar to the one they used to play. We are basing * + * it on the final publish of the game prior to end-game events. * + * * + * This file is part of Holocore. * + * * + * --------------------------------------------------------------------------------* + * * + * Holocore is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * Holocore 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with Holocore. If not, see . * + ***********************************************************************************/ +package com.projectswg.holocore.services.gameplay.crafting.resource + +import com.projectswg.common.data.location.Location +import com.projectswg.common.data.location.Terrain +import com.projectswg.holocore.intents.gameplay.combat.RequestCreatureDeathIntent +import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent +import com.projectswg.holocore.resources.support.global.player.Player +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.resources.support.objects.swg.weapon.DefaultWeaponFactory +import com.projectswg.holocore.services.gameplay.combat.CombatDeathblowService +import com.projectswg.holocore.services.gameplay.player.experience.ExperiencePointService +import com.projectswg.holocore.test.resources.GenericCreatureObject +import com.projectswg.holocore.test.runners.TestRunnerSynchronousIntents +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class CreatureHarvestingTest : TestRunnerSynchronousIntents() { + + @BeforeEach + fun setup() { + registerService(CombatDeathblowService()) + registerService(CreatureHarvestingService()) + registerService(ResourceService()) + registerService(ExperiencePointService()) + } + + @Test + fun `harvested resources are placed in the inventory of the player`() { + val player = createPlayer() + val previousInventorySize = inventorySize(player) + val bantha = createNpc("creature_bantha") + + broadcastAndWait(RequestCreatureDeathIntent(player.creatureObject, bantha)) + broadcastAndWait(HarvestHideIntent(player, bantha)) + + val nextInventorySize = inventorySize(player) + assertTrue(nextInventorySize > previousInventorySize, "Inventory contents should have increased") + } + + @Test + fun `you get Scouting XP by harvesting creatures`() { + val player = createPlayer() + val previousScoutXp = scoutXp(player) + val bantha = createNpc("creature_bantha") + + broadcastAndWait(RequestCreatureDeathIntent(player.creatureObject, bantha)) + broadcastAndWait(HarvestHideIntent(player, bantha)) + + val nextScoutXp = scoutXp(player) + assertTrue(nextScoutXp > previousScoutXp, "Scout XP should have increased") + } + + private fun inventorySize(player: Player): Int { + return player.creatureObject.inventory.childObjects.size + } + + private fun scoutXp(player: Player): Int { + return player.playerObject.experience.getOrElse("scout") { 0 } + } + + private fun createPlayer(): Player { + val creatureObject = GenericCreatureObject(ObjectCreator.getNextObjectId()) + val inFrontOfMosEisleyStarport = Location.builder() + .setTerrain(Terrain.TATOOINE) + .setX(-3521.0) + .setY(5.0) + .setZ(-4807.0) + .build() + creatureObject.location = inFrontOfMosEisleyStarport + ObjectCreatedIntent.broadcast(creatureObject) + val defaultWeapon = DefaultWeaponFactory.createDefaultWeapon() + defaultWeapon.moveToContainer(creatureObject) + creatureObject.equippedWeapon = defaultWeapon + return creatureObject.owner ?: throw RuntimeException("Unable to access player") + } + + private fun createNpc(npcId: String): AIObject { + val inFrontOfMosEisleyStarport = Location.builder() + .setTerrain(Terrain.TATOOINE) + .setX(-3521.0) + .setY(5.0) + .setZ(-4807.0) + .build() + + val egg = ObjectCreator.createObjectFromTemplate("object/tangible/ground_spawning/shared_patrol_spawner.iff") + egg.moveToContainer(null, inFrontOfMosEisleyStarport) + + val spawnInfo = SimpleSpawnInfo.builder() + .withNpcId(npcId) + .withDifficulty(CreatureDifficulty.ELITE) + .withMinLevel(19) + .withMaxLevel(19) + .withLocation(inFrontOfMosEisleyStarport) + .build() + + return NPCCreator.createAllNPCs(Spawner(spawnInfo, egg)).first() + } +} \ No newline at end of file