Add missing files
This commit is contained in:
parent
a9edc5e564
commit
58c42f04bf
21 changed files with 1233 additions and 0 deletions
|
@ -0,0 +1,49 @@
|
|||
//package org.dimdev.dimdoors.commands;
|
||||
//
|
||||
//import net.minecraft.command.CommandBase;
|
||||
//import net.minecraft.command.CommandException;
|
||||
//import net.minecraft.command.ICommandSender;
|
||||
//import net.minecraft.command.WrongUsageException;
|
||||
//import net.minecraft.entity.player.EntityPlayerMP;
|
||||
//import net.minecraft.server.MinecraftServer;
|
||||
//import net.minecraft.util.math.Vec3i;
|
||||
//import org.dimdev.util.schem.Schematic;
|
||||
//import org.dimdev.dimdoors.pockets.SchematicHandler;
|
||||
//import org.dimdev.pocketlib.Pocket;
|
||||
//import org.dimdev.pocketlib.PocketRegistry;
|
||||
//import org.dimdev.pocketlib.PocketWorldDimension;
|
||||
//
|
||||
//public class CommandSaveSchem extends CommandBase {
|
||||
//
|
||||
// @Override
|
||||
// public String getName() {
|
||||
// return "saveschem";
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getUsage(ICommandSender sender) {
|
||||
// return "commands.saveschem.usage";
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
|
||||
// EntityPlayerMP player = getCommandSenderAsPlayer(sender);
|
||||
//
|
||||
// if (args.length != 1) {
|
||||
// throw new WrongUsageException("commands.saveschem.usage");
|
||||
// }
|
||||
//
|
||||
// if (!(player.world.dimension instanceof PocketWorldDimension))
|
||||
// throw new CommandException("commands.generic.dimdoors.not_in_pocket");
|
||||
// Pocket pocket = PocketRegistry.instance(player.dimension).getPocketAt(player.getPosition());
|
||||
// if (pocket == null) throw new CommandException("commands.generic.dimdoors.not_in_pocket");
|
||||
//
|
||||
// int size = (pocket.getSize() + 1) * 16 - 1;
|
||||
// Schematic schematic = Schematic.createFromWorld(player.world, pocket.getOrigin(), pocket.getOrigin().add(new Vec3i(size, size, size)));
|
||||
// schematic.name = args[0];
|
||||
// schematic.author = player.getName();
|
||||
//
|
||||
// SchematicHandler.INSTANCE.saveSchematicForEditing(schematic, args[0]);
|
||||
// notifyCommandListener(sender, this, "commands.saveschem.success", args[0]);
|
||||
// }
|
||||
//}
|
129
src/main/java/org/dimdev/dimdoors/item/RiftSignatureItem.java
Normal file
129
src/main/java/org/dimdev/dimdoors/item/RiftSignatureItem.java
Normal file
|
@ -0,0 +1,129 @@
|
|||
package org.dimdev.dimdoors.item;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.rift.targets.RiftReference;
|
||||
import org.dimdev.dimdoors.sound.ModSoundEvents;
|
||||
import org.dimdev.dimdoors.tileentities.DetachedRiftBlockEntity;
|
||||
import org.dimdev.util.Location;
|
||||
import org.dimdev.util.RotatedLocation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RiftSignatureItem extends Item {
|
||||
public static final String ID = "rift_signature";
|
||||
|
||||
public RiftSignatureItem(Settings settings) {
|
||||
setMaxStackSize(1);
|
||||
setMaxDamage(1);
|
||||
setCreativeTab(ModItemGroups.DIMENSIONAL_DOORS);
|
||||
setTranslationKey(ID);
|
||||
setRegistryName(new Identifier("dimdoors", ID));
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Override
|
||||
public boolean hasEffect(ItemStack stack) {
|
||||
return stack.getTagCompound() != null && stack.getTagCompound().hasKey("destination");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onItemUse(PlayerEntity player, World world, BlockPos pos, Hand hand, Direction side, float hitX, float hitY, float hitZ) {
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
pos = world.getBlockState(pos).getBlock().isReplaceable(world, pos) ? pos : pos.offset(side);
|
||||
|
||||
// Fail if the player can't place a block there
|
||||
if (!player.canPlayerEdit(pos, side.getOpposite(), stack)) {
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
|
||||
if (world.isClient) {
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
RotatedLocation target = getSource(stack);
|
||||
|
||||
if (target == null) {
|
||||
// The link signature has not been used. Store its current target as the first location.
|
||||
setSource(stack, new RotatedLocation(world, pos, player.rotationYaw, 0));
|
||||
player.sendStatusMessage(new TextComponentTranslation(getRegistryName() + ".stored"), true);
|
||||
world.playSound(null, player.getPosition(), ModSoundEvents.RIFT_START, SoundCategory.BLOCKS, 0.6f, 1);
|
||||
} else {
|
||||
// Place a rift at the saved point
|
||||
if (target.getBlockState().getBlock() != ModBlocks.DETACHED_RIFT) {
|
||||
if (!target.getBlockState().getBlock().isReplaceable(world, ((Location) target).getPos())) {
|
||||
DimDoors.sendTranslatedMessage(player, "tools.target_became_block");
|
||||
clearSource(stack); // TODO: But is this fair? It's a rather hidden way of unbinding your signature!
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
World sourceWorld = ((Location) target).getWorld();
|
||||
sourceWorld.setBlockState(((Location) target).getPos(), ModBlocks.DETACHED_RIFT.getDefaultState());
|
||||
DetachedRiftBlockEntity rift1 = (DetachedRiftBlockEntity) target.getBlockEntity();
|
||||
rift1.setDestination(RiftReference.tryMakeRelative(target, new Location(world, pos)));
|
||||
rift1.setTeleportTargetRotation(target.yaw, 0); // setting pitch to 0 because player is always facing down to place rift
|
||||
rift1.register();
|
||||
}
|
||||
|
||||
// Place a rift at the target point
|
||||
world.setBlockState(pos, ModBlocks.DETACHED_RIFT.getDefaultState());
|
||||
DetachedRiftBlockEntity rift2 = (DetachedRiftBlockEntity) world.getBlockEntity(pos);
|
||||
rift2.setDestination(RiftReference.tryMakeRelative(new Location(world, pos), target));
|
||||
rift2.setTeleportTargetRotation(player.rotationYaw, 0);
|
||||
rift2.register();
|
||||
|
||||
stack.damageItem(1, player); // TODO: calculate damage based on position?
|
||||
|
||||
clearSource(stack);
|
||||
player.sendStatusMessage(new TextComponentTranslation(getRegistryName() + ".created"), true);
|
||||
// null = send sound to the player too, we have to do this because this code is not run client-side
|
||||
world.playSound(null, player.getPosition(), ModSoundEvents.RIFT_END, SoundCategory.BLOCKS, 0.6f, 1);
|
||||
}
|
||||
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public static void setSource(ItemStack itemStack, RotatedLocation destination) {
|
||||
if (!itemStack.hasTagCompound()) itemStack.setTagCompound(new CompoundTag());
|
||||
itemStack.getTagCompound().put("destination", destination.serialize());
|
||||
}
|
||||
|
||||
public static void clearSource(ItemStack itemStack) {
|
||||
if (itemStack.hasTagCompound()) {
|
||||
itemStack.getTagCompound().removeTag("destination");
|
||||
}
|
||||
}
|
||||
|
||||
public static RotatedLocation getSource(ItemStack itemStack) {
|
||||
if (itemStack.hasTagCompound() && itemStack.getTagCompound().hasKey("destination")) {
|
||||
RotatedLocation transform = RotatedLocation.deserialize(itemStack.getTagCompound().getCompoundTag("destination"));
|
||||
return transform;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void addInformation(ItemStack stack, World world, List<String> tooltip, ITooltipFlag flag) {
|
||||
RotatedLocation transform = getSource(stack);
|
||||
if (transform != null) {
|
||||
tooltip.add(I18n.format(I18n.format(getRegistryName() + ".bound.info", transform.getX(), transform.getY(), transform.getZ(), ((Location) transform).dim)));
|
||||
} else {
|
||||
tooltip.add(I18n.format(getRegistryName() + ".unbound.info"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.dimdev.dimdoors.item;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.ArmorMaterial;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
|
||||
public class WorldThreadArmorItem extends ArmorItem {
|
||||
public static final ArmorMaterial WOVEN_WORLD_THREAD = EnumHelper.addArmorMaterial(
|
||||
"woven_world_thread",
|
||||
"dimdoors:woven_world_thread",
|
||||
20,
|
||||
new int[]{2, 3, 4, 5},
|
||||
20,
|
||||
SoundEvents.ITEM_ARMOR_EQUIP_GENERIC,
|
||||
1.0f)
|
||||
.setRepairItem(new ItemStack(ModItems.WORLD_THREAD));
|
||||
|
||||
public WorldThreadArmorItem(String name, int renderIndex, EquipmentSlot equipmentSlot) {
|
||||
super(WOVEN_WORLD_THREAD, renderIndex, equipmentSlot);
|
||||
setRegistryName("dimdoors", name);
|
||||
setTranslationKey(name);
|
||||
setCreativeTab(ModItemGroups.DIMENSIONAL_DOORS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package org.dimdev.dimdoors.rift.registry;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
|
||||
public class RiftPlaceholder extends Rift { // TODO: don't extend rift
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public void sourceGone(RegistryVertex source) {}
|
||||
|
||||
@Override
|
||||
public void targetGone(RegistryVertex target) {}
|
||||
|
||||
@Override
|
||||
public void sourceAdded(RegistryVertex source) {}
|
||||
|
||||
@Override
|
||||
public void targetAdded(RegistryVertex target) {}
|
||||
|
||||
@Override
|
||||
public void targetChanged(RegistryVertex target) {}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
RiftRegistry.instance().markSubregistryDirty(dim);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
LOGGER.error("Reading a rift placeholder from NBT!");
|
||||
super.fromTag(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag nbt) {
|
||||
LOGGER.error("Writing a rift placeholder from NBT!");
|
||||
return super.toTag(nbt);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import org.dimdev.util.InstanceMap;
|
||||
|
||||
public final class DefaultTargets {
|
||||
private static final InstanceMap DEFAULT_TARGETS = new InstanceMap();
|
||||
|
||||
public static <T extends Target> T getDefaultTarget(Class<T> type) {
|
||||
if (DEFAULT_TARGETS.containsKey(type)) {
|
||||
return DEFAULT_TARGETS.get(type);
|
||||
} else {
|
||||
throw new RuntimeException("No default target for " + type.getName() + " registered");
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends Target, U extends T> void registerDefaultTarget(Class<T> type, U impl) {
|
||||
DEFAULT_TARGETS.put(type, impl);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
public interface FluidTarget extends Target {
|
||||
boolean addFluidFlow(Direction relativeFacing, Fluid fluid, int level);
|
||||
|
||||
void subtractFluidFlow(Direction relativeFacing, Fluid fluid, int level);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.util.Location;
|
||||
import org.dimdev.annotatednbt.AnnotatedNbt;
|
||||
|
||||
public class LocalReference extends RiftReference {
|
||||
@Saved protected BlockPos target;
|
||||
|
||||
public LocalReference(BlockPos target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
super.fromTag(nbt);
|
||||
AnnotatedNbt.load(this, nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag nbt) {
|
||||
nbt = super.toTag(nbt);
|
||||
return AnnotatedNbt.serialize(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getReferencedLocation() {
|
||||
return new Location(location.world, target);
|
||||
}
|
||||
|
||||
public BlockPos getTarget() {return target;}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
@SuppressWarnings("OverloadedVarargsMethod")
|
||||
public class MessageTarget implements EntityTarget {
|
||||
private Target forwardTo;
|
||||
private String message;
|
||||
private Object[] messageParams;
|
||||
|
||||
public MessageTarget(Target forwardTo, String message, Object... messageParams) {
|
||||
this.forwardTo = forwardTo;
|
||||
this.message = message;
|
||||
this.messageParams = messageParams;
|
||||
}
|
||||
|
||||
public MessageTarget(String message, Object... messageParams) {
|
||||
this.message = message;
|
||||
this.messageParams = messageParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean receiveEntity(Entity entity, float relativeYaw, float relativePitch) {
|
||||
entity.sendMessage(new TranslatableText(message, messageParams));
|
||||
|
||||
if (forwardTo != null) {
|
||||
forwardTo.as(Targets.ENTITY).receiveEntity(entity, relativeYaw, relativePitch);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
public class PocketExitMarker extends VirtualTarget implements EntityTarget {
|
||||
public PocketExitMarker() {}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
super.fromTag(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag nbt) {
|
||||
nbt = super.toTag(nbt);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean receiveEntity(Entity entity, float relativeYaw, float relativePitch) {
|
||||
entity.sendMessage(new TranslatableText("The exit of this dungeon has not been linked. If this is a normally generated pocket, please report this bug."));
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.item.DyeItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.pockets.PocketGenerator;
|
||||
import org.dimdev.dimdoors.rift.registry.RiftRegistry;
|
||||
import org.dimdev.pocketlib.Pocket;
|
||||
import org.dimdev.pocketlib.PrivatePocketData;
|
||||
import org.dimdev.pocketlib.VirtualLocation;
|
||||
import org.dimdev.util.EntityUtils;
|
||||
import org.dimdev.util.Location;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PrivatePocketTarget extends VirtualTarget implements EntityTarget {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public PrivatePocketTarget() {}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) { super.fromTag(nbt); }
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag nbt) {
|
||||
nbt = super.toTag(nbt);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean receiveEntity(Entity entity, float relativeYaw, float relativePitch) {
|
||||
// TODO: make this recursive
|
||||
UUID uuid = EntityUtils.getOwner(entity).getUuid();
|
||||
VirtualLocation virtualLocation = VirtualLocation.fromLocation(location);
|
||||
if (uuid != null) {
|
||||
Pocket pocket = PrivatePocketData.instance().getPrivatePocket(uuid);
|
||||
if (pocket == null) { // generate the private pocket and get its entrances
|
||||
// set to where the pocket was first created
|
||||
pocket = PocketGenerator.generatePrivatePocket(virtualLocation != null ?
|
||||
new VirtualLocation(virtualLocation.world, virtualLocation.x, virtualLocation.z, -1) :
|
||||
null
|
||||
);
|
||||
|
||||
PrivatePocketData.instance().setPrivatePocketID(uuid, pocket);
|
||||
processEntity(pocket, RiftRegistry.instance().getPocketEntrance(pocket).getBlockEntity(), entity, uuid, relativeYaw, relativePitch);
|
||||
return true;
|
||||
} else {
|
||||
Location destLoc = RiftRegistry.instance().getPrivatePocketEntrance(uuid); // get the last used entrances
|
||||
if (destLoc == null) destLoc = RiftRegistry.instance().getPocketEntrance(pocket); // if there's none, then set the target to the main entrances
|
||||
if (destLoc == null) { // if the pocket entrances is gone, then create a new private pocket
|
||||
LOGGER.info("All entrances are gone, creating a new private pocket!");
|
||||
pocket = PocketGenerator.generatePrivatePocket(virtualLocation != null ?
|
||||
new VirtualLocation(virtualLocation.world, virtualLocation.x, virtualLocation.z, -1) :
|
||||
null
|
||||
);
|
||||
|
||||
PrivatePocketData.instance().setPrivatePocketID(uuid, pocket);
|
||||
destLoc = RiftRegistry.instance().getPocketEntrance(pocket);
|
||||
}
|
||||
|
||||
processEntity(pocket, destLoc.getBlockEntity(), entity, uuid, relativePitch, relativePitch);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void processEntity(Pocket pocket, BlockEntity BlockEntity, Entity entity, UUID uuid, float relativeYaw, float relativePitch) {
|
||||
if (entity instanceof ItemEntity) {
|
||||
Item item = ((ItemEntity) entity).getStack().getItem();
|
||||
|
||||
if (item instanceof DyeItem) {
|
||||
pocket.addDye(EntityUtils.getOwner(entity), ((DyeItem) item).getColor());
|
||||
entity.remove();
|
||||
} else {
|
||||
((EntityTarget) BlockEntity).receiveEntity(entity, relativeYaw, relativePitch);
|
||||
}
|
||||
} else {
|
||||
((EntityTarget) BlockEntity).receiveEntity(entity, relativeYaw, relativePitch);
|
||||
RiftRegistry.instance().setLastPrivatePocketExit(uuid, location);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getColor() {
|
||||
return new float[]{0, 1, 0, 1};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import org.dimdev.annotatednbt.AnnotatedNbt;
|
||||
import org.dimdev.annotatednbt.Saved;
|
||||
import org.dimdev.util.Location;
|
||||
|
||||
public class RelativeReference extends RiftReference {
|
||||
@Saved protected Vec3i offset;
|
||||
|
||||
public RelativeReference() {}
|
||||
|
||||
public RelativeReference(Vec3i offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
super.fromTag(nbt);
|
||||
AnnotatedNbt.load(this, nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag = super.toTag(tag);
|
||||
AnnotatedNbt.save(this, tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getReferencedLocation() {
|
||||
return new Location(location.world, location.pos.add(offset));
|
||||
}
|
||||
|
||||
public Vec3i getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
45
src/main/java/org/dimdev/dimdoors/rift/targets/Targets.java
Normal file
45
src/main/java/org/dimdev/dimdoors/rift/targets/Targets.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
// A list of the default targets provided by dimcore. Add your own in ModTargets
|
||||
public final class Targets {
|
||||
public static final Class<EntityTarget> ENTITY = EntityTarget.class;
|
||||
public static final Class<ItemTarget> ITEM = ItemTarget.class;
|
||||
public static final Class<FluidTarget> FLUID = FluidTarget.class;
|
||||
public static final Class<RedstoneTarget> REDSTONE = RedstoneTarget.class;
|
||||
|
||||
public static void registerDefaultTargets() {
|
||||
DefaultTargets.registerDefaultTarget(ENTITY, (entity, relativeYaw, relativePitch) -> {
|
||||
entity.sendMessage(new TranslatableText("rifts.unlinked"));
|
||||
return false;
|
||||
});
|
||||
DefaultTargets.registerDefaultTarget(ITEM, stack -> false);
|
||||
|
||||
DefaultTargets.registerDefaultTarget(FLUID, new FluidTarget() {
|
||||
@Override
|
||||
public boolean addFluidFlow(Direction relativeFacing, Fluid fluid, int level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subtractFluidFlow(Direction relativeFacing, Fluid fluid, int level) {
|
||||
throw new RuntimeException("Subtracted fluid flow that was never accepted");
|
||||
}
|
||||
});
|
||||
|
||||
DefaultTargets.registerDefaultTarget(REDSTONE, new RedstoneTarget() {
|
||||
@Override
|
||||
public boolean addRedstonePower(Direction relativeFacing, int strength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subtractRedstonePower(Direction relativeFacing, int strength) {
|
||||
throw new RuntimeException("Subtracted redstone that was never accepted");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package org.dimdev.dimdoors.rift.targets;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.dimdev.util.Location;
|
||||
|
||||
/**
|
||||
* A target that is not an actual object in the game such as a block or a tile
|
||||
* entity. Only virtual targets can be saved to NBT.
|
||||
*/
|
||||
public abstract class VirtualTarget implements Target {
|
||||
|
||||
public static final BiMap<String, Class<? extends VirtualTarget>> registry = HashBiMap.create();
|
||||
protected Location location;
|
||||
|
||||
public static VirtualTarget readVirtualTargetNBT(CompoundTag nbt) {
|
||||
String type = nbt.getString("type");
|
||||
Class<? extends VirtualTarget> destinationClass = registry.get(type);
|
||||
if (destinationClass == null) throw new RuntimeException("Unknown type '" + type + "'.");
|
||||
try {
|
||||
VirtualTarget destination = destinationClass.newInstance();
|
||||
destination.fromTag(nbt);
|
||||
return destination;
|
||||
} catch (IllegalAccessException | InstantiationException e) {
|
||||
throw new RuntimeException("The class registered for virtual target " + type + " must have a public no-args constructor and must not be abstract", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void fromTag(CompoundTag nbt) {}
|
||||
|
||||
public CompoundTag toTag(CompoundTag nbt) {
|
||||
String type = registry.inverse().get(getClass());
|
||||
if (type == null) throw new RuntimeException("No type has been registered for class" + getClass().getName());
|
||||
nbt.putString("type", type);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public void register() {}
|
||||
|
||||
public void unregister() {}
|
||||
|
||||
public boolean shouldInvalidate(Location riftDeleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public float[] getColor() {
|
||||
return new float[]{1, 0, 0, 1};
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof VirtualTarget &&
|
||||
((VirtualTarget) o).canEqual(this) &&
|
||||
(location == null ? ((VirtualTarget) o).location == null : ((Object) location).equals(((VirtualTarget) o).location));
|
||||
}
|
||||
|
||||
protected boolean canEqual(Object other) {return other instanceof VirtualTarget;}
|
||||
|
||||
public int hashCode() {
|
||||
return 59 + (location == null ? 43 : location.hashCode());
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {this.location = location; }
|
||||
}
|
224
src/main/java/org/dimdev/dimdoors/tools/SchematicGenerator.java
Normal file
224
src/main/java/org/dimdev/dimdoors/tools/SchematicGenerator.java
Normal file
|
@ -0,0 +1,224 @@
|
|||
//package org.dimdev.dimdoors.tools;
|
||||
//
|
||||
//import net.minecraft.block.DoorBlock;
|
||||
//import net.minecraft.block.state.BlockState;
|
||||
//import net.minecraft.item.DyeColor;
|
||||
//import net.minecraft.nbt.CompressedStreamTools;
|
||||
//import net.minecraft.nbt.CompoundTag;
|
||||
//import org.dimdev.util.schem.Schematic;
|
||||
//import org.dimdev.dimdoors.block.DimensionalDoorBlock;
|
||||
//import org.dimdev.dimdoors.block.FabricBlock;
|
||||
//import org.dimdev.dimdoors.block.AncientFabricBlock;
|
||||
//import org.dimdev.dimdoors.block.ModBlocks;
|
||||
//import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
//import org.dimdev.dimdoors.rift.targets.PocketEntranceMarker;
|
||||
//import org.dimdev.dimdoors.rift.targets.PocketExitMarker;
|
||||
//import org.dimdev.dimdoors.rift.targets.PrivatePocketExitTarget;
|
||||
//import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
//import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity;
|
||||
//
|
||||
//import java.io.DataOutputStream;
|
||||
//import java.io.File;
|
||||
//import java.io.FileOutputStream;
|
||||
//import java.io.IOException;
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.Arrays;
|
||||
//import java.util.Collections;
|
||||
//import java.util.List;
|
||||
//
|
||||
//public final class SchematicGenerator {
|
||||
//
|
||||
// // Run "gradlew generatePocketSchematics" to generate the pocket schematics
|
||||
// @SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
// public static void main(String... args) throws IOException {
|
||||
//
|
||||
// // Parse arguments
|
||||
// File schematicDir;
|
||||
// if (args.length > 1) {
|
||||
// System.err.println("Too many arguments!");
|
||||
// return;
|
||||
// } else if (args.length == 1) {
|
||||
// schematicDir = new File(args[0]);
|
||||
// if (!schematicDir.isDirectory()) {
|
||||
// System.err.print("The directory " + args[0] + " couldn't be found!");
|
||||
// return;
|
||||
// }
|
||||
// } else {
|
||||
// schematicDir = new File("schematics/");
|
||||
// }
|
||||
//
|
||||
// // Register blocks and tile entities to be able to run this without starting Minecraft
|
||||
// Initializer.initialize();
|
||||
//
|
||||
// // Generate the schematics
|
||||
// List<Schematic> schematics = generatePocketSchematics();
|
||||
//
|
||||
// // Save the schematics
|
||||
// String[] saveFolders = {"public/", "private/", "blank/", "blank/", "blank/"};
|
||||
// int i = 0;
|
||||
// for (Schematic schematic : schematics) {
|
||||
// CompoundTag schematicNBT = schematic.saveToNBT();
|
||||
// File saveFile = new File(schematicDir, saveFolders[i++ % saveFolders.length] + schematic.name + ".schem");
|
||||
// saveFile.getParentFile().mkdirs();
|
||||
// DataOutputStream schematicDataStream = new DataOutputStream(new FileOutputStream(saveFile));
|
||||
// CompressedStreamTools.writeCompressed(schematicNBT, schematicDataStream);
|
||||
// schematicDataStream.flush();
|
||||
// schematicDataStream.close();
|
||||
// }
|
||||
// // TODO: also generate JSON files
|
||||
// }
|
||||
//
|
||||
// public static List<Schematic> generatePocketSchematics() {
|
||||
// List<Schematic> schematics = new ArrayList<>();
|
||||
// for (int pocketSize = 0; pocketSize < 8; pocketSize++) { // Changing to 8 to 16 would cause out of memory (256^3*4 bytes = 64MB/schematic)
|
||||
// schematics.add(generateBlankWithDoor(
|
||||
// "public_pocket", // base name
|
||||
// pocketSize, // size
|
||||
// ModBlocks.ANCIENT_FABRIC.getDefaultState(), // outer wall
|
||||
// ModBlocks.BLACK_FABRIC.getDefaultState(), // inner wall
|
||||
// ModBlocks.IRON_DIMENSIONAL_DOOR, // door
|
||||
// PocketExitMarker.builder().build(),// exit rift destination
|
||||
// LinkProperties.builder()
|
||||
// .groups(Collections.singleton(1))
|
||||
// .linksRemaining(1)
|
||||
// .entranceWeight(1)
|
||||
// .floatingWeight(1)
|
||||
// .build()));
|
||||
//
|
||||
// schematics.add(generateBlankWithDoor(
|
||||
// "private_pocket", // base name
|
||||
// pocketSize, // size
|
||||
// ModBlocks.ANCIENT_FABRIC.getDefaultState().withProperty(AncientFabricBlock.COLOR, DyeColor.WHITE), // outer wall
|
||||
// ModBlocks.BLACK_FABRIC.getDefaultState().withProperty(AncientFabricBlock.COLOR, DyeColor.WHITE), // inner wall
|
||||
// ModBlocks.QUARTZ_DIMENSIONAL_DOOR, // door
|
||||
// PrivatePocketExitTarget.builder().build(),// exit rift destination
|
||||
// null));
|
||||
//
|
||||
// schematics.add(generateBlank(
|
||||
// "blank_pocket",
|
||||
// pocketSize,
|
||||
// ModBlocks.ANCIENT_FABRIC.getDefaultState(),
|
||||
// ModBlocks.BLACK_FABRIC.getDefaultState()));
|
||||
//
|
||||
// schematics.add(generateFrame(
|
||||
// "void_pocket",
|
||||
// pocketSize,
|
||||
// ModBlocks.BLACK_FABRIC.getDefaultState().withProperty(FabricBlock.COLOR, DyeColor.LIGHT_BLUE)));
|
||||
//
|
||||
// schematics.add(generateResizableFrame(
|
||||
// "resizable_pocket",
|
||||
// pocketSize,
|
||||
// ModBlocks.BLACK_FABRIC.getDefaultState().withProperty(FabricBlock.COLOR, DyeColor.ORANGE)));
|
||||
// }
|
||||
// return schematics;
|
||||
// }
|
||||
//
|
||||
// private static Schematic generateBlank(String baseName, int pocketSize, BlockState outerWall, BlockState innerWall) {
|
||||
// short size = (short) ((pocketSize + 1) * 16 - 1); // -1 so that the door can be centered
|
||||
//
|
||||
// // Set schematic info
|
||||
// Schematic schematic = new Schematic(baseName + "_" + pocketSize, "DimDoors", size, size, size);
|
||||
// schematic.requiredMods = new String[]{"dimdoors"};
|
||||
//
|
||||
// // Set block data
|
||||
// for (int x = 0; x < size; x++) {
|
||||
// for (int y = 0; y < size; y++) {
|
||||
// for (int z = 0; z < size; z++) {
|
||||
// int layer = Collections.min(Arrays.asList(x, y, z, size - 1 - x, size - 1 - y, size - 1 - z));
|
||||
// if (layer == 0) {
|
||||
// schematic.setBlockState(x, y, z, outerWall);
|
||||
// } else if (layer < 5) {
|
||||
// schematic.setBlockState(x, y, z, innerWall);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return schematic;
|
||||
// }
|
||||
//
|
||||
// private static Schematic generateBlankWithDoor(String baseName, int pocketSize, BlockState outerWall, BlockState innerWall, DimensionalDoorBlock doorBlock, VirtualTarget exitDest, LinkProperties link) {
|
||||
// short size = (short) ((pocketSize + 1) * 16 - 1); // -1 so that the door can be centered
|
||||
//
|
||||
// // Make the schematic
|
||||
// Schematic schematic = generateBlank(baseName, pocketSize, outerWall, innerWall);
|
||||
//
|
||||
// // Add the door
|
||||
// schematic.setBlockState((size - 1) / 2, 5, 4, doorBlock.getDefaultState().withProperty(DoorBlock.HALF, DoorBlock.EnumDoorHalf.LOWER));
|
||||
// schematic.setBlockState((size - 1) / 2, 6, 4, doorBlock.getDefaultState().withProperty(DoorBlock.HALF, DoorBlock.EnumDoorHalf.UPPER));
|
||||
//
|
||||
// // Set the rift entities
|
||||
// schematic.tileEntities = new ArrayList<>();
|
||||
// EntranceRiftBlockEntity rift = (EntranceRiftBlockEntity) doorBlock.createTileEntity(null, doorBlock.getDefaultState());
|
||||
// rift.setDestination(PocketEntranceMarker.builder()
|
||||
// .ifDestination(exitDest)
|
||||
// .build());
|
||||
// rift.setProperties(link);
|
||||
//
|
||||
// rift.setLeaveRiftOnBreak(true);
|
||||
// CompoundTag tileNBT = rift.serializeNBT();
|
||||
// tileNBT.setInteger("x", (size - 1) / 2);
|
||||
// tileNBT.setInteger("y", 5);
|
||||
// tileNBT.setInteger("z", 4);
|
||||
// schematic.tileEntities.add(tileNBT);
|
||||
//
|
||||
// return schematic;
|
||||
// }
|
||||
//
|
||||
// private static Schematic generateFrame(String baseName, int chunkSize, BlockState frame) {
|
||||
// short size = (short) ((chunkSize + 1) * 16 - 1); // -1 so that the door can be centered
|
||||
//
|
||||
// // Set schematic info
|
||||
// Schematic schematic = new Schematic(baseName + "_" + chunkSize, "DimDoors", size, size, size);
|
||||
// schematic.requiredMods = new String[]{"dimdoors"};
|
||||
//
|
||||
// // Set block data
|
||||
// for (int x = 0; x < size; x++) {
|
||||
// for (int y = 0; y < size; y++) {
|
||||
// for (int z = 0; z < size; z++) {
|
||||
// int sides = 0;
|
||||
// if (x == 0 || x == size - 1) sides++;
|
||||
// if (y == 0 || y == size - 1) sides++;
|
||||
// if (z == 0 || z == size - 1) sides++;
|
||||
//
|
||||
// if (sides >= 2) {
|
||||
// schematic.setBlockState(x, y, z, frame);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return schematic;
|
||||
// }
|
||||
//
|
||||
// private static Schematic generateResizableFrame(String baseName, int chunkSize, BlockState frame) {
|
||||
// short size = (short) ((chunkSize + 1) * 16);
|
||||
//
|
||||
// // Set schematic info
|
||||
// Schematic schematic = new Schematic(baseName + "_" + chunkSize, "DimDoors", size, size, size);
|
||||
// schematic.requiredMods = new String[]{"dimdoors"};
|
||||
//
|
||||
// // Set block data
|
||||
// for (int x = 0; x < size; x++) {
|
||||
// for (int y = 0; y < size; y++) {
|
||||
// for (int z = 0; z < size; z++) {
|
||||
// int sides = 0;
|
||||
// if (x % 16 == 0) sides++;
|
||||
// if (y % 16 == 0) sides++;
|
||||
// if (z % 16 == 0) sides++;
|
||||
// int cubeSides = 3;
|
||||
// int cubeSize = Math.max(x, Math.max(y, z));
|
||||
// if (cubeSize - x != 0) cubeSides--;
|
||||
// if (cubeSize - y != 0) cubeSides--;
|
||||
// if (cubeSize - z != 0) cubeSides--;
|
||||
//
|
||||
// if (sides >= 2 && cubeSides >= 2) {
|
||||
// schematic.setBlockState(x, y, z, frame);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return schematic;
|
||||
// }
|
||||
//}
|
34
src/main/java/org/dimdev/dimdoors/world/ModBiomes.java
Normal file
34
src/main/java/org/dimdev/dimdoors/world/ModBiomes.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package org.dimdev.dimdoors.world;
|
||||
|
||||
import org.dimdev.dimdoors.world.limbo.BiomeLimbo;
|
||||
import org.dimdev.dimdoors.world.pocketdimension.BlankBiome;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.common.BiomeDictionary;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
public final class ModBiomes {
|
||||
|
||||
public static final BiomeLimbo LIMBO = new BiomeLimbo();
|
||||
public static final BlankBiome WHITE_VOID = new BlankBiome(true, false);
|
||||
public static final BlankBiome BLACK_VOID = new BlankBiome(false, false);
|
||||
public static final BlankBiome DANGEROUS_BLACK_VOID = new BlankBiome(false, true);
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerBiomes(RegistryEvent.Register<Biome> event) {
|
||||
LIMBO.setRegistryName(new Identifier("dimdoors", "limbo"));
|
||||
WHITE_VOID.setRegistryName(new Identifier("dimdoors", "white_void"));
|
||||
BLACK_VOID.setRegistryName(new Identifier("dimdoors", "black_void"));
|
||||
DANGEROUS_BLACK_VOID.setRegistryName(new Identifier("dimdoors", "dangerous_black_void"));
|
||||
event.getRegistry().registerAll(
|
||||
LIMBO,
|
||||
WHITE_VOID,
|
||||
BLACK_VOID,
|
||||
DANGEROUS_BLACK_VOID);
|
||||
BiomeDictionary.addTypes(LIMBO, BiomeDictionary.Type.VOID);
|
||||
BiomeDictionary.addTypes(WHITE_VOID, BiomeDictionary.Type.VOID);
|
||||
BiomeDictionary.addTypes(BLACK_VOID, BiomeDictionary.Type.VOID);
|
||||
BiomeDictionary.addTypes(DANGEROUS_BLACK_VOID, BiomeDictionary.Type.VOID);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package org.dimdev.dimdoors.world.gateways;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimDoors;
|
||||
import org.dimdev.dimdoors.pockets.PocketTemplate;
|
||||
import org.dimdev.util.schem.Schematic;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public abstract class BaseSchematicGateway extends BaseGateway {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private Schematic schematic;
|
||||
|
||||
public BaseSchematicGateway(String id) {
|
||||
String schematicJarDirectory = "/assets/dimdoors/gateways/";
|
||||
|
||||
//Initialising the possible locations/formats for the schematic file
|
||||
InputStream schematicStream = DimDoors.class.getResourceAsStream(schematicJarDirectory + id + ".schem");
|
||||
|
||||
//determine which location to load the schematic file from (and what format)
|
||||
DataInputStream schematicDataStream = null;
|
||||
boolean streamOpened = false;
|
||||
if (schematicStream != null) {
|
||||
schematicDataStream = new DataInputStream(schematicStream);
|
||||
streamOpened = true;
|
||||
} else {
|
||||
LOGGER.warn("Schematic '" + id + "' was not found in the jar or config directory, neither with the .schem extension, nor with the .schematic extension.");
|
||||
}
|
||||
|
||||
CompoundTag schematicNBT;
|
||||
schematic = null;
|
||||
if (streamOpened) {
|
||||
try {
|
||||
schematicNBT = NbtIo.readCompressed(schematicDataStream);
|
||||
schematic = Schematic.loadFromNBT(schematicNBT);
|
||||
PocketTemplate.replacePlaceholders(schematic);
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Schematic file for " + id + " could not be read as a valid schematic NBT file.", ex);
|
||||
} finally {
|
||||
try {
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Error occured while closing schematicDataStream", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(World world, int x, int y, int z) {
|
||||
schematic.place(world, x, y, z);
|
||||
generateRandomBits(world, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates randomized portions of the gateway structure (e.g. rubble, foliage)
|
||||
*
|
||||
* @param world - the world in which to generate the gateway
|
||||
* @param x - the x-coordinate at which to center the gateway; usually where the door is placed
|
||||
* @param y - the y-coordinate of the block on which the gateway may be built
|
||||
* @param z - the z-coordinate at which to center the gateway; usually where the door is placed
|
||||
*/
|
||||
protected void generateRandomBits(World world, int x, int y, int z) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.dimdev.dimdoors.world.gateways;
|
||||
|
||||
import net.minecraft.block.BlockStoneBrick;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class GatewayTwoPillars extends BaseSchematicGateway {
|
||||
private static final int GATEWAY_RADIUS = 4;
|
||||
|
||||
public GatewayTwoPillars() {
|
||||
super("two_pillars");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateRandomBits(World world, int x, int y, int z) {
|
||||
//Replace some of the ground around the gateway with bricks
|
||||
for (int xc = -GATEWAY_RADIUS; xc <= GATEWAY_RADIUS; xc++) {
|
||||
for (int zc = -GATEWAY_RADIUS; zc <= GATEWAY_RADIUS; zc++) {
|
||||
//Check that the block is supported by an opaque block.
|
||||
//This prevents us from building over a cliff, on the peak of a mountain,
|
||||
//or the surface of the ocean or a frozen lake.
|
||||
if (world.getBlockState(new BlockPos(x + xc, y - 1, z + zc)).getMaterial().isSolid()) {
|
||||
//Randomly choose whether to place bricks or not. The math is designed so that the
|
||||
//chances of placing a block decrease as we get farther from the gateway's center.
|
||||
if (Math.abs(xc) + Math.abs(zc) < world.rand.nextInt(2) + 3) {
|
||||
//Place Stone Bricks
|
||||
world.setBlockState(new BlockPos(x + xc, y, z + zc), Blocks.STONEBRICK.getDefaultState());
|
||||
} else if (Math.abs(xc) + Math.abs(zc) < world.rand.nextInt(3) + 3) {
|
||||
//Place Cracked Stone Bricks
|
||||
world.setBlockState(new BlockPos(x + xc, y, z + zc), Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CRACKED));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.dimdev.dimdoors.world.gateways;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.item.DimensionalDoorItem;
|
||||
import org.dimdev.dimdoors.world.limbo.LimboDimension;
|
||||
|
||||
public class LimboGateway extends BaseGateway {
|
||||
@Override
|
||||
public void generate(World world, int x, int y, int z) {
|
||||
BlockState unravelledFabric = ModBlocks.UNRAVELLED_FABRIC.getDefaultState();
|
||||
// Build the gateway out of Unraveled Fabric. Since nearly all the blocks in Limbo are of
|
||||
// that type, there is no point replacing the ground.
|
||||
world.setBlockState(new BlockPos(x, y + 3, z + 1), unravelledFabric);
|
||||
world.setBlockState(new BlockPos(x, y + 3, z - 1), unravelledFabric);
|
||||
|
||||
// Build the columns around the door
|
||||
world.setBlockState(new BlockPos(x, y + 2, z - 1), unravelledFabric);
|
||||
world.setBlockState(new BlockPos(x, y + 2, z + 1), unravelledFabric);
|
||||
world.setBlockState(new BlockPos(x, y + 1, z - 1), unravelledFabric);
|
||||
world.setBlockState(new BlockPos(x, y + 1, z + 1), unravelledFabric);
|
||||
|
||||
DimensionalDoorItem.placeDoor(world, new BlockPos(x, y + 1, z), Direction.NORTH, ModBlocks.DIMENSIONAL_PORTAL, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocationValid(World world, int x, int y, int z) {
|
||||
return world.dimension instanceof LimboDimension;
|
||||
}
|
||||
}
|
128
src/main/java/org/dimdev/dimdoors/world/limbo/LimboDecay.java
Normal file
128
src/main/java/org/dimdev/dimdoors/world/limbo/LimboDecay.java
Normal file
|
@ -0,0 +1,128 @@
|
|||
package org.dimdev.dimdoors.world.limbo;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.BlockWithEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import static net.minecraft.block.Blocks.*;
|
||||
import static org.dimdev.dimdoors.block.ModBlocks.*;
|
||||
|
||||
/**
|
||||
* Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo
|
||||
* naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes.
|
||||
*/
|
||||
public final class LimboDecay {
|
||||
private static final Map<Block, Block> DECAY_SEQUENCE = new HashMap<>();
|
||||
|
||||
static { // TODO: make this work on the server
|
||||
try {
|
||||
for (Resource resource : MinecraftClient.getInstance().getResourceManager().getAllResources(new Identifier("dimdoors:limbo_decay"))) {
|
||||
Map<String, String> decays = new Gson().fromJson(new InputStreamReader(resource.getInputStream()), new TypeToken<Map<String, String>>() {}.getType());
|
||||
|
||||
for (Map.Entry<String, String> decay : decays.entrySet()) {
|
||||
DECAY_SEQUENCE.put(Registry.BLOCK.get(new Identifier(decay.getKey())), Registry.BLOCK.get(new Identifier(decay.getValue())));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Random random = new Random();
|
||||
private static Block[] blocksImmuneToDecay = null;
|
||||
|
||||
public static Map<Block, Block> getDecaySequence() {
|
||||
return DECAY_SEQUENCE;
|
||||
}
|
||||
|
||||
public static Block[] getBlocksImmuneToDecay() {
|
||||
if (blocksImmuneToDecay == null) {
|
||||
blocksImmuneToDecay = new Block[]{
|
||||
UNRAVELLED_FABRIC,
|
||||
ETERNAL_FABRIC,
|
||||
DIMENSIONAL_PORTAL,
|
||||
IRON_DIMENSIONAL_DOOR,
|
||||
WOOD_DIMENSIONAL_DOOR,
|
||||
DETACHED_RIFT,
|
||||
GOLD_DOOR,
|
||||
QUARTZ_DOOR,
|
||||
GOLD_DIMENSIONAL_DOOR
|
||||
};
|
||||
}
|
||||
|
||||
return blocksImmuneToDecay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the blocks orthogonally around a given location (presumably the location of an Unraveled Fabric block)
|
||||
* and applies Limbo decay to them. This gives the impression that decay spreads outward from Unraveled Fabric.
|
||||
*/
|
||||
public static void applySpreadDecay(World world, BlockPos pos) {
|
||||
//Check if we randomly apply decay spread or not. This can be used to moderate the frequency of
|
||||
//full spread decay checks, which can also shift its performance impact on the game.
|
||||
if (random.nextDouble() < ModConfig.LIMBO.decaySpreadChance) {
|
||||
//Apply decay to the blocks above, below, and on all four sides.
|
||||
//World.getBlockId() implements bounds checking, so we don't have to worry about reaching out of the world
|
||||
decayBlock(world, pos.up());
|
||||
decayBlock(world, pos.down());
|
||||
decayBlock(world, pos.north());
|
||||
decayBlock(world, pos.south());
|
||||
decayBlock(world, pos.west());
|
||||
decayBlock(world, pos.east());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a block can be decayed and, if so, changes it to the next block ID along the decay sequence.
|
||||
*/
|
||||
private static boolean decayBlock(World world, BlockPos pos) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
|
||||
if (canDecayBlock(state, world, pos)) {
|
||||
//Loop over the block IDs that decay can go through.
|
||||
//Find an index matching the current blockID, if any.
|
||||
|
||||
if (getDecaySequence().containsKey(state.getBlock())) {
|
||||
Block decay = getDecaySequence().get(state.getBlock());
|
||||
world.setBlockState(pos, decay.getDefaultState());
|
||||
} else if (!state.isFullCube(world, pos)) {
|
||||
world.setBlockState(pos, AIR.getDefaultState());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a block can decay. We will not decay air, certain DD blocks, or containers.
|
||||
*/
|
||||
private static boolean canDecayBlock(BlockState state, World world, BlockPos pos) {
|
||||
if (world.isAir(pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int k = 0; k < getBlocksImmuneToDecay().length; k++) {
|
||||
if (state.getBlock().equals(getBlocksImmuneToDecay()[k])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !(state.getBlock() instanceof BlockWithEntity);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.dimdev.dimdoors.world.limbo;
|
||||
|
||||
import org.dimdev.dimdoors.world.CustomSkyProvider;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
/**
|
||||
* Created by Jared Johnson on 1/24/2017.
|
||||
*/
|
||||
public class LimboSkyProvider extends CustomSkyProvider {
|
||||
private static final Identifier moonRenderPath = new Identifier("dimdoors:textures/other/limbo_moon.png");
|
||||
private static final Identifier sunRenderPath = new Identifier("dimdoors:textures/other/limbo_sun.png");
|
||||
|
||||
@Override
|
||||
public Identifier getMoonRenderPath() {
|
||||
return moonRenderPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getSunRenderPath() {
|
||||
return sunRenderPath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.dimdev.dimdoors.world.pocketdimension;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.chunk.ChunkPrimer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BlankBiome extends Biome {
|
||||
|
||||
private final boolean white;
|
||||
|
||||
public BlankBiome(boolean white, boolean monoliths) {
|
||||
super(new BiomeProperties((monoliths ? "Dangerous " : "") + (white ? "White" : "Black") + " Void")
|
||||
.setBaseHeight(0F)
|
||||
.setHeightVariation(0F)
|
||||
.setRainDisabled()
|
||||
.setRainfall(0)
|
||||
.setWaterColor(white ? 0xFFFFFF : 0x000055));
|
||||
this.white = white;
|
||||
|
||||
topBlock = Blocks.AIR.getDefaultState();
|
||||
fillerBlock = Blocks.AIR.getDefaultState();
|
||||
|
||||
spawnableMonsterList.clear();
|
||||
spawnableCreatureList.clear();
|
||||
spawnableWaterCreatureList.clear();
|
||||
spawnableCaveCreatureList.clear();
|
||||
|
||||
flowers.clear();
|
||||
|
||||
decorator.extraTreeChance = 0;
|
||||
decorator.flowersPerChunk = 0;
|
||||
decorator.grassPerChunk = 0;
|
||||
decorator.gravelPatchesPerChunk = 0;
|
||||
decorator.sandPatchesPerChunk = 0;
|
||||
decorator.clayPerChunk = 0;
|
||||
decorator.generateFalls = false;
|
||||
}
|
||||
|
||||
// Some mods like RFTools rely on the decorator being present, so we need to create one even if we don't use it.
|
||||
//@Override public BiomeDecorator createBiomeDecorator() { return null; }
|
||||
|
||||
@Override
|
||||
public void decorate(World world, Random rand, BlockPos pos) {}
|
||||
|
||||
@Override
|
||||
public void genTerrainBlocks(World world, Random rand, ChunkPrimer chunkPrimer, int x, int z, double noiseVal) {}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public int getSkyColorByTemp(float currentTemperature) {
|
||||
return white ? 0xFCFCFC : 0x000000; // https://bugs.mojang.com/projects/MC/issues/MC-123703
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public int getGrassColorAtPos(BlockPos pos) {
|
||||
return getModdedBiomeGrassColor(white ? 0xFFFFFF : 0x003300);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public int getFoliageColorAtPos(BlockPos pos) {
|
||||
return getModdedBiomeFoliageColor(white ? 0xFFFFFF : 0x003300);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue