ah
This commit is contained in:
@@ -6,7 +6,7 @@ minecraft_version=1.20.1
|
|||||||
yarn_mappings=1.20.1+build.10
|
yarn_mappings=1.20.1+build.10
|
||||||
loader_version=0.18.3
|
loader_version=0.18.3
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=26.2.26.1
|
mod_version=26.2.27
|
||||||
maven_group=dev.tggamesyt
|
maven_group=dev.tggamesyt
|
||||||
archives_base_name=szar
|
archives_base_name=szar
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package dev.tggamesyt.szar;
|
package dev.tggamesyt.szar;
|
||||||
|
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.*;
|
||||||
import net.minecraft.entity.ItemEntity;
|
|
||||||
import net.minecraft.entity.TntEntity;
|
|
||||||
import net.minecraft.entity.ai.TargetPredicate;
|
import net.minecraft.entity.ai.TargetPredicate;
|
||||||
import net.minecraft.entity.ai.goal.Goal;
|
import net.minecraft.entity.ai.goal.Goal;
|
||||||
import net.minecraft.entity.ai.goal.LookAroundGoal;
|
import net.minecraft.entity.ai.goal.LookAroundGoal;
|
||||||
@@ -15,13 +13,24 @@ import net.minecraft.entity.mob.MobEntity;
|
|||||||
import net.minecraft.entity.mob.PathAwareEntity;
|
import net.minecraft.entity.mob.PathAwareEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.LocalDifficulty;
|
||||||
|
import net.minecraft.world.ServerWorldAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class IslamTerrorist extends PathAwareEntity implements Arrestable{
|
public class IslamTerrorist extends PathAwareEntity implements Arrestable{
|
||||||
|
private BlockPos targetCoreBlock = null; // the core block this mob is attacking
|
||||||
|
private Vec3d taxiDirection;
|
||||||
|
private Vec3d currentDirection = null; // direction plane is moving
|
||||||
|
private BlockPos taxiTarget;
|
||||||
|
private int flyStraightTicks = 0;
|
||||||
|
private int planeTaxiTicks = 0;
|
||||||
public static boolean arrestable = false;
|
public static boolean arrestable = false;
|
||||||
private int BlowUpCooldown = 0;
|
private int BlowUpCooldown = 0;
|
||||||
private int panicTicks = 0;
|
private int panicTicks = 0;
|
||||||
@@ -56,6 +65,108 @@ public class IslamTerrorist extends PathAwareEntity implements Arrestable{
|
|||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (BlowUpCooldown > 0) BlowUpCooldown--;
|
if (BlowUpCooldown > 0) BlowUpCooldown--;
|
||||||
|
|
||||||
|
Entity vehicle = this.getVehicle();
|
||||||
|
if (!(vehicle instanceof PlaneEntity plane) || targetCoreBlock == null) return;
|
||||||
|
|
||||||
|
Vec3d vel = plane.getVelocity();
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// TAXI PHASE: ground, random direction
|
||||||
|
// -------------------------
|
||||||
|
if (planeTaxiTicks > 0) {
|
||||||
|
planeTaxiTicks--;
|
||||||
|
|
||||||
|
if (taxiTarget != null) {
|
||||||
|
Vec3d toTarget = Vec3d.ofCenter(taxiTarget).subtract(plane.getPos());
|
||||||
|
if (toTarget.length() > 0.5) {
|
||||||
|
Vec3d desired = toTarget.normalize().multiply(0.4);
|
||||||
|
plane.setVelocity(vel.lerp(desired, 0.1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// small lift near end
|
||||||
|
if (planeTaxiTicks < 20) {
|
||||||
|
plane.setVelocity(plane.getVelocity().x, 0.08, plane.getVelocity().z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Face movement
|
||||||
|
Vec3d look = plane.getVelocity().normalize();
|
||||||
|
if (look.length() > 0) {
|
||||||
|
plane.setYaw((float) Math.toDegrees(Math.atan2(-look.x, look.z)));
|
||||||
|
plane.setPitch((float) -Math.toDegrees(Math.asin(look.y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// FLY STRAIGHT PHASE
|
||||||
|
// -------------------------
|
||||||
|
if (flyStraightTicks > 0) {
|
||||||
|
flyStraightTicks--;
|
||||||
|
|
||||||
|
plane.setVelocity(currentDirection.x * 1.4, 0.25, currentDirection.z * 1.4);
|
||||||
|
|
||||||
|
Vec3d look = plane.getVelocity().normalize();
|
||||||
|
if (look.length() > 0) {
|
||||||
|
plane.setYaw((float) Math.toDegrees(Math.atan2(-look.x, look.z)));
|
||||||
|
plane.setPitch((float) -Math.toDegrees(Math.asin(look.y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// HOMING PHASE
|
||||||
|
// -------------------------
|
||||||
|
Vec3d target = Vec3d.ofCenter(targetCoreBlock);
|
||||||
|
Vec3d toTarget = target.subtract(plane.getPos());
|
||||||
|
Vec3d desired = toTarget.normalize().multiply(1.8);
|
||||||
|
|
||||||
|
// Add small upward lift if below target
|
||||||
|
if (plane.getY() < target.y - 10) {
|
||||||
|
desired = desired.add(0, 0.2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smooth turning toward target
|
||||||
|
currentDirection = currentDirection.lerp(desired.normalize(), 0.03).normalize();
|
||||||
|
|
||||||
|
plane.setVelocity(currentDirection.multiply(1.8));
|
||||||
|
|
||||||
|
// Face movement
|
||||||
|
Vec3d look = plane.getVelocity().normalize();
|
||||||
|
if (look.length() > 0) {
|
||||||
|
plane.setYaw((float) Math.toDegrees(Math.atan2(-look.x, look.z)));
|
||||||
|
plane.setPitch((float) -Math.toDegrees(Math.asin(look.y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// IMPACT
|
||||||
|
// -------------------------
|
||||||
|
if (!getWorld().isClient &&
|
||||||
|
(plane.horizontalCollision || plane.verticalCollision)) {
|
||||||
|
|
||||||
|
getWorld().createExplosion(
|
||||||
|
plane,
|
||||||
|
plane.getX(),
|
||||||
|
plane.getY(),
|
||||||
|
plane.getZ(),
|
||||||
|
7.0f,
|
||||||
|
World.ExplosionSourceType.TNT
|
||||||
|
);
|
||||||
|
|
||||||
|
plane.discard();
|
||||||
|
this.discard();
|
||||||
|
|
||||||
|
BlockEntity be = getWorld().getBlockEntity(targetCoreBlock);
|
||||||
|
if (be instanceof ObeliskCoreBlockEntity core) {
|
||||||
|
core.setHasPlaneMob(false);
|
||||||
|
core.markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
targetCoreBlock = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= VISIBILITY =================
|
// ================= VISIBILITY =================
|
||||||
@@ -96,6 +207,19 @@ public class IslamTerrorist extends PathAwareEntity implements Arrestable{
|
|||||||
this.velocityDirty = true;
|
this.velocityDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeath(DamageSource source) {
|
||||||
|
super.onDeath(source);
|
||||||
|
|
||||||
|
if (targetCoreBlock == null) return;
|
||||||
|
|
||||||
|
BlockEntity be = getWorld().getBlockEntity(targetCoreBlock);
|
||||||
|
if (be instanceof ObeliskCoreBlockEntity core) {
|
||||||
|
core.setHasPlaneMob(false);
|
||||||
|
core.markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ================= DAMAGE =================
|
// ================= DAMAGE =================
|
||||||
|
|
||||||
@@ -119,6 +243,70 @@ public class IslamTerrorist extends PathAwareEntity implements Arrestable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityData initialize(
|
||||||
|
ServerWorldAccess worldAccess,
|
||||||
|
LocalDifficulty difficulty,
|
||||||
|
SpawnReason spawnReason,
|
||||||
|
@Nullable EntityData entityData,
|
||||||
|
@Nullable NbtCompound entityNbt
|
||||||
|
) {
|
||||||
|
EntityData data = super.initialize(worldAccess, difficulty, spawnReason, entityData, entityNbt);
|
||||||
|
|
||||||
|
if (!(worldAccess instanceof ServerWorld world)) return data;
|
||||||
|
|
||||||
|
BlockPos corePos = findNearbyCoreBlock(this.getBlockPos(), 100);
|
||||||
|
if (corePos == null) return data;
|
||||||
|
|
||||||
|
BlockEntity be = world.getBlockEntity(corePos);
|
||||||
|
if (!(be instanceof ObeliskCoreBlockEntity core)) return data;
|
||||||
|
|
||||||
|
if (!core.hasPlaneMob() && world.random.nextInt(100) == 0) {
|
||||||
|
|
||||||
|
PlaneEntity plane = new PlaneEntity(Szar.PLANE_ENTITY_TYPE, world);
|
||||||
|
plane.refreshPositionAndAngles(getX(), getY(), getZ(), getYaw(), getPitch());
|
||||||
|
|
||||||
|
world.spawnEntity(plane);
|
||||||
|
this.startRiding(plane, true);
|
||||||
|
|
||||||
|
core.setHasPlaneMob(true);
|
||||||
|
core.markDirty();
|
||||||
|
|
||||||
|
this.targetCoreBlock = corePos;
|
||||||
|
|
||||||
|
// Taxi + straight flight setup
|
||||||
|
this.planeTaxiTicks = 60; // 3 seconds ground taxi
|
||||||
|
this.flyStraightTicks = 40; // 2 seconds straight flight before homing
|
||||||
|
|
||||||
|
// Random horizontal direction
|
||||||
|
float randomYaw = world.random.nextFloat() * 360f;
|
||||||
|
this.currentDirection = Vec3d.fromPolar(0, randomYaw).normalize();
|
||||||
|
|
||||||
|
// Taxi target 20 blocks ahead in random direction
|
||||||
|
this.taxiTarget = this.getBlockPos().add(
|
||||||
|
(int)(currentDirection.x * 20),
|
||||||
|
0,
|
||||||
|
(int)(currentDirection.z * 20)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockPos findNearbyCoreBlock(BlockPos pos, int radius) {
|
||||||
|
for (int dx = -radius; dx <= radius; dx++) {
|
||||||
|
for (int dy = -radius; dy <= radius; dy++) {
|
||||||
|
for (int dz = -radius; dz <= radius; dz++) {
|
||||||
|
BlockPos check = pos.add(dx, dy, dz);
|
||||||
|
if (getWorld().getBlockState(check).getBlock() == Szar.OBELISK_CORE) {
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// 🔴 Flee from only specific victim, hide behind others
|
// 🔴 Flee from only specific victim, hide behind others
|
||||||
private static class FleeSpecificPlayerGoal extends Goal {
|
private static class FleeSpecificPlayerGoal extends Goal {
|
||||||
private final IslamTerrorist mob;
|
private final IslamTerrorist mob;
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
package dev.tggamesyt.szar;
|
package dev.tggamesyt.szar;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockEntityProvider;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.explosion.Explosion;
|
import net.minecraft.world.explosion.Explosion;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class ObeliskCoreBlock extends Block {
|
public class ObeliskCoreBlock extends Block implements BlockEntityProvider {
|
||||||
|
|
||||||
public ObeliskCoreBlock(Settings settings) {
|
public ObeliskCoreBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ObeliskCoreBlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
return new ObeliskCoreBlockEntity(pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
|
public void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
|
||||||
super.onDestroyedByExplosion(world, pos, explosion);
|
super.onDestroyedByExplosion(world, pos, explosion);
|
||||||
@@ -19,5 +30,12 @@ public class ObeliskCoreBlock extends Block {
|
|||||||
if (!(world instanceof ServerWorld serverWorld)) return;
|
if (!(world instanceof ServerWorld serverWorld)) return;
|
||||||
|
|
||||||
TwoTowersUtil.grantNearbyAdvancement(serverWorld, pos, 100);
|
TwoTowersUtil.grantNearbyAdvancement(serverWorld, pos, 100);
|
||||||
|
|
||||||
|
BlockEntity be = world.getBlockEntity(pos);
|
||||||
|
if (be instanceof ObeliskCoreBlockEntity core) {
|
||||||
|
core.setHasPlaneMob(false); // reset in case a plane was active
|
||||||
|
core.markDirty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
src/main/java/dev/tggamesyt/szar/ObeliskCoreBlockEntity.java
Normal file
31
src/main/java/dev/tggamesyt/szar/ObeliskCoreBlockEntity.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package dev.tggamesyt.szar;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public class ObeliskCoreBlockEntity extends BlockEntity {
|
||||||
|
|
||||||
|
private boolean hasPlaneMob = false;
|
||||||
|
|
||||||
|
public ObeliskCoreBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
super(Szar.OBELISK_CORE_ENTITY, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NBT serialization
|
||||||
|
@Override
|
||||||
|
public void writeNbt(NbtCompound nbt) {
|
||||||
|
super.writeNbt(nbt);
|
||||||
|
nbt.putBoolean("hasPlaneMob", hasPlaneMob);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readNbt(NbtCompound nbt) {
|
||||||
|
super.readNbt(nbt);
|
||||||
|
hasPlaneMob = nbt.getBoolean("hasPlaneMob");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPlaneMob() { return hasPlaneMob; }
|
||||||
|
public void setHasPlaneMob(boolean value) { hasPlaneMob = value; }
|
||||||
|
}
|
||||||
@@ -17,12 +17,15 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
|||||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
|
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
|
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.trade.TradeOfferHelper;
|
import net.fabricmc.fabric.api.object.builder.v1.trade.TradeOfferHelper;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.world.poi.PointOfInterestHelper;
|
import net.fabricmc.fabric.api.object.builder.v1.world.poi.PointOfInterestHelper;
|
||||||
import net.minecraft.advancement.Advancement;
|
import net.minecraft.advancement.Advancement;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.entity.*;
|
import net.minecraft.entity.*;
|
||||||
import net.minecraft.entity.damage.DamageType;
|
import net.minecraft.entity.damage.DamageType;
|
||||||
import net.minecraft.entity.data.DataTracker;
|
import net.minecraft.entity.data.DataTracker;
|
||||||
@@ -649,6 +652,26 @@ public class Szar implements ModInitializer {
|
|||||||
return count;
|
return count;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
dispatcher.register(
|
||||||
|
LiteralArgumentBuilder.<ServerCommandSource>literal("getnearestobeliskcore")
|
||||||
|
.requires(context -> context.hasPermissionLevel(2))
|
||||||
|
.executes(context -> {
|
||||||
|
ServerCommandSource source = context.getSource();
|
||||||
|
ServerWorld world = source.getWorld();
|
||||||
|
|
||||||
|
assert source.getEntity() != null;
|
||||||
|
ObeliskCoreBlockEntity nearest = findNearestObelisk(world, source.getEntity().getBlockPos(), 100);
|
||||||
|
if (nearest != null) {
|
||||||
|
boolean hasPlane = nearest.hasPlaneMob();
|
||||||
|
|
||||||
|
source.sendMessage(Text.literal(
|
||||||
|
"HasPlane: " + hasPlane
|
||||||
|
));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
Registry.register(
|
Registry.register(
|
||||||
Registries.ITEM,
|
Registries.ITEM,
|
||||||
@@ -656,6 +679,36 @@ public class Szar implements ModInitializer {
|
|||||||
new BlockItem(OBELISK_CORE, new Item.Settings())
|
new BlockItem(OBELISK_CORE, new Item.Settings())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
public static ObeliskCoreBlockEntity findNearestObelisk(ServerWorld world, BlockPos center, int radius) {
|
||||||
|
ObeliskCoreBlockEntity closest = null;
|
||||||
|
double closestDistance = Double.MAX_VALUE;
|
||||||
|
|
||||||
|
BlockPos.Mutable mutable = new BlockPos.Mutable();
|
||||||
|
|
||||||
|
for (int x = -radius; x <= radius; x++) {
|
||||||
|
for (int y = -radius; y <= radius; y++) {
|
||||||
|
for (int z = -radius; z <= radius; z++) {
|
||||||
|
|
||||||
|
mutable.set(center.getX() + x,
|
||||||
|
center.getY() + y,
|
||||||
|
center.getZ() + z);
|
||||||
|
|
||||||
|
BlockEntity be = world.getBlockEntity(mutable);
|
||||||
|
|
||||||
|
if (be instanceof ObeliskCoreBlockEntity obelisk) {
|
||||||
|
double distance = center.getSquaredDistance(mutable);
|
||||||
|
|
||||||
|
if (distance < closestDistance) {
|
||||||
|
closestDistance = distance;
|
||||||
|
closest = obelisk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
public static final Item CNDM = Registry.register(
|
public static final Item CNDM = Registry.register(
|
||||||
Registries.ITEM,
|
Registries.ITEM,
|
||||||
new Identifier(MOD_ID, "cndm"),
|
new Identifier(MOD_ID, "cndm"),
|
||||||
@@ -691,7 +744,14 @@ public class Szar implements ModInitializer {
|
|||||||
.copy(Blocks.DIRT) // soft block
|
.copy(Blocks.DIRT) // soft block
|
||||||
.strength(0.5f, 1.0f) // very easy to break, low blast resistance
|
.strength(0.5f, 1.0f) // very easy to break, low blast resistance
|
||||||
)
|
)
|
||||||
|
);
|
||||||
|
public static final BlockEntityType<ObeliskCoreBlockEntity> OBELISK_CORE_ENTITY = Registry.register(
|
||||||
|
Registries.BLOCK_ENTITY_TYPE,
|
||||||
|
new Identifier(MOD_ID, "obelisk_core"),
|
||||||
|
FabricBlockEntityTypeBuilder.create(
|
||||||
|
ObeliskCoreBlockEntity::new,
|
||||||
|
OBELISK_CORE // block(s) this BE is linked to
|
||||||
|
).build(null)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user