diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index bc1f43e57..513325225 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -1516,6 +1516,50 @@ udmf } } + polyobject + { + title = "PolyObject"; + + 20 + { + title = "First Line"; + prefix = "(20)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Parent ID"; + type = 14; + } + arg2 + { + title = "Translucency"; + } + arg3 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Don't render insides"; + 2 = "Intangible"; + 4 = "Stopped by pushables"; + 8 = "Don't render planes"; + 16 = "Trigger linedef executor on touch"; + 32 = "Crush player"; + } + } + arg4 + { + title = "Trigger linedef tag"; + type = 15; + } + } + } + fof { title = "FOF"; diff --git a/src/dehacked.c b/src/dehacked.c index a6c73e0b4..0cbb638c8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8754,7 +8754,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_ANGLEMAN", "MT_POLYANCHOR", "MT_POLYSPAWN", - "MT_POLYSPAWNCRUSH", // Skybox objects "MT_SKYBOX", diff --git a/src/info.c b/src/info.c index d443e035d..f65d336aa 100644 --- a/src/info.c +++ b/src/info.c @@ -3361,7 +3361,7 @@ state_t states[NUMSTATES] = // CTF Sign {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG - + // Finish flag {SPR_FNSF, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_FINISHFLAG @@ -18009,7 +18009,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - + { // MT_FINISHFLAG -1, // doomednum S_FINISHFLAG, // spawnstate @@ -19854,7 +19854,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - + { // MT_FLINGNIGHTSSTAR -1, // doomednum S_NIGHTSSTAR, // spawnstate @@ -20857,33 +20857,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_POLYSPAWNCRUSH - 762, // doomednum - S_INVISIBLE, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 0, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 3, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height - 0, // display offset - 1000, // mass - 8, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags - S_NULL // raisestate - }, - { // MT_SKYBOX 780, // doomednum S_INVISIBLE, // spawnstate diff --git a/src/info.h b/src/info.h index 79af9bbbb..271a6f3f6 100644 --- a/src/info.h +++ b/src/info.h @@ -3498,7 +3498,7 @@ typedef enum state // Got Flag Sign S_GOTFLAG, - + // Finish flag S_FINISHFLAG, @@ -4765,7 +4765,6 @@ typedef enum mobj_type MT_ANGLEMAN, MT_POLYANCHOR, MT_POLYSPAWN, - MT_POLYSPAWNCRUSH, // Skybox objects MT_SKYBOX, diff --git a/src/p_mobj.c b/src/p_mobj.c index a22e655e0..b39f350be 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2941,10 +2941,8 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->z == polysec->ceilingheight) { - // We're landing on a PO, so check for - // a linedef executor. - // Trigger tags are 32000 + the PO's ID number. - P_LinedefExecute((INT16)(32000 + po->id), mo, NULL); + // We're landing on a PO, so check for a linedef executor. + P_LinedefExecute(po->triggertag, mo, NULL); } po = (polyobj_t *)(po->link.next); diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 539ddb741..d745a5749 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -204,44 +204,41 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) return true; } -// Finds the 'polyobject settings' linedef for a polyobject -// the polyobject's id should be set as its tag -static void Polyobj_GetInfo(polyobj_t *po) +// Gets the polyobject's settings from its first line +// args[0] of the first line should be the polyobject's id +static void Polyobj_GetInfo(polyobj_t *po, line_t *line) { - INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, po->id, -1); - - po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; - - if (i == -1) - return; // no extra settings to apply, let's leave it - - po->parent = lines[i].frontsector->special; + po->parent = line->args[1]; if (po->parent == po->id) // do not allow a self-reference po->parent = -1; - po->translucency = (lines[i].flags & ML_DONTPEGTOP) - ? (sides[lines[i].sidenum[0]].textureoffset>>FRACBITS) - : ((lines[i].frontsector->floorheight>>FRACBITS) / 100); + po->translucency = max(min(line->args[2], NUMTRANSMAPS), 0); - po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); + po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES|POF_RENDERPLANES; - if (lines[i].flags & ML_EFFECT1) + if (line->args[3] & TMPF_NOINSIDES) po->flags |= POF_ONESIDE; - if (lines[i].flags & ML_EFFECT2) + if (line->args[3] & TMPF_INTANGIBLE) po->flags &= ~POF_SOLID; - if (lines[i].flags & ML_EFFECT3) + if (line->args[3] & TMPF_PUSHABLESTOP) po->flags |= POF_PUSHABLESTOP; - if (lines[i].flags & ML_EFFECT4) - po->flags |= POF_RENDERPLANES; + if (line->args[3] & TMPF_INVISIBLEPLANES) + po->flags &= ~POF_RENDERPLANES; - /*if (lines[i].flags & ML_EFFECT5) + /*if (line->args[3] & TMPF_DONTCLIPPLANES) po->flags &= ~POF_CLIPPLANES;*/ - if (lines[i].flags & ML_NOCLIMB) // Has a linedef executor + if (line->args[3] & TMPF_EXECUTOR) // Has a linedef executor po->flags |= POF_LDEXEC; + + // TODO: support customized damage somehow? + if (line->args[3] & TMPF_CRUSH) + po->damage = 3; + + po->triggertag = line->args[4]; } // Reallocating array maintenance @@ -480,10 +477,6 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) po->id = id; - // TODO: support customized damage somehow? - if (spawnSpot->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM) - po->damage = 3; - // set to default thrust; may be modified by attached thinkers // TODO: support customized thrust? po->thrust = FRACUNIT; @@ -505,10 +498,10 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (seg->linedef->special != POLYOBJ_START_LINE) continue; - if (seg->linedef->tag != po->id) + if (seg->linedef->args[0] != po->id) continue; - Polyobj_GetInfo(po); // apply extra settings if they exist! + Polyobj_GetInfo(po, seg->linedef); // apply extra settings if they exist! // save original flags and translucency to reference later for netgames! po->spawnflags = po->flags; @@ -1313,8 +1306,7 @@ void Polyobj_InitLevel(void) mo = (mobj_t *)th; - if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM || - mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM) + if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM) { ++numPolyObjects; diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 68aff4bf1..b59e9c235 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -26,10 +26,8 @@ #define POLYOBJ_ANCHOR_DOOMEDNUM 760 #define POLYOBJ_SPAWN_DOOMEDNUM 761 -#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE #define POLYOBJ_START_LINE 20 -#define POLYINFO_SPECIALNUM 22 typedef enum { @@ -51,6 +49,17 @@ typedef enum POF_NOSPECIALS = 0x1000, ///< Don't apply sector specials. } polyobjflags_e; +typedef enum +{ + TMPF_NOINSIDES = 1, + TMPF_INTANGIBLE = 1<<1, + TMPF_PUSHABLESTOP = 1<<2, + TMPF_INVISIBLEPLANES = 1<<3, + TMPF_EXECUTOR = 1<<4, + TMPF_CRUSH = 1<<5, + //TMPF_DONTCLIPPLANES = 1<<6, +} textmappolyobjectflags_t; + // // Polyobject Structure // @@ -96,6 +105,7 @@ typedef struct polyobj_s UINT8 isBad; // a bad polyobject: should not be rendered/manipulated INT32 translucency; // index to translucency tables + INT16 triggertag; // Tag of linedef executor to trigger on touch struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later diff --git a/src/p_setup.c b/src/p_setup.c index b39f4a516..4ff9e6117 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2797,6 +2797,30 @@ static void P_LinkMapData(void) } } +/** Hashes the sector tags across the sectors and linedefs. + * + * \sa P_FindSectorFromTag, P_ChangeSectorTag + * \author Lee Killough + */ +static inline void P_InitTagLists(void) +{ + register size_t i; + + for (i = numsectors - 1; i != (size_t)-1; i--) + { + size_t j = (unsigned)sectors[i].tag % numsectors; + sectors[i].nexttag = sectors[j].firsttag; + sectors[j].firsttag = (INT32)i; + } + + for (i = numlines - 1; i != (size_t)-1; i--) + { + size_t j = (unsigned)lines[i].tag % numlines; + lines[i].nexttag = lines[j].firsttag; + lines[j].firsttag = (INT32)i; + } +} + //For maps in binary format, converts setup of specials to UDMF format. static void P_ConvertBinaryMap(void) { @@ -2806,6 +2830,45 @@ static void P_ConvertBinaryMap(void) { switch (lines[i].special) { + case 20: //PolyObject first line + { + INT32 paramline = P_FindSpecialLineFromTag(22, lines[i].tag, -1); + + //PolyObject ID + lines[i].args[0] = lines[i].tag; + + //Default: Invisible planes + lines[i].args[3] |= TMPF_INVISIBLEPLANES; + + //Linedef executor tag + lines[i].args[4] = 32000 + lines[i].args[0]; + + if (paramline == -1) + break; // no extra settings to apply, let's leave it + + //Parent ID + lines[i].args[1] = lines[paramline].frontsector->special; + //Translucency + lines[i].args[2] = (lines[paramline].flags & ML_DONTPEGTOP) + ? (sides[lines[paramline].sidenum[0]].textureoffset >> FRACBITS) + : ((lines[paramline].frontsector->floorheight >> FRACBITS) / 100); + + //Flags + if (lines[paramline].flags & ML_EFFECT1) + lines[i].args[3] |= TMPF_NOINSIDES; + if (lines[paramline].flags & ML_EFFECT2) + lines[i].args[3] |= TMPF_INTANGIBLE; + if (lines[paramline].flags & ML_EFFECT3) + lines[i].args[3] |= TMPF_PUSHABLESTOP; + if (lines[paramline].flags & ML_EFFECT4) + lines[i].args[3] &= ~TMPF_INVISIBLEPLANES; + /*if (lines[paramline].flags & ML_EFFECT5) + lines[i].args[3] |= TMPF_DONTCLIPPLANES;*/ + if (lines[paramline].flags & ML_NOCLIMB) + lines[i].args[3] |= TMPF_EXECUTOR; + + break; + } case 443: //Call Lua function if (lines[i].text) { @@ -2956,9 +3019,17 @@ static void P_ConvertBinaryMap(void) case 750: case 760: case 761: - case 762: mapthings[i].tag = mapthings[i].angle; break; + case 762: + { + INT32 firstline = P_FindSpecialLineFromTag(20, mapthings[i].angle, -1); + if (firstline != -1) + lines[firstline].args[3] |= TMPF_CRUSH; + mapthings[i].tag = mapthings[i].angle; + mapthings[i].type = 761; + break; + } case 780: mapthings[i].tag = mapthings[i].extrainfo; break; @@ -3043,6 +3114,8 @@ static boolean P_LoadMapFromFile(void) P_LinkMapData(); + P_InitTagLists(); // Create xref tables for tags + if (!udmf) P_ConvertBinaryMap(); @@ -3905,8 +3978,7 @@ boolean P_LoadLevel(boolean fromnetsave) if (!P_LoadMapFromFile()) return false; - // init gravity, tag lists, - // anything that P_SpawnSlopes/P_LoadThings needs to know + // init anything that P_SpawnSlopes/P_LoadThings needs to know P_InitSpecials(); P_SpawnSlopes(fromnetsave); diff --git a/src/p_spec.c b/src/p_spec.c index dae3971fb..f1d2c13b5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1485,30 +1485,6 @@ void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean e } } -/** Hashes the sector tags across the sectors and linedefs. - * - * \sa P_FindSectorFromTag, P_ChangeSectorTag - * \author Lee Killough - */ -static inline void P_InitTagLists(void) -{ - register size_t i; - - for (i = numsectors - 1; i != (size_t)-1; i--) - { - size_t j = (unsigned)sectors[i].tag % numsectors; - sectors[i].nexttag = sectors[j].firsttag; - sectors[j].firsttag = (INT32)i; - } - - for (i = numlines - 1; i != (size_t)-1; i--) - { - size_t j = (unsigned)lines[i].tag % numlines; - lines[i].nexttag = lines[j].firsttag; - lines[j].firsttag = (INT32)i; - } -} - /** Finds minimum light from an adjacent sector. * * \param sector Sector to start in. @@ -6264,7 +6240,7 @@ static void P_RunLevelLoadExecutors(void) * by P_SpawnSlopes or P_LoadThings. This was split off from * P_SpawnSpecials, in case you couldn't tell. * - * \sa P_SpawnSpecials, P_InitTagLists + * \sa P_SpawnSpecials * \author Monster Iestyn */ void P_InitSpecials(void) @@ -6295,8 +6271,6 @@ void P_InitSpecials(void) // Set globalweather globalweather = mapheaderinfo[gamemap-1]->weather; - - P_InitTagLists(); // Create xref tables for tags } static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs)