Fixed a crash found in #25 relating to spawn configuration registration
Actually defined hitbox sizes Made size adjustments to several creatures Added the Achillobator, Chilesaurus, Mussaurus, Suchomimus, Thescelosaurus and it's items Improved swimming behavior for terrestrial and avian creatures Made Dilophosaurus animation fixes relating to its frill Added natural breeding as life finds a way Added a short amount of health regeneration after full hunger so dinos don't die from hunting too much Fixed avian AI to not select the Idle state while flying, and generally improved their behavior Increased the chance and timespan of which dinos select a new place to move Increased the minimum speed for dinos to move when roaming to stop animations not playing Set a minimum speed when a dino is on Ice so it actaully moves Add random setting to spawn egg item Fix entities not middle-mouse-clickable Drastically reduced spawn rate of many creatures Fixes hand feeding, and thereby being able to put entities in the breeding state Replaces machine models Changed AI to ignore creepers Adds tags for each entity in the forge namespace to have compatibility with other mods that add the same entity, as long as they support this too Fixes machine input and export logic with pipes and hoppers Fixes inworld water input via bucket with fossil cleaner Fixes pipe logic to actually select a new fill point Fixes herbivores not being able to self feed
This commit is contained in:
@@ -111,6 +111,10 @@ public class CommonClientClass {
|
||||
EntityRendererRegistry.register(ModEntities.TROODON, TroodonRenderer::new);
|
||||
EntityRendererRegistry.register(ModEntities.UTAHRAPTOR, UtahraptorRenderer::new);
|
||||
EntityRendererRegistry.register(ModEntities.ACHILLOBATOR, AchillobatorRenderer::new);
|
||||
EntityRendererRegistry.register(ModEntities.SUCHOMIMUS, SuchomimusRenderer::new);
|
||||
EntityRendererRegistry.register(ModEntities.CHILESAURUS, ChilesaurusRenderer::new);
|
||||
EntityRendererRegistry.register(ModEntities.MUSSASAURUS, MussasaurusRenderer::new);
|
||||
EntityRendererRegistry.register(ModEntities.THESCELOSAURUS, ThescelosaurusRenderer::new);
|
||||
|
||||
if (Platform.isFabric()) {
|
||||
registerSpawnEggColors();
|
||||
|
||||
@@ -445,6 +445,18 @@ public class ModBlocks {
|
||||
public static final RegistrySupplier<Block> ACHILLOBATOR_EGG = registerBlock("achillobator_egg",
|
||||
() -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.ACHILLOBATOR));
|
||||
|
||||
public static final RegistrySupplier<Block> SUCHOMIMUS_EGG = registerBlock("suchomimus_egg",
|
||||
() -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.SUCHOMIMUS));
|
||||
|
||||
public static final RegistrySupplier<Block> CHILESAURUS_EGG = registerBlock("chilesaurus_egg",
|
||||
() -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.CHILESAURUS));
|
||||
|
||||
public static final RegistrySupplier<Block> THESCELOSAURUS_EGG = registerBlock("thescelosaurus_egg",
|
||||
() -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.THESCELOSAURUS));
|
||||
|
||||
public static final RegistrySupplier<Block> MUSSASAURUS_EGG = registerBlock("mussasaurus_egg",
|
||||
() -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.MUSSASAURUS));
|
||||
|
||||
|
||||
|
||||
public static final RegistrySupplier<Block> INCUBATED_APATOSAURUS_EGG = registerBlock("incubated_apatosaurus_egg",
|
||||
@@ -669,6 +681,18 @@ public class ModBlocks {
|
||||
public static final RegistrySupplier<Block> INCUBATED_ACHILLOBATOR_EGG = registerBlock("incubated_achillobator_egg",
|
||||
() -> new IncubatedEggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.ACHILLOBATOR));
|
||||
|
||||
public static final RegistrySupplier<Block> INCUBATED_SUCHOMIMUS_EGG = registerBlock("incubated_suchomimus_egg",
|
||||
() -> new IncubatedEggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.SUCHOMIMUS));
|
||||
|
||||
public static final RegistrySupplier<Block> INCUBATED_CHILESAURUS_EGG = registerBlock("incubated_chilesaurus_egg",
|
||||
() -> new IncubatedEggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.CHILESAURUS));
|
||||
|
||||
public static final RegistrySupplier<Block> INCUBATED_THESCELOSAURUS_EGG = registerBlock("incubated_thescelosaurus_egg",
|
||||
() -> new IncubatedEggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.THESCELOSAURUS));
|
||||
|
||||
public static final RegistrySupplier<Block> INCUBATED_MUSSASAURUS_EGG = registerBlock("incubated_mussasaurus_egg",
|
||||
() -> new IncubatedEggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.MUSSASAURUS));
|
||||
|
||||
|
||||
// --- Helper Methods ---
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ public class FossilCleanerBlock extends BaseEntityBlock {
|
||||
if (!pPlayer.getAbilities().instabuild) {
|
||||
pPlayer.setItemInHand(pHand, new ItemStack(Items.BUCKET));
|
||||
}
|
||||
// Actual addition is handled in BE tick for simplicity across loaders
|
||||
fossilCleanerBlockEntity.getFluidHandler(null).fill(dev.architectury.fluid.FluidStack.create(net.minecraft.world.level.material.Fluids.WATER, 1000), false);
|
||||
return ItemInteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -211,6 +211,7 @@ public class FossilCleanerBlock extends BaseEntityBlock {
|
||||
if (!player.getAbilities().instabuild) {
|
||||
player.setItemInHand(hand, new ItemStack(Items.BUCKET));
|
||||
}
|
||||
fossilCleanerBlockEntity.getFluidHandler(null).fill(dev.architectury.fluid.FluidStack.create(net.minecraft.world.level.material.Fluids.WATER, 1000), false);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +137,11 @@ public class PipeBlock extends Block implements EntityBlock, SimpleWaterloggedBl
|
||||
BlockPos pos = ctx.getClickedPos();
|
||||
BlockState state = this.defaultBlockState()
|
||||
.setValue(WATERLOGGED, level.getFluidState(pos).getType() == Fluids.WATER);
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
state = setConnectionForDirection(level, pos, state, dir);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -149,6 +151,7 @@ public class PipeBlock extends Block implements EntityBlock, SimpleWaterloggedBl
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
|
||||
}
|
||||
|
||||
return setConnectionForDirection(level, pos, state, direction);
|
||||
}
|
||||
|
||||
@@ -285,18 +288,11 @@ public class PipeBlock extends Block implements EntityBlock, SimpleWaterloggedBl
|
||||
if (val == ConnectionType.CONNECTOR) {
|
||||
return state.setValue(prop, ConnectionType.CONNECTOR_PULL);
|
||||
} else if (val == ConnectionType.CONNECTOR_PULL) {
|
||||
return state.setValue(prop, ConnectionType.NONE);
|
||||
} else if (val == ConnectionType.NONE) {
|
||||
return state.setValue(prop, ConnectionType.CONNECTOR);
|
||||
} else {
|
||||
Direction nearest = nearestConnectedDirection(state, hit, pos);
|
||||
if (nearest == null) return null;
|
||||
prop = getProp(nearest);
|
||||
val = state.getValue(prop);
|
||||
if (val == ConnectionType.CONNECTOR) {
|
||||
return state.setValue(prop, ConnectionType.CONNECTOR_PULL);
|
||||
} else if (val == ConnectionType.CONNECTOR_PULL) {
|
||||
return state.setValue(prop, ConnectionType.CONNECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -313,17 +309,32 @@ public class PipeBlock extends Block implements EntityBlock, SimpleWaterloggedBl
|
||||
if (intersects(CAP_WEST, x, y, z) || intersects(ARM_WEST, x, y, z)) { if (state.getValue(WEST) != ConnectionType.NONE) return Direction.WEST; }
|
||||
if (intersects(CAP_EAST, x, y, z) || intersects(ARM_EAST, x, y, z)) { if (state.getValue(EAST) != ConnectionType.NONE) return Direction.EAST; }
|
||||
|
||||
return nearestConnectedDirection(state, x, y, z);
|
||||
return nearestDirection(x, y, z);
|
||||
}
|
||||
|
||||
private static Direction nearestConnectedDirection(BlockState state, BlockHitResult hit, BlockPos pos) {
|
||||
Vec3 local = hit.getLocation().subtract(pos.getX(), pos.getY(), pos.getZ());
|
||||
double x = Mth.clamp(local.x * 16.0, 0.0, 16.0);
|
||||
double y = Mth.clamp(local.y * 16.0, 0.0, 16.0);
|
||||
double z = Mth.clamp(local.z * 16.0, 0.0, 16.0);
|
||||
return nearestConnectedDirection(state, x, y, z);
|
||||
private static Direction nearestDirection(double x, double y, double z) {
|
||||
Direction best = null;
|
||||
double bestScore = Double.NEGATIVE_INFINITY;
|
||||
|
||||
for (Direction d : Direction.values()) {
|
||||
double score = switch (d) {
|
||||
case UP -> y;
|
||||
case DOWN -> 16 - y;
|
||||
case NORTH -> 16 - z;
|
||||
case SOUTH -> z;
|
||||
case WEST -> 16 - x;
|
||||
case EAST -> x;
|
||||
};
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
best = d;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Direction nearestConnectedDirection(BlockState state, double x, double y, double z) {
|
||||
Direction best = null;
|
||||
double bestScore = Double.NEGATIVE_INFINITY;
|
||||
|
||||
@@ -105,6 +105,10 @@ public class ModBlockEntities {
|
||||
ModBlocks.UTAHRAPTOR_EGG.get(),
|
||||
ModBlocks.ZHENYUANOPTERUS_EGG.get(),
|
||||
ModBlocks.ACHILLOBATOR_EGG.get(),
|
||||
ModBlocks.SUCHOMIMUS_EGG.get(),
|
||||
ModBlocks.CHILESAURUS_EGG.get(),
|
||||
ModBlocks.MUSSASAURUS_EGG.get(),
|
||||
ModBlocks.THESCELOSAURUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_APATOSAURUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_ALBERTOSAURUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_VELOCIRAPTOR_EGG.get(),
|
||||
@@ -178,7 +182,11 @@ public class ModBlockEntities {
|
||||
ModBlocks.INCUBATED_TUPUXUARA_EGG.get(),
|
||||
ModBlocks.INCUBATED_UTAHRAPTOR_EGG.get(),
|
||||
ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get()
|
||||
ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get(),
|
||||
ModBlocks.INCUBATED_SUCHOMIMUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_MUSSASAURUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_THESCELOSAURUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_CHILESAURUS_EGG.get()
|
||||
).build(null));
|
||||
|
||||
public static final RegistrySupplier<BlockEntityType<DNAExtractorBlockEntity>> DNA_EXTRACTOR_BE =
|
||||
|
||||
+75
-8
@@ -23,6 +23,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -31,6 +32,7 @@ import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -45,7 +47,9 @@ import java.util.Optional;
|
||||
|
||||
public class DNAAnalyzerBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(5) {
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(3) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
@@ -54,6 +58,30 @@ public class DNAAnalyzerBlockEntity extends BlockEntity implements ExtendedMenuP
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
if (slot == 2) return false;
|
||||
if (slot == 0) return stack.is(net.cmr.jurassicrevived.item.ModItems.TEST_TUBE.get());
|
||||
if (slot == 1) return stack.is(net.cmr.jurassicrevived.item.ModItems.FROG_MATERIAL.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if ((slot == TEST_TUBE_SLOT || slot == MATERIAL_SLOT) && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int TEST_TUBE_SLOT = 0;
|
||||
@@ -107,6 +135,16 @@ public class DNAAnalyzerBlockEntity extends BlockEntity implements ExtendedMenuP
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -239,6 +277,7 @@ public class DNAAnalyzerBlockEntity extends BlockEntity implements ExtendedMenuP
|
||||
if (level.isClientSide) return;
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*Optional<RecipeHolder<DNAAnalyzerRecipe>> recipeOpt = getCurrentRecipe();
|
||||
@@ -288,14 +327,19 @@ public class DNAAnalyzerBlockEntity extends BlockEntity implements ExtendedMenuP
|
||||
}
|
||||
|
||||
private void craftItem(ItemStack output) {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT_1);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT_1, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT_1);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT_1, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
}
|
||||
itemHandler.removeItem(0, 1);
|
||||
itemHandler.removeItem(1, 1);
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
itemHandler.removeItem(TEST_TUBE_SLOT, 1);
|
||||
itemHandler.removeItem(MATERIAL_SLOT, 1);
|
||||
}
|
||||
|
||||
private boolean canInsertOutput(ItemStack output) {
|
||||
@@ -392,6 +436,29 @@ public class DNAAnalyzerBlockEntity extends BlockEntity implements ExtendedMenuP
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
pushSlotToHoppers(OUTPUT_SLOT_1);
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return saveWithoutMetadata(registries); }
|
||||
|
||||
+81
-12
@@ -23,6 +23,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -31,6 +32,7 @@ import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -45,6 +47,8 @@ import java.util.Optional;
|
||||
|
||||
public class DNAExtractorBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(5) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
@@ -54,6 +58,30 @@ public class DNAExtractorBlockEntity extends BlockEntity implements ExtendedMenu
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
if (slot >= 2 && slot <= 4) return false;
|
||||
if (slot == TEST_TUBE_SLOT) return stack.is(ModItems.TEST_TUBE.get());
|
||||
if (slot == MATERIAL_SLOT) return stack.is(ModItems.MOSQUITO_IN_AMBER.get()) || stack.is(ModTags.Items.TISSUES);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if ((slot == TEST_TUBE_SLOT || slot == MATERIAL_SLOT) && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int TEST_TUBE_SLOT = 0;
|
||||
@@ -107,6 +135,16 @@ public class DNAExtractorBlockEntity extends BlockEntity implements ExtendedMenu
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -237,6 +275,7 @@ public class DNAExtractorBlockEntity extends BlockEntity implements ExtendedMenu
|
||||
if (level.isClientSide) return;
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*Optional<RecipeHolder<DNAExtractorRecipe>> recipeOpt = getCurrentRecipe();
|
||||
@@ -286,19 +325,24 @@ public class DNAExtractorBlockEntity extends BlockEntity implements ExtendedMenu
|
||||
}
|
||||
|
||||
private void craftItem(ItemStack output) {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) {
|
||||
itemHandler.setItem(slot, output.copy());
|
||||
itemHandler.removeItem(TEST_TUBE_SLOT, 1);
|
||||
itemHandler.removeItem(MATERIAL_SLOT, 1);
|
||||
return;
|
||||
} else if (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize()) {
|
||||
stack.grow(output.getCount());
|
||||
itemHandler.removeItem(TEST_TUBE_SLOT, 1);
|
||||
itemHandler.removeItem(MATERIAL_SLOT, 1);
|
||||
return;
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) {
|
||||
itemHandler.setItem(slot, output.copy());
|
||||
itemHandler.removeItem(TEST_TUBE_SLOT, 1);
|
||||
itemHandler.removeItem(MATERIAL_SLOT, 1);
|
||||
return;
|
||||
} else if (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize()) {
|
||||
stack.grow(output.getCount());
|
||||
itemHandler.removeItem(TEST_TUBE_SLOT, 1);
|
||||
itemHandler.removeItem(MATERIAL_SLOT, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,6 +447,31 @@ public class DNAExtractorBlockEntity extends BlockEntity implements ExtendedMenu
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
pushSlotToHoppers(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return saveWithoutMetadata(registries); }
|
||||
|
||||
+76
-8
@@ -10,6 +10,7 @@ import net.cmr.jurassicrevived.recipe.DNAHybridizerRecipe;
|
||||
import net.cmr.jurassicrevived.recipe.DNAHybridizerRecipeInput;
|
||||
import net.cmr.jurassicrevived.recipe.ModRecipes;
|
||||
import net.cmr.jurassicrevived.screen.custom.DNAHybridizerMenu;
|
||||
import net.cmr.jurassicrevived.util.ModTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
@@ -20,6 +21,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -29,6 +31,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -45,6 +48,8 @@ import java.util.Optional;
|
||||
|
||||
public class DNAHybridizerBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(11) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
@@ -54,6 +59,30 @@ public class DNAHybridizerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
if (slot == OUTPUT_SLOT) return false;
|
||||
if (slot >= 0 && slot <= 7) return stack.is(ModTags.Items.DNA);
|
||||
if (slot == CATALYST_SLOT) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if (slot != OUTPUT_SLOT && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int[] DNA_SLOTS = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
@@ -107,6 +136,16 @@ public class DNAHybridizerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -239,6 +278,7 @@ public class DNAHybridizerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
if (level.isClientSide) return;
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*Optional<RecipeHolder<DNAHybridizerRecipe>> recipeOpt = getCurrentRecipe();
|
||||
@@ -297,14 +337,19 @@ public class DNAHybridizerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
}
|
||||
|
||||
private void craftItem(ItemStack output, List<Integer> matchedIndices) {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
}
|
||||
for (int idx : matchedIndices) {
|
||||
itemHandler.removeItem(idx, 1);
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
}
|
||||
for (int idx : matchedIndices) {
|
||||
itemHandler.removeItem(idx, 1);
|
||||
}
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,6 +452,29 @@ public class DNAHybridizerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
pushSlotToHoppers(OUTPUT_SLOT);
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return saveWithoutMetadata(registries); }
|
||||
|
||||
+76
-7
@@ -10,6 +10,7 @@ import net.cmr.jurassicrevived.recipe.EmbryoCalcificationMachineRecipe;
|
||||
import net.cmr.jurassicrevived.recipe.EmbryoCalcificationMachineRecipeInput;
|
||||
import net.cmr.jurassicrevived.recipe.ModRecipes;
|
||||
import net.cmr.jurassicrevived.screen.custom.EmbryoCalcificationMachineMenu;
|
||||
import net.cmr.jurassicrevived.util.ModTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
@@ -20,14 +21,17 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
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.ContainerData;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -42,6 +46,8 @@ import java.util.Optional;
|
||||
|
||||
public class EmbryoCalcificationMachineBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(5) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
@@ -51,6 +57,30 @@ public class EmbryoCalcificationMachineBlockEntity extends BlockEntity implement
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
if (slot == OUTPUT_SLOT) return false;
|
||||
if (slot == SYRINGE_SLOT) return stack.is(ModTags.Items.SYRINGES);
|
||||
if (slot == EGG_SLOT) return stack.is(Items.EGG);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if ((slot == SYRINGE_SLOT|| slot == EGG_SLOT) && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int SYRINGE_SLOT = 0;
|
||||
@@ -104,6 +134,16 @@ public class EmbryoCalcificationMachineBlockEntity extends BlockEntity implement
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -238,6 +278,7 @@ public class EmbryoCalcificationMachineBlockEntity extends BlockEntity implement
|
||||
if (level.isClientSide) return;
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*Optional<RecipeHolder<EmbryoCalcificationMachineRecipe>> recipeOpt = getCurrentRecipe();
|
||||
@@ -287,14 +328,19 @@ public class EmbryoCalcificationMachineBlockEntity extends BlockEntity implement
|
||||
}
|
||||
|
||||
private void craftItem(ItemStack output) {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
}
|
||||
itemHandler.removeItem(SYRINGE_SLOT, 1);
|
||||
itemHandler.removeItem(EGG_SLOT, 1);
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
itemHandler.removeItem(SYRINGE_SLOT, 1);
|
||||
itemHandler.removeItem(EGG_SLOT, 1);
|
||||
}
|
||||
|
||||
private boolean canInsertOutput(ItemStack output) {
|
||||
@@ -346,6 +392,29 @@ public class EmbryoCalcificationMachineBlockEntity extends BlockEntity implement
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
pushSlotToHoppers(OUTPUT_SLOT);
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return saveWithoutMetadata(registries); }
|
||||
|
||||
+76
-8
@@ -23,6 +23,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -31,6 +32,7 @@ import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -45,6 +47,8 @@ import java.util.Optional;
|
||||
|
||||
public class EmbryonicMachineBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(4) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
@@ -54,6 +58,31 @@ public class EmbryonicMachineBlockEntity extends BlockEntity implements Extended
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
if (slot == OUTPUT_SLOT) return false;
|
||||
if (slot == SYRINGE_SLOT) return stack.is(ModItems.SYRINGE.get());
|
||||
if (slot == MATERIAL_SLOT) return stack.is(ModTags.Items.DNA);
|
||||
if (slot == FROG_SLOT) return stack.is(ModItems.FROG_DNA.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if ((slot == SYRINGE_SLOT || slot == MATERIAL_SLOT || slot == FROG_SLOT) && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int SYRINGE_SLOT = 0;
|
||||
@@ -108,6 +137,16 @@ public class EmbryonicMachineBlockEntity extends BlockEntity implements Extended
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -242,6 +281,7 @@ public class EmbryonicMachineBlockEntity extends BlockEntity implements Extended
|
||||
if (level.isClientSide) return;
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*Optional<RecipeHolder<EmbryonicMachineRecipe>> recipeOpt = getCurrentRecipe();
|
||||
@@ -293,15 +333,20 @@ public class EmbryonicMachineBlockEntity extends BlockEntity implements Extended
|
||||
}
|
||||
|
||||
private void craftItem(ItemStack output) {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
ItemStack current = itemHandler.getItem(OUTPUT_SLOT);
|
||||
if (current.isEmpty()) {
|
||||
itemHandler.setItem(OUTPUT_SLOT, output.copy());
|
||||
} else {
|
||||
current.grow(output.getCount());
|
||||
}
|
||||
itemHandler.removeItem(SYRINGE_SLOT, 1);
|
||||
itemHandler.removeItem(MATERIAL_SLOT, 1);
|
||||
itemHandler.removeItem(FROG_SLOT, 1);
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
itemHandler.removeItem(SYRINGE_SLOT, 1);
|
||||
itemHandler.removeItem(MATERIAL_SLOT, 1);
|
||||
itemHandler.removeItem(FROG_SLOT, 1);
|
||||
}
|
||||
|
||||
private boolean canInsertOutput(ItemStack output) {
|
||||
@@ -398,6 +443,29 @@ public class EmbryonicMachineBlockEntity extends BlockEntity implements Extended
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
pushSlotToHoppers(OUTPUT_SLOT);
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return saveWithoutMetadata(registries); }
|
||||
|
||||
+155
-11
@@ -7,6 +7,8 @@ import net.cmr.jurassicrevived.block.entity.ModBlockEntities;
|
||||
import net.cmr.jurassicrevived.block.entity.energy.ModEnergyStorage;
|
||||
import net.cmr.jurassicrevived.block.entity.energy.ModEnergyUtil;
|
||||
import net.cmr.jurassicrevived.config.JRConfigManager;
|
||||
import net.cmr.jurassicrevived.platform.transfer.InternalFluidHandler;
|
||||
import net.cmr.jurassicrevived.platform.transfer.InternalFluidProvider;
|
||||
import net.cmr.jurassicrevived.recipe.FossilCleanerRecipe;
|
||||
import net.cmr.jurassicrevived.recipe.FossilCleanerRecipeInput;
|
||||
import net.cmr.jurassicrevived.recipe.ModRecipes;
|
||||
@@ -24,6 +26,7 @@ import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -33,6 +36,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -45,7 +49,9 @@ import net.minecraft.core.RegistryAccess;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider, InternalFluidProvider
|
||||
{
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(5) {
|
||||
@Override
|
||||
@@ -56,6 +62,43 @@ public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
if (slot >= 2 && slot <= 4) return false;
|
||||
if (slot == WATER_SLOT) {
|
||||
return stack.is(Items.WATER_BUCKET);
|
||||
}
|
||||
if (slot == FOSSILBLOCK_SLOT) return stack.is(net.cmr.jurassicrevived.block.ModBlocks.STONE_FOSSIL.get().asItem()) || stack.is(net.cmr.jurassicrevived.block.ModBlocks.DEEPSLATE_FOSSIL.get().asItem());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if (slot == FOSSILBLOCK_SLOT && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
if (slot == WATER_SLOT && getItem(slot).is(Items.WATER_BUCKET)) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int WATER_SLOT = 0;
|
||||
@@ -76,6 +119,62 @@ public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
private static final int TRANSFER_RATE = 1000;
|
||||
private final ModEnergyStorage energyStorage = createEnergyStorage();
|
||||
|
||||
private final InternalFluidHandler fluidHandler = new InternalFluidHandler() {
|
||||
@Override
|
||||
public FluidStack getFluid() {
|
||||
return fluidStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCapacity() {
|
||||
return TANK_CAPACITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long fill(FluidStack stack, boolean simulate) {
|
||||
if (stack.isEmpty()) return 0;
|
||||
if (!fluidStack.isEmpty() && fluidStack.getFluid() != stack.getFluid()) return 0;
|
||||
|
||||
long space = TANK_CAPACITY - fluidStack.getAmount();
|
||||
if (space <= 0) return 0;
|
||||
|
||||
long toFill = Math.min(space, stack.getAmount());
|
||||
if (!simulate) {
|
||||
fluidStack = FluidStack.create(stack.getFluid(), fluidStack.getAmount() + toFill);
|
||||
setChanged();
|
||||
if (level != null && !level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
return toFill;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(long amount, boolean simulate) {
|
||||
if (fluidStack.isEmpty() || amount <= 0) return FluidStack.empty();
|
||||
|
||||
long drained = Math.min(amount, fluidStack.getAmount());
|
||||
FluidStack out = FluidStack.create(fluidStack.getFluid(), drained);
|
||||
|
||||
if (!simulate) {
|
||||
long remaining = fluidStack.getAmount() - drained;
|
||||
fluidStack = remaining > 0
|
||||
? FluidStack.create(fluidStack.getFluid(), remaining)
|
||||
: FluidStack.empty();
|
||||
setChanged();
|
||||
if (level != null && !level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public InternalFluidHandler getFluidHandler(@Nullable Direction side) {
|
||||
return this.fluidHandler;
|
||||
}
|
||||
|
||||
public FossilCleanerBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntities.FOSSIL_CLEANER_BE.get(), pos, blockState);
|
||||
this.data = new ContainerData() {
|
||||
@@ -112,6 +211,16 @@ public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -126,6 +235,10 @@ public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
|
||||
private void setFluid(FluidStack stack) {
|
||||
this.fluidStack = stack == null || stack.isEmpty() ? FluidStack.empty() : stack;
|
||||
setChanged();
|
||||
if (level != null && !level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -266,6 +379,7 @@ public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
handleBucketInput();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*Optional<RecipeHolder<FossilCleanerRecipe>> recipeOpt = getCurrentRecipe();
|
||||
@@ -322,17 +436,22 @@ public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
}
|
||||
|
||||
private void craftItem(ItemStack output) {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) {
|
||||
itemHandler.setItem(slot, output.copy());
|
||||
itemHandler.removeItem(FOSSILBLOCK_SLOT, 1);
|
||||
return;
|
||||
} else if (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize()) {
|
||||
stack.grow(output.getCount());
|
||||
itemHandler.removeItem(FOSSILBLOCK_SLOT, 1);
|
||||
return;
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) {
|
||||
itemHandler.setItem(slot, output.copy());
|
||||
itemHandler.removeItem(FOSSILBLOCK_SLOT, 1);
|
||||
return;
|
||||
} else if (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize()) {
|
||||
stack.grow(output.getCount());
|
||||
itemHandler.removeItem(FOSSILBLOCK_SLOT, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,6 +538,31 @@ public class FossilCleanerBlockEntity extends BlockEntity implements ExtendedMen
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
pushSlotToHoppers(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return saveWithoutMetadata(registries); }
|
||||
|
||||
+77
-10
@@ -21,6 +21,7 @@ import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -29,6 +30,7 @@ import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -42,6 +44,7 @@ import net.minecraft.core.RegistryAccess;
|
||||
import java.util.Optional;
|
||||
|
||||
public class FossilGrinderBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(4) {
|
||||
@Override
|
||||
@@ -52,6 +55,29 @@ public class FossilGrinderBlockEntity extends BlockEntity implements ExtendedMen
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
if (slot >= 1 && slot <= 3) return false;
|
||||
if (slot == 0) return stack.is(net.cmr.jurassicrevived.util.ModTags.Items.FOSSILS) || stack.is(net.cmr.jurassicrevived.util.ModTags.Items.SKULLS);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if (slot == 0 && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int FOSSIL_SLOT = 0;
|
||||
@@ -104,6 +130,16 @@ public class FossilGrinderBlockEntity extends BlockEntity implements ExtendedMen
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -238,6 +274,7 @@ public class FossilGrinderBlockEntity extends BlockEntity implements ExtendedMen
|
||||
if (level.isClientSide) return;
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*Optional<RecipeHolder<FossilGrinderRecipe>> recipeOpt = getCurrentRecipe();
|
||||
@@ -294,17 +331,22 @@ public class FossilGrinderBlockEntity extends BlockEntity implements ExtendedMen
|
||||
}
|
||||
|
||||
private void craftItem(ItemStack output) {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) {
|
||||
itemHandler.setItem(slot, output.copy());
|
||||
itemHandler.removeItem(FOSSIL_SLOT, 1);
|
||||
return;
|
||||
} else if (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize()) {
|
||||
stack.grow(output.getCount());
|
||||
itemHandler.removeItem(FOSSIL_SLOT, 1);
|
||||
return;
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) {
|
||||
itemHandler.setItem(slot, output.copy());
|
||||
itemHandler.removeItem(FOSSIL_SLOT, 1);
|
||||
return;
|
||||
} else if (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize()) {
|
||||
stack.grow(output.getCount());
|
||||
itemHandler.removeItem(FOSSIL_SLOT, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,6 +438,31 @@ public class FossilGrinderBlockEntity extends BlockEntity implements ExtendedMen
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
for (int slot : OUTPUT_SLOTS) {
|
||||
pushSlotToHoppers(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (stack.isEmpty()) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//? if >1.20.1 {
|
||||
/*@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registries) {
|
||||
|
||||
+16
@@ -41,6 +41,22 @@ public class GeneratorBlockEntity extends BlockEntity implements ExtendedMenuPro
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
if (slot == INPUT_SLOT) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
public static final int INPUT_SLOT = 0;
|
||||
|
||||
+80
-1
@@ -10,6 +10,7 @@ import net.cmr.jurassicrevived.recipe.IncubatorRecipe;
|
||||
import net.cmr.jurassicrevived.recipe.IncubatorRecipeInput;
|
||||
import net.cmr.jurassicrevived.recipe.ModRecipes;
|
||||
import net.cmr.jurassicrevived.screen.custom.IncubatorMenu;
|
||||
import net.cmr.jurassicrevived.util.ModTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -19,14 +20,17 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
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.ContainerData;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -41,6 +45,8 @@ import java.util.Optional;
|
||||
|
||||
public class IncubatorBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider {
|
||||
|
||||
private boolean allowInternalExtraction = false;
|
||||
|
||||
public final SimpleContainer itemHandler = new SimpleContainer(3) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
@@ -50,6 +56,33 @@ public class IncubatorBlockEntity extends BlockEntity implements ExtendedMenuPro
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
return stack.is(net.cmr.jurassicrevived.util.ModTags.Items.EGGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
ItemStack stack = getItem(slot);
|
||||
if (!stack.isEmpty()) {
|
||||
boolean isIncubated = stack.getItem() instanceof net.minecraft.world.item.BlockItem blockItem
|
||||
&& blockItem.getBlock().defaultBlockState().is(net.cmr.jurassicrevived.util.ModTags.Blocks.INCUBATED_EGGS);
|
||||
|
||||
if (!isIncubated && !allowInternalExtraction) {
|
||||
boolean isPlayer = false;
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
|
||||
String className = element.getClassName();
|
||||
if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) {
|
||||
isPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isPlayer) return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
return super.removeItem(slot, amount);
|
||||
}
|
||||
};
|
||||
|
||||
private final ContainerData data;
|
||||
@@ -105,6 +138,16 @@ public class IncubatorBlockEntity extends BlockEntity implements ExtendedMenuPro
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -253,6 +296,7 @@ public class IncubatorBlockEntity extends BlockEntity implements ExtendedMenuPro
|
||||
if (level.isClientSide) return;
|
||||
|
||||
pullEnergyFromNeighbors();
|
||||
pushOutputsToHoppers();
|
||||
|
||||
boolean changed = false;
|
||||
boolean anyActive = false;
|
||||
@@ -310,7 +354,12 @@ public class IncubatorBlockEntity extends BlockEntity implements ExtendedMenuPro
|
||||
ItemStack out = recipeOpt.get().assemble(new IncubatorRecipeInput(stack), level.registryAccess());
|
||||
//?}
|
||||
if (!out.isEmpty()) {
|
||||
itemHandler.setItem(s, out.copy());
|
||||
allowInternalExtraction = true;
|
||||
try {
|
||||
itemHandler.setItem(s, out.copy());
|
||||
} finally {
|
||||
allowInternalExtraction = false;
|
||||
}
|
||||
progress[s] = 0;
|
||||
maxProgress[s] = DEFAULT_MAX_PROGRESS;
|
||||
changed = true;
|
||||
@@ -347,6 +396,36 @@ public class IncubatorBlockEntity extends BlockEntity implements ExtendedMenuPro
|
||||
}
|
||||
}
|
||||
|
||||
private void pushOutputsToHoppers() {
|
||||
for (int slot = 0; slot < itemHandler.getContainerSize(); slot++) {
|
||||
pushSlotToHoppers(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private void pushSlotToHoppers(int slot) {
|
||||
ItemStack stack = itemHandler.getItem(slot);
|
||||
if (!isIncubatedEgg(stack)) return;
|
||||
|
||||
for (Direction dir : Direction.values()) {
|
||||
BlockEntity be = level.getBlockEntity(worldPosition.relative(dir));
|
||||
if (!(be instanceof Container target)) continue;
|
||||
|
||||
ItemStack toMove = stack.copy();
|
||||
ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir);
|
||||
|
||||
if (remainder.getCount() != stack.getCount()) {
|
||||
itemHandler.setItem(slot, remainder);
|
||||
setChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isIncubatedEgg(ItemStack stack) {
|
||||
return stack.getItem() instanceof BlockItem blockItem
|
||||
&& blockItem.getBlock().defaultBlockState().is(ModTags.Blocks.INCUBATED_EGGS);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Packet<ClientGamePacketListener> getUpdatePacket() {
|
||||
|
||||
+70
-54
@@ -123,27 +123,30 @@ public class PipeBlockEntity extends BlockEntity
|
||||
.orElse(null);
|
||||
if (src == null) continue;
|
||||
|
||||
PipeEndpoint sinkEp = findNearestSink(level, srcEp.pipePos, sinksByPipe, Transport.ITEMS);
|
||||
if (sinkEp == null) continue;
|
||||
List<PipeEndpoint> sinkEndpoints = findReachableSinks(level, srcEp.pipePos, sinksByPipe, Transport.ITEMS);
|
||||
for (PipeEndpoint sinkEp : sinkEndpoints) {
|
||||
if (remaining <= 0) break;
|
||||
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
|
||||
PlatformItemHandler dst = Services.TRANSFER
|
||||
.getItemHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
PlatformItemHandler dst = Services.TRANSFER
|
||||
.getItemHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
|
||||
remaining = moveFromSourceToSingleTarget(src, dst, remaining);
|
||||
remaining = moveFromSourceToSingleTarget(src, dst, remaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PipeEndpoint findNearestSink(
|
||||
private static List<PipeEndpoint> findReachableSinks(
|
||||
Level level,
|
||||
BlockPos startPipe,
|
||||
Map<BlockPos, List<PipeEndpoint>> sinksByPipe,
|
||||
Transport transport
|
||||
) {
|
||||
List<PipeEndpoint> result = new ArrayList<>();
|
||||
ArrayDeque<BlockPos> q = new ArrayDeque<>();
|
||||
HashSet<BlockPos> seen = new HashSet<>();
|
||||
q.add(startPipe);
|
||||
@@ -154,7 +157,7 @@ public class PipeBlockEntity extends BlockEntity
|
||||
|
||||
List<PipeEndpoint> sinksHere = sinksByPipe.get(p);
|
||||
if (sinksHere != null && !sinksHere.isEmpty()) {
|
||||
return sinksHere.get(0);
|
||||
result.addAll(sinksHere);
|
||||
}
|
||||
|
||||
BlockState st = level.getBlockState(p);
|
||||
@@ -167,7 +170,7 @@ public class PipeBlockEntity extends BlockEntity
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void transferEnergy(Level level, BlockPos pos, BlockState state, int perTickLimit) {
|
||||
@@ -188,26 +191,28 @@ public class PipeBlockEntity extends BlockEntity
|
||||
.orElse(null);
|
||||
if (src == null) continue;
|
||||
|
||||
PipeEndpoint sinkEp = findNearestSink(level, srcEp.pipePos, sinksByPipe, Transport.ENERGY);
|
||||
if (sinkEp == null) continue;
|
||||
List<PipeEndpoint> sinkEndpoints = findReachableSinks(level, srcEp.pipePos, sinksByPipe, Transport.ENERGY);
|
||||
for (PipeEndpoint sinkEp : sinkEndpoints) {
|
||||
if (remaining <= 0) break;
|
||||
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
|
||||
PlatformEnergyHandler dst = Services.TRANSFER
|
||||
.getEnergyHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
PlatformEnergyHandler dst = Services.TRANSFER
|
||||
.getEnergyHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
|
||||
int available = src.extract(remaining, true);
|
||||
if (available <= 0) continue;
|
||||
int available = src.extract(remaining, true);
|
||||
if (available <= 0) break;
|
||||
|
||||
int accepted = dst.insert(available, true);
|
||||
if (accepted <= 0) continue;
|
||||
int accepted = dst.insert(available, true);
|
||||
if (accepted <= 0) continue;
|
||||
|
||||
int extracted = src.extract(accepted, false);
|
||||
int inserted = dst.insert(extracted, false);
|
||||
remaining -= inserted;
|
||||
int extracted = src.extract(accepted, false);
|
||||
int inserted = dst.insert(extracted, false);
|
||||
remaining -= inserted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,34 +234,45 @@ public class PipeBlockEntity extends BlockEntity
|
||||
.orElse(null);
|
||||
if (src == null) continue;
|
||||
|
||||
PipeEndpoint sinkEp = findNearestSink(level, srcEp.pipePos, sinksByPipe, Transport.FLUIDS);
|
||||
if (sinkEp == null) continue;
|
||||
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
|
||||
PlatformFluidHandler dst = Services.TRANSFER
|
||||
.getFluidHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
|
||||
for (FluidStack candidate : src.getExtractableFluids()) {
|
||||
if (candidate.isEmpty()) continue;
|
||||
|
||||
long available = src.extract(candidate, remaining, true);
|
||||
if (available <= 0) continue;
|
||||
|
||||
long accepted = dst.insert(candidate, available, true);
|
||||
if (accepted <= 0) continue;
|
||||
|
||||
FluidStack toMove = candidate.copy();
|
||||
toMove.setAmount(accepted);
|
||||
|
||||
long extracted = src.extract(toMove, accepted, false);
|
||||
long inserted = dst.insert(toMove, extracted, false);
|
||||
remaining -= inserted;
|
||||
|
||||
List<PipeEndpoint> sinkEndpoints = findReachableSinks(level, srcEp.pipePos, sinksByPipe, Transport.FLUIDS);
|
||||
for (PipeEndpoint sinkEp : sinkEndpoints) {
|
||||
if (remaining <= 0) break;
|
||||
|
||||
BlockPos dstPos = sinkEp.pipePos.relative(sinkEp.side);
|
||||
Direction dstSide = sinkEp.side.getOpposite();
|
||||
|
||||
PlatformFluidHandler dst = Services.TRANSFER
|
||||
.getFluidHandler(level, dstPos, dstSide)
|
||||
.orElse(null);
|
||||
if (dst == null) continue;
|
||||
|
||||
for (FluidStack candidate : src.getExtractableFluids()) {
|
||||
if (remaining <= 0) break;
|
||||
if (candidate.isEmpty()) continue;
|
||||
|
||||
long available = src.extract(candidate, remaining, true);
|
||||
if (available <= 0) continue;
|
||||
|
||||
long accepted = dst.insert(candidate, available, true);
|
||||
if (accepted <= 0) continue;
|
||||
|
||||
FluidStack toMove = candidate.copy();
|
||||
toMove.setAmount(accepted);
|
||||
|
||||
long extracted = src.extract(toMove, accepted, false);
|
||||
if (extracted <= 0) continue;
|
||||
|
||||
toMove.setAmount(extracted);
|
||||
|
||||
long inserted = dst.insert(toMove, extracted, false);
|
||||
remaining -= inserted;
|
||||
|
||||
if (inserted < extracted) {
|
||||
FluidStack remainder = toMove.copy();
|
||||
remainder.setAmount(extracted - inserted);
|
||||
src.insert(remainder, extracted - inserted, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,11 @@ public final class JRConfig {
|
||||
*/
|
||||
public boolean waterConsumption = false;
|
||||
|
||||
/**
|
||||
* Controls whether dinosaurs breed over time.
|
||||
*/
|
||||
public boolean naturalBreeding = false;
|
||||
|
||||
/**
|
||||
* Energy pipe transfer rate in FE per second.
|
||||
*/
|
||||
|
||||
@@ -34,6 +34,7 @@ public final class JRConfigManager {
|
||||
loaded.naturallySpawning = readBoolean(text, "naturallySpawning", loaded.naturallySpawning);
|
||||
loaded.hungerConsumption = readBoolean(text, "hungerConsumption", loaded.hungerConsumption);
|
||||
loaded.waterConsumption = readBoolean(text, "waterConsumption", loaded.waterConsumption);
|
||||
loaded.naturalBreeding = readBoolean(text, "naturalBreeding", loaded.naturalBreeding);
|
||||
loaded.fePerSecond = readPositiveInt(text, "fePerSecond", loaded.fePerSecond);
|
||||
loaded.itemsPerSecond = readPositiveInt(text, "itemsPerSecond", loaded.itemsPerSecond);
|
||||
loaded.milliBucketsPerSecond = readPositiveInt(text, "milliBucketsPerSecond", loaded.milliBucketsPerSecond);
|
||||
@@ -55,6 +56,7 @@ public final class JRConfigManager {
|
||||
" \"naturallySpawning\": " + config.naturallySpawning + ",\n" +
|
||||
" \"hungerConsumption\": " + config.hungerConsumption + ",\n" +
|
||||
" \"waterConsumption\": " + config.waterConsumption + ",\n" +
|
||||
" \"naturalBreeding\": " + config.naturalBreeding + ",\n" +
|
||||
" \"fePerSecond\": " + config.fePerSecond + ",\n" +
|
||||
" \"itemsPerSecond\": " + config.itemsPerSecond + ",\n" +
|
||||
" \"milliBucketsPerSecond\": " + config.milliBucketsPerSecond + "\n" +
|
||||
|
||||
@@ -135,6 +135,10 @@ public class ModBlockLootTableProvider {
|
||||
helper.dropSelf(ModBlocks.UTAHRAPTOR_EGG.get());
|
||||
helper.dropSelf(ModBlocks.ZHENYUANOPTERUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.ACHILLOBATOR_EGG.get());
|
||||
helper.dropSelf(ModBlocks.SUCHOMIMUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.CHILESAURUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.MUSSASAURUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.THESCELOSAURUS_EGG.get());
|
||||
|
||||
helper.dropSelf(ModBlocks.INCUBATED_APATOSAURUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.INCUBATED_ALBERTOSAURUS_EGG.get());
|
||||
@@ -210,6 +214,10 @@ public class ModBlockLootTableProvider {
|
||||
helper.dropSelf(ModBlocks.INCUBATED_UTAHRAPTOR_EGG.get());
|
||||
helper.dropSelf(ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get());
|
||||
helper.dropSelf(ModBlocks.INCUBATED_SUCHOMIMUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.INCUBATED_CHILESAURUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.INCUBATED_MUSSASAURUS_EGG.get());
|
||||
helper.dropSelf(ModBlocks.INCUBATED_THESCELOSAURUS_EGG.get());
|
||||
|
||||
helper.dropSelf(ModBlocks.ROYAL_FERN.get());
|
||||
helper.add(ModBlocks.POTTED_ROYAL_FERN.get(), helper.createPotFlowerItemTable(ModBlocks.ROYAL_FERN.get()));
|
||||
|
||||
@@ -197,6 +197,10 @@ public class ModBlockStateProvider {
|
||||
helper.eggLike(ModBlocks.UTAHRAPTOR_EGG.get());
|
||||
helper.eggLike(ModBlocks.ZHENYUANOPTERUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.ACHILLOBATOR_EGG.get());
|
||||
helper.eggLike(ModBlocks.SUCHOMIMUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.CHILESAURUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.MUSSASAURUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.THESCELOSAURUS_EGG.get());
|
||||
|
||||
helper.eggLike(ModBlocks.INCUBATED_VELOCIRAPTOR_EGG.get());
|
||||
helper.eggLike(ModBlocks.INCUBATED_TYRANNOSAURUS_REX_EGG.get());
|
||||
@@ -272,6 +276,10 @@ public class ModBlockStateProvider {
|
||||
helper.eggLike(ModBlocks.INCUBATED_UTAHRAPTOR_EGG.get());
|
||||
helper.eggLike(ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get());
|
||||
helper.eggLike(ModBlocks.INCUBATED_SUCHOMIMUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.INCUBATED_CHILESAURUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.INCUBATED_MUSSASAURUS_EGG.get());
|
||||
helper.eggLike(ModBlocks.INCUBATED_THESCELOSAURUS_EGG.get());
|
||||
|
||||
helper.customFenceMultipart(
|
||||
ModBlocks.LOW_SECURITY_FENCE_POLE.get(),
|
||||
|
||||
@@ -143,7 +143,9 @@ public class ModBlockTagProvider {
|
||||
ModBlocks.INCUBATED_TUPUXUARA_EGG.get(),
|
||||
ModBlocks.INCUBATED_UTAHRAPTOR_EGG.get(),
|
||||
ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get()
|
||||
ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get(),
|
||||
ModBlocks.INCUBATED_SUCHOMIMUS_EGG.get(),
|
||||
ModBlocks.INCUBATED_CHILESAURUS_EGG.get()
|
||||
);
|
||||
|
||||
helper.tag(BlockTags.MINEABLE_WITH_SHOVEL);
|
||||
@@ -169,6 +171,13 @@ public class ModBlockTagProvider {
|
||||
Blocks.CLAY
|
||||
);
|
||||
|
||||
helper.tag(ModTags.Blocks.PLANTS,
|
||||
ModBlocks.HORSETAIL_FERN.get(),
|
||||
ModBlocks.ROYAL_FERN.get(),
|
||||
ModBlocks.WESTERN_SWORD_FERN.get(),
|
||||
ModBlocks.ONYCHIOPSIS.get()
|
||||
);
|
||||
|
||||
helper.tag(BlockTags.WALLS,
|
||||
ModBlocks.GYPSUM_BRICK_WALL.get(),
|
||||
ModBlocks.REINFORCED_BRICK_WALL.get()
|
||||
|
||||
@@ -503,5 +503,33 @@ public class ModEntityLootTableProvider {
|
||||
.add(LootItem.lootTableItem(ModItems.FRESH_ACHILLOBATOR_SKULL.get()))
|
||||
)
|
||||
);
|
||||
|
||||
helper.add(ModEntities.SUCHOMIMUS.get(), LootTable.lootTable()
|
||||
.withPool(LootPool.lootPool()
|
||||
.setRolls(ConstantValue.exactly(1))
|
||||
.add(LootItem.lootTableItem(ModItems.FRESH_SUCHOMIMUS_SKULL.get()))
|
||||
)
|
||||
);
|
||||
|
||||
helper.add(ModEntities.CHILESAURUS.get(), LootTable.lootTable()
|
||||
.withPool(LootPool.lootPool()
|
||||
.setRolls(ConstantValue.exactly(1))
|
||||
.add(LootItem.lootTableItem(ModItems.FRESH_CHILESAURUS_SKULL.get()))
|
||||
)
|
||||
);
|
||||
|
||||
helper.add(ModEntities.MUSSASAURUS.get(), LootTable.lootTable()
|
||||
.withPool(LootPool.lootPool()
|
||||
.setRolls(ConstantValue.exactly(1))
|
||||
.add(LootItem.lootTableItem(ModItems.FRESH_MUSSASAURUS_SKULL.get()))
|
||||
)
|
||||
);
|
||||
|
||||
helper.add(ModEntities.THESCELOSAURUS.get(), LootTable.lootTable()
|
||||
.withPool(LootPool.lootPool()
|
||||
.setRolls(ConstantValue.exactly(1))
|
||||
.add(LootItem.lootTableItem(ModItems.FRESH_THESCELOSAURUS_SKULL.get()))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.cmr.jurassicrevived.datagen;
|
||||
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.util.ModTags;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
public class ModEntityTagProvider {
|
||||
|
||||
public interface EntityTagHelper {
|
||||
void tag(TagKey<EntityType<?>> tag, EntityType<?>... entityTypes);
|
||||
}
|
||||
|
||||
public static void registerEntityTags(EntityTagHelper helper) {
|
||||
ModEntities.ENTITIES.forEach(entitySupplier -> {
|
||||
EntityType<?> entityType = entitySupplier.get();
|
||||
ResourceLocation id = EntityType.getKey(entityType);
|
||||
|
||||
if (id == null || id.equals(EntityType.getKey(ModEntities.SEAT.get()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
String path = id.getPath();
|
||||
helper.tag(ModTags.EntityTypes.forgeDino(path), entityType);
|
||||
helper.tag(ModTags.EntityTypes.neoforgeDino(path), entityType);
|
||||
helper.tag(ModTags.EntityTypes.fabricDino(path), entityType);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -96,6 +96,10 @@ public class ModItemModelProvider {
|
||||
helper.spawnEgg(ModItems.TROODON_SPAWN_EGG.get());
|
||||
helper.spawnEgg(ModItems.UTAHRAPTOR_SPAWN_EGG.get());
|
||||
helper.spawnEgg(ModItems.ACHILLOBATOR_SPAWN_EGG.get());
|
||||
helper.spawnEgg(ModItems.SUCHOMIMUS_SPAWN_EGG.get());
|
||||
helper.spawnEgg(ModItems.CHILESAURUS_SPAWN_EGG.get());
|
||||
helper.spawnEgg(ModItems.THESCELOSAURUS_SPAWN_EGG.get());
|
||||
helper.spawnEgg(ModItems.MUSSASAURUS_SPAWN_EGG.get());
|
||||
|
||||
helper.basicItemModel(ModItems.FROG_MATERIAL.get());
|
||||
helper.basicItemModel(ModItems.FROG_DNA.get());
|
||||
@@ -187,6 +191,10 @@ public class ModItemModelProvider {
|
||||
helper.basicItemModel(ModItems.UTAHRAPTOR_SKULL_FOSSIL.get());
|
||||
helper.basicItemModel(ModItems.ZHENYUANOPTERUS_SKULL_FOSSIL.get());
|
||||
helper.basicItemModel(ModItems.ACHILLOBATOR_SKULL_FOSSIL.get());
|
||||
helper.basicItemModel(ModItems.SUCHOMIMUS_SKULL_FOSSIL.get());
|
||||
helper.basicItemModel(ModItems.CHILESAURUS_SKULL_FOSSIL.get());
|
||||
helper.basicItemModel(ModItems.THESCELOSAURUS_SKULL_FOSSIL.get());
|
||||
helper.basicItemModel(ModItems.MUSSASAURUS_SKULL_FOSSIL.get());
|
||||
|
||||
helper.basicItemModel(ModItems.FRESH_APATOSAURUS_SKULL.get());
|
||||
helper.basicItemModel(ModItems.FRESH_ALBERTOSAURUS_SKULL.get());
|
||||
@@ -262,6 +270,10 @@ public class ModItemModelProvider {
|
||||
helper.basicItemModel(ModItems.FRESH_UTAHRAPTOR_SKULL.get());
|
||||
helper.basicItemModel(ModItems.FRESH_ZHENYUANOPTERUS_SKULL.get());
|
||||
helper.basicItemModel(ModItems.FRESH_ACHILLOBATOR_SKULL.get());
|
||||
helper.basicItemModel(ModItems.FRESH_SUCHOMIMUS_SKULL.get());
|
||||
helper.basicItemModel(ModItems.FRESH_CHILESAURUS_SKULL.get());
|
||||
helper.basicItemModel(ModItems.FRESH_THESCELOSAURUS_SKULL.get());
|
||||
helper.basicItemModel(ModItems.FRESH_MUSSASAURUS_SKULL.get());
|
||||
|
||||
helper.basicItemModel(ModItems.APATOSAURUS_TISSUE.get());
|
||||
helper.basicItemModel(ModItems.ALBERTOSAURUS_TISSUE.get());
|
||||
@@ -337,6 +349,10 @@ public class ModItemModelProvider {
|
||||
helper.basicItemModel(ModItems.UTAHRAPTOR_TISSUE.get());
|
||||
helper.basicItemModel(ModItems.ZHENYUANOPTERUS_TISSUE.get());
|
||||
helper.basicItemModel(ModItems.ACHILLOBATOR_TISSUE.get());
|
||||
helper.basicItemModel(ModItems.SUCHOMIMUS_TISSUE.get());
|
||||
helper.basicItemModel(ModItems.CHILESAURUS_TISSUE.get());
|
||||
helper.basicItemModel(ModItems.THESCELOSAURUS_TISSUE.get());
|
||||
helper.basicItemModel(ModItems.MUSSASAURUS_TISSUE.get());
|
||||
|
||||
helper.basicItemModel(ModItems.APATOSAURUS_DNA.get());
|
||||
helper.basicItemModel(ModItems.ALBERTOSAURUS_DNA.get());
|
||||
@@ -412,6 +428,10 @@ public class ModItemModelProvider {
|
||||
helper.basicItemModel(ModItems.UTAHRAPTOR_DNA.get());
|
||||
helper.basicItemModel(ModItems.ZHENYUANOPTERUS_DNA.get());
|
||||
helper.basicItemModel(ModItems.ACHILLOBATOR_DNA.get());
|
||||
helper.basicItemModel(ModItems.SUCHOMIMUS_DNA.get());
|
||||
helper.basicItemModel(ModItems.CHILESAURUS_DNA.get());
|
||||
helper.basicItemModel(ModItems.THESCELOSAURUS_DNA.get());
|
||||
helper.basicItemModel(ModItems.MUSSASAURUS_DNA.get());
|
||||
|
||||
helper.basicItemModel(ModItems.APATOSAURUS_SYRINGE.get());
|
||||
helper.basicItemModel(ModItems.ALBERTOSAURUS_SYRINGE.get());
|
||||
@@ -487,6 +507,10 @@ public class ModItemModelProvider {
|
||||
helper.basicItemModel(ModItems.UTAHRAPTOR_SYRINGE.get());
|
||||
helper.basicItemModel(ModItems.ZHENYUANOPTERUS_SYRINGE.get());
|
||||
helper.basicItemModel(ModItems.ACHILLOBATOR_SYRINGE.get());
|
||||
helper.basicItemModel(ModItems.SUCHOMIMUS_SYRINGE.get());
|
||||
helper.basicItemModel(ModItems.CHILESAURUS_SYRINGE.get());
|
||||
helper.basicItemModel(ModItems.THESCELOSAURUS_SYRINGE.get());
|
||||
helper.basicItemModel(ModItems.MUSSASAURUS_SYRINGE.get());
|
||||
|
||||
helper.simpleBlockItemModel(ModBlocks.APATOSAURUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.ALBERTOSAURUS_EGG.get());
|
||||
@@ -562,6 +586,10 @@ public class ModItemModelProvider {
|
||||
helper.simpleBlockItemModel(ModBlocks.UTAHRAPTOR_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.ZHENYUANOPTERUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.ACHILLOBATOR_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.SUCHOMIMUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.CHILESAURUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.THESCELOSAURUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.MUSSASAURUS_EGG.get());
|
||||
|
||||
helper.basicItemModel(ModBlocks.LOW_SECURITY_FENCE_POLE.get().asItem());
|
||||
helper.basicItemModel(ModBlocks.LOW_SECURITY_FENCE_WIRE.get().asItem());
|
||||
@@ -645,6 +673,10 @@ public class ModItemModelProvider {
|
||||
helper.simpleBlockItemModel(ModBlocks.INCUBATED_UTAHRAPTOR_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.INCUBATED_SUCHOMIMUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.INCUBATED_CHILESAURUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.INCUBATED_THESCELOSAURUS_EGG.get());
|
||||
helper.simpleBlockItemModel(ModBlocks.INCUBATED_MUSSASAURUS_EGG.get());
|
||||
|
||||
helper.flowerItem(ModBlocks.ROYAL_FERN.get());
|
||||
helper.flowerItem(ModBlocks.HORSETAIL_FERN.get());
|
||||
|
||||
@@ -88,7 +88,11 @@ public class ModItemTagProvider {
|
||||
ModItems.TUPUXUARA_TISSUE.get(),
|
||||
ModItems.UTAHRAPTOR_TISSUE.get(),
|
||||
ModItems.ZHENYUANOPTERUS_TISSUE.get(),
|
||||
ModItems.ACHILLOBATOR_TISSUE.get()
|
||||
ModItems.ACHILLOBATOR_TISSUE.get(),
|
||||
ModItems.SUCHOMIMUS_TISSUE.get(),
|
||||
ModItems.MUSSASAURUS_TISSUE.get(),
|
||||
ModItems.THESCELOSAURUS_TISSUE.get(),
|
||||
ModItems.CHILESAURUS_TISSUE.get()
|
||||
);
|
||||
|
||||
helper.tag(ModTags.Items.DNA,
|
||||
@@ -166,7 +170,11 @@ public class ModItemTagProvider {
|
||||
ModItems.TUPUXUARA_DNA.get(),
|
||||
ModItems.UTAHRAPTOR_DNA.get(),
|
||||
ModItems.ZHENYUANOPTERUS_DNA.get(),
|
||||
ModItems.ACHILLOBATOR_DNA.get()
|
||||
ModItems.ACHILLOBATOR_DNA.get(),
|
||||
ModItems.SUCHOMIMUS_DNA.get(),
|
||||
ModItems.MUSSASAURUS_DNA.get(),
|
||||
ModItems.THESCELOSAURUS_DNA.get(),
|
||||
ModItems.CHILESAURUS_DNA.get()
|
||||
);
|
||||
|
||||
helper.tag(ModTags.Items.SYRINGES,
|
||||
@@ -244,7 +252,11 @@ public class ModItemTagProvider {
|
||||
ModItems.TUPUXUARA_SYRINGE.get(),
|
||||
ModItems.UTAHRAPTOR_SYRINGE.get(),
|
||||
ModItems.ZHENYUANOPTERUS_SYRINGE.get(),
|
||||
ModItems.ACHILLOBATOR_SYRINGE.get()
|
||||
ModItems.ACHILLOBATOR_SYRINGE.get(),
|
||||
ModItems.SUCHOMIMUS_SYRINGE.get(),
|
||||
ModItems.MUSSASAURUS_SYRINGE.get(),
|
||||
ModItems.THESCELOSAURUS_SYRINGE.get(),
|
||||
ModItems.CHILESAURUS_SYRINGE.get()
|
||||
);
|
||||
|
||||
helper.tag(ModTags.Items.EGGS,
|
||||
@@ -321,7 +333,11 @@ public class ModItemTagProvider {
|
||||
Item.byBlock(ModBlocks.TUPUXUARA_EGG.get()),
|
||||
Item.byBlock(ModBlocks.UTAHRAPTOR_EGG.get()),
|
||||
Item.byBlock(ModBlocks.ZHENYUANOPTERUS_EGG.get()),
|
||||
Item.byBlock(ModBlocks.ACHILLOBATOR_EGG.get())
|
||||
Item.byBlock(ModBlocks.ACHILLOBATOR_EGG.get()),
|
||||
Item.byBlock(ModBlocks.SUCHOMIMUS_EGG.get()),
|
||||
Item.byBlock(ModBlocks.MUSSASAURUS_EGG.get()),
|
||||
Item.byBlock(ModBlocks.THESCELOSAURUS_EGG.get()),
|
||||
Item.byBlock(ModBlocks.CHILESAURUS_EGG.get())
|
||||
);
|
||||
|
||||
helper.tag(ModTags.Items.FOSSILS,
|
||||
@@ -396,7 +412,11 @@ public class ModItemTagProvider {
|
||||
ModItems.TUPUXUARA_SKULL_FOSSIL.get(),
|
||||
ModItems.UTAHRAPTOR_SKULL_FOSSIL.get(),
|
||||
ModItems.ZHENYUANOPTERUS_SKULL_FOSSIL.get(),
|
||||
ModItems.ACHILLOBATOR_SKULL_FOSSIL.get()
|
||||
ModItems.ACHILLOBATOR_SKULL_FOSSIL.get(),
|
||||
ModItems.SUCHOMIMUS_SKULL_FOSSIL.get(),
|
||||
ModItems.MUSSASAURUS_SKULL_FOSSIL.get(),
|
||||
ModItems.THESCELOSAURUS_SKULL_FOSSIL.get(),
|
||||
ModItems.CHILESAURUS_SKULL_FOSSIL.get()
|
||||
);
|
||||
|
||||
helper.tag(ModTags.Items.SKULLS,
|
||||
@@ -474,7 +494,11 @@ public class ModItemTagProvider {
|
||||
ModItems.FRESH_TUPUXUARA_SKULL.get(),
|
||||
ModItems.FRESH_UTAHRAPTOR_SKULL.get(),
|
||||
ModItems.FRESH_ZHENYUANOPTERUS_SKULL.get(),
|
||||
ModItems.FRESH_ACHILLOBATOR_SKULL.get()
|
||||
ModItems.FRESH_ACHILLOBATOR_SKULL.get(),
|
||||
ModItems.FRESH_SUCHOMIMUS_SKULL.get(),
|
||||
ModItems.FRESH_MUSSASAURUS_SKULL.get(),
|
||||
ModItems.FRESH_THESCELOSAURUS_SKULL.get(),
|
||||
ModItems.FRESH_CHILESAURUS_SKULL.get()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,10 @@ public class ModRecipeProvider {
|
||||
helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.UTAHRAPTOR_TISSUE.get(), ModItems.UTAHRAPTOR_DNA.get(), 1);
|
||||
helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.ZHENYUANOPTERUS_TISSUE.get(), ModItems.ZHENYUANOPTERUS_DNA.get(), 1);
|
||||
helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.ACHILLOBATOR_TISSUE.get(), ModItems.ACHILLOBATOR_DNA.get(), 1);
|
||||
helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.SUCHOMIMUS_TISSUE.get(), ModItems.SUCHOMIMUS_DNA.get(), 1);
|
||||
helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.CHILESAURUS_TISSUE.get(), ModItems.CHILESAURUS_DNA.get(), 1);
|
||||
helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.THESCELOSAURUS_TISSUE.get(), ModItems.THESCELOSAURUS_DNA.get(), 1);
|
||||
helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.MUSSASAURUS_TISSUE.get(), ModItems.MUSSASAURUS_DNA.get(), 1);
|
||||
|
||||
helper.fossilCleaning(ModBlocks.STONE_FOSSIL.get(), ModItems.APATOSAURUS_SKULL_FOSSIL.get(), 1);
|
||||
helper.fossilCleaning(ModBlocks.DEEPSLATE_FOSSIL.get(), ModItems.VELOCIRAPTOR_SKULL_FOSSIL.get(), 1);
|
||||
@@ -270,6 +274,10 @@ public class ModRecipeProvider {
|
||||
helper.fossilGrinding(ModItems.UTAHRAPTOR_SKULL_FOSSIL.get(), ModItems.UTAHRAPTOR_TISSUE.get(), 1);
|
||||
helper.fossilGrinding(ModItems.ZHENYUANOPTERUS_SKULL_FOSSIL.get(), ModItems.ZHENYUANOPTERUS_TISSUE.get(), 1);
|
||||
helper.fossilGrinding(ModItems.ACHILLOBATOR_SKULL_FOSSIL.get(), ModItems.ACHILLOBATOR_TISSUE.get(), 1);
|
||||
helper.fossilGrinding(ModItems.SUCHOMIMUS_SKULL_FOSSIL.get(), ModItems.SUCHOMIMUS_TISSUE.get(), 1);
|
||||
helper.fossilGrinding(ModItems.CHILESAURUS_SKULL_FOSSIL.get(), ModItems.CHILESAURUS_TISSUE.get(), 1);
|
||||
helper.fossilGrinding(ModItems.THESCELOSAURUS_SKULL_FOSSIL.get(), ModItems.THESCELOSAURUS_TISSUE.get(), 1);
|
||||
helper.fossilGrinding(ModItems.MUSSASAURUS_SKULL_FOSSIL.get(), ModItems.MUSSASAURUS_TISSUE.get(), 1);
|
||||
|
||||
helper.skullToTissue(ModItems.FRESH_ALBERTOSAURUS_SKULL.get(), ModItems.ALBERTOSAURUS_TISSUE.get(), 1);
|
||||
helper.skullToTissue(ModItems.FRESH_APATOSAURUS_SKULL.get(), ModItems.APATOSAURUS_TISSUE.get(), 1);
|
||||
@@ -345,6 +353,10 @@ public class ModRecipeProvider {
|
||||
helper.skullToTissue(ModItems.FRESH_UTAHRAPTOR_SKULL.get(), ModItems.UTAHRAPTOR_TISSUE.get(), 1);
|
||||
helper.skullToTissue(ModItems.FRESH_ZHENYUANOPTERUS_SKULL.get(), ModItems.ZHENYUANOPTERUS_TISSUE.get(), 1);
|
||||
helper.skullToTissue(ModItems.FRESH_ACHILLOBATOR_SKULL.get(), ModItems.ACHILLOBATOR_TISSUE.get(), 1);
|
||||
helper.skullToTissue(ModItems.FRESH_SUCHOMIMUS_SKULL.get(), ModItems.SUCHOMIMUS_TISSUE.get(), 1);
|
||||
helper.skullToTissue(ModItems.FRESH_CHILESAURUS_SKULL.get(), ModItems.CHILESAURUS_TISSUE.get(), 1);
|
||||
helper.skullToTissue(ModItems.FRESH_THESCELOSAURUS_SKULL.get(), ModItems.THESCELOSAURUS_TISSUE.get(), 1);
|
||||
helper.skullToTissue(ModItems.FRESH_MUSSASAURUS_SKULL.get(), ModItems.MUSSASAURUS_TISSUE.get(), 1);
|
||||
|
||||
helper.dnaAnalyzing(ModItems.TEST_TUBE.get(), ModItems.FROG_MATERIAL.get(), ModItems.FROG_DNA.get(), 1);
|
||||
|
||||
@@ -438,6 +450,10 @@ public class ModRecipeProvider {
|
||||
helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.UTAHRAPTOR_DNA.get(), ModItems.FROG_DNA.get(), ModItems.UTAHRAPTOR_SYRINGE.get(), 1);
|
||||
helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.ZHENYUANOPTERUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.ZHENYUANOPTERUS_SYRINGE.get(), 1);
|
||||
helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.ACHILLOBATOR_DNA.get(), ModItems.FROG_DNA.get(), ModItems.ACHILLOBATOR_SYRINGE.get(), 1);
|
||||
helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.SUCHOMIMUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.SUCHOMIMUS_SYRINGE.get(), 1);
|
||||
helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.CHILESAURUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.CHILESAURUS_SYRINGE.get(), 1);
|
||||
helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.THESCELOSAURUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.THESCELOSAURUS_SYRINGE.get(), 1);
|
||||
helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.MUSSASAURUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.MUSSASAURUS_SYRINGE.get(), 1);
|
||||
|
||||
helper.embryoCalcification(ModItems.ALBERTOSAURUS_SYRINGE.get(), Items.EGG, ModBlocks.ALBERTOSAURUS_EGG.get(), 1);
|
||||
helper.embryoCalcification(ModItems.APATOSAURUS_SYRINGE.get(), Items.EGG, ModBlocks.APATOSAURUS_EGG.get(), 1);
|
||||
@@ -513,6 +529,10 @@ public class ModRecipeProvider {
|
||||
helper.embryoCalcification(ModItems.UTAHRAPTOR_SYRINGE.get(), Items.EGG, ModBlocks.UTAHRAPTOR_EGG.get(), 1);
|
||||
helper.embryoCalcification(ModItems.ZHENYUANOPTERUS_SYRINGE.get(), Items.EGG, ModBlocks.ZHENYUANOPTERUS_EGG.get(), 1);
|
||||
helper.embryoCalcification(ModItems.ACHILLOBATOR_SYRINGE.get(), Items.EGG, ModBlocks.ACHILLOBATOR_EGG.get(), 1);
|
||||
helper.embryoCalcification(ModItems.SUCHOMIMUS_SYRINGE.get(), Items.EGG, ModBlocks.SUCHOMIMUS_EGG.get(), 1);
|
||||
helper.embryoCalcification(ModItems.CHILESAURUS_SYRINGE.get(), Items.EGG, ModBlocks.CHILESAURUS_EGG.get(), 1);
|
||||
helper.embryoCalcification(ModItems.THESCELOSAURUS_SYRINGE.get(), Items.EGG, ModBlocks.THESCELOSAURUS_EGG.get(), 1);
|
||||
helper.embryoCalcification(ModItems.MUSSASAURUS_SYRINGE.get(), Items.EGG, ModBlocks.MUSSASAURUS_EGG.get(), 1);
|
||||
|
||||
helper.incubating(ModBlocks.APATOSAURUS_EGG.get(), ModBlocks.INCUBATED_APATOSAURUS_EGG.get(), 1);
|
||||
helper.incubating(ModBlocks.ALBERTOSAURUS_EGG.get(), ModBlocks.INCUBATED_ALBERTOSAURUS_EGG.get(), 1);
|
||||
@@ -588,6 +608,10 @@ public class ModRecipeProvider {
|
||||
helper.incubating(ModBlocks.UTAHRAPTOR_EGG.get(), ModBlocks.INCUBATED_UTAHRAPTOR_EGG.get(), 1);
|
||||
helper.incubating(ModBlocks.ZHENYUANOPTERUS_EGG.get(), ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get(), 1);
|
||||
helper.incubating(ModBlocks.ACHILLOBATOR_EGG.get(), ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get(), 1);
|
||||
helper.incubating(ModBlocks.SUCHOMIMUS_EGG.get(), ModBlocks.INCUBATED_SUCHOMIMUS_EGG.get(), 1);
|
||||
helper.incubating(ModBlocks.CHILESAURUS_EGG.get(), ModBlocks.INCUBATED_CHILESAURUS_EGG.get(), 1);
|
||||
helper.incubating(ModBlocks.THESCELOSAURUS_EGG.get(), ModBlocks.INCUBATED_THESCELOSAURUS_EGG.get(), 1);
|
||||
helper.incubating(ModBlocks.MUSSASAURUS_EGG.get(), ModBlocks.INCUBATED_MUSSASAURUS_EGG.get(), 1);
|
||||
|
||||
helper.amberRandomDNA(ModItems.TEST_TUBE.get(), ModItems.MOSQUITO_IN_AMBER.get(), ModItems.FROG_DNA.get(), 1);
|
||||
}
|
||||
|
||||
@@ -263,6 +263,18 @@ public class ModEntities {
|
||||
ENTITIES.register("dryosaurus", () -> EntityType.Builder.of(DryosaurusEntity::new, MobCategory.CREATURE)
|
||||
.sized(1.0f, 1.5f).build("dryosaurus"));
|
||||
|
||||
public static final RegistrySupplier<EntityType<ThescelosaurusEntity>> THESCELOSAURUS =
|
||||
ENTITIES.register("thescelosaurus", () -> EntityType.Builder.of(ThescelosaurusEntity::new, MobCategory.CREATURE)
|
||||
.sized(1.0f, 1.5f).build("thescelosaurus"));
|
||||
|
||||
public static final RegistrySupplier<EntityType<MussasaurusEntity>> MUSSASAURUS =
|
||||
ENTITIES.register("mussasaurus", () -> EntityType.Builder.of(MussasaurusEntity::new, MobCategory.CREATURE)
|
||||
.sized(1.0f, 1.5f).build("mussasaurus"));
|
||||
|
||||
public static final RegistrySupplier<EntityType<ChilesaurusEntity>> CHILESAURUS =
|
||||
ENTITIES.register("chilesaurus", () -> EntityType.Builder.of(ChilesaurusEntity::new, MobCategory.CREATURE)
|
||||
.sized(1.0f, 1.5f).build("chilesaurus"));
|
||||
|
||||
public static final RegistrySupplier<EntityType<HadrosaurusEntity>> HADROSAURUS =
|
||||
ENTITIES.register("hadrosaurus", () -> EntityType.Builder.of(HadrosaurusEntity::new, MobCategory.CREATURE)
|
||||
.sized(2.0f, 3.0f).build("hadrosaurus"));
|
||||
@@ -335,6 +347,10 @@ public class ModEntities {
|
||||
ENTITIES.register("achillobator", () -> EntityType.Builder.of(AchillobatorEntity::new, MobCategory.CREATURE)
|
||||
.sized(1.0f, 2.0f).build("achillobator"));
|
||||
|
||||
public static final RegistrySupplier<EntityType<SuchomimusEntity>> SUCHOMIMUS =
|
||||
ENTITIES.register("suchomimus", () -> EntityType.Builder.of(SuchomimusEntity::new, MobCategory.CREATURE)
|
||||
.sized(2.0f, 3.0f).build("suchomimus"));
|
||||
|
||||
public static void registerAttributes() {
|
||||
EntityAttributeRegistry.register(APATOSAURUS, ApatosaurusEntity::createAttributes);
|
||||
EntityAttributeRegistry.register(ALBERTOSAURUS, AlbertosaurusEntity::createAttributes);
|
||||
@@ -412,6 +428,10 @@ public class ModEntities {
|
||||
EntityAttributeRegistry.register(TROODON, TroodonEntity::createAttributes);
|
||||
EntityAttributeRegistry.register(UTAHRAPTOR, UtahraptorEntity::createAttributes);
|
||||
EntityAttributeRegistry.register(ACHILLOBATOR, AchillobatorEntity::createAttributes);
|
||||
EntityAttributeRegistry.register(SUCHOMIMUS, SuchomimusEntity::createAttributes);
|
||||
EntityAttributeRegistry.register(CHILESAURUS, ChilesaurusEntity::createAttributes);
|
||||
EntityAttributeRegistry.register(MUSSASAURUS, MussasaurusEntity::createAttributes);
|
||||
EntityAttributeRegistry.register(THESCELOSAURUS, ThescelosaurusEntity::createAttributes);
|
||||
}
|
||||
|
||||
public static void registerSpawnPlacements() {
|
||||
@@ -495,6 +515,10 @@ public class ModEntities {
|
||||
registerGroundAnimalSpawn(VELOCIRAPTOR);
|
||||
registerGroundAnimalSpawn(ZHENYUANOPTERUS);
|
||||
registerGroundAnimalSpawn(ACHILLOBATOR);
|
||||
registerGroundAnimalSpawn(SUCHOMIMUS);
|
||||
registerGroundAnimalSpawn(CHILESAURUS);
|
||||
registerGroundAnimalSpawn(MUSSASAURUS);
|
||||
registerGroundAnimalSpawn(THESCELOSAURUS);
|
||||
}
|
||||
|
||||
private static <T extends Animal> void registerGroundAnimalSpawn(RegistrySupplier<EntityType<T>> entityType) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,14 @@
|
||||
package net.cmr.jurassicrevived.entity.ai;
|
||||
|
||||
import net.cmr.jurassicrevived.config.JRConfigManager;
|
||||
import net.cmr.jurassicrevived.entity.ai.navigation.CustomDinoNavigation;
|
||||
import net.cmr.jurassicrevived.util.ModTags;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.Difficulty;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
@@ -21,6 +25,7 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class DinoEntityBase extends Animal {
|
||||
@@ -83,6 +88,17 @@ public abstract class DinoEntityBase extends Animal {
|
||||
|
||||
public IDinoData getDinoData() { return this.dinoData; }
|
||||
|
||||
public List<TagKey<EntityType<?>>> getDinoTags() {
|
||||
ResourceLocation id = EntityType.getKey(this.getType());
|
||||
String path = id.getPath();
|
||||
|
||||
return List.of(
|
||||
ModTags.EntityTypes.forgeDino(path),
|
||||
ModTags.EntityTypes.neoforgeDino(path),
|
||||
ModTags.EntityTypes.fabricDino(path)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult mobInteract(Player player, InteractionHand hand) {
|
||||
if (!this.level().isClientSide && hand == InteractionHand.MAIN_HAND && player.isShiftKeyDown() && player.getMainHandItem().isEmpty()) {
|
||||
@@ -118,41 +134,106 @@ public abstract class DinoEntityBase extends Animal {
|
||||
}
|
||||
|
||||
player.sendSystemMessage(Component.literal(sb.toString()));
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
return super.mobInteract(player, hand);
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFood(ItemStack stack) {
|
||||
if (dinoData == null) return false;
|
||||
IDinoData.DietaryClassification diet = dinoData.getDiet();
|
||||
ItemStack stack = player.getItemInHand(hand);
|
||||
if (this.isFood(stack)) {
|
||||
if (!this.level().isClientSide) {
|
||||
feedDino(player, stack);
|
||||
}
|
||||
|
||||
// 1. Carnivores: All meat
|
||||
if (diet == IDinoData.DietaryClassification.CARNIVORE || diet == IDinoData.DietaryClassification.PISCIVORE) {
|
||||
// WOLF_FOOD includes beef, pork, chicken, rabbit, mutton, rotten flesh
|
||||
//if (stack.is(ItemTags.WOLF_FOOD)) return true;
|
||||
// Fallback for fish items
|
||||
if (stack.is(ItemTags.FISHES)) return true;
|
||||
}
|
||||
return InteractionResult.sidedSuccess(this.level().isClientSide);
|
||||
}
|
||||
|
||||
// 3. Herbivores: Leaves, Fruits, Vegetables
|
||||
if (diet == IDinoData.DietaryClassification.HERBIVORE) {
|
||||
if (stack.is(ItemTags.LEAVES)) return true;
|
||||
if (stack.is(ItemTags.FLOWERS)) return true;
|
||||
if (stack.is(Items.APPLE) || stack.is(Items.MELON_SLICE) || stack.is(Items.SWEET_BERRIES) || stack.is(Items.GLOW_BERRIES)) return true;
|
||||
if (stack.is(Items.SEAGRASS) || stack.is(Items.KELP)) return true;
|
||||
}
|
||||
return super.mobInteract(player, hand);
|
||||
}
|
||||
|
||||
// 4. Omnivores: Both
|
||||
if (diet == IDinoData.DietaryClassification.OMNIVORE) {
|
||||
//if (stack.is(ItemTags.WOLF_FOOD)) return true;
|
||||
if (stack.is(ItemTags.LEAVES)) return true;
|
||||
}
|
||||
private void feedDino(Player player, ItemStack stack) {
|
||||
if (this.dinoData != null) {
|
||||
float hunger = this.dinoData.getHunger();
|
||||
float maxHunger = this.getAIConfig().maxHunger();
|
||||
float replenishAmount = Math.max(1.0f, this.getAIConfig().defaultHungerReplenishment());
|
||||
|
||||
return false;
|
||||
}
|
||||
this.dinoData.setHunger(Math.min(maxHunger, hunger + replenishAmount));
|
||||
}
|
||||
|
||||
if (this.canFallInLove()) {
|
||||
this.setInLove(player);
|
||||
|
||||
if (this.dinoData != null) {
|
||||
this.dinoData.addCondition(IDinoData.Condition.READY_TO_MATE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.getAbilities().instabuild) {
|
||||
stack.shrink(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFood(ItemStack stack) {
|
||||
if (dinoData == null) return false;
|
||||
IDinoData.DietaryClassification diet = dinoData.getDiet();
|
||||
|
||||
if (diet == IDinoData.DietaryClassification.CARNIVORE) {
|
||||
return isMeatFood(stack);
|
||||
}
|
||||
|
||||
if (diet == IDinoData.DietaryClassification.PISCIVORE) {
|
||||
return isMeatFood(stack) || isFishFood(stack);
|
||||
}
|
||||
|
||||
if (diet == IDinoData.DietaryClassification.HERBIVORE) {
|
||||
return isPlantFood(stack);
|
||||
}
|
||||
|
||||
if (diet == IDinoData.DietaryClassification.OMNIVORE) {
|
||||
return isMeatFood(stack) || isFishFood(stack) || isPlantFood(stack);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isMeatFood(ItemStack stack) {
|
||||
return stack.is(Items.BEEF)
|
||||
|| stack.is(Items.COOKED_BEEF)
|
||||
|| stack.is(Items.PORKCHOP)
|
||||
|| stack.is(Items.COOKED_PORKCHOP)
|
||||
|| stack.is(Items.CHICKEN)
|
||||
|| stack.is(Items.COOKED_CHICKEN)
|
||||
|| stack.is(Items.MUTTON)
|
||||
|| stack.is(Items.COOKED_MUTTON)
|
||||
|| stack.is(Items.RABBIT)
|
||||
|| stack.is(Items.COOKED_RABBIT)
|
||||
|| stack.is(Items.ROTTEN_FLESH);
|
||||
}
|
||||
|
||||
private boolean isFishFood(ItemStack stack) {
|
||||
return stack.is(ItemTags.FISHES)
|
||||
|| stack.is(Items.COD)
|
||||
|| stack.is(Items.COOKED_COD)
|
||||
|| stack.is(Items.SALMON)
|
||||
|| stack.is(Items.COOKED_SALMON)
|
||||
|| stack.is(Items.TROPICAL_FISH)
|
||||
|| stack.is(Items.PUFFERFISH);
|
||||
}
|
||||
|
||||
private boolean isPlantFood(ItemStack stack) {
|
||||
return stack.is(ItemTags.LEAVES)
|
||||
|| stack.is(ItemTags.FLOWERS)
|
||||
|| stack.is(Items.WHEAT)
|
||||
|| stack.is(Items.CARROT)
|
||||
|| stack.is(Items.POTATO)
|
||||
|| stack.is(Items.BEETROOT)
|
||||
|| stack.is(Items.APPLE)
|
||||
|| stack.is(Items.MELON_SLICE)
|
||||
|| stack.is(Items.SWEET_BERRIES)
|
||||
|| stack.is(Items.GLOW_BERRIES)
|
||||
|| stack.is(Items.SEAGRASS)
|
||||
|| stack.is(Items.KELP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnChildFromBreeding(ServerLevel level, Animal partner) {
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
||||
|
||||
|
||||
public class AchillobatorRenderer extends GeoEntityRenderer<AchillobatorEntity> {
|
||||
private final float animalScale = 1.3F;
|
||||
private final float animalScale = 1.0F;
|
||||
public AchillobatorRenderer(EntityRendererProvider.Context renderManager) {
|
||||
super(renderManager, new AchillobatorModel());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.entity.custom.ChilesaurusEntity;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
/*? if <=1.20.1 {*/
|
||||
import software.bernie.geckolib.core.animation.AnimationState;
|
||||
/*?} else {*/
|
||||
/*import software.bernie.geckolib.animation.AnimationState;
|
||||
*//*?}*/
|
||||
import software.bernie.geckolib.cache.object.GeoBone;
|
||||
import software.bernie.geckolib.constant.DataTickets;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ChilesaurusModel extends GeoModel<ChilesaurusEntity> {
|
||||
|
||||
private static final Map<ChilesaurusVariant, ResourceLocation> LOCATION_BY_VARIANT =
|
||||
Util.make(Maps.newEnumMap(ChilesaurusVariant.class), map -> {
|
||||
map.put(ChilesaurusVariant.MALE, Constants.rl("textures/entity/chilesaurus.png"));
|
||||
map.put(ChilesaurusVariant.FEMALE, Constants.rl("textures/entity/chilesaurus_female.png"));
|
||||
});
|
||||
|
||||
// Model-local "currently applied" offsets; cleared before each entity render
|
||||
private float[] appliedYaw = null;
|
||||
private float[] appliedRoll = null;
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelResource(ChilesaurusEntity animatable) {
|
||||
return Constants.rl("geo/chilesaurus.geo.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureResource(ChilesaurusEntity animatable) {
|
||||
return LOCATION_BY_VARIANT.get(animatable.getVariant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(ChilesaurusEntity animatable) {
|
||||
return Constants.rl("animations/chilesaurus.animation.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomAnimations(ChilesaurusEntity entity, long id, AnimationState<ChilesaurusEntity> state) {
|
||||
super.setCustomAnimations(entity, id, state);
|
||||
|
||||
String[] tailBones = { "Tail Base", "Tail 2", "Tail 3", "Tail 4", "Tail 5", "Tail 6" };
|
||||
int n = tailBones.length;
|
||||
|
||||
if (appliedYaw == null || appliedYaw.length != n) {
|
||||
appliedYaw = new float[n];
|
||||
appliedRoll = new float[n];
|
||||
}
|
||||
|
||||
// 1) Clear previous offsets (from the last entity rendered with this model instance)
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (appliedYaw[i] == 0.0f && appliedRoll[i] == 0.0f) continue;
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
if (appliedYaw[i] != 0.0f) bone.setRotY(bone.getRotY() - appliedYaw[i]);
|
||||
if (appliedRoll[i] != 0.0f) bone.setRotZ(bone.getRotZ() - appliedRoll[i]);
|
||||
appliedYaw[i] = 0.0f;
|
||||
appliedRoll[i] = 0.0f;
|
||||
}
|
||||
|
||||
// 2) Interpolated sway for extra smoothness between ticks
|
||||
float sway = entity.getTailSwayOffset(state.getPartialTick()); // [-1, 1]
|
||||
|
||||
// Tuning
|
||||
float maxYawDeg = 22.0f; // increased max sweep
|
||||
float swayGain = 1.35f; // amplifies overall power
|
||||
float rollFraction = 0.40f; // slightly stronger roll for heft
|
||||
|
||||
float deg2rad = (float)Math.PI / 180f;
|
||||
|
||||
// Direction: positive sway (left turn) -> tail swings right (negative yaw)
|
||||
// Flip the sign here if the sway feels inverted
|
||||
float baseYaw = sway * maxYawDeg * deg2rad;
|
||||
float baseRoll = -baseYaw * rollFraction;
|
||||
|
||||
float[] weights = { 1.00f, 0.78f, 0.58f, 0.42f, 0.30f, 0.22f, 0.16f };
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
|
||||
float w = weights[i];
|
||||
float yaw = baseYaw * w;
|
||||
float roll = baseRoll * w;
|
||||
|
||||
// OVERRIDE animations on Y/Z only: keep the model's predefined X bend intact
|
||||
// Do NOT reset rotX here, so the upward bend stays
|
||||
bone.setRotY(yaw);
|
||||
bone.setRotZ(roll);
|
||||
|
||||
appliedYaw[i] = yaw;
|
||||
appliedRoll[i] = roll;
|
||||
}
|
||||
|
||||
GeoBone head = (GeoBone) getAnimationProcessor().getBone("Body FRONT");
|
||||
|
||||
if (head != null) {
|
||||
var entityData = state.getData(DataTickets.ENTITY_MODEL_DATA);
|
||||
float clampedYawDeg = Mth.clamp(entityData.netHeadYaw(), -30.0f, 30.0f);
|
||||
head.setRotY(clampedYawDeg * Mth.DEG_TO_RAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.cmr.jurassicrevived.entity.custom.ChilesaurusEntity;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.util.Mth;
|
||||
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||
import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
||||
|
||||
|
||||
public class ChilesaurusRenderer extends GeoEntityRenderer<ChilesaurusEntity> {
|
||||
private final float animalScale = 0.6F;
|
||||
public ChilesaurusRenderer(EntityRendererProvider.Context renderManager) {
|
||||
super(renderManager, new ChilesaurusModel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ChilesaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) {
|
||||
poseStack.scale(animalScale, animalScale, animalScale);
|
||||
if(animatable.isBaby()) {
|
||||
float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F);
|
||||
float scale = Mth.lerp(growthProgress, 0.2F, 1.0F);
|
||||
poseStack.scale(scale, scale, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public enum ChilesaurusVariant {
|
||||
MALE(0),
|
||||
FEMALE(1);
|
||||
|
||||
private static final ChilesaurusVariant[] BY_ID = Arrays.stream(values()).sorted(
|
||||
Comparator.comparingInt(ChilesaurusVariant::getId)).toArray(ChilesaurusVariant[]::new);
|
||||
|
||||
private final int id;
|
||||
|
||||
ChilesaurusVariant(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static ChilesaurusVariant byId(int id) {
|
||||
return BY_ID[id % BY_ID.length];
|
||||
}
|
||||
}
|
||||
@@ -41,11 +41,7 @@ public class GeosternbergiaModel extends GeoModel<GeosternbergiaEntity> {
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(GeosternbergiaEntity animatable) {
|
||||
//? if >1.20.1 {
|
||||
/*return ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "animations/geosternbergia.animation.json");
|
||||
*///?} else {
|
||||
return new ResourceLocation(Constants.MOD_ID, "animations/geosternbergia.animation.json");
|
||||
//?}
|
||||
return Constants.rl("animations/geosternbergia.animation.json");
|
||||
}
|
||||
public void setCustomAnimations(GeosternbergiaEntity entity, long id, AnimationState<GeosternbergiaEntity> state) {
|
||||
super.setCustomAnimations(entity, id, state);
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.entity.custom.MussasaurusEntity;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
/*? if <=1.20.1 {*/
|
||||
import software.bernie.geckolib.core.animation.AnimationState;
|
||||
/*?} else {*/
|
||||
/*import software.bernie.geckolib.animation.AnimationState;
|
||||
*//*?}*/
|
||||
import software.bernie.geckolib.cache.object.GeoBone;
|
||||
import software.bernie.geckolib.constant.DataTickets;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MussasaurusModel extends GeoModel<MussasaurusEntity> {
|
||||
|
||||
private static final Map<MussasaurusVariant, ResourceLocation> LOCATION_BY_VARIANT =
|
||||
Util.make(Maps.newEnumMap(MussasaurusVariant.class), map -> {
|
||||
map.put(MussasaurusVariant.MALE, Constants.rl("textures/entity/mussasaurus.png"));
|
||||
map.put(MussasaurusVariant.FEMALE, Constants.rl("textures/entity/mussasaurus_female.png"));
|
||||
});
|
||||
|
||||
// Model-local "currently applied" offsets; cleared before each entity render
|
||||
private float[] appliedYaw = null;
|
||||
private float[] appliedRoll = null;
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelResource(MussasaurusEntity animatable) {
|
||||
return Constants.rl("geo/mussasaurus.geo.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureResource(MussasaurusEntity animatable) {
|
||||
return LOCATION_BY_VARIANT.get(animatable.getVariant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(MussasaurusEntity animatable) {
|
||||
return Constants.rl("animations/mussasaurus.animation.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomAnimations(MussasaurusEntity entity, long id, AnimationState<MussasaurusEntity> state) {
|
||||
super.setCustomAnimations(entity, id, state);
|
||||
|
||||
String[] tailBones = { "Tail1", "Tail2", "Tail3", "Tail4", "Tail5", "Tail6", "Tail7", "Tail8" };
|
||||
int n = tailBones.length;
|
||||
|
||||
if (appliedYaw == null || appliedYaw.length != n) {
|
||||
appliedYaw = new float[n];
|
||||
appliedRoll = new float[n];
|
||||
}
|
||||
|
||||
// 1) Clear previous offsets (from the last entity rendered with this model instance)
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (appliedYaw[i] == 0.0f && appliedRoll[i] == 0.0f) continue;
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
if (appliedYaw[i] != 0.0f) bone.setRotY(bone.getRotY() - appliedYaw[i]);
|
||||
if (appliedRoll[i] != 0.0f) bone.setRotZ(bone.getRotZ() - appliedRoll[i]);
|
||||
appliedYaw[i] = 0.0f;
|
||||
appliedRoll[i] = 0.0f;
|
||||
}
|
||||
|
||||
// 2) Interpolated sway for extra smoothness between ticks
|
||||
float sway = entity.getTailSwayOffset(state.getPartialTick()); // [-1, 1]
|
||||
|
||||
// Tuning
|
||||
float maxYawDeg = 22.0f; // increased max sweep
|
||||
float swayGain = 1.35f; // amplifies overall power
|
||||
float rollFraction = 0.40f; // slightly stronger roll for heft
|
||||
|
||||
float deg2rad = (float)Math.PI / 180f;
|
||||
|
||||
// Direction: positive sway (left turn) -> tail swings right (negative yaw)
|
||||
// Flip the sign here if the sway feels inverted
|
||||
float baseYaw = sway * maxYawDeg * deg2rad;
|
||||
float baseRoll = -baseYaw * rollFraction;
|
||||
|
||||
float[] weights = { 1.00f, 0.78f, 0.58f, 0.42f, 0.30f, 0.22f, 0.16f, 0.10f };
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
|
||||
float w = weights[i];
|
||||
float yaw = baseYaw * w;
|
||||
float roll = baseRoll * w;
|
||||
|
||||
// OVERRIDE animations on Y/Z only: keep the model's predefined X bend intact
|
||||
// Do NOT reset rotX here, so the upward bend stays
|
||||
bone.setRotY(yaw);
|
||||
bone.setRotZ(roll);
|
||||
|
||||
appliedYaw[i] = yaw;
|
||||
appliedRoll[i] = roll;
|
||||
}
|
||||
|
||||
GeoBone head = (GeoBone) getAnimationProcessor().getBone("Neck1");
|
||||
|
||||
if (head != null) {
|
||||
var entityData = state.getData(DataTickets.ENTITY_MODEL_DATA);
|
||||
float clampedYawDeg = Mth.clamp(entityData.netHeadYaw(), -20.0f, 20.0f);
|
||||
head.setRotY(clampedYawDeg * Mth.DEG_TO_RAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.cmr.jurassicrevived.entity.custom.MussasaurusEntity;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.util.Mth;
|
||||
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||
import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
||||
|
||||
|
||||
public class MussasaurusRenderer extends GeoEntityRenderer<MussasaurusEntity> {
|
||||
private final float animalScale = 0.7F;
|
||||
public MussasaurusRenderer(EntityRendererProvider.Context renderManager) {
|
||||
super(renderManager, new MussasaurusModel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MussasaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) {
|
||||
poseStack.scale(animalScale, animalScale, animalScale);
|
||||
if(animatable.isBaby()) {
|
||||
float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F);
|
||||
float scale = Mth.lerp(growthProgress, 0.2F, 1.0F);
|
||||
poseStack.scale(scale, scale, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public enum MussasaurusVariant {
|
||||
MALE(0),
|
||||
FEMALE(1);
|
||||
|
||||
private static final MussasaurusVariant[] BY_ID = Arrays.stream(values()).sorted(
|
||||
Comparator.comparingInt(MussasaurusVariant::getId)).toArray(MussasaurusVariant[]::new);
|
||||
|
||||
private final int id;
|
||||
|
||||
MussasaurusVariant(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static MussasaurusVariant byId(int id) {
|
||||
return BY_ID[id % BY_ID.length];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.entity.custom.SuchomimusEntity;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
/*? if <=1.20.1 {*/
|
||||
import software.bernie.geckolib.core.animation.AnimationState;
|
||||
/*?} else {*/
|
||||
/*import software.bernie.geckolib.animation.AnimationState;
|
||||
*//*?}*/
|
||||
import software.bernie.geckolib.cache.object.GeoBone;
|
||||
import software.bernie.geckolib.constant.DataTickets;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SuchomimusModel extends GeoModel<SuchomimusEntity> {
|
||||
|
||||
private static final Map<SuchomimusVariant, ResourceLocation> LOCATION_BY_VARIANT =
|
||||
Util.make(Maps.newEnumMap(SuchomimusVariant.class), map -> {
|
||||
map.put(SuchomimusVariant.MALE, Constants.rl("textures/entity/suchomimus.png"));
|
||||
map.put(SuchomimusVariant.FEMALE, Constants.rl("textures/entity/suchomimus_female.png"));
|
||||
});
|
||||
|
||||
// Model-local "currently applied" offsets; cleared before each entity render
|
||||
private float[] appliedYaw = null;
|
||||
private float[] appliedRoll = null;
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelResource(SuchomimusEntity animatable) {
|
||||
return Constants.rl("geo/suchomimus.geo.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureResource(SuchomimusEntity animatable) {
|
||||
return LOCATION_BY_VARIANT.get(animatable.getVariant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(SuchomimusEntity animatable) {
|
||||
return Constants.rl("animations/suchomimus.animation.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomAnimations(SuchomimusEntity entity, long id, AnimationState<SuchomimusEntity> state) {
|
||||
super.setCustomAnimations(entity, id, state);
|
||||
|
||||
String[] tailBones = { "Tail 1", "Tail 2", "Tail 3", "Tail 4", "Tail 5", "Tail 6" };
|
||||
int n = tailBones.length;
|
||||
|
||||
if (appliedYaw == null || appliedYaw.length != n) {
|
||||
appliedYaw = new float[n];
|
||||
appliedRoll = new float[n];
|
||||
}
|
||||
|
||||
// 1) Clear previous offsets (from the last entity rendered with this model instance)
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (appliedYaw[i] == 0.0f && appliedRoll[i] == 0.0f) continue;
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
if (appliedYaw[i] != 0.0f) bone.setRotY(bone.getRotY() - appliedYaw[i]);
|
||||
if (appliedRoll[i] != 0.0f) bone.setRotZ(bone.getRotZ() - appliedRoll[i]);
|
||||
appliedYaw[i] = 0.0f;
|
||||
appliedRoll[i] = 0.0f;
|
||||
}
|
||||
|
||||
// 2) Interpolated sway for extra smoothness between ticks
|
||||
float sway = entity.getTailSwayOffset(state.getPartialTick()); // [-1, 1]
|
||||
|
||||
// Tuning
|
||||
float maxYawDeg = 22.0f; // increased max sweep
|
||||
float swayGain = 1.35f; // amplifies overall power
|
||||
float rollFraction = 0.40f; // slightly stronger roll for heft
|
||||
|
||||
float deg2rad = (float)Math.PI / 180f;
|
||||
|
||||
// Direction: positive sway (left turn) -> tail swings right (negative yaw)
|
||||
// Flip the sign here if the sway feels inverted
|
||||
float baseYaw = sway * maxYawDeg * deg2rad;
|
||||
float baseRoll = -baseYaw * rollFraction;
|
||||
|
||||
float[] weights = { 1.00f, 0.78f, 0.58f, 0.42f, 0.30f, 0.22f };
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
|
||||
float w = weights[i];
|
||||
float yaw = baseYaw * w;
|
||||
float roll = baseRoll * w;
|
||||
|
||||
// OVERRIDE animations on Y/Z only: keep the model's predefined X bend intact
|
||||
// Do NOT reset rotX here, so the upward bend stays
|
||||
bone.setRotY(yaw);
|
||||
bone.setRotZ(roll);
|
||||
|
||||
appliedYaw[i] = yaw;
|
||||
appliedRoll[i] = roll;
|
||||
}
|
||||
|
||||
GeoBone head = (GeoBone) getAnimationProcessor().getBone("Neck 1");
|
||||
|
||||
if (head != null) {
|
||||
var entityData = state.getData(DataTickets.ENTITY_MODEL_DATA);
|
||||
float clampedYawDeg = Mth.clamp(entityData.netHeadYaw(), -20.0f, 20.0f);
|
||||
head.setRotY(clampedYawDeg * Mth.DEG_TO_RAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.cmr.jurassicrevived.entity.custom.SuchomimusEntity;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.util.Mth;
|
||||
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||
import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
||||
|
||||
|
||||
public class SuchomimusRenderer extends GeoEntityRenderer<SuchomimusEntity> {
|
||||
private final float animalScale = 1.5F;
|
||||
public SuchomimusRenderer(EntityRendererProvider.Context renderManager) {
|
||||
super(renderManager, new SuchomimusModel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, SuchomimusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) {
|
||||
poseStack.scale(animalScale, animalScale, animalScale);
|
||||
if(animatable.isBaby()) {
|
||||
float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F);
|
||||
float scale = Mth.lerp(growthProgress, 0.2F, 1.0F);
|
||||
poseStack.scale(scale, scale, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public enum SuchomimusVariant {
|
||||
MALE(0),
|
||||
FEMALE(1);
|
||||
|
||||
private static final SuchomimusVariant[] BY_ID = Arrays.stream(values()).sorted(
|
||||
Comparator.comparingInt(SuchomimusVariant::getId)).toArray(SuchomimusVariant[]::new);
|
||||
|
||||
private final int id;
|
||||
|
||||
SuchomimusVariant(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static SuchomimusVariant byId(int id) {
|
||||
return BY_ID[id % BY_ID.length];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.cmr.jurassicrevived.Constants;
|
||||
import net.cmr.jurassicrevived.entity.custom.ThescelosaurusEntity;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
/*? if <=1.20.1 {*/
|
||||
import software.bernie.geckolib.core.animation.AnimationState;
|
||||
/*?} else {*/
|
||||
/*import software.bernie.geckolib.animation.AnimationState;
|
||||
*//*?}*/
|
||||
import software.bernie.geckolib.cache.object.GeoBone;
|
||||
import software.bernie.geckolib.constant.DataTickets;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ThescelosaurusModel extends GeoModel<ThescelosaurusEntity> {
|
||||
|
||||
private static final Map<ThescelosaurusVariant, ResourceLocation> LOCATION_BY_VARIANT =
|
||||
Util.make(Maps.newEnumMap(ThescelosaurusVariant.class), map -> {
|
||||
map.put(ThescelosaurusVariant.MALE, Constants.rl("textures/entity/thescelosaurus.png"));
|
||||
map.put(ThescelosaurusVariant.FEMALE, Constants.rl("textures/entity/thescelosaurus_female.png"));
|
||||
});
|
||||
|
||||
// Model-local "currently applied" offsets; cleared before each entity render
|
||||
private float[] appliedYaw = null;
|
||||
private float[] appliedRoll = null;
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelResource(ThescelosaurusEntity animatable) {
|
||||
return Constants.rl("geo/thescelosaurus.geo.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureResource(ThescelosaurusEntity animatable) {
|
||||
return LOCATION_BY_VARIANT.get(animatable.getVariant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(ThescelosaurusEntity animatable) {
|
||||
return Constants.rl("animations/thescelosaurus.animation.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomAnimations(ThescelosaurusEntity entity, long id, AnimationState<ThescelosaurusEntity> state) {
|
||||
super.setCustomAnimations(entity, id, state);
|
||||
|
||||
String[] tailBones = { "Tail BASE", "Tail 2", "Tail 3", "Tail 4", "Tail 5", "Tail 6", "Tail 7" };
|
||||
int n = tailBones.length;
|
||||
|
||||
if (appliedYaw == null || appliedYaw.length != n) {
|
||||
appliedYaw = new float[n];
|
||||
appliedRoll = new float[n];
|
||||
}
|
||||
|
||||
// 1) Clear previous offsets (from the last entity rendered with this model instance)
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (appliedYaw[i] == 0.0f && appliedRoll[i] == 0.0f) continue;
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
if (appliedYaw[i] != 0.0f) bone.setRotY(bone.getRotY() - appliedYaw[i]);
|
||||
if (appliedRoll[i] != 0.0f) bone.setRotZ(bone.getRotZ() - appliedRoll[i]);
|
||||
appliedYaw[i] = 0.0f;
|
||||
appliedRoll[i] = 0.0f;
|
||||
}
|
||||
|
||||
// 2) Interpolated sway for extra smoothness between ticks
|
||||
float sway = entity.getTailSwayOffset(state.getPartialTick()); // [-1, 1]
|
||||
|
||||
// Tuning
|
||||
float maxYawDeg = 22.0f; // increased max sweep
|
||||
float swayGain = 1.35f; // amplifies overall power
|
||||
float rollFraction = 0.40f; // slightly stronger roll for heft
|
||||
|
||||
float deg2rad = (float)Math.PI / 180f;
|
||||
|
||||
// Direction: positive sway (left turn) -> tail swings right (negative yaw)
|
||||
// Flip the sign here if the sway feels inverted
|
||||
float baseYaw = sway * maxYawDeg * deg2rad;
|
||||
float baseRoll = -baseYaw * rollFraction;
|
||||
|
||||
float[] weights = { 1.00f, 0.78f, 0.58f, 0.42f, 0.30f, 0.22f, 0.16f };
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
GeoBone bone = (GeoBone) getAnimationProcessor().getBone(tailBones[i]);
|
||||
if (bone == null) continue;
|
||||
|
||||
float w = weights[i];
|
||||
float yaw = baseYaw * w;
|
||||
float roll = baseRoll * w;
|
||||
|
||||
// OVERRIDE animations on Y/Z only: keep the model's predefined X bend intact
|
||||
// Do NOT reset rotX here, so the upward bend stays
|
||||
bone.setRotY(yaw);
|
||||
bone.setRotZ(roll);
|
||||
|
||||
appliedYaw[i] = yaw;
|
||||
appliedRoll[i] = roll;
|
||||
}
|
||||
|
||||
GeoBone head = (GeoBone) getAnimationProcessor().getBone("Body FRONT");
|
||||
|
||||
if (head != null) {
|
||||
var entityData = state.getData(DataTickets.ENTITY_MODEL_DATA);
|
||||
float clampedYawDeg = Mth.clamp(entityData.netHeadYaw(), -30.0f, 30.0f);
|
||||
head.setRotY(clampedYawDeg * Mth.DEG_TO_RAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.cmr.jurassicrevived.entity.custom.ThescelosaurusEntity;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.util.Mth;
|
||||
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||
import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
||||
|
||||
|
||||
public class ThescelosaurusRenderer extends GeoEntityRenderer<ThescelosaurusEntity> {
|
||||
private final float animalScale = 0.7F;
|
||||
public ThescelosaurusRenderer(EntityRendererProvider.Context renderManager) {
|
||||
super(renderManager, new ThescelosaurusModel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ThescelosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) {
|
||||
poseStack.scale(animalScale, animalScale, animalScale);
|
||||
if(animatable.isBaby()) {
|
||||
float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F);
|
||||
float scale = Mth.lerp(growthProgress, 0.2F, 1.0F);
|
||||
poseStack.scale(scale, scale, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.cmr.jurassicrevived.entity.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public enum ThescelosaurusVariant {
|
||||
MALE(0),
|
||||
FEMALE(1);
|
||||
|
||||
private static final ThescelosaurusVariant[] BY_ID = Arrays.stream(values()).sorted(
|
||||
Comparator.comparingInt(ThescelosaurusVariant::getId)).toArray(ThescelosaurusVariant[]::new);
|
||||
|
||||
private final int id;
|
||||
|
||||
ThescelosaurusVariant(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static ThescelosaurusVariant byId(int id) {
|
||||
return BY_ID[id % BY_ID.length];
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
||||
|
||||
|
||||
public class UtahraptorRenderer extends GeoEntityRenderer<UtahraptorEntity> {
|
||||
private final float animalScale = 0.9F;
|
||||
private final float animalScale = 1.0F;
|
||||
public UtahraptorRenderer(EntityRendererProvider.Context renderManager) {
|
||||
super(renderManager, new UtahraptorModel());
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.cmr.jurassicrevived.entity.ai.DinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.DinoEntityBase;
|
||||
import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.client.AchillobatorVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -22,6 +23,7 @@ import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.ai.attributes.DefaultAttributes;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -71,6 +73,11 @@ public class AchillobatorEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ACHILLOBATOR_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
@@ -98,13 +105,13 @@ public class AchillobatorEntity extends DinoEntityBase implements GeoEntity {
|
||||
|
||||
public static AttributeSupplier.Builder createAttributes() {
|
||||
return Animal.createLivingAttributes()
|
||||
.add(Attributes.MAX_HEALTH, 55D)
|
||||
.add(Attributes.MAX_HEALTH, 30D)
|
||||
.add(Attributes.MOVEMENT_SPEED, 0.3D)
|
||||
.add(Attributes.ARMOR, 0D)
|
||||
.add(Attributes.FOLLOW_RANGE, 32D)
|
||||
.add(Attributes.KNOCKBACK_RESISTANCE, 0D)
|
||||
.add(Attributes.ATTACK_KNOCKBACK, 0D)
|
||||
.add(Attributes.ATTACK_DAMAGE, 16D);
|
||||
.add(Attributes.ATTACK_DAMAGE, 8D)
|
||||
.add(Attributes.KNOCKBACK_RESISTANCE, 0.3D)
|
||||
.add(Attributes.ATTACK_KNOCKBACK, 0D);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.cmr.jurassicrevived.entity.ai.DinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.DinoEntityBase;
|
||||
import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -72,6 +73,10 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
IDinoData.ActivityPattern.CATHEMERAL
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ALBERTOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.entity.ai.*;
|
||||
import net.cmr.jurassicrevived.entity.client.AllosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.AllosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -75,6 +76,11 @@ public class AllosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ALLOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlvarezsaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.AlvarezsaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ALVAREZSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AnkylosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.AnkylosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -79,6 +80,11 @@ public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ANKYLOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.ApatosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ApatosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -81,6 +82,11 @@ public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.APATOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.ArambourgianiaVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ArambourgianiaVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ARAMBOURGIANIA_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.BaryonyxVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.BaryonyxVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class BaryonyxEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.BARYONYX_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.BrachiosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.BrachiosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -81,6 +82,11 @@ public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.BRACHIOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
+6
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.CarcharodontosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CarcharodontosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -83,6 +84,11 @@ public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEnti
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CARCHARODONTOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.entity.ai.*;
|
||||
import net.cmr.jurassicrevived.entity.client.CarnotaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CarnotaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CARNOTAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.CearadactylusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CearadactylusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, Fl
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CEARADACTYLUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.entity.ai.*;
|
||||
import net.cmr.jurassicrevived.entity.client.CeratosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CeratosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -76,6 +77,11 @@ public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CERATOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.ChasmosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ChasmosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -79,6 +80,11 @@ public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CHASMOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -81,6 +81,11 @@ public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CHICKENOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
package net.cmr.jurassicrevived.entity.custom;
|
||||
|
||||
import net.cmr.jurassicrevived.block.ModBlocks;
|
||||
import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.entity.ai.DinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.DinoEntityBase;
|
||||
import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.client.ChilesaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
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.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.*;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.ai.attributes.DefaultAttributes;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import software.bernie.geckolib.animatable.GeoEntity;
|
||||
/*? if <=1.20.1 {*/
|
||||
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
|
||||
import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache;
|
||||
import software.bernie.geckolib.core.animation.AnimatableManager;
|
||||
import software.bernie.geckolib.core.animation.Animation;
|
||||
import software.bernie.geckolib.core.animation.AnimationController;
|
||||
import software.bernie.geckolib.core.animation.RawAnimation;
|
||||
import software.bernie.geckolib.core.object.PlayState;
|
||||
/*?} else {*/
|
||||
/*import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
|
||||
import software.bernie.geckolib.animatable.instance.SingletonAnimatableInstanceCache;
|
||||
import software.bernie.geckolib.animation.*;
|
||||
*//*?}*/
|
||||
|
||||
public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this);
|
||||
|
||||
private static final EntityDataAccessor<Integer> VARIANT =
|
||||
SynchedEntityData.defineId(ChilesaurusEntity.class, EntityDataSerializers.INT);
|
||||
private static final EntityDataAccessor<Integer> DATA_SYNCED_AGE =
|
||||
SynchedEntityData.defineId(ChilesaurusEntity.class, EntityDataSerializers.INT);
|
||||
|
||||
// Procedural tail sway state (client-side use for rendering)
|
||||
private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1]
|
||||
private float tailSwayVelocity; // Internal velocity for spring-damper
|
||||
private float tailSwayPrev; // Previous frame value for interpolation
|
||||
|
||||
public ChilesaurusEntity(EntityType<? extends Animal> pEntityType, Level pLevel) {
|
||||
super(pEntityType, pLevel);
|
||||
|
||||
this.dinoData = new DinoData(
|
||||
getAIConfig().maxHunger(),
|
||||
getAIConfig().maxThirst(),
|
||||
IDinoData.Mood.NEUTRAL,
|
||||
IDinoData.Aggression.TERRITORIAL,
|
||||
0.75f,
|
||||
IDinoData.DietaryClassification.HERBIVORE,
|
||||
IDinoData.Type.TERRESTRIAL,
|
||||
IDinoData.Group.ORNITHOPOD,
|
||||
IDinoData.BirthType.EGG_LAYING,
|
||||
IDinoData.ActivityPattern.CATHEMERAL
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CHILESAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMarine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmphibious() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getEggBlock() {
|
||||
return ModBlocks.INCUBATED_CHILESAURUS_EGG.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DinoAIConfig getAIConfig() {
|
||||
return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20);
|
||||
}
|
||||
|
||||
public static AttributeSupplier.Builder createAttributes() {
|
||||
return Animal.createLivingAttributes()
|
||||
.add(Attributes.MAX_HEALTH, 20D)
|
||||
.add(Attributes.MOVEMENT_SPEED, 0.3D)
|
||||
.add(Attributes.ARMOR, 0D)
|
||||
.add(Attributes.FOLLOW_RANGE, 32D)
|
||||
.add(Attributes.KNOCKBACK_RESISTANCE, 0D)
|
||||
.add(Attributes.ATTACK_KNOCKBACK, 0D)
|
||||
.add(Attributes.ATTACK_DAMAGE, 0D);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) {
|
||||
AgeableMob child = ModEntities.CHILESAURUS.get().create(pLevel);
|
||||
if (child instanceof ChilesaurusEntity baby) {
|
||||
ChilesaurusVariant randomVariant = Util.getRandom(ChilesaurusVariant.values(), this.random);
|
||||
baby.setVariant(randomVariant);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doHurtTarget(Entity target) {
|
||||
boolean hit = super.doHurtTarget(target);
|
||||
if (!level().isClientSide && hit && target instanceof LivingEntity) {
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
this.triggerAnim("attackController", "attack");
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
|
||||
controllers.add(new AnimationController<>(this, "Walk/Run/Idle", 5, state -> {
|
||||
if (state.isMoving())
|
||||
return state.setAndContinue(ChilesaurusEntity.this.isSprinting() ? RawAnimation.begin().then("anim.chilesaurus.run", Animation.LoopType.LOOP) : RawAnimation.begin().then("anim.chilesaurus.walk", Animation.LoopType.LOOP));
|
||||
|
||||
return state.setAndContinue(RawAnimation.begin().then("anim.chilesaurus.idle", Animation.LoopType.LOOP));
|
||||
}));
|
||||
|
||||
controllers.add(new AnimationController<>(this, "attackController", 5, state -> PlayState.STOP)
|
||||
.triggerableAnim("attack", RawAnimation.begin().then("anim.chilesaurus.attack", Animation.LoopType.PLAY_ONCE)));
|
||||
}
|
||||
|
||||
private float getSignedTurnDelta() {
|
||||
// Only consider the body (torso) rotation so head look does not affect tail sway
|
||||
return Mth.wrapDegrees(this.yBodyRot - this.yBodyRotO);
|
||||
}
|
||||
|
||||
private int mouthAnimCooldown = 0;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!level().isClientSide) {
|
||||
this.entityData.set(DATA_SYNCED_AGE, this.getAge());
|
||||
var maxHealthAttr = getAttribute(Attributes.MAX_HEALTH);
|
||||
if (maxHealthAttr != null) {
|
||||
double baseAdult = DefaultAttributes.getSupplier((EntityType<? extends LivingEntity>) this.getType()).getValue(Attributes.MAX_HEALTH);
|
||||
double desired = this.isBaby() ? baseAdult * 0.10D : baseAdult;
|
||||
if (maxHealthAttr.getBaseValue() != desired) {
|
||||
double oldMax = maxHealthAttr.getBaseValue();
|
||||
double healthRatio = this.getHealth() / (float) oldMax;
|
||||
maxHealthAttr.setBaseValue(desired);
|
||||
this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!level().isClientSide) {
|
||||
if (mouthAnimCooldown > 0) {
|
||||
mouthAnimCooldown--;
|
||||
} else {
|
||||
this.playSound(ModSounds.CHILESAURUS_CALL.get(), 1.0F, 1.0F);
|
||||
// 30s–60s in ticks
|
||||
mouthAnimCooldown = this.random.nextInt(1200 - 600 + 1) + 600;
|
||||
}
|
||||
}
|
||||
|
||||
if (level().isClientSide) {
|
||||
// Capture previous for smooth interpolation between ticks
|
||||
this.tailSwayPrev = this.tailSwayOffset;
|
||||
updateProceduralTailSway();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProceduralTailSway() {
|
||||
// Turn input derived from rotation deltas; works even when standing still and turning
|
||||
float turnDegrees = getSignedTurnDelta();
|
||||
|
||||
// Deadzone to ignore tiny jitter so the tail can return to center cleanly
|
||||
float deadzoneDeg = 0.6f; // smaller deadzone for more responsiveness
|
||||
float turnInput = 0.0f;
|
||||
if (Math.abs(turnDegrees) >= deadzoneDeg) {
|
||||
// Higher sensitivity so small in-place turns still affect the model
|
||||
turnInput = Mth.clamp(turnDegrees / 15.0f, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
// Target offset: keep intuitive sign (positive input -> positive sway)
|
||||
float target = turnInput;
|
||||
|
||||
// One-pole low-pass (no bounce). Larger alpha => snappier and less "stiff".
|
||||
float alpha = 0.24f; // try 0.20–0.30 to taste
|
||||
|
||||
tailSwayOffset += (target - tailSwayOffset) * alpha;
|
||||
|
||||
// Snap tiny residuals to zero so it visibly settles
|
||||
if (Math.abs(tailSwayOffset) < 0.003f) {
|
||||
tailSwayOffset = 0.0f;
|
||||
}
|
||||
|
||||
// No oscillation velocity retained
|
||||
tailSwayVelocity = 0.0f;
|
||||
|
||||
tailSwayOffset = Mth.clamp(tailSwayOffset, -1.5f, 1.5f);
|
||||
}
|
||||
|
||||
// Expose to the model for bone rotation
|
||||
public float getTailSwayOffset() {
|
||||
return tailSwayOffset;
|
||||
}
|
||||
|
||||
// Interpolated sway for smooth rendering between ticks
|
||||
public float getTailSwayOffset(float partialTick) {
|
||||
return Mth.lerp(Mth.clamp(partialTick, 0.0f, 1.0f), tailSwayPrev, tailSwayOffset);
|
||||
}
|
||||
|
||||
/*? if <=1.20.1 {*/
|
||||
@Override
|
||||
protected void defineSynchedData() {
|
||||
super.defineSynchedData();
|
||||
this.entityData.define(VARIANT, 0);
|
||||
this.entityData.define(DATA_SYNCED_AGE, 0);
|
||||
}
|
||||
/*?} else {*/
|
||||
/*@Override
|
||||
protected void defineSynchedData(SynchedEntityData.Builder pBuilder) {
|
||||
super.defineSynchedData(pBuilder);
|
||||
pBuilder.define(VARIANT, 0);
|
||||
pBuilder.define(DATA_SYNCED_AGE, 0);
|
||||
}
|
||||
*//*?}*/
|
||||
|
||||
public int getSyncedAge() {
|
||||
return this.entityData.get(DATA_SYNCED_AGE);
|
||||
}
|
||||
public int getTypeVariant() {
|
||||
return this.entityData.get(VARIANT);
|
||||
}
|
||||
|
||||
public ChilesaurusVariant getVariant() {
|
||||
return ChilesaurusVariant.byId(this.getTypeVariant() & 255);
|
||||
}
|
||||
|
||||
private void setVariant(ChilesaurusVariant variant) {
|
||||
this.entityData.set(VARIANT, variant.getId() & 255);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMate(Animal other) {
|
||||
if (!super.canMate(other)) return false;
|
||||
if (!(other instanceof ChilesaurusEntity that)) return false;
|
||||
return this.getVariant() != that.getVariant();
|
||||
}
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag pCompound) {
|
||||
super.addAdditionalSaveData(pCompound);
|
||||
pCompound.putInt("Variant", this.getTypeVariant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag pCompound) {
|
||||
super.readAdditionalSaveData(pCompound);
|
||||
this.entityData.set(VARIANT, pCompound.getInt("Variant"));
|
||||
}
|
||||
|
||||
/*? if <=1.20.1 {*/
|
||||
@Override
|
||||
public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) {
|
||||
ChilesaurusVariant variant = Util.getRandom(ChilesaurusVariant.values(), this.random);
|
||||
this.setVariant(variant);
|
||||
return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag);
|
||||
}
|
||||
/*?} else {*/
|
||||
/*@Override
|
||||
public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) {
|
||||
ChilesaurusVariant variant = Util.getRandom(ChilesaurusVariant.values(), this.random);
|
||||
this.setVariant(variant);
|
||||
return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);
|
||||
}
|
||||
*//*?}*/
|
||||
|
||||
@Override
|
||||
public AnimatableInstanceCache getAnimatableInstanceCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable SoundEvent getHurtSound(DamageSource damageSource) {
|
||||
return ModSounds.CHILESAURUS_HURT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable SoundEvent getDeathSound() {
|
||||
return ModSounds.CHILESAURUS_DEATH.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable SoundEvent getAmbientSound() {
|
||||
return ModSounds.CHILESAURUS_CALL.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFluidJumpThreshold() {
|
||||
return this.getEyeHeight();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.CoelophysisVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CoelophysisVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class CoelophysisEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.COELOPHYSIS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.CoelurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CoelurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class CoelurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.COELURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.CompsognathusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CompsognathusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -79,6 +80,11 @@ public class CompsognathusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.COMPSOGNATHUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.entity.ai.*;
|
||||
import net.cmr.jurassicrevived.entity.client.ConcavenatorVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ConcavenatorVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -76,6 +77,11 @@ public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CONCAVENATOR_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.CorythosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.CorythosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.CORYTHOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.DeinonychusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.DeinonychusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class DeinonychusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.DEINONYCHUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.DilophosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.DilophosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.DILOPHOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.DimorphodonVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.DimorphodonVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, Flyi
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.DIMORPHODON_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.DiplodocusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.DiplodocusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -81,6 +82,11 @@ public class DiplodocusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.DIPLODOCUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.DistortusRexVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.DistortusRexVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -83,6 +84,11 @@ public class DistortusRexEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.DISTORTUS_REX_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.DryosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.DryosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class DryosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.DRYOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.EdmontosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.EdmontosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.EDMONTOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -81,6 +81,11 @@ public class FDuckEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.FDUCK_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.GallimimusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.GallimimusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class GallimimusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.GALLIMIMUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.GeosternbergiaVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.GeosternbergiaVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, F
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.GEOSTERNBERGIA_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.GiganotosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.GiganotosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -83,6 +84,11 @@ public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.GIGANOTOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.GuanlongVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.GuanlongVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -81,6 +82,11 @@ public class GuanlongEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.GUANLONG_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.GuidracoVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.GuidracoVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingA
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.GUIDRACO_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.HadrosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.HadrosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.HADROSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.HerrerasaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.HerrerasaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -81,6 +82,11 @@ public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.HERRERASAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.HypsilophodonVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.HypsilophodonVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.HYPSILOPHODON_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.IndominusRexVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.IndominusRexVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -82,6 +83,11 @@ public class IndominusRexEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.INDOMINUS_REX_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.IndoraptorVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.IndoraptorVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class IndoraptorEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.INDORAPTOR_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.InostranceviaVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.InostranceviaVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class InostranceviaEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.INOSTRANCEVIA_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.LambeosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.LambeosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.LAMBEOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.LudodactylusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.LudodactylusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, Fly
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.LUDODACTYLUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.MajungasaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.MajungasaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -81,6 +82,11 @@ public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.MAJUNGASAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.MamenchisaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.MamenchisaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -81,6 +82,11 @@ public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.MAMENCHISAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
+6
@@ -5,6 +5,7 @@ import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.entity.ai.*;
|
||||
import net.cmr.jurassicrevived.entity.client.MetriacanthosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.MetriacanthosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -76,6 +77,11 @@ public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntit
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.METRIACANTHOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.MoganopterusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.MoganopterusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class MoganopterusEntity extends DinoEntityBase implements GeoEntity, Fly
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.MOGANOPTERUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
package net.cmr.jurassicrevived.entity.custom;
|
||||
|
||||
import net.cmr.jurassicrevived.block.ModBlocks;
|
||||
import net.cmr.jurassicrevived.entity.ModEntities;
|
||||
import net.cmr.jurassicrevived.entity.ai.DinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.DinoEntityBase;
|
||||
import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.client.MussasaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
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.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.*;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.ai.attributes.DefaultAttributes;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import software.bernie.geckolib.animatable.GeoEntity;
|
||||
/*? if <=1.20.1 {*/
|
||||
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
|
||||
import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache;
|
||||
import software.bernie.geckolib.core.animation.AnimatableManager;
|
||||
import software.bernie.geckolib.core.animation.Animation;
|
||||
import software.bernie.geckolib.core.animation.AnimationController;
|
||||
import software.bernie.geckolib.core.animation.RawAnimation;
|
||||
import software.bernie.geckolib.core.object.PlayState;
|
||||
/*?} else {*/
|
||||
/*import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
|
||||
import software.bernie.geckolib.animatable.instance.SingletonAnimatableInstanceCache;
|
||||
import software.bernie.geckolib.animation.*;
|
||||
*//*?}*/
|
||||
|
||||
public class MussasaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this);
|
||||
|
||||
private static final EntityDataAccessor<Integer> VARIANT =
|
||||
SynchedEntityData.defineId(MussasaurusEntity.class, EntityDataSerializers.INT);
|
||||
private static final EntityDataAccessor<Integer> DATA_SYNCED_AGE =
|
||||
SynchedEntityData.defineId(MussasaurusEntity.class, EntityDataSerializers.INT);
|
||||
|
||||
// Procedural tail sway state (client-side use for rendering)
|
||||
private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1]
|
||||
private float tailSwayVelocity; // Internal velocity for spring-damper
|
||||
private float tailSwayPrev; // Previous frame value for interpolation
|
||||
|
||||
public MussasaurusEntity(EntityType<? extends Animal> pEntityType, Level pLevel) {
|
||||
super(pEntityType, pLevel);
|
||||
|
||||
this.dinoData = new DinoData(
|
||||
getAIConfig().maxHunger(),
|
||||
getAIConfig().maxThirst(),
|
||||
IDinoData.Mood.NEUTRAL,
|
||||
IDinoData.Aggression.TERRITORIAL,
|
||||
0.75f,
|
||||
IDinoData.DietaryClassification.HERBIVORE,
|
||||
IDinoData.Type.TERRESTRIAL,
|
||||
IDinoData.Group.CERAPOD,
|
||||
IDinoData.BirthType.EGG_LAYING,
|
||||
IDinoData.ActivityPattern.CATHEMERAL
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.MUSSASAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMarine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmphibious() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getEggBlock() {
|
||||
return ModBlocks.INCUBATED_MUSSASAURUS_EGG.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DinoAIConfig getAIConfig() {
|
||||
return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20);
|
||||
}
|
||||
|
||||
public static AttributeSupplier.Builder createAttributes() {
|
||||
return Animal.createLivingAttributes()
|
||||
.add(Attributes.MAX_HEALTH, 34D)
|
||||
.add(Attributes.MOVEMENT_SPEED, 0.3D)
|
||||
.add(Attributes.ARMOR, 0D)
|
||||
.add(Attributes.FOLLOW_RANGE, 32D)
|
||||
.add(Attributes.KNOCKBACK_RESISTANCE, 0D)
|
||||
.add(Attributes.ATTACK_KNOCKBACK, 0D)
|
||||
.add(Attributes.ATTACK_DAMAGE, 6D);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) {
|
||||
AgeableMob child = ModEntities.MUSSASAURUS.get().create(pLevel);
|
||||
if (child instanceof MussasaurusEntity baby) {
|
||||
MussasaurusVariant randomVariant = Util.getRandom(MussasaurusVariant.values(), this.random);
|
||||
baby.setVariant(randomVariant);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doHurtTarget(Entity target) {
|
||||
boolean hit = super.doHurtTarget(target);
|
||||
if (!level().isClientSide && hit && target instanceof LivingEntity) {
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
this.triggerAnim("attackController", "attack");
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
|
||||
controllers.add(new AnimationController<>(this, "Walk/Run/Idle", 5, state -> {
|
||||
if (state.isMoving())
|
||||
return state.setAndContinue(MussasaurusEntity.this.isSprinting() ? RawAnimation.begin().then("anim.mussasaurus.run", Animation.LoopType.LOOP) : RawAnimation.begin().then("anim.mussasaurus.walk", Animation.LoopType.LOOP));
|
||||
|
||||
return state.setAndContinue(RawAnimation.begin().then("anim.mussasaurus.idle", Animation.LoopType.LOOP));
|
||||
}));
|
||||
|
||||
controllers.add(new AnimationController<>(this, "attackController", 5, state -> PlayState.STOP)
|
||||
.triggerableAnim("attack", RawAnimation.begin().then("anim.mussasaurus.attack", Animation.LoopType.PLAY_ONCE)));
|
||||
|
||||
controllers.add(new AnimationController<>(this, "mouthController", 5, state -> PlayState.STOP)
|
||||
.triggerableAnim("mouth", RawAnimation.begin().then("anim.mussasaurus.mouth", Animation.LoopType.PLAY_ONCE)));
|
||||
}
|
||||
|
||||
private float getSignedTurnDelta() {
|
||||
// Only consider the body (torso) rotation so head look does not affect tail sway
|
||||
return Mth.wrapDegrees(this.yBodyRot - this.yBodyRotO);
|
||||
}
|
||||
|
||||
private int mouthAnimCooldown = 0;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!level().isClientSide) {
|
||||
this.entityData.set(DATA_SYNCED_AGE, this.getAge());
|
||||
var maxHealthAttr = getAttribute(Attributes.MAX_HEALTH);
|
||||
if (maxHealthAttr != null) {
|
||||
double baseAdult = DefaultAttributes.getSupplier((EntityType<? extends LivingEntity>) this.getType()).getValue(Attributes.MAX_HEALTH);
|
||||
double desired = this.isBaby() ? baseAdult * 0.10D : baseAdult;
|
||||
if (maxHealthAttr.getBaseValue() != desired) {
|
||||
double oldMax = maxHealthAttr.getBaseValue();
|
||||
double healthRatio = this.getHealth() / (float) oldMax;
|
||||
maxHealthAttr.setBaseValue(desired);
|
||||
this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!level().isClientSide) {
|
||||
if (mouthAnimCooldown > 0) {
|
||||
mouthAnimCooldown--;
|
||||
} else {
|
||||
this.triggerAnim("mouthController", "mouth");
|
||||
this.playSound(ModSounds.MUSSASAURUS_CALL.get(), 1.0F, 1.0F);
|
||||
// 30s–60s in ticks
|
||||
mouthAnimCooldown = this.random.nextInt(1200 - 600 + 1) + 600;
|
||||
}
|
||||
}
|
||||
|
||||
if (level().isClientSide) {
|
||||
// Capture previous for smooth interpolation between ticks
|
||||
this.tailSwayPrev = this.tailSwayOffset;
|
||||
updateProceduralTailSway();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProceduralTailSway() {
|
||||
// Turn input derived from rotation deltas; works even when standing still and turning
|
||||
float turnDegrees = getSignedTurnDelta();
|
||||
|
||||
// Deadzone to ignore tiny jitter so the tail can return to center cleanly
|
||||
float deadzoneDeg = 0.6f; // smaller deadzone for more responsiveness
|
||||
float turnInput = 0.0f;
|
||||
if (Math.abs(turnDegrees) >= deadzoneDeg) {
|
||||
// Higher sensitivity so small in-place turns still affect the model
|
||||
turnInput = Mth.clamp(turnDegrees / 15.0f, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
// Target offset: keep intuitive sign (positive input -> positive sway)
|
||||
float target = turnInput;
|
||||
|
||||
// One-pole low-pass (no bounce). Larger alpha => snappier and less "stiff".
|
||||
float alpha = 0.24f; // try 0.20–0.30 to taste
|
||||
|
||||
tailSwayOffset += (target - tailSwayOffset) * alpha;
|
||||
|
||||
// Snap tiny residuals to zero so it visibly settles
|
||||
if (Math.abs(tailSwayOffset) < 0.003f) {
|
||||
tailSwayOffset = 0.0f;
|
||||
}
|
||||
|
||||
// No oscillation velocity retained
|
||||
tailSwayVelocity = 0.0f;
|
||||
|
||||
tailSwayOffset = Mth.clamp(tailSwayOffset, -1.5f, 1.5f);
|
||||
}
|
||||
|
||||
// Expose to the model for bone rotation
|
||||
public float getTailSwayOffset() {
|
||||
return tailSwayOffset;
|
||||
}
|
||||
|
||||
// Interpolated sway for smooth rendering between ticks
|
||||
public float getTailSwayOffset(float partialTick) {
|
||||
return Mth.lerp(Mth.clamp(partialTick, 0.0f, 1.0f), tailSwayPrev, tailSwayOffset);
|
||||
}
|
||||
|
||||
/*? if <=1.20.1 {*/
|
||||
@Override
|
||||
protected void defineSynchedData() {
|
||||
super.defineSynchedData();
|
||||
this.entityData.define(VARIANT, 0);
|
||||
this.entityData.define(DATA_SYNCED_AGE, 0);
|
||||
}
|
||||
/*?} else {*/
|
||||
/*@Override
|
||||
protected void defineSynchedData(SynchedEntityData.Builder pBuilder) {
|
||||
super.defineSynchedData(pBuilder);
|
||||
pBuilder.define(VARIANT, 0);
|
||||
pBuilder.define(DATA_SYNCED_AGE, 0);
|
||||
}
|
||||
*//*?}*/
|
||||
|
||||
public int getSyncedAge() {
|
||||
return this.entityData.get(DATA_SYNCED_AGE);
|
||||
}
|
||||
public int getTypeVariant() {
|
||||
return this.entityData.get(VARIANT);
|
||||
}
|
||||
|
||||
public MussasaurusVariant getVariant() {
|
||||
return MussasaurusVariant.byId(this.getTypeVariant() & 255);
|
||||
}
|
||||
|
||||
private void setVariant(MussasaurusVariant variant) {
|
||||
this.entityData.set(VARIANT, variant.getId() & 255);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMate(Animal other) {
|
||||
if (!super.canMate(other)) return false;
|
||||
if (!(other instanceof MussasaurusEntity that)) return false;
|
||||
return this.getVariant() != that.getVariant();
|
||||
}
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag pCompound) {
|
||||
super.addAdditionalSaveData(pCompound);
|
||||
pCompound.putInt("Variant", this.getTypeVariant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag pCompound) {
|
||||
super.readAdditionalSaveData(pCompound);
|
||||
this.entityData.set(VARIANT, pCompound.getInt("Variant"));
|
||||
}
|
||||
|
||||
/*? if <=1.20.1 {*/
|
||||
@Override
|
||||
public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) {
|
||||
MussasaurusVariant variant = Util.getRandom(MussasaurusVariant.values(), this.random);
|
||||
this.setVariant(variant);
|
||||
return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag);
|
||||
}
|
||||
/*?} else {*/
|
||||
/*@Override
|
||||
public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) {
|
||||
MussasaurusVariant variant = Util.getRandom(MussasaurusVariant.values(), this.random);
|
||||
this.setVariant(variant);
|
||||
return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);
|
||||
}
|
||||
*//*?}*/
|
||||
|
||||
@Override
|
||||
public AnimatableInstanceCache getAnimatableInstanceCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable SoundEvent getHurtSound(DamageSource damageSource) {
|
||||
return ModSounds.MUSSASAURUS_HURT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable SoundEvent getDeathSound() {
|
||||
return ModSounds.MUSSASAURUS_DEATH.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable SoundEvent getAmbientSound() {
|
||||
return ModSounds.MUSSASAURUS_CALL.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFluidJumpThreshold() {
|
||||
return this.getEyeHeight();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.NyctosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.NyctosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -90,6 +91,11 @@ public class NyctosaurusEntity extends DinoEntityBase implements GeoEntity, Flyi
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.NYCTOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.OrnitholestesVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.OrnitholestesVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ORNITHOLESTES_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.OrnithomimusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.ORNITHOMIMUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.OuranosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.OURANOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.OviraptorVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -79,6 +80,11 @@ public class OviraptorEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.OVIRAPTOR_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
+6
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.PachycephalosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -79,6 +80,11 @@ public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntit
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.PACHYCEPHALOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.cmr.jurassicrevived.entity.ai.IDinoData;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ParasaurolophusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -77,6 +78,11 @@ public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.PARASAUROLOPHUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ProceratosaurusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.PROCERATOSAURUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ProcompsognathusVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -80,6 +81,11 @@ public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.PROCOMPSOGNATHUS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal;
|
||||
import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal;
|
||||
import net.cmr.jurassicrevived.entity.client.AlbertosaurusVariant;
|
||||
import net.cmr.jurassicrevived.entity.client.ProtoceratopsVariant;
|
||||
import net.cmr.jurassicrevived.item.ModItems;
|
||||
import net.cmr.jurassicrevived.sound.ModSounds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -79,6 +80,11 @@ public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickResult() {
|
||||
return new ItemStack(ModItems.PROTOCERATOPS_SPAWN_EGG.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCarnivore() {
|
||||
return false;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user