From 30da54b689d7619e8a9f0b2d4234928af936da99 Mon Sep 17 00:00:00 2001 From: MadDeCoDeR <18539489+MadDeCoDeR@users.noreply.github.com> Date: Fri, 6 Dec 2024 19:21:16 +0200 Subject: [PATCH] Classic DOOM - Add MBF21 line and sector support --- doomclassic/doom/doomdata.h | 5 +- doomclassic/doom/p_map.cpp | 5 +- doomclassic/doom/p_mobj.cpp | 19 ++++ doomclassic/doom/p_mobj.h | 3 + doomclassic/doom/p_spec.cpp | 197 ++++++++++++++++++++++-------------- doomclassic/doom/p_spec.h | 4 + 6 files changed, 155 insertions(+), 78 deletions(-) diff --git a/doomclassic/doom/doomdata.h b/doomclassic/doom/doomdata.h index d785e749..a5447019 100644 --- a/doomclassic/doom/doomdata.h +++ b/doomclassic/doom/doomdata.h @@ -35,8 +35,6 @@ If you have questions concerning this license or the applicable additional terms // Some global defines, that configure the game. #include "doomdef.h" - - // // Map level types. // The following data structures define the persistent format @@ -140,7 +138,10 @@ typedef struct // Set if already seen, thus drawn in automap. #define ML_MAPPED 256 +// mbf21 +#define ML_BLOCKLANDMONSTERS 4096 +#define ML_BLOCKPLAYERS 8192 // Sector definition, from editing. diff --git a/doomclassic/doom/p_map.cpp b/doomclassic/doom/p_map.cpp index a9adf858..dd6f624b 100644 --- a/doomclassic/doom/p_map.cpp +++ b/doomclassic/doom/p_map.cpp @@ -208,10 +208,11 @@ qboolean PIT_CheckLine (line_t* ld) if (!(::g->tmthing->flags & MF_MISSILE) ) { - if ( ld->flags & ML_BLOCKING ) + if ( ld->flags & ML_BLOCKING || (::g->tmthing->player && ld->flags & ML_BLOCKPLAYERS)) return false; // explicitly blocking everything - if ( !::g->tmthing->player && ld->flags & ML_BLOCKMONSTERS ) + if ( !::g->tmthing->player && ld->flags & ML_BLOCKMONSTERS || + (ld->flags & ML_BLOCKLANDMONSTERS && !(::g->tmthing->flags & MF_FLOAT)) ) return false; // block monsters only } diff --git a/doomclassic/doom/p_mobj.cpp b/doomclassic/doom/p_mobj.cpp index 2f0e031b..663907db 100644 --- a/doomclassic/doom/p_mobj.cpp +++ b/doomclassic/doom/p_mobj.cpp @@ -440,6 +440,25 @@ void P_MobjThinker (mobj_t* mobj) return; // mobj was removed } + { + sector_t* sector = mobj->subsector->sector; + + if ( + sector->special & KILL_MONSTERS_MASK && + mobj->z == mobj->floorz && + mobj->player == NULL && + mobj->flags & MF_SHOOTABLE && + !(mobj->flags & MF_FLOAT) + ) + { + P_DamageMobj(mobj, NULL, NULL, 10000); + + // must have been removed + if (mobj->thinker.function.acv == (actionf_v) (-1)) + return; + } + } + // cycle through states, // calling action functions at transitions diff --git a/doomclassic/doom/p_mobj.h b/doomclassic/doom/p_mobj.h index 40ab7741..0e119f83 100644 --- a/doomclassic/doom/p_mobj.h +++ b/doomclassic/doom/p_mobj.h @@ -117,6 +117,9 @@ If you have questions concerning this license or the applicable additional terms // Any questions? // +//GK: MBF21 Support +#define KILL_MONSTERS_MASK 0x2000 // bit 13 + // // Misc. mobj flags // diff --git a/doomclassic/doom/p_spec.cpp b/doomclassic/doom/p_spec.cpp index 0452ad49..77639272 100644 --- a/doomclassic/doom/p_spec.cpp +++ b/doomclassic/doom/p_spec.cpp @@ -1548,92 +1548,120 @@ void P_PlayerInSpecialSector (player_t* player) return; // Has hitten ground. - switch (sector->special) - { - case 5: - // HELLSLIME DAMAGE - if (!player->powers[pw_ironfeet]) - if (!(::g->leveltime&0x1f)) - P_DamageMobj (player->mo, NULL, NULL, 10); - break; - - case 7: - // NUKAGE DAMAGE - if (!player->powers[pw_ironfeet]) - if (!(::g->leveltime&0x1f)) - P_DamageMobj (player->mo, NULL, NULL, 5); - break; - - case 16: - // SUPER HELLSLIME DAMAGE - case 4: - // STROBE HURT - if (!player->powers[pw_ironfeet] - || (P_Random()<5) ) + if (sector->special < 32) { + switch (sector->special) { - if (!(::g->leveltime&0x1f)) - P_DamageMobj (player->mo, NULL, NULL, 20); - } - break; + case 5: + // HELLSLIME DAMAGE + if (!player->powers[pw_ironfeet]) + if (!(::g->leveltime&0x1f)) + P_DamageMobj (player->mo, NULL, NULL, 10); + break; - case 9: - // SECRET SECTOR - player->secretcount++; - //GK send message when secret found - ::g->plyr->message = GOTSECRET; - S_StartSound(player->mo, sfx_getpow); - sector->special = 0; + case 7: + // NUKAGE DAMAGE + if (!player->powers[pw_ironfeet]) + if (!(::g->leveltime&0x1f)) + P_DamageMobj (player->mo, NULL, NULL, 5); + break; + case 16: + // SUPER HELLSLIME DAMAGE + case 4: + // STROBE HURT + if (!player->powers[pw_ironfeet] + || (P_Random()<5) ) + { + if (!(::g->leveltime&0x1f)) + P_DamageMobj (player->mo, NULL, NULL, 20); + } + break; - if ( !::g->demoplayback && ( ::g->usergame && !::g->netgame ) ) { - // DHM - Nerve :: Let's give achievements in real time in Doom 2 - if ( !common->IsMultiplayer() ) { - switch( DoomLib::GetGameSKU() ) { - case GAME_SKU_DOOM1_BFG: { - // Removing trophies for DOOM and DOOM II BFG due to point limit. - //gameLocal->UnlockAchievement( Doom1BFG_Trophies::SCOUT_FIND_ANY_SECRET ); - break; - } - case GAME_SKU_DOOM2_BFG: { -#ifdef __MONOLITH__ - //gameLocal->UnlockAchievement( Doom2BFG_Trophies::IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET ); - idAchievementManager::LocalUser_CompleteAchievement(ACHIEVEMENT_DOOM2_IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET ); -#endif - break; - } - case GAME_SKU_DCC: { - // Not on PC. - //gameLocal->UnlockAchievement( DOOM_ACHIEVEMENT_FIND_SECRET ); - break; - } - default: { - // No unlocks for other SKUs. - break; + case 9: + // SECRET SECTOR + player->secretcount++; + //GK send message when secret found + ::g->plyr->message = GOTSECRET; + S_StartSound(player->mo, sfx_getpow); + sector->special = 0; + + + if ( !::g->demoplayback && ( ::g->usergame && !::g->netgame ) ) { + // DHM - Nerve :: Let's give achievements in real time in Doom 2 + if ( !common->IsMultiplayer() ) { + switch( DoomLib::GetGameSKU() ) { + case GAME_SKU_DOOM1_BFG: { + // Removing trophies for DOOM and DOOM II BFG due to point limit. + //gameLocal->UnlockAchievement( Doom1BFG_Trophies::SCOUT_FIND_ANY_SECRET ); + break; + } + case GAME_SKU_DOOM2_BFG: { + #ifdef __MONOLITH__ + //gameLocal->UnlockAchievement( Doom2BFG_Trophies::IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET ); + idAchievementManager::LocalUser_CompleteAchievement(ACHIEVEMENT_DOOM2_IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET ); + #endif + break; + } + case GAME_SKU_DCC: { + // Not on PC. + //gameLocal->UnlockAchievement( DOOM_ACHIEVEMENT_FIND_SECRET ); + break; + } + default: { + // No unlocks for other SKUs. + break; + } } } } - } - - break; - case 11: - // EXIT SUPER DAMAGE! (for E1M8 finale) - player->cheats &= ~CF_GODMODE; + break; - if (!(::g->leveltime&0x1f)) - P_DamageMobj (player->mo, NULL, NULL, 20); + case 11: + // EXIT SUPER DAMAGE! (for E1M8 finale) + player->cheats &= ~CF_GODMODE; - if (player->health <= 10) - G_ExitLevel(); - break; + if (!(::g->leveltime&0x1f)) + P_DamageMobj (player->mo, NULL, NULL, 20); - default: - I_Error ("P_PlayerInSpecialSector: " - "unknown special %i", - sector->special); - break; - }; + if (player->health <= 10) + G_ExitLevel(); + break; + default: + I_Error ("P_PlayerInSpecialSector: " + "unknown special %i", + sector->special); + break; + }; + } else if(sector->special & DEATH_MASK) { + switch(sector->special & DAMAGE_MASK >> DAMAGE_SHIFT) { + case 0: { + if (!player->powers[pw_invulnerability] && !player->powers[pw_ironfeet]) + P_DamageMobj(player->mo, NULL, NULL, 10000); + break; + } + case 1: + P_DamageMobj(player->mo, NULL, NULL, 10000); + break; + case 2: + for (int i = 0; i < ::g->doomcom.numnodes; i++) { + if (::g->playeringame[i]) { + P_DamageMobj(::g->players[i].mo, NULL, NULL, 10000); + } + } + G_ExitLevel(); + break; + case 3: + for (int i = 0; i < ::g->doomcom.numnodes; i++) { + if (::g->playeringame[i]) { + P_DamageMobj(::g->players[i].mo, NULL, NULL, 10000); + } + } + G_SecretExitLevel(); + break; + } + } } @@ -2293,6 +2321,27 @@ static void P_SpawnScrollers(void) case 85: // jff 1/30/98 2-way scroll Add_Scroller(sc_side, -FRACUNIT, 0, -1, ::g->lines[i].sidenum[0], accel); break; + case 1024: // special 255 with tag control + + case 1025: + case 1026: + if (l->tag == 0) + I_Error("Line %d is missing a tag!", i); + + if (special > 1024) + control = ::g->sides[*l->sidenum].sector->counter; //GK: it's the same as iSectorID + + if (special == 1026) + accel = 1; + + s = ::g->lines[i].sidenum[0]; + dx = -::g->sides[s].textureoffset; + dy = ::g->sides[s].rowoffset; + for (s = -1; (s = P_FindLineFromLineTag(l, s)) >= 0;) + if (s != i) + Add_Scroller(sc_side, dx, dy, control, ::g->lines[s].sidenum[0], accel); + + break; } } } diff --git a/doomclassic/doom/p_spec.h b/doomclassic/doom/p_spec.h index 313a7a75..bbc6bafc 100644 --- a/doomclassic/doom/p_spec.h +++ b/doomclassic/doom/p_spec.h @@ -36,6 +36,10 @@ If you have questions concerning this license or the applicable additional terms extern qboolean levelTimer; extern int levelTimeCount; +//GK: MBF21 support +#define DEATH_MASK 0x1000 +#define DAMAGE_MASK 0x60 +#define DAMAGE_SHIFT 5 // Define values for map objects #define MO_TELEPORTMAN 14