Skip to content

Commit

Permalink
Rotate piranha based on attached block side
Browse files Browse the repository at this point in the history
  • Loading branch information
WenXin20 committed Jan 15, 2025
1 parent ac32ace commit 9542c73
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.wenxin2.marioverse.client.renderers.entities;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.wenxin2.marioverse.client.models.entities.PiranhaPlantModel;
import com.wenxin2.marioverse.entities.PiranhaPlantEntity;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
Expand All @@ -14,4 +16,36 @@ public PiranhaPlantRenderer(EntityRendererProvider.Context renderManager) {
protected float getDeathMaxRotation(PiranhaPlantEntity animatable) {
return 0.0F;
}

@Override
protected void applyRotations(PiranhaPlantEntity animatable, PoseStack poseStack, float ageInTicks, float rotationYaw, float partialTick, float nativeScale) {
if (animatable.getAttachedSide() != null) {
switch (animatable.getAttachedSide()) {
case UP:
break;
case DOWN:
poseStack.mulPose(Axis.XP.rotationDegrees(180));
poseStack.translate(0, -1.0, 0);
break;
case NORTH:
poseStack.mulPose(Axis.XP.rotationDegrees(-90));
poseStack.translate(0, 0, 0.5D);
break;
case SOUTH:
poseStack.mulPose(Axis.XP.rotationDegrees(90));
poseStack.translate(0, 0, -0.5D);
break;
case EAST:
poseStack.mulPose(Axis.ZP.rotationDegrees(-90));
poseStack.translate(-0.5D, 0, 0);
break;
case WEST:
poseStack.mulPose(Axis.ZP.rotationDegrees(90));
poseStack.translate(0.5D, 0, 0);
break;
}
}

super.applyRotations(animatable, poseStack, ageInTicks, rotationYaw, partialTick, nativeScale);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class PiranhaPlantEntity extends Monster implements GeoEntity {
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);
private BlockPos attachedBlock = null;
private Direction attachedSide = null;

@Nullable private BlockPos targetPosition;

Expand Down Expand Up @@ -174,6 +176,24 @@ public void tick() {
AttributeInstance scale = this.getAttribute(Attributes.SCALE);
if (scale != null && this.level().getBlockState(this.blockPosition()).getBlock() instanceof FlowerPotBlock)
scale.setBaseValue(0.4F);

if (attachedBlock != null) {
if (this.level().isEmptyBlock(attachedBlock)) {
this.detachFromBlock();
} else {
this.setNoGravity(true);
this.setDeltaMovement(Vec3.ZERO);
}
}

if (attachedBlock == null) {
BlockPos newBlock = this.findValidBlock();
if (newBlock != null) {
this.attachToBlock(newBlock, this.determineAttachmentSide(newBlock));
} else if (this.onGround() && this.getAttachedSide() != Direction.UP) {
setNoGravity(false);
}
}
}

@Override
Expand Down Expand Up @@ -231,6 +251,49 @@ protected Vec3 getLeashOffset() {
return new Vec3(0.0, this.getEyeHeight() / 1.75, this.getBbWidth() / 2);
}

public Direction getAttachedSide() {
return attachedSide;
}

public void setAttachedSide(Direction side) {
this.attachedSide = side;
}

public void attachToBlock(BlockPos blockPos, Direction side) {
this.attachedBlock = blockPos;
this.attachedSide = side;
this.setNoGravity(true);
this.setDeltaMovement(Vec3.ZERO);
}

public void detachFromBlock() {
this.attachedBlock = null;
this.attachedSide = null;
this.setNoGravity(false);
}

private BlockPos findValidBlock() {
BlockPos entityPos = this.blockPosition();
for (Direction direction : Direction.values()) {
BlockPos neighborPos = entityPos.relative(direction);
BlockState neighborState = this.level().getBlockState(neighborPos);
if (!neighborState.isAir() && neighborState.isFaceSturdy(this.level(), neighborPos, direction.getOpposite())) {
return neighborPos;
}
}
return null;
}

private Direction determineAttachmentSide(BlockPos blockPos) {
BlockPos entityPos = this.blockPosition();
for (Direction direction : Direction.values()) {
if (blockPos.relative(direction.getOpposite()).equals(entityPos)) {
return direction.getOpposite();
}
}
return Direction.UP;
}

private float currentScale = 1.0F;
private float targetScale = 1.0F;
private float scaleCooldown;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public class EntityRegistry {
.nameTagOffset(-0.05F).build("mini_goomba"));
public static final DeferredHolder<EntityType<?>, EntityType<PiranhaPlantEntity>> PIRANHA_PLANT =
Marioverse.ENTITIES.register("piranha_plant", () -> EntityType.Builder.of(PiranhaPlantEntity::new, MobCategory.MONSTER)
.sized(1.0F, 2.3125F).eyeHeight(2.0F).ridingOffset(0.1F).build("piranha_plant"));
.sized(1.0F, 1.0F).eyeHeight(1.0F).ridingOffset(0.1F).build("piranha_plant"));

@SubscribeEvent
public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/wenxin2/marioverse/init/ItemRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.wenxin2.marioverse.Marioverse;
import com.wenxin2.marioverse.items.BasePowerUpItem;
import com.wenxin2.marioverse.items.BetterSpawnEggItem;
import com.wenxin2.marioverse.items.FireCostumeItem;
import com.wenxin2.marioverse.items.OneUpMushroomItem;
import com.wenxin2.marioverse.items.WarpDisruptorItem;
Expand Down Expand Up @@ -78,7 +79,7 @@ public class ItemRegistry {
MINI_GOOMBA_SPAWN_EGG = registerItem("mini_goomba_spawn_egg",
() -> new DeferredSpawnEggItem(EntityRegistry.MINI_GOOMBA, 0xCC5F51, 0xF7CDA5, new Item.Properties()));
PIRANHA_PLANT_SPAWN_EGG = registerItem("piranha_plant_spawn_egg",
() -> new DeferredSpawnEggItem(EntityRegistry.PIRANHA_PLANT, 0xFF0000, 0xFFFFFF, new Item.Properties()));
() -> new BetterSpawnEggItem(EntityRegistry.PIRANHA_PLANT, 0xFF0000, 0xFFFFFF, new Item.Properties()));
}

public static <T extends Item> DeferredItem<T> registerItem(String name, Supplier<T> item) {
Expand Down
28 changes: 14 additions & 14 deletions src/main/java/com/wenxin2/marioverse/items/BasePowerUpItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,44 @@ public BasePowerUpItem(Supplier<? extends EntityType<? extends Mob>> entityType,
@NotNull
@Override
public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel();
if (!(level instanceof ServerLevel)) {
Level world = context.getLevel();
if (!(world instanceof ServerLevel)) {
return InteractionResult.SUCCESS;
} else {
ItemStack stack = context.getItemInHand();
BlockPos blockpos = context.getClickedPos();
Direction direction = context.getClickedFace();
BlockState blockstate = level.getBlockState(blockpos);
BlockState blockstate = world.getBlockState(blockpos);

if (level.getBlockEntity(blockpos) instanceof Spawner spawner
if (world.getBlockEntity(blockpos) instanceof Spawner spawner
&& (context.getPlayer() != null && context.getPlayer().isCreative())) {
EntityType<?> entitytype1 = this.getType(stack);
spawner.setEntityId(entitytype1, level.getRandom());
level.sendBlockUpdated(blockpos, blockstate, blockstate, 3);
level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, blockpos);
spawner.setEntityId(entitytype1, world.getRandom());
world.sendBlockUpdated(blockpos, blockstate, blockstate, 3);
world.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, blockpos);
stack.shrink(1);
return InteractionResult.CONSUME;
} else if (level.getBlockEntity(blockpos) instanceof Spawner spawner
} else if (world.getBlockEntity(blockpos) instanceof Spawner spawner
&& context.getPlayer() == null) {
EntityType<?> entitytype1 = this.getType(stack);
spawner.setEntityId(entitytype1, level.getRandom());
level.sendBlockUpdated(blockpos, blockstate, blockstate, 3);
level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, blockpos);
spawner.setEntityId(entitytype1, world.getRandom());
world.sendBlockUpdated(blockpos, blockstate, blockstate, 3);
world.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, blockpos);
stack.shrink(1);
return InteractionResult.CONSUME;
} else {
BlockPos blockpos1;
if (blockstate.getCollisionShape(level, blockpos).isEmpty()) {
if (blockstate.getCollisionShape(world, blockpos).isEmpty()) {
blockpos1 = blockpos;
} else {
blockpos1 = blockpos.relative(direction);
}

EntityType<?> entitytype = this.getType(stack);
if (entitytype.spawn((ServerLevel) level, stack, context.getPlayer(), blockpos1, MobSpawnType.SPAWN_EGG, true,
if (entitytype.spawn((ServerLevel) world, stack, context.getPlayer(), blockpos1, MobSpawnType.SPAWN_EGG, true,
!Objects.equals(blockpos, blockpos1) && direction == Direction.UP) != null) {
stack.shrink(1);
level.gameEvent(context.getPlayer(), GameEvent.ENTITY_PLACE, blockpos);
world.gameEvent(context.getPlayer(), GameEvent.ENTITY_PLACE, blockpos);
}

return InteractionResult.CONSUME;
Expand Down
70 changes: 70 additions & 0 deletions src/main/java/com/wenxin2/marioverse/items/BetterSpawnEggItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.wenxin2.marioverse.items;

import com.wenxin2.marioverse.entities.PiranhaPlantEntity;
import java.util.Objects;
import java.util.function.Supplier;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.Spawner;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.neoforged.neoforge.common.DeferredSpawnEggItem;

public class BetterSpawnEggItem extends DeferredSpawnEggItem {
public BetterSpawnEggItem(Supplier<? extends EntityType<? extends Mob>> entityType,
int primaryColor, int secondaryColor, Properties properties) {
super(entityType, primaryColor, secondaryColor, properties);
}

@Override
public InteractionResult useOn(UseOnContext context) {
Level world = context.getLevel();
if (!(world instanceof ServerLevel)) {
return InteractionResult.SUCCESS;
} else {
ItemStack stack = context.getItemInHand();
BlockPos pos = context.getClickedPos();
Direction direction = context.getClickedFace();
BlockState state = world.getBlockState(pos);

if (world.getBlockEntity(pos) instanceof Spawner spawner) {
EntityType<?> entityType1 = this.getType(stack);
spawner.setEntityId(entityType1, world.getRandom());
world.sendBlockUpdated(pos, state, state, 3);
world.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, pos);
stack.shrink(1);
return InteractionResult.CONSUME;
} else {

EntityType<?> entityType = this.getType(stack);
BlockPos spawnPos = context.getClickedFace().getOpposite() == Direction.DOWN
? (new BlockPos(pos.getX(), (int) (pos.getY() - entityType.getHeight()), pos.getZ())) : pos.relative(context.getClickedFace());
BlockPos pos1;
if (state.getCollisionShape(world, spawnPos).isEmpty())
pos1 = spawnPos;
else pos1 = spawnPos.relative(direction);

Entity entity = entityType.spawn((ServerLevel) world, stack, context.getPlayer(), pos1, MobSpawnType.SPAWN_EGG, true,
!Objects.equals(spawnPos, pos1) && direction == Direction.UP);
if (entity != null) {
stack.shrink(1);
world.gameEvent(context.getPlayer(), GameEvent.ENTITY_PLACE, pos);

if (entity instanceof PiranhaPlantEntity piranhaPlant)
piranhaPlant.setAttachedSide(context.getClickedFace().getOpposite());
}

return InteractionResult.CONSUME;
}
}
}
}

0 comments on commit 9542c73

Please sign in to comment.