diff --git a/extras/conf/Includes/SRB222_linedefs.cfg b/extras/conf/Includes/SRB222_linedefs.cfg index fdf191850..9f6613620 100644 --- a/extras/conf/Includes/SRB222_linedefs.cfg +++ b/extras/conf/Includes/SRB222_linedefs.cfg @@ -2483,4 +2483,119 @@ udmf prefix = "(0)"; } } + + slope + { + title = "Slope"; + + 700 + { + title = "Create Sector-Based Slope"; + prefix = "(700)"; + id = "plane_align"; + slope = "regular"; + arg0 + { + title = "Floor"; + type = 11; + enum = "frontback"; + } + arg1 + { + title = "Ceiling"; + type = 11; + enum = "frontback"; + } + arg2 + { + title = "Flags"; + type = 12; + enum + { + 1 = "No physics"; + 2 = "Dynamic"; + } + } + } + + 704 + { + title = "Create Vertex-Based Slope"; + prefix = "(704)"; + slope = "vertex"; + arg0 + { + title = "Plane"; + type = 11; + enum + { + 0 = "Front floor"; + 1 = "Front ceiling"; + 2 = "Back floor"; + 3 = "Back ceiling"; + } + } + arg1 + { + title = "Vertex 1 tag"; + } + arg2 + { + title = "Vertex 2 tag"; + } + arg3 + { + title = "Vertex 3 tag"; + } + arg4 + { + title = "Flags"; + type = 12; + enum + { + 1 = "No physics"; + 2 = "Dynamic"; + } + } + } + + 720 + { + title = "Copy Slope"; + prefix = "(720)"; + slope = "copy"; + arg0 + { + title = "Front floor tag"; + type = 13; + } + arg1 + { + title = "Front ceiling tag"; + type = 13; + } + arg2 + { + title = "Back floor tag"; + type = 13; + } + arg3 + { + title = "Back ceiling tag"; + type = 13; + } + arg4 + { + title = "Share slope"; + type = 12; + enum + { + 1 = "Front floor to back sector"; + 2 = "Back floor to front sector"; + 4 = "Front ceiling to back sector"; + 8 = "Back ceiling to front sector"; + } + } + } + } } \ No newline at end of file diff --git a/extras/conf/Includes/SRB222_misc.cfg b/extras/conf/Includes/SRB222_misc.cfg index ce23388b2..7fe4890fd 100644 --- a/extras/conf/Includes/SRB222_misc.cfg +++ b/extras/conf/Includes/SRB222_misc.cfg @@ -63,19 +63,19 @@ linedefflags_udmf midpeg = "Peg Midtexture"; midsolid = "Solid Midtexture"; wrapmidtex = "Repeat Midtexture"; -// netonly = "Netgame-Only special"; -// nonet = "No netgame special"; -// effect6 = "Effect 6"; +// netonly = "Netgame Only"; +// nonet = "No Netgame"; + effect6 = "Effect 6"; bouncy = "Bouncy Wall"; -// transfer = "Transfer Line"; + transfer = "Transfer Line"; } linedefactivations_udmf { - notriggerorder = "Out of Order"; - netonly = "Netgame-Only"; - nonet = "No netgame"; +// notriggerorder = "Out of Order"; + netonly = "Netgame Only"; + nonet = "No Netgame"; } sidedefflags diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 2a82ec512..8c4739b02 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -175,6 +175,7 @@ static const struct { {META_SECTORLINES, "sector_t.lines"}, {META_SIDENUM, "line_t.sidenum"}, + {META_LINEARGS, "line_t.args"}, #ifdef HAVE_LUA_SEGS {META_NODEBBOX, "node_t.bbox"}, {META_NODECHILDREN, "node_t.children"}, diff --git a/src/lua_libs.h b/src/lua_libs.h index 6a908d03d..155c34eaa 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -56,6 +56,7 @@ extern lua_State *gL; #define META_SECTORLINES "SECTOR_T*LINES" #define META_SIDENUM "LINE_T*SIDENUM" +#define META_LINEARGS "LINE_T*ARGS" #ifdef HAVE_LUA_SEGS #define META_NODEBBOX "NODE_T*BBOX" #define META_NODECHILDREN "NODE_T*CHILDREN" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 309ba86a1..03da0a2e0 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -94,6 +94,7 @@ enum line_e { line_flags, line_special, line_tag, + line_args, line_sidenum, line_frontside, line_backside, @@ -115,6 +116,7 @@ static const char *const line_opt[] = { "flags", "special", "tag", + "args", "sidenum", "frontside", "backside", @@ -701,6 +703,24 @@ static int subsector_num(lua_State *L) // line_t // //////////// +// args, i -> args[i] +static int lineargs_get(lua_State *L) +{ + INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_LINEARGS)); + int i = luaL_checkinteger(L, 2); + if (i < 0 || i >= NUMLINEARGS) + return luaL_error(L, LUA_QL("line_t.args") " index cannot be %d", i); + lua_pushinteger(L, args[i]); + return 1; +} + +// #args -> NUMLINEARGS +static int lineargs_len(lua_State* L) +{ + lua_pushinteger(L, NUMLINEARGS); + return 1; +} + static int line_get(lua_State *L) { line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE)); @@ -741,6 +761,9 @@ static int line_get(lua_State *L) case line_tag: lua_pushinteger(L, line->tag); return 1; + case line_args: + LUA_PushUserdata(L, line->args, META_LINEARGS); + return 1; case line_sidenum: LUA_PushUserdata(L, line->sidenum, META_SIDENUM); return 1; @@ -2137,6 +2160,14 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + luaL_newmetatable(L, META_LINEARGS); + lua_pushcfunction(L, lineargs_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lineargs_len); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + luaL_newmetatable(L, META_SIDENUM); lua_pushcfunction(L, sidenum_get); lua_setfield(L, -2, "__index"); diff --git a/src/p_saveg.c b/src/p_saveg.c index 2b6a474bf..1e6451164 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -768,6 +768,17 @@ static void P_NetUnArchiveColormaps(void) #define LD_S2TOPTEX 0x02 #define LD_S2BOTTEX 0x04 #define LD_S2MIDTEX 0x08 +#define LD_ARGS 0x10 + +static boolean P_AreArgsEqual(const INT32 args[NUMLINEARGS], const INT32 spawnargs[NUMLINEARGS]) +{ + UINT8 i; + for (i = 0; i < NUMLINEARGS; i++) + if (args[i] != spawnargs[i]) + return false; + + return true; +} // // P_NetArchiveWorld @@ -944,6 +955,9 @@ static void P_NetArchiveWorld(void) if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved diff |= LD_CLLCOUNT; + if (!P_AreArgsEqual(li->args, spawnli->args)) + diff2 |= LD_ARGS; + if (li->sidenum[0] != 0xffff) { si = &sides[li->sidenum[0]]; @@ -970,10 +984,11 @@ static void P_NetArchiveWorld(void) diff2 |= LD_S2BOTTEX; if (si->midtexture != spawnsi->midtexture) diff2 |= LD_S2MIDTEX; - if (diff2) - diff |= LD_DIFF2; } + if (diff2) + diff |= LD_DIFF2; + if (diff) { statline++; @@ -1007,6 +1022,12 @@ static void P_NetArchiveWorld(void) WRITEINT32(put, si->bottomtexture); if (diff2 & LD_S2MIDTEX) WRITEINT32(put, si->midtexture); + if (diff2 & LD_ARGS) + { + UINT8 j; + for (j = 0; j < NUMLINEARGS; j++) + WRITEINT32(put, li->args[j]); + } } } WRITEUINT16(put, 0xffff); @@ -1190,6 +1211,13 @@ static void P_NetUnArchiveWorld(void) si->bottomtexture = READINT32(get); if (diff2 & LD_S2MIDTEX) si->midtexture = READINT32(get); + if (diff2 & LD_ARGS) + { + UINT8 j; + for (j = 0; j < NUMLINEARGS; j++) + li->args[j] = READINT32(get); + } + } save_p = get; diff --git a/src/p_setup.c b/src/p_setup.c index cfe141381..dc7f07d9e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1052,6 +1052,7 @@ static void P_LoadLinedefs(UINT8 *data) ld->flags = SHORT(mld->flags); ld->special = SHORT(mld->special); ld->tag = SHORT(mld->tag); + memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args)); P_SetLinedefV1(i, SHORT(mld->v1)); P_SetLinedefV2(i, SHORT(mld->v2)); @@ -1426,6 +1427,13 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) P_SetLinedefV1(i, atol(val)); else if (fastcmp(param, "v2")) P_SetLinedefV2(i, atol(val)); + else if (fastncmp(param, "arg", 3) && strlen(param) > 3) + { + size_t argnum = atol(param + 3); + if (argnum >= NUMLINEARGS) + return; + lines[i].args[argnum] = atol(val); + } else if (fastcmp(param, "sidefront")) lines[i].sidenum[0] = atol(val); else if (fastcmp(param, "sideback")) @@ -1613,6 +1621,7 @@ static void P_LoadTextmap(void) ld->flags = 0; ld->special = 0; ld->tag = 0; + memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args)); ld->sidenum[0] = 0xffff; ld->sidenum[1] = 0xffff; @@ -2634,6 +2643,97 @@ static void P_LinkMapData(void) } } +//For maps in binary format, converts setup of specials to UDMF format. +static void P_ConvertBinaryMap(void) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + switch (lines[i].special) + { + case 700: //Slope front sector floor + case 701: //Slope front sector ceiling + case 702: //Slope front sector floor and ceiling + case 703: //Slope front sector floor and back sector ceiling + case 710: //Slope back sector floor + case 711: //Slope back sector ceiling + case 712: //Slope back sector floor and ceiling + case 713: //Slope back sector floor and front sector ceiling + { + boolean frontfloor = (lines[i].special == 700 || lines[i].special == 702 || lines[i].special == 703); + boolean backfloor = (lines[i].special == 710 || lines[i].special == 712 || lines[i].special == 713); + boolean frontceil = (lines[i].special == 701 || lines[i].special == 702 || lines[i].special == 713); + boolean backceil = (lines[i].special == 711 || lines[i].special == 712 || lines[i].special == 703); + + lines[i].args[0] = backfloor ? 2 : (frontfloor ? 1 : 0); + lines[i].args[1] = backceil ? 2 : (frontceil ? 1 : 0); + + if (lines[i].flags & ML_NETONLY) + lines[i].args[2] |= SL_NOPHYSICS; + if (lines[i].flags & ML_NONET) + lines[i].args[2] |= SL_DYNAMIC; + + lines[i].special = 700; + break; + } + case 704: //Slope front sector floor by 3 tagged vertices + case 705: //Slope front sector ceiling by 3 tagged vertices + case 714: //Slope back sector floor by 3 tagged vertices + case 715: //Slope back sector ceiling by 3 tagged vertices + { + if (lines[i].special == 704) + lines[i].args[0] = 0; + else if (lines[i].special == 705) + lines[i].args[0] = 1; + else if (lines[i].special == 714) + lines[i].args[0] = 2; + else if (lines[i].special == 715) + lines[i].args[0] = 3; + + lines[i].args[1] = lines[i].tag; + + if (lines[i].flags & ML_EFFECT6) + { + UINT8 side = lines[i].special >= 714; + + if (side == 1 && lines[i].sidenum[1] == 0xffff) + CONS_Debug(DBG_GAMELOGIC, "P_ConvertBinaryMap: Line special %d (line #%s) missing 2nd side!\n", lines[i].special, sizeu1(i)); + else + { + lines[i].args[2] = sides[lines[i].sidenum[side]].textureoffset >> FRACBITS; + lines[i].args[3] = sides[lines[i].sidenum[side]].rowoffset >> FRACBITS; + } + } + else + { + lines[i].args[2] = lines[i].args[1]; + lines[i].args[3] = lines[i].args[1]; + } + + if (lines[i].flags & ML_NETONLY) + lines[i].args[4] |= SL_NOPHYSICS; + if (lines[i].flags & ML_NONET) + lines[i].args[4] |= SL_DYNAMIC; + + lines[i].special = 704; + break; + } + case 720: //Copy front side floor slope + case 721: //Copy front side ceiling slope + case 722: //Copy front side floor and ceiling slope + if (lines[i].special != 721) + lines[i].args[0] = lines[i].tag; + if (lines[i].special != 720) + lines[i].args[1] = lines[i].tag; + lines[i].special = 720; + break; + default: + break; + } + } +} + /** Compute MD5 message digest for bytes read from memory source * * The resulting message digest number will be written into the 16 bytes @@ -2697,6 +2797,7 @@ static void P_MakeMapMD5(virtres_t *virt, void *dest) static boolean P_LoadMapFromFile(void) { virtres_t *virt = vres_GetMap(lastloadedmaplumpnum); + virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); if (!P_LoadMapData(virt)) return false; @@ -2705,6 +2806,9 @@ static boolean P_LoadMapFromFile(void) P_LinkMapData(); + if (!textmap) + P_ConvertBinaryMap(); + // Copy relevant map data for NetArchive purposes. spawnsectors = Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL); spawnlines = Z_Calloc(numlines * sizeof(*lines), PU_LEVEL, NULL); diff --git a/src/p_slopes.c b/src/p_slopes.c index 2cf2c74ba..f16975726 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -247,32 +247,30 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) // because checking to see if a slope had changed will waste more memory than // if the slope was just updated when called line_t *line = lines + linenum; - INT16 special = line->special; pslope_t *fslope = NULL, *cslope = NULL; vector3_t origin, point; vector2_t direction; fixed_t nx, ny, dz, extent; - boolean frontfloor = (special == 700 || special == 702 || special == 703); - boolean backfloor = (special == 710 || special == 712 || special == 713); - boolean frontceil = (special == 701 || special == 702 || special == 713); - boolean backceil = (special == 711 || special == 712 || special == 703); - + boolean frontfloor = line->args[0] == 1; + boolean backfloor = line->args[0] == 2; + boolean frontceil = line->args[1] == 1; + boolean backceil = line->args[1] == 2; UINT8 flags = 0; // Slope flags - if (line->flags & ML_NETONLY) + if (line->args[2] & 1) flags |= SL_NOPHYSICS; - if (line->flags & ML_NONET) + if (line->args[2] & 2) flags |= SL_DYNAMIC; if(!frontfloor && !backfloor && !frontceil && !backceil) { - CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); + CONS_Printf("line_SpawnViaLine: Slope special with nothing to do.\n"); return; } if(!line->frontsector || !line->backsector) { - CONS_Debug(DBG_SETUP, "P_SpawnSlope_Line used on a line without two sides. (line number %i)\n", linenum); + CONS_Debug(DBG_SETUP, "line_SpawnViaLine: Slope special used on a line without two sides. (line number %i)\n", linenum); return; } @@ -299,7 +297,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) if(extent < 0) { - CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); + CONS_Printf("line_SpawnViaLine failed to get frontsector extent on line number %i\n", linenum); return; } @@ -365,7 +363,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) if(extent < 0) { - CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum); + CONS_Printf("line_SpawnViaLine failed to get backsector extent on line number %i\n", linenum); return; } @@ -464,49 +462,81 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) line_t *line = lines + linenum; side_t *side; pslope_t **slopetoset; - UINT16 tag1, tag2, tag3; - - UINT8 flags = 0; - if (line->flags & ML_NETONLY) + UINT16 tag1 = line->args[1]; + UINT16 tag2 = line->args[2]; + UINT16 tag3 = line->args[3]; + UINT8 flags = 0; // Slope flags + if (line->args[4] & 1) flags |= SL_NOPHYSICS; - if (line->flags & ML_NONET) + if (line->args[4] & 2) flags |= SL_DYNAMIC; - switch(line->special) + switch(line->args[0]) { - case 704: + case 0: slopetoset = &line->frontsector->f_slope; side = &sides[line->sidenum[0]]; break; - case 705: + case 1: slopetoset = &line->frontsector->c_slope; side = &sides[line->sidenum[0]]; break; - case 714: + case 2: slopetoset = &line->backsector->f_slope; side = &sides[line->sidenum[1]]; break; - case 715: + case 3: slopetoset = &line->backsector->c_slope; side = &sides[line->sidenum[1]]; default: return; } - if (line->flags & ML_EFFECT6) - { - tag1 = line->tag; - tag2 = side->textureoffset >> FRACBITS; - tag3 = side->rowoffset >> FRACBITS; - } - else - tag1 = tag2 = tag3 = line->tag; - *slopetoset = MakeViaMapthings(tag1, tag2, tag3, flags, spawnthinker); side->sector->hasslope = true; } +static boolean P_SetSlopeFromTag(sector_t *sec, INT32 tag, boolean ceiling) +{ + INT32 i; + pslope_t **secslope = ceiling ? &sec->c_slope : &sec->f_slope; + + if (!tag || *secslope) + return false; + + for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0;) + { + pslope_t *srcslope = ceiling ? sectors[i].c_slope : sectors[i].f_slope; + if (srcslope) + { + *secslope = srcslope; + return true; + } + } + return false; +} + +static boolean P_CopySlope(pslope_t **toslope, pslope_t *fromslope) +{ + if (*toslope || !fromslope) + return true; + + *toslope = fromslope; + return true; +} + +static void P_UpdateHasSlope(sector_t *sec) +{ + size_t i; + + sec->hasslope = true; + + // if this is an FOF control sector, make sure any target sectors also are marked as having slopes + if (sec->numattached) + for (i = 0; i < sec->numattached; i++) + sectors[sec->attached[i]].hasslope = true; +} // // P_CopySectorSlope @@ -516,25 +546,31 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) void P_CopySectorSlope(line_t *line) { sector_t *fsec = line->frontsector; - int i, special = line->special; + sector_t *bsec = line->backsector; + boolean setfront = false; + boolean setback = false; - // Check for copy linedefs - for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) + setfront |= P_SetSlopeFromTag(fsec, line->args[0], false); + setfront |= P_SetSlopeFromTag(fsec, line->args[1], true); + if (bsec) { - sector_t *srcsec = sectors + i; + setback |= P_SetSlopeFromTag(bsec, line->args[2], false); + setback |= P_SetSlopeFromTag(bsec, line->args[3], true); - if ((special - 719) & 1 && !fsec->f_slope && srcsec->f_slope) - fsec->f_slope = srcsec->f_slope; //P_CopySlope(srcsec->f_slope); - if ((special - 719) & 2 && !fsec->c_slope && srcsec->c_slope) - fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); + if (line->args[4] & 1) + setback |= P_CopySlope(&bsec->f_slope, fsec->f_slope); + if (line->args[4] & 2) + setfront |= P_CopySlope(&fsec->f_slope, bsec->f_slope); + if (line->args[4] & 4) + setback |= P_CopySlope(&bsec->c_slope, fsec->c_slope); + if (line->args[4] & 8) + setfront |= P_CopySlope(&fsec->c_slope, bsec->c_slope); } - fsec->hasslope = true; - - // if this is an FOF control sector, make sure any target sectors also are marked as having slopes - if (fsec->numattached) - for (i = 0; i < (int)fsec->numattached; i++) - sectors[fsec->attached[i]].hasslope = true; + if (setfront) + P_UpdateHasSlope(fsec); + if (setback) + P_UpdateHasSlope(bsec); line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef } @@ -563,20 +599,10 @@ void P_ResetDynamicSlopes(const boolean fromsave) { switch (lines[i].special) { case 700: - case 701: - case 702: - case 703: - case 710: - case 711: - case 712: - case 713: line_SpawnViaLine(i, !fromsave); break; case 704: - case 705: - case 714: - case 715: line_SpawnViaVertexes(i, !fromsave); break; @@ -591,8 +617,6 @@ void P_ResetDynamicSlopes(const boolean fromsave) { switch (lines[i].special) { case 720: - case 721: - case 722: P_CopySectorSlope(&lines[i]); default: break; diff --git a/src/r_defs.h b/src/r_defs.h index 52b9bea95..677c34a9d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -401,6 +401,8 @@ typedef enum #define HORIZONSPECIAL 41 +#define NUMLINEARGS 6 + typedef struct line_s { // Vertices, from v1 to v2. @@ -413,6 +415,7 @@ typedef struct line_s INT16 flags; INT16 special; INT16 tag; + INT32 args[NUMLINEARGS]; // Visual appearance: sidedefs. UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided