-
-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathModelManagerMixin.java
More file actions
59 lines (52 loc) · 3.23 KB
/
ModelManagerMixin.java
File metadata and controls
59 lines (52 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package org.geysermc.rainbow.mixin;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.item.ClientItem;
import net.minecraft.client.resources.model.ClientItemInfoLoader;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ResolvedModel;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import org.geysermc.rainbow.accessor.ResolvedModelAccessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Mixin(ModelManager.class)
public abstract class ModelManagerMixin implements PreparableReloadListener, AutoCloseable, ResolvedModelAccessor {
@Unique
private Map<ResourceLocation, ResolvedModel> unbakedResolvedModels;
@Unique
private Map<ResourceLocation, ClientItem> clientItems;
@WrapOperation(method = "method_65753", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;join()Ljava/lang/Object;", ordinal = 1))
private static Object setResolvedModels(CompletableFuture<?> instance, Operation<Object> original) {
Object resolved = original.call(instance);
try {
// Couldn't be bothered setting up access wideners, this resolves the second component of the ResolvedModels record, which is called "models"
// Ideally we'd somehow use the "this" instance, but that's not possible here since the lambda we inject into is a static one
((ModelManagerMixin) (Object) Minecraft.getInstance().getModelManager()).unbakedResolvedModels = (Map<ResourceLocation, ResolvedModel>) resolved.getClass().getRecordComponents()[1].getAccessor().invoke(resolved);
} catch (IllegalAccessException | InvocationTargetException | ClassCastException exception) {
throw new RuntimeException(exception);
}
return resolved;
}
@WrapOperation(method = "method_65753", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/ClientItemInfoLoader$LoadedClientInfos;contents()Ljava/util/Map;"))
private static Map<ResourceLocation, ClientItem> setClientItems(ClientItemInfoLoader.LoadedClientInfos instance, Operation<Map<ResourceLocation, ClientItem>> original) {
// Same note as above for not using "this"
ModelManagerMixin thiz = ((ModelManagerMixin) (Object) Minecraft.getInstance().getModelManager());
thiz.clientItems = original.call(instance);
return thiz.clientItems;
}
@Override
public Optional<ResolvedModel> rainbow$getResolvedModel(ResourceLocation location) {
return unbakedResolvedModels == null ? Optional.empty() : Optional.ofNullable(unbakedResolvedModels.get(location));
}
@Override
public Optional<ClientItem> rainbow$getClientItem(ResourceLocation location) {
return clientItems == null ? Optional.empty() : Optional.ofNullable(clientItems.get(location));
}
}