[API](https://github.com/SpongePowered/SpongeAPI/pull/1226) | **Common** | [Forg…e](https://github.com/SpongePowered/SpongeForge/pull/794)
This implements many of the missing parts to both `MobSpawnerData` and `Dungeon`.
Dungeons now have two possible ways of generating a spawner:
- `WeightedTable<EntityArchetype>`
- When left as default, will use the vanilla/forge list of entity names and their weights
- `MobSpawnerData`
Both the builder and the `Dungeon` object itself have setters for these - setting one disables the other. Setting the choices to null, as mentioned in the java docs, will cause the `Dungeon` to use the vanilla list.
Test code:
``` java
@Plugin(id = "test-plugin", name = "Test Plugin", version = "1.0.0")
public class TestPlugin {
@Inject
private Logger log;
@Inject
private PluginContainer container;
@Listener
public void onInit(LoadWorldEvent event) {
event.getTargetWorld()
.getWorldGenerator()
.getPopulators(Dungeon.class)
.stream()
.map(Dungeon.class::cast)
.filter(Objects::nonNull)
.forEach(dungeon -> {
WeightedTable<EntityArchetype> choices = new WeightedTable<>();
choices.add(EntityArchetype.of(EntityTypes.COW), 1);
choices.add(EntityArchetype.of(EntityTypes.ENDERMAN), 1);
dungeon.setChoices(choices);
// MobSpawnerData data = new SpongeMobSpawnerData(); // Lazy, but meh
// data.set(Keys.SPAWNER_NEXT_ENTITY_TO_SPAWN, new WeightedSerializableObject<>(EntityArchetype.of(EntityTypes.CHICKEN), 1));
// dungeon.setMobSpawnerData(data);
});
}
@Listener
public void onGameStartedServer(GameStartedServerEvent event) {
Sponge.getCommandManager().register(this, testKeysCommand(), "test-keys");
Sponge.getCommandManager().register(this, testDataCommand(), "test-data");
}
private CommandCallable testKeysCommand() {
return CommandSpec.builder()
.executor((src, args) -> {
Location<World> loc = getDefaultWorld().getLocation(0, 0, 0);
if ((src instanceof Locatable)) {
loc = ((Locatable) src).getLocation();
}
// Create infront of location
loc = loc.getBlockRelative(Direction.NORTH);
loc.setBlock(BlockTypes.MOB_SPAWNER.getDefaultState(), Cause.of(NamedCause.source(container)));
log.info("=== BEFORE ===");
dump(loc);
loc.offer(Keys.SPAWNER_REMAINING_DELAY, (short) 1000);
loc.offer(Keys.SPAWNER_MINIMUM_DELAY, (short) 200);
loc.offer(Keys.SPAWNER_MAXIMUM_DELAY, (short) 1000);
loc.offer(Keys.SPAWNER_SPAWN_COUNT, (short) 15);
loc.offer(Keys.SPAWNER_MAXIMUM_NEARBY_ENTITIES, (short) 1);
loc.offer(Keys.SPAWNER_REQUIRED_PLAYER_RANGE, (short) 50);
loc.offer(Keys.SPAWNER_SPAWN_RANGE, (short) 3);
loc.offer(Keys.SPAWNER_NEXT_ENTITY_TO_SPAWN, new WeightedSerializableObject<>(EntityArchetype.of(EntityTypes.SLIME), 1));
WeightedTable<EntityArchetype> table = new WeightedTable<>();
table.add(EntityArchetype.of(EntityTypes.BAT), 1);
loc.offer(Keys.SPAWNER_ENTITIES, table);
log.info("=== AFTER ===");
dump(loc);
return CommandResult.success();
})
.build();
}
private CommandCallable testDataCommand() {
return CommandSpec.builder()
.executor((src, args) -> {
Location<World> loc = getDefaultWorld().getLocation(0, 0, 1);
if ((src instanceof Locatable)) {
loc = ((Locatable) src).getLocation();
}
// Create infront of location
loc = loc.getBlockRelative(Direction.NORTH);
loc.setBlock(BlockTypes.MOB_SPAWNER.getDefaultState(), Cause.of(NamedCause.source(container)));
MobSpawnerData data = loc.getOrCreate(MobSpawnerData.class).get();
log.info("=== BEFORE ===");
dump(data);
data.set(Keys.SPAWNER_REMAINING_DELAY, (short) 1000);
data.set(Keys.SPAWNER_MINIMUM_DELAY, (short) 200);
data.set(Keys.SPAWNER_MAXIMUM_DELAY, (short) 1000);
data.set(Keys.SPAWNER_SPAWN_COUNT, (short) 15);
data.set(Keys.SPAWNER_MAXIMUM_NEARBY_ENTITIES, (short) 1);
data.set(Keys.SPAWNER_REQUIRED_PLAYER_RANGE, (short) 50);
data.set(Keys.SPAWNER_SPAWN_RANGE, (short) 3);
data.set(Keys.SPAWNER_NEXT_ENTITY_TO_SPAWN, new WeightedSerializableObject<>(EntityArchetype.of(EntityTypes.SLIME), 1));
WeightedTable<EntityArchetype> table = new WeightedTable<>();
table.add(EntityArchetype.of(EntityTypes.BAT), 1);
data.set(Keys.SPAWNER_ENTITIES, table);
log.info("=== AFTER ===");
log.info("result {}", loc.offer(data).isSuccessful());
dump(loc.get(MobSpawnerData.class).get());
return CommandResult.success();
})
.build();
}
private static World getDefaultWorld() {
// Lazy, but meh
return (World) SpongeImpl.getServer().getEntityWorld();
}
private void dump(ValueContainer<?> data) {
log.info("remaining {}", data.get(Keys.SPAWNER_REMAINING_DELAY).get());
log.info("min {}", data.get(Keys.SPAWNER_MINIMUM_DELAY).get());
log.info("max {}", data.get(Keys.SPAWNER_MAXIMUM_DELAY).get());
log.info("count {}", data.get(Keys.SPAWNER_SPAWN_COUNT).get());
log.info("nearby {}", data.get(Keys.SPAWNER_MAXIMUM_NEARBY_ENTITIES).get());
log.info("playerrange {}", data.get(Keys.SPAWNER_REQUIRED_PLAYER_RANGE).get());
log.info("range {}", data.get(Keys.SPAWNER_SPAWN_RANGE).get());
log.info("next {}", data.get(Keys.SPAWNER_NEXT_ENTITY_TO_SPAWN).get().toContainer().toString());
log.info("possible [{}]", Joiner.on(", ").join(data.get(Keys.SPAWNER_ENTITIES).get()));
}
}
```