Gez
Why don't I have a custom title by now?!
Posts: 9138
Registered: 07-07 |
Vanilla code:
code: //
// A_FireCGun
//
void
A_FireCGun
( player_t* player,
pspdef_t* psp )
{
S_StartSound (player->mo, sfx_pistol);
if (!player->ammo[weaponinfo[player->readyweapon].ammo])
return;
P_SetMobjState (player->mo, S_PLAY_ATK2);
player->ammo[weaponinfo[player->readyweapon].ammo]--;
P_SetPsprite (player,
ps_flash,
weaponinfo[player->readyweapon].flashstate
+ psp->state
- &states[S_CHAIN1] );
P_BulletSlope (player->mo);
P_GunShot (player->mo, !player->refire);
}
The important part here is this:
code:
P_SetPsprite (player,
ps_flash,
weaponinfo[player->readyweapon].flashstate
+ psp->state
- &states[S_CHAIN1] );
The function's prototype:
code: P_SetPsprite
( player_t* player,
int position,
statenum_t stnum )
What is a statenum? It's an enum, that is to say, an integer. Here's an excerpt:
code: typedef enum
{
S_NULL,
S_LIGHTDONE,
S_PUNCH,
S_PUNCHDOWN,
S_PUNCHUP,
S_PUNCH1,
S_PUNCH2,
S_PUNCH3,
S_PUNCH4,
S_PUNCH5,
S_PISTOL,
S_PISTOLDOWN,
S_PISTOLUP,
S_PISTOL1,
S_PISTOL2,
S_PISTOL3,
S_PISTOL4,
S_PISTOLFLASH,
<snip shotgun states>
S_CHAIN,
S_CHAINDOWN,
S_CHAINUP,
S_CHAIN1,
S_CHAIN2,
S_CHAIN3,
S_CHAINFLASH1,
S_CHAINFLASH2,
<snip a ton of stuff>
S_BRAINSTEM,
S_TECHLAMP,
S_TECHLAMP2,
S_TECHLAMP3,
S_TECHLAMP4,
S_TECH2LAMP,
S_TECH2LAMP2,
S_TECH2LAMP3,
S_TECH2LAMP4,
NUMSTATES
} statenum_t;
Little digression about the chaingun states:
code:
{
// chaingun
am_clip, // ammo/amunition type
S_CHAINUP, // upstate
S_CHAINDOWN, // downstate
S_CHAIN, // readystate
S_CHAIN1, // atkstate, i.e. attack/fire/hit frame
S_CHAINFLASH1 // flashstate, muzzle flash
},
Now let's look at the stnum value here:
- weaponinfo[player->readyweapon].flashstate => this is the state you defined, which can be NULL. In vanilla, it is S_CHAINFLASH1.
- + psp->state => this is the current player sprite state on the weapon position; in vanilla it's going to be CHAIN1 or CHAIN2.
- - &states[S_CHAIN1] => we subtract the chaingun attack state (note: not the chaingun flash state).
The result? If we currently are in CHAIN1, it'll be flash state + CHAIN1 - CHAIN1, or flash state. If we currently are in CHAIN2, it'll be flash state + CHAIN2 - CHAIN1, or flash state + 1.
Now what if we are in a totally different state from what vanilla expect? What if our attack state is PISTOL? Then it'll be flash state + 10 - 52, or flash state -42. Your flash state is 0? Yeah, don't expect things to work well.
Or, what if it's something different in the other way around? Your attack state somehow is BRAINSTEM. Flash state + 958 - 52 = flash state + 906. Your flash state is 0? Then, now, it's STALAGTITE. (Blame Id for the misspelling.)
Anyway, the only way you can have things working correctly is if you keep as many flash states as you have attack states with A_FireCGun, and you keep in mind that the offset between your attack state and S_CHAIN1, whatever that is, will be used as the offset between the weapon's flash state and the state actually used for the muzzle flash.
For instance, looking at your BEX code, I see A_FireCGun is used in frame 58. 58-52=6. Firing frame is 1. 1 + 6 = 7. What is state 7? Why, it just happens to be PUNCH3!
Incidentally, why does it work as you expected it in ZDoom? Simple:
code: //
// A_FireCGun
//
DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
{
player_t *player;
if (self == NULL || NULL == (player = self->player))
{
return;
}
AWeapon *weapon = player->ReadyWeapon;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
return;
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
FState *flash = weapon->FindState(NAME_Flash);
if (flash != NULL)
{
// [RH] Fix for Sparky's messed-up Dehacked patch! Blargh!
FState * atk = weapon->FindState(NAME_Fire);
int theflash = clamp (int(player->psprites[ps_weapon].state - atk), 0, 1);
if (flash[theflash].sprite != flash->sprite)
{
theflash = 0;
}
P_SetSafeFlash (weapon, player, flash, theflash);
}
}
player->mo->PlayAttacking2 ();
P_GunShot (self, !player->refire, PClass::FindClass(NAME_BulletPuff), P_BulletSlope (self));
}
As you can see, there's a fix for Sparky's messed up Dehacked patch, blargh! A consequence of this is that ZDoom will not accept an offset between flash state and actual flash greater than 1. So if you make something which rely on having an offset of 7, ZDoom will clamp it to an offset of 1. That means that it'll be broken in ZDoom...
Conclusion: if you want your dehacked to work in both ZDoom and PrBoom/Choco, you need to make sure that you use the same chaingun attack states as the chaingun itself. You can use only one of them, or both, or none; but you cannot use, say, a rocket launcher frame for A_FireCGun.
Last edited by Gez on 02-02-13 at 22:28
|