Merge pull request #408 from PolyhedralDev/dev/physics

Allows you to create a block with physics enabled
This commit is contained in:
Zoë
2023-10-01 19:07:15 -06:00
committed by GitHub
16 changed files with 127 additions and 110 deletions

View File

@@ -30,15 +30,17 @@ public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
@Override
public BlockFunction build(List<Returnable<?>> argumentList, Position position) {
if(argumentList.size() < 4) throw new ParseException("Expected data", position);
Returnable<Boolean> booleanReturnable = new BooleanConstant(true, position);
if(argumentList.size() == 5) booleanReturnable = (Returnable<Boolean>) argumentList.get(4);
Returnable<Boolean> overwrite = new BooleanConstant(true, position);
if(argumentList.size() >= 5) overwrite = (Returnable<Boolean>) argumentList.get(4);
Returnable<Boolean> physics = new BooleanConstant(false, position);
if(argumentList.size() == 6) physics = (Returnable<Boolean>) argumentList.get(5);
if(argumentList.get(3) instanceof StringConstant) {
return new BlockFunction.Constant((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (StringConstant) argumentList.get(3),
booleanReturnable, platform, position);
overwrite, physics, platform, position);
}
return new BlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), booleanReturnable,
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), overwrite, physics,
platform, position);
}
@@ -52,7 +54,7 @@ public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
case 3 -> Returnable.ReturnType.STRING;
case 4 -> Returnable.ReturnType.BOOLEAN;
case 4, 5 -> Returnable.ReturnType.BOOLEAN;
default -> null;
};
}

View File

@@ -35,10 +35,11 @@ public class BlockFunction implements Function<Void> {
protected final Platform platform;
private final Map<String, BlockState> data = new HashMap<>();
private final Returnable<Boolean> overwrite;
private final Returnable<Boolean> physics;
private final Position position;
public BlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> blockData,
Returnable<Boolean> overwrite, Platform platform, Position position) {
Returnable<Boolean> overwrite, Returnable<Boolean> physics, Platform platform, Position position) {
this.x = x;
this.y = y;
this.z = z;
@@ -46,6 +47,7 @@ public class BlockFunction implements Function<Void> {
this.overwrite = overwrite;
this.platform = platform;
this.position = position;
this.physics = physics;
}
@Override
@@ -76,7 +78,7 @@ public class BlockFunction implements Function<Void> {
FastMath.roundToInt(xz.getZ())).mutable().add(arguments.getOrigin());
BlockState current = arguments.getWorld().getBlockState(set);
if(overwrite.apply(implementationArguments, scope) || current.isAir()) {
arguments.getWorld().setBlockState(set, rot);
arguments.getWorld().setBlockState(set, rot, physics.apply(implementationArguments, scope));
}
} catch(RuntimeException e) {
logger.error("Failed to place block at location {}", arguments.getOrigin(), e);
@@ -92,8 +94,8 @@ public class BlockFunction implements Function<Void> {
private final BlockState state;
public Constant(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, StringConstant blockData,
Returnable<Boolean> overwrite, Platform platform, Position position) {
super(x, y, z, blockData, overwrite, platform, position);
Returnable<Boolean> overwrite, Returnable<Boolean> physics, Platform platform, Position position) {
super(x, y, z, blockData, overwrite, physics, platform, position);
this.state = platform.getWorldHandle().createBlockState(blockData.getConstant());
}

View File

@@ -8,5 +8,4 @@ terra.license=MIT
# Gradle options
org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC
org.gradle.warning.mode=all
#org.gradle.parallel=true

View File

@@ -0,0 +1,12 @@
package com.dfsek.terra.bukkit.util;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
public class BukkitUtils {
public static boolean isLiquid(BlockData blockState) {
Material material = blockState.getMaterial();
return material == Material.WATER || material == Material.LAVA;
}
}

View File

@@ -1,6 +1,9 @@
package com.dfsek.terra.bukkit.world;
import com.dfsek.terra.bukkit.util.BukkitUtils;
import org.bukkit.Location;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.LimitedRegion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,9 +50,14 @@ public class BukkitProtoWorld implements ProtoWorld {
@Override
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
access(x, y, z, () -> {
delegate.setBlockData(x, y, z, BukkitAdapter.adapt(data));
BlockData bukkitData = BukkitAdapter.adapt(data);
delegate.setBlockData(x, y, z, bukkitData);
if(physics) {
delegate.scheduleBlockUpdate(x, y, z);
if (BukkitUtils.isLiquid(bukkitData)) {
delegate.scheduleFluidUpdate(x, y, z);
} else {
delegate.scheduleBlockUpdate(x, y, z);
}
}
});
}

View File

@@ -50,10 +50,10 @@ loom {
launches {
named("client") {
property("fabric.log.level", "debug")
property("fabric.log.level", "info")
}
named("server") {
property("fabric.log.level", "debug")
property("fabric.log.level", "info")
}
}
}

View File

@@ -17,35 +17,16 @@
package com.dfsek.terra.fabric;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.fabric.FabricServerCommandManager;
import net.fabricmc.api.ModInitializer;
import net.minecraft.server.command.ServerCommandSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.api.command.CommandSender;
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.lifecycle.LifecycleEntryPoint;
public class FabricEntryPoint implements ModInitializer {
private static final Logger logger = LoggerFactory.getLogger(FabricEntryPoint.class);
public class FabricEntryPoint extends LifecycleEntryPoint implements ModInitializer {
private static final FabricPlatform TERRA_PLUGIN = new FabricPlatform();
@Override
public void onInitialize() {
logger.info("Initializing Terra Fabric mod...");
FabricServerCommandManager<CommandSender> manager = new FabricServerCommandManager<>(
CommandExecutionCoordinator.simpleCoordinator(),
serverCommandSource -> (CommandSender) serverCommandSource,
commandSender -> (ServerCommandSource) commandSender
);
manager.brigadierManager().setNativeNumberSuggestions(false);
TERRA_PLUGIN.getEventManager().callEvent(new CommandRegistrationEvent(manager));
initialize("Fabric", TERRA_PLUGIN);
}
}

View File

@@ -17,43 +17,24 @@
package com.dfsek.terra.fabric;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.Version;
import net.fabricmc.loader.api.FabricLoader;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.dfsek.terra.addon.EphemeralAddon;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.lifecycle.LifecyclePlatform;
public class FabricPlatform extends LifecyclePlatform {
private static final Logger LOGGER = LoggerFactory.getLogger(FabricPlatform.class);
@Override
protected Collection<BaseAddon> getPlatformMods() {
return FabricLoader.getInstance().getAllMods().stream().flatMap(mod -> {
String id = mod.getMetadata().getId();
if(id.equals("terra") || id.equals("minecraft") || id.equals("java")) return Stream.empty();
try {
Version version = Versions.parseVersion(mod.getMetadata().getVersion().getFriendlyString());
return Stream.<BaseAddon>of(new EphemeralAddon(version, "fabric:" + id));
} catch(ParseException e) {
LOGGER.warn(
"Mod {}, version {} does not follow semantic versioning specification, Terra addons will be unable to depend on " +
"it.",
id, mod.getMetadata().getVersion().getFriendlyString());
}
return Stream.empty();
}).collect(Collectors.toList());
return FabricLoader.getInstance().getAllMods().stream().flatMap(
mod -> parseModData(mod.getMetadata().getId(), mod.getMetadata().getVersion().getFriendlyString())).collect(
Collectors.toList());
}
@Override

View File

@@ -39,11 +39,11 @@ loom {
launches {
named("client") {
property("fabric.log.level", "debug")
property("fabric.log.level", "info")
property("mixin.env.disableRefMap", "true")
}
named("server") {
property("fabric.log.level", "debug")
property("fabric.log.level", "info")
property("mixin.env.disableRefMap", "true")
}
}

View File

@@ -17,8 +17,11 @@
package com.dfsek.terra.mod.mixin.implementations.terra.chunk;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk.TickSchedulers;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.tick.OrderedTick;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
@@ -47,8 +50,21 @@ public abstract class WorldChunkMixin {
@Nullable
public abstract net.minecraft.block.BlockState setBlockState(BlockPos pos, net.minecraft.block.BlockState state, boolean moved);
@Shadow
public abstract TickSchedulers getTickSchedulers();
public void terra$setBlock(int x, int y, int z, BlockState data, boolean physics) {
setBlockState(new BlockPos(x, y, z), (net.minecraft.block.BlockState) data, false);
BlockPos blockPos = new BlockPos(x, y, z);
setBlockState(blockPos, (net.minecraft.block.BlockState) data, false);
if (physics) {
net.minecraft.block.BlockState state = ((net.minecraft.block.BlockState) data);
if (state.isLiquid()) {
world.getFluidTickScheduler().scheduleTick(OrderedTick.create(state.getFluidState().getFluid(), blockPos));
} else {
world.getBlockTickScheduler().scheduleTick(OrderedTick.create(state.getBlock(), blockPos));
}
}
}
public void terra$setBlock(int x, int y, int z, @NotNull BlockState blockState) {

View File

@@ -15,6 +15,11 @@ dependencies {
minecraft("com.mojang:minecraft:${Versions.Mod.minecraft}")
mappings("net.fabricmc:yarn:${Versions.Mod.yarn}:v2")
modImplementation("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud) {
exclude("net.fabricmc")
exclude("net.fabricmc.fabric-api")
}
}
loom {

View File

@@ -0,0 +1,34 @@
package com.dfsek.terra.lifecycle;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.fabric.FabricServerCommandManager;
import com.dfsek.terra.api.command.CommandSender;
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.mod.MinecraftAddon;
import net.minecraft.server.command.ServerCommandSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LifecycleEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(LifecycleEntryPoint.class);
protected static void initialize(String modName, LifecyclePlatform platform) {
logger.info("Initializing Terra {} mod...", modName);
FabricServerCommandManager<CommandSender> manager = new FabricServerCommandManager<>(
CommandExecutionCoordinator.simpleCoordinator(),
serverCommandSource -> (CommandSender) serverCommandSource,
commandSender -> (ServerCommandSource) commandSender
);
manager.brigadierManager().setNativeNumberSuggestions(false);
platform.getEventManager().callEvent(new CommandRegistrationEvent(manager));
}
}

View File

@@ -2,6 +2,7 @@ package com.dfsek.terra.lifecycle;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.Version;
import com.dfsek.terra.lifecycle.util.BiomeUtil;
@@ -20,6 +21,7 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;
import java.util.concurrent.atomic.AtomicReference;
import com.dfsek.terra.addon.EphemeralAddon;
@@ -103,12 +105,26 @@ public abstract class LifecyclePlatform extends ModPlatform {
LOGGER.warn("Failed to parse Minecraft version", e);
}
}
addons.addAll(getPlatformMods());
return addons;
}
protected Stream<EphemeralAddon> parseModData(String id, String modVersion) {
if(id.equals("terra") || id.equals("minecraft") || id.equals("java")) return Stream.empty();
try {
Version version = Versions.parseVersion(modVersion);
return Stream.of(new EphemeralAddon(version, "quilt:" + id));
} catch(ParseException e) {
LOGGER.warn(
"Mod {}, version {} does not follow semantic versioning specification, Terra addons will be unable to depend on " +
"it.",
id, modVersion);
}
return Stream.empty();
}
@Override
public Registry<DimensionType> dimensionTypeRegistry() {
return DIMENSIONS.get();

View File

@@ -50,10 +50,10 @@ loom {
launches {
named("client") {
property("fabric.log.level", "debug")
property("fabric.log.level", "info")
}
named("server") {
property("fabric.log.level", "debug")
property("fabric.log.level", "info")
}
}
}

View File

@@ -17,36 +17,17 @@
package com.dfsek.terra.quilt;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.fabric.FabricServerCommandManager;
import net.minecraft.server.command.ServerCommandSource;
import org.quiltmc.loader.api.ModContainer;
import org.quiltmc.qsl.base.api.entrypoint.ModInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.api.command.CommandSender;
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.lifecycle.LifecycleEntryPoint;
public class QuiltEntryPoint implements ModInitializer {
private static final Logger logger = LoggerFactory.getLogger(QuiltEntryPoint.class);
public class QuiltEntryPoint extends LifecycleEntryPoint implements ModInitializer {
private static final QuiltPlatform TERRA_PLUGIN = new QuiltPlatform();
@Override
public void onInitialize(ModContainer container) {
logger.info("Initializing Terra Quilt mod...");
FabricServerCommandManager<CommandSender> manager = new FabricServerCommandManager<>(
CommandExecutionCoordinator.simpleCoordinator(),
serverCommandSource -> (CommandSender) serverCommandSource,
commandSender -> (ServerCommandSource) commandSender
);
manager.brigadierManager().setNativeNumberSuggestions(false);
TERRA_PLUGIN.getEventManager().callEvent(new CommandRegistrationEvent(manager));
initialize("Quilt", TERRA_PLUGIN);
}
}

View File

@@ -17,43 +17,23 @@
package com.dfsek.terra.quilt;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.Version;
import org.jetbrains.annotations.NotNull;
import org.quiltmc.loader.api.QuiltLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.dfsek.terra.addon.EphemeralAddon;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.lifecycle.LifecyclePlatform;
public class QuiltPlatform extends LifecyclePlatform {
private static final Logger LOGGER = LoggerFactory.getLogger(QuiltPlatform.class);
@Override
protected Collection<BaseAddon> getPlatformMods() {
return QuiltLoader.getAllMods().stream().flatMap(mod -> {
String id = mod.metadata().id();
if(id.equals("terra") || id.equals("minecraft") || id.equals("java")) return Stream.empty();
try {
Version version = Versions.parseVersion(mod.metadata().version().raw());
return Stream.of(new EphemeralAddon(version, "quilt:" + id));
} catch(ParseException e) {
LOGGER.warn(
"Mod {}, version {} does not follow semantic versioning specification, Terra addons will be unable to depend on " +
"it.",
id, mod.metadata().version().raw());
}
return Stream.empty();
}).collect(Collectors.toList());
return QuiltLoader.getAllMods().stream().flatMap(mod -> parseModData(mod.metadata().id(), mod.metadata().version().raw())).collect(
Collectors.toList());
}
@Override