new Attempt -> not functional yet
das hier ist ein backup, das noch unglaublich viele Fehler hat aber es war echt anstrengend, deswegen brauchen wir das. Bitte löschen sobald funktionierender release (hoffentlich) irgendwann kommt.
This commit is contained in:
parent
74e05e6c7e
commit
936c50e13c
|
@ -1,5 +1,7 @@
|
|||
package modchest;
|
||||
|
||||
import modchest.assets.OverlayAssetListener;
|
||||
import modchest.block.custom.gridCodecs;
|
||||
import modchest.networking.modNetworkingClient;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.minecraft.client.util.ModelIdentifier;
|
||||
|
@ -9,6 +11,8 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class REServerModClient implements ClientModInitializer {
|
||||
public static gridCodecs CODECS;
|
||||
public static OverlayAssetListener CLIENT_OVERLAYS;
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("modchest"); // Erster Error Logger
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package modchest.assets;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.spongepowered.include.com.google.gson.Gson;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener;
|
||||
import net.minecraft.client.gui.screen.Overlay;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class OverlayAssetListener implements SimpleResourceReloadListener<Collection<Identifier>> {
|
||||
private final Map<Identifier, Overlay> overlayInfoMap = new HashMap<>();
|
||||
|
||||
public Overlay getOverlayFor(final Identifier id) {
|
||||
return Overlay.ofNullable(overlayInfoMap.get(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Collection<Identifier>> load(ResourceManager manager, Profiler profiler,
|
||||
Executor executor) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
overlayInfoMap.clear();
|
||||
return resourceManager.findResources("modchest/overlays", s -> s.endsWith(".json"));
|
||||
}, executor);
|
||||
}
|
||||
|
||||
private DataResult<Unit> parseOverlayAndDependencies(final ResourceManager resourceManager,
|
||||
final Identifier rootOverlayId) {
|
||||
final Set<Identifier> loadedDependencies = new HashSet<>();
|
||||
|
||||
if (!overlayInfoMap.containsKey(rootOverlayId)) {
|
||||
return parseOverlay(resourceManager, loadedDependencies, rootOverlayId);
|
||||
} else {
|
||||
return DataResult.success(Unit.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
private DataResult<Unit> parseOverlay(final ResourceManager resourceManager,
|
||||
final Set<Identifier> loadedDependencies, final Identifier overlayId) {
|
||||
final JsonElement element;
|
||||
try {
|
||||
element = new Gson().fromJson(
|
||||
new BufferedReader(new InputStreamReader(resourceManager.getResource(overlayId).getInputStream())),
|
||||
JsonElement.class);
|
||||
} catch (final IOException e) {
|
||||
return DataResult.error("Exception while loading an overlay:");
|
||||
}
|
||||
|
||||
final DataResult<Pair<Overlay.Some, JsonElement>> result = Overlay.Some.PARENT_CODEC
|
||||
.decode(JsonOps.INSTANCE, element)
|
||||
.flatMap(pair -> pair.getFirst().map(parentId -> {
|
||||
if (!loadedDependencies.add(parentId)) {
|
||||
return DataResult.error("Circular dependency;" + pair.getFirst() + "and" + overlayId + ".");
|
||||
} else {
|
||||
parseOverlay(resourceManager, loadedDependencies, parentId);
|
||||
return DataResult.success(Unit.INSTANCE);
|
||||
}
|
||||
}).orElse(DataResult.success(Unit.INSTANCE)))
|
||||
.flatMap(unit -> Overlay.Some.CODEC.decode(JsonOps.INSTANCE, element));
|
||||
|
||||
result.get().mapLeft(pair -> {
|
||||
overlayInfoMap.put(overlayId, pair.getFirst());
|
||||
});
|
||||
return result.map(p -> Unit.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> apply(Collection<Identifier> data, ResourceManager manager, Profiler profiler,
|
||||
Executor executor) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
for (final Identifier id : identifiers) {
|
||||
final DataResult<Unit> result = parseOverlayAndDependencies(manager, id);
|
||||
result.get().ifRight(partial -> META.LOGGER
|
||||
.warn("Error while parsing overlay \"" + id + "\": " + partial.message()));
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getFabricId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package modchest.assets;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.NonnullDefault;
|
||||
|
||||
import modchest.util.ToOptional;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class Parent implements ToOptional<Parent> {
|
||||
public static Parent ofNullable(@Nullable final Identifier parentId) {
|
||||
if (parentId == null) {
|
||||
return NONE;
|
||||
} else {
|
||||
return new Some(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Optional<Identifier> id();
|
||||
public abstract <T> T run(@NonnullDefault Function<Identifier, T> f, T whenNone);
|
||||
|
||||
public static class Some extends Parent implements ToOptional.Some<Parent> {
|
||||
|
||||
private final @NonnullDefault Identifier parent;
|
||||
|
||||
public Some(final @NonnullDefault Identifier parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Identifier> id() {
|
||||
return Optional.of(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T run(Function<Identifier, T> f, T whenNone) {
|
||||
return f.apply(parent);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Parent NONE = new Parent() {
|
||||
@Override
|
||||
public Optional<Identifier> id() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T run(@NonnullDefault final Function<Identifier, T> f, final T whenNone) {
|
||||
return whenNone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T match(final Function<Parent, T> some, final Supplier<T> none) {
|
||||
return none.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Parent> toOptional() {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ColoredLike {
|
||||
public static final Codec<ColoredLike> CODEC = Identifier.CODEC
|
||||
.xmap(id -> Registry.BLOCK.get(id).getDefaultState(), state -> Registry.BLOCK.getId(state.getBlock()))
|
||||
.xmap(ColoredLike::new, coloredLike -> coloredLike.colorSource);
|
||||
|
||||
private final BlockState colorSource;
|
||||
|
||||
public ColoredLike(final BlockState colorSource) {
|
||||
this.colorSource = colorSource;
|
||||
}
|
||||
|
||||
public BlockState colorSource() {
|
||||
return colorSource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import modchest.util.ToOptional;
|
||||
|
||||
import modchest.util.Float4;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Offsetter extends ToOptional<Offsetter> {
|
||||
Float4 offsett(Float4 original);
|
||||
|
||||
public Identifier getId();
|
||||
|
||||
Identifier NONE_ID = META.id("none");
|
||||
|
||||
Offsetter NONE = new Offsetter() {
|
||||
@Override
|
||||
public Optional<Offsetter> toOptional() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T match(final Function<Offsetter, T> some, final Supplier<T> none) {
|
||||
return none.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return NONE_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float4 offsett(Float4 original) {
|
||||
return original;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import modchest.util.Identifiable;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class OffsetterRegistry {
|
||||
private OffsetterRegistry() {
|
||||
}
|
||||
|
||||
private static final Map<Identifier, Identifiable<Codec<Offsetter>>> registeredOffsetters = new HashMap<>();
|
||||
|
||||
private static void register(final Identifier id, final Codec<Offsetter> codec) {
|
||||
registeredOffsetters.put(id, new Identifiable<>(codec, id));
|
||||
}
|
||||
|
||||
public static Identifiable<Codec<Offsetter>> get(final Identifier id) {
|
||||
return registeredOffsetters.get(id);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class Offsetters {
|
||||
public static final Codec<Offsetters> CODEC = RecordCodecBuilder.create(inst -> inst.group(
|
||||
CODECS.OFFSETTER.optionalFieldOf("u").forGetter(o -> o.u.toOptional()),
|
||||
CODECS.OFFSETTER.optionalFieldOf("v").forGetter(o -> o.v.toOptional())
|
||||
).apply(inst, Offsetters::new));
|
||||
|
||||
public static final Offsetters NONE = new Offsetters();
|
||||
|
||||
public final Offsetter u;
|
||||
public final Offsetter v;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public Offsetters(final Optional<Offsetter> u, final Optional<Offsetter> v) {
|
||||
this.u = u.orElse(Offsetter.NONE);
|
||||
this.v = v.orElse(Offsetter.NONE);
|
||||
}
|
||||
|
||||
private Offsetters() {
|
||||
this.u = Offsetter.NONE;
|
||||
this.v = Offsetter.NONE;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import modchest.assets.Parent;
|
||||
import modchest.assets.Parent.Some;
|
||||
import modchest.transform.TransformResult;
|
||||
import modchest.util.Float4;
|
||||
import modchest.util.ToOptional;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class Overlay implements ToOptional<Overlay> {
|
||||
public static Overlay ofNullable(final @Nullable Some some) {
|
||||
if (some == null) {
|
||||
return NONE;
|
||||
} else {
|
||||
return some;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract TransformResult apply(MutableQuadView mqv, Float4 us, Float4 vs, Direction dir);
|
||||
|
||||
public abstract TextureSource textureSource();
|
||||
|
||||
public abstract Optional<ColoredLike> coloredLike();
|
||||
|
||||
public abstract SidedOffsetters.Base sideOffsetters();
|
||||
|
||||
public static final Overlay NONE = new Overlay() {
|
||||
@Override
|
||||
public TransformResult apply(MutableQuadView mqv, Float4 us, Float4 vs, Direction dir) {
|
||||
return TransformResult.NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureSource textureSource() {
|
||||
return TextureSource.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ColoredLike> coloredLike() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SidedOffsetters.Base sideOffsetters() {
|
||||
return SidedOffsetters.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Overlay> toOptional() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T match(Function<Overlay, T> some, Supplier<T> none) {
|
||||
return none.get();
|
||||
}
|
||||
};
|
||||
|
||||
public static class Some extends Overlay implements ToOptional.Some<Overlay> {
|
||||
public static final Codec<Optional<Identifier>> PARENT_CODEC = RecordCodecBuilder.create(inst -> inst.group(
|
||||
Identifier.CODEC.optionalFieldOf("parent").forGetter(i -> i)).apply(inst, i -> i));
|
||||
|
||||
public static final Codec<Overlay.Some> CODEC = RecordCodecBuilder.create(inst -> inst.group(
|
||||
Identifier.CODEC.optionalFieldOf("parent").forGetter(o -> o.parent.id()),
|
||||
TextureSource.CODEC.optionalFieldOf("textureSource").forGetter(o -> o.textureSource.toOptional()),
|
||||
ColoredLike.CODEC.optionalFieldOf("coloredLike").forGetter(o -> o.coloredLike),
|
||||
SidedOffsetters.CODEC.optionalFieldOf("offsets").forGetter(o -> o.sideOffsetters.toOptional()))
|
||||
.apply(inst, Overlay.Some::new));
|
||||
|
||||
private final Parent parent;
|
||||
private final TextureSource textureSource;
|
||||
private final Optional<ColoredLike> coloredLike;
|
||||
private final SidedOffsetters.Base sideOffsetters;
|
||||
|
||||
public Some(final Optional<Identifier> parent, final Optional<TextureSource> textureSource,
|
||||
final Optional<ColoredLike> coloredLike, final Optional<SidedOffsetters.Base> sideOffsetters) {
|
||||
this.parent = Parent.ofNullable(parent.orElse(null));
|
||||
this.textureSource = textureSource.ofNullable(parent.orElse(null));
|
||||
this.coloredLike = coloredLike;
|
||||
this.sideOffsetters = sideOffsetters.orElse(SidedOffsetters.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformResult apply(MutableQuadView mqv, Float4 us, Float4 vs, Direction dir) {
|
||||
final Float4 finalUs = sidedOffsetters().applyUs(us, dir);
|
||||
float Float4 finalVs = sidedOffsetters().applyVs(vs, dir);
|
||||
return textureSource().apply(mqv, finalUs, finalVs, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureSource textureSource() {
|
||||
if (textureSource != TextureSource.NONE) {
|
||||
return textureSource;
|
||||
} else {
|
||||
return parent.run(parent -> CLIENT_OVERLAYS.getOverlayFor(parent).textureSource(), TextureSource.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ColoredLike> coloredLike() {
|
||||
if (coloredLike.isPresent()) {
|
||||
return coloredLike;
|
||||
} else {
|
||||
return parent.run(parent -> CLIENT_OVERLAYS.getOverlayFor(parent).coloredLike(), Optional.empty());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base sideOffsetters() {
|
||||
if (sideOffsetters != SidedOffsetters.NONE) {
|
||||
return sidedOffsetters;
|
||||
} else {
|
||||
return parent.run(parent -> CLIENT_OVERLAYS.getOverlayFor(parent).sidedOffsetters(),
|
||||
SidedOffsetters.NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import modchest.util.Float4;
|
||||
import modchest.util.ToOptional;
|
||||
import modchest.util.initializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class SidedOffsetters {
|
||||
private SidedOffsetters() {
|
||||
}
|
||||
|
||||
public static final Codec<SidedOffsetters.Base> CODEC = Some.CODEC.xmap(some -> some, base -> (Some) base);
|
||||
public static final Base NONE = new Base() {
|
||||
|
||||
@Override
|
||||
public Optional<Base> toOptional() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float4 applyUs(final Float4 origUs, Direction dir) {
|
||||
return origUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float4 applyVs(final Float4 origVs, Direction dir) {
|
||||
return origVs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, t> T match(Function<Base, t> some, Supplier<T> none) {
|
||||
return none.get();
|
||||
}
|
||||
};
|
||||
|
||||
public interface Base extends ToOptional<Base> {
|
||||
Float4 applyUs(Float4 origUs, Direction dir);
|
||||
|
||||
Float4 applyVs(Float4 origVs, Direction dir);
|
||||
}
|
||||
|
||||
public static class Some implements Base, ToOptional.Some<Base> {
|
||||
public static final Codec<SidedOffsetters.Some> CODEC = CODECS.sidedMapOf(Offsetters.CODEC)
|
||||
.xmap(SidedOffsetters.Some::new, so -> so.map);
|
||||
private final Map<Direction, Offsetters> map;
|
||||
|
||||
public Some(final Map<Direction, Offsetters> map) {
|
||||
for (final Direction dir : Direction.values()) {
|
||||
map.putIfAbsent(dir, Offsetters.NONE);
|
||||
}
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float4 applyUs(Float4 origUs, Direction dir) {
|
||||
return map.get(dir).u.offsett(origUs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float4 applyVs(Float4 origVs, Direction dir) {
|
||||
return map.get(dir).v.offsett(origVs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import java.rmi.registry.Registry;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import modchest.transform.MaterialApplier;
|
||||
import modchest.transform.SpriteApplier;
|
||||
import modchest.transform.TransformResult;
|
||||
import modchest.util.Float4;
|
||||
import modchest.util.ToOptional;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class TextureSource implements ToOptional<TextureSource> {
|
||||
public static class Entry {
|
||||
public final SpriteApplier textureApplier;
|
||||
public final MaterialApplier materialApplier;
|
||||
|
||||
public static final Entry NONE = new Entry();
|
||||
|
||||
private Entry() {
|
||||
this.textureApplier = SpriteApplier.NONE;
|
||||
this.materialApplier = MaterialApplier.NONE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public Entry(Identifier texture, Optional<Identifier> materialSource) {
|
||||
final Sprite sprite = MinecraftClient.getInstance().getSpriteAtlas(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
|
||||
.apply(texture);
|
||||
this.textureApplier = SpriteApplier.ofNullable(sprite);
|
||||
final Optional<BlockState> materialSourceState = materialSource
|
||||
.map(id -> Registry.BLOCK.get(id).getDefaultState());
|
||||
this.materialApplier = MaterialApplier.ofSpriteAndBlockState(sprite, materialSourceState.orElse(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final Codec<TextureSource> CODEC = Codec.STRING
|
||||
.flatXmap(TextureSourceKind::fromString, kind -> DataResult.success(kind.toString()))
|
||||
.dispatch(ts -> ts.kind, kind -> {
|
||||
switch (kind) {
|
||||
case SINGLE:
|
||||
return RecordCodecBuilder.create(
|
||||
inst -> inst.group(Single.SINGLE_CODEC.fieldOf("value").forGetter(i -> (Single) i))
|
||||
.apply(inst, i -> i));
|
||||
case SIDED:
|
||||
return RecordCodecBuilder.create(
|
||||
inst -> inst.group(Sided.SIDED_CODEC.fieldOf("value").forGetter(i -> (Single) i))
|
||||
.apply(inst, i -> i));
|
||||
default:
|
||||
throw new IllegalStateException("Invalid TextureSourceKind:" + kind);
|
||||
}
|
||||
});
|
||||
|
||||
public final TextureSourceKind kind;
|
||||
|
||||
protected TextureSource(final TextureSourceKind kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
public TransformResult apply(final MutableQuadView mqv, final Float4 us, Float4 vs, final Direction side) {
|
||||
final Entry entry = entryFor(side);
|
||||
entry.materialApplier.apply(mqv);
|
||||
return entry.textureApplier.apply(mqv, us, vs);
|
||||
}
|
||||
|
||||
protected abstract Entry entryFor(final Direction side);
|
||||
|
||||
public static class Single extends TextureSource implements ToOptional.Some<TextureSource> {
|
||||
public static final Codec<Single> SINGLE_CODEC = RecordCodecBuilder.create(inst -> inst
|
||||
.group(Identifier.CODEC.fieldOf("texture").forGetter(s -> s.entry.textureApplier.id()),
|
||||
Identifier.CODEC.optionalFieldOf("materialSource").forGetter(s -> s.entry.materialApplier.id()))
|
||||
.apply(inst, Single::new));
|
||||
private final Entry entry;
|
||||
|
||||
public Single(final Identifier texture, final Optional<Identifier> materialSourceId) {
|
||||
super(TextureSourceKind.SINGLE);
|
||||
entry = new Entry(texture, materialSourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry entryFor(Direction side) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Sided extends TextureSource implements ToOptional.Some<TextureSource> {
|
||||
public static final Codec<Sided> SIDED_CODEC;
|
||||
|
||||
static {
|
||||
final Codec<Entry> sidedValueCodec = RecordCodecBuilder.create(inst -> inst.group(
|
||||
Identifier.CODEC.fieldOf("texture").forGetter(e -> e.textureApplier.id()),
|
||||
Identifier.CODEC.optionalFieldOf("materialFrom").forGetter(e -> e.materialApplier.id()))
|
||||
.apply(inst, Entry::new));
|
||||
|
||||
SIDED_CODEC = CODECS.sidedMapOf(sidedValueCodec).xmap(
|
||||
map -> new Sided(new EnumMap<>(map)),
|
||||
sided -> sided.entries);
|
||||
}
|
||||
|
||||
private final EnumMap<Direction, Entry> entries;
|
||||
|
||||
public Sided(final EnumMap<Direction, Entry> entries) {
|
||||
super(TextureSourceKind.SIDED);
|
||||
for (final Direction dir : Direction.values()) {
|
||||
entries.putIfAbsent(dir, Entry.NONE);
|
||||
}
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<TextureSource> toOptional() {
|
||||
return Optional.of(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry entryFor(Direction side) {
|
||||
return entries.get(side);
|
||||
}
|
||||
}
|
||||
|
||||
public static final TextureSource NONE = new TextureSource(null) {
|
||||
@Override
|
||||
public Optional<TextureSource> toOptional() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T match(Function<TextureSource, T> some, Supplier<T> none) {
|
||||
return none.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformResult apply(MutableQuadView mqv, Float4 us, Float4 vs, Direction side) {
|
||||
return TransformResult.NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry entryFor(Direction side) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import com.ibm.icu.impl.locale.LocaleDistance.Data;
|
||||
import com.mojang.serialization.DataResult;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public enum TextureSourceKind {
|
||||
SINGLE,
|
||||
SIDED;
|
||||
|
||||
public static DataResult<TextureSourceKind> fromString(final String string) {
|
||||
switch (string) {
|
||||
case "single":
|
||||
return DataResult.success(SINGLE);
|
||||
case "sided":
|
||||
return DataResult.success(SIDED);
|
||||
default:
|
||||
return DataResult.error("Invalid texture source:" + string);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package modchest.assets.overlay;
|
||||
|
||||
import modchest.util.Float4;
|
||||
import modchest.util.ToOptional;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ZeroOffsetter implements Offsetter, ToOptional.Some<Offsetter> {
|
||||
private final Identifier id;
|
||||
|
||||
public ZeroOffsetter(final Identifier id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float4 offset(final Float4 original) {
|
||||
final float min = original.min();
|
||||
final float max = original.max();
|
||||
final float delta = max - min;
|
||||
|
||||
if (original.a == min) {
|
||||
return Float4.of(0, delta, delta, 0);
|
||||
} else {
|
||||
return Float4.of(delta, 0, 0, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package modchest.block.custom;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import modchest.assets.overlay.Offsetter;
|
||||
import modchest.assets.overlay.OffsetterRegistry;
|
||||
import modchest.util.Identifiable;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class gridCodecs {
|
||||
public final Codec<Direction> DIRECTION = Codec.STRING.flatXmap(
|
||||
name -> {
|
||||
Direction result = Direction.byName(name);
|
||||
if (result != null) {
|
||||
return DataResult.success(result);
|
||||
} else {
|
||||
return DataResult.error("Invalid direction:" + name);
|
||||
}
|
||||
},
|
||||
d -> DataResult.success(d.toString()));
|
||||
|
||||
public final Codec<Offsetter> OFFSETTER = Identifier.CODEC
|
||||
.flatXmap(
|
||||
id -> {
|
||||
final @Nullable Identifiable<Codec<Offsetter>> codec = OffsetterRegistry.get(id);
|
||||
if (codec != null) {
|
||||
return DataResult.success(codec);
|
||||
} else {
|
||||
return DataResult.error("Invalid offsetter type:" + id);
|
||||
}
|
||||
},
|
||||
codec -> DataResult.success(codec.id())
|
||||
)
|
||||
.dispatch(
|
||||
o -> OffsetterRegistry.get(o.getId()),
|
||||
codec -> RecordCodecBuilder.create(inst -> inst.group(
|
||||
codec.value().fieldOf("value").forGetter(c -> c)
|
||||
).apply(inst, c -> c))
|
||||
);
|
||||
|
||||
public <V> Codec<Map<Direction, V>> sideMapOf(final Codec<V> valueCodec) {
|
||||
final Codec<Pair<List<Direction>, V>> itemCodec = RecordCodecBuilder.create(inst -> inst.group(
|
||||
DIRECTION.listOf().fieldOf("sides").forGetter(Pair::getFirst),
|
||||
valueCodec.fieldOf("value").forGetter(Pair::getSecond)
|
||||
.apply(inst, Pair::new));
|
||||
|
||||
return itemCodec.listOf().xmap(
|
||||
pairs -> pairs.stream().flatMap(pair -> pair.getFirst().stream().map(dir -> new Pair<>(dir, pair.getSecond()))).collect(Pair.toMap()),
|
||||
map -> map.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue))
|
||||
.entrySet().stream()
|
||||
.map(e -> new Pair<>(e.getValue().stream().map(Map.Entry::getKey).collect(Collectors.toList()), e.getKey()))
|
||||
.collect(Collectors.toList()));
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package modchest.block.custom;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.transformer.Config;
|
||||
|
||||
public class gridConfig extends Config<OwenElement> {
|
||||
public static final ValueKey<Boolean> SHOW_PLACEMENT_PREVIEW = builder(true)
|
||||
.with((oldValue, newValue) -> gridPreviewOutline.enabled = newValue)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigSerializer<OwenElement> getSerializer() {
|
||||
return FlatOwenSerializer.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull SaveType getSafeType() {
|
||||
return SaveType.ROOT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/*package modchest.block.custom;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.swing.Renderer;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||
import net.minecraft.client.render.model.ModelLoader;
|
||||
import net.minecraft.client.render.model.UnbakedModel;
|
||||
import net.minecraft.client.render.model.json.ModelOverrideList;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class gridModelChange implements UnbakedModel, BakedModel, FabricBakedModel {
|
||||
|
||||
@Override
|
||||
public boolean isVanillaAdapter() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'isVanillaAdapter'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos,
|
||||
Supplier<Random> randomSupplier, RenderContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'emitBlockQuads'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'emitItemQuads'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelOverrideList getOverrides() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOverrides'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sprite getParticleSprite() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getParticleSprite'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(BlockState arg0, Direction arg1, Random arg2) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getQuads'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelTransformation getTransformation() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getTransformation'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDepth() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'hasDepth'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'isBuiltin'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSideLit() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'isSideLit'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'useAmbientOcclusion'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings rotationContainer, Identifier modelId) {
|
||||
|
||||
Get the sprites
|
||||
for (int i = 0; i < SPRITE_IDS.length; ++i) {
|
||||
sprites[i] = textureGetter.apply(SPRITE_IDS[i]);
|
||||
}
|
||||
// Build the mesh using the Renderer API
|
||||
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
|
||||
MeshBuilder builder = renderer.meshBuilder();
|
||||
QuadEmitter emitter = builder.getEmitter();
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
// UP and DOWN share the Y axis
|
||||
int spriteIdx = direction == Direction.UP || direction == Direction.DOWN ? SPRITE_TOP : SPRITE_SIDE;
|
||||
// Add a new face to the mesh
|
||||
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);
|
||||
// Set the sprite of the face, must be called after .square()
|
||||
// We haven't specified any UV coordinates, so we want to use the whole texture.
|
||||
// BAKE_LOCK_UV does exactly that.
|
||||
emitter.spriteBake(sprites[spriteIdx], MutableQuadView.BAKE_LOCK_UV);
|
||||
// Enable texture usage
|
||||
emitter.color(-1, -1, -1, -1);
|
||||
// Add the quad to the mesh
|
||||
emitter.emit();
|
||||
}
|
||||
mesh = builder.build();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> getModelDependencies() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getModelDependencies'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter,
|
||||
Set<Pair<String, String>> unresolvedTextureReferences) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getTextureDependencies'");
|
||||
}
|
||||
|
||||
/*@SuppressWarnings("deprecation")
|
||||
private static final SpriteIdentifier[] SPRITE_IDS = new SpriteIdentifier[] {
|
||||
new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier("minecraft:block/furnace_front_on")),
|
||||
new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("minecraft:block/furnace_top"))
|
||||
};
|
||||
private final Sprite[] sprites = new Sprite[SPRITE_IDS.length];
|
||||
|
||||
// Some constants to avoid magic numbers, these need to match the SPRITE_IDS
|
||||
private static final int SPRITE_SIDE = 0;
|
||||
private static final int SPRITE_TOP = 1;
|
||||
|
||||
private Mesh mesh;
|
||||
|
||||
} */
|
|
@ -0,0 +1,203 @@
|
|||
package modchest.block.custom;
|
||||
|
||||
import static net.minecraft.block.Block.field_31022;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
import modchest.event.playerAfterRespawnEvent;
|
||||
import modchest.grid.gridBlock;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
|
||||
import net.fabricmc.tinyremapper.extension.mixin.hard.util.CamelPrefixString;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.TexturedRenderLayers;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.util.math.Vector3d;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.math.Vector4f;
|
||||
|
||||
public class gridPreviewOutline {
|
||||
public static boolean enanbled = true;
|
||||
|
||||
public static void renderPreviewOutline(final WorldRenderContext context) {
|
||||
if (!enanbled) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
||||
final ClientPlayerEntity player = client.player;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack stack = player.getStackInHand(Hand.MAIN_HAND);
|
||||
if (!(stack.getItem() instanceof BlockItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Block block = ((BlockItem) stack.getItem()).getBlock();
|
||||
if (!(block instanceof gridBlock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(client.crosshairTarget instanceof BlockHitResult)
|
||||
|| client.crosshairTarget.getType() == HitResult.Type.MISS || client.world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockHitResult hitResult = (BlockHitResult) client.crosshairTarget;
|
||||
final ItemPlacementContext placementContext = new ItemPlacementContext(player, Hand.MAIN_HAND, stack,
|
||||
hitResult);
|
||||
final BlockState blockState = ((BlockItemAccess) player.getMainHandStack().getItem())
|
||||
.getPlacementStateProxy(placementContext);
|
||||
|
||||
if (blockState == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockPos pos = placementContext.getBlockPos();
|
||||
final BakedModel model = client.getBlockRenderManager().getModel(blockState);
|
||||
final boolean valid;
|
||||
|
||||
if (block == Blocks.GRID_DOOR) {
|
||||
final BlockPos upPos = pos.up();
|
||||
final BlockState upState = blockState.with(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER);
|
||||
final BakedModel upModel = client.getBlockRenderManager().getModel(upState);
|
||||
final boolean upValid = new ItemPlacementContext(player, Hand.MAIN_HAND, stack,
|
||||
hitResult.withBlockPos(upPos)).canReplaceExisting() || client.world.getBlockState(upPos).isAir();
|
||||
final boolean downValid = blockState.canPlaceAt(client.world, pos)
|
||||
&& (placementContext.canPlace() || client.world.getBlockState(pos).isAir());
|
||||
if (!upValid) {
|
||||
valid = false;
|
||||
} else {
|
||||
valid = downValid;
|
||||
}
|
||||
|
||||
renderPreview(context, client.world, upState, upPos, upModel, upValid && downValid);
|
||||
|
||||
} else {
|
||||
valid = blockState.canPlaceAt(client.world, pos)
|
||||
&& (placementContext.canPlace() || client.world.getBlockState(pos).isAir());
|
||||
}
|
||||
|
||||
renderPreview(context, client.world, blockState, pos, model, valid);
|
||||
}
|
||||
|
||||
private static void renderPreview(final WorldRenderContext context, final ClientWorld world,
|
||||
final BlockState blockState, final BlockPos pos, final BakedModel model, final boolean valid) {
|
||||
final MatrixStack matrixStack = context.matrixStack();
|
||||
final Camera camera = context.camera();
|
||||
final int ticks = ((WorldRendererAccess) context.worldRenderer()).ticks();
|
||||
final float tickDelta = context.tickDelta();
|
||||
|
||||
for (int directionId = 0; directionId <= 6; directionId++) {
|
||||
final List<BakedQuad> quads = model.getQuads(blockState, ModelHelper.faceFromIndex(directionId),
|
||||
world.random);
|
||||
|
||||
matrixStack.push();
|
||||
matrixStack.translate(-camera.getPos().x, -camera.getPos().y, -camera.getPos().z);
|
||||
matrixStack.translate(pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
if (blockState.contains(Properties.HORIZONTAL_FACING)) {
|
||||
matrixStack.translate(0.5, 0.5, 0.5);
|
||||
matrixStack.translate(-0.5, -0.5, -0.5);
|
||||
}
|
||||
|
||||
final float scale = 1F - (1F / 60) + ((float) Math.sin((ticks + tickDelta) / 4.5F) / 60);
|
||||
matrixStack.translate(-0.5 * scale, -0.5 * scale, -0.5 * scale);
|
||||
matrixStack.translate(scale, scale, scale);
|
||||
matrixStack.translate(0.5 / scale, 0.5 / scale, 0.5 / scale);
|
||||
|
||||
final int c = 0;
|
||||
final int r = valid ? c : 255;
|
||||
final int g = valid ? 255 : c;
|
||||
final int b = valid ? 64 : 0;
|
||||
final int a = valid ? 191 : 63;
|
||||
|
||||
final MatrixStack.Entry entry = matrixStack.peek();
|
||||
|
||||
final VertexConsumer faces = context.consumers()
|
||||
.getBuffer(TexturedRenderLayers.getItemEntityTranslucentCull());
|
||||
for (final BakedQuad quad : quads) {
|
||||
render(quad, entry, faces, r, g, b, a);
|
||||
}
|
||||
matrixStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private static void render(final BakedQuad quad, final MatrixStack.Entry entry, final VertexConsumer consumer,
|
||||
final float r, final float g, final float b, final float a) {
|
||||
final int[] vertexData = quad.getVertexData();
|
||||
final Vec3i vector = quad.getFace().getVector();
|
||||
final Vector3f newVector = new Vector3f((float) vec3i.getX(), (float) vec3i.getY(), (float) vec3i.getZ());
|
||||
final Matrix4f model = entry.getModel();
|
||||
newVector.transform(entry.getNormal());
|
||||
|
||||
final int j = vertexData.length / 8;
|
||||
final MemoryStack memoryStack = MemoryStack.stackPush();
|
||||
Throwable var17 = null;
|
||||
|
||||
try {
|
||||
final ByteBuffer byteBuffer = memoryStack
|
||||
.malloc(VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL.getVertexSize());
|
||||
final IntBuffer intBuffer = byteBuffer.asIntBuffer();
|
||||
|
||||
for (int k = 0; k < j; ++k) {
|
||||
intBuffer.clear();
|
||||
intBuffer.put(vertexData, k * 8, 8);
|
||||
final float x = byteBuffer.getFloat(0);
|
||||
final float y = byteBuffer.getFloat(4);
|
||||
final float z = byteBuffer.getFloat(8);
|
||||
final float v;
|
||||
final float w;
|
||||
|
||||
final int u = 0x00F000F0;
|
||||
v = byteBuffer.getFloat(16);
|
||||
w = byteBuffer.getFloat(20);
|
||||
final Vector4f vector4f = new Vector4f(x, y, z, 1.0F);
|
||||
vector4f.transform(model);
|
||||
consumer.vertex(vector4f.getX(), vector4f.getY(), vector4f.getZ(), r / 255F, g / 255F, b / 255F,
|
||||
a / 255F, v, w, OverlayTexture.DEFAULT_UV, u, newVector.getX(), newVector.getY(),
|
||||
newVector.getZ());
|
||||
}
|
||||
} catch (final Throwable var38) {
|
||||
var17 = var38;
|
||||
throw var38;
|
||||
} finally {
|
||||
if (var17 != null) {
|
||||
try {
|
||||
memoryStack.close();
|
||||
} catch (final Throwable var37) {
|
||||
var17.addSuppressed(var37);
|
||||
}
|
||||
} else {
|
||||
memoryStack.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package modchest.gui;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class gridScreen extends CottonInventoryScreen<gridGuiDescription>{
|
||||
@SuppressWarnings("deprecation")
|
||||
public static final ScreenRegistry.Factory<gridGuiDescription, gridScreen> FACTORY = (desc, playerInventory, title) ->
|
||||
new gridScreen(desc, playerInventory.player, title);
|
||||
|
||||
public gridScreen(final gridGuiDescription description, final PlayerEntity player, final Text title) {
|
||||
super(description, player, title);
|
||||
}
|
||||
}
|
|
@ -1,66 +1,230 @@
|
|||
package modchest.networking.packet;
|
||||
/*
|
||||
* package modchest.networking.packet;
|
||||
*
|
||||
* import static net.minecraft.block.Block.getBlockFromItem;
|
||||
*
|
||||
* import java.util.Random;
|
||||
*
|
||||
* import modchest.block.custom.grid.gridBlock;
|
||||
* import modchest.rendering.gridBlockTexture;
|
||||
* import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
* import net.minecraft.block.Block;
|
||||
* import net.minecraft.block.BlockState;
|
||||
* import net.minecraft.block.Blocks;
|
||||
* import net.minecraft.block.entity.BlockEntity;
|
||||
* import net.minecraft.client.MinecraftClient;
|
||||
* import net.minecraft.client.color.block.BlockColors;
|
||||
* import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
* import net.minecraft.client.render.BufferBuilder;
|
||||
* import net.minecraft.client.render.OverlayTexture;
|
||||
* import net.minecraft.client.render.RenderLayer;
|
||||
* import net.minecraft.client.render.Tessellator;
|
||||
* import net.minecraft.client.render.VertexConsumer;
|
||||
* import net.minecraft.client.render.VertexConsumerProvider;
|
||||
* import net.minecraft.client.render.VertexFormat;
|
||||
* import net.minecraft.client.render.VertexFormats;
|
||||
* import net.minecraft.client.render.WorldRenderer;
|
||||
* import net.minecraft.client.render.block.BlockModelRenderer;
|
||||
* import net.minecraft.client.render.entity.ItemFrameEntityRenderer;
|
||||
* import net.minecraft.client.render.model.BakedModel;
|
||||
* import net.minecraft.client.util.ModelIdentifier;
|
||||
* import net.minecraft.client.util.SpriteIdentifier;
|
||||
* import net.minecraft.client.util.math.MatrixStack;
|
||||
* import net.minecraft.entity.decoration.ItemFrameEntity;
|
||||
* import net.minecraft.entity.player.PlayerEntity;
|
||||
* import net.minecraft.nbt.NbtCompound;
|
||||
* import net.minecraft.network.PacketByteBuf;
|
||||
* import net.minecraft.text.Text;
|
||||
* import net.minecraft.util.Identifier;
|
||||
* import net.minecraft.util.math.BlockPos;
|
||||
* import net.minecraft.util.math.Matrix3f;
|
||||
* import net.minecraft.util.math.Matrix4f;
|
||||
* import net.minecraft.world.BlockRenderView;
|
||||
*
|
||||
* public class gridRenderRequestS2CPacket extends BlockModelRenderer {
|
||||
*
|
||||
* public gridRenderRequestS2CPacket(BlockColors colors) {
|
||||
* super(colors);
|
||||
* // TODO Auto-generated constructor stub
|
||||
* }
|
||||
*
|
||||
*
|
||||
*
|
||||
* public static void receive(MinecraftClient minecraftClient,
|
||||
* ClientPlayNetworkHandler clientPlayNetworkHandler,
|
||||
* PacketByteBuf buffer, PacketSender PacketSender) {
|
||||
*
|
||||
* NbtCompound nbtgrid = buffer.readNbt();
|
||||
* int[] gridPostitionAr = nbtgrid.getIntArray("gridBlockPos");
|
||||
* int x = gridPostitionAr[0];
|
||||
* int y = gridPostitionAr[1];
|
||||
* int z = gridPostitionAr[2];
|
||||
* BlockPos gridBlockPos = new BlockPos(x, y, z);
|
||||
*
|
||||
*
|
||||
* /*PlayerEntity playerEntity = minecraftClient.player;
|
||||
* playerEntity.sendMessage(Text.of("gridRenderRequestS2CPacket.receive"));
|
||||
* BlockRenderView world = minecraftClient.world;
|
||||
*
|
||||
* NbtCompound nbtgrid = buffer.readNbt();
|
||||
* int[] gridPostitionAr = nbtgrid.getIntArray("gridBlockPos");
|
||||
* int x = gridPostitionAr[0];
|
||||
* int y = gridPostitionAr[1];
|
||||
* int z = gridPostitionAr[2];
|
||||
* BlockPos gridBlockPos = new BlockPos(x, y, z);
|
||||
*
|
||||
* /*
|
||||
* long seed = nbtgrid.getLong("WorldSeed");
|
||||
* Random randomGrid = new Random(seed);
|
||||
* BlockState gridBlockState = world.getBlockState(gridBlockPos);
|
||||
* //playerEntity.sendMessage(Text.of(gridBlockState.toString())); //
|
||||
* {minecraft:spruce_planks}
|
||||
* Block BlockInHand =
|
||||
* getBlockFromItem(playerEntity.getMainHandStack().getItem());
|
||||
* String inHandData = BlockInHand.getDefaultState().toString();
|
||||
* //playerEntity.sendMessage(Text.of(inHandData)); // Bsp:
|
||||
* {minecraft:warped_planks}
|
||||
* BlockState stateInHand = BlockInHand.getDefaultState();
|
||||
* Object obj = inHandData.split("minecraft:");
|
||||
* //playerEntity.sendMessage(Text.of(obj.toString())); // Bsp:
|
||||
* java.lang.string;@4f4001c7
|
||||
* Identifier gridBlockId = new Identifier("modchest", "block/grid_block"); //
|
||||
* Mod-ID + Blockpfad
|
||||
* //playerEntity.sendMessage(Text.of(gridBlockId.toString()));
|
||||
* // minecraftClient.getBakedModelManager().getBlockModels();
|
||||
* // minecraftClient.getSpriteAtlas(gridBlockTexture.getBlockInHandId(null));
|
||||
* playerEntity.sendMessage(Text.of("before bracket"));
|
||||
*
|
||||
* //ModelIdentifier gridModelId = (ModelIdentifier) gridBlockId; -> geht nicht,
|
||||
* gridBlockId nicht instance of ModelIdentifier
|
||||
* // playerEntity.sendMessage(Text.of(gridModelId.toString()));
|
||||
* //BakedModel gridModel =
|
||||
* MinecraftClient.getInstance().getBakedModelManager().getModel(gridModelId);
|
||||
* //int overlay = OverlayTexture.DEFAULT_UV;
|
||||
* //MatrixStack matrix = new MatrixStack();
|
||||
* //MatrixStack.Entry matrix;
|
||||
* //Tessellator tessellator = Tessellator.getInstance();
|
||||
* //Matrix4f positionMatrix =
|
||||
* drawContext.getMatrices().peek().getPositionMatrix();
|
||||
* //BufferBuilder builder = tessellator.getBuffer();
|
||||
* /*builder.begin(VertexFormat.DrawMode.QUADS,
|
||||
* VertexFormats.POSITION_COLOR_TEXTURE);
|
||||
* builder.vertex(positionMatrix, 20, 20, 0).color(1f, 1f, 1f, 1f).texture(0f,
|
||||
* 0f).next();
|
||||
* builder.vertex(positionMatrix, 20, 60, 0).color(1f, 0f, 0f, 1f).texture(0f,
|
||||
* 1f).next();
|
||||
* builder.vertex(positionMatrix, 60, 60, 0).color(0f, 1f, 0f, 1f).texture(1f,
|
||||
* 1f).next();
|
||||
* builder.vertex(positionMatrix, 60, 20, 0).color(0f, 0f, 1f, 1f).texture(1f,
|
||||
* 0f).next();
|
||||
* // RenderSystem.setShader(null);
|
||||
* // RenderSystem.setShaderTexture(0, new Identifier("REServerMod",
|
||||
* // "block/grid_block_texture.png"));
|
||||
* // RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
|
||||
* tessellator.draw();
|
||||
* builder.begin(VertexFormat.DrawMode.QUADS,
|
||||
* VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL); //kaputt
|
||||
* builder.vertex(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1); //kaputt
|
||||
* builder.popState(); //funktioniert ohne Zwei Zeilen davor
|
||||
*/
|
||||
// drawContext.getMatrices().peek().getPositionMatrix(): Matrix4f positionMatrix
|
||||
// = drawContext.getMatrices().peek().getPositionMatrix();
|
||||
|
||||
import static net.minecraft.block.Block.getBlockFromItem;
|
||||
|
||||
/*import modchest.rendering.gridBlockRender;
|
||||
import modchest.rendering.gridBlockTexture;*/
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.render.block.BlockModelRenderer;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class gridRenderRequestS2CPacket extends BlockModelRenderer {
|
||||
|
||||
public gridRenderRequestS2CPacket(BlockColors colors) {
|
||||
super(colors);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public static void receive(MinecraftClient minecraftClient, ClientPlayNetworkHandler clientPlayNetworkHandler,
|
||||
PacketByteBuf buffer, PacketSender PacketSender) {
|
||||
// clientPlayNetworkHandler.getWorld();
|
||||
NbtCompound nbtgrid = buffer.readNbt();
|
||||
int[] positionarray = nbtgrid.getIntArray("BlockPosition");
|
||||
Integer h = positionarray[0];
|
||||
Integer i = positionarray[1];
|
||||
Integer j = positionarray[2];
|
||||
|
||||
BlockPos gridBlockPos = new BlockPos(h, i, j);
|
||||
|
||||
// minecraftClient.getBakedModelManager().getBlockModels();
|
||||
// minecraftClient.getSpriteAtlas(gridBlockTexture.getBlockInHandId(null));
|
||||
|
||||
//BlockRenderView world = minecraftClient.world;
|
||||
|
||||
/*@Nullable
|
||||
BlockState gridBlockState = getStateFromRawId(FORCE_STATE);
|
||||
MatrixStack matrix = new MatrixStack();
|
||||
MatrixStack.Entry entry;
|
||||
Random randomGrid = new Random();
|
||||
long seed = 7756495;*/
|
||||
|
||||
PlayerEntity playerEntity = minecraftClient.player;
|
||||
Block BlockInHand = getBlockFromItem(playerEntity.getMainHandStack().getItem());
|
||||
String inHandData = BlockInHand.getDefaultState().toString();
|
||||
playerEntity.sendMessage(Text.of(inHandData));
|
||||
|
||||
//Identifier testBlockId = new Identifier("modchest", "block/test_block"); // Mod-ID + Blockpfad
|
||||
//ModelIdentifier testModelId = new ModelIdentifier(testBlockId, "all"); // Verwende "normal" als Variante
|
||||
//BakedModel gridModel = MinecraftClient.getInstance().getBakedModelManager().getModel(testModelId);
|
||||
|
||||
/*
|
||||
* gridBlockRender.render(world, BakedModel model, gridBlockState, gridBlockPos,
|
||||
* matrix, gridConsumer, true, randomGrid, seed, overlay);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Tessellator tessellator = Tessellator.getInstance();
|
||||
* BufferBuilder bufferBuilder = tessellator.getBuffer();
|
||||
*
|
||||
* MatrixStack matrices = new MatrixStack();
|
||||
* BlockState defaultState = Blocks.STONE.getDefaultState();
|
||||
* playerEntity.sendMessage(Text.of(defaultState.toString()));
|
||||
* VertexConsumerProvider consumers =
|
||||
* VertexConsumerProvider.immediate(bufferBuilder);
|
||||
* playerEntity.sendMessage(Text.of(consumers.toString()));
|
||||
* Identifier TEXTURE = new Identifier("modchest",
|
||||
* "textures/block/texture_test.png");
|
||||
* playerEntity.sendMessage(Text.of(TEXTURE.toString()));
|
||||
* //SpriteIdentifier SPRITE = ;
|
||||
* //SpriteIdentifier#getVertexConsumer( consumers, LAYER_SUPPLIER ) // to use a
|
||||
* sprite as a texture
|
||||
* //VertexConsumer consumer = consumers.getBuffer(RenderLayer.getCutout());
|
||||
* //VertexConsumer consumer =
|
||||
* consumers.getBuffer(RenderLayer.getEntityCutout(TEXTURE));
|
||||
* //playerEntity.sendMessage(Text.of(consumer.toString()));
|
||||
* /*MatrixStack.Entry matrix = matrices.peek();
|
||||
* matrices.push();
|
||||
* matrices.translate(0.5, 0.5, 0.5);
|
||||
* Matrix4f model = matrix.getPositionMatrix();
|
||||
* Matrix3f normal = matrix.getNormalMatrix();
|
||||
* int r = 225;
|
||||
* int g = 255;
|
||||
* int b = 255;
|
||||
* int a = 200;
|
||||
*
|
||||
* //int light = gridBlockState.getLuminance();
|
||||
* int light = WorldRenderer.getLightmapCoordinates(world, gridBlockPos);
|
||||
* int overlay = OverlayTexture.DEFAULT_UV;
|
||||
*
|
||||
* consumer.vertex(model, -0.5f, -0.5f, -0.5f).color(r, g, b, a).texture(0,
|
||||
* 0).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* consumer.vertex(model, 0.5f, -0.5f, -0.5f).color(r, g, b, a).texture(1,
|
||||
* 0).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* consumer.vertex(model, 0.5f, -0.5f, 0.5f).color(r, g, b, a).texture(1,
|
||||
* 1).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* consumer.vertex(model, -0.5f, -0.5f, 0.5f).color(r, g, b, a).texture(0,
|
||||
* 1).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* matrices.pop();
|
||||
*
|
||||
* MinecraftClient.getInstance().getBlockRenderManager().renderBlockAsEntity(
|
||||
* defaultState, matrices, consumers, light, overlay);
|
||||
*
|
||||
* /*
|
||||
*
|
||||
* SpriteIdentifier SPRITE =;
|
||||
* // solid layer, no texture
|
||||
* VertexConsumer consumer = consumers.getBuffer(RenderLayer.getSolid());
|
||||
* // cutout layer, textured
|
||||
* VertexConsumer consumer =
|
||||
* consumers.getBuffer(RenderLayer.getEntityCutout(TEXTURE));
|
||||
* // cutout layer, textured (sprite)
|
||||
* VertexConsumer consumer = SPRITE.getVertexConsumer(consumers,
|
||||
* RenderLayer::getEntityCutout);
|
||||
* Identifier texture = new Identifier("textures/block/texture_test.png");
|
||||
* // set texture and enable transparency
|
||||
* VertexConsumer consumer =
|
||||
* consumers.getBuffer(RenderLayer.getEntityTranslucentCull(texture));
|
||||
* MatrixStack.Entry matrix = matrices.peek();
|
||||
* // translate to the middle of the block
|
||||
* matrices.push();
|
||||
* matrices.translate(0.5, 0.5, 0.5);
|
||||
* Matrix4f model = matrix.getModel();
|
||||
* Matrix3f normal = matrix.getNormal();
|
||||
* int r = 255;
|
||||
* int g = 255;
|
||||
* int b = 255;
|
||||
* int a = 200;
|
||||
* // use the value provided (in block entity renderer) for breaking animation,
|
||||
* or
|
||||
* // use 'OverlayTexture.DEFAULT_UV' to disable breaking animation
|
||||
* int overlay = OverlayTexture.DEFAULT_UV;
|
||||
* // provided by block entity renderer, or queried from WorldRenderer:
|
||||
* // (use only to query light at positions different than provided)
|
||||
* int light = WorldRenderer.getLightmapCoordinates(world, gridBlockPos);
|
||||
* // emit 4 vertices - one quad
|
||||
* consumer.vertex(model, -0.5f, -0.5f, -0.5f).color(r, g, b, a).texture(0,
|
||||
* 0).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* consumer.vertex(model, 0.5f, -0.5f, -0.5f).color(r, g, b, a).texture(1,
|
||||
* 0).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* consumer.vertex(model, 0.5f, -0.5f, 0.5f).color(r, g, b, a).texture(1,
|
||||
* 1).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* consumer.vertex(model, -0.5f, -0.5f, 0.5f).color(r, g, b, a).texture(0,
|
||||
* 1).overlay(overlay).light(light).normal(normal, 0.0F, 1.0F, 0.0F).next();
|
||||
* matrices.pop();
|
||||
*
|
||||
*
|
||||
* // gridBlockRender.render(world, gridModel, gridBlockState, gridBlockPos,
|
||||
* // matrix, gridConsumer, true, randomGrid, seed, overlay);
|
||||
*
|
||||
* }
|
||||
*
|
||||
* }
|
||||
*/
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
package modchest.rendering;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.block.BlockModelRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
public class gridBlockRender extends BlockModelRenderer{
|
||||
|
||||
public gridBlockRender(BlockColors colors) {
|
||||
super(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BlockRenderView world, BakedModel model, BlockState state, BlockPos pos,
|
||||
MatrixStack matrices, VertexConsumer vertexConsumer, boolean cull, Random random, long seed, int overlay) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package modchest.transform;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import modchest.util.Float4;
|
||||
import modchest.util.ToOptional;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class BaseApplier implements ToOptional<BaseApplier> {
|
||||
public abstract TransformResult apply(MutableQuadView mqv, Direction dir, int index, Float4 vs, int color);
|
||||
|
||||
public static final BaseApplier NONE = new BaseApplier() {
|
||||
@Override
|
||||
public TransformResult apply(MutableQuadView mqv, Direction dir, int index, Float4 vs, int color) {
|
||||
return TransformResult.NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BaseApplier> toOptional() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T match(final Function<BaseApplier, T> some, final Supplier<T> none) {
|
||||
return none.get();
|
||||
}
|
||||
};
|
||||
|
||||
public static class Some extends BaseApplier implements ToOptional.Some<BaseApplier> {
|
||||
private final BlockState state;
|
||||
private final Object2IntMap<Direction> sizes = new Object2IntOpenHashMap<>(7);
|
||||
private final Map<Direction, SpriteApplier[]> spriteAppliers = new HashMap<>(7);
|
||||
private final Map<Direction, MaterialApplier[]> materialAppliers = new HashMap<>(7);
|
||||
private final Map<Direction, LazyColorApplier[]> colorAppliers = new HashMap<>(7);
|
||||
|
||||
public Some(final BlockState state, final BakedModel model, final Random r) {
|
||||
this.state= state;
|
||||
for (int i = 0; i<= 6; i++) {
|
||||
final Direction dir = ModelHelper.faceFromIndex(i);
|
||||
final List<BakedQuad> quads = model.getQuads(state, dir, r);
|
||||
final int size = quads.size();
|
||||
sizes.put(dir, size);
|
||||
final SpriteApplier[] spriteAppliers = this.spriteAppliers.computeIfAbsent(dir, x -> new SpriteAppliers[size]);
|
||||
final MaterialApplier[] materialAppliers = this.materialAppliers.computeIfAbsent(dir, x -> new MaterialApplier[size]);
|
||||
final LazyColorApplier[] colorAppliers = this.colorAppliers.computeIfAbsent(dir, x -> new LazyColorApplier[size]);
|
||||
|
||||
for(int j = 0; j < size; j++) {
|
||||
final BakedQuad quad = quads.get(j);
|
||||
final Sprite sprite = ((BakedQuadAccess) quad).sprite();
|
||||
spriteAppliers[j] = new SpriteApplier.Some(sprite);
|
||||
materialAppliers[j] = new MaterialApplier,ofSpriteAndBlockState(sprite, state);
|
||||
|
||||
if (quad.hasColor()) {
|
||||
colorAppliers[j] = new LazyColorApplier.Some();
|
||||
} else {
|
||||
colorAppliers[j] = LazyColorApplier.NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformResult apply(MutableQuadView mqv, Direction dir, int quadIndex, Float4 vs, int color) {
|
||||
int size = sizes.getInt(dir);
|
||||
if (size == 0) {
|
||||
return TransformResult.failed(String.format("No %s quads in model for %s", dir, state));
|
||||
}
|
||||
final int index = quadIndex % size;
|
||||
materialAppliers.get(dir)[index].apply(mqv);
|
||||
colorAppliers.get(dir)[index].apply(mqv, color);
|
||||
return spriteAppliers.get(dir)[index].apply(mqv, us, vs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package modchest.transform;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import modchest.util.ToOptional;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class ColorApplier implements ToOptional<ColorApplier> {
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public static ColorApplier ofOptional(final OptionalInt optional) {
|
||||
if (optional.isPresent()) {
|
||||
return new Some(optional.getAsInt());
|
||||
} else {
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void apply(MutableQuadView mqv);
|
||||
|
||||
@SuppressWarnings("java:S1186")
|
||||
public static final ColorApplier NONE = new ColorApplier() {
|
||||
@Override
|
||||
public void apply(final MutableQuadView mqv) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ColorApplier> toOptional() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T match(final Function<ColorApplier, T> some, final Supplier<T> none) {
|
||||
return none.get();
|
||||
}
|
||||
};
|
||||
|
||||
public static class Some extends ColorApplier implements ToOptional.Some<ColorApplier> {
|
||||
private final int color;
|
||||
|
||||
public Some(final int color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(final MutableQuadView mqv) {
|
||||
mqv.spriteColor(0, color, color, color, color);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package modchest.transform;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class LazyColorApplier {
|
||||
@SuppressWarnings("java:S1186")
|
||||
public static final LazyColorApplier NONE = new LazyColorApplier() {
|
||||
@Override
|
||||
public void apply(final MutableQuadView mqv, final int color) {
|
||||
}
|
||||
};
|
||||
|
||||
public abstract void apply(MutableQuadView mqv, int color);
|
||||
|
||||
public static class Some extends LazyColorApplier {
|
||||
@Override
|
||||
public void apply(final MutableQuadView mqv, final int color) {
|
||||
mqv.spriteColor(0, color, color, color, color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package modchest.transform;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class MaterialApplier {
|
||||
public static MaterialApplier ofSpriteAndBlockState(@NotNull final Sprite sprite, @NotNull final BlockState blockState) {
|
||||
if (blockState == null) {
|
||||
return NONE;
|
||||
}
|
||||
final RenderMaterial material = MaterialMap.get(blockState).getMapped(sprite);
|
||||
final Identifier id = Registry.BLOCK.getId(blockState.getBlock());
|
||||
return MaterialApplier.ofNullable(id, material);
|
||||
}
|
||||
|
||||
public static final MaterialApplier NONE = new MaterialApplier() {
|
||||
@Override
|
||||
public void apply(final MutableQuadView mqv) {}
|
||||
|
||||
@Override
|
||||
public Optional<Identifier> id() {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
|
||||
public abstract void apply(MutableQuadView mqv);
|
||||
public abstract Optional<Identifier> id();
|
||||
|
||||
public static class Some extends MaterialApplier {
|
||||
private final @NotNull Identifier id;
|
||||
private final @NotNull RenderMaterial toApply;
|
||||
|
||||
public Some(final @NotNull Identifier id, final @NotNull RenderMaterial toApply) {
|
||||
this.toApply = toApply;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(final MutableQuadView mqv) {
|
||||
mqv.material(toApply);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Identifier> id() {
|
||||
return Optional.of(id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package modchest.transform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import modchest.util.Float4;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.minecraft.client.texture.MissingSprite;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class SpriteApplier {
|
||||
public static SpriteApplier ofNullable(@Nullable final Sprite toApply) {
|
||||
if (toApply != null) {
|
||||
return new Some(toApply);
|
||||
} else {
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract TransformResult apply(MutableQuadView mqv, Float4 us, Float4 vs);
|
||||
|
||||
public abstract Identifier id();
|
||||
|
||||
public static final SpriteApplier NONE = new SpriteApplier() {
|
||||
@Override
|
||||
public TransformResult apply(final MutableQuadView mqv, final Float4 us, final Float4 vs) {
|
||||
return TransformResult.NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier id() {
|
||||
return MissingSprite.getMissingSpriteId();
|
||||
}
|
||||
};
|
||||
|
||||
public static class Some extends SpriteApplier {
|
||||
private final Sprite toApply;
|
||||
|
||||
public Some(final Sprite toApply) {
|
||||
this.toApply = toApply;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformResult apply(final MutableQuadView mqv, final Float4 us, final Float4 vs) {
|
||||
mqv.sprite(0, 0, MathHelper.lerp(us.a, toApply.getMinU(), toApply.getMaxU()),
|
||||
MathHelper.lerp(vs.a, toApply.getMinV(), toApply.getMaxV()));
|
||||
mqv.sprite(1, 0, MathHelper.lerp(us.b, toApply.getMinU(), toApply.getMaxU()),
|
||||
MathHelper.lerp(vs.b, toApply.getMinV(), toApply.getMaxV()));
|
||||
mqv.sprite(2, 0, MathHelper.lerp(us.c, toApply.getMinU(), toApply.getMaxU()),
|
||||
MathHelper.lerp(vs.c, toApply.getMinV(), toApply.getMaxV()));
|
||||
mqv.sprite(3, 0, MathHelper.lerp(us.d, toApply.getMinU(), toApply.getMaxU()),
|
||||
MathHelper.lerp(vs.d, toApply.getMinV(), toApply.getMaxV()));
|
||||
return TransformResult.DID_SOMETHING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier id() {
|
||||
return toApply.getId();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package modchest.transform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class TransformResult {
|
||||
public enum Status {
|
||||
DID_SOMETHING,
|
||||
NOTHING_TO_DO,
|
||||
FAILED,;
|
||||
}
|
||||
|
||||
public static final TransformResult DID_SOMETHING = new TransformResult(Status.DID_SOMETHING, null);
|
||||
public static final TransformResult NOTHING_TO_DO = new TransformResult(Status.NOTHING_TO_DO, null);
|
||||
|
||||
public final Status status;
|
||||
public final @Nullable String message;
|
||||
|
||||
private TransformResult(Status status, @Nullable String message) {
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static TransformResult failed(String message) {
|
||||
return new TransformResult(Status.FAILED, message);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package modchest.transform;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import modchest.block.custom.grid.gridSlotInfo;
|
||||
import modchest.grid.data.gridData;
|
||||
import modchest.util.Float4;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Overlay;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture.Data;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class gridTransform implements RenderContext.QuadTransform {
|
||||
public static final QuadTransformRegistry.QuadTransformSource SOURCE = new QuadTransformRegistry.QuadTransformSource() {
|
||||
|
||||
@Override
|
||||
public RenderContext.QuadTransform getForBlock(final BlockRenderView brv, final BlockState state,
|
||||
final BlockPos pos, final Supplier<Random> randomSupplier) {
|
||||
return new gridTransform(brv, state, pos, randomSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderContext.QuadTransform getForItem(final ItemStack stack, final Supplier<Random> randomSupplier) {
|
||||
final gridSlotInfo slotInfo = (gridSlotInfo) ((BlockItem) stack.getItem()).getBlock();
|
||||
if (!stack.hasTag()) {
|
||||
return new gridTransform(slotInfo, new gridData(slotInfo.sections()), randomSupplier);
|
||||
} else {
|
||||
return new gridTransform(slotInfo,
|
||||
gridData.fromTag(stack.getSubTag("BlockEntityTag").getCompound("gridData")), randomSupplier);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final EnumMap<Direction, Integer> transformCount = new EnumMap<>(Direction.class);
|
||||
|
||||
@Override
|
||||
public boolean transform(MutableQuadView mqv) {
|
||||
if (mqv.tag() == 0) {
|
||||
return true;
|
||||
}
|
||||
final Direction dir = mqv.lightFace();
|
||||
final int quadIndex = transformedCount.computeIfAbsent(dir, d-> 0);
|
||||
transformedCount.put(dir, quadIndex + 1);
|
||||
final int partIndex = getPartIndex(mqv, dir);
|
||||
final Data data = this.data[partIndex];
|
||||
final Pair<Float4, Float4> origUvs = getUvs(mqv, dir);
|
||||
|
||||
if (mqv.tag() == 1) {
|
||||
TransformResult result = data.baseApplier.apply(mqv, dir, quadIndex, origUvs.getFirst(), origUvs.getSecond(), data.baseColor);
|
||||
switch (result.status) {
|
||||
case DID_SOMETHING:
|
||||
case NOTHING_TO_DO:
|
||||
return true;
|
||||
case FAILED:
|
||||
META:LOGGER.warn("An error occured with a gridEntity:" + result.message);
|
||||
return false;
|
||||
}
|
||||
} else if (mqv.tag() == 2) {
|
||||
TransformResult result = data.overlay.match(overlay -> {
|
||||
data.overlayColorApplier.apply(mqv);
|
||||
return overlay.apply(mqv, dir, quadIndex, origUvs.getFirst(), origUvs.getSecond(), data.baseColor)
|
||||
},
|
||||
() -> data.baseApplier.apply(mqv, dir, quadIndex, origUvs.getFirst(), origUvs.getSecond(), data.baseColor)
|
||||
);
|
||||
|
||||
switch (result.status) {
|
||||
case DID_SOMETHING:
|
||||
return true;
|
||||
case NOTHING_TO_DO:
|
||||
return false;
|
||||
case FAILED:
|
||||
META:LOGGER.warn("An error occured with a gridEntity:" + result.message);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
META.LOGGER.warn("Somehow gridTransform::transform didn't return a valid value");
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private static class Data {
|
||||
public final BaseApplier baseApplier;
|
||||
public final Overlay overlay;
|
||||
public final ColorApplier overlayColorApplier;
|
||||
public final int baseColor;
|
||||
|
||||
public Data(final BaseApplier baseApplier, final Overlay overlay, final OverlayInt maybeCachedOverlayColor,
|
||||
final int baseColor) {
|
||||
this.baseApplier = baseApplier;
|
||||
this.overlay = overlay;
|
||||
this.overlayColorApplier = ColorApplier.ofOptional(maybeCachedOverlayColor);
|
||||
this.baseColor = baseColor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final gridSlotInfo slotInfo;
|
||||
private final Data[] data;
|
||||
|
||||
private gridTransform(final gridSlotInfo slotInfo, final BlockRenderView brv, final BlockPos pos,
|
||||
final Supplier<Random> ranSupplier,
|
||||
final List<Pair<Optional<BlockState>, Optional<Identifier>>> attachment) {
|
||||
this.slotInfo = slotInfo;
|
||||
data = attachment.stream().map(pair -> {
|
||||
final Optional<BlockState> maybeBaseState = pair.getFirst();
|
||||
final int color;
|
||||
final BaseApplier baseApplier;
|
||||
if (maybeBaseState.isPresent()) {
|
||||
final BlockState baseState = maybeBaseState.get();
|
||||
color = Optional.ofNullable(ColorProviderRegistry.BLOCK.get(baseState.getBlock()))
|
||||
.map(prov -> prov.getColor(baseState, brv, pos, 1) | 0xFF000000).orElse(0xFFFFFFFF);
|
||||
baseApplier = new BaseApplier.Some(baseState,
|
||||
MinecraftClient.getInstance().getBlockRenderManager().getModel(baseState),
|
||||
randomSupplier.get());
|
||||
} else {
|
||||
color = 0xFFFFFFFF;
|
||||
baseApplier = BaseApplier.NONE;
|
||||
}
|
||||
|
||||
final Overlay overlay = pair.getSecond().map(CLIENT_OVERLAYS::getOverlayFor).orElse(Overlay.NONE);
|
||||
final OptionalInt cachedOverlayColor = flatMapToInt(overlay.coloredLike(), coloredLike -> mapToInt(
|
||||
Optional.ofNullable(ColorProviderRegistry.BLOCK.get(coloredLike.colorSource().getBlock())),
|
||||
prov -> prov.getColor(coloredLike.colorSource(), brv, pos, 1) | 0xFF000000));
|
||||
return new Data(baseApplier, overlay, cachedOverlayColor, color);
|
||||
}).toArray(Data[]::new);
|
||||
|
||||
}
|
||||
|
||||
private gridTransform(final gridSlotInfo slotInfo, final gridData gridData, final Supplier<Random> randomSupplier) {
|
||||
this(slotInfo, MinecraftClient.getInstance().player.clientWorld,
|
||||
MinecraftClient.getInstance().player.getBlockPos(), randomSupplier, gridData.toRenderAttachment());
|
||||
}
|
||||
|
||||
private gridTransform(final BlockRenderView brv, final BlockState state, final BlockPos pos,
|
||||
final Supplier<Random> randomSupplier) {
|
||||
this(
|
||||
(gridSlotInfo) state.getBlock(),
|
||||
brv,
|
||||
pos,
|
||||
randomSupplier,
|
||||
(List<Pair<Optional<BlockState>, Optional<Identifier>>>) ((RenderAttachedBlockView) brv)
|
||||
.getBlockEntityRenderAttachment(pos));
|
||||
}
|
||||
|
||||
protected int getPartIndex(final MutableQuadView mqv, final Direction dir) {
|
||||
return slotInfo.getRelativeSlotAt(
|
||||
new Vec3d(calcCenter(mqv::x), calcCenter(mqv::y), calcCenter(mqv::z)), dir);
|
||||
}
|
||||
|
||||
protected Pair<Float4, Float4> getUvs(final MutableQuadView mqv, final Direction dir) {
|
||||
final IntStream us = IntStream.rangeClosed(0, 3);
|
||||
final IntStream vs = IntStream.rangeClosed(0, 3);
|
||||
switch (dir) {
|
||||
case DOWN:
|
||||
return Pair.of(
|
||||
Float4.fromIterator(us.mapToDouble(i -> MathHelper.clamp(mqv.x(i), 0, 1)).iterator()),
|
||||
Float4.fromIterator(vs.mapToDouble(i -> 1 - MathHelper.clamp(mqv.z(i), 0, 1)).iterator()));
|
||||
case UP:
|
||||
return Pair.of(
|
||||
Float4.fromIterator(us.mapToDouble(i -> MathHelper.clamp(mqv.x(i), 0, 1)).iterator()),
|
||||
Float4.fromIterator(vs.mapToDouble(i -> MathHelper.clamp(mqv.z(i), 0, 1)).iterator()));
|
||||
case NORTH:
|
||||
return Pair.of(
|
||||
Float4.fromIterator(us.mapToDouble(i -> 1 - MathHelper.clamp(mqv.x(i), 0f, 1f)).iterator()),
|
||||
Float4.fromIterator(vs.mapToDouble(i -> 1 - MathHelper.clamp(mqv.y(i), 0f, 1f)).iterator()));
|
||||
case SOUTH:
|
||||
return Pair.of(
|
||||
Float4.fromIterator(us.mapToDouble(i -> MathHelper.clamp(mqv.x(i), 0f, 1f)).iterator()),
|
||||
Float4.fromIterator(vs.mapToDouble(i -> 1 - MathHelper.clamp(mqv.y(i), 0f, 1f)).iterator()));
|
||||
case EAST:
|
||||
return Pair.of(
|
||||
Float4.fromIterator(us.mapToDouble(i -> 1 - MathHelper.clamp(mqv.z(i), 0f, 1f)).iterator()),
|
||||
Float4.fromIterator(vs.mapToDouble(i -> 1 - MathHelper.clamp(mqv.y(i), 0f, 1f)).iterator()));
|
||||
case WEST:
|
||||
return Pair.of(
|
||||
Float4.fromIterator(us.mapToDouble(i -> MathHelper.clamp(mqv.z(i), 0f, 1f)).iterator()),
|
||||
Float4.fromIterator(vs.mapToDouble(i -> 1 - MathHelper.clamp(mqv.y(i), 0f, 1f)).iterator()));
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid direction:" + dir);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package modchest.util;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatFunction;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class QuadUtil {
|
||||
private QuadUtil() {
|
||||
throw new IllegalStateException("Should not instantiate utility class.");
|
||||
}
|
||||
|
||||
public static float calcCenter(final Int2FloatFunction key) {
|
||||
float min = Float.POSITIVE_INFINITY;
|
||||
float max = Float.NEGATIVE_INFINITY;
|
||||
|
||||
for ( int i = 0; i <= 3; i++) {
|
||||
final float cur = key.get(i);
|
||||
if (cur > max) {
|
||||
max = cur;
|
||||
} else if (cur < min) {
|
||||
min = cur;
|
||||
}
|
||||
}
|
||||
return (min +max) / 2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package modchest.util;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ToOptional<O extends ToOptional<O>> {
|
||||
Optional<O> toOptional();
|
||||
|
||||
<T> T match(Function<O, T> some, Supplier<T> none);
|
||||
|
||||
interface Some<O extends ToOptional<O>> extends ToOptional<O> {
|
||||
default Optional<O> toOptional() {
|
||||
return Optional.of((O) this);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <T> T match(final Function<O, T> some, final Supplier<T> none) {
|
||||
return some.apply((O) this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,18 @@ package modchest;
|
|||
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import modchest.data.OverlayDataListener;
|
||||
import modchest.grid.gridBlockEntityTypes;
|
||||
import modchest.grid.gridBlocks;
|
||||
import modchest.grid.gridItems;
|
||||
import modchest.grid.gridMeta;
|
||||
import modchest.item.custom.SpecialItems;
|
||||
import modchest.util.initializer;
|
||||
|
||||
//Main file; Hier wird alles aufgesetzt
|
||||
|
@ -11,6 +21,16 @@ public class REServerMod implements ModInitializer {
|
|||
public static final String MOD_ID = "modchest";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("modchest"); // Erster Error Logger
|
||||
|
||||
public static REServerModProperties PROPERTIES;
|
||||
public static SpecialItems SPECIAL_ITEMS;
|
||||
|
||||
public static gridMeta META;
|
||||
public static gridBlocks BLOCKS;
|
||||
public static gridItems ITEMS;
|
||||
public static gridBlockEntityTypes BLOCK_ENTITY_TYPES;
|
||||
|
||||
public static OverlayDataListener OVERLAYS;
|
||||
|
||||
@Override
|
||||
public void onInitialize() { //Der uebersicht halber sind jetzt alle initializer in Klassen in util in initializer
|
||||
initializer.itemGroups();
|
||||
|
@ -18,6 +38,17 @@ public class REServerMod implements ModInitializer {
|
|||
initializer.events();
|
||||
initializer.networking();
|
||||
|
||||
PROPERTIES = new GridProperties();
|
||||
SPECIAL_ITEMS = new SpecialItems();
|
||||
|
||||
META = new gridMeta()
|
||||
BLOCKS = new gridBlocks();
|
||||
ITEMS = new gridItems();
|
||||
BLOCK_ENTITY_TYPES = new gridBlockEntityTypes();
|
||||
|
||||
OVERLAYS = new OverlayDataListener();
|
||||
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(OVERLAYS);
|
||||
|
||||
LOGGER.info("Modchest successfully loaded!");
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package modchest.block.custom;
|
||||
|
||||
public class grid {
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
public interface grid {
|
||||
|
||||
/*
|
||||
* public static PacketByteBuf writeBufferEntity(EntityHitResult hitResult,
|
||||
* ServerWorld serverWorld) {
|
||||
* long seed = serverWorld.getSeed();
|
||||
* Vec3d gridEntityPos = hitResult.getPos();
|
||||
* NbtCompound Nbtgrid = new NbtCompound();
|
||||
* double gridX = gridEntityPos.getX();
|
||||
* Nbtgrid.putDouble("gridX", gridX);
|
||||
* double gridY = gridEntityPos.getY();
|
||||
* Nbtgrid.putDouble("gridY", gridY);
|
||||
* double gridZ = gridEntityPos.getZ();
|
||||
* Nbtgrid.putDouble("gridZ", gridZ);
|
||||
* Nbtgrid.putLong("WorldSeed", seed);
|
||||
* PacketByteBuf gridBuffer = PacketByteBufs.create();
|
||||
* gridBuffer.writeNbt(Nbtgrid);
|
||||
* return gridBuffer;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* public static PacketByteBuf writeBufferBlock(BlockHitResult hitResult,
|
||||
* ServerWorld serverWorld){
|
||||
* long seed = serverWorld.getSeed();
|
||||
* BlockPos gridBlockPos = hitResult.getBlockPos();
|
||||
* int[] gridBlockPosAr = new int[3];
|
||||
* gridBlockPosAr [0] = gridBlockPos.getX();
|
||||
* gridBlockPosAr [1] = gridBlockPos.getY();
|
||||
* gridBlockPosAr [2] = gridBlockPos.getZ();
|
||||
* NbtCompound Nbtgrid = new NbtCompound();
|
||||
* Nbtgrid.putIntArray("gridBlockPos", gridBlockPosAr);
|
||||
* Nbtgrid.putLong("WorldSeed", seed);
|
||||
* PacketByteBuf gridBlockBuffer = PacketByteBufs.create();
|
||||
* return gridBlockBuffer;
|
||||
*
|
||||
* }
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
||||
public class gridBlock extends Block {
|
||||
|
||||
public gridBlock(final Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
|
||||
return super.isSideInvisible(state, stateFrom, direction) || (state == stateFrom);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* public gridBlock(Settings settings) {
|
||||
* super(settings);
|
||||
* }
|
||||
*
|
||||
* @SuppressWarnings("deprecation")
|
||||
*
|
||||
* @Override
|
||||
* public boolean isSideInvisible(BlockState state, BlockState stateFrom,
|
||||
* Direction direction) {
|
||||
* return super.isSideInvisible(state, stateFrom, direction) || (state ==
|
||||
* stateFrom);
|
||||
* }
|
||||
*
|
||||
* /* BLOCK ENTITY
|
||||
*/
|
||||
|
||||
/*
|
||||
* @Override
|
||||
* public BlockRenderType getRenderType(BlockState state) { // sonst Block
|
||||
* unsichtbar
|
||||
* return BlockRenderType.MODEL;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public BlockEntity createBlockEntity(BlockPos arg0, BlockState arg1) {
|
||||
* // TODO Auto-generated method stub
|
||||
* throw new
|
||||
* UnsupportedOperationException("Unimplemented method 'createBlockEntity'");
|
||||
* }
|
||||
*
|
||||
* /*@SuppressWarnings("deprecation")
|
||||
*
|
||||
* @Override
|
||||
* public void onStateReplaced(BlockState state, World world, BlockPos pos,
|
||||
* BlockState newState, boolean moved) { // wenn Block zerstört wird Inventar
|
||||
* Inhalt in die Welt gespawnt
|
||||
* if (state.getBlock() != newState.getBlock()) {
|
||||
* BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
* if (blockEntity instanceof gridBlockEntity) {
|
||||
* ItemScatterer.spawn(world, pos, (gridBlockEntity) blockEntity);
|
||||
* world.updateComparators(pos, this);
|
||||
* }
|
||||
* super.onStateReplaced(state, world, pos, newState, moved);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* @SuppressWarnings("deprecation")
|
||||
*
|
||||
* @Override
|
||||
* public ActionResult onUse(BlockState state, World world, BlockPos pos,
|
||||
* PlayerEntity player, Hand hand,
|
||||
* BlockHitResult hitResult) {
|
||||
*
|
||||
* if (!world.isClient) {
|
||||
* NamedScreenHandlerFactory screenHandlerFactory =
|
||||
* state.createScreenHandlerFactory(world, pos);
|
||||
*
|
||||
* if (screenHandlerFactory != null) {
|
||||
* player.openHandledScreen(screenHandlerFactory);
|
||||
* }
|
||||
* }
|
||||
* player.sendMessage(Text.literal("onUse"));
|
||||
* return ActionResult.SUCCESS;
|
||||
* /*
|
||||
* if (!world.isClient) {
|
||||
* Block BlockInHand = getBlockFromItem(player.getMainHandStack().getItem());
|
||||
* BlockState StateInHand = BlockInHand.getDefaultState();
|
||||
* BlockPos gridBlockPos = hitResult.getBlockPos();
|
||||
* if
|
||||
* (world.getBlockState(hitResult.getBlockPos()).getBlock().toString().equals(
|
||||
* "Block{modchest:grid_block}")
|
||||
* && player.isSpectator() == false) {
|
||||
* if (BlockInHand instanceof gridBlock) {
|
||||
* return ActionResult.PASS;
|
||||
* } else {
|
||||
* player.sendMessage(Text.of("gridBlock benutzt"));
|
||||
* // world.setBlockState(gridBlockPos, StateInHand); // tauscht den "benutzten"
|
||||
* // gridBlock mit dem
|
||||
* // Blocks in der Hand, wie platzieren, nur cooler
|
||||
* player.getMainHandStack().decrement(1);
|
||||
* player.jump();
|
||||
* // player.onLanding(player.playSoundIfNotSilent());
|
||||
* if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) {
|
||||
* // nötig, um
|
||||
* // sicherzustellen, dass
|
||||
* // eine
|
||||
* // ServerPlayerEntity
|
||||
* // fürs networking übergeben wird und nicht eine
|
||||
* // PlayerEntity, da sonst Absturz; gleiches für ServerWorld
|
||||
* ServerWorld serverWorld = (ServerWorld) world;
|
||||
* ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
|
||||
* ServerPlayNetworking.send(serverPlayer,
|
||||
* modNetworkingServer.grid_block_networking,
|
||||
* grid.writeBufferBlock(hitResult, serverWorld));
|
||||
* }
|
||||
* }
|
||||
* } else {
|
||||
* return ActionResult.PASS;
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* return ActionResult.SUCCESS;
|
||||
*/
|
||||
/*
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public BlockEntity createBlockEntity(BlockPos arg0, BlockState arg1) {
|
||||
* // TODO Auto-generated method stub
|
||||
* throw new
|
||||
* UnsupportedOperationException("Unimplemented method 'createBlockEntity'");
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* @Override
|
||||
* public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||
* return new gridBlockEntity(pos, state);
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world,
|
||||
* BlockState state, BlockEntityType<T> type) {
|
||||
* return checkType(type, modBlockEntities.grid_block_entity,
|
||||
* gridBlockEntity::tick);
|
||||
* }
|
||||
* }
|
||||
*/
|
|
@ -0,0 +1,10 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.CarpetBlock;
|
||||
|
||||
public class gridCarpet extends CarpetBlock {
|
||||
|
||||
public gridCarpet(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.DoorBlock;
|
||||
|
||||
public class gridDoor extends DoorBlock {
|
||||
|
||||
public gridDoor(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.FenceBlock;
|
||||
|
||||
public class gridFence extends FenceBlock{
|
||||
|
||||
public gridFence(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.FenceGateBlock;
|
||||
|
||||
public class gridFenceGate extends FenceGateBlock{
|
||||
|
||||
public gridFenceGate(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.SnowBlock;
|
||||
|
||||
public class gridLayer extends SnowBlock{
|
||||
|
||||
public gridLayer(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.PaneBlock;
|
||||
|
||||
public class gridPane extends PaneBlock{
|
||||
|
||||
public gridPane(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.AbstractBlock.Settings;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
public class gridPath extends PathBlock {
|
||||
public gridPath(final Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
|
||||
return super.isSideInvisible(state, stateFrom, direction) || (state == stateFrom);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.PressurePlateBlock;
|
||||
|
||||
public class gridPressurePlate extends PressurePlateBlock{
|
||||
|
||||
public gridPressurePlate(ActivationRule type, Settings settings) {
|
||||
super(ActivationRule.MOBS, settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.swing.text.html.BlockView;
|
||||
|
||||
import modchest.block.entity.gridEntity;
|
||||
import modchest.grid.data.Sections;
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class gridSlab extends SlabBlock implements gridSlotInfo, BlockEntityProvider {
|
||||
|
||||
public gridSlab(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
public static final int LOWER_SLOT = 0;
|
||||
public static final int UPPER_SLOT = 1;
|
||||
|
||||
@Override
|
||||
public Sections sections() {
|
||||
return META.GRID_SLAB_SECTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelativeSlotAt(final Vec3d posInBlock, final Direction side) {
|
||||
switch (side) {
|
||||
case UP:
|
||||
return posInBlock.y == 0.5 ? LOWER_SLOT : UPPER_SLOT;
|
||||
case DOWN:
|
||||
return posInBlock.y == 0.5 ? UPPER_SLOT : LOWER_SLOT;
|
||||
default:
|
||||
return posInBlock.y < 0.5 ? LOWER_SLOT : UPPER_SLOT;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean absoluteSlotIsValid(final gridEntity grid, final BlockState state, final int slot) {
|
||||
final int wantedSlot;
|
||||
switch (state.get(Properties.SLAB_TYPE)) {
|
||||
case DOUBLE:
|
||||
return true;
|
||||
case TOP:
|
||||
wantedSlot = UPPER_SLOT;
|
||||
break;
|
||||
case BOTTOM:
|
||||
wantedSlot = LOWER_SLOT;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unreachable");
|
||||
}
|
||||
switch (grid.sections().findSectionIndexOf(slot)) {
|
||||
case Sections.BASE_INDEX:
|
||||
return grid.sections().base().makeAbsolute(slot) == wantedSlot;
|
||||
case Sections.OVERLAY_INDEX:
|
||||
return grid.sections().overlay().makeAbsolute(slot) == wantedSlot;
|
||||
case Sections.SPECIAL_INDEX:
|
||||
return true;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid slot for grid slab:" + slot);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
|
||||
return super.isSideInvisible(state, stateFrom, direction) || (state == stateFrom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity createBlockEntity(final BlockView world) {
|
||||
return new gridEntity(BLOCK_ENTITY_TYPES.GRID_SLAB, META.GRID_SLAB_SECTIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity createBlockEntity(BlockPos arg0, BlockState arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createBlockEntity'");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import modchest.block.entity.gridEntity;
|
||||
import modchest.grid.data.Sections;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public interface gridSlotInfo {
|
||||
Sections sections();
|
||||
int getRelativeSlotAt(Vec3d posInBlock, Direction side);
|
||||
boolean absoluteSlotIsValid(gridEntity entity, BlockState state, int slot);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.StairsBlock;
|
||||
|
||||
public class gridStairs extends StairsBlock{
|
||||
|
||||
public gridStairs(BlockState baseBlockState, Settings settings) {
|
||||
super(baseBlockState, settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.TorchBlock;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
|
||||
public class gridTorch extends TorchBlock{
|
||||
|
||||
public gridTorch(Settings settings, ParticleEffect particle) {
|
||||
super(settings, ParticleTypes.FLAME);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.TrapdoorBlock;
|
||||
|
||||
public class gridTrapdoor extends TrapdoorBlock{
|
||||
|
||||
public gridTrapdoor(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.WallBlock;
|
||||
|
||||
public class gridWall extends WallBlock{
|
||||
|
||||
public gridWall(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package modchest.block.custom.grid;
|
||||
|
||||
import net.minecraft.block.WallTorchBlock;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
|
||||
public class gridWallTorch extends WallTorchBlock {
|
||||
|
||||
public gridWallTorch(Settings settings, ParticleEffect particleEffect) {
|
||||
super(settings, ParticleTypes.FLAME);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package modchest.block.custom;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
public class gridBlock extends Block {
|
||||
|
||||
public static final String ServerPlayNetworking = null;
|
||||
|
||||
public gridBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderType getRenderType(BlockState state) {
|
||||
return BlockRenderType.MODEL;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
|
||||
return super.isSideInvisible(state, stateFrom, direction) || (state == stateFrom);
|
||||
}
|
||||
|
||||
public static PacketByteBuf writeBuffer(BlockHitResult hitResult) {
|
||||
BlockPos gridBlockPos = hitResult.getBlockPos();
|
||||
int[] gridPos = new int[3];
|
||||
gridPos[0] = gridBlockPos.getX();
|
||||
gridPos[1] = gridBlockPos.getY();
|
||||
gridPos[2] = gridBlockPos.getZ();
|
||||
|
||||
NbtCompound Nbtgrid = new NbtCompound();
|
||||
Nbtgrid.putIntArray("BlockPosition", gridPos);
|
||||
|
||||
PacketByteBuf gridBlockBuffer = PacketByteBufs.create();
|
||||
gridBlockBuffer.writeNbt(Nbtgrid);
|
||||
|
||||
// gridBlockBuffer.writeBlockHitResult(hitResult);
|
||||
// gridBlockBuffer.writeBlockPos(gridBlockPos);
|
||||
|
||||
return gridBlockBuffer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,370 @@
|
|||
package modchest.block.entity;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
|
||||
import org.spongepowered.asm.mixin.transformer.ClassInfo.FrameData;
|
||||
|
||||
import com.ibm.icu.impl.Pair;
|
||||
|
||||
import modchest.item.modItems;
|
||||
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.block.entity.LockableContainerBlockEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventories;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.PropertyDelegate;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableTextContent;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class gridEntity extends LockableContainerBlockEntity implements ExtendedScreenHandlerFactory, RenderAttachedBlockEntity, BlockEntityClientSerializable {
|
||||
private gridData data;
|
||||
//private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(1, ItemStack.EMPTY);
|
||||
|
||||
//protected final PropertyDelegate propertyDelegate; // synchronisieren zwischen client und server
|
||||
//private int progress = 0;
|
||||
//private int maxProgress = 72;
|
||||
|
||||
public gridEntity(final BlockEntityType type, final Sections sections) {
|
||||
super type;
|
||||
|
||||
data = new gridData(sections);
|
||||
}
|
||||
|
||||
public gridData data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Sections sections() {
|
||||
return data.sections();
|
||||
}
|
||||
|
||||
public Optional<ItemStack>[] items() {
|
||||
return data.items();
|
||||
}
|
||||
|
||||
public List<Optional<ItemStack>> baseItems() {
|
||||
return data.baseItems();
|
||||
}
|
||||
|
||||
public List<Optional<ItemStack>> overlayItems() {
|
||||
return data.overlayItems();
|
||||
}
|
||||
|
||||
public List<Optional<ItemStack>> specialItems() {
|
||||
return data.specialItems();
|
||||
}
|
||||
|
||||
public Optional<BlockState>[] baseStates() {
|
||||
return data.baseStates();
|
||||
}
|
||||
|
||||
public void copyFrom(final int slot, final ItemStack stack, final int count, final boolean take) {
|
||||
final ItemStack newStack = stack.copy();
|
||||
final int realCount = Math.min(count, stack.getCount());
|
||||
|
||||
newStack.setCount(realCount);
|
||||
|
||||
if (take) {
|
||||
stack.setCount(stack.getCount() - realCount);
|
||||
}
|
||||
this.setStack(slot, newStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCountPerStack() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(final int slot, final ItemStack stack) {
|
||||
switch (sections().findSectionIndexOf(slot)) {
|
||||
case Sections.BASE_INDEX: return checkIf(stack).isValidForBase(s -> Optional.of(s.getBlock().getDefaultState()), world, pos).isPresent();
|
||||
case Sections.OVERLAY_INDEX: return checkIf(stack).isValidForOverlay();
|
||||
case Sections.SPECIAL_INDEX: return checkIf(stack).isValidForSpecial();
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void beforeRemove(final int slot) {
|
||||
switch (sections().findSectionIndexOf(slot)) {
|
||||
case Sections.BASE_INDEX: baseStates()[sections().base().makeRelative(slot)] = Optional.empty();
|
||||
break;
|
||||
case Sections.OVERLAY_INDEX:
|
||||
break;
|
||||
case Sections.SPECIAL_INDEX:
|
||||
SPECIAL_ITEMS.Map.get(getItemBeforeEmpty(getStack(slot))).onRemove(world, this);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid slot:" + slot);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStack(final int slot, final int amount) {
|
||||
beforeRemove(slot);
|
||||
|
||||
return Optional.of(slot).filter(s -> sections().itemIndices().contains(s)).filter(s -> amount > 0).flatMap(s -> items()[s])
|
||||
.map(orig -> new Pair<>(orig, orig.split(amount))).map(pair -> {
|
||||
markDirty();
|
||||
if (pair.getFirst().isEmpty()) {
|
||||
items() [slot] = Optional.empty();
|
||||
}
|
||||
return pair.getSecond();
|
||||
}).orElse(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStack(int slot) {
|
||||
beforeRemove(slot);
|
||||
markDirty();
|
||||
final Optional<ItemStack> result = items()[slot];
|
||||
items()[slot] = Optional.empty();
|
||||
return result.orElse(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack(int slot) {
|
||||
return items()[slot].orElse(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return items().length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return Arrays.stream(items()).noneMatch(Optional::isPresent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayerUse(PlayerEntity player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
for (int i = 0; size = size(); i < size; i++) {
|
||||
items()[i] = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack(int slot, ItemStack stack) {
|
||||
final int sectionIndex = sections().findSectionIndexOf(slot);
|
||||
final Runnable setStack = () -> {
|
||||
items()[slot] = Optional.of(stack);
|
||||
stack.setCount(Math.min(stack.getCount(), getMaxCountPerStack()));
|
||||
markDirty();
|
||||
};
|
||||
|
||||
switch (sectionIndex) {
|
||||
case Sections.BASE_INDEX: setStack.run();
|
||||
final int baseSlot = sections().base().makeRelative(slot);
|
||||
baseStates()[baseSlot] = baseItems().get(baseSlot).map(ItemStack::getItem).filter(i -> i instanceof BlockItem).map(i -> ((BlockItem) i).getBlock().getDefaultState());
|
||||
break;
|
||||
case Sections.SPECIAL_INDEX:
|
||||
final SpecialItems.SpecialItem old = SPECIAL_ITEMS.Map.get(getItemBeforeEmpty(getStack(slot)));
|
||||
if (old != null && world != null) {
|
||||
old.onRemove(world, this);
|
||||
}
|
||||
setStack.run();
|
||||
|
||||
final SpecialItems.SpecialItems _new = SPECIAL_ITEMS.Map.get(getStack(slot).getItem());
|
||||
if (_new != null && world != null) {
|
||||
_new.onAdd(world,this);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: setStack.run();;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
super.markDirty();
|
||||
|
||||
final World world = this.world;
|
||||
if (world != null) {
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
final Block block = state.getBlock();
|
||||
|
||||
if (world.isClient) {
|
||||
MinecraftClient.getInstance().worldRenderer.updateBlock(world, pos, getCachedState(), state, 1);
|
||||
} else {
|
||||
sync();
|
||||
PlayerLookup.tracking(this).forEach(p -> p.networkHandler.sendPacket(this.toUpdatePacket()));
|
||||
world.updateNeighborsAlways(pos.offset(Direction.UP), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<Optional<BlockState>, Optional<Identifier>>> getRenderAttachmentData() {
|
||||
return data.toRenderAttachment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(final CompoundTag tag) {
|
||||
toClientTag(tag);
|
||||
return super.toTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(BlockState state, CompoundTag tag) {
|
||||
fromClientTag(tag);
|
||||
super.fromTag(state, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toClientTag(CompoundTag tag) {
|
||||
tag.put("gridData", data.toTag());
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag fromClientTag (final CompoundTag tag) {
|
||||
data = gridData.fromTag(compoundTag.getCompound("gridData"));
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ScreenHandler createScreenHandler(final int syncId, final PlayerInventory playerInventory) {
|
||||
return new gridGuiDescription(syncId, playerInventory, ScreenHandlerContext.create(world, pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeScreenopeningData(final ServerPlayerEntity serverPlayerEntity, final PacketByteBuf packetByteBuf) {
|
||||
packetByteBuf.writeBlockPos(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Text getContainerName() {
|
||||
return new TranslatableText(getCachedState().getBlock().getTranslationKey());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*@Override
|
||||
public DefaultedList<ItemStack> getItems() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return Text.literal("gridBlock");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeNbt(NbtCompound nbt) {
|
||||
Inventories.writeNbt(nbt, inventory);
|
||||
super.writeNbt(nbt);
|
||||
nbt.putInt("grid_block_entity_progress", progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNbt(NbtCompound nbt) {
|
||||
Inventories.readNbt(nbt, inventory);
|
||||
progress = nbt.getInt("grid_block_entity_progress");
|
||||
super.readNbt(nbt);
|
||||
}
|
||||
|
||||
public static void tick(World world, BlockPos pos, BlockState state, gridBlockEntity entity) {
|
||||
if (world.isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(hasRecipe(entity)) {
|
||||
entity.progress++;
|
||||
markDirty(world, pos, state); //reloads blockPosition/chunk -> synchronize server and client
|
||||
if (entity.progress >= entity.maxProgress) {
|
||||
craftItem(entity);
|
||||
}
|
||||
} else {
|
||||
entity.resetProgress();
|
||||
markDirty(world, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetProgress() {
|
||||
this.progress = 0;
|
||||
}
|
||||
|
||||
private static void craftItem(gridBlockEntity entity) {
|
||||
SimpleInventory inventory = new SimpleInventory(entity.size());
|
||||
for (int i = 0; i < entity.size(); i++) {
|
||||
inventory.setStack(i, entity.getStack(i));
|
||||
}
|
||||
|
||||
if (hasRecipe(entity)) {
|
||||
entity.removeStack(1,1);
|
||||
|
||||
entity.setStack(2, new ItemStack(modItems.pirates_coin, entity.getStack(2).getCount() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasRecipe(gridBlockEntity entity) {
|
||||
SimpleInventory inventory = new SimpleInventory(entity.size());
|
||||
for (int i = 0; i< entity.size(); i++) {
|
||||
inventory.setStack(i, entity.getStack(i));
|
||||
}
|
||||
|
||||
boolean hasRawGemInFirstSlot = entity.getStack(1).getItem() == modItems.pirates_coin;
|
||||
|
||||
return hasRawGemInFirstSlot && canInsertAmountIntoOutputSlot(inventory, 1) && canInsertItemIntoOutputSlot(inventory, modItems.pirates_coin);
|
||||
}
|
||||
|
||||
private static boolean canInsertItemIntoOutputSlot(SimpleInventory inventory, Item output) {
|
||||
return inventory.getStack(2).getItem() == output || inventory.getStack(2).isEmpty();
|
||||
}
|
||||
|
||||
private static boolean canInsertAmountIntoOutputSlot(SimpleInventory inventory, int count) {
|
||||
return inventory.getStack(2).getMaxCount() > inventory.getStack(2).getCount() + count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScreenHandler createMenu(int arg0, PlayerInventory arg1, PlayerEntity arg2) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createMenu'");
|
||||
}
|
||||
|
||||
public ItemStack getRenderStack() {
|
||||
if (this.getStack(2).isEmpty()) {
|
||||
return this.getStack(1);
|
||||
} else {
|
||||
return this.getStack(2);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
}
|
|
@ -10,10 +10,16 @@ import net.minecraft.util.registry.Registry;
|
|||
//rendert letztendlich die Interaktionsmenüs der Blöcke
|
||||
public class modBlockEntities {
|
||||
public static BlockEntityType<steeringWheelEntity> steering_wheel_interface; // Interaktionsmenü wird erstellt
|
||||
// public static BlockEntityType<gridBlockEntity> grid_block_entity;
|
||||
|
||||
public static void registerBlockEntities() {
|
||||
steering_wheel_interface = Registry.register(Registry.BLOCK_ENTITY_TYPE,
|
||||
new Identifier(REServerMod.MOD_ID, "steering_wheel_interface"), // Interkationsmenü wird gerendert
|
||||
FabricBlockEntityTypeBuilder.create(steeringWheelEntity::new, modBlocks.steering_wheel).build(null));
|
||||
|
||||
/*grid_block_entity = Registry.register(Registry.BLOCK_ENTITY_TYPE,
|
||||
new Identifier(REServerMod.MOD_ID, "grid_block_entity"),
|
||||
FabricBlockEntityTypeBuilder.create(gridBlockEntity::new, modBlocks.grid_block).build(null));*/
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package modchest.block;
|
||||
|
||||
import modchest.block.custom.gridBlock;
|
||||
import modchest.block.custom.steeringWheelBlock;
|
||||
import modchest.block.custom.grid.gridBlock;
|
||||
import modchest.item.modItemGroup;
|
||||
import modchest.REServerMod;
|
||||
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package modchest.data;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.spongepowered.include.com.google.gson.Gson;
|
||||
import org.spongepowered.include.com.google.gson.JsonParseException;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
|
||||
public class OverlayDataListener implements SimpleResourceReloadListener<Collection<Identifier>> {
|
||||
private final Map<Ingredient, Identifier> triggers = new HashMap<>();
|
||||
|
||||
public Optional<Identifier> getOverlayId(final ItemStack stack) {
|
||||
return triggers.entrySet().stream().filter(e -> e.getKey().test(stack)).map(Map.Entry::getValue).findFirst();
|
||||
}
|
||||
|
||||
public boolean hasOverlay(final ItemStack stack) {
|
||||
return getOverlayId(stack).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Collection<Identifier>> load(final ResourceManager manager, final Profiler profiler,
|
||||
final Executor executor) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
triggers.clear();
|
||||
return ResourceManager.findResources("grid/overlays", s -> s.endsWith(".json"));
|
||||
}, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> apply(final Collection<Identifier> data, final ResourceManager manager, final Profiler profiler,
|
||||
final Executor executor) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
for (final Identifier id : identifiers) {
|
||||
try {
|
||||
final JsonElement element = new Gson().fromJson(new BufferedReader(new InputStreamReader(resourceManager.getResource(id).getInputStream())), JsonElement.class);
|
||||
|
||||
if (!element.isJsonObject()) {
|
||||
throw new JsonParseException("Invalid JSON: expected an object.");
|
||||
}
|
||||
|
||||
final JsonObject obj = element.getAsJsonObject();
|
||||
if (!obj.has("trigger")) {
|
||||
throw new JsonParseException("Invalid JSON: expected the key 'triger'.");
|
||||
}
|
||||
|
||||
triggers.put(Ingredient.fromJson(.get("trigger")), id);
|
||||
} catch (final Exception e) {
|
||||
META.LOGGER.warn("Exception while parsing overlay:" + e);
|
||||
}
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
private final Identifier id = META.id("data/overlay");
|
||||
|
||||
@Override
|
||||
public Identifier getFabricId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
package modchest.event;
|
||||
/*package modchest.event;
|
||||
|
||||
import static net.minecraft.block.Block.getBlockFromItem;
|
||||
|
||||
import modchest.block.custom.gridBlock;
|
||||
import modchest.networking.modNetworkingServer;
|
||||
import modchest.networking.packet.gridBlockS2CPacket;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -12,11 +11,13 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class useBlockCallback implements UseBlockCallback {
|
||||
|
@ -26,7 +27,7 @@ public class useBlockCallback implements UseBlockCallback {
|
|||
Block BlockInHand = getBlockFromItem(player.getMainHandStack().getItem());
|
||||
BlockState StateInHand = BlockInHand.getDefaultState();
|
||||
BlockPos gridBlockPos = hitResult.getBlockPos();
|
||||
|
||||
//MinecraftServer server = player.getServer(); //funktioniert
|
||||
// PlayerPublicKey playerPublicKey = player.getPublicKey();
|
||||
if (world.getBlockState(hitResult.getBlockPos()).getBlock().toString().equals("Block{modchest:grid_block}")
|
||||
&& player.isSpectator() == false) {
|
||||
|
@ -34,17 +35,18 @@ public class useBlockCallback implements UseBlockCallback {
|
|||
return ActionResult.PASS;
|
||||
} else {
|
||||
player.sendMessage(Text.of("gridBlock benutzt"));
|
||||
world.setBlockState(gridBlockPos, StateInHand); // tauscht die Textur des "benutzten" gridBlocks mit der
|
||||
// des Blocks in der Hand
|
||||
//world.setBlockState(gridBlockPos, StateInHand); // tauscht den "benutzten" gridBlock mit dem
|
||||
// Blocks in der Hand, wie platzieren, nur cooler
|
||||
player.getMainHandStack().decrement(1);
|
||||
player.jump();
|
||||
// player.onLanding(player.playSoundIfNotSilent());
|
||||
if (player instanceof ServerPlayerEntity) { // nötig, um sicherzustellen, dass eine ServerPlayerEntity
|
||||
if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) { // nötig, um sicherzustellen, dass eine ServerPlayerEntity
|
||||
// fürs networking übergeben wird und nicht eine
|
||||
// PlayerEntity, da sonst Absturz
|
||||
// PlayerEntity, da sonst Absturz; gleiches für ServerWorld
|
||||
ServerWorld serverWorld = (ServerWorld) world;
|
||||
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
|
||||
ServerPlayNetworking.send(serverPlayer, modNetworkingServer.grid_block_networking,
|
||||
gridBlock.writeBuffer(hitResult));
|
||||
gridBlock.writeBuffer(hitResult, serverWorld));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -52,4 +54,4 @@ public class useBlockCallback implements UseBlockCallback {
|
|||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
}*/
|
|
@ -0,0 +1,62 @@
|
|||
/*package modchest.event;
|
||||
|
||||
import static net.minecraft.block.Block.getBlockFromItem;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import modchest.block.custom.grid.gridBlock;
|
||||
import modchest.networking.modNetworkingServer;
|
||||
import net.fabricmc.fabric.api.event.player.UseEntityCallback;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class useEntityCallback implements UseEntityCallback {
|
||||
|
||||
@Override
|
||||
public ActionResult interact(PlayerEntity player, World world, Hand hand, Entity entity,
|
||||
@Nullable EntityHitResult hitResult) {
|
||||
Block BlockInHand = getBlockFromItem(player.getMainHandStack().getItem());
|
||||
BlockState StateInHand = BlockInHand.getDefaultState();
|
||||
Vec3d gridBlockPos = hitResult.getPos();
|
||||
if (hitResult.getEntity().toString().equals("Block{modchest:grid_block_entity}")
|
||||
&& player.isSpectator() == false) {
|
||||
if (BlockInHand instanceof gridBlock) {
|
||||
return ActionResult.PASS;
|
||||
} else {
|
||||
player.sendMessage(Text.of("gridBlock benutzt"));
|
||||
// world.setBlockState(gridBlockPos, StateInHand); // tauscht den "benutzten"
|
||||
// gridBlock mit dem
|
||||
// Blocks in der Hand, wie platzieren, nur cooler
|
||||
player.getMainHandStack().decrement(1);
|
||||
player.jump();
|
||||
// player.onLanding(player.playSoundIfNotSilent());
|
||||
if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) { // nötig, um
|
||||
// sicherzustellen, dass
|
||||
// eine ServerPlayerEntity
|
||||
// fürs networking übergeben wird und nicht eine
|
||||
// PlayerEntity, da sonst Absturz; gleiches für ServerWorld
|
||||
ServerWorld serverWorld = (ServerWorld) world;
|
||||
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
|
||||
/*ServerPlayNetworking.send(serverPlayer, modNetworkingServer.grid_block_networking,
|
||||
grid.writeEntityBuffer(hitResult, serverWorld));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,16 @@
|
|||
package modchest.grid;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class Registrar<T> {
|
||||
private final Registry<T> target;
|
||||
|
||||
protected Registrar(final Registry<T> target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
protected <U extends T> U register(final U value, final Identifier id) {
|
||||
return Registry.register(target, id, value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package modchest.grid.data;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.spongepowered.asm.util.perf.Profiler.Section;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class Sections {
|
||||
public static final int BASE_INDEX = 0;
|
||||
public static final int OVERLAY_INDEX = 1;
|
||||
public static final int SPECIAL_INDEX = 2;
|
||||
|
||||
public static Sections fromTag(ListTag tag) {
|
||||
return new Sections(makesections(tag.stream().mapToInt(t -> ((IntTag) t).getInt())));
|
||||
}
|
||||
|
||||
private static Section[] makSections(final IntStream sizes) {
|
||||
int start = 0;
|
||||
final int[] sizeArr = sizes.toArray();
|
||||
final Section[] sections = new Section[sizeArr.length];
|
||||
for (int i = 0, sizeArrLength = sizeArr.length; i < sizeArrLength; i++) {
|
||||
final int size = sizeArr[i];
|
||||
sections[i] = Section.exclusive(start, start + size);
|
||||
start += size;
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
|
||||
private final Section[] sections;
|
||||
|
||||
public Sections(final Section[] sections) {
|
||||
this.sections = sections;
|
||||
}
|
||||
|
||||
public Sections(final int partCount, final int... otherSizes) {
|
||||
this(makSections(IntStream.concat(IntStream.of(partCount, partCount, SPECIAL_ITEMS.Map.size()), Arrays.stream(otherSizes))));
|
||||
}
|
||||
|
||||
public Section get(final int index) {
|
||||
return sections[index];
|
||||
}
|
||||
|
||||
public Section base() {
|
||||
return get(BASE_INDEX);
|
||||
}
|
||||
|
||||
public Section overlay() {
|
||||
return get(OVERLAY_INDEX);
|
||||
}
|
||||
|
||||
public Section special() {
|
||||
return get(SPECIAL_INDEX);
|
||||
}
|
||||
|
||||
public Section itemIndices() {
|
||||
return Section.exclusive(0, sections[sections.length -1].end());
|
||||
}
|
||||
|
||||
public boolean containsSlot(final int slot) {
|
||||
return 0 <= slot && slot < sections[sections.length -1].end();
|
||||
}
|
||||
|
||||
public int findSectionIndexOf(final int absoluteIndex) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (absoluteIndex < sections[i].end()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Optional<ItemStack>[] makeItems() {
|
||||
final Optional<ItemStack>[] items = new Optional[sections[sections.length -1].end()];
|
||||
Arrays.fill(items, Optional.empty());
|
||||
return items;
|
||||
}
|
||||
|
||||
public Optional<BlockState>[] makeBaseStates() {
|
||||
final Optional<BlockState>[] baseStates = new Optional[base().size()];
|
||||
Arrays.fill(baseStates, Optional.empty());
|
||||
return baseStates;
|
||||
}
|
||||
|
||||
public ListTag toTag() {
|
||||
final ListTag tag = new ListTag();
|
||||
|
||||
for (final Section section : sections) {
|
||||
tag.add(IntTag.of(section.size()));
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final Sections sections1 = (Sections) o;
|
||||
return Arrays.equals(sections, sections1.sections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(sections);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package modchest.grid.data;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Pair;
|
||||
|
||||
public class gridData {
|
||||
private static Optional<ItemStack>[] itemsFromTag(final Sections sections, final ListTag tag) {
|
||||
final Optional<ItemStack>[] items = sections.makeItems();
|
||||
|
||||
for (int i = 0, size = tag.size(); i< size; i++) {
|
||||
final CompoundTag stackTag = tag.getCompound(i);
|
||||
final int slot = stackTag.getByte("Slot") & 255;
|
||||
if (sections.containsSlot(slot)) {
|
||||
items[slot] = Optional.of(ItemStack.fromTag(stackTag));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private static optional<BlockState>[] baseStatesFromTag(final Sections sections, final ListTag tag) {
|
||||
final Optional<BlockState>[] baseStates = sections.makeBaseStates();
|
||||
|
||||
for (int i = 0, size = tag.size(); i < size; i++) {
|
||||
final CompoundTag stateTag = tag.getCompound(i);
|
||||
final int realIndex = stateTag.getInt("i");
|
||||
baseStates[realIndex] = BlockState.CODEC.decode(new Dynamic<>(NbtOps.INSTANCE, stateTag)).result().map(Pair::getFirst);
|
||||
}
|
||||
return baseStates;
|
||||
}
|
||||
|
||||
public static gridData fromTag(final CompoundTag tag) {
|
||||
final Sections sections = Sections.fromTag(tag.getList("format", 3));
|
||||
|
||||
return new gridData(sections, itemsFromTag(sections, tag.getList("Items", 10)), baseStatesFromTag(sections, tag.getList("states", 10)));
|
||||
}
|
||||
|
||||
private final Sections sections;
|
||||
private final Optional<ItemStack>[] items;
|
||||
private final Optional<BlockState>[] baseStates;
|
||||
|
||||
public gridData(final Sections sections, final Optional<ItemStack>[] items, final Optional<BlockState>[] baseStates) {
|
||||
this.sections = sections;
|
||||
this.items = items;
|
||||
this.baseStates = baseStates;
|
||||
}
|
||||
|
||||
public gridData(@NotNull final Sections sections) {
|
||||
this(sections, sections.makeItems(), sections.makeBaseStates());
|
||||
}
|
||||
|
||||
public Sections sections() {
|
||||
return sections;
|
||||
}
|
||||
|
||||
public Optional<ItemStack>[] items() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public List<Optional<ItemStack>> baseItems() {
|
||||
return Arrays.asList(items).subList(sections.base().start(), sections.base().end());
|
||||
}
|
||||
|
||||
public List<Optional<ItemStack>> overlayItems() {
|
||||
return Arrays.asList(items).subList(sections.overlay().start(), sections.overlay().end());
|
||||
}
|
||||
|
||||
public List<Optional<ItemStack>> specialItems() {
|
||||
return Arrays.asList(items).subList(sections.special().start(), sections.special().end());
|
||||
}
|
||||
|
||||
public Optional<BlockState>[] baseStates() {
|
||||
return baseStates;
|
||||
}
|
||||
|
||||
public CompoundTag toTag() {
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
|
||||
tag.put("format", sections.toTag());
|
||||
|
||||
final ListTag itemsTag = new ListTag();
|
||||
for (int i = 0, size = items.length; i < size; i++) {
|
||||
final int i2 = i;
|
||||
items[i].ifPresent(stack -> {
|
||||
final CompoundTag stackTag = new CompoundTag();
|
||||
stack.toTag(stackTag);
|
||||
stackTag.putByte("Slot", (byte)i2);
|
||||
itemsTag.add(stackTag);
|
||||
});
|
||||
}
|
||||
if (!itemsTag.isEmpty()) {
|
||||
tag.put("Items", itemsTag);
|
||||
}
|
||||
|
||||
final ListTag baseStatesTag = new ListTag();
|
||||
for (int i = 0, size = baseStates.length; i < size; i++) {
|
||||
final int i2 = i;
|
||||
baseStates[i].ifPresent(baseState -> {
|
||||
final CompoundTag baseStateTag = new CompoundTag();
|
||||
baseStateTag.putInt("i", i2);
|
||||
baseStateTag.add(
|
||||
BlockState.CODEC.encode(baseState, NbtOps.INSTANCE, baseStateTag).get().left().get()
|
||||
);
|
||||
});
|
||||
}
|
||||
if (!baseStatesTag.isEmpty()) {
|
||||
tag.put("states", baseStatesTag);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
public List<Pair<Optional<BlockState>, Optional<Identifier>>> toRenderAttachment() {
|
||||
return Streams.zip(Arrays.stream(baseStates), overlayItems().stream().map(i -> i.flatMap(OVERLAYS::getOverlayId)), Pair::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*package modchest.grid;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
public class gridBlock extends Block{
|
||||
|
||||
public gridBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
|
||||
return super.isSideInvisible(state, stateFrom, direction) || (state == stateFrom);
|
||||
}
|
||||
}*/
|
|
@ -0,0 +1,36 @@
|
|||
package modchest.grid;
|
||||
|
||||
import modchest.block.entity.gridEntity;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class gridBlockEntityTypes extends Registrar<BlockEntityType<?>> {
|
||||
public gridBlockEntityTypes() {
|
||||
super(Registry.BLOCK_ENTITY_TYPE);
|
||||
}
|
||||
|
||||
public final BlockEntityType<gridEntity> GRID = register(
|
||||
BlockEntityType.Builder.create(
|
||||
() -> new gridEntity(this.GRID, META.GRID_SECTIONS),
|
||||
BLOCKS.GRID_BLOCK,
|
||||
BLOCK.GRID_STAIRS,
|
||||
BLOCK.GRID_FENCE,
|
||||
BLOCK.GRID_FENCE_GATE,
|
||||
BLOCKS.GRID_TRAPDOOR,
|
||||
BLOCKS.GRID_DOOR,
|
||||
BLOCKS.GRID_PATH,
|
||||
BLOCKS.GRID_TORCH,
|
||||
BLOCKS.GRID_WALL_TORCH,
|
||||
BLOCKS.GRID_PRESSURE_PLATE,
|
||||
BLOCKS.GRID_WALL,
|
||||
BLOCKS.GRID_LAYER,
|
||||
BLOCKS.GRID_CARPET,
|
||||
BLOCKS.GRID_PANE).build(null),
|
||||
META.id("frame"));
|
||||
|
||||
public final BlockEntityType<gridEntity> GRID_SLAB = register(
|
||||
BlockEntityType.Builder.create(
|
||||
() -> new gridEntity(this.GRID_SLAB, META.GRID_SLAB_SECTIONS),
|
||||
BLOCKS.GRID_SLAB).build(null),
|
||||
META.id("grid_slab"));
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package modchest.grid;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
|
||||
import modchest.block.custom.grid.gridBlock;
|
||||
import modchest.block.custom.grid.gridCarpet;
|
||||
import modchest.block.custom.grid.gridDoor;
|
||||
import modchest.block.custom.grid.gridFence;
|
||||
import modchest.block.custom.grid.gridFenceGate;
|
||||
import modchest.block.custom.grid.gridLayer;
|
||||
import modchest.block.custom.grid.gridPane;
|
||||
import modchest.block.custom.grid.gridPath;
|
||||
import modchest.block.custom.grid.gridPressurePlate;
|
||||
import modchest.block.custom.grid.gridSlab;
|
||||
import modchest.block.custom.grid.gridStairs;
|
||||
import modchest.block.custom.grid.gridTorch;
|
||||
import modchest.block.custom.grid.gridTrapdoor;
|
||||
import modchest.block.custom.grid.gridWall;
|
||||
import modchest.block.custom.grid.gridWallTorch;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.sound.BlockSoundGroup;
|
||||
import net.minecraft.state.property.Property;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class gridBlocks extends Registrar<Block> {
|
||||
public final gridBlock GRID_BLOCK;
|
||||
public final gridSlab GRID_SLAB;
|
||||
public final gridStairs GRID_STAIRS;
|
||||
public final gridFence GRID_FENCE;
|
||||
public final gridFenceGate GRID_FENCE_GATE;
|
||||
public final gridTrapdoor GRID_TRAPDOOR;
|
||||
public final gridDoor GRID_DOOR;
|
||||
public final gridPath GRID_PATH;
|
||||
public final gridTorch GRID_TORCH;
|
||||
public final gridWallTorch GRID_WALL_TORCH;
|
||||
public final gridPressurePlate GRID_PRESSURE_PLATE;
|
||||
public final gridWall GRID_WALL;
|
||||
public final gridLayer GRID_LAYER;
|
||||
public final gridCarpet GRID_CARPET;
|
||||
public final gridPane GRID_PANE;
|
||||
|
||||
private <A extends Block> A registerWithItem(final A block, final Identifier id, final Item.Settings settings) {
|
||||
Registry.register(Registry.ITEM, id, new BlockItem(block, settings));
|
||||
return register(block, id);
|
||||
}
|
||||
|
||||
public gridBlocks() {
|
||||
super(Registry.BLOCK);
|
||||
|
||||
final Function<Material, AbstractBlock.Settings> makeSettings = material -> FabricBlockSettings
|
||||
.of(material)
|
||||
.hardness(0.33f)
|
||||
.sounds(BlockSoundGroup.WOOD)
|
||||
.nonOpaque()
|
||||
.solidBlock((a, b, c) -> false)
|
||||
.luminance(state -> Boolean.TRUE.equals(state.get(Properties.LIT)) ? 15 : 0);
|
||||
|
||||
final AbstractBlock.Settings gridSettings = makeSettings.apply(Material.WOOD);
|
||||
final AbstractBlock.Settings gridTorchSettings = makeSettings.apply(Material.SUPPORTED).noCollision()
|
||||
.breakInstantly()
|
||||
.luminance(state -> Boolean.TRUE.equals(state.get(Properties.LIT)) ? 15 : 14);
|
||||
|
||||
final Item.Settings itemSettings = new Item.Settings().group(META.MAIN_ITEM_GROUP);
|
||||
|
||||
GRID_BLOCK = registerWithItem(new gridBlock(gridSettings), META.id("grid_block"), itemSettings);
|
||||
GRID_SLAB = registerWithItem(new gridSlab(gridSettings), META.id("grid_slab"), itemSettings);
|
||||
GRID_STAIRS = registerWithItem(new gridStairs(GRID_BLOCK.getDefaultState(), gridSettings),
|
||||
META.id("grid_stairs"), itemSettings);
|
||||
GRID_FENCE = registerWithItem(new gridFence(gridSettings), META.id("grid_fence"), itemSettings);
|
||||
GRID_FENCE_GATE = registerWithItem(new gridFenceGate(gridSettings), META.id("grid_fence_gate"), itemSettings);
|
||||
GRID_TRAPDOOR = registerWithItem(new gridTrapdoor(gridSettings.allowsSpawning((a, b, c, d) -> false)),
|
||||
META.id("grid_trapdoor"), itemSettings);
|
||||
GRID_DOOR = registerWithItem(new gridDoor(gridSettings), META.id("grid_door"), itemSettings);
|
||||
GRID_PATH = registerWithItem(new gridPath(gridSettings), META.id("grid_path"), itemSettings);
|
||||
GRID_PRESSURE_PLATE = registerWithItem(new gridPressurePlate(gridSettings), META.id("grid_pressure_plate"),
|
||||
itemSettings);
|
||||
GRID_WALL = registerWithItem(new gridWall(gridSettings), META.id("grid_wall"), itemSettings);
|
||||
GRID_LAYER = registerWithItem(new gridLayer(gridSettings), META.id("grid_layer"), itemSettings);
|
||||
GRID_CARPET = registerWithItem(new gridCarpet(gridSettings), META.id("grid_carpet"), itemSettings);
|
||||
GRID_PANE = registerWithItem(new gridPane(gridSettings), META.id("grid_pane"), itemSettings);
|
||||
|
||||
GRID_TORCH = registerWithItem(new gridTorch(gridTorchSettings), META.id("grid_torch"));
|
||||
GRID_WALL_TORCH = registerWithItem(new gridWallTorch(gridTorchSettings), META.id("grid_wall_torch"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package modchest.grid;
|
||||
|
||||
import modchest.item.custom.Hammer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.WallStandingBlockItem;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class gridItems extends Registrar<Item> {
|
||||
public gridItems() {
|
||||
super(Registry.ITEM);
|
||||
}
|
||||
|
||||
public final Hammer HAMMER = register(new Hammer(new Item.Settings().maxCount(1).group(META.MAIN_ITEM_GROUP)), META.id("hammer"));
|
||||
|
||||
public final WallStandingBlockItem GRID_TORCH = register(
|
||||
new WallStandingBlockItem(BLOCKS.GRID_TORCH, BLOCKS.GRID_WALL_TORCH, new Item.Settings().group(META.MAIN_ITEM_GROUP)),
|
||||
META.id("grid_torch")
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package modchest.grid;
|
||||
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import modchest.grid.data.Sections;
|
||||
import modchest.gui.gridGuiDescription;
|
||||
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class gridMeta {
|
||||
public final String NAMESPACE = "grid";
|
||||
|
||||
public Identifier id(final String path) {
|
||||
return new Identifier(NAMESPACE, path);
|
||||
}
|
||||
|
||||
public final Logger LOGGER = LogManager.getLogger("grid");
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public final ScreenHandlerType<gridGuiDescription> GRID_SCREEN_HANDLER_TYPE = ScreenHandlerRegistry
|
||||
.registerExtended(id("grid"),
|
||||
(syncId, inventory, buf) -> new gridGuiDescription(syncId, inventory,
|
||||
ScreenHandlerContext.create(inventory.player.world, buf.readBlockPos())));
|
||||
|
||||
public final Sections GRID_SECTIONS = new Sections(1);
|
||||
public final Sections GRID_SLAB_SECTIONS = new Sections(2);
|
||||
|
||||
public final ItemGroup MAIN_ITEM_GROUP = FabricItemGroupBuilder.create(id("grid"))
|
||||
.icon(() -> new ItemStack(ITEMS.HAMMER)).build();
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package modchest.grid;
|
||||
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
|
||||
public class gridProperties {
|
||||
public final BooleanProperty HAS_REDSTONE = BooleanProperty.of("has_redstone");
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package modchest.gui;
|
||||
|
||||
import net.minecraft.inventory.Inventory;
|
||||
|
||||
public class SingleItemSlots extends WItemSlot {
|
||||
public SingleItemSlots(final Inventory inventory, final int startIndex, final int slotsWide, final int slotsHigh, final boolean big) {
|
||||
super(inventory, startIndex, slotsWide, slotsHigh, big);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ValidatedSlot createSlotPeer(final Inventory inventory, final int index, final int x, final int y) {
|
||||
return new ValidatedSingleItemSlot(inventory, index, x, y);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package modchest.gui;
|
||||
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class ValidatedSingleItemSlot extends ValidatedSlot {
|
||||
public ValidatedSingleItemSlot(final Inventory inventory, final int index, final int x, final int y) {
|
||||
super(inventory, index, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxItemCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxItemCount(final ItemStack stack) {
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package modchest.gui;
|
||||
|
||||
import modchest.block.entity.gridEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
|
||||
public class gridGuiDescription extends SyncedGuiDescription {
|
||||
public gridGuiDescription(final int syncId, final PlayerInventory playerInventory, final ScreenHandlerContext context) {
|
||||
this (syncId, playerInventory, context, context.run((world, pos) -> (gridEntity) world.getBlockEntity(pos))
|
||||
.orElseThrow(() -> new IllegalArgumentException("gridGuiDescription can only be used with gridEntity"))
|
||||
);
|
||||
}
|
||||
|
||||
private gridGuiDescription(final int syncId, final PlayerInventory playerInventory, final ScreenHandlerContext context, final gridEntity grid) {
|
||||
super(META.GRID_SCREEN_HANDLER_TYPE, syncId, playerInventory, SyncedGuiDescription.getBlockInventory(context, frame.size()), SyncedGuiDescription.getBlockPropertyDelegate(context));
|
||||
final WGridPanel root = new GridPanel(9);
|
||||
root.add(centered(label("gui.framed.frame.base_label")), 1, 2, 8, 2);
|
||||
root.add(
|
||||
slotRow(SingleItemSlots::new, blockInventory, frame.sections().overlay()),
|
||||
13 - gridBlock.sections().overlay().size(), 4 //gridBlock ersetzt in diesem Fall frame also nochmal TODO
|
||||
);
|
||||
root.add(centered(label("gui.framed.frame.special_label")), 0, 6, 18, 2);
|
||||
|
||||
SPECIAL_ITEMS.Map.forEach((item, specialItem) -> root.add(
|
||||
new SingleItemSlots(blockInventory, grid.sections().special().makeAbsolute(specialItem.offset()), 1, 1, false),
|
||||
9 - grid.sections().special().size() + specialItem.offset() *2, 8
|
||||
));
|
||||
root.add(createPlayerInventoryPanel(), 0, 11);
|
||||
root.validate(this);
|
||||
rootPanel = root;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,225 @@
|
|||
package modchest.item.custom;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import modchest.block.custom.grid.gridSlotInfo;
|
||||
import modchest.block.entity.gridEntity;
|
||||
import modchest.grid.data.gridData;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.text.TranslatableTextContent;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class Hammer extends Item {
|
||||
|
||||
public Hammer(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
public enum CopyMode {
|
||||
NONE(0, "none"), ANY(1, "any"), REQUIRE_ALL(2, "require_all");
|
||||
|
||||
public final int id;
|
||||
public final String translationKey;
|
||||
|
||||
CopyMode(final int id, final String translationKey) {
|
||||
this.translationKey = translationKey;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public CopyMode next() {
|
||||
return CopyMode.values()[(id + 1) % CopyMode.values().length];
|
||||
}
|
||||
|
||||
public static final CopyMode DEFAULT = NONE;
|
||||
|
||||
public static Optional<CopyMode> fromString(final String string) {
|
||||
return Arrays.stream(values()).filter(s -> s.translationKey.equals(string)).findFirst();
|
||||
}
|
||||
|
||||
public static CopyMode fromStringOrDefault(final String string) {
|
||||
return fromString(string).orElse(DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
public static Data fromTag(final CompoundTag tag) {
|
||||
return new Data(
|
||||
tag.contains("storedData") ? gridData.fromTag(tag.getCompound("storedData")) : null,
|
||||
(tag.contains("mode") ? CopyMode.fromString(tag.getString("mode")) : Optional.<CopyMode>empty())
|
||||
.orElse(CopyMode.DEFAULT));
|
||||
}
|
||||
|
||||
private final @Nullable gridData storedData;
|
||||
private final CopyMode mode;
|
||||
|
||||
public Data(@Nullable final gridData storedData, final CopyMode mode) {
|
||||
this.storedData = storedData;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public boolean applySettings(final gridSlotInfo slotInfo, final BlockState state, final gridEntity entity, final PlayerEntity player, final World world) {
|
||||
final gridData storedData = this.storedData;
|
||||
if (storedData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!storedData.sections().equals(grid.sections())) {
|
||||
player.sendMessage(new TranslatableText("gui.framers_hammer.different_format"), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.isCreative()) {
|
||||
if (mode == CopyMode.NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!world.isClient) {
|
||||
IntStream.range(0, storedData.items().length)
|
||||
.boxed()
|
||||
.map(i -> new Pair<>(storedData.items()[i], i))
|
||||
.flatMap(pair -> pair.getFirst().map(itemStack -> Stream.of(new Pair<>(itemStack, pair.getSecond()))).orElseGet(Stream::empty))
|
||||
.forEach(pair -> grid.setStack(pair.getSecond(), pair.getFirst().copy()));
|
||||
}
|
||||
} else {
|
||||
final boolean requireAllItems;
|
||||
switch (mode) {
|
||||
case NONE:
|
||||
return false;
|
||||
case ANY:
|
||||
requireAllItems = false;
|
||||
break;
|
||||
case REQUIRE_ALL:
|
||||
requireAllItems = true;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unreachable.");
|
||||
}
|
||||
|
||||
final Map<Item, Integer> itemSlotToGridSlot = IntStream.range(0, storedData.items().length).boxed()
|
||||
.map(i -> new Pair<>(storedData.items()[i], i))
|
||||
.flatMap(pair -> {
|
||||
if (pair.getFirst().isPresent()) {
|
||||
return Stream.of(pair.mapFirst(stack -> stack.get().getItem()));
|
||||
} else {
|
||||
return Stream.empty();
|
||||
}
|
||||
}).collect(Pair.toMap());
|
||||
|
||||
final Map<Integer, Integer> playerSlotToGridSlot = IntStream.range(0, player.getInventory().size()).boxed()
|
||||
.map(i -> new Pair<>(Optional.of(player.getInventory().getStack(i)).filter(s -> !s.isEmpty()), i))
|
||||
.flatMap(pair -> {
|
||||
final Item item = maybeStack.get().getItem();
|
||||
if (itemSlotToGridSlot.containsKey(item)) {
|
||||
return Stream.of(new Pair<A,B>(pair.getSecond(), itemSlotToGridSlot.get(item)));
|
||||
} else {
|
||||
return Stream.empty();
|
||||
} else {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
}).collect(Pair.toMap());
|
||||
|
||||
if (!world.isClient) {
|
||||
for (final Map.Entry<Integer, Integer> entry : playerSlotToGridSlot.entrySet()) {
|
||||
final int playerSlot = entry.getKey();
|
||||
final int gridSlot = entry.getValue();
|
||||
|
||||
if (grid.getStack(gridSlot).getItem() != player.getInventory().getStack(playerSlot).getItem() && slotInfo.absoluteSlotIsValid(grid, state, gridSlot)) {
|
||||
if (!grid.getStack(gridSlot).isEmpty()) {
|
||||
player.getInventory().offerOrDrop(world, grid.removeStack(gridSlot));
|
||||
}
|
||||
grid.setStack(gridSlot, player.getInventory().removeStack(playerSlot, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player.sendMessage(new TranslatableText("gui.framed.framers_hammer.apply_settings"), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CompoundTag getTagOrAssignDefault (final ItemStack stack) {
|
||||
if (stack.getTag() == null) {
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
tag.putString("mode", CopyMode.DEFAULT.toString());
|
||||
stack.setTag(tag);
|
||||
}
|
||||
return stack.getTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult useOnBlock(final ItemUsageContext context) {
|
||||
final CompoundTag tag = getTagOrAssignDefault(context.getStack());
|
||||
final Data data = Data.fromTag(tag);
|
||||
|
||||
final BlockPos pos = context.getBlockPos();
|
||||
final World world = context.getWorld();
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
|
||||
final Block block = state.getBlock();
|
||||
if (!(block instanceof gridSlotInfo)) {
|
||||
return super.useOnBlock(context);
|
||||
}
|
||||
|
||||
final gridSlotInfo slotInfo = (gridSlotInfo) block;
|
||||
|
||||
final BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
if (!(blockEntity instanceof gridEntity)) {
|
||||
return super.useOnBlock(context);
|
||||
}
|
||||
final gridEntity grid = (gridEntity) blockEntity;
|
||||
|
||||
final PlayerEntity player = context.getPlayer();
|
||||
if (player == null) {
|
||||
return super.useOnBlock(context);
|
||||
}
|
||||
|
||||
if (player.isSneaking()) {
|
||||
player.sendMessage(new TranslatableText("gui.framers_hammer.copy_settings"), true);
|
||||
tag.put("storedData", grid.data().toTag());
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
if (data.applySettings(slotInfo, state, grid, player, world)) {
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return super.useOnBlock(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(final World world, final PlayerEntity user, final Hand hand) {
|
||||
if (!user.isSneaking()) {
|
||||
return super.use(world, user, hand);
|
||||
}
|
||||
|
||||
final ItemStack stack = user.getStackInHand(hand);
|
||||
final CompoundTag tag = getTagOrAssignDefault(stack);
|
||||
final CopyMode mode = CopyMode.fromStringOrDefault(tag.getString("mode"));
|
||||
|
||||
final CopyMode newMode = mode.next();
|
||||
tag.putString("mode", newMode.toString());
|
||||
user.sendMessage(new TranslatableText("gui.framed.framers_hammer" + newMode.translationKey), true);
|
||||
return TypedActionResult.success(stack);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package modchest.item.custom;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Streams;
|
||||
|
||||
import modchest.block.entity.gridEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SpecialItems {
|
||||
public static class SpecialItem {
|
||||
private final int offset;
|
||||
private final BooleanProperty property;
|
||||
|
||||
public SpecialItem(final int offset, final BooleanProperty property) {
|
||||
this.offset = offset;
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
public int offset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void onAdd(final World world, final gridEntity grid) {
|
||||
world.setBlockState(grid.getPos(), world.getBlockState(grid.getPos()).with(property, true));
|
||||
}
|
||||
|
||||
public void onRemove(final World world, final gridEntity grid) {
|
||||
world.setBlockState(grid.getPos(), world.getBlockState(frame.getPos()).with(property, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final Map<Item, SpecialItem> MAP;
|
||||
|
||||
public SpecialItems() {
|
||||
final List<Pair<Item, BooleanProperty>> pairs = Lists.newArrayList(
|
||||
Pair.of(Items.GLOWSTONE_DUST, Properties.LIT), Pair.of(Items.REDSTONE, PROPERTIES.HAS_REDSTONE)
|
||||
);
|
||||
|
||||
MAP = Streams.zip(IntStream.range(0, pairs.size()).boxed(), pairs.stream(), Pair::new)
|
||||
.map(pair -> new Pair<>(pair.getSecond().getFirst(), new SpecialItem(pair.getFirst(), pair.getSecond().getSecond()))
|
||||
).collect(Pair.toMap());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package modchest.mixin.local;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import modchest.block.custom.grid.gridBlock;
|
||||
import modchest.block.custom.grid.gridCarpet;
|
||||
import modchest.block.custom.grid.gridDoor;
|
||||
import modchest.block.custom.grid.gridFence;
|
||||
import modchest.block.custom.grid.gridFenceGate;
|
||||
import modchest.block.custom.grid.gridLayer;
|
||||
import modchest.block.custom.grid.gridPane;
|
||||
import modchest.block.custom.grid.gridPath;
|
||||
import modchest.block.custom.grid.gridPressurePlate;
|
||||
import modchest.block.custom.grid.gridSlab;
|
||||
import modchest.block.custom.grid.gridSlotInfo;
|
||||
import modchest.block.custom.grid.gridStairs;
|
||||
import modchest.block.custom.grid.gridTorch;
|
||||
import modchest.block.custom.grid.gridTrapdoor;
|
||||
import modchest.block.custom.grid.gridWall;
|
||||
import modchest.block.custom.grid.gridWallTorch;
|
||||
import modchest.block.entity.gridEntity;
|
||||
import modchest.grid.data.Sections;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
@Mixin({
|
||||
gridBlock.class,
|
||||
gridSlab.class,
|
||||
gridStairs.class,
|
||||
gridFence.class,
|
||||
gridFenceGate.class,
|
||||
gridTrapdoor.class,
|
||||
gridDoor.class,
|
||||
gridPath.class,
|
||||
gridTorch.class,
|
||||
gridWallTorch.class,
|
||||
gridPressurePlate.class,
|
||||
gridWall.class,
|
||||
gridLayer.class,
|
||||
gridCarpet.class,
|
||||
gridPane.class
|
||||
})
|
||||
public class SinglePartGridBlock implements gridSlotInfo {
|
||||
private SinglePartGridBlock() {
|
||||
throw new IllegalStateException("Mixin constructor should not run");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sections sections() {
|
||||
return META.GRID_SECTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelativeSlotAt(final Vec3d posInBlock, final Direction side) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean absoluteSlotIsValid(final gridEntity grid, final BlockState state, final int slot) {
|
||||
return grid.sections().containsSlot(slot);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
package modchest.mixin.local;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.swing.text.html.BlockView;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.NonnullDefault;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.datafixers.util.Function3;
|
||||
|
||||
import modchest.block.custom.grid.grid;
|
||||
import modchest.block.custom.grid.gridBlock;
|
||||
import modchest.block.custom.grid.gridCarpet;
|
||||
import modchest.block.custom.grid.gridDoor;
|
||||
import modchest.block.custom.grid.gridFence;
|
||||
import modchest.block.custom.grid.gridFenceGate;
|
||||
import modchest.block.custom.grid.gridLayer;
|
||||
import modchest.block.custom.grid.gridPane;
|
||||
import modchest.block.custom.grid.gridPath;
|
||||
import modchest.block.custom.grid.gridPressurePlate;
|
||||
import modchest.block.custom.grid.gridSlab;
|
||||
import modchest.block.custom.grid.gridSlotInfo;
|
||||
import modchest.block.custom.grid.gridStairs;
|
||||
import modchest.block.custom.grid.gridTorch;
|
||||
import modchest.block.custom.grid.gridTrapdoor;
|
||||
import modchest.block.custom.grid.gridWall;
|
||||
import modchest.block.custom.grid.gridWallTorch;
|
||||
import modchest.block.entity.gridEntity;
|
||||
import modchest.event.playerAfterRespawnEvent;
|
||||
import modchest.item.custom.Hammer;
|
||||
import modchest.item.custom.SpecialItems;
|
||||
import modchest.item.custom.SpecialItems.SpecialItem;
|
||||
import modchest.util.ValidQuery;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.StructureBlockBlockEntity.Action;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.StateManager.Builder;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.ItemScatterer;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@Mixin({
|
||||
gridBlock.class,
|
||||
gridSlab.class,
|
||||
gridStairs.class,
|
||||
gridFence.class,
|
||||
gridFenceGate.class,
|
||||
gridTrapdoor.class,
|
||||
gridDoor.class,
|
||||
gridPath.class,
|
||||
gridTorch.class,
|
||||
gridWallTorch.class,
|
||||
gridPressurePlate.class,
|
||||
gridWall.class,
|
||||
gridLayer.class,
|
||||
gridCarpet.class,
|
||||
gridPane.class
|
||||
})
|
||||
public abstract class gridBehaviour extends Block implements BlockEntityProvider, grid, gridSlotInfo {
|
||||
|
||||
public gridBehaviour(Settings settings) {
|
||||
super(settings);
|
||||
throw new IllegalStateException("Mixin constructor should never run");
|
||||
}
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
void setGridPropertiesDefaultState(CallbackInfo ci) {
|
||||
setDefaultState(getDefaultState().with(Properties.LIT, false).with(Properties.HAS_REDSTONE, false));
|
||||
}
|
||||
|
||||
@Unique
|
||||
@Nullable
|
||||
private PlayerEntity breaker;
|
||||
|
||||
@Override
|
||||
protected void appendProperties(final StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder);
|
||||
builder.add(Properties.LIT, Properties.HAS_REDSTONE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean emitsRedstonePower(final BlockState state) {
|
||||
return super.emitsRedstonePower(state) || state.get(PROPERTIES.HAS_REDSTONE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public int getWeakRedstonePower(BlockState state, net.minecraft.world.BlockView world, BlockPos pos,
|
||||
Direction direction) {
|
||||
if (state.get(PROPERTIES.HAS_REDSTONE)) {
|
||||
return 15 - super.getWeakRedstonePower(state, world, pos, direction)
|
||||
} else {
|
||||
return super.getWeakRedstonePower(state, world, pos, direction);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onSyncedBlockEvent(BlockState state, World world, BlockPos pos, int type, int data) {
|
||||
super.onSyncedBlockEvent(state, world, pos, type, data);
|
||||
final @Nullable BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
if (blockEntity == null) {
|
||||
return false;
|
||||
}
|
||||
return blockEntity.onSyncedBlockEvent(type, data);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Nullable
|
||||
@Override
|
||||
public NamedScreenHandlerFactory createScreenHandlerFactory(BlockState state, World world, BlockPos pos) {
|
||||
return (NamedScreenHandlerFactory) world.getBlockEntity(pos);
|
||||
}
|
||||
|
||||
private void removeStack(final World world, final gridEntity from, final PlayerEntity to, final int slot,
|
||||
final boolean giveItem) {
|
||||
final ItemStack stack = from.removeStack(slot);
|
||||
if (!stack.isEmpty() && giveItem) {
|
||||
to.getInventory().offerOrDrop(stack);
|
||||
world.playSound(null, from.getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 0.2f,
|
||||
(float) (Math.random() - Math.random()) * 1.4f + 2f);
|
||||
}
|
||||
}
|
||||
|
||||
private void onHammerRemoved(final World world, final gridEntity grid, final BlockState state,
|
||||
final PlayerEntity player, final boolean giveItem) {
|
||||
world.setBlockState(grid.getPos(), state);
|
||||
|
||||
if (player.isSneaking()) {
|
||||
for (final int i : grid.sections().itemIndices()) {
|
||||
removeStack(world, grid, player, i, giveItem);
|
||||
}
|
||||
} else {
|
||||
int slot = -1;
|
||||
for (int i = grid.size() - 1; i >= 0; i--) {
|
||||
if (grid.items()[i].isPresent()) {
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (slot != -1) {
|
||||
removeStack(world, grid, player, slot, giveItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onStateReplaced(BlockState oldState, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
if (world.isClient || oldState.getBlock() == newState.getBlock()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final @Nullable BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
final @Nullable PlayerEntity player = breaker;
|
||||
|
||||
if (player != null) {
|
||||
if (player.getStackInHand(player.getActiveHand()).getItem() == ITEMS.GRID_HAMMER) {
|
||||
onHammerRemoved(world, (gridEntity) blockEntity, oldState, player, false);
|
||||
} else {
|
||||
super.onStateReplaced(oldState, world, pos, newState, moved);
|
||||
}
|
||||
} else {
|
||||
if (blockEntity instanceof Inventory) {
|
||||
ItemScatterer.spawn(world, pos, (Inventory) blockEntity);
|
||||
}
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onBlockBreakStart(BlockState state, World world, BlockPos pos, PlayerEntity player) {
|
||||
super.onBlockBreakStart(state, world, pos, player);
|
||||
if (world.isClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getStackInHand(player.getActiveHand()).getItem() == ITEMS.GRID_HAMMER) {
|
||||
final @Nullable BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
|
||||
if (blockEntity instanceof gridEntity) {
|
||||
onHammerRemoved(world, (gridEntity) blockEntity, state, player, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
|
||||
super.onBreak(world, pos, state, player);
|
||||
if (world.isClient || !player.isCreative()) {
|
||||
return;
|
||||
}
|
||||
breaker = player;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||
BlockHitResult hit) {
|
||||
final @Nullable BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
if (!(blockEntity instanceof gridEntity)) {
|
||||
return ActionResult.CONSUME;
|
||||
}
|
||||
|
||||
final @NotNull gridEntity grid = (gridEntity) blockEntity;
|
||||
final @Nullable ItemStack playerStack = player.getMainHandStack();
|
||||
|
||||
if (playerStack != null) {
|
||||
final Vec3d posInBlock = hit.getPos().subtract(Vec3d.of(hit.getBlockPos()));
|
||||
final int relativeSlot = getRelativeSlotAt(posInBlock, hit.getSide());
|
||||
|
||||
final Function3<List<Optional<ItemStack>>, Integer, Supplier<Unit>, ActionResult> swapItems = (slots,
|
||||
absoluteSlot, onSuccess) -> {
|
||||
final Optional<ItemStack> maybeStack = slots.get(relativeSlot);
|
||||
if (playerStack.getItem() != maybeStack.orElse(ItemStack.EMPTY).getItem()) {
|
||||
if (!world.isClient) {
|
||||
if (!player.isCreative() && maybeStack.isPresent()) {
|
||||
player.getInventory().offerOrDrop(maybeStack.get());
|
||||
}
|
||||
grid.copyFrom(absoluteSlot, playerStack, 1, !player.isCreative());
|
||||
onSuccess.get();
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return ActionResult.CONSUME;
|
||||
}
|
||||
};
|
||||
|
||||
final ValidQuery.ItemStackValidQuery query = checkIf(playerStack);
|
||||
|
||||
if (query.isValidForOverlay()) {
|
||||
final int absoluteSlot = grid.sections().overlay().makeAbsolute(relativeSlot);
|
||||
return swapItems.apply(grid.overlayItems(), absoluteSlot, () -> Unit.INSTANCE);
|
||||
}
|
||||
|
||||
final Optional<BlockState> maybeBaseState = query.isValidForBase(
|
||||
i -> Optional.ofNullable(i.getBlock()
|
||||
.getPlacementState(new ItemPlacementContext(new ItemUsageContext(player, hand, hit)))),
|
||||
world, pos);
|
||||
if (maybeBaseState.isPresent()) {
|
||||
final int absoluteSlot = grid.sections().base().makeAbsolute(relativeSlot);
|
||||
return swapItems.apply(grid.baseItems(), absoluteSlot, () -> {
|
||||
grid.baseStates()[relativeSlot] = maybeBaseState;
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
if (query.isValidForSpecial()) {
|
||||
final SpecialItems.SpecialItem specialItem = SPECIAL_ITEM.Map.get(playerStack.getItem());
|
||||
final int slot = grid.sections().special().makeAbsolute(specialItem.offset());
|
||||
|
||||
if (grid.getStack(slot).isEmpty()) {
|
||||
if (!world.isClient) {
|
||||
grid.copyFrom(slot, playerStack, 1, !player.isCreative());
|
||||
specialItem.onAdd(world, grid);
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
} else {
|
||||
return ActionResult.CONSUME;
|
||||
}
|
||||
}
|
||||
if (playerStack.isEmpty() && player.isSneaking()) {
|
||||
player.openHandledScreen(state.createScreenHandlerFactory(world, pos));
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
return super.onUse(state, world, pos, player, hand, hit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
|
||||
final boolean tryCopy;
|
||||
|
||||
if (placer instanceof PlayerEntity) {
|
||||
final PlayerEntity player = (PlayerEntity) placer;
|
||||
if (player.getOffHandStack().getItem() != ITEMS.GRID_HAMMER || player.getOffHandStack().getTag() == null) {
|
||||
tryCopy = false;
|
||||
} else {
|
||||
final BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
if (blockEntity instanceof gridEntity) {
|
||||
tryCopy = Hammer.Data.fromTag(player.getOffHandStack().getTag()).applySettings(this,
|
||||
(gridEntity) blockEntity, player, world);
|
||||
} else {
|
||||
tryCopy = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tryCopy = false;
|
||||
}
|
||||
if (!tryCopy) {
|
||||
super.onPlaced(world, pos, state, placer, itemStack);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package modchest.mixin.local;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import modchest.block.custom.grid.gridBlock;
|
||||
import modchest.block.custom.grid.gridCarpet;
|
||||
import modchest.block.custom.grid.gridDoor;
|
||||
import modchest.block.custom.grid.gridFence;
|
||||
import modchest.block.custom.grid.gridFenceGate;
|
||||
import modchest.block.custom.grid.gridLayer;
|
||||
import modchest.block.custom.grid.gridPane;
|
||||
import modchest.block.custom.grid.gridPath;
|
||||
import modchest.block.custom.grid.gridPressurePlate;
|
||||
import modchest.block.custom.grid.gridSlab;
|
||||
import modchest.block.custom.grid.gridStairs;
|
||||
import modchest.block.custom.grid.gridTorch;
|
||||
import modchest.block.custom.grid.gridTrapdoor;
|
||||
import modchest.block.custom.grid.gridWall;
|
||||
import modchest.block.custom.grid.gridWallTorch;
|
||||
import modchest.block.entity.gridEntity;
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
@Mixin({
|
||||
gridBlock.class,
|
||||
gridSlab.class,
|
||||
gridStairs.class,
|
||||
gridFence.class,
|
||||
gridFenceGate.class,
|
||||
gridTrapdoor.class,
|
||||
gridDoor.class,
|
||||
gridPath.class,
|
||||
gridTorch.class,
|
||||
gridWallTorch.class,
|
||||
gridPressurePlate.class,
|
||||
gridWall.class,
|
||||
gridLayer.class,
|
||||
gridCarpet.class,
|
||||
gridPane.class
|
||||
})
|
||||
public class gridEntityProvider implements BlockEntityProvider {
|
||||
private gridEntityProvider() {
|
||||
throw new IllegalStateException("Mixin constructor should not run");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new gridEntity(BLOCK_ENTITY_TYPES.GRID, META.FRAME_SECTIONS);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package modchest.mixin.mc;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
|
||||
@Mixin(BakedQuad.class)
|
||||
public interface BakedQuadAccess {
|
||||
@Accessor("sprite")
|
||||
Sprite sprite;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package modchest.mixin.mc;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
|
||||
@Mixin(BlockItem.class)
|
||||
public interface BlockItemAccess {
|
||||
@Invoker("getPlacementState")
|
||||
@Nullable BlockState getPlacementStateProxy(ItemPlacementContext context);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package modchest.mixin.mc;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import modchest.REServerMod;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.FenceBlock;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
@Mixin(FenceBlock.class)
|
||||
public class FenceBlockMixin {
|
||||
@Inject(method = "canConnect", at = @At("HEAD"), cancellable = true)
|
||||
void connectToGridFence(final BlockState state, final boolean neighborIsFullSquare, final Direction dir,
|
||||
final CallbackInfoReturnable<Boolean> cir) {
|
||||
if (state.isOf(modchest.REServerMod.BLOCKS.GRID_FENCE)) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
|
||||
if ((Object) this == REServerMod.BLOCKS.GRID_FENCE && state.getBlock() instanceof FenceBlock) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package modchest.mixin.mc;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
@Mixin(ItemStack.class)
|
||||
public interface GetItemBeforeEmpty {
|
||||
@Accessor("item")
|
||||
Item getItemBeforeEmpty();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package modchest.mixin.mc;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import modchest.util.initializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.render.item.ItemModels;
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.ModelIdentifier;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Mixin(ItemRenderer.class)
|
||||
public abstract class ItemRendererMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private ItemModels models;
|
||||
|
||||
@Shadow
|
||||
public abstract BakedModel getHeldItemModel(ItemStack stack, World world, LivingEntity entity);
|
||||
|
||||
@Redirect(method = "getHeldItemModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/ItemModels;getModel(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/client/render/model/BakedModel;"))
|
||||
BakedModel getModelProxy(final ItemModels itemModels, final ItemStack stack) {
|
||||
if (stack.getItem() == ITEMS.HAMMER) {
|
||||
return itemModels.getModelManager().getModel(new ModelIdentifier(META.id("hammer_none"), "inventory"));
|
||||
}
|
||||
return itemModels.getModel(stack);
|
||||
}
|
||||
|
||||
@Redirect(method = "innerRenderInGui", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/ItemRenderer;getHeldItemModel(Lnet/minecraft/item/ItemStack;Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;)Lnet/minecraft/client/render/model/BakedModel;"))
|
||||
BakedModel getHeldItemModelProxy(final ItemRenderer itemRenderer, final ItemStack stack, final World world,
|
||||
final LivingEntity entity) {
|
||||
if (stack.getItem() == ITEMS.HAMMER) {
|
||||
final ClientWorld clientWorld = world instanceof ClientWorld ? (ClientWorld) world : null;
|
||||
final BakedModel model = models.getModelManager()
|
||||
.getModel(new ModelIdentifier(META.id("hammer"), "inventory"));
|
||||
final BakedModel model2 = model.getOverrides().apply(model, stack, clientWorld, entity, 0);
|
||||
return model2 == null ? models.getModelManager().getMissingModel() : model2;
|
||||
}
|
||||
return this.getHeldItemModel(stack, world, entity);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package modchest.mixin.mc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.WallBlock;
|
||||
import net.minecraft.block.enums.WallShape;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.state.property.EnumProperty;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
|
||||
@Mixin(WallBlock.class)
|
||||
public class WallBlockMixin extends Block {
|
||||
@Shadow
|
||||
@Final
|
||||
public static BooleanProperty UP;
|
||||
@Shadow
|
||||
@Final
|
||||
public static EnumProperty<WallShape> EAST_SHAPE;
|
||||
@Shadow
|
||||
@Final
|
||||
public static EnumProperty<WallShape> WEST_SHAPE;
|
||||
@Shadow
|
||||
@Final
|
||||
public static EnumProperty<WallShape> SOUTH_SHAPE;
|
||||
@Shadow
|
||||
@Final
|
||||
public static EnumProperty<WallShape> NORTH_SHAPE;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public WallBlockMixin(Settings settings) {
|
||||
super(settings);
|
||||
throw new IllegalStateException("Mixin constructor should not run");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Shadow
|
||||
private static VoxelShape method_24426(VoxelShape voxelShape, WallShape wallShape, VoxelShape voxelShape2, VoxelShape voxelShape3) {
|
||||
throw new IllegalStateException("Shadow method should not run.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
@Override
|
||||
private Map<BlockState, VoxelShape> getShapeMap(float f, float g, float h, float i, float j, float k) {
|
||||
float l = 8.0F - f;
|
||||
float m = 8.0F + f;
|
||||
float n = 8.0F - g;
|
||||
float o = 8.0F + g;
|
||||
VoxelShape voxelShape = Block.createCuboidShape(l, 0.0D, l, m, h, m);
|
||||
VoxelShape voxelShape2 = Block.createCuboidShape(n, i, 0.0D, o, j, o);
|
||||
VoxelShape voxelShape3 = Block.createCuboidShape(n, i, n, o, j, 16.0D);
|
||||
VoxelShape voxelShape4 = Block.createCuboidShape(0.0D, i, n, o, j, o);
|
||||
VoxelShape voxelShape5 = Block.createCuboidShape(n, i, n, 16.0D, j, o);
|
||||
VoxelShape voxelShape6 = Block.createCuboidShape(n, i, 0.0D, o, k, o);
|
||||
VoxelShape voxelShape7 = Block.createCuboidShape(n, i, n, o, k, 16.0D);
|
||||
VoxelShape voxelShape8 = Block.createCuboidShape(0.0D, i, n, o, k, o);
|
||||
VoxelShape voxelShape9 = Block.createCuboidShape(n, i, n, 16.0D, k, o);
|
||||
ImmutableMap.Builder<BlockState, VoxelShape> builder = ImmutableMap.builder();
|
||||
|
||||
for (BlockState state : stateManager.getStates()) {
|
||||
Boolean boolean_ = state.get(UP);
|
||||
WallShape wallShape = state.get(EAST_SHAPE);
|
||||
WallShape wallShape2 = state.get(NORTH_SHAPE);
|
||||
WallShape wallShape3 = state.get(WEST_SHAPE);
|
||||
WallShape wallShape4 = state.get(SOUTH_SHAPE);
|
||||
|
||||
VoxelShape voxelShape10 = VoxelShapes.empty();
|
||||
voxelShape10 = method_24426(voxelShape10, wallShape, voxelShape5, voxelShape9);
|
||||
voxelShape10 = method_24426(voxelShape10, wallShape3, voxelShape4, voxelShape8);
|
||||
voxelShape10 = method_24426(voxelShape10, wallShape2, voxelShape2, voxelShape6);
|
||||
voxelShape10 = method_24426(voxelShape10, wallShape4, voxelShape3, voxelShape7);
|
||||
if (Boolean.TRUE.equals(boolean_)) {
|
||||
voxelShape10 = VoxelShapes.union(voxelShape10, voxelShape);
|
||||
}
|
||||
builder.put(state, voxelShape10);
|
||||
|
||||
}
|
||||
return builder.build();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package modchest.mixin.mc;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
|
||||
@Mixin(WorldRenderer.class)
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface WorldRendererAccess {
|
||||
@Accessor("ticks")
|
||||
int ticks();
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package modchest.util;
|
||||
|
||||
import java.util.PrimitiveIterator;
|
||||
|
||||
public class Float4 {
|
||||
public final float a;
|
||||
public final float b;
|
||||
public final float c;
|
||||
public final float d;
|
||||
|
||||
public Float4(final float a, final float b, final float c, final float d) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.d = d;
|
||||
}
|
||||
|
||||
public static Float4 of(final float a, final float b, final float c, final float d) {
|
||||
return new Float4(a, b, c, d);
|
||||
}
|
||||
|
||||
public float min() {
|
||||
return Math.min(Math.min(Math.min(a, b), c), d);
|
||||
}
|
||||
|
||||
public float max() {
|
||||
return Math.max(Math.max(Math.max(a, b), c), d);
|
||||
}
|
||||
|
||||
public static Float4 fromIterator(final PrimitiveIterator.OfDouble doubles) {
|
||||
return new Float4((float) doubles.nextDouble(), (float) doubles.nextDouble(), (float) doubles.nextDouble(), (float) doubles.nextDouble());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package modchest.util;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ToIntFunction;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public class FunctionalUtil {
|
||||
private FunctionalUtil() {
|
||||
throw new IllegalStateException("Should not instantiate utility class.");
|
||||
}
|
||||
|
||||
public static <A> OptionalInt mapToInt(final Optional<A> optional, final ToIntFunction<A> f) {
|
||||
return optional.map(a -> OptionalInt.of(f.applyAsInt(a))).orElseGet(OptionalInt::empty);
|
||||
}
|
||||
|
||||
public static <A> OptionalInt flatMapToInt(final Optional<A> optional, final Function<A, OptionalInt> f) {
|
||||
return optional.isPresent() ? f.apply(optional.get()) : OptionalInt.empty();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package modchest.util;
|
||||
|
||||
import modchest.mixin.mc.GetItemBeforeEmpty;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class GetItemBeforeEmptyUtil {
|
||||
private GetItemBeforeEmptyUtil(){
|
||||
throw new IllegalStateException("Should not instantiate utility class.");
|
||||
}
|
||||
|
||||
public static Item getItemBeforeEmpty(final ItemStack stack) {
|
||||
return ((GetItemBeforeEmpty) (Object) stack).getItemBeforeEmpty();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package modchest.util;
|
||||
|
||||
import org.intellij.lang.annotations.JdkConstants.HorizontalAlignment;
|
||||
import org.spongepowered.asm.util.perf.Profiler.Section;
|
||||
|
||||
import com.mojang.datafixers.util.Function5;
|
||||
|
||||
import net.minecraft.inventory.Inventory;
|
||||
|
||||
public enum GuiUtil {
|
||||
;
|
||||
|
||||
public static WLabel label(final String translationKey) {
|
||||
return new WLabel(new TranslatableText(translationKey));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static <L extends WLabel> L centered(final L label) {
|
||||
label.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||
label.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
return label;
|
||||
}
|
||||
|
||||
public static <S extends WItemSlot> S slotRow(
|
||||
final Function5<Inventory, Integer, Integer, Integer, Boolean, S> constructor, final Inventory inventory,
|
||||
final Section section) {
|
||||
return constructor.apply(inventory, section.start(), section.size(), 1, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package modchest.util;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class Identifiable<A> {
|
||||
private final A value;
|
||||
private final Identifier id;
|
||||
|
||||
public Identifiable (final A value, final Identifier id) {
|
||||
this.value = value;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public A value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Identifier id() {
|
||||
return id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package modchest.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class Section implements Iterable<Integer> {
|
||||
private final int start;
|
||||
private final int end;
|
||||
|
||||
public Section(final int start, final int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public static Section exclusive(final int start, final int end) {
|
||||
return new Section(start, end);
|
||||
}
|
||||
|
||||
public int start() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public int end() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
public int makeRelative(final int absolute) {
|
||||
return absolute - start;
|
||||
}
|
||||
|
||||
public int makeAbsolute(final int relative) {
|
||||
return relative + start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
final Section section = (Section) o;
|
||||
if (start != section.start)
|
||||
return false;
|
||||
return end == section.end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = start;
|
||||
result = 31 * result + end;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean contains(final int i) {
|
||||
return start <= i && i < end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return new SectionIterator();
|
||||
}
|
||||
|
||||
private class SectionIterator implements Iterator<Integer> {
|
||||
int current = start;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current < end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
if (current >= end) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return current++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package modchest.util;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ValidQuery {
|
||||
private ValidQuery() {}
|
||||
|
||||
public static class ItemStackValidQuery {
|
||||
private final ItemStack stack;
|
||||
|
||||
public ItemStackValidQuery(final ItemStack stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
public Optional<BlockState> isValidForBase (final Function<BlockItem, Optional<BlockState>> toState, final World world, final BlockPos pos) {
|
||||
final Item item = stack.getItem();
|
||||
|
||||
if (item instanceof BlockItem) {
|
||||
final BlockItem blockItem = (BlockItem) item;
|
||||
if (blockItem.getBlock() instanceof grid) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return toState.apply(blockItem).filter(b -> checkIf(b).isValidForBase(world, pos));
|
||||
}
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValidForOverlay () {
|
||||
return OVERLAYS.hasOverlay(stack);
|
||||
}
|
||||
|
||||
public boolean isValidForSpecial() {
|
||||
return SPECIAL_ITEMS.Map.containsKey(stack.getItem());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class BlockStateValidQuery {
|
||||
private final BlockState state;
|
||||
|
||||
public BlockStateValidQuery(final BlockState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean isValidForBase(final World world, final BlockPos pos) {
|
||||
if (state.getBlock() instanceof BlockEntityProvider && state.getRenderType() != BlockRenderType.MODEL) {
|
||||
return false;
|
||||
}
|
||||
return state.getOutlineShape(world, pos).getBoundingBoxes().equals(VoxelShapes.fullCube().getBoundingBoxes());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static ItemStackValidQuery checkIf(final ItemStack stack) {
|
||||
return new ItemStackValidQuery(stack);
|
||||
}
|
||||
|
||||
public static BlockStateValidQuery checkIf(final BlockState state) {
|
||||
return new BlockStateValidQuery(state);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,6 @@ package modchest.util;
|
|||
import modchest.block.entity.modBlockEntities;
|
||||
import modchest.block.modBlocks;
|
||||
import modchest.event.playerAfterRespawnEvent;
|
||||
import modchest.event.useBlockCallback;
|
||||
import modchest.item.modItemGroup;
|
||||
import modchest.item.modItems;
|
||||
import modchest.networking.modNetworkingServer;
|
||||
|
@ -23,7 +22,8 @@ public class initializer {
|
|||
|
||||
public static void events() { //Events, bei denen custom Code ausgefuehrt wird, werden eingefuehrt
|
||||
ServerPlayerEvents.AFTER_RESPAWN.register(new playerAfterRespawnEvent());
|
||||
useBlockCallback.EVENT.register(new useBlockCallback());
|
||||
//useBlockCallback.EVENT.register(new useBlockCallback());
|
||||
//useEntityCallback.EVENT.register(new useEntityCallback());
|
||||
}
|
||||
|
||||
public static void networking() { //Identifier unter denen der Server zuhoert werden registriert
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 769 B |
Loading…
Reference in New Issue