From 04c1fc3528c2703ec88be9bc957cc0f3b9110f16 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Fri, 15 Jan 2021 17:23:54 +0300 Subject: [PATCH] Mole nest interaction --- .../betterend/blocks/SilkMothNestBlock.java | 35 ++++++- .../ru/betterend/entity/SilkMothEntity.java | 94 ++++++++++++++++++- 2 files changed, 126 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java b/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java index deacc08a..6f502ded 100644 --- a/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java +++ b/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java @@ -2,6 +2,7 @@ package ru.betterend.blocks; import java.util.Collections; import java.util.List; +import java.util.Random; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.minecraft.block.Block; @@ -13,7 +14,10 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; import net.minecraft.loot.context.LootContext; +import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.DirectionProperty; @@ -22,14 +26,18 @@ import net.minecraft.tag.BlockTags; import net.minecraft.util.BlockMirror; import net.minecraft.util.BlockRotation; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.BlockView; import net.minecraft.world.World; import net.minecraft.world.WorldAccess; import ru.betterend.blocks.basis.BaseBlock; import ru.betterend.client.render.ERenderLayer; +import ru.betterend.entity.SilkMothEntity; import ru.betterend.interfaces.IRenderTypeable; +import ru.betterend.registry.EndEntities; import ru.betterend.util.BlocksHelper; public class SilkMothNestBlock extends BaseBlock implements IRenderTypeable { @@ -39,7 +47,7 @@ public class SilkMothNestBlock extends BaseBlock implements IRenderTypeable { private static final VoxelShape BOTTOM = createCuboidShape(0, 0, 0, 16, 16, 16); public SilkMothNestBlock() { - super(FabricBlockSettings.of(Material.WOOL).hardness(0.5F).resistance(0.1F).sounds(BlockSoundGroup.WOOL).nonOpaque()); + super(FabricBlockSettings.of(Material.WOOL).hardness(0.5F).resistance(0.1F).sounds(BlockSoundGroup.WOOL).nonOpaque().ticksRandomly()); this.setDefaultState(getDefaultState().with(ACTIVE, true)); } @@ -103,4 +111,29 @@ public class SilkMothNestBlock extends BaseBlock implements IRenderTypeable { } super.onBreak(world, pos, state, player); } + + @Override + public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (!state.get(ACTIVE)) { + return; + } + if (random.nextInt(16) > 0) { + return; + } + Direction dir = state.get(FACING); + BlockPos spawn = pos.offset(dir); + if (!world.getBlockState(spawn).isAir()) { + return; + } + int count = world.getEntitiesByType(EndEntities.SILK_MOTH, new Box(pos).expand(16), (entity) -> { return true; }).size(); + if (count > 8) { + return; + } + SilkMothEntity moth = new SilkMothEntity(EndEntities.SILK_MOTH, world); + moth.refreshPositionAndAngles(spawn.getX() + 0.5, spawn.getY() + 0.5, spawn.getZ() + 0.5, dir.asRotation(), 0); + moth.setVelocity(new Vec3d(dir.getOffsetX() * 0.4, 0, dir.getOffsetZ() * 0.4)); + moth.setHive(world, pos); + world.spawnEntity(moth); + world.playSound(null, pos, SoundEvents.BLOCK_BEEHIVE_EXIT, SoundCategory.BLOCKS, 1, 1); + } } diff --git a/src/main/java/ru/betterend/entity/SilkMothEntity.java b/src/main/java/ru/betterend/entity/SilkMothEntity.java index c5b625ca..dc1169de 100644 --- a/src/main/java/ru/betterend/entity/SilkMothEntity.java +++ b/src/main/java/ru/betterend/entity/SilkMothEntity.java @@ -23,13 +23,27 @@ import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.passive.AnimalEntity; import net.minecraft.entity.passive.PassiveEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtHelper; import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.registry.RegistryKey; import net.minecraft.world.World; +import ru.betterend.BetterEnd; +import ru.betterend.blocks.SilkMothNestBlock; +import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndEntities; public class SilkMothEntity extends AnimalEntity implements Flutterer { + private BlockPos hivePos; + private BlockPos entrance; + private World hiveWorld; + public SilkMothEntity(EntityType entityType, World world) { super(entityType, world); this.moveControl = new FlightMoveControl(this, 20, true); @@ -46,9 +60,38 @@ public class SilkMothEntity extends AnimalEntity implements Flutterer { .add(EntityAttributes.GENERIC_FLYING_SPEED, 0.4D) .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.1D); } + + public void setHive(World world, BlockPos hive) { + this.hivePos = hive; + this.hiveWorld = world; + } + + @Override + public void writeCustomDataToTag(CompoundTag tag) { + if (hivePos != null) { + tag.put("HivePos", NbtHelper.fromBlockPos(hivePos)); + tag.putString("HiveWorld", hiveWorld.getRegistryKey().getValue().toString()); + } + } + + @Override + public void readCustomDataFromTag(CompoundTag tag) { + if (tag.contains("HivePos")) { + hivePos = NbtHelper.toBlockPos(tag.getCompound("HivePos")); + Identifier worldID = new Identifier(tag.getString("HiveWorld")); + try { + hiveWorld = world.getServer().getWorld(RegistryKey.of(Registry.DIMENSION, worldID)); + } + catch (Exception e) { + BetterEnd.LOGGER.warning("Silk Moth Hive World {} is missing!", worldID); + hivePos = null; + } + } + } @Override protected void initGoals() { + this.goalSelector.add(1, new ReturnToHiveGoal()); this.goalSelector.add(2, new AnimalMateGoal(this, 1.0D)); this.goalSelector.add(5, new FollowParentGoal(this, 1.25D)); this.goalSelector.add(8, new WanderAroundGoal()); @@ -118,23 +161,25 @@ public class SilkMothEntity extends AnimalEntity implements Flutterer { this.setControls(EnumSet.of(Goal.Control.MOVE)); } + @Override public boolean canStart() { return SilkMothEntity.this.navigation.isIdle() && SilkMothEntity.this.random.nextInt(10) == 0; } + @Override public boolean shouldContinue() { return SilkMothEntity.this.navigation.isFollowingPath(); } + @Override public void start() { Vec3d vec3d = this.getRandomLocation(); if (vec3d != null) { try { - SilkMothEntity.this.navigation.startMovingAlong(SilkMothEntity.this.navigation.findPathTo((BlockPos) (new BlockPos(vec3d)), 1), 1.0D); + SilkMothEntity.this.navigation.startMovingAlong(SilkMothEntity.this.navigation.findPathTo(new BlockPos(vec3d), 1), 1.0D); } catch (Exception e) {} } - } @Nullable @@ -144,4 +189,49 @@ public class SilkMothEntity extends AnimalEntity implements Flutterer { return vec3d4 != null ? vec3d4 : TargetFinder.findGroundTarget(SilkMothEntity.this, 8, 4, -2, vec3d3, 1.5707963705062866D); } } + + class ReturnToHiveGoal extends Goal { + ReturnToHiveGoal() { + this.setControls(EnumSet.of(Goal.Control.MOVE)); + } + + @Override + public boolean canStart() { + return SilkMothEntity.this.hivePos != null + && SilkMothEntity.this.hiveWorld == SilkMothEntity.this.world + && SilkMothEntity.this.navigation.isIdle() + && SilkMothEntity.this.random.nextInt(16) == 0 + && SilkMothEntity.this.getPos().squaredDistanceTo(SilkMothEntity.this.hivePos.getX(), SilkMothEntity.this.hivePos.getY(), SilkMothEntity.this.hivePos.getZ()) < 32; + } + + @Override + public boolean shouldContinue() { + return SilkMothEntity.this.navigation.isFollowingPath() && world.getBlockState(entrance).isAir(); + } + + @Override + public void start() { + BlockState state = SilkMothEntity.this.world.getBlockState(SilkMothEntity.this.hivePos); + if (!state.isOf(EndBlocks.SILK_MOTH_NEST)) { + SilkMothEntity.this.hivePos = null; + } + try { + entrance = SilkMothEntity.this.hivePos.offset(state.get(SilkMothNestBlock.FACING)); + SilkMothEntity.this.navigation.startMovingAlong(SilkMothEntity.this.navigation.findPathTo(entrance, 1), 1.0D); + } + catch (Exception e) {} + } + + @Override + public void tick() { + super.tick(); + double dx = Math.abs(SilkMothEntity.this.entrance.getX() - SilkMothEntity.this.getX()); + double dy = Math.abs(SilkMothEntity.this.entrance.getY() - SilkMothEntity.this.getY()); + double dz = Math.abs(SilkMothEntity.this.entrance.getZ() - SilkMothEntity.this.getZ()); + if (dx + dy + dz < 1) { + SilkMothEntity.this.world.playSound(null, SilkMothEntity.this.entrance, SoundEvents.BLOCK_BEEHIVE_ENTER, SoundCategory.BLOCKS, 1, 1); + SilkMothEntity.this.remove(); + } + } + } }