From 1c667b95f6e930f1d0c29ddbc4364d1882bc32fe Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 16:49:49 +0200 Subject: [PATCH 1/8] Introduce thing groups --- prboom2/src/dsda/global.c | 15 +++++++++++++++ prboom2/src/info.h | 16 ++++++++++++++++ prboom2/src/p_inter.c | 9 ++++++++- prboom2/src/p_map.c | 22 ++++++++++++++-------- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/prboom2/src/dsda/global.c b/prboom2/src/dsda/global.c index a75b66651..6bf1313c0 100644 --- a/prboom2/src/dsda/global.c +++ b/prboom2/src/dsda/global.c @@ -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 = 0; + mobjinfo[i].projectile_immunity_group = 0; } // don't want to reorganize info.c structure for a few tweaks... @@ -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_immunity_group = PIG_BARON; + mobjinfo[MT_KNIGHT].projectile_immunity_group = PIG_BARON; } static void dsda_InitHeretic(void) { @@ -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 = 0; + mobjinfo[j].projectile_immunity_group = 0; } + // 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; diff --git a/prboom2/src/info.h b/prboom2/src/info.h index 95f213ac0..de69e4105 100644 --- a/prboom2/src/info.h +++ b/prboom2/src/info.h @@ -2995,6 +2995,18 @@ typedef enum { TOTAL_NUMMOBJTYPES = HERETIC_NUMMOBJTYPES } mobjtype_t; +typedef enum { + IG_DEFAULT, + IG_WIZARD, + IG_END +} infighting_group_t; + +typedef enum { + PIG_DEFAULT, + PIG_BARON, + PIG_END +} projectile_immunity_group_t; + /******************************************************************** * Definition of the Thing structure ********************************************************************/ @@ -3055,6 +3067,10 @@ typedef struct // heretic int crashstate; uint_64_t flags2; + + // mbf21 + int infighting_group; + int projectile_immunity_group; } mobjinfo_t; typedef struct diff --git a/prboom2/src/p_inter.c b/prboom2/src/p_inter.c index 830d42d2f..b94c33d7b 100644 --- a/prboom2/src/p_inter.c +++ b/prboom2/src/p_inter.c @@ -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; @@ -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 diff --git a/prboom2/src/p_map.c b/prboom2/src/p_map.c index 9ab90e6eb..4eb86bae8 100644 --- a/prboom2/src/p_map.c +++ b/prboom2/src/p_map.c @@ -510,6 +510,19 @@ dboolean PIT_CheckLine (line_t* ld) // PIT_CheckThing // +static dboolean P_ProjectileImmune(mobj_t *target, mobj_t *source) +{ + return + ( // target type has default behaviour, and things are the same type + mobjinfo[target->type].projectile_immunity_group == PIG_DEFAULT && + source->type == target->type + ) || + ( // target type has special behaviour, and things have the same group + mobjinfo[target->type].projectile_immunity_group != PIG_DEFAULT && + mobjinfo[target->type].projectile_immunity_group == mobjinfo[source->type].projectile_immunity_group + ); +} + static dboolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static { fixed_t blockdist; @@ -624,14 +637,7 @@ 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. From f9f8c268fb0ef130f377da150a0d2c1137a31f60 Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 17:26:43 +0200 Subject: [PATCH 2/8] Add "groupless" projectile group --- prboom2/src/info.h | 1 + prboom2/src/p_map.c | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/prboom2/src/info.h b/prboom2/src/info.h index de69e4105..6491eccf1 100644 --- a/prboom2/src/info.h +++ b/prboom2/src/info.h @@ -3002,6 +3002,7 @@ typedef enum { } infighting_group_t; typedef enum { + PIG_GROUPLESS = -1, PIG_DEFAULT, PIG_BARON, PIG_END diff --git a/prboom2/src/p_map.c b/prboom2/src/p_map.c index 4eb86bae8..4f91c665e 100644 --- a/prboom2/src/p_map.c +++ b/prboom2/src/p_map.c @@ -513,13 +513,19 @@ dboolean PIT_CheckLine (line_t* ld) static dboolean P_ProjectileImmune(mobj_t *target, mobj_t *source) { return - ( // target type has default behaviour, and things are the same type - mobjinfo[target->type].projectile_immunity_group == PIG_DEFAULT && - source->type == target->type - ) || - ( // target type has special behaviour, and things have the same group - mobjinfo[target->type].projectile_immunity_group != PIG_DEFAULT && - mobjinfo[target->type].projectile_immunity_group == mobjinfo[source->type].projectile_immunity_group + ( // PIG_GROUPLESS means no immunity, even to own species + mobjinfo[target->type].projectile_immunity_group != PIG_GROUPLESS || + target == source + ) && + ( + ( // target type has default behaviour, and things are the same type + mobjinfo[target->type].projectile_immunity_group == PIG_DEFAULT && + source->type == target->type + ) || + ( // target type has special behaviour, and things have the same group + mobjinfo[target->type].projectile_immunity_group != PIG_DEFAULT && + mobjinfo[target->type].projectile_immunity_group == mobjinfo[source->type].projectile_immunity_group + ) ); } From 5d1e6b72a186e8a66048b5c7240eb88f65ee16e5 Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 17:28:28 +0200 Subject: [PATCH 3/8] Use "projectile group" --- prboom2/src/dsda/global.c | 8 ++++---- prboom2/src/info.h | 12 ++++++------ prboom2/src/p_map.c | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/prboom2/src/dsda/global.c b/prboom2/src/dsda/global.c index 6bf1313c0..a9282083f 100644 --- a/prboom2/src/dsda/global.c +++ b/prboom2/src/dsda/global.c @@ -254,7 +254,7 @@ static void dsda_InitDoom(void) { // mbf21 mobjinfo[i].infighting_group = 0; - mobjinfo[i].projectile_immunity_group = 0; + mobjinfo[i].projectile_group = 0; } // don't want to reorganize info.c structure for a few tweaks... @@ -269,8 +269,8 @@ static void dsda_InitDoom(void) { mobjinfo[MT_BRUISER].flags2 = MF2_E1M8BOSS; mobjinfo[MT_UNDEAD].flags2 = MF2_LONGMELEE | MF2_RANGEHALF; - mobjinfo[MT_BRUISER].projectile_immunity_group = PIG_BARON; - mobjinfo[MT_KNIGHT].projectile_immunity_group = PIG_BARON; + mobjinfo[MT_BRUISER].projectile_group = PG_BARON; + mobjinfo[MT_KNIGHT].projectile_group = PG_BARON; } static void dsda_InitHeretic(void) { @@ -381,7 +381,7 @@ static void dsda_InitHeretic(void) { // mbf21 mobjinfo[j].infighting_group = 0; - mobjinfo[j].projectile_immunity_group = 0; + mobjinfo[j].projectile_group = 0; } // don't want to reorganize info.c structure for a few tweaks... diff --git a/prboom2/src/info.h b/prboom2/src/info.h index 6491eccf1..cacc2f7f5 100644 --- a/prboom2/src/info.h +++ b/prboom2/src/info.h @@ -3002,11 +3002,11 @@ typedef enum { } infighting_group_t; typedef enum { - PIG_GROUPLESS = -1, - PIG_DEFAULT, - PIG_BARON, - PIG_END -} projectile_immunity_group_t; + PG_GROUPLESS = -1, + PG_DEFAULT, + PG_BARON, + PG_END +} projectile_group_t; /******************************************************************** * Definition of the Thing structure @@ -3071,7 +3071,7 @@ typedef struct // mbf21 int infighting_group; - int projectile_immunity_group; + int projectile_group; } mobjinfo_t; typedef struct diff --git a/prboom2/src/p_map.c b/prboom2/src/p_map.c index 4f91c665e..a579b9f93 100644 --- a/prboom2/src/p_map.c +++ b/prboom2/src/p_map.c @@ -513,18 +513,18 @@ dboolean PIT_CheckLine (line_t* ld) static dboolean P_ProjectileImmune(mobj_t *target, mobj_t *source) { return - ( // PIG_GROUPLESS means no immunity, even to own species - mobjinfo[target->type].projectile_immunity_group != PIG_GROUPLESS || + ( // 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_immunity_group == PIG_DEFAULT && + 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_immunity_group != PIG_DEFAULT && - mobjinfo[target->type].projectile_immunity_group == mobjinfo[source->type].projectile_immunity_group + mobjinfo[target->type].projectile_group != PG_DEFAULT && + mobjinfo[target->type].projectile_group == mobjinfo[source->type].projectile_group ) ); } From 2e3e01f145a812c8ec2dc5db4a52f9bec9106292 Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 17:46:15 +0200 Subject: [PATCH 4/8] Configure groups in deh --- prboom2/src/d_deh.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/prboom2/src/d_deh.c b/prboom2/src/d_deh.c index c2226729e..9f60f7c14 100644 --- a/prboom2/src/d_deh.c +++ b/prboom2/src/d_deh.c @@ -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: @@ -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) @@ -1888,6 +1892,21 @@ 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) + 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; } } From 97c5ac3ecd92e3a1f983a2eb0df6a1f23f07d4c8 Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 17:50:55 +0200 Subject: [PATCH 5/8] Don't rely on raw values --- prboom2/src/dsda/global.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prboom2/src/dsda/global.c b/prboom2/src/dsda/global.c index a9282083f..ac293d352 100644 --- a/prboom2/src/dsda/global.c +++ b/prboom2/src/dsda/global.c @@ -253,8 +253,8 @@ static void dsda_InitDoom(void) { mobjinfo[i].flags2 = 0; // not in doom // mbf21 - mobjinfo[i].infighting_group = 0; - mobjinfo[i].projectile_group = 0; + mobjinfo[i].infighting_group = IG_DEFAULT; + mobjinfo[i].projectile_group = PG_DEFAULT; } // don't want to reorganize info.c structure for a few tweaks... @@ -380,8 +380,8 @@ static void dsda_InitHeretic(void) { mobjinfo[j].flags2 = mobjinfo_p->flags2; // mbf21 - mobjinfo[j].infighting_group = 0; - mobjinfo[j].projectile_group = 0; + mobjinfo[j].infighting_group = IG_DEFAULT; + mobjinfo[j].projectile_group = PG_DEFAULT; } // don't want to reorganize info.c structure for a few tweaks... From b30d25651651c5341520b44b61b817341d5b38f3 Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 17:52:37 +0200 Subject: [PATCH 6/8] Fix wrong comment --- prboom2/src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prboom2/src/p_map.c b/prboom2/src/p_map.c index a579b9f93..194b41e44 100644 --- a/prboom2/src/p_map.c +++ b/prboom2/src/p_map.c @@ -646,7 +646,7 @@ static dboolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static 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. From 21d48bfb267e3a236101f601736400bb21c63dd3 Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 18:10:31 +0200 Subject: [PATCH 7/8] Add thing groups to readme --- prboom2/src/mbf21.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/prboom2/src/mbf21.md b/prboom2/src/mbf21.md index 57304cd37..d2c3646b7 100644 --- a/prboom2/src/mbf21.md +++ b/prboom2/src/mbf21.md @@ -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, From c843037d7c92827eefe1be50472c07d2e314d8de Mon Sep 17 00:00:00 2001 From: kraflab Date: Fri, 9 Apr 2021 18:17:35 +0200 Subject: [PATCH 8/8] Add check for bad infighting group --- prboom2/src/d_deh.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/prboom2/src/d_deh.c b/prboom2/src/d_deh.c index 9f60f7c14..4bdadf16f 100644 --- a/prboom2/src/d_deh.c +++ b/prboom2/src/d_deh.c @@ -1897,7 +1897,13 @@ static void setMobjInfoValue(int mobjInfoIndex, int keyIndex, uint_64_t value) { // custom groups count from the end of the vanilla list // -> no concern for clashes case 25: - mi->infighting_group = (int)(value) + IG_END; + 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);