Добавить общую систему весовых объектов
This commit is contained in:
@@ -80,6 +80,9 @@ public final class CorpseManagerTest {
|
||||
assertFalse(body.crushed());
|
||||
assertFalse(body.activatesPressure());
|
||||
assertTrue(manager.bodies().contains(body));
|
||||
assertTrue(body instanceof IWeightedObject);
|
||||
assertEquals(1, body.pressureMass());
|
||||
assertEquals(body.x(), body.weightedX(), 0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -14,7 +15,7 @@ public final class LevelCatalogTest {
|
||||
@Test
|
||||
public void productionCatalogContainsHazardsAndTwoCorpseStateTeachingLevels() {
|
||||
List<LevelDefinition> levels = LevelCatalog.all();
|
||||
assertEquals(16, levels.size());
|
||||
assertEquals(17, levels.size());
|
||||
Set<String> titles = new HashSet<>();
|
||||
for (int i = 0; i < levels.size(); i++) {
|
||||
LevelDefinition level = levels.get(i);
|
||||
@@ -29,6 +30,16 @@ public final class LevelCatalogTest {
|
||||
assertTrue(levels.get(14).containsMechanic(LevelDefinition.HazardType.CRUSHER));
|
||||
assertTrue(levels.get(15).containsMechanic(LevelDefinition.HazardType.FIRE));
|
||||
assertFalse(levels.get(15).platforms.get(1).controlId.isEmpty());
|
||||
LevelDefinition weighted = levels.get(16);
|
||||
assertEquals(5, weighted.objects.size());
|
||||
Set<LevelDefinition.PhysicalObjectType> objectTypes = new HashSet<>();
|
||||
for (LevelDefinition.PhysicalObject object : weighted.objects) {
|
||||
objectTypes.add(object.type);
|
||||
}
|
||||
assertEquals(new HashSet<>(Arrays.asList(LevelDefinition.PhysicalObjectType.values())),
|
||||
objectTypes);
|
||||
assertEquals(9, weighted.switches.get(0).requiredMass);
|
||||
assertFalse(weighted.doors.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -214,6 +214,43 @@ public final class LevelJsonLoaderTest {
|
||||
assertEquals("explosion-blast", explosion.audioCue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allApprovedWeightedObjectTypesLoadThroughOneMassContract() {
|
||||
String objects = "\"objects\":["
|
||||
+ "{\"type\":\"BOX\",\"box\":{\"x\":300,\"y\":800,\"width\":80,\"height\":80},\"mass\":1},"
|
||||
+ "{\"type\":\"ROCK\",\"box\":{\"x\":400,\"y\":820,\"width\":60,\"height\":60},\"mass\":2},"
|
||||
+ "{\"type\":\"BALL\",\"box\":{\"x\":500,\"y\":820,\"width\":60,\"height\":60},\"mass\":1},"
|
||||
+ "{\"type\":\"ICE_BLOCK\",\"box\":{\"x\":600,\"y\":800,\"width\":80,\"height\":80},\"mass\":2},"
|
||||
+ "{\"type\":\"COUNTERWEIGHT\",\"box\":{\"x\":700,\"y\":780,\"width\":80,\"height\":100},\"mass\":3}],";
|
||||
String json = validLevelJson(1).replace("\"platforms\":", objects + "\"platforms\":");
|
||||
|
||||
LevelDefinition level = LevelJsonLoader.load(new StringReader(json), "weighted.json");
|
||||
|
||||
assertEquals(5, level.objects.size());
|
||||
assertEquals(LevelDefinition.PhysicalObjectType.BOX, level.objects.get(0).type);
|
||||
assertEquals(LevelDefinition.PhysicalObjectType.ROCK, level.objects.get(1).type);
|
||||
assertEquals(LevelDefinition.PhysicalObjectType.BALL, level.objects.get(2).type);
|
||||
assertEquals(LevelDefinition.PhysicalObjectType.ICE_BLOCK, level.objects.get(3).type);
|
||||
assertEquals(LevelDefinition.PhysicalObjectType.COUNTERWEIGHT, level.objects.get(4).type);
|
||||
assertEquals(3, level.objects.get(4).mass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void weightedObjectRejectsNonPositiveMassWithItsJsonPath() {
|
||||
String object = "\"objects\":[{\"type\":\"BOX\","
|
||||
+ "\"box\":{\"x\":300,\"y\":800,\"width\":80,\"height\":80},\"mass\":0}],";
|
||||
String json = validLevelJson(1).replace("\"platforms\":", object + "\"platforms\":");
|
||||
|
||||
try {
|
||||
LevelJsonLoader.load(new StringReader(json), "massless.json");
|
||||
fail("A pressure object with no mass must fail closed");
|
||||
} catch (IllegalArgumentException error) {
|
||||
assertTrue(error.getMessage(), error.getMessage().contains(
|
||||
"massless.json.objects[0].mass"));
|
||||
assertTrue(error.getMessage(), error.getMessage().contains("must be positive"));
|
||||
}
|
||||
}
|
||||
|
||||
static String validLevelJson(int formatVersion) {
|
||||
return "{"
|
||||
+ "\"formatVersion\":" + formatVersion + ","
|
||||
|
||||
@@ -8,8 +8,8 @@ import org.junit.Test;
|
||||
|
||||
public final class LevelPageTest {
|
||||
@Test
|
||||
public void sixteenLevelsUseTwoBoundedTenCardPages() {
|
||||
LevelPage page = new LevelPage(16, 10);
|
||||
public void seventeenLevelsUseTwoBoundedTenCardPages() {
|
||||
LevelPage page = new LevelPage(17, 10);
|
||||
|
||||
assertEquals(2, page.pageCount());
|
||||
assertEquals(0, page.firstIndex());
|
||||
@@ -19,7 +19,7 @@ public final class LevelPageTest {
|
||||
|
||||
page.next();
|
||||
assertEquals(10, page.firstIndex());
|
||||
assertEquals(16, page.endExclusive());
|
||||
assertEquals(17, page.endExclusive());
|
||||
assertTrue(page.hasPrevious());
|
||||
assertFalse(page.hasNext());
|
||||
|
||||
@@ -29,5 +29,7 @@ public final class LevelPageTest {
|
||||
assertEquals(0, page.pageIndex());
|
||||
page.selectIndex(15);
|
||||
assertEquals(1, page.pageIndex());
|
||||
page.selectIndex(16);
|
||||
assertEquals(1, page.pageIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.projectsacrifice.game;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public final class PhysicalObjectStateTest {
|
||||
@Test
|
||||
public void authoredObjectPublishesStableMassGeometryAndRuntimeState() {
|
||||
LevelDefinition.PhysicalObject definition = new LevelDefinition.PhysicalObject(
|
||||
LevelDefinition.PhysicalObjectType.COUNTERWEIGHT,
|
||||
new LevelDefinition.Box(420f, 760f, 80f, 120f), 3);
|
||||
|
||||
PhysicalObjectState state = new PhysicalObjectState(definition);
|
||||
state.velocity(120f, -30f).grounded(true).supportIndex(2);
|
||||
|
||||
assertEquals(LevelDefinition.PhysicalObjectType.COUNTERWEIGHT, state.type());
|
||||
assertEquals(420f, state.weightedX(), 0f);
|
||||
assertEquals(760f, state.weightedY(), 0f);
|
||||
assertEquals(80f, state.weightedWidth(), 0f);
|
||||
assertEquals(120f, state.weightedHeight(), 0f);
|
||||
assertEquals(3, state.pressureMass());
|
||||
assertTrue(state.activatesPressure());
|
||||
assertEquals(120f, state.velocityX(), 0f);
|
||||
assertEquals(-30f, state.velocityY(), 0f);
|
||||
assertTrue(state.grounded());
|
||||
assertEquals(2, state.supportIndex());
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,10 @@ public final class VersionedSessionCodecTest {
|
||||
assertTrue(restored.bodies().get(1).conductive());
|
||||
assertTrue(restored.bodies().get(0).crushed());
|
||||
assertTrue(restored.bodies().get(1).burned());
|
||||
assertEquals(2, restored.objects().size());
|
||||
assertEquals(LevelDefinition.PhysicalObjectType.BOX,
|
||||
restored.objects().get(0).type());
|
||||
assertEquals(3, restored.objects().get(1).mass());
|
||||
assertEquals(Arrays.asList(1.25f, 3.5f), restored.platformMotionTimes());
|
||||
assertTrue(restored.toggleSignals().get("gate"));
|
||||
assertEquals(2.25f, restored.timedSignals().get("clock"), 0f);
|
||||
@@ -58,6 +62,18 @@ public final class VersionedSessionCodecTest {
|
||||
assertTrue(decoded.snapshot().previousSwitchContacts().get("gate@420.0"));
|
||||
assertFalse(decoded.snapshot().bodies().get(0).crushed());
|
||||
assertFalse(decoded.snapshot().bodies().get(1).burned());
|
||||
assertTrue(decoded.snapshot().objects().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void legacyV3MigratesWithSafeEmptyPhysicalObjectRuntime() {
|
||||
VersionedSessionCodec.DecodeResult decoded = VersionedSessionCodec.decode(
|
||||
VersionedSessionCodec.encodeLegacyV3(sampleSnapshot()));
|
||||
|
||||
assertEquals(VersionedSessionCodec.Status.MIGRATED, decoded.status());
|
||||
assertTrue(decoded.snapshot().bodies().get(0).crushed());
|
||||
assertTrue(decoded.snapshot().bodies().get(1).burned());
|
||||
assertTrue(decoded.snapshot().objects().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -105,6 +121,12 @@ public final class VersionedSessionCodecTest {
|
||||
720f, 826f, 72f, 54f, 0f, 0f,
|
||||
false, true, true, true, false, true,
|
||||
-1, "FIRE"))
|
||||
.addObject(new GameSessionSnapshot.ObjectData(
|
||||
LevelDefinition.PhysicalObjectType.BOX,
|
||||
300f, 800f, 80f, 80f, 20f, 0f, 1, true, -1))
|
||||
.addObject(new GameSessionSnapshot.ObjectData(
|
||||
LevelDefinition.PhysicalObjectType.COUNTERWEIGHT,
|
||||
700f, 780f, 80f, 100f, 0f, 0f, 3, true, 1))
|
||||
.platformMotionTimes(Arrays.asList(1.25f, 3.5f))
|
||||
.toggleSignal("gate", true)
|
||||
.timedSignal("clock", 2.25f)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.projectsacrifice.game;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public final class WeightedPressureResolverTest {
|
||||
@Test
|
||||
public void plateUsesOneMassContractForPlayerCorpseAndPhysicalObject() {
|
||||
LevelDefinition.Box plate = new LevelDefinition.Box(100f, 200f, 180f, 20f);
|
||||
IWeightedObject player = item(110f, 150f, 62f, 100f, 1, true);
|
||||
IWeightedObject corpse = item(170f, 166f, 72f, 54f, 1, true);
|
||||
IWeightedObject counterweight = item(230f, 140f, 70f, 80f, 3, true);
|
||||
|
||||
assertFalse(PressureMassResolver.active(
|
||||
plate, 6, Arrays.asList(player, corpse, counterweight)));
|
||||
assertTrue(PressureMassResolver.active(
|
||||
plate, 5, Arrays.asList(player, corpse, counterweight)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inactiveAndNonIntersectingObjectsNeverContributeMass() {
|
||||
LevelDefinition.Box plate = new LevelDefinition.Box(100f, 200f, 180f, 20f);
|
||||
IWeightedObject burnedCorpse = item(120f, 166f, 72f, 54f, 5, false);
|
||||
IWeightedObject distantRock = item(500f, 160f, 60f, 60f, 5, true);
|
||||
|
||||
assertFalse(PressureMassResolver.active(
|
||||
plate, 1, Arrays.asList(burnedCorpse, distantRock)));
|
||||
}
|
||||
|
||||
private static IWeightedObject item(float x, float y, float width, float height,
|
||||
int mass, boolean active) {
|
||||
return new IWeightedObject() {
|
||||
@Override public float weightedX() { return x; }
|
||||
@Override public float weightedY() { return y; }
|
||||
@Override public float weightedWidth() { return width; }
|
||||
@Override public float weightedHeight() { return height; }
|
||||
@Override public int pressureMass() { return mass; }
|
||||
@Override public boolean activatesPressure() { return active; }
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user