diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 7cd53b49c..515a3015e 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -100,52 +100,88 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol) // // A_Saw // +enum SAW_Flags +{ + SF_NORANDOM = 1, + SF_RANDOMLIGHTMISS = 2, + SF_RANDOMLIGHTHIT = 4, + SF_NOUSEAMMOMISS = 8, + SF_NOUSEAMMO = 16, +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) { - angle_t angle; + angle_t angle; + angle_t slope; player_t *player; AActor *linetarget; - ACTION_PARAM_START(4); + ACTION_PARAM_START(9); ACTION_PARAM_SOUND(fullsound, 0); ACTION_PARAM_SOUND(hitsound, 1); ACTION_PARAM_INT(damage, 2); ACTION_PARAM_CLASS(pufftype, 3); - ACTION_PARAM_FIXED(Range, 4) - ACTION_PARAM_FIXED(LifeSteal, 5); + ACTION_PARAM_INT(Flags, 4); + ACTION_PARAM_FIXED(Range, 5); + ACTION_PARAM_ANGLE(Spread_XY, 6); + ACTION_PARAM_ANGLE(Spread_Z, 7); + ACTION_PARAM_FIXED(LifeSteal, 8); if (NULL == (player = self->player)) { return; } + if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff); + if (damage == 0) damage = 2; + + if (!(Flags & SF_NORANDOM)) + damage *= (pr_saw()%10+1); + + // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) + if (Range == 0) Range = MELEERANGE+1; + + angle = self->angle + (pr_saw.Random2() * (Spread_XY / 255)); + slope = P_AimLineAttack (self, angle, Range, &linetarget) + (pr_saw.Random2() * (Spread_Z / 255)); + + P_LineAttack (self, angle, Range, + slope, damage, + NAME_None, pufftype); + AWeapon *weapon = self->player->ReadyWeapon; - if (weapon != NULL) + if ((weapon != NULL) && !(Flags & SF_NOUSEAMMO) && !(!linetarget && (Flags & SF_NOUSEAMMOMISS))) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return; } - if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff); - if (damage == 0) damage = 2; - - damage *= (pr_saw()%10+1); - angle = self->angle; - angle += pr_saw.Random2() << 18; - - // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) - if (Range == 0) Range = MELEERANGE+1; - - P_LineAttack (self, angle, Range, - P_AimLineAttack (self, angle, Range, &linetarget), damage, - NAME_None, pufftype); - if (!linetarget) { + if ((Flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64)) + { + player->extralight = !player->extralight; + } S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM); return; } + if (Flags & SF_RANDOMLIGHTHIT) + { + int randVal = pr_saw(); + if (randVal < 64) + { + player->extralight = 0; + } + else if (randVal < 160) + { + player->extralight = 1; + } + else + { + player->extralight = 2; + } + } + if (LifeSteal) P_GiveBody (self, (damage * LifeSteal) >> FRACBITS); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index ab2630688..dcf029ca9 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -1,4 +1,12 @@ +// Flags for A_Saw +const int SF_NORANDOM = 1; +const int SF_RANDOMLIGHTMISS = 2; +const int SF_RANDOMLIGHTHIT = 4; +const int SF_RANDOMLIGHTBOTH = 6; +const int SF_NOUSEAMMOMISS = 8; +const int SF_NOUSEAMMO = 16; + // Flags for A_CustomMissile const int CMF_AIMOFFSET = 1; const int CMF_AIMDIRECTION = 2; diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 3a4dd20d9..22cd69e6f 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -40,7 +40,7 @@ ACTOR Inventory native action native A_ClearReFire(); action native A_CheckReload(); action native A_GunFlash(state flash = ""); - action native A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class pufftype = "BulletPuff", float range = 0, float lifesteal = 0); + action native A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class pufftype = "BulletPuff", int flags = 0, float range = 0, float spread_xy = 2.8125, float spread_z = 0, float lifesteal = 0); action native A_CheckForReload(int counter, state label, bool dontincrement = false); action native A_ResetReloadCounter(); action native A_RestoreSpecialPosition();