Skip to content

Commit

Permalink
WIP hide in block goal
Browse files Browse the repository at this point in the history
  • Loading branch information
WenXin20 committed Jan 6, 2025
1 parent d2612c7 commit f0817da
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .bbmodels/piranha_plant.bbmodel

Large diffs are not rendered by default.

105 changes: 95 additions & 10 deletions src/main/java/com/wenxin2/marioverse/entities/PiranhaPlantEntity.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.wenxin2.marioverse.entities;

import com.wenxin2.marioverse.entities.ai.goals.NearestAttackableTagGoal;
import com.wenxin2.marioverse.entities.ai.goals.PiranhaPlantHideInBlockGoal;
import com.wenxin2.marioverse.init.DamageSourceRegistry;
import com.wenxin2.marioverse.init.SoundRegistry;
import com.wenxin2.marioverse.init.TagRegistry;
Expand All @@ -13,17 +14,20 @@
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.RandomSource;
import net.minecraft.world.Difficulty;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoAnimatable;
Expand All @@ -41,6 +45,8 @@ public class PiranhaPlantEntity extends Monster implements GeoEntity {
private static final EntityDataAccessor<Byte> DATA_ID_HIDE_FLAGS = SynchedEntityData.defineId(PiranhaPlantEntity.class, EntityDataSerializers.BYTE);
public static final RawAnimation CONSTANT_BITES_ANIM = RawAnimation.begin().thenLoop("piranha_plant.constant_bite");
public static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlayAndHold("piranha_plant.death");
public static final RawAnimation EMERGE_ANIM = RawAnimation.begin().thenPlayAndHold("piranha_plant.emerge");
public static final RawAnimation HIDE_ANIM = RawAnimation.begin().thenPlayAndHold("piranha_plant.hide");
public static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("piranha_plant.idle");
public static final RawAnimation SQUASH_ANIM = RawAnimation.begin().thenPlayAndHold("piranha_plant.squash");
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
Expand Down Expand Up @@ -71,10 +77,6 @@ protected void playStepSound(BlockPos pos, BlockState state) {
this.playSound(SoundRegistry.GOOMBA_STEP.get(), 1.0F, 1.0F);
}

protected SoundEvent getBumpSound() {
return SoundRegistry.GOOMBA_BUMP.get();
}

@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
Expand All @@ -83,7 +85,8 @@ protected void defineSynchedData(SynchedEntityData.Builder builder) {

@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 0.6D, true));
this.goalSelector.addGoal(0, new PiranhaPlantHideInBlockGoal(this, 40, 40));
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 0.6D, true));
this.targetSelector.addGoal(0, new NearestAttackableTagGoal(this, TagRegistry.PIRANHA_PLANT_CAN_ATTACK, true));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers());
}
Expand All @@ -94,6 +97,7 @@ public void registerControllers(AnimatableManager.ControllerRegistrar controller
controllers.add(new AnimationController<>(this, "Idle", 5, this::walkAnimController));
controllers.add(new AnimationController<>(this, "Run", 5, this::walkAnimController));
controllers.add(new AnimationController<>(this, "Squash", 5, this::squashAnimController));
controllers.add(new AnimationController<>(this, "Hide", 5, this::hideAnimController));
controllers.add(DefaultAnimations.genericAttackAnimation(this, DefaultAnimations.ATTACK_BITE).transitionLength(1));
}

Expand All @@ -112,6 +116,14 @@ protected <E extends GeoAnimatable> PlayState walkAnimController(final Animation
return PlayState.CONTINUE;
}

protected <E extends GeoAnimatable> PlayState hideAnimController(final AnimationState<E> event) {
if (this.isHiding()) {
event.setAndContinue(HIDE_ANIM);
} else if (this.level().getBlockState(this.blockPosition().below()).is(TagRegistry.PIRANHA_PLANTS_CAN_HIDE))
event.setAndContinue(EMERGE_ANIM);
return PlayState.CONTINUE;
}

protected <E extends GeoAnimatable> PlayState squashAnimController(final AnimationState<E> event) {
if (this.dead) {
if (this.getLastDamageSource() != null
Expand All @@ -137,17 +149,81 @@ public boolean isPushable() {
return false;
}

// @Override
// public boolean canBeCollidedWith() {
// return !this.isHiding();
// }

@Override
public boolean isInWall() {
if (isHiding()) {
return false;
} else return super.isInWall();
}

@Override
protected boolean wouldNotSuffocateAtTargetPose(Pose pose) {
AABB aabb = this.getDimensions(pose).makeBoundingBox(this.position());
return this.level().noBlockCollision(this, aabb) || this.isHiding();
}

@NotNull
@Override
protected AABB makeBoundingBox() {
AABB originalBoundingBox = super.makeBoundingBox();

if (isHiding()) {
double height = originalBoundingBox.getYsize() * 0.5;
return new AABB(originalBoundingBox.minX, originalBoundingBox.minY, originalBoundingBox.minZ,
originalBoundingBox.maxX, originalBoundingBox.maxY * 0.5, originalBoundingBox.maxZ);
} else return super.makeBoundingBox();
}

public boolean isHiding() {
return this.getHideFlag(8) && this.getPersistentData().getInt("marioverse:piranha_hide_cooldown") > 0;
return this.getHideFlag(8)/* && this.getPersistentData().getInt("marioverse:piranha_plant_hide_cooldown") > 0*/;
}

@Override
public void tick() {
super.tick();
this.checkForCollisionsAndWakeUp();
this.checkForCollisions();
double targetY;

// int hideCooldown = this.getPersistentData().getInt("marioverse:piranha_plant_hide_cooldown");
// if (hideCooldown > 0) {
// --hideCooldown;
// }

if (this.isInWaterOrBubble())
this.ejectPassengers();

if (this.isHiding()) {
this.noPhysics = true;
this.setNoGravity(true);
} else {
this.noPhysics = false;
this.setNoGravity(false);
}

// if (!this.isHiding()
// && this.level().getBlockState(this.blockPosition().below()).is(TagRegistry.PIRANHA_PLANTS_CAN_HIDE)) {
// targetY = this.blockPosition().getY() - 1;
// this.tryToHide();
// this.getPersistentData().putInt("marioverse:piranha_plant_hide_cooldown", 40);
// } else {
// targetY = this.blockPosition().getY();
// }
//
// double currentY = this.getY();
// double speed = 0.1;
//
// if (Math.abs(targetY - currentY) > speed) {
// double direction = targetY > currentY ? speed : -speed;
// this.setDeltaMovement(0, direction, 0);
// } else {
// this.setDeltaMovement(0, 0, 0);
// this.setPos(this.getX(), targetY, this.getZ());
// }
}

@Override
Expand Down Expand Up @@ -192,9 +268,9 @@ protected Vec3 getLeashOffset() {
return new Vec3(0.0, this.getEyeHeight() - 0.5D, this.getBbWidth() * 0.4F);
}

public void checkForCollisionsAndWakeUp() {
public void checkForCollisions() {
List<Entity> nearbyEntities = this.level().getEntities(this,
this.getBoundingBox().inflate(0.25D, 0, 0.25D), entity -> !entity.isSpectator()
this.getBoundingBox().inflate(0.15D), entity -> !entity.isSpectator()
&& entity instanceof LivingEntity && !(entity instanceof PiranhaPlantEntity));

if (!nearbyEntities.isEmpty()) {
Expand All @@ -203,6 +279,7 @@ public void checkForCollisionsAndWakeUp() {
|| !(collidingEntity.getType().is(TagRegistry.PIRANHA_PLANT_CAN_ATTACK)))
return;

this.swing(InteractionHand.MAIN_HAND);
this.doHurtTarget(collidingEntity);
break;
}
Expand All @@ -219,10 +296,18 @@ private boolean getHideFlag(int i) {

public void tryToHide() {
this.hide(Boolean.TRUE);
this.getPersistentData().putInt("marioverse:piranha_hide_cooldown", 40);
this.stopInPlace();
}

public void stopHiding() {
this.hide(Boolean.FALSE);
this.isHideStoping();
}

public boolean isHideStoping() {
return this.getHideFlag(8);
}

private void setHideFlag(int i, boolean b) {
byte b0 = this.entityData.get(DATA_ID_HIDE_FLAGS);
if (b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ protected AABB getTargetSearchArea(double followDistance) {
}

protected void findTarget() {
if (this.target != null && this.target.isAlive() && this.mob.distanceToSqr(this.target) < this.getFollowDistance() * this.getFollowDistance()) {
return;
}
// if (this.target != null && this.target.isAlive()
// && this.mob.distanceToSqr(this.target) < this.getFollowDistance() * this.getFollowDistance()) {
// return;
// }

if (this.target == null || !this.target.isAlive()) {
List<LivingEntity> potentialTargets = this.mob.level().getEntitiesOfClass(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.wenxin2.marioverse.entities.ai.goals;

import com.wenxin2.marioverse.entities.PiranhaPlantEntity;
import com.wenxin2.marioverse.init.TagRegistry;
import java.util.EnumSet;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;

public class PiranhaPlantHideInBlockGoal extends Goal {
private final PiranhaPlantEntity entity;
private final int hideDuration; // Ticks to remain hidden
private int hideCooldown;
private int hideTime;
private boolean isHiding;
private double targetY;

public PiranhaPlantHideInBlockGoal(PiranhaPlantEntity entity, int hideDuration, int hideCooldown) {
this.entity = entity;
this.hideCooldown = hideCooldown;
this.hideDuration = hideDuration;
this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
this.isHiding = false;
}

@Override
public boolean canUse() {
if (hideCooldown > 0) {
--hideCooldown;
return false;
}

BlockPos posBelow = this.entity.blockPosition().below();
BlockState blockBelow = this.entity.level().getBlockState(posBelow);
return blockBelow.is(TagRegistry.PIRANHA_PLANTS_CAN_HIDE);
}

@Override
public void start() {
hideTime = 0;
hideCooldown = hideDuration;
BlockPos posBelow = entity.blockPosition().below();
targetY = posBelow.getY();
isHiding = false;
}

@Override
public void tick() {
double currentY = entity.getY();
double speed = 0.1;

if (!isHiding) {
// Move down to hide
if (currentY > targetY + speed) {
entity.setDeltaMovement(0, -speed, 0);
entity.tryToHide();
} else {
entity.setDeltaMovement(0, 0, 0);
entity.setPos(entity.getX(), targetY, entity.getZ());
entity.tryToHide(); // Activate hiding
isHiding = true;
}
} else {
// Stay hidden for `hideDuration` ticks
hideTime++;
if (hideTime >= hideDuration) {
// Start rising after hiding duration
targetY = entity.getY() + 1.0; // Move up by 1 block
if (currentY < targetY - speed) {
entity.setDeltaMovement(0, speed, 0);
} else {
entity.setDeltaMovement(0, 0, 0);
entity.setPos(entity.getX(), targetY, entity.getZ());
entity.stopHiding(); // Exit hiding state
isHiding = false;
}
}
}
}

@Override
public boolean canContinueToUse() {
return hideCooldown > 0 || isHiding;
}
}
1 change: 1 addition & 0 deletions src/main/java/com/wenxin2/marioverse/init/TagRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class TagRegistry {
public static final TagKey<Block> MELTS_INTO_PACKED_ICE = blockTags("melts_into_packed_ice");
public static final TagKey<Block> MELTS_INTO_WATER = blockTags("melts_into_water");
public static final TagKey<Block> QUESTION_BLOCK_BLOCKS = blockTags("question_blocks");
public static final TagKey<Block> PIRANHA_PLANTS_CAN_HIDE = blockTags("piranha_plants_can_hide");
public static final TagKey<Block> SMASHABLE_BLOCKS = blockTags("smashable_blocks");
public static final TagKey<Block> WARP_PIPE_BLOCKS = blockTags("warp_pipes");
public static final TagKey<Block> WRENCH_EFFICIENT = blockTags("wrench_efficient");
Expand Down
Loading

0 comments on commit f0817da

Please sign in to comment.