This repository has been archived by the owner on Jul 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Functional (albeit messy) proof of concept
- Loading branch information
1 parent
09666bf
commit 8a1cc78
Showing
14 changed files
with
256 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 9 additions & 3 deletions
12
src/main/java/cocona20xx/retribution/RetributionModClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,23 @@ | ||
package cocona20xx.retribution; | ||
|
||
import cocona20xx.retribution.impl.EmissiveDataReloader; | ||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper; | ||
import net.minecraft.client.MinecraftClient; | ||
import net.minecraft.resource.ResourceType; | ||
import org.quiltmc.loader.api.ModContainer; | ||
import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; | ||
import org.quiltmc.qsl.resource.loader.api.ResourceLoader; | ||
import org.quiltmc.qsl.resource.loader.api.reloader.ResourceReloaderKeys; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class RetributionModClient implements ClientModInitializer { | ||
public static final String MOD_ID = "retribution"; | ||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); | ||
|
||
public static final int MODIFIER = 0; | ||
@Override | ||
public void onInitializeClient(ModContainer mod) { | ||
LOGGER.info("It's retributing time!!!"); | ||
LOGGER.info("Retribution is loading..."); | ||
ResourceLoader.get(ResourceType.CLIENT_RESOURCES).registerReloader(new EmissiveDataReloader()); | ||
ResourceLoader.get(ResourceType.CLIENT_RESOURCES).addReloaderOrdering(EmissiveDataReloader.RELOADER_ID, ResourceReloaderKeys.BEFORE_VANILLA); | ||
} | ||
} |
114 changes: 114 additions & 0 deletions
114
src/main/java/cocona20xx/retribution/impl/EmissiveDataReloader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package cocona20xx.retribution.impl; | ||
|
||
import cocona20xx.retribution.RetributionModClient; | ||
import com.google.common.collect.Lists; | ||
import com.google.gson.Gson; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParseException; | ||
import com.google.gson.JsonPrimitive; | ||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; | ||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap; | ||
import net.minecraft.resource.Resource; | ||
import net.minecraft.resource.ResourceManager; | ||
import net.minecraft.util.Identifier; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.quiltmc.qsl.resource.loader.api.reloader.SimpleSynchronousResourceReloader; | ||
|
||
import java.io.BufferedReader; | ||
import java.util.ArrayList; | ||
import java.util.Objects; | ||
import java.util.regex.Pattern; | ||
|
||
public class EmissiveDataReloader implements SimpleSynchronousResourceReloader { | ||
private static final Object2ObjectMap<String, ParsedItemFlagData> EMISSIVE_MAP = new Object2ObjectArrayMap<>(); | ||
private static final Gson GSON = new Gson(); | ||
private static final String[] PARENT_BLACKLIST = {"template_banner", "template_bed", "template_shulker_box", "template_skull", "template_spawn_egg", "trident_in_hand", "spyglass_in_hand", "block"}; | ||
private static final ArrayList<String> BLACKLIST_LIST = Lists.newArrayList(PARENT_BLACKLIST); | ||
public static final Identifier RELOADER_ID = new Identifier("retribution", "emissive"); | ||
private static final String[] flags = {"layer0", "layer1", "layer2", "layer3", "layer4"}; | ||
|
||
@Override | ||
public void reload(ResourceManager manager) { | ||
RetributionModClient.LOGGER.info("Starting Emissive Load..."); | ||
EMISSIVE_MAP.clear(); | ||
for(Identifier id : manager.findResources("models/item", path -> path.toString().endsWith(".json")).keySet()){ | ||
try { | ||
for(Resource r : manager.getAllResources(id)){ | ||
try (BufferedReader reader = r.openBufferedReader()){ | ||
JsonObject mainObject = GSON.fromJson(reader, JsonObject.class); | ||
if(mainObject.has("emissive_flags")){ | ||
if(!BLACKLIST_LIST.contains(mainObject.get("parent").getAsString())){ | ||
JsonObject flagObject = mainObject.getAsJsonObject("emissive_flags"); | ||
JsonObject textureObject = mainObject.getAsJsonObject("textures"); | ||
for (int i = 0; i < 4; i++) { | ||
if (flagObject.has(flags[i])) { | ||
JsonPrimitive flagPrim = flagObject.getAsJsonPrimitive(flags[i]); | ||
if (flagPrim.isBoolean()) { | ||
if (flagPrim.getAsBoolean()) { | ||
if (!textureObject.has(flags[i])) { | ||
throw new JsonParseException("Flag set for layer but layer is not present"); | ||
} else { | ||
String texSimple = simplifyFromIdString(textureObject.get(flags[i]).getAsString()); | ||
ParsedItemFlagData data = new ParsedItemFlagData(); | ||
data.setFlag(i, texSimple); | ||
EMISSIVE_MAP.put(texSimple, data); | ||
} | ||
} | ||
} else throw new JsonParseException("Flag set to non-boolean value"); | ||
} | ||
} | ||
} | ||
} | ||
} catch (Exception e){ | ||
RetributionModClient.LOGGER.warn("Error occurred when trying to parse emissive data: " + e); | ||
} | ||
} | ||
} catch (Exception e){ | ||
RetributionModClient.LOGGER.warn("IO Error when trying to parse emissive data: " + e); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public @NotNull Identifier getQuiltId() { | ||
return RELOADER_ID; | ||
} | ||
|
||
private static void add(String simplifiedId, ParsedItemFlagData data){ | ||
if(EMISSIVE_MAP.containsKey(simplifiedId)) RetributionModClient.LOGGER.warn("Emissive map key overlap detected: "+ simplifiedId); | ||
EMISSIVE_MAP.put(simplifiedId, data); | ||
} | ||
public static ParsedItemFlagData getData(String simplifiedId){ | ||
return EMISSIVE_MAP.get(simplifiedId); | ||
} | ||
public static boolean hasDataForSimple(String simplifiedId){ | ||
return EMISSIVE_MAP.containsKey(simplifiedId); | ||
} | ||
public static String simplifyFromId(Identifier id){ | ||
String buildSimple = ""; | ||
buildSimple = buildSimple.concat(id.getNamespace()).concat("#"); | ||
String[] slashSeparatedPath = id.getPath().split(Pattern.quote("/")); | ||
int s = slashSeparatedPath.length - 1; | ||
return buildSimple.concat(slashSeparatedPath[s]); | ||
} | ||
private static String simplifyFromIdString(String idAsString){ | ||
if(idAsString.contains(":")) { | ||
//string contains a namespace, we can parse it like an Identifier object | ||
String buildSimple = idAsString.split(Pattern.quote(":"))[0].concat("#"); | ||
String[] slashSeparatedPath = idAsString.split(Pattern.quote(":"))[1].split("/"); | ||
int s = slashSeparatedPath.length - 1; | ||
return buildSimple.concat(slashSeparatedPath[s]); | ||
} else { | ||
//no namespace means implicit minecraft namespace | ||
String buildSimple = idAsString.replaceFirst(Pattern.quote("item/"),""); | ||
buildSimple = "minecraft#" + buildSimple; | ||
return buildSimple; | ||
} | ||
} | ||
public static int flagStringToInt(String flag){ | ||
for(int i = 0; i < 4; i++){ | ||
if(Objects.equals(flag, flags[i])) return i; | ||
} | ||
return -1; | ||
} | ||
} |
33 changes: 0 additions & 33 deletions
33
src/main/java/cocona20xx/retribution/impl/EmissiveFlagJsonParser.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/main/java/cocona20xx/retribution/internal/ModelElementEmissiveAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package cocona20xx.retribution.internal; | ||
|
||
import net.minecraft.client.render.model.json.ModelElement; | ||
|
||
public interface ModelElementEmissiveAccessor { | ||
boolean isEmissive(); | ||
void setEmissive(boolean set); | ||
|
||
ModelElement getActual(); | ||
|
||
void storeActual(ModelElement actual); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
src/main/java/cocona20xx/retribution/mixins/ItemModelGeneratorMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package cocona20xx.retribution.mixins; | ||
|
||
import cocona20xx.retribution.RetributionModClient; | ||
import cocona20xx.retribution.impl.EmissiveDataReloader; | ||
import cocona20xx.retribution.impl.ParsedItemFlagData; | ||
import cocona20xx.retribution.internal.ModelElementEmissiveAccessor; | ||
import com.mojang.datafixers.util.Either; | ||
import net.minecraft.client.render.model.json.ItemModelGenerator; | ||
import net.minecraft.client.render.model.json.JsonUnbakedModel; | ||
import net.minecraft.client.render.model.json.ModelElement; | ||
import net.minecraft.client.texture.Sprite; | ||
import net.minecraft.client.util.SpriteIdentifier; | ||
import net.minecraft.util.Identifier; | ||
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 org.spongepowered.asm.mixin.injection.callback.LocalCapture; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
|
||
@Mixin(ItemModelGenerator.class) | ||
public class ItemModelGeneratorMixin { | ||
@Inject(method = "create", at = @At(value = "INVOKE_ASSIGN", | ||
target = "Lnet/minecraft/client/render/model/json/ItemModelGenerator;addLayerElements(ILjava/lang/String;Lnet/minecraft/client/texture/Sprite;)Ljava/util/List;", shift = At.Shift.BY, by = 1), | ||
locals = LocalCapture.CAPTURE_FAILHARD) | ||
public void createInjector(Function<SpriteIdentifier, Sprite> textureGetter, JsonUnbakedModel blockModel, CallbackInfoReturnable<JsonUnbakedModel> cir, Map<String, Either<SpriteIdentifier, String>> map, List<ModelElement> list, int i, String string, SpriteIdentifier spriteIdentifier, Sprite sprite){ | ||
int size = list.size(); | ||
Identifier id = spriteIdentifier.getTextureId(); | ||
String simple = EmissiveDataReloader.simplifyFromId(id); | ||
if(EmissiveDataReloader.hasDataForSimple(simple)){ | ||
RetributionModClient.LOGGER.info(simple); | ||
int flagInt = EmissiveDataReloader.flagStringToInt(string); | ||
ParsedItemFlagData data = EmissiveDataReloader.getData(simple); | ||
if(data.hasId(flagInt)){ | ||
for (int j = 0; j < size; j++) { | ||
ModelElement current = list.get(j); | ||
ModelElementEmissiveAccessor elementAccessor = (ModelElementEmissiveAccessor)current; | ||
elementAccessor.setEmissive(true); | ||
elementAccessor.storeActual(current); | ||
list.set(j, elementAccessor.getActual()); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.