Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
35852bd
First batch of changes
DanyGames2014 Jun 29, 2026
4c58d72
Fix a Dany L Moment
DanyGames2014 Jun 29, 2026
869ac43
BlockStateReloadEvent
DanyGames2014 Jun 29, 2026
0c23b00
Cant run without this
DanyGames2014 Jun 29, 2026
9628bb6
Merge branch 'ModificationStation:develop' into various-gripes
DanyGames2014 Jun 29, 2026
7063374
oops
DanyGames2014 Jun 29, 2026
b4705e9
Brought back from the dead
DanyGames2014 Jun 29, 2026
558b603
Code stealing moment
DanyGames2014 Jun 29, 2026
2bc5b10
Fix getTextureDependencies
DanyGames2014 Jun 29, 2026
71e4059
proper names
DanyGames2014 Jun 29, 2026
ca0c7ae
Reduced to a helper method
DanyGames2014 Jun 29, 2026
d1b10b3
More changes, more events and mine's beloved SuperBuilder
DanyGames2014 Jun 30, 2026
c97849c
Fix AMI yelling
DanyGames2014 Jun 30, 2026
317389d
Finish ModelVariantMapOverrideEvent
DanyGames2014 Jun 30, 2026
d842080
Optimize PackedIntegerArray to 1.4% of runtime cost when looking up i…
DanyGames2014 Jul 9, 2026
4836c33
Use Objects.checkIndex in EmptyPaletteStorage
DanyGames2014 Jul 11, 2026
3454ed5
This helps a bit.. for some reason
DanyGames2014 Jul 11, 2026
4864b41
CachedFlattenedChunk, reduced block id lookup by around 12s over a 60…
DanyGames2014 Jul 11, 2026
7c78b05
Try using shorts in CachedFlattenedChunk and fix crash if bottomY is …
DanyGames2014 Jul 25, 2026
aacf2b6
Bye bye items
DanyGames2014 Jul 26, 2026
7112672
whoops
mineLdiver Jul 26, 2026
40d613f
Merge remote-tracking branch 'DanyGames2014/various-gripes' into fork…
mineLdiver Jul 26, 2026
efd0397
BlockStateReloadEvent bad
mineLdiver Jul 26, 2026
a145f38
getBlock() -> owner = performance
DanyGames2014 Jul 26, 2026
fd44dc0
owner -> block
DanyGames2014 Jul 26, 2026
1fb6dcf
deimport the imported import
DanyGames2014 Jul 26, 2026
351aaac
make this immutable
DanyGames2014 Jul 26, 2026
281d11c
Literally saved 50% of memory on models
DanyGames2014 Jul 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ allprojects {
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
tasks.withType<JavaCompile> {
options.release = 17
options.encoding = "UTF-8"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public void registerItems(ItemRegistryEvent event) {
testPickaxe = new ModdedPickaxeItem(NAMESPACE.id("test_pickaxe"), testMaterial); //8476
testNBTItem = new NBTItem(NAMESPACE.id("nbt_item")); //8477
testModelItem = new ModelItem(NAMESPACE.id("model_item")).setMaxCount(1);
ironOre = event.register(NAMESPACE.id("iron_ore"), new Item(ItemRegistry.AUTO_ID));
generatedItem = event.register(NAMESPACE.id("generated_item"), new Item(ItemRegistry.AUTO_ID));
ironOre = event.register(NAMESPACE.id("iron_ore"), new Item(ItemRegistry.AUTO_ID).setTranslationKey(NAMESPACE.id("iron_ore")));
generatedItem = event.register(NAMESPACE.id("generated_item"), new Item(ItemRegistry.AUTO_ID).setTranslationKey(NAMESPACE.id("generated_item")));
variationBlockIdle = new BlockStateItem(NAMESPACE.id("variation_block_idle"), Blocks.VARIATION_BLOCK.get().getDefaultState());
variationBlockPassive = new BlockStateItem(NAMESPACE.id("variation_block_passive"), Blocks.VARIATION_BLOCK.get().getDefaultState().with(VariationBlock.VARIANT, VariationBlock.Variant.PASSIVE));
variationBlockActive = new BlockStateItem(NAMESPACE.id("variation_block_active"), Blocks.VARIATION_BLOCK.get().getDefaultState().with(VariationBlock.VARIANT, VariationBlock.Variant.ACTIVE));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package net.modificationstation.sltest.render;

import com.mojang.datafixers.util.Pair;
import net.mine_diver.unsafeevents.listener.EventListener;
import net.modificationstation.sltest.SLTest;
import net.modificationstation.stationapi.api.client.event.render.model.BeforeModelLoaderInitEvent;
import net.modificationstation.stationapi.api.client.event.render.model.ModelVariantMapOverrideEvent;
import net.modificationstation.stationapi.api.client.event.render.model.UnbakedModelLoadingFinishedEvent;
import net.modificationstation.stationapi.api.client.render.model.ModelLoader;
import net.modificationstation.stationapi.api.client.render.model.json.ModelVariantMap;
import net.modificationstation.stationapi.api.event.resource.RuntimeResourcesEvent;
import net.modificationstation.stationapi.api.util.Identifier;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.List;

public class ModelLoadingListener {
@EventListener
public void modelsLoaded(UnbakedModelLoadingFinishedEvent event) {
SLTest.LOGGER.info(event.unbakedModels.size() + " models loaded");
}

String blockstateJson = ("""
{
"variants": {
"": {"model": "sltest:block/test_block"}
}
}"""
);

String dirtBlockstateJson = ("""
{
"variants": {
"": {"model": "sltest:block/dirt"}
}
}"""
);

@EventListener
public void injectBlockStates(RuntimeResourcesEvent.Assets event) {
event.with(ModelLoader.BLOCK_STATES_FINDER)
.add(Identifier.of("minecraft:sponge"), blockstateJson)
.add(Identifier.of("minecraft:dirt"), dirtBlockstateJson);
}

@EventListener
public void beforeLoader(BeforeModelLoaderInitEvent event) {
SLTest.LOGGER.info("Model Loader Init");
logBlockStateSources(event, Identifier.of("minecraft:sponge"));
logBlockStateSources(event, Identifier.of("minecraft:dirt"));
}

private static void logBlockStateSources(BeforeModelLoaderInitEvent event, Identifier block) {
List<ModelLoader.SourceTrackedData> sources = event.blockStates.get(ModelLoader.BLOCK_STATES_FINDER.toResourcePath(block));
SLTest.LOGGER.info("blockstate {} has {} definition(s) layered", block, sources == null ? 0 : sources.size());
if (sources != null) for (int i = 0; i < sources.size(); i++)
SLTest.LOGGER.info(" layer {}: {}", i, sources.get(i).data());
}

String blockstateVariantJson = ("""
{
"variants": {
"": {"model": "sltest:block/test_block"}
}
}"""
);

@EventListener
public void mineLdiver(ModelVariantMapOverrideEvent event) {
if (event.id.equals(Identifier.of("minecraft:note_block"))) {
BufferedReader reader = new BufferedReader(new StringReader(blockstateVariantJson));
event.addModelVariantMap(SLTest.NAMESPACE, ModelVariantMap.fromJson(event.deserializationContext, reader));
}

System.err.println(event.id);
for (Pair<String, ModelVariantMap> variantMap : event.variantMaps) {
System.err.println(" - " + variantMap.getFirst() + " | " + variantMap.getSecond().getVariantMap().toString());
}
}
}
3 changes: 2 additions & 1 deletion src/test/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"net.modificationstation.sltest.option.OptionListener",
"net.modificationstation.sltest.keyboard.KeyboardListener",
"net.modificationstation.sltest.texture.TextureListener",
"net.modificationstation.sltest.render.entity.EntityRendererListener"
"net.modificationstation.sltest.render.entity.EntityRendererListener",
"net.modificationstation.sltest.render.ModelLoadingListener"
],
"main": [
"net.modificationstation.sltest.MainTest"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package net.modificationstation.stationapi.api.effect;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NbtCompound;
Expand All @@ -10,16 +8,15 @@ public abstract class EntityEffect<THIS extends EntityEffect<THIS>> {
public static final int INFINITY_TICKS = -1;
protected Entity entity;
private int ticks;

private final String nameTranslationKey;
private final String descriptionTranslationKey;

protected EntityEffect(Entity entity, int ticks) {
this.entity = entity;
this.ticks = ticks;
var effectId = getType().registryEntry.registryKey().getValue();
nameTranslationKey = "gui.stationapi.effect." + effectId.namespace + "." + effectId.path + ".name";
descriptionTranslationKey = nameTranslationKey.substring(0, nameTranslationKey.length() - 4) + "desc";
this.nameTranslationKey = getType().getTranslationKey();
this.descriptionTranslationKey = getType().getDescriptionTranslationKey();
}

/**
Expand All @@ -29,58 +26,72 @@ protected EntityEffect(Entity entity, int ticks) {
* or synchronized from the server later.
*/
public abstract void onAdded(boolean appliedNow);

/**
* This method is called on each entity tick.
*/
public abstract void onTick();

/**
* This method is called immediately when the effect is removed.
*/
public abstract void onRemoved();

/**
* Allows to write any custom data to the tag storage.
*
* @param tag effect data root tag
*/
protected abstract void writeNbt(NbtCompound tag);

/**
* Allows to read any custom data from the tag storage.
*
* @param tag effect data root tag
*/
protected abstract void readNbt(NbtCompound tag);

public abstract EntityEffectType<THIS> getType();

/**
* Get remaining effect ticks.
*/
public final int getTicks() {
return ticks;
}

/**
* Check if effect is infinite.
*/
public final boolean isInfinite() {
return ticks == INFINITY_TICKS;
}

/**
* Get translated effect name, client side only.
* Get the translation key for the name of the effect.
*/
@Environment(EnvType.CLIENT)
public final String getName() {
public final String getTranslationKey() {
return this.nameTranslationKey;
}

/**
* Get the translation key for the description of the effect.
*/
public final String getDescriptionTranslationKey() {
return this.descriptionTranslationKey;
}

/**
* Get translated effect name.
*/
public final String getTranslatedName() {
return I18n.getTranslation(nameTranslationKey, nameTranslationKey);
}

/**
* Get translated effect description, client side only.
* Get translated effect description.
*/
@Environment(EnvType.CLIENT)
public final String getDescription() {
public final String getTranslatedDescription() {
return I18n.getTranslation(descriptionTranslationKey, descriptionTranslationKey);
}

Expand All @@ -93,12 +104,12 @@ public final void tick() {
}
}
}

public final void write(NbtCompound nbt) {
nbt.putInt("ticks", ticks);
writeNbt(nbt);
}

public final void read(NbtCompound nbt) {
ticks = nbt.getInt("ticks");
readNbt(nbt);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.modificationstation.stationapi.api.effect;

import net.modificationstation.stationapi.api.registry.RegistryEntry;
import net.modificationstation.stationapi.api.util.Identifier;

/**
* Static reference of an effect. Since {@link EntityEffect} is initialized per-entity, a separate class is required
Expand All @@ -24,6 +25,29 @@ private EntityEffectType(Builder<EFFECT_INSTANCE> builder) {
factory = builder.factory;
}

/**
* Returns the identifier of the effect
*/
public Identifier getIdentifier() {
return registryEntry.registryKey().getValue();
}

/**
* Returns the translation key of the effect's name.
*/
public String getTranslationKey() {
Identifier identifier = registryEntry.registryKey().getValue();
return "gui.stationapi.effect." + identifier.namespace + "." + identifier.path + ".name";
}

/**
* Returns the translation key of the effect's description.
*/
public String getDescriptionTranslationKey() {
Identifier identifier = registryEntry.registryKey().getValue();
return "gui.stationapi.effect." + identifier.namespace + "." + identifier.path + ".desc";
}

/**
* @param factory the effect instance's factory which takes an {@link net.minecraft.entity.Entity} argument
* of the entity the effect's been applied to, and an int argument defining the duration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public void renderEffects(Minecraft minecraft, float delta, boolean extended) {
int py = 2;
for (EntityEffect<?> effect : renderEffects) {
if (extended) {
String name = effect.getName();
String desc = effect.getDescription();
String name = effect.getTranslatedName();
String desc = effect.getTranslatedDescription();
int width = Math.max(
textRenderer.getWidth(name),
textRenderer.getWidth(desc)
Expand Down Expand Up @@ -127,8 +127,8 @@ private void renderEffectBack(Minecraft minecraft, int y, int width) {

private int getEffectWidth(EntityEffect<?> effect) {
if (effect.isInfinite()) return 26;
String name = effect.getName();
String desc = effect.getDescription();
String name = effect.getTranslatedName();
String desc = effect.getTranslatedDescription();
return Math.max(
textRenderer.getWidth(name),
textRenderer.getWidth(desc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.stream.Stream;

public abstract class AbstractBlockState extends State<Block, BlockState> {
public final Block block;
private final boolean isAir;
private final Material material;
private final MapColor materialColor;
Expand All @@ -32,6 +33,7 @@ public abstract class AbstractBlockState extends State<Block, BlockState> {

protected AbstractBlockState(Block block, ImmutableMap<Property<?>, Comparable<?>> propertyMap, MapCodec<BlockState> mapCodec) {
super(block, propertyMap, mapCodec);
this.block = block;
this.isAir = block.material == Material.AIR;
this.material = block.material;
this.materialColor = block.material.mapColor;
Expand All @@ -40,7 +42,7 @@ protected AbstractBlockState(Block block, ImmutableMap<Property<?>, Comparable<?
}

public Block getBlock() {
return this.owner;
return this.block;
}

public Material getMaterial() {
Expand All @@ -52,7 +54,7 @@ public Material getMaterial() {
*/
public int getLuminance() {
return luminance == -1 ?
luminance = ((StationFlatteningBlockInternal) owner).stationapi_getLuminanceProvider().applyAsInt(asBlockState()) :
luminance = ((StationFlatteningBlockInternal) block).stationapi_getLuminanceProvider().applyAsInt(asBlockState()) :
luminance;
}

Expand All @@ -65,47 +67,47 @@ public MapColor getTopMaterialColor(BlockView world, BlockPos pos) {
}

public float getHardness(BlockView world, BlockPos pos) {
return getBlock().getHardness(asBlockState(), world, pos);
return block.getHardness(asBlockState(), world, pos);
}

public float calcBlockBreakingDelta(PlayerEntity player, BlockView world, BlockPos pos) {
return getBlock().calcBlockBreakingDelta(asBlockState(), player, world, pos);
return block.calcBlockBreakingDelta(asBlockState(), player, world, pos);
}

public boolean isOpaque() {
return this.opaque;
}

public void onStateReplaced(World world, BlockPos pos, BlockState state) {
this.getBlock().onStateReplaced(this.asBlockState(), world, pos, state);
this.block.onStateReplaced(this.asBlockState(), world, pos, state);
}

public boolean canReplace(ItemPlacementContext context) {
return this.getBlock().canReplace(this.asBlockState(), context);
return this.block.canReplace(this.asBlockState(), context);
}

public boolean isIn(TagKey<Block> tag) {
return getBlock().getRegistryEntry().isIn(tag);
return block.getRegistryEntry().isIn(tag);
}

public boolean isIn(TagKey<Block> tag, Predicate<AbstractBlockState> predicate) {
return this.isIn(tag) && predicate.test(this);
}

public boolean isIn(RegistryEntryList<Block> blocks) {
return blocks.contains(getBlock().getRegistryEntry());
return blocks.contains(block.getRegistryEntry());
}

public Stream<TagKey<Block>> streamTags() {
return getBlock().getRegistryEntry().streamTags();
return block.getRegistryEntry().streamTags();
}

public boolean isOf(Block block) {
return this.getBlock() == block;
return this.block == block;
}

public boolean hasRandomTicks() {
return Block.BLOCKS_RANDOM_TICK[getBlock().id];
return Block.BLOCKS_RANDOM_TICK[block.id];
}

@Environment(EnvType.CLIENT)
Expand Down
Loading