Generating a Head Hunter Pack¶
Setup¶
Start by cloning or downloading this repository to your computer. You'll also need to install Python (3.10 or newer) if it's not already on your system.
Then had over to the VanillaTweaks website and download the "Wandering Trades (Hermit Edition)" and (if you want) the "More Mob Heads" one as well. Extract the combined zip file ("VanillaTweaks_dXXXXXX_UNZIP_ME.zip") into the "packs" folder of this repo. You do not need to unzip the individual data packs.
Once all the files are downloaded and in place, open a terminal, navigate to the root of this repository, and start a Python, IPython or Jupyter session.
Bootstrap¶
You're going to want to first start off with all of the files from the original version of the data pack. You can do that using the extract
module.
from head_hunter import extract
extract.copy_data_from_existing_pack()
/main/Workspace/head-hunter/head_hunter/extract.py:89: RuntimeWarning: Multiple packs match wanderingtrades*: - packs/wandering trades hermit edition v1.8.3 (MC 1.20-1.20.4).zip - packs/wandering trades hermit edition v1.9.3 (MC 1.21.0).zip Extracting: packs/wandering trades hermit edition v1.9.3 (MC 1.21.0).zip warnings.warn(message, RuntimeWarning)
If you see any warnings like the above, make sure that it grabbed the pack that you wanted.
Creating a Head List¶
Now it's time to create your list of heads. There are three methods for doing this, all of which are in the parse
module:
from head_hunter import parse
Hermit Heads¶
We'll start by grabbing the Hermit heads.
hermit_heads, block_trades = parse.parse_wandering_trades()
/main/Workspace/head-hunter/head_hunter/extract.py:89: RuntimeWarning: Multiple packs match wanderingtradeshermitedition*: - packs/wandering trades hermit edition v1.8.3 (MC 1.20-1.20.4).zip - packs/wandering trades hermit edition v1.9.3 (MC 1.21.0).zip Extracting: packs/wandering trades hermit edition v1.9.3 (MC 1.21.0).zip warnings.warn(message, RuntimeWarning)
(the block trades we'll hold onto for later)
Let's look at whose heads we grabbed.
for idx, head in enumerate(hermit_heads):
print(idx, repr(head))
0 HeadSpec('PythonGB') 1 HeadSpec('Xisuma') 2 HeadSpec('Docm77') 3 HeadSpec('Jessassin') 4 HeadSpec('xBCrafted') 5 HeadSpec('Etho') 6 HeadSpec('Mumbo') 7 HeadSpec('iJevin') 8 HeadSpec('impulseSV') 9 HeadSpec('Renthedog') 10 HeadSpec('Tinfoilchef') 11 HeadSpec('Biffa2001') 12 HeadSpec('Stressmonster101') 13 HeadSpec('GoodTimesWithScar') 14 HeadSpec('Zedaph') 15 HeadSpec('joehillssays') 16 HeadSpec('cubfan135') 17 HeadSpec('Welsknight') 18 HeadSpec('Keralis') 19 HeadSpec('falsesymmetry') 20 HeadSpec('hypnotizd') 21 HeadSpec('VintageBeef') 22 HeadSpec('BdoubleO100') 23 HeadSpec('Tango') 24 HeadSpec('Grian') 25 HeadSpec('iskall85') 26 HeadSpec('ZombieCleo') 27 HeadSpec('GeminiTay') 28 HeadSpec('PearlescentMoon') 29 HeadSpec('Skizzleman') 30 HeadSpec('SmallishBeans')
Maybe I don't want every Hermit. I can create a new list by index:
# this is a demo and not a reflection of my feelings about any hermit
my_hermits = [hermit_heads[i] for i in (1, 2, 3, 5, 8, 13, 21)]
for idx, head in enumerate(my_hermits):
print(idx, repr(head))
0 HeadSpec('Xisuma') 1 HeadSpec('Docm77') 2 HeadSpec('Jessassin') 3 HeadSpec('Etho') 4 HeadSpec('impulseSV') 5 HeadSpec('GoodTimesWithScar') 6 HeadSpec('VintageBeef')
Mob Heads¶
I don't know about you, but there are some mobs I am just not willing to kill, even for an amazing decorative head. So instead, why not have the Wandering Trader do the dirtywork sell them to us?
mob_heads = []
for mob in ("bee", "cat", "fox", "panda", "sniffer", "silverfish"):
mob_heads.extend(parse.parse_mob_heads(mob))
for idx, head in enumerate(mob_heads):
print(idx, repr(head))
0 HeadSpec('Bee Head') 1 HeadSpec('Pollinated Bee Head') 2 HeadSpec('Angry Bee Head') 3 HeadSpec('Angry Pollinated Bee Head') 4 HeadSpec('Tabby Cat Head') 5 HeadSpec('Tuxedo Cat Head') 6 HeadSpec('Ginger Cat Head') 7 HeadSpec('Siamese Cat Head') 8 HeadSpec('British Shorthair Cat Head') 9 HeadSpec('Calico Cat Head') 10 HeadSpec('Persian Cat Head') 11 HeadSpec('Ragdoll Cat Head') 12 HeadSpec('White Cat Head') 13 HeadSpec('Jellie Cat Head') 14 HeadSpec('Black Cat Head') 15 HeadSpec('Fox Head') 16 HeadSpec('Snow Fox Head') 17 HeadSpec('Aggressive Panda Head') 18 HeadSpec('Lazy Panda Head') 19 HeadSpec('Playful Panda Head') 20 HeadSpec('Worried Panda Head') 21 HeadSpec('Brown Panda Head') 22 HeadSpec('Weak Panda Head') 23 HeadSpec('Panda Head') 24 HeadSpec('Sniffer Head') 25 HeadSpec('Silverfish Head')
/main/Workspace/head-hunter/head_hunter/extract.py:89: RuntimeWarning: Multiple packs match moremobheads*: - packs/more mob heads v2.12.3 (MC 1.20-1.20.4).zip - packs/more mob heads v2.14.0 (MC 1.21-1.21.1).zip Extracting: packs/more mob heads v2.14.0 (MC 1.21-1.21.1).zip warnings.warn(message, RuntimeWarning)
Notice that this will grab all mob head variants for each mob you specify, so feel free to prune that list if you don't want every sheep variant, for example.
my_mob_heads = [mob_heads[i] for i in (0, 4, 13, 14, 15, 16, 19, 24, 25)]
for idx, head in enumerate(my_mob_heads):
print(idx, repr(head))
0 HeadSpec('Bee Head') 1 HeadSpec('Tabby Cat Head') 2 HeadSpec('Jellie Cat Head') 3 HeadSpec('Black Cat Head') 4 HeadSpec('Fox Head') 5 HeadSpec('Snow Fox Head') 6 HeadSpec('Playful Panda Head') 7 HeadSpec('Sniffer Head') 8 HeadSpec('Silverfish Head')
Adding Your Own Player Heads¶
Now let's say there are other players whose heads you want to add. There are two ways you can add their heads to the list:
- by username, if you just want their latest head
- by parsing a
/give
command you might get from a site like namemc.com (which is the way you can get a particular / previous skin).
from head_hunter import HeadSpec
Take a loot at the documentation for HeadSpec
—it supports easily setting a bunch of formatting options and other fancy properties.
my_player_heads = [
HeadSpec.from_username("C418"),
HeadSpec.from_username("gnembon"),
HeadSpec.from_username("kingbdogz"),
HeadSpec(
"ilmango",
player_name="ilmango",
rarity="epic",
italic=True,
note_block_sound="minecraft:block.piston.extend",
),
parse.parse_give_command(
"""
/give @p minecraft:player_head[profile={id:[I;-1405566186,1057774577,-1697157085,849040296],properties:[{name:"textures",value:"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjM3YWRiNjNhNjlkYjNjZTQ3YWI1MDRmN2VkYTllYTEzNWU4ZjkxYWIzNGI5MzgyODE3NGZiMWRhNDViYWE4ZSJ9fX0="}]},minecraft:lore=['{"text":"https://namemc.com/skin/0374e097cf976fa3"}']]
""",
name="OpenBagTwo",
),
parse.parse_give_command(
"""
/give @p minecraft:player_head[profile={id:[I;205100906,1600410248,-1252686760,-1716300551],properties:[{name:"textures",value:"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGZiNzUwM2EzZjdlZTY1NzFkYTA1MDIwMmM4NDgzMzU5MzFkMTkzM2Q1NDcxNTgzMDI4N2I4ZmNkMTk3OWY2OSJ9fX0="}]},minecraft:lore=['{"text":"https://namemc.com/skin/e25939ff8abaec6a"}']]
""",
"Steveix",
obfuscated=True,
color="gold",
),
]
Write Your Trade List¶
Now that you've got your list of player heads, you're set to write them to your data pack. The methods to do this are in the write
module.
from head_hunter import write
First we'll want to write the trade list itself
write.write_head_trades(my_hermits + my_mob_heads + my_player_heads)
(2, 23)
and then use the numbers we got back from that function to update the trade counts.
write.update_trade_count(*_, trade_provider="head") # a little sugar
If you want to make sure your trade list worked correctly, you can try reading it back in:
for idx, head in enumerate(
parse.parse_wandering_trades(
"Head Hunter/data/wandering_trades/function/add_trade.mcfunction"
)[0]
):
print(idx, repr(head))
0 HeadSpec('Xisuma') 1 HeadSpec('Docm77') 2 HeadSpec('Jessassin') 3 HeadSpec('Etho') 4 HeadSpec('impulseSV') 5 HeadSpec('GoodTimesWithScar') 6 HeadSpec('VintageBeef') 7 HeadSpec('Bee Head') 8 HeadSpec('Tabby Cat Head') 9 HeadSpec('Jellie Cat Head') 10 HeadSpec('Black Cat Head') 11 HeadSpec('Fox Head') 12 HeadSpec('Snow Fox Head') 13 HeadSpec('Playful Panda Head') 14 HeadSpec('Sniffer Head') 15 HeadSpec('Silverfish Head') 16 HeadSpec('C418') 17 HeadSpec('gnembon') 18 HeadSpec('kingbdogz') 19 HeadSpec('ilmango') 20 HeadSpec('OpenBagTwo') 21 HeadSpec('Steveix')
Now remember those block trades we extracted earlier? Let's write them to file now too.
bounds = write.write_block_trades(block_trades)
print(bounds)
write.update_trade_count(*bounds, trade_provider="block")
(1002, 1191)
Finishing Up¶
Now all that remains is updating some metadata files:
write.write_meta_files()
And then compressing everything into a nice compact ZIP.
A utility for which can be found in the release
module.
from head_hunter import release
release.make_zip()
And there you go! Take your new "Head Hunter.zip" file, plop it in your world's datapacks folder and listen for that familiar "wwap wwap?"