Skip to content

Commit

Permalink
New api (#288)
Browse files Browse the repository at this point in the history
* add api subproject

* WIP move api into its own mod

* update mdg

* load ae2wtlib api when ae2wtlib is present

* rename the api run config, so it doesn't run both

* fix ordering so ae2wtlib runs after api (and by extension, ae2)

* fix ordering so ae2wtlib runs after ae2 (turns out ordering is not applied transitively)

* properly register components

* get the ModContainer via constructor parameter

* fix upgrades, run terminal registration at the right time

* spotless

* make api methods static instead of requiring to use .instance() anywhere

* move lang entries that are relevant on api to api

* scale up icon to 400*400 because neoforge is stupid and doesn't use nearest neighbor scaling

* slightly clean up buildscript

* use sourceSet instead of subproject

* CHANGELOG [no ci]

* Revert "use sourceSet instead of subproject"

This reverts commit ca32ef0.

* update dependencies

* add incompatible marker to currently released extendedae versions

* CHANGELOG [no ci]

* fix rebase error

* match changes from main branch

* move assets that are required in api to api

* remove outdated icon from gui

* always open universal terminal first if there is one

* update reference textures and move them into their own folder [no ci]

* update dependencies

* slightly change which libraries are set as dependencies
sadly I can't get it to not include the runtimeOnly dependencies

* add modmaven publishing

* add megacells as incompatibility

* fix modmaven publishing using the wrong url

* use smaller scale icon again and turn off blurring

* fix typo in CHANGELOG

* update incompatible version ranges for extendedae and megacells

* add incompatibility with old ae2wtlib versions to ae2wtlib_api

* fix formatting in build.gradle.kts

* add some api documentation to the readme
  • Loading branch information
Mari023 authored Jul 28, 2024
1 parent 1101081 commit 2fe63b5
Show file tree
Hide file tree
Showing 101 changed files with 1,302 additions and 299 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ jobs:
with:
cache-read-only: true

- name: Build with Gradle
run: gradle build
- name: Build and publish with Gradle
run: gradle build publishAllPublicationsToModmavenRepository
env:
TAG: ${{ github.event.release.tag_name }}
MODMAVEN_USER: ${{ secrets.MODMAVEN_USER }}
MODMAVEN_PASSWORD: ${{ secrets.MODMAVEN_PASSWORD }}
ORG_GRADLE_PROJECT_runtimeItemlistMod: none

- name: Upload a neoforge build
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- new API for addons
- updated the mod icon
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,55 @@ It also adds a wireless universal terminal which has all wireless terminals in o

* Text and Translations
- [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/)

## API

Like ae2, ae2wtlib is available on modmaven
```
repositories {
maven {
url = uri("https://modmaven.dev/")
content {
includeGroup "appeng"
includeGroup "de.mari_023"
}
}
}
```

ae2wtlib has an api, which is what you should compile against when making integrations with ae2wtlib
```
dependencies {
implementation("de.mari_023:ae2wtlib_api:VERSION")
runtimeOnly("de.mari_023:ae2wtlib:VERSION")
}
```

If you want to add your own terminals, you should jar-in-jar ae2wtlib_api
```
dependencies {
jarJar(implementation("de.mari_023:ae2wtlib_api:VERSION"))
runtimeOnly("de.mari_023:ae2wtlib:VERSION")
}
```

If you want to add upgrades to ae2wtlib terminals, you can use `UpgradeHelper#addUpgradeToAllTerminals`
```java
addUpgradeToAllTerminals(upgradeCard, maxSupported);
// use 0 to add the maximum amount of upgrades the terminal can fit
addUpgradeToAllTerminals(upgradeCard, 0);
```

### Adding terminals

For a simple example of a wireless terminal, you can look at the Wireless Pattern Access Terminal.
The related classes are `ItemWAT`, `WATMenu`, `WATMenuHost` and `WATScreen`

For registration, you need to listen to the `AddTerminalEvent` (it isn't actually an EventBus event)
```java
AddTerminalEvent.register(event -> event.builder(
...
).addTerminal())
```

The builder has some additional methods for overriding properties that are inferred from other attributes, like `WTDefinitionBuilder#translationKey`
111 changes: 111 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
plugins {
id("net.neoforged.moddev")
id("com.diffplug.spotless")
id("maven-publish")
java
idea
}

val ae2Version: String by project
val neoforgeVersion: String by project
val mavenGroup: String by project
val modID: String by project


version = "0.0.0-SNAPSHOT"

val pr = System.getenv("PR_NUMBER") ?: ""
if (pr != "") {
version = "0.0.0-pr$pr"
}

val tag = System.getenv("TAG") ?: ""
if (tag != "") {
version = tag
}

val artifactVersion = version

java.toolchain.languageVersion = JavaLanguageVersion.of(21)

dependencies {
implementation("appeng:appliedenergistics2:${ae2Version}")
compileOnly("com.google.code.findbugs:jsr305:3.0.2")
}

tasks {
processResources {
// Ensure the resources get re-evaluate when the version changes
inputs.property("version", version)
inputs.property("ae2_version", ae2Version)

val replaceProperties = mapOf(
"version" to version as String, "ae2_version" to ae2Version
)

inputs.properties(replaceProperties)
filesMatching("META-INF/neoforge.mods.toml") {
expand(replaceProperties)
}
}
withType<JavaCompile> {
options.encoding = "UTF-8"
}
}

neoForge {
version = neoforgeVersion
mods {
create(modID) {
sourceSet(sourceSets.main.get())
}
}
runs {
configureEach {
gameDirectory.file("run")
systemProperty("forge.logging.console.level", "debug")
}

create("api_client") {
client()
}
create("api_server") {
server()
}
}
}

publishing {
publications {
create<MavenPublication>(modID) {
groupId = mavenGroup
artifactId = modID
version = artifactVersion.toString()

from(components["java"])
}
}
repositories {
maven {
credentials {
username = System.getenv("MODMAVEN_USER")
password = System.getenv("MODMAVEN_PASSWORD")
}
name = "modmaven"
url = uri("https://modmaven.dev/artifactory/local-releases/")
}
}
}

spotless {
java {
target("/src/**/java/**/*.java")

endWithNewline()
indentWithSpaces()
removeUnusedImports()
toggleOffOn()
eclipse().configFile("../codeformat/codeformat.xml")
importOrderFile("../codeformat/ae2wtlib.importorder")
}
}
1 change: 1 addition & 0 deletions api/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
modID=ae2wtlib_api
76 changes: 76 additions & 0 deletions api/src/main/java/de/mari_023/ae2wtlib/api/AE2wtlibAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package de.mari_023.ae2wtlib.api;

import java.util.function.Supplier;

import com.mojang.datafixers.util.Unit;

import org.jetbrains.annotations.ApiStatus;

import net.minecraft.core.component.DataComponentType;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.neoforged.fml.ModList;

import appeng.api.upgrades.IUpgradeInventory;
import appeng.menu.locator.ItemMenuHostLocator;

import de.mari_023.ae2wtlib.api.terminal.ItemWUT;

public class AE2wtlibAPI {
public static final String MOD_NAME = "ae2wtlib";
public static final String API_MOD_NAME = "ae2wtlib_api";

private AE2wtlibAPI() {}

public static ResourceLocation id(String name) {
return ResourceLocation.fromNamespaceAndPath(MOD_NAME, name);
}

public static boolean isModPresent(String mod) {
return ModList.get().isLoaded(mod);
}

public static boolean hasQuantumBridgeCard(Supplier<IUpgradeInventory> upgrades) {
return AE2wtlibAPIImpl.instance().hasQuantumBridgeCard(upgrades);
}

public static boolean isUniversalTerminal(Item item) {
return AE2wtlibAPIImpl.instance().isUniversalTerminal(item);
}

public static boolean isUniversalTerminal(ItemStack stack) {
return isUniversalTerminal(stack.getItem());
}

public static ItemStack makeWUT(DataComponentType<Unit> componentType) {
if (!(getWUT() instanceof ItemWUT wutItem))
return ItemStack.EMPTY;
ItemStack wut = new ItemStack(wutItem);

wut.set(componentType, Unit.INSTANCE);
return wut;
}

public static Item getWUT() {
return AE2wtlibAPIImpl.instance().getWUT();
}

@ApiStatus.Internal
public static void cycleTerminal(boolean isHandlingRightClick) {
AE2wtlibAPIImpl.instance().cycleTerminal(isHandlingRightClick);
}

/**
* Sends an update to the client about the current terminal. This is only relevant for Universal Terminals, and only
* sent when ae2wtlib is present.
*
* @param player The server player.
* @param locator The menu locator.
* @param stack The compound tag containing terminal data.
*/
public static void updateClientTerminal(ServerPlayer player, ItemMenuHostLocator locator, ItemStack stack) {
AE2wtlibAPIImpl.instance().updateClientTerminal(player, locator, stack);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package de.mari_023.ae2wtlib.api;

import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.registries.RegisterEvent;

import de.mari_023.ae2wtlib.api.registration.AddTerminalEvent;
import de.mari_023.ae2wtlib.api.registration.UpgradeHelper;

@Mod(AE2wtlibAPI.API_MOD_NAME)
public class AE2wtlibAPIEntrypoint {
public AE2wtlibAPIEntrypoint(IEventBus modEventBus) {
modEventBus.addListener((RegisterEvent event) -> {
if (!event.getRegistryKey().equals(Registries.ITEM)) {
return;
}
AddTerminalEvent.run();
UpgradeHelper.addUpgrades();
for (var entry : AE2wtlibComponents.DR.entrySet())
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, entry.getKey(), entry.getValue());
});
}
}
53 changes: 53 additions & 0 deletions api/src/main/java/de/mari_023/ae2wtlib/api/AE2wtlibAPIImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package de.mari_023.ae2wtlib.api;

import java.util.Objects;
import java.util.function.Supplier;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;

import appeng.api.upgrades.IUpgradeInventory;
import appeng.menu.locator.ItemMenuHostLocator;

@ApiStatus.Internal
public class AE2wtlibAPIImpl {
@Nullable
private static AE2wtlibAPIImpl instance;

protected AE2wtlibAPIImpl() {
if (instance != null)
throw new IllegalStateException("Already initialized");
instance = this;
}

public static AE2wtlibAPIImpl instance() {
return Objects.requireNonNull(instance);
}

static {
if (!AE2wtlibAPI.isModPresent("ae2wtlib"))
new AE2wtlibAPIImpl();
}

public boolean hasQuantumBridgeCard(Supplier<IUpgradeInventory> upgrades) {
return false;
}

public boolean isUniversalTerminal(Item item) {
return false;
}

public Item getWUT() {
return Items.AIR;
}

@ApiStatus.Internal
public void cycleTerminal(boolean isHandlingRightClick) {}

public void updateClientTerminal(ServerPlayer player, ItemMenuHostLocator locator, ItemStack stack) {}
}
Loading

0 comments on commit 2fe63b5

Please sign in to comment.