diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 11a1d3b21..44db46e54 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -605,6 +605,14 @@ public class CreatureObject extends TangibleObject { public long getStatesBitmask() { return statesBitmask; } + + public boolean isStatesBitmask(CreatureState ... states) { + for (CreatureState state : states) { + if ((statesBitmask & state.getBitmask()) == 0) + return false; + } + return true; + } public void setStatesBitmask(CreatureState ... states) { for (CreatureState state : states) diff --git a/src/services/objects/ObjectAwareness.java b/src/services/objects/ObjectAwareness.java index 70fc45faf..e2ff828d0 100644 --- a/src/services/objects/ObjectAwareness.java +++ b/src/services/objects/ObjectAwareness.java @@ -64,6 +64,7 @@ import resources.objects.awareness.AwarenessHandler; import resources.objects.awareness.DataTransformHandler; import resources.objects.awareness.TerrainMap.TerrainMapCallback; import resources.objects.creature.CreatureObject; +import resources.objects.creature.CreatureState; import resources.player.Player; import resources.player.PlayerEvent; import resources.player.PlayerState; @@ -304,6 +305,8 @@ public class ObjectAwareness extends Service implements TerrainMapCallback { } private void moveObjectWithTransform(SWGObject obj, SWGObject parent, Location requestedLocation, double speed, int update) { + if (obj instanceof CreatureObject && ((CreatureObject) obj).isStatesBitmask(CreatureState.RIDING_MOUNT)) + parent = obj.getParent(); moveObject(obj, parent, requestedLocation); if (parent == null) dataTransformHandler.handleMove(obj, speed, update); diff --git a/src/services/objects/ObjectCreator.java b/src/services/objects/ObjectCreator.java index fd5546732..29bf30aa8 100644 --- a/src/services/objects/ObjectCreator.java +++ b/src/services/objects/ObjectCreator.java @@ -154,6 +154,7 @@ public final class ObjectCreator { case GOTM_RESOURCE_CONTAINER: return new ResourceContainerObject(objectId); case GOTM_SHIP: return new ShipObject(objectId); case GOTM_WEAPON: return new WeaponObject(objectId); + case GOTM_VEHICLE: return new CreatureObject(objectId); case GOTM_ARMOR: case GOTM_CLOTHING: case GOTM_COMPONENT: @@ -163,8 +164,7 @@ public final class ObjectCreator { case GOTM_CHRONICLES: case GOTM_CYBERNETIC: case GOTM_TERMINAL: - case GOTM_POWERUP_WEAPON: - case GOTM_VEHICLE: return new TangibleObject(objectId); + case GOTM_POWERUP_WEAPON: return new TangibleObject(objectId); default: return null; } } diff --git a/test/resources/objects/awareness/TestObjectAwareness.java b/test/resources/objects/awareness/TestObjectAwareness.java index f72eca6c7..08e2cd748 100644 --- a/test/resources/objects/awareness/TestObjectAwareness.java +++ b/test/resources/objects/awareness/TestObjectAwareness.java @@ -37,14 +37,19 @@ import org.junit.runners.JUnit4; import com.projectswg.common.concurrency.Delay; import com.projectswg.common.control.Intent; import com.projectswg.common.control.IntentManager; +import com.projectswg.common.data.location.Location; import com.projectswg.common.data.location.Terrain; import intents.PlayerEventIntent; +import intents.object.ContainerTransferIntent; import intents.object.DestroyObjectIntent; +import intents.object.MoveObjectIntent; import intents.object.ObjectCreatedIntent; +import resources.Posture; import resources.objects.building.BuildingObject; import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; +import resources.objects.creature.CreatureState; import resources.player.PlayerEvent; import services.objects.ObjectAwareness; import services.objects.ObjectCreator; @@ -150,6 +155,52 @@ public class TestObjectAwareness { Assert.assertTrue(awareness.terminate()); } + @Test + public void testVehicleMount() { + CreatureObject vehicle = (CreatureObject) ObjectCreator.createObjectFromTemplate("object/mobile/vehicle/shared_barc_speeder.iff"); + player1.setPosition(Terrain.TATOOINE, 3500, 5, -4800); + player2.setPosition(Terrain.TATOOINE, 3510, 5, -4810); // 12ish meters away + vehicle.setPosition(Terrain.TATOOINE, 3500, 5, -4800); + + ObjectAwareness awareness = new ObjectAwareness(); + Assert.assertTrue(awareness.initialize()); + Assert.assertTrue(awareness.start()); + Assert.assertTrue(fireAndWait(100, new ObjectCreatedIntent(player1))); + Assert.assertTrue(fireAndWait(100, new ObjectCreatedIntent(player2))); + Assert.assertTrue(fireAndWait(100, new ObjectCreatedIntent(vehicle))); + + Assert.assertTrue("Player1 is not inside Player2's observer set!", player2.getObservers().contains(player1.getOwner())); + Assert.assertTrue("Player2 is not inside Player1's observer set!", player1.getObservers().contains(player2.getOwner())); + Assert.assertTrue("Vehicle is not inside Player1's awareness set!", player1.getObjectsAware().contains(vehicle)); + Assert.assertTrue("Vehicle is not inside Player2's awareness set!", player2.getObjectsAware().contains(vehicle)); + Assert.assertNull("Player1 is in a parent!", player1.getParent()); + + // Mount + player1.setStatesBitmask(CreatureState.RIDING_MOUNT); + vehicle.setStatesBitmask(CreatureState.MOUNTED_CREATURE); + vehicle.setPosture(Posture.DRIVING_VEHICLE); + Assert.assertTrue(fireAndWait(100, new ContainerTransferIntent(player1, vehicle))); + + Assert.assertTrue("Player1 is not inside Player2's observer set!", player2.getObservers().contains(player1.getOwner())); + Assert.assertTrue("Player2 is not inside Player1's observer set!", player1.getObservers().contains(player2.getOwner())); + Assert.assertFalse("Vehicle is still inside Player1's awareness set!", player1.getObjectsAware().contains(vehicle)); + Assert.assertTrue("Vehicle is not inside Player2's awareness set!", player2.getObjectsAware().contains(vehicle)); + Assert.assertNotNull("Player1 is not in a parent!", player1.getParent()); + Assert.assertEquals("Player1 is not mounted to the vehicle!", vehicle, player1.getParent()); + + Assert.assertTrue(fireAndWait(100, new MoveObjectIntent(player1, new Location(3510, 5, -4810, Terrain.TATOOINE), 7.3, 1))); + + Assert.assertTrue("Player1 is not inside Player2's observer set!", player2.getObservers().contains(player1.getOwner())); + Assert.assertTrue("Player2 is not inside Player1's observer set!", player1.getObservers().contains(player2.getOwner())); + Assert.assertFalse("Vehicle is inside Player1's awareness set!", player1.getObjectsAware().contains(vehicle)); + Assert.assertTrue("Vehicle is not inside Player2's awareness set!", player2.getObjectsAware().contains(vehicle)); + Assert.assertNotNull("Player1 is not in a parent!", player1.getParent()); + Assert.assertEquals("Player1 is not mounted to the vehicle!", vehicle, player1.getParent()); + + Assert.assertTrue(awareness.stop()); + Assert.assertTrue(awareness.terminate()); + } + private static boolean fireAndWait(long timeout, Intent intent) { intent.broadcast(); for (int i = 0; i < timeout; i++) {