first herc beetle implementation

This commit is contained in:
craisinlord committed 2026-06-30 14:02:16 -05:00
1 parent 14a1dfda1e
commit 8cabdb33bf
52 files changed
+2102 -411

No files matched your search

@@ -150,7 +150,7 @@ public final class AntarchySettings {
private static int basiliskSpawnMaxLightLevel = 5;
private static double basiliskHealth = 150.0D;
private static double basiliskAttackDamage = 36.0D;
private static double basiliskMovementSpeed = 0.30D;
private static double basiliskMovementSpeed = 0.225D;
private static double basiliskArmor = 6.0D;
private static double basiliskKnockbackResistance = 0.5D;
private static double basiliskFollowRange = 28.0D;
@@ -470,6 +470,9 @@ public final class AntarchySettings {
private static double cheepHealth = 8.0D;
private static double cheepAttackDamage = 3.0D;
private static double dorrieHealth = 60.0D;
private static double herculesBeetleHealth = 500.0D;
private static double herculesBeetleAttackDamage = 30.0D;
private static double herculesBeetleChargeDamage = 40.0D;
private AntarchySettings() {
}
@@ -2398,5 +2401,11 @@ public final class AntarchySettings {
public static double cheepAttackDamage() { return cheepAttackDamage; }
public static void setCheepAttackDamage(double v) { cheepAttackDamage = v; }
public static double dorrieHealth() { return dorrieHealth; }
public static double herculesBeetleHealth() { return herculesBeetleHealth; }
public static void setHerculesBeetleHealth(double v) { herculesBeetleHealth = v; }
public static double herculesBeetleAttackDamage() { return herculesBeetleAttackDamage; }
public static void setHerculesBeetleAttackDamage(double v) { herculesBeetleAttackDamage = v; }
public static double herculesBeetleChargeDamage() { return herculesBeetleChargeDamage; }
public static void setHerculesBeetleChargeDamage(double v) { herculesBeetleChargeDamage = v; }
public static void setDorrieHealth(double v) { dorrieHealth = v; }
}
@@ -5,6 +5,7 @@ import com.craisinlord.antarchy.content.entity.BomberEntity;
import com.craisinlord.antarchy.content.entity.ButterflyEntity;
import com.craisinlord.antarchy.content.entity.CaterpillarEntity;
import com.craisinlord.antarchy.content.entity.EasterBunnyEntity;
import com.craisinlord.antarchy.content.entity.HerculesBeetleEntity;
import com.craisinlord.antarchy.content.entity.HushProjectileEntity;
import com.craisinlord.antarchy.content.entity.StinkBugEntity;
import com.craisinlord.antarchy.content.entity.WaterBombEntity;
@@ -96,6 +97,8 @@ public final class AntarchyObjects {
@SuppressWarnings("unchecked")
public static Supplier<EntityType<com.craisinlord.antarchy.content.entity.DorrieEntity>> DORRIE = (Supplier<EntityType<com.craisinlord.antarchy.content.entity.DorrieEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<EntityType<HerculesBeetleEntity>> HERCULES_BEETLE = (Supplier<EntityType<HerculesBeetleEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<net.minecraft.world.item.Item> CHEEP_ITEM = (Supplier<net.minecraft.world.item.Item>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<Block> DUPLICATOR_LOG = (Supplier<Block>) UNBOUND;
@@ -433,6 +436,10 @@ public final class AntarchyObjects {
OCTOPUS_BOMB = supplier;
}
public static void setHerculesBeetle(Supplier<EntityType<HerculesBeetleEntity>> supplier) {
HERCULES_BEETLE = supplier;
}
public static BlockBehaviour.Properties shellstoneProperties() {
return BlockBehaviour.Properties.ofFullCopy(Blocks.STONE).requiresCorrectToolForDrops();
}
@@ -30,6 +30,7 @@ public final class AntarchyTags {
public static final TagKey<Block> MOLEVORE_SEE_THROUGH_BLOCKS = TagKey.create(Registries.BLOCK, id("molevore_see_through_blocks"));
public static final TagKey<Block> TERMITE_FOODS = TagKey.create(Registries.BLOCK, id("termite_foods"));
public static final TagKey<Block> UMBRAL_MOSS_REPLACEABLE = TagKey.create(Registries.BLOCK, id("umbral_moss_replaceable"));
public static final TagKey<Block> HERCULES_BEETLE_CHARGE_IMMUNE_BLOCKS = TagKey.create(Registries.BLOCK, id("hercules_beetle_charge_immune_blocks"));
private Blocks() {
}
@@ -88,6 +89,7 @@ public final class AntarchyTags {
public static final TagKey<Item> CATERPILLAR_FOODS = TagKey.create(Registries.ITEM, id("caterpillar_foods"));
public static final TagKey<Item> BUTTERFLY_BREEDING_FOODS = TagKey.create(Registries.ITEM, id("butterfly_breeding_foods"));
public static final TagKey<Item> REVERIE_DUPLICATION_ITEMS = TagKey.create(Registries.ITEM, id("reverie_duplication_items"));
public static final TagKey<Item> HERCULES_BEETLE_FOOD = TagKey.create(Registries.ITEM, id("hercules_beetle_food"));
private Items() {
}
@@ -104,6 +104,19 @@ public final class StinkyBehavior {
applyNearbyNausea(entity, STINK_BUG_AURA_RADIUS, STINK_BUG_BURST_NAUSEA_DURATION_TICKS);
}
public static void applyBurstStinkyEffect(LivingEntity source, double radius, int durationTicks) {
if (source.level().isClientSide()) {
return;
}
for (LivingEntity entity : source.level().getEntitiesOfClass(
LivingEntity.class,
source.getBoundingBox().inflate(radius),
e -> e.isAlive() && e != source
)) {
entity.addEffect(new MobEffectInstance(AntarchyObjects.STINKY_EFFECT.get(), durationTicks, 0, false, true, true));
}
}
public static void applyNearbyNausea(LivingEntity source, double radius, int durationTicks) {
if (source.level().isClientSide()) {
return;
@@ -0,0 +1,26 @@
package com.craisinlord.antarchy.content.client;
public final class HerculesBeetleImpactShakeClientState {
private static int shakeTicks;
private HerculesBeetleImpactShakeClientState() {
}
public static void trigger(int ticks) {
shakeTicks = Math.max(shakeTicks, Math.max(0, ticks));
}
public static void tick() {
if (shakeTicks > 0) {
shakeTicks--;
}
}
public static int getTicks() {
return shakeTicks;
}
public static void clear() {
shakeTicks = 0;
}
}
@@ -0,0 +1,28 @@
package com.craisinlord.antarchy.content.client.model;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.entity.HerculesBeetleEntity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class HerculesBeetleModel extends GeoModel<HerculesBeetleEntity> {
private static final ResourceLocation TEXTURE =
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/hercules_beetle/hercules_beetle.png");
private static final ResourceLocation TEXTURE_SADDLED =
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/hercules_beetle/hercules_beetle_saddle.png");
@Override
public ResourceLocation getModelResource(HerculesBeetleEntity animatable) {
return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/hercules_beetle.geo.json");
}
@Override
public ResourceLocation getTextureResource(HerculesBeetleEntity animatable) {
return animatable.hasSaddle() ? TEXTURE_SADDLED : TEXTURE;
}
@Override
public ResourceLocation getAnimationResource(HerculesBeetleEntity animatable) {
return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/hercules_beetle.animation.json");
}
}
@@ -0,0 +1,12 @@
package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.client.model.HerculesBeetleModel;
import com.craisinlord.antarchy.content.entity.HerculesBeetleEntity;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class HerculesBeetleRenderer extends GeoEntityRenderer<HerculesBeetleEntity> {
public HerculesBeetleRenderer(EntityRendererProvider.Context context) {
super(context, new HerculesBeetleModel());
}
}
@@ -1,40 +0,0 @@
package com.craisinlord.antarchy.content.client.screen;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.menu.DorrieMenu;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
public class DorrieScreen extends AbstractContainerScreen<DorrieMenu> {
// A 176 × 130 texture: saddle slot area at top, player inventory below.
// Art file: assets/antarchy/textures/gui/container/dorrie.png
private static final ResourceLocation TEXTURE =
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/gui/container/dorrie.png");
public static final int TEXTURE_WIDTH = 176;
public static final int TEXTURE_HEIGHT = 130;
public DorrieScreen(DorrieMenu menu, Inventory playerInventory, Component title) {
super(menu, playerInventory, title);
this.imageWidth = TEXTURE_WIDTH;
this.imageHeight = TEXTURE_HEIGHT;
this.inventoryLabelY = this.imageHeight - 94;
}
@Override
protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY) {
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
guiGraphics.blit(TEXTURE, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight);
}
@Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
this.renderBackground(guiGraphics, mouseX, mouseY, partialTick);
super.render(guiGraphics, mouseX, mouseY, partialTick);
this.renderTooltip(guiGraphics, mouseX, mouseY);
}
}
@@ -1,13 +1,14 @@
package com.craisinlord.antarchy.content.entity;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.config.AntarchySettings;
import com.craisinlord.antarchy.content.item.CheepOnAStickItem;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
@@ -31,8 +32,6 @@ import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.ai.goal.RandomSwimmingGoal;
import net.minecraft.world.entity.ai.goal.TryFindWaterGoal;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation;
import net.minecraft.world.entity.animal.Animal;
@@ -40,7 +39,6 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoEntity;
@@ -54,6 +52,7 @@ import software.bernie.geckolib.util.GeckoLibUtil;
public class DorrieEntity extends Animal implements GeoEntity {
private static final ResourceLocation CHEEP_ITEM_ID = ResourceLocation.fromNamespaceAndPath("antarchy", "cheep");
private static final EntityDataAccessor<Boolean> HAS_SADDLE =
SynchedEntityData.defineId(DorrieEntity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Boolean> TAMED =
@@ -62,8 +61,8 @@ public class DorrieEntity extends Animal implements GeoEntity {
SynchedEntityData.defineId(DorrieEntity.class, EntityDataSerializers.INT);
private static final int MAX_CHARGE_TICKS = 40;
private static final float BASE_SPEED = 0.6F;
private static final float BOOSTED_SPEED = 1.3F;
private static final float WATER_RIDE_SPEED = 1.26F;
private static final float LAND_BEACH_SPEED = 0.04F;
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
private static final RawAnimation SWIM_ANIM = RawAnimation.begin().thenLoop("swim");
@@ -73,16 +72,21 @@ public class DorrieEntity extends Animal implements GeoEntity {
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private static final int RIDES_TO_TAME = 4;
private static final int BUCK_DELAY_TICKS = 60;
private int chargeTicks = 0;
private boolean isCharging = false;
private boolean isLeaping = false;
private boolean wasInAir = false;
private int landAnimTicks = 0;
private boolean isPressingJump = false;
private int rideAttempts = 0;
private int buckTimer = 0;
private int swimForwardTicks = 0;
public DorrieEntity(EntityType<? extends DorrieEntity> entityType, Level level) {
super(entityType, level);
this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, BASE_SPEED, 1.0F, true);
this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 1.0F, true);
this.lookControl = new SmoothSwimmingLookControl(this, 10);
}
@@ -113,12 +117,11 @@ public class DorrieEntity extends Animal implements GeoEntity {
public static AttributeSupplier.Builder createAttributes() {
return Mob.createMobAttributes()
.add(Attributes.MAX_HEALTH, AntarchySettings.dorrieHealth())
.add(Attributes.MOVEMENT_SPEED, BASE_SPEED)
.add(Attributes.MOVEMENT_SPEED, 1.0D)
.add(Attributes.FOLLOW_RANGE, 16.0D)
.add(Attributes.ATTACK_DAMAGE, 4.0D);
}
public boolean hasSaddle() {
return this.entityData.get(HAS_SADDLE);
}
@@ -143,12 +146,12 @@ public class DorrieEntity extends Animal implements GeoEntity {
this.entityData.set(JUMP_CHARGE, charge);
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.putBoolean("Tamed", this.isTamed());
tag.putBoolean("HasSaddle", this.hasSaddle());
tag.putInt("RideAttempts", this.rideAttempts);
}
@Override
@@ -156,28 +159,20 @@ public class DorrieEntity extends Animal implements GeoEntity {
super.readAdditionalSaveData(tag);
this.setTamed(tag.getBoolean("Tamed"));
this.setSaddle(tag.getBoolean("HasSaddle"));
this.rideAttempts = tag.getInt("RideAttempts");
}
@Override
public InteractionResult mobInteract(Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
if (!this.isTamed()) {
if (!this.level().isClientSide && this.isCheepItem(stack)) {
if (!player.getAbilities().instabuild) stack.shrink(1);
if (this.random.nextInt(3) == 0) {
this.setTamed(true);
this.playSound(SoundEvents.HORSE_BREATHE, 0.5F, 1.0F);
} else {
this.playSound(SoundEvents.DOLPHIN_HURT, 0.5F, 1.0F);
}
return InteractionResult.sidedSuccess(this.level().isClientSide);
if (!this.level().isClientSide) {
player.startRiding(this);
}
return super.mobInteract(player, hand);
return InteractionResult.sidedSuccess(this.level().isClientSide);
}
// Remove saddle with empty hand
if (this.hasSaddle() && stack.isEmpty() && !player.isPassengerOfSameVehicle(this)) {
if (!this.level().isClientSide) {
this.setSaddle(false);
@@ -187,99 +182,112 @@ public class DorrieEntity extends Animal implements GeoEntity {
return InteractionResult.sidedSuccess(this.level().isClientSide);
}
// Apply saddle
if (!this.hasSaddle() && stack.is(Items.SADDLE)) {
if (!this.level().isClientSide) {
this.setSaddle(true);
if (!player.getAbilities().instabuild) stack.shrink(1);
if (!player.getAbilities().instabuild) {
stack.shrink(1);
}
this.playSound(SoundEvents.HORSE_SADDLE, 1.0F, 1.0F);
}
return InteractionResult.sidedSuccess(this.level().isClientSide);
}
// Mount
if (this.hasSaddle() && !player.isPassengerOfSameVehicle(this)) {
if (!this.level().isClientSide) player.startRiding(this);
if (!this.level().isClientSide) {
player.startRiding(this);
}
return InteractionResult.sidedSuccess(this.level().isClientSide);
}
return super.mobInteract(player, hand);
}
@Override
public boolean isFood(ItemStack stack) {
return this.isCheepItem(stack);
}
@Override
@Nullable
public LivingEntity getControllingPassenger() {
if (!this.isTamed() || !this.hasSaddle()) return null;
if (!this.isTamed() || !this.hasSaddle()) {
return null;
}
Entity passenger = this.getFirstPassenger();
if (passenger instanceof Player player) return player;
if (passenger instanceof Player player) {
return player;
}
return null;
}
private boolean riderHasCheepStick(Player player) {
return player.getMainHandItem().getItem() instanceof CheepOnAStickItem
|| player.getOffhandItem().getItem() instanceof CheepOnAStickItem;
}
private ItemStack getCheepStick(Player player) {
if (player.getMainHandItem().getItem() instanceof CheepOnAStickItem) return player.getMainHandItem();
if (player.getOffhandItem().getItem() instanceof CheepOnAStickItem) return player.getOffhandItem();
return ItemStack.EMPTY;
}
@Override
protected Vec3 getRiddenInput(Player player, Vec3 travelVector) {
if (!riderHasCheepStick(player)) return Vec3.ZERO;
float forward = player.zza > 0 ? player.zza : player.zza / 4.0F;
float forward = player.zza;
float strafe = player.xxa * 0.5F;
return new Vec3(strafe, travelVector.y, forward);
return new Vec3(strafe, 0, forward);
}
@Override
protected float getRiddenSpeed(Player player) {
float speed = BASE_SPEED;
if (riderHasCheepStick(player)) {
speed = BOOSTED_SPEED;
if (!this.level().isClientSide) {
ItemStack stick = getCheepStick(player);
if (!stick.isEmpty() && this.tickCount % 10 == 0) {
stick.hurtAndBreak(1, player,
player.getMainHandItem().getItem() instanceof CheepOnAStickItem
? net.minecraft.world.entity.EquipmentSlot.MAINHAND
: net.minecraft.world.entity.EquipmentSlot.OFFHAND);
}
}
}
float speed = (this.isInWater() || this.isInLava())
? WATER_RIDE_SPEED * (1.0F + Math.min(this.swimForwardTicks, 60) * 0.025F)
: LAND_BEACH_SPEED;
return (float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * speed;
}
@Override
public void tick() {
super.tick();
if (!this.level().isClientSide) {
LivingEntity passenger = this.getControllingPassenger();
if (passenger != null && isPressingJump) {
Vec3 mov = this.getDeltaMovement();
double boost = this.isInWater() ? 0.1D : 0.04D;
this.setDeltaMovement(mov.x, Math.min(mov.y + boost, 0.5D), mov.z);
this.hasImpulse = true;
}
if (passenger instanceof Player && isCharging) {
chargeTicks = Math.min(chargeTicks + 1, MAX_CHARGE_TICKS);
setJumpCharge((int) ((chargeTicks / (float) MAX_CHARGE_TICKS) * 100));
if (this.getControllingPassenger() instanceof Player player) {
this.setYRot(player.getYRot());
this.yRotO = this.getYRot();
this.yBodyRot = this.getYRot();
this.yHeadRot = this.getYRot();
if (this.isInWater() || this.isInLava()) {
if (player.zza > 0.05F) {
this.swimForwardTicks = Math.min(this.swimForwardTicks + 1, 60);
} else {
this.swimForwardTicks = Math.max(this.swimForwardTicks - 2, 0);
}
} else {
this.swimForwardTicks = 0;
}
} else {
this.swimForwardTicks = 0;
}
if (landAnimTicks > 0) landAnimTicks--;
if (!this.level().isClientSide && !this.isTamed() && this.getFirstPassenger() instanceof Player rider) {
buckTimer++;
if (buckTimer >= BUCK_DELAY_TICKS) {
rider.stopRiding();
buckTimer = 0;
rideAttempts++;
if (rideAttempts >= RIDES_TO_TAME) {
this.setTamed(true);
this.playSound(SoundEvents.HORSE_BREATHE, 0.8F, 1.0F);
} else {
this.playSound(SoundEvents.HORSE_ANGRY, 0.8F, 1.0F);
}
}
} else if (!this.isTamed() && this.getFirstPassenger() == null) {
buckTimer = 0;
}
if (!this.level().isClientSide && this.getControllingPassenger() instanceof Player && isCharging) {
chargeTicks = Math.min(chargeTicks + 1, MAX_CHARGE_TICKS);
setJumpCharge((int) ((chargeTicks / (float) MAX_CHARGE_TICKS) * 100));
}
// Surface buoyancy: when in water and not mid-leap, push toward the waterline.
// Stronger upward force when fully submerged, gentle when at the surface so
// Dorrie glides on top rather than diving or bouncing.
if (this.isInWater() && !isLeaping) {
Vec3 mov = this.getDeltaMovement();
double push = this.isUnderWater() ? 0.07D : 0.015D;
double cappedY = this.isUnderWater() ? 0.3D : 0.05D;
this.setDeltaMovement(mov.x, Math.min(mov.y + push, cappedY), mov.z);
}
if (landAnimTicks > 0) {
landAnimTicks--;
}
boolean inAirNow = !this.onGround() && !this.isInWater() && !this.isInLava();
if (wasInAir && !inAirNow && isLeaping) {
@@ -289,32 +297,29 @@ public class DorrieEntity extends Animal implements GeoEntity {
wasInAir = inAirNow;
}
public void setPressingJump(boolean pressing) {}
/** Called when the rider presses/releases space (up movement). */
public void setPressingJump(boolean pressing) {
this.isPressingJump = pressing;
}
/** Called when the rider presses left-control (charge start). */
public void startJumpCharge() {
if (!this.level().isClientSide) {
isCharging = true;
}
}
/** Called when the rider releases left-control (charge release). */
public void releaseJump() {
if (!this.level().isClientSide && isCharging) {
float power = chargeTicks / (float) MAX_CHARGE_TICKS;
if (power > 0.05F) {
double horizontal = 0.8D + power * 1.4D;
double vertical = 0.4D + power * 0.8D;
Vec3 look = this.getLookAngle();
Vec3 current = this.getDeltaMovement();
// Add to existing momentum — no direction snap. The rider already has
// forward speed, so the jump just launches them upward and slightly
// accelerates in the direction they're already facing.
double forwardAdd = power * 0.5D;
double vertical = 0.55D + power * 0.9D;
this.setDeltaMovement(
look.x * horizontal * 0.7D + current.x * 0.3D,
current.x + look.x * forwardAdd,
vertical,
look.z * horizontal * 0.7D + current.z * 0.3D
current.z + look.z * forwardAdd
);
this.hasImpulse = true;
isLeaping = true;
@@ -325,14 +330,14 @@ public class DorrieEntity extends Animal implements GeoEntity {
}
}
@Override
protected void positionRider(Entity passenger, MoveFunction moveFunction) {
if (this.hasPassenger(passenger)) {
Vec3 forward = this.getLookAngle().multiply(1.0D, 0.0D, 1.0D);
moveFunction.accept(passenger,
this.getX(),
this.getY() + this.getPassengersRidingOffset() + passenger.getBbHeight() * 0.5D,
this.getZ());
this.getX() - forward.x * 0.25D,
this.getY() + 0.5D,
this.getZ() - forward.z * 0.25D);
}
}
@@ -340,7 +345,6 @@ public class DorrieEntity extends Animal implements GeoEntity {
return 0.6D;
}
@Override
protected void dropEquipment() {
super.dropEquipment();
@@ -349,14 +353,12 @@ public class DorrieEntity extends Animal implements GeoEntity {
}
}
@Override
@Nullable
public DorrieEntity getBreedOffspring(ServerLevel level, AgeableMob mob) {
return null;
}
@Override
public boolean canBeLeashed() {
return true;
@@ -382,14 +384,15 @@ public class DorrieEntity extends Animal implements GeoEntity {
return SoundEvents.DOLPHIN_SWIM;
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController));
}
private PlayState mainAnimController(AnimationState<DorrieEntity> state) {
if (landAnimTicks > 0) return state.setAndContinue(JUMP_LAND_ANIM);
if (landAnimTicks > 0) {
return state.setAndContinue(JUMP_LAND_ANIM);
}
if (isLeaping) {
return state.setAndContinue(wasInAir ? JUMP_LOOP_ANIM : JUMP_START_ANIM);
}
@@ -401,12 +404,17 @@ public class DorrieEntity extends Animal implements GeoEntity {
return this.geoCache;
}
@Override
public boolean isFood(ItemStack stack) {
return this.isCheepItem(stack);
}
private boolean isCheepItem(ItemStack stack) {
return !stack.isEmpty() && stack.is(BuiltInRegistries.ITEM.getOptional(CHEEP_ITEM_ID).orElse(Items.AIR));
}
private static class HuntCheepGoal extends Goal {
private static final int COOLDOWN_TICKS = 600; // 30 seconds
private static final int COOLDOWN_TICKS = 600;
private static final double HUNT_RANGE = 16.0D;
private static final double ATTACK_RANGE_SQ = 2.5D * 2.5D;
@@ -421,13 +429,21 @@ public class DorrieEntity extends Animal implements GeoEntity {
@Override
public boolean canUse() {
if (dorrie.level().isClientSide) return false;
if (cooldown > 0) { cooldown--; return false; }
if (dorrie.level().isClientSide) {
return false;
}
if (cooldown > 0) {
cooldown--;
return false;
}
if (dorrie.getControllingPassenger() != null) {
return false;
}
List<CheepEntity> nearby = dorrie.level().getEntitiesOfClass(
CheepEntity.class,
dorrie.getBoundingBox().inflate(HUNT_RANGE)
);
if (nearby.isEmpty()) return false;
CheepEntity.class, dorrie.getBoundingBox().inflate(HUNT_RANGE));
if (nearby.isEmpty()) {
return false;
}
nearby.sort((a, b) -> Double.compare(a.distanceToSqr(dorrie), b.distanceToSqr(dorrie)));
target = nearby.get(0);
return true;
@@ -435,7 +451,9 @@ public class DorrieEntity extends Animal implements GeoEntity {
@Override
public boolean canContinueToUse() {
return target != null && target.isAlive() && dorrie.distanceToSqr(target) <= HUNT_RANGE * HUNT_RANGE * 4;
return target != null && target.isAlive()
&& dorrie.getControllingPassenger() == null
&& dorrie.distanceToSqr(target) <= HUNT_RANGE * HUNT_RANGE * 4;
}
@Override
@@ -445,11 +463,14 @@ public class DorrieEntity extends Animal implements GeoEntity {
@Override
public void tick() {
if (target == null) return;
if (target == null) {
return;
}
dorrie.getLookControl().setLookAt(target, 30.0F, 30.0F);
dorrie.getNavigation().moveTo(target, 1.4D);
if (dorrie.distanceToSqr(target) <= ATTACK_RANGE_SQ) {
target.hurt(dorrie.damageSources().mobAttack(dorrie), (float) dorrie.getAttributeValue(Attributes.ATTACK_DAMAGE));
target.hurt(dorrie.damageSources().mobAttack(dorrie),
(float) dorrie.getAttributeValue(Attributes.ATTACK_DAMAGE));
stop();
}
}
@@ -460,6 +481,5 @@ public class DorrieEntity extends Animal implements GeoEntity {
dorrie.getNavigation().stop();
cooldown = COOLDOWN_TICKS;
}
}
}
@@ -15,6 +15,7 @@ import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
import net.minecraft.world.entity.ai.goal.PanicGoal;
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.animal.Animal;
@@ -38,9 +39,12 @@ public class StinkBugEntity extends Animal implements GeoEntity {
private static final RawAnimation FART_ANIM = RawAnimation.begin().thenPlay("fart");
private static final int FART_ANIMATION_TICKS = 30;
private static final int STINK_BURST_PARTICLES = 32;
private static final double STINK_BURST_RADIUS = 8.0D;
private static final int STINK_BURST_DURATION_TICKS = 1200;
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private int fartAnimationTicks;
private boolean pendingFartBurst;
public StinkBugEntity(EntityType<? extends StinkBugEntity> entityType, Level level) {
super(entityType, level);
@@ -65,9 +69,10 @@ public class StinkBugEntity extends Animal implements GeoEntity {
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
this.goalSelector.addGoal(1, new WaterAvoidingRandomStrollGoal(this, 0.9D));
this.goalSelector.addGoal(2, new LookAtPlayerGoal(this, Player.class, 6.0F));
this.goalSelector.addGoal(3, new RandomLookAroundGoal(this));
this.goalSelector.addGoal(1, new PanicGoal(this, 1.4D));
this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 0.9D));
this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 6.0F));
this.goalSelector.addGoal(4, new RandomLookAroundGoal(this));
}
@Override
@@ -76,15 +81,20 @@ public class StinkBugEntity extends Animal implements GeoEntity {
if (this.fartAnimationTicks > 0) {
this.fartAnimationTicks--;
if (this.fartAnimationTicks == 0 && this.pendingFartBurst && !this.level().isClientSide()) {
StinkyBehavior.emitBurst(this, STINK_BURST_PARTICLES);
StinkyBehavior.applyBurstStinkyEffect(this, STINK_BURST_RADIUS, STINK_BURST_DURATION_TICKS);
this.pendingFartBurst = false;
}
}
}
@Override
public boolean hurt(DamageSource source, float amount) {
boolean hurt = super.hurt(source, amount);
if (hurt) {
if (hurt && !this.pendingFartBurst) {
this.triggerFartAnimation();
StinkyBehavior.emitBurst(this, STINK_BURST_PARTICLES);
this.pendingFartBurst = true;
}
return hurt;
}
@@ -163,6 +163,7 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new ToreterrorFloatGoal());
this.goalSelector.addGoal(1, new ToreterrorRangedGoal());
this.goalSelector.addGoal(2, new ToreterrorJumpGoal());
this.goalSelector.addGoal(3, new ToreterrorSpinGoal());
@@ -822,6 +823,28 @@ public class ToreterrorEntity extends Monster implements GeoEntity {
}
}
private final class ToreterrorFloatGoal extends Goal {
ToreterrorFloatGoal() {
this.setFlags(EnumSet.of(Flag.JUMP));
}
@Override
public boolean canUse() {
return ToreterrorEntity.this.isInWater() && !ToreterrorEntity.this.onGround();
}
@Override
public boolean canContinueToUse() {
return canUse();
}
@Override
public void tick() {
Vec3 vel = ToreterrorEntity.this.getDeltaMovement();
ToreterrorEntity.this.setDeltaMovement(vel.x, Math.min(vel.y + 0.08D, 0.2D), vel.z);
}
}
private final class ToreterrorSpinGoal extends Goal {
ToreterrorSpinGoal() {
this.setFlags(EnumSet.of(Flag.MOVE));
@@ -55,6 +55,7 @@ import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.EnumSet;
import java.util.Optional;
import java.util.UUID;
public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
@@ -71,6 +72,8 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
SynchedEntityData.defineId(FlyingSquirrelEntity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Integer> TEXTURE_VARIANT =
SynchedEntityData.defineId(FlyingSquirrelEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Optional<UUID>> SHOULDER_PLAYER_DATA =
SynchedEntityData.defineId(FlyingSquirrelEntity.class, EntityDataSerializers.OPTIONAL_UUID);
private static final String PICKUP_ANIM_TICKS_KEY = "PickupAnimTicks";
private static final String TEXTURE_VARIANT_KEY = "TextureVariant";
@@ -227,6 +230,7 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
builder.define(CLIMBING, false);
builder.define(PICKING_UP_NUT, false);
builder.define(TEXTURE_VARIANT, TEXTURE_VARIANT_REGULAR);
builder.define(SHOULDER_PLAYER_DATA, Optional.empty());
}
@Override
@@ -376,13 +380,19 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
}
if (this.isOnShoulder()) {
if (!(this.getVehicle() instanceof Player shoulderPlayer)
|| !shoulderPlayer.isAlive()) {
Player shoulderPlayer = this.getShoulderPlayer();
if (shoulderPlayer == null || !shoulderPlayer.isAlive()) {
this.dismountShoulder();
} else if (this.shoulderSneakGraceTicks <= 0 && shoulderPlayer.isShiftKeyDown()) {
this.glideOffShoulder();
} else {
Vec3 shoulderPos = this.getShoulderRidePos(shoulderPlayer);
this.setPos(shoulderPos.x, shoulderPos.y, shoulderPos.z);
this.setDeltaMovement(Vec3.ZERO);
this.setYRot(shoulderPlayer.getYHeadRot());
this.setXRot(shoulderPlayer.getXRot());
this.yBodyRot = shoulderPlayer.getYHeadRot();
this.yHeadRot = shoulderPlayer.getYHeadRot();
this.fallDistance = 0.0F;
}
this.setNoGravity(true);
@@ -434,22 +444,25 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
this.tickIdleStallLogging(horizontalSpeed);
}
if (this.isOnShoulder() && this.level().isClientSide) {
Player shoulderPlayer = this.getShoulderPlayer();
if (shoulderPlayer != null) {
Vec3 shoulderPos = this.getShoulderRidePos(shoulderPlayer);
this.setPos(shoulderPos.x, shoulderPos.y, shoulderPos.z);
this.setDeltaMovement(Vec3.ZERO);
this.setYRot(shoulderPlayer.getYHeadRot());
this.setXRot(shoulderPlayer.getXRot());
this.yBodyRot = shoulderPlayer.getYHeadRot();
this.yHeadRot = shoulderPlayer.getYHeadRot();
this.fallDistance = 0.0F;
}
}
this.setNoGravity(this.isGliding() || this.isClimbingTrunk() || this.isClimbingToShoulder() || this.isOnShoulder());
}
@Override
public void rideTick() {
super.rideTick();
if (this.getVehicle() instanceof Player player) {
Vec3 shoulderPos = this.getShoulderRidePos(player);
this.setPos(shoulderPos.x, shoulderPos.y, shoulderPos.z);
this.setDeltaMovement(Vec3.ZERO);
this.setYRot(player.getYHeadRot());
this.setXRot(player.getXRot());
this.yBodyRot = player.getYHeadRot();
this.yHeadRot = player.getYHeadRot();
this.fallDistance = 0.0F;
}
}
@Override
@@ -703,7 +716,14 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
}
public boolean isOnShoulder() {
return this.getVehicle() instanceof Player;
return this.entityData.get(SHOULDER_PLAYER_DATA).isPresent();
}
@Nullable
private Player getShoulderPlayer() {
return this.entityData.get(SHOULDER_PLAYER_DATA)
.map(uuid -> this.level().getPlayerByUUID(uuid))
.orElse(null);
}
public boolean isClimbingToShoulder() {
@@ -725,10 +745,9 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
}
private void dismountShoulder() {
Entity vehicle = this.getVehicle();
if (vehicle != null) {
this.stopRiding();
Vec3 dismountPos = vehicle.position().add(0.0D, 0.1D, 0.0D);
Player shoulderPlayer = this.getShoulderPlayer();
if (shoulderPlayer != null) {
Vec3 dismountPos = shoulderPlayer.position().add(0.0D, 0.1D, 0.0D);
this.setPos(dismountPos.x, dismountPos.y, dismountPos.z);
}
this.clearShoulderMountState();
@@ -737,6 +756,7 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
}
private void clearShoulderMountState() {
this.entityData.set(SHOULDER_PLAYER_DATA, Optional.empty());
this.shoulderPlayerId = null;
this.shoulderClimbStartPos = null;
this.climbingToShoulderTicks = 0;
@@ -746,16 +766,15 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
}
private void glideOffShoulder() {
Entity vehicle = this.getVehicle();
if (!(vehicle instanceof Player player)) {
Player player = this.getShoulderPlayer();
if (player == null) {
this.dismountShoulder();
return;
}
Vec3 launchPos = this.getShoulderRidePos(player);
this.stopRiding();
this.setPos(launchPos.x, launchPos.y, launchPos.z);
this.clearShoulderMountState();
this.setPos(launchPos.x, launchPos.y, launchPos.z);
this.fallDistance = 0.0F;
BlockPos glideTarget = this.findFallGlideTarget();
@@ -815,7 +834,7 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
this.shoulderPlayerId = null;
this.shoulderSneakGraceTicks = SHOULDER_SNEAK_GRACE_TICKS;
this.setClimbingTrunk(false);
this.startRiding(player, true);
this.entityData.set(SHOULDER_PLAYER_DATA, Optional.of(player.getUUID()));
this.setDeltaMovement(Vec3.ZERO);
this.fallDistance = 0.0F;
}
@@ -1,9 +0,0 @@
package com.craisinlord.antarchy.content.item;
import net.minecraft.world.item.Item;
public class CheepOnAStickItem extends Item {
public CheepOnAStickItem(Properties properties) {
super(properties);
}
}
@@ -1,129 +0,0 @@
package com.craisinlord.antarchy.content.menu;
import net.minecraft.world.Container;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import java.util.function.Supplier;
public class DorrieMenu extends AbstractContainerMenu {
// Set by the Fabric platform during registration so common entity code can open the menu.
@SuppressWarnings("unchecked")
public static Supplier<MenuType<DorrieMenu>> TYPE_SUPPLIER = () -> {
throw new IllegalStateException("DorrieMenu.TYPE_SUPPLIER accessed before registration");
};
private static final int EQUIPMENT_SLOTS = 1;
private static final int PLAYER_INV_ROWS = 3;
private static final int PLAYER_INV_COLS = 9;
// GUI layout constants (relative to background image top-left)
public static final int SADDLE_SLOT_X = 80;
public static final int SADDLE_SLOT_Y = 18;
public static final int PLAYER_INV_X = 8;
public static final int PLAYER_INV_Y = 48;
public static final int HOTBAR_Y = 106;
private final Container equipment;
// Server-side constructor — receives the real Dorrie inventory.
public DorrieMenu(int syncId, Inventory playerInventory, Container equipment) {
super(TYPE_SUPPLIER.get(), syncId);
this.equipment = equipment;
checkContainerSize(equipment, EQUIPMENT_SLOTS);
// Slot 0: saddle
this.addSlot(new Slot(equipment, 0, SADDLE_SLOT_X, SADDLE_SLOT_Y) {
@Override
public boolean mayPlace(ItemStack stack) {
return stack.is(Items.SADDLE);
}
@Override
public int getMaxStackSize() {
return 1;
}
});
// Player inventory (3 × 9)
for (int row = 0; row < PLAYER_INV_ROWS; row++) {
for (int col = 0; col < PLAYER_INV_COLS; col++) {
this.addSlot(new Slot(
playerInventory,
col + row * PLAYER_INV_COLS + PLAYER_INV_COLS,
PLAYER_INV_X + col * 18,
PLAYER_INV_Y + row * 18
));
}
}
// Hotbar (9)
for (int col = 0; col < PLAYER_INV_COLS; col++) {
this.addSlot(new Slot(playerInventory, col, PLAYER_INV_X + col * 18, HOTBAR_Y));
}
}
// Client-side factory — syncs slot data from server.
public static DorrieMenu clientCreate(int syncId, Inventory playerInventory) {
return new DorrieMenu(syncId, playerInventory, new SimpleContainer(EQUIPMENT_SLOTS));
}
@Override
public boolean stillValid(Player player) {
return this.equipment.stillValid(player);
}
@Override
public ItemStack quickMoveStack(Player player, int index) {
ItemStack result = ItemStack.EMPTY;
Slot slot = this.slots.get(index);
if (!slot.hasItem()) return result;
ItemStack stack = slot.getItem();
result = stack.copy();
int equipEnd = EQUIPMENT_SLOTS;
int invEnd = equipEnd + PLAYER_INV_ROWS * PLAYER_INV_COLS;
int totalSlots = invEnd + PLAYER_INV_COLS;
if (index < equipEnd) {
// Equipment slot → player inventory
if (!this.moveItemStackTo(stack, equipEnd, totalSlots, true)) {
return ItemStack.EMPTY;
}
} else {
// Player inventory/hotbar → try equipment slot first
if (stack.is(Items.SADDLE) && this.slots.get(0).mayPlace(stack)) {
if (!this.moveItemStackTo(stack, 0, equipEnd, false)) {
return ItemStack.EMPTY;
}
} else if (index < invEnd) {
// Inventory → hotbar
if (!this.moveItemStackTo(stack, invEnd, totalSlots, false)) {
return ItemStack.EMPTY;
}
} else {
// Hotbar → inventory
if (!this.moveItemStackTo(stack, equipEnd, invEnd, false)) {
return ItemStack.EMPTY;
}
}
}
if (stack.isEmpty()) {
slot.set(ItemStack.EMPTY);
} else {
slot.setChanged();
}
if (stack.getCount() == result.getCount()) return ItemStack.EMPTY;
slot.onTake(player, stack);
return result;
}
}
@@ -0,0 +1,20 @@
package com.craisinlord.antarchy.content.network;
import com.craisinlord.antarchy.Antarchy;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public record HerculesBeetleImpactShakePayload(int durationTicks) implements CustomPacketPayload {
public static final Type<HerculesBeetleImpactShakePayload> TYPE =
new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "hercules_beetle_impact_shake"));
public static final StreamCodec<ByteBuf, HerculesBeetleImpactShakePayload> STREAM_CODEC =
ByteBufCodecs.VAR_INT.map(HerculesBeetleImpactShakePayload::new, HerculesBeetleImpactShakePayload::durationTicks);
@Override
public Type<HerculesBeetleImpactShakePayload> type() {
return TYPE;
}
}
@@ -0,0 +1,22 @@
package com.craisinlord.antarchy.content.network;
import java.util.function.BiConsumer;
import net.minecraft.server.level.ServerPlayer;
public final class HerculesBeetleImpactShakeSync {
private static final BiConsumer<ServerPlayer, Integer> NOOP = (player, ticks) -> {
};
private static volatile BiConsumer<ServerPlayer, Integer> sink = NOOP;
private HerculesBeetleImpactShakeSync() {
}
public static void setSink(BiConsumer<ServerPlayer, Integer> sink) {
HerculesBeetleImpactShakeSync.sink = sink == null ? NOOP : sink;
}
public static void send(ServerPlayer player, int ticks) {
sink.accept(player, ticks);
}
}
@@ -0,0 +1,23 @@
package com.craisinlord.antarchy.content.network;
import com.craisinlord.antarchy.Antarchy;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public record HerculesBeetleJumpInputPayload(boolean pressing) implements CustomPacketPayload {
public static final Type<HerculesBeetleJumpInputPayload> TYPE =
new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "hercules_beetle_jump_input"));
public static final StreamCodec<ByteBuf, HerculesBeetleJumpInputPayload> STREAM_CODEC =
StreamCodec.composite(
ByteBufCodecs.BOOL, HerculesBeetleJumpInputPayload::pressing,
HerculesBeetleJumpInputPayload::new
);
@Override
public Type<HerculesBeetleJumpInputPayload> type() {
return TYPE;
}
}
@@ -0,0 +1,19 @@
package com.craisinlord.antarchy.content.network;
import com.craisinlord.antarchy.Antarchy;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public record HerculesBeetleMountedAttackPayload() implements CustomPacketPayload {
public static final Type<HerculesBeetleMountedAttackPayload> TYPE =
new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "hercules_beetle_mounted_attack"));
public static final StreamCodec<ByteBuf, HerculesBeetleMountedAttackPayload> STREAM_CODEC =
StreamCodec.unit(new HerculesBeetleMountedAttackPayload());
@Override
public Type<HerculesBeetleMountedAttackPayload> type() {
return TYPE;
}
}
@@ -0,0 +1,20 @@
package com.craisinlord.antarchy.content.network;
import com.craisinlord.antarchy.Antarchy;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public record HerculesBeetleMountedChargePayload(int chargeTicks) implements CustomPacketPayload {
public static final Type<HerculesBeetleMountedChargePayload> TYPE =
new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "hercules_beetle_mounted_charge"));
public static final StreamCodec<ByteBuf, HerculesBeetleMountedChargePayload> STREAM_CODEC =
ByteBufCodecs.VAR_INT.map(HerculesBeetleMountedChargePayload::new, HerculesBeetleMountedChargePayload::chargeTicks);
@Override
public Type<HerculesBeetleMountedChargePayload> type() {
return TYPE;
}
}
@@ -0,0 +1,49 @@
package com.craisinlord.antarchy.mixins.client;
import com.craisinlord.antarchy.content.entity.DorrieEntity;
import com.craisinlord.antarchy.content.entity.HerculesBeetleEntity;
import net.minecraft.client.Camera;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
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.ModifyArgs;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
@Mixin(Camera.class)
public abstract class MountedVehicleCameraMixin {
@Shadow
private Entity entity;
@ModifyArgs(
method = "setup",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(FFF)V")
)
private void antarchy$adjustMountedCameraOffset(
Args args,
BlockGetter level,
Entity entity,
boolean detached,
boolean mirrored,
float partialTick
) {
if (!detached || this.entity == null || this.entity.getVehicle() == null) {
return;
}
Entity vehicle = this.entity.getVehicle();
if (vehicle instanceof HerculesBeetleEntity) {
args.set(0, (Float) args.get(0) * 1.45F);
args.set(1, (Float) args.get(1) + 0.2F);
args.set(2, (Float) args.get(2) + 0.45F);
return;
}
if (vehicle instanceof DorrieEntity) {
args.set(0, (Float) args.get(0) * 1.6F);
args.set(1, (Float) args.get(1) + 0.15F);
args.set(2, (Float) args.get(2) + 0.55F);
}
}
}
@@ -51,6 +51,7 @@
"client.ElythiaSkyMixin",
"client.ElytraModelAccessor",
"client.LightningBoltRendererMixin",
"client.MountedVehicleCameraMixin",
"client.ParalyzedMouseTurnMixin",
"client.ScreenEffectRendererFireVisualMixin",
"client.SplashManagerMixin",
@@ -766,12 +766,13 @@
"death.attack.water_soaked.player": "%1$s was super soaked to death by %2$s",
"entity.antarchy.cheep": "Cheep",
"entity.antarchy.dorrie": "Dorrie",
"entity.antarchy.hercules_beetle": "Hercules Beetle",
"item.antarchy.cheep": "Cheep",
"item.antarchy.cheep_on_a_stick": "Cheep on a Stick",
"item.antarchy.cheep_spawn_egg": "Cheep Spawn Egg",
"item.antarchy.dorrie_spawn_egg": "Dorrie Spawn Egg",
"container.antarchy.dorrie": "Dorrie",
"item.antarchy.hercules_beetle_spawn_egg": "Hercules Beetle Spawn Egg",
"key.antarchy.dorrie_charge_jump": "Dorrie: Charge Jump",
"key.antarchy.hercules_beetle_charge": "Hercules Beetle: Charge",
"entity.antarchy.reverie": "Reverie",
"biome.antarchy.thoraxis": "Thoraxis",
"biome.antarchy.nightmare_wastes": "Nightmare Wastes",
@@ -0,0 +1,3 @@
{
"parent": "minecraft:item/template_spawn_egg"
}
@@ -9,7 +9,7 @@
"logical_height": 192,
"infiniburn": "#minecraft:infiniburn_overworld",
"effects": "minecraft:overworld",
"ambient_light": 0.01,
"ambient_light": 0.015,
"piglin_safe": false,
"has_raids": false,
"monster_spawn_light_level": 0,
@@ -0,0 +1,18 @@
{
"replace": false,
"values": [
"minecraft:bedrock",
"minecraft:obsidian",
"minecraft:crying_obsidian",
"minecraft:barrier",
"minecraft:command_block",
"minecraft:chain_command_block",
"minecraft:repeating_command_block",
"minecraft:structure_block",
"minecraft:jigsaw",
"minecraft:structure_void",
"minecraft:end_portal_frame",
"minecraft:end_portal",
"minecraft:end_gateway"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:glow_berries"
]
}
@@ -18,10 +18,6 @@
}
},
"spawn_costs": {
"antarchy:brutalfly": {
"energy_budget": 0.3,
"charge": 1.2
}
},
"carvers": {
"air": [],
@@ -22,7 +22,12 @@
}
}
},
"spawn_costs": {},
"spawn_costs": {
"antarchy:hercules_beetle": {
"energy_budget": 0.1,
"charge": 15
}
},
"carvers": {
"air": [],
"liquid": []
@@ -61,6 +66,12 @@
"weight": 95,
"minCount": 2,
"maxCount": 5
},
{
"type": "antarchy:hercules_beetle",
"weight": 5,
"minCount": 1,
"maxCount": 1
}
],
"creature": [
@@ -11,6 +11,7 @@
"antarchy:jumpy_bug",
"antarchy:spit_bug",
"antarchy:stink_bug",
"antarchy:hercules_beetle",
"antarchy:creeping_horror",
"antarchy:lurking_terror",
"antarchy:scorpion",