Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package dev.ryanhcode.sable.physics.config;

import dev.ryanhcode.sable.physics.floating_block.FloatingBlockMaterial;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Supplier;

public abstract class FloatingBlockMaterialProvider implements DataProvider {
protected final PackOutput.PathProvider pathProvider;
private final CompletableFuture<HolderLookup.Provider> registries;
protected final String modId;
private final Map<ResourceLocation, FloatingBlockMaterial> definitions = new HashMap<>();

public FloatingBlockMaterialProvider(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> registries, String modId) {
this.pathProvider = packOutput.createPathProvider(PackOutput.Target.DATA_PACK, "floating_block_material");
this.registries = registries;
this.modId = modId;
}

protected abstract void addProperties(HolderLookup.Provider holderLookup);

public final CompletableFuture<?> run(CachedOutput output) {
return this.registries.thenCompose((provider) -> {
final Set<CompletableFuture<?>> list = new HashSet<>();
this.addProperties(provider);
this.definitions.forEach((id, definition) -> {
list.add(DataProvider.saveStable(output, provider, FloatingBlockMaterial.CODEC, definition, this.pathProvider.json(id)));
});
return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new));
});
}

public final FloatingBlockMaterial define(final Supplier<Block> block, double liftStrength, final Function<Builder, Builder> builderFunction) {
return this.define(BuiltInRegistries.BLOCK.getKey(block.get()), liftStrength, builderFunction);
}

public final FloatingBlockMaterial define(final ResourceLocation id, double liftStrength, final Function<Builder, Builder> builderFunction) {
return this.definitions.computeIfAbsent(id, (k) -> builderFunction.apply(new Builder(liftStrength)).build());
}

@Override
public @NotNull String getName() {
return "Floating Block Material Properties for " + this.modId;
}

public static class Builder {
boolean preventSelfLift = false;
boolean scaleWithPressure = false;
boolean scaleWithGravity = false;
final double liftStrength;
double transitionSpeed = 0.0d;
double slowVerticalFriction = 0.0d;
double fastVerticalFriction = 0.0d;
double slowHorizontalFriction = 0.0d;
double fastHorizontalFriction = 0.0d;

public Builder(double liftStrength) {
this.liftStrength = liftStrength;
}

public Builder preventSelfLift() {
this.preventSelfLift = true;
return this;
}

public Builder scaleWithPressure() {
this.scaleWithPressure = true;
return this;
}

public Builder scaleWithGravity() {
this.scaleWithGravity = true;
return this;
}

public Builder transitionSpeed(double transitionSpeed) {
this.transitionSpeed = transitionSpeed;
return this;
}

public Builder slowVerticalFriction(double slowVerticalFriction) {
this.slowVerticalFriction = slowVerticalFriction;
return this;
}

public Builder fastVerticalFriction(double fastVerticalFriction) {
this.fastVerticalFriction = fastVerticalFriction;
return this;
}

public Builder slowHorizontalFriction(double slowHorizontalFriction) {
this.slowHorizontalFriction = slowHorizontalFriction;
return this;
}

public Builder fastHorizontalFriction(double fastHorizontalFriction) {
this.fastHorizontalFriction = fastHorizontalFriction;
return this;
}

public FloatingBlockMaterial build() {
return new FloatingBlockMaterial(this.preventSelfLift, this.scaleWithPressure, this.scaleWithGravity, this.liftStrength, this.transitionSpeed, this.slowVerticalFriction, this.fastVerticalFriction, this.slowHorizontalFriction, this.fastHorizontalFriction);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package dev.ryanhcode.sable.physics.config.block_properties;

import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Supplier;

public abstract class BlockPhysicsPropertiesProvider implements DataProvider {
protected final PackOutput.PathProvider pathProvider;
private final CompletableFuture<HolderLookup.Provider> registries;
protected final String modId;
private final Map<ResourceLocation, PhysicsBlockPropertiesDefinition> definitions = new HashMap<>();

public BlockPhysicsPropertiesProvider(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> registries, String modId) {
this.pathProvider = packOutput.createPathProvider(PackOutput.Target.DATA_PACK, "physics_block_properties");
this.registries = registries;
this.modId = modId;
}

protected abstract void addProperties(HolderLookup.Provider holderLookup);

public final CompletableFuture<?> run(CachedOutput output) {
return this.registries.thenCompose((provider) -> {
final Set<CompletableFuture<?>> list = new HashSet<>();
this.addProperties(provider);
this.definitions.forEach((id, definition) -> {
list.add(DataProvider.saveStable(output, provider, PhysicsBlockPropertiesDefinition.CODEC, definition, this.pathProvider.json(id)));
});
return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new));
});
}

public final PhysicsBlockPropertiesDefinition define(final TagKey<Block> key, final Function<Builder, Builder> builderFunction) {
return this.define(key.location(), true, builderFunction);
}

public final PhysicsBlockPropertiesDefinition define(final Supplier<Block> block, final Function<Builder, Builder> builderFunction) {
return this.define(BuiltInRegistries.BLOCK.getKey(block.get()), false, builderFunction);
}

public final PhysicsBlockPropertiesDefinition define(final ResourceLocation id, boolean tag, final Function<Builder, Builder> builderFunction) {
return this.definitions.computeIfAbsent(id, (k) -> builderFunction.apply(new Builder(k, tag)).build());
}

@Override
public @NotNull String getName() {
return "Block Physics Properties for " + this.modId;
}

public static class Builder {
final ExtraCodecs.TagOrElementLocation selector;
int priority = 1000;
Map<ResourceLocation, Object> properties = new HashMap<>();
Map<BlockStateConditionSet, Map<ResourceLocation, Object>> overrides = null;

public Builder(ResourceLocation id, boolean tag) {
this.selector = new ExtraCodecs.TagOrElementLocation(id, tag);
}

/**
* Sets the priority of the properties
* @param priority the priority
* @return this
*/
public Builder priority(int priority) {
this.priority = priority;
return this;
}

/**
* @param properties function to apply multiple properties in one place
* @return this
* @see PhysicsBlockPropertyTypes
*/
public Builder properties(Function<PropertyBuilder, PropertyBuilder> properties) {
this.properties.putAll(properties.apply(new PropertyBuilder()).getProperties());
return this;
}

/**
* @param type the physics property type
* @param value the value to set
* @return this
* @see PhysicsBlockPropertyTypes
*/
public <T> Builder property(PhysicsBlockPropertyTypes.PhysicsBlockPropertyType<T> type, T value) {
this.properties.put(PhysicsBlockPropertyTypes.REGISTRY.getKey(type), value);
return this;
}

/**
* @param type the physics property type
* @param value the value to set
* @return this
* @see PhysicsBlockPropertyTypes
*/
public <T> Builder property(Supplier<PhysicsBlockPropertyTypes.PhysicsBlockPropertyType<T>> type, T value) {
this.properties.put(PhysicsBlockPropertyTypes.REGISTRY.getKey(type.get()), value);
return this;
}

/**
* @param conditions conditions that must be met for these properties
* @param properties function to assign override properties
* @return this
* @see BlockStateConditionSet.Builder
*/
public Builder override(BlockStateConditionSet conditions, Function<PropertyBuilder, PropertyBuilder> properties) {
if (this.overrides == null) this.overrides = new HashMap<>();
this.overrides.put(conditions, properties.apply(new PropertyBuilder()).getProperties());
return this;
}

public PhysicsBlockPropertiesDefinition build() {
return new PhysicsBlockPropertiesDefinition(this.selector, this.priority, this.properties, Optional.ofNullable(this.overrides));
}

public static class PropertyBuilder {
Map<ResourceLocation, Object> properties = new HashMap<>();

/**
* @param type the physics property type
* @param value the value to set
* @return this
* @see PhysicsBlockPropertyTypes
*/
public <T> PropertyBuilder property(PhysicsBlockPropertyTypes.PhysicsBlockPropertyType<T> type, T value) {
this.properties.put(PhysicsBlockPropertyTypes.REGISTRY.getKey(type), value);
return this;
}

/**
* @param type the physics property type
* @param value the value to set
* @return this
* @see PhysicsBlockPropertyTypes
*/
public <T> PropertyBuilder property(Supplier<PhysicsBlockPropertyTypes.PhysicsBlockPropertyType<T>> type, T value) {
this.properties.put(PhysicsBlockPropertyTypes.REGISTRY.getKey(type.get()), value);
return this;
}

public Map<ResourceLocation, Object> getProperties() {
return this.properties;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,27 @@ public String toString() {
}
}

public static Builder builder() {
return new Builder();
}

public static class Builder {
List<BlockStateCondition> conditions = new ArrayList<>();

public Builder expect(String property, String value) {
this.conditions.add(new BlockStateCondition(property, value));
return this;
}

public <T extends Comparable<T>> Builder expect(Property<T> property, T value) {
return this.expect(property.getName(), property.getName(value));
}

public BlockStateConditionSet build() {
if (this.conditions.isEmpty()) {
throw new IllegalStateException("conditions must not be empty");
}
return new BlockStateConditionSet(this.conditions);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
public class PhysicsBlockPropertyTypes {
public static final ResourceKey<Registry<PhysicsBlockPropertyType<?>>> REGISTRY_KEY = ResourceKey.createRegistryKey(Sable.sablePath("physics_block_properties"));
private static final RegistrationProvider<PhysicsBlockPropertyType<?>> VANILLA_PROVIDER;
private static final Registry<PhysicsBlockPropertyType<?>> REGISTRY;
protected static final Registry<PhysicsBlockPropertyType<?>> REGISTRY;

static {
VANILLA_PROVIDER = RegistrationProvider.get(REGISTRY_KEY, Sable.MOD_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,21 @@ public record BezierPoint(double altitude, double value, double slope) {
BezierPoint::new
);
}

public static Builder builder() {
return new Builder();
}

public static class Builder {
List<BezierPoint> points = new ArrayList<>();

public Builder addPoint(double altitude, double value, double slope) {
this.points.add(new BezierPoint(altitude, value, slope));
return this;
}

public BezierResourceFunction build() {
return new BezierResourceFunction(this.points);
}
}
}
Loading