Skip to content

Commit

Permalink
[1.20.1 - Fabric] Adjust logic for equipping hats to tag method using…
Browse files Browse the repository at this point in the history
… tag injection (#77)

* Switch to using tag injector method for adding hats to hat slot for trinkets rather than a mixin into trinkets

* Adjust code for render Armor to use `getEquipped` instead

* Update modmenu to prevent issues with running game in dev
  • Loading branch information
Dragon-Seeker authored Jul 20, 2024
1 parent 384382d commit 6960386
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 32 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ org.gradle.daemon=false
trinkets_version=3.7.0
cloth_config_version=11.0.99
cc_version=5.2.0
modmenu_version=5.0.2
modmenu_version=7.2.2
4 changes: 4 additions & 0 deletions src/main/java/fonnymunkey/simplehats/SimpleHats.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.LootPool;
Expand All @@ -24,6 +25,7 @@
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
Expand All @@ -36,6 +38,8 @@ public class SimpleHats implements ModInitializer {

public static RegistryKey<ItemGroup> HAT_TAB = RegistryKey.of(RegistryKeys.ITEM_GROUP, new Identifier(modId, "hat_group"));

public static final TagKey<Item> ALL_HATS = TagKey.of(RegistryKeys.ITEM, new Identifier(modId, "all_hats"));

@Override
public void onInitialize() {
config = AutoConfig.register(ModConfig.class, PartitioningSerializer.wrap(Toml4jConfigSerializer::new)).getConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import fonnymunkey.simplehats.common.recipe.HatVariantRecipe;
import fonnymunkey.simplehats.util.HatEntry;
import fonnymunkey.simplehats.util.HatEntry.HatSeason;
import fonnymunkey.simplehats.util.TagInjector;
import net.minecraft.block.cauldron.CauldronBehavior;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
Expand Down Expand Up @@ -62,6 +63,8 @@ public static void registerHats() {
if(hat instanceof HatItemDyeable) CauldronBehavior.WATER_CAULDRON_BEHAVIOR.put((HatItemDyeable)hat, CauldronBehavior.CLEAN_DYEABLE_ITEM);
}
SimpleHats.logger.log(Level.INFO, "Generated " + ModRegistry.hatList.size() + " hat items from hat entries.");

TagInjector.inject(Registries.ITEM, SimpleHats.ALL_HATS.id(), ModRegistry.hatList.stream().map(hatItem -> (Item) hatItem).toList());
}

////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ public class MixinHumanoidArmorLayer {
@Inject(method = "renderArmor", at = @At("HEAD"), cancellable = true)
public void simplehats_renderArmor(MatrixStack matrices, VertexConsumerProvider vertexConsumers, LivingEntity entity, EquipmentSlot armorSlot, int light, BipedEntityModel<LivingEntity> model, CallbackInfo ci) {
if(entity instanceof PlayerEntity && armorSlot.equals(EquipmentSlot.HEAD)) {
TrinketsApi.getTrinketComponent(entity).ifPresent(component ->
component.forEach((slotReference, stack) -> {
if(stack.getItem() instanceof HatItem) ci.cancel();
})
);
TrinketsApi.getTrinketComponent(entity).ifPresent(component -> {
var hasHatTrinket = !component.getEquipped(stack -> stack.getItem() instanceof HatItem).isEmpty();

if(hasHatTrinket) ci.cancel();
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package fonnymunkey.simplehats.mixin.core;

import fonnymunkey.simplehats.util.TagInjector;
import net.minecraft.registry.tag.TagGroupLoader;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Code taken 1:1 from <a href="https://github.com/wisp-forest/owo-lib/blob/f705f91a33f9a31f38f27c0fd9032977f97f15ca/src/main/java/io/wispforest/owo/mixin/TagGroupLoaderMixin.java#L19">TagGroupLoaderMixin</a>
* <p>
* Such is under the MIT license and full credits go to <a href="https://github.com/gliscowo">glisco<a/> for such
*/
@Mixin(TagGroupLoader.class)
public class MixinTagGroupLoader {
@Shadow
@Final
private String dataType;

@Inject(method = "loadTags", at = @At("TAIL"))
public void injectValues(ResourceManager manager, CallbackInfoReturnable<Map<Identifier, List<TagGroupLoader.TrackedEntry>>> cir) {
var map = cir.getReturnValue();

TagInjector.ADDITIONS.forEach((location, entries) -> {
if (!this.dataType.equals(location.type())) return;

var list = map.computeIfAbsent(location.tagId(), id -> new ArrayList<>());
entries.forEach(addition -> list.add(new TagGroupLoader.TrackedEntry(addition, "owo")));
});
}
}

This file was deleted.

124 changes: 124 additions & 0 deletions src/main/java/fonnymunkey/simplehats/util/TagInjector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package fonnymunkey.simplehats.util;

import com.google.common.collect.ForwardingMap;
import net.minecraft.registry.Registry;
import net.minecraft.registry.tag.TagEntry;
import net.minecraft.registry.tag.TagManagerLoader;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Function;

/**
* Code taken 1:1 from <a href="https://github.com/wisp-forest/owo-lib/blob/f705f91a33f9a31f38f27c0fd9032977f97f15ca/src/main/java/io/wispforest/owo/util/TagInjector.java#L18">TagInjector</a>
* <p>
* Such is under the MIT license and full credits go to <a href="https://github.com/gliscowo">glisco<a/> for such
*/
public final class TagInjector {
@ApiStatus.Internal
public static final HashMap<TagLocation, Set<TagEntry>> ADDITIONS = new HashMap<>();

private static final Map<TagLocation, Set<TagEntry>> ADDITIONS_VIEW = new ForwardingMap<>() {
@Override
protected @NotNull Map<TagLocation, Set<TagEntry>> delegate() {
return Collections.unmodifiableMap(ADDITIONS);
}

@Override
public Set<TagEntry> get(@Nullable Object key) {
return Collections.unmodifiableSet(this.delegate().get(key));
}
};

private TagInjector() {}

/**
* @return A view of all planned tag injections
*/
public static Map<TagLocation, Set<TagEntry>> getInjections() {
return ADDITIONS_VIEW;
}

/**
* Inject the given identifiers into the given tag
* <p>
* If any of the identifiers don't correspond to an entry in the
* given registry, you <i>will</i> break the tag.
* If the tag does not exist, it will be created.
*
* @param registry The registry for which the injected tags should apply
* @param tag The tag to insert into, this could contain all kinds of values
* @param entryMaker The function to use for creating tag entries from the given identifiers
* @param values The values to insert
*/
public static void injectRaw(Registry<?> registry, Identifier tag, Function<Identifier, TagEntry> entryMaker, Collection<Identifier> values) {
ADDITIONS.computeIfAbsent(new TagLocation(TagManagerLoader.getPath(registry.getKey()), tag), identifier -> new HashSet<>())
.addAll(values.stream().map(entryMaker).toList());
}

public static void injectRaw(Registry<?> registry, Identifier tag, Function<Identifier, TagEntry> entryMaker, Identifier... values) {
injectRaw(registry, tag, entryMaker, Arrays.asList(values));
}

// -------

/**
* Inject the given values into the given tag, obtaining
* their identifiers from the given registry
*
* @param registry The registry the target tag is for
* @param tag The identifier of the tag to inject into
* @param values The values to inject
* @param <T> The type of the target registry
*/
public static <T> void inject(Registry<T> registry, Identifier tag, Collection<T> values) {
injectDirectReference(registry, tag, values.stream().map(registry::getId).toList());
}

@SafeVarargs
public static <T> void inject(Registry<T> registry, Identifier tag, T... values) {
inject(registry, tag, Arrays.asList(values));
}

// -------

/**
* Inject the given identifiers into the given tag
*
* @param registry The registry the target tag is for
* @param tag The identifier of the tag to inject into
* @param values The values to inject
*/
public static void injectDirectReference(Registry<?> registry, Identifier tag, Collection<Identifier> values) {
injectRaw(registry, tag, TagEntry::create, values);
}

public static void injectDirectReference(Registry<?> registry, Identifier tag, Identifier... values) {
injectDirectReference(registry, tag, Arrays.asList(values));
}

// -------

/**
* Inject the given tags into the given tag,
* effectively nesting them. This is equivalent to
* prefixing an entry in the tag JSON's {@code values} array
* with a {@code #}
*
* @param registry The registry the target tag is for
* @param tag The identifier of the tag to inject into
* @param values The values to inject
*/
public static void injectTagReference(Registry<?> registry, Identifier tag, Collection<Identifier> values) {
injectRaw(registry, tag, TagEntry::createTag, values);
}

public static void injectTagReference(Registry<?> registry, Identifier tag, Identifier... values) {
injectTagReference(registry, tag, Arrays.asList(values));
}

public record TagLocation(String type, Identifier tagId) {}
}
4 changes: 4 additions & 0 deletions src/main/resources/data/simplehats/tags/items/all_hats.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"replace": false,
"values": []
}
6 changes: 6 additions & 0 deletions src/main/resources/data/trinkets/tags/items/head/hat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#simplehats:all_hats"
]
}
2 changes: 1 addition & 1 deletion src/main/resources/mixins.simplehats.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"refmap": "simplehats-fabric-refmap.json",
"mixins": [
"MixinLivingEntity",
"MixinTrinketsApi"
"MixinTagGroupLoader"
],
"minVersion": "0.8",
"client": [
Expand Down

0 comments on commit 6960386

Please sign in to comment.