generated from Nekojimi/ForgeModTemplate
parent
21392fc84b
commit
1f9a053f68
@ -0,0 +1,64 @@ |
|||||||
|
package moe.nekojimi.dimensionwalker; |
||||||
|
|
||||||
|
import com.mojang.logging.LogUtils; |
||||||
|
import net.minecraft.client.renderer.item.ItemProperties; |
||||||
|
import net.minecraft.core.Registry; |
||||||
|
import net.minecraft.server.MinecraftServer; |
||||||
|
import net.minecraft.server.commands.TeleportCommand; |
||||||
|
import net.minecraft.server.level.ServerLevel; |
||||||
|
import net.minecraft.server.level.ServerPlayer; |
||||||
|
import net.minecraft.world.InteractionHand; |
||||||
|
import net.minecraft.world.InteractionResultHolder; |
||||||
|
import net.minecraft.world.entity.player.Player; |
||||||
|
import net.minecraft.world.item.CreativeModeTab; |
||||||
|
import net.minecraft.world.item.Item; |
||||||
|
import net.minecraft.world.item.ItemStack; |
||||||
|
import net.minecraft.world.level.Level; |
||||||
|
import net.minecraft.world.level.block.NetherPortalBlock; |
||||||
|
import net.minecraftforge.registries.DeferredRegister; |
||||||
|
import net.minecraftforge.registries.ForgeRegistries; |
||||||
|
import net.minecraftforge.registries.RegistryObject; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import java.util.Collection; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Random; |
||||||
|
import java.util.logging.Logger; |
||||||
|
import java.util.stream.StreamSupport; |
||||||
|
|
||||||
|
public class DimensionwalkerItem extends Item |
||||||
|
{ |
||||||
|
private static DeferredRegister<Level> DIMENSION_REGISTER = DeferredRegister.create(Registry.DIMENSION_REGISTRY, DimensionwalkerMod.MODID); |
||||||
|
|
||||||
|
private static final org.slf4j.Logger LOGGER = LogUtils.getLogger(); |
||||||
|
|
||||||
|
public DimensionwalkerItem() { |
||||||
|
super(new Item.Properties().tab(CreativeModeTab.TAB_TOOLS)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public @NotNull InteractionResultHolder<ItemStack> use(Level level, @NotNull Player player, @NotNull InteractionHand hand) |
||||||
|
{ |
||||||
|
if (!level.isClientSide()) |
||||||
|
{ |
||||||
|
MinecraftServer server = level.getServer(); |
||||||
|
if (server != null) |
||||||
|
{ |
||||||
|
Iterable<ServerLevel> allLevels = server.getAllLevels(); |
||||||
|
List<ServerLevel> levels = new java.util.ArrayList<>(StreamSupport.stream(allLevels.spliterator(), false).toList()); |
||||||
|
levels.remove((ServerLevel) level); |
||||||
|
ServerLevel destination = levels.get(new Random().nextInt(levels.size())); |
||||||
|
// server.getPlayerList().getPlayer(player.getUUID()).teleportTo(destination, player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||||
|
ServerPlayer serverPlayer = server.getPlayerList().getPlayer(player.getUUID()); |
||||||
|
if (serverPlayer != null) |
||||||
|
serverPlayer.changeDimension(destination, DimensionwalkerTeleporter.instance()); |
||||||
|
else |
||||||
|
LOGGER.warn("Can't teleport, serverPlayer == null"); |
||||||
|
} |
||||||
|
else |
||||||
|
LOGGER.warn("Can't teleport, server == null"); |
||||||
|
} |
||||||
|
return super.use(level, player, hand); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package moe.nekojimi.dimensionwalker; |
||||||
|
|
||||||
|
import com.mojang.logging.LogUtils; |
||||||
|
import net.minecraft.client.Minecraft; |
||||||
|
import net.minecraft.server.level.ServerLevel; |
||||||
|
import net.minecraft.world.item.Item; |
||||||
|
import net.minecraft.world.level.block.Blocks; |
||||||
|
import net.minecraftforge.common.MinecraftForge; |
||||||
|
import net.minecraftforge.eventbus.api.IEventBus; |
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent; |
||||||
|
import net.minecraftforge.fml.common.Mod; |
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; |
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; |
||||||
|
import net.minecraftforge.event.server.ServerStartingEvent; |
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; |
||||||
|
import net.minecraftforge.registries.DeferredRegister; |
||||||
|
import net.minecraftforge.registries.ForgeRegistries; |
||||||
|
import net.minecraftforge.registries.RegistryObject; |
||||||
|
import org.slf4j.Logger; |
||||||
|
|
||||||
|
// The value here should match an entry in the META-INF/mods.toml file
|
||||||
|
@Mod(DimensionwalkerMod.MODID) |
||||||
|
public class DimensionwalkerMod |
||||||
|
{ |
||||||
|
// Define mod id in a common place for everything to reference
|
||||||
|
public static final String MODID = "examplemod"; |
||||||
|
// Directly reference a slf4j logger
|
||||||
|
private static final Logger LOGGER = LogUtils.getLogger(); |
||||||
|
|
||||||
|
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); |
||||||
|
|
||||||
|
public static final RegistryObject<Item> DIMENSIONWALKER_GLOVE_ITEM = ITEMS.register("dimensionwalker_glove", ()->new DimensionwalkerItem() ); |
||||||
|
|
||||||
|
public DimensionwalkerMod() |
||||||
|
{ |
||||||
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); |
||||||
|
|
||||||
|
// Register the commonSetup method for modloading
|
||||||
|
modEventBus.addListener(this::commonSetup); |
||||||
|
|
||||||
|
// Register the Deferred Register to the mod event bus so items get registered
|
||||||
|
ITEMS.register(modEventBus); |
||||||
|
|
||||||
|
// Register ourselves for server and other game events we are interested in
|
||||||
|
MinecraftForge.EVENT_BUS.register(this); |
||||||
|
} |
||||||
|
|
||||||
|
private void commonSetup(final FMLCommonSetupEvent event) |
||||||
|
{ |
||||||
|
// Some common setup code
|
||||||
|
LOGGER.info("HELLO FROM COMMON SETUP"); |
||||||
|
LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT)); |
||||||
|
} |
||||||
|
|
||||||
|
// You can use SubscribeEvent and let the Event Bus discover methods to call
|
||||||
|
@SubscribeEvent |
||||||
|
public void onServerStarting(ServerStartingEvent event) |
||||||
|
{ |
||||||
|
// Do something when the server starts
|
||||||
|
LOGGER.info("HELLO from server starting"); |
||||||
|
|
||||||
|
Iterable<ServerLevel> levels = event.getServer().getAllLevels(); |
||||||
|
levels.forEach(serverLevel -> |
||||||
|
{ |
||||||
|
LOGGER.info(serverLevel.dimension().toString() + " scale: " + serverLevel.dimensionType().coordinateScale()); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
package moe.nekojimi.dimensionwalker; |
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos; |
||||||
|
import net.minecraft.core.Direction; |
||||||
|
import net.minecraft.server.level.ServerLevel; |
||||||
|
import net.minecraft.world.entity.Entity; |
||||||
|
import net.minecraft.world.level.block.state.BlockState; |
||||||
|
import net.minecraft.world.level.border.WorldBorder; |
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess; |
||||||
|
import net.minecraft.world.level.levelgen.Heightmap; |
||||||
|
import net.minecraft.world.level.portal.PortalInfo; |
||||||
|
import net.minecraft.world.phys.Vec3; |
||||||
|
import net.minecraftforge.common.util.ITeleporter; |
||||||
|
import org.apache.http.io.SessionOutputBuffer; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Comparator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.function.Function; |
||||||
|
|
||||||
|
public class DimensionwalkerTeleporter implements ITeleporter |
||||||
|
{ |
||||||
|
private static DimensionwalkerTeleporter INSTANCE = null; |
||||||
|
|
||||||
|
@Override |
||||||
|
public Entity placeEntity(Entity entity, ServerLevel currentWorld, ServerLevel destWorld, float yaw, Function<Boolean, Entity> repositionEntity) |
||||||
|
{ |
||||||
|
return repositionEntity.apply(true); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public @Nullable PortalInfo getPortalInfo(Entity entity, ServerLevel destWorld, Function<ServerLevel, PortalInfo> defaultPortalInfo) |
||||||
|
{ |
||||||
|
// return ITeleporter.super.getPortalInfo(entity, destWorld, defaultPortalInfo);
|
||||||
|
|
||||||
|
BlockPos startPos = new BlockPos(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()); |
||||||
|
System.out.println("Current player position: " + startPos); |
||||||
|
// ChunkAccess chunk = destWorld.getChunk(startPos);
|
||||||
|
// int maxHeight = startPos.getY();
|
||||||
|
// destWorld.get
|
||||||
|
// for (Heightmap.Types type : Heightmap.Types.values())
|
||||||
|
// {
|
||||||
|
// int height = chunk.getHeight(type,startPos.getX(),startPos.getZ());
|
||||||
|
// System.out.println("Heightmap type: " + type.name() + ", height: " + height);
|
||||||
|
// if (height > maxHeight)
|
||||||
|
// maxHeight = height;
|
||||||
|
// }
|
||||||
|
BlockPos blockPos = findSafePosition(destWorld,startPos); |
||||||
|
if (blockPos == null) |
||||||
|
blockPos = startPos; |
||||||
|
return new PortalInfo(new Vec3((double)blockPos.getX() + 0.5D, (double)blockPos.getY()+1.0D, (double)blockPos.getZ() + 0.5D), entity.getDeltaMovement(), entity.getYRot(), entity.getXRot()); |
||||||
|
} |
||||||
|
|
||||||
|
public @Nullable BlockPos findSafePosition(ServerLevel destWorld, BlockPos startPos) |
||||||
|
{ |
||||||
|
// List<BlockPos> candidates = new ArrayList<>();
|
||||||
|
|
||||||
|
WorldBorder worldborder = destWorld.getWorldBorder(); |
||||||
|
int worldHeight = Math.min(destWorld.getMaxBuildHeight(), destWorld.getMinBuildHeight() + destWorld.getLogicalHeight()) - 1; |
||||||
|
|
||||||
|
outer: |
||||||
|
for (BlockPos.MutableBlockPos pos : BlockPos.spiralAround(startPos, 16, Direction.EAST, Direction.SOUTH)) |
||||||
|
{ |
||||||
|
if (pos == null) |
||||||
|
return null; |
||||||
|
ChunkAccess chunk = destWorld.getChunk(pos); |
||||||
|
int terrainHeight = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES,pos.getX(),pos.getZ()); |
||||||
|
int freeBlocksAbove = 999; |
||||||
|
int startY = Math.min(worldHeight, terrainHeight); |
||||||
|
System.out.println("Starting search for safe destination at Y=" + startY); |
||||||
|
for (int y = startY; y >= destWorld.getMinBuildHeight(); y--) |
||||||
|
{ |
||||||
|
pos.setY(y); |
||||||
|
|
||||||
|
// check that y is solid
|
||||||
|
BlockState blockState = chunk.getBlockState(pos); |
||||||
|
if (blockState.getMaterial().isSolid()) |
||||||
|
{ |
||||||
|
if (worldborder.isWithinBounds(pos) && y < worldHeight-3 && freeBlocksAbove >= 2) |
||||||
|
{ |
||||||
|
System.out.println("Found safe destination! pos: " + pos + " material: " + blockState.getMaterial() + " state: " + blockState); |
||||||
|
return pos; |
||||||
|
// candidates.add(pos);
|
||||||
|
// if (candidates.size() >= 16)
|
||||||
|
// break outer;
|
||||||
|
} |
||||||
|
freeBlocksAbove = 0; |
||||||
|
} |
||||||
|
else if (blockState.getMaterial().isLiquid() || !blockState.isAir()) |
||||||
|
{ |
||||||
|
freeBlocksAbove = 0; // liquid blocks aren't free
|
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
freeBlocksAbove++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// if (candidates.size() > 0)
|
||||||
|
// {
|
||||||
|
// candidates.sort(Comparator.comparingDouble(a -> a.distSqr(startPos)));
|
||||||
|
// return candidates.get(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static ITeleporter instance() |
||||||
|
{ |
||||||
|
if (INSTANCE == null) |
||||||
|
INSTANCE = new DimensionwalkerTeleporter(); |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package moe.nekojimi.dimensionwalker; |
||||||
|
|
||||||
|
public class Peachy |
||||||
|
{ |
||||||
|
Peachy() |
||||||
|
{ |
||||||
|
System.out.println("I'm Peachy!"); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue