From f6068438eb2675a3fbb5437d7bb7ef04334b58b0 Mon Sep 17 00:00:00 2001 From: Ziggy Date: Sun, 17 Jul 2022 20:11:35 +0200 Subject: [PATCH 1/3] Holocore-671 Previous learned and dropped ability can still be executed from toolbar Reduced test runtime by checking the command queue more often during certain tests --- .../zone/creation/CharacterCreation.java | 10 +-- .../global/commands/CommandQueueService.java | 18 ++++- .../creation/CharacterCreationService.java | 30 ++++---- .../commands/callbacks/EquipArmorTest.kt | 2 +- .../commands/callbacks/EquipClothingTest.kt | 2 +- .../commands/callbacks/EquipLightsaberTest.kt | 2 +- .../commands/callbacks/EquipWeaponTest.kt | 2 +- .../callbacks/LightsaberInventoryTest.kt | 2 +- .../services/gameplay/combat/AbilityTest.kt | 72 +++++++++++++++++++ .../gameplay/combat/AttackCostTest.kt | 35 +++++---- .../gameplay/combat/FactionPvpTest.kt | 8 ++- 11 files changed, 139 insertions(+), 44 deletions(-) create mode 100644 src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt diff --git a/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java b/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java index 94709d7ae..0006f16c9 100644 --- a/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java +++ b/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java @@ -47,7 +47,6 @@ import com.projectswg.holocore.resources.support.objects.swg.player.PlayerObject import com.projectswg.holocore.resources.support.objects.swg.tangible.TangibleObject; import com.projectswg.holocore.resources.support.objects.swg.weapon.DefaultWeaponFactory; import com.projectswg.holocore.resources.support.objects.swg.weapon.WeaponObject; -import com.projectswg.holocore.resources.support.objects.swg.weapon.WeaponType; import com.projectswg.holocore.services.support.objects.ObjectStorageService.BuildingLookup; import me.joshlarson.jlcommon.utilities.Arguments; import org.jetbrains.annotations.NotNull; @@ -61,12 +60,10 @@ public class CharacterCreation { private final Player player; private final ClientCreateCharacter create; - private final String biography; - public CharacterCreation(Player player, ClientCreateCharacter create, String biography) { + public CharacterCreation(Player player, ClientCreateCharacter create) { this.player = player; this.create = create; - this.biography = biography; } public CreatureObject createCharacter(AccessLevel accessLevel, ZoneInsertion info) { @@ -79,7 +76,7 @@ public class CharacterCreation { createHair(creatureObj, create.getHair(), create.getHairCustomization()); createStarterClothing(creatureObj, race, create.getClothes()); playerObj.setAdminTag(accessLevel); - playerObj.setBiography(biography); + playerObj.setBiography(create.getBiography()); ObjectCreatedIntent.broadcast(playerObj); ObjectCreatedIntent.broadcast(creatureObj); @@ -165,6 +162,9 @@ public class CharacterCreation { // new GrantSkillIntent(GrantSkillIntent.IntentType.GRANT, "crafting_artisan_novice", creatureObj, true).broadcast(); new GrantSkillIntent(GrantSkillIntent.IntentType.GRANT, "combat_brawler_novice", creatureObj, true).broadcast(); // new GrantSkillIntent(GrantSkillIntent.IntentType.GRANT, "combat_marksman_novice", creatureObj, true).broadcast(); + + // Everyone can Burst Run + creatureObj.addCommand("burstRun"); Collection languages = languagesSkillsForRace(creatureObj.getRace()); diff --git a/src/main/java/com/projectswg/holocore/services/support/global/commands/CommandQueueService.java b/src/main/java/com/projectswg/holocore/services/support/global/commands/CommandQueueService.java index 195da98d9..56f3217c1 100644 --- a/src/main/java/com/projectswg/holocore/services/support/global/commands/CommandQueueService.java +++ b/src/main/java/com/projectswg/holocore/services/support/global/commands/CommandQueueService.java @@ -38,23 +38,30 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; public class CommandQueueService extends Service { private final ScheduledThreadPool executor; private final Map combatQueueMap; private final CombatCommandHandler combatCommandHandler; + private final long delayBetweenCheckingCommandQueue; public CommandQueueService() { + this(100); + } + + public CommandQueueService(long delayBetweenCheckingCommandQueue) { this.executor = new ScheduledThreadPool(4, "command-queue-%d"); this.combatQueueMap = new ConcurrentHashMap<>(); this.combatCommandHandler = new CombatCommandHandler(); + this.delayBetweenCheckingCommandQueue = delayBetweenCheckingCommandQueue; } @Override public boolean initialize() { executor.start(); - executor.executeWithFixedRate(0, 100, this::executeQueuedCommands); + executor.executeWithFixedRate(0, delayBetweenCheckingCommandQueue, this::executeQueuedCommands); return true; } @@ -331,6 +338,15 @@ public class CommandQueueService extends Service { } if (rootCommand instanceof CombatCommand combatCommand) { + Collection sourceCommands = source.getCommands() + .stream() + .map(sourceCommand -> sourceCommand.toLowerCase(Locale.US)) + .collect(Collectors.toSet()); + + if (!sourceCommands.contains(rootCommand.getName())) { + return new CheckCommandResult(ErrorCode.ABILITY, 0); + } + if (combatCommand.getHitType() == HitType.HEAL && combatCommand.getAttackType() == AttackType.SINGLE_TARGET) { SWGObject target; switch (combatCommand.getTargetType()) { diff --git a/src/main/java/com/projectswg/holocore/services/support/global/zone/creation/CharacterCreationService.java b/src/main/java/com/projectswg/holocore/services/support/global/zone/creation/CharacterCreationService.java index 12b3d8c07..73dee921d 100644 --- a/src/main/java/com/projectswg/holocore/services/support/global/zone/creation/CharacterCreationService.java +++ b/src/main/java/com/projectswg/holocore/services/support/global/zone/creation/CharacterCreationService.java @@ -169,23 +169,17 @@ public class CharacterCreationService extends Service { } private void sendCharCreationFailure(Player player, ClientCreateCharacter create, ErrorMessage err, String actualReason) { - NameFailureReason reason = NameFailureReason.NAME_SYNTAX; - switch (err) { - case NAME_DECLINED_INTERNAL_ERROR: - case NAME_APPROVED: - reason = NameFailureReason.NAME_RETRY; - break; - case NAME_DECLINED_FICTIONALLY_INAPPROPRIATE: - reason = NameFailureReason.NAME_FICTIONALLY_INAPPRORIATE; - break; - case NAME_DECLINED_IN_USE: reason = NameFailureReason.NAME_IN_USE; break; - case NAME_DECLINED_EMPTY: reason = NameFailureReason.NAME_DECLINED_EMPTY; break; - case NAME_DECLINED_RESERVED: reason = NameFailureReason.NAME_DEV_RESERVED; break; - case NAME_DECLINED_TOO_FAST: reason = NameFailureReason.NAME_TOO_FAST; break; - case SERVER_CHARACTER_CREATION_MAX_CHARS: reason = NameFailureReason.TOO_MANY_CHARACTERS; break; - default: - break; - } + NameFailureReason reason = switch (err) { + case NAME_DECLINED_INTERNAL_ERROR, NAME_APPROVED -> NameFailureReason.NAME_RETRY; + case NAME_DECLINED_FICTIONALLY_INAPPROPRIATE -> NameFailureReason.NAME_FICTIONALLY_INAPPRORIATE; + case NAME_DECLINED_IN_USE -> NameFailureReason.NAME_IN_USE; + case NAME_DECLINED_EMPTY -> NameFailureReason.NAME_DECLINED_EMPTY; + case NAME_DECLINED_RESERVED -> NameFailureReason.NAME_DEV_RESERVED; + case NAME_DECLINED_TOO_FAST -> NameFailureReason.NAME_TOO_FAST; + case SERVER_CHARACTER_CREATION_MAX_CHARS -> NameFailureReason.TOO_MANY_CHARACTERS; + default -> NameFailureReason.NAME_SYNTAX; + }; + StandardLog.onPlayerError(this, player, "failed to create character '%s' with server error [%s] from %s", create.getName(), actualReason, create.getSocketAddress()); player.sendPacket(new CreateCharacterFailure(reason)); } @@ -225,7 +219,7 @@ public class CharacterCreationService extends Service { Log.e("Failed to get spawn information for location: " + spawnLocation); return null; } - CharacterCreation creation = new CharacterCreation(player, create, create.getBiography()); + CharacterCreation creation = new CharacterCreation(player, create); return creation.createCharacter(player.getAccessLevel(), info); } diff --git a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipArmorTest.kt b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipArmorTest.kt index d71403bcc..421397baf 100644 --- a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipArmorTest.kt +++ b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipArmorTest.kt @@ -24,7 +24,7 @@ class EquipArmorTest : TestRunnerSimulatedWorld() { @BeforeEach fun setUp() { - registerService(CommandQueueService()) + registerService(CommandQueueService(5)) registerService(CommandExecutionService()) registerService(SkillService()) } diff --git a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipClothingTest.kt b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipClothingTest.kt index 31dfbd12d..21dd9cbc0 100644 --- a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipClothingTest.kt +++ b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipClothingTest.kt @@ -22,7 +22,7 @@ class EquipClothingTest : TestRunnerSimulatedWorld() { @BeforeEach fun setUp() { - registerService(CommandQueueService()) + registerService(CommandQueueService(5)) registerService(CommandExecutionService()) } diff --git a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipLightsaberTest.kt b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipLightsaberTest.kt index 14fbd18fa..81873770f 100644 --- a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipLightsaberTest.kt +++ b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipLightsaberTest.kt @@ -29,7 +29,7 @@ class EquipLightsaberTest : TestRunnerSimulatedWorld() { @BeforeEach internal fun setUp() { - registerService(CommandQueueService()) + registerService(CommandQueueService(5)) registerService(CommandExecutionService()) registerService(SkillService()) registerService(LightsaberService()) diff --git a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipWeaponTest.kt b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipWeaponTest.kt index d367a53fa..ccf426254 100644 --- a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipWeaponTest.kt +++ b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/EquipWeaponTest.kt @@ -22,7 +22,7 @@ class EquipWeaponTest : TestRunnerSimulatedWorld() { @BeforeEach fun setUp() { - registerService(CommandQueueService()) + registerService(CommandQueueService(5)) registerService(CommandExecutionService()) } diff --git a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/LightsaberInventoryTest.kt b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/LightsaberInventoryTest.kt index 9ef5cd0e0..c1e0e3758 100644 --- a/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/LightsaberInventoryTest.kt +++ b/src/test/java/com/projectswg/holocore/resources/support/global/commands/callbacks/LightsaberInventoryTest.kt @@ -30,7 +30,7 @@ class LightsaberInventoryTest : TestRunnerSimulatedWorld() { @BeforeEach internal fun setUp() { - registerService(CommandQueueService()) + registerService(CommandQueueService(5)) registerService(CommandExecutionService()) registerService(SkillService()) registerService(LightsaberService()) diff --git a/src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt b/src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt new file mode 100644 index 000000000..b5eab7c44 --- /dev/null +++ b/src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt @@ -0,0 +1,72 @@ +package com.projectswg.holocore.services.gameplay.combat + +import com.projectswg.common.data.CRC +import com.projectswg.common.network.packets.swg.zone.object_controller.CommandQueueEnqueue +import com.projectswg.holocore.intents.gameplay.player.experience.skills.GrantSkillIntent +import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent +import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent +import com.projectswg.holocore.resources.support.objects.ObjectCreator +import com.projectswg.holocore.resources.support.objects.swg.weapon.DefaultWeaponFactory +import com.projectswg.holocore.services.gameplay.combat.buffs.BuffService +import com.projectswg.holocore.services.gameplay.player.experience.skills.SkillService +import com.projectswg.holocore.services.support.global.commands.CommandExecutionService +import com.projectswg.holocore.services.support.global.commands.CommandQueueService +import com.projectswg.holocore.test.resources.GenericCreatureObject +import com.projectswg.holocore.test.resources.GenericPlayer +import com.projectswg.holocore.test.runners.TestRunnerSimulatedWorld +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class AbilityTest : TestRunnerSimulatedWorld() { + + @BeforeEach + fun setup() { + registerService(BuffService()) + registerService(CommandQueueService(5)) + registerService(CommandExecutionService()) + registerService(SkillService()) + } + + @Test + fun `you can execute an ability when you have the skill that grants it`() { + val creatureObject = createCreatureObject() + val player = creatureObject.owner ?: throw RuntimeException("Unable to access player") + grantRequiredSkillForParryRiposte(creatureObject) + + parryRiposte(player) + + assertTrue(creatureObject.hasBuff("parryRiposte")) + } + + @Test + fun `you cannot execute an ability when you are missing the skill that grants it`() { + val creatureObject = createCreatureObject() + val player = creatureObject.owner ?: throw RuntimeException("Unable to access player") + + parryRiposte(player) + + assertFalse(creatureObject.hasBuff("parryRiposte")) + } + + private fun grantRequiredSkillForParryRiposte(creatureObject: GenericCreatureObject) { + GrantSkillIntent.broadcast(GrantSkillIntent.IntentType.GRANT, "combat_brawler_master", creatureObject, true) + waitForIntents() + } + + private fun parryRiposte(player: GenericPlayer) { + val crc = CRC.getCrc("parryriposte") + + broadcastAndWait(InboundPacketIntent(player, CommandQueueEnqueue(player.creatureObject.objectId, 0, crc, 0, ""))) + Thread.sleep(10) // Give the command queue a chance to be processed + } + + private fun createCreatureObject(): GenericCreatureObject { + val creatureObject = GenericCreatureObject(ObjectCreator.getNextObjectId()) + ObjectCreatedIntent.broadcast(creatureObject) + val defaultWeapon = DefaultWeaponFactory.createDefaultWeapon() + defaultWeapon.moveToContainer(creatureObject) + creatureObject.equippedWeapon = defaultWeapon + return creatureObject + } +} \ No newline at end of file diff --git a/src/test/java/com/projectswg/holocore/services/gameplay/combat/AttackCostTest.kt b/src/test/java/com/projectswg/holocore/services/gameplay/combat/AttackCostTest.kt index 50b74b23f..6084c4a9c 100644 --- a/src/test/java/com/projectswg/holocore/services/gameplay/combat/AttackCostTest.kt +++ b/src/test/java/com/projectswg/holocore/services/gameplay/combat/AttackCostTest.kt @@ -1,15 +1,17 @@ package com.projectswg.holocore.services.gameplay.combat import com.projectswg.common.data.CRC +import com.projectswg.common.network.packets.swg.login.creation.ClientCreateCharacter import com.projectswg.common.network.packets.swg.zone.object_controller.CommandQueueEnqueue import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent -import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent -import com.projectswg.holocore.resources.support.objects.ObjectCreator -import com.projectswg.holocore.resources.support.objects.swg.weapon.DefaultWeaponFactory import com.projectswg.holocore.services.gameplay.combat.buffs.BuffService +import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader +import com.projectswg.holocore.resources.support.global.player.AccessLevel +import com.projectswg.holocore.resources.support.global.player.Player +import com.projectswg.holocore.resources.support.global.zone.creation.CharacterCreation +import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject import com.projectswg.holocore.services.support.global.commands.CommandExecutionService import com.projectswg.holocore.services.support.global.commands.CommandQueueService -import com.projectswg.holocore.test.resources.GenericCreatureObject import com.projectswg.holocore.test.resources.GenericPlayer import com.projectswg.holocore.test.runners.TestRunnerSimulatedWorld import org.junit.jupiter.api.Assertions.assertFalse @@ -22,7 +24,7 @@ class AttackCostTest : TestRunnerSimulatedWorld() { @BeforeEach fun setup() { registerService(BuffService()) - registerService(CommandQueueService()) + registerService(CommandQueueService(5)) registerService(CommandExecutionService()) registerService(CombatStatusService()) } @@ -90,19 +92,26 @@ class AttackCostTest : TestRunnerSimulatedWorld() { assertFalse(creatureObject.hasBuff("burstRun")) } - private fun burstRun(player: GenericPlayer) { + private fun burstRun(player: Player) { val crc = CRC.getCrc("burstrun") broadcastAndWait(InboundPacketIntent(player, CommandQueueEnqueue(player.creatureObject.objectId, 0, crc, 0, ""))) - Thread.sleep(150) // Give the command queue a chance to be processed + Thread.sleep(10) // Give the command queue a chance to be processed } - private fun createCreatureObject(): GenericCreatureObject { - val creatureObject = GenericCreatureObject(ObjectCreator.getNextObjectId()) - ObjectCreatedIntent.broadcast(creatureObject) - val defaultWeapon = DefaultWeaponFactory.createDefaultWeapon() - defaultWeapon.moveToContainer(creatureObject) - creatureObject.equippedWeapon = defaultWeapon + private fun createCreatureObject(): CreatureObject { + val player = GenericPlayer() + val clientCreateCharacter = ClientCreateCharacter() + clientCreateCharacter.biography = "" + clientCreateCharacter.clothes = "combat_brawler" + clientCreateCharacter.race = "object/creature/player/shared_human_male.iff" + clientCreateCharacter.name = "Testing Character" + val characterCreation = CharacterCreation(player, clientCreateCharacter) + + val mosEisley = DataLoader.zoneInsertions().getInsertion("tat_moseisley") + val creatureObject = characterCreation.createCharacter(AccessLevel.PLAYER, mosEisley) + creatureObject.owner = player + return creatureObject } diff --git a/src/test/java/com/projectswg/holocore/services/gameplay/combat/FactionPvpTest.kt b/src/test/java/com/projectswg/holocore/services/gameplay/combat/FactionPvpTest.kt index 9a247596c..24e9ee7e0 100644 --- a/src/test/java/com/projectswg/holocore/services/gameplay/combat/FactionPvpTest.kt +++ b/src/test/java/com/projectswg/holocore/services/gameplay/combat/FactionPvpTest.kt @@ -4,6 +4,7 @@ import com.projectswg.common.data.CRC import com.projectswg.common.data.encodables.tangible.PvpStatus import com.projectswg.common.network.packets.swg.zone.object_controller.CommandQueueEnqueue import com.projectswg.holocore.intents.gameplay.gcw.faction.FactionIntent +import com.projectswg.holocore.intents.gameplay.player.experience.skills.GrantSkillIntent import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent import com.projectswg.holocore.resources.support.data.server_info.loader.ServerData @@ -12,6 +13,7 @@ import com.projectswg.holocore.resources.support.objects.ObjectCreator import com.projectswg.holocore.resources.support.objects.swg.SWGObject import com.projectswg.holocore.resources.support.objects.swg.weapon.DefaultWeaponFactory import com.projectswg.holocore.services.gameplay.faction.FactionFlagService +import com.projectswg.holocore.services.gameplay.player.experience.skills.SkillService import com.projectswg.holocore.services.support.global.commands.CommandExecutionService import com.projectswg.holocore.services.support.global.commands.CommandQueueService import com.projectswg.holocore.test.resources.GenericCreatureObject @@ -25,7 +27,8 @@ class FactionPvpTest : TestRunnerSimulatedWorld() { @BeforeEach fun setup() { - registerService(CommandQueueService()) + registerService(SkillService()) + registerService(CommandQueueService(5)) registerService(CommandExecutionService()) registerService(FactionFlagService()) registerService(CombatStatusService()) @@ -66,11 +69,12 @@ class FactionPvpTest : TestRunnerSimulatedWorld() { val targetObjectId = target.objectId broadcastAndWait(InboundPacketIntent(player, CommandQueueEnqueue(player.creatureObject.objectId, 0, crc, targetObjectId, ""))) - Thread.sleep(150) // Give the command queue a chance to be processed + Thread.sleep(10) // Give the command queue a chance to be processed } private fun createCreatureObject(): GenericCreatureObject { val creatureObject = GenericCreatureObject(ObjectCreator.getNextObjectId()) + GrantSkillIntent.broadcast(GrantSkillIntent.IntentType.GRANT, "species_human", creatureObject, true) ObjectCreatedIntent.broadcast(creatureObject) val defaultWeapon = DefaultWeaponFactory.createDefaultWeapon() defaultWeapon.moveToContainer(creatureObject) From b60780cfe953187d84ae7ca22da2cf89d237c457 Mon Sep 17 00:00:00 2001 From: Ziggy Date: Mon, 18 Jul 2022 19:37:11 +0200 Subject: [PATCH 2/3] Our other commands are lowercased, so let's lowercase this one as well --- .../support/global/zone/creation/CharacterCreation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java b/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java index 0006f16c9..6739006ba 100644 --- a/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java +++ b/src/main/java/com/projectswg/holocore/resources/support/global/zone/creation/CharacterCreation.java @@ -164,7 +164,7 @@ public class CharacterCreation { // new GrantSkillIntent(GrantSkillIntent.IntentType.GRANT, "combat_marksman_novice", creatureObj, true).broadcast(); // Everyone can Burst Run - creatureObj.addCommand("burstRun"); + creatureObj.addCommand("burstrun"); Collection languages = languagesSkillsForRace(creatureObj.getRace()); From 72d90e14eb557ab2f106cb2afeb6fef14f623cc8 Mon Sep 17 00:00:00 2001 From: Ziggy Date: Wed, 20 Jul 2022 18:37:46 +0200 Subject: [PATCH 3/3] Attempt at fixing flakiness of tests in AbilityTest --- .../services/gameplay/combat/AbilityTest.kt | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt b/src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt index b5eab7c44..7f27135be 100644 --- a/src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt +++ b/src/test/java/com/projectswg/holocore/services/gameplay/combat/AbilityTest.kt @@ -2,12 +2,13 @@ package com.projectswg.holocore.services.gameplay.combat import com.projectswg.common.data.CRC import com.projectswg.common.network.packets.swg.zone.object_controller.CommandQueueEnqueue +import com.projectswg.common.network.packets.swg.zone.object_controller.CommandTimer import com.projectswg.holocore.intents.gameplay.player.experience.skills.GrantSkillIntent import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent +import com.projectswg.holocore.intents.support.global.network.OutboundPacketIntent import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent import com.projectswg.holocore.resources.support.objects.ObjectCreator import com.projectswg.holocore.resources.support.objects.swg.weapon.DefaultWeaponFactory -import com.projectswg.holocore.services.gameplay.combat.buffs.BuffService import com.projectswg.holocore.services.gameplay.player.experience.skills.SkillService import com.projectswg.holocore.services.support.global.commands.CommandExecutionService import com.projectswg.holocore.services.support.global.commands.CommandQueueService @@ -22,21 +23,20 @@ class AbilityTest : TestRunnerSimulatedWorld() { @BeforeEach fun setup() { - registerService(BuffService()) registerService(CommandQueueService(5)) registerService(CommandExecutionService()) registerService(SkillService()) } - + @Test fun `you can execute an ability when you have the skill that grants it`() { val creatureObject = createCreatureObject() val player = creatureObject.owner ?: throw RuntimeException("Unable to access player") grantRequiredSkillForParryRiposte(creatureObject) - parryRiposte(player) - - assertTrue(creatureObject.hasBuff("parryRiposte")) + val success = parryRiposte(player) + + assertTrue(success) } @Test @@ -44,9 +44,9 @@ class AbilityTest : TestRunnerSimulatedWorld() { val creatureObject = createCreatureObject() val player = creatureObject.owner ?: throw RuntimeException("Unable to access player") - parryRiposte(player) + val success = parryRiposte(player) - assertFalse(creatureObject.hasBuff("parryRiposte")) + assertFalse(success) } private fun grantRequiredSkillForParryRiposte(creatureObject: GenericCreatureObject) { @@ -54,11 +54,17 @@ class AbilityTest : TestRunnerSimulatedWorld() { waitForIntents() } - private fun parryRiposte(player: GenericPlayer) { + private fun parryRiposte(player: GenericPlayer): Boolean { val crc = CRC.getCrc("parryriposte") + InboundPacketIntent.broadcast(player, CommandQueueEnqueue(player.creatureObject.objectId, 0, crc, 0, "")) - broadcastAndWait(InboundPacketIntent(player, CommandQueueEnqueue(player.creatureObject.objectId, 0, crc, 0, ""))) - Thread.sleep(10) // Give the command queue a chance to be processed + val commandTimer = player.waitForNextPacket(CommandTimer::class.java) + + if (commandTimer != null) { + return commandTimer.flags.contains(CommandTimer.CommandTimerFlag.EXECUTE) + } else { + throw RuntimeException("No CommandTimer packet was sent at all") + } } private fun createCreatureObject(): GenericCreatureObject {