Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MBF21 Melee Range property #46

Merged
merged 13 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions prboom2/doc/mbf21.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ In this example:
- Add `Fast speed = X` in the Thing definition.
- `X` has the same units as the normal `Speed` field.

#### Melee range
- [PR](https://github.com/kraflab/dsda-doom/pull/46)
- Sets the range at which a monster will initiate a melee attack.
- Also affects the range for vanilla melee attack codepointers, e.g. A_SargAttack, A_TroopAttack, etc.
- Similarly, adjusting the player mobj's melee range will adjust the range of A_Punch and A_Saw
- Add `Melee range = X` in the Thing definition.
- `X` is in fixed point, like the Radius and Height fields

## Weapons

#### Weapon Flags
Expand Down Expand Up @@ -265,7 +273,7 @@ MBF21 defaults:
- `damagebase (int)`: Base damage of attack; if not set, defaults to 3
- `damagedice (int)`: Attack damage random multiplier; if not set, defaults to 8
- `sound (uint)`: Sound to play if attack hits
- `range (fixed)`: Attack range; if not set, defaults to 64.0
- `range (fixed)`: Attack range; if not set, defaults to calling actor's melee range property
- Notes:
- Damage formula is: `damage = (damagebase * random(1, damagedice))`

Expand Down Expand Up @@ -415,7 +423,7 @@ MBF21 defaults:
- `damagedice (int)`: Attack damage random multiplier; if not set, defaults to 10
- `zerkfactor (fixed)`: Berserk damage multiplier; if not set, defaults to 1.0
- `sound (uint)`: Sound to play if attack hits
- `range (fixed)`: Attack range; if not set, defaults to 64.0
- `range (fixed)`: Attack range; if not set, defaults to player mobj's melee range property
- Notes:
- Damage formula is: `damage = (damagebase * random(1, damagedice))`; this is then multiplied by `zerkfactor` if the player has Berserk.

Expand Down
8 changes: 5 additions & 3 deletions prboom2/src/d_deh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ typedef struct
// killough 8/9/98: make DEH_BLOCKMAX self-adjusting
#define DEH_BLOCKMAX (sizeof(deh_blocks) / sizeof(*deh_blocks)) // size of array
#define DEH_MAXKEYLEN 32 // as much of any key as we'll look at
#define DEH_MOBJINFOMAX 31 // number of mobjinfo configuration keys
#define DEH_MOBJINFOMAX 32 // number of mobjinfo configuration keys

// Put all the block header values, and the function to be called when that
// one is encountered, in this array:
Expand Down Expand Up @@ -1139,6 +1139,7 @@ static const char *deh_mobjinfo[DEH_MOBJINFOMAX] =
"MBF21 Bits", // .flags2
"Rip sound", // .ripsound
"Fast speed", // .altspeed
"Melee range", // .meleerange
};

// Strings that are used to indicate flags ("Bits" in mobjinfo)
Expand Down Expand Up @@ -1489,7 +1490,7 @@ static const deh_bexptr deh_bexptrs[] = // CPhipps - static const
{A_SpawnObject, "A_SpawnObject", 8},
{A_MonsterProjectile, "A_MonsterProjectile", 5},
{A_MonsterBulletAttack, "A_MonsterBulletAttack", 5, {0, 0, 1, 3, 5}},
{A_MonsterMeleeAttack, "A_MonsterMeleeAttack", 4, {3, 8, 0, MELEERANGE}},
{A_MonsterMeleeAttack, "A_MonsterMeleeAttack", 4, {3, 8, 0, 0}},
{A_RadiusDamage, "A_RadiusDamage", 2},
{A_NoiseAlert, "A_NoiseAlert", 0},
{A_HealChase, "A_HealChase", 2},
Expand All @@ -1506,7 +1507,7 @@ static const deh_bexptr deh_bexptrs[] = // CPhipps - static const
{A_RemoveFlags, "A_RemoveFlags", 2},
{A_WeaponProjectile, "A_WeaponProjectile", 5},
{A_WeaponBulletAttack, "A_WeaponBulletAttack", 5, {0, 0, 1, 5, 3}},
{A_WeaponMeleeAttack, "A_WeaponMeleeAttack", 5, {2, 10, 1 * FRACUNIT, 0, MELEERANGE}},
{A_WeaponMeleeAttack, "A_WeaponMeleeAttack", 5, {2, 10, 1 * FRACUNIT, 0, 0}},
{A_WeaponSound, "A_WeaponSound", 2},
{A_WeaponAlert, "A_WeaponAlert", 0},
{A_WeaponJump, "A_WeaponJump", 2},
Expand Down Expand Up @@ -1981,6 +1982,7 @@ static void setMobjInfoValue(int mobjInfoIndex, int keyIndex, uint_64_t value) {
return;
case 29: mi->ripsound = (int)value; return;
case 30: mi->altspeed = (int)value; return;
case 31: mi->meleerange = (int)value; return;

default: return;
}
Expand Down
3 changes: 3 additions & 0 deletions prboom2/src/dsda/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "d_items.h"
#include "p_inter.h"
#include "p_spec.h"
#include "p_map.h"
#include "sounds.h"
#include "d_main.h"
#include "v_video.h"
Expand Down Expand Up @@ -260,6 +261,7 @@ static void dsda_InitDoom(void) {
mobjinfo[i].splash_group = SG_DEFAULT;
mobjinfo[i].ripsound = sfx_None;
mobjinfo[i].altspeed = NO_ALTSPEED;
mobjinfo[i].meleerange = MELEERANGE;
}

// don't want to reorganize info.c structure for a few tweaks...
Expand Down Expand Up @@ -403,6 +405,7 @@ static void dsda_InitHeretic(void) {
mobjinfo[j].splash_group = SG_DEFAULT;
mobjinfo[j].ripsound = heretic_sfx_None;
mobjinfo[j].altspeed = NO_ALTSPEED;
mobjinfo[j].meleerange = MELEERANGE;
}

// don't want to reorganize info.c structure for a few tweaks...
Expand Down
1 change: 1 addition & 0 deletions prboom2/src/info.h
Original file line number Diff line number Diff line change
Expand Up @@ -3087,6 +3087,7 @@ typedef struct
int splash_group;
int ripsound;
int altspeed;
int meleerange;
} mobjinfo_t;

#define NO_ALTSPEED -1
Expand Down
33 changes: 20 additions & 13 deletions prboom2/src/p_enemy.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,14 @@ static dboolean P_CheckRange(mobj_t *actor, fixed_t range)

static dboolean P_CheckMeleeRange(mobj_t *actor)
{
return P_CheckRange(
actor,
compatibility_level == doom_12_compatibility ?
MELEERANGE :
MELEERANGE - 20*FRACUNIT + actor->target->info->radius
);
int range;

range = actor->info->meleerange;

if (compatibility_level != doom_12_compatibility)
range += actor->target->info->radius - 20 * FRACUNIT;

return P_CheckRange(actor, range);
}

//
Expand Down Expand Up @@ -717,9 +719,9 @@ static void P_NewChaseDir(mobj_t *actor)
actor->info->missilestate &&
actor->type != MT_SKULL &&
(
(!target->info->missilestate && dist < MELEERANGE*2) ||
(!target->info->missilestate && dist < target->info->meleerange*2) ||
(
target->player && dist < MELEERANGE*3 &&
target->player && dist < target->player->mo->info->meleerange*3 &&
weaponinfo[target->player->readyweapon].flags & WPF_FLEEMELEE
)
)
Expand Down Expand Up @@ -754,7 +756,7 @@ static dboolean P_IsVisible(mobj_t *actor, mobj_t *mo, dboolean allaround)
angle_t an = R_PointToAngle2(actor->x, actor->y,
mo->x, mo->y) - actor->angle;
if (an > ANG90 && an < ANG270 &&
P_AproxDistance(mo->x-actor->x, mo->y-actor->y) > MELEERANGE)
P_AproxDistance(mo->x-actor->x, mo->y-actor->y) > WAKEUPRANGE)
return false;
}
return P_CheckSight(actor, mo);
Expand Down Expand Up @@ -3171,7 +3173,7 @@ void A_MonsterBulletAttack(mobj_t *actor)
// args[0]: Base damage of attack (e.g. for 3d8, customize the 3); if not set, defaults to 3
// args[1]: Attack damage modulus (e.g. for 3d8, customize the 8); if not set, defaults to 8
// args[2]: Sound to play if attack hits
// args[3]: Range (fixed point); if not set, defaults to MELEERANGE (64.0)
// args[3]: Range (fixed point); if not set, defaults to monster's melee range
//
void A_MonsterMeleeAttack(mobj_t *actor)
{
Expand All @@ -3186,8 +3188,13 @@ void A_MonsterMeleeAttack(mobj_t *actor)
hitsound = actor->state->args[2];
range = actor->state->args[3];

if (range == 0)
range = actor->info->meleerange;

range += actor->target->info->radius - 20 * FRACUNIT;

A_FaceTarget(actor);
if (!P_CheckRange(actor, range + actor->target->info->radius))
if (!P_CheckRange(actor, range))
return;

S_StartSound(actor, hitsound);
Expand Down Expand Up @@ -4858,14 +4865,14 @@ dboolean Heretic_P_LookForPlayers(mobj_t * actor, dboolean allaround)
dist = P_AproxDistance(player->mo->x - actor->x,
player->mo->y - actor->y);
// if real close, react anyway
if (dist > MELEERANGE)
if (dist > WAKEUPRANGE)
continue; // behind back
}
}
if (player->mo->flags & MF_SHADOW)
{ // Player is invisible
if ((P_AproxDistance(player->mo->x - actor->x,
player->mo->y - actor->y) > 2 * MELEERANGE)
player->mo->y - actor->y) > SNEAKRANGE)
&& P_AproxDistance(player->mo->momx, player->mo->momy)
< 5 * FRACUNIT)
{ // Player is sneaking - can't detect
Expand Down
4 changes: 4 additions & 0 deletions prboom2/src/p_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
#define MELEERANGE (64*FRACUNIT)
#define MISSILERANGE (32*64*FRACUNIT)

// a couple of explicit constants for non-melee things that used to use MELEERANGE
#define WAKEUPRANGE (64*FRACUNIT)
#define SNEAKRANGE (128*FRACUNIT)

// MAXRADIUS is for precalculated sector block boxes the spider demon
// is larger, but we do not have any moving sectors nearby
#define MAXRADIUS (32*FRACUNIT)
Expand Down
29 changes: 18 additions & 11 deletions prboom2/src/p_pspr.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ void A_GunFlash(player_t *player, pspdef_t *psp)
void A_Punch(player_t *player, pspdef_t *psp)
{
angle_t angle;
int t, slope, damage;
int t, slope, damage, range;

CHECK_WEAPON_CODEPOINTER("A_Punch", player);

Expand All @@ -738,13 +738,15 @@ void A_Punch(player_t *player, pspdef_t *psp)
t = P_Random(pr_punchangle);
angle += (t - P_Random(pr_punchangle))<<18;

range = (mbf21 ? player->mo->info->meleerange : MELEERANGE);

/* killough 8/2/98: make autoaiming prefer enemies */
if (!mbf_features ||
(slope = P_AimLineAttack(player->mo, angle, MELEERANGE, MF_FRIEND),
(slope = P_AimLineAttack(player->mo, angle, range, MF_FRIEND),
!linetarget))
slope = P_AimLineAttack(player->mo, angle, MELEERANGE, 0);
slope = P_AimLineAttack(player->mo, angle, range, 0);

P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);
P_LineAttack(player->mo, angle, range, slope, damage);

if (!linetarget)
return;
Expand All @@ -764,7 +766,7 @@ void A_Punch(player_t *player, pspdef_t *psp)

void A_Saw(player_t *player, pspdef_t *psp)
{
int slope, damage;
int slope, damage, range;
angle_t angle;
int t;

Expand All @@ -776,14 +778,16 @@ void A_Saw(player_t *player, pspdef_t *psp)
t = P_Random(pr_saw);
angle += (t - P_Random(pr_saw))<<18;

/* Use meleerange + 1 so that the puff doesn't skip the flash
* killough 8/2/98: make autoaiming prefer enemies */
// Use meleerange + 1 so that the puff doesn't skip the flash
range = (mbf21 ? player->mo->info->meleerange : MELEERANGE) + 1;

/* killough 8/2/98: make autoaiming prefer enemies */
if (!mbf_features ||
(slope = P_AimLineAttack(player->mo, angle, MELEERANGE+1, MF_FRIEND),
(slope = P_AimLineAttack(player->mo, angle, range, MF_FRIEND),
!linetarget))
slope = P_AimLineAttack(player->mo, angle, MELEERANGE+1, 0);
slope = P_AimLineAttack(player->mo, angle, range, 0);

P_LineAttack(player->mo, angle, MELEERANGE+1, slope, damage);
P_LineAttack(player->mo, angle, range, slope, damage);

if (!linetarget)
{
Expand Down Expand Up @@ -1232,7 +1236,7 @@ void A_WeaponBulletAttack(player_t *player, pspdef_t *psp)
// args[1]: Attack damage modulus (e.g. for 2d10, customize the 10); if not set, defaults to 10
// args[2]: Berserk damage multiplier (fixed point); if not set, defaults to 1.0 (no change).
// args[3]: Sound to play if attack hits
// args[4]: Range (fixed point); if not set, defaults to MELEERANGE (64.0)
// args[4]: Range (fixed point); if not set, defaults to player mobj's melee range
//
void A_WeaponMeleeAttack(player_t *player, pspdef_t *psp)
{
Expand All @@ -1251,6 +1255,9 @@ void A_WeaponMeleeAttack(player_t *player, pspdef_t *psp)
hitsound = psp->state->args[3];
range = psp->state->args[4];

if (range == 0)
range = player->mo->info->meleerange;

damage = (P_Random(pr_mbf21) % damagemod + 1) * damagebase;
if (player->powers[pw_strength])
damage = (damage * zerkfactor) >> FRACBITS;
Expand Down