Skip to content

Commit

Permalink
Implement more fluid behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Nov 21, 2024
1 parent 7e3754f commit 0112b2f
Show file tree
Hide file tree
Showing 15 changed files with 61,178 additions and 9,449 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,11 @@
public class Main implements ModInitializer {
@Override
public void onInitialize() {
// Entity.class;
// LivingEntity.class;
// Player.class;
// AbstractClientPlayer.class;
// LocalPlayer.class;
// FluidState
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.FallingBlock;
import net.minecraft.world.level.block.IceBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;

public class BlocksJsonGenerator implements IDataGenerator {
@SuppressWarnings("deprecation")
@SneakyThrows
public static JsonObject generateBlock(Block block) {
var blockDesc = new JsonObject();
Expand All @@ -46,6 +48,9 @@ public static JsonObject generateBlock(Block block) {
if (block instanceof FallingBlock) {
blockDesc.addProperty("fallingBlock", true);
}
if (block instanceof IceBlock) {
blockDesc.addProperty("iceBlock", true);
}
if (defaultState.canBeReplaced()) {
blockDesc.addProperty("replaceable", true);
}
Expand Down Expand Up @@ -81,6 +86,10 @@ public static JsonObject generateBlock(Block block) {
stateDesc.addProperty("default", true);
}

if (state.blocksMotion()) {
stateDesc.addProperty("blocksMotion", state.blocksMotion());
}

var fluidStateDesc = new JsonObject();
var fluidState = state.getFluidState();
fluidStateDesc.addProperty("type", BuiltInRegistries.FLUID.getKey(fluidState.getType()).toString());
Expand All @@ -99,6 +108,22 @@ public static JsonObject generateBlock(Block block) {
fluidStateDesc.addProperty("empty", true);
}

var fluidPropertiesDesc = new JsonObject();
for (var property : fluidState.getProperties()) {
var value = fluidState.getValue(property);
if (value instanceof Integer integer) {
fluidPropertiesDesc.addProperty(property.getName(), integer);
} else if (value instanceof Boolean bool) {
fluidPropertiesDesc.addProperty(property.getName(), bool);
} else {
fluidPropertiesDesc.addProperty(property.getName(), Util.getPropertyName(property, value));
}
}

if (!fluidPropertiesDesc.isEmpty()) {
fluidStateDesc.add("properties", fluidPropertiesDesc);
}

stateDesc.add("fluidState", fluidStateDesc);

var propertiesDesc = new JsonObject();
Expand Down
1 change: 1 addition & 0 deletions data-generator/src/main/resources/templates/BlockType.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public record BlockType(
float explosionResistance,
boolean air,
boolean fallingBlock,
boolean iceBlock,
boolean replaceable,
boolean requiresCorrectToolForDrops,
List<LootPoolEntry> lootTableData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@ public record BlockState(
int id,
BlockType blockType,
boolean defaultState,
boolean blocksMotion,
FluidState fluidState,
BlockStateProperties properties,
BlockShapeGroup blockShapeGroup) {
public BlockState(
int id,
boolean defaultState,
boolean blocksMotion,
FluidState fluidState,
BlockStateProperties properties,
BlockType blockType,
Key key,
int stateIndex) {
this(id, blockType, defaultState, fluidState, properties, getBlockShapeGroup(key, stateIndex));
this(id, blockType, defaultState, blocksMotion, fluidState, properties, getBlockShapeGroup(key, stateIndex));
}

public static BlockState forDefaultBlockType(BlockType blockType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
*/
package com.soulfiremc.server.data;

import com.google.gson.JsonDeserializer;
import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.objects.*;
import lombok.ToString;

@ToString
public class BlockStateProperties {
public static final JsonDeserializer<BlockStateProperties> BLOCK_STATE_PROPERTIES =
(json, typeOfT, context) -> new BlockStateProperties(json.getAsJsonObject());
private final Object2BooleanMap<String> booleanProperties;
private final Object2IntMap<String> intProperties;
private final Object2ObjectMap<String, String> stringProperties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,17 @@ public static BlockStates fromJsonArray(BlockType blockType, Key key, JsonArray
var stateObject = state.getAsJsonObject();
var stateId = stateObject.get("id").getAsInt();
var defaultStateValue = stateObject.get("default") != null;
var blocksMotionValue = stateObject.get("blocksMotion") != null;

var fluidState = GsonDataHelper.createGson(Map.of(
FluidType.class,
BlockType.CUSTOM_FLUID_TYPE
BlockType.CUSTOM_FLUID_TYPE,
BlockStateProperties.class,
BlockStateProperties.BLOCK_STATE_PROPERTIES
)).fromJson(stateObject.get("fluidState"), FluidState.class);
var properties = new BlockStateProperties(stateObject.getAsJsonObject("properties"));

var blockState = new BlockState(stateId, defaultStateValue, fluidState, properties, blockType, key, i);
var blockState = new BlockState(stateId, defaultStateValue, blocksMotionValue, fluidState, properties, blockType, key, i);

if (defaultStateValue) {
defaultState = blockState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public record BlockType(
float explosionResistance,
boolean air,
boolean fallingBlock,
boolean iceBlock,
boolean replaceable,
boolean requiresCorrectToolForDrops,
List<LootPoolEntry> lootTableData,
Expand Down
74 changes: 72 additions & 2 deletions server/src/main/java/com/soulfiremc/server/data/FluidState.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,94 @@
package com.soulfiremc.server.data;

import com.soulfiremc.server.protocol.bot.state.Level;
import com.soulfiremc.server.util.mcstructs.Direction;
import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3i;

public record FluidState(
FluidType type,
int amount,
float ownHeight,
boolean source,
boolean empty
boolean empty,
BlockStateProperties properties
) {
private boolean hasSameAbove(Level level, Vector3i blockPos) {
return type.equals(level.getBlockState(blockPos.add(0, 1, 0)).fluidState().type());
}

public float getHeight(Level level, Vector3i blockPos) {
if (type == FluidType.EMPTY) {
if (empty) {
return 0.0F;
} else {
return hasSameAbove(level, blockPos) ? 1.0F : ownHeight;
}
}

private boolean affectsFlow(FluidState state) {
return state.empty() || state.type().equals(type);
}

public Vector3d getFlow(Level level, Vector3i blockPos) {
if (empty) {
return Vector3d.ZERO;
}

var d = 0.0;
var e = 0.0;
var currentBlock = Vector3i.ZERO;

for (var direction : Direction.Plane.HORIZONTAL) {
currentBlock = direction.offset(blockPos);
var relativeFluidState = level.getBlockState(currentBlock).fluidState();
if (this.affectsFlow(relativeFluidState)) {
var f = relativeFluidState.ownHeight();
var g = 0.0F;
if (f == 0.0F) {
if (!level.getBlockState(currentBlock).blocksMotion()) {
var lv4 = currentBlock.add(0, -1, 0);
var lv5 = level.getBlockState(lv4).fluidState();
if (this.affectsFlow(lv5)) {
f = lv5.ownHeight();
if (f > 0.0F) {
g = ownHeight - (f - 0.8888889F);
}
}
}
} else if (f > 0.0F) {
g = ownHeight - f;
}

if (g != 0.0F) {
d += (float) direction.getStepX() * g;
e += (float) direction.getStepZ() * g;
}
}
}

var lv6 = Vector3d.from(d, 0.0, e);
if (properties.getBoolean("falling")) {
for (var direction : Direction.Plane.HORIZONTAL) {
currentBlock = direction.offset(blockPos);
if (this.isSolidFace(level, currentBlock, direction) || this.isSolidFace(level, currentBlock.add(0, 1, 0), direction)) {
lv6 = lv6.normalize().add(0.0, -6.0, 0.0);
break;
}
}
}

return lv6.normalize();
}

private boolean isSolidFace(Level level, Vector3i neighborPos, Direction side) {
var blockState = level.getBlockState(neighborPos);
var fluidState = blockState.fluidState();
if (fluidState.type().equals(type)) {
return false;
} else if (side == Direction.UP) {
return true;
} else {
return blockState.blockType().iceBlock() ? false : blockState.isFaceSturdy(level, neighborPos, side);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public Key read(JsonReader in) throws IOException {
return Key.key(key);
}
};
private static final Function<Map<Class<?>, TypeAdapter<?>>, Gson> GSON_FACTORY = (typeAdapters) -> {
private static final Function<Map<Class<?>, Object>, Gson> GSON_FACTORY = (typeAdapters) -> {
var builder = new GsonBuilder()
.registerTypeAdapter(Key.class, RESOURCE_KEY_ADAPTER)
.registerTypeAdapter(ByteDataComponents.class, ByteDataComponents.SERIALIZER);
Expand All @@ -64,7 +64,7 @@ public static <T> T fromJson(String dataFile, String dataKey, Class<T> clazz) {
}

public static <T> T fromJson(String dataFile, String dataKey, Class<T> clazz,
Map<Class<?>, TypeAdapter<?>> typeAdapters) {
Map<Class<?>, Object> typeAdapters) {
var gson = createGson(typeAdapters);
var array =
LOADED_DATA.computeIfAbsent(
Expand All @@ -88,7 +88,7 @@ public static <T> T fromJson(String dataFile, String dataKey, Class<T> clazz,
throw new RuntimeException("Failed to find data key %s in file %s".formatted(dataKey, dataFile));
}

public static Gson createGson(Map<Class<?>, TypeAdapter<?>> typeAdapters) {
public static Gson createGson(Map<Class<?>, Object> typeAdapters) {
return GSON_FACTORY.apply(typeAdapters);
}
}
Loading

0 comments on commit 0112b2f

Please sign in to comment.