Last active
March 2, 2020 20:55
-
-
Save boneskull/fb08f25bf790e27fd69639ef7806db90 to your computer and use it in GitHub Desktop.
HexFiend template for Terraria .wld files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
proc tile_entity {} { | |
set tile_entity_type [uint8] | |
int32 "ID" | |
int16 "x" | |
int16 "y" | |
if {$tile_entity_type == 0} { | |
int16 "Target Dummy" | |
} elseif {$tile_entity_type == 1} { | |
itemstack "" | |
} elseif {$tile_entity_type == 2} { | |
section "Logic Sensor" { | |
uint8 "Logic Check" | |
bool "Enabled" | |
} | |
} else { | |
entry "Type" "(unknown)" 1 | |
} | |
} | |
proc itemstack {index} { | |
set qty [int16] | |
if {$qty > 0} { | |
section "Stack $index" { | |
entry "Qty." $qty 1 | |
int32 "Item ID" | |
set modifier [uint8] | |
if {$modifier != 0} { | |
entry "Modifier" $modifier 1 | |
} | |
} | |
} | |
} | |
proc chest {max_items} { | |
position "Position" | |
tstr "Name" | |
for {set i 0} {$i < $max_items} {incr i} { | |
itemstack $i | |
} | |
} | |
proc quadrant args { | |
foreach arg $args { | |
section $arg { | |
int32 "Left X-coord" | |
int32 "Center X-coord" | |
int32 "Right X-coord" | |
int32 "Quadrant 1" | |
int32 "Quadrant 2" | |
int32 "Quadrant 3" | |
int32 "Quadrdant 4" | |
} | |
} | |
} | |
proc tstr args { | |
set result [uleb128] | |
foreach arg $args { | |
if {$result > 0} { | |
str $result "ascii" $arg | |
} else { | |
entry $arg "(empty string)" 1 | |
} | |
} | |
} | |
proc hardmode_ore args { | |
set ore [int32] | |
if {$ore == 107} { | |
set ore "Cobalt" | |
} elseif {$ore == 108} { | |
set ore "Mythril" | |
} elseif {$ore == 111} { | |
set ore "Adamantite" | |
} elseif {$ore == 221} { | |
set ore "Palladium" | |
} elseif {$ore == 222} { | |
set ore "Orichalcum" | |
} elseif {$ore == 223} { | |
set ore "Titanium" | |
} else { | |
set ore "Unknown" | |
} | |
foreach arg $args { | |
entry $arg $ore 1 | |
} | |
return $ore | |
} | |
proc position args { | |
foreach arg $args { | |
section $arg { | |
int32 "X" | |
int32 "Y" | |
} | |
} | |
} | |
proc bool args { | |
set byte [uint8] | |
set result [expr {$byte == 0 ? "False" : "True"}] | |
foreach arg $args { | |
entry $arg $result 1 | |
} | |
return $result | |
} | |
proc uleb128 args { | |
set result 0 | |
set shift 0 | |
set count 0 | |
while {true} { | |
set byte [uint8] | |
if {$shift == 63 && $byte != 0 && $byte != 1} { | |
break | |
} | |
set result [expr {$result | (($byte & -129) << $shift)}] | |
incr count | |
incr shift 7 | |
if {$byte < 128} { | |
break | |
} | |
} | |
foreach arg $args { | |
entry $arg $result $count | |
} | |
return $result | |
} | |
little_endian | |
section "Header" { | |
int32 "Version" | |
str 7 "ascii" "Signature" | |
uint8 "Savefile Type" | |
uint32 "Revision" | |
uint64 "Favorite" | |
int16 "Offset Count" | |
section "Offsets" { | |
set header_offset [int32 "Header"] | |
set tiles_offset [int32 "Tiles"] | |
set chests_offset [int32 "Chests"] | |
set signs_offset [int32 "Signs"] | |
set npcs_offset [int32 "NPCs"] | |
set tile_entities_offset [int32 "Tile Entities"] | |
set pressure_plates_offset [int32 "Pressure Plates"] | |
set town_manager_offset [int32 "Town Manager"] | |
set footer_offset [int32 "Footer"] | |
# garbage | |
int32 | |
} | |
section "Properties" { | |
set tile_frame_importances_size [int16] | |
set tile_frame_importances [list] | |
section "Tile Frame Importances" { | |
for {set i 0} {$i < [expr {ceil($tile_frame_importances_size / 8.0)} ]} {incr i} { | |
lappend tile_frame_importances [uint8 "TFI $i"] | |
} | |
} | |
set world_name [tstr "World Name"] | |
section "Generator" { | |
tstr "Seed" | |
uint64 "Version" | |
} | |
uuid "UUID" | |
set world_id [int32 "ID"] | |
section "Bounds" { | |
int32 "Left" | |
int32 "Right" | |
int32 "Top" | |
int32 "Bottom" | |
} | |
set world_height [int32 "World Height"] | |
set world_width [int32 "World Width"] | |
bool "Expert" | |
uint64 "Created On" | |
section "Style Info" { | |
uint8 "Moon" | |
quadrant "Trees" | |
quadrant "Moss" | |
int32 "Underground Snow" | |
int32 "Underground Jungle" | |
int32 "Hell" | |
} | |
position "Spawn Point" | |
double "Underground Level" | |
double "Cavern Level" | |
double "Current Time" | |
bool "Daytime" | |
uint32 "Moon Phase" | |
bool "Blood Moon" | |
bool "Eclipse" | |
position "Dungeon Entrance" | |
set evil_type [uint8] | |
entry "Evil Type" [expr {$evil_type != 0 ? "Crimson" : "Corruption"}] 1 | |
section "Bosses Killed" { | |
bool "Eye of Cthulhu" | |
bool "Eater of Worlds" | |
bool "Skeletron" | |
bool "Queen Bee" | |
bool "The Twins" | |
bool "The Destroyer" | |
bool "Skeletron Prime" | |
bool "Mechanical Boss" | |
bool "Plantera" | |
bool "Golem" | |
bool "King Slime" | |
} | |
section "Saved NPCs" { | |
bool "Goblin Tinkerer" | |
bool "Wizard" | |
bool "Mechanic" | |
} | |
section "Events Completed" { | |
bool "Goblin Army" | |
bool "Clown Killed" | |
bool "Frost Moon" | |
bool "Pirate Invasion" | |
} | |
section "Shadow Orb" { | |
bool "Smashed" | |
bool "Meteorite Spawned" | |
int32 "Smash Counter" | |
} | |
int32 "Smashed Altar Count" | |
bool "Hardmode" | |
section "Invasion Status" { | |
int32 "Delay" | |
int32 "Size" | |
set invasion_type [int32] | |
set invasion_type [expr {$invasion_type == 0 ? "None" : $invasion_type == 1 ? "Goblin" : $invasion_type == 2 ? "Frost" : $invasion_type == 3 ? "Pirate" : "Martian Madness"}] | |
entry "Invasion Type" $invasion_type 1 | |
double "Position" | |
double "Slime Rain Time Left" | |
} | |
uint8 "Sundial Cooldown" | |
section "Rain Status" { | |
bool "Active" | |
int32 "Time Left" | |
float "Max Rain" | |
} | |
section "Hardmode Ores" { | |
hardmode_ore "Hardmode Ore 1" | |
hardmode_ore "Hardmode Ore 2" | |
hardmode_ore "Hardmode Ore 3" | |
} | |
section "Backgrounds" { | |
uint8 "Forest" | |
uint8 "Corruption" | |
uint8 "Jungle" | |
uint8 "Snow" | |
uint8 "Hallow" | |
uint8 "Crimson" | |
uint8 "Desert" | |
uint8 "Ocean" | |
} | |
section "Clouds" { | |
int32 "Background" | |
int16 "Count" | |
float "Wind Speed" | |
} | |
section "Angler Quests" { | |
set players_count [uint8] | |
for {set i 0} {$i < $players_count} {incr i} { | |
tstr "Player $i Quest Complete" | |
} | |
bool "Angler Saved" | |
int32 "Quest Fish ID" | |
} | |
bool "Stylist NPC Saved" | |
bool "Tax Collector NPC Saved" | |
int32 "Invasion Size Start" | |
int32 "Cultist Delay" | |
section "Mob Kill Counts" { | |
set mob_kill_count [int16] | |
for {set i 0} {$i < $mob_kill_count} {incr i} { | |
set count [int32] | |
if {$count > 0} { | |
entry "Mob ID $i" $count 1 | |
} | |
} | |
} | |
bool "Fast-Forward Time" | |
section "More Bosses Slain" { | |
bool "Duke Fishron" | |
bool "Martian Saucer" | |
bool "Lunatic Cultist" | |
bool "Moon Lord" | |
bool "Pumpking" | |
bool "Mourning Wood" | |
bool "Ice Queen" | |
bool "Santa-NK1" | |
bool "Everscream" | |
bool "Solar Pillar" | |
bool "Vortex Pillar" | |
bool "Nebula Pillar" | |
bool "Stardust Pillar" | |
} | |
section "Lunar Events" { | |
bool "Solar" | |
bool "Vortex" | |
bool "Nebula" | |
bool "Stardust" | |
bool "Active" | |
} | |
section "Party" { | |
bool "Party Center Active" | |
bool "Natural Party Active" | |
int32 "Party Cooldown" | |
set partying_npc_count [int32] | |
if {$partying_npc_count > 0} { | |
section "Partying NPCs" { | |
for {set i 0} {$i < $partying_npc_count} {incr i} { | |
int32 "Partying NPC $i" | |
} | |
} | |
} | |
} | |
section "Sandstorm" { | |
bool "Active" | |
int32 "Time Left" | |
float "Severity" | |
float "Intended Severity" | |
} | |
bool "Bartender Saved" | |
section "Old One's Army" { | |
bool "Tier 1" | |
bool "Tier 2" | |
bool "Tier 3" | |
} | |
} | |
} | |
# skip tiles; it takes too long to compute | |
goto $chests_offset | |
section "Chests" { | |
set chests_count [int16 "Chest Count"] | |
set chest_max_items [int16 "Max Items per Chest"] | |
for {set i 0} {$i < $chests_count} {incr i} { | |
section "Chest $i" { | |
chest $chest_max_items | |
} | |
} | |
} | |
goto $signs_offset | |
section "Signs" { | |
set signs_count [uint16 "Sign Count"] | |
for {set i 0} {$i < $signs_count} {incr i} { | |
section "Sign $i" { | |
tstr "Text" | |
position "Position" | |
} | |
} | |
} | |
goto $npcs_offset | |
section "NPCs" { | |
set has_more_npcs [bool] | |
set i 0 | |
while {$has_more_npcs} { | |
section "NPC $i" { | |
int32 "Entity ID" | |
tstr "Name" | |
float "x" | |
float "y" | |
set is_homeless [bool "Homeless"] | |
if {!$is_homeless} { | |
position "Home Position" | |
} | |
} | |
set has_more_npcs [bool] | |
incr i | |
} | |
} | |
section "Mobs" { | |
set has_more_npcs [bool] | |
set i 0 | |
while {$has_more_npcs} { | |
section "NPC $i" { | |
int32 "Entity ID" | |
float "x" | |
float "y" | |
} | |
set has_more_npcs [bool] | |
incr i | |
} | |
} | |
goto $tile_entities_offset | |
section "Tile Entities" { | |
set tile_entities_count [int32 "Tile Entities Count"] | |
for {set i 0} {$i < $tile_entities_count} {incr i} { | |
section "Tile Entity $i" { | |
tile_entity | |
} | |
} | |
} | |
goto $pressure_plates_offset | |
section "Pressure Plates" { | |
set pressure_plate_count [uint32 "Pressure Plate Count"] | |
for {set i 0} {$i < $pressure_plate_count} {incr i} { | |
position "Pressure Plate $i" | |
} | |
} | |
goto $town_manager_offset | |
section "Towns" { | |
set house_count [uint32 "House Count"] | |
for {set i 0} {$i < $house_count} {incr i} { | |
section "Room $i" { | |
int32 "NPC ID" | |
position "Position" | |
} | |
} | |
} | |
goto $footer_offset | |
section "Footer" { | |
bool "OK" | |
set name [tstr "Name"] | |
set id [int32 "ID"] | |
entry "Valid Name" [expr {$name == $world_name ? "True" : "False"}] 1 | |
entry "Valid ID" [expr {$id == $world_id ? "True" : "False"}] 1 | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This template breaks out the non-tile data in a Terraria v1.3.5.3 World (
.wld
) file, for ease of inspection & comparison.Usage:
~/Library/Application Support/com.ridiculousfish.HexFiend/Templates/
).wld
fileterraria-wld
template from the pane's dropdown (if already selected, choose "refresh")