Implement sector damagetype field

This commit is contained in:
MascaraSnake 2021-12-31 08:53:00 +01:00
parent feaa4f1273
commit b3be8d1f44
12 changed files with 194 additions and 63 deletions

View file

@ -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
{

View file

@ -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<<i));
return 1;
}
if (mathlib) return luaL_error(L, "linedef flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("MSF_", word, 3)) {
else if (fastncmp("MSF_", word, 4)) {
p = word + 4;
for (i = 0; i < 7; i++)
if (MSF_LIST[i] && fastcmp(p, MSF_LIST[i])) {
for (i = 0; MSF_LIST[i]; i++)
if (fastcmp(p, MSF_LIST[i])) {
lua_pushinteger(L, ((lua_Integer)1 << i));
return 1;
}
@ -353,16 +353,26 @@ static inline int lib_getenum(lua_State *L)
if (mathlib) return luaL_error(L, "sector flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("SSF_", word, 3)) {
else if (fastncmp("SSF_", word, 4)) {
p = word + 4;
for (i = 0; i < 19; i++)
if (SSF_LIST[i] && fastcmp(p, SSF_LIST[i])) {
for (i = 0; SSF_LIST[i]; i++)
if (fastcmp(p, SSF_LIST[i])) {
lua_pushinteger(L, ((lua_Integer)1 << i));
return 1;
}
if (mathlib) return luaL_error(L, "sector special flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("SD_", word, 3)) {
p = word + 3;
for (i = 0; SD_LIST[i]; i++)
if (fastcmp(p, SD_LIST[i])) {
lua_pushinteger(L, i);
return 1;
}
if (mathlib) return luaL_error(L, "sector damagetype '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("S_",word,2)) {
p = word+2;
for (i = 0; i < NUMSTATEFREESLOTS; i++) {

View file

@ -4452,7 +4452,7 @@ const char *const GAMETYPERULE_LIST[] = {
};
// Linedef flags
const char *const ML_LIST[16] = {
const char *const ML_LIST[] = {
"IMPASSIBLE",
"BLOCKMONSTERS",
"TWOSIDED",
@ -4464,15 +4464,16 @@ const char *const ML_LIST[16] = {
"EFFECT3",
"EFFECT4",
"EFFECT5",
"NOSONIC",
"NOTAILS",
"NOKNUX",
"NETONLY",
"NONET",
"EFFECT6",
"BOUNCY",
"TFERLINE"
"TFERLINE",
NULL
};
// Sector flags
const char *const MSF_LIST[7] = {
const char *const MSF_LIST[] = {
"FLIPSPECIAL_FLOOR",
"FLIPSPECIAL_CEILING",
"TRIGGERSPECIAL_TOUCH",
@ -4480,10 +4481,11 @@ const char *const MSF_LIST[7] = {
"GRAVITYFLIP",
"HEATWAVE",
"NOCLIPCAMERA",
NULL
};
// Sector special flags
const char* const SSF_LIST[19] = {
const char *const SSF_LIST[] = {
"OUTERSPACE",
"DOUBLESTEPUP",
"WINDCURRENT",
@ -4502,6 +4504,22 @@ const char* const SSF_LIST[19] = {
"ZOOMTUBEEND",
"FINISHLINE",
"ROPEHANG",
NULL
};
// Sector damagetypes
const char *const SD_LIST[] = {
"NONE",
"GENERIC",
"WATER",
"FIRE",
"ELECTRIC",
"SPIKE",
"DEATHPITTILT",
"DEATHPITNOTILT",
"INSTAKILL",
"SPECIALSTAGE",
NULL
};
const char *COLOR_ENUMS[] = {

View file

@ -64,9 +64,10 @@ extern const char *const MOBJEFLAG_LIST[];
extern const char *const MAPTHINGFLAG_LIST[4];
extern const char *const PLAYERFLAG_LIST[];
extern const char *const GAMETYPERULE_LIST[];
extern const char *const ML_LIST[16]; // Linedef flags
extern const char* const MSF_LIST[7]; // Sector flags
extern const char* const SSF_LIST[19]; // Sector special flags
extern const char *const ML_LIST[]; // Linedef flags
extern const char *const MSF_LIST[]; // Sector flags
extern const char *const SSF_LIST[]; // Sector special flags
extern const char *const SD_LIST[]; // Sector damagetype
extern const char *COLOR_ENUMS[];
extern const char *const POWERS_LIST[];
extern const char *const HUDITEMS_LIST[];

View file

@ -51,6 +51,7 @@ enum sector_e {
sector_cslope,
sector_flags,
sector_specialflags,
sector_damagetype,
sector_friction,
sector_gravity,
};
@ -78,6 +79,7 @@ static const char *const sector_opt[] = {
"c_slope",
"flags",
"specialflags",
"damagetype",
"friction",
"gravity",
NULL};
@ -663,6 +665,9 @@ static int sector_get(lua_State *L)
case sector_specialflags: // specialflags
lua_pushinteger(L, sector->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;

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -4917,7 +4917,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
mtag_t sectag = Tag_FGet(&sector->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);

View file

@ -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)

View file

@ -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;