diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/Combinations.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/Combinations.java index d34108a..01f5ed1 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/Combinations.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/Combinations.java @@ -47,7 +47,9 @@ public final class Combinations { } } Effects.applyAll(c.effects(), ctx); - ctx.getIo().write(c.response()); + if (c.response() != null && !c.response().isBlank()) { + ctx.getIo().write(c.response()); + } } private static boolean present(GameContext ctx, String id) { diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/loader/CombinationFactory.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/loader/CombinationFactory.java index 81234b4..296b4bd 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/loader/CombinationFactory.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/loader/CombinationFactory.java @@ -18,6 +18,10 @@ public final class CombinationFactory { public static Combination fromDto(CombinationDto dto, Map items) { requireItem(items, dto.a(), "a"); requireItem(items, dto.b(), "b"); + if (dto.a().equals(dto.b())) { + throw new WorldLoadException( + "Combination cannot combine an item with itself: '" + dto.a() + "'"); + } if (dto.consume() != null) { for (String id : dto.consume()) { requireItem(items, id, "consume"); diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/CombinationsTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/CombinationsTest.java index 16fb1e6..910446e 100644 --- a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/CombinationsTest.java +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/CombinationsTest.java @@ -123,6 +123,20 @@ class CombinationsTest { assertThat(ctx.getPlayer().hasItem("matches")).isTrue(); // not consumed } + @Test + void effectsOnlyRecipeAppliesEffectsWithoutProduceOrResponse() { + Combination effectsOnly = new Combination("matches", "shovel", + java.util.List.of(), java.util.List.of(), null, + java.util.List.of(new Effect(Effect.Type.SET_FLAG, "rite_done")), + null, null); + GameContext ctx = ctx(effectsOnly); + give(ctx, "matches"); + give(ctx, "shovel"); + Combinations.tryUse(ctx, "matches", "shovel"); + assertThat(ctx.getState().isSet("rite_done")).isTrue(); + assertThat(out(ctx)).doesNotContain("null"); + } + @Test void metRequiresAppliesEffectsAndProduces() { Combination gated = new Combination("matches", "torch", diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/loader/CombinationFactoryTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/loader/CombinationFactoryTest.java index 61cd55c..afa1723 100644 --- a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/loader/CombinationFactoryTest.java +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/loader/CombinationFactoryTest.java @@ -58,4 +58,12 @@ class CombinationFactoryTest { .isInstanceOf(WorldLoadException.class) .hasMessageContaining("wraith"); } + + @Test + void rejectsSelfCombination() { + CombinationDto dto = new CombinationDto("torch", "torch", null, null, null, null, "x", null); + assertThatThrownBy(() -> CombinationFactory.fromDto(dto, items())) + .isInstanceOf(WorldLoadException.class) + .hasMessageContaining("itself"); + } }