From b3be8d1f44bb09bff9d3a36235511393b2ab4f47 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 31 Dec 2021 08:53:00 +0100 Subject: [PATCH] Implement sector damagetype field --- extras/conf/udb/Includes/SRB222_common.cfg | 3 ++ src/deh_lua.c | 26 +++++++--- src/deh_tables.c | 32 +++++++++--- src/deh_tables.h | 7 +-- src/lua_maplib.c | 8 +++ src/p_map.c | 2 +- src/p_mobj.c | 14 ++--- src/p_saveg.c | 33 +++++++++--- src/p_setup.c | 53 ++++++++++++++++++- src/p_spec.c | 60 ++++++++++++---------- src/p_user.c | 4 +- src/r_defs.h | 15 ++++++ 12 files changed, 194 insertions(+), 63 deletions(-) diff --git a/extras/conf/udb/Includes/SRB222_common.cfg b/extras/conf/udb/Includes/SRB222_common.cfg index d5cf5a405..d15fbcdcb 100644 --- a/extras/conf/udb/Includes/SRB222_common.cfg +++ b/extras/conf/udb/Includes/SRB222_common.cfg @@ -258,6 +258,9 @@ mapformat_udmf include("SRB222_sectors.cfg", "gen_sectortypes"); } + damagetypes = "Generic Water Fire Electric Spike DeathPitTilt DeathPitNoTilt Instakill SpecialStage"; + + // LINEDEF FLAGS linedefflags { diff --git a/src/deh_lua.c b/src/deh_lua.c index 56d2ec1e9..e313c5888 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -330,18 +330,18 @@ static inline int lib_getenum(lua_State *L) } else if (fastncmp("ML_", word, 3)) { p = word+3; - for (i = 0; i < 16; i++) - if (ML_LIST[i] && fastcmp(p, ML_LIST[i])) { + for (i = 0; ML_LIST[i]; i++) + if (fastcmp(p, ML_LIST[i])) { lua_pushinteger(L, ((lua_Integer)1<specialflags); return 1; + case sector_damagetype: // damagetype + lua_pushinteger(L, (UINT8)sector->damagetype); + return 1; case sector_friction: // friction lua_pushinteger(L, sector->friction); return 1; @@ -763,6 +768,9 @@ static int sector_set(lua_State *L) case sector_specialflags: sector->specialflags = luaL_checkinteger(L, 3); break; + case sector_damagetype: + sector->damagetype = (UINT8)luaL_checkinteger(L, 3); + break; case sector_gravity: sector->gravity = luaL_checkfixed(L, 3); break; diff --git a/src/p_map.c b/src/p_map.c index beae1a8ea..c3271c10e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3594,7 +3594,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) if (!(rover->flags & FF_SWIMMABLE)) continue; - if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 3) + if (rover->master->frontsector->damagetype != SD_FIRE) continue; if (rover->master->flags & ML_BLOCKMONSTERS) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4b31307ef..004575a79 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2325,8 +2325,8 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) && ((mo->subsector->sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & MSF_FLIPSPECIAL_FLOOR)) || (mo->z + mo->height >= mo->subsector->sector->ceilingheight && ((mo->subsector->sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & MSF_FLIPSPECIAL_CEILING))) - && (GETSECSPECIAL(mo->subsector->sector->special, 1) == 6 - || GETSECSPECIAL(mo->subsector->sector->special, 1) == 7)) + && (mo->subsector->sector->damagetype == SD_DEATHPITTILT + || mo->subsector->sector->damagetype == SD_DEATHPITNOTILT)) return true; return false; @@ -2334,7 +2334,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) boolean P_CheckSolidLava(ffloor_t *rover) { - if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3 + if (rover->flags & FF_SWIMMABLE && rover->master->frontsector->damagetype == SD_FIRE && !(rover->master->flags & ML_BLOCKMONSTERS)) return true; @@ -3305,7 +3305,7 @@ void P_MobjCheckWater(mobj_t *mobj) if (mobj->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) { - if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 3) + if (rover->master->frontsector->damagetype == SD_FIRE) mobj->eflags |= MFE_TOUCHLAVA; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) @@ -4097,7 +4097,7 @@ static void P_KillRingsInLava(mobj_t *mo) if (!(rover->flags & FF_EXISTS)) continue; // fof must be real if (!(rover->flags & FF_SWIMMABLE // fof must be water - && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3)) // fof must be lava water + && rover->master->frontsector->damagetype == SD_FIRE)) // fof must be lava water continue; // find heights of FOF @@ -10985,8 +10985,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype if (mobj->floorz != starting_floorz) mobj->precipflags |= PCF_FOF; - else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7 - || GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6 + else if (mobj->subsector->sector->damagetype == SD_DEATHPITNOTILT + || mobj->subsector->sector->damagetype == SD_DEATHPITTILT || mobj->subsector->sector->floorpic == skyflatnum) mobj->precipflags |= PCF_PIT; diff --git a/src/p_saveg.c b/src/p_saveg.c index 1923fa576..1baa34582 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -854,7 +854,11 @@ static void P_NetUnArchiveWaypoints(void) #define SD_CEILLIGHT 0x10 #define SD_FLAG 0x20 #define SD_SPECIALFLAG 0x40 -#define SD_GRAVITY 0x80 +#define SD_DIFF4 0x80 + +//diff4 flags +#define SD_DAMAGETYPE 0x01 +#define SD_GRAVITY 0x02 #define LD_FLAG 0x01 #define LD_SPECIAL 0x02 @@ -993,11 +997,11 @@ static void ArchiveSectors(void) size_t i, j; const sector_t *ss = sectors; const sector_t *spawnss = spawnsectors; - UINT8 diff, diff2, diff3; + UINT8 diff, diff2, diff3, diff4; for (i = 0; i < numsectors; i++, ss++, spawnss++) { - diff = diff2 = diff3 = 0; + diff = diff2 = diff3 = diff4 = 0; if (ss->floorheight != spawnss->floorheight) diff |= SD_FLOORHT; if (ss->ceilingheight != spawnss->ceilingheight) @@ -1044,12 +1048,17 @@ static void ArchiveSectors(void) diff3 |= SD_FLAG; if (ss->specialflags != spawnss->specialflags) diff3 |= SD_SPECIALFLAG; + if (ss->damagetype != spawnss->damagetype) + diff4 |= SD_DAMAGETYPE; if (ss->gravity != spawnss->gravity) - diff3 |= SD_GRAVITY; + diff4 |= SD_GRAVITY; if (ss->ffloors && CheckFFloorDiff(ss)) diff |= SD_FFLOORS; + if (diff4) + diff3 |= SD_DIFF4; + if (diff3) diff2 |= SD_DIFF3; @@ -1064,6 +1073,8 @@ static void ArchiveSectors(void) WRITEUINT8(save_p, diff2); if (diff2 & SD_DIFF3) WRITEUINT8(save_p, diff3); + if (diff3 & SD_DIFF4) + WRITEUINT8(save_p, diff4); if (diff & SD_FLOORHT) WRITEFIXED(save_p, ss->floorheight); if (diff & SD_CEILHT) @@ -1114,7 +1125,9 @@ static void ArchiveSectors(void) WRITEUINT32(save_p, ss->flags); if (diff3 & SD_SPECIALFLAG) WRITEUINT32(save_p, ss->specialflags); - if (diff3 & SD_GRAVITY) + if (diff4 & SD_DAMAGETYPE) + WRITEUINT8(save_p, ss->damagetype); + if (diff4 & SD_GRAVITY) WRITEFIXED(save_p, ss->gravity); if (diff & SD_FFLOORS) ArchiveFFloors(ss); @@ -1127,7 +1140,7 @@ static void ArchiveSectors(void) static void UnArchiveSectors(void) { UINT16 i, j; - UINT8 diff, diff2, diff3; + UINT8 diff, diff2, diff3, diff4; for (;;) { i = READUINT16(save_p); @@ -1147,6 +1160,10 @@ static void UnArchiveSectors(void) diff3 = READUINT8(save_p); else diff3 = 0; + if (diff3 & SD_DIFF4) + diff4 = READUINT8(save_p); + else + diff4 = 0; if (diff & SD_FLOORHT) sectors[i].floorheight = READFIXED(save_p); @@ -1224,7 +1241,9 @@ static void UnArchiveSectors(void) } if (diff3 & SD_SPECIALFLAG) sectors[i].specialflags = READUINT32(save_p); - if (diff3 & SD_GRAVITY) + if (diff4 & SD_DAMAGETYPE) + sectors[i].damagetype = READUINT8(save_p); + if (diff4 & SD_GRAVITY) sectors[i].gravity = READFIXED(save_p); if (diff & SD_FFLOORS) diff --git a/src/p_setup.c b/src/p_setup.c index 17fd5bb63..4efbc4e4b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1049,6 +1049,8 @@ static void P_LoadSectors(UINT8 *data) ss->gravity = FRACUNIT; ss->flags = MSF_FLIPSPECIAL_FLOOR; + ss->specialflags = 0; + ss->damagetype = SD_NONE; P_InitializeSector(ss); } @@ -1721,6 +1723,27 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) sectors[i].friction = atol(val); else if (fastcmp(param, "gravity")) sectors[i].gravity = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "damagetype")) + { + if (fastcmp(val, "Generic")) + sectors[i].damagetype = SD_GENERIC; + if (fastcmp(val, "Water")) + sectors[i].damagetype = SD_WATER; + if (fastcmp(val, "Fire")) + sectors[i].damagetype = SD_FIRE; + if (fastcmp(val, "Electric")) + sectors[i].damagetype = SD_ELECTRIC; + if (fastcmp(val, "Spike")) + sectors[i].damagetype = SD_SPIKE; + if (fastcmp(val, "DeathPitTilt")) + sectors[i].damagetype = SD_DEATHPITTILT; + if (fastcmp(val, "DeathPitNoTilt")) + sectors[i].damagetype = SD_DEATHPITNOTILT; + if (fastcmp(val, "Instakill")) + sectors[i].damagetype = SD_INSTAKILL; + if (fastcmp(val, "SpecialStage")) + sectors[i].damagetype = SD_SPECIALSTAGE; + } } static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val) @@ -2000,6 +2023,8 @@ static void P_LoadTextmap(void) sc->gravity = FRACUNIT; sc->flags = MSF_FLIPSPECIAL_FLOOR; + sc->specialflags = 0; + sc->damagetype = SD_NONE; textmap_colormap.used = false; textmap_colormap.lightcolor = 0; @@ -5059,9 +5084,35 @@ static void P_ConvertBinaryMap(void) for (i = 0; i < numsectors; i++) { - switch(GETSECSPECIAL(sectors[i].special, 1)) { + case 1: //Damage + sectors[i].damagetype = SD_GENERIC; + break; + case 2: //Damage (Water) + sectors[i].damagetype = SD_WATER; + break; + case 3: //Damage (Fire) + sectors[i].damagetype = SD_FIRE; + break; + case 4: //Damage (Electric) + sectors[i].damagetype = SD_ELECTRIC; + break; + case 5: //Spikes + sectors[i].damagetype = SD_SPIKE; + break; + case 6: //Death pit (camera tilt) + sectors[i].damagetype = SD_DEATHPITTILT; + break; + case 7: //Death pit (no camera tilt) + sectors[i].damagetype = SD_DEATHPITNOTILT; + break; + case 8: //Instakill + sectors[i].damagetype = SD_INSTAKILL; + break; + case 11: //Special stage damage + sectors[i].damagetype = SD_SPECIALSTAGE; + break; case 12: //Space countdown sectors[i].specialflags |= SSF_OUTERSPACE; break; diff --git a/src/p_spec.c b/src/p_spec.c index 2e4821972..95c3a5118 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4917,7 +4917,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers mtag_t sectag = Tag_FGet(§or->tags); boolean isTouching; - if (!sector->special && sector->specialflags == 0) + if (!sector->special && sector->specialflags == 0 && sector->damagetype == SD_NONE) return; // Ignore spectators @@ -4995,33 +4995,30 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers if ((sector->specialflags & SSF_ROPEHANG) && isTouching) P_ProcessRopeHang(player, sectag); - section1 = GETSECSPECIAL(sector->special, 1); - section2 = GETSECSPECIAL(sector->special, 2); - - switch (section1) + switch (sector->damagetype) { - case 1: // Damage (Generic) + case SD_GENERIC: if (isTouching) P_DamageMobj(player->mo, NULL, NULL, 1, 0); break; - case 2: // Damage (Water) + case SD_WATER: if (isTouching && (player->powers[pw_underwater] || player->powers[pw_carry] == CR_NIGHTSMODE)) P_DamageMobj(player->mo, NULL, NULL, 1, DMG_WATER); break; - case 3: // Damage (Fire) + case SD_FIRE: if (isTouching) P_DamageMobj(player->mo, NULL, NULL, 1, DMG_FIRE); break; - case 4: // Damage (Electrical) + case SD_ELECTRIC: if (isTouching) P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC); break; - case 5: // Spikes + case SD_SPIKE: if (isTouching) P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPIKE); break; - case 6: // Death Pit (Camera Mod) - case 7: // Death Pit (No Camera Mod) + case SD_DEATHPITTILT: + case SD_DEATHPITNOTILT: if (!isTouching) break; if (player->quittime) @@ -5029,12 +5026,33 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers else P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT); break; - case 8: // Instant Kill + case SD_INSTAKILL: if (player->quittime) G_MovePlayerToSpawnOrStarpost(player - players); else P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); break; + case SD_SPECIALSTAGE: + if (!isTouching) + break; + + if (player->exiting || player->bot) // Don't do anything for bots or players who have just finished + break; + + if (!(player->powers[pw_shield] || player->spheres > 0)) // Don't do anything if no shield or spheres anyway + break; + + P_SpecialStageDamage(player, NULL, NULL); + break; + default: + break; + } + + section1 = GETSECSPECIAL(sector->special, 1); + section2 = GETSECSPECIAL(sector->special, 2); + + switch (section1) + { case 9: // Ring Drainer (Floor Touch) if (!isTouching) break; @@ -5048,18 +5066,6 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers S_StartSound(player->mo, sfx_antiri); } break; - case 11: // Special Stage Damage - if (!isTouching) - break; - - if (player->exiting || player->bot) // Don't do anything for bots or players who have just finished - break; - - if (!(player->powers[pw_shield] || player->spheres > 0)) // Don't do anything if no shield or spheres anyway - break; - - P_SpecialStageDamage(player, NULL, NULL); - break; } switch (section2) @@ -5100,7 +5106,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!rover->master->frontsector->special && rover->master->frontsector->specialflags == 0) + if (!rover->master->frontsector->special && rover->master->frontsector->specialflags == 0 && rover->master->frontsector->damagetype == SD_NONE) continue; if (!(rover->flags & FF_EXISTS)) @@ -5134,7 +5140,7 @@ static void P_PlayerOnSpecialPolyobj(player_t *player) polysec = po->lines[0]->backsector; - if (!polysec->special && polysec->specialflags == 0) + if (!polysec->special && polysec->specialflags == 0 && polysec->damagetype == SD_NONE) continue; touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, player->mo); diff --git a/src/p_user.c b/src/p_user.c index 1006e21ed..7360d2ef9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10258,7 +10258,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall thiscam->momx = FixedMul(x - thiscam->x, camspeed); thiscam->momy = FixedMul(y - thiscam->y, camspeed); - if (GETSECSPECIAL(thiscam->subsector->sector->special, 1) == 6 + if (thiscam->subsector->sector->damagetype == SD_DEATHPITTILT && thiscam->z < thiscam->subsector->sector->floorheight + 256*FRACUNIT && FixedMul(z - thiscam->z, camspeed) < 0) { @@ -12230,7 +12230,7 @@ static boolean P_MobjAboveLava(mobj_t *mobj) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || GETSECSPECIAL(rover->master->frontsector->special, 1) != 3) + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->master->frontsector->damagetype != SD_FIRE) continue; if (mobj->eflags & MFE_VERTICALFLIP) diff --git a/src/r_defs.h b/src/r_defs.h index 2b1cbfa58..4180af800 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -312,6 +312,20 @@ typedef enum SSF_ROPEHANG = 1<<18, } sectorspecialflags_t; +typedef enum +{ + SD_NONE = 0, + SD_GENERIC = 1, + SD_WATER = 2, + SD_FIRE = 3, + SD_ELECTRIC = 4, + SD_SPIKE = 5, + SD_DEATHPITTILT = 6, + SD_DEATHPITNOTILT = 7, + SD_INSTAKILL = 8, + SD_SPECIALSTAGE = 9, +} sectordamage_t; + typedef enum { CRUMBLE_NONE, // No crumble thinker @@ -394,6 +408,7 @@ typedef struct sector_s fixed_t *gravityptr; // For binary format: Read gravity from floor height of master sector sectorflags_t flags; sectorspecialflags_t specialflags; + UINT8 damagetype; INT32 friction;