Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,40 +1,27 @@
package com.wanderersoftherift.wotr.block.blockentity.anomaly;

import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.wanderersoftherift.wotr.block.blockentity.AnomalyBlockEntity;
import com.wanderersoftherift.wotr.entity.mob.RiftMobVariantData;
import com.wanderersoftherift.wotr.entity.mob.RiftZombie;
import com.wanderersoftherift.wotr.init.WotrAttachments;
import com.wanderersoftherift.wotr.init.WotrRegistries;
import com.wanderersoftherift.wotr.spawning.SpawnType;
import com.wanderersoftherift.wotr.util.FastWeightedList;
import com.wanderersoftherift.wotr.util.RandomFactoryType;
import com.wanderersoftherift.wotr.util.RandomSourceFromJavaRandom;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.util.valueproviders.IntProvider;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.event.EventHooks;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Function;

public record BattleTask(SpawnData spawnData) implements AnomalyTask<BattleTaskState> {
public static final AnomalyTaskType<BattleTaskState> TYPE = new AnomalyTaskType<>(
Expand All @@ -60,17 +47,12 @@ public InteractionResult interact(

for (int i = 0; i < count; i++) {
var type = spawnData.types.random(randomSource);
var mob = type.entityType().value().create(serverLevel, EntitySpawnReason.SPAWNER);
var mob = type.createSpawn(serverLevel, anomalyBlockEntity, randomSource);
if (mob == null) {
continue;
}
mob.moveTo(anomalyBlockEntity.getBlockPos().above(), 0, 0);

if (mob instanceof Mob mob2) {
type.spawnFunctions.forEach(it -> it.applyToMob(mob2, anomalyBlockEntity, randomSource));
}
serverLevel.addFreshEntityWithPassengers(mob);
mobUUIDs.add(mob.getUUID());
mob.getPassengersAndSelf().map(Entity::getUUID).forEach(mobUUIDs::add);
}

anomalyBlockEntity.updateTask(new BattleTaskState(mobUUIDs, Optional.of(player.getUUID())));
Expand Down Expand Up @@ -134,81 +116,6 @@ public int scheduledTick(ServerLevel serverLevel, AnomalyBlockEntity anomalyBloc
return 1;
}

// todo move everything below elsewhere
public interface SpawnFunction {
Codec<SpawnFunction> CODEC = WotrRegistries.SPAWN_FUNCTION_TYPES.byNameCodec()
.dispatch(SpawnFunction::codec, Function.identity());

MapCodec<? extends SpawnFunction> codec();

void applyToMob(Mob mob, BlockEntity spawner, RandomSource random);
}

public record ApplyMobVariant(Holder<RiftMobVariantData> variant) implements SpawnFunction {
public static final MapCodec<ApplyMobVariant> MAP_CODEC = RiftMobVariantData.VARIANT_HOLDER_CODEC
.fieldOf("variant")
.xmap(ApplyMobVariant::new, ApplyMobVariant::variant);

@Override
public MapCodec<? extends SpawnFunction> codec() {
return MAP_CODEC;
}

@Override
public void applyToMob(Mob mob, BlockEntity spawner, RandomSource random) {
if (mob instanceof RiftZombie zombie) {
zombie.setVariant(variant);
}
}
}

public record AddDeathNotifier() implements SpawnFunction {
public static final AddDeathNotifier INSTANCE = new AddDeathNotifier();
public static final MapCodec<AddDeathNotifier> MAP_CODEC = MapCodec.unit(INSTANCE);

@Override
public MapCodec<? extends SpawnFunction> codec() {
return MAP_CODEC;
}

@Override
public void applyToMob(Mob mob, BlockEntity spawner, RandomSource random) {
mob.setData(WotrAttachments.DEATH_NOTIFICATION, new DeathNotifierAttachment(spawner.getBlockPos()));
}
}

public record FinalizeSpawn() implements SpawnFunction {
public static final FinalizeSpawn INSTANCE = new FinalizeSpawn();
public static final MapCodec<FinalizeSpawn> MAP_CODEC = MapCodec.unit(INSTANCE);

@Override
public MapCodec<? extends SpawnFunction> codec() {
return MAP_CODEC;
}

@Override
public void applyToMob(Mob mob, BlockEntity spawner, RandomSource random) {
if (!(spawner.getLevel() instanceof ServerLevel serverLevel)) {
return;
}
EventHooks.finalizeMobSpawn(mob, serverLevel, serverLevel.getCurrentDifficultyAt(mob.blockPosition()),
EntitySpawnReason.SPAWNER, null);
}
}

public record SpawnType(Holder<EntityType<?>> entityType, List<SpawnFunction> spawnFunctions) {
public static final Codec<SpawnType> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
BuiltInRegistries.ENTITY_TYPE.holderByNameCodec()
.fieldOf("entity_type")
.forGetter(SpawnType::entityType),
SpawnFunction.CODEC.listOf()
.optionalFieldOf("spawn_functions", Collections.emptyList())
.forGetter(SpawnType::spawnFunctions)
).apply(instance, SpawnType::new)
);
}

public record SpawnData(FastWeightedList<SpawnType> types, IntProvider count) {
public static final Codec<SpawnData> CODEC = RecordCodecBuilder.create(instance -> instance.group(
FastWeightedList.listCodec(SpawnType.CODEC).fieldOf("mobs").forGetter(SpawnData::types),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import com.wanderersoftherift.wotr.abilities.upgrade.AbilityUpgrade;
import com.wanderersoftherift.wotr.block.blockentity.anomaly.AnomalyReward;
import com.wanderersoftherift.wotr.block.blockentity.anomaly.AnomalyTask;
import com.wanderersoftherift.wotr.block.blockentity.anomaly.BattleTask;
import com.wanderersoftherift.wotr.core.goal.Goal;
import com.wanderersoftherift.wotr.core.goal.GoalProvider;
import com.wanderersoftherift.wotr.core.guild.Guild;
Expand All @@ -41,6 +40,7 @@
import com.wanderersoftherift.wotr.modifier.effect.ModifierEffect;
import com.wanderersoftherift.wotr.modifier.source.ModifierSource;
import com.wanderersoftherift.wotr.serialization.DualCodec;
import com.wanderersoftherift.wotr.spawning.functions.SpawnFunction;
import com.wanderersoftherift.wotr.util.listedit.EditType;
import com.wanderersoftherift.wotr.world.level.levelgen.RiftPostProcessingStep;
import com.wanderersoftherift.wotr.world.level.levelgen.jigsaw.JigsawListProcessor;
Expand Down Expand Up @@ -136,7 +136,7 @@ public class WotrRegistries {
Keys.TARGET_AREA_SHAPES).create();
public static final Registry<AnomalyTask.AnomalyTaskType<?>> ANOMALY_TASK_TYPE = new RegistryBuilder<>(
Keys.ANOMALY_TASK_TYPE).sync(true).create();
public static final Registry<MapCodec<? extends BattleTask.SpawnFunction>> SPAWN_FUNCTION_TYPES = new RegistryBuilder<>(
public static final Registry<MapCodec<? extends SpawnFunction>> SPAWN_FUNCTION_TYPES = new RegistryBuilder<>(
Keys.SPAWN_FUNCTION_TYPES).sync(true).create();

public static final class Keys {
Expand Down Expand Up @@ -250,8 +250,11 @@ public static final class Keys {
// Mobs
public static final ResourceKey<Registry<MapCodec<? extends NpcInteraction>>> MOB_INTERACTIONS = ResourceKey
.createRegistryKey(WanderersOfTheRift.id("mob_interactions"));
public static final ResourceKey<Registry<MapCodec<? extends BattleTask.SpawnFunction>>> SPAWN_FUNCTION_TYPES = ResourceKey
public static final ResourceKey<Registry<MapCodec<? extends SpawnFunction>>> SPAWN_FUNCTION_TYPES = ResourceKey
.createRegistryKey(WanderersOfTheRift.id("spawn_function_type"));
public static final ResourceKey<Registry<SpawnFunction>> SPAWN_FUNCTIONS = ResourceKey
.createRegistryKey(WanderersOfTheRift.id("spawn_function"));

public static final ResourceKey<Registry<AnomalyTask<?>>> ANOMALY_TASK = ResourceKey
.createRegistryKey(WanderersOfTheRift.id("anomaly_task"));
public static final ResourceKey<Registry<AnomalyTask.AnomalyTaskType<?>>> ANOMALY_TASK_TYPE = ResourceKey
Expand Down Expand Up @@ -327,5 +330,6 @@ public static void registerDatapackRegistries(DataPackRegistryEvent.NewRegistry
event.dataPackRegistry(Keys.ANOMALY_REWARD, AnomalyReward.DIRECT_CODEC, AnomalyReward.DIRECT_CODEC);
event.dataPackRegistry(Keys.ABILITY_RESOURCES, AbilityResource.DIRECT_CODEC, AbilityResource.DIRECT_CODEC);
event.dataPackRegistry(Keys.NPCS, NpcIdentity.DIRECT_CODEC, NpcIdentity.DIRECT_CODEC);
event.dataPackRegistry(Keys.SPAWN_FUNCTIONS, SpawnFunction.CODEC, SpawnFunction.CODEC);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,46 @@

import com.mojang.serialization.MapCodec;
import com.wanderersoftherift.wotr.WanderersOfTheRift;
import com.wanderersoftherift.wotr.block.blockentity.anomaly.BattleTask;
import com.wanderersoftherift.wotr.spawning.functions.AddDeathNotifierSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.AddPassengerSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.ApplyMobVariantSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.ChanceSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.EquipmentSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.FinalizeSpawnSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.FindSuitableSpawnLocationSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.ListSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.MoveSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.MoveToSpawnerSpawnFunction;
import com.wanderersoftherift.wotr.spawning.functions.SpawnFunction;
import net.neoforged.neoforge.registries.DeferredRegister;

import java.util.function.Supplier;

public class WotrSpawnFunctionTypes {
public static final DeferredRegister<MapCodec<? extends BattleTask.SpawnFunction>> SPAWN_FUNCTION_TYPES = DeferredRegister
public static final DeferredRegister<MapCodec<? extends SpawnFunction>> SPAWN_FUNCTION_TYPES = DeferredRegister
.create(WotrRegistries.SPAWN_FUNCTION_TYPES, WanderersOfTheRift.MODID);

public static final Supplier<MapCodec<? extends BattleTask.SpawnFunction>> APPLY_MOB_VARIANT = SPAWN_FUNCTION_TYPES
.register("apply_mob_variant", () -> BattleTask.ApplyMobVariant.MAP_CODEC);
public static final Supplier<MapCodec<? extends BattleTask.SpawnFunction>> ADD_DEATH_NOTIFIER = SPAWN_FUNCTION_TYPES
.register("add_death_notifier", () -> BattleTask.AddDeathNotifier.MAP_CODEC);
public static final Supplier<MapCodec<? extends BattleTask.SpawnFunction>> FINALIZE_SPAWN = SPAWN_FUNCTION_TYPES
.register("finalize_spawn", () -> BattleTask.FinalizeSpawn.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> APPLY_MOB_VARIANT = SPAWN_FUNCTION_TYPES
.register("apply_mob_variant", () -> ApplyMobVariantSpawnFunction.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> ADD_DEATH_NOTIFIER = SPAWN_FUNCTION_TYPES
.register("add_death_notifier", () -> AddDeathNotifierSpawnFunction.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> FINALIZE_SPAWN = SPAWN_FUNCTION_TYPES
.register("finalize_spawn", () -> FinalizeSpawnSpawnFunction.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> LIST = SPAWN_FUNCTION_TYPES.register("list",
() -> ListSpawnFunction.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> CHANCE = SPAWN_FUNCTION_TYPES.register("chance",
() -> ChanceSpawnFunction.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> EQUIPMENT = SPAWN_FUNCTION_TYPES.register("equip",
() -> EquipmentSpawnFunction.MAP_CODEC);

public static final Supplier<MapCodec<? extends SpawnFunction>> ADD_PASSENGER = SPAWN_FUNCTION_TYPES
.register("add_passenger", () -> AddPassengerSpawnFunction.MAP_CODEC);

public static final Supplier<MapCodec<? extends SpawnFunction>> MOVE_TO_SPAWNER = SPAWN_FUNCTION_TYPES
.register("move_to_spawner", () -> MoveToSpawnerSpawnFunction.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> MOVE = SPAWN_FUNCTION_TYPES.register("move",
() -> MoveSpawnFunction.MAP_CODEC);
public static final Supplier<MapCodec<? extends SpawnFunction>> FIND_SPAWN_LOCATION = SPAWN_FUNCTION_TYPES
.register("find_spawn", () -> FindSuitableSpawnLocationSpawnFunction.MAP_CODEC);

}
43 changes: 43 additions & 0 deletions src/main/java/com/wanderersoftherift/wotr/spawning/SpawnType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.wanderersoftherift.wotr.spawning;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.wanderersoftherift.wotr.spawning.functions.SpawnFunction;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.block.entity.BlockEntity;

import java.util.Collections;
import java.util.List;

public record SpawnType(Holder<EntityType<?>> entityType, List<Holder<SpawnFunction>> spawnFunctions) {
public static final Codec<SpawnType> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
BuiltInRegistries.ENTITY_TYPE.holderByNameCodec()
.fieldOf("entity_type")
.forGetter(SpawnType::entityType),
SpawnFunction.HOLDER_CODEC.listOf()
.optionalFieldOf("spawn_functions", Collections.emptyList())
.forGetter(SpawnType::spawnFunctions)
).apply(instance, SpawnType::new)
);

public Entity createSpawn(ServerLevel serverLevel, BlockEntity anomalyBlockEntity, RandomSource randomSource) {

var mob = entityType().value().create(serverLevel, EntitySpawnReason.SPAWNER);
if (mob == null) {
return null;
}

if (mob instanceof Mob mob2) {
spawnFunctions.forEach(it -> it.value().applyToMob(mob2, anomalyBlockEntity, randomSource));
}
return mob;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.wanderersoftherift.wotr.spawning.functions;

import com.mojang.serialization.MapCodec;
import com.wanderersoftherift.wotr.block.blockentity.anomaly.DeathNotifierAttachment;
import com.wanderersoftherift.wotr.init.WotrAttachments;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.block.entity.BlockEntity;

public record AddDeathNotifierSpawnFunction() implements SpawnFunction {
public static final AddDeathNotifierSpawnFunction INSTANCE = new AddDeathNotifierSpawnFunction();
public static final MapCodec<AddDeathNotifierSpawnFunction> MAP_CODEC = MapCodec.unit(INSTANCE);

@Override
public MapCodec<? extends SpawnFunction> codec() {
return MAP_CODEC;
}

@Override
public void applyToMob(Mob mob, BlockEntity spawner, RandomSource random) {
mob.setData(WotrAttachments.DEATH_NOTIFICATION, new DeathNotifierAttachment(spawner.getBlockPos()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.wanderersoftherift.wotr.spawning.functions;

import com.mojang.serialization.MapCodec;
import com.wanderersoftherift.wotr.spawning.SpawnType;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.block.entity.BlockEntity;

public record AddPassengerSpawnFunction(SpawnType spawn) implements SpawnFunction {
public static final MapCodec<AddPassengerSpawnFunction> MAP_CODEC = SpawnType.CODEC.fieldOf("spawn")
.xmap(AddPassengerSpawnFunction::new, AddPassengerSpawnFunction::spawn);

@Override
public MapCodec<? extends SpawnFunction> codec() {
return MAP_CODEC;
}

@Override
public void applyToMob(Mob mob, BlockEntity spawner, RandomSource random) {
var spawn = this.spawn.createSpawn((ServerLevel) mob.level(), spawner, random);
if (spawn != null) {
spawn.startRiding(mob, true);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.wanderersoftherift.wotr.spawning.functions;

import com.mojang.serialization.MapCodec;
import com.wanderersoftherift.wotr.entity.mob.RiftMobVariantData;
import com.wanderersoftherift.wotr.entity.mob.VariedRiftMob;
import net.minecraft.core.Holder;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.block.entity.BlockEntity;

public record ApplyMobVariantSpawnFunction(Holder<RiftMobVariantData> variant) implements SpawnFunction {
public static final MapCodec<ApplyMobVariantSpawnFunction> MAP_CODEC = RiftMobVariantData.VARIANT_HOLDER_CODEC
.fieldOf("variant")
.xmap(ApplyMobVariantSpawnFunction::new, ApplyMobVariantSpawnFunction::variant);

@Override
public MapCodec<? extends SpawnFunction> codec() {
return MAP_CODEC;
}

@Override
public void applyToMob(Mob mob, BlockEntity spawner, RandomSource random) {
if (mob instanceof VariedRiftMob zombie) {
zombie.setVariant(variant);
}
}
}
Loading