Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Darch

help with dehacked

Recommended Posts

I want to make a Boom project, so I'm getting started with Dehacked. What I want to do is simple (with Decorate, at least):

I need to replace the armor sprites with the Heretic Tome of Power sprites. (Tome of Power is our friend plums' avatar, to illustrate it better). Thing is, Doom armor has 2 frames while Tome of Power has 15. I've heard you have to replace existing sprites in order to add new graphics, it wouldn't be a problem to use Commander Keen's or SS Nazis, but how to I include them in the Green Armor thing? Do I have to use this? http://www.aspectsweb.co.uk/dehacked/deh06.html

I don't know where to start, actually.

Share this post


Link to post

Yes, you'll have to use the frame table. Frames are like actor states in DECORATE. In each frame (state), you define a sprite, subsprite, duration, codepointer (=action function), brightness (yes or no), and finally, the frame number where to go next. You can freely edit (almost) any of these in the frame table.

Take a look at Thing Editor and find thing "Green Armor" in the list. Notice that its "Spawn state" is 802. Now open the Frame Table and find frame 802. There's "ARM1 A" sprite. Notice the "Next" number is 803. That's "ARM1 B" sprite, and the "Next" number is 802 again. That's how the armor's animation loops by default.

Feel free to change the "Next" numbers to lead the animation to any other states you want, and set the appropriate sprites and durations there. Yes, you need to "overwrite" (sacrifice) the states for it, so that your Commander Keen or SS Nazi would no longer work properly.

I recommend you to use WhackEd editor and .BEX format, since you're making the project for Boom. In standard format, you cannot set codepointers to frames that have NULL codepointers, and vice versa.

Share this post


Link to post

Here's a link to the latest version of WhackEd. Bear in mind that there's a large amount of useless frames you can eat up first, like the Pain Elemental's reanimation frames and some of the gibbing frames.

Share this post


Link to post
Obsidian said:

Bear in mind that there's a large amount of useless frames you can eat up first, like the Pain Elemental's reanimation frames and some of the gibbing frames.

Yes. Also the frames of Item Respawn Fog (if you change the Thing to share frames with teleporter flash).

But Nazis and Keens are good sources of frames, since they're unfitting in Doom's environment and their animations consist of many frames.

Share this post


Link to post

I was about to make a thread about dehacked but I may as well ask it here...

I just started messing around with WhackEd, and the first thing I did was to make some simple changes to the SS Nazi, changing its attack from CPosAttack to BspiAttack. When I loaded the resulting bex file with a test map in zdoom, the monsters refused to attack me. Not only that, changing the bex file has no effect, and even running the map without the bex file the monsters don't attack. And even making a new map with a different name the monsters don't attack.

Any idea what is going on?

Share this post


Link to post

Could you post the code? The only thing I can think of is that you picked the wrong starting frame in the Things table or accidentally altered the Next Frame codepointer for one of the frames.

Share this post


Link to post
mouldy said:

...and even running the map without the bex file the monsters don't attack. And even making a new map with a different name the monsters don't attack.

How do you mean this? Did you permanently break your ZDoom, or you wanted to say something else?

Share this post


Link to post

Maybe the test map has only one sector? (with some nodebuilders you need at least two for the monsters to see you)

Share this post


Link to post
Memfis said:

Maybe the test map has only one sector? (with some nodebuilders you need at least two for the monsters to see you)


wow I think this might be the problem, being a test map I just had one sector, just tried again with 2 and it seems to work.

i'll do some further tests...

Share this post


Link to post

Scifista, Obsidian, thanks a lot guys, I've downloaded Whacked, didn't really had the time to mess with it yet, but I quickly opened it and seems like its gonna work out.

Share this post


Link to post

Is it possible to have "animated" frames for a berserk pack?

I've tried turning the Berserk Pack into a Berserk Sphere and I get an error if I pick up the sphere when it's not showing the original frame.

Share this post


Link to post
TendaMonsta said:

Is it possible to have "animated" frames for a berserk pack?

I've tried turning the Berserk Pack into a Berserk Sphere and I get an error if I pick up the sphere when it's not showing the original frame.


In vanilla, pickups are not determined by the mobj type of the object you pick, but by the frame it's displaying when you pick it up. See P_TouchSpecialThing() in p_inter.c:

Spoiler

// // P_TouchSpecialThing // void P_TouchSpecialThing ( mobj_t* special, mobj_t* toucher ) { player_t* player; int i; fixed_t delta; int sound; delta = special->z - toucher->z; if (delta > toucher->height || delta < -8*FRACUNIT) { // out of reach return; } sound = sfx_itemup; player = toucher->player; // Dead thing touching. // Can happen with a sliding player corpse. if (toucher->health <= 0) return; // Identify by sprite. switch (special->sprite) { // armor case SPR_ARM1: if (!P_GiveArmor (player, 1)) return; player->message = GOTARMOR; break; case SPR_ARM2: if (!P_GiveArmor (player, 2)) return; player->message = GOTMEGA; break; // bonus items case SPR_BON1: player->health++; // can go over 100% if (player->health > 200) player->health = 200; player->mo->health = player->health; player->message = GOTHTHBONUS; break; case SPR_BON2: player->armorpoints++; // can go over 100% if (player->armorpoints > 200) player->armorpoints = 200; if (!player->armortype) player->armortype = 1; player->message = GOTARMBONUS; break; case SPR_SOUL: player->health += 100; if (player->health > 200) player->health = 200; player->mo->health = player->health; player->message = GOTSUPER; sound = sfx_getpow; break; case SPR_MEGA: if (gamemode != commercial) return; player->health = 200; player->mo->health = player->health; P_GiveArmor (player,2); player->message = GOTMSPHERE; sound = sfx_getpow; break; // cards // leave cards for everyone case SPR_BKEY: if (!player->cards[it_bluecard]) player->message = GOTBLUECARD; P_GiveCard (player, it_bluecard); if (!netgame) break; return; case SPR_YKEY: if (!player->cards[it_yellowcard]) player->message = GOTYELWCARD; P_GiveCard (player, it_yellowcard); if (!netgame) break; return; case SPR_RKEY: if (!player->cards[it_redcard]) player->message = GOTREDCARD; P_GiveCard (player, it_redcard); if (!netgame) break; return; case SPR_BSKU: if (!player->cards[it_blueskull]) player->message = GOTBLUESKUL; P_GiveCard (player, it_blueskull); if (!netgame) break; return; case SPR_YSKU: if (!player->cards[it_yellowskull]) player->message = GOTYELWSKUL; P_GiveCard (player, it_yellowskull); if (!netgame) break; return; case SPR_RSKU: if (!player->cards[it_redskull]) player->message = GOTREDSKULL; P_GiveCard (player, it_redskull); if (!netgame) break; return; // medikits, heals case SPR_STIM: if (!P_GiveBody (player, 10)) return; player->message = GOTSTIM; break; case SPR_MEDI: if (!P_GiveBody (player, 25)) return; if (player->health < 25) player->message = GOTMEDINEED; else player->message = GOTMEDIKIT; break; // power ups case SPR_PINV: if (!P_GivePower (player, pw_invulnerability)) return; player->message = GOTINVUL; sound = sfx_getpow; break; case SPR_PSTR: if (!P_GivePower (player, pw_strength)) return; player->message = GOTBERSERK; if (player->readyweapon != wp_fist) player->pendingweapon = wp_fist; sound = sfx_getpow; break; case SPR_PINS: if (!P_GivePower (player, pw_invisibility)) return; player->message = GOTINVIS; sound = sfx_getpow; break; case SPR_SUIT: if (!P_GivePower (player, pw_ironfeet)) return; player->message = GOTSUIT; sound = sfx_getpow; break; case SPR_PMAP: if (!P_GivePower (player, pw_allmap)) return; player->message = GOTMAP; sound = sfx_getpow; break; case SPR_PVIS: if (!P_GivePower (player, pw_infrared)) return; player->message = GOTVISOR; sound = sfx_getpow; break; // ammo case SPR_CLIP: if (special->flags & MF_DROPPED) { if (!P_GiveAmmo (player,am_clip,0)) return; } else { if (!P_GiveAmmo (player,am_clip,1)) return; } player->message = GOTCLIP; break; case SPR_AMMO: if (!P_GiveAmmo (player, am_clip,5)) return; player->message = GOTCLIPBOX; break; case SPR_ROCK: if (!P_GiveAmmo (player, am_misl,1)) return; player->message = GOTROCKET; break; case SPR_BROK: if (!P_GiveAmmo (player, am_misl,5)) return; player->message = GOTROCKBOX; break; case SPR_CELL: if (!P_GiveAmmo (player, am_cell,1)) return; player->message = GOTCELL; break; case SPR_CELP: if (!P_GiveAmmo (player, am_cell,5)) return; player->message = GOTCELLBOX; break; case SPR_SHEL: if (!P_GiveAmmo (player, am_shell,1)) return; player->message = GOTSHELLS; break; case SPR_SBOX: if (!P_GiveAmmo (player, am_shell,5)) return; player->message = GOTSHELLBOX; break; case SPR_BPAK: if (!player->backpack) { for (i=0 ; i<NUMAMMO ; i++) player->maxammo[i] *= 2; player->backpack = true; } for (i=0 ; i<NUMAMMO ; i++) P_GiveAmmo (player, i, 1); player->message = GOTBACKPACK; break; // weapons case SPR_BFUG: if (!P_GiveWeapon (player, wp_bfg, false) ) return; player->message = GOTBFG9000; sound = sfx_wpnup; break; case SPR_MGUN: if (!P_GiveWeapon (player, wp_chaingun, special->flags&MF_DROPPED) ) return; player->message = GOTCHAINGUN; sound = sfx_wpnup; break; case SPR_CSAW: if (!P_GiveWeapon (player, wp_chainsaw, false) ) return; player->message = GOTCHAINSAW; sound = sfx_wpnup; break; case SPR_LAUN: if (!P_GiveWeapon (player, wp_missile, false) ) return; player->message = GOTLAUNCHER; sound = sfx_wpnup; break; case SPR_PLAS: if (!P_GiveWeapon (player, wp_plasma, false) ) return; player->message = GOTPLASMA; sound = sfx_wpnup; break; case SPR_SHOT: if (!P_GiveWeapon (player, wp_shotgun, special->flags&MF_DROPPED ) ) return; player->message = GOTSHOTGUN; sound = sfx_wpnup; break; case SPR_SGN2: if (!P_GiveWeapon (player, wp_supershotgun, special->flags&MF_DROPPED ) ) return; player->message = GOTSHOTGUN2; sound = sfx_wpnup; break; default: I_Error ("P_SpecialThing: Unknown gettable thing"); } if (special->flags & MF_COUNTITEM) player->itemcount++; P_RemoveMobj (special); player->bonuscount += BONUSADD; if (player == &players[consoleplayer]) S_StartSound (NULL, sound); }

What this means, notably, is that you can make items that correspond to multiple powerups/items/whatever, and which give you different things depending on when you pick them up.

Note also how the megasphere is coded not to do anything when picked up outside of Doom II.

Share this post


Link to post

You're also not limited by the sprites that are included in the IWAD. Only by sprite sets (BON1, BON2, PSTR, and so on). So, to make the berserk pack animated, you can (and should) use the following sprites:

PSTRA0
PSTRB0
PSTRC0
...

Even though only the first one appears in the IWADs.

Share this post


Link to post

In other words, you must name your custom sprites PSTRA0, PSTRB0 and so on, otherwise they won't give you the Berserk upon pickup.

Spoiler

And if you're mapping for strict vanilla and want custom sprites without having to reinclude all, you must not include PSTRA0 (because the IWAD already contains one) and only include PSTRB0,C0 etc. But this is probably not your case, I know you do .bex patches for Boom.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×