The Heretic Hack Editor (HHE)
HHE was a game behavior editor for Heretic, written by Greg Lewis and designed to be similar to the popular DeHackEd behavior editor for Doom. However, HHE never reached the level of polish that DeHackEd did, and there are some distinct gotchas when trying to use it, especially with the Shadow of the Serpent Riders edition of Heretic. Be warned that the program is poor quality/incomplete and can't easily do (or do at all) some things you might expect it to.
This page is meant to help with some of the more obtuse characteristics of the editor, for anyone who might still want to mod Heretic the old fashioned way. As far as I know, Chocolate Heretic is the only modern port that can use HHE patches; other ports generally have their own methods for changing game behavior. The HHE program itself is for DOS and is unlikely to work on anything newer than Windows 9x versions.
General usage of the editor is very similar to DeHackEd, and information on modding with DeHackEd usually applies, except that HHE's code pointer reassignment works differently and some other aspects of the editor are less polished and functional than DeHackEd's.
Some of the information on this page may be incomplete.
SotSR setup
For working with Heretic: Shadow of the Serpent Riders (aka Heretic v1.3) some changes to the default HHE.INI file are required. The values to use are as follows:
# The size of the user-defined heretic.exe file.
size = 728031
# These are the offsets for the various data sections...
thingoff = 617600
soundoff = 639734
frameoff = 583860
spriteoff = 583348
ammooff = 635780
weaponoff = 636204
textoff = 563284
codepoff = 258020
By default, HHE works with v1.0 of Heretic. I am not sure of the values needed to use it with v1.2, but they are unlikely to be necessary. Also note that loading an HHE patch built for the SotSR version of Heretic in Chocolate Heretic will require an additional -hhever 1.3 parameter.
Unused Things and Frames
Useful for making a small addition without having to disrupt the rest of the game's behavior, Heretic v1.3 does have some unused data that should be able to be recycled without incident:
Thing #82 (described as "Wand Shot PL1") is an unused thing.
Frames 460 and 461 are frames whose only association is with the unused Thing #82.
Possible uses of these include adding a new scenery object or adding a ghost variant of a monster (such as the elusive ghost weredragon, perhaps).
The Thing Flags (Bits)
Several of the flag descriptions HHE gives for the thing bits are incomplete, unhelpful or outright incorrect. Here's a table of what internal names they correspond to and what they do, arranged in the same way that the HHE screen itself presents them.
NB if you are familiar with ZDoom modding, that some things work a bit differently. For instance, translucency and ghostliness are bound to each other rather than separate properties.
Bits Page 1 (flags) The original flags set inherited from Doom, with a few adjustments |
|
---|---|
0 Gettable Thing MF_SPECIAL: Will trigger thing pickup code depending on what the thing's sprite is currently set at. If the sprite is not on the list of valid gettables, the game will terminate. |
16 Projectiles MF_MISSILE: Handle this object as a missile. |
1 Obstacle MF_SOLID: Will block movement of other things. |
17 Disappearing Item MF_DROPPED: Item will not respawn and can be crushed by moving sectors. Automatically set on items dropped by monsters. |
2 Shootable Thing MF_SHOOTABLE: Handle this object as one which can be shot and damaged. |
18 Partial Invisibility MF_SHADOW: Drawn translucent; when applied to shootable things, they are treated as ghosts (THRUGHOST projectiles pass through them without causing damage, staff cannot hit them, monsters have trouble targeting.) |
3 Total Invisibility MF_NOSECTOR: Used for certain invisible support objects like teleport destinations and pod/glitter spawners. Unsure of the separation between this and MF2_DONTDRAW, aside that NOSECTOR flagged items don't get linked to a subsector. |
19 Puffs (vs. bleeds) MF_NOBLOOD: Don't spawn blood splatters when hit (used together with SHOOTABLE). |
4 'Automatics' MF_NOBLOCKMAP: Don't link into the blockmap. Things with this flag set will be walk-through and shoot-through; overrides SHOOTABLE and SOLID if they are also set. By default, projectiles are flagged with this, among other things. |
20 Sliding Helpless MF_CORPSE: Internally set on dead bodies to make them tumble down stairs. |
5 Semi-Deaf MF_AMBUSH: Typically set by map designer rather than directly on enemies. Thing will not activate its chase sequence unless there is a line of sight to its intended target (doesn't alert on weapon fire). |
21 Unknown MF_INFLOAT: Used internally when an enemy is in the process of floating to a different height. |
6 In Pain MF_JUSTHIT: Used internally for infighting retaliation. Setting it on a thing at spawn time makes projectile enemies respond aggressively when first activated but the flag will then be flipped back off. |
22 Counts for Kills MF_COUNTKILL: Counts for kills on the end of level score. Is also treated as a monster for a few other purposes: -respawn and -nomonsters modes, and will also receive massive (gibbing) damage if a Massacre event is triggered (boss death event, cheat code) |
7 Unknown MF_JUSTATTACKED: Used internally for projectile attack limiting when not on the top skill level. Setting it on a thing at spawn time makes projectile enemies less aggressive when first activated but the flag will then be flipped back off. If JUSTATTACKED and JUSTHIT are both set at spawn time, JUSTATTACKED is the one that holds sway. |
23 Counts for Items MF_COUNTITEM: Counts for items on the end of level score. |
8 Hangs from Ceiling MF_SPAWNCEILING: Start at ceiling height instead of on the ground. Will fall unless NOGRAVITY is also set. |
24 Running MF_SKULLFLY: Used internally for swooping/charging monsters. |
9 No Gravity MF_NOGRAVITY: Don't apply gravity; for example flying monsters and most missiles. |
25 Not in Deathmatch MF_NOTDMATCH: Don't spawn in deathmatch games (used on keys, by default) |
10 Travels Up Cliffs MF_DROPOFF: Ignore heights when crossing two-sided lines. Normally monsters and projectiles are blocked from crossing to a lower sector from a significantly higher one. This is typically set for projectiles and not set for monsters. Flying monsters do not need this. (It would be slightly more accurate to call this "Travels Down Cliffs"). |
26 Color 1 (yel./blue) Color translation part 1. If just this part is set, green becomes yellow. If both translations flags are set, green becomes blue. |
11 Can pick up items MF_PICKUP: Allows this thing to remove gettable items, normally set only on players. Does not appear to have an effect on non-player things. |
27 Color 2 (red/blue) Color translation part 2. If just this part is set, green becomes red. If both translations flags are set, green becomes blue. |
12 No Clipping MF_NOCLIP: Allows things to move through walls. |
28 Unused |
13 Unknown MF_SLIDE: Never used, does not trigger any code. |
29 Unused |
14 Floating MF_FLOAT: Paired with NOGRAVITY, allow a monster to fly. |
30 Unused |
15 Semi-No Clipping MF_TELEPORT: Don't trigger line specials. Projectiles/charging monsters will "jump" to the nearest floor/ceiling on the other side when hitting a two-sided wall (never used by default). |
31 Unused |
Bits Page 2 (flags2) The new flags added for Heretic, many of which are incompletely or incorrectly described in HHE |
|
---|---|
0 Subject to Inertia MF2_LOGRAV: Effect of gravity on this object is divided by 8. |
16 Causes Burning Death MF2_FIREDAMAGE: Kills with this weapon will initiate a burning death sequence for players and only players. (Despite HHE listing a "Burning frame" on objects there is no such thing: this is actually a "crash" frame with a different purpose.) |
1 Blown by Wind MF2_WINDTHRUST: Wind sectors will push this object. |
17 Does Not Push Things MF2_NODMGTHRUST: Doesn't cause damage momentum when hitting something |
2 Bounces MF2_FLOORBOUNCE: For bouncing projectiles. The projectile is set to its death state upon hitting the floor, but can still deal damage after bouncing. Firemace code pointers can also be used at the start of the death sequence to reset the projectile to its spawn state (with other potential effects). |
18 Telefrags MF2_TELESTOMP: This thing is allowed to telefrag things if one sits at the destination point of an attempted teleport. If this flag is not set, the thing is forbidden to teleport to a blocked position. |
3 Goes Through Invis. MF2_THRUGHOST: A projectile does not collide with things that have the SHADOW flag, instead passing through with no damage. No other effects (won't work on monsters, melee, or hitscans - immunity to staff jabs is handled separately in a hardcoded manner). |
19 Bobbing MF2_FLOATBOB: Object bobs up and down (used by default on some pickups). Highjacks the object's health variable to manage bobbing, randomizing it at level start and continually increasing it afterwards. Due to this, killable things given the flag will be almost invincible. Also manually sets object's vertical position, preventing free flight on mobile objects. |
4 Pushable Up Cliffs MF2_FLY: Intended for players with Wings of Wrath and may be set/unset internally when used on a player object. On monsters or pushables, gives them certain altered flying player physics, which changes their friction and makes them attempt to drift up/down to a passable level when blocked by an object or two-sided wall, which can have potentially interesting (ab)uses. |
20 Unknown MF2_DONTDRAW: Total invisibility, never consumes visible sprite quota. Used internally for picked-up items that are awaiting a respawn. |
5 Walks IN Liquids MF2_FOOTCLIP: If an object has this flag, then the MF2_FEETARECLIPPED flag will be toggled if it moves into/out of a liquid floor. |
21 Unknown Not used |
6 Starts on Floor MF2_SPAWNFLOAT: Floating object is given a random vertical height at the start of the map. Exactly opposite of what HHE implies, flying monsters start on the floor if this flag is not set (excepting the effect of SPAWNCEILING). |
22 Unknown Not used |
7 Does Not Teleport MF2_NOTELEPORT: Forbidden from teleporting. Usually set on projectiles by default, which in Heretic can teleport if not flagged otherwise here. |
23 Unknown Not used |
8 Dragon Claw Spikes (?) MF2_RIP: Projectiles pass through shootable objects, doing repeated damage as they go. |
24 Unknown Not used |
9 Pushable MF2_PUSHABLE: If another thing bumps this thing, some momentum will be transferred unless the bumper is flagged CANNOTPUSH. |
25 Unknown Not used |
10 Only Hits Monsters MF2_SLIDE: "Slides" along walls, the path being deflected instead of blocked when hitting them; normally used for player and pushables. Projectiles also won't die when hitting walls/things and will generally act semi-similarly to MF2_RIP when hitting a monster. Use on regular projectiles is a bit strange, but combines well with FLOORBOUNCE on gravity-affected missiles to create the appearance of a projectile that bounces off both floors and walls. |
26 Unknown Not used |
11 Unknown MF2_ONMOBJ: Internal, set if standing on another object. Affects movement friction when set. |
27 Unknown Not used |
12: Unknown MF2_PASSMOBJ: Allows this thing to move over/under other things (given to monsters). There is a hardcoded exception for Gargoyles and Disciples of D'Sparil that forbids them from going over/under each other, possibly related to the flying monsters sticking together bug. |
28 Unknown Not used |
13: Particles (?) MF2_CANNOTPUSH: This thing cannot push PUSHABLE things. If MISSILE is set, then this is irrelevant unless RIP is also set (rippers can push). For other projectiles see NODMGTHRUST instead. |
29 Unknown Not used |
14: Unknown MF2_FEETARECLIPPED: Used internally to handle standing in liquids, likely not useful for setting in hacks (the game adjusts it according to the floor the object is on). Instead, set FOOTCLIP on objects that you want the standing sunken in water effect to apply to. |
30 Unknown Not used |
15: Varying Damage MF2_BOSS: This thing is a boss monster. Affects infighting (no retaliation against bosses) and some weapon damage formulae such as rain and tomed mace instakills. |
31 Unknown Not used |
String editing
When renaming maps, keep in mind a few things. The map name appears as-is on the automap while the same string, used for the intermission screen, removes the first seven characters (the "ExMx: " tag line. It doesn't care what seven characters are there, they'll always be stripped for the intermission display, so don't try to squeeze in more letters by dropping the leading map number. The other thing you must bear in mind is to use ALL CAPS (the Heretic in-game font is all lowercase so that's how it will appear, but if you use lowercase in the map name strings, you'll get a garbled mess or even crash the game.)
As with many things in HHE, string editing is a bit messed up when using Heretic v1.3; towards the end of the list you'll see some messed up "strings" which you shouldn't touch. Unfortunately, you might also find that the string editing segment gets corrupted in your patches and doesn't work at all.
Weapon modding
Note that setting the type of ammo that a weapon uses only partially works; the setting in the weapons pane determines which ammo type will be displayed on the status bar and checked when making sure the weapon hasn't run out of ammo, but attacks will subtract from whatever ammo type the code pointer was originally attached to. So if you, say, make the crossbow use a wand firing pointer, it'll use wand crystals even if you leave the weapon's ammo type as arrows. Leaving them mismatched can result in some weird stuff like being able to fire the weapon infinitely and ending up with negative ammo counts. Furthermore, if you make a weapon use a different ammo type than its slot usually dictates, you may end up with problems when it comes to the automatic weapon switching when out of ammo, so you should probably stick close to the original arsenal's layout here and do more of your modding in the properties of the projectiles themselves.
There are some "unhackables" when it comes to Tome of Power behavior. There is a single Gauntlets of the Necromancer attack pointer, and whether it does the tomed version or not is decided inside said pointer. Also, the tomed Staff knockback is decided by a specific check that neither cares about the codepointer that triggered the attack nor can be shifted to any other weapon by HHE.
There is also a hardcoded check for using the staff against ghosts. This checks against the weapon held, not the codepointer, so no hitscan generated by the player while the staff is the weapon held can hit a ghost. This does not apply to projectile attacks, if you've hacked the staff to launch one.
Misc. Hardcoded Peculiarities
These are just some of the other special behaviors that are hardcoded to particular thing or frame numbers, etc. There may be others.
Thing #122 (Disciple of D'Sparil) and thing #124 (Gargoyle) are forbidden from moving over/under other things of these two types even if they have PASSMOBJ set.
Thing #122 (Disciple of D'Sparil) has a 50% chance of using its sight sound instead of its active sound when doing active sounds.
Thing #135 (dismounted D'Sparil) will not retaliate against thing #122 (Disciple) in infighting.
Thing #135 (dismounted D'Sparil) makes active sounds at full volume regardless of distance.
Thing #133 (mounted D'Sparil), thing #135 (dismounted D'Sparil) and thing #140 (maulotaur) are immune to splash damage.
Reorganizing frames
Because you can only redirect existing code pointers, rather than add/remove them freely from any frame, you may need to get creative if you want to heavily alter the gameplay. It is possible to shuffle codepointers a bit by messing around with the "next frame" property in the frame table, but at most you can use the same number of code pointers as the original, on the same frames. In addition, some frames have other hardcoded significance, for instance, certain codepointers may force an actor into a particular frame. Here is a table of frame numbers known to have special significance to the game.
The following table is a work in progress as I haven't yet matched every codepointer to the frame it occurs on (they don't always appear in the same order).
Frame Number | Executes | Affected by |
10 | Codepointer #0 | |
19 | Codepointer #1 | |
30 | Codepointer #3 | |
31 | Codepointer #2 | |
40 | Codepointer #4 | |
86 | Codepointer #6 | |
87 | Codepointer #5 | |
98 | Codepointer #10 | |
99 | Codepointer #9 | |
100 | Codepointer #8 | |
101 | Codepointer #7 | |
103 | A_MakePod | |
114 | Codepointer #11 | |
179 | Codepointer #12 | |
182 | A_InitKeyGizmo | |
183 | A_InitKeyGizmo | |
184 | A_InitKeyGizmo | |
186 | Codepointer #13 | |
193 | Codepointer #15 | |
194 | Codepointer #14 | |
195 | Codepointer #17 | |
196 | Codepointer #16 | |
211 | Codepointer #19 | |
212 | Codepointer #18 | |
246 | Codepointer #34 | |
249 | Codepointer #32 | |
261 | Codepointer #38 | |
263 | Codepointer #43 | |
264 | Codepointer #42 | |
265 | Codepointer #41 | |
303 | Codepointer #61 | |
309 | Codepointer #64 | |
314 | Codepointer #66 | |
365 | Codepointer #77 | |
372 | Codepointer #81 | |
376 | Codepointer #83 | |
381 | Codepointer #86 | |
382 | Codepointer #85 | |
383 | Codepointer #84 | |
388 | Codepointer #89 | |
392 | Codepointer #90 | |
405 | Codepointer #92 | |
411 | Codepointer #95 | |
412 | Codepointer #94 | |
437 | A_RainImpact | |
438 | A_RainImpact | |
439 | A_RainImpact | |
440 | A_RainImpact | |
453 | Codepointer #105 | |
455 | Codepointer #104 | |
457 | Codepointer #103 | |
459 | Codepointer #106 | |
478 | Codepointer #113 | |
485 | Codepointer #116 | A_FirePhoenixPL2 |
486 | Codepointer #115 | |
505 | Codepointer #118 | |
511 | Codepointer #119 | |
536 | Codepointer #137 | |
554 | Codepointer #141 | |
556 | Codepointer #143 | |
589 | Codepointer #163 | |
615 | Codepointer #172 | |
616 | A_CheckBurnGone | |
622 | Codepointer #173 | A_CheckSkullFloor |
623 | A_CheckSkullDone | |
637 | Codepointer #188 | |
639 | Codepointer #186 | |
664 | Codepointer #198 | |
671 | Codepointer #202 | |
706 | Codepointer #153 | |
760 | A_SnakeAttack and A_SnakeAttack2 | |
772 | Codepointer #237 | |
803 | Codepointer #244 | |
816 | Codepointer #247 | |
830 | A_HeadAttack and A_HeadFireGrow | |
856 | Codepointer #258 | |
884 | Codepointer #308 | |
916 | Codepointer #325 | |
918 | Codepointer #323 | |
925 | Codepointer #328 | |
928 | Codepointer #332 | |
930 | Codepointer #331 | |
933 | Codepointer #336 | |
935 | Codepointer #335 | A_ImpXDeath2 |
939 | A_ImpExplode | |
993 | Codepointer #277 | |
997 | A_Srcr1Attack | |
1017 | Codepointer #293 | |
1026 | A_SorcererRise | |
1028 | Codepointer #351 | |
1032 | Codepointer #356 | |
1041 | Codepointer #358 | |
1043 | Codepointer #362 | |
1050 | Codepointer #364 | |
1052 | Codepointer #363 | A_Sor2DthLoop |
1055 | Codepointer #368 | |
1056 | Codepointer #367 | |
1060 | Codepointer #365 | |
1078 | Codepointer #374 | |
1099 | Codepointer #386 | |
1100 | Codepointer #385 | |
1102 | Codepointer #383 | |
1103 | A_MinotaurDecide | |
1105 | Codepointer #390 | |
1106 | A_MinotaurAtk3 | |
1107 | Codepointer #389 | A_MinotaurDecide |
1133 | Codepointer #396 | |
Code pointers
Unfortunately, HHE's method of redefining code pointers is rather unintuitive. Changing the code pointer field on the frame table is of no use, and the listing on the code pointer screen doesn't clearly indicate which slots are associated with which frames (for codepointer-to-frame listing, see special frames table above).
Pointers marked for use on weapons should be used on weapons only. Likewise, pointers designed for use on monsters should not be used on weapons. These types of functions have their own types of handling that are not interchangeable. If you want to give the player a monster attack, or vice versa, your best possibility of doing so is via altering the properties of the projectile things and/or frames to emulate similar attack properties.
When altering code pointers on the code pointer screen, you can direct the execution pretty much anywhere in the program. This could have useful effects but is also potentially risky to experiment indiscriminately with (you could crash the game / your computer if you send the execution to instructions that are invalid), and unlikely to be fully supported by source ports. Here is a list of which offsets, in Heretic v1.3, are associated with defined functions and what those functions are. Thing numbers referenced in this table are the HHE internal thing table numbers, not map editor thing numbers.
Offset | Source Code name | Function |
71792 | A_Look | Monster - Watch for target |
71920 | A_Chase | Monster - Chase target |
72464 | A_FaceTarget | Monster - Face target |
72560 | A_Pain | Play the calling thing's pain sound, if there is one. |
72592 | A_DripBlood | Spawns blood (thing #95). |
72736 | A_KnightAttack | Deal 1d8×3 damage at melee range, otherwise if caller is a ghost knight (#130) or by random chance throw a red axe (#132), otherwise throw a green axe (#131). |
72880 | A_ImpExplode | Throw a couple of gargoyle gibs (#126 and #127) in random direction. Potentially forces the calling actor into frame 939. |
73056 | A_BeastPuff | Approximately 1/4 chance to spawn weredragon fireball's smoke puffs (#112) with somewhat randomized spawn position. |
73168 | A_ImpMeAttack | Melee attack for 5 to 12 damage. |
73248 | A_ImpMsAttack | Thing charges at target (gargoyle swoop). Random chance to not attack and go back to sight state instead. |
73456 | A_ImpMsAttack2 | Deal 5 to 12 damage at melee range, or else throw a gargoyle fireball (#128) |
73552 | A_ImpDeath | Handles gargoyle death fall, forces thing to frame 935 when it hits the floor. |
73600 | A_ImpXDeath1 | Setup flags (unsets solid, sets nogravity and footclip) and special for gargoyle crash splatter. |
73648 | A_ImpXDeath2 | Unsets nogravity flag, checks if thing has hit floor and if so forces its state to frame 935. |
73952 | A_ChicAttack | Calls some internal checking for chickens, if passed, do a melee attack for 1 to 2 damage. |
74032 | A_ChicLook | Calls some internal checking for chickens, if passed, do A_Look |
74064 | A_ChicChase | Calls some internal checking for chickens, if passed, do A_Chase |
74096 | A_ChicPain | Calls some internal checking for chickens, then plays the calling thing's pain sound. |
74144 | A_Feathers | Randomly spawn one or two feathers (thing #102) if the calling thing is alive, or 5 to 8 of them if the caller is dead. |
74352 | A_MummyAttack | Melee attack for 1d8×2 damage (Golem punch) |
74464 | A_MummyAttack2 | Deal 1d8×2 damage to target at melee range or else launch projectile #108 (Nitrogolem attack) |
74560 | A_MummyFX1Seek | Seeking function for nitrogolem projectiles |
74592 | A_MummySoul | Spawns a golem soul (#106) with upwards momentum. |
74640 | A_Sor1Pain | Sets the calling thing's special variable to 20 (for Chaos Serpent rage speedup), then calls A_Pain |
74688 | A_Sor1Chase | If the calling thing's special variable is set, decrement it and speed up the thing's animation. Then calls A_Chase |
74736 | A_Srcr1Attack | Deal 1d8×8 damage at melee range, or shoot chaos serpent fireballs (#134). If health is less than 2/3 max then fires spreadshots. If health is less than 1/3 max then additionally gets a random chance for double attacks (can force thing's frame to 997) |
75024 | A_SorcererRise | Spawn thing #135 (D'Sparil on foot) and makes the calling actor non-blocking. Sets the spawned D'Sparil into frame 1026. |
75360 | A_Srcr2Decide | By random chance weighted by thing's level of HP remaining, potentially pick one of D'Sparil's teleport destinations and warp there. |
75440 | A_Srcr2Attack | Deal 1d8×20 damage at melee range, otherwise by random chance weighted by thing's remaining HP, either shoot two of thing #138 (summoning ring) to the sides or one of thing #136 (thunderbolt) at the target. |
75664 | A_BlueSpark | Spawn thing #137 (thunderbolt sparkle) with randomized momentum |
75776 | A_GenWizard | Spawn thing #122 (Disciple) if there is space; calling actor then enters its death state and spawns thing #56 (Teleport Flash) |
75936 | A_Sor2DthInit | Set actor's special variable to 7 and kill all monsters |
75968 | A_Sor2DthLoop | Decrements the actor's special variable and if it's still not zero, set actor's frame to 1052. |
76000 | A_SorZap | Play sound "sorzap". |
76032 | A_SorRise | Play sound "sorrise". |
76064 | A_SorDSph | Play sound "sordsph". |
76096 | A_SorDExp | Play sound "sordexp". |
76128 | A_SorDBon | Play sound "sordbon". |
76160 | A_SorSightSnd | Play sound "sorsit". |
76192 | A_MinotaurAtk1 | Maulotaur hammer smash for 1d8×4 melee damage, knocks player view down, hardcoded hit sound "stfpow" |
76304 | A_MinotaurDecide | Maulotaur multi-attack handler and charging initiator. Can force calling thing into frame 1103 or 1107. |
76576 | A_MinotaurCharge | Maulotaur charging handler, spawns phoenix smoke puffs (thing #88) and decrements special counter, ends charge if counter has run down. Actual charge is initiated by A_MinotaurDecide. |
76656 | A_MinotaurAtk2 | Fire a spreadshot of 5 maulotaur fire shots (#141) or do 1d8×5 melee damage, depending on target range |
76896 | A_MinotaurAtk3 | Maulotaur fire trail (spawn thing #142) or 1d8×5 melee strike, random chance of looping to frame 1106 |
77072 | A_MntrFloorFire | Do Maulotaur floor fire trail (spawns thing #143) |
77184 | A_BeastAttack | Do 1d8×3 damage at melee range or shoot a projectile of thing type #109 (Weredragon attack) |
77296 | A_HeadAttack | Deals 1d8×6 damage at melee range or else fire an iron lich projectile: possibilities are thing #117 (ice ball), #119 (fire, potentially forced to frame 830), or #120 (tornado). |
77728 | A_WhirlwindSeek | Handler for tornado seeking its target. |
77888 | A_HeadIceImpact | Fire a ring of 8 Iron Lich ice shards (thing #118) |
78048 | A_HeadFireGrow | Counts down using the things health variable, adjusting its vertical position. When health is 0, force frame to 830. |
78112 | A_SnakeAttack | Fires Ophidian shot type 1 (#114), or forces actor to frame 760 if no target |
78192 | A_SnakeAttack2 | Fires Ophidian shot type 2 (#115), or forces actor to frame 760 if no target |
78272 | A_ClinkAttack | Melee attack for 8 to 10 damage (Sabreclaw slash) |
78368 | A_GhostOff | Removes the ghost flag from the calling thing. |
78384 | A_WizAtk1 | Calls A_FaceTarget and removes the ghost flag from the calling thing. |
78416 | A_WizAtk2 | Calls A_FaceTarget and sets the ghost flag on the calling thing. |
78448 | A_WizAtk3 | Removes the ghost flag from the calling thing, deal 1d8×4 damage at melee range or else fire a spread of three wizard shots (thing #123) |
78640 | A_Scream | Plays a thing's death sound. Maulotaurs (#140), mounted D'Sparils (#133), and chicken players (#99) make full-volume screams. Players (#98) make one of four different sounds depending on the intensity of death. Otherwise just makes the death sound normally. |
78896 | A_NoBlocking | Unsets the SOLID flag but also does random item drops for certain thing types |
79312 | A_Explode | Deal blast damage. Time Bombs, Maulotaur fire and D'Sparil lightning have some individual hardcoded effects here, everything else just explodes like a Doom rocket/barrel. |
79424 | A_PodPain | Randomly spawn pod particles (#19). |
79584 | A_RemovePod | Decrement parent's special variable (pod spawn limiting counter). |
79632 | A_MakePod | As long as the calling actor's special variable is not 16, attempt to create a pod (#18) if there is space. The new pod's frame is forced to 103. |
79872 | A_BossDeath | Handle boss monster death specials (tag 666 when map number is 8), with hardcoded boss types per episode (things #116, #140, #135, #116, #140 respectively). Potentially kill all other monsters if episode is not E1. |
80000 | A_ESound | Play waterfall or wind sounds. Thing type is hardcoded and does not work for any other thing number, and HHE does not conveniently extend to these things. Sounds won't play on other things. |
80048 | A_SpawnTeleGlitter | Spawner for teleport glitter (#54). |
80128 | A_SpawnTeleGlitter2 | Spawner for exit glitter (#55). |
80208 | A_AccTeleGlitter | Increment calling actor's health variable and if it exceeds 35, increase vertical momentum by 50% of its current value. |
80256 | A_InitKeyGizmo | Create an orb (thing #48). The frame of this orb is decided by the calling thing's type (#45 -> 182, #46 -> 183, #47 -> 184). |
80352 | A_VolcanoSet | Randomizes the tic duration of the calling thing's current frame, from 105 to 232. |
80384 | A_VolcanoBlast | Volcano eruption launching 1 to 3 lava blobs (thing #50). |
80608 | A_VolcBallImpact | Handle explosion of a volcano blob, spawning for little lava bits (thing #51) |
80816 | A_SkullPop | Spawns a player's decapitated head (thing #98), attaches player's view to it (not advisable to use on non-players) |
80976 | A_CheckSkullFloor | If calling thing has hit floor, force it to frame 622. |
81008 | A_CheckSkullDone | If calling things's special2 variable has reached 666, force thing's frame to 623. |
81040 | A_CheckBurnGone | If calling things's special2 variable has reached 666, force thing's frame to 616. |
81072 | A_FreeTargMobj | Unsets SHOOTABLE, SOLID, FLOAT, SKULLFLY, PASSMOBJ, and LOGRAV flags, sets CORPSE, DROPOFF, NOGRAVITY flags, detaches thing from a player. |
81168 | A_AddPlayerCorpse | Manage a list for existing player corpses and delete an old one if there are too many. |
81264 | A_FlameSnd | Play sound "headat1". |
81296 | A_HideThing | Set calling thing's DONTDRAW flag. |
81312 | A_UnHideThing | Unset calling thing's DONTDRAW flag. |
84528 | A_RestoreArtifact | Respawns an item, with a respawning sound effect. |
84608 | A_RestoreSpecialThing1 | If the calling thing is a firemace (thing #70), then call the mace pickup randomizer. Regardless, make the calling thing visible and play a respawn sound. |
84656 | A_RestoreSpecialThing2 | Respawn an item, without sound. |
111056 | A_ContMobjSound | Hardcoded sound handler for projectiles, if the calling thing type is a knight axe (#131) plays sound "kgtatk", for nitrogolem shots (#107) plays "mumhed". Does nothing otherwise. |
113728 | A_WeaponReady | Weapon - placed on frames where the weapon is prepared to respond to the player's fire button. Contains some special handling, for instance, if called from frame 240 then there is a random chance of playing sound "stfcrk". |
114128 | A_BeakReady | Weapon - Special handling for chicken beak's ready states |
114256 | A_ReFire | Weapon - Check if the player is holding down the fire button, and continue firing the weapon if appropriate. |
114320 | A_Lower | Weapon - Handler for putting a weapon away (lowers sprite towards bottom of screen and switches weapons when it's lowered enough.) Also handles weapon disappearing from screen if player is killed. |
114416 | A_BeakRaise | Weapon - Special handler for the chicken beak becoming the current weapon. Weapon raising is done instantly and does not take into account Tome of Power status. |
114480 | A_Raise | Weapon - Handler for selecting a new weapon, shows sprite rising onto the screen and selects weapon ready state depending on if the Tome of Power is active. |
114720 | A_BeakAttackPL1 | Weapon - Beak peck, melee attack for 1 to 4 damage and sets player's "chickenPeck" variable to 12. |
114896 | A_BeakAttackPL2 | Weapon - Super beak peck, melee attack for 1d8×4 damage and sets player's "chickenPeck" variable to 12. |
115088 | A_StaffAttackPL1 | Weapon - Staff normal jab, deal 5 to 20 melee damage (no ammo) |
115232 | A_StaffAttackPL2 | Weapon - Staff tomed jab, deal 18 to 81 melee damage (no ammo) |
115376 | A_FireBlasterPL1 | Weapon - Dragon Claw fire, hitscan for 1d8×4 damage, accuracy decreases if refiring (1 energy orb) |
115520 | A_FireBlasterPL2 | Weapon - Dragon Claw tomed fire, launches a tomed claw projectile (thing #65) which is given special fast-projectile movement logic (5 energy orbs) |
115600 | A_FireGoldWandPL1 | Weapon - Elven Wand fire, hitscan for 7 to 14 damage, accuracy decreases if refiring (1 wand crystal) |
115744 | A_FireGoldWandPL2 | Weapon - Elven Wand tomed fire, launch two wand projectiles (#83) at angles, plus a spread of five hitscans that do 1 to 8 damage each (1 wand crystal) |
116208 | A_FireMacePL1 | Weapon - Firemace fire, usually fires a small mace ball (#71), but has random chance to lob a larger ball (#72) with momentum affected by the firing player's momentum (1 mace sphere) |
116352 | A_MacePL1Check | Decrements the calling thing's special variable and if it's brought to or below 0, turn on the LOGRAV flag and adjust its angle/momentum. |
116464 | A_MaceBallImpact | Handle mace balls bouncing or landing in liquid, also being destroyed when done bouncing. |
116624 | A_MaceBallImpact2 | Similar to the above but also spawns a pair of tiny mace balls (#73). |
117056 | A_FireMacePL2 | Weapon - Firemace tomed fire, lobs a giant ball (thing #74) with momentum affected by the firing player's movement (5 mace spheres) |
117184 | A_DeathBallImpact | Handles bouncing and target-seeking properties of the giant mace ball. |
117520 | A_SpawnRippers | Tomed Dragon Claw blast ring, spawns a ring of eight claw rippers (thing #67). |
117664 | A_FireCrossbowPL1 | Weapon - Crossbow fire, shoot one centered large bolt (#91) and two small ones (#93) at angles (1 arrow) |
117744 | A_FireCrossbowPL2 | Weapon - Crossbow tomed fire, shoot three large bolts (#92) and two small ones (#93) (1 arrow) |
117888 | A_BoltSpark | Spawns crossbow bolt glitter (thing #94) |
118000 | A_FireSkullRodPL1 | Weapon - Hellstaff fire, shoot a projectile of type #76 with a random chance to force the projectile's frame to 394 (1 rune) |
118080 | A_FireSkullRodPL2 | Weapon - Hellstaff tomed fire, shoot a projectile of type #77, uses special variable for seeking/sounds and special 2 variable to remember owning player (5 runes) |
118208 | A_SkullRodPL2Seek | Calls seeking missile function with parameters set for Hellstaff's tomed shots |
118240 | A_AddPlayerRain | Handler for initializing acid rain storms from Hellstaff |
118416 | A_SkullRodStorm | Spawn raindrops, thing number may be #78 through #81 depending on the calling actor's special 2 variable. |
118688 | A_RainImpact | Potentially set thing's frame to 437 through 440 depending on it's special 2 variable. |
118752 | A_HideInCeiling | Move the calling thing up into the ceiling. |
118784 | A_FirePhoenixPL1 | Weapon - Phoenix Rod fire, launch a projectile of type #87 and apply recoil momentum to the firing player |
118896 | A_PhoenixPuff | Spawns Phoenix shot smoke trails, two of thing type #88 |
119120 | A_InitPhoenixPL2 | Weapon - sets firing player's "flamecount" variable |
119136 | A_FirePhoenixPL2 | Weapon - Decreases player's flamecount variable and forces weapon frame to 485 if the fire has run out, otherwise shoots flames (thing type #89) with influence from player's momentum. |
119504 | A_ShutdownPhoenixPL2 | Weapon - Decrements player's Phoenix Rod ammo (1 flame orb) |
119520 | A_FlameEnd | Adjusts calling thing's vertical momentum. |
119552 | A_FloatPuff | Adjusts calling thing's vertical momentum. |
119584 | A_GauntletAttack | Weapon - Gauntlet, if player is Tomed, do extended-range melee for 1d8×2 damage with puff type #63 and life steal for half of damage dealt, otherwise do 1d8×2 melee damage with puff type #62, both modes also set weapon light flash |
120064 | A_Light0 | Weapon - Turns off weapon's light flash |
Thing table
HHE gives the wrong names for some of the things in the things window when used with v1.3. I would guess Heretic's internal thing table was altered between versions; the discrepancy begins around entry 88 and it seems that the "Phoenix Puff" object was removed. Some of the names in HHE are also unorthodox compared to the object's official name. A ditto mark (") in the Actual Thing column means that HHE's description is accurate.NB: The thing numbers in HHE's table are independent of the thing numbers used in creating a map (which can be customized by the program).
Number | HHE's name | Actual thing in v1.3 |
---|---|---|
1 | Crystal Vial | " |
2 | Silver Shield | " |
3 | Enchanted Shield | " |
4 | Bag of Holding | " |
5 | Map Scroll | " |
6 | Shadowsphere | " |
7 | Quartz Flask | " |
8 | Wings of Wrath | " |
9 | Invulnerability | " |
10 | Tome of Power | " |
11 | Morph Ovum | " |
12 | Morph Projectile | " |
13 | Mystic Urn | " |
14 | Torch | " (item) |
15 | Time Bomb | " (item) |
16 | Time Bomb, Active | " |
17 | Chaos Device | " |
18 | Gasbag | Pod |
19 | Gasbag Fragment | Pod Fragment |
20 | Gasbag Generator | Pod Generator |
21 | Water Droplet | " |
22 | Water Splash | " |
23 | Lava Splash | " |
24 | Lava Smoke | " |
25 | Sludge Droplet | " |
26 | Sludge Splash | " |
27 | Skull Hang 70 | " |
28 | Skull Hang 60 | " |
29 | Skull Hang 45 | " |
30 | Skull Hang 35 | " |
31 | Chandelier | " |
32 | Serpent Torch | " |
33 | Small Pillar | " |
34 | Stalagmite, Small | " |
35 | Stalagmite, Large | " |
36 | Stalactite, Small | " |
37 | Stalactite, Large | " |
38 | Fire Brazier | " |
39 | Barrel | " |
40 | Brown Pillar | " |
41 | Moss 1 | " (3 strands) |
42 | Moss 2 | " (1 strand) |
43 | Wall Torch | " |
44 | Hanging Corpse | " |
45 | Key Statue, Blue | " |
46 | Key Statue, Green | " |
47 | Key Statue, Yellow | " |
48 | Key Statue Ball | " (alterations affect all 3 colors) |
49 | Volcano | " |
50 | Volcano Ball | " |
51 | Volcano Chunk | " (small lava fragment) |
52 | Tel. Spark Red 1 | " (map placement ver.) |
53 | Tel. Spark Blue 1 | " (map placement ver.) |
54 | Tel. Spark Red 2 | " (spawned) |
55 | Tel. Spark Blue 2 | " (spawned) |
56 | Teleport Flash | " |
57 | Teleport Spot | " |
58 | Smoke Puff 1 | Staff Puff |
59 | Blazing Blue Puff | Powered Staff Puff |
60 | Smoke Puff 2 | Chicken Peck Puff |
61 | Gauntlet | " |
62 | Gauntlet Puff PL1 | " |
63 | Gauntlet Puff PL2 | " |
64 | Dragon Claw | " |
65 | Drag. Claw Puff | Dragon Claw Tomed Projectile |
66 | Drag. Claw Sparkle | " (Tomed trail) |
67 | Drag. Claw Spike | " (Tomed rippers) |
68 | Drag. Claw Puff 2 | Dragon Claw Wall Puff |
69 | Drag. Claw Puff 3 | Dragon Claw Impact Puff |
70 | Mace | Firemace |
71 | Mace Small Ball 1 | " |
72 | Mace Medium Ball | " |
73 | Mace Small Ball 2 | Mace Tiny Ball (impact fragment) |
74 | Mace Big Ball | " |
75 | Hellstaff | " |
76 | Staff Shot PL1 | " |
77 | Staff Shot PL2 | " |
78 | Staff Drip Green | " |
79 | Staff Drip Yellow | " |
80 | Staff Drip Red | " |
81 | Staff Drip Blue | " |
82 | Wand Shot PL1 | Not used |
83 | Wand Shot PL2 | Tomed Wand Ball |
84 | Wand Puff 1 | " |
85 | Wand Puff 2 | Tomed Wand Puff |
86 | Phoenix Rod | " |
87 | Phoenix Shot | " |
88 | Phoenix Puff | Phoenix Smoke Trail |
89 | Phoenix Smoke | Tomed Phoenix Rod Fire |
90 | Phoenix Flame | Ethereal Crossbow |
91 | Ethereal Crossbow | Crossbow Shot (center) |
92 | Arrow Shot 1 | Crossbow Shot (Tomed center) |
93 | Arrow Shot 2 | Crossbow Shot (side) |
94 | Arrow Fragment | Tomed Crossbow Glitter |
95 | Arrow Trail | Blood Splat 1 |
96 | Blood Drip 1 | Blood Splat 2 |
97 | Blood Drip 2 | Player |
98 | Player | Bloody Skull (from gibbed player) |
99 | Bloody Skull | Chicken, Player |
100 | Chicken, Player | Chicken, Monster |
101 | Chicken, Monster | Chicken Feather |
102 | Chicken Feather | Golem |
103 | Mummy | Nitrogolem |
104 | Mummy Chief | Golem Ghost |
105 | Mummy Ghost | Nitrogolem Ghost |
106 | Mummy Chief Ghost | Golem soul |
107 | Rising Spirit | Nitrogolem attack |
108 | Flaming Skull | Weredragon |
109 | Weredragon | Weredragon attack |
110 | Weredragon Shot 1 | Unused? |
111 | Weredragon Shot 2 | Unused? |
112 | Weredragon Shot 3 | Weredragon attack smoke trail |
113 | Weredragon Shot 4 | Ophidian |
114 | Ophidian | Ophidian blue shot |
115 | Ophidian Ice Ball | Ophidian red shot |
116 | Ophidian Fire Ball | Iron Lich |
117 | Lich, Iron | Iron Lich ice shot |
118 | Lich Ice Crystal | Iron Lich ice shard |
119 | Lich Ice Shard | Iron Lich fire shot |
120 | Lich Fire | Iron Lich tornado |
121 | Lich Tornado | Sabreclaw |
122 | Clink | Disciple of D'Sparil |
123 | Wizard | Disciple shot |
124 | Wizard Shot 1 | Gargoyle |
125 | Gargoyle | Fire Gargoyle |
126 | Garg. Leader | Gargoyle gibs 1 |
127 | Garg. Glob 1 | Gargoyle gibs 2 |
128 | Garg. Glob 2 | Gargoyle fireball |
129 | Garg. Fireball | Undead Warrior |
130 | Knight | Undead Warrior Ghost |
131 | Knight Ghost | UW Green Axe |
132 | Knight Green Axe | UW Red Axe |
133 | Knight Red Axe | D'Sparil on Serpent |
134 | D'Sparil Beast | Chaos Serpent fireball |
135 | D'Sp. Beast Fire | D'Sparil, dismounted |
136 | D'Sparil | D'Sparil thunderbolt |
137 | D'Sparil Attack | D'Sparil thunderbolt trail |
138 | D'Sp. Attack Part | D'Sparil summoning effect |
139 | D'Sp Summon Ring | D'Sparil teleporting? |
140 | Sorceror Teleport | Maulotaur |
141 | Maulotaur | Maulotaur fire spread |
142 | Maulotaur Fireball | Maulotaur ground trail? |
143 | Maul. Explosion | Maulotaur ground flame |
144 | Maul. Ground Attack | Green Key |
145 | Green Key | Blue Key |
146 | Blue Key | Yellow Key |
147 | Yellow Key | Wand Crystal |
148 | Wand Crystal | Crystal Geode |
149 | Wand Crystal Geode | Mace Spheres |
150 | Mace Balls, Small | Pile of Mace Spheres |
151 | Mace Balls, Large | Ethereal Arrows |
152 | Ethereal Arrows | Quiver of Ethereal Arrows |
153 | Eth. Arrow Quiver | Lesser Runes |
154 | Lesser Runes | Greater Runes |
155 | Greater Runes | Flame Orb |
156 | Flame Orb | Inferno Orb |
157 | Inferno Orb | Claw Orb |
158 | Claw Orb | Energy Orb |
159 | Energy Orb | Wind |
160 | Clipboard | Clipboard (in-editor use) |
Beyond HHE
Some aspects of the game that could be hacked without too much trouble, but which HHE does not support editing for.
Music assignment.
The music table is found at offset 0x09C074 of the v1.3 HERETIC.EXE.
Each entry is 12 bytes:
a 9-byte string with the 8-character MUS lump name and NULL terminator,
plus 3 padding bytes.
Assignments start at E1M1 and set music for every map in order through E6M3,
then come assignments for the title screen, intermission, and end episode
story screens in that order.
This table is found in SOUNDS.C of the Heretic source code as released by Raven.