Skip to content

Commit

Permalink
Merge pull request #22 from kraflab/add-thing-groups
Browse files Browse the repository at this point in the history
Add thing groups
  • Loading branch information
kraflab authored Apr 9, 2021
2 parents ee33cad + c843037 commit baddbb4
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 11 deletions.
27 changes: 26 additions & 1 deletion prboom2/src/d_deh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,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 25 // number of ints in the mobjinfo_t structure (!)
#define DEH_MOBJINFOMAX 27 // 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 @@ -1112,6 +1112,10 @@ static const char *deh_mobjinfo[DEH_MOBJINFOMAX] =
"Bits2", // .flags
"Respawn frame", // .raisestate
"Dropped item", // .droppeditem

// mbf21
"Infighting group", // .infighting_group
"Projectile group", // .projectile_group
};

// Strings that are used to indicate flags ("Bits" in mobjinfo)
Expand Down Expand Up @@ -1888,6 +1892,27 @@ static void setMobjInfoValue(int mobjInfoIndex, int keyIndex, uint_64_t value) {
}
break;
case 24: mi->droppeditem = (int)(value-1); return; // make it base zero (deh is 1-based)

// mbf21
// custom groups count from the end of the vanilla list
// -> no concern for clashes
case 25:
mi->infighting_group = (int)(value);
if (mi->infighting_group < 0)
{
I_Error("Infighting groups must be >= 0 (check your dehacked)");
return;
}
mi->infighting_group = mi->infighting_group + IG_END;
return;
case 26:
mi->projectile_group = (int)(value);
if (mi->projectile_group < 0)
mi->projectile_group = PG_GROUPLESS;
else
mi->projectile_group = mi->projectile_group + PG_END;
return;

default: return;
}
}
Expand Down
15 changes: 15 additions & 0 deletions prboom2/src/dsda/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ static void dsda_InitDoom(void) {
mobjinfo[i].droppeditem = mobjinfo_p->droppeditem;
mobjinfo[i].crashstate = 0; // not in doom
mobjinfo[i].flags2 = 0; // not in doom

// mbf21
mobjinfo[i].infighting_group = IG_DEFAULT;
mobjinfo[i].projectile_group = PG_DEFAULT;
}

// don't want to reorganize info.c structure for a few tweaks...
Expand All @@ -264,6 +268,9 @@ static void dsda_InitDoom(void) {
mobjinfo[MT_BABY].flags2 = MF2_MAP07BOSS2;
mobjinfo[MT_BRUISER].flags2 = MF2_E1M8BOSS;
mobjinfo[MT_UNDEAD].flags2 = MF2_LONGMELEE | MF2_RANGEHALF;

mobjinfo[MT_BRUISER].projectile_group = PG_BARON;
mobjinfo[MT_KNIGHT].projectile_group = PG_BARON;
}

static void dsda_InitHeretic(void) {
Expand Down Expand Up @@ -371,8 +378,16 @@ static void dsda_InitHeretic(void) {
mobjinfo[j].droppeditem = 0; // not in heretic
mobjinfo[j].crashstate = mobjinfo_p->crashstate;
mobjinfo[j].flags2 = mobjinfo_p->flags2;

// mbf21
mobjinfo[j].infighting_group = IG_DEFAULT;
mobjinfo[j].projectile_group = PG_DEFAULT;
}

// don't want to reorganize info.c structure for a few tweaks...
mobjinfo[HERETIC_MT_SORCERER2].infighting_group = IG_WIZARD;
mobjinfo[HERETIC_MT_WIZARD].infighting_group = IG_WIZARD;

// heretic doesn't use "clip" concept
for (i = 0; i < NUMAMMO; ++i) clipammo[i] = 1;

Expand Down
17 changes: 17 additions & 0 deletions prboom2/src/info.h
Original file line number Diff line number Diff line change
Expand Up @@ -2995,6 +2995,19 @@ typedef enum {
TOTAL_NUMMOBJTYPES = HERETIC_NUMMOBJTYPES
} mobjtype_t;

typedef enum {
IG_DEFAULT,
IG_WIZARD,
IG_END
} infighting_group_t;

typedef enum {
PG_GROUPLESS = -1,
PG_DEFAULT,
PG_BARON,
PG_END
} projectile_group_t;

/********************************************************************
* Definition of the Thing structure
********************************************************************/
Expand Down Expand Up @@ -3055,6 +3068,10 @@ typedef struct
// heretic
int crashstate;
uint_64_t flags2;

// mbf21
int infighting_group;
int projectile_group;
} mobjinfo_t;

typedef struct
Expand Down
38 changes: 38 additions & 0 deletions prboom2/src/mbf21.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,44 @@ This is proof-of-concept implemented in dsda-doom.
#### Option default changes
- comp_pursuit: 1 (was 0)

#### Dehacked Thing Groups

##### Infighting
- Add `Infighting group = N` in Thing definition.
- `N` is a nonnegative integer.
- Things with the same value of `N` will not target each other after taking damage.

##### Projectile
- Add `Projectile group = M` in Thing definition.
- `M` is an integer.
- Things with the same value of `M` will not deal projectile damage to each other.
- A negative value of `M` means that species has no projectile immunity, even to other things in the same species.

##### Examples

```
Thing 12 (Imp)
Projectile group = -1
Thing 16 (Baron of Hell)
Projectile group = 2
Thing 18 (Hell Knight)
Infighting group = 1
Projectile group = 1
Thing 21 (Arachnotron)
Infighting group = 1
Projectile group = 2
```

In this example:
- Imp projectiles now damage other Imps (and they will infight with their own kind).
- Barons and Arachnotrons are in the same projectile group: their projectiles will no longer damage each other.
- Barons and Hell Knights are not in the same projectile group: their projectiles will now damage each other, leading to infighting.
- Hell Knights and Arachnotrons are in the same infighting group: they will not infight with each other, despite taking damage from each other's projectiles.
- Note that the group numbers for infighting and projectiles are separate - being in infighting group 1 doesn't mean you are in projectile group 1.

#### New Thing Flags

Implementations match between DSDA-Doom and Eternity Engine,
Expand Down
9 changes: 8 additions & 1 deletion prboom2/src/p_inter.c
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,13 @@ static void P_KillMobj(mobj_t *source, mobj_t *target)
// and other environmental stuff.
//

static dboolean P_InfightingImmune(mobj_t *target, mobj_t *source)
{
return // not default behaviour, and same group
mobjinfo[target->type].infighting_group != IG_DEFAULT &&
mobjinfo[target->type].infighting_group == mobjinfo[source->type].infighting_group;
}

void P_DamageMobj(mobj_t *target,mobj_t *inflictor, mobj_t *source, int damage)
{
player_t *player;
Expand Down Expand Up @@ -1177,7 +1184,7 @@ void P_DamageMobj(mobj_t *target,mobj_t *inflictor, mobj_t *source, int damage)
(!target->threshold || target->flags2 & MF2_NOTHRESHOLD) &&
((source->flags ^ target->flags) & MF_FRIEND || monster_infighting || !mbf_features) &&
!(heretic && source->flags2 & MF2_BOSS) &&
!(target->type == HERETIC_MT_SORCERER2 && source->type == HERETIC_MT_WIZARD)
!P_InfightingImmune(target, source)
)
{
/* if not intent on another player, chase after this one
Expand Down
30 changes: 21 additions & 9 deletions prboom2/src/p_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,25 @@ dboolean PIT_CheckLine (line_t* ld)
// PIT_CheckThing
//

static dboolean P_ProjectileImmune(mobj_t *target, mobj_t *source)
{
return
( // PG_GROUPLESS means no immunity, even to own species
mobjinfo[target->type].projectile_group != PG_GROUPLESS ||
target == source
) &&
(
( // target type has default behaviour, and things are the same type
mobjinfo[target->type].projectile_group == PG_DEFAULT &&
source->type == target->type
) ||
( // target type has special behaviour, and things have the same group
mobjinfo[target->type].projectile_group != PG_DEFAULT &&
mobjinfo[target->type].projectile_group == mobjinfo[source->type].projectile_group
)
);
}

static dboolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
{
fixed_t blockdist;
Expand Down Expand Up @@ -624,17 +643,10 @@ static dboolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath

if (
tmthing->target &&
(
tmthing->target->type == thing->type ||
(tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER) ||
(tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT)
)
)
if (tmthing->target && P_ProjectileImmune(thing, tmthing->target))
{
if (thing == tmthing->target)
return true; // Don't hit same species as originator.
return true; // Don't hit self.
else
// e6y: Dehacked support - monsters infight
if (thing->type != g_mt_player && !monsters_infight) // Explode, but do no damage.
Expand Down

0 comments on commit baddbb4

Please sign in to comment.