feat: switchable items apply effects when turned on

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 21:59:46 +02:00
parent 258ab4f63b
commit 00bad46661
4 changed files with 49 additions and 1 deletions

View File

@@ -44,6 +44,7 @@ public final class ItemFactory {
.state(Boolean.TRUE.equals(dto.initialState()))
.onText(dto.onText())
.offText(dto.offText())
.effects(thb.jeanluc.adventure.loader.dto.EffectDto.toModelList(dto.effects()))
.build();
default -> throw new WorldLoadException(
"Unknown item type '" + dto.type() + "' on item '" + dto.id() + "'");

View File

@@ -1,5 +1,7 @@
package thb.jeanluc.adventure.loader.dto;
import java.util.List;
/**
* YAML representation of a single item. Fields outside of the type's
* scope (e.g. {@code readText} on a switchable) are simply ignored.
@@ -12,6 +14,7 @@ package thb.jeanluc.adventure.loader.dto;
* @param initialState initial on/off state of a switchable item
* @param onText message printed when a switchable transitions to on
* @param offText message printed when a switchable transitions to off
* @param effects effects applied when a switchable transitions to on; nullable
*/
public record ItemDto(
String type,
@@ -21,6 +24,12 @@ public record ItemDto(
String readText,
Boolean initialState,
String onText,
String offText
String offText,
List<EffectDto> effects
) {
/** Backward-compatible constructor without effects. */
public ItemDto(String type, String id, String name, String description,
String readText, Boolean initialState, String onText, String offText) {
this(type, id, name, description, readText, initialState, onText, offText, null);
}
}

View File

@@ -2,7 +2,11 @@ package thb.jeanluc.adventure.model.item;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
import thb.jeanluc.adventure.game.Effects;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.model.Effect;
import java.util.List;
/**
* Item with two boolean states (on / off). Each {@code use} toggles the
@@ -24,6 +28,9 @@ public class SwitchableItem extends Item {
*/
private boolean state;
/** Effects applied when this item transitions to on; null = none. */
private final List<Effect> effects;
/**
* Toggles the state and writes the corresponding transition text.
*
@@ -33,6 +40,9 @@ public class SwitchableItem extends Item {
public void use(GameContext ctx) {
state = !state;
ctx.getIo().write(state ? onText : offText);
if (state) {
Effects.applyAll(effects, ctx);
}
}
/**

View File

@@ -0,0 +1,28 @@
package thb.jeanluc.adventure.model.item;
import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.io.TestIO;
import thb.jeanluc.adventure.model.Effect;
import thb.jeanluc.adventure.model.Player;
import thb.jeanluc.adventure.model.Room;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class SwitchEffectsTest {
@Test
void switchingOnAppliesEffects() {
SwitchableItem breaker = SwitchableItem.builder()
.id("breaker").name("Breaker").description("d")
.state(false).onText("hums to life").offText("off")
.effects(List.of(new Effect(Effect.Type.SET_FLAG, "power_on")))
.build();
Player player = new Player(new Room("k", "K", "d"), 0);
GameContext ctx = new GameContext(null, player, new TestIO());
breaker.use(ctx);
assertThat(ctx.getState().isSet("power_on")).isTrue();
}
}