Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3852c0c
feat: add struct grammar rules to sfml
ReinderN Jan 24, 2026
1aa745e
feat: add struct ast classes
ReinderN Jan 24, 2026
c5ea665
refactor: implement structfieldvalue on existing ast classes
ReinderN Jan 24, 2026
48314d3
feat: add struct support to program and labelaccess
ReinderN Jan 24, 2026
586d8eb
feat: add struct visitor methods to astbuilder
ReinderN Jan 24, 2026
1635366
feat: add struct linters
ReinderN Jan 24, 2026
8bac6ed
test: add struct tests
ReinderN Jan 24, 2026
9559894
feat: add protocol, macro, and library support to SFML
ReinderN Jan 24, 2026
d2372c6
feat: add library block for sharing SFML definitions
ReinderN Jan 24, 2026
6274bb6
feat: add linters for protocol and macro usage
ReinderN Jan 24, 2026
b6705d9
feat: add syntax highlighting and localization for new keywords
ReinderN Jan 24, 2026
5eebc38
test: add tests for protocols, macros, and structs
ReinderN Jan 24, 2026
cb49705
feat: add library block GUI, textures, and disk indicator renderer
ReinderN Jan 24, 2026
abf34fe
refactor: remove unused import feature and add templates
ReinderN Jan 25, 2026
a314d63
perf: optimize library block resolution with auto-label cache
ReinderN Jan 25, 2026
bbef8e3
fix: auto-revalidate programs when library blocks change
ReinderN Jan 25, 2026
804a138
refactor: consolidate code duplication and improve maintainability
ReinderN Jan 25, 2026
62f7e42
feat: replace EXPAND keyword with DO and @ symbol for macro invocation
ReinderN Jan 25, 2026
53eab73
style: rename ITEMS constant to items field
ReinderN Jan 25, 2026
d9f26b3
fix: add debouncing for library changes and circular dependency detec…
ReinderN Jan 25, 2026
2fe9c1f
feat: add library block crafting recipe
ReinderN Jan 25, 2026
dbfc900
feat: enable USE statements in library disks and error display
ReinderN Jan 25, 2026
f64f993
feat: improve library block visuals with pulsing indicators and serve…
ReinderN Jan 25, 2026
2ad7702
feat: redesign library GUI to match server rack aesthetic
ReinderN Jan 25, 2026
013f499
fix: recompile libraries and managers on cable network changes
ReinderN Jan 25, 2026
eda119f
feat: integrate LED indicator into disk slot
ReinderN Jan 25, 2026
f64970d
fix: notify disconnected blocks when cable is removed
ReinderN Jan 25, 2026
f5cb7a2
fix: ensure network discovery on world reload and batch notifications
ReinderN Jan 25, 2026
095bb5d
fix: recompile library disks when isolated from network
ReinderN Jan 25, 2026
eb31736
test: add library and definitions tests
ReinderN Jan 25, 2026
39dd822
refactor: simplify struct instantiation syntax
ReinderN Jan 25, 2026
5081e36
docs: add WITH clause example to structs template
ReinderN Jan 25, 2026
a34904d
fix: truncate long library names and add scroll on hover
ReinderN Jan 25, 2026
e141081
Merge remote-tracking branch 'upstream/1.19.2' into feature/library-a…
ReinderN Jan 26, 2026
e9415a9
Merge branch '1.19.2' into feature/library-and-definitions
ReinderN Jan 28, 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
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ protected void registerStatesAndModels() {
registerWaterTank();
registerTestBarrel();
registerBuffer();
registerLibrary();
}

private void registerTestBarrel() {
Expand Down Expand Up @@ -283,4 +284,36 @@ private void registerBuffer() {
});

}

private void registerLibrary() {
if (SFMBlocks.LIBRARY_BLOCK == null) return;

// Create a model with different textures for front, back, and sides
ModelFile libraryModel = models().cube(
SFMBlocks.LIBRARY_BLOCK.getPath(),
modLoc("block/library_bot"), // down
modLoc("block/library_top"), // up
modLoc("block/library_front"), // north (front)
modLoc("block/library_back"), // south (back)
modLoc("block/library_side"), // west
modLoc("block/library_side") // east
).texture("particle", modLoc("block/library_top"));

// Create variants for each horizontal facing direction
getVariantBuilder(SFMBlocks.LIBRARY_BLOCK.get())
.forAllStates(state -> {
Direction facing = state.getValue(ca.teamdman.sfm.common.block.LibraryBlock.FACING);
int yRot = switch (facing) {
case NORTH -> 0;
case EAST -> 90;
case SOUTH -> 180;
case WEST -> 270;
default -> 0;
};
return ConfiguredModel.builder()
.modelFile(libraryModel)
.rotationY(yRot)
.build();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ protected void registerModels() {
justParent(SFMItems.PRINTING_PRESS_ITEM, SFMBlocks.PRINTING_PRESS_BLOCK);
justParent(SFMItems.WATER_TANK_ITEM, SFMBlocks.WATER_TANK_BLOCK, "_active");
justParent(SFMItems.BUFFER_ITEM, SFMBlocks.BUFFER_BLOCK, "_item");
if (SFMItems.LIBRARY_ITEM != null) {
justParent(SFMItems.LIBRARY_ITEM, SFMBlocks.LIBRARY_BLOCK);
}
basicItem(SFMItems.DISK_ITEM);
basicItem(SFMItems.LABEL_GUN_ITEM);
basicItem(SFMItems.EXPERIENCE_GOOP_ITEM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ protected void populate(BlockLootWriter writer) {
writer.dropOther(SFMBlocks.FANCY_CABLE_FACADE_BLOCK, SFMBlocks.FANCY_CABLE_BLOCK);
writer.dropSelf(SFMBlocks.PRINTING_PRESS_BLOCK);
writer.dropSelf(SFMBlocks.WATER_TANK_BLOCK);
if (SFMBlocks.LIBRARY_BLOCK != null) {
writer.dropSelf(SFMBlocks.LIBRARY_BLOCK);
}
}

@Override
Expand Down
13 changes: 13 additions & 0 deletions src/datagen/java/ca/teamdman/sfm/datagen/SFMRecipesDatagen.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ca.teamdman.sfm.common.registry.SFMBlocks;
import ca.teamdman.sfm.common.registry.SFMItems;
import ca.teamdman.sfm.common.registry.SFMRecipeSerializers;
import ca.teamdman.sfm.common.util.SFMEnvironmentUtils;
import ca.teamdman.sfm.common.util.SFMResourceLocation;
import ca.teamdman.sfm.datagen.version_plumbing.MCVersionAgnosticRecipeDataGen;
import net.minecraft.data.recipes.FinishedRecipe;
Expand Down Expand Up @@ -196,6 +197,18 @@ protected void populate(Consumer<FinishedRecipe> writer) {
.pattern("gxg")
.save(writer);

if (SFMEnvironmentUtils.isInIDE() && SFMBlocks.LIBRARY_BLOCK != null) {
beginShaped(SFMBlocks.LIBRARY_BLOCK.get(), 1)
.define('M', SFMBlocks.MANAGER_BLOCK.get())
.define('B', Blocks.BOOKSHELF)
.define('L', Blocks.LECTERN)
.unlockedBy("has_manager", RecipeProvider.has(SFMBlocks.MANAGER_BLOCK.get()))
.pattern("MBM")
.pattern("BLB")
.pattern("MBM")
.save(writer);
}

addPrintingPressRecipe(
writer,
SFMResourceLocation.fromSFMPath("written_book_copy"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package ca.teamdman.sfm.gametest;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Classes annotated with this that extend {@link SFMGameTestGeneratorBase} will have their
* {@link SFMGameTestGeneratorBase#generateTests} method invoked to produce game test definitions.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SFMGameTestGenerator {
}
package ca.teamdman.sfm.gametest;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Classes annotated with this that extend {@link SFMGameTestGeneratorBase} will have their
* {@link SFMGameTestGeneratorBase#generateTests} method invoked to produce game test definitions.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SFMGameTestGenerator {
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package ca.teamdman.sfm.gametest;
import java.util.function.Consumer;
/**
* Base class for game test generators. Subclasses annotated with
* {@link SFMGameTestGenerator} will have their {@link #generateTests} method
* invoked during test discovery to produce multiple game test definitions.
*/
public abstract class SFMGameTestGeneratorBase {
/**
* Generates game test definitions and passes them to the provided consumer.
*
* @param testConsumer a consumer that accepts generated test definitions
*/
public abstract void generateTests(Consumer<SFMGameTestDefinition> testConsumer);
}
package ca.teamdman.sfm.gametest;

import java.util.function.Consumer;

/**
* Base class for game test generators. Subclasses annotated with
* {@link SFMGameTestGenerator} will have their {@link #generateTests} method
* invoked during test discovery to produce multiple game test definitions.
*/
public abstract class SFMGameTestGeneratorBase {

/**
* Generates game test definitions and passes them to the provided consumer.
*
* @param testConsumer a consumer that accepts generated test definitions
*/
public abstract void generateTests(Consumer<SFMGameTestDefinition> testConsumer);
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public void assertExpr(

BoolExpr expr = BoolExpr.from(exprString);
ProgramContext programContext = new ProgramContext(
new Program(new ASTBuilder(), "temp lol", List.of(), Set.of(), Set.of()),
new Program(new ASTBuilder(), "temp lol", List.of(), List.of(), List.of(), Set.of(), Set.of()),
manager,
ExecuteProgramBehaviour::new
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private void runConditions(
if (conditions.isEmpty()) return;
List<BoolExpr> expressions = conditions.stream().map(BoolExpr::from).toList();
ProgramContext programContext = new ProgramContext(
new Program(new ASTBuilder(), "temp lol", List.of(), Set.of(), Set.of()),
new Program(new ASTBuilder(), "temp lol", List.of(), List.of(), List.of(), Set.of(), Set.of()),
manager,
ExecuteProgramBehaviour::new
);
Expand Down
Loading