Skip to content

Commit a65aebe

Browse files
committed
fix: rendering
1 parent 40deadc commit a65aebe

7 files changed

Lines changed: 286 additions & 28 deletions

File tree

src/lib/custom_resources_apply.go

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,41 @@ type textureCacheLookupDetail struct {
5050
StableKey string
5151
}
5252

53+
func isGenericPackedSkullTexture(input ItemTextureInput, texture AppliedItemTexture) bool {
54+
id := normalizeMinecraftItemID(input.ID)
55+
if id == "" {
56+
id = normalizeMinecraftItemID(input.ItemModel)
57+
}
58+
if skullIdentityFromInput(input) == "" && !isVanillaSkullItemID(id) {
59+
return false
60+
}
61+
62+
texturePath := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(texture.Texture), "\\", "/"))
63+
return strings.Contains(texturePath, "model=minecraft_item_template_skull") &&
64+
strings.Contains(texturePath, "tex1=block_soul_sand")
65+
}
66+
67+
func isVanillaSkullItemID(id string) bool {
68+
switch normalizeMinecraftItemID(id) {
69+
case "minecraft:player_head",
70+
"minecraft:zombie_head",
71+
"minecraft:skeleton_skull",
72+
"minecraft:wither_skeleton_skull",
73+
"minecraft:creeper_head",
74+
"minecraft:dragon_head",
75+
"minecraft:piglin_head":
76+
return true
77+
default:
78+
return false
79+
}
80+
}
81+
5382
func cachedTextureForInputDetailed(input ItemTextureInput, textureCtx TextureApplyContext) (AppliedItemTexture, bool, textureCacheLookupDetail) {
5483
skyblockID := strings.TrimSpace(input.SkyBlockID)
5584
hasItemModel := normalizeMinecraftItemID(input.ItemModel) != ""
5685
hasSkullIdentity := skullIdentityFromInput(input) != ""
5786
if !hasItemModel || hasSkullIdentity {
58-
if texture, ok := cachedStableSkyBlockTexture(skyblockID, textureCtx); ok {
87+
if texture, ok := cachedStableSkyBlockTexture(skyblockID, textureCtx); ok && !isGenericPackedSkullTexture(input, texture) {
5988
return texture, true, textureCacheLookupDetail{
6089
Reason: "stable_skyblock_cache",
6190
StableKey: "skyblock:" + skyblockID,
@@ -67,15 +96,15 @@ func cachedTextureForInputDetailed(input ItemTextureInput, textureCtx TextureApp
6796
if skyblockID != "" && stableKey == "skyblock:"+skyblockID {
6897
continue
6998
}
70-
if texture, ok := cachedTextureForStableKey(stableKey, textureCtx.PackSignature, textureCtx.EnabledPackIDs, textureCtx.EnabledPackSet); ok {
99+
if texture, ok := cachedTextureForStableKey(stableKey, textureCtx.PackSignature, textureCtx.EnabledPackIDs, textureCtx.EnabledPackSet); ok && !isGenericPackedSkullTexture(input, texture) {
71100
return texture, true, textureCacheLookupDetail{
72101
Reason: "stable_key_cache",
73102
StableKey: stableKey,
74103
}
75104
}
76105
}
77106
if skyblockID != "" && !hasSkullIdentity && !hasItemModel {
78-
if texture, ok := cachedItemTexture(skyblockID, textureCtx); ok {
107+
if texture, ok := cachedItemTexture(skyblockID, textureCtx); ok && !isGenericPackedSkullTexture(input, texture) {
79108
return texture, true, textureCacheLookupDetail{
80109
Reason: "legacy_skyblock_cache",
81110
StableKey: skyblockID,
@@ -464,11 +493,13 @@ func ApplyTextureInput(input ItemTextureInput, textureCtx TextureApplyContext) A
464493
Texture: publicCacheTextureURL(customTexture.Path),
465494
TexturePack: customTexture.TexturePackID,
466495
}
467-
if stats != nil {
468-
stats.RenderHits++
496+
if !isGenericPackedSkullTexture(input, outputTexture) {
497+
if stats != nil {
498+
stats.RenderHits++
499+
}
500+
setCachedTextureForInput(input, textureCtx, outputTexture)
501+
return finishFallback("runtime_render_hit", "", outputTexture)
469502
}
470-
setCachedTextureForInput(input, textureCtx, outputTexture)
471-
return finishFallback("runtime_render_hit", "", outputTexture)
472503
}
473504

474505
if renderErr != nil && id != "" && vanillaItemResourceExists(id) {
@@ -491,11 +522,13 @@ func ApplyTextureInput(input ItemTextureInput, textureCtx TextureApplyContext) A
491522
Texture: publicCacheTextureURL(customTexture.Path),
492523
TexturePack: customTexture.TexturePackID,
493524
}
494-
if stats != nil {
495-
stats.RenderHits++
525+
if !isGenericPackedSkullTexture(input, outputTexture) {
526+
if stats != nil {
527+
stats.RenderHits++
528+
}
529+
setCachedTextureForInput(input, textureCtx, outputTexture)
530+
return finishFallback("runtime_vanilla_render_hit", "", outputTexture)
496531
}
497-
setCachedTextureForInput(input, textureCtx, outputTexture)
498-
return finishFallback("runtime_vanilla_render_hit", "", outputTexture)
499532
}
500533
}
501534
}
@@ -556,19 +589,19 @@ func ApplyTextureInput(input ItemTextureInput, textureCtx TextureApplyContext) A
556589
}
557590
return finishFallback("vanilla_texture_fallback", "", vanillaTexture)
558591
}
559-
if vanillaTexture := vanillaModelTextureURL(id); vanillaTexture.Texture != "" {
592+
if vanillaTexture := vanillaSpecialHeadTextureURL(id); vanillaTexture.Texture != "" {
560593
if stats != nil {
561594
stats.VanillaFallbacks++
562595
stats.VanillaModelFallbacks++
563596
}
564-
return finishFallback("vanilla_model_fallback", "", vanillaTexture)
597+
return finishFallback("vanilla_special_head_fallback", "", vanillaTexture)
565598
}
566-
if vanillaTexture := vanillaSpecialHeadTextureURL(id); vanillaTexture.Texture != "" {
599+
if vanillaTexture := vanillaModelTextureURL(id); vanillaTexture.Texture != "" {
567600
if stats != nil {
568601
stats.VanillaFallbacks++
569602
stats.VanillaModelFallbacks++
570603
}
571-
return finishFallback("vanilla_special_head_fallback", "", vanillaTexture)
604+
return finishFallback("vanilla_model_fallback", "", vanillaTexture)
572605
}
573606

574607
if renderErr != nil {

src/lib/custom_resources_vanilla.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,22 +244,34 @@ func vanillaModelTextureURL(id string) AppliedItemTexture {
244244

245245
func vanillaSpecialHeadTextureURL(id string) AppliedItemTexture {
246246
id = strings.TrimSpace(strings.ToLower(strings.TrimPrefix(id, "minecraft:")))
247+
texturePath := ""
247248
switch id {
248249
case "zombie_head":
249-
return vanillaAssetTextureURL("entity/zombie/zombie")
250+
texturePath = "entity/zombie/zombie"
250251
case "skeleton_skull":
251-
return vanillaAssetTextureURL("entity/skeleton/skeleton")
252+
texturePath = "entity/skeleton/skeleton"
252253
case "wither_skeleton_skull":
253-
return vanillaAssetTextureURL("entity/skeleton/wither_skeleton")
254+
texturePath = "entity/skeleton/wither_skeleton"
254255
case "creeper_head":
255-
return vanillaAssetTextureURL("entity/creeper/creeper")
256+
texturePath = "entity/creeper/creeper"
256257
case "dragon_head":
257258
return vanillaAssetTextureURL("entity/enderdragon/dragon")
258259
case "piglin_head":
259260
return vanillaAssetTextureURL("entity/piglin/piglin")
260261
default:
261262
return AppliedItemTexture{}
262263
}
264+
265+
appRoot, err := appRootDir()
266+
if err != nil {
267+
return AppliedItemTexture{}
268+
}
269+
sourcePath := filepath.Join(appRoot, "assets", "resourcepacks", "Vanilla", "assets", "minecraft", "textures", filepath.FromSlash(texturePath+".png"))
270+
cacheID := "minecraft_" + id
271+
if rendered := RenderLocalHead(cacheID, sourcePath); len(rendered) == 0 {
272+
return AppliedItemTexture{}
273+
}
274+
return AppliedItemTexture{Texture: publicCacheTextureURL(filepath.Join(CACHE_DIR, "heads", cacheID+".png"))}
263275
}
264276

265277
func readVanillaJSON(path string) map[string]any {

src/lib/item_renderer.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,69 @@ func itemTextureCandidates(itemID string, damage int) (map[string]any, map[strin
7777
customItem, modelItem := skyBlockTextureCandidates(itemData, damage)
7878
return customItem, modelItem, nil
7979
}
80+
if neuItem, err := notenoughupdates.GetItem(strings.ToUpper(itemID)); err == nil {
81+
customItem, modelItem := neuTextureCandidates(itemID, neuItem, damage)
82+
return customItem, modelItem, nil
83+
}
8084

8185
customItem, err := vanillaTextureCandidate(itemID, damage)
8286
return customItem, nil, err
8387
}
8488

89+
func neuTextureCandidates(itemID string, neuItem models.NEUItem, damage int) (map[string]any, map[string]any) {
90+
itemDamage := neuItem.Damage
91+
if damage != 0 {
92+
itemDamage = damage
93+
}
94+
95+
skyBlockID := strings.TrimSpace(neuItem.NEUId)
96+
if skyBlockID == "" {
97+
skyBlockID = strings.ToUpper(strings.TrimSpace(itemID))
98+
}
99+
100+
tag := neuItem.NBT.ToMap()
101+
itemModel := strings.TrimSpace(neuItem.NBT.ItemModel)
102+
minecraftID, numericID := neuMinecraftItemID(neuItem.MinecraftId, itemModel, itemDamage)
103+
104+
customItem := map[string]any{
105+
"id": minecraftID,
106+
"tag": tagWithoutItemModel(tag),
107+
"damage": itemDamage,
108+
"item_id": numericID,
109+
"skyblock_id": skyBlockID,
110+
}
111+
if itemModel == "" {
112+
return customItem, nil
113+
}
114+
115+
return customItem, map[string]any{
116+
"id": normalizeMinecraftItemID(itemModel),
117+
"ItemModel": itemModel,
118+
"tag": tag,
119+
"damage": itemDamage,
120+
"item_id": numericID,
121+
"skyblock_id": skyBlockID,
122+
}
123+
}
124+
125+
func neuMinecraftItemID(minecraftID string, itemModel string, damage int) (string, int) {
126+
normalizedID := normalizeMinecraftItemID(minecraftID)
127+
lookupID := strings.ToUpper(strings.TrimPrefix(normalizedID, "minecraft:"))
128+
if lookupID == "SKULL" {
129+
lookupID = "SKULL_ITEM"
130+
}
131+
numericID := constants.BUKKIT_TO_ID[lookupID]
132+
if numericID != 0 {
133+
if mappedID := constants.GetVanillaItemId(constants.ItemModel{NumericId: numericID, ItemDamage: damage}); mappedID != "" {
134+
normalizedID = "minecraft:" + mappedID
135+
}
136+
}
137+
if normalizedID == "" && strings.TrimSpace(itemModel) != "" {
138+
normalizedID = normalizeMinecraftItemID(itemModel)
139+
}
140+
return normalizedID, numericID
141+
}
142+
85143
func skyBlockTextureCandidates(itemData models.ProcessedHypixelItem, damage int) (map[string]any, map[string]any) {
86144
itemDamage := itemData.Damage
87145
if damage != 0 {

src/lib/renderer.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,48 @@ func RenderHead(textureId string) []byte {
222222
return b
223223
}
224224

225+
func RenderLocalHead(cacheID string, texturePath string) []byte {
226+
cachePath := filepath.Join(CACHE_DIR, "heads", cacheID+".png")
227+
if data, err := os.ReadFile(cachePath); err == nil {
228+
return data
229+
}
230+
231+
result, err, _ := headGroup.Do("local:"+cacheID, func() (interface{}, error) {
232+
if data, err := os.ReadFile(cachePath); err == nil {
233+
return data, nil
234+
}
235+
236+
img, err := loadImage(texturePath)
237+
if err != nil {
238+
return nil, err
239+
}
240+
241+
head := To3DHead(img)
242+
var buf bytes.Buffer
243+
if err := png.Encode(&buf, head); err != nil {
244+
return nil, err
245+
}
246+
data := buf.Bytes()
247+
248+
if err := os.MkdirAll(filepath.Dir(cachePath), 0755); err == nil {
249+
if err := os.WriteFile(cachePath, data, 0644); err != nil {
250+
log.Println("Error saving local head to cache:", err)
251+
}
252+
}
253+
return data, nil
254+
})
255+
if err != nil {
256+
log.Printf("Error rendering local head %s: %v", cacheID, err)
257+
return nil
258+
}
259+
260+
data, ok := result.([]byte)
261+
if !ok {
262+
return nil
263+
}
264+
return data
265+
}
266+
225267
type imageResult struct {
226268
img image.Image
227269
err error

0 commit comments

Comments
 (0)