Optifine Custom Item Textures - The-Iceburg/TotemsPlus Wiki


Optifine Custom Item Textures is the Legacy integration for Totems+ (It was the first one we made) and it utilises the ability in Optifine to rename an item (in this case the Totem) and have its texture change. OFCIT allows the user to take advantage of this capability by uploading multiple of their own totems textures and decide a string to rename each one to in-game.


import os, shutil, getpass, PySimpleGUI as sg
from ANIM import ANI
from RESIZE import RES

First we import the modules used within this integration, currently we utilise:

  • os - To make and check directories/files
  • shutil - To copy/paste images
  • getpass - To use the .minecraft directory
  • pysimplegui - Provides the GUI features
packFormat4 = ["1.14","1.14.1","1.14.2","1.14.3","1.14.4"]
packFormat5 = ["1.15","1.15.1","1.15.2","1.16","1.16.1"]
packFormat6 = ["1.16.2","1.16.3","1.16.4","1.16.5"]

Next we define the pack format codes as a list of their corresponding version. The reason we can't just use .startswith() is because minecraft pack format codes are weird read more here. Minecraft have started to change this however so .startswith is used for versions 1.16.5+ as you'll see later in the code.

def CIT(textureList, version):

Next we actually define the CIT function taking to parameters from the main (totem.py) file the submitted list of textures in the format of the "textureList" and the selected version of minecraft in the format of "version"

counter = 0

Now we define the counter variable for use in the loop part of our code to ensure we know when we've reached the end of a cycle of textures. There's a very long reason as to why we utilise this over a for loop which i won't go into here but just know that it's needed.

textureList = textureList.split(";")

When we are supplied with the texture list it is given as one long string so to format it for use in the looped part of the code (with counter as the index) we split it at every ";" thus transforming it into a list

pathList = RES(textureList)

Then we resize each image for temporary viewing during setup and this is done using the RES function which (as it is utilised across all integrations) is kept in a separate file but essentially just resizes each image in the list to a 100x100 version and saves them in a separate location for the aforementioned use during setup

layout = [ 
        [
            sg.Image(filename=pathList[0], key='-IMAGE-'),
            sg.Text("You've selected Totems+ CIT Integration!\n" + 
            'This integration will generate:\n' + 
            'A Custom Resource Pack\n' + 
            'Follow the tooltip below to customize your packs!\n' + 
            ' ', font=('Helvetica', 10), justification='left'),
        ],
        [
            sg.Text('Rename your different textures to what you wish to rename them in-game\nIt should be noted totems may appear blurred/streched here but\n wont in Minecraft. .GIF files also wont play in this release', key='tooltip')
        ],
        [
            sg.Text('Name:  '),
            sg.InputText(size=(25, 1), key='itemName'),
        ],
        [
            sg.Button('Next', key='next'),
            sg.Button('Cancel', key='cancel'),
        ],
    ]

Without going into line by line detail next we define the layout of the window to make everything look fancy! we also give necessary items tags for use later in the code

window = sg.Window("CIT", layout, icon="img/totems.ico")

Next we actually create the physical window assigning it to a variable to we can listen for button presses later. We give it the window title of "CIT" a layout of the above list and an icon of our totems+ logo stored in the /img folder

name = "Totems+ OFCIT"

As we've coded for the eventuality for the resource pack name to be customized we have to set a deafult in case this feature isnt utlilised. In this case its "Totems+ OFCIT"

if os.path.exists('C:/Users/' + getpass.getuser() + '/AppData/Roaming/.minecraft/resourcepacks/Totems+ OFCIT'):
        name = sg.popup_get_text("An OFCIT Integration resource pack allready exists\nPlease choose a different name for this one:", title = "Duplicate Pack")

Next we check if the user has an existing OFCIT integration pack and if they do we provide a popup allowing for them to enter a different name for the resource pack

os.mkdir("C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name)
os.mkdir("C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name + "/assets")
os.mkdir("C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name + "/assets/minecraft")
os.mkdir("C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name + "/assets/minecraft/optifine")
os.mkdir("C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name + "/assets/minecraft/optifine/cit")
os.mkdir("C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name + "/assets/minecraft/optifine/cit/totems")

Now we create the necessary file directories required for the resource pack that also don't require any user input.

shutil.copy("img/pack.png", "C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name)

We utilise shutil to copy the "pack.png" or resource pack icon to its necessary location.

packMeta = open("C:/Users/" + getpass.getuser() + "/AppData/Roaming/.minecraft/resourcepacks/" + name + "/pack.mcmeta", "w+")

We then create the pack.mcmeta file which allows us to add a pack description and change which version the pack was made for using the pack_format code

if version in packFormat4:
    packFormat = 4
elif version in packFormat5:
    packFormat = 5
elif version in packFormat6:
    packFormat = 6
elif version.startswith("1.17"):
    packFormat = 7
elif version.startswith("1.18"):
    packFormat = 8
elif version.startswith("1.19"):
    packFormat = 9

Now we determine the pack format code from the given version number when defining the subroutine.

packMeta.writelines(['{\n',
'  "pack": {\n',
'    "pack_format": ' + str(packFormat) + ',\n',
'	"description": "Version: ' + version + '\n',
'Made By: The Totems+ Team"\n',
'  }\n',
'}'])
packMeta.close()

With the newfound pack format code we rite the nessesary information to the pack.mcmeta file and save it aswell