Fix Bugs And Add Particle Effects To Glowing Obsidian
All checks were successful
Twine/pipeline/head This commit looks good

This commit is contained in:
TheBrokenRail 2020-06-18 14:49:22 -04:00
parent 38f16baa75
commit fec445e22a
8 changed files with 102 additions and 42 deletions

View File

@ -46,6 +46,9 @@ public class Twine implements ModInitializer {
public static final int STAGE_COUNT = 6; public static final int STAGE_COUNT = 6;
public static final int STAGE_TIME = 24000; public static final int STAGE_TIME = 24000;
public static final int AI_RANGE = 16;
public static final int AI_MAX_Y_DIFFERENCE = 4;
public static ScreenHandlerType<? extends GenericContainerScreenHandler> BACKPACK_SCREEN_TYPE; public static ScreenHandlerType<? extends GenericContainerScreenHandler> BACKPACK_SCREEN_TYPE;
public static ScreenHandlerType<? extends CraftingScreenHandler> BOAT_CRAFTING_SCREEN_TYPE; public static ScreenHandlerType<? extends CraftingScreenHandler> BOAT_CRAFTING_SCREEN_TYPE;

View File

@ -12,6 +12,8 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.Monster; import net.minecraft.entity.mob.Monster;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
@ -27,13 +29,14 @@ public class GlowingObsidianBlock extends Block {
@Override @Override
public void onSteppedOn(World world, BlockPos pos, Entity entity) { public void onSteppedOn(World world, BlockPos pos, Entity entity) {
super.onSteppedOn(world, pos, entity); super.onSteppedOn(world, pos, entity);
if (entity instanceof LivingEntity && entity.age % 5 == 0) { if (!world.isClient() && entity instanceof LivingEntity && entity.age % 10 == 0) {
final float amount = 2f; final float amount = 2f;
if (entity instanceof Monster) { if (entity instanceof Monster) {
((LivingEntity) entity).heal(amount); ((LivingEntity) entity).heal(amount);
} else { } else {
entity.damage(DamageSource.MAGIC, amount); entity.damage(DamageSource.MAGIC, amount);
} }
((ServerWorld) world).spawnParticles(ParticleTypes.SMOKE, pos.getX() + 0.5d, pos.getY() + 1d, pos.getZ() + 0.5d, 12 + world.getRandom().nextInt(12), 0.1d, 0.5d, 0.1d,0.01d);
} }
} }

View File

@ -16,7 +16,7 @@ import net.minecraft.world.chunk.ChunkStatus;
public class ExplodeArtificialBlockGoal extends MoveToTargetPosGoal { public class ExplodeArtificialBlockGoal extends MoveToTargetPosGoal {
public ExplodeArtificialBlockGoal(MobEntityWithAi mob) { public ExplodeArtificialBlockGoal(MobEntityWithAi mob) {
super(mob, 1d, 24, 4); super(mob, 1d, Twine.AI_RANGE, Twine.AI_MAX_Y_DIFFERENCE);
} }
@Override @Override
@ -62,4 +62,13 @@ public class ExplodeArtificialBlockGoal extends MoveToTargetPosGoal {
return stage >= StageUtil.CREEPERS_TARGET_ARTIFICIAL_BLOCKS && super.canStart(); return stage >= StageUtil.CREEPERS_TARGET_ARTIFICIAL_BLOCKS && super.canStart();
} }
@Override
protected boolean findTargetPos() {
if (targetPos != null && isTargetPos(mob.world, targetPos)) {
return true;
} else {
return super.findTargetPos();
}
}
} }

View File

@ -1,5 +1,6 @@
package com.thebrokenrail.twine.entity; package com.thebrokenrail.twine.entity;
import com.thebrokenrail.twine.Twine;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.entity.ai.TargetFinder; import net.minecraft.entity.ai.TargetFinder;
import net.minecraft.entity.ai.goal.Goal; import net.minecraft.entity.ai.goal.Goal;
@ -12,9 +13,6 @@ import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkStatus; import net.minecraft.world.chunk.ChunkStatus;
public class FleeEndRodGoal extends Goal { public class FleeEndRodGoal extends Goal {
private static final int RANGE = 16;
private static final int MAX_Y_DIFFERENCE = 7;
private final MobEntityWithAi mob; private final MobEntityWithAi mob;
private Vec3d targetPos; private Vec3d targetPos;
private Path fleePath; private Path fleePath;
@ -37,8 +35,8 @@ public class FleeEndRodGoal extends Goal {
BlockPos blockPos = mob.getBlockPos(); BlockPos blockPos = mob.getBlockPos();
BlockPos.Mutable mutable = new BlockPos.Mutable(); BlockPos.Mutable mutable = new BlockPos.Mutable();
for (int k = 0; k <= MAX_Y_DIFFERENCE; k = k > 0 ? -k : 1 - k) { for (int k = 0; k <= Twine.AI_MAX_Y_DIFFERENCE; k = k > 0 ? -k : 1 - k) {
for (int l = 0; l < RANGE; ++l) { for (int l = 0; l < Twine.AI_RANGE; ++l) {
for (int m = 0; m <= l; m = m > 0 ? -m : 1 - m) { for (int m = 0; m <= l; m = m > 0 ? -m : 1 - m) {
for (int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) { for (int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) {
mutable.set(blockPos, m, k - 1, n); mutable.set(blockPos, m, k - 1, n);
@ -64,7 +62,7 @@ public class FleeEndRodGoal extends Goal {
@Override @Override
public boolean canStart() { public boolean canStart() {
if (findTargetPos()) { if (findTargetPos()) {
Vec3d vec3d = TargetFinder.findTargetAwayFrom(mob, RANGE * 2, MAX_Y_DIFFERENCE * 2, targetPos); Vec3d vec3d = TargetFinder.findTargetAwayFrom(mob, Twine.AI_RANGE * 2, Twine.AI_MAX_Y_DIFFERENCE * 2, targetPos);
if (vec3d == null) { if (vec3d == null) {
return false; return false;
} else if (squaredDistanceTo(vec3d) < mob.squaredDistanceTo(targetPos)) { } else if (squaredDistanceTo(vec3d) < mob.squaredDistanceTo(targetPos)) {
@ -98,7 +96,7 @@ public class FleeEndRodGoal extends Goal {
@Override @Override
public void tick() { public void tick() {
if (squaredDistanceTo(mob.getPos()) < (RANGE / 2d)) { if (squaredDistanceTo(mob.getPos()) < (Twine.AI_RANGE / 2d)) {
mob.getNavigation().setSpeed(FAST_SPEED); mob.getNavigation().setSpeed(FAST_SPEED);
} else { } else {
mob.getNavigation().setSpeed(SLOW_SPEED); mob.getNavigation().setSpeed(SLOW_SPEED);

View File

@ -1,30 +0,0 @@
package com.thebrokenrail.twine.entity;
import com.thebrokenrail.twine.Twine;
import net.minecraft.entity.ai.goal.MoveToTargetPosGoal;
import net.minecraft.entity.mob.MobEntityWithAi;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldView;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkStatus;
public class StandOnGlowingObsidian extends MoveToTargetPosGoal {
public StandOnGlowingObsidian(MobEntityWithAi mob) {
super(mob, 1d, 24);
}
@Override
protected boolean isTargetPos(WorldView world, BlockPos pos) {
Chunk chunk = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.FULL, false);
if (chunk == null) {
return false;
} else {
return chunk.getBlockState(pos).isOf(Twine.GLOWING_OBSIDIAN) && chunk.getBlockState(pos.up()).isAir() && chunk.getBlockState(pos.up(2)).isAir();
}
}
@Override
public boolean canStart() {
return super.canStart() && (mob.getHealth() / mob.getMaxHealth()) <= 0.5;
}
}

View File

@ -0,0 +1,77 @@
package com.thebrokenrail.twine.entity;
import com.thebrokenrail.twine.Twine;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.ai.pathing.Path;
import net.minecraft.entity.mob.MobEntityWithAi;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.WorldView;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkStatus;
public class StandOnGlowingObsidianGoal extends Goal {
private final MobEntityWithAi mob;
private Vec3d targetPos;
private Path path;
public StandOnGlowingObsidianGoal(MobEntityWithAi mob) {
super();
this.mob = mob;
}
private boolean findTargetPos() {
BlockPos blockPos = mob.getBlockPos();
BlockPos.Mutable mutable = new BlockPos.Mutable();
for (int k = 0; k <= Twine.AI_MAX_Y_DIFFERENCE; k = k > 0 ? -k : 1 - k) {
for (int l = 0; l < Twine.AI_RANGE; ++l) {
for (int m = 0; m <= l; m = m > 0 ? -m : 1 - m) {
for (int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) {
mutable.set(blockPos, m, k - 1, n);
if (mob.isInWalkTargetRange(mutable) && isTargetPos(mob.world, mutable)) {
targetPos = new Vec3d(mutable.getX() + 0.5d, mutable.getY(), mutable.getZ() + 0.5d);
return true;
}
}
}
}
}
return false;
}
@Override
public boolean canStart() {
if ((mob.getHealth() / mob.getMaxHealth()) <= 0.5f && findTargetPos()) {
path = mob.getNavigation().findPathTo(targetPos.x, targetPos.y, targetPos.z, 0);
return path != null;
} else {
return false;
}
}
@Override
public boolean shouldContinue() {
return !mob.getNavigation().isIdle();
}
@Override
public void start() {
mob.getNavigation().startMovingAlong(path, 1f);
}
@Override
public void stop() {
targetPos = null;
}
private boolean isTargetPos(WorldView world, BlockPos pos) {
Chunk chunk = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.FULL, false);
if (chunk == null) {
return false;
} else {
return chunk.getBlockState(pos).isOf(Twine.GLOWING_OBSIDIAN) && chunk.getBlockState(pos.up()).isAir() && chunk.getBlockState(pos.up(2)).isAir();
}
}
}

View File

@ -93,7 +93,7 @@ public class MixinBoatEntity implements BoatUtil {
player.getEntityWorld().playSound(null, ((BoatEntity) (Object) this).getBlockPos(), SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, ((BoatEntity) (Object) this).getSoundCategory(), 1f, 1f); player.getEntityWorld().playSound(null, ((BoatEntity) (Object) this).getBlockPos(), SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, ((BoatEntity) (Object) this).getSoundCategory(), 1f, 1f);
} }
info.setReturnValue(ActionResult.SUCCESS); info.setReturnValue(ActionResult.SUCCESS);
} else if (player.isSneaking()) { } else if (player.shouldCancelInteraction()) {
if (!player.getEntityWorld().isClient()) { if (!player.getEntityWorld().isClient()) {
openInventory(player); openInventory(player);
} }

View File

@ -4,7 +4,7 @@ import com.thebrokenrail.twine.component.StageDataComponent;
import com.thebrokenrail.twine.entity.ExplodeArtificialBlockGoal; import com.thebrokenrail.twine.entity.ExplodeArtificialBlockGoal;
import com.thebrokenrail.twine.entity.FleeEndRodGoal; import com.thebrokenrail.twine.entity.FleeEndRodGoal;
import com.thebrokenrail.twine.entity.FollowPassiveEntityGoal; import com.thebrokenrail.twine.entity.FollowPassiveEntityGoal;
import com.thebrokenrail.twine.entity.StandOnGlowingObsidian; import com.thebrokenrail.twine.entity.StandOnGlowingObsidianGoal;
import com.thebrokenrail.twine.util.StageUtil; import com.thebrokenrail.twine.util.StageUtil;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.ai.goal.FollowTargetGoal; import net.minecraft.entity.ai.goal.FollowTargetGoal;
@ -44,7 +44,7 @@ public class MixinMobEntity {
if (world != null && !world.isClient()) { if (world != null && !world.isClient()) {
if (this instanceof Monster) { if (this instanceof Monster) {
if ((Object) this instanceof MobEntityWithAi) { if ((Object) this instanceof MobEntityWithAi) {
goalSelector.add(1, new StandOnGlowingObsidian((MobEntityWithAi) (Object) this)); goalSelector.add(1, new StandOnGlowingObsidianGoal((MobEntityWithAi) (Object) this));
goalSelector.add(3, new FleeEndRodGoal((MobEntityWithAi) (Object) this)); goalSelector.add(3, new FleeEndRodGoal((MobEntityWithAi) (Object) this));
if ((Object) this instanceof CreeperEntity) { if ((Object) this instanceof CreeperEntity) {
goalSelector.add(3, new ExplodeArtificialBlockGoal((MobEntityWithAi) (Object) this)); goalSelector.add(3, new ExplodeArtificialBlockGoal((MobEntityWithAi) (Object) this));