import new repo

This commit is contained in:
ItsBlackGear 2022-08-25 17:53:18 -04:00
parent a8ea9d276c
commit f50eacb1e0
91 changed files with 930 additions and 729 deletions

View File

@ -0,0 +1 @@
[Architectury Transformer DEBUG] Closing File Systems for C:\Users\Alecan\Desktop\wildbackport\common\build\libs\wildbackport-1.2.0.jar

2
.gitattributes vendored
View File

@ -1,2 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto

131
.gitignore vendored
View File

@ -1,118 +1,19 @@
# User-specific stuff
.idea/
*.iml
*.ipr
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
.gradle
build/
# Ignore Gradle GUI config
gradle-app.setting
# Cache of project
.gradletasknamecache
**/build/
# Common working directory
*.ipr
run/
*.iws
out/
*.iml
.gradle/
output/
bin/
libs/
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
.classpath
.project
.idea/
classes/
.metadata
.vscode
.settings
*.launch

View File

@ -1,6 +1,7 @@
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "0.11.0-SNAPSHOT" apply false
id "dev.architectury.loom" version "0.12.0-SNAPSHOT" apply false
id "io.github.juuxel.loom-quiltflower" version "1.7.1" apply false
}
architectury {
@ -9,6 +10,7 @@ architectury {
subprojects {
apply plugin: "dev.architectury.loom"
apply plugin: "io.github.juuxel.loom-quiltflower"
loom {
silentMojangMappingsLicense()
@ -19,7 +21,7 @@ subprojects {
// The following line declares the mojmap mappings, you may use other mappings as well
mappings loom.officialMojangMappings()
// The following line declares the yarn mappings you may select this one as well.
// mappings "net.fabricmc:yarn:@YARN_MAPPINGS@:v2"
// mappings "net.fabricmc:yarn:1.18.2+build.3:v2"
}
}

View File

@ -1,15 +1,17 @@
architectury {
common(rootProject.enabled_platforms.split(","))
}
loom {
accessWidenerPath = file("src/main/resources/wildbackport.accesswidener")
}
dependencies {
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
// Do NOT use other classes from fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
}
architectury {
common("forge", "fabric")
}
loom {
accessWidenerPath.set(file("src/main/resources/wildbackport.accesswidener"))
// Remove the next line if you don't want to depend on the API
// modApi "dev.architectury:architectury:${rootProject.architectury_version}"
}
publishing {
@ -20,5 +22,8 @@ publishing {
}
}
repositories {}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}

View File

@ -16,7 +16,7 @@ import com.cursedcauldron.wildbackport.common.registry.worldgen.RootPlacerType;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBTreeDecorators;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBTrunkPlacers;
import com.cursedcauldron.wildbackport.common.registry.entity.WBActivities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.registry.entity.WBSensorTypes;
import com.cursedcauldron.wildbackport.common.tag.WBBiomeTags;
@ -40,7 +40,7 @@ public class WildBackport {
WBBlockEntities.BLOCKS.register();
WBBlocks.BLOCKS.register();
WBEnchantments.ENCHANTMENTS.register();
WBEntities.ENTITIES.register();
WBEntityTypes.ENTITIES.register();
WBGameEvents.EVENTS.register();
WBFeatures.FEATURES.register();
WBItems.ITEMS.register();

View File

@ -17,7 +17,7 @@ import com.cursedcauldron.wildbackport.client.render.model.FrogModel;
import com.cursedcauldron.wildbackport.client.render.model.TadpoleModel;
import com.cursedcauldron.wildbackport.client.render.model.WardenModel;
import com.cursedcauldron.wildbackport.common.registry.WBBlocks;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.core.api.ColorRegistry;
import com.cursedcauldron.wildbackport.core.api.ParticleRegistry;
import com.cursedcauldron.wildbackport.core.api.RenderRegistry;
@ -40,16 +40,16 @@ public class ClientSetup {
// Entity Renderers
RenderRegistry.setLayerDefinition(AllayRenderer.MODEL_LAYER, AllayModel::createBodyLayer);
RenderRegistry.setEntityRender(WBEntities.ALLAY, AllayRenderer::new);
RenderRegistry.setEntityRender(WBEntityTypes.ALLAY, AllayRenderer::new);
RenderRegistry.setLayerDefinition(WardenRenderer.MODEL_LAYER, WardenModel::createBodyLayer);
RenderRegistry.setEntityRender(WBEntities.WARDEN, WardenRenderer::new);
RenderRegistry.setEntityRender(WBEntityTypes.WARDEN, WardenRenderer::new);
RenderRegistry.setLayerDefinition(FrogRenderer.MODEL_LAYER, FrogModel::createBodyLayer);
RenderRegistry.setEntityRender(WBEntities.FROG, FrogRenderer::new);
RenderRegistry.setEntityRender(WBEntityTypes.FROG, FrogRenderer::new);
RenderRegistry.setLayerDefinition(TadpoleRenderer.MODEL_LAYER, TadpoleModel::createBodyLayer);
RenderRegistry.setEntityRender(WBEntities.TADPOLE, TadpoleRenderer::new);
RenderRegistry.setEntityRender(WBEntityTypes.TADPOLE, TadpoleRenderer::new);
for (Boat.Type type : Boat.Type.values()) RenderRegistry.setLayerDefinition(ChestBoatModel.createChestBoat(type), () -> ChestBoatModel.createBodyModel(true));
RenderRegistry.setEntityRender(WBEntities.MANGROVE_BOAT, context -> new ChestBoatRenderer(context, false));
RenderRegistry.setEntityRender(WBEntities.CHEST_BOAT, context -> new ChestBoatRenderer(context, true));
RenderRegistry.setEntityRender(WBEntityTypes.MANGROVE_BOAT, context -> new ChestBoatRenderer(context, false));
RenderRegistry.setEntityRender(WBEntityTypes.CHEST_BOAT, context -> new ChestBoatRenderer(context, true));
// Particle Renderers
ParticleRegistry.create(WBParticleTypes.SCULK_SOUL, SculkSoulParticle.Provider::new);

View File

@ -3,13 +3,19 @@ package com.cursedcauldron.wildbackport.client.render;
import com.cursedcauldron.wildbackport.client.render.model.Drawable;
import com.cursedcauldron.wildbackport.client.render.model.WardenModel;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.core.mixin.access.RenderStateShardAccessor;
import com.cursedcauldron.wildbackport.core.mixin.access.RenderTypeAccessor;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.Util;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderStateShard;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.RenderLayerParent;
@ -17,11 +23,17 @@ import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.resources.ResourceLocation;
import java.util.List;
import java.util.function.BiFunction;
//<>
@Environment(EnvType.CLIENT)
public class WardenLayerRenderer<T extends Warden, M extends WardenModel<T>> extends RenderLayer<T, M> {
public static final BiFunction<ResourceLocation, Boolean, RenderType> ENTITY_TRANSLUCENT_EMISSIVE = Util.memoize((location, create) -> {
RenderType.CompositeState compositeState = RenderType.CompositeState.builder().setShaderState(RenderStateShardAccessor.getRENDERTYPE_EYES_SHADER()).setTextureState(new RenderStateShard.TextureStateShard(location, false, false)).setTransparencyState(RenderStateShardAccessor.getTRANSLUCENT_TRANSPARENCY()).setCullState(RenderStateShardAccessor.getNO_CULL()).setWriteMaskState(RenderStateShardAccessor.getCOLOR_WRITE()).setOverlayState(RenderStateShardAccessor.getOVERLAY()).createCompositeState(create);
return RenderTypeAccessor.callCreate("entity_translucent_emissive", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, true, true, compositeState);
});
private final ResourceLocation texture;
private final AnimationAngleAdjuster<T> animationAngleAdjuster;
private final ModelPartVisibility<T, M> modelPartVisibility;
@ -37,7 +49,7 @@ public class WardenLayerRenderer<T extends Warden, M extends WardenModel<T>> ext
public void render(PoseStack stack, MultiBufferSource source, int light, T entity, float angle, float distance, float tickDelta, float animationProgress, float yaw, float pitch) {
if (!entity.isInvisible()) {
this.updateModelPartVisibility();
VertexConsumer consumer = source.getBuffer(RenderType.entityCutoutNoCull(this.texture));
VertexConsumer consumer = source.getBuffer(ENTITY_TRANSLUCENT_EMISSIVE.apply(this.texture, true));
this.getParentModel().renderToBuffer(stack, consumer, light, LivingEntityRenderer.getOverlayCoords(entity, 0.0F), 1.0F, 1.0F, 1.0F, this.animationAngleAdjuster.apply(entity, tickDelta, animationProgress));
this.unhideAllModelParts();
}

View File

@ -4,34 +4,11 @@ import com.cursedcauldron.wildbackport.common.entities.Allay;
import com.cursedcauldron.wildbackport.common.entities.Frog;
import com.cursedcauldron.wildbackport.common.entities.Tadpole;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.common.registry.WBBlocks;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.events.StructureGeneration;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBWorldGeneration;
import com.cursedcauldron.wildbackport.common.tag.WBBlockTags;
import com.cursedcauldron.wildbackport.core.api.MobRegistry;
import com.cursedcauldron.wildbackport.core.api.event.Interactions;
import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeModifier;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockSource;
import net.minecraft.core.Direction;
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ItemUtils;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
public class CommonSetup {
/**
@ -39,10 +16,10 @@ public class CommonSetup {
*/
public static void onCommon() {
// Entity Attributes
MobRegistry.registerAttributes(WBEntities.ALLAY, Allay::createAttributes);
MobRegistry.registerAttributes(WBEntities.FROG, Frog::createAttributes);
MobRegistry.registerAttributes(WBEntities.TADPOLE, Tadpole::createAttributes);
MobRegistry.registerAttributes(WBEntities.WARDEN, Warden::createAttributes);
MobRegistry.registerAttributes(WBEntityTypes.ALLAY, Allay::createAttributes);
MobRegistry.registerAttributes(WBEntityTypes.FROG, Frog::createAttributes);
MobRegistry.registerAttributes(WBEntityTypes.TADPOLE, Tadpole::createAttributes);
MobRegistry.registerAttributes(WBEntityTypes.WARDEN, Warden::createAttributes);
}
@ -53,5 +30,7 @@ public class CommonSetup {
WBWorldGeneration.bootstrap();
BiomeModifier.setup();
VanillaInteraction.setup();
StructureGeneration.registerAllayCages();
}
}

View File

@ -2,7 +2,7 @@ package com.cursedcauldron.wildbackport.common.blocks;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.Tadpole;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
@ -28,8 +28,6 @@ import java.util.Random;
public class FrogspawnBlock extends Block {
protected static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 1.5D, 16.0D);
private static final int MIN_HATCH_TIME = 3600;
private static final int MAX_HATCH_TIME = 12000;
public FrogspawnBlock(Properties properties) {
super(properties);
@ -51,7 +49,7 @@ public class FrogspawnBlock extends Block {
}
private static int hatchTime(Random random) {
return random.nextInt(MIN_HATCH_TIME, MAX_HATCH_TIME);
return random.nextInt(3600, 12000);
}
@Override
@ -95,7 +93,7 @@ public class FrogspawnBlock extends Block {
int i = random.nextInt(2, 6);
for (int index = 1; index <= i; ++index) {
Tadpole tadpole = WBEntities.TADPOLE.get().create(level);
Tadpole tadpole = WBEntityTypes.TADPOLE.get().create(level);
if (tadpole != null) {
double x = (double)pos.getX() + this.getSpawnOffset(random);
double z = (double)pos.getZ() + this.getSpawnOffset(random);
@ -108,7 +106,6 @@ public class FrogspawnBlock extends Block {
}
private double getSpawnOffset(Random random) {
double d = Tadpole.WIDTH / 2.0F;
return Mth.clamp(random.nextDouble(), d, 1.0 - d);
return Mth.clamp(random.nextDouble(), 0.2F, 0.8F);
}
}

View File

@ -18,8 +18,8 @@ public class MangroveLeavesBlock extends LeavesBlock implements BonemealableBloc
}
@Override
public boolean isValidBonemealTarget(BlockGetter getter, BlockPos pos, BlockState state, boolean bl) {
return getter.getBlockState(pos.below()).isAir();
public boolean isValidBonemealTarget(BlockGetter block, BlockPos pos, BlockState state, boolean flag) {
return block.getBlockState(pos.below()).isAir();
}
@Override

View File

@ -31,7 +31,7 @@ import java.util.Random;
public class MangrovePropaguleBlock extends SaplingBlock implements SimpleWaterloggedBlock {
private static final VoxelShape[] SHAPES = new VoxelShape[]{Block.box(7.0D, 13.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 10.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 7.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 3.0D, 7.0D, 9.0D, 16.0D, 9.0D), Block.box(7.0D, 0.0D, 7.0D, 9.0D, 16.0D, 9.0D)};
public static final IntegerProperty AGE = BlockProperties.AGE_4;
public static final IntegerProperty AGE = StateProperties.AGE_4;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public static final BooleanProperty HANGING = BlockStateProperties.HANGING;
@ -46,32 +46,32 @@ public class MangrovePropaguleBlock extends SaplingBlock implements SimpleWaterl
}
@Override
protected boolean mayPlaceOn(BlockState state, BlockGetter getter, BlockPos pos) {
return super.mayPlaceOn(state, getter, pos) || state.is(Blocks.CLAY);
protected boolean mayPlaceOn(BlockState state, BlockGetter block, BlockPos pos) {
return super.mayPlaceOn(state, block, pos) || state.is(Blocks.CLAY);
}
@Override @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) {
FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos());
return super.getStateForPlacement(context).setValue(WATERLOGGED, fluidState.getType() == Fluids.WATER).setValue(AGE, 4);
@Override @Nullable @SuppressWarnings("ConstantConditions")
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
FluidState fluidState = ctx.getLevel().getFluidState(ctx.getClickedPos());
return super.getStateForPlacement(ctx).setValue(WATERLOGGED, fluidState.getType() == Fluids.WATER).setValue(AGE, 4);
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter getter, BlockPos pos, CollisionContext context) {
Vec3 offset = state.getOffset(getter, pos);
public VoxelShape getShape(BlockState state, BlockGetter block, BlockPos pos, CollisionContext context) {
Vec3 offset = state.getOffset(block, pos);
VoxelShape shape = !state.getValue(HANGING) ? SHAPES[4] : SHAPES[state.getValue(AGE)];
return shape.move(offset.x, offset.y, offset.z);
}
@Override
public boolean canSurvive(BlockState state, LevelReader reader, BlockPos pos) {
return isHanging(state) ? reader.getBlockState(pos.above()).is(WBBlocks.MANGROVE_LEAVES.get()) : super.canSurvive(state, reader, pos);
public boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) {
return isHanging(state) ? level.getBlockState(pos.above()).is(WBBlocks.MANGROVE_LEAVES.get()) : super.canSurvive(state, level, pos);
}
@Override
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor accessor, BlockPos pos, BlockPos neighborPos) {
if (state.getValue(WATERLOGGED)) accessor.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(accessor));
return direction == Direction.UP && !state.canSurvive(accessor, pos) ? Blocks.AIR.defaultBlockState() : super.updateShape(state, direction, neighborState, accessor, pos, neighborPos);
public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor level, BlockPos pos, BlockPos newPos) {
if (state.getValue(WATERLOGGED)) level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
return direction == Direction.UP && !state.canSurvive(level, pos) ? Blocks.AIR.defaultBlockState() : super.updateShape(state, direction, newState, level, pos, newPos);
}
@Override
@ -94,7 +94,7 @@ public class MangrovePropaguleBlock extends SaplingBlock implements SimpleWaterl
}
@Override
public boolean isValidBonemealTarget(BlockGetter getter, BlockPos pos, BlockState state, boolean flag) {
public boolean isValidBonemealTarget(BlockGetter block, BlockPos pos, BlockState state, boolean flag) {
return !isHanging(state) || !ageAtMax(state);
}

View File

@ -29,16 +29,15 @@ public class MangroveRootsBlock extends Block implements SimpleWaterloggedBlock
return stateFrom.is(WBBlocks.MANGROVE_ROOTS.get()) && direction.getAxis() == Direction.Axis.Y;
}
@Override @Nullable
@Override @Nullable @SuppressWarnings("ConstantConditions")
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
FluidState state = ctx.getLevel().getFluidState(ctx.getClickedPos());
return super.getStateForPlacement(ctx).setValue(WATERLOGGED, state.getType() == Fluids.WATER);
return super.getStateForPlacement(ctx).setValue(WATERLOGGED, ctx.getLevel().getFluidState(ctx.getClickedPos()).getType() == Fluids.WATER);
}
@Override
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor accessor, BlockPos pos, BlockPos neighborPos) {
if (state.getValue(WATERLOGGED)) accessor.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(accessor));
return super.updateShape(state, direction, neighborState, accessor, pos, neighborPos);
public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor level, BlockPos pos, BlockPos newPos) {
if (state.getValue(WATERLOGGED)) level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
return super.updateShape(state, direction, newState, level, pos, newPos);
}
@Override

View File

@ -28,7 +28,7 @@ import java.util.Random;
//<>
public class SculkCatalystBlock extends BaseEntityBlock {
public static final BooleanProperty BLOOM = BlockProperties.BLOOM;
public static final BooleanProperty BLOOM = StateProperties.BLOOM;
public SculkCatalystBlock(Properties properties) {
super(properties);

View File

@ -37,8 +37,8 @@ import java.util.Random;
//<>
public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterloggedBlock {
public static final BooleanProperty SHRIEKING = BlockProperties.SHRIEKING;
public static final BooleanProperty CAN_SUMMON = BlockProperties.CAN_SUMMON;
public static final BooleanProperty SHRIEKING = StateProperties.SHRIEKING;
public static final BooleanProperty CAN_SUMMON = StateProperties.CAN_SUMMON;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
private static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D);
public static final double TOP_Y = SHAPE.max(Direction.Axis.Y);
@ -50,9 +50,7 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(SHRIEKING);
builder.add(WATERLOGGED);
builder.add(CAN_SUMMON);
builder.add(SHRIEKING, WATERLOGGED, CAN_SUMMON);
}
@Override

View File

@ -342,7 +342,7 @@ public class SculkSpreadManager {
if (level == null) return;
Random random = level.getRandom();
ClientLevel client = level instanceof ClientLevel side ? side : null;
ClientLevel client = level.isClientSide() && level instanceof ClientLevel side ? side : null;
ServerLevel server = level instanceof ServerLevel side ? side : null;
int charge = data >> 6;

View File

@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
public class BlockProperties {
public class StateProperties {
// Block Properties
public static final BooleanProperty SHRIEKING = BooleanProperty.create("shrieking");
public static final BooleanProperty CAN_SUMMON = BooleanProperty.create("can_summon");

View File

@ -11,7 +11,7 @@ import com.cursedcauldron.wildbackport.common.entities.warden.WardenSpawnTracker
import com.cursedcauldron.wildbackport.common.registry.WBBlockEntities;
import com.cursedcauldron.wildbackport.common.registry.WBGameEvents;
import com.cursedcauldron.wildbackport.common.registry.WBGameRules;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags;
import com.mojang.serialization.Dynamic;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
@ -176,7 +176,7 @@ public class SculkShriekerBlockEntity extends BlockEntity implements VibrationHa
}
private boolean trySummonWarden(ServerLevel level) {
return this.warningLevel >= 4 && WardenSpawnHelper.trySpawnMob(WBEntities.WARDEN.get(), MobSpawnType.TRIGGERED, level, this.getBlockPos(), 20, 5, 6).isPresent();
return this.warningLevel >= 4 && WardenSpawnHelper.trySpawnMob(WBEntityTypes.WARDEN.get(), MobSpawnType.TRIGGERED, level, this.getBlockPos(), 20, 5, 6).isPresent();
}
@Override

View File

@ -1,10 +1,9 @@
package com.cursedcauldron.wildbackport.common.entities;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.access.Vibration;
import com.cursedcauldron.wildbackport.common.entities.brain.AllayBrain;
import com.cursedcauldron.wildbackport.common.entities.warden.MobPositionSource;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationHandler;
import com.cursedcauldron.wildbackport.common.registry.WBGameEvents;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags;
@ -13,12 +12,10 @@ import com.mojang.serialization.Dynamic;
import net.minecraft.core.BlockPos;
import net.minecraft.core.GlobalPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.TagKey;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
@ -54,6 +51,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.GameEventListener;
import net.minecraft.world.level.gameevent.GameEventListenerRegistrar;
import net.minecraft.world.level.gameevent.vibrations.VibrationListener;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
@ -64,12 +62,12 @@ import java.util.UUID;
//<>
public class Allay extends PathfinderMob implements InventoryCarrier, VibrationHandler.VibrationConfig {
public class Allay extends PathfinderMob implements InventoryCarrier {
protected static final ImmutableList<? extends SensorType<? extends Sensor<? super Allay>>> SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY, SensorType.NEAREST_ITEMS);
protected static final ImmutableList<MemoryModuleType<?>> MEMORIES = ImmutableList.of(MemoryModuleType.PATH, MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.HURT_BY, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, WBMemoryModules.LIKED_PLAYER.get(), WBMemoryModules.LIKED_NOTEBLOCK.get(), WBMemoryModules.LIKED_NOTEBLOCK_COOLDOWN_TICKS.get(), WBMemoryModules.ITEM_PICKUP_COOLDOWN_TICKS.get());
public static final ImmutableList<Float> THROW_SOUND_PITCHES = ImmutableList.of(0.5625F, 0.625F, 0.75F, 0.9375F, 1.0F, 1.0F, 1.125F, 1.25F, 1.5F, 1.875F, 2.0F, 2.25F, 2.5F, 3.0F, 3.75F, 4.0F);
private final GameEventListenerRegistrar registrar;
private VibrationHandler listener;
// private final GameEventListenerRegistrar registrar;
// private final VibrationListener listener;
private final SimpleContainer inventory = new SimpleContainer(1);
private float holdingTicks;
private float holdingTicksOld;
@ -78,8 +76,14 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationH
super(type, level);
this.moveControl = new FlyingMoveControl(this, 20, true);
this.setCanPickUpLoot(this.canPickUpLoot());
this.listener = new VibrationHandler(new MobPositionSource(this, this.getEyeHeight()), 16, this, null, 0.0F, 0);
this.registrar = new GameEventListenerRegistrar(this.listener);
// this.listener = new VibrationListener(new MobPositionSource(this, this.getEyeHeight()), 16, new VibrationListenerCallback()) {
// @Override
// public boolean handleGameEvent(Level level, GameEvent event, @Nullable Entity entity, BlockPos pos) {
// boolean flag = super.handleGameEvent(level, event, entity, pos);
// return flag || event.is(WBGameEventTags.ALLAY_CAN_LISTEN);
// }
// };
// this.registrar = new GameEventListenerRegistrar(this.listener);
}
@Override
@ -214,7 +218,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationH
this.holdingTicks = Mth.clamp(this.holdingTicks - 1.0F, 0.0F, 5.0F);
}
} else {
this.listener.tick(this.level);
// this.listener.tick(this.level);
}
}
@ -302,10 +306,10 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationH
return !this.isOnGround();
}
@Override @Nullable
public GameEventListenerRegistrar getGameEventListenerRegistrar() {
return this.registrar;
}
// @Override @Nullable
// public GameEventListenerRegistrar getGameEventListenerRegistrar() {
// return this.registrar;
// }
public float getHoldingItemAnimationProgress(float animationProgress) {
return Mth.lerp(animationProgress, this.holdingTicksOld, this.holdingTicks) / 5.0F;
@ -327,42 +331,16 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationH
return false;
}
@Override
public boolean shouldListen(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity) {
if (this.level == level && !this.isRemoved() && !this.isNoAi()) {
if (!this.brain.hasMemoryValue(WBMemoryModules.LIKED_NOTEBLOCK.get())) {
return true;
} else {
Optional<GlobalPos> likedNoteblock = this.brain.getMemory(WBMemoryModules.LIKED_NOTEBLOCK.get());
return likedNoteblock.isPresent() && likedNoteblock.get().dimension() == level.dimension() && likedNoteblock.get().pos() == pos;
}
} else {
return false;
}
}
@Override
public void onSignalReceive(ServerLevel level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity, @Nullable Entity source, float distance) {
if (event == WBGameEvents.NOTE_BLOCK_PLAY.get()) AllayBrain.rememberNoteBlock(this, new BlockPos(pos));
}
@Override
public TagKey<GameEvent> getListenableEvents() {
return WBGameEventTags.ALLAY_CAN_LISTEN;
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.put("Inventory", this.inventory.createTag());
VibrationHandler.codec(this).encodeStart(NbtOps.INSTANCE, this.listener).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> tag.put("listener", listener));
}
@Override
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
this.inventory.fromTag(tag.getList("Inventory", 10));
if (tag.contains("listener", 10)) VibrationHandler.codec(this).parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("listener"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(listener -> this.listener = listener);
}
public Iterable<BlockPos> getPotentialEscapePositions() {
@ -380,4 +358,28 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationH
public Vec3 getLeashOffset() {
return new Vec3(0.0D, this.getEyeHeight() * 0.6D, this.getBbWidth() * 0.1D);
}
// class VibrationListenerCallback implements VibrationListener.VibrationListenerConfig {
// @Override
// public void onSignalReceive(Level level, GameEventListener listener, GameEvent event, int distance) {
// Vibration.Instance instance = Vibration.Instance.of(Allay.this.listener);
// if (event == WBGameEvents.NOTE_BLOCK_PLAY.get()) {
// AllayBrain.rememberNoteBlock(Allay.this, new BlockPos(instance.getPos()));
// }
// }
//
// @Override
// public boolean shouldListen(Level level, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity) {
// if (Allay.this.getLevel() != level || Allay.this.isRemoved() || Allay.this.isNoAi()) {
// return false;
// } else {
// Optional<GlobalPos> position = Allay.this.getBrain().getMemory(WBMemoryModules.LIKED_NOTEBLOCK.get());
// if (position.isEmpty()) {
// return true;
// } else {
// return position.get().dimension().equals(level.dimension()) && position.get().pos().equals(pos);
// }
// }
// }
// }
}

View File

@ -1,7 +1,7 @@
package com.cursedcauldron.wildbackport.common.entities;
import com.cursedcauldron.wildbackport.common.registry.WBItems;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
@ -49,7 +49,7 @@ public class ChestBoat extends MangroveBoat implements Container, MenuProvider {
}
public ChestBoat(Level level, double x, double y, double z) {
super(WBEntities.CHEST_BOAT.get(), level);
super(WBEntityTypes.CHEST_BOAT.get(), level);
this.setPos(x, y, z);
this.xo = x;
this.yo = y;

View File

@ -4,7 +4,7 @@ import com.cursedcauldron.wildbackport.client.animation.api.AnimationState;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.brain.FrogBrain;
import com.cursedcauldron.wildbackport.common.entities.access.api.Poses;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.registry.entity.WBSensorTypes;
import com.cursedcauldron.wildbackport.common.tag.WBBiomeTags;
@ -240,7 +240,7 @@ public class Frog extends Animal {
@Nullable @Override
public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob mob) {
Frog frog = WBEntities.FROG.get().create(level);
Frog frog = WBEntityTypes.FROG.get().create(level);
if (frog != null) FrogBrain.coolDownLongJump(frog, level.getRandom());
return frog;
}

View File

@ -2,7 +2,7 @@ package com.cursedcauldron.wildbackport.common.entities;
import com.cursedcauldron.wildbackport.common.entities.access.api.BoatTypes;
import com.cursedcauldron.wildbackport.common.registry.WBItems;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
@ -20,7 +20,7 @@ public class MangroveBoat extends Boat {
}
public MangroveBoat(Level level, double x, double y, double z) {
super(WBEntities.MANGROVE_BOAT.get(), level);
super(WBEntityTypes.MANGROVE_BOAT.get(), level);
this.setPos(x, y, z);
this.xo = x;
this.yo = y;

View File

@ -3,7 +3,7 @@ package com.cursedcauldron.wildbackport.common.entities;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.brain.TadpoleBrain;
import com.cursedcauldron.wildbackport.common.registry.WBItems;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Dynamic;
import net.minecraft.core.particles.ParticleTypes;
@ -38,8 +38,6 @@ import org.jetbrains.annotations.Nullable;
public class Tadpole extends AbstractFish {
public static final int MAX_TADPOLE_AGE = Math.abs(-24000);
public static final float WIDTH = 0.4F;
public static final float HEIGHT = 0.3F;
private int age;
protected static final ImmutableList<SensorType<? extends Sensor<? super Tadpole>>> SENSORS = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY);
protected static final ImmutableList<MemoryModuleType<?>> MEMORIES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.NEAREST_VISIBLE_ADULT);
@ -51,8 +49,8 @@ public class Tadpole extends AbstractFish {
}
@Override
protected PathNavigation createNavigation(Level world) {
return new WaterBoundPathNavigation(this, world);
protected PathNavigation createNavigation(Level level) {
return new WaterBoundPathNavigation(this, level);
}
@Override
@ -93,21 +91,19 @@ public class Tadpole extends AbstractFish {
@Override
public void aiStep() {
super.aiStep();
if (!this.level.isClientSide()) {
this.setAge(this.age + 1);
}
if (!this.level.isClientSide) this.setAge(this.age + 1);
}
@Override
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putInt("Age", this.age);
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.putInt("Age", this.age);
}
@Override
public void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
this.setAge(nbt.getInt("Age"));
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
this.setAge(tag.getInt("Age"));
}
@Override @Nullable
@ -201,14 +197,12 @@ public class Tadpole extends AbstractFish {
private void setAge(int age) {
this.age = age;
if (this.age >= MAX_TADPOLE_AGE) {
this.growUp();
}
if (this.age >= MAX_TADPOLE_AGE) this.growUp();
}
private void growUp() {
if (this.level instanceof ServerLevel server) {
Frog frog = WBEntities.FROG.get().create(this.level);
Frog frog = WBEntityTypes.FROG.get().create(this.level);
if (frog == null) return;
frog.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());

View File

@ -11,7 +11,7 @@ import com.cursedcauldron.wildbackport.common.entities.warden.MobPositionSource;
import com.cursedcauldron.wildbackport.common.entities.warden.VibrationHandler;
import com.cursedcauldron.wildbackport.common.entities.warden.WardenAngerManager;
import com.cursedcauldron.wildbackport.common.registry.WBMobEffects;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.tag.WBGameEventTags;
import com.cursedcauldron.wildbackport.common.utils.MobUtils;
@ -60,8 +60,8 @@ import net.minecraft.world.level.gameevent.GameEventListener;
import net.minecraft.world.level.gameevent.GameEventListenerRegistrar;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Optional;
import java.util.Random;
@ -69,6 +69,9 @@ import java.util.Random;
//<>
public class Warden extends Monster implements VibrationHandler.VibrationConfig {
public static final byte PLAY_ATTACK_SOUND = 4;
public static final byte EARS_TWITCH = 61;
public static final byte SONIC_BOOM = 62;
private static final EntityDataAccessor<Integer> ANGER = SynchedEntityData.defineId(Warden.class, EntityDataSerializers.INT);
private int tendrilPitchEnd;
private int tendrilPitchStart;
@ -152,7 +155,8 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
return 4.0F;
}
@Nullable @Override
@Nullable
@Override
protected SoundEvent getAmbientSound() {
return !this.hasPose(Poses.ROARING.get()) && !this.isDiggingOrEmerging() ? this.getAngriness().getSound() : null;
}
@ -199,7 +203,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
if (this.level instanceof ServerLevel server) {
this.listener.tick(server);
if (this.isPersistenceRequired() || this.requiresCustomPersistence()) {
WardenBrain.setDigCooldown(this);
WardenBrain.resetDigCooldown(this);
}
}
@ -248,7 +252,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
this.updateAnger();
}
WardenBrain.updateActivity(this);
WardenBrain.updateActivities(this);
}
@Override
@ -346,7 +350,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
public boolean isValidTarget(@Nullable Entity entity) {
if (entity instanceof LivingEntity living) {
return this.level == entity.level && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) && !this.isAlliedTo(entity) && living.getType() != EntityType.ARMOR_STAND && living.getType() != WBEntities.WARDEN.get() && !living.isInvulnerable() && !living.isDeadOrDying() && this.level.getWorldBorder().isWithinBounds(living.getBoundingBox());
return this.level == entity.level && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) && !this.isAlliedTo(entity) && living.getType() != EntityType.ARMOR_STAND && living.getType() != WBEntityTypes.WARDEN.get() && !living.isInvulnerable() && !living.isDeadOrDying() && this.level.getWorldBorder().isWithinBounds(living.getBoundingBox());
}
return false;
@ -360,7 +364,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
WardenAngerManager.createCodec(this::isValidTarget).encodeStart(NbtOps.INSTANCE, this.angerManager).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> tag.put("anger", manager));
WardenAngerManager.codec(this::isValidTarget).encodeStart(NbtOps.INSTANCE, this.angerManager).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> tag.put("anger", manager));
}
@ -368,7 +372,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
if (tag.contains("anger")) {
WardenAngerManager.createCodec(this::isValidTarget).parse(new Dynamic<>(NbtOps.INSTANCE, tag.get("anger"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> this.angerManager = manager);
WardenAngerManager.codec(this::isValidTarget).parse(new Dynamic<>(NbtOps.INSTANCE, tag.get("anger"))).resultOrPartial(WildBackport.LOGGER::error).ifPresent(manager -> this.angerManager = manager);
this.updateAnger();
}
}
@ -382,7 +386,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
}
public int getPrimeSuspectAnger() {
return this.angerManager.getPrimeSuspectAnger();
return this.angerManager.getAngerFor(this.getTarget());
}
public void removeSuspect(Entity entity) {
@ -395,7 +399,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
public void increaseAngerAt(Entity entity, int amount, boolean listening) {
if (!this.isNoAi() && this.isValidTarget(entity)) {
WardenBrain.setDigCooldown(this);
WardenBrain.resetDigCooldown(this);
boolean targetNotPlayer = !(this.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null) instanceof Player);
int anger = this.angerManager.increaseAngerAt(entity, amount);
if (entity instanceof Player && targetNotPlayer && Angriness.getForAnger(anger).isAngry()) {
@ -410,7 +414,8 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
return this.getAngriness().isAngry() ? this.angerManager.getPrimeSuspect() : Optional.empty();
}
@Nullable @Override
@Nullable
@Override
public LivingEntity getTarget() {
return this.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null);
}
@ -420,7 +425,8 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
return false;
}
@Nullable @Override
@Nullable
@Override
public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance instance, MobSpawnType spawn, @Nullable SpawnGroupData data, @Nullable CompoundTag tag) {
this.getBrain().setMemoryWithExpiry(WBMemoryModules.DIG_COOLDOWN.get(), Unit.INSTANCE, 1200L);
if (spawn == MobSpawnType.TRIGGERED) {
@ -471,7 +477,7 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
if (!this.isNoAi() && !this.getBrain().hasMemoryValue(WBMemoryModules.TOUCH_COOLDOWN.get())) {
this.getBrain().setMemoryWithExpiry(WBMemoryModules.TOUCH_COOLDOWN.get(), Unit.INSTANCE, 20L);
this.increaseAngerAt(entity);
WardenBrain.setDisturbanceLocation(this, entity.blockPosition());
WardenBrain.lookAtDisturbance(this, entity.blockPosition());
}
super.doPush(entity);
@ -518,14 +524,22 @@ public class Warden extends Monster implements VibrationHandler.VibrationConfig
if (!this.getAngriness().isAngry()) {
Optional<LivingEntity> primeSuspect = this.angerManager.getPrimeSuspect();
if (source != null || primeSuspect.isEmpty() || primeSuspect.get() == entity) {
WardenBrain.setDisturbanceLocation(this, position);
WardenBrain.lookAtDisturbance(this, position);
}
}
}
}
@Nullable @Override
@Nullable
@Override
public GameEventListenerRegistrar getGameEventListenerRegistrar() {
return this.gameEventHandler;
}
public boolean closerThan(Entity entity, double xzRange, double yRange) {
double x = entity.getX() - this.getX();
double y = entity.getY() - this.getY();
double z = entity.getZ() - this.getZ();
return Mth.lengthSquared(x, z) < Mth.square(xzRange) && Mth.square(y) < Mth.square(yRange);
}
}

View File

@ -0,0 +1,41 @@
package com.cursedcauldron.wildbackport.common.entities.access;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.entity.LevelCallback;
import net.minecraft.world.level.gameevent.GameEventListener;
import net.minecraft.world.level.gameevent.GameEventListenerRegistrar;
import javax.annotation.Nullable;
import java.util.function.BiConsumer;
public class Listener {
public interface Instance {
static Instance of(GameEventListenerRegistrar instance) {
return (Instance)instance;
}
void onPosCallback(Level level);
void setListener(GameEventListener listener, @Nullable Level level);
GameEventListener getListener();
}
public interface MobInstance {
static MobInstance of(Entity entity) {
return MobInstance.class.cast(entity);
}
default void updateEventHandler(BiConsumer<GameEventListenerRegistrar, Level> callback) {
}
}
public interface Callback<T> extends LevelCallback<T> {
@SuppressWarnings("unchecked")
static <T> Callback<T> of(T entity) {
return (Callback<T>)entity;
}
void onSectionChange(T entry);
}
}

View File

@ -10,7 +10,7 @@ import com.cursedcauldron.wildbackport.common.entities.brain.frog.WalkTowardsLan
import com.cursedcauldron.wildbackport.common.entities.brain.frog.WalkTowardsWater;
import com.cursedcauldron.wildbackport.common.registry.WBBlocks;
import com.cursedcauldron.wildbackport.common.registry.entity.WBActivities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.tag.WBBlockTags;
import com.google.common.collect.ImmutableList;
@ -72,7 +72,7 @@ public class FrogBrain {
}
private static void addIdleActivities(Brain<Frog> brain) {
brain.addActivityWithConditions(Activity.IDLE, ImmutableList.of(Pair.of(0, new RunSometimes<LivingEntity>(new SetEntityLookTarget(EntityType.PLAYER, 6.0F), UniformInt.of(30, 60))), Pair.of(0, new AnimalMakeLove(WBEntities.FROG.get(), 1.0F)), Pair.of(1, new FollowTemptation(entity -> 1.25F)), Pair.of(2, new StartAttacking<>(FrogBrain::isNotBreeding, frog -> frog.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE))), Pair.of(3, new WalkTowardsLand(6, 1.0F)), Pair.of(4, new RunOne<>(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), ImmutableList.of(Pair.of(new RandomStroll(1.0F), 1), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 1), Pair.of(new Croak(), 3), Pair.of(new RunIf<>(Entity::isOnGround, new DoNothing(5, 20)), 2))))), ImmutableSet.of(Pair.of(MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_IN_WATER.get(), MemoryStatus.VALUE_ABSENT)));
brain.addActivityWithConditions(Activity.IDLE, ImmutableList.of(Pair.of(0, new RunSometimes<LivingEntity>(new SetEntityLookTarget(EntityType.PLAYER, 6.0F), UniformInt.of(30, 60))), Pair.of(0, new AnimalMakeLove(WBEntityTypes.FROG.get(), 1.0F)), Pair.of(1, new FollowTemptation(entity -> 1.25F)), Pair.of(2, new StartAttacking<>(FrogBrain::isNotBreeding, frog -> frog.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE))), Pair.of(3, new WalkTowardsLand(6, 1.0F)), Pair.of(4, new RunOne<>(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), ImmutableList.of(Pair.of(new RandomStroll(1.0F), 1), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 1), Pair.of(new Croak(), 3), Pair.of(new RunIf<>(Entity::isOnGround, new DoNothing(5, 20)), 2))))), ImmutableSet.of(Pair.of(MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_IN_WATER.get(), MemoryStatus.VALUE_ABSENT)));
}
private static void addSwimActivities(Brain<Frog> brain) {

View File

@ -42,7 +42,7 @@ public class TadpoleBrain {
}
private static void addIdleActivities(Brain<Tadpole> brain) {
brain.addActivity(Activity.IDLE, ImmutableList.of(Pair.of(0, new RunSometimes<LivingEntity>(new SetEntityLookTarget(EntityType.PLAYER, 6.0f), UniformInt.of(30, 60))), Pair.of(3, new TryFindWater(6, 0.15f)), Pair.of(4, new GateBehavior<>(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), ImmutableSet.of(), GateBehavior.OrderPolicy.ORDERED, GateBehavior.RunningPolicy.TRY_ALL, ImmutableList.of(Pair.of(new RandomSwim(0.5f), 2), Pair.of(new RandomStroll(0.15f), 2), Pair.of(new SetWalkTargetFromLookTarget(0.5f, 3), 3), Pair.of(new RunIf<>(Entity::isInWaterOrBubble, new DoNothing(30, 60)), 5))))));
brain.addActivity(Activity.IDLE, ImmutableList.of(Pair.of(0, new RunSometimes<LivingEntity>(new SetEntityLookTarget(EntityType.PLAYER, 6.0f), UniformInt.of(30, 60))), Pair.of(3, new TryFindWater(6, 0.15f)), Pair.of(4, new GateBehavior<>(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT), ImmutableSet.of(), GateBehavior.OrderPolicy.ORDERED, GateBehavior.RunningPolicy.TRY_ALL, ImmutableList.of(Pair.of(new RandomSwim(0.5F), 2), Pair.of(new RandomStroll(0.15F), 2), Pair.of(new SetWalkTargetFromLookTarget(0.5f, 3), 3), Pair.of(new RunIf<>(Entity::isInWaterOrBubble, new DoNothing(30, 60)), 5))))));
}
public static void updateActivities(Tadpole tadpole) {

View File

@ -1,17 +1,17 @@
package com.cursedcauldron.wildbackport.common.entities.brain;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.ForgetAttackTarget;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.Digging;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.Dismount;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.Emerging;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.ForgetAttackTarget;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.GoToTargetLocation;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.Roar;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.SetRoarTarget;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.FindRoarTarget;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.SetWardenLookTarget;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.Sniffing;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.SonicBoom;
import com.cursedcauldron.wildbackport.common.entities.brain.warden.TryToSniff;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.common.registry.entity.WBActivities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.registry.entity.WBSensorTypes;
@ -49,24 +49,24 @@ import java.util.List;
//<>
public class WardenBrain {
private static final int DIGGING_DURATION = Mth.ceil(100.0F);
public static final int EMERGE_DURATION = Mth.ceil(133.59999F);
public static final int ROAR_DURATION = Mth.ceil(84.0F);
private static final int SNIFFING_DURATION = Mth.ceil(83.2F);
private static final List<SensorType<? extends Sensor<? super Warden>>> SENSORS = List.of(SensorType.NEAREST_PLAYERS, WBSensorTypes.WARDEN_ENTITY_SENSOR.get());
private static final List<MemoryModuleType<?>> MEMORIES = List.of(MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_ATTACKABLE, WBMemoryModules.ROAR_TARGET.get(), WBMemoryModules.DISTURBANCE_LOCATION.get(), WBMemoryModules.RECENT_PROJECTILE.get(), WBMemoryModules.IS_SNIFFING.get(), WBMemoryModules.IS_EMERGING.get(), WBMemoryModules.ROAR_SOUND_DELAY.get(), WBMemoryModules.DIG_COOLDOWN.get(), WBMemoryModules.ROAR_SOUND_COOLDOWN.get(), WBMemoryModules.SNIFF_COOLDOWN.get(), WBMemoryModules.TOUCH_COOLDOWN.get(), WBMemoryModules.VIBRATION_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get());
private static final int DIGGING_DURATION = Mth.ceil(100.0F);
public static final int EMERGE_DURATION = Mth.ceil(133.59999F);
public static final int ROAR_DURATION = Mth.ceil(84.0F);
private static final int SNIFFING_DURATION = Mth.ceil(83.2F);
private static final List<SensorType<? extends Sensor<? super Warden>>> SENSOR_TYPES = List.of(SensorType.NEAREST_PLAYERS, WBSensorTypes.WARDEN_ENTITY_SENSOR.get());
private static final List<MemoryModuleType<?>> MEMORY_TYPES = List.of(MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_ATTACKABLE, WBMemoryModules.ROAR_TARGET.get(), WBMemoryModules.DISTURBANCE_LOCATION.get(), WBMemoryModules.RECENT_PROJECTILE.get(), WBMemoryModules.IS_SNIFFING.get(), WBMemoryModules.IS_EMERGING.get(), WBMemoryModules.ROAR_SOUND_DELAY.get(), WBMemoryModules.DIG_COOLDOWN.get(), WBMemoryModules.ROAR_SOUND_COOLDOWN.get(), WBMemoryModules.SNIFF_COOLDOWN.get(), WBMemoryModules.TOUCH_COOLDOWN.get(), WBMemoryModules.VIBRATION_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get());
private static final Behavior<Warden> DIG_COOLDOWN_SETTER = new Behavior<>(ImmutableMap.of(WBMemoryModules.DIG_COOLDOWN.get(), MemoryStatus.REGISTERED)) {
@Override protected void start(ServerLevel level, Warden warden, long time) {
setDigCooldown(warden);
resetDigCooldown(warden);
}
};
public static void updateActivity(Warden warden) {
public static void updateActivities(Warden warden) {
warden.getBrain().setActiveActivityToFirstValid(ImmutableList.of(WBActivities.EMERGE.get(), WBActivities.DIG.get(), WBActivities.ROAR.get(), Activity.FIGHT, WBActivities.INVESTIGATE.get(), WBActivities.SNIFF.get(), Activity.IDLE));
}
public static Brain<?> makeBrain(Warden warden, Dynamic<?> dynamic) {
Brain.Provider<Warden> provider = Brain.provider(MEMORIES, SENSORS);
Brain.Provider<Warden> provider = Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
Brain<Warden> brain = provider.makeBrain(dynamic);
initCoreActivity(brain);
initEmergeActivity(brain);
@ -95,15 +95,15 @@ public class WardenBrain {
}
private static void initIdleActivity(Brain<Warden> brain) {
brain.addActivity(Activity.IDLE, 10, ImmutableList.of(new SetRoarTarget<>(Warden::getPrimeSuspect), new TryToSniff(), new RunOne<>(ImmutableMap.of(WBMemoryModules.IS_SNIFFING.get(), MemoryStatus.VALUE_ABSENT), ImmutableList.of(Pair.of(new RandomStroll(0.5F), 2), Pair.of(new DoNothing(30, 60), 1)))));
brain.addActivity(Activity.IDLE, 10, ImmutableList.of(new FindRoarTarget<>(Warden::getPrimeSuspect), new TryToSniff(), new RunOne<>(ImmutableMap.of(WBMemoryModules.IS_SNIFFING.get(), MemoryStatus.VALUE_ABSENT), ImmutableList.of(Pair.of(new RandomStroll(0.5F), 2), Pair.of(new DoNothing(30, 60), 1)))));
}
private static void initInvestigateActivity(Brain<Warden> brain) {
brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.INVESTIGATE.get(), 5, ImmutableList.of(new SetRoarTarget<>(Warden::getPrimeSuspect), new GoToTargetLocation<>(WBMemoryModules.DISTURBANCE_LOCATION.get(), 2, 0.7F)), WBMemoryModules.DISTURBANCE_LOCATION.get());
brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.INVESTIGATE.get(), 5, ImmutableList.of(new FindRoarTarget<>(Warden::getPrimeSuspect), new GoToTargetLocation<>(WBMemoryModules.DISTURBANCE_LOCATION.get(), 2, 0.7F)), WBMemoryModules.DISTURBANCE_LOCATION.get());
}
private static void initSniffingActivity(Brain<Warden> brain) {
brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.SNIFF.get(), 5, ImmutableList.of(new SetRoarTarget<>(Warden::getPrimeSuspect), new Sniffing<>(SNIFFING_DURATION)), WBMemoryModules.IS_SNIFFING.get());
brain.addActivityAndRemoveMemoryWhenStopped(WBActivities.SNIFF.get(), 5, ImmutableList.of(new FindRoarTarget<>(Warden::getPrimeSuspect), new Sniffing<>(SNIFFING_DURATION)), WBMemoryModules.IS_SNIFFING.get());
}
private static void initRoarActivity(Brain<Warden> brain) {
@ -111,29 +111,27 @@ public class WardenBrain {
}
private static void initFightActivity(Warden warden, Brain<Warden> brain) {
brain.addActivityAndRemoveMemoryWhenStopped(Activity.FIGHT, 10, ImmutableList.of(DIG_COOLDOWN_SETTER, new ForgetAttackTarget<>(target -> {
return !warden.getAngriness().isAngry() || !warden.isValidTarget(target);
}, WardenBrain::onTargetInvalid, false), new SetEntityLookTarget(target -> {
return isTarget(warden, target);
}, (float)warden.getAttributeValue(Attributes.FOLLOW_RANGE)), new SetWalkTargetFromAttackTargetIfTargetOutOfReach(1.2F), new SonicBoom(), new MeleeAttack(18)), MemoryModuleType.ATTACK_TARGET);
brain.addActivityAndRemoveMemoryWhenStopped(Activity.FIGHT, 10, ImmutableList.of(DIG_COOLDOWN_SETTER, new ForgetAttackTarget<>(entity -> !warden.getAngriness().isAngry() || !warden.isValidTarget(entity), WardenBrain::removeDeadSuspect, false), new SetEntityLookTarget(entity -> isTargeting(warden, entity), (float)warden.getAttributeValue(Attributes.FOLLOW_RANGE)), new SetWalkTargetFromAttackTargetIfTargetOutOfReach(1.2F), new SonicBoom(), new MeleeAttack(18)), MemoryModuleType.ATTACK_TARGET);
}
private static boolean isTarget(Warden warden, LivingEntity entity) {
private static boolean isTargeting(Warden warden, LivingEntity entity) {
return warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).filter(target -> target == entity).isPresent();
}
private static void onTargetInvalid(Warden warden, LivingEntity entity) {
if (!warden.isValidTarget(entity)) warden.removeSuspect(entity);
setDigCooldown(warden);
private static void removeDeadSuspect(Warden warden, LivingEntity suspect) {
if (!warden.isValidTarget(suspect)) warden.removeSuspect(suspect);
resetDigCooldown(warden);
}
public static void setDigCooldown(LivingEntity entity) {
if (entity.getBrain().hasMemoryValue(WBMemoryModules.DIG_COOLDOWN.get())) entity.getBrain().setMemoryWithExpiry(WBMemoryModules.DIG_COOLDOWN.get(), Unit.INSTANCE, 1200L);
public static void resetDigCooldown(LivingEntity warden) {
if (warden.getBrain().hasMemoryValue(WBMemoryModules.DIG_COOLDOWN.get())) {
warden.getBrain().setMemoryWithExpiry(WBMemoryModules.DIG_COOLDOWN.get(), Unit.INSTANCE, 1200L);
}
}
public static void setDisturbanceLocation(Warden warden, BlockPos pos) {
public static void lookAtDisturbance(Warden warden, BlockPos pos) {
if (warden.level.getWorldBorder().isWithinBounds(pos) && warden.getPrimeSuspect().isEmpty() && warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).isEmpty()) {
setDigCooldown(warden);
resetDigCooldown(warden);
warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SNIFF_COOLDOWN.get(), Unit.INSTANCE, 100L);
warden.getBrain().setMemoryWithExpiry(MemoryModuleType.LOOK_TARGET, new BlockPosTracker(pos), 100L);
warden.getBrain().setMemoryWithExpiry(WBMemoryModules.DISTURBANCE_LOCATION.get(), pos, 100L);

View File

@ -12,24 +12,24 @@ import net.minecraft.world.entity.ai.memory.MemoryStatus;
import java.util.Optional;
import java.util.function.Function;
public class SetRoarTarget<E extends Warden> extends Behavior<E> {
public class FindRoarTarget<E extends Warden> extends Behavior<E> {
private final Function<E, Optional<? extends LivingEntity>> targetFinder;
public SetRoarTarget(Function<E, Optional<? extends LivingEntity>> target) {
public FindRoarTarget(Function<E, Optional<? extends LivingEntity>> targetFinder) {
super(ImmutableMap.of(WBMemoryModules.ROAR_TARGET.get(), MemoryStatus.VALUE_ABSENT, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryStatus.REGISTERED));
this.targetFinder = target;
this.targetFinder = targetFinder;
}
@Override
protected boolean checkExtraStartConditions(ServerLevel level, E entity) {
return this.targetFinder.apply(entity).filter(entity::isValidTarget).isPresent();
protected boolean checkExtraStartConditions(ServerLevel level, E warden) {
return this.targetFinder.apply(warden).filter(warden::isValidTarget).isPresent();
}
@Override
protected void start(ServerLevel level, E entity, long time) {
this.targetFinder.apply(entity).ifPresent(target -> {
entity.getBrain().setMemory(WBMemoryModules.ROAR_TARGET.get(), target);
entity.getBrain().eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
protected void start(ServerLevel level, E warden, long time) {
this.targetFinder.apply(warden).ifPresent(target -> {
warden.getBrain().setMemory(WBMemoryModules.ROAR_TARGET.get(), target);
warden.getBrain().eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
});
}
}

View File

@ -13,34 +13,34 @@ import java.util.function.BiConsumer;
import java.util.function.Predicate;
public class ForgetAttackTarget<E extends Mob> extends Behavior<E> {
private final Predicate<LivingEntity> stopAttackingWhen;
private final BiConsumer<E, LivingEntity> onTargetErased;
private final boolean canGrowTiredOfTryingToReachTarget;
private final Predicate<LivingEntity> alternativeCondition;
private final BiConsumer<E, LivingEntity> forgetCallback;
private final boolean shouldForgetIfTargetUnreachable;
public ForgetAttackTarget(Predicate<LivingEntity> stopAttackingWhen, BiConsumer<E, LivingEntity> onTargetEased, boolean canGrowTiredOfTryingToReachTarget) {
public ForgetAttackTarget(Predicate<LivingEntity> alternativeCondition, BiConsumer<E, LivingEntity> forgetCallback, boolean shouldForgetIfTargetUnreachable) {
super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryStatus.REGISTERED));
this.stopAttackingWhen = stopAttackingWhen;
this.onTargetErased = onTargetEased;
this.canGrowTiredOfTryingToReachTarget = canGrowTiredOfTryingToReachTarget;
this.alternativeCondition = alternativeCondition;
this.forgetCallback = forgetCallback;
this.shouldForgetIfTargetUnreachable = shouldForgetIfTargetUnreachable;
}
@Override
protected void start(ServerLevel level, E entity, long time) {
LivingEntity target = this.getAttackTarget(entity);
if (!entity.canAttack(target)) {
this.clearAttackTarget(entity);
} else if (this.canGrowTiredOfTryingToReachTarget && isTiredOfTryingToReachTarget(entity)) {
this.clearAttackTarget(entity);
} else if (this.isCurrentTargetDeadOrRemoved(entity)) {
this.clearAttackTarget(entity);
} else if (this.isCurrentTargetInDifferentLevel(entity)) {
this.clearAttackTarget(entity);
} else if (this.stopAttackingWhen.test(this.getAttackTarget(entity))) {
this.clearAttackTarget(entity);
this.forgetAttackTarget(entity);
} else if (this.shouldForgetIfTargetUnreachable && cannotReachTarget(entity)) {
this.forgetAttackTarget(entity);
} else if (this.isAttackTargetDead(entity)) {
this.forgetAttackTarget(entity);
} else if (this.isAttackTargetInAnotherWorld(entity)) {
this.forgetAttackTarget(entity);
} else if (this.alternativeCondition.test(this.getAttackTarget(entity))) {
this.forgetAttackTarget(entity);
}
}
private boolean isCurrentTargetInDifferentLevel(E entity) {
private boolean isAttackTargetInAnotherWorld(E entity) {
return this.getAttackTarget(entity).level != entity.level;
}
@ -48,18 +48,18 @@ public class ForgetAttackTarget<E extends Mob> extends Behavior<E> {
return entity.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get();
}
private static <E extends LivingEntity> boolean isTiredOfTryingToReachTarget(E entity) {
private static <E extends LivingEntity> boolean cannotReachTarget(E entity) {
Optional<Long> time = entity.getBrain().getMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
return time.isPresent() && entity.level.getGameTime() - time.get() > 200L;
}
private boolean isCurrentTargetDeadOrRemoved(E entity) {
private boolean isAttackTargetDead(E entity) {
Optional<LivingEntity> target = entity.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET);
return target.isPresent() && !target.get().isAlive();
}
protected void clearAttackTarget(E entity) {
this.onTargetErased.accept(entity, this.getAttackTarget(entity));
protected void forgetAttackTarget(E entity) {
this.forgetCallback.accept(entity, this.getAttackTarget(entity));
entity.getBrain().eraseMemory(MemoryModuleType.ATTACK_TARGET);
}
}

View File

@ -17,18 +17,18 @@ import java.util.Set;
public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T> {
@Override
protected void doTick(ServerLevel level, T entity) {
AABB box = entity.getBoundingBox().inflate(this.radiusXZ(), this.radiusY(), this.radiusXZ());
List<LivingEntity> entities = level.getEntitiesOfClass(LivingEntity.class, box, (target) -> target != entity && target.isAlive());
AABB box = entity.getBoundingBox().inflate(this.getHorizontalExpansion(), this.getHeightExpansion(), this.getHorizontalExpansion());
List<LivingEntity> entities = level.getEntitiesOfClass(LivingEntity.class, box, target -> target != entity && target.isAlive());
entities.sort(Comparator.comparingDouble(entity::distanceToSqr));
entity.getBrain().setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entities);
entity.getBrain().setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(entity, entities));
}
protected int radiusXZ() {
protected int getHorizontalExpansion() {
return 16;
}
protected int radiusY() {
protected int getHeightExpansion() {
return 16;
}

View File

@ -1,8 +1,8 @@
package com.cursedcauldron.wildbackport.common.entities.brain.warden;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.access.api.Poses;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.common.entities.access.api.Poses;
import com.cursedcauldron.wildbackport.common.entities.brain.WardenBrain;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.google.common.collect.ImmutableMap;
@ -23,10 +23,10 @@ public class Roar extends Behavior<Warden> {
@Override
protected void start(ServerLevel level, Warden warden, long time) {
Brain<Warden> brain = warden.getBrain();
brain.setMemoryWithExpiry(WBMemoryModules.ROAR_SOUND_DELAY.get(), Unit.INSTANCE, 25L);
Brain<?> brain = warden.getBrain();
brain.setMemoryWithExpiry(WBMemoryModules.ROAR_SOUND_DELAY.get(), Unit.INSTANCE, 26L);
brain.eraseMemory(MemoryModuleType.WALK_TARGET);
LivingEntity target = brain.getMemory(WBMemoryModules.ROAR_TARGET.get()).get();
LivingEntity target = warden.getBrain().getMemory(WBMemoryModules.ROAR_TARGET.get()).get();
BehaviorUtils.lookAtEntity(warden, target);
warden.setPose(Poses.ROARING.get());
warden.increaseAngerAt(target, 20, false);
@ -48,7 +48,6 @@ public class Roar extends Behavior<Warden> {
@Override
protected void stop(ServerLevel level, Warden warden, long time) {
if (warden.hasPose(Poses.ROARING.get())) warden.setPose(Pose.STANDING);
warden.getBrain().getMemory(WBMemoryModules.ROAR_TARGET.get()).ifPresent(warden::updateAttackTarget);
warden.getBrain().eraseMemory(WBMemoryModules.ROAR_TARGET.get());
}

View File

@ -5,7 +5,6 @@ import com.cursedcauldron.wildbackport.common.entities.access.api.Poses;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.common.entities.brain.WardenBrain;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.utils.MobUtils;
import com.google.common.collect.ImmutableMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Pose;
@ -36,12 +35,12 @@ public class Sniffing<E extends Warden> extends Behavior<E> {
entity.getBrain().eraseMemory(WBMemoryModules.IS_SNIFFING.get());
entity.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE).filter(entity::isValidTarget).ifPresent(target -> {
if (MobUtils.closerThan(entity, target, 6.0D, 20.0D)) {
if (entity.closerThan(target, 6.0D, 20.0D)) {
entity.increaseAngerAt(target);
}
if (!entity.getBrain().hasMemoryValue(WBMemoryModules.DISTURBANCE_LOCATION.get())) {
WardenBrain.setDisturbanceLocation(entity, target.blockPosition());
WardenBrain.lookAtDisturbance(entity, target.blockPosition());
}
});
}

View File

@ -4,7 +4,6 @@ import com.cursedcauldron.wildbackport.client.registry.WBParticleTypes;
import com.cursedcauldron.wildbackport.client.registry.WBSoundEvents;
import com.cursedcauldron.wildbackport.common.entities.Warden;
import com.cursedcauldron.wildbackport.common.registry.entity.WBMemoryModules;
import com.cursedcauldron.wildbackport.common.utils.MobUtils;
import com.cursedcauldron.wildbackport.core.mixin.access.DamageSourceAccessor;
import com.google.common.collect.ImmutableMap;
import net.minecraft.server.level.ServerLevel;
@ -23,16 +22,16 @@ import net.minecraft.world.phys.Vec3;
//<>
public class SonicBoom extends Behavior<Warden> {
private static final int TICKS_BEFORE_PLAYING_SOUND = Mth.ceil(34.0D);
private static final int SOUND_DELAY = Mth.ceil(34.0D);
private static final int DURATION = Mth.ceil(60.0F);
public SonicBoom() {
super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT, WBMemoryModules.SONIC_BOOM_COOLDOWN.get(), MemoryStatus.VALUE_ABSENT, WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), MemoryStatus.REGISTERED, WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get(), MemoryStatus.REGISTERED), DURATION);
}
@Override
protected boolean checkExtraStartConditions(ServerLevel level, Warden warden) {
return MobUtils.closerThan(warden, warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(), 15.0D, 20.0D);
return warden.closerThan(warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(), 15.0D, 20.0D);
}
@Override
@ -43,8 +42,8 @@ public class SonicBoom extends Behavior<Warden> {
@Override
protected void start(ServerLevel level, Warden warden, long time) {
warden.getBrain().setMemoryWithExpiry(MemoryModuleType.ATTACK_COOLING_DOWN, true, DURATION);
warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get(), Unit.INSTANCE, TICKS_BEFORE_PLAYING_SOUND);
level.broadcastEntityEvent(warden, (byte)62);
warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get(), Unit.INSTANCE, SOUND_DELAY + 5);
level.broadcastEntityEvent(warden, Warden.SONIC_BOOM);
warden.playSound(WBSoundEvents.WARDEN_SONIC_CHARGE, 3.0F, 1.0F);
}
@ -52,14 +51,14 @@ public class SonicBoom extends Behavior<Warden> {
protected void tick(ServerLevel level, Warden warden, long time) {
warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).ifPresent(target -> warden.getLookControl().setLookAt(target.position()));
if (!warden.getBrain().hasMemoryValue(WBMemoryModules.SONIC_BOOM_SOUND_DELAY.get()) && !warden.getBrain().hasMemoryValue(WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get())) {
warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), Unit.INSTANCE, DURATION - TICKS_BEFORE_PLAYING_SOUND);
warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).filter(warden::isValidTarget).filter(target -> MobUtils.closerThan(warden, target, 15.0D, 20.0D)).ifPresent(target -> {
Vec3 source = warden.position().add(0.0D, 1.6F, 0.0D);
Vec3 distance = target.getEyePosition().subtract(source);
Vec3 position = distance.normalize();
warden.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_SOUND_COOLDOWN.get(), Unit.INSTANCE, DURATION - SOUND_DELAY + 5);
warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).filter(warden::isValidTarget).filter(target -> warden.closerThan(target, 15.0D, 20.0D)).ifPresent(target -> {
Vec3 sourcePos = warden.position().add(0.0D, 1.6F, 0.0D);
Vec3 targetPos = target.getEyePosition().subtract(sourcePos);
Vec3 distance = targetPos.normalize();
for(int i = 1; i < Mth.floor(distance.length()) + 7; ++i) {
Vec3 charge = source.add(position.scale(i));
for(int i = 1; i < Mth.floor(targetPos.length()) + 7; ++i) {
Vec3 charge = sourcePos.add(distance.scale(i));
level.sendParticles(WBParticleTypes.SONIC_BOOM.get(), charge.x, charge.y, charge.z, 1, 0.0D, 0.0D, 0.0D, 0.0D);
}
@ -67,20 +66,21 @@ public class SonicBoom extends Behavior<Warden> {
target.hurt(sonicBoom(warden), 10.0F);
double yKnockback = 0.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
double xzKnockback = 2.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
target.push(position.x() * xzKnockback, position.y() * yKnockback, position.z() * xzKnockback);
target.push(distance.x() * xzKnockback, distance.y() * yKnockback, distance.z() * xzKnockback);
});
}
}
@Override
protected void stop(ServerLevel level, Warden warden, long time) {
setCooldown(warden, 40);
SonicBoom.setCooldown(warden, 60L);
}
public static void setCooldown(LivingEntity entity, int cooldown) {
public static void setCooldown(LivingEntity entity, long cooldown) {
entity.getBrain().setMemoryWithExpiry(WBMemoryModules.SONIC_BOOM_COOLDOWN.get(), Unit.INSTANCE, cooldown);
}
@SuppressWarnings("ConstantConditions")
public static DamageSource sonicBoom(Entity entity) {
return ((DamageSourceAccessor)new EntityDamageSource("sonic_boom", entity)).callBypassArmor().setMagic();
}

View File

@ -23,30 +23,20 @@ public class WardenEntitySensor extends NearestLivingEntitySensor<Warden> {
@Override
protected void doTick(ServerLevel level, Warden warden) {
super.doTick(level, warden);
getClosest(warden, target -> {
return target.getType() == EntityType.PLAYER;
}).or(() -> {
return getClosest(warden, target -> {
return target.getType() != EntityType.PLAYER;
});
}).ifPresentOrElse(target -> {
warden.getBrain().setMemory(MemoryModuleType.NEAREST_ATTACKABLE, target);
}, () -> {
warden.getBrain().eraseMemory(MemoryModuleType.NEAREST_ATTACKABLE);
});
findNearestTarget(warden, target -> target.getType() == EntityType.PLAYER).or(() -> findNearestTarget(warden, target -> target.getType() != EntityType.PLAYER)).ifPresentOrElse(target -> warden.getBrain().setMemory(MemoryModuleType.NEAREST_ATTACKABLE, target), () -> warden.getBrain().eraseMemory(MemoryModuleType.NEAREST_ATTACKABLE));
}
private static Optional<LivingEntity> getClosest(Warden warden, Predicate<LivingEntity> targetFilter) {
return warden.getBrain().getMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES).stream().flatMap(Collection::stream).filter(warden::isValidTarget).filter(targetFilter).findFirst();
private static Optional<LivingEntity> findNearestTarget(Warden warden, Predicate<LivingEntity> targetPredicate) {
return warden.getBrain().getMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES).stream().flatMap(Collection::stream).filter(warden::isValidTarget).filter(targetPredicate).findFirst();
}
@Override
protected int radiusXZ() {
protected int getHorizontalExpansion() {
return 24;
}
@Override
protected int radiusY() {
protected int getHeightExpansion() {
return 24;
}
}

View File

@ -6,6 +6,7 @@ import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import net.minecraft.core.SerializableUUID;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ExtraCodecs;
@ -13,12 +14,11 @@ import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Random;
@ -29,135 +29,147 @@ import java.util.stream.Collectors;
//<>
public class WardenAngerManager {
private int updateTimer = Mth.randomBetweenInclusive(new Random(System.nanoTime()), 0, 2);
private int updateTimer = Mth.randomBetweenInclusive(new Random(), 0, 2);
int primeAnger;
private static final Codec<Pair<UUID, Integer>> SUSPECT_CODEC = RecordCodecBuilder.create(instance -> instance.group(SerializableUUID.CODEC.fieldOf("uuid").forGetter(Pair::getFirst), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("anger").forGetter(Pair::getSecond)).apply(instance, Pair::of));
private final Predicate<Entity> validTarget;
private final Predicate<Entity> suspectPredicate;
protected final ArrayList<Entity> suspects;
private final SuspectComparator suspectComparator;
protected final Object2IntMap<Entity> suspectsToAngerLevel;
protected final Object2IntMap<UUID> suspectUuidsToAngerLevel;
public static Codec<WardenAngerManager> createCodec(Predicate<Entity> validTarget) {
public static Codec<WardenAngerManager> codec(Predicate<Entity> validTarget) {
return RecordCodecBuilder.create(instance -> instance.group(SUSPECT_CODEC.listOf().fieldOf("suspects").orElse(Collections.emptyList()).forGetter(WardenAngerManager::getSuspects)).apply(instance, suspects -> new WardenAngerManager(validTarget, suspects)));
}
public WardenAngerManager(Predicate<Entity> validTarget, List<Pair<UUID, Integer>> suspects) {
this.validTarget = validTarget;
public WardenAngerManager(Predicate<Entity> suspectPredicate, List<Pair<UUID, Integer>> suspectUuidsToAngerLevel) {
this.suspectPredicate = suspectPredicate;
this.suspects = new ArrayList<>();
this.suspectComparator = new SuspectComparator(this);
this.suspectsToAngerLevel = new Object2IntOpenHashMap<>();
this.suspectUuidsToAngerLevel = new Object2IntOpenHashMap<>(suspects.size());
suspects.forEach(pair -> this.suspectUuidsToAngerLevel.put(pair.getFirst(), pair.getSecond()));
this.suspectUuidsToAngerLevel = new Object2IntOpenHashMap<>(suspectUuidsToAngerLevel.size());
suspectUuidsToAngerLevel.forEach(suspect -> this.suspectUuidsToAngerLevel.put(suspect.getFirst(), suspect.getSecond()));
}
private List<Pair<UUID, Integer>> getSuspects() {
return Streams.concat(this.suspects.stream().map(suspect -> Pair.of(suspect.getUUID(), this.suspectsToAngerLevel.getInt(suspect))), this.suspectUuidsToAngerLevel.object2IntEntrySet().stream().map(entry -> Pair.of(entry.getKey(), entry.getIntValue()))).collect(Collectors.toList());
}
public void tick(ServerLevel world, Predicate<Entity> suspectPredicate) {
public void tick(ServerLevel level, Predicate<Entity> suspectPredicate) {
--this.updateTimer;
if (this.updateTimer <= 0) {
this.updateSuspectsMap(world);
this.updateSuspectsMap(level);
this.updateTimer = 2;
}
Iterator<Object2IntMap.Entry<UUID>> uuidAngerLevels = this.suspectUuidsToAngerLevel.object2IntEntrySet().iterator();
while (uuidAngerLevels.hasNext()) {
Object2IntMap.Entry<UUID> entry = uuidAngerLevels.next();
int level = entry.getIntValue();
if (level <= 1) {
uuidAngerLevels.remove();
ObjectIterator<Object2IntMap.Entry<UUID>> uuidToAnger = this.suspectUuidsToAngerLevel.object2IntEntrySet().iterator();
while(uuidToAnger.hasNext()) {
Object2IntMap.Entry<UUID> entry = uuidToAnger.next();
int anger = entry.getIntValue();
if (anger <= 1) {
uuidToAnger.remove();
} else {
entry.setValue(level - 1);
entry.setValue(anger - 1);
}
}
Iterator<Object2IntMap.Entry<Entity>> angerLevels = this.suspectsToAngerLevel.object2IntEntrySet().iterator();
while (angerLevels.hasNext()) {
Object2IntMap.Entry<Entity> entry = angerLevels.next();
int level = entry.getIntValue();
ObjectIterator<Object2IntMap.Entry<Entity>> suspectToAnger = this.suspectsToAngerLevel.object2IntEntrySet().iterator();
while(suspectToAnger.hasNext()) {
Object2IntMap.Entry<Entity> entry = suspectToAnger.next();
int anger = entry.getIntValue();
Entity entity = entry.getKey();
Entity.RemovalReason reason = entity.getRemovalReason();
if (level > 1 && suspectPredicate.test(entity) && reason == null) {
entry.setValue(level - 1);
if (anger > 1 && suspectPredicate.test(entity) && reason == null) {
entry.setValue(anger - 1);
} else {
this.suspects.remove(entity);
angerLevels.remove();
if (level > 1 && reason != null) {
suspectToAnger.remove();
if (anger > 1 && reason != null) {
switch (reason) {
case CHANGED_DIMENSION, UNLOADED_TO_CHUNK, UNLOADED_WITH_PLAYER -> this.suspectUuidsToAngerLevel.put(entity.getUUID(), level - 1);
case CHANGED_DIMENSION, UNLOADED_TO_CHUNK, UNLOADED_WITH_PLAYER -> this.suspectUuidsToAngerLevel.put(entity.getUUID(), anger - 1);
}
}
}
}
this.suspects.sort(this.suspectComparator);
this.updatePrimeAnger();
}
private void updateSuspectsMap(ServerLevel world) {
Iterator<Object2IntMap.Entry<UUID>> angerLevels = this.suspectUuidsToAngerLevel.object2IntEntrySet().iterator();
private void updatePrimeAnger() {
this.primeAnger = 0;
this.suspects.sort(this.suspectComparator);
if (this.suspects.size() == 1) this.primeAnger = this.suspectsToAngerLevel.getInt(this.suspects.get(0));
}
while (angerLevels.hasNext()) {
Object2IntMap.Entry<UUID> entry = angerLevels.next();
int level = entry.getIntValue();
Entity entity = world.getEntity(entry.getKey());
private void updateSuspectsMap(ServerLevel level) {
ObjectIterator<Object2IntMap.Entry<UUID>> uuidsToAnger = this.suspectUuidsToAngerLevel.object2IntEntrySet().iterator();
while(uuidsToAnger.hasNext()) {
Object2IntMap.Entry<UUID> entry = uuidsToAnger.next();
int anger = entry.getIntValue();
Entity entity = level.getEntity(entry.getKey());
if (entity != null) {
this.suspectsToAngerLevel.put(entity, level);
this.suspectsToAngerLevel.put(entity, anger);
this.suspects.add(entity);
angerLevels.remove();
uuidsToAnger.remove();
}
}
this.suspects.sort(this.suspectComparator);
}
public int increaseAngerAt(Entity entity, int amount) {
boolean canAffectAnger = !this.suspectsToAngerLevel.containsKey(entity);
int angerValue = this.suspectsToAngerLevel.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount));
if (canAffectAnger) {
int anger = this.suspectUuidsToAngerLevel.removeInt(entity.getUUID());
this.suspectsToAngerLevel.put(entity, angerValue += anger);
boolean isTarget = !this.suspectsToAngerLevel.containsKey(entity);
int angerLevel = this.suspectsToAngerLevel.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount));
if (isTarget) {
int modifier = this.suspectUuidsToAngerLevel.removeInt(entity.getUUID());
this.suspectsToAngerLevel.put(entity, angerLevel += modifier);
this.suspects.add(entity);
}
this.suspects.sort(this.suspectComparator);
return angerValue;
this.updatePrimeAnger();
return angerLevel;
}
public void removeSuspect(Entity entity) {
this.suspectsToAngerLevel.removeInt(entity);
this.suspects.remove(entity);
this.updatePrimeAnger();
}
@Nullable
private Entity getSuspect() {
return this.suspects.stream().filter(this.validTarget).findFirst().orElse(null);
private Entity getPrimeSuspectInternal() {
return this.suspects.stream().filter(this.suspectPredicate).findFirst().orElse(null);
}
public int getPrimeSuspectAnger() {
return this.suspectsToAngerLevel.getInt(this.getSuspect());
public int getAngerFor(@Nullable Entity entity) {
return entity == null ? this.primeAnger : this.suspectsToAngerLevel.getInt(entity);
}
public Optional<LivingEntity> getPrimeSuspect() {
return Optional.ofNullable(this.getSuspect()).filter(suspect -> suspect instanceof LivingEntity).map(suspect -> (LivingEntity)suspect);
return Optional.ofNullable(this.getPrimeSuspectInternal()).filter(suspect -> suspect instanceof LivingEntity).map(suspect -> (LivingEntity)suspect);
}
protected record SuspectComparator(WardenAngerManager angerManagement) implements Comparator<Entity> {
@Override
public int compare(Entity first, Entity second) {
if (first.equals(second)) {
public int compare(Entity firstSuspect, Entity secondSuspect) {
if (firstSuspect.equals(secondSuspect)) {
return 0;
} else {
int firstAngerLevel = this.angerManagement.suspectsToAngerLevel.getOrDefault(first, 0);
int secondAngerLevel = this.angerManagement.suspectsToAngerLevel.getOrDefault(second, 0);
boolean angryTowardsFirst = Angriness.getForAnger(firstAngerLevel).isAngry();
boolean angryTowardsSecond = Angriness.getForAnger(secondAngerLevel).isAngry();
if (angryTowardsFirst != angryTowardsSecond) {
return angryTowardsFirst ? -1 : 1;
} else if (angryTowardsFirst && first instanceof Player != second instanceof Player) {
return first instanceof Player ? -1 : 1;
int angerToFirstSuspect = this.angerManagement.suspectsToAngerLevel.getOrDefault(firstSuspect, 0);
int angerToSecondSuspect = this.angerManagement.suspectsToAngerLevel.getOrDefault(secondSuspect, 0);
this.angerManagement.primeAnger = Math.max(this.angerManagement.primeAnger, Math.max(angerToFirstSuspect, angerToSecondSuspect));
boolean isAngryWithFirstSuspect = Angriness.getForAnger(angerToFirstSuspect).isAngry();
boolean isAngryWithSecondSuspect = Angriness.getForAnger(angerToSecondSuspect).isAngry();
if (isAngryWithFirstSuspect != isAngryWithSecondSuspect) {
return isAngryWithFirstSuspect ? -1 : 1;
} else {
return firstAngerLevel > secondAngerLevel ? -1 : 1;
boolean isFirstSuspectPlayer = firstSuspect instanceof Player;
boolean isSecondSuspectPlayer = secondSuspect instanceof Player;
if (isFirstSuspectPlayer != isSecondSuspectPlayer) {
return isFirstSuspectPlayer ? -1 : 1;
} else {
return Integer.compare(angerToSecondSuspect, angerToFirstSuspect);
}
}
}
}

View File

@ -1,47 +0,0 @@
package com.cursedcauldron.wildbackport.common.events;
import com.cursedcauldron.wildbackport.core.mixin.access.StructureTemplatePoolAccessor;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
import java.util.ArrayList;
import java.util.List;
//<>
public class StructureEvent {
private static final ResourceKey<StructureProcessorList> EMPTY_PROCESSOR_LIST_KEY = ResourceKey.create(Registry.PROCESSOR_LIST_REGISTRY, new ResourceLocation("minecraft", "empty"));
private static void addBuildingToPool(Registry<StructureTemplatePool> templatePoolRegistry,
Registry<StructureProcessorList> processorListRegistry,
ResourceLocation poolRL,
String nbtPieceRL,
int weight) {
Holder<StructureProcessorList> emptyProcessorList = processorListRegistry.getHolderOrThrow(EMPTY_PROCESSOR_LIST_KEY);
StructureTemplatePool pool = templatePoolRegistry.get(poolRL);
if (pool == null) return;
SinglePoolElement piece = SinglePoolElement.legacy(nbtPieceRL, emptyProcessorList).apply(StructureTemplatePool.Projection.RIGID);
StructureTemplatePoolAccessor pools = (StructureTemplatePoolAccessor)pool;
for (int i = 0; i < weight; i++) pools.getTemplates().add(piece);
List<Pair<StructurePoolElement, Integer>> listOfPieceEntries = new ArrayList<>(pools.getRawTemplates());
listOfPieceEntries.add(new Pair<>(piece, weight));
pools.setRawTemplates(listOfPieceEntries);
}
public static void bootstrap() {
// Registry<StructureTemplatePool> templatePoolRegistry = server.registryAccess().registry(Registry.TEMPLATE_POOL_REGISTRY).orElseThrow();
// Registry<StructureProcessorList> processorListRegistry = server.registryAccess().registry(Registry.PROCESSOR_LIST_REGISTRY).orElseThrow();
//
// addBuildingToPool(templatePoolRegistry, processorListRegistry, new ResourceLocation("minecraft:pillager_outpost/features"), "wildbackport:feature_cage_with_allays", 1);
}
}

View File

@ -0,0 +1,36 @@
package com.cursedcauldron.wildbackport.common.events;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.mixin.access.StructureTemplatePoolAccessor;
import com.mojang.datafixers.util.Pair;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.data.worldgen.PillagerOutpostPools;
import net.minecraft.data.worldgen.ProcessorLists;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
import java.util.List;
//<>
public class StructureGeneration {
public static void registerAllayCages() {
PillagerOutpostPools.bootstrap();
StructureGeneration.addToPool(new ResourceLocation("pillager_outpost/features"), new ResourceLocation(WildBackport.MOD_ID, "pillager_outpost/feature_cage_with_allays"), 1);
}
private static void addToPool(ResourceLocation poolId, ResourceLocation pieceId, int weight) {
StructureTemplatePool pool = BuiltinRegistries.TEMPLATE_POOL.get(poolId);
if (pool == null) return;
StructurePoolElement piece = StructurePoolElement.legacy(pieceId.toString(), ProcessorLists.EMPTY).apply(StructureTemplatePool.Projection.RIGID);
List<StructurePoolElement> templates = ((StructureTemplatePoolAccessor)pool).getTemplates();
List<Pair<StructurePoolElement, Integer>> rawTemplates = ((StructureTemplatePoolAccessor)pool).getRawTemplates();
if (templates == null || rawTemplates == null) return;
for (int i = 0; i < weight; i++) templates.add(piece);
rawTemplates.add(Pair.of(piece, weight));
}
}

View File

@ -31,13 +31,13 @@ import java.util.function.Supplier;
//<>
public class TadpoleBucketItem extends BucketItem {
private final Supplier<? extends EntityType<?>> entityTypeSupplier;
private final Supplier<? extends SoundEvent> emptySoundSupplier;
private final Supplier<? extends EntityType<?>> entityType;
private final Supplier<? extends SoundEvent> emptySound;
public TadpoleBucketItem(Supplier<? extends EntityType<?>> type, Fluid fluid, Supplier<? extends SoundEvent> sound, Item.Properties properties) {
public TadpoleBucketItem(Supplier<? extends EntityType<?>> entityType, Fluid fluid, Supplier<? extends SoundEvent> emptySound, Item.Properties properties) {
super(fluid, properties);
this.emptySoundSupplier = sound;
this.entityTypeSupplier = type;
this.entityType = entityType;
this.emptySound = emptySound;
}
public void checkExtraContent(@Nullable Player player, Level level, ItemStack stack, BlockPos pos) {
@ -48,11 +48,11 @@ public class TadpoleBucketItem extends BucketItem {
}
protected void playEmptySound(@Nullable Player player, LevelAccessor access, BlockPos pos) {
access.playSound(player, pos, this.emptySoundSupplier.get(), SoundSource.NEUTRAL, 1.0F, 1.0F);
access.playSound(player, pos, this.emptySound.get(), SoundSource.NEUTRAL, 1.0F, 1.0F);
}
private void spawn(ServerLevel level, ItemStack stack, BlockPos pos) {
Entity entity = this.entityTypeSupplier.get().spawn(level, stack, null, pos, MobSpawnType.BUCKET, true, false);
Entity entity = this.entityType.get().spawn(level, stack, null, pos, MobSpawnType.BUCKET, true, false);
if (entity instanceof Bucketable bucketable) {
bucketable.loadFromBucketTag(stack.getOrCreateTag());
bucketable.setFromBucket(true);
@ -60,7 +60,7 @@ public class TadpoleBucketItem extends BucketItem {
}
public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> components, TooltipFlag tooltip) {
if (this.entityTypeSupplier.get() == EntityType.TROPICAL_FISH) {
if (this.entityType.get() == EntityType.TROPICAL_FISH) {
CompoundTag tag = stack.getTag();
if (tag != null && tag.contains("BucketVariantTag", 3)) {
int variant = tag.getInt("BucketVariantTag");

View File

@ -17,6 +17,4 @@ public class WBBlockEntities {
public static final Supplier<BlockEntityType<SculkCatalystBlockEntity>> SCULK_CATALYST = BLOCKS.register("sculk_catalyst", () -> BlockEntityType.Builder.of(SculkCatalystBlockEntity::new, WBBlocks.SCULK_CATALYST.get()).build(null));
public static final Supplier<BlockEntityType<SculkShriekerBlockEntity>> SCULK_SHRIEKER = BLOCKS.register("sculk_shrieker", () -> BlockEntityType.Builder.of(SculkShriekerBlockEntity::new, WBBlocks.SCULK_SHRIEKER.get()).build(null));
// public static final Supplier<BlockEntityType<MangroveSignBlockEntity>> MANGROVE_SIGN = BLOCKS.register("mangrove_sign", () -> BlockEntityType.Builder.of(MangroveSignBlockEntity::new, WBBlocks.MANGROVE_SIGN.get(), WBBlocks.MANGROVE_WALL_SIGN.get()).build(null));
// public static final Supplier<BlockEntityType<MangroveSignBlockEntity>> MANGROVE_SIGN = BLOCKS.register("mangrove_sign", () -> BlockEntityType.Builder.of(MangroveSignBlockEntity::new, WBBlocks.MANGROVE_SIGN.getFirst().get(), WBBlocks.MANGROVE_SIGN.getSecond().get()).build(null));
}

View File

@ -2,7 +2,7 @@ package com.cursedcauldron.wildbackport.common.registry;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.client.registry.WBSoundTypes;
import com.cursedcauldron.wildbackport.common.blocks.BlockProperties;
import com.cursedcauldron.wildbackport.common.blocks.StateProperties;
import com.cursedcauldron.wildbackport.common.blocks.FrogspawnBlock;
import com.cursedcauldron.wildbackport.common.blocks.MangroveLeavesBlock;
import com.cursedcauldron.wildbackport.common.blocks.MangrovePropaguleBlock;
@ -76,18 +76,18 @@ public class WBBlocks {
public static final Supplier<Block> MANGROVE_FENCE = create("mangrove_fence", () -> new FenceBlock(BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).strength(2.0F, 3.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_DECORATIONS);
public static final Supplier<Block> MANGROVE_FENCE_GATE = create("mangrove_fence_gate", () -> new FenceGateBlock(BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).strength(2.0F, 3.0F).sound(SoundType.WOOD)), CreativeModeTab.TAB_REDSTONE);
public static final Supplier<Block> MANGROVE_DOOR = create("mangrove_door", () -> DoorBlockAccessor.createDoorBlock(BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).strength(3.0F).sound(SoundType.WOOD).noOcclusion()), CreativeModeTab.TAB_REDSTONE);
public static final Supplier<Block> MANGROVE_TRAPDOOR = create("mangrove_trapdoor", () -> TrapDoorBlockAccessor.createTrapDoorBlock(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(3.0F).sound(SoundType.WOOD).noOcclusion().isValidSpawn(BlockProperties::never)), CreativeModeTab.TAB_REDSTONE);
public static final Supplier<Block> MANGROVE_TRAPDOOR = create("mangrove_trapdoor", () -> TrapDoorBlockAccessor.createTrapDoorBlock(BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.COLOR_RED).strength(3.0F).sound(SoundType.WOOD).noOcclusion().isValidSpawn(StateProperties::never)), CreativeModeTab.TAB_REDSTONE);
public static final Supplier<Block> MANGROVE_PRESSURE_PLATE = create("mangrove_pressure_plate", () -> PressurePlateBlockAccessor.createPressurePlateBlock(PressurePlateBlock.Sensitivity.EVERYTHING, BlockBehaviour.Properties.of(Material.WOOD, MANGROVE_PLANKS.get().defaultMaterialColor()).noCollission().strength(0.5F).sound(SoundType.WOOD)), CreativeModeTab.TAB_REDSTONE);
public static final Supplier<Block> MANGROVE_BUTTON = create("mangrove_button", () -> WoodButtonBlockAccessor.createWoodButtonBlock(BlockBehaviour.Properties.of(Material.DECORATION).noCollission().strength(0.5F).sound(SoundType.WOOD)), CreativeModeTab.TAB_REDSTONE);
public static final Supplier<Block> MANGROVE_LEAVES = create("mangrove_leaves", () -> new MangroveLeavesBlock(BlockBehaviour.Properties.of(Material.LEAVES).strength(0.2F).randomTicks().sound(SoundType.GRASS).noOcclusion().isValidSpawn(BlockProperties::ocelotOrParrot).isSuffocating(BlockProperties::never).isViewBlocking(BlockProperties::never)), CreativeModeTab.TAB_DECORATIONS);
public static final Supplier<Block> MANGROVE_LEAVES = create("mangrove_leaves", () -> new MangroveLeavesBlock(BlockBehaviour.Properties.of(Material.LEAVES).strength(0.2F).randomTicks().sound(SoundType.GRASS).noOcclusion().isValidSpawn(StateProperties::ocelotOrParrot).isSuffocating(StateProperties::never).isViewBlocking(StateProperties::never)), CreativeModeTab.TAB_DECORATIONS);
public static final Supplier<Block> MANGROVE_PROPAGULE = create("mangrove_propagule", () -> new MangrovePropaguleBlock(BlockBehaviour.Properties.of(Material.PLANT).noCollission().randomTicks().instabreak().sound(SoundType.GRASS)), CreativeModeTab.TAB_DECORATIONS);
public static final Supplier<Block> POTTED_MANGROVE_PROPAGULE = create("potted_mangrove_propagule", () -> new FlowerPotBlock(MANGROVE_PROPAGULE.get(), BlockBehaviour.Properties.of(Material.DECORATION).instabreak().noOcclusion()));
public static final Supplier<Block> MANGROVE_ROOTS = create("mangrove_roots", () -> new MangroveRootsBlock(BlockBehaviour.Properties.of(Material.WOOD).strength(0.7F).randomTicks().sound(WBSoundTypes.MANGROVE_ROOTS).noOcclusion().isValidSpawn(BlockProperties::ocelotOrParrot).isSuffocating(BlockProperties::never).isViewBlocking(BlockProperties::never)), CreativeModeTab.TAB_BUILDING_BLOCKS);
public static final Supplier<Block> MANGROVE_ROOTS = create("mangrove_roots", () -> new MangroveRootsBlock(BlockBehaviour.Properties.of(Material.WOOD).strength(0.7F).randomTicks().sound(WBSoundTypes.MANGROVE_ROOTS).noOcclusion().isValidSpawn(StateProperties::ocelotOrParrot).isSuffocating(StateProperties::never).isViewBlocking(StateProperties::never)), CreativeModeTab.TAB_BUILDING_BLOCKS);
public static final Supplier<Block> MUDDY_MANGROVE_ROOTS = create("muddy_mangrove_roots", () -> new RotatedPillarBlock(BlockBehaviour.Properties.of(Material.DIRT).strength(0.7F).sound(WBSoundTypes.MUDDY_MANGROVE_ROOTS)), CreativeModeTab.TAB_BUILDING_BLOCKS);
public static final Pair<Supplier<StandingSignBlock>, Supplier<WallSignBlock>> MANGROVE_SIGN = create("mangrove", Material.WOOD, MaterialColor.COLOR_RED);
// Mud
public static final Supplier<Block> MUD = create("mud", () -> new MudBlock(BlockBehaviour.Properties.copy(Blocks.DIRT).color(MaterialColor.TERRACOTTA_CYAN).isValidSpawn(BlockProperties::always).isRedstoneConductor(BlockProperties::always).isViewBlocking(BlockProperties::always).isSuffocating(BlockProperties::always).sound(WBSoundTypes.MUD)), CreativeModeTab.TAB_BUILDING_BLOCKS);
public static final Supplier<Block> MUD = create("mud", () -> new MudBlock(BlockBehaviour.Properties.copy(Blocks.DIRT).color(MaterialColor.TERRACOTTA_CYAN).isValidSpawn(StateProperties::always).isRedstoneConductor(StateProperties::always).isViewBlocking(StateProperties::always).isSuffocating(StateProperties::always).sound(WBSoundTypes.MUD)), CreativeModeTab.TAB_BUILDING_BLOCKS);
public static final Supplier<Block> PACKED_MUD = create("packed_mud", () -> new Block(BlockBehaviour.Properties.copy(Blocks.DIRT).strength(1.0F, 3.0F).sound(WBSoundTypes.PACKED_MUD)), CreativeModeTab.TAB_BUILDING_BLOCKS);
public static final Supplier<Block> MUD_BRICKS = create("mud_bricks", () -> new Block(BlockBehaviour.Properties.of(Material.STONE, MaterialColor.COLOR_LIGHT_GRAY).requiresCorrectToolForDrops().strength(1.5F, 3.0F).sound(WBSoundTypes.MUD_BRICKS)), CreativeModeTab.TAB_BUILDING_BLOCKS);
public static final Supplier<Block> MUD_BRICK_STAIRS = create("mud_brick_stairs", () -> StairBlockAccessor.createStairBlock(MUD_BRICKS.get().defaultBlockState(), BlockBehaviour.Properties.copy(MUD_BRICKS.get())), CreativeModeTab.TAB_BUILDING_BLOCKS);

View File

@ -6,7 +6,7 @@ import com.cursedcauldron.wildbackport.common.entities.access.api.BoatTypes;
import com.cursedcauldron.wildbackport.common.items.ChestBoatItem;
import com.cursedcauldron.wildbackport.common.items.DiscFragmentItem;
import com.cursedcauldron.wildbackport.common.items.TadpoleBucketItem;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.core.api.CoreRegistry;
import com.cursedcauldron.wildbackport.core.mixin.access.RecordItemAccessor;
import dev.architectury.injectables.annotations.ExpectPlatform;
@ -17,7 +17,6 @@ import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.RecordItem;
import net.minecraft.world.level.material.Fluids;
import java.util.function.Supplier;
@ -28,11 +27,11 @@ public class WBItems {
public static final CoreRegistry<Item> ITEMS = CoreRegistry.create(Registry.ITEM, WildBackport.MOD_ID);
// Spawns
public static final Supplier<Item> ALLAY_SPAWN_EGG = create("allay_spawn_egg", spawnEgg(WBEntities.ALLAY, 56063, 44543));
public static final Supplier<Item> FROG_SPAWN_EGG = create("frog_spawn_egg", spawnEgg(WBEntities.FROG, 13661252, 16762748));
public static final Supplier<Item> TADPOLE_SPAWN_EGG = create("tadpole_spawn_egg", spawnEgg(WBEntities.TADPOLE, 7164733, 1444352));
public static final Supplier<Item> WARDEN_SPAWN_EGG = create("warden_spawn_egg", spawnEgg(WBEntities.WARDEN, 1001033, 3790560));
public static final Supplier<Item> TADPOLE_BUCKET = create("tadpole_bucket", () -> new TadpoleBucketItem(WBEntities.TADPOLE, Fluids.WATER, () -> WBSoundEvents.BUCKED_EMPTY_TADPOLE, new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_MISC)));
public static final Supplier<Item> ALLAY_SPAWN_EGG = create("allay_spawn_egg", spawnEgg(WBEntityTypes.ALLAY, 56063, 44543));
public static final Supplier<Item> FROG_SPAWN_EGG = create("frog_spawn_egg", spawnEgg(WBEntityTypes.FROG, 13661252, 16762748));
public static final Supplier<Item> TADPOLE_SPAWN_EGG = create("tadpole_spawn_egg", spawnEgg(WBEntityTypes.TADPOLE, 7164733, 1444352));
public static final Supplier<Item> WARDEN_SPAWN_EGG = create("warden_spawn_egg", spawnEgg(WBEntityTypes.WARDEN, 1001033, 3790560));
public static final Supplier<Item> TADPOLE_BUCKET = create("tadpole_bucket", () -> new TadpoleBucketItem(WBEntityTypes.TADPOLE, Fluids.WATER, () -> WBSoundEvents.BUCKED_EMPTY_TADPOLE, new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_MISC)));
// Boats
public static final Supplier<Item> MANGROVE_BOAT = create("mangrove_boat", boat(false, BoatTypes.MANGROVE.get()));

View File

@ -17,12 +17,12 @@ import java.util.function.Supplier;
//<>
public class WBEntities {
public class WBEntityTypes {
public static final CoreRegistry<EntityType<?>> ENTITIES = CoreRegistry.create(Registry.ENTITY_TYPE, WildBackport.MOD_ID);
public static final Supplier<EntityType<Allay>> ALLAY = create("allay", EntityType.Builder.of(Allay::new, MobCategory.CREATURE).sized(0.35F, 0.6F).clientTrackingRange(8).updateInterval(2));
public static final Supplier<EntityType<Frog>> FROG = create("frog", EntityType.Builder.of(Frog::new, MobCategory.CREATURE).sized(0.5F, 0.5F).clientTrackingRange(10));
public static final Supplier<EntityType<Tadpole>> TADPOLE = create("tadpole", EntityType.Builder.of(Tadpole::new, MobCategory.CREATURE).sized(Tadpole.WIDTH, Tadpole.HEIGHT).clientTrackingRange(10));
public static final Supplier<EntityType<Tadpole>> TADPOLE = create("tadpole", EntityType.Builder.of(Tadpole::new, MobCategory.CREATURE).sized(0.4F, 0.3F).clientTrackingRange(10));
public static final Supplier<EntityType<Warden>> WARDEN = create("warden", EntityType.Builder.of(Warden::new, MobCategory.MONSTER).sized(0.9F, 2.9F).clientTrackingRange(16).fireImmune());
public static final Supplier<EntityType<MangroveBoat>> MANGROVE_BOAT = create("mangrove_boat", EntityType.Builder.<MangroveBoat>of(MangroveBoat::new, MobCategory.MISC).sized(1.375F, 0.5625F).clientTrackingRange(10));
public static final Supplier<EntityType<ChestBoat>> CHEST_BOAT = create("chest_boat", EntityType.Builder.<ChestBoat>of(ChestBoat::new, MobCategory.MISC).sized(1.375F, 0.5625F).clientTrackingRange(10));

View File

@ -1,7 +1,6 @@
package com.cursedcauldron.wildbackport.common.registry.worldgen;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.mixin.access.RegistryAccessor;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
@ -14,7 +13,7 @@ public class WBRegistries {
private static <T> Pair<ResourceKey<Registry<T>>, Registry<T>> create(String key, Registry.RegistryBootstrap<T> bootstrap) {
ResourceKey<Registry<T>> resource = ResourceKey.createRegistryKey(new ResourceLocation(WildBackport.MOD_ID, key));
Registry<T> registry = RegistryAccessor.callRegisterSimple(resource, bootstrap);
Registry<T> registry = Registry.registerSimple(resource, bootstrap);
return Pair.of(resource, registry);
}
}

View File

@ -7,7 +7,7 @@ import com.cursedcauldron.wildbackport.common.tag.WBBlockTags;
import com.cursedcauldron.wildbackport.common.worldgen.PredicatedStateProvider;
import com.cursedcauldron.wildbackport.common.worldgen.WorldGenerator;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.AttachedToLeavesDecorator;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.LayerRootDecorator;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.AboveRootPlacement;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.MangroveRootPlacement;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.WeightedLeaveVineDecorator;
import com.cursedcauldron.wildbackport.common.worldgen.features.GrassDiskConfiguration;
@ -66,7 +66,7 @@ public class WBWorldGeneration {
new UpwardBranchingTrunk(2, 1, 4, UniformInt.of(1, 4), 0.5F, UniformInt.of(0, 1), Registry.BLOCK.getOrCreateTag(WBBlockTags.MANGROVE_LOGS_CAN_GROW_THROUGH)),
BlockStateProvider.simple(WBBlocks.MANGROVE_LEAVES.get()),
new RandomSpreadFoliagePlacer(ConstantInt.of(3), ConstantInt.of(0), ConstantInt.of(2), 70),
Optional.of(new MangroveRootPlacer(UniformInt.of(1, 3), BlockStateProvider.simple(WBBlocks.MANGROVE_ROOTS.get()), Optional.of(new LayerRootDecorator(BlockStateProvider.simple(Blocks.MOSS_CARPET), 0.5F)), new MangroveRootPlacement(Registry.BLOCK.getOrCreateTag(WBBlockTags.MANGROVE_ROOTS_CAN_GROW_THROUGH), HolderSet.direct(Block::builtInRegistryHolder, WBBlocks.MUD.get(), WBBlocks.MUDDY_MANGROVE_ROOTS.get()), BlockStateProvider.simple(WBBlocks.MUDDY_MANGROVE_ROOTS.get()), 8, 15, 0.2F))),
Optional.of(new MangroveRootPlacer(UniformInt.of(1, 3), BlockStateProvider.simple(WBBlocks.MANGROVE_ROOTS.get()), Optional.of(new AboveRootPlacement(BlockStateProvider.simple(Blocks.MOSS_CARPET), 0.5F)), new MangroveRootPlacement(Registry.BLOCK.getOrCreateTag(WBBlockTags.MANGROVE_ROOTS_CAN_GROW_THROUGH), HolderSet.direct(Block::builtInRegistryHolder, WBBlocks.MUD.get(), WBBlocks.MUDDY_MANGROVE_ROOTS.get()), BlockStateProvider.simple(WBBlocks.MUDDY_MANGROVE_ROOTS.get()), 8, 15, 0.2F))),
new TwoLayersFeatureSize(2, 0, 2)
).decorators(List.of(
new WeightedLeaveVineDecorator(0.125F),
@ -79,7 +79,7 @@ public class WBWorldGeneration {
new UpwardBranchingTrunk(4, 1, 9, UniformInt.of(1, 6), 0.5F, UniformInt.of(0, 1), Registry.BLOCK.getOrCreateTag(WBBlockTags.MANGROVE_LOGS_CAN_GROW_THROUGH)),
BlockStateProvider.simple(WBBlocks.MANGROVE_LEAVES.get()),
new RandomSpreadFoliagePlacer(ConstantInt.of(3), ConstantInt.of(0), ConstantInt.of(2), 70),
Optional.of(new MangroveRootPlacer(UniformInt.of(3, 7), BlockStateProvider.simple(WBBlocks.MANGROVE_ROOTS.get()), Optional.of(new LayerRootDecorator(BlockStateProvider.simple(Blocks.MOSS_CARPET), 0.5F)), new MangroveRootPlacement(Registry.BLOCK.getOrCreateTag(WBBlockTags.MANGROVE_ROOTS_CAN_GROW_THROUGH), HolderSet.direct(Block::builtInRegistryHolder, WBBlocks.MUD.get(), WBBlocks.MUDDY_MANGROVE_ROOTS.get()), BlockStateProvider.simple(WBBlocks.MUDDY_MANGROVE_ROOTS.get()), 8, 15, 0.2F))),
Optional.of(new MangroveRootPlacer(UniformInt.of(3, 7), BlockStateProvider.simple(WBBlocks.MANGROVE_ROOTS.get()), Optional.of(new AboveRootPlacement(BlockStateProvider.simple(Blocks.MOSS_CARPET), 0.5F)), new MangroveRootPlacement(Registry.BLOCK.getOrCreateTag(WBBlockTags.MANGROVE_ROOTS_CAN_GROW_THROUGH), HolderSet.direct(Block::builtInRegistryHolder, WBBlocks.MUD.get(), WBBlocks.MUDDY_MANGROVE_ROOTS.get()), BlockStateProvider.simple(WBBlocks.MUDDY_MANGROVE_ROOTS.get()), 8, 15, 0.2F))),
new TwoLayersFeatureSize(3, 0, 2)
).decorators(List.of(
new WeightedLeaveVineDecorator(0.125F),

View File

@ -1,13 +1,13 @@
package com.cursedcauldron.wildbackport.common.tag;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.api.TagRegistry;
import com.cursedcauldron.wildbackport.core.api.TagBuilder;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
public class WBBiomeTags {
public static final TagRegistry<Biome> TAGS = TagRegistry.create(BuiltinRegistries.BIOME, WildBackport.MOD_ID);
public static final TagBuilder<Biome> TAGS = TagBuilder.create(BuiltinRegistries.BIOME, WildBackport.MOD_ID);
public static final TagKey<Biome> SPAWNS_WARM_VARIANT_FROGS = TAGS.create("spawns_warm_variant_frogs");
public static final TagKey<Biome> SPAWNS_COLD_VARIANT_FROGS = TAGS.create("spawns_cold_variant_frogs");

View File

@ -1,13 +1,13 @@
package com.cursedcauldron.wildbackport.common.tag;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.api.TagRegistry;
import com.cursedcauldron.wildbackport.core.api.TagBuilder;
import net.minecraft.core.Registry;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.block.Block;
public class WBBlockTags {
public static final TagRegistry<Block> TAGS = TagRegistry.create(Registry.BLOCK, WildBackport.MOD_ID);
public static final TagBuilder<Block> TAGS = TagBuilder.create(Registry.BLOCK, WildBackport.MOD_ID);
// Mangrove Swamp
public static final TagKey<Block> CONVERTABLE_TO_MUD = TAGS.create("convertable_to_mud");

View File

@ -1,15 +1,13 @@
package com.cursedcauldron.wildbackport.common.tag;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.api.TagRegistry;
import com.cursedcauldron.wildbackport.core.api.TagBuilder;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.Item;
public class WBEntityTypeTags {
public static final TagRegistry<EntityType<?>> TAGS = TagRegistry.create(Registry.ENTITY_TYPE, WildBackport.MOD_ID);
public static final TagBuilder<EntityType<?>> TAGS = TagBuilder.create(Registry.ENTITY_TYPE, WildBackport.MOD_ID);
public static final TagKey<EntityType<?>> FROG_FOOD = TAGS.create("frog_food");
}

View File

@ -1,13 +1,13 @@
package com.cursedcauldron.wildbackport.common.tag;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.api.TagRegistry;
import com.cursedcauldron.wildbackport.core.api.TagBuilder;
import net.minecraft.core.Registry;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.gameevent.GameEvent;
public class WBGameEventTags {
public static final TagRegistry<GameEvent> TAGS = TagRegistry.create(Registry.GAME_EVENT, WildBackport.MOD_ID);
public static final TagBuilder<GameEvent> TAGS = TagBuilder.create(Registry.GAME_EVENT, WildBackport.MOD_ID);
public static final TagKey<GameEvent> SHRIEKER_CAN_LISTEN = TAGS.create("shrieker_can_listen");
public static final TagKey<GameEvent> WARDEN_CAN_LISTEN = TAGS.create("warden_can_listen");

View File

@ -1,13 +1,13 @@
package com.cursedcauldron.wildbackport.common.tag;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.core.api.TagRegistry;
import com.cursedcauldron.wildbackport.core.api.TagBuilder;
import net.minecraft.core.Registry;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
public class WBItemTags {
public static final TagRegistry<Item> TAGS = TagRegistry.create(Registry.ITEM, WildBackport.MOD_ID);
public static final TagBuilder<Item> TAGS = TagBuilder.create(Registry.ITEM, WildBackport.MOD_ID);
public static final TagKey<Item> CHEST_BOATS = TAGS.create("chest_boats");
public static final TagKey<Item> MANGROVE_LOGS = TAGS.create("mangrove_logs");

View File

@ -2,7 +2,6 @@ package com.cursedcauldron.wildbackport.common.utils;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
@ -24,13 +23,6 @@ public class MobUtils {
players.forEach(player -> player.addEffect(new MobEffectInstance(instance), entity));
}
public static boolean closerThan(Entity source, Entity entity, double xzRange, double yRange) {
double x = entity.getX() - source.getX();
double y = entity.getY() - source.getY();
double z = entity.getZ() - source.getZ();
return Mth.lengthSquared(x, z) < Mth.square(xzRange) && Mth.square(y) < Mth.square(yRange);
}
public static void walkTowards(LivingEntity entity, PositionTracker target, float speed, int closeEnough) {
WalkTarget walkTarget = new WalkTarget(target, speed, closeEnough);
entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, target);

View File

@ -1,12 +1,13 @@
package com.cursedcauldron.wildbackport.common.worldgen;
import com.cursedcauldron.wildbackport.common.registry.WBBiomes;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBWorldGeneration;
import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeModifier;
import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeWriter;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.GenerationStep;
//<>
@ -15,6 +16,9 @@ public class WorldGenerator {
public static void setup() {
BiomeModifier.add(WorldGenerator::mangroveSwamp, WBBiomes.MANGROVE_SWAMP);
BiomeModifier.add(WorldGenerator::deepDark, WBBiomes.DEEP_DARK);
BiomeModifier.add(WorldGenerator::addFrogs, Biome.BiomeCategory.SWAMP);
}
public static void mangroveSwamp(BiomeWriter writer) {
@ -22,7 +26,6 @@ public class WorldGenerator {
writer.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, WBWorldGeneration.TREES_MANGROVE);
writer.addSpawn(MobCategory.MONSTER, EntityType.SLIME, 1, 1, 1);
writer.addSpawn(MobCategory.CREATURE, WBEntities.FROG.get(), 10, 2, 5);
writer.addSpawn(MobCategory.WATER_AMBIENT, EntityType.TROPICAL_FISH, 25, 8, 8);
}
@ -30,4 +33,8 @@ public class WorldGenerator {
writer.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, WBWorldGeneration.SCULK_VEIN);
writer.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, WBWorldGeneration.SCULK_PATCH_DEEP_DARK);
}
public static void addFrogs(BiomeWriter writer) {
writer.addSpawn(MobCategory.CREATURE, WBEntityTypes.FROG.get(), 10, 2, 5);
}
}

View File

@ -4,12 +4,12 @@ import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
public record LayerRootDecorator(BlockStateProvider aboveRootProvider, float aboveRootPlacementChance) {
public static final Codec<LayerRootDecorator> CODEC = RecordCodecBuilder.create(instance -> {
public record AboveRootPlacement(BlockStateProvider aboveRootProvider, float aboveRootPlacementChance) {
public static final Codec<AboveRootPlacement> CODEC = RecordCodecBuilder.create(instance -> {
return instance.group(BlockStateProvider.CODEC.fieldOf("above_root_provider").forGetter(decorator -> {
return decorator.aboveRootProvider;
}), Codec.floatRange(0.0F, 1.0F).fieldOf("above_root_placement_chance").forGetter(decorator -> {
return decorator.aboveRootPlacementChance;
})).apply(instance, LayerRootDecorator::new);
})).apply(instance, AboveRootPlacement::new);
});
}

View File

@ -1,7 +1,7 @@
package com.cursedcauldron.wildbackport.common.worldgen.placers;
import com.cursedcauldron.wildbackport.common.registry.worldgen.RootPlacerType;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.LayerRootDecorator;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.AboveRootPlacement;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.MangroveRootPlacement;
import com.cursedcauldron.wildbackport.common.worldgen.features.RootedTreeConfig;
import com.google.common.collect.Lists;
@ -28,7 +28,7 @@ public class MangroveRootPlacer extends RootPlacer {
});
private final MangroveRootPlacement mangroveRootPlacement;
public MangroveRootPlacer(IntProvider trunkOffsetY, BlockStateProvider rootProvider, Optional<LayerRootDecorator> aboveRootPlacement, MangroveRootPlacement mangroveRootPlacement) {
public MangroveRootPlacer(IntProvider trunkOffsetY, BlockStateProvider rootProvider, Optional<AboveRootPlacement> aboveRootPlacement, MangroveRootPlacement mangroveRootPlacement) {
super(trunkOffsetY, rootProvider, aboveRootPlacement);
this.mangroveRootPlacement = mangroveRootPlacement;
}

View File

@ -2,7 +2,7 @@ package com.cursedcauldron.wildbackport.common.worldgen.placers;
import com.cursedcauldron.wildbackport.common.registry.worldgen.RootPlacerType;
import com.cursedcauldron.wildbackport.common.registry.worldgen.WBRegistries;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.LayerRootDecorator;
import com.cursedcauldron.wildbackport.common.worldgen.decorator.AboveRootPlacement;
import com.cursedcauldron.wildbackport.common.worldgen.features.RootedTreeConfig;
import com.mojang.datafixers.Products;
import com.mojang.serialization.Codec;
@ -25,19 +25,19 @@ public abstract class RootPlacer {
public static final Codec<RootPlacer> CODEC = WBRegistries.ROOT_PLACER_TYPES.getSecond().byNameCodec().dispatch(RootPlacer::getType, RootPlacerType::codec);
protected final IntProvider trunkOffsetY;
protected final BlockStateProvider rootProvider;
protected final Optional<LayerRootDecorator> aboveRootPlacement;
protected final Optional<AboveRootPlacement> aboveRootPlacement;
protected static <P extends RootPlacer> Products.P3<RecordCodecBuilder.Mu<P>, IntProvider, BlockStateProvider, Optional<LayerRootDecorator>> codec(RecordCodecBuilder.Instance<P> instance) {
protected static <P extends RootPlacer> Products.P3<RecordCodecBuilder.Mu<P>, IntProvider, BlockStateProvider, Optional<AboveRootPlacement>> codec(RecordCodecBuilder.Instance<P> instance) {
return instance.group(IntProvider.CODEC.fieldOf("trunk_offset_y").forGetter(placer -> {
return placer.trunkOffsetY;
}), BlockStateProvider.CODEC.fieldOf("root_provider").forGetter(placer -> {
return placer.rootProvider;
}), LayerRootDecorator.CODEC.optionalFieldOf("above_root_placement").forGetter(placer -> {
}), AboveRootPlacement.CODEC.optionalFieldOf("above_root_placement").forGetter(placer -> {
return placer.aboveRootPlacement;
}));
}
public RootPlacer(IntProvider trunkOffsetY, BlockStateProvider rootProvider, Optional<LayerRootDecorator> aboveRootPlacement) {
public RootPlacer(IntProvider trunkOffsetY, BlockStateProvider rootProvider, Optional<AboveRootPlacement> aboveRootPlacement) {
this.trunkOffsetY = trunkOffsetY;
this.rootProvider = rootProvider;
this.aboveRootPlacement = aboveRootPlacement;
@ -55,9 +55,11 @@ public abstract class RootPlacer {
if (this.canGrowThrough(level, pos)) {
replacer.accept(pos, this.applyWaterlogging(level, pos, this.rootProvider.getState(random, pos)));
if (this.aboveRootPlacement.isPresent()) {
LayerRootDecorator decorator = this.aboveRootPlacement.get();
AboveRootPlacement placement = this.aboveRootPlacement.get();
BlockPos above = pos.above();
if (random.nextFloat() < decorator.aboveRootPlacementChance() && level.isStateAtPosition(above, BlockBehaviour.BlockStateBase::isAir)) replacer.accept(above, this.applyWaterlogging(level, above, decorator.aboveRootProvider().getState(random, above)));
if (random.nextFloat() < placement.aboveRootPlacementChance() && level.isStateAtPosition(above, BlockBehaviour.BlockStateBase::isAir)) {
replacer.accept(above, this.applyWaterlogging(level, above, placement.aboveRootProvider().getState(random, above)));
}
}
}
}

View File

@ -6,9 +6,9 @@ import net.minecraft.tags.TagKey;
//<>
public record TagRegistry<T>(Registry<T> registry, String modId) {
public static <T> TagRegistry<T> create(Registry<T> key, String modId) {
return new TagRegistry<>(key, modId);
public record TagBuilder<T>(Registry<T> registry, String modId) {
public static <T> TagBuilder<T> create(Registry<T> key, String modId) {
return new TagBuilder<>(key, modId);
}
public TagKey<T> create(String key) {

View File

@ -9,7 +9,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
public class BiomeModifier {
private static final Map<Consumer<BiomeWriter>, ResourceKey<Biome>[]> FEATURES = new ConcurrentHashMap<>();
private static final Map<Consumer<BiomeWriter>, ResourceKey<Biome>[]> FEATURES_PER_BIOME = new ConcurrentHashMap<>();
private static final Map<Consumer<BiomeWriter>, Biome.BiomeCategory[]> FEATURES_PER_CATEGORY = new ConcurrentHashMap<>();
public static final BiomeModifier INSTANCE = new BiomeModifier();
@ExpectPlatform
@ -18,11 +19,16 @@ public class BiomeModifier {
}
public void register(BiomeWriter writer) {
FEATURES.forEach(writer::add);
FEATURES_PER_BIOME.forEach(writer::add);
FEATURES_PER_CATEGORY.forEach(writer::add);
}
@SafeVarargs
public static void add(Consumer<BiomeWriter> writer, ResourceKey<Biome>... biomes) {
FEATURES.put(writer, biomes);
FEATURES_PER_BIOME.put(writer, biomes);
}
public static void add(Consumer<BiomeWriter> writer, Biome.BiomeCategory... biomes) {
FEATURES_PER_CATEGORY.put(writer, biomes);
}
}

View File

@ -20,12 +20,22 @@ public abstract class BiomeWriter {
for (ResourceKey<Biome> biome : biomes) if (this.is(biome)) writer.accept(this);
}
public final void add(Consumer<BiomeWriter> writer, Biome.BiomeCategory... categories) {
for (Biome.BiomeCategory category : categories) if (this.is(category)) writer.accept(this);
}
public boolean is(ResourceKey<Biome> biome) {
return biome == ResourceKey.create(Registry.BIOME_REGISTRY, this.name());
}
public boolean is(Biome.BiomeCategory category) {
return category == this.category();
}
public abstract ResourceLocation name();
public abstract Biome.BiomeCategory category();
public abstract void addFeature(GenerationStep.Decoration step, Holder<PlacedFeature> feature);
public abstract void addSpawn(MobCategory category, EntityType<?> entityType, int weight, int minGroupSize, int maxGroupSize);

View File

@ -1,14 +0,0 @@
package com.cursedcauldron.wildbackport.core.mixin.access;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Registry.class)
public interface RegistryAccessor {
@Invoker
static <T> Registry<T> callRegisterSimple(ResourceKey<? extends Registry<T>> resourceKey, Registry.RegistryBootstrap<T> registryBootstrap) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,33 @@
package com.cursedcauldron.wildbackport.core.mixin.access;
import net.minecraft.client.renderer.RenderStateShard;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(RenderStateShard.class)
public interface RenderStateShardAccessor {
@Accessor
static RenderStateShard.TransparencyStateShard getTRANSLUCENT_TRANSPARENCY() {
throw new UnsupportedOperationException();
}
@Accessor
static RenderStateShard.OverlayStateShard getOVERLAY() {
throw new UnsupportedOperationException();
}
@Accessor
static RenderStateShard.CullStateShard getNO_CULL() {
throw new UnsupportedOperationException();
}
@Accessor
static RenderStateShard.WriteMaskStateShard getCOLOR_WRITE() {
throw new UnsupportedOperationException();
}
@Accessor
static RenderStateShard.ShaderStateShard getRENDERTYPE_EYES_SHADER() {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,14 @@
package com.cursedcauldron.wildbackport.core.mixin.access;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(RenderType.class)
public interface RenderTypeAccessor {
@Invoker
static RenderType.CompositeRenderType callCreate(String string, VertexFormat vertexFormat, VertexFormat.Mode mode, int i, boolean bl, boolean bl2, RenderType.CompositeState compositeState) {
throw new UnsupportedOperationException();
}
}

View File

@ -6,13 +6,8 @@ import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(WoodType.class)
public interface WoodTypeAccessor {
@Invoker("<init>")
static WoodType createWoodType(String string) {
throw new UnsupportedOperationException();
}
@Invoker
static WoodType callRegister(WoodType woodType) {
throw new UnsupportedOperationException();
}
}
}

View File

@ -18,17 +18,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public class LocalPlayerMixin {
@Shadow public Input input;
@Inject(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/tutorial/Tutorial;onInput(Lnet/minecraft/client/player/Input;)V", shift = At.Shift.AFTER))
@Inject(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/tutorial/Tutorial;onInput(Lnet/minecraft/client/player/Input;)V", shift = At.Shift.BEFORE))
private void wb$aiStep(CallbackInfo ci) {
LocalPlayer player = LocalPlayer.class.cast(this);
double swiftnessModifier = EnchantmentHelper.getEnchantmentLevel(WBEnchantments.SWIFT_SNEAK.get(), player) * 0.15D;
double slownessModifier = Mth.clamp(0.3D + swiftnessModifier, 0.0D, 1.0D);
if (this.input instanceof KeyboardInput input) {
float swiftnessModifier = (float)EnchantmentHelper.getEnchantmentLevel(WBEnchantments.SWIFT_SNEAK.get(), player) * 0.15F;
float slownessModifier = Mth.clamp(0.3F + swiftnessModifier, 0.0F, 1.0F);
if (this.input instanceof KeyboardInput input && !player.isVisuallySwimming()) {
input.forwardImpulse = input.up == input.down ? 0.0F : (input.up ? 1.0F : -1.0F);
input.leftImpulse = input.left == input.right ? 0.0F : (input.left ? 1.0F : -1.0F);
if (player.isCrouching()) {
input.leftImpulse = (float)((double)input.leftImpulse * slownessModifier);
input.forwardImpulse = (float)((double)input.forwardImpulse * slownessModifier);
input.leftImpulse *= slownessModifier;
input.forwardImpulse *= slownessModifier;
}
}
}

View File

@ -63,8 +63,7 @@ public class MobEffectMixin implements EffectFactor {
@Inject(method = "update", at = @At("HEAD"), cancellable = true)
private void wb$update(MobEffectInstance instance, CallbackInfoReturnable<Boolean> cir) {
int i = instance.getDuration();
// int i = this.duration;
int i = this.duration;
if (i != this.duration) {
this.factorCalculationData.ifPresent(data -> data.effectChangedTimestamp += this.duration - i);
cir.setReturnValue(true);

View File

@ -0,0 +1,45 @@
package com.cursedcauldron.wildbackport.core.mixin.common.event;
import com.cursedcauldron.wildbackport.common.entities.access.Listener;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEventDispatcher;
import net.minecraft.world.level.gameevent.GameEventListener;
import net.minecraft.world.level.gameevent.GameEventListenerRegistrar;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import java.util.function.Consumer;
@Mixin(GameEventListenerRegistrar.class)
public abstract class GameEventListenerRegistrarMixin implements Listener.Instance {
@Mutable
@Shadow @Final private GameEventListener listener;
@Shadow protected abstract void ifEventDispatcherExists(Level level, @Nullable SectionPos sectionPos, Consumer<GameEventDispatcher> consumer);
@Shadow @Nullable private SectionPos sectionPos;
@Shadow public abstract void onListenerMove(Level level);
@Override
public void onPosCallback(Level level) {
this.onListenerMove(level);
}
@Override
public void setListener(GameEventListener listener, @Nullable Level level) {
if (this.listener == listener) return;
this.ifEventDispatcherExists(level, this.sectionPos, dispatcher -> dispatcher.unregister(this.listener));
this.ifEventDispatcherExists(level, this.sectionPos, dispatcher -> dispatcher.register(this.listener));
this.listener = listener;
}
@Override
public GameEventListener getListener() {
return this.listener;
}
}

View File

@ -0,0 +1,31 @@
package com.cursedcauldron.wildbackport.core.mixin.common.event;
import com.cursedcauldron.wildbackport.common.entities.access.Listener;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.gameevent.GameEventListenerRegistrar;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerLevel.EntityCallbacks.class)
public abstract class ServerLevel$CallbackMixin implements Listener.Callback<Entity> {
// @Inject(method = "onTrackingStart(Lnet/minecraft/world/entity/Entity;)V", at = @At("TAIL"))
// private void wb$onTrackingStart(Entity entity, CallbackInfo ci) {
// Listener.MobInstance instance = Listener.MobInstance.of(entity);
// instance.updateEventHandler(GameEventListenerRegistrar::onListenerMove);
// }
//
// @Inject(method = "onTrackingEnd(Lnet/minecraft/world/entity/Entity;)V", at = @At("TAIL"))
// private void wb$onTrackingEnd(Entity entity, CallbackInfo ci) {
// Listener.MobInstance instance = Listener.MobInstance.of(entity);
// instance.updateEventHandler(GameEventListenerRegistrar::onListenerRemoved);
// }
//
// @Override
// public void onSectionChange(Entity entry) {
// Listener.MobInstance instance = Listener.MobInstance.of(entry);
// instance.updateEventHandler(GameEventListenerRegistrar::onListenerRemoved);
// }
}

View File

@ -0,0 +1,28 @@
package com.cursedcauldron.wildbackport.core.mixin.common.event;
import com.cursedcauldron.wildbackport.common.entities.access.Listener;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.entity.EntityAccess;
import net.minecraft.world.level.entity.LevelCallback;
import net.minecraft.world.level.entity.TransientEntitySectionManager;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(TransientEntitySectionManager.Callback.class)
public class TransientEntitySectionManager$CallbackMixin<T extends EntityAccess> {
@Shadow @Final TransientEntitySectionManager<T> field_27285;
@Shadow @Final private T entity;
@SuppressWarnings("unchecked")
@Inject(method = "onMove", at = @At(value = "INVOKE", shift = At.Shift.BEFORE, target = "Lnet/minecraft/world/level/entity/EntityAccess;isAlwaysTicking()Z"))
private void wb$onMove(CallbackInfo ci) {
// Listener.Callback<LevelCallback<T>> callback = Listener.Callback.of(((TransientEntitySectionManagerAccessor<T>)this.field_27285).getCallbacks());
// Listener.Callback.of(callback).onSectionChange(this.entity);
}
}

View File

@ -0,0 +1,12 @@
package com.cursedcauldron.wildbackport.core.mixin.common.event;
import net.minecraft.world.level.entity.LevelCallback;
import net.minecraft.world.level.entity.TransientEntitySectionManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(TransientEntitySectionManager.class)
public interface TransientEntitySectionManagerAccessor<T> {
@Accessor
LevelCallback<T> getCallbacks();
}

View File

@ -0,0 +1,35 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:flower_pot"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
},
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "wildbackport:mangrove_propagule"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@ -19,7 +19,7 @@
"access.PointedDripstoneBlockAccessor",
"access.PressurePlateBlockAccessor",
"access.RecordItemAccessor",
"access.RegistryAccessor",
"access.RenderTypeAccessor",
"access.SensorTypeAccessor",
"access.SheetsAccessor",
"access.SimpleParticleTypeAccessor",
@ -45,12 +45,17 @@
"common.SculkSensorBlockMixin",
"common.SlimeMixin",
"common.VibrationListenerMixin",
"common.event.GameEventListenerRegistrarMixin",
"common.event.ServerLevel$CallbackMixin",
"common.event.TransientEntitySectionManager$CallbackMixin",
"common.event.TransientEntitySectionManagerAccessor",
"extension.BoatTypeMixin",
"extension.PoseMixin",
"network.ClientboundUpdateMobEffectPacketMixin",
"network.ServerGamePacketListenerImplMixin"
],
"client": [
"access.RenderStateShardAccessor",
"client.LightTextureMixin",
"client.LocalPlayerMixin",
"client.ModelPartMixin",

View File

@ -6,8 +6,20 @@ transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/J
transitive-accessible class net/minecraft/server/level/ServerLevel$EntityCallbacks
transitive-accessible class net/minecraft/world/level/entity/PersistentEntitySectionManager$Callback
transitive-accessible class net/minecraft/world/level/entity/TransientEntitySectionManager$Callback
transitive-accessible class net/minecraft/core/Registry$RegistryBootstrap
transitive-accessible class net/minecraft/client/renderer/RenderType$CompositeState
transitive-accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$TextureStateShard
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$TransparencyStateShard
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$OverlayStateShard
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$CullStateShard
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$WriteMaskStateShard
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$ShaderStateShard
transitive-accessible method net/minecraft/client/particle/HugeExplosionParticle <init> (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V
transitive-accessible method net/minecraft/world/level/block/MultifaceBlock hasFace (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;)Z
transitive-accessible method net/minecraft/world/level/block/MultifaceBlock hasFace (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;)Z
transitive-accessible method net/minecraft/core/Registry registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Registry$RegistryBootstrap;)Lnet/minecraft/core/Registry;

View File

@ -8,7 +8,7 @@ architectury {
}
loom {
accessWidenerPath.set(project(":common").file("src/main/resources/wildbackport.accesswidener"))
accessWidenerPath = project(":common").loom.accessWidenerPath
}
configurations {
@ -20,15 +20,14 @@ configurations {
}
repositories {
maven {
url = 'https://maven.minecraftforge.net/'
}
maven { url = 'https://maven.minecraftforge.net/' }
}
dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
// Remove the next line if you don't want to depend on the API
// modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}"
modImplementation("com.github.glitchfiend:TerraBlender-fabric:${minecraft_version}-${terrablender_version}")
common(project(path: ":common", configuration: "namedElements")) { transitive false }
@ -51,6 +50,7 @@ shadowJar {
}
remapJar {
injectAccessWidener = true
input.set shadowJar.archiveFile
dependsOn shadowJar
classifier null
@ -85,4 +85,4 @@ publishing {
repositories {
// Add repositories to publish to here.
}
}
}

View File

@ -1,12 +1,14 @@
package com.cursedcauldron.wildbackport.core.api.worldgen.fabric;
import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeWriter;
import com.cursedcauldron.wildbackport.core.mixin.fabric.access.BiomeAccessor;
import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.MobSpawnSettings;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
@ -26,6 +28,11 @@ public class FabricBiomeWriter extends BiomeWriter {
return this.selection.getBiomeKey().location();
}
@Override
public Biome.BiomeCategory category() {
return ((BiomeAccessor)(Object)this.selection.getBiome()).callGetBiomeCategory();
}
@Override
public void addFeature(GenerationStep.Decoration step, Holder<PlacedFeature> feature) {
this.modification.getGenerationSettings().addBuiltInFeature(step, feature.value());

View File

@ -0,0 +1,11 @@
package com.cursedcauldron.wildbackport.core.mixin.fabric.access;
import net.minecraft.world.level.biome.Biome;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Biome.class)
public interface BiomeAccessor {
@Invoker
Biome.BiomeCategory callGetBiomeCategory();
}

View File

@ -2,8 +2,8 @@
"schemaVersion": 1,
"id": "wildbackport",
"version": "${version}",
"name": "Wildbackport",
"description": "a mod that backports the features from the wild update",
"name": "TheWildBackport",
"description": "backport features from the wild update",
"authors": [
"BlackGear",
"Orcinus",
@ -30,6 +30,7 @@
],
"depends": {
"fabricloader": ">=0.14.8",
"minecraft": ">=1.18.2"
"minecraft": ">=1.18.2",
"terrablender": ">=1.0.0.59"
}
}

View File

@ -1,13 +0,0 @@
accessWidener v2 named
transitive-accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier
transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$Placer
transitive-accessible class net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement$PieceState
transitive-accessible class net/minecraft/server/level/ServerLevel$EntityCallbacks
transitive-accessible class net/minecraft/world/level/entity/PersistentEntitySectionManager$Callback
transitive-accessible class net/minecraft/core/Registry$RegistryBootstrap
transitive-accessible method net/minecraft/client/particle/HugeExplosionParticle <init> (Lnet/minecraft/client/multiplayer/ClientLevel;DDDDLnet/minecraft/client/particle/SpriteSet;)V
transitive-accessible method net/minecraft/world/level/block/MultifaceBlock hasFace (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;)Z

View File

@ -4,6 +4,7 @@
"package": "com.cursedcauldron.wildbackport.core.mixin.fabric",
"compatibilityLevel": "JAVA_17",
"mixins": [
"access.BiomeAccessor"
],
"client": [
"client.FogRendererMixin",

View File

@ -1,8 +1,6 @@
buildscript {
repositories {
maven {
url = 'https://maven.minecraftforge.net/'
}
maven { url = 'https://maven.minecraftforge.net/' }
}
}
@ -10,20 +8,23 @@ plugins {
id "com.github.johnrengelman.shadow" version "7.1.2"
}
architectury {
platformSetupLoomIde()
forge()
}
loom {
accessWidenerPath = project(":common").loom.accessWidenerPath
forge {
mixinConfig "wildbackport-common.mixins.json"
mixinConfig "wildbackport.mixins.json"
convertAccessWideners = true
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
}
}
architectury {
platformSetupLoomIde()
forge()
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
@ -34,11 +35,7 @@ configurations {
dependencies {
forge "net.minecraftforge:forge:${rootProject.forge_version}"
// forge "net.minecraftforge:forge:${rootProject.forge_version}"
modApi ("com.github.glitchfiend:TerraBlender-forge:${minecraft_version}-${terrablender_version}")
// implementation fg.deobf('com.github.glitchfiend:TerraBlender-forge:x.x.x-y.y.y.y')
modApi "com.github.glitchfiend:TerraBlender-forge:${minecraft_version}-${terrablender_version}"
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false }

View File

@ -1,6 +1,5 @@
package com.cursedcauldron.wildbackport.core.api.forge;
import com.cursedcauldron.wildbackport.core.mixin.access.WoodTypeAccessor;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.state.properties.WoodType;
@ -8,7 +7,7 @@ import net.minecraftforge.fml.loading.FMLLoader;
public class WoodTypeRegistryImpl {
public static WoodType create(ResourceLocation location) {
WoodType woodType = WoodTypeAccessor.callRegister(WoodTypeAccessor.createWoodType(location.toString()));
WoodType woodType = WoodType.register(WoodType.create(location.toString()));
if (FMLLoader.getDist().isClient()) Sheets.addWoodType(woodType);
return woodType;
}

View File

@ -5,6 +5,8 @@ import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.MobSpawnSettings;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraftforge.event.world.BiomeLoadingEvent;
@ -22,6 +24,11 @@ public class ForgeBiomeWriter extends BiomeWriter {
return this.event.getName();
}
@Override
public Biome.BiomeCategory category() {
return this.event.getCategory();
}
@Override
public void addFeature(GenerationStep.Decoration step, Holder<PlacedFeature> feature) {
this.event.getGeneration().addFeature(step, feature);
@ -29,6 +36,6 @@ public class ForgeBiomeWriter extends BiomeWriter {
@Override
public void addSpawn(MobCategory category, EntityType<?> entityType, int weight, int minGroupSize, int maxGroupSize) {
this.event.getSpawns().addSpawn(category, new MobSpawnSettings.SpawnerData(entityType, weight, minGroupSize, maxGroupSize));
}
}

View File

@ -0,0 +1,77 @@
package com.cursedcauldron.wildbackport.forge;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.common.effects.EffectFactor;
import com.cursedcauldron.wildbackport.common.registry.WBMobEffects;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.FogType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = WildBackport.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class DarknessSetup {
@SubscribeEvent
public static void darknessFogColor(EntityViewRenderEvent.FogColors event) {
FogType type = event.getCamera().getFluidInCamera();
Level level = event.getCamera().getEntity().getLevel();
if (level.isClientSide() && level instanceof ClientLevel client) {
double colorModifier = (event.getCamera().getPosition().y - (double)client.getMinBuildHeight()) * client.getLevelData().getClearColorScale();
if (event.getCamera().getEntity() instanceof LivingEntity living && living.hasEffect(WBMobEffects.DARKNESS.get())) {
MobEffectInstance effect = living.getEffect(WBMobEffects.DARKNESS.get());
if (effect != null) {
EffectFactor.Instance instance = EffectFactor.Instance.of(effect);
if (instance.getFactorCalculationData().isPresent()) {
colorModifier = 1.0F - instance.getFactorCalculationData().get().lerp(living, (float)event.getPartialTicks());
} else {
colorModifier = 0.0D;
}
}
}
if (colorModifier < 1.0D && type != FogType.LAVA) {
if (colorModifier < 0.0D) {
colorModifier = 0.0D;
}
colorModifier *= colorModifier;
event.setRed((float)((double)event.getRed() * colorModifier));
event.setGreen((float)((double)event.getGreen() * colorModifier));
event.setBlue((float)((double)event.getBlue() * colorModifier));
}
}
}
@SubscribeEvent
public static void darknessFog(EntityViewRenderEvent.RenderFogEvent event) {
FogType type = event.getCamera().getFluidInCamera();
if (type != FogType.WATER) {
if (event.getCamera().getEntity() instanceof LivingEntity living && living.hasEffect(WBMobEffects.DARKNESS.get())) {
MobEffectInstance effect = living.getEffect(WBMobEffects.DARKNESS.get());
if (effect != null) {
EffectFactor.Instance instance = EffectFactor.Instance.of(effect);
if (instance.getFactorCalculationData().isPresent()) {
float modifier = Mth.lerp(instance.getFactorCalculationData().get().lerp(living, (float)event.getPartialTicks()), event.getFarPlaneDistance(), 15.0F);
float start = event.getMode() == FogRenderer.FogMode.FOG_SKY ? 0.0F : modifier * 0.75F;
RenderSystem.setShaderFogStart(start);
RenderSystem.setShaderFogEnd(modifier);
}
}
}
}
}
}

View File

@ -0,0 +1,38 @@
package com.cursedcauldron.wildbackport.forge;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.common.registry.entity.WBEntityTypes;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = WildBackport.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class RemappingSetup {
@SubscribeEvent
public static void missingBlockEntityMapping(RegistryEvent.MissingMappings<BlockEntityType<?>> event) {
for (RegistryEvent.MissingMappings.Mapping<BlockEntityType<?>> mapping : event.getMappings(WildBackport.MOD_ID)) {
ResourceLocation location = mapping.key;
if (location != null) if (location.getPath().equals("wb_sign")) mapping.remap(BlockEntityType.SIGN);
}
}
@SubscribeEvent
public static void missingEntityMapping(RegistryEvent.MissingMappings<EntityType<?>> event) {
for (RegistryEvent.MissingMappings.Mapping<EntityType<?>> mapping : event.getMappings(WildBackport.MOD_ID)) {
ResourceLocation location = mapping.key;
if (location != null) if (location.getPath().equals("wb_boat")) mapping.remap(WBEntityTypes.MANGROVE_BOAT.get());
}
}
@SubscribeEvent
public static void missingPositionSourceMapping(RegistryEvent.MissingMappings<FoliagePlacerType<?>> event) {
for (RegistryEvent.MissingMappings.Mapping<FoliagePlacerType<?>> mapping : event.getMappings(WildBackport.MOD_ID)) {
ResourceLocation location = mapping.key;
if (location != null) if (location.getPath().equals("water_tree_foliage_placer")) mapping.remap(FoliagePlacerType.RANDOM_SPREAD_FOLIAGE_PLACER);
}
}
}

View File

@ -3,29 +3,17 @@ package com.cursedcauldron.wildbackport.forge;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.client.ClientSetup;
import com.cursedcauldron.wildbackport.common.CommonSetup;
import com.cursedcauldron.wildbackport.common.effects.EffectFactor;
import com.cursedcauldron.wildbackport.common.registry.WBBiomes;
import com.cursedcauldron.wildbackport.common.registry.WBMobEffects;
import com.cursedcauldron.wildbackport.common.worldgen.MangroveSwampSurface;
import com.cursedcauldron.wildbackport.core.api.forge.EventBuses;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.material.FogType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
@ -51,9 +39,6 @@ public class WildBackportForge {
bus.addListener(this::terrablenderSetup);
MinecraftForge.EVENT_BUS.addListener(this::darknessFog);
MinecraftForge.EVENT_BUS.addListener(this::darknessFogColor);
WildBackport.bootstrap();
CommonSetup.onCommon();
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientSetup::onClient);
@ -71,60 +56,4 @@ public class WildBackportForge {
});
SurfaceRuleManager.addSurfaceRules(SurfaceRuleManager.RuleCategory.OVERWORLD, WildBackport.MOD_ID, MangroveSwampSurface.makeRules());
}
private void darknessFogColor(EntityViewRenderEvent.FogColors event) {
FogType type = event.getCamera().getFluidInCamera();
Level level = event.getCamera().getEntity().getLevel();
if (level.isClientSide() && level instanceof ClientLevel client) {
double colorModifier = (event.getCamera().getPosition().y - (double)client.getMinBuildHeight()) * client.getLevelData().getClearColorScale();
if (event.getCamera().getEntity() instanceof LivingEntity living && living.hasEffect(WBMobEffects.DARKNESS.get())) {
MobEffectInstance effect = living.getEffect(WBMobEffects.DARKNESS.get());
if (effect != null) {
EffectFactor.Instance instance = EffectFactor.Instance.of(effect);
if (instance.getFactorCalculationData().isPresent()) {
colorModifier = 1.0F - instance.getFactorCalculationData().get().lerp(living, (float)event.getPartialTicks());
} else {
colorModifier = 0.0D;
}
}
}
if (colorModifier < 1.0D && type != FogType.LAVA) {
if (colorModifier < 0.0D) {
colorModifier = 0.0D;
}
colorModifier *= colorModifier;
event.setRed((float)((double)event.getRed() * colorModifier));
event.setGreen((float)((double)event.getGreen() * colorModifier));
event.setBlue((float)((double)event.getBlue() * colorModifier));
}
}
// RenderSystem.clearColor(event.getRed(), event.getGreen(), event.getBlue(), 0.0F);
}
private void darknessFog(EntityViewRenderEvent.RenderFogEvent event) {
FogType type = event.getCamera().getFluidInCamera();
if (type != FogType.WATER) {
if (event.getCamera().getEntity() instanceof LivingEntity living && living.hasEffect(WBMobEffects.DARKNESS.get())) {
MobEffectInstance effect = living.getEffect(WBMobEffects.DARKNESS.get());
if (effect != null) {
EffectFactor.Instance instance = EffectFactor.Instance.of(effect);
if (instance.getFactorCalculationData().isPresent()) {
float modifier = Mth.lerp(instance.getFactorCalculationData().get().lerp(living, (float)event.getPartialTicks()), event.getFarPlaneDistance(), 15.0F);
float start = event.getMode() == FogRenderer.FogMode.FOG_SKY ? 0.0F : modifier * 0.75F;
RenderSystem.setShaderFogStart(start);
RenderSystem.setShaderFogEnd(modifier);
}
}
}
}
}
}

View File

@ -3,14 +3,12 @@ loaderVersion = "[40,)"
license = "All Rights Reserved"
[[mods]]
modId = "wildbackport"
version = "${version}"
displayName = "The Wild Backport"
logoFile = "icon.png"
authors = "BlackGear, Orcinus, Dopadream"
description = '''
a mod that backports the features from the wild update
'''
modId = "wildbackport"
version = "${version}"
displayName = "TheWildBackport"
logoFile = "icon.png"
authors = "BlackGear, Orcinus, Dopadream"
description = '''backport features from the wild update'''
[[dependencies.wildbackport]]
modId = "forge"
@ -24,4 +22,11 @@ a mod that backports the features from the wild update
mandatory = true
versionRange = "[1.18.2,1.19)"
ordering = "NONE"
side = "BOTH"
side = "BOTH"
[[dependencies.wildbackport]]
modId="terrablender"
mandatory=true
versionRange="[1.0.0.59,)"
ordering="NONE"
side="BOTH"

View File

@ -1,11 +1,15 @@
org.gradle.jvmargs=-Xmx2G
org.gradle.jvmargs=-Xmx2048M
minecraft_version=1.18.2
enabled_platforms=fabric,forge
archives_base_name=wildbackport
mod_version=1.0.0
mod_version=1.2.1
maven_group=com.cursedcauldron
architectury_version=4.5.74
fabric_loader_version=0.14.8
fabric_api_version=0.56.1+1.18.2
fabric_api_version=0.57.0+1.18.2
forge_version=1.18.2-40.1.54
terrablender_version=1.1.0.95

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

10
gradlew vendored
View File

@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -32,10 +32,10 @@
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#

View File

@ -9,4 +9,6 @@ pluginManagement {
include("common")
include("fabric")
include("forge")
include("forge")
rootProject.name = "architectury-example-mod"