diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 5dd7a1c5b349b2d9f9707a5fd7072dc8e7fb70c3..5ed05d4d693ed233fc931250ac93c7dd41bb7163 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -750,12 +750,6 @@ linedeftypes prefix = "(20)"; } - 21 - { - title = "Explicitly Include Line <disabled>"; - prefix = "(21)"; - } - 22 { title = "Parameters"; @@ -2603,45 +2597,63 @@ linedeftypes 500 { - title = "Scroll Wall Front Side Left"; + title = "Scroll Front Wall Left"; prefix = "(500)"; } 501 { - title = "Scroll Wall Front Side Right"; + title = "Scroll Front Wall Right"; prefix = "(501)"; } 502 { - title = "Scroll Wall According to Linedef"; + title = "Scroll Tagged Wall"; prefix = "(502)"; + flags128text = "[7] Use texture offsets"; + flags256text = "[8] Scroll back side"; } 503 { - title = "Scroll Wall According to Linedef (Accelerative)"; + title = "Scroll Tagged Wall (Accelerative)"; prefix = "(503)"; + flags128text = "[7] Use texture offsets"; + flags256text = "[8] Scroll back side"; } 504 { - title = "Scroll Wall According to Linedef (Displacement)"; + title = "Scroll Tagged Wall (Displacement)"; prefix = "(504)"; + flags128text = "[7] Use texture offsets"; + flags256text = "[8] Scroll back side"; } 505 { - title = "Scroll Texture by Front Side Offsets"; + title = "Scroll Front Wall by Front Side Offsets"; prefix = "(505)"; } 506 { - title = "Scroll Texture by Back Side Offsets"; + title = "Scroll Front Wall by Back Side Offsets"; prefix = "(506)"; } + + 507 + { + title = "Scroll Back Wall by Front Side Offsets"; + prefix = "(507)"; + } + + 508 + { + title = "Scroll Back Wall by Back Side Offsets"; + prefix = "(508)"; + } } planescroll diff --git a/src/am_map.c b/src/am_map.c index cdbaaf80aea702a02b77618ac4081c6cbb7abfa6..53a7480a5468d113226cdcbdde34d495f735e55d 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -931,11 +931,8 @@ static inline void AM_drawWalls(void) l.b.y = lines[i].v2->y >> FRACTOMAPBITS; #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \ - end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, normalheight); \ + end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, normalheight); SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight) SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index dbf10d58e43f18d93710ed54094f8798b8f390f8..4d7ff10656dbcab4c3b3da18b31242fc36204118 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -195,24 +195,25 @@ static inline void *G_ScpyTiccmd(ticcmd_t* dest, void* src, const size_t n) // of 512 bytes is like 0.1) UINT16 software_MAXPACKETLENGTH; -/** Guesses the value of a tic from its lowest byte and from maketic +/** Guesses the full value of a tic from its lowest byte, for a specific node * * \param low The lowest byte of the tic value + * \param node The node to deduce the tic for * \return The full tic value * */ -tic_t ExpandTics(INT32 low) +tic_t ExpandTics(INT32 low, INT32 node) { INT32 delta; - delta = low - (maketic & UINT8_MAX); + delta = low - (nettics[node] & UINT8_MAX); if (delta >= -64 && delta <= 64) - return (maketic & ~UINT8_MAX) + low; + return (nettics[node] & ~UINT8_MAX) + low; else if (delta > 64) - return (maketic & ~UINT8_MAX) - 256 + low; + return (nettics[node] & ~UINT8_MAX) - 256 + low; else //if (delta < -64) - return (maketic & ~UINT8_MAX) + 256 + low; + return (nettics[node] & ~UINT8_MAX) + 256 + low; } // ----------------------------------------------------------------- @@ -1508,7 +1509,7 @@ static boolean SV_SendServerConfig(INT32 node) if (!playeringame[i]) continue; netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin; - netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor; + netbuffer->u.servercfg.playercolor[i] = (UINT16)players[i].skincolor; netbuffer->u.servercfg.playeravailabilities[i] = (UINT32)LONG(players[i].availabilities); } @@ -1703,7 +1704,7 @@ static void CL_LoadReceivedSavegame(void) // load a base level if (P_LoadNetGame()) { - const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; + const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) { @@ -3308,7 +3309,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) boolean splitscreenplayer; boolean rejoined; player_t *newplayer; - char *port; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -3339,10 +3339,15 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (server && I_GetNodeAddress) { - strcpy(playeraddress[newplayernum], I_GetNodeAddress(node)); - port = strchr(playeraddress[newplayernum], ':'); - if (port) - *port = '\0'; + const char *address = I_GetNodeAddress(node); + char *port = NULL; + if (address) // MI: fix msvcrt.dll!_mbscat crash? + { + strcpy(playeraddress[newplayernum], address); + port = strchr(playeraddress[newplayernum], ':'); + if (port) + *port = '\0'; + } } } @@ -3894,7 +3899,7 @@ static void HandlePacketFromAwayNode(SINT8 node) for (j = 0; j < MAXPLAYERS; j++) { if (netbuffer->u.servercfg.playerskins[j] == 0xFF - && netbuffer->u.servercfg.playercolor[j] == 0xFF + && netbuffer->u.servercfg.playercolor[j] == 0xFFFF && netbuffer->u.servercfg.playeravailabilities[j] == 0xFFFFFFFF) continue; // not in game @@ -4026,8 +4031,8 @@ static void HandlePacketFromPlayer(SINT8 node) // To save bytes, only the low byte of tic numbers are sent // Use ExpandTics to figure out what the rest of the bytes are - realstart = ExpandTics(netbuffer->u.clientpak.client_tic); - realend = ExpandTics(netbuffer->u.clientpak.resendfrom); + realstart = ExpandTics(netbuffer->u.clientpak.client_tic, node); + realend = ExpandTics(netbuffer->u.clientpak.resendfrom, node); if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS || netbuffer->packettype == PT_NODEKEEPALIVEMIS @@ -4275,15 +4280,15 @@ static void HandlePacketFromPlayer(SINT8 node) break; } - realstart = ExpandTics(netbuffer->u.serverpak.starttic); + realstart = netbuffer->u.serverpak.starttic; realend = realstart + netbuffer->u.serverpak.numtics; if (!txtpak) txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots * netbuffer->u.serverpak.numtics]; - if (realend > gametic + BACKUPTICS) - realend = gametic + BACKUPTICS; + if (realend > gametic + CLIENTBACKUPTICS) + realend = gametic + CLIENTBACKUPTICS; cl_packetmissed = realstart > neededtic; if (realstart <= neededtic && realend > neededtic) @@ -4634,11 +4639,11 @@ static void SV_SendTics(void) for (n = 1; n < MAXNETNODES; n++) if (nodeingame[n]) { - lasttictosend = maketic; - // assert supposedtics[n]>=nettics[n] realfirsttic = supposedtics[n]; - if (realfirsttic >= maketic) + lasttictosend = min(maketic, realfirsttic + CLIENTBACKUPTICS); + + if (realfirsttic >= lasttictosend) { // well we have sent all tics we will so use extrabandwidth // to resent packet that are supposed lost (this is necessary since lost @@ -4647,7 +4652,7 @@ static void SV_SendTics(void) DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n", n, maketic, supposedtics[n], nettics[n])); realfirsttic = nettics[n]; - if (realfirsttic >= maketic || (I_GetTime() + n)&3) + if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) // all tic are ok continue; DEBFILE(va("Sent %d anyway\n", realfirsttic)); @@ -4690,7 +4695,7 @@ static void SV_SendTics(void) // Send the tics netbuffer->packettype = PT_SERVERTICS; - netbuffer->u.serverpak.starttic = (UINT8)realfirsttic; + netbuffer->u.serverpak.starttic = realfirsttic; netbuffer->u.serverpak.numtics = (UINT8)(lasttictosend - realfirsttic); netbuffer->u.serverpak.numslots = (UINT8)SHORT(doomcom->numslots); bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index c8241fedee2895ba74ef6933e7f22b64ab086a58..da893a5b7438fd9ee5d229a09cbb199807c236b2 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -34,6 +34,7 @@ applications may follow different packet versions. // Networking and tick handling related. #define BACKUPTICS 96 +#define CLIENTBACKUPTICS 32 #define MAXTEXTCMD 256 // // Packet structure @@ -130,7 +131,7 @@ typedef struct // this packet is too large typedef struct { - UINT8 starttic; + tic_t starttic; UINT8 numtics; UINT8 numslots; // "Slots filled": Highest player number in use plus one. ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large @@ -190,7 +191,7 @@ typedef struct SINT8 xtralife; SINT8 pity; - UINT8 skincolor; + UINT16 skincolor; INT32 skin; UINT32 availabilities; // Just in case Lua does something like @@ -310,7 +311,7 @@ typedef struct // 0xFF == not in game; else player skin num UINT8 playerskins[MAXPLAYERS]; - UINT8 playercolor[MAXPLAYERS]; + UINT16 playercolor[MAXPLAYERS]; UINT32 playeravailabilities[MAXPLAYERS]; UINT8 gametype; @@ -433,7 +434,7 @@ typedef struct { char name[MAXPLAYERNAME+1]; UINT8 skin; - UINT8 color; + UINT16 color; UINT32 pflags; UINT32 score; UINT8 ctfteam; @@ -541,7 +542,7 @@ extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; // Used in d_net, the only dependence -tic_t ExpandTics(INT32 low); +tic_t ExpandTics(INT32 low, INT32 node); void D_ClientServerInit(void); // Initialise the other field diff --git a/src/d_main.c b/src/d_main.c index 07e15aec4e3488a922a670432def281f2ffe09ca..2e5519c83cd647883a888994c61998367d874573 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -125,6 +125,11 @@ boolean advancedemo; INT32 debugload = 0; #endif +UINT16 numskincolors; +menucolor_t *menucolorhead, *menucolortail; + +char savegamename[256]; + char srb2home[256] = "."; char srb2path[256] = "."; boolean usehome = true; @@ -1189,6 +1194,10 @@ void D_SRB2Main(void) if (M_CheckParm("-password") && M_IsNextParm()) D_SetPassword(M_GetNextParm()); + // player setup menu colors must be initialized before + // any wad file is added, as they may contain colors themselves + M_InitPlayerSetupColors(); + CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); Z_Init(); diff --git a/src/d_net.c b/src/d_net.c index c0f97ca877d71d00574335cc7de515863f257682..2823ce2191ebcde53dc1c2a21d1a8ff9e03bef08 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -814,6 +814,7 @@ static const char *packettypename[NUMPACKETTYPE] = "CLIENTJOIN", "NODETIMEOUT", "RESYNCHING", + "LOGIN", "PING" }; @@ -840,7 +841,7 @@ static void DebugPrintpacket(const char *header) size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd; fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ", - (UINT32)ExpandTics(serverpak->starttic), serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd)); + (UINT32)serverpak->starttic, serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd)); /// \todo Display more readable information about net commands fprintfstringnewline((char *)cmd, ntxtcmd); /*fprintfstring((char *)cmd, 3); @@ -859,8 +860,8 @@ static void DebugPrintpacket(const char *header) case PT_NODEKEEPALIVE: case PT_NODEKEEPALIVEMIS: fprintf(debugfile, " tic %4u resendfrom %u\n", - (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), - (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); + (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode), + (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode)); break; case PT_TEXTCMD: case PT_TEXTCMD2: diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 042b99cc719d0e5e8fdcea23f08af12db3d365eb..8b75741ae177cd7c3b78b6ae9b11b546090ad263 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -225,6 +225,7 @@ consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, NULL, consvar_t cv_playername = {"name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // player colors +UINT16 lastgoodcolor = SKINCOLOR_BLUE, lastgoodcolor2 = SKINCOLOR_BLUE; consvar_t cv_playercolor = {"color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // player's skin, saved for commodity, when using a favorite skins wad.. @@ -621,7 +622,7 @@ void D_RegisterClientCommands(void) for (i = 0; i < MAXSKINCOLORS; i++) { Color_cons_t[i].value = i; - Color_cons_t[i].strvalue = Color_Names[i]; + Color_cons_t[i].strvalue = skincolors[i].name; } Color_cons_t[MAXSKINCOLORS].value = 0; Color_cons_t[MAXSKINCOLORS].strvalue = NULL; @@ -1223,15 +1224,20 @@ static void SendNameAndColor(void) CV_StealthSetValue(&cv_playercolor, skincolor_blueteam); } - // never allow the color "none" - if (!cv_playercolor.value) + // don't allow inaccessible colors + if (!skincolors[cv_playercolor.value].accessible) { - if (players[consoleplayer].skincolor) + if (players[consoleplayer].skincolor && skincolors[players[consoleplayer].skincolor].accessible) CV_StealthSetValue(&cv_playercolor, players[consoleplayer].skincolor); - else if (skins[players[consoleplayer].skin].prefcolor) - CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor); - else + else if (skincolors[atoi(cv_playercolor.defaultvalue)].accessible) CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue); + else if (skins[players[consoleplayer].skin].prefcolor && skincolors[skins[players[consoleplayer].skin].prefcolor].accessible) + CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor); + else { + UINT16 i = 0; + while (i<numskincolors && !skincolors[i].accessible) i++; + CV_StealthSetValue(&cv_playercolor, (i != numskincolors) ? i : SKINCOLOR_BLUE); + } } if (!strcmp(cv_playername.string, player_names[consoleplayer]) @@ -1278,10 +1284,10 @@ static void SendNameAndColor(void) { CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor); - players[consoleplayer].skincolor = cv_playercolor.value % MAXSKINCOLORS; + players[consoleplayer].skincolor = cv_playercolor.value % numskincolors; if (players[consoleplayer].mo) - players[consoleplayer].mo->color = (UINT8)players[consoleplayer].skincolor; + players[consoleplayer].mo->color = (UINT16)players[consoleplayer].skincolor; }*/ } else @@ -1319,7 +1325,7 @@ static void SendNameAndColor(void) // Finally write out the complete packet and send it off. WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME); WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities); - WRITEUINT8(p, (UINT8)cv_playercolor.value); + WRITEUINT16(p, (UINT16)cv_playercolor.value); WRITEUINT8(p, (UINT8)cv_skin.value); SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf); } @@ -1346,15 +1352,20 @@ static void SendNameAndColor2(void) CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam); } - // never allow the color "none" - if (!cv_playercolor2.value) + // don't allow inaccessible colors + if (!skincolors[cv_playercolor2.value].accessible) { - if (players[secondplaya].skincolor) + if (players[secondplaya].skincolor && skincolors[players[secondplaya].skincolor].accessible) CV_StealthSetValue(&cv_playercolor2, players[secondplaya].skincolor); - else if (skins[players[secondplaya].skin].prefcolor) + else if (skincolors[atoi(cv_playercolor2.defaultvalue)].accessible) + CV_StealthSet(&cv_playercolor, cv_playercolor2.defaultvalue); + else if (skins[players[secondplaya].skin].prefcolor && skincolors[skins[players[secondplaya].skin].prefcolor].accessible) CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor); - else - CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue); + else { + UINT16 i = 0; + while (i<numskincolors && !skincolors[i].accessible) i++; + CV_StealthSetValue(&cv_playercolor2, (i != numskincolors) ? i : SKINCOLOR_BLUE); + } } players[secondplaya].availabilities = R_GetSkinAvailabilities(); @@ -1407,7 +1418,7 @@ static void SendNameAndColor2(void) { CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor); - players[secondplaya].skincolor = cv_playercolor2.value % MAXSKINCOLORS; + players[secondplaya].skincolor = cv_playercolor2.value % numskincolors; if (players[secondplaya].mo) players[secondplaya].mo->color = players[secondplaya].skincolor; @@ -1430,7 +1441,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) { player_t *p = &players[playernum]; char name[MAXPLAYERNAME+1]; - UINT8 color, skin; + UINT16 color; + UINT8 skin; #ifdef PARANOIA if (playernum < 0 || playernum > MAXPLAYERS) @@ -1449,7 +1461,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) READSTRINGN(*cp, name, MAXPLAYERNAME); p->availabilities = READUINT32(*cp); - color = READUINT8(*cp); + color = READUINT16(*cp); skin = READUINT8(*cp); // set name @@ -1457,9 +1469,9 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) SetPlayerName(playernum, name); // set color - p->skincolor = color % MAXSKINCOLORS; + p->skincolor = color % numskincolors; if (p->mo) - p->mo->color = (UINT8)p->skincolor; + p->mo->color = (UINT16)p->skincolor; // normal player colors if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer])) @@ -1476,8 +1488,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) kick = true; } - // don't allow color "none" - if (!p->skincolor) + // don't allow inaccessible colors + if (skincolors[p->skincolor].accessible == false) kick = true; // availabilities @@ -4475,25 +4487,30 @@ static void Skin2_OnChange(void) */ static void Color_OnChange(void) { - if (!Playing()) - return; // do whatever you want - - if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. - { - CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); - return; - } - - if (!P_PlayerMoving(consoleplayer)) - { - // Color change menu scrolling fix is no longer necessary - SendNameAndColor(); + if (!Playing()) { + if (!cv_playercolor.value || !skincolors[cv_playercolor.value].accessible) + CV_StealthSetValue(&cv_playercolor, lastgoodcolor); } else { - CV_StealthSetValue(&cv_playercolor, - players[consoleplayer].skincolor); + if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. + { + CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); + return; + } + + if (!P_PlayerMoving(consoleplayer) && skincolors[players[consoleplayer].skincolor].accessible == true) + { + // Color change menu scrolling fix is no longer necessary + SendNameAndColor(); + } + else + { + CV_StealthSetValue(&cv_playercolor, + players[consoleplayer].skincolor); + } } + lastgoodcolor = cv_playercolor.value; } /** Sends a color change for the secondary splitscreen player, unless that @@ -4504,18 +4521,24 @@ static void Color_OnChange(void) static void Color2_OnChange(void) { if (!Playing() || !splitscreen) - return; // do whatever you want - - if (!P_PlayerMoving(secondarydisplayplayer)) { - // Color change menu scrolling fix is no longer necessary - SendNameAndColor2(); + if (!cv_playercolor2.value || !skincolors[cv_playercolor2.value].accessible) + CV_StealthSetValue(&cv_playercolor2, lastgoodcolor2); } else { - CV_StealthSetValue(&cv_playercolor2, - players[secondarydisplayplayer].skincolor); + if (!P_PlayerMoving(secondarydisplayplayer) && skincolors[players[secondarydisplayplayer].skincolor].accessible == true) + { + // Color change menu scrolling fix is no longer necessary + SendNameAndColor2(); + } + else + { + CV_StealthSetValue(&cv_playercolor2, + players[secondarydisplayplayer].skincolor); + } } + lastgoodcolor2 = cv_playercolor2.value; } /** Displays the result of the chat being muted or unmuted. diff --git a/src/d_player.h b/src/d_player.h index 8697e9836929c0e269f61127d7245686e71b0232..0f10317084b046d713a5b96a3a2e9392af6fb892 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -239,7 +239,8 @@ typedef enum CR_MACESPIN, CR_MINECART, CR_ROLLOUT, - CR_PTERABYTE + CR_PTERABYTE, + CR_DUSTDEVIL } carrytype_t; // pw_carry // Player powers. (don't edit this comment) @@ -365,7 +366,7 @@ typedef struct player_s UINT16 flashpal; // Player skin colorshift, 0-15 for which color to draw player. - UINT8 skincolor; + UINT16 skincolor; INT32 skin; UINT32 availabilities; diff --git a/src/dehacked.c b/src/dehacked.c index a6c73e0b45cbe96cdd6ae0de18cf687baec9ef5b..627a3a11921ad43b945f0ea1519fec4d20750dff 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -56,10 +56,12 @@ int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); // The crazy word-reading stuff uses these. static char *FREE_STATES[NUMSTATEFREESLOTS]; static char *FREE_MOBJS[NUMMOBJFREESLOTS]; +static char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; static UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. #define initfreeslots() {\ memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\ memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\ +memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ } @@ -77,6 +79,7 @@ static hudnum_t get_huditem(const char *word); static menutype_t get_menutype(const char *word); //static INT16 get_gametype(const char *word); //static powertype_t get_power(const char *word); +skincolornum_t get_skincolor(const char *word); boolean deh_loaded = false; static int dbg_line; @@ -449,7 +452,7 @@ static void readPlayer(MYFILE *f, INT32 num) else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR")) { SLOTFOUND - description[num].oppositecolor = (UINT8)get_number(word2); + description[num].oppositecolor = (UINT16)get_number(word2); } else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME")) { @@ -459,12 +462,12 @@ static void readPlayer(MYFILE *f, INT32 num) else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR")) { SLOTFOUND - description[num].tagtextcolor = (UINT8)get_number(word2); + description[num].tagtextcolor = (UINT16)get_number(word2); } else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR")) { SLOTFOUND - description[num].tagoutlinecolor = (UINT8)get_number(word2); + description[num].tagoutlinecolor = (UINT16)get_number(word2); } else if (fastcmp(word, "STATUS")) { @@ -571,6 +574,16 @@ static void readfreeslots(MYFILE *f) break; } } + else if (fastcmp(type, "SKINCOLOR")) + { + for (i = 0; i < NUMCOLORFREESLOTS; i++) + if (!FREE_SKINCOLORS[i]) { + FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); + strcpy(FREE_SKINCOLORS[i],word); + M_AddMenuColor(numskincolors++); + break; + } + } else if (fastcmp(type, "SPR2")) { // Search if we already have an SPR2 by that name... @@ -753,6 +766,84 @@ static void readthing(MYFILE *f, INT32 num) Z_Free(s); } +static void readskincolor(MYFILE *f, INT32 num) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word, *word2, *word3; + char *tmp; + + Color_cons_t[num].value = num; + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + tmp = strchr(s, '#'); + if (tmp) + *tmp = '\0'; + if (s == tmp) + continue; // Skip comment lines, but don't break. + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + word2 = strtok(NULL, " = "); + if (word2) { + word3 = Z_StrDup(word2); + strupr(word2); + } else + break; + if (word2[strlen(word2)-1] == '\n') + word2[strlen(word2)-1] = '\0'; + if (word3[strlen(word3)-1] == '\n') + word3[strlen(word3)-1] = '\0'; + + if (fastcmp(word, "NAME")) + { + deh_strlcpy(skincolors[num].name, word3, + sizeof (skincolors[num].name), va("Skincolor %d: name", num)); + } + else if (fastcmp(word, "RAMP")) + { + UINT8 i; + tmp = strtok(word2,","); + for (i = 0; i < COLORRAMPSIZE; i++) { + skincolors[num].ramp[i] = (UINT8)get_number(tmp); + if ((tmp = strtok(NULL,",")) == NULL) + break; + } + } + else if (fastcmp(word, "INVCOLOR")) + { + skincolors[num].invcolor = (UINT16)get_number(word2); + } + else if (fastcmp(word, "INVSHADE")) + { + skincolors[num].invshade = get_number(word2)%COLORRAMPSIZE; + } + else if (fastcmp(word, "CHATCOLOR")) + { + skincolors[num].chatcolor = get_number(word2); + } + else if (fastcmp(word, "ACCESSIBLE")) + { + if (num > FIRSTSUPERCOLOR) + skincolors[num].accessible = (boolean)(atoi(word2) || word2[0] == 'T' || word2[0] == 'Y'); + } + else + deh_warning("Skincolor %d: unknown word '%s'", num, word); + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + #ifdef HWRENDER static void readlight(MYFILE *f, INT32 num) { @@ -1557,7 +1648,7 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "ACT")) { - if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19 + if (i >= 0 && i <= 99) // 0 for no act number mapheaderinfo[num-1]->actnum = (UINT8)i; else deh_warning("Level header %d: invalid act number %d", num, i); @@ -2813,7 +2904,7 @@ static actionpointer_t actionpointers[] = {{A_ThrownRing}, "A_THROWNRING"}, {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, - {{A_SignSpin}, "S_SIGNSPIN"}, + {{A_SignSpin}, "A_SIGNSPIN"}, {{A_SignPlayer}, "A_SIGNPLAYER"}, {{A_OverlayThink}, "A_OVERLAYTHINK"}, {{A_JetChase}, "A_JETCHASE"}, @@ -3952,19 +4043,19 @@ static void readmaincfg(MYFILE *f) } else if (fastcmp(word, "REDTEAM")) { - skincolor_redteam = (UINT8)get_number(word2); + skincolor_redteam = (UINT16)get_number(word2); } else if (fastcmp(word, "BLUETEAM")) { - skincolor_blueteam = (UINT8)get_number(word2); + skincolor_blueteam = (UINT16)get_number(word2); } else if (fastcmp(word, "REDRING")) { - skincolor_redring = (UINT8)get_number(word2); + skincolor_redring = (UINT16)get_number(word2); } else if (fastcmp(word, "BLUERING")) { - skincolor_bluering = (UINT8)get_number(word2); + skincolor_bluering = (UINT16)get_number(word2); } else if (fastcmp(word, "INVULNTICS")) { @@ -4556,6 +4647,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ignorelines(f); } } + else if (fastcmp(word, "SKINCOLOR") || fastcmp(word, "COLOR")) + { + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_skincolor(word2); // find a skincolor by name + if (i < numskincolors && i >= (INT32)SKINCOLOR_FIRSTFREESLOT) + readskincolor(f, i); + else + { + deh_warning("Skincolor %d out of range (%d - %d)", i, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + ignorelines(f); + } + } else if (fastcmp(word, "SPRITE2")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number @@ -9000,8 +9103,6 @@ static const char *const ML_LIST[16] = { "TFERLINE" }; -// This DOES differ from r_draw's Color_Names, unfortunately. -// Also includes Super colors static const char *COLOR_ENUMS[] = { "NONE", // SKINCOLOR_NONE, @@ -9437,7 +9538,8 @@ struct { // SKINCOLOR_ doesn't include these..! {"MAXSKINCOLORS",MAXSKINCOLORS}, - {"MAXTRANSLATIONS",MAXTRANSLATIONS}, + {"FIRSTSUPERCOLOR",FIRSTSUPERCOLOR}, + {"NUMSUPERCOLORS",NUMSUPERCOLORS}, // Precipitation {"PRECIP_NONE",PRECIP_NONE}, @@ -9488,6 +9590,7 @@ struct { {"CR_MINECART",CR_MINECART}, {"CR_ROLLOUT",CR_ROLLOUT}, {"CR_PTERABYTE",CR_PTERABYTE}, + {"CR_DUSTDEVIL",CR_DUSTDEVIL}, // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon @@ -9938,6 +10041,26 @@ static statenum_t get_state(const char *word) return S_NULL; } +skincolornum_t get_skincolor(const char *word) +{ // Returns the value of SKINCOLOR_ enumerations + skincolornum_t i; + if (*word >= '0' && *word <= '9') + return atoi(word); + if (fastncmp("SKINCOLOR_",word,10)) + word += 10; // take off the SKINCOLOR_ + for (i = 0; i < NUMCOLORFREESLOTS; i++) { + if (!FREE_SKINCOLORS[i]) + break; + if (fastcmp(word, FREE_SKINCOLORS[i])) + return SKINCOLOR_FIRSTFREESLOT+i; + } + for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++) + if (fastcmp(word, COLOR_ENUMS[i])) + return i; + deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'",word); + return SKINCOLOR_GREEN; +} + static spritenum_t get_sprite(const char *word) { // Returns the value of SPR_ enumerations spritenum_t i; @@ -10232,6 +10355,11 @@ static fixed_t find_const(const char **rword) free(word); return r; } + else if (fastncmp("SKINCOLOR_",word,10)) { + r = get_skincolor(word); + free(word); + return r; + } else if (fastncmp("MT_",word,3)) { r = get_mobjtype(word); free(word); @@ -10300,17 +10428,6 @@ static fixed_t find_const(const char **rword) free(word); return r; } - else if (fastncmp("SKINCOLOR_",word,10)) { - char *p = word+10; - for (i = 0; i < MAXTRANSLATIONS; i++) - if (fastcmp(p, COLOR_ENUMS[i])) { - free(word); - return i; - } - const_warning("color",word); - free(word); - return 0; - } else if (fastncmp("GRADE_",word,6)) { char *p = word+6; @@ -10371,8 +10488,8 @@ void DEH_Check(void) if (dehpowers != NUMPOWERS) I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers)); - if (dehcolors != MAXTRANSLATIONS) - I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXTRANSLATIONS, sizeu1(dehcolors)); + if (dehcolors != SKINCOLOR_FIRSTFREESLOT) + I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors)); #endif } @@ -10480,6 +10597,22 @@ static inline int lib_freeslot(lua_State *L) if (i == NUMMOBJFREESLOTS) CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); } + else if (fastcmp(type, "SKINCOLOR")) + { + skincolornum_t i; + for (i = 0; i < NUMCOLORFREESLOTS; i++) + if (!FREE_SKINCOLORS[i]) { + CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word); + FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); + strcpy(FREE_SKINCOLORS[i],word); + M_AddMenuColor(numskincolors++); + lua_pushinteger(L, i); + r++; + break; + } + if (i == NUMCOLORFREESLOTS) + CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); + } else if (fastcmp(type, "SPR2")) { // Search if we already have an SPR2 by that name... @@ -10811,13 +10944,20 @@ static inline int lib_getenum(lua_State *L) } else if (fastncmp("SKINCOLOR_",word,10)) { p = word+10; - for (i = 0; i < MAXTRANSLATIONS; i++) + for (i = 0; i < NUMCOLORFREESLOTS; i++) { + if (!FREE_SKINCOLORS[i]) + break; + if (fastcmp(p, FREE_SKINCOLORS[i])) { + lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT+i); + return 1; + } + } + for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++) if (fastcmp(p, COLOR_ENUMS[i])) { lua_pushinteger(L, i); return 1; } - if (mathlib) return luaL_error(L, "skincolor '%s' could not be found.\n", word); - return 0; + return luaL_error(L, "skincolor '%s' could not be found.\n", word); } else if (fastncmp("GRADE_",word,6)) { diff --git a/src/djgppdos/i_system.c b/src/djgppdos/i_system.c index dae9ed16e3b426d195bf91c8ee62890fc42d7f48..9f6972fa67663065e65fb29973d99ee60711d1aa 100644 --- a/src/djgppdos/i_system.c +++ b/src/djgppdos/i_system.c @@ -61,6 +61,8 @@ #include "../console.h" +#include "../m_menu.h" + #ifdef __GNUG__ #pragma implementation "../i_system.h" #endif @@ -555,6 +557,7 @@ void I_Error (const char *error, ...) if (demorecording) G_CheckDemoStatus(); D_QuitNetGame (); + M_FreePlayerSetupColors(); if (shutdowning) { @@ -622,6 +625,7 @@ void I_Quit (void) if (demorecording) G_CheckDemoStatus(); D_QuitNetGame (); + M_FreePlayerSetupColors(); I_ShutdownMusic(); I_ShutdownSound(); I_ShutdownCD(); diff --git a/src/doomdata.h b/src/doomdata.h index c2ee50c2eec019342c125f667e0204ea4f1193d8..77ed56bc23e853f825159ccbc60b1c7d3f98e823 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -208,10 +208,6 @@ typedef struct #define ZSHIFT 4 -extern const UINT8 Color_Index[MAXTRANSLATIONS-1][16]; -extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS]; -extern const UINT8 Color_Opposite[MAXSKINCOLORS - 1][2]; - #define NUMMAPS 1035 #endif // __DOOMDATA__ diff --git a/src/doomdef.h b/src/doomdef.h index 6112881fbd8c6b7ba445beb67065d672b6baef8c..1cb491a10ab65fe032afd9af873b6b3088f2c722 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -239,6 +239,20 @@ extern char logfilename[1024]; #define PLAYERSMASK (MAXPLAYERS-1) #define MAXPLAYERNAME 21 +#define COLORRAMPSIZE 16 +#define MAXCOLORNAME 32 +#define NUMCOLORFREESLOTS 1024 + +typedef struct skincolor_s +{ + char name[MAXCOLORNAME+1]; // Skincolor name + UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp + UINT16 invcolor; // Signpost color + UINT8 invshade; // Signpost color shade + UINT16 chatcolor; // Chat color + boolean accessible; // Accessible by the color command + setup menu +} skincolor_t; + typedef enum { SKINCOLOR_NONE = 0, @@ -317,12 +331,10 @@ typedef enum SKINCOLOR_RASPBERRY, SKINCOLOR_ROSY, - // SKINCOLOR_? - one left before we bump up against 0x39, which isn't a HARD limit anymore but would be excessive - - MAXSKINCOLORS, + FIRSTSUPERCOLOR, // Super special awesome Super flashing colors! - SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS, + SKINCOLOR_SUPERSILVER1 = FIRSTSUPERCOLOR, SKINCOLOR_SUPERSILVER2, SKINCOLOR_SUPERSILVER3, SKINCOLOR_SUPERSILVER4, @@ -376,9 +388,17 @@ typedef enum SKINCOLOR_SUPERTAN4, SKINCOLOR_SUPERTAN5, - MAXTRANSLATIONS, - NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5) -} skincolors_t; + SKINCOLOR_FIRSTFREESLOT, + SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, + + MAXSKINCOLORS, + + NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5) +} skincolornum_t; + +extern UINT16 numskincolors; + +extern skincolor_t skincolors[MAXSKINCOLORS]; // State updates, number of tics / second. // NOTE: used to setup the timer rate, see I_StartupTimer(). @@ -458,7 +478,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG; // Things that used to be in dstrings.h #define SAVEGAMENAME "srb2sav" -char savegamename[256]; +extern char savegamename[256]; // m_misc.h #ifdef GETTEXT @@ -565,10 +585,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; // None of these that are disabled in the normal build are guaranteed to work perfectly // Compile them at your own risk! -/// Backwards compatibility with SRB2CB's slope linedef types. -/// \note A simple shim that prints a warning. -#define ESLOPE_TYPESHIM - /// Allows the use of devmode in multiplayer. AKA "fishcake" //#define NETGAME_DEVMODE diff --git a/src/doomstat.h b/src/doomstat.h index 1ec03a86cd438b1425a251942e909170589809c0..fa346540cf6bb3606c53cc8c90ed048258cbe75d 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -145,7 +145,7 @@ extern INT32 tutorialanalog; // store cv_analog[0] user value extern boolean looptitle; // CTF colors. -extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering; +extern UINT16 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering; extern tic_t countdowntimer; extern boolean countdowntimeup; @@ -545,7 +545,7 @@ extern recorddata_t *mainrecords[NUMMAPS]; extern UINT8 mapvisited[NUMMAPS]; // Temporary holding place for nights data for the current map -nightsdata_t ntemprecords; +extern nightsdata_t ntemprecords; extern UINT32 token; ///< Number of tokens collected in a level extern UINT32 tokenlist; ///< List of tokens collected @@ -620,6 +620,19 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF +#define WAYPOINTSEQUENCESIZE 256 +#define NUMWAYPOINTSEQUENCES 256 +extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE]; +extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES]; + +void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint); +mobj_t *P_GetFirstWaypoint(UINT8 sequence); +mobj_t *P_GetLastWaypoint(UINT8 sequence); +mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap); +mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap); +mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo); +boolean P_IsDegeneratedWaypointSequence(UINT8 sequence); + // ===================================== // Internal parameters, used for engine. // ===================================== diff --git a/src/f_finale.c b/src/f_finale.c index 825f646b04755cbdce6222c2527dc7aed96143df..8b5a69ae4a2390419856a9366240e5eb20674c6c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2185,7 +2185,7 @@ void F_EndingDrawer(void) for (i = 0; i < 7; ++i) { UINT8* colormap; - skincolors_t col = SKINCOLOR_GREEN; + skincolornum_t col = SKINCOLOR_GREEN; switch (i) { case 1: diff --git a/src/f_finale.h b/src/f_finale.h index 63319d7d6f6b1c23541e267d0c986bdf2ca111e0..b3abf1778408a43e54fe310d28d5410f821f98da 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -162,7 +162,9 @@ extern wipestyleflags_t wipestyleflags; // Even my function names are borderline boolean F_ShouldColormapFade(void); boolean F_TryColormapFade(UINT8 wipecolor); +#ifndef NOWIPE void F_DecideWipeStyle(void); +#endif #define FADECOLORMAPDIV 8 #define FADECOLORMAPROWS (256/FADECOLORMAPDIV) diff --git a/src/f_wipe.c b/src/f_wipe.c index 08d7ed9913cf0f02058ea74d4906076ad205bf4f..01b45b0c2927e6fe6e1f054c156bd0e016a0ed48 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -464,6 +464,7 @@ void F_WipeEndScreen(void) */ boolean F_ShouldColormapFade(void) { +#ifndef NOWIPE if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set && !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading { @@ -479,11 +480,13 @@ boolean F_ShouldColormapFade(void) // Menus || gamestate == GS_TIMEATTACK); } +#endif return false; } /** Decides what wipe style to use. */ +#ifndef NOWIPE void F_DecideWipeStyle(void) { // Set default wipe style @@ -493,6 +496,7 @@ void F_DecideWipeStyle(void) if (F_ShouldColormapFade()) wipestyle = WIPESTYLE_COLORMAP; } +#endif /** Attempt to run a colormap fade, provided all the conditionals were properly met. @@ -501,6 +505,7 @@ void F_DecideWipeStyle(void) */ boolean F_TryColormapFade(UINT8 wipecolor) { +#ifndef NOWIPE if (F_ShouldColormapFade()) { #ifdef HWRENDER @@ -510,6 +515,7 @@ boolean F_TryColormapFade(UINT8 wipecolor) return true; } else +#endif { F_WipeColorFill(wipecolor); return false; @@ -608,6 +614,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) tic_t F_GetWipeLength(UINT8 wipetype) { #ifdef NOWIPE + (void)wipetype; return 0; #else static char lumpname[10] = "FADEmmss"; @@ -634,6 +641,7 @@ tic_t F_GetWipeLength(UINT8 wipetype) boolean F_WipeExists(UINT8 wipetype) { #ifdef NOWIPE + (void)wipetype; return false; #else static char lumpname[10] = "FADEmm00"; diff --git a/src/g_demo.c b/src/g_demo.c index 30bc8ca48f57d299afd94d47bc5faea7a3d36663..7c949a4c822293e50a1eef11ed1b129f19381a2a 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -68,7 +68,7 @@ static struct { UINT8 flags; // EZT flags // EZT_COLOR - UINT8 color, lastcolor; + UINT16 color, lastcolor; // EZT_SCALE fixed_t scale, lastscale; @@ -82,7 +82,8 @@ static struct { // There is no conflict here. typedef struct demoghost { UINT8 checksum[16]; - UINT8 *buffer, *p, color, fadein; + UINT8 *buffer, *p, fadein; + UINT16 color; UINT16 version; mobj_t oldmo, *mo; struct demoghost *next; @@ -93,7 +94,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x000c +#define DEMOVERSION 0x000d #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -280,13 +281,13 @@ void G_GhostAddColor(ghostcolor_t color) { if (!demorecording || !(demoflags & DF_GHOST)) return; - if (ghostext.lastcolor == (UINT8)color) + if (ghostext.lastcolor == (UINT16)color) { ghostext.flags &= ~EZT_COLOR; return; } ghostext.flags |= EZT_COLOR; - ghostext.color = (UINT8)color; + ghostext.color = (UINT16)color; } void G_GhostAddScale(fixed_t scale) @@ -425,7 +426,7 @@ void G_WriteGhostTic(mobj_t *ghost) WRITEUINT8(demo_p,ghostext.flags); if (ghostext.flags & EZT_COLOR) { - WRITEUINT8(demo_p,ghostext.color); + WRITEUINT16(demo_p,ghostext.color); ghostext.lastcolor = ghostext.color; } if (ghostext.flags & EZT_SCALE) @@ -501,7 +502,7 @@ void G_WriteGhostTic(mobj_t *ghost) WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); WRITEUINT16(demo_p,ghost->player->followmobj->sprite); WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK)); - WRITEUINT8(demo_p,ghost->player->followmobj->color); + WRITEUINT16(demo_p,ghost->player->followmobj->color); *followtic_p = followtic; } @@ -566,7 +567,7 @@ void G_ConsGhostTic(void) { // But wait, there's more! UINT8 xziptic = READUINT8(demo_p); if (xziptic & EZT_COLOR) - demo_p++; + demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16); if (xziptic & EZT_SCALE) demo_p += sizeof(fixed_t); if (xziptic & EZT_HIT) @@ -633,7 +634,7 @@ void G_ConsGhostTic(void) demo_p++; demo_p += sizeof(UINT16); demo_p++; - demo_p++; + demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16); } // Re-synchronise @@ -731,7 +732,7 @@ void G_GhostTicker(void) xziptic = READUINT8(g->p); if (xziptic & EZT_COLOR) { - g->color = READUINT8(g->p); + g->color = (g->version==0x000c) ? READUINT8(g->p) : READUINT16(g->p); switch(g->color) { default: @@ -864,7 +865,7 @@ void G_GhostTicker(void) g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); break; case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours + g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours break; default: break; @@ -918,7 +919,7 @@ void G_GhostTicker(void) follow->sprite = READUINT16(g->p); follow->frame = (READUINT8(g->p)) | (g->mo->frame & FF_TRANSMASK); follow->angle = g->mo->angle; - follow->color = READUINT8(g->p); + follow->color = (g->version==0x000c) ? READUINT8(g->p) : READUINT16(g->p); if (!(followtic & FZT_SPAWNED)) { @@ -1158,7 +1159,7 @@ void G_ReadMetalTic(mobj_t *metal) follow->sprite = READUINT16(metal_p); follow->frame = READUINT32(metal_p); // NOT & FF_FRAMEMASK here, so 32 bits follow->angle = metal->angle; - follow->color = READUINT8(metal_p); + follow->color = (metalversion==0x000c) ? READUINT8(metal_p) : READUINT16(metal_p); if (!(followtic & FZT_SPAWNED)) { @@ -1340,7 +1341,7 @@ void G_WriteMetalTic(mobj_t *metal) WRITEUINT8(demo_p,metal->player->followmobj->sprite2); WRITEUINT16(demo_p,metal->player->followmobj->sprite); WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits - WRITEUINT8(demo_p,metal->player->followmobj->color); + WRITEUINT16(demo_p,metal->player->followmobj->color); *followtic_p = followtic; } @@ -1394,7 +1395,7 @@ void G_RecordMetal(void) void G_BeginRecording(void) { UINT8 i; - char name[16]; + char name[MAXCOLORNAME+1]; player_t *player = &players[consoleplayer]; if (demo_p) @@ -1457,12 +1458,12 @@ void G_BeginRecording(void) demo_p += 16; // Color - for (i = 0; i < 16 && cv_playercolor.string[i]; i++) + for (i = 0; i < MAXCOLORNAME && cv_playercolor.string[i]; i++) name[i] = cv_playercolor.string[i]; - for (; i < 16; i++) + for (; i < MAXCOLORNAME; i++) name[i] = '\0'; - M_Memcpy(demo_p,name,16); - demo_p += 16; + M_Memcpy(demo_p,name,MAXCOLORNAME); + demo_p += MAXCOLORNAME; // Stats WRITEUINT8(demo_p,player->charability); @@ -1622,7 +1623,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) c = READUINT8(p); // SUBVERSION I_Assert(c == SUBVERSION); s = READUINT16(p); - I_Assert(s == DEMOVERSION); + I_Assert(s >= 0x000c); p += 16; // demo checksum I_Assert(!memcmp(p, "PLAY", 4)); p += 4; // PLAY @@ -1671,6 +1672,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported + case 0x000c: // all that changed between then and now was longer color name break; // too old, cannot support. default: @@ -1744,15 +1746,15 @@ void G_DoPlayDemo(char *defdemoname) { UINT8 i; lumpnum_t l; - char skin[17],color[17],*n,*pdemoname; - UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; + char skin[17],color[MAXCOLORNAME+1],*n,*pdemoname; + UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration,cnamelen; pflags_t pflags; UINT32 randseed, followitem; fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; char msg[1024]; skin[16] = '\0'; - color[16] = '\0'; + color[MAXCOLORNAME] = '\0'; n = defdemoname+strlen(defdemoname); while (*n != '/' && *n != '\\' && n != defdemoname) @@ -1810,6 +1812,11 @@ void G_DoPlayDemo(char *defdemoname) switch(demoversion) { case DEMOVERSION: // latest always supported + cnamelen = MAXCOLORNAME; + break; + // all that changed between then and now was longer color name + case 0x000c: + cnamelen = 16; break; // too old, cannot support. default: @@ -1876,8 +1883,8 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 16; // Color - M_Memcpy(color,demo_p,16); - demo_p += 16; + M_Memcpy(color,demo_p,cnamelen); + demo_p += cnamelen; charability = READUINT8(demo_p); charability2 = READUINT8(demo_p); @@ -1941,7 +1948,9 @@ void G_DoPlayDemo(char *defdemoname) // Set skin SetPlayerSkin(0, skin); +#ifdef HAVE_BLUA LUAh_MapChange(gamemap); +#endif displayplayer = consoleplayer = 0; memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; @@ -1949,8 +1958,9 @@ void G_DoPlayDemo(char *defdemoname) G_InitNew(false, G_BuildMapName(gamemap), true, true, false); // Set color - for (i = 0; i < MAXSKINCOLORS; i++) - if (!stricmp(Color_Names[i],color)) + players[0].skincolor = skins[players[0].skin].prefcolor; + for (i = 0; i < numskincolors; i++) + if (!stricmp(skincolors[i].name,color)) { players[0].skincolor = i; break; @@ -1992,7 +2002,8 @@ void G_AddGhost(char *defdemoname) { INT32 i; lumpnum_t l; - char name[17],skin[17],color[17],*n,*pdemoname,md5[16]; + char name[17],skin[17],color[MAXCOLORNAME+1],*n,*pdemoname,md5[16]; + UINT8 cnamelen; demoghost *gh; UINT8 flags; UINT8 *buffer,*p; @@ -2047,6 +2058,11 @@ void G_AddGhost(char *defdemoname) switch(ghostversion) { case DEMOVERSION: // latest always supported + cnamelen = MAXCOLORNAME; + break; + // all that changed between then and now was longer color name + case 0x000c: + cnamelen = 16; break; // too old, cannot support. default: @@ -2109,8 +2125,8 @@ void G_AddGhost(char *defdemoname) p += 16; // Color - M_Memcpy(color, p,16); - p += 16; + M_Memcpy(color, p,cnamelen); + p += cnamelen; // Ghosts do not have a player structure to put this in. p++; // charability @@ -2198,10 +2214,10 @@ void G_AddGhost(char *defdemoname) // Set color gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor; - for (i = 0; i < MAXSKINCOLORS; i++) - if (!stricmp(Color_Names[i],color)) + for (i = 0; i < numskincolors; i++) + if (!stricmp(skincolors[i].name,color)) { - gh->mo->color = (UINT8)i; + gh->mo->color = (UINT16)i; break; } gh->oldmo.color = gh->mo->color; @@ -2292,6 +2308,7 @@ void G_DoPlayMetal(void) switch(metalversion) { case DEMOVERSION: // latest always supported + case 0x000c: // all that changed between then and now was longer color name break; // too old, cannot support. default: @@ -2332,6 +2349,38 @@ void G_DoneLevelLoad(void) =================== */ +// Writes the demo's checksum, or just random garbage if you can't do that for some reason. +static void WriteDemoChecksum(void) +{ + UINT8 *p = demobuffer+16; // checksum position +#ifdef NOMD5 + UINT8 i; + for (i = 0; i < 16; i++, p++) + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. +#else + md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. +#endif +} + +// Stops recording a demo. +static void G_StopDemoRecording(void) +{ + boolean saved = false; + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker + WriteDemoChecksum(); + saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. + free(demobuffer); + demorecording = false; + + if (modeattacking != ATTACKING_RECORD) + { + if (saved) + CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); + else + CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); + } +} + // Stops metal sonic's demo. Separate from other functions because metal + replays can coexist void G_StopMetalDemo(void) { @@ -2349,20 +2398,8 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) boolean saved = false; if (demo_p) { - UINT8 *p = demobuffer+16; // checksum position - if (kill) - WRITEUINT8(demo_p, METALDEATH); // add the metal death marker - else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker -#ifdef NOMD5 - { - UINT8 i; - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. - } -#else - md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. -#endif + WRITEUINT8(demo_p, (kill) ? METALDEATH : DEMOMARKER); // add the demo end (or metal death) marker + WriteDemoChecksum(); saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. } free(demobuffer); @@ -2372,6 +2409,63 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) I_Error("Failed to save demo!"); } +// Stops timing a demo. +static void G_StopTimingDemo(void) +{ + INT32 demotime; + double f1, f2; + demotime = I_GetTime() - demostarttime; + if (!demotime) + return; + G_StopDemo(); + timingdemo = false; + f1 = (double)demotime; + f2 = (double)framecount*TICRATE; + + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), + leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + // CSV-readable timedemo results, for external parsing + if (timedemo_csv) + { + FILE *f; + const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); + const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; + const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; + boolean headerrow = !FIL_FileExists(csvpath); + UINT8 procbits = 0; + + // Bitness + if (sizeof(void*) == 4) + procbits = 32; + else if (sizeof(void*) == 8) + procbits = 64; + + f = fopen(csvpath, "a+"); + + if (f) + { + if (headerrow) + fputs(header, f); + fprintf(f, rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + fclose(f); + CONS_Printf("Timedemo results saved to '%s'\n", csvpath); + } + else + { + // Just print the CSV output to console + CON_LogMessage(header); + CONS_Printf(rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + } + } + + if (restorecv_vidwait != cv_vidwait.value) + CV_SetValue(&cv_vidwait, restorecv_vidwait); + D_AdvanceDemo(); +} + // reset engine variable set for the demos // called from stopdemo command, map command, and g_checkdemoStatus. void G_StopDemo(void) @@ -2394,66 +2488,13 @@ void G_StopDemo(void) boolean G_CheckDemoStatus(void) { - boolean saved; - G_FreeGhosts(); // DO NOT end metal sonic demos here if (timingdemo) { - INT32 demotime; - double f1, f2; - demotime = I_GetTime() - demostarttime; - if (!demotime) - return true; - G_StopDemo(); - timingdemo = false; - f1 = (double)demotime; - f2 = (double)framecount*TICRATE; - - CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), - leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); - - // CSV-readable timedemo results, for external parsing - if (timedemo_csv) - { - FILE *f; - const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); - const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; - const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; - boolean headerrow = !FIL_FileExists(csvpath); - UINT8 procbits = 0; - - // Bitness - if (sizeof(void*) == 4) - procbits = 32; - else if (sizeof(void*) == 8) - procbits = 64; - - f = fopen(csvpath, "a+"); - - if (f) - { - if (headerrow) - fputs(header, f); - fprintf(f, rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - fclose(f); - CONS_Printf("Timedemo results saved to '%s'\n", csvpath); - } - else - { - // Just print the CSV output to console - CON_LogMessage(header); - CONS_Printf(rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - } - } - - if (restorecv_vidwait != cv_vidwait.value) - CV_SetValue(&cv_vidwait, restorecv_vidwait); - D_AdvanceDemo(); + G_StopTimingDemo(); return true; } @@ -2473,27 +2514,7 @@ boolean G_CheckDemoStatus(void) if (demorecording) { - UINT8 *p = demobuffer+16; // checksum position -#ifdef NOMD5 - UINT8 i; - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. -#else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. -#endif - saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. - free(demobuffer); - demorecording = false; - - if (modeattacking != ATTACKING_RECORD) - { - if (saved) - CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); - else - CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); - } + G_StopDemoRecording(); return true; } diff --git a/src/g_game.c b/src/g_game.c index 92d71fbaeb831be0b113d48c04df59ddb258ec8d..d3cb9e7a1467b89c9bba0d9c8c08c8de50147695 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -54,7 +54,7 @@ UINT8 ultimatemode = false; boolean botingame; UINT8 botskin; -UINT8 botcolor; +UINT16 botcolor; JoyType_t Joystick; JoyType_t Joystick2; @@ -135,10 +135,10 @@ INT32 tutorialanalog = 0; // store cv_analog[0] user value boolean looptitle = false; -UINT8 skincolor_redteam = SKINCOLOR_RED; -UINT8 skincolor_blueteam = SKINCOLOR_BLUE; -UINT8 skincolor_redring = SKINCOLOR_SALMON; -UINT8 skincolor_bluering = SKINCOLOR_CORNFLOWER; +UINT16 skincolor_redteam = SKINCOLOR_RED; +UINT16 skincolor_blueteam = SKINCOLOR_BLUE; +UINT16 skincolor_redring = SKINCOLOR_SALMON; +UINT16 skincolor_bluering = SKINCOLOR_CORNFLOWER; tic_t countdowntimer = 0; boolean countdowntimeup = false; @@ -1866,6 +1866,7 @@ void G_StartTitleCard(void) // void G_PreLevelTitleCard(void) { +#ifndef NOWIPE tic_t starttime = I_GetTime(); tic_t endtime = starttime + (PRELEVELTIME*NEWTICRATERATIO); tic_t nowtime = starttime; @@ -1888,6 +1889,7 @@ void G_PreLevelTitleCard(void) } if (!cv_showhud.value) wipestyleflags = WSF_CROSSFADE; +#endif } static boolean titlecardforreload = false; @@ -2381,7 +2383,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) INT16 totalring; UINT8 laps; UINT8 mare; - UINT8 skincolor; + UINT16 skincolor; INT32 skin; UINT32 availabilities; tic_t jointime; @@ -4475,7 +4477,7 @@ cleanup: // void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS) { - UINT8 color = skins[pickedchar].prefcolor; + UINT16 color = skins[pickedchar].prefcolor; paused = false; if (demoplayback) @@ -4629,7 +4631,7 @@ char *G_BuildMapTitle(INT32 mapnum) { size_t len = 1; const char *zonetext = NULL; - const INT32 actnum = mapheaderinfo[mapnum-1]->actnum; + const UINT8 actnum = mapheaderinfo[mapnum-1]->actnum; len += strlen(mapheaderinfo[mapnum-1]->lvlttl); if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE)) diff --git a/src/g_state.h b/src/g_state.h index 3320ebc47e91e8a78be0ea45a64fd0ba46db19bb..e364c5a35b62c323464783d518bf266b2abe4185 100644 --- a/src/g_state.h +++ b/src/g_state.h @@ -57,6 +57,7 @@ extern UINT8 ultimatemode; // was sk_insane extern gameaction_t gameaction; extern boolean botingame; -extern UINT8 botskin, botcolor; +extern UINT8 botskin; +extern UINT16 botcolor; #endif //__G_STATE__ diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 69da6655a9847f48a30ced4c5141ee7a6ca5d042..df51198143f86cc9749cd1f53ae82beabf60e198 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -511,7 +511,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool // Set fixedheight to the slope's height from our viewpoint, if we have a slope if (slope) - fixedheight = P_GetZAt(slope, viewx, viewy); + fixedheight = P_GetSlopeZAt(slope, viewx, viewy); height = FIXED_TO_FLOAT(fixedheight); @@ -657,7 +657,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool \ if (slope)\ {\ - fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ + fixedheight = P_GetSlopeZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ vert->y = FIXED_TO_FLOAT(fixedheight);\ }\ } @@ -1100,8 +1100,8 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, float endpegt, endpegb, endpegmul; float endheight = 0.0f, endbheight = 0.0f; - // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly - // use this as a temp var to store P_GetZAt's return value each time + // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly + // use this as a temp var to store P_GetSlopeZAt's return value each time fixed_t temp; fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); @@ -1164,26 +1164,16 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, else solid = false; - if (list[i].slope) - { - temp = P_GetZAt(list[i].slope, v1x, v1y); - height = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(list[i].slope, v2x, v2y); - endheight = FIXED_TO_FLOAT(temp); - } - else - height = endheight = FIXED_TO_FLOAT(list[i].height); + temp = P_GetLightZAt(&list[i], v1x, v1y); + height = FIXED_TO_FLOAT(temp); + temp = P_GetLightZAt(&list[i], v2x, v2y); + endheight = FIXED_TO_FLOAT(temp); if (solid) { - if (*list[i].caster->b_slope) - { - temp = P_GetZAt(*list[i].caster->b_slope, v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(*list[i].caster->b_slope, v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); - } - else - bheight = endbheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight); + temp = P_GetFFloorBottomZAt(list[i].caster, v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetFFloorBottomZAt(list[i].caster, v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); } if (endheight >= endtop && height >= top) @@ -1196,15 +1186,10 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (i + 1 < sector->numlights) { - if (list[i+1].slope) - { - temp = P_GetZAt(list[i+1].slope, v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(list[i+1].slope, v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); - } - else - bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + temp = P_GetLightZAt(&list[i+1], v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetLightZAt(&list[i+1], v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); } else { @@ -1343,11 +1328,8 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) v2y = FLOAT_TO_FIXED(ve.y); #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, v1x, v1y); \ - end2 = P_GetZAt(slope, v2x, v2y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ + end2 = P_GetZAt(slope, v2x, v2y, normalheight); SLOPEPARAMS(gr_frontsector->c_slope, worldtop, worldtopslope, gr_frontsector->ceilingheight) SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight) @@ -1950,10 +1932,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } - h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; - hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight; - l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight; - lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight; + h = P_GetFFloorTopZAt (rover, v1x, v1y); + hS = P_GetFFloorTopZAt (rover, v2x, v2y); + l = P_GetFFloorBottomZAt(rover, v1x, v1y); + lS = P_GetFFloorBottomZAt(rover, v2x, v2y); if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut) h = hS = highcut; if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut) @@ -2091,10 +2073,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) newline = rover->master->frontsector->lines[0] + linenum; texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } - h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight; - hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight; - l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight; - lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight; + h = P_GetFFloorTopZAt (rover, v1x, v1y); + hS = P_GetFFloorTopZAt (rover, v2x, v2y); + l = P_GetFFloorBottomZAt(rover, v1x, v1y); + lS = P_GetFFloorBottomZAt(rover, v2x, v2y); if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut) h = hS = highcut; if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut) @@ -2212,24 +2194,21 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, v1x, v1y); \ - end2 = P_GetZAt(slope, v2x, v2y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ + end2 = P_GetZAt(slope, v2x, v2y, normalheight); - SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector->floorheight) + SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector-> floorheight) SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight) - SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector->floorheight) - SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight) + SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector-> floorheight) + SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight) #undef SLOPEPARAMS } else { - frontf1 = frontf2 = afrontsector->floorheight; + frontf1 = frontf2 = afrontsector-> floorheight; frontc1 = frontc2 = afrontsector->ceilingheight; - backf1 = backf2 = abacksector->floorheight; - backc1 = backc2 = abacksector->ceilingheight; + backf1 = backf2 = abacksector-> floorheight; + backc1 = backc2 = abacksector->ceilingheight; } // properly render skies (consider door "open" if both ceilings are sky) // same for floors @@ -2763,16 +2742,13 @@ static void HWR_AddLine(seg_t * line) fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, v1x, v1y); \ - end2 = P_GetZAt(slope, v2x, v2y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ + end2 = P_GetZAt(slope, v2x, v2y, normalheight); - SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector->floorheight) + SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector-> floorheight) SLOPEPARAMS(gr_frontsector->c_slope, frontc1, frontc2, gr_frontsector->ceilingheight) - SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight) - SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) + SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector-> floorheight) + SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) #undef SLOPEPARAMS // if both ceilings are skies, consider it always "open" // same for floors @@ -3330,20 +3306,10 @@ static void HWR_Subsector(size_t num) } else { - cullFloorHeight = locFloorHeight = gr_frontsector->floorheight; - cullCeilingHeight = locCeilingHeight = gr_frontsector->ceilingheight; - - if (gr_frontsector->f_slope) - { - cullFloorHeight = P_GetZAt(gr_frontsector->f_slope, viewx, viewy); - locFloorHeight = P_GetZAt(gr_frontsector->f_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } - - if (gr_frontsector->c_slope) - { - cullCeilingHeight = P_GetZAt(gr_frontsector->c_slope, viewx, viewy); - locCeilingHeight = P_GetZAt(gr_frontsector->c_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } + cullFloorHeight = P_GetSectorFloorZAt (gr_frontsector, viewx, viewy); + cullCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, viewx, viewy); + locFloorHeight = P_GetSectorFloorZAt (gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); + locCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); } // ----- end special tricks ----- @@ -3435,13 +3401,8 @@ static void HWR_Subsector(size_t num) fixed_t cullHeight, centerHeight; // bottom plane - if (*rover->b_slope) - { - cullHeight = P_GetZAt(*rover->b_slope, viewx, viewy); - centerHeight = P_GetZAt(*rover->b_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } - else - cullHeight = centerHeight = *rover->bottomheight; + cullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy); + centerHeight = P_GetFFloorBottomZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue; @@ -3501,13 +3462,8 @@ static void HWR_Subsector(size_t num) } // top plane - if (*rover->t_slope) - { - cullHeight = P_GetZAt(*rover->t_slope, viewx, viewy); - centerHeight = P_GetZAt(*rover->t_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - } - else - cullHeight = centerHeight = *rover->topheight; + cullHeight = P_GetFFloorTopZAt(rover, viewx, viewy); + centerHeight = P_GetFFloorTopZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && @@ -3906,20 +3862,21 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale UINT8 lightlevel = 255; extracolormap_t *colormap = NULL; UINT8 i; + SINT8 flip = P_MobjFlip(thing); INT32 light; fixed_t scalemul; UINT16 alpha; fixed_t floordiff; - fixed_t floorz; + fixed_t groundz; fixed_t slopez; - pslope_t *floorslope; + pslope_t *groundslope; - floorz = R_GetShadowZ(thing, &floorslope); + groundz = R_GetShadowZ(thing, &groundslope); - //if (abs(floorz - gr_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes + //if (abs(groundz - gr_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes - floordiff = abs(thing->z - floorz); + floordiff = abs((flip < 0 ? thing->height : 0) + thing->z - groundz); alpha = floordiff / (4*FRACUNIT) + 75; if (alpha >= 255) return; @@ -3951,18 +3908,18 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale shadowVerts[0].z = shadowVerts[1].z = fy - offset; shadowVerts[3].z = shadowVerts[2].z = fy + offset; - if (floorslope) + if (groundslope) { for (i = 0; i < 4; i++) { - slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); - shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f; + slopez = P_GetSlopeZAt(groundslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); + shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + flip * 0.05f; } } else { for (i = 0; i < 4; i++) - shadowVerts[i].y = FIXED_TO_FLOAT(floorz) + 0.05f; + shadowVerts[i].y = FIXED_TO_FLOAT(groundz) + flip * 0.05f; } if (spr->flip) @@ -3990,7 +3947,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale if (thing->subsector->sector->numlights) { - light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before + light = R_GetPlaneLight(thing->subsector->sector, groundz, false); // Always use the light at the top instead of whatever I was doing before if (*thing->subsector->sector->lightlist[light].lightlevel > 255) lightlevel = 255; @@ -4191,8 +4148,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) for (i = 1; i < sector->numlights; i++) { - fixed_t h = sector->lightlist[i].slope ? P_GetZAt(sector->lightlist[i].slope, spr->mobj->x, spr->mobj->y) - : sector->lightlist[i].height; + fixed_t h = P_GetLightZAt(§or->lightlist[i], spr->mobj->x, spr->mobj->y); if (h <= temp) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) @@ -4217,15 +4173,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (i + 1 < sector->numlights) { - if (list[i+1].slope) - { - temp = P_GetZAt(list[i+1].slope, v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetZAt(list[i+1].slope, v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); - } - else - bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + temp = P_GetLightZAt(&list[i+1], v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetLightZAt(&list[i+1], v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); } else { diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index b47ac09bfeb321ccc67e870bc2b5c8885aee4de7..e4ea26d861a8189c0668fcb487b907ad995ecc0f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -677,12 +677,12 @@ spritemodelfound: #define SETBRIGHTNESS(brightness,r,g,b) \ brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) -static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) +static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolornum_t color) { UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; - UINT8 translation[16]; // First the color index + UINT16 translation[16]; // First the color index UINT8 cutoff[16]; // Brightness cutoff before using the next color UINT8 translen = 0; UINT8 i; @@ -718,16 +718,16 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, if (skinnum == TC_METALSONIC) color = SKINCOLOR_COBALT; - if (color != SKINCOLOR_NONE) + if (color != SKINCOLOR_NONE && color < numskincolors) { UINT8 numdupes = 1; - translation[translen] = Color_Index[color-1][0]; + translation[translen] = skincolors[color].ramp[0]; cutoff[translen] = 255; for (i = 1; i < 16; i++) { - if (translation[translen] == Color_Index[color-1][i]) + if (translation[translen] == skincolors[color].ramp[i]) { numdupes++; continue; @@ -741,7 +741,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, numdupes = 1; translen++; - translation[translen] = (UINT8)Color_Index[color-1][i]; + translation[translen] = (UINT16)skincolors[color].ramp[i]; } translen++; @@ -1043,7 +1043,7 @@ skippixel: #undef SETBRIGHTNESS -static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color) +static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolornum_t color) { // mostly copied from HWR_GetMappedPatch, hence the similarities and comment GLMipmap_t *grmip, *newmip; @@ -1336,7 +1336,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) else skinnum = TC_BOSS; } - else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE) + else if ((skincolornum_t)spr->mobj->color != SKINCOLOR_NONE) { if (spr->mobj->colorized) skinnum = TC_RAINBOW; @@ -1356,7 +1356,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) } // Translation or skin number found - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolornum_t)spr->mobj->color); } else { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6aa5a451000a429ab351065c3c97b2d9a7fb72f4..6f2319a50cc4eb83e5aaccd77f7c9f2d81313b9c 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -68,7 +68,7 @@ patch_t *nightsnum[10]; // 0-9 // Level title and credits fonts patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; -patch_t *ttlnum[20]; // act numbers (0-19) +patch_t *ttlnum[10]; // act numbers (0-9) // Name tag fonts patch_t *ntb_font[NT_FONTSIZE]; @@ -243,7 +243,7 @@ void HU_LoadGraphics(void) tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); // cache act numbers for level titles - for (i = 0; i < 20; i++) + for (i = 0; i < 10; i++) { sprintf(buffer, "TTL%.2d", i); ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); @@ -755,113 +755,40 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } else { - const UINT8 color = players[playernum].skincolor; - - cstart = "\x83"; - - // Follow palette order at r_draw.c Color_Names - switch (color) - { - default: - case SKINCOLOR_WHITE: - case SKINCOLOR_BONE: - case SKINCOLOR_CLOUDY: - case SKINCOLOR_GREY: - case SKINCOLOR_SILVER: - case SKINCOLOR_AETHER: - case SKINCOLOR_SLATE: - cstart = "\x80"; // white - break; - case SKINCOLOR_CARBON: - case SKINCOLOR_JET: - case SKINCOLOR_BLACK: - cstart = "\x86"; // V_GRAYMAP - break; - case SKINCOLOR_PINK: - case SKINCOLOR_RUBY: - case SKINCOLOR_SALMON: - case SKINCOLOR_RED: - case SKINCOLOR_CRIMSON: - case SKINCOLOR_FLAME: - case SKINCOLOR_KETCHUP: - cstart = "\x85"; // V_REDMAP - break; - case SKINCOLOR_YOGURT: - case SKINCOLOR_BROWN: - case SKINCOLOR_BRONZE: - case SKINCOLOR_TAN: - case SKINCOLOR_BEIGE: - case SKINCOLOR_QUAIL: - cstart = "\x8d"; // V_BROWNMAP - break; - case SKINCOLOR_MOSS: - case SKINCOLOR_GREEN: - case SKINCOLOR_FOREST: - case SKINCOLOR_EMERALD: - case SKINCOLOR_MINT: - cstart = "\x83"; // V_GREENMAP - break; - case SKINCOLOR_AZURE: - cstart = "\x8c"; // V_AZUREMAP - break; - case SKINCOLOR_LAVENDER: - case SKINCOLOR_PASTEL: - case SKINCOLOR_PURPLE: - cstart = "\x89"; // V_PURPLEMAP - break; - case SKINCOLOR_PEACHY: - case SKINCOLOR_LILAC: - case SKINCOLOR_PLUM: - case SKINCOLOR_ROSY: - cstart = "\x8e"; // V_ROSYMAP - break; - case SKINCOLOR_SUNSET: - case SKINCOLOR_COPPER: - case SKINCOLOR_APRICOT: - case SKINCOLOR_ORANGE: - case SKINCOLOR_RUST: - cstart = "\x87"; // V_ORANGEMAP - break; - case SKINCOLOR_GOLD: - case SKINCOLOR_SANDY: - case SKINCOLOR_YELLOW: - case SKINCOLOR_OLIVE: - cstart = "\x82"; // V_YELLOWMAP - break; - case SKINCOLOR_LIME: - case SKINCOLOR_PERIDOT: - case SKINCOLOR_APPLE: - cstart = "\x8b"; // V_PERIDOTMAP - break; - case SKINCOLOR_SEAFOAM: - case SKINCOLOR_AQUA: - cstart = "\x8a"; // V_AQUAMAP - break; - case SKINCOLOR_TEAL: - case SKINCOLOR_WAVE: - case SKINCOLOR_CYAN: - case SKINCOLOR_SKY: - case SKINCOLOR_CERULEAN: - case SKINCOLOR_ICY: - case SKINCOLOR_SAPPHIRE: - case SKINCOLOR_VAPOR: - cstart = "\x88"; // V_SKYMAP - break; - case SKINCOLOR_CORNFLOWER: - case SKINCOLOR_BLUE: - case SKINCOLOR_COBALT: - case SKINCOLOR_DUSK: - case SKINCOLOR_BLUEBELL: - cstart = "\x84"; // V_BLUEMAP - break; - case SKINCOLOR_BUBBLEGUM: - case SKINCOLOR_MAGENTA: - case SKINCOLOR_NEON: - case SKINCOLOR_VIOLET: - case SKINCOLOR_RASPBERRY: - cstart = "\x81"; // V_MAGENTAMAP - break; - } + UINT16 chatcolor = skincolors[players[playernum].skincolor].chatcolor; + + if (!chatcolor || chatcolor%0x1000 || chatcolor>V_INVERTMAP) + cstart = "\x80"; + else if (chatcolor == V_MAGENTAMAP) + cstart = "\x81"; + else if (chatcolor == V_YELLOWMAP) + cstart = "\x82"; + else if (chatcolor == V_GREENMAP) + cstart = "\x83"; + else if (chatcolor == V_BLUEMAP) + cstart = "\x84"; + else if (chatcolor == V_REDMAP) + cstart = "\x85"; + else if (chatcolor == V_GRAYMAP) + cstart = "\x86"; + else if (chatcolor == V_ORANGEMAP) + cstart = "\x87"; + else if (chatcolor == V_SKYMAP) + cstart = "\x88"; + else if (chatcolor == V_PURPLEMAP) + cstart = "\x89"; + else if (chatcolor == V_AQUAMAP) + cstart = "\x8a"; + else if (chatcolor == V_PERIDOTMAP) + cstart = "\x8b"; + else if (chatcolor == V_AZUREMAP) + cstart = "\x8c"; + else if (chatcolor == V_BROWNMAP) + cstart = "\x8d"; + else if (chatcolor == V_ROSYMAP) + cstart = "\x8e"; + else if (chatcolor == V_INVERTMAP) + cstart = "\x8f"; } prefix = cstart; diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 9e3c667479906955a1063d478062fd06aa71cfd5..63d85f1b81a7637579a1b510a2d979f79368281c 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -85,7 +85,7 @@ extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; extern patch_t *ntb_font[NT_FONTSIZE]; extern patch_t *nto_font[NT_FONTSIZE]; -extern patch_t *ttlnum[20]; +extern patch_t *ttlnum[10]; extern patch_t *emeraldpics[3][8]; extern patch_t *rflagico; extern patch_t *bflagico; diff --git a/src/info.c b/src/info.c index d443e035d004c8437401d89d31a1e6a1186284c5..f0272fc79da8aa54131151664f5e41f278a85d5b 100644 --- a/src/info.c +++ b/src/info.c @@ -20,6 +20,7 @@ #include "m_misc.h" #include "z_zone.h" #include "d_player.h" +#include "v_video.h" // V_*MAP constants #include "lzf.h" #ifdef HWRENDER #include "hardware/hw_light.h" @@ -21616,8 +21617,140 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = #endif }; +skincolor_t skincolors[MAXSKINCOLORS] = { + {"None", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_NONE + + // Greyscale ranges + {"White", {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11}, SKINCOLOR_BLACK, 5, 0, true}, // SKINCOLOR_WHITE + {"Bone", {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12}, SKINCOLOR_JET, 7, 0, true}, // SKINCOLOR_BONE + {"Cloudy", {0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, SKINCOLOR_CARBON, 7, 0, true}, // SKINCOLOR_CLOUDY + {"Grey", {0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, SKINCOLOR_AETHER, 12, 0, true}, // SKINCOLOR_GREY + {"Silver", {0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, SKINCOLOR_SLATE, 12, 0, true}, // SKINCOLOR_SILVER + {"Carbon", {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1c, 0x1d}, SKINCOLOR_CLOUDY, 7, V_GRAYMAP, true}, // SKINCOLOR_CARBON + {"Jet", {0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f}, SKINCOLOR_BONE, 7, V_GRAYMAP, true}, // SKINCOLOR_JET + {"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK + + // Desaturated + {"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER + {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE + {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL + {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK + {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT + {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN + {"Bronze", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BRONZE + {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN + {"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE + {"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS + {"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE + {"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER + + // Viv's vivid colours (toast 21/07/17) + {"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY + {"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON + {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED + {"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON + {"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME + {"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BRONZE, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP + {"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY + {"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL + {"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET + {"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER + {"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT + {"Orange", {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE + {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST + {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD + {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY + {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW + {"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE + {"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME + {"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT + {"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE + {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN + {"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST + {"Emerald", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD + {"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT + {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM + {"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA + {"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL + {"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE + {"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN + {"Sky", {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, SKINCOLOR_SANDY, 1, V_SKYMAP, true}, // SKINCOLOR_SKY + {"Cerulean", {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, SKINCOLOR_NEON, 4, V_SKYMAP, true}, // SKINCOLOR_CERULEAN + {"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY + {"Sapphire", {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE + {"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER + {"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE + {"Cobalt", {0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT + {"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR + {"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK + {"Pastel", {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_BUBBLEGUM, 9, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL + {"Purple", {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_FLAME, 7, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE + {"Bubblegum", {0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM + {"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA + {"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON + {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET + {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC + {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 15, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY + {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY + + // super + {"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1 + {"Super Silver 2", {0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, SKINCOLOR_BLACK, 6, 0, false}, // SKINCOLOR_SUPERSILVER2 + {"Super Silver 3", {0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, SKINCOLOR_BLACK, 5, 0, false}, // SKINCOLOR_SUPERSILVER3 + {"Super Silver 4", {0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false}, // SKINCOLOR_SUPERSILVER4 + {"Super Silver 5", {0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, SKINCOLOR_BLACK, 5, V_GRAYMAP, false}, // SKINCOLOR_SUPERSILVER5 + + {"Super Red 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, SKINCOLOR_CYAN, 15, 0, false}, // SKINCOLOR_SUPERRED1 + {"Super Red 2", {0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, SKINCOLOR_CYAN, 14, V_ROSYMAP, false}, // SKINCOLOR_SUPERRED2 + {"Super Red 3", {0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, SKINCOLOR_CYAN, 13, V_REDMAP, false}, // SKINCOLOR_SUPERRED3 + {"Super Red 4", {0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, SKINCOLOR_CYAN, 11, V_REDMAP, false}, // SKINCOLOR_SUPERRED4 + {"Super Red 5", {0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, SKINCOLOR_CYAN, 10, V_REDMAP, false}, // SKINCOLOR_SUPERRED5 + + {"Super Orange 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, SKINCOLOR_SAPPHIRE, 15, 0, false}, // SKINCOLOR_SUPERORANGE1 + {"Super Orange 2", {0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, SKINCOLOR_SAPPHIRE, 12, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE2 + {"Super Orange 3", {0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, SKINCOLOR_SAPPHIRE, 9, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE3 + {"Super Orange 4", {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, SKINCOLOR_SAPPHIRE, 4, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE4 + {"Super Orange 5", {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_SAPPHIRE, 3, V_ORANGEMAP, false}, // SKINCOLOR_SUPERORANGE5 + + {"Super Gold 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, SKINCOLOR_CORNFLOWER, 15, 0, false}, // SKINCOLOR_SUPERGOLD1 + {"Super Gold 2", {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, SKINCOLOR_CORNFLOWER, 9, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD2 + {"Super Gold 3", {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD3 + {"Super Gold 4", {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD4 + {"Super Gold 5", {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, false}, // SKINCOLOR_SUPERGOLD5 + + {"Super Peridot 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, SKINCOLOR_COBALT, 15, 0, false}, // SKINCOLOR_SUPERPERIDOT1 + {"Super Peridot 2", {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, SKINCOLOR_COBALT, 4, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT2 + {"Super Peridot 3", {0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, SKINCOLOR_COBALT, 3, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT3 + {"Super Peridot 4", {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, SKINCOLOR_COBALT, 3, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT4 + {"Super Peridot 5", {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, SKINCOLOR_COBALT, 3, V_PERIDOTMAP, false}, // SKINCOLOR_SUPERPERIDOT5 + + {"Super Sky 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, SKINCOLOR_RUST, 15, 0, false}, // SKINCOLOR_SUPERSKY1 + {"Super Sky 2", {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, SKINCOLOR_RUST, 4, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY2 + {"Super Sky 3", {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY3 + {"Super Sky 4", {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY4 + {"Super Sky 5", {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, SKINCOLOR_RUST, 3, V_SKYMAP, false}, // SKINCOLOR_SUPERSKY5 + + {"Super Purple 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, SKINCOLOR_EMERALD, 15, 0, false}, // SKINCOLOR_SUPERPURPLE1 + {"Super Purple 2", {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, SKINCOLOR_EMERALD, 4, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE2 + {"Super Purple 3", {0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE3 + {"Super Purple 4", {0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE4 + {"Super Purple 5", {0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, SKINCOLOR_EMERALD, 0, V_PURPLEMAP, false}, // SKINCOLOR_SUPERPURPLE5 + + {"Super Rust 1", {0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, SKINCOLOR_CYAN, 14, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST1 + {"Super Rust 2", {0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, SKINCOLOR_CYAN, 10, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST2 + {"Super Rust 3", {0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, SKINCOLOR_CYAN, 9, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST3 + {"Super Rust 4", {0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST4 + {"Super Rust 5", {0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, SKINCOLOR_CYAN, 8, V_ORANGEMAP, false}, // SKINCOLOR_SUPERRUST5 + + {"Super Tan 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, SKINCOLOR_BROWN, 14, 0, false}, // SKINCOLOR_SUPERTAN1 + {"Super Tan 2", {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, SKINCOLOR_BROWN, 13, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN2 + {"Super Tan 3", {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, SKINCOLOR_BROWN, 12, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN3 + {"Super Tan 4", {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, SKINCOLOR_BROWN, 11, V_BROWNMAP, false}, // SKINCOLOR_SUPERTAN4 + {"Super Tan 5", {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef}, SKINCOLOR_BROWN, 10, V_BROWNMAP, false} // SKINCOLOR_SUPERTAN5 +}; -/** Patches the mobjinfo table and state table. +/** Patches the mobjinfo, state, and skincolor tables. * Free slots are emptied out and set to initial values. */ void P_PatchInfoTables(void) @@ -21645,6 +21778,11 @@ void P_PatchInfoTables(void) sprnames[i][0] = '\0'; // i == NUMSPRITES memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS); memset(&mobjinfo[MT_FIRSTFREESLOT], 0, sizeof (mobjinfo_t) * NUMMOBJFREESLOTS); + memset(&skincolors[SKINCOLOR_FIRSTFREESLOT], 0, sizeof (skincolor_t) * NUMCOLORFREESLOTS); + for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) { + skincolors[i].accessible = false; + skincolors[i].name[0] = '\0'; + } for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++) mobjinfo[i].doomednum = -1; } @@ -21653,7 +21791,8 @@ void P_PatchInfoTables(void) static char *sprnamesbackup; static state_t *statesbackup; static mobjinfo_t *mobjinfobackup; -static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize; +static skincolor_t *skincolorsbackup; +static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize, skincolorsbackupsize; #endif void P_BackupTables(void) @@ -21663,6 +21802,7 @@ void P_BackupTables(void) sprnamesbackup = Z_Malloc(sizeof(sprnames), PU_STATIC, NULL); statesbackup = Z_Malloc(sizeof(states), PU_STATIC, NULL); mobjinfobackup = Z_Malloc(sizeof(mobjinfo), PU_STATIC, NULL); + skincolorsbackup = Z_Malloc(sizeof(skincolors), PU_STATIC, NULL); // Sprite names sprnamesbackupsize = lzf_compress(sprnames, sizeof(sprnames), sprnamesbackup, sizeof(sprnames)); @@ -21684,6 +21824,13 @@ void P_BackupTables(void) mobjinfobackup = Z_Realloc(mobjinfobackup, mobjinfobackupsize, PU_STATIC, NULL); else M_Memcpy(mobjinfobackup, mobjinfo, sizeof(mobjinfo)); + + //Skincolor info + skincolorsbackupsize = lzf_compress(skincolors, sizeof(skincolors), skincolorsbackup, sizeof(skincolors)); + if (skincolorsbackupsize > 0) + skincolorsbackup = Z_Realloc(skincolorsbackup, skincolorsbackupsize, PU_STATIC, NULL); + else + M_Memcpy(skincolorsbackup, skincolors, sizeof(skincolors)); #endif } @@ -21716,5 +21863,13 @@ void P_ResetData(INT32 flags) else M_Memcpy(mobjinfo, mobjinfobackup, sizeof(mobjinfobackup)); } + + if (flags & 8) + { + if (skincolorsbackupsize > 0) + lzf_decompress(skincolorsbackup, skincolorsbackupsize, skincolors, sizeof(skincolors)); + else + M_Memcpy(skincolors, skincolorsbackup, sizeof(skincolorsbackup)); + } #endif } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 74938739c405b1d8b9d2c83d2915865b6d639931..d460f8cf715c9667d74ed3595050d0d518c2dd41 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -14,7 +14,7 @@ #include "fastcmp.h" #include "p_local.h" #include "p_setup.h" // So we can have P_SetupLevelSky -#include "p_slopes.h" // P_GetZAt +#include "p_slopes.h" // P_GetSlopeZAt #include "z_zone.h" #include "r_main.h" #include "r_draw.h" @@ -27,6 +27,7 @@ #include "hu_stuff.h" // HU_AddChatText #include "console.h" #include "d_netcmd.h" // IsPlayerAdmin +#include "m_menu.h" // Player Setup menu color stuff #include "lua_script.h" #include "lua_libs.h" @@ -144,6 +145,8 @@ static const struct { {META_STATE, "state_t"}, {META_MOBJINFO, "mobjinfo_t"}, {META_SFXINFO, "sfxinfo_t"}, + {META_SKINCOLOR, "skincolor_t"}, + {META_COLORRAMP, "skincolor_t.ramp"}, {META_SPRITEINFO, "spriteinfo_t"}, {META_PIVOTLIST, "spriteframepivot_t[]"}, {META_FRAMEPIVOT, "spriteframepivot_t"}, @@ -252,6 +255,43 @@ static int lib_reserveLuabanks(lua_State *L) return 1; } +// M_MENU +////////////// + +static int lib_pMoveColorBefore(lua_State *L) +{ + UINT16 color = (UINT16)luaL_checkinteger(L, 1); + UINT16 targ = (UINT16)luaL_checkinteger(L, 2); + + NOHUD + M_MoveColorBefore(color, targ); + return 0; +} + +static int lib_pMoveColorAfter(lua_State *L) +{ + UINT16 color = (UINT16)luaL_checkinteger(L, 1); + UINT16 targ = (UINT16)luaL_checkinteger(L, 2); + + NOHUD + M_MoveColorAfter(color, targ); + return 0; +} + +static int lib_pGetColorBefore(lua_State *L) +{ + UINT16 color = (UINT16)luaL_checkinteger(L, 1); + lua_pushinteger(L, M_GetColorBefore(color)); + return 1; +} + +static int lib_pGetColorAfter(lua_State *L) +{ + UINT16 color = (UINT16)luaL_checkinteger(L, 1); + lua_pushinteger(L, M_GetColorAfter(color)); + return 1; +} + // M_RANDOM ////////////// @@ -2184,14 +2224,20 @@ static int lib_evStartCrumble(lua_State *L) static int lib_pGetZAt(lua_State *L) { - pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); fixed_t x = luaL_checkfixed(L, 2); fixed_t y = luaL_checkfixed(L, 3); //HUDSAFE - if (!slope) - return LUA_ErrInvalid(L, "pslope_t"); + if (lua_isnil(L, 1)) + { + fixed_t z = luaL_checkfixed(L, 4); + lua_pushfixed(L, P_GetZAt(NULL, x, y, z)); + } + else + { + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + lua_pushfixed(L, P_GetSlopeZAt(slope, x, y)); + } - lua_pushfixed(L, P_GetZAt(slope, x, y)); return 1; } @@ -2382,10 +2428,10 @@ static int lib_rGetColorByName(lua_State *L) // SKINCOLOR_GREEN > "Green" for example static int lib_rGetNameByColor(lua_State *L) { - UINT8 colornum = (UINT8)luaL_checkinteger(L, 1); - if (!colornum || colornum >= MAXSKINCOLORS) - return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, MAXSKINCOLORS-1); - lua_pushstring(L, Color_Names[colornum]); + UINT16 colornum = (UINT16)luaL_checkinteger(L, 1); + if (!colornum || colornum >= numskincolors) + return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1); + lua_pushstring(L, skincolors[colornum].name); return 1; } @@ -2458,6 +2504,20 @@ static int lib_sStopSound(lua_State *L) return 0; } +static int lib_sStopSoundByID(lua_State *L) +{ + void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + sfxenum_t sound_id = luaL_checkinteger(L, 2); + //NOHUD + if (!origin) + return LUA_ErrInvalid(L, "mobj_t"); + if (sound_id >= NUMSFX) + return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1); + + S_StopSoundByID(origin, sound_id); + return 0; +} + static int lib_sChangeMusic(lua_State *L) { #ifdef MUSICSLOT_COMPATIBILITY @@ -2878,15 +2938,50 @@ static int lib_gAddGametype(lua_State *L) return 0; } +static int Lcheckmapnumber (lua_State *L, int idx, const char *fun) +{ + if (ISINLEVEL) + return luaL_optinteger(L, idx, gamemap); + else + { + if (lua_isnoneornil(L, idx)) + { + return luaL_error(L, + "%s can only be used without a parameter while in a level.", + fun + ); + } + else + return luaL_checkinteger(L, idx); + } +} + static int lib_gBuildMapName(lua_State *L) { - INT32 map = luaL_optinteger(L, 1, gamemap); + INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapName"); //HUDSAFE - INLEVEL lua_pushstring(L, G_BuildMapName(map)); return 1; } +static int lib_gBuildMapTitle(lua_State *L) +{ + INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapTitle"); + char *name; + if (map < 1 || map > NUMMAPS) + { + return luaL_error(L, + "map number %d out of range (1 - %d)", + map, + NUMMAPS + ); + } + name = G_BuildMapTitle(map); + lua_pushstring(L, name); + Z_Free(name); + return 1; +} + static int lib_gDoReborn(lua_State *L) { INT32 playernum = luaL_checkinteger(L, 1); @@ -3073,6 +3168,12 @@ static luaL_Reg lib[] = { {"IsPlayerAdmin", lib_isPlayerAdmin}, {"reserveLuabanks", lib_reserveLuabanks}, + // m_menu + {"M_MoveColorAfter",lib_pMoveColorAfter}, + {"M_MoveColorBefore",lib_pMoveColorBefore}, + {"M_GetColorAfter",lib_pGetColorAfter}, + {"M_GetColorBefore",lib_pGetColorBefore}, + // m_random {"P_RandomFixed",lib_pRandomFixed}, {"P_RandomByte",lib_pRandomByte}, @@ -3253,6 +3354,7 @@ static luaL_Reg lib[] = { {"S_StartSound",lib_sStartSound}, {"S_StartSoundAtVolume",lib_sStartSoundAtVolume}, {"S_StopSound",lib_sStopSound}, + {"S_StopSoundByID",lib_sStopSoundByID}, {"S_ChangeMusic",lib_sChangeMusic}, {"S_SpeedMusic",lib_sSpeedMusic}, {"S_StopMusic",lib_sStopMusic}, @@ -3271,6 +3373,7 @@ static luaL_Reg lib[] = { // g_game {"G_AddGametype", lib_gAddGametype}, {"G_BuildMapName",lib_gBuildMapName}, + {"G_BuildMapTitle",lib_gBuildMapTitle}, {"G_DoReborn",lib_gDoReborn}, {"G_SetCustomExitVars",lib_gSetCustomExitVars}, {"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished}, diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index d4fe72682dfe62702e9fb16a2950f672e9cd5290..b3390eb95279a6bc27a586d035f8432e1fcdaf03 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -108,6 +108,12 @@ static hook_p linedefexecutorhooks; // For other hooks, a unique linked list hook_p roothook; +static void PushHook(lua_State *L, hook_p hookp) +{ + lua_pushfstring(L, FMT_HOOKID, hookp->id); + lua_gettable(L, LUA_REGISTRYINDEX); +} + // Takes hook, function, and additional arguments (mobj type to act on, etc.) static int lib_addHook(lua_State *L) { @@ -253,6 +259,7 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) I_Assert(mo->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) @@ -260,12 +267,11 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) if (hookp->type != which) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 0)) { + if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -282,12 +288,11 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) if (hookp->type != which) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 0)) { + if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -311,18 +316,18 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which) return false; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = playerhooks; hookp; hookp = hookp->next) { if (hookp->type != which) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, plr, META_PLAYER); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 0)) { + if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -346,6 +351,7 @@ void LUAh_MapChange(INT16 mapnumber) return; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); lua_pushinteger(gL, mapnumber); for (hookp = roothook; hookp; hookp = hookp->next) @@ -353,10 +359,12 @@ void LUAh_MapChange(INT16 mapnumber) if (hookp->type != hook_MapChange) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - LUA_Call(gL, 1); + if (lua_pcall(gL, 1, 0, 1)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + } } lua_settop(gL, 0); @@ -370,6 +378,7 @@ void LUAh_MapLoad(void) return; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); lua_pushinteger(gL, gamemap); for (hookp = roothook; hookp; hookp = hookp->next) @@ -377,10 +386,12 @@ void LUAh_MapLoad(void) if (hookp->type != hook_MapLoad) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - LUA_Call(gL, 1); + if (lua_pcall(gL, 1, 0, 1)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + } } lua_settop(gL, 0); @@ -394,6 +405,7 @@ void LUAh_PlayerJoin(int playernum) return; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); lua_pushinteger(gL, playernum); for (hookp = roothook; hookp; hookp = hookp->next) @@ -401,10 +413,12 @@ void LUAh_PlayerJoin(int playernum) if (hookp->type != hook_PlayerJoin) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - LUA_Call(gL, 1); + if (lua_pcall(gL, 1, 0, 1)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + } } lua_settop(gL, 0); @@ -417,20 +431,23 @@ void LUAh_PreThinkFrame(void) if (!gL || !(hooksAvailable[hook_PreThinkFrame/8] & (1<<(hook_PreThinkFrame%8)))) return; + lua_pushcfunction(gL, LUA_GetErrorMessage); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_PreThinkFrame) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); - if (lua_pcall(gL, 0, 0, 0)) { + PushHook(gL, hookp); + if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); hookp->error = true; } } + + lua_pop(gL, 1); // Pop error handler } // Hook for frame (after mobj and player thinkers) @@ -440,22 +457,24 @@ void LUAh_ThinkFrame(void) if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) return; + lua_pushcfunction(gL, LUA_GetErrorMessage); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_ThinkFrame) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); - if (lua_pcall(gL, 0, 0, 0)) { + PushHook(gL, hookp); + if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); hookp->error = true; } } -} + lua_pop(gL, 1); // Pop error handler +} // Hook for frame (at end of tick, ie after overlays, precipitation, specials) void LUAh_PostThinkFrame(void) @@ -464,20 +483,23 @@ void LUAh_PostThinkFrame(void) if (!gL || !(hooksAvailable[hook_PostThinkFrame/8] & (1<<(hook_PostThinkFrame%8)))) return; + lua_pushcfunction(gL, LUA_GetErrorMessage); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_PostThinkFrame) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); - if (lua_pcall(gL, 0, 0, 0)) { + PushHook(gL, hookp); + if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); hookp->error = true; } } + + lua_pop(gL, 1); // Pop error handler } // Hook for mobj collisions @@ -491,6 +513,7 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) I_Assert(thing1->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj collision hooks for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) @@ -498,16 +521,15 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) if (hookp->type != which) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing1, META_MOBJ); LUA_PushUserdata(gL, thing2, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -529,16 +551,15 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) if (hookp->type != which) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing1, META_MOBJ); LUA_PushUserdata(gL, thing2, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -569,6 +590,7 @@ UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) I_Assert(thing->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj collision hooks for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) @@ -576,16 +598,15 @@ UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) if (hookp->type != which) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing, META_MOBJ); LUA_PushUserdata(gL, line, META_LINE); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -607,16 +628,15 @@ UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) if (hookp->type != which) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, thing, META_MOBJ); LUA_PushUserdata(gL, line, META_LINE); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -648,16 +668,16 @@ boolean LUAh_MobjThinker(mobj_t *mo) I_Assert(mo->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj thinker hooks for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) { - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 0)) { + if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -671,12 +691,11 @@ boolean LUAh_MobjThinker(mobj_t *mo) for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) { - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 0)) { + if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -703,6 +722,7 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) I_Assert(special->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic touch special hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) @@ -710,16 +730,15 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) if (hookp->type != hook_TouchSpecial) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -736,16 +755,15 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) if (hookp->type != hook_TouchSpecial) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -772,6 +790,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 I_Assert(target->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic should damage hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) @@ -779,7 +798,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type != hook_ShouldDamage) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); @@ -787,14 +806,13 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 lua_pushinteger(gL, damage); lua_pushinteger(gL, damagetype); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 0)) { + if (lua_pcall(gL, 5, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -815,7 +833,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 { if (hookp->type != hook_ShouldDamage) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); @@ -823,14 +841,13 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 lua_pushinteger(gL, damage); lua_pushinteger(gL, damagetype); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 0)) { + if (lua_pcall(gL, 5, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -862,6 +879,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 I_Assert(target->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj damage hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) @@ -869,7 +887,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type != hook_MobjDamage) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); @@ -877,14 +895,13 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 lua_pushinteger(gL, damage); lua_pushinteger(gL, damagetype); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 0)) { + if (lua_pcall(gL, 5, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -901,7 +918,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type != hook_MobjDamage) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); @@ -909,14 +926,13 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 lua_pushinteger(gL, damage); lua_pushinteger(gL, damagetype); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 0)) { + if (lua_pcall(gL, 5, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -943,6 +959,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 I_Assert(target->type < NUMMOBJTYPES); lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj death hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) @@ -950,20 +967,19 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 if (hookp->type != hook_MobjDeath) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damagetype); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + if (lua_pcall(gL, 4, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -980,20 +996,19 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 if (hookp->type != hook_MobjDeath) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damagetype); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + if (lua_pcall(gL, 4, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1018,22 +1033,22 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd) return false; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_BotTiccmd) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, bot, META_PLAYER); LUA_PushUserdata(gL, cmd, META_TICCMD); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1058,6 +1073,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) return false; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = roothook; hookp; hookp = hookp->next) { @@ -1065,16 +1081,15 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) || (hookp->s.str && strcmp(hookp->s.str, ((skin_t*)tails->skin)->name))) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, sonic, META_MOBJ); LUA_PushUserdata(gL, tails, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 8, 0)) { + if (lua_pcall(gL, 2, 8, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1121,22 +1136,22 @@ boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails) return false; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_BotRespawn) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, sonic, META_MOBJ); LUA_PushUserdata(gL, tails, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1166,24 +1181,27 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) return 0; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) { if (strcmp(hookp->s.str, line->text)) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, line, META_LINE); LUA_PushUserdata(gL, mo, META_MOBJ); LUA_PushUserdata(gL, sector, META_SECTOR); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); - LUA_Call(gL, 3); + if (lua_pcall(gL, 3, 0, 1)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + } hooked = true; } @@ -1200,13 +1218,14 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) return false; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_PlayerMsg) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c @@ -1224,13 +1243,12 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) } lua_pushstring(gL, msg); // msg } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + if (lua_pcall(gL, 4, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1256,6 +1274,7 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 return false; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = roothook; hookp; hookp = hookp->next) { @@ -1263,20 +1282,19 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 || (hookp->s.mt && !(inflictor && hookp->s.mt == inflictor->type))) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damagetype); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + if (lua_pcall(gL, 4, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1295,7 +1313,7 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 void LUAh_NetArchiveHook(lua_CFunction archFunc) { hook_p hookp; - + int errorhandlerindex; if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8)))) return; @@ -1303,8 +1321,11 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) I_Assert(lua_gettop(gL) > 0); I_Assert(lua_istable(gL, -1)); + lua_pushcfunction(gL, LUA_GetErrorMessage); + errorhandlerindex = lua_gettop(gL); + // tables becomes an upvalue of archFunc - lua_pushvalue(gL, -1); + lua_pushvalue(gL, -2); lua_pushcclosure(gL, archFunc, 1); // stack: tables, archFunc @@ -1313,13 +1334,15 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) if (hookp->type != hook_NetVars) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -2); // archFunc - LUA_Call(gL, 1); + if (lua_pcall(gL, 1, 0, errorhandlerindex)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + } } - lua_pop(gL, 1); // pop archFunc + lua_pop(gL, 2); // Pop archFunc and error handler // stack: tables } @@ -1331,6 +1354,7 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) return false; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj map thing spawn hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) @@ -1338,16 +1362,15 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) if (hookp->type != hook_MapThingSpawn) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, mo, META_MOBJ); LUA_PushUserdata(gL, mthing, META_MAPTHING); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1364,16 +1387,15 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) if (hookp->type != hook_MapThingSpawn) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, mo, META_MOBJ); LUA_PushUserdata(gL, mthing, META_MAPTHING); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1398,6 +1420,7 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) return 0; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); // Look for all generic mobj follow item hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) @@ -1405,16 +1428,15 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) if (hookp->type != hook_FollowMobj) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, mobj, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1431,16 +1453,15 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) if (hookp->type != hook_FollowMobj) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, mobj, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1465,22 +1486,22 @@ UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj) return 0; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = playerhooks; hookp; hookp = hookp->next) { if (hookp->type != hook_PlayerCanDamage) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, mobj, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1508,22 +1529,25 @@ void LUAh_PlayerQuit(player_t *plr, kickreason_t reason) return; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_PlayerQuit) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit lua_pushinteger(gL, reason); // Reason for quitting } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - LUA_Call(gL, 2); + if (lua_pcall(gL, 2, 0, 1)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + } } lua_settop(gL, 0); @@ -1536,20 +1560,23 @@ void LUAh_IntermissionThinker(void) if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8)))) return; + lua_pushcfunction(gL, LUA_GetErrorMessage); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_IntermissionThinker) continue; - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); - if (lua_pcall(gL, 0, 0, 0)) { + PushHook(gL, hookp); + if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); hookp->error = true; } } + + lua_pop(gL, 1); // Pop error handler } // Hook for team switching @@ -1562,13 +1589,14 @@ boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, b return true; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); for (hookp = playerhooks; hookp; hookp = hookp->next) { if (hookp->type != hook_TeamSwitch) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); lua_pushinteger(gL, newteam); @@ -1576,14 +1604,13 @@ boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, b lua_pushboolean(gL, tryingautobalance); lua_pushboolean(gL, tryingscramble); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 0)) { + if (lua_pcall(gL, 5, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1608,6 +1635,8 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean return 0; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + hud_running = true; // local hook for (hookp = playerhooks; hookp; hookp = hookp->next) @@ -1615,18 +1644,17 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean if (hookp->type != hook_ViewpointSwitch) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, newdisplayplayer, META_PLAYER); lua_pushboolean(gL, forced); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + if (lua_pcall(gL, 3, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1644,6 +1672,7 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean } lua_settop(gL, 0); + hud_running = false; return canSwitchView; @@ -1659,6 +1688,8 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) return true; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + hud_running = true; // local hook for (hookp = playerhooks; hookp; hookp = hookp->next) @@ -1666,16 +1697,15 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) if (hookp->type != hook_SeenPlayer) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, seenfriend, META_PLAYER); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1688,6 +1718,7 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) } lua_settop(gL, 0); + hud_running = false; return hasSeenPlayer; @@ -1702,6 +1733,8 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) return true; lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + hud_running = true; // local hook for (hookp = roothook; hookp; hookp = hookp->next) @@ -1710,16 +1743,15 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) || (hookp->s.str && strcmp(hookp->s.str, musname))) continue; - if (lua_gettop(gL) == 0) + if (lua_gettop(gL) == 1) { LUA_PushUserdata(gL, player, META_PLAYER); lua_pushstring(gL, musname); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + PushHook(gL, hookp); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 0)) { + if (lua_pcall(gL, 2, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1732,6 +1764,7 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) } lua_settop(gL, 0); + hud_running = false; return keepplaying; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 703b924bb908fe7b2adfeb2fe16b453fd5b05bd0..4aa70574b3802b62b22cbc4772fb11aa216cdd61 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -878,8 +878,8 @@ static int libd_drawNameTag(lua_State *L) INT32 y; const char *str; INT32 flags; - UINT8 basecolor; - UINT8 outlinecolor; + UINT16 basecolor; + UINT16 outlinecolor; UINT8 *basecolormap = NULL; UINT8 *outlinecolormap = NULL; @@ -908,8 +908,8 @@ static int libd_drawScaledNameTag(lua_State *L) const char *str; INT32 flags; fixed_t scale; - UINT8 basecolor; - UINT8 outlinecolor; + UINT16 basecolor; + UINT16 outlinecolor; UINT8 *basecolormap = NULL; UINT8 *outlinecolormap = NULL; @@ -966,7 +966,7 @@ static int libd_nameTagWidth(lua_State *L) static int libd_getColormap(lua_State *L) { INT32 skinnum = TC_DEFAULT; - skincolors_t color = luaL_optinteger(L, 2, 0); + skincolornum_t color = luaL_optinteger(L, 2, 0); UINT8* colormap = NULL; HUDONLY if (lua_isnoneornil(L, 1)) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index a82403097835cf38cb9c8c92b801c26e8724eec8..81a215c5363c96655b41782f24bb67d30aad671f 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -25,6 +25,9 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors +extern CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; +extern void R_FlushTranslationColormapCache(void); + boolean LUA_CallAction(const char *action, mobj_t *actor); state_t *astate; @@ -1465,6 +1468,229 @@ static int lib_luabankslen(lua_State *L) return 1; } +//////////////////// +// SKINCOLOR INFO // +//////////////////// + +// Arbitrary skincolors[] table index -> skincolor_t * +static int lib_getSkinColor(lua_State *L) +{ + UINT32 i; + lua_remove(L, 1); + + i = luaL_checkinteger(L, 1); + if (!i || i >= numskincolors) + return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", i, numskincolors-1); + LUA_PushUserdata(L, &skincolors[i], META_SKINCOLOR); + return 1; +} + +//Set the entire c->ramp array +static void setRamp(lua_State *L, skincolor_t* c) { + UINT32 i; + lua_pushnil(L); + for (i=0; i<COLORRAMPSIZE; i++) { + if (lua_objlen(L,-2)<COLORRAMPSIZE) { + luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' must be %d entries long; got %d.", COLORRAMPSIZE, lua_objlen(L,-2)); + break; + } + if (lua_next(L, -2) != 0) { + c->ramp[i] = lua_isnumber(L,-1) ? (UINT8)luaL_checkinteger(L,-1) : 120; + lua_pop(L, 1); + } else + c->ramp[i] = 120; + } + lua_pop(L,1); +} + +// Lua table full of data -> skincolors[] +static int lib_setSkinColor(lua_State *L) +{ + UINT32 j; + skincolor_t *info; + UINT16 cnum; //skincolor num + lua_remove(L, 1); // don't care about skincolors[] userdata. + { + cnum = (UINT16)luaL_checkinteger(L, 1); + if (cnum < SKINCOLOR_FIRSTFREESLOT || cnum >= numskincolors) + return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + info = &skincolors[cnum]; // get the skincolor to assign to. + } + luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table. + lua_remove(L, 1); // pop skincolor num, don't need it any more. + lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the skincolor. + + if (hud_running) + return luaL_error(L, "Do not alter skincolors in HUD rendering code!"); + + // clear the skincolor to start with, in case of missing table elements + memset(info,0,sizeof(skincolor_t)); + + Color_cons_t[cnum].value = cnum; + lua_pushnil(L); + while (lua_next(L, 1)) { + lua_Integer i = 0; + const char *str = NULL; + if (lua_isnumber(L, 2)) + i = lua_tointeger(L, 2); + else + str = luaL_checkstring(L, 2); + + if (i == 1 || (str && fastcmp(str,"name"))) { + const char* n = luaL_checkstring(L, 3); + strlcpy(info->name, n, MAXCOLORNAME+1); + if (strlen(n) > MAXCOLORNAME) + CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') longer than %d chars; shortened to %s.\n", n, MAXCOLORNAME, info->name); + } else if (i == 2 || (str && fastcmp(str,"ramp"))) { + if (!lua_istable(L, 3) && luaL_checkudata(L, 3, META_COLORRAMP) == NULL) + return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' must be a table or array."); + else if (lua_istable(L, 3)) + setRamp(L, info); + else + for (j=0; j<COLORRAMPSIZE; j++) + info->ramp[j] = (*((UINT8 **)luaL_checkudata(L, 3, META_COLORRAMP)))[j]; + R_FlushTranslationColormapCache(); + } else if (i == 3 || (str && fastcmp(str,"invcolor"))) + info->invcolor = (UINT16)luaL_checkinteger(L, 3); + else if (i == 4 || (str && fastcmp(str,"invshade"))) + info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE; + else if (i == 5 || (str && fastcmp(str,"chatcolor"))) + info->chatcolor = (UINT16)luaL_checkinteger(L, 3); + else if (i == 6 || (str && fastcmp(str,"accessible"))) { + boolean v = lua_isboolean(L,3) ? lua_toboolean(L, 3) : true; + if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) + return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", i); + else + info->accessible = v; + } + lua_pop(L, 1); + } + return 0; +} + +// #skincolors -> numskincolors +static int lib_skincolorslen(lua_State *L) +{ + lua_pushinteger(L, numskincolors); + return 1; +} + +// skincolor_t *, field -> number +static int skincolor_get(lua_State *L) +{ + skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR)); + const char *field = luaL_checkstring(L, 2); + + I_Assert(info != NULL); + I_Assert(info >= skincolors); + + if (fastcmp(field,"name")) + lua_pushstring(L, info->name); + else if (fastcmp(field,"ramp")) + LUA_PushUserdata(L, info->ramp, META_COLORRAMP); + else if (fastcmp(field,"invcolor")) + lua_pushinteger(L, info->invcolor); + else if (fastcmp(field,"invshade")) + lua_pushinteger(L, info->invshade); + else if (fastcmp(field,"chatcolor")) + lua_pushinteger(L, info->chatcolor); + else if (fastcmp(field,"accessible")) + lua_pushboolean(L, info->accessible); + else + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field); + return 1; +} + +// skincolor_t *, field, number -> skincolors[] +static int skincolor_set(lua_State *L) +{ + UINT32 i; + skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR)); + const char *field = luaL_checkstring(L, 2); + + I_Assert(info != NULL); + I_Assert(info >= skincolors); + + if (info-skincolors < SKINCOLOR_FIRSTFREESLOT || info-skincolors >= numskincolors) + return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", info-skincolors, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + + if (fastcmp(field,"name")) { + const char* n = luaL_checkstring(L, 3); + if (strchr(n, ' ') != NULL) + CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') contains spaces.\n", n); + strlcpy(info->name, n, MAXCOLORNAME+1); + if (strlen(n) > MAXCOLORNAME) + CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') longer than %d chars; clipped to %s.\n", n, MAXCOLORNAME, info->name); + } else if (fastcmp(field,"ramp")) { + if (!lua_istable(L, 3) && luaL_checkudata(L, 3, META_COLORRAMP) == NULL) + return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' must be a table or array."); + else if (lua_istable(L, 3)) + setRamp(L, info); + else + for (i=0; i<COLORRAMPSIZE; i++) + info->ramp[i] = (*((UINT8 **)luaL_checkudata(L, 3, META_COLORRAMP)))[i]; + R_FlushTranslationColormapCache(); + } else if (fastcmp(field,"invcolor")) + info->invcolor = (UINT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"invshade")) + info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE; + else if (fastcmp(field,"chatcolor")) + info->chatcolor = (UINT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"accessible")) + info->accessible = lua_isboolean(L,3); + else + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field); + return 1; +} + +// skincolor_t * -> SKINCOLOR_* +static int skincolor_num(lua_State *L) +{ + skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR)); + + I_Assert(info != NULL); + I_Assert(info >= skincolors); + + lua_pushinteger(L, info-skincolors); + return 1; +} + +// ramp, n -> ramp[n] +static int colorramp_get(lua_State *L) +{ + UINT8 *colorramp = *((UINT8 **)luaL_checkudata(L, 1, META_COLORRAMP)); + UINT32 n = luaL_checkinteger(L, 2); + if (n >= COLORRAMPSIZE) + return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' index %d out of range (0 - %d)", n, COLORRAMPSIZE-1); + lua_pushinteger(L, colorramp[n]); + return 1; +} + +// ramp, n, value -> ramp[n] = value +static int colorramp_set(lua_State *L) +{ + UINT8 *colorramp = *((UINT8 **)luaL_checkudata(L, 1, META_COLORRAMP)); + UINT16 cnum = (UINT16)(((uint8_t*)colorramp - (uint8_t*)(skincolors[0].ramp))/sizeof(skincolor_t)); + UINT32 n = luaL_checkinteger(L, 2); + UINT8 i = (UINT8)luaL_checkinteger(L, 3); + if (cnum < SKINCOLOR_FIRSTFREESLOT || cnum >= numskincolors) + return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + if (n >= COLORRAMPSIZE) + return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' index %d out of range (0 - %d)", n, COLORRAMPSIZE-1); + if (hud_running) + return luaL_error(L, "Do not alter skincolor_t in HUD rendering code!"); + colorramp[n] = i; + R_FlushTranslationColormapCache(); + return 0; +} + +// #ramp -> COLORRAMPSIZE +static int colorramp_len(lua_State *L) +{ + lua_pushinteger(L, COLORRAMPSIZE); + return 1; +} + ////////////////////////////// // // Now push all these functions into the Lua state! @@ -1502,6 +1728,28 @@ int LUA_InfoLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + luaL_newmetatable(L, META_SKINCOLOR); + lua_pushcfunction(L, skincolor_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, skincolor_set); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, skincolor_num); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_COLORRAMP); + lua_pushcfunction(L, colorramp_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, colorramp_set); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, colorramp_len); + lua_setfield(L, -2, "__len"); + lua_pop(L,1); + luaL_newmetatable(L, META_SFXINFO); lua_pushcfunction(L, sfxinfo_get); lua_setfield(L, -2, "__index"); @@ -1605,6 +1853,19 @@ int LUA_InfoLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "mobjinfo"); + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getSkinColor); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_setSkinColor); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, lib_skincolorslen); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "skincolors"); + lua_newuserdata(L, 0); lua_createtable(L, 0, 2); lua_pushcfunction(L, lib_getSfxInfo); diff --git a/src/lua_libs.h b/src/lua_libs.h index d0334d7255e0cbf8393211ccb4444251d0225cec..a78128e9f88bed6d1b2c99677fabc6f665ab753c 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -20,6 +20,8 @@ extern lua_State *gL; #define META_STATE "STATE_T*" #define META_MOBJINFO "MOBJINFO_T*" #define META_SFXINFO "SFXINFO_T*" +#define META_SKINCOLOR "SKINCOLOR_T*" +#define META_COLORRAMP "SKINCOLOR_T*RAMP" #define META_SPRITEINFO "SPRITEINFO_T*" #define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]" #define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*" diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 215903278107416bed4d740d644cdc27a1b120f2..76c80c541314a2914ccff349f41928bf4dcd7b9a 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -172,15 +172,14 @@ static int lib_all7emeralds(lua_State *L) return 1; } -// Whee, special Lua-exclusive function for making use of Color_Opposite[] // Returns both color and signpost shade numbers! static int lib_coloropposite(lua_State *L) { - UINT8 colornum = (UINT8)luaL_checkinteger(L, 1); - if (!colornum || colornum >= MAXSKINCOLORS) - return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, MAXSKINCOLORS-1); - lua_pushinteger(L, Color_Opposite[colornum-1][0]); // push color - lua_pushinteger(L, Color_Opposite[colornum-1][1]); // push sign shade index, 0-15 + UINT16 colornum = (UINT16)luaL_checkinteger(L, 1); + if (!colornum || colornum >= numskincolors) + return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1); + lua_pushinteger(L, skincolors[colornum].invcolor); // push color + lua_pushinteger(L, skincolors[colornum].invshade); // push sign shade index, 0-15 return 2; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 81729b7889a4dcabe9f2a394a53e76afb05eafbb..3ca3ca1d7c1293bfb9bc8ba3fddcedb56cc922a5 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -574,9 +574,9 @@ static int mobj_set(lua_State *L) } case mobj_color: { - UINT8 newcolor = (UINT8)luaL_checkinteger(L,3); - if (newcolor >= MAXTRANSLATIONS) - return luaL_error(L, "mobj.color %d out of range (0 - %d).", newcolor, MAXTRANSLATIONS-1); + UINT16 newcolor = (UINT16)luaL_checkinteger(L,3); + if (newcolor >= numskincolors) + return luaL_error(L, "mobj.color %d out of range (0 - %d).", newcolor, numskincolors-1); mo->color = newcolor; break; } @@ -829,6 +829,15 @@ static int mapthing_set(lua_State *L) return 0; } +static int mapthing_num(lua_State *L) +{ + mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); + if (!mt) + return luaL_error(L, "accessed mapthing_t doesn't exist anymore."); + lua_pushinteger(L, mt-mapthings); + return 1; +} + static int lib_iterateMapthings(lua_State *L) { size_t i = 0; @@ -893,6 +902,9 @@ int LUA_MobjLib(lua_State *L) lua_pushcfunction(L, mapthing_set); lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, mapthing_num); + lua_setfield(L, -2, "__len"); lua_pop(L,1); lua_newuserdata(L, 0); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index cdece1fb79ebf9fb27eb553f6cf45ac252655973..1ce9be525f50146735f3973bb5b36de246c5b383 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -461,9 +461,9 @@ static int player_set(lua_State *L) plr->flashpal = (UINT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"skincolor")) { - UINT8 newcolor = (UINT8)luaL_checkinteger(L,3); - if (newcolor >= MAXSKINCOLORS) - return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, MAXSKINCOLORS-1); + UINT16 newcolor = (UINT16)luaL_checkinteger(L,3); + if (newcolor >= numskincolors) + return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1); plr->skincolor = newcolor; } else if (fastcmp(field,"score")) diff --git a/src/lua_script.c b/src/lua_script.c index d2069e8a72f1f370c36b086482c2c68d8c529705..06ea18b0ee9e574604a38cc524ed4da9c185ffd5 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -78,6 +78,58 @@ FUNCNORETURN static int LUA_Panic(lua_State *L) #endif } +#define LEVELS1 12 // size of the first part of the stack +#define LEVELS2 10 // size of the second part of the stack + +// Error handler used with pcall() when loading scripts or calling hooks +// Takes a string with the original error message, +// appends the traceback to it, and return the result +int LUA_GetErrorMessage(lua_State *L) +{ + int level = 1; + int firstpart = 1; // still before eventual `...' + lua_Debug ar; + + lua_pushliteral(L, "\nstack traceback:"); + while (lua_getstack(L, level++, &ar)) + { + if (level > LEVELS1 && firstpart) + { + // no more than `LEVELS2' more levels? + if (!lua_getstack(L, level + LEVELS2, &ar)) + level--; // keep going + else + { + lua_pushliteral(L, "\n ..."); // too many levels + while (lua_getstack(L, level + LEVELS2, &ar)) // find last levels + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n "); + lua_getinfo(L, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') // is there a name? + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else + { + if (*ar.what == 'm') // main? + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); // C function or tail call + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L)); + } + lua_concat(L, lua_gettop(L)); + return 1; +} + // Moved here from lib_getenum. int LUA_PushGlobals(lua_State *L, const char *word) { @@ -410,11 +462,13 @@ static inline void LUA_LoadFile(MYFILE *f, char *name) lua_lumploading = true; // turn on loading flag - if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, 0)) { + lua_pushcfunction(gL, LUA_GetErrorMessage); + if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, lua_gettop(gL) - 1)) { CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); lua_pop(gL,1); } lua_gc(gL, LUA_GCCOLLECT, 0); + lua_pop(gL, 1); // Pop error handler lua_lumploading = false; // turn off again } @@ -756,6 +810,7 @@ enum ARCH_FFLOOR, ARCH_SLOPE, ARCH_MAPHEADER, + ARCH_SKINCOLOR, ARCH_TEND=0xFF, }; @@ -781,6 +836,7 @@ static const struct { {META_FFLOOR, ARCH_FFLOOR}, {META_SLOPE, ARCH_SLOPE}, {META_MAPHEADER, ARCH_MAPHEADER}, + {META_SKINCOLOR, ARCH_SKINCOLOR}, {NULL, ARCH_NULL} }; @@ -1068,6 +1124,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } break; } + + case ARCH_SKINCOLOR: + { + skincolor_t *info = *((skincolor_t **)lua_touserdata(gL, myindex)); + WRITEUINT8(save_p, ARCH_SKINCOLOR); + WRITEUINT16(save_p, info - skincolors); + break; + } default: WRITEUINT8(save_p, ARCH_NULL); return 2; @@ -1299,6 +1363,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_MAPHEADER: LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); break; + case ARCH_SKINCOLOR: + LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR); + break; case ARCH_TEND: return 1; } diff --git a/src/lua_script.h b/src/lua_script.h index 3166fdfc7ce03b21fc0f6f4b6a0fd081850faad7..9568503e13e33a94538254fc498e5580e24d6cb3 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -39,6 +39,7 @@ void LUA_ClearExtVars(void); extern boolean lua_lumploading; // is LUA_LoadLump being called? +int LUA_GetErrorMessage(lua_State *L); void LUA_LoadLump(UINT16 wad, UINT16 lump); #ifdef LUA_ALLOW_BYTECODE void LUA_DumpFile(const char *filename); @@ -99,5 +100,8 @@ void COM_Lua_f(void); // uncomment if you want seg_t/node_t in Lua // #define HAVE_LUA_SEGS -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ +#define ISINLEVEL \ + (gamestate == GS_LEVEL || titlemapinaction) + +#define INLEVEL if (! ISINLEVEL)\ return luaL_error(L, "This can only be used in a level!"); diff --git a/src/m_anigif.c b/src/m_anigif.c index ce2ca20b9677302f08e140f65abc6c638fd7ce89..1b71a09bce278b59741db664f334faa5075e2aec 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -490,29 +490,28 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by static UINT8 *gifframe_data = NULL; static size_t gifframe_size = 8192; +// +// GIF_rgbconvert +// converts an RGB frame to a frame with a palette. +// #ifdef HWRENDER -static void hwrconvert(void) +static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr) { - UINT8 *linear = HWR_GetScreenshot(); - UINT8 *dest = screens[2]; UINT8 r, g, b; - INT32 x, y; - size_t i = 0; + size_t src = 0, dest = 0; + size_t size = (vid.width * vid.height * 3); InitColorLUT(gif_framepalette); - for (y = 0; y < vid.height; y++) + while (src < size) { - for (x = 0; x < vid.width; x++, i += 3) - { - r = (UINT8)linear[i]; - g = (UINT8)linear[i + 1]; - b = (UINT8)linear[i + 2]; - dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; - } + r = (UINT8)linear[src]; + g = (UINT8)linear[src + 1]; + b = (UINT8)linear[src + 2]; + scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; + src += (3 * scrbuf_downscaleamt); + dest += scrbuf_downscaleamt; } - - free(linear); } #endif @@ -556,7 +555,11 @@ static void GIF_framewrite(void) I_ReadScreen(movie_screen); #ifdef HWRENDER else if (rendermode == render_opengl) - hwrconvert(); + { + UINT8 *linear = HWR_GetScreenshot(); + GIF_rgbconvert(linear, movie_screen); + free(linear); + } #endif } else @@ -565,18 +568,20 @@ static void GIF_framewrite(void) blitw = vid.width; blith = vid.height; - if (gif_frames == 0) - { - if (rendermode == render_soft) - I_ReadScreen(movie_screen); #ifdef HWRENDER - else if (rendermode == render_opengl) - { - hwrconvert(); - VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); - } -#endif + // Copy the current OpenGL frame into the base screen + if (rendermode == render_opengl) + { + UINT8 *linear = HWR_GetScreenshot(); + GIF_rgbconvert(linear, screens[0]); + free(linear); } +#endif + + // Copy the first frame into the movie screen + // OpenGL already does the same above. + if (gif_frames == 0 && rendermode == render_soft) + I_ReadScreen(movie_screen); movie_screen = screens[0]; } diff --git a/src/m_cheat.c b/src/m_cheat.c index f6fdb63e962f63ad051190ad89be384d6e05da06..3d188644b0226e16464fc5a603fee7c036ab6ab1 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -978,7 +978,7 @@ static mobjflag2_t op_oldflags2 = 0; static UINT32 op_oldeflags = 0; static fixed_t op_oldmomx = 0, op_oldmomy = 0, op_oldmomz = 0, op_oldheight = 0; static statenum_t op_oldstate = 0; -static UINT8 op_oldcolor = 0; +static UINT16 op_oldcolor = 0; // // Static calculation / common output help @@ -1032,8 +1032,8 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) if (ceiling) { // Truncate position to match where mapthing would be when spawned - // (this applies to every further P_GetZAt call as well) - fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; + // (this applies to every further P_GetSlopeZAt call as well) + fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) { @@ -1044,7 +1044,7 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) } else { - fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; + fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) { CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"), @@ -1091,12 +1091,12 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c mt->y = (INT16)(player->mo->y>>FRACBITS); if (ceiling) { - fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->ceilingheight; + fixed_t cheight = P_GetSectorCeilingZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS); mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); } else { - fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->floorheight; + fixed_t fheight = P_GetSectorFloorZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS); mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS); } mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle))); @@ -1342,12 +1342,12 @@ void OP_ObjectplaceMovement(player_t *player) if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP)) { - fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; + fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS); } else { - fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; + fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000); op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS); } op_displayflags <<= ZSHIFT; diff --git a/src/m_cond.c b/src/m_cond.c index 0abc7adf88c7ace2907b69ea4c8277a500549b99..36fcd7cf295aff241e7637d906381422121bd60a 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -523,9 +523,9 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum) return NULL; } -skincolors_t M_GetEmblemColor(emblem_t *em) +skincolornum_t M_GetEmblemColor(emblem_t *em) { - if (!em || em->color >= MAXSKINCOLORS) + if (!em || em->color >= numskincolors) return SKINCOLOR_NONE; return em->color; } @@ -549,9 +549,9 @@ const char *M_GetEmblemPatch(emblem_t *em, boolean big) return pnamebuf; } -skincolors_t M_GetExtraEmblemColor(extraemblem_t *em) +skincolornum_t M_GetExtraEmblemColor(extraemblem_t *em) { - if (!em || em->color >= MAXSKINCOLORS) + if (!em || em->color >= numskincolors) return SKINCOLOR_NONE; return em->color; } diff --git a/src/m_cond.h b/src/m_cond.h index d7b9704dd94bb4c5793302ff6204ae061d5007f0..9bb162ff317a34f40d69cc1ec37230e1d818af27 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -90,7 +90,7 @@ typedef struct INT16 tag; ///< Tag of emblem mapthing INT16 level; ///< Level on which this emblem can be found. UINT8 sprite; ///< emblem sprite to use, 0 - 25 - UINT8 color; ///< skincolor to use + UINT16 color; ///< skincolor to use INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) char hint[110]; ///< Hint for emblem hints menu UINT8 collected; ///< Do you have this emblem? @@ -102,7 +102,7 @@ typedef struct UINT8 conditionset; ///< Condition set that awards this emblem. UINT8 showconditionset; ///< Condition set that shows this emblem. UINT8 sprite; ///< emblem sprite to use, 0 - 25 - UINT8 color; ///< skincolor to use + UINT16 color; ///< skincolor to use UINT8 collected; ///< Do you have this emblem? } extraemblem_t; @@ -172,9 +172,9 @@ INT32 M_CountEmblems(void); // Emblem shit emblem_t *M_GetLevelEmblems(INT32 mapnum); -skincolors_t M_GetEmblemColor(emblem_t *em); +skincolornum_t M_GetEmblemColor(emblem_t *em); const char *M_GetEmblemPatch(emblem_t *em, boolean big); -skincolors_t M_GetExtraEmblemColor(extraemblem_t *em); +skincolornum_t M_GetExtraEmblemColor(extraemblem_t *em); const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big); // If you're looking to compare stats for unlocks or what not, use these diff --git a/src/m_menu.c b/src/m_menu.c index 2977b432f19fef2fe8010a5ad0de0ea0685b8283..f9061b2513259639aad55948a90904037a2f825f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -882,7 +882,8 @@ static menuitem_t SP_NightsAttackLevelSelectMenu[] = static menuitem_t SP_NightsAttackMenu[] = { {IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52}, - {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 62}, + {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62}, + {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 72}, {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100}, {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110}, @@ -893,6 +894,7 @@ static menuitem_t SP_NightsAttackMenu[] = enum { nalevel, + nachar, narecords, naguest, @@ -5186,7 +5188,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) { if (M_CanShowLevelOnPlatter(mapnum, gt)) { - const INT32 actnum = mapheaderinfo[mapnum]->actnum; + const UINT8 actnum = mapheaderinfo[mapnum]->actnum; const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl)); const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); @@ -7543,7 +7545,7 @@ static void M_DrawSoundTest(void) { frame[1] = (2-st_time); frame[2] = ((cv_soundtest.value - 1) % 9); - frame[3] += (((cv_soundtest.value - 1) / 9) % (MAXSKINCOLORS - frame[3])); + frame[3] += (((cv_soundtest.value - 1) / 9) % (FIRSTSUPERCOLOR - frame[3])); if (st_time < 2) st_time++; } @@ -8211,13 +8213,13 @@ static void M_DrawLoadGameData(void) { if (charskin->prefoppositecolor) { - col = charskin->prefoppositecolor - 1; - col = Color_Index[col][Color_Opposite[Color_Opposite[col][0] - 1][1]]; + col = charskin->prefoppositecolor; + col = skincolors[col].ramp[skincolors[skincolors[col].invcolor].invshade]; } else { - col = charskin->prefcolor - 1; - col = Color_Index[Color_Opposite[col][0]-1][Color_Opposite[col][1]]; + col = charskin->prefcolor; + col = skincolors[skincolors[col].invcolor].ramp[skincolors[col].invshade]; } } @@ -9053,7 +9055,7 @@ static void M_DrawSetupChoosePlayerMenu(void) skin_t *charskin = &skins[0]; INT32 skinnum = 0; - UINT8 col; + UINT16 col; UINT8 *colormap = NULL; INT32 prev = -1, next = -1; @@ -9092,10 +9094,10 @@ static void M_DrawSetupChoosePlayerMenu(void) // Use the opposite of the character's skincolor col = description[char_on].oppositecolor; if (!col) - col = Color_Opposite[charskin->prefcolor - 1][0]; + col = skincolors[charskin->prefcolor].invcolor; // Make the translation colormap - colormap = R_GetTranslationColormap(TC_DEFAULT, col, 0); + colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE); // Don't render the title map hidetitlemap = true; @@ -9143,8 +9145,8 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 ox, oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; patch_t *curpatch = NULL, *prevpatch = NULL, *nextpatch = NULL; const char *curtext = NULL, *prevtext = NULL, *nexttext = NULL; - UINT8 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0; - UINT8 curoutlinecolor = 0, prevoutlinecolor = 0, nextoutlinecolor = 0; + UINT16 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0; + UINT16 curoutlinecolor = 0, prevoutlinecolor = 0, nextoutlinecolor = 0; // Name tag curtext = description[char_on].displayname; @@ -9155,7 +9157,7 @@ static void M_DrawSetupChoosePlayerMenu(void) if (!curtextcolor) curtextcolor = charskin->prefcolor; if (!curoutlinecolor) - curoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + curoutlinecolor = col = skincolors[charskin->prefcolor].invcolor; txsh = oxsh; ox = 8 + SHORT((description[char_on].charpic)->width)/2; @@ -9171,8 +9173,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, curtextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, curtextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, GTC_CACHE), curtext ); } @@ -9194,7 +9196,7 @@ static void M_DrawSetupChoosePlayerMenu(void) if (!prevtextcolor) prevtextcolor = charskin->prefcolor; if (!prevoutlinecolor) - prevoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + prevoutlinecolor = col = skincolors[charskin->prefcolor].invcolor; x = (ox - txsh) - w; if (prevpatch) @@ -9204,8 +9206,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, GTC_CACHE), prevtext ); } @@ -9224,7 +9226,7 @@ static void M_DrawSetupChoosePlayerMenu(void) if (!nexttextcolor) nexttextcolor = charskin->prefcolor; if (!nextoutlinecolor) - nextoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + nextoutlinecolor = col = skincolors[charskin->prefcolor].invcolor; x = (ox - txsh) + w; if (nextpatch) @@ -9234,8 +9236,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, GTC_CACHE), nexttext ); } @@ -11074,15 +11076,15 @@ static UINT8 multi_spr2; // this is set before entering the MultiPlayer setup menu, // for either player 1 or 2 -static char setupm_name[MAXPLAYERNAME+1]; -static player_t *setupm_player; -static consvar_t *setupm_cvskin; -static consvar_t *setupm_cvcolor; -static consvar_t *setupm_cvname; -static consvar_t *setupm_cvdefaultskin; -static consvar_t *setupm_cvdefaultcolor; -static INT32 setupm_fakeskin; -static INT32 setupm_fakecolor; +static char setupm_name[MAXPLAYERNAME+1]; +static player_t *setupm_player; +static consvar_t *setupm_cvskin; +static consvar_t *setupm_cvcolor; +static consvar_t *setupm_cvname; +static consvar_t *setupm_cvdefaultskin; +static consvar_t *setupm_cvdefaultcolor; +static INT32 setupm_fakeskin; +static menucolor_t *setupm_fakecolor; static void M_DrawSetupMultiPlayerMenu(void) { @@ -11149,11 +11151,11 @@ static void M_DrawSetupMultiPlayerMenu(void) sprdef = &skins[setupm_fakeskin].sprites[multi_spr2]; - if (!setupm_fakecolor || !sprdef->numframes) // should never happen but hey, who knows + if (!setupm_fakecolor->color || !sprdef->numframes) // should never happen but hey, who knows goto faildraw; // ok, draw player sprite for sure now - colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, 0); + colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, 0); if (multi_frame >= sprdef->numframes) multi_frame = 0; @@ -11199,11 +11201,11 @@ colordraw: // draw color string V_DrawRightAlignedString(BASEVIDWIDTH - x, y, ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, - Color_Names[setupm_fakecolor]); + skincolors[setupm_fakecolor->color].name); if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) { - V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(Color_Names[setupm_fakecolor], V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skincolors[setupm_fakecolor->color].name, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, '\x1C' | V_YELLOWMAP, false); V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, '\x1D' | V_YELLOWMAP, false); @@ -11213,25 +11215,39 @@ colordraw: #define indexwidth 8 { - const INT32 colwidth = (282-charw)/(2*indexwidth); - INT32 i = -colwidth; - INT16 col = setupm_fakecolor - colwidth; - INT32 w = indexwidth; + const INT32 numcolors = (282-charw)/(2*indexwidth); // Number of colors per side + INT32 w = indexwidth; // Width of a singular color block + menucolor_t *mc = setupm_fakecolor->prev; // Last accessed color UINT8 h; + INT16 i; + + // Draw color in the middle + x += numcolors*w; + for (h = 0; h < 16; h++) + V_DrawFill(x, y+h, charw, 1, skincolors[setupm_fakecolor->color].ramp[h]); + + //Draw colors from middle to left + for (i=0; i<numcolors; i++) { + x -= w; + // Find accessible color before this one + while (!skincolors[mc->color].accessible) + mc = mc->prev; + for (h = 0; h < 16; h++) + V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]); + mc = mc->prev; + } - while (col < 1) - col += MAXSKINCOLORS-1; - while (i <= colwidth) - { - if (!(i++)) - w = charw; - else - w = indexwidth; + // Draw colors from middle to right + mc = setupm_fakecolor->next; + x += numcolors*w + charw; + for (i=0; i<numcolors; i++) { + // Find accessible color after this one + while (!skincolors[mc->color].accessible) + mc = mc->next; for (h = 0; h < 16; h++) - V_DrawFill(x, y+h, w, 1, Color_Index[col-1][h]); - if (++col >= MAXSKINCOLORS) - col -= MAXSKINCOLORS-1; + V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]); x += w; + mc = mc->next; } } #undef charw @@ -11242,7 +11258,7 @@ colordraw: V_DrawString(x, y, ((R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin - || setupm_cvdefaultcolor->value != setupm_fakecolor) + || setupm_cvdefaultcolor->value != setupm_fakecolor->color) ? 0 : V_TRANSLUCENT) | ((itemOn == 3) ? V_YELLOWMAP : 0), @@ -11290,19 +11306,19 @@ static void M_HandleSetupMultiPlayer(INT32 choice) else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakecolor--; + setupm_fakecolor = setupm_fakecolor->prev; } break; case KEY_ENTER: if (itemOn == 3 && (R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin - || setupm_cvdefaultcolor->value != setupm_fakecolor)) + || setupm_cvdefaultcolor->value != setupm_fakecolor->color)) { S_StartSound(NULL,sfx_strpst); // you know what? always putting these in the buffer won't hurt anything. COM_BufAddText (va("%s \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin].name)); - COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor)); + COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor->color)); break; } /* FALLTHRU */ @@ -11323,7 +11339,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice) else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakecolor++; + setupm_fakecolor = setupm_fakecolor->next; } break; @@ -11339,11 +11355,13 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } else if (itemOn == 2) { - UINT8 col = skins[setupm_fakeskin].prefcolor; - if (setupm_fakecolor != col) + UINT16 col = skins[setupm_fakeskin].prefcolor; + if ((setupm_fakecolor->color != col) && skincolors[col].accessible) { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakecolor = col; + for (setupm_fakecolor=menucolorhead;;setupm_fakecolor=setupm_fakecolor->next) + if (setupm_fakecolor->color == col || setupm_fakecolor == menucolortail) + break; } } break; @@ -11371,10 +11389,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } // check color - if (setupm_fakecolor < 1) - setupm_fakecolor = MAXSKINCOLORS-1; - if (setupm_fakecolor > MAXSKINCOLORS-1) - setupm_fakecolor = 1; + if (itemOn == 2 && !skincolors[setupm_fakecolor->color].accessible) { + if (choice == KEY_LEFTARROW) + while (!skincolors[setupm_fakecolor->color].accessible) + setupm_fakecolor = setupm_fakecolor->prev; + else if (choice == KEY_RIGHTARROW || choice == KEY_ENTER) + while (!skincolors[setupm_fakecolor->color].accessible) + setupm_fakecolor = setupm_fakecolor->next; + } if (exitmenu) { @@ -11406,7 +11428,10 @@ static void M_SetupMultiPlayer(INT32 choice) setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); if (setupm_fakeskin == -1) setupm_fakeskin = 0; - setupm_fakecolor = setupm_cvcolor->value; + + for (setupm_fakecolor=menucolorhead;;setupm_fakecolor=setupm_fakecolor->next) + if (setupm_fakecolor->color == setupm_cvcolor->value || setupm_fakecolor == menucolortail) + break; // disable skin changes if we can't actually change skins if (!CanChangeSkin(consoleplayer)) @@ -11447,7 +11472,10 @@ static void M_SetupMultiPlayer2(INT32 choice) setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); if (setupm_fakeskin == -1) setupm_fakeskin = 0; - setupm_fakecolor = setupm_cvcolor->value; + + for (setupm_fakecolor=menucolorhead;;setupm_fakecolor=setupm_fakecolor->next) + if (setupm_fakecolor->color == setupm_cvcolor->value || setupm_fakecolor == menucolortail) + break; // disable skin changes if we can't actually change skins if (splitscreen && !CanChangeSkin(secondarydisplayplayer)) @@ -11479,12 +11507,181 @@ static boolean M_QuitMultiPlayerMenu(void) setupm_name[l] =0; COM_BufAddText (va("%s \"%s\"\n",setupm_cvname->name,setupm_name)); } - // you know what? always putting these in the buffer won't hurt anything. COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name)); - COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor)); + // send color if changed + if (setupm_fakecolor->color != setupm_cvcolor->value) + COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor->color)); return true; } +void M_AddMenuColor(UINT16 color) { + menucolor_t *c; + + if (color >= numskincolors) { + CONS_Printf("M_AddMenuColor: color %d does not exist.",color); + return; + } + + c = (menucolor_t *)malloc(sizeof(menucolor_t)); + c->color = color; + if (menucolorhead == NULL) { + c->next = c; + c->prev = c; + menucolorhead = c; + menucolortail = c; + } else { + c->next = menucolorhead; + c->prev = menucolortail; + menucolortail->next = c; + menucolorhead->prev = c; + menucolortail = c; + } +} + +void M_MoveColorBefore(UINT16 color, UINT16 targ) { + menucolor_t *look, *c = NULL, *t = NULL; + + if (color == targ) + return; + if (color >= numskincolors) { + CONS_Printf("M_MoveColorBefore: color %d does not exist.",color); + return; + } + if (targ >= numskincolors) { + CONS_Printf("M_MoveColorBefore: target color %d does not exist.",targ); + return; + } + + for (look=menucolorhead;;look=look->next) { + if (look->color == color) + c = look; + else if (look->color == targ) + t = look; + if (c != NULL && t != NULL) + break; + if (look==menucolortail) + return; + } + + if (c == t->prev) + return; + + if (t==menucolorhead) + menucolorhead = c; + if (c==menucolortail) + menucolortail = c->prev; + + c->prev->next = c->next; + c->next->prev = c->prev; + + c->prev = t->prev; + c->next = t; + t->prev->next = c; + t->prev = c; +} + +void M_MoveColorAfter(UINT16 color, UINT16 targ) { + menucolor_t *look, *c = NULL, *t = NULL; + + if (color == targ) + return; + if (color >= numskincolors) { + CONS_Printf("M_MoveColorAfter: color %d does not exist.\n",color); + return; + } + if (targ >= numskincolors) { + CONS_Printf("M_MoveColorAfter: target color %d does not exist.\n",targ); + return; + } + + for (look=menucolorhead;;look=look->next) { + if (look->color == color) + c = look; + else if (look->color == targ) + t = look; + if (c != NULL && t != NULL) + break; + if (look==menucolortail) + return; + } + + if (t == c->prev) + return; + + if (t==menucolortail) + menucolortail = c; + else if (c==menucolortail) + menucolortail = c->prev; + + c->prev->next = c->next; + c->next->prev = c->prev; + + c->next = t->next; + c->prev = t; + t->next->prev = c; + t->next = c; +} + +UINT16 M_GetColorBefore(UINT16 color) { + menucolor_t *look; + + if (color >= numskincolors) { + CONS_Printf("M_GetColorBefore: color %d does not exist.\n",color); + return 0; + } + + for (look=menucolorhead;;look=look->next) { + if (look->color == color) + return look->prev->color; + if (look==menucolortail) + return 0; + } +} + +UINT16 M_GetColorAfter(UINT16 color) { + menucolor_t *look; + + if (color >= numskincolors) { + CONS_Printf("M_GetColorAfter: color %d does not exist.\n",color); + return 0; + } + + for (look=menucolorhead;;look=look->next) { + if (look->color == color) + return look->next->color; + if (look==menucolortail) + return 0; + } +} + +void M_InitPlayerSetupColors(void) { + UINT8 i; + numskincolors = SKINCOLOR_FIRSTFREESLOT; + menucolorhead = menucolortail = NULL; + for (i=0; i<numskincolors; i++) + M_AddMenuColor(i); +} + +void M_FreePlayerSetupColors(void) { + menucolor_t *look = menucolorhead, *tmp; + + if (menucolorhead==NULL) + return; + + while (true) { + if (look != menucolortail) { + tmp = look; + look = look->next; + free(tmp); + } else { + free(look); + return; + } + } + + menucolorhead = menucolortail = NULL; +} + // ================= // DATA OPTIONS MENU // ================= diff --git a/src/m_menu.h b/src/m_menu.h index 565b98945718e9612a47da82e1d306fa64a54845..cce5a6a6c12f9e28987e7016f74b7caec66f13f8 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -355,11 +355,11 @@ typedef struct // new character select char displayname[SKINNAMESIZE+1]; SINT8 skinnum[2]; - UINT8 oppositecolor; + UINT16 oppositecolor; char nametag[8]; patch_t *namepic; - UINT8 tagtextcolor; - UINT8 tagoutlinecolor; + UINT16 tagtextcolor; + UINT16 tagoutlinecolor; } description_t; // level select platter @@ -443,6 +443,23 @@ void Addons_option_Onchange(void); // Moviemode menu updating void Moviemode_option_Onchange(void); +// Player Setup menu colors linked list +typedef struct menucolor_s { + struct menucolor_s *next; + struct menucolor_s *prev; + UINT16 color; +} menucolor_t; + +extern menucolor_t *menucolorhead, *menucolortail; + +void M_AddMenuColor(UINT16 color); +void M_MoveColorBefore(UINT16 color, UINT16 targ); +void M_MoveColorAfter(UINT16 color, UINT16 targ); +UINT16 M_GetColorBefore(UINT16 color); +UINT16 M_GetColorAfter(UINT16 color); +void M_InitPlayerSetupColors(void); +void M_FreePlayerSetupColors(void); + // These defines make it a little easier to make menus #define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\ {\ diff --git a/src/mserv.h b/src/mserv.h index 6d91da64395be09b8b7eda1d87e9718767a49fdd..5f9b8da5f430f5cbc384ba3497de3845fcb5c8b6 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -68,7 +68,7 @@ extern consvar_t cv_masterserver, cv_servername; // < 0 to not connect (usually -1) (offline mode) // == 0 to show all rooms, not a valid hosting room // anything else is whatever room the MS assigns to that number (online mode) -INT16 ms_RoomId; +extern INT16 ms_RoomId; const char *GetMasterServerPort(void); const char *GetMasterServerIP(void); diff --git a/src/p_enemy.c b/src/p_enemy.c index 246ca1321bfbaee050ec0fc2645b68ac88de9500..75d32c50616da692ed88c94a7e736126823f4f77 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5106,13 +5106,13 @@ void A_SignPlayer(mobj_t *actor) INT32 locvar2 = var2; skin_t *skin = NULL; mobj_t *ov; - UINT8 facecolor, signcolor = (UINT8)locvar2; + UINT16 facecolor, signcolor = (UINT16)locvar2; UINT32 signframe = states[actor->info->raisestate].frame; if (LUA_CallAction("A_SignPlayer", actor)) return; - if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= MAXTRANSLATIONS) + if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins || signcolor >= numskincolors) return; // if no face overlay, spawn one @@ -5143,7 +5143,7 @@ void A_SignPlayer(mobj_t *actor) else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? signcolor = skin->prefoppositecolor; else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. - signcolor = Color_Opposite[actor->target->player->skincolor - 1][0]; + signcolor = skincolors[actor->target->player->skincolor].invcolor; else signcolor = SKINCOLOR_NONE; } @@ -5181,7 +5181,7 @@ void A_SignPlayer(mobj_t *actor) else if (skin->prefoppositecolor) signcolor = skin->prefoppositecolor; else if (facecolor) - signcolor = Color_Opposite[facecolor - 1][0]; + signcolor = skincolors[facecolor].invcolor; } if (skin) @@ -5212,19 +5212,8 @@ void A_SignPlayer(mobj_t *actor) } actor->tracer->color = signcolor; - /* - If you're here from the comment above Color_Opposite, - the following line is the one which is dependent on the - array being symmetrical. It gets the opposite of the - opposite of your desired colour just so it can get the - brightness frame for the End Sign. It's not a great - design choice, but it's constant time array access and - the idea that the colours should be OPPOSITES is kind - of in the name. If you have a better idea, feel free - to let me know. ~toast 2016/07/20 - */ - if (signcolor && signcolor < MAXSKINCOLORS) - signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]); + if (signcolor && signcolor < numskincolors) + signframe += (15 - skincolors[signcolor].invshade); actor->tracer->frame = signframe; } @@ -8804,10 +8793,10 @@ void A_ChangeColorRelative(mobj_t *actor) { // Have you ever seen anything so hideous? if (actor->target) - actor->color = (UINT8)(actor->color + actor->target->color); + actor->color = (UINT16)(actor->color + actor->target->color); } else - actor->color = (UINT8)(actor->color + locvar2); + actor->color = (UINT16)(actor->color + locvar2); } // Function: A_ChangeColorAbsolute @@ -8831,7 +8820,7 @@ void A_ChangeColorAbsolute(mobj_t *actor) actor->color = actor->target->color; } else - actor->color = (UINT8)locvar2; + actor->color = (UINT16)locvar2; } // Function: A_Dye @@ -8850,21 +8839,21 @@ void A_Dye(mobj_t *actor) UINT8 color = (UINT8)locvar2; if (LUA_CallAction("A_Dye", actor)) return; - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) return; - + if (!color) target->colorized = false; else target->colorized = true; - + // What if it's a player? if (target->player) { target->player->powers[pw_dye] = color; return; } - + target->color = color; } @@ -9707,6 +9696,9 @@ void A_SplitShot(mobj_t *actor) if (LUA_CallAction("A_SplitShot", actor)) return; + if (!actor->target) + return; + A_FaceTarget(actor); { const angle_t an = (actor->angle + ANGLE_90) >> ANGLETOFINESHIFT; @@ -12700,8 +12692,8 @@ void A_Boss5FindWaypoint(mobj_t *actor) else // locvar1 == 0 { fixed_t hackoffset = P_MobjFlip(actor)*56*FRACUNIT; - INT32 numwaypoints = 0; - mobj_t **waypoints; + INT32 numfangwaypoints = 0; + mobj_t **fangwaypoints; INT32 key; actor->z += hackoffset; @@ -12726,7 +12718,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (!P_CheckSight(actor, mapthings[i].mobj)) continue; - numwaypoints++; + numfangwaypoints++; } // players also count as waypoints apparently @@ -12748,11 +12740,11 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (!P_CheckSight(actor, players[i].mo)) continue; - numwaypoints++; + numfangwaypoints++; } } - if (!numwaypoints) + if (!numfangwaypoints) { // restore z position actor->z -= hackoffset; @@ -12760,8 +12752,8 @@ void A_Boss5FindWaypoint(mobj_t *actor) } // allocate the table and reset count to zero - waypoints = Z_Calloc(sizeof(*waypoints)*numwaypoints, PU_STATIC, NULL); - numwaypoints = 0; + fangwaypoints = Z_Calloc(sizeof(*waypoints)*numfangwaypoints, PU_STATIC, NULL); + numfangwaypoints = 0; // now find them again and add them to the table! for (i = 0; i < nummapthings; i++) @@ -12786,7 +12778,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) } if (!P_CheckSight(actor, mapthings[i].mobj)) continue; - waypoints[numwaypoints++] = mapthings[i].mobj; + fangwaypoints[numfangwaypoints++] = mapthings[i].mobj; } if (actor->extravalue2 > 1) @@ -12807,25 +12799,25 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (!P_CheckSight(actor, players[i].mo)) continue; - waypoints[numwaypoints++] = players[i].mo; + fangwaypoints[numfangwaypoints++] = players[i].mo; } } // restore z position actor->z -= hackoffset; - if (!numwaypoints) + if (!numfangwaypoints) { - Z_Free(waypoints); // free table + Z_Free(fangwaypoints); // free table goto nowaypoints; // ??? } - key = P_RandomKey(numwaypoints); + key = P_RandomKey(numfangwaypoints); - P_SetTarget(&actor->tracer, waypoints[key]); + P_SetTarget(&actor->tracer, fangwaypoints[key]); if (actor->tracer->type == MT_FANGWAYPOINT) - actor->tracer->reactiontime = numwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script - Z_Free(waypoints); // free table + actor->tracer->reactiontime = numfangwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script + Z_Free(fangwaypoints); // free table } // now face the tracer you just set! @@ -13369,8 +13361,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) P_ResetPlayer(player); A_PlayActiveSound(dustdevil); } + player->powers[pw_carry] = CR_DUSTDEVIL; player->powers[pw_nocontrol] = 2; - player->drawangle += ANG20; + P_SetTarget(&thing->tracer, dustdevil); P_SetPlayerMobjState(thing, S_PLAY_PAIN); if (dist > dragamount) @@ -13390,7 +13383,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) P_ResetPlayer(player); thing->z = dustdevil->z + dustdevil->height; thrust = 20 * FRACUNIT; + player->powers[pw_carry] = CR_NONE; player->powers[pw_nocontrol] = 0; + P_SetTarget(&thing->tracer, NULL); S_StartSound(thing, sfx_wdjump); P_SetPlayerMobjState(thing, S_PLAY_FALL); } diff --git a/src/p_floor.c b/src/p_floor.c index d6ffb95bfd1096379f3a836da1020c24fe8d0abc..a0f7edd9ca0e68617b1eede0441c5a14a2dbe549 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -696,10 +696,20 @@ void T_BounceCheese(bouncecheese_t *bouncer) return; } - T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight - - 70*FRACUNIT, false, true, -1); // move ceiling - T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT, - false, false, -1); // move floor + if (bouncer->speed >= 0) // move floor first to fix height desync and any bizarre bugs following that + { + T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT, + false, false, -1); // move floor + T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight - + 70*FRACUNIT, false, true, -1); // move ceiling + } + else + { + T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight - + 70*FRACUNIT, false, true, -1); // move ceiling + T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT, + false, false, -1); // move floor + } bouncer->sector->floorspeed = -bouncer->speed/2; bouncer->sector->ceilspeed = 42; @@ -2231,9 +2241,9 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) { mobj_t *spawned = NULL; if (*rover->t_slope) - topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1); + topz = P_GetSlopeZAt(*rover->t_slope, a, b) - (spacing>>1); if (*rover->b_slope) - bottomz = P_GetZAt(*rover->b_slope, a, b); + bottomz = P_GetSlopeZAt(*rover->b_slope, a, b); for (c = topz; c > bottomz; c -= spacing) { diff --git a/src/p_map.c b/src/p_map.c index 0fade484795369c806f722708964391af661aef9..b63ce84ba2a53f3ce23fbae730aad832b813c9f1 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3202,102 +3202,83 @@ isblocking: static boolean P_IsClimbingValid(player_t *player, angle_t angle) { fixed_t platx, platy; - subsector_t *glidesector; + sector_t *glidesector; fixed_t floorz, ceilingz; + mobj_t *mo = player->mo; + ffloor_t *rover; - platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); + platx = P_ReturnThrustX(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale)); + platy = P_ReturnThrustY(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale)); - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + glidesector = R_PointInSubsector(mo->x + platx, mo->y + platy)->sector; - floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; - ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; + floorz = P_GetSectorFloorZAt (glidesector, mo->x, mo->y); + ceilingz = P_GetSectorCeilingZAt(glidesector, mo->x, mo->y); - if (glidesector->sector != player->mo->subsector->sector) + if (glidesector != mo->subsector->sector) { boolean floorclimb = false; fixed_t topheight, bottomheight; - if (glidesector->sector->ffloors) + for (rover = glidesector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - for (rover = glidesector->sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) + continue; - floorclimb = true; + topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) - { - floorclimb = true; - } - if (topheight < player->mo->z) // Waaaay below the ledge. - { - floorclimb = false; - } - if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - else - { - if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) - { - floorclimb = true; - } - if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. - { - floorclimb = false; - } - if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } + floorclimb = true; - if (floorclimb) - break; + if (mo->eflags & MFE_VERTICALFLIP) + { + if ((topheight < mo->z + mo->height) && ((mo->z + mo->height + mo->momz) < topheight)) + floorclimb = true; + if (topheight < mo->z) // Waaaay below the ledge. + floorclimb = false; + if (bottomheight > mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale)) + floorclimb = false; + } + else + { + if ((bottomheight > mo->z) && ((mo->z - mo->momz) > bottomheight)) + floorclimb = true; + if (bottomheight > mo->z + mo->height) // Waaaay below the ledge. + floorclimb = false; + if (topheight < mo->z + FixedMul(16*FRACUNIT,mo->scale)) + floorclimb = false; } + + if (floorclimb) + break; } - if (player->mo->eflags & MFE_VERTICALFLIP) + if (mo->eflags & MFE_VERTICALFLIP) { - if ((floorz <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) + if ((floorz <= mo->z + mo->height) + && ((mo->z + mo->height - mo->momz) <= floorz)) floorclimb = true; - if ((floorz > player->mo->z) - && glidesector->sector->floorpic == skyflatnum) + if ((floorz > mo->z) + && glidesector->floorpic == skyflatnum) return false; - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) - || (player->mo->z + player->mo->height <= floorz)) + if ((mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale) > ceilingz) + || (mo->z + mo->height <= floorz)) floorclimb = true; } else { - if ((ceilingz >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= ceilingz)) + if ((ceilingz >= mo->z) + && ((mo->z - mo->momz) >= ceilingz)) floorclimb = true; - if ((ceilingz < player->mo->z+player->mo->height) - && glidesector->sector->ceilingpic == skyflatnum) + if ((ceilingz < mo->z+mo->height) + && glidesector->ceilingpic == skyflatnum) return false; - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) - || (player->mo->z >= ceilingz)) + if ((mo->z + FixedMul(16*FRACUNIT,mo->scale) < floorz) + || (mo->z >= ceilingz)) floorclimb = true; } @@ -3310,162 +3291,150 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) return false; } -// -// PTR_SlideTraverse -// -static boolean PTR_SlideTraverse(intercept_t *in) +static boolean PTR_LineIsBlocking(line_t *li) { - line_t *li; - - I_Assert(in->isaline); - - li = in->d.line; - // one-sided linedefs are always solid to sliding movement. - // one-sided linedef if (!li->backsector) - { - if (P_PointOnLineSide(slidemo->x, slidemo->y, li)) - return true; // don't hit the back side - goto isblocking; - } + return !P_PointOnLineSide(slidemo->x, slidemo->y, li); if (!(slidemo->flags & MF_MISSILE)) { if (li->flags & ML_IMPASSIBLE) - goto isblocking; + return true; if ((slidemo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) - goto isblocking; + return true; } // set openrange, opentop, openbottom P_LineOpening(li, slidemo); if (openrange < slidemo->height) - goto isblocking; // doesn't fit + return true; // doesn't fit if (opentop - slidemo->z < slidemo->height) - goto isblocking; // mobj is too high + return true; // mobj is too high if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) - goto isblocking; // too big a step up + return true; // too big a step up - // this line doesn't block movement - return true; + return false; +} - // the line does block movement, - // see if it is closer than best so far -isblocking: - if (li->polyobj && slidemo->player) - { - if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) - P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); - } +static void PTR_GlideClimbTraverse(line_t *li) +{ + line_t *checkline = li; + ffloor_t *rover; + fixed_t topheight, bottomheight; + boolean fofline = false; + sector_t *checksector = (li->backsector && !P_PointOnLineSide(slidemo->x, slidemo->y, li)) ? li->backsector : li->frontsector; - if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) - && slidemo->player->charability == CA_GLIDEANDCLIMB) + if (checksector->ffloors) { - line_t *checkline = li; - sector_t *checksector; - ffloor_t *rover; - fixed_t topheight, bottomheight; - boolean fofline = false; - INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - if (!side && li->backsector) - checksector = li->backsector; - else - checksector = li->frontsector; - - if (checksector->ffloors) + for (rover = checksector->ffloors; rover; rover = rover->next) { - for (rover = checksector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) + continue; - if (topheight < slidemo->z) - continue; + topheight = P_GetFFloorTopZAt (rover, slidemo->x, slidemo->y); + bottomheight = P_GetFFloorBottomZAt(rover, slidemo->x, slidemo->y); - if (bottomheight > slidemo->z + slidemo->height) - continue; + if (topheight < slidemo->z) + continue; - // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? - if (rover->master->flags & ML_TFERLINE) - { - size_t linenum = li-checksector->lines[0]; - checkline = rover->master->frontsector->lines[0] + linenum; - fofline = true; - } + if (bottomheight > slidemo->z + slidemo->height) + continue; - break; + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? + if (rover->master->flags & ML_TFERLINE) + { + size_t linenum = li-checksector->lines[0]; + checkline = rover->master->frontsector->lines[0] + linenum; + fofline = true; } + + break; } + } - // see about climbing on the wall - if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) - { - boolean canclimb; - angle_t climbangle, climbline; - INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); + // see about climbing on the wall + if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) + { + boolean canclimb; + angle_t climbangle, climbline; + INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); - climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); + climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); - if (whichside) // on second side? - climbline += ANGLE_180; + if (whichside) // on second side? + climbline += ANGLE_180; - climbangle += (ANGLE_90 * (whichside ? -1 : 1)); + climbangle += (ANGLE_90 * (whichside ? -1 : 1)); - canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); + canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); - if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) + if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) && canclimb) + { + slidemo->angle = climbangle; + /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) { - slidemo->angle = climbangle; - /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - }*/ + if (slidemo->player == &players[consoleplayer]) + localangle = slidemo->angle; + else if (slidemo->player == &players[secondarydisplayplayer]) + localangle2 = slidemo->angle; + }*/ - if (!slidemo->player->climbing) - { - S_StartSound(slidemo->player->mo, sfx_s3k4a); - slidemo->player->climbing = 5; - } - - slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); - slidemo->player->glidetime = 0; - slidemo->player->secondjump = 0; + if (!slidemo->player->climbing) + { + S_StartSound(slidemo->player->mo, sfx_s3k4a); + slidemo->player->climbing = 5; + } - if (slidemo->player->climbing > 1) - slidemo->momz = slidemo->momx = slidemo->momy = 0; + slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); + slidemo->player->glidetime = 0; + slidemo->player->secondjump = 0; - if (fofline) - whichside = 0; + if (slidemo->player->climbing > 1) + slidemo->momz = slidemo->momx = slidemo->momy = 0; - if (!whichside) - { - slidemo->player->lastsidehit = checkline->sidenum[whichside]; - slidemo->player->lastlinehit = (INT16)(checkline - lines); - } + if (fofline) + whichside = 0; - P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); + if (!whichside) + { + slidemo->player->lastsidehit = checkline->sidenum[whichside]; + slidemo->player->lastlinehit = (INT16)(checkline - lines); } + + P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); } } +} + +static boolean PTR_SlideTraverse(intercept_t *in) +{ + line_t *li; + + I_Assert(in->isaline); + + li = in->d.line; + + if (!PTR_LineIsBlocking(li)) + return true; + + // the line blocks movement, + // see if it is closer than best so far + if (li->polyobj && slidemo->player) + { + if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) + P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); + } + + if (slidemo->player && slidemo->player->charability == CA_GLIDEANDCLIMB + && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)) + PTR_GlideClimbTraverse(li); if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) { @@ -3596,9 +3565,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) if (rover->master->flags & ML_BLOCKMONSTERS) continue; - topheight = *rover->t_slope ? - P_GetZAt(*rover->t_slope, mo->x, mo->y) : - *rover->topheight; + topheight = P_GetFFloorTopZAt(rover, mo->x, mo->y); if (mo->eflags & MFE_VERTICALFLIP) { @@ -3611,9 +3578,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) continue; } - bottomheight = *rover->b_slope ? - P_GetZAt(*rover->b_slope, mo->x, mo->y) : - *rover->bottomheight; + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); if (mo->eflags & MFE_VERTICALFLIP) { @@ -4199,11 +4164,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) topheight = *rover->topheight; bottomheight = *rover->bottomheight; - - /*if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, thing->x, thing->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);*/ + //topheight = P_GetFFloorTopZAt (rover, thing->x, thing->y); + //bottomheight = P_GetFFloorBottomZAt(rover, thing->x, thing->y); delta1 = thing->z - (bottomheight + topheight)/2; delta2 = thingtop - (bottomheight + topheight)/2; @@ -4980,10 +4942,7 @@ void P_MapEnd(void) fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) { sector_t *sec = R_PointInSubsector(x, y)->sector; - fixed_t floorz = sec->floorheight; - - if (sec->f_slope) - floorz = P_GetZAt(sec->f_slope, x, y); + fixed_t floorz = P_GetSectorFloorZAt(sec, x, y); // Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002 if (sec->ffloors) @@ -5000,13 +4959,8 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) continue; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, x, y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, x, y); + topheight = P_GetFFloorTopZAt (rover, x, y); + bottomheight = P_GetFFloorBottomZAt(rover, x, y); if (rover->flags & FF_QUICKSAND) { diff --git a/src/p_maputl.c b/src/p_maputl.c index b0289db36c7b3598f41c696c5f76d025512482c8..c6e064d184a722ef2c6fb371ff7e5f9767f2afcd 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -303,45 +303,33 @@ void P_CameraLineOpening(line_t *linedef) // If you can see through it, why not move the camera through it too? if (front->camsec >= 0) { - frontfloor = sectors[front->camsec].floorheight; - frontceiling = sectors[front->camsec].ceilingheight; - if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y); - if (sectors[front->camsec].c_slope) - frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetSectorFloorZAt (§ors[front->camsec], camera.x, camera.y); + frontceiling = P_GetSectorCeilingZAt(§ors[front->camsec], camera.x, camera.y); } else if (front->heightsec >= 0) { - frontfloor = sectors[front->heightsec].floorheight; - frontceiling = sectors[front->heightsec].ceilingheight; - if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y); - if (sectors[front->heightsec].c_slope) - frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetSectorFloorZAt (§ors[front->heightsec], camera.x, camera.y); + frontceiling = P_GetSectorCeilingZAt(§ors[front->heightsec], camera.x, camera.y); } else { - frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef); + frontfloor = P_CameraGetFloorZ (mapcampointer, front, tmx, tmy, linedef); frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef); } if (back->camsec >= 0) { - backfloor = sectors[back->camsec].floorheight; - backceiling = sectors[back->camsec].ceilingheight; - if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y); - if (sectors[back->camsec].c_slope) - frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope) + backfloor = P_GetSectorFloorZAt (§ors[back->camsec], camera.x, camera.y); + backceiling = P_GetSectorCeilingZAt(§ors[back->camsec], camera.x, camera.y); } else if (back->heightsec >= 0) { - backfloor = sectors[back->heightsec].floorheight; - backceiling = sectors[back->heightsec].ceilingheight; - if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y); - if (sectors[back->heightsec].c_slope) - frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y); + // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope) + backfloor = P_GetSectorFloorZAt (§ors[back->heightsec], camera.x, camera.y); + backceiling = P_GetSectorCeilingZAt(§ors[back->heightsec], camera.x, camera.y); } else { diff --git a/src/p_mobj.c b/src/p_mobj.c index 78e0ccd41b868f62c2eed19d9f894c0e2d80fb8c..983d1f9a64c40ca5a0eaff6bfff353c290f54cdc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -436,7 +436,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->sprite2 = spr2; mobj->frame = frame|(st->frame&~FF_FRAMEMASK); - if (mobj->color >= MAXSKINCOLORS && mobj->color < MAXTRANSLATIONS) // Super colours? Super bright! + if (mobj->color >= FIRSTSUPERCOLOR && mobj->color < numskincolors) // Super colours? Super bright! mobj->frame |= FF_FULLBRIGHT; } // Regular sprites @@ -926,13 +926,8 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) return false; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); + topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); + bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); if (mobj->z > topheight) return false; @@ -963,12 +958,12 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, /*CONS_Printf("BEFORE: v1 = %f %f %f\n", FIXED_TO_FLOAT(v1.x), FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y)) ); CONS_Printf(" v2 = %f %f %f\n", FIXED_TO_FLOAT(v2.x), FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y)) );*/ if (abs(v1.x-x) > radius) { @@ -1026,24 +1021,24 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, /*CONS_Printf("AFTER: v1 = %f %f %f\n", FIXED_TO_FLOAT(v1.x), FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y)) ); CONS_Printf(" v2 = %f %f %f\n", FIXED_TO_FLOAT(v2.x), FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y)) );*/ // Return the higher of the two points if (actuallylowest) return min( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) + P_GetSlopeZAt(slope, v1.x, v1.y), + P_GetSlopeZAt(slope, v2.x, v2.y) ); else return max( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) + P_GetSlopeZAt(slope, v1.x, v1.y), + P_GetSlopeZAt(slope, v2.x, v2.y) ); } @@ -1077,7 +1072,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1117,7 +1112,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height @@ -1154,7 +1149,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1194,7 +1189,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height @@ -1232,7 +1227,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1272,7 +1267,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height @@ -1309,7 +1304,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f // If the highest point is in the sector, then we have it easy! Just get the Z at that point if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) - return P_GetZAt(slope, testx, testy); + return P_GetSlopeZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point if (perfect) { @@ -1349,7 +1344,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) - return P_GetZAt(slope, x, y); + return P_GetSlopeZAt(slope, x, y); return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height @@ -1674,70 +1669,74 @@ static void P_PushableCheckBustables(mobj_t *mo) for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + fixed_t topheight, bottomheight; + if (!node->m_sector) break; - if (node->m_sector->ffloors) + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) + continue; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_BUSTUP)) + continue; - if (!(rover->flags & FF_BUSTUP)) continue; + // Needs ML_EFFECT4 flag for pushables to break it + if (!(rover->master->flags & ML_EFFECT4)) + continue; - // Needs ML_EFFECT4 flag for pushables to break it - if (!(rover->master->flags & ML_EFFECT4)) continue; + if (rover->master->frontsector->crumblestate != CRUMBLE_NONE) + continue; - if (rover->master->frontsector->crumblestate == CRUMBLE_NONE) - { - topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); - bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); - // Height checks - if (rover->flags & FF_SHATTERBOTTOM) - { - if (mo->z+mo->momz + mo->height < bottomheight) - continue; + topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); + bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); - if (mo->z+mo->height > bottomheight) - continue; - } - else if (rover->flags & FF_SPINBUST) - { - if (mo->z+mo->momz > topheight) - continue; + // Height checks + if (rover->flags & FF_SHATTERBOTTOM) + { + if (mo->z + mo->momz + mo->height < bottomheight) + continue; - if (mo->z+mo->height < bottomheight) - continue; - } - else if (rover->flags & FF_SHATTER) - { - if (mo->z+mo->momz > topheight) - continue; + if (mo->z + mo->height > bottomheight) + continue; + } + else if (rover->flags & FF_SPINBUST) + { + if (mo->z + mo->momz > topheight) + continue; - if (mo->z+mo->momz + mo->height < bottomheight) - continue; - } - else - { - if (mo->z >= topheight) - continue; + if (mo->z + mo->height < bottomheight) + continue; + } + else if (rover->flags & FF_SHATTER) + { + if (mo->z + mo->momz > topheight) + continue; - if (mo->z+mo->height < bottomheight) - continue; - } + if (mo->z + mo->momz + mo->height < bottomheight) + continue; + } + else + { + if (mo->z >= topheight) + continue; + + if (mo->z + mo->height < bottomheight) + continue; + } - EV_CrumbleChain(NULL, rover); // node->m_sector + EV_CrumbleChain(NULL, rover); // node->m_sector - // Run a linedef executor?? - if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); + // Run a linedef executor?? + if (rover->master->flags & ML_EFFECT5) + P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); - goto bustupdone; - } - } + goto bustupdone; } } bustupdone: @@ -2798,6 +2797,94 @@ static boolean P_ZMovement(mobj_t *mo) return true; } +// Check for "Mario" blocks to hit and bounce them +static void P_CheckMarioBlocks(mobj_t *mo) +{ + msecnode_t *node; + + if (netgame && mo->player->spectator) + return; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_MARIO)) + continue; + + if (mo->eflags & MFE_VERTICALFLIP) + continue; // if you were flipped, your head isn't actually hitting your ceilingz is it? + + if (*rover->bottomheight != mo->ceilingz) + continue; + + if (rover->flags & FF_SHATTERBOTTOM) // Brick block! + EV_CrumbleChain(node->m_sector, rover); + else // Question block! + EV_MarioBlock(rover, node->m_sector, mo); + } + } +} + +// Check if we're on a polyobject that triggers a linedef executor. +static boolean P_PlayerPolyObjectZMovement(mobj_t *mo) +{ + msecnode_t *node; + boolean stopmovecut = false; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + sector_t *sec = node->m_sector; + subsector_t *newsubsec; + size_t i; + + for (i = 0; i < numsubsectors; i++) + { + polyobj_t *po; + sector_t *polysec; + newsubsec = &subsectors[i]; + + if (newsubsec->sector != sec) + continue; + + for (po = newsubsec->polyList; po; po = (polyobj_t *)(po->link.next)) + { + if (!(po->flags & POF_SOLID)) + continue; + + if (!P_MobjInsidePolyobj(po, mo)) + continue; + + polysec = po->lines[0]->backsector; + + // Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red + if ((mo->z == polysec->ceilingheight || mo->z + mo->height == polysec->floorheight) && po->thinker) + stopmovecut = true; + + if (!(po->flags & POF_LDEXEC)) + continue; + + if (mo->z != polysec->ceilingheight) + continue; + + // 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); + } + } + } + + return stopmovecut; +} + static void P_PlayerZMovement(mobj_t *mo) { boolean onground; @@ -2894,66 +2981,8 @@ static void P_PlayerZMovement(mobj_t *mo) mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack + if (!P_PlayerPolyObjectZMovement(mo)) { - // Check if we're on a polyobject - // that triggers a linedef executor. - msecnode_t *node; - boolean stopmovecut = false; - - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - sector_t *sec = node->m_sector; - subsector_t *newsubsec; - size_t i; - - for (i = 0; i < numsubsectors; i++) - { - newsubsec = &subsectors[i]; - - if (newsubsec->sector != sec) - continue; - - if (newsubsec->polyList) - { - polyobj_t *po = newsubsec->polyList; - sector_t *polysec; - - while(po) - { - if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - // We're inside it! Yess... - polysec = po->lines[0]->backsector; - - // Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red - if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && po->thinker) - stopmovecut = true; - - if (!(po->flags & POF_LDEXEC)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - 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); - } - - po = (polyobj_t *)(po->link.next); - } - } - } - } - - if (!stopmovecut) // Cut momentum in half when you hit the ground and // aren't pressing any controls. if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) @@ -3019,39 +3048,10 @@ nightsdone: } } - // Check for "Mario" blocks to hit and bounce them if (P_MobjFlip(mo)*mo->momz > 0) { - msecnode_t *node; - - if (CheckForMarioBlocks && !(netgame && mo->player->spectator)) // Only let the player punch - { - // Search the touching sectors, from side-to-side... - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - ffloor_t *rover; - if (!node->m_sector->ffloors) - continue; - - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) - continue; - - // Come on, it's time to go... - if (rover->flags & FF_MARIO - && !(mo->eflags & MFE_VERTICALFLIP) // if you were flipped, your head isn't actually hitting your ceilingz is it? - && *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom! - { - // DO THE MARIO! - if (rover->flags & FF_SHATTERBOTTOM) // Brick block! - EV_CrumbleChain(node->m_sector, rover); - else // Question block! - EV_MarioBlock(rover, node->m_sector, mo); - } - } - } // Ugly ugly billions of braces! Argh! - } + if (CheckForMarioBlocks) + P_CheckMarioBlocks(mo); // hit the ceiling if (mariomode) @@ -3210,9 +3210,7 @@ static boolean P_SceneryZMovement(mobj_t *mo) // boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) { - fixed_t topheight = *rover->t_slope ? - P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : - *rover->topheight; + fixed_t topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y); if (!player->powers[pw_carry] && !player->homing && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height) @@ -3255,14 +3253,8 @@ void P_MobjCheckWater(mobj_t *mobj) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) continue; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); + topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); + bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); if (mobj->eflags & MFE_VERTICALFLIP) { @@ -3509,14 +3501,8 @@ static void P_SceneryCheckWater(mobj_t *mobj) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); + topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); + bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); if (topheight <= mobj->z || bottomheight > (mobj->z + (mobj->height>>1))) @@ -3561,13 +3547,9 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) if (!(rover->flags & FF_EXISTS)) continue; - if (halfheight >= (*rover->t_slope ? - P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : - *rover->topheight)) + if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y)) continue; - if (halfheight <= (*rover->b_slope ? - P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : - *rover->bottomheight)) + if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y)) continue; if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1) @@ -3595,13 +3577,9 @@ static boolean P_CameraCheckWater(camera_t *thiscam) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (halfheight >= (*rover->t_slope ? - P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : - *rover->topheight)) + if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y)) continue; - if (halfheight <= ( - *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : - *rover->bottomheight)) + if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y)) continue; return true; @@ -3777,13 +3755,114 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled return false; } -// -// P_PlayerMobjThinker -// -static void P_PlayerMobjThinker(mobj_t *mobj) +static void P_CheckCrumblingPlatforms(mobj_t *mobj) { msecnode_t *node; + if (netgame && mobj->player->spectator) + return; + + for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_CRUMBLE)) + continue; + + if (mobj->eflags & MFE_VERTICALFLIP) + { + if (P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z + mobj->height) + continue; + } + else + { + if (P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z) + continue; + } + + EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); + } + } +} + +static boolean P_MobjTouchesSectorWithWater(mobj_t *mobj) +{ + msecnode_t *node; + + for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_SWIMMABLE)) + continue; + + return true; + } + } + + return false; +} + +// Check for floating water platforms and bounce them +static void P_CheckFloatbobPlatforms(mobj_t *mobj) +{ + msecnode_t *node; + + // Can't land on anything if you're not moving downwards + if (P_MobjFlip(mobj)*mobj->momz >= 0) + return; + + if (!P_MobjTouchesSectorWithWater(mobj)) + return; + + for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_FLOATBOB)) + continue; + + + if (mobj->eflags & MFE_VERTICALFLIP) + { + if (abs(*rover->bottomheight - (mobj->z + mobj->height)) > abs(mobj->momz)) + continue; + } + else + { + if (abs(*rover->topheight - mobj->z) > abs(mobj->momz)) + continue; + } + + // Initiate a 'bouncy' elevator function which slowly diminishes. + EV_BounceSector(rover->master->frontsector, -mobj->momz, rover->master); + } + } +} + +static void P_PlayerMobjThinker(mobj_t *mobj) +{ I_Assert(mobj != NULL); I_Assert(mobj->player != NULL); I_Assert(!P_MobjWasRemoved(mobj)); @@ -3836,77 +3915,10 @@ static void P_PlayerMobjThinker(mobj_t *mobj) else P_TryMove(mobj, mobj->x, mobj->y, true); - if (!(netgame && mobj->player->spectator)) - { - // Crumbling platforms - for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) - { - fixed_t topheight, bottomheight; - ffloor_t *rover; + P_CheckCrumblingPlatforms(mobj); - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_CRUMBLE)) - continue; - - topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector); - bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector); - - if ((topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) - || (bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. - EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); - } - } - } - - // Check for floating water platforms and bounce them - if (CheckForFloatBob && P_MobjFlip(mobj)*mobj->momz < 0) - { - boolean thereiswater = false; - - for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (node->m_sector->ffloors) - { - ffloor_t *rover; - // Get water boundaries first - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) - continue; - - if (rover->flags & FF_SWIMMABLE) // Is there water? - { - thereiswater = true; - break; - } - } - } - } - if (thereiswater) - { - for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (node->m_sector->ffloors) - { - ffloor_t *rover; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_FLOATBOB)) - continue; - - if ((!(mobj->eflags & MFE_VERTICALFLIP) && abs(*rover->topheight-mobj->z) <= abs(mobj->momz)) // The player is landing on the cheese! - || (mobj->eflags & MFE_VERTICALFLIP && abs(*rover->bottomheight-(mobj->z+mobj->height)) <= abs(mobj->momz))) - { - // Initiate a 'bouncy' elevator function - // which slowly diminishes. - EV_BounceSector(rover->master->frontsector, -mobj->momz, rover->master); - } - } - } - } - } // Ugly ugly billions of braces! Argh! - } + if (CheckForFloatBob) + P_CheckFloatbobPlatforms(mobj); // always do the gravity bit now, that's simpler // BUT CheckPosition only if wasn't done before. @@ -3949,9 +3961,7 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) mobjsecsubsec = mobj->subsector->sector; else return; - mobj->floorz = mobjsecsubsec->f_slope ? - P_GetZAt(mobjsecsubsec->f_slope, mobj->x, mobj->y) : - mobjsecsubsec->floorheight; + mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y); if (mobjsecsubsec->ffloors) { ffloor_t *rover; @@ -3966,11 +3976,7 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE)) continue; - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - else - topheight = *rover->topheight; - + topheight = P_GetFFloorTopZAt(rover, mobj->x, mobj->y); if (topheight > mobj->floorz) mobj->floorz = topheight; } @@ -9462,7 +9468,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_BOSSFLYPOINT: return false; case MT_NIGHTSCORE: - mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); + mobj->color = (UINT16)(leveltime % SKINCOLOR_WHITE); break; case MT_JETFUME1: if (!P_JetFume1Think(mobj)) @@ -10497,12 +10503,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // Make sure scale matches destscale immediately when spawned P_SetScale(mobj, mobj->destscale); - mobj->floorz = mobj->subsector->sector->f_slope ? - P_GetZAt(mobj->subsector->sector->f_slope, x, y) : - mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->c_slope ? - P_GetZAt(mobj->subsector->sector->c_slope, x, y) : - mobj->subsector->sector->ceilingheight; + mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y); + mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y); mobj->floorrover = NULL; mobj->ceilingrover = NULL; @@ -10673,7 +10675,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_EGGROBO1: mobj->movecount = P_RandomKey(13); - mobj->color = SKINCOLOR_RUBY + P_RandomKey(MAXSKINCOLORS - SKINCOLOR_RUBY); + mobj->color = SKINCOLOR_RUBY + P_RandomKey(numskincolors - SKINCOLOR_RUBY); break; case MT_HIVEELEMENTAL: mobj->extravalue1 = 5; @@ -10855,12 +10857,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype // set subsector and/or block links P_SetPrecipitationThingPosition(mobj); - mobj->floorz = starting_floorz = mobj->subsector->sector->f_slope ? - P_GetZAt(mobj->subsector->sector->f_slope, x, y) : - mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->c_slope ? - P_GetZAt(mobj->subsector->sector->c_slope, x, y) : - mobj->subsector->sector->ceilingheight; + mobj->floorz = starting_floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y); + mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y); mobj->floorrover = NULL; mobj->ceilingrover = NULL; @@ -11495,12 +11493,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) // set Z height sector = R_PointInSubsector(x, y)->sector; - floor = sector->f_slope ? - P_GetZAt(sector->f_slope, x, y) : - sector->floorheight; - ceiling = sector->c_slope ? - P_GetZAt(sector->c_slope, x, y) : - sector->ceilingheight; + floor = P_GetSectorFloorZAt (sector, x, y); + ceiling = P_GetSectorCeilingZAt(sector, x, y); ceilingspawn = ceiling - mobjinfo[MT_PLAYER].height; if (mthing) @@ -11570,12 +11564,8 @@ void P_MovePlayerToStarpost(INT32 playernum) P_SetThingPosition(mobj); sector = R_PointInSubsector(mobj->x, mobj->y)->sector; - floor = sector->f_slope ? - P_GetZAt(sector->f_slope, mobj->x, mobj->y) : - sector->floorheight; - ceiling = sector->c_slope ? - P_GetZAt(sector->c_slope, mobj->x, mobj->y) : - sector->ceilingheight; + floor = P_GetSectorFloorZAt (sector, mobj->x, mobj->y); + ceiling = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y); z = p->starpostz << FRACBITS; @@ -11624,11 +11614,9 @@ fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const f // Establish height. if (flip) - return (ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : ss->sector->ceilingheight) - - offset - mobjinfo[mobjtype].height; + return P_GetSectorCeilingZAt(ss->sector, x, y) - offset - mobjinfo[mobjtype].height; else - return (ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : ss->sector->floorheight) - + offset; + return P_GetSectorFloorZAt(ss->sector, x, y) + offset; } fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) @@ -11967,7 +11955,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) { INT32 j; emblem_t* emblem = M_GetLevelEmblems(gamemap); - skincolors_t emcolor; + skincolornum_t emcolor; while (emblem) { @@ -11990,7 +11978,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) mobj->health = j + 1; emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting - mobj->color = (UINT8)emcolor; + mobj->color = (UINT16)emcolor; if (emblemlocations[j].collected || (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin)) @@ -12629,7 +12617,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; case MT_BALLOON: if (mthing->angle > 0) - mobj->color = ((mthing->angle - 1) % (MAXSKINCOLORS - 1)) + 1; + mobj->color = ((mthing->angle - 1) % (numskincolors - 1)) + 1; break; #define makesoftwarecorona(mo, h) \ corona = P_SpawnMobjFromMobj(mo, 0, 0, h<<FRACBITS, MT_PARTICLE);\ @@ -12729,9 +12717,14 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->threshold = min(mthing->extrainfo, 7); break; case MT_TUBEWAYPOINT: - mobj->health = mthing->angle & 255; - mobj->threshold = mthing->angle >> 8; + { + UINT8 sequence = mthing->angle >> 8; + UINT8 id = mthing->angle & 255; + mobj->health = id; + mobj->threshold = sequence; + P_AddWaypoint(sequence, id, mobj); break; + } case MT_IDEYAANCHOR: mobj->health = mthing->extrainfo; break; diff --git a/src/p_mobj.h b/src/p_mobj.h index eda7383df2efdeb03b7846ad2310db01b0a8aad0..dae8c8a86079726aa17ebf45f4283761960d26d0 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -312,7 +312,7 @@ typedef struct mobj_s void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin) // Player and mobj sprites in multiplayer modes are modified // using an internal color lookup table for re-indexing. - UINT8 color; // This replaces MF_TRANSLATION. Use 0 for default (no translation). + UINT16 color; // This replaces MF_TRANSLATION. Use 0 for default (no translation). // Interaction info, by BLOCKMAP. // Links in blocks (if needed). diff --git a/src/p_polyobj.c b/src/p_polyobj.c index cd63f4509cbd0c792054d837186a8c089acdcaa3..3b6195285bd2cea5cb36e7f380b0ef422ccb21d4 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1569,17 +1569,39 @@ void T_PolyObjMove(polymove_t *th) } } +static void T_MovePolyObj(polyobj_t *po, fixed_t distx, fixed_t disty, fixed_t distz) +{ + polyobj_t *child; + INT32 start; + + Polyobj_moveXY(po, distx, disty, true); + // TODO: use T_MovePlane + po->lines[0]->backsector->floorheight += distz; + po->lines[0]->backsector->ceilingheight += distz; + // Sal: Remember to check your sectors! + // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap + // updating objects in the front one too just added teleporting to ground bugs + P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); + // Apply action to mirroring polyobjects as well + start = 0; + while ((child = Polyobj_GetChild(po, &start))) + { + if (child->isBad) + continue; + + Polyobj_moveXY(child, distx, disty, true); + // TODO: use T_MovePlane + child->lines[0]->backsector->floorheight += distz; + child->lines[0]->backsector->ceilingheight += distz; + P_CheckSector(child->lines[0]->backsector, (boolean)(child->damage)); + } +} + void T_PolyObjWaypoint(polywaypoint_t *th) { - mobj_t *mo2; mobj_t *target = NULL; - mobj_t *waypoint = NULL; - thinker_t *wp; - fixed_t adjustx, adjusty, adjustz; - fixed_t momx, momy, momz, dist; - INT32 start; polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); - polyobj_t *oldpo = po; + fixed_t speed = th->speed; if (!po) #ifdef RANGECHECK @@ -1593,31 +1615,10 @@ void T_PolyObjWaypoint(polywaypoint_t *th) #endif // check for displacement due to override and reattach when possible - if (po->thinker == NULL) + if (!po->thinker) po->thinker = &th->thinker; -/* - // Find out target first. - // We redo this each tic to make savegame compatibility easier. - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold == th->sequence && mo2->health == th->pointnum) - { - target = mo2; - break; - } - } -*/ - - target = th->target; + target = waypoints[th->sequence][th->pointnum]; if (!target) { @@ -1625,240 +1626,93 @@ void T_PolyObjWaypoint(polywaypoint_t *th) return; } - // Compensate for position offset - adjustx = po->centerPt.x + th->diffx; - adjusty = po->centerPt.y + th->diffy; - adjustz = po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2 + th->diffz; - - dist = P_AproxDistance(P_AproxDistance(target->x - adjustx, target->y - adjusty), target->z - adjustz); + // Move along the waypoint sequence until speed for the current tic is exhausted + while (speed > 0) + { + mobj_t *waypoint = NULL; + fixed_t pox, poy, poz; + fixed_t distx, disty, distz, dist; - if (dist < 1) - dist = 1; + // Current position of polyobject + pox = po->centerPt.x; + poy = po->centerPt.y; + poz = (po->lines[0]->backsector->floorheight + po->lines[0]->backsector->ceilingheight)/2; - momx = FixedMul(FixedDiv(target->x - adjustx, dist), (th->speed)); - momy = FixedMul(FixedDiv(target->y - adjusty, dist), (th->speed)); - momz = FixedMul(FixedDiv(target->z - adjustz, dist), (th->speed)); + // Calculate the distance between the polyobject and the waypoint + distx = target->x - pox; + disty = target->y - poy; + distz = target->z - poz; + dist = P_AproxDistance(P_AproxDistance(distx, disty), distz); - // Calculate the distance between the polyobject and the waypoint - // 'dist' already equals this. + if (dist < 1) + dist = 1; - // Will the polyobject be FURTHER away if the momx/momy/momz is added to - // its current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(target->x - adjustx - momx, target->y - adjusty - momy), target->z - adjustz - momz)>>FRACBITS) - { - // If further away, set XYZ of polyobject to waypoint location - fixed_t amtx, amty, amtz; - fixed_t diffz; - amtx = (target->x - th->diffx) - po->centerPt.x; - amty = (target->y - th->diffy) - po->centerPt.y; - Polyobj_moveXY(po, amtx, amty, true); - // TODO: use T_MovePlane - amtz = (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2; - diffz = po->lines[0]->backsector->floorheight - (target->z - amtz); - po->lines[0]->backsector->floorheight = target->z - amtz; - po->lines[0]->backsector->ceilingheight = target->z + amtz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); - // Apply action to mirroring polyobjects as well - start = 0; - while ((po = Polyobj_GetChild(oldpo, &start))) + // Will the polyobject overshoot its target? + if (speed < dist) { - if (po->isBad) - continue; + // No. Move towards waypoint + fixed_t momx, momy, momz; - Polyobj_moveXY(po, amtx, amty, true); - // TODO: use T_MovePlane - po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did - po->lines[0]->backsector->ceilingheight += diffz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); + momx = FixedMul(FixedDiv(target->x - pox, dist), speed); + momy = FixedMul(FixedDiv(target->y - poy, dist), speed); + momz = FixedMul(FixedDiv(target->z - poz, dist), speed); + T_MovePolyObj(po, momx, momy, momz); + return; } - - po = oldpo; - - if (!th->stophere) + else { - CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n"); + // Yes. Teleport to waypoint and look for the next one + T_MovePolyObj(po, distx, disty, distz); - // Find next waypoint - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) + if (!th->stophere) { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; + CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n"); + waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false); - if (th->direction == -1) + if (!waypoint && th->returnbehavior == PWR_WRAP) // If specified, wrap waypoints { - if (mo2->health == target->health - 1) + if (!th->continuous) { - waypoint = mo2; - break; + th->returnbehavior = PWR_STOP; + th->stophere = true; } - } - else - { - if (mo2->health == target->health + 1) - { - waypoint = mo2; - break; - } - } - } - if (!waypoint && th->wrap) // If specified, wrap waypoints - { - if (!th->continuous) - { - th->wrap = 0; - th->stophere = true; + waypoint = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence); } - - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) + else if (!waypoint && th->returnbehavior == PWR_COMEBACK) // Come back to the start { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; + th->direction = -th->direction; - if (mo2->type != MT_TUBEWAYPOINT) - continue; + if (!th->continuous) + th->returnbehavior = PWR_STOP; - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) - { - if (waypoint == NULL) - waypoint = mo2; - else if (mo2->health > waypoint->health) - waypoint = mo2; - } - else - { - if (mo2->health == 0) - { - waypoint = mo2; - break; - } - } + waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false); } } - else if (!waypoint && th->comeback) // Come back to the start - { - th->direction = -th->direction; - if (!th->continuous) - th->comeback = false; - - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; + if (waypoint) + { + CONS_Debug(DBG_POLYOBJ, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); - if (mo2->threshold != th->sequence) - continue; + target = waypoint; + th->pointnum = target->health; - if (th->direction == -1) - { - if (mo2->health == target->health - 1) - { - waypoint = mo2; - break; - } - } - else - { - if (mo2->health == target->health + 1) - { - waypoint = mo2; - break; - } - } - } + // Calculate remaining speed + speed -= dist; } - } - - if (waypoint) - { - CONS_Debug(DBG_POLYOBJ, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); - - target = waypoint; - th->pointnum = target->health; - // Set the mobj as your target! -- Monster Iestyn 27/12/19 - P_SetTarget(&th->target, target); - - // calculate MOMX/MOMY/MOMZ for next waypoint - // change slope - dist = P_AproxDistance(P_AproxDistance(target->x - adjustx, target->y - adjusty), target->z - adjustz); - - if (dist < 1) - dist = 1; - - momx = FixedMul(FixedDiv(target->x - adjustx, dist), (th->speed)); - momy = FixedMul(FixedDiv(target->y - adjusty, dist), (th->speed)); - momz = FixedMul(FixedDiv(target->z - adjustz, dist), (th->speed)); - } - else - { - momx = momy = momz = 0; - - if (!th->stophere) - CONS_Debug(DBG_POLYOBJ, "Next waypoint not found!\n"); + else + { + if (!th->stophere) + CONS_Debug(DBG_POLYOBJ, "Next waypoint not found!\n"); - if (po->thinker == &th->thinker) - po->thinker = NULL; + if (po->thinker == &th->thinker) + po->thinker = NULL; - P_RemoveThinker(&th->thinker); - return; + P_RemoveThinker(&th->thinker); + return; + } } } - else - { - // momx/momy/momz already equals the right speed - } - - // Move the polyobject - Polyobj_moveXY(po, momx, momy, true); - // TODO: use T_MovePlane - po->lines[0]->backsector->floorheight += momz; - po->lines[0]->backsector->ceilingheight += momz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); - - // Apply action to mirroring polyobjects as well - start = 0; - while ((po = Polyobj_GetChild(oldpo, &start))) - { - if (po->isBad) - continue; - - Polyobj_moveXY(po, momx, momy, true); - // TODO: use T_MovePlane - po->lines[0]->backsector->floorheight += momz; - po->lines[0]->backsector->ceilingheight += momz; - // Sal: Remember to check your sectors! - // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap - // updating objects in the front one too just added teleporting to ground bugs - P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); - } } void T_PolyDoorSlide(polyslidedoor_t *th) @@ -2276,11 +2130,7 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) { polyobj_t *po; polywaypoint_t *th; - mobj_t *mo2; mobj_t *first = NULL; - mobj_t *last = NULL; - mobj_t *target = NULL; - thinker_t *wp; if (!(po = Polyobj_GetForNum(pwdata->polyObjNum))) { @@ -2304,56 +2154,16 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // set fields th->polyObjNum = pwdata->polyObjNum; th->speed = pwdata->speed; - th->sequence = pwdata->sequence; // Used to specify sequence # - if (pwdata->reverse) - th->direction = -1; - else - th->direction = 1; + th->sequence = pwdata->sequence; + th->direction = (pwdata->flags & PWF_REVERSE) ? -1 : 1; - th->comeback = pwdata->comeback; - th->continuous = pwdata->continuous; - th->wrap = pwdata->wrap; + th->returnbehavior = pwdata->returnbehavior; + if (pwdata->flags & PWF_LOOP) + th->continuous = true; th->stophere = false; // Find the first waypoint we need to use - for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) // highest waypoint # - { - if (mo2->health == 0) - last = mo2; - else - { - if (first == NULL) - first = mo2; - else if (mo2->health > first->health) - first = mo2; - } - } - else // waypoint 0 - { - if (mo2->health == 0) - first = mo2; - else - { - if (last == NULL) - last = mo2; - else if (mo2->health > last->health) - last = mo2; - } - } - } + first = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence); if (!first) { @@ -2363,77 +2173,16 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) return false; } - // Hotfix to not crash on single-waypoint sequences -Red - if (!last) - last = first; - - // Set diffx, diffy, diffz - // Put these at 0 for now...might not be needed after all. - th->diffx = 0;//first->x - po->centerPt.x; - th->diffy = 0;//first->y - po->centerPt.y; - th->diffz = 0;//first->z - (po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2); - - if (last->x == po->centerPt.x - && last->y == po->centerPt.y - && last->z == (po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2)) - { - // Already at the destination point... - if (!th->wrap) - { - po->thinker = NULL; - P_RemoveThinker(&th->thinker); - } - } - - // Find the actual target movement waypoint - target = first; - /*for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) - { - if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)wp; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != th->sequence) - continue; - - if (th->direction == -1) // highest waypoint # - { - if (mo2->health == first->health - 1) - { - target = mo2; - break; - } - } - else // waypoint 0 - { - if (mo2->health == first->health + 1) - { - target = mo2; - break; - } - } - }*/ - - if (!target) + // Sanity check: If all waypoints are in the same location, + // don't allow the movement to be continuous so we don't get stuck in an infinite loop. + if (th->continuous && P_IsDegeneratedWaypointSequence(th->sequence)) { - CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: Missing target waypoint!\n"); - po->thinker = NULL; - P_RemoveThinker(&th->thinker); - return false; + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: All waypoints are in the same location!\n"); + th->continuous = false; } - // Set pointnum - th->pointnum = target->health; - th->target = NULL; // set to NULL first so the below doesn't go wrong - // Set the mobj as your target! -- Monster Iestyn 27/12/19 - P_SetTarget(&th->target, target); + th->pointnum = first->health; - // We don't deal with the mirror crap here, we'll - // handle that in the T_Thinker function. return true; } diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 68aff4bf189ec518a5faeb69ecdee3894c403be5..8037c545f28877240893360018bf25e9a9027c8d 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -140,26 +140,26 @@ typedef struct polymove_s UINT32 angle; // angle along which to move } polymove_t; +// PolyObject waypoint movement return behavior +typedef enum +{ + PWR_STOP, // Stop after reaching last waypoint + PWR_WRAP, // Wrap back to first waypoint + PWR_COMEBACK, // Repeat sequence in reverse +} polywaypointreturn_e; + typedef struct polywaypoint_s { thinker_t thinker; // must be first - INT32 polyObjNum; // numeric id of polyobject - INT32 speed; // resultant velocity - INT32 sequence; // waypoint sequence # - INT32 pointnum; // waypoint # - INT32 direction; // 1 for normal, -1 for backwards - UINT8 comeback; // reverses and comes back when the end is reached - UINT8 wrap; // Wrap around waypoints - UINT8 continuous; // continuously move - used with COMEBACK or WRAP - UINT8 stophere; // Will stop after it reaches the next waypoint - - // Difference between location of PO and location of waypoint (offset) - fixed_t diffx; - fixed_t diffy; - fixed_t diffz; - - mobj_t *target; // next waypoint mobj + INT32 polyObjNum; // numeric id of polyobject + INT32 speed; // resultant velocity + INT32 sequence; // waypoint sequence # + INT32 pointnum; // waypoint # + INT32 direction; // 1 for normal, -1 for backwards + UINT8 returnbehavior; // behavior after reaching the last waypoint + UINT8 continuous; // continuously move - used with PWR_WRAP or PWR_COMEBACK + UINT8 stophere; // Will stop after it reaches the next waypoint } polywaypoint_t; typedef struct polyslidedoor_s @@ -254,15 +254,19 @@ typedef struct polymovedata_s UINT8 overRide; // if true, will override any action on the object } polymovedata_t; +typedef enum +{ + PWF_REVERSE = 1, // Move through waypoints in reverse order + PWF_LOOP = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK) +} polywaypointflags_e; + typedef struct polywaypointdata_s { - INT32 polyObjNum; // numeric id of polyobject to affect - INT32 sequence; // waypoint sequence # - fixed_t speed; // linear speed - UINT8 reverse; // if true, will go in reverse waypoint order - UINT8 comeback; // reverses and comes back when the end is reached - UINT8 wrap; // Wrap around waypoints - UINT8 continuous; // continuously move - used with COMEBACK or WRAP + INT32 polyObjNum; // numeric id of polyobject to affect + INT32 sequence; // waypoint sequence # + fixed_t speed; // linear speed + UINT8 returnbehavior; // behavior after reaching the last waypoint + UINT8 flags; // PWF_ flags } polywaypointdata_t; // polyobject door types diff --git a/src/p_saveg.c b/src/p_saveg.c index 34bd3724b7a4b6ceb7a908a669ce7de888c8ed1c..6f80949ead2e583d6aad07aeef506dcd691ccd1d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -717,6 +717,34 @@ static void P_NetUnArchiveColormaps(void) net_colormaps = NULL; } +static void P_NetArchiveWaypoints(void) +{ + INT32 i, j; + + for (i = 0; i < NUMWAYPOINTSEQUENCES; i++) + { + WRITEUINT16(save_p, numwaypoints[i]); + for (j = 0; j < numwaypoints[i]; j++) + WRITEUINT32(save_p, waypoints[i][j] ? waypoints[i][j]->mobjnum : 0); + } +} + +static void P_NetUnArchiveWaypoints(void) +{ + INT32 i, j; + UINT32 mobjnum; + + for (i = 0; i < NUMWAYPOINTSEQUENCES; i++) + { + numwaypoints[i] = READUINT16(save_p); + for (j = 0; j < numwaypoints[i]; j++) + { + mobjnum = READUINT32(save_p); + waypoints[i][j] = (mobjnum == 0) ? NULL : P_FindNewPosition(mobjnum); + } + } +} + /// /// World Archiving /// @@ -1593,7 +1621,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (diff2 & MD2_SKIN) WRITEUINT8(save_p, (UINT8)((skin_t *)mobj->skin - skins)); if (diff2 & MD2_COLOR) - WRITEUINT8(save_p, mobj->color); + WRITEUINT16(save_p, mobj->color); if (diff2 & MD2_EXTVAL1) WRITEINT32(save_p, mobj->extravalue1); if (diff2 & MD2_EXTVAL2) @@ -1888,8 +1916,7 @@ static void SaveLaserThinker(const thinker_t *th, const UINT8 type) { const laserthink_t *ht = (const void *)th; WRITEUINT8(save_p, type); - WRITEUINT32(save_p, SaveSector(ht->sector)); - WRITEUINT32(save_p, SaveSector(ht->sec)); + WRITEINT16(save_p, ht->tag); WRITEUINT32(save_p, SaveLine(ht->sourceline)); WRITEUINT8(save_p, ht->nobosses); } @@ -2019,14 +2046,9 @@ static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) WRITEINT32(save_p, ht->sequence); WRITEINT32(save_p, ht->pointnum); WRITEINT32(save_p, ht->direction); - WRITEUINT8(save_p, ht->comeback); - WRITEUINT8(save_p, ht->wrap); + WRITEUINT8(save_p, ht->returnbehavior); WRITEUINT8(save_p, ht->continuous); WRITEUINT8(save_p, ht->stophere); - WRITEFIXED(save_p, ht->diffx); - WRITEFIXED(save_p, ht->diffy); - WRITEFIXED(save_p, ht->diffz); - WRITEUINT32(save_p, SaveMobjnum(ht->target)); } static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type) @@ -2606,7 +2628,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_SKIN) mobj->skin = &skins[READUINT8(save_p)]; if (diff2 & MD2_COLOR) - mobj->color = READUINT8(save_p); + mobj->color = READUINT16(save_p); if (diff2 & MD2_EXTVAL1) mobj->extravalue1 = READINT32(save_p); if (diff2 & MD2_EXTVAL2) @@ -2995,16 +3017,10 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker) static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) { laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); - ffloor_t *rover = NULL; ht->thinker.function.acp1 = thinker; - ht->sector = LoadSector(READUINT32(save_p)); - ht->sec = LoadSector(READUINT32(save_p)); + ht->tag = READINT16(save_p); ht->sourceline = LoadLine(READUINT32(save_p)); ht->nobosses = READUINT8(save_p); - for (rover = ht->sector->ffloors; rover; rover = rover->next) - if (rover->secnum == (size_t)(ht->sec - sectors) - && rover->master == ht->sourceline) - ht->ffloor = rover; return &ht->thinker; } @@ -3164,14 +3180,9 @@ static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) ht->sequence = READINT32(save_p); ht->pointnum = READINT32(save_p); ht->direction = READINT32(save_p); - ht->comeback = READUINT8(save_p); - ht->wrap = READUINT8(save_p); + ht->returnbehavior = READUINT8(save_p); ht->continuous = READUINT8(save_p); ht->stophere = READUINT8(save_p); - ht->diffx = READFIXED(save_p); - ht->diffy = READFIXED(save_p); - ht->diffz = READFIXED(save_p); - ht->target = LoadMobj(READUINT32(save_p)); return &ht->thinker; } @@ -3418,7 +3429,6 @@ static void P_NetUnArchiveThinkers(void) case tc_polywaypoint: th = LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint); - restoreNum = true; break; case tc_polyslidedoor: @@ -3478,7 +3488,6 @@ static void P_NetUnArchiveThinkers(void) if (restoreNum) { executor_t *delay = NULL; - polywaypoint_t *polywp = NULL; UINT32 mobjnum; for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN]; currentthinker = currentthinker->next) { @@ -3489,15 +3498,6 @@ static void P_NetUnArchiveThinkers(void) continue; delay->caller = P_FindNewPosition(mobjnum); } - for (currentthinker = thlist[THINK_POLYOBJ].next; currentthinker != &thlist[THINK_POLYOBJ]; currentthinker = currentthinker->next) - { - if (currentthinker->function.acp1 != (actionf_p1)T_PolyObjWaypoint) - continue; - polywp = (void *)currentthinker; - if (!(mobjnum = (UINT32)(size_t)polywp->target)) - continue; - polywp->target = P_FindNewPosition(mobjnum); - } } } @@ -4070,6 +4070,7 @@ void P_SaveNetGame(void) P_NetArchiveThinkers(); P_NetArchiveSpecials(); P_NetArchiveColormaps(); + P_NetArchiveWaypoints(); } LUA_Archive(); @@ -4108,6 +4109,7 @@ boolean P_LoadNetGame(void) P_NetUnArchiveThinkers(); P_NetUnArchiveSpecials(); P_NetUnArchiveColormaps(); + P_NetUnArchiveWaypoints(); P_RelinkPointers(); P_FinishMobjs(); } diff --git a/src/p_setup.c b/src/p_setup.c index b4a5f2c3c75a49b2fdd6d61229c581b67f615414..84e89d7463abb5190b456d2c1d44e239f5c5cca1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -144,6 +144,133 @@ mapthing_t *playerstarts[MAXPLAYERS]; mapthing_t *bluectfstarts[MAXPLAYERS]; mapthing_t *redctfstarts[MAXPLAYERS]; +// Maintain waypoints +mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE]; +UINT16 numwaypoints[NUMWAYPOINTSEQUENCES]; + +void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint) +{ + waypoints[sequence][id] = waypoint; + if (id >= numwaypoints[sequence]) + numwaypoints[sequence] = id + 1; +} + +static void P_ResetWaypoints(void) +{ + UINT16 sequence, id; + for (sequence = 0; sequence < NUMWAYPOINTSEQUENCES; sequence++) + { + for (id = 0; id < numwaypoints[sequence]; id++) + waypoints[sequence][id] = NULL; + + numwaypoints[sequence] = 0; + } +} + +mobj_t *P_GetFirstWaypoint(UINT8 sequence) +{ + return waypoints[sequence][0]; +} + +mobj_t *P_GetLastWaypoint(UINT8 sequence) +{ + return waypoints[sequence][numwaypoints[sequence] - 1]; +} + +mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap) +{ + UINT8 sequence = current->threshold; + UINT8 id = current->health; + + if (id == 0) + { + if (!wrap) + return NULL; + + id = numwaypoints[sequence] - 1; + } + else + id--; + + return waypoints[sequence][id]; +} + +mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap) +{ + UINT8 sequence = current->threshold; + UINT8 id = current->health; + + if (id == numwaypoints[sequence] - 1) + { + if (!wrap) + return NULL; + + id = 0; + } + else + id++; + + return waypoints[sequence][id]; +} + +mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo) +{ + UINT8 wp; + mobj_t *mo2, *result = NULL; + fixed_t bestdist = 0; + fixed_t curdist; + + for (wp = 0; wp < numwaypoints[sequence]; wp++) + { + mo2 = waypoints[sequence][wp]; + + if (!mo2) + continue; + + curdist = P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z); + + if (result && curdist > bestdist) + continue; + + result = mo2; + bestdist = curdist; + } + + return result; +} + +// Return true if all waypoints are in the same location +boolean P_IsDegeneratedWaypointSequence(UINT8 sequence) +{ + mobj_t *first, *waypoint; + UINT8 wp; + + if (numwaypoints[sequence] <= 1) + return true; + + first = waypoints[sequence][0]; + + for (wp = 1; wp < numwaypoints[sequence]; wp++) + { + waypoint = waypoints[sequence][wp]; + + if (!waypoint) + continue; + + if (waypoint->x != first->x) + return false; + + if (waypoint->y != first->y) + return false; + + if (waypoint->z != first->z) + return false; + } + + return true; +} + + /** Logs an error about a map being corrupt, then terminate. * This allows reporting highly technical errors for usefulness, without * confusing a novice map designer who simply needs to run ZenNode. @@ -3545,6 +3672,8 @@ boolean P_LoadLevel(boolean fromnetsave) P_ResetSpawnpoints(); + P_ResetWaypoints(); + P_MapStart(); if (!P_LoadMapFromFile()) diff --git a/src/p_sight.c b/src/p_sight.c index 3e44281d0511e65c8841033242cd6ca8c1dadafd..2e1e499970418d23f5129e9271199592dbb9ce23 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -259,10 +259,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) fracx = los->strace.x + FixedMul(los->strace.dx, frac); fracy = los->strace.y + FixedMul(los->strace.dy, frac); // calculate sector heights - frontf = (front->f_slope) ? P_GetZAt(front->f_slope, fracx, fracy) : front->floorheight; - frontc = (front->c_slope) ? P_GetZAt(front->c_slope, fracx, fracy) : front->ceilingheight; - backf = (back->f_slope) ? P_GetZAt(back->f_slope, fracx, fracy) : back->floorheight; - backc = (back->c_slope) ? P_GetZAt(back->c_slope, fracx, fracy) : back->ceilingheight; + frontf = P_GetSectorFloorZAt (front, fracx, fracy); + frontc = P_GetSectorCeilingZAt(front, fracx, fracy); + backf = P_GetSectorFloorZAt (back , fracx, fracy); + backc = P_GetSectorCeilingZAt(back , fracx, fracy); // crosses a two sided line // no wall to block sight with? if (frontf == backf && frontc == backc @@ -312,10 +312,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) continue; } - topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; - bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; - topslope = FixedDiv(topz - los->sightzstart , frac); - bottomslope = FixedDiv(bottomz - los->sightzstart , frac); + topz = P_GetFFloorTopZAt (rover, fracx, fracy); + bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy); + topslope = FixedDiv( topz - los->sightzstart, frac); + bottomslope = FixedDiv(bottomz - los->sightzstart, frac); if (topslope >= los->topslope && bottomslope <= los->bottomslope) return false; // view completely blocked } @@ -328,10 +328,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) continue; } - topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; - bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; - topslope = FixedDiv(topz - los->sightzstart , frac); - bottomslope = FixedDiv(bottomz - los->sightzstart , frac); + topz = P_GetFFloorTopZAt (rover, fracx, fracy); + bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy); + topslope = FixedDiv( topz - los->sightzstart, frac); + bottomslope = FixedDiv(bottomz - los->sightzstart, frac); if (topslope >= los->topslope && bottomslope <= los->bottomslope) return false; // view completely blocked } @@ -457,21 +457,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) continue; } - if (*rover->t_slope) - { - topz1 = P_GetZAt(*rover->t_slope, t1->x, t1->y); - topz2 = P_GetZAt(*rover->t_slope, t2->x, t2->y); - } - else - topz1 = topz2 = *rover->topheight; - - if (*rover->b_slope) - { - bottomz1 = P_GetZAt(*rover->b_slope, t1->x, t1->y); - bottomz2 = P_GetZAt(*rover->b_slope, t2->x, t2->y); - } - else - bottomz1 = bottomz2 = *rover->bottomheight; + topz1 = P_GetFFloorTopZAt (rover, t1->x, t1->y); + topz2 = P_GetFFloorTopZAt (rover, t2->x, t2->y); + bottomz1 = P_GetFFloorBottomZAt(rover, t1->x, t1->y); + bottomz2 = P_GetFFloorBottomZAt(rover, t2->x, t2->y); // Check for blocking floors here. if ((los.sightzstart < bottomz1 && t2->z >= topz2) diff --git a/src/p_slopes.c b/src/p_slopes.c index 92b40f70faaba601124af421f5a73814c1235295..6aeb1b02596633e7c4d6a9db1e0f0853b6c244c3 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -655,17 +655,49 @@ void P_SpawnSlopes(const boolean fromsave) { // Various utilities related to slopes // -// -// P_GetZAt -// // Returns the height of the sloped plane at (x, y) as a fixed_t -// -fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) +fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) { - fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + - FixedMul(y - slope->o.y, slope->d.y); + fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + + FixedMul(y - slope->o.y, slope->d.y); + + return slope->o.z + FixedMul(dist, slope->zdelta); +} + +// Like P_GetSlopeZAt but falls back to z if slope is NULL +fixed_t P_GetZAt(const pslope_t *slope, fixed_t x, fixed_t y, fixed_t z) +{ + return slope ? P_GetSlopeZAt(slope, x, y) : z; +} + +// Returns the height of the sector floor at (x, y) +fixed_t P_GetSectorFloorZAt(const sector_t *sector, fixed_t x, fixed_t y) +{ + return sector->f_slope ? P_GetSlopeZAt(sector->f_slope, x, y) : sector->floorheight; +} - return slope->o.z + FixedMul(dist, slope->zdelta); +// Returns the height of the sector ceiling at (x, y) +fixed_t P_GetSectorCeilingZAt(const sector_t *sector, fixed_t x, fixed_t y) +{ + return sector->c_slope ? P_GetSlopeZAt(sector->c_slope, x, y) : sector->ceilingheight; +} + +// Returns the height of the FOF top at (x, y) +fixed_t P_GetFFloorTopZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y) +{ + return *ffloor->t_slope ? P_GetSlopeZAt(*ffloor->t_slope, x, y) : *ffloor->topheight; +} + +// Returns the height of the FOF bottom at (x, y) +fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y) +{ + return *ffloor->b_slope ? P_GetSlopeZAt(*ffloor->b_slope, x, y) : *ffloor->bottomheight; +} + +// Returns the height of the light list at (x, y) +fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y) +{ + return light->slope ? P_GetSlopeZAt(light->slope, x, y) : light->height; } diff --git a/src/p_slopes.h b/src/p_slopes.h index e7c850ab811e33c19cca5700453472f3804d4c56..06d900b666b91c8a901392a4f243b0941a0d05e7 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -33,7 +33,21 @@ void P_CopySectorSlope(line_t *line); pslope_t *P_SlopeById(UINT16 id); // Returns the height of the sloped plane at (x, y) as a fixed_t -fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); +fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y); + +// Like P_GetSlopeZAt but falls back to z if slope is NULL +fixed_t P_GetZAt(const pslope_t *slope, fixed_t x, fixed_t y, fixed_t z); + +// Returns the height of the sector at (x, y) +fixed_t P_GetSectorFloorZAt (const sector_t *sector, fixed_t x, fixed_t y); +fixed_t P_GetSectorCeilingZAt(const sector_t *sector, fixed_t x, fixed_t y); + +// Returns the height of the FOF at (x, y) +fixed_t P_GetFFloorTopZAt (const ffloor_t *ffloor, fixed_t x, fixed_t y); +fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y); + +// Returns the height of the light list at (x, y) +fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y); // Lots of physics-based bullshit void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); diff --git a/src/p_spec.c b/src/p_spec.c index feac4dea008df0b9b2599ffb353ba07b7d8e5cb5..57ae42c698cd5d88dbb75ef6ccd01f106bf0800f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1276,10 +1276,21 @@ static boolean PolyWaypoint(line_t *line) pwd.polyObjNum = line->tag; pwd.speed = sides[line->sidenum[0]].textureoffset / 8; pwd.sequence = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Sequence # - pwd.reverse = (line->flags & ML_EFFECT1) == ML_EFFECT1; // Reverse? - pwd.comeback = (line->flags & ML_EFFECT2) == ML_EFFECT2; // Return when reaching end? - pwd.wrap = (line->flags & ML_EFFECT3) == ML_EFFECT3; // Wrap around waypoints - pwd.continuous = (line->flags & ML_EFFECT4) == ML_EFFECT4; // Continuously move - used with COMEBACK or WRAP + + // Behavior after reaching the last waypoint? + if (line->flags & ML_EFFECT3) + pwd.returnbehavior = PWR_WRAP; // Wrap back to first waypoint + else if (line->flags & ML_EFFECT2) + pwd.returnbehavior = PWR_COMEBACK; // Go through sequence in reverse + else + pwd.returnbehavior = PWR_STOP; // Stop + + // Flags + pwd.flags = 0; + if (line->flags & ML_EFFECT1) + pwd.flags |= PWF_REVERSE; + if (line->flags & ML_EFFECT4) + pwd.flags |= PWF_LOOP; return EV_DoPolyObjWaypoint(&pwd); } @@ -3960,7 +3971,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (mo) { - if (color < 0 || color >= MAXTRANSLATIONS) + if (color < 0 || color >= numskincolors) return; var1 = 0; @@ -4799,9 +4810,7 @@ DoneSection2: INT32 sequence; fixed_t speed; INT32 lineindex; - thinker_t *th; mobj_t *waypoint = NULL; - mobj_t *mo2; angle_t an; if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) @@ -4826,25 +4835,7 @@ DoneSection2: break; } - // scan the thinkers - // to find the first waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - if (mo2->threshold != sequence) - continue; - if (mo2->health != 0) - continue; - - waypoint = mo2; - break; - } + waypoint = P_GetFirstWaypoint(sequence); if (!waypoint) { @@ -4881,9 +4872,7 @@ DoneSection2: INT32 sequence; fixed_t speed; INT32 lineindex; - thinker_t *th; mobj_t *waypoint = NULL; - mobj_t *mo2; angle_t an; if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) @@ -4908,25 +4897,7 @@ DoneSection2: break; } - // scan the thinkers - // to find the last waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - if (mo2->threshold != sequence) - continue; - - if (!waypoint) - waypoint = mo2; - else if (mo2->health > waypoint->health) - waypoint = mo2; - } + waypoint = P_GetLastWaypoint(sequence); if (!waypoint) { @@ -5008,14 +4979,11 @@ DoneSection2: INT32 sequence; fixed_t speed; INT32 lineindex; - thinker_t *th; mobj_t *waypointmid = NULL; mobj_t *waypointhigh = NULL; mobj_t *waypointlow = NULL; - mobj_t *mo2; mobj_t *closest = NULL; vector3_t p, line[2], resulthigh, resultlow; - mobj_t *highest = NULL; if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG) break; @@ -5061,98 +5029,16 @@ DoneSection2: // Determine the closest spot on the line between the three waypoints // Put player at that location. - // scan the thinkers - // to find the first waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; + waypointmid = P_GetClosestWaypoint(sequence, player->mo); - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (!highest) - highest = mo2; - else if (mo2->health > highest->health) // Find the highest waypoint # in case we wrap - highest = mo2; - - if (closest && P_AproxDistance(P_AproxDistance(player->mo->x-mo2->x, player->mo->y-mo2->y), - player->mo->z-mo2->z) > P_AproxDistance(P_AproxDistance(player->mo->x-closest->x, - player->mo->y-closest->y), player->mo->z-closest->z)) - continue; - - // Found a target - closest = mo2; - } - - waypointmid = closest; - - closest = NULL; - - if (waypointmid == NULL) + if (!waypointmid) { CONS_Debug(DBG_GAMELOGIC, "ERROR: WAYPOINT(S) IN SEQUENCE %d NOT FOUND.\n", sequence); break; } - // Find waypoint before this one (waypointlow) - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (waypointmid->health == 0) - { - if (mo2->health != highest->health) - continue; - } - else if (mo2->health != waypointmid->health - 1) - continue; - - // Found a target - waypointlow = mo2; - break; - } - - // Find waypoint after this one (waypointhigh) - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (waypointmid->health == highest->health) - { - if (mo2->health != 0) - continue; - } - else if (mo2->health != waypointmid->health + 1) - continue; - - // Found a target - waypointhigh = mo2; - break; - } + waypointlow = P_GetPreviousWaypoint(waypointmid, true); + waypointhigh = P_GetNextWaypoint(waypointmid, true); CONS_Debug(DBG_GAMELOGIC, "WaypointMid: %d; WaypointLow: %d; WaypointHigh: %d\n", waypointmid->health, waypointlow ? waypointlow->health : -1, waypointhigh ? waypointhigh->health : -1); @@ -5199,6 +5085,7 @@ DoneSection2: if (lines[lineindex].flags & ML_EFFECT1) // Don't wrap { + mobj_t *highest = P_GetLastWaypoint(sequence); highest->flags |= MF_SLIDEME; } @@ -5210,7 +5097,7 @@ DoneSection2: player->mo->y = resulthigh.y; player->mo->z = resulthigh.z - P_GetPlayerHeight(player); } - else if ((lines[lineindex].flags & ML_EFFECT1) && waypointmid->health == highest->health) + else if ((lines[lineindex].flags & ML_EFFECT1) && waypointmid->health == numwaypoints[sequence] - 1) { closest = waypointmid; player->mo->x = resultlow.x; @@ -6135,92 +6022,83 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto elevator->distance = FixedInt(AngleFixed(angle)); } -static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; - /** Flashes a laser block. * * \param flash Thinker structure for this laser. - * \sa EV_AddLaserThinker + * \sa P_AddLaserThinker * \author SSNTails <http://www.ssntails.org> */ void T_LaserFlash(laserthink_t *flash) { msecnode_t *node; mobj_t *thing; - sector_t *sourcesec; - ffloor_t *fflr = flash->ffloor; - sector_t *sector = flash->sector; + INT32 s; + ffloor_t *fflr; + sector_t *sector; + sector_t *sourcesec = flash->sourceline->frontsector; fixed_t top, bottom; - if (!fflr || !(fflr->flags & FF_EXISTS)) - return; + for (s = -1; (s = P_FindSectorFromTag(flash->tag, s)) >= 0 ;) + { + sector = §ors[s]; + for (fflr = sector->ffloors; fflr; fflr = fflr->next) + { + if (fflr->master != flash->sourceline) + continue; - if (leveltime & 2) - //fflr->flags |= FF_RENDERALL; - fflr->alpha = 0xB0; - else - //fflr->flags &= ~FF_RENDERALL; - fflr->alpha = 0x90; + if (!(fflr->flags & FF_EXISTS)) + break; - sourcesec = fflr->master->frontsector; // Less to type! + if (leveltime & 2) + //fflr->flags |= FF_RENDERALL; + fflr->alpha = 0xB0; + else + //fflr->flags &= ~FF_RENDERALL; + fflr->alpha = 0x90; - top = (*fflr->t_slope) ? P_GetZAt(*fflr->t_slope, sector->soundorg.x, sector->soundorg.y) - : *fflr->topheight; - bottom = (*fflr->b_slope) ? P_GetZAt(*fflr->b_slope, sector->soundorg.x, sector->soundorg.y) - : *fflr->bottomheight; - sector->soundorg.z = (top + bottom)/2; - S_StartSound(§or->soundorg, sfx_laser); + top = P_GetFFloorTopZAt (fflr, sector->soundorg.x, sector->soundorg.y); + bottom = P_GetFFloorBottomZAt(fflr, sector->soundorg.x, sector->soundorg.y); + sector->soundorg.z = (top + bottom)/2; + S_StartSound(§or->soundorg, sfx_laser); - // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* - for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next) - { - thing = node->m_thing; + // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* + for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next) + { + thing = node->m_thing; - if (flash->nobosses && thing->flags & MF_BOSS) - continue; // Don't hurt bosses + if (flash->nobosses && thing->flags & MF_BOSS) + continue; // Don't hurt bosses - // Don't endlessly kill egg guard shields (or anything else for that matter) - if (thing->health <= 0) - continue; + // Don't endlessly kill egg guard shields (or anything else for that matter) + if (thing->health <= 0) + continue; - top = P_GetSpecialTopZ(thing, sourcesec, sector); - bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + top = P_GetSpecialTopZ(thing, sourcesec, sector); + bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); - if (thing->z >= top - || thing->z + thing->height <= bottom) - continue; + if (thing->z >= top + || thing->z + thing->height <= bottom) + continue; - if (thing->flags & MF_SHOOTABLE) - P_DamageMobj(thing, NULL, NULL, 1, 0); - else if (thing->type == MT_EGGSHIELD) - P_KillMobj(thing, NULL, NULL, 0); + if (thing->flags & MF_SHOOTABLE) + P_DamageMobj(thing, NULL, NULL, 1, 0); + else if (thing->type == MT_EGGSHIELD) + P_KillMobj(thing, NULL, NULL, 0); + } + + break; + } } } -/** Adds a laser thinker to a 3Dfloor. - * - * \param fflr 3Dfloor to turn into a laser block. - * \param sector Target sector. - * \param secthkiners Lists of thinkers sorted by sector. May be NULL. - * \sa T_LaserFlash - * \author SSNTails <http://www.ssntails.org> - */ -static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *line, thinkerlist_t *secthinkers, boolean nobosses) +static inline void P_AddLaserThinker(INT16 tag, line_t *line, boolean nobosses) { - laserthink_t *flash; - ffloor_t *fflr = P_AddFakeFloor(sec, sec2, line, laserflags, secthinkers); - - if (!fflr) - return; - - flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); + laserthink_t *flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &flash->thinker); flash->thinker.function.acp1 = (actionf_p1)T_LaserFlash; - flash->ffloor = fflr; - flash->sector = sec; // For finding mobjs - flash->sec = sec2; + flash->tag = tag; flash->sourceline = line; flash->nobosses = nobosses; } @@ -6987,14 +6865,8 @@ void P_SpawnSpecials(boolean fromnetsave) fixed_t crushspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dy >> 3 : 10*FRACUNIT; fixed_t retractspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dx >> 3 : 2*FRACUNIT; UINT16 sound = (lines[i].flags & ML_EFFECT4) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; - - sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) - { - P_AddThwompThinker(§ors[sec], lines[i].tag, &lines[i], crushspeed, retractspeed, sound); - P_AddFakeFloor(§ors[s], §ors[sec], lines + i, - FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - } + P_AddThwompThinker(lines[i].frontsector, lines[i].tag, &lines[i], crushspeed, retractspeed, sound); + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); break; } @@ -7035,11 +6907,8 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 258: // Laser block - sec = sides[*lines[i].sidenum].sector - sectors; - - // No longer totally disrupts netgames - for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) - EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers, !!(lines[i].flags & ML_EFFECT1)); + P_AddLaserThinker(lines[i].tag, lines + i, !!(lines[i].flags & ML_EFFECT1)); + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT, secthinkers); break; case 259: // Custom FOF @@ -7196,6 +7065,9 @@ void P_SpawnSpecials(boolean fromnetsave) // 503 is used for a scroller // 504 is used for a scroller // 505 is used for a scroller + // 506 is used for a scroller + // 507 is used for a scroller + // 508 is used for a scroller // 510 is used for a scroller // 511 is used for a scroller // 512 is used for a scroller @@ -7712,7 +7584,20 @@ static void P_SpawnScrollers(void) case 502: for (s = -1; (s = P_FindLineFromTag(l->tag, s)) >= 0 ;) if (s != (INT32)i) - Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); + { + if (l->flags & ML_EFFECT2) // use texture offsets instead + { + dx = sides[l->sidenum[0]].textureoffset; + dy = sides[l->sidenum[0]].rowoffset; + } + if (l->flags & ML_EFFECT3) + { + if (lines[s].sidenum[1] != 0xffff) + Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[1], accel, 0); + } + else + Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); + } break; case 505: @@ -7726,7 +7611,25 @@ static void P_SpawnScrollers(void) if (s != 0xffff) Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[0], accel, 0); else - CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing 2nd side!\n", sizeu1(i)); + CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing back side!\n", sizeu1(i)); + break; + + case 507: + s = lines[i].sidenum[0]; + + if (lines[i].sidenum[1] != 0xffff) + Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[1], accel, 0); + else + CONS_Debug(DBG_GAMELOGIC, "Line special 507 (line #%s) missing back side!\n", sizeu1(i)); + break; + + case 508: + s = lines[i].sidenum[1]; + + if (s != 0xffff) + Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, s, accel, 0); + else + CONS_Debug(DBG_GAMELOGIC, "Line special 508 (line #%s) missing back side!\n", sizeu1(i)); break; case 500: // scroll first side @@ -7795,10 +7698,7 @@ void T_Disappear(disappear_t *d) if (!(lines[d->sourceline].flags & ML_NOCLIMB)) { - if (*rover->t_slope) - sectors[s].soundorg.z = P_GetZAt(*rover->t_slope, sectors[s].soundorg.x, sectors[s].soundorg.y); - else - sectors[s].soundorg.z = *rover->topheight; + sectors[s].soundorg.z = P_GetFFloorTopZAt(rover, sectors[s].soundorg.x, sectors[s].soundorg.y); S_StartSound(§ors[s].soundorg, sfx_appear); } } diff --git a/src/p_spec.h b/src/p_spec.h index 0228f8a028f34051f2db8069e579d7a8385faf33..596d8171d2acfb8b8b337f8a4fc4c686f2d3ce9b 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -104,9 +104,7 @@ typedef struct typedef struct { thinker_t thinker; ///< Thinker structure for laser. - ffloor_t *ffloor; ///< 3Dfloor that is a laser. - sector_t *sector; ///< Sector in which the effect takes place. - sector_t *sec; + INT16 tag; line_t *sourceline; UINT8 nobosses; } laserthink_t; diff --git a/src/p_user.c b/src/p_user.c index f5c8caf7265a72ffdcc350e6bc85fb8b2c3cb815..1cfcd0bde20c1d4185ed574f28ac2b0408a5a0c6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1916,7 +1916,7 @@ void P_SpawnShieldOrb(player_t *player) shieldobj->colorized = true; } else - shieldobj->color = (UINT8)shieldobj->info->painchance; + shieldobj->color = (UINT16)shieldobj->info->painchance; shieldobj->threshold = (player->powers[pw_shield] & SH_FORCE) ? SH_FORCE : (player->powers[pw_shield] & SH_NOSTACK); if (shieldobj->info->seestate) @@ -2267,8 +2267,8 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); if (mo->z + (mo->height/2) > topheight) continue; @@ -2505,8 +2505,8 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand if (!(rover->flags & FF_QUICKSAND)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y); if (mo->z + flipoffset > topheight) continue; @@ -2521,6 +2521,72 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand return false; // No sand here, Captain! } +static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover) +{ + if (!(rover->flags & FF_EXISTS)) + return false; + + if (!(rover->flags & FF_BUSTUP)) + return false; + + /*if (rover->master->frontsector->crumblestate != CRUMBLE_NONE) + return false;*/ + + // If it's an FF_SHATTER, you can break it just by touching it. + if (rover->flags & FF_SHATTER) + return true; + + // If it's an FF_SPINBUST, you can break it if you are in your spinning frames + // (either from jumping or spindashing). + if (rover->flags & FF_SPINBUST) + { + if ((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH)) + return true; + + if ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) + return true; + } + + // Strong abilities can break even FF_STRONGBUST. + if (player->charability == CA_GLIDEANDCLIMB) + return true; + + if (player->pflags & PF_BOUNCING) + return true; + + if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) + return true; + + if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) + return true; + + // Everyone else is out of luck. + if (rover->flags & FF_STRONGBUST) + return false; + + // Spinning (and not jumping) + if ((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) + return true; + + // Super + if (player->powers[pw_super]) + return true; + + // Dashmode + if ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) && player->dashmode >= DASHMODE_THRESHOLD) + return true; + + // NiGHTS drill + if (player->pflags & PF_DRILLING) + return true; + + // Recording for Metal Sonic + if (metalrecording) + return true; + + return false; +} + static void P_CheckBustableBlocks(player_t *player) { msecnode_t *node; @@ -2543,121 +2609,83 @@ static void P_CheckBustableBlocks(player_t *player) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + fixed_t topheight, bottomheight; + if (!node->m_sector) break; - if (node->m_sector->ffloors) - { - ffloor_t *rover; - fixed_t topheight, bottomheight; - - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) continue; + if (!node->m_sector->ffloors) + continue; - if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/) - { - // If it's an FF_SHATTER, you can break it just by touching it. - if (rover->flags & FF_SHATTER) - goto bust; - - // If it's an FF_SPINBUST, you can break it if you are in your spinning frames - // (either from jumping or spindashing). - if (rover->flags & FF_SPINBUST - && (((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH)) - || (player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE)))) - goto bust; - - // You can always break it if you have CA_GLIDEANDCLIMB - // or if you are bouncing on it - // or you are using CA_TWINSPIN/CA2_MELEE. - if (player->charability == CA_GLIDEANDCLIMB - || (player->pflags & PF_BOUNCING) - || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) - goto bust; - - if (rover->flags & FF_STRONGBUST) - continue; + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!P_PlayerCanBust(player, rover)) + continue; - // If it's not an FF_STRONGBUST, you can break if you are spinning (and not jumping) - // or you are super - // or you are in dashmode with SF_DASHMODE - // or you are drilling in NiGHTS - // or you are recording for Metal Sonic - if (!((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) - && !(player->powers[pw_super]) - && !(((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (player->dashmode >= DASHMODE_THRESHOLD)) - && !(player->pflags & PF_DRILLING) - && !metalrecording) - continue; + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bust: - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - - if (((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - || ((P_MobjFlip(player->mo)*player->mo->momz < 0) && (player->pflags & PF_BOUNCING || ((player->charability2 == CA2_MELEE) && (player->panim == PA_ABILITY2))))) - { - topheight -= player->mo->momz; - bottomheight -= player->mo->momz; - } + if (((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + || ((P_MobjFlip(player->mo)*player->mo->momz < 0) && (player->pflags & PF_BOUNCING || ((player->charability2 == CA2_MELEE) && (player->panim == PA_ABILITY2))))) + { + topheight -= player->mo->momz; + bottomheight -= player->mo->momz; + } - // Height checks - if (rover->flags & FF_SHATTERBOTTOM) - { - if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) - continue; + // Height checks + if (rover->flags & FF_SHATTERBOTTOM) + { + if (player->mo->z + player->mo->momz + player->mo->height < bottomheight) + continue; - if (player->mo->z+player->mo->height > bottomheight) - continue; - } - else if (rover->flags & FF_SPINBUST) - { - if (player->mo->z+player->mo->momz > topheight) - continue; + if (player->mo->z + player->mo->height > bottomheight) + continue; + } + else if (rover->flags & FF_SPINBUST) + { + if (player->mo->z + player->mo->momz > topheight) + continue; - if (player->mo->z + player->mo->height < bottomheight) - continue; - } - else if (rover->flags & FF_SHATTER) - { - if (player->mo->z + player->mo->momz > topheight) - continue; + if (player->mo->z + player->mo->height < bottomheight) + continue; + } + else if (rover->flags & FF_SHATTER) + { + if (player->mo->z + player->mo->momz > topheight) + continue; - if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) - continue; - } - else - { - if (player->mo->z >= topheight) - continue; + if (player->mo->z + player->mo->momz + player->mo->height < bottomheight) + continue; + } + else + { + if (player->mo->z >= topheight) + continue; - if (player->mo->z + player->mo->height < bottomheight) - continue; - } + if (player->mo->z + player->mo->height < bottomheight) + continue; + } - // Impede the player's fall a bit - if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight) - player->mo->momz >>= 1; - else if (rover->flags & FF_SHATTER) - { - player->mo->momx >>= 1; - player->mo->momy >>= 1; - } + // Impede the player's fall a bit + if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight) + player->mo->momz >>= 1; + else if (rover->flags & FF_SHATTER) + { + player->mo->momx >>= 1; + player->mo->momy >>= 1; + } - //if (metalrecording) - // G_RecordBustup(rover); + //if (metalrecording) + // G_RecordBustup(rover); - EV_CrumbleChain(NULL, rover); // node->m_sector + EV_CrumbleChain(NULL, rover); // node->m_sector - // Run a linedef executor?? - if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); + // Run a linedef executor?? + if (rover->master->flags & ML_EFFECT5) + P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); - goto bustupdone; - } - } + goto bustupdone; } } bustupdone: @@ -2690,122 +2718,109 @@ static void P_CheckBouncySectors(player_t *player) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + if (!node->m_sector) break; - if (node->m_sector->ffloors) + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - boolean top = true; + fixed_t bouncestrength; fixed_t topheight, bottomheight; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) - continue; // FOFs should not be bouncy if they don't even "exist" - - if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15) - continue; // this sector type is required for FOFs to be bouncy - - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - - if (player->mo->z > topheight) - continue; - - if (player->mo->z + player->mo->height < bottomheight) - continue; - - if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) - && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) - top = false; - - { - fixed_t linedist; - - linedist = P_AproxDistance(rover->master->v1->x-rover->master->v2->x, rover->master->v1->y-rover->master->v2->y); - - linedist = FixedDiv(linedist,100*FRACUNIT); + if (!(rover->flags & FF_EXISTS)) + continue; // FOFs should not be bouncy if they don't even "exist" - if (top) - { - fixed_t newmom; + if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15) + continue; // this sector type is required for FOFs to be bouncy - pslope_t *slope; - if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top - slope = *rover->t_slope; - } else { // Hit bottom - slope = *rover->b_slope; - } + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - momentum.x = player->mo->momx; - momentum.y = player->mo->momy; - momentum.z = player->mo->momz*2; + if (player->mo->z > topheight) + continue; - if (slope) - P_ReverseQuantizeMomentumToSlope(&momentum, slope); + if (player->mo->z + player->mo->height < bottomheight) + continue; - newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; + bouncestrength = P_AproxDistance(rover->master->dx, rover->master->dy)/100; - if (abs(newmom) < (linedist*2)) - { - goto bouncydone; - } + if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) + && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) + { + player->mo->momx = -FixedMul(player->mo->momx,bouncestrength); + player->mo->momy = -FixedMul(player->mo->momy,bouncestrength); - if (!(rover->master->flags & ML_BOUNCY)) - { - if (newmom > 0) - { - if (newmom < 8*FRACUNIT) - newmom = 8*FRACUNIT; - } - else if (newmom > -8*FRACUNIT && newmom != 0) - newmom = -8*FRACUNIT; - } + if (player->pflags & PF_SPINNING) + { + player->pflags &= ~PF_SPINNING; + player->pflags |= P_GetJumpFlags(player); + player->pflags |= PF_THOKKED; + } + } + else + { + fixed_t newmom; + pslope_t *slope = (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) ? *rover->t_slope : *rover->b_slope; - if (newmom > P_GetPlayerHeight(player)/2) - newmom = P_GetPlayerHeight(player)/2; - else if (newmom < -P_GetPlayerHeight(player)/2) - newmom = -P_GetPlayerHeight(player)/2; + momentum.x = player->mo->momx; + momentum.y = player->mo->momy; + momentum.z = player->mo->momz*2; - momentum.z = newmom*2; + if (slope) + P_ReverseQuantizeMomentumToSlope(&momentum, slope); - if (slope) - P_QuantizeMomentumToSlope(&momentum, slope); + newmom = momentum.z = -FixedMul(momentum.z,bouncestrength)/2; - player->mo->momx = momentum.x; - player->mo->momy = momentum.y; - player->mo->momz = momentum.z/2; + if (abs(newmom) < (bouncestrength*2)) + goto bouncydone; - if (player->pflags & PF_SPINNING) - { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); - player->pflags |= PF_THOKKED; - } - } - else + if (!(rover->master->flags & ML_BOUNCY)) + { + if (newmom > 0) { - player->mo->momx = -FixedMul(player->mo->momx,linedist); - player->mo->momy = -FixedMul(player->mo->momy,linedist); - - if (player->pflags & PF_SPINNING) - { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); - player->pflags |= PF_THOKKED; - } + if (newmom < 8*FRACUNIT) + newmom = 8*FRACUNIT; } - - if ((player->pflags & PF_SPINNING) && player->speed < FixedMul(1<<FRACBITS, player->mo->scale) && player->mo->momz) + else if (newmom < 0) { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); + if (newmom > -8*FRACUNIT) + newmom = -8*FRACUNIT; } + } - goto bouncydone; + if (newmom > P_GetPlayerHeight(player)/2) + newmom = P_GetPlayerHeight(player)/2; + else if (newmom < -P_GetPlayerHeight(player)/2) + newmom = -P_GetPlayerHeight(player)/2; + + momentum.z = newmom*2; + + if (slope) + P_QuantizeMomentumToSlope(&momentum, slope); + + player->mo->momx = momentum.x; + player->mo->momy = momentum.y; + player->mo->momz = momentum.z/2; + + if (player->pflags & PF_SPINNING) + { + player->pflags &= ~PF_SPINNING; + player->pflags |= P_GetJumpFlags(player); + player->pflags |= PF_THOKKED; } } + + if ((player->pflags & PF_SPINNING) && player->speed < FixedMul(1<<FRACBITS, player->mo->scale) && player->mo->momz) + { + player->pflags &= ~PF_SPINNING; + player->pflags |= P_GetJumpFlags(player); + } + + goto bouncydone; } } bouncydone: @@ -2832,8 +2847,8 @@ static void P_CheckQuicksand(player_t *player) if (!(rover->flags & FF_QUICKSAND)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height) { @@ -2986,7 +3001,7 @@ static void P_CheckInvincibilityTimer(player_t *player) return; if (mariomode && !player->powers[pw_super]) - player->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours + player->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (numskincolors - SKINCOLOR_RUBY))); // Passes through all saturated colours else if (leveltime % (TICRATE/7) == 0) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); @@ -3173,10 +3188,8 @@ static void P_DoClimbing(player_t *player) floorclimb = true; else { - floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) - : glidesector->sector->floorheight; - ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) - : glidesector->sector->ceilingheight; + floorheight = P_GetSectorFloorZAt (glidesector->sector, player->mo->x, player->mo->y); + ceilingheight = P_GetSectorCeilingZAt(glidesector->sector, player->mo->x, player->mo->y); if (glidesector->sector->ffloors) { @@ -3190,8 +3203,8 @@ static void P_DoClimbing(player_t *player) floorclimb = true; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); // Only supports rovers that are moving like an 'elevator', not just the top or bottom. if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) @@ -3232,8 +3245,7 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; - + bottomheight2 = P_GetFFloorBottomZAt(roverbelow, player->mo->x, player->mo->y); if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -3278,8 +3290,7 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; - + topheight2 = P_GetFFloorTopZAt(roverbelow, player->mo->x, player->mo->y); if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -3333,8 +3344,7 @@ static void P_DoClimbing(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; - + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; @@ -3374,8 +3384,7 @@ static void P_DoClimbing(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - + topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y); if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; @@ -3747,12 +3756,8 @@ static void P_DoTeeter(player_t *player) sec = R_PointInSubsector(checkx, checky)->sector; - ceilingheight = sec->ceilingheight; - floorheight = sec->floorheight; - if (sec->c_slope) - ceilingheight = P_GetZAt(sec->c_slope, checkx, checky); - if (sec->f_slope) - floorheight = P_GetZAt(sec->f_slope, checkx, checky); + ceilingheight = P_GetSectorCeilingZAt(sec, checkx, checky); + floorheight = P_GetSectorFloorZAt (sec, checkx, checky); highestceilingheight = (ceilingheight > highestceilingheight) ? ceilingheight : highestceilingheight; lowestfloorheight = (floorheight < lowestfloorheight) ? floorheight : lowestfloorheight; @@ -3763,8 +3768,8 @@ static void P_DoTeeter(player_t *player) { if (!(rover->flags & FF_EXISTS)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (P_CheckSolidLava(rover)) ; @@ -7743,7 +7748,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) if (player->mo->standingslope) { - ground = P_GetZAt(player->mo->standingslope, newx, newy); + ground = P_GetSlopeZAt(player->mo->standingslope, newx, newy); if (player->mo->eflags & MFE_VERTICALFLIP) ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); } @@ -8719,10 +8724,7 @@ static void P_MovePlayer(player_t *player) static void P_DoZoomTube(player_t *player) { - INT32 sequence; fixed_t speed; - thinker_t *th; - mobj_t *mo2; mobj_t *waypoint = NULL; fixed_t dist; boolean reverse; @@ -8738,8 +8740,6 @@ static void P_DoZoomTube(player_t *player) speed = abs(player->speed); - sequence = player->mo->tracer->threshold; - // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); @@ -8771,28 +8771,7 @@ static void P_DoZoomTube(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); // Find next waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (reverse && mo2->health != player->mo->tracer->health - 1) - continue; - - if (!reverse && mo2->health != player->mo->tracer->health + 1) - continue; - - waypoint = mo2; - break; - } + waypoint = reverse ? P_GetPreviousWaypoint(player->mo->tracer, false) : P_GetNextWaypoint(player->mo->tracer, false); if (waypoint) { @@ -8843,8 +8822,6 @@ static void P_DoRopeHang(player_t *player) { INT32 sequence; fixed_t speed; - thinker_t *th; - mobj_t *mo2; mobj_t *waypoint = NULL; fixed_t dist; fixed_t playerz; @@ -8907,50 +8884,14 @@ static void P_DoRopeHang(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); // Find next waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (mo2->health != player->mo->tracer->health + 1) - continue; - - waypoint = mo2; - break; - } + waypoint = P_GetNextWaypoint(player->mo->tracer, false); if (!(player->mo->tracer->flags & MF_SLIDEME) && !waypoint) { CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, wrapping to start...\n"); // Wrap around back to first waypoint - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold != sequence) - continue; - - if (mo2->health != 0) - continue; - - waypoint = mo2; - break; - } + waypoint = P_GetFirstWaypoint(sequence); } if (waypoint) @@ -10646,8 +10587,8 @@ static void P_CalcPostImg(player_t *player) if (!(rover->flags & FF_EXISTS)) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (pviewheight >= topheight || pviewheight <= bottomheight) continue; @@ -10669,8 +10610,8 @@ static void P_CalcPostImg(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER) continue; - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); + bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y); if (pviewheight >= topheight || pviewheight <= bottomheight) continue; @@ -10732,7 +10673,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n if (!(rover->flags & (FF_EXISTS|FF_BLOCKOTHERS))) continue; - *nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; + *nz = P_GetFFloorTopZAt(rover, x, y); if (abs(z - *nz) <= 56*FRACUNIT) { sec = §ors[rover->secnum]; @@ -10742,7 +10683,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n } - *nz = sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight; + *nz = P_GetSectorFloorZAt(sec, x, y); if (abs(z - *nz) > 56*FRACUNIT) return NULL; @@ -11096,8 +11037,8 @@ static void P_MinecartThink(player_t *player) if (minecart->standingslope) { fixed_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t front = P_GetZAt(minecart->standingslope, minecart->x, minecart->y); - fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2)); + fixed_t front = P_GetSlopeZAt(minecart->standingslope, minecart->x, minecart->y); + fixed_t back = P_GetSlopeZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2)); if (abs(front - back) < 3*FRACUNIT) currentSpeed += (back - front)/3; @@ -11918,6 +11859,9 @@ void P_PlayerThink(player_t *player) factor = 4; } break; + case CR_DUSTDEVIL: + player->drawangle += ANG20; + break; /* -- in case we wanted to have the camera freely movable during zoom tubes case CR_ZOOMTUBE:*/ case CR_ROPEHANG: @@ -12690,6 +12634,19 @@ void P_PlayerAfterThink(player_t *player) } break; } + case CR_DUSTDEVIL: + { + mobj_t *mo = player->mo, *dustdevil = player->mo->tracer; + + if (abs(mo->x - dustdevil->x) > dustdevil->radius || abs(mo->y - dustdevil->y) > dustdevil->radius) + { + P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_carry] = CR_NONE; + break; + } + + break; + } case CR_ROLLOUT: { mobj_t *mo = player->mo, *rock = player->mo->tracer; diff --git a/src/r_bsp.c b/src/r_bsp.c index 3bd023dbf1012bd0315f927d2b8c4fbb739ba355..60291da0ff12b64fd5f55ba52e044ce9d966cf56 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -495,16 +495,13 @@ static void R_AddLine(seg_t *line) fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \ - end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, line->v1->x, line->v1->y, normalheight); \ + end2 = P_GetZAt(slope, line->v2->x, line->v2->y, normalheight); - SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight) + SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector-> floorheight) SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight) - SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight) - SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) + SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector-> floorheight) + SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) #undef SLOPEPARAMS // if both ceilings are skies, consider it always "open" // same for floors @@ -851,13 +848,8 @@ static void R_Subsector(size_t num) floorcolormap = ceilingcolormap = frontsector->extra_colormap; - floorcenterz = frontsector->f_slope ? - P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - frontsector->floorheight; - - ceilingcenterz = frontsector->c_slope ? - P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - frontsector->ceilingheight; + floorcenterz = P_GetSectorFloorZAt (frontsector, frontsector->soundorg.x, frontsector->soundorg.y); + ceilingcenterz = P_GetSectorCeilingZAt(frontsector, frontsector->soundorg.x, frontsector->soundorg.y); // Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps. if (frontsector->ffloors) @@ -883,7 +875,7 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; - if ((frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : frontsector->floorheight) < viewz + if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz || frontsector->floorpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { @@ -893,7 +885,7 @@ static void R_Subsector(size_t num) else floorplane = NULL; - if ((frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : frontsector->ceilingheight) > viewz + if (P_GetSectorCeilingZAt(frontsector, viewx, viewy) > viewz || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) { @@ -930,13 +922,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - heightcheck = *rover->b_slope ? - P_GetZAt(*rover->b_slope, viewx, viewy) : - *rover->bottomheight; + heightcheck = P_GetFFloorBottomZAt(rover, viewx, viewy); - planecenterz = *rover->b_slope ? - P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - *rover->bottomheight; + planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz <= ceilingcenterz && planecenterz >= floorcenterz && ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) @@ -964,13 +952,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - heightcheck = *rover->t_slope ? - P_GetZAt(*rover->t_slope, viewx, viewy) : - *rover->topheight; + heightcheck = P_GetFFloorTopZAt(rover, viewx, viewy); - planecenterz = *rover->t_slope ? - P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : - *rover->topheight; + planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz >= floorcenterz && planecenterz <= ceilingcenterz && ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) @@ -1133,7 +1117,7 @@ void R_Prep3DFloors(sector_t *sector) else memset(sector->lightlist, 0, sizeof (lightlist_t) * count); - heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; + heighttest = P_GetSectorCeilingZAt(sector, sector->soundorg.x, sector->soundorg.y); sector->lightlist[0].height = heighttest + 1; sector->lightlist[0].slope = sector->c_slope; @@ -1154,7 +1138,7 @@ void R_Prep3DFloors(sector_t *sector) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) continue; - heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight; + heighttest = P_GetFFloorTopZAt(rover, sector->soundorg.x, sector->soundorg.y); if (heighttest > bestheight && heighttest < maxheight) { @@ -1164,7 +1148,7 @@ void R_Prep3DFloors(sector_t *sector) continue; } if (rover->flags & FF_DOUBLESHADOW) { - heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight; + heighttest = P_GetFFloorBottomZAt(rover, sector->soundorg.x, sector->soundorg.y); if (heighttest > bestheight && heighttest < maxheight) @@ -1206,7 +1190,7 @@ void R_Prep3DFloors(sector_t *sector) if (best->flags & FF_DOUBLESHADOW) { - heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight; + heighttest = P_GetFFloorBottomZAt(best, sector->soundorg.x, sector->soundorg.y); if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red { sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; diff --git a/src/r_draw.c b/src/r_draw.c index 0155ec113365735bd1e76ac1bceac4d121875b4f..5351ef37f079b151a0c5c3effd5fe3d006109783 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -135,318 +135,6 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; static UINT8** translationtablecache[MAXSKINS + 7] = {NULL}; -const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { - // {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_NONE - - // Greyscale ranges - {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11}, // SKINCOLOR_WHITE - {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12}, // SKINCOLOR_BONE - {0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, // SKINCOLOR_CLOUDY - {0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, // SKINCOLOR_GREY - {0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, // SKINCOLOR_SILVER - {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1c, 0x1d}, // SKINCOLOR_CARBON - {0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_JET - {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, // SKINCOLOR_BLACK - - // Desaturated - {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AETHER - {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_SLATE - {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, // SKINCOLOR_BLUEBELL - {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, // SKINCOLOR_PINK - {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, // SKINCOLOR_YOGURT - {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, // SKINCOLOR_BROWN - {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, // SKINCOLOR_BRONZE - {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, // SKINCOLOR_TAN - {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, // SKINCOLOR_BEIGE - {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, // SKINCOLOR_MOSS - {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AZURE - {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, // SKINCOLOR_LAVENDER - - // Viv's vivid colours (toast 21/07/17) - {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, // SKINCOLOR_RUBY - {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, // SKINCOLOR_SALMON - {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, // SKINCOLOR_RED - {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, // SKINCOLOR_CRIMSON - {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, // SKINCOLOR_FLAME - {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, // SKINCOLOR_KETCHUP - {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, // SKINCOLOR_PEACHY - {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, // SKINCOLOR_QUAIL - {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, // SKINCOLOR_SUNSET - {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, // SKINCOLOR_COPPER - {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, // SKINCOLOR_APRICOT - {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, // SKINCOLOR_ORANGE - {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_RUST - {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_GOLD - {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, // SKINCOLOR_SANDY - {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, // SKINCOLOR_YELLOW - {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, // SKINCOLOR_OLIVE - {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_LIME - {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, // SKINCOLOR_PERIDOT - {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, // SKINCOLOR_APPLE - {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_GREEN - {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, // SKINCOLOR_FOREST - {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, // SKINCOLOR_EMERALD - {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, // SKINCOLOR_MINT - {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, // SKINCOLOR_SEAFOAM - {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, // SKINCOLOR_AQUA - {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, // SKINCOLOR_TEAL - {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_WAVE - {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, // SKINCOLOR_CYAN - {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SKY - {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_CERULEAN - {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_ICY - {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_SAPPHIRE - {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, // SKINCOLOR_CORNFLOWER - {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_BLUE - {0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_COBALT - {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_VAPOR - {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_DUSK - {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_PASTEL - {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_PURPLE - {0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_BUBBLEGUM - {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, // SKINCOLOR_MAGENTA - {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, // SKINCOLOR_NEON - {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_VIOLET - {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, // SKINCOLOR_LILAC - {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, // SKINCOLOR_PLUM - {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, // SKINCOLOR_RASPBERRY - {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, // SKINCOLOR_ROSY - - // {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_? - - // super - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, // SKINCOLOR_SUPERSILVER1 - {0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, // SKINCOLOR_SUPERSILVER2 - {0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, // SKINCOLOR_SUPERSILVER3 - {0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, // SKINCOLOR_SUPERSILVER4 - {0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, // SKINCOLOR_SUPERSILVER5 - - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, // SKINCOLOR_SUPERRED1 - {0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, // SKINCOLOR_SUPERRED2 - {0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, // SKINCOLOR_SUPERRED3 - {0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, // SKINCOLOR_SUPERRED4 - {0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, // SKINCOLOR_SUPERRED5 - - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, // SKINCOLOR_SUPERORANGE1 - {0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, // SKINCOLOR_SUPERORANGE2 - {0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, // SKINCOLOR_SUPERORANGE3 - {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4 - {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5 - - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48, 0x48, 0x48}, // SKINCOLOR_SUPERGOLD1 - {0x00, 0x50, 0x51, 0x52, 0x53, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x41, 0x41}, // SKINCOLOR_SUPERGOLD2 - {0x51, 0x52, 0x53, 0x53, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x43, 0x43}, // SKINCOLOR_SUPERGOLD3 - {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, 0x46}, // SKINCOLOR_SUPERGOLD4 - {0x48, 0x48, 0x49, 0x49, 0x49, 0x40, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x47}, // SKINCOLOR_SUPERGOLD5 - - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1 - {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2 - {0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, // SKINCOLOR_SUPERPERIDOT3 - {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, // SKINCOLOR_SUPERPERIDOT4 - {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, // SKINCOLOR_SUPERPERIDOT5 - - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, // SKINCOLOR_SUPERSKY1 - {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, // SKINCOLOR_SUPERSKY2 - {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, // SKINCOLOR_SUPERSKY3 - {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, // SKINCOLOR_SUPERSKY4 - {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SUPERSKY5 - - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, // SKINCOLOR_SUPERPURPLE1 - {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, // SKINCOLOR_SUPERPURPLE2 - {0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, // SKINCOLOR_SUPERPURPLE3 - {0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, // SKINCOLOR_SUPERPURPLE4 - {0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, // SKINCOLOR_SUPERPURPLE5 - - {0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST1 - {0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST2 - {0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST3 - {0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST4 - {0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, // SKINCOLOR_SUPERRUST5 - - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, // SKINCOLOR_SUPERTAN1 - {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, // SKINCOLOR_SUPERTAN2 - {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, // SKINCOLOR_SUPERTAN3 - {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, // SKINCOLOR_SUPERTAN4 - {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef} // SKINCOLOR_SUPERTAN5 -}; - -// See also the enum skincolors_t -// TODO Callum: Can this be translated? -const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = -{ - "None", // SKINCOLOR_NONE, - - // Greyscale ranges - "White", // SKINCOLOR_WHITE, - "Bone", // SKINCOLOR_BONE, - "Cloudy", // SKINCOLOR_CLOUDY, - "Grey", // SKINCOLOR_GREY, - "Silver", // SKINCOLOR_SILVER, - "Carbon", // SKINCOLOR_CARBON, - "Jet", // SKINCOLOR_JET, - "Black", // SKINCOLOR_BLACK, - - // Desaturated - "Aether", // SKINCOLOR_AETHER, - "Slate", // SKINCOLOR_SLATE, - "Bluebell", // SKINCOLOR_BLUEBELL, - "Pink", // SKINCOLOR_PINK, - "Yogurt", // SKINCOLOR_YOGURT, - "Brown", // SKINCOLOR_BROWN, - "Bronze", // SKINCOLOR_BRONZE, - "Tan", // SKINCOLOR_TAN, - "Beige", // SKINCOLOR_BEIGE, - "Moss", // SKINCOLOR_MOSS, - "Azure", // SKINCOLOR_AZURE, - "Lavender", // SKINCOLOR_LAVENDER, - - // Viv's vivid colours (toast 21/07/17) - "Ruby", // SKINCOLOR_RUBY, - "Salmon", // SKINCOLOR_SALMON, - "Red", // SKINCOLOR_RED, - "Crimson", // SKINCOLOR_CRIMSON, - "Flame", // SKINCOLOR_FLAME, - "Ketchup", // SKINCOLOR_KETCHUP, - "Peachy", // SKINCOLOR_PEACHY, - "Quail", // SKINCOLOR_QUAIL, - "Sunset", // SKINCOLOR_SUNSET, - "Copper", // SKINCOLOR_COPPER, - "Apricot", // SKINCOLOR_APRICOT, - "Orange", // SKINCOLOR_ORANGE, - "Rust", // SKINCOLOR_RUST, - "Gold", // SKINCOLOR_GOLD, - "Sandy", // SKINCOLOR_SANDY, - "Yellow", // SKINCOLOR_YELLOW, - "Olive", // SKINCOLOR_OLIVE, - "Lime", // SKINCOLOR_LIME, - "Peridot", // SKINCOLOR_PERIDOT, - "Apple", // SKINCOLOR_APPLE, - "Green", // SKINCOLOR_GREEN, - "Forest", // SKINCOLOR_FOREST, - "Emerald", // SKINCOLOR_EMERALD, - "Mint", // SKINCOLOR_MINT, - "Seafoam", // SKINCOLOR_SEAFOAM, - "Aqua", // SKINCOLOR_AQUA, - "Teal", // SKINCOLOR_TEAL, - "Wave", // SKINCOLOR_WAVE, - "Cyan", // SKINCOLOR_CYAN, - "Sky", // SKINCOLOR_SKY, - "Cerulean", // SKINCOLOR_CERULEAN, - "Icy", // SKINCOLOR_ICY, - "Sapphire", // SKINCOLOR_SAPPHIRE, - "Cornflower", // SKINCOLOR_CORNFLOWER, - "Blue", // SKINCOLOR_BLUE, - "Cobalt", // SKINCOLOR_COBALT, - "Vapor", // SKINCOLOR_VAPOR, - "Dusk", // SKINCOLOR_DUSK, - "Pastel", // SKINCOLOR_PASTEL, - "Purple", // SKINCOLOR_PURPLE, - "Bubblegum", // SKINCOLOR_BUBBLEGUM, - "Magenta", // SKINCOLOR_MAGENTA, - "Neon", // SKINCOLOR_NEON, - "Violet", // SKINCOLOR_VIOLET, - "Lilac", // SKINCOLOR_LILAC, - "Plum", // SKINCOLOR_PLUM, - "Raspberry", // SKINCOLOR_RASPBERRY, - "Rosy", // SKINCOLOR_ROSY, - - // Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName. - "Silver", // SKINCOLOR_SUPERSILVER1, - "Red", // SKINCOLOR_SUPERRED1, - "Orange", // SKINCOLOR_SUPERORANGE1, - "Gold", // SKINCOLOR_SUPERGOLD1, - "Peridot", // SKINCOLOR_SUPERPERIDOT1, - "Sky", // SKINCOLOR_SUPERSKY1, - "Purple", // SKINCOLOR_SUPERPURPLE1, - "Rust", // SKINCOLOR_SUPERRUST1, - "Tan" // SKINCOLOR_SUPERTAN1, -}; - -/* -A word of warning: If the following array is non-symmetrical, -A_SignPlayer's prefoppositecolor behaviour will break. -*/ -// [0] = opposite skin color, -// [1] = shade index used by signpost, 0-15 (actual sprite frame is 15 minus this value) -const UINT8 Color_Opposite[MAXSKINCOLORS - 1][2] = -{ - // {SKINCOLOR_NONE, 8}, // SKINCOLOR_NONE - - // Greyscale ranges - {SKINCOLOR_BLACK, 5}, // SKINCOLOR_WHITE, - {SKINCOLOR_JET, 7}, // SKINCOLOR_BONE, - {SKINCOLOR_CARBON, 7}, // SKINCOLOR_CLOUDY, - {SKINCOLOR_AETHER, 12}, // SKINCOLOR_GREY, - {SKINCOLOR_SLATE, 12}, // SKINCOLOR_SILVER, - {SKINCOLOR_CLOUDY, 7}, // SKINCOLOR_CARBON, - {SKINCOLOR_BONE, 7}, // SKINCOLOR_JET, - {SKINCOLOR_WHITE, 7}, // SKINCOLOR_BLACK, - - // Desaturated - {SKINCOLOR_GREY, 15}, // SKINCOLOR_AETHER, - {SKINCOLOR_SILVER, 12}, // SKINCOLOR_SLATE, - {SKINCOLOR_COPPER, 4}, // SKINCOLOR_BLUEBELL, - {SKINCOLOR_AZURE, 9}, // SKINCOLOR_PINK, - {SKINCOLOR_RUST, 7}, // SKINCOLOR_YOGURT, - {SKINCOLOR_TAN, 2}, // SKINCOLOR_BROWN, - {SKINCOLOR_KETCHUP, 0}, // SKINCOLOR_BRONZE, - {SKINCOLOR_BROWN, 12}, // SKINCOLOR_TAN, - {SKINCOLOR_MOSS, 5}, // SKINCOLOR_BEIGE, - {SKINCOLOR_BEIGE, 13}, // SKINCOLOR_MOSS, - {SKINCOLOR_PINK, 5}, // SKINCOLOR_AZURE, - {SKINCOLOR_GOLD, 4}, // SKINCOLOR_LAVENDER, - - // Viv's vivid colours (toast 21/07/17) - {SKINCOLOR_EMERALD, 10}, // SKINCOLOR_RUBY, - {SKINCOLOR_FOREST, 6}, // SKINCOLOR_SALMON, - {SKINCOLOR_GREEN, 10}, // SKINCOLOR_RED, - {SKINCOLOR_ICY, 10}, // SKINCOLOR_CRIMSON, - {SKINCOLOR_PURPLE, 8}, // SKINCOLOR_FLAME, - {SKINCOLOR_BRONZE, 8}, // SKINCOLOR_KETCHUP, - {SKINCOLOR_TEAL, 7}, // SKINCOLOR_PEACHY, - {SKINCOLOR_WAVE, 5}, // SKINCOLOR_QUAIL, - {SKINCOLOR_SAPPHIRE, 5}, // SKINCOLOR_SUNSET, - {SKINCOLOR_BLUEBELL, 5}, // SKINCOLOR_COPPER - {SKINCOLOR_CYAN, 4}, // SKINCOLOR_APRICOT, - {SKINCOLOR_BLUE, 4}, // SKINCOLOR_ORANGE, - {SKINCOLOR_YOGURT, 8}, // SKINCOLOR_RUST, - {SKINCOLOR_LAVENDER, 10}, // SKINCOLOR_GOLD, - {SKINCOLOR_SKY, 8}, // SKINCOLOR_SANDY, - {SKINCOLOR_CORNFLOWER, 8}, // SKINCOLOR_YELLOW, - {SKINCOLOR_DUSK, 3}, // SKINCOLOR_OLIVE, - {SKINCOLOR_MAGENTA, 9}, // SKINCOLOR_LIME, - {SKINCOLOR_COBALT, 2}, // SKINCOLOR_PERIDOT, - {SKINCOLOR_RASPBERRY, 13}, // SKINCOLOR_APPLE, - {SKINCOLOR_RED, 6}, // SKINCOLOR_GREEN, - {SKINCOLOR_SALMON, 9}, // SKINCOLOR_FOREST, - {SKINCOLOR_RUBY, 4}, // SKINCOLOR_EMERALD, - {SKINCOLOR_VIOLET, 5}, // SKINCOLOR_MINT, - {SKINCOLOR_PLUM, 6}, // SKINCOLOR_SEAFOAM, - {SKINCOLOR_ROSY, 7}, // SKINCOLOR_AQUA, - {SKINCOLOR_PEACHY, 7}, // SKINCOLOR_TEAL, - {SKINCOLOR_QUAIL, 5}, // SKINCOLOR_WAVE, - {SKINCOLOR_APRICOT, 6}, // SKINCOLOR_CYAN, - {SKINCOLOR_SANDY, 1}, // SKINCOLOR_SKY, - {SKINCOLOR_NEON, 4}, // SKINCOLOR_CERULEAN, - {SKINCOLOR_CRIMSON, 0}, // SKINCOLOR_ICY, - {SKINCOLOR_SUNSET, 5}, // SKINCOLOR_SAPPHIRE, - {SKINCOLOR_YELLOW, 4}, // SKINCOLOR_CORNFLOWER, - {SKINCOLOR_ORANGE, 5}, // SKINCOLOR_BLUE, - {SKINCOLOR_PERIDOT, 5}, // SKINCOLOR_COBALT, - {SKINCOLOR_LILAC, 4}, // SKINCOLOR_VAPOR, - {SKINCOLOR_OLIVE, 0}, // SKINCOLOR_DUSK, - {SKINCOLOR_BUBBLEGUM, 9}, // SKINCOLOR_PASTEL, - {SKINCOLOR_FLAME, 7}, // SKINCOLOR_PURPLE, - {SKINCOLOR_PASTEL, 8}, // SKINCOLOR_BUBBLEGUM, - {SKINCOLOR_LIME, 6}, // SKINCOLOR_MAGENTA, - {SKINCOLOR_CERULEAN, 2}, // SKINCOLOR_NEON, - {SKINCOLOR_MINT, 6}, // SKINCOLOR_VIOLET, - {SKINCOLOR_VAPOR, 4}, // SKINCOLOR_LILAC, - {SKINCOLOR_MINT, 7}, // SKINCOLOR_PLUM, - {SKINCOLOR_APPLE, 13}, // SKINCOLOR_RASPBERRY - {SKINCOLOR_AQUA, 1} // SKINCOLOR_ROSY, -}; - CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; /** \brief The R_InitTranslationTables @@ -496,7 +184,7 @@ void R_InitTranslationTables(void) \param dest_colormap colormap to populate \param skincolor translation color */ -static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) +static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor) { INT32 i; RGBA_t color; @@ -509,7 +197,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) // first generate the brightness of all the colours of that skincolour for (i = 0; i < 16; i++) { - color = V_GetColor(Color_Index[skincolor-1][i]); + color = V_GetColor(skincolors[skincolor].ramp[i]); SETBRIGHTNESS(colorbrightnesses[i], color.s.red, color.s.green, color.s.blue); } @@ -530,7 +218,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) if (temp < brightdif) { brightdif = (UINT16)temp; - dest_colormap[i] = Color_Index[skincolor-1][j]; + dest_colormap[i] = skincolors[skincolor].ramp[j]; } } } @@ -538,7 +226,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) #undef SETBRIGHTNESS -static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) +static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT16 color) { INT32 i, starttranscolor, skinramplength; @@ -551,7 +239,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8)); return; case TC_RAINBOW: - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) I_Error("Invalid skin color #%hu.", (UINT16)color); if (color != SKINCOLOR_NONE) { @@ -560,11 +248,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U } break; case TC_BLINK: - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) I_Error("Invalid skin color #%hu.", (UINT16)color); if (color != SKINCOLOR_NONE) { - memset(dest_colormap, Color_Index[color-1][3], NUM_PALETTE_ENTRIES * sizeof(UINT8)); + memset(dest_colormap, skincolors[color].ramp[3], NUM_PALETTE_ENTRIES * sizeof(UINT8)); return; } break; @@ -585,11 +273,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U { for (i = 0; i < 6; i++) { - dest_colormap[Color_Index[SKINCOLOR_BLUE-1][12-i]] = Color_Index[SKINCOLOR_BLUE-1][i]; + dest_colormap[skincolors[SKINCOLOR_BLUE].ramp[12-i]] = skincolors[SKINCOLOR_BLUE].ramp[i]; } dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0; for (i = 0; i < 16; i++) - dest_colormap[96+i] = dest_colormap[Color_Index[SKINCOLOR_COBALT-1][i]]; + dest_colormap[96+i] = dest_colormap[skincolors[SKINCOLOR_COBALT].ramp[i]]; } else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices { @@ -634,7 +322,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U return; } - if (color >= MAXTRANSLATIONS) + if (color >= numskincolors) I_Error("Invalid skin color #%hu.", (UINT16)color); starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; @@ -658,7 +346,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U // Build the translated ramp for (i = 0; i < skinramplength; i++) - dest_colormap[starttranscolor + i] = (UINT8)Color_Index[color-1][i]; + dest_colormap[starttranscolor + i] = (UINT8)skincolors[color].ramp[i]; } @@ -670,7 +358,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U \return Colormap. If not cached, caller should Z_Free. */ -UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) +UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags) { UINT8* ret; INT32 skintableindex; @@ -693,7 +381,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) // Allocate table for skin if necessary if (!translationtablecache[skintableindex]) - translationtablecache[skintableindex] = Z_Calloc(MAXTRANSLATIONS * sizeof(UINT8**), PU_STATIC, NULL); + translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL); // Get colormap ret = translationtablecache[skintableindex][color]; @@ -728,29 +416,32 @@ void R_FlushTranslationColormapCache(void) for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++) if (translationtablecache[i]) - memset(translationtablecache[i], 0, MAXTRANSLATIONS * sizeof(UINT8**)); + memset(translationtablecache[i], 0, MAXSKINCOLORS * sizeof(UINT8**)); } -UINT8 R_GetColorByName(const char *name) +UINT16 R_GetColorByName(const char *name) { - UINT8 color = (UINT8)atoi(name); - if (color > 0 && color < MAXSKINCOLORS) + UINT16 color = (UINT16)atoi(name); + if (color > 0 && color < numskincolors) return color; - for (color = 1; color < MAXSKINCOLORS; color++) - if (!stricmp(Color_Names[color], name)) + for (color = 1; color < numskincolors; color++) + if (!stricmp(skincolors[color].name, name)) return color; return SKINCOLOR_GREEN; } -UINT8 R_GetSuperColorByName(const char *name) +UINT16 R_GetSuperColorByName(const char *name) { - UINT8 color; /* = (UINT8)atoi(name); -- This isn't relevant to S_SKIN, which is the only way it's accessible right now. Let's simplify things. - if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS && !((color - MAXSKINCOLORS) % 5)) - return color;*/ - for (color = 0; color < NUMSUPERCOLORS; color++) - if (!stricmp(Color_Names[color + MAXSKINCOLORS], name)) - return ((color*5) + MAXSKINCOLORS); - return SKINCOLOR_SUPERGOLD1; + UINT16 i, color = SKINCOLOR_SUPERGOLD1; + char *realname = Z_Malloc(MAXCOLORNAME+1, PU_STATIC, NULL); + snprintf(realname, MAXCOLORNAME+1, "Super %s 1", name); + for (i = 1; i < numskincolors; i++) + if (!stricmp(skincolors[i].name, realname)) { + color = i; + break; + } + Z_Free(realname); + return color; } // ========================================================================== diff --git a/src/r_draw.h b/src/r_draw.h index 4d94f861b3f747f6e033b876112962916288fb78..329c4974a6ca722322fb754fd3faf90e6cd92e13 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -112,10 +112,10 @@ extern lumpnum_t viewborderlump[8]; // Initialize color translation tables, for player rendering etc. void R_InitTranslationTables(void); -UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags); +UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags); void R_FlushTranslationColormapCache(void); -UINT8 R_GetColorByName(const char *name); -UINT8 R_GetSuperColorByName(const char *name); +UINT16 R_GetColorByName(const char *name); +UINT16 R_GetSuperColorByName(const char *name); // Custom player skin translation void R_InitViewBuffer(INT32 width, INT32 height); diff --git a/src/r_main.c b/src/r_main.c index 9a3d98870fe1d206400fed4e4d0240deea52b682..e47bb06e3fb116b3735988d1c0ac90f93b0b64af 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1388,7 +1388,7 @@ void R_RenderPlayerView(player_t *player) else { portalclipstart = 0; - portalclipend = viewwidth-1; + portalclipend = viewwidth; R_ClearClipSegs(); } R_ClearDrawSegs(); diff --git a/src/r_plane.c b/src/r_plane.c index 9b5a943408d1b06139cc6a97c5f7fb62ae9d0875..6857b6dca9b131cd025f69599ffc6123ac7a0cdb 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -833,15 +833,15 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) floatv3_t p, m, n; float ang; float vx, vy, vz; - // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly - // use this as a temp var to store P_GetZAt's return value each time + // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly + // use this as a temp var to store P_GetSlopeZAt's return value each time fixed_t temp; vx = FIXED_TO_FLOAT(pl->viewx+xoffs); vy = FIXED_TO_FLOAT(pl->viewy-yoffs); vz = FIXED_TO_FLOAT(pl->viewz); - temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy); + temp = P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy); zeroheight = FIXED_TO_FLOAT(temp); // p is the texture origin in view space @@ -850,7 +850,7 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) ang = ANG2RAD(ANGLE_270 - pl->viewangle); p.x = vx * cos(ang) - vy * sin(ang); p.z = vx * sin(ang) + vy * cos(ang); - temp = P_GetZAt(pl->slope, -xoffs, yoffs); + temp = P_GetSlopeZAt(pl->slope, -xoffs, yoffs); p.y = FIXED_TO_FLOAT(temp) - vz; // m is the v direction vector in view space @@ -863,9 +863,9 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) n.z = -cos(ang); ang = ANG2RAD(pl->plangle); - temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang))); + temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang))); m.y = FIXED_TO_FLOAT(temp) - zeroheight; - temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); + temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); n.y = FIXED_TO_FLOAT(temp) - zeroheight; if (ds_powersoftwo) @@ -1177,7 +1177,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (itswater) { INT32 i; - fixed_t plheight = abs(P_GetZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); + fixed_t plheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); fixed_t rxoffs = xoffs; fixed_t ryoffs = yoffs; diff --git a/src/r_segs.c b/src/r_segs.c index 6a838be79434b570b10fb2932c00b611a4b4a49a..741a25254037fbc1dd15017603e116d3ee4f8f7d 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -376,16 +376,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) fixed_t leftheight, rightheight; light = &frontsector->lightlist[i]; rlight = &dc_lightlist[i]; - if (light->slope) { - leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); - rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); - } else - leftheight = rightheight = light->height; + leftheight = P_GetLightZAt(light, ds-> leftpos.x, ds-> leftpos.y); + rightheight = P_GetLightZAt(light, ds->rightpos.x, ds->rightpos.y); - leftheight -= viewz; + leftheight -= viewz; rightheight -= viewz; - rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->height = (centeryfrac) - FixedMul(leftheight , ds->scale1); rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); //if (x1 > ds->x1) @@ -799,11 +796,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight = &dc_lightlist[p]; #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ - end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, ds-> leftpos.x, ds-> leftpos.y, normalheight); \ + end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y, normalheight); SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) @@ -816,8 +810,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) { lightlist_t *nextlight = &frontsector->lightlist[i+1]; - if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft - && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) + if (P_GetZAt(nextlight->slope, ds-> leftpos.x, ds-> leftpos.y, nextlight->height) > pfloorleft + && P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y, nextlight->height) > pfloorright) continue; } @@ -913,15 +907,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_texheight = textureheight[texnum]>>FRACBITS; // calculate both left ends - if (*pfloor->t_slope) - left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - left_top = *pfloor->topheight - viewz; + left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; + left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; - if (*pfloor->b_slope) - left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - left_bottom = *pfloor->bottomheight - viewz; skewslope = *pfloor->t_slope; // skew using top slope by default if (newline) { @@ -997,15 +985,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t right_top, right_bottom; // calculate right ends now - if (*pfloor->t_slope) - right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_bottom = *pfloor->bottomheight - viewz; + right_top = P_GetFFloorTopZAt (pfloor, ds->rightpos.x, ds->rightpos.y) - viewz; + right_bottom = P_GetFFloorBottomZAt(pfloor, ds->rightpos.x, ds->rightpos.y) - viewz; // using INT64 to avoid 32bit overflow top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); @@ -1787,11 +1768,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) #define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, segleft.x, segleft.y); \ - end2 = P_GetZAt(slope, segright.x, segright.y); \ - } else \ - end1 = end2 = normalheight; + end1 = P_GetZAt(slope, segleft.x, segleft.y, normalheight); \ + end2 = P_GetZAt(slope, segright.x, segright.y, normalheight); SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) @@ -1820,12 +1798,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) continue; - if (ffloor[i].slope) { - ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; - ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; - } - else - ffloor[i].f_pos_slope = ffloor[i].f_pos = ffloor[i].height - viewz; + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft .x, segleft .y, ffloor[i].height) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y, ffloor[i].height) - viewz; } } @@ -1918,12 +1892,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldbottomslope > worldlowslope || worldbottom > worldlow) { ds_p->silhouette = SIL_BOTTOM; - if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz) ds_p->bsilheight = INT32_MAX; else ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); } - else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + else if (P_GetSectorFloorZAt(backsector, viewx, viewy) > viewz) { ds_p->silhouette = SIL_BOTTOM; ds_p->bsilheight = INT32_MAX; @@ -1936,12 +1910,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldtopslope < worldhighslope || worldtop < worldhigh) { ds_p->silhouette |= SIL_TOP; - if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz) ds_p->tsilheight = INT32_MIN; else ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); } - else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + else if (P_GetSectorCeilingZAt(backsector, viewx, viewy) < viewz) { ds_p->silhouette |= SIL_TOP; ds_p->tsilheight = INT32_MIN; @@ -2272,10 +2246,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; // Oy vey. - if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldbottom + viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldbottomslope + viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldtop + viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope + viewz)) + if ( ((P_GetFFloorTopZAt (rover, segleft .x, segleft .y)) <= worldbottom + viewz + && (P_GetFFloorTopZAt (rover, segright.x, segright.y)) <= worldbottomslope + viewz) + ||((P_GetFFloorBottomZAt(rover, segleft .x, segleft .y)) >= worldtop + viewz + && (P_GetFFloorBottomZAt(rover, segright.x, segright.y)) >= worldtopslope + viewz)) continue; ds_p->thicksides[i] = rover; @@ -2293,16 +2267,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; // Oy vey. - if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldbottom + viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldbottomslope + viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldtop + viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope + viewz)) + if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldbottom + viewz + && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldbottomslope + viewz) + ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldtop + viewz + && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldtopslope + viewz)) continue; - if ( ((*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft .x, segleft .y) : *rover-> topheight) <= worldlow + viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover-> topheight) <= worldlowslope + viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft .x, segleft .y) : *rover->bottomheight) >= worldhigh + viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope + viewz)) + if ( (P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= worldlow + viewz + && P_GetFFloorTopZAt (rover, segright.x, segright.y) <= worldlowslope + viewz) + ||(P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) >= worldhigh + viewz + && P_GetFFloorBottomZAt(rover, segright.x, segright.y) >= worldhighslope + viewz)) continue; ds_p->thicksides[i] = rover; @@ -2425,17 +2399,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (frontsector->floorpic != skyflatnum && (frontsector->f_slope ? - P_GetZAt(frontsector->f_slope, viewx, viewy) : - frontsector->floorheight) >= viewz) + if (frontsector->floorpic != skyflatnum && P_GetSectorFloorZAt(frontsector, viewx, viewy) >= viewz) { // above view plane markfloor = false; } - if (frontsector->ceilingpic != skyflatnum && (frontsector->c_slope ? - P_GetZAt(frontsector->c_slope, viewx, viewy) : - frontsector->ceilingheight) <= viewz) + if (frontsector->ceilingpic != skyflatnum && P_GetSectorCeilingZAt(frontsector, viewx, viewy) <= viewz) { // below view plane markceiling = false; @@ -2487,14 +2457,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; - if (light->slope) { - leftheight = P_GetZAt(light->slope, segleft.x, segleft.y); - rightheight = P_GetZAt(light->slope, segright.x, segright.y); + leftheight = P_GetLightZAt(light, segleft.x, segleft.y); + rightheight = P_GetLightZAt(light, segright.x, segright.y); + if (light->slope) // Flag sector as having slopes frontsector->hasslope = true; - } else - leftheight = rightheight = light->height; leftheight -= viewz; rightheight -= viewz; @@ -2518,19 +2486,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (light->caster && light->caster->flags & FF_CUTSOLIDS) { - if (*light->caster->b_slope) { - leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y); - rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y); + leftheight = P_GetFFloorBottomZAt(light->caster, segleft.x, segleft.y); + rightheight = P_GetFFloorBottomZAt(light->caster, segright.x, segright.y); + if (*light->caster->b_slope) // Flag sector as having slopes frontsector->hasslope = true; - } else - leftheight = rightheight = *light->caster->bottomheight; - leftheight -= viewz; + leftheight -= viewz; rightheight -= viewz; - leftheight >>= 4; + leftheight >>= 4; rightheight >>= 4; rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); @@ -2614,9 +2580,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) backsector->hasslope = true; - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && @@ -2637,9 +2603,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorTopZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && @@ -2671,9 +2637,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) frontsector->hasslope = true; - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + roverleft = P_GetFFloorBottomZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorBottomZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorBottomZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && @@ -2694,9 +2660,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + roverleft = P_GetFFloorTopZAt(rover, segleft .x, segleft .y) - viewz; + roverright = P_GetFFloorTopZAt(rover, segright.x, segright.y) - viewz; + planevistest = P_GetFFloorTopZAt(rover, viewx, viewy); if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && diff --git a/src/r_skins.c b/src/r_skins.c index caf1fb17299dc0cbad0352df4fa8ec5b71b79ef4..57ce382c4183618a66dde1c45a0874b48d5a7535 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -248,7 +248,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { player_t *player = &players[playernum]; skin_t *skin = &skins[skinnum]; - UINT8 newcolor = 0; + UINT16 newcolor = 0; if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists! { diff --git a/src/r_skins.h b/src/r_skins.h index 96697b4220038c1bdbe491cbd4943b2b4127113b..45c90bdb4b9e5964547c579abcbdd3d80ed91162 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -65,9 +65,9 @@ typedef struct // Definable color translation table UINT8 starttranscolor; - UINT8 prefcolor; - UINT8 supercolor; - UINT8 prefoppositecolor; // if 0 use tables instead + UINT16 prefcolor; + UINT16 supercolor; + UINT16 prefoppositecolor; // if 0 use tables instead fixed_t highresscale; // scale of highres, default is 0.5 UINT8 contspeed; // continue screen animation speed diff --git a/src/r_things.c b/src/r_things.c index 61bd17cb9905ffe7eca914a3b848a005c7cc304c..228c86a643695c12ef6d5f379fae83b782e6497e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1019,13 +1019,12 @@ static void R_SplitSprite(vissprite_t *sprite) for (i = 1; i < sector->numlights; i++) { - fixed_t testheight = sector->lightlist[i].height; + fixed_t testheight; if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) continue; - if (sector->lightlist[i].slope) - testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy); + testheight = P_GetLightZAt(§or->lightlist[i], sprite->gx, sprite->gy); if (testheight >= sprite->gzt) continue; @@ -1097,25 +1096,29 @@ static void R_SplitSprite(vissprite_t *sprite) // fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) { - fixed_t z, floorz = INT32_MIN; - pslope_t *slope, *floorslope = NULL; + boolean isflipped = thing->eflags & MFE_VERTICALFLIP; + fixed_t z, groundz = isflipped ? INT32_MAX : INT32_MIN; + pslope_t *slope, *groundslope = NULL; msecnode_t *node; sector_t *sector; ffloor_t *rover; +#define CHECKZ (isflipped ? z > thing->z+thing->height/2 && z < groundz : z < thing->z+thing->height/2 && z > groundz) for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next) { sector = node->m_sector; - slope = (sector->heightsec != -1) ? NULL : sector->f_slope; - z = slope ? P_GetZAt(slope, thing->x, thing->y) : ( - (sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight - ); + slope = sector->heightsec != -1 ? NULL : (isflipped ? sector->c_slope : sector->f_slope); - if (z < thing->z+thing->height/2 && z > floorz) + if (sector->heightsec != -1) + z = isflipped ? sectors[sector->heightsec].ceilingheight : sectors[sector->heightsec].floorheight; + else + z = isflipped ? P_GetSectorCeilingZAt(sector, thing->x, thing->y) : P_GetSectorFloorZAt(sector, thing->x, thing->y); + + if CHECKZ { - floorz = z; - floorslope = slope; + groundz = z; + groundslope = slope; } if (sector->ffloors) @@ -1124,23 +1127,25 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) continue; - z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; - if (z < thing->z+thing->height/2 && z > floorz) + z = isflipped ? P_GetFFloorBottomZAt(rover, thing->x, thing->y) : P_GetFFloorTopZAt(rover, thing->x, thing->y); + if CHECKZ { - floorz = z; - floorslope = *rover->t_slope; + groundz = z; + groundslope = isflipped ? *rover->b_slope : *rover->t_slope; } } } - if (thing->floorz > floorz + (!floorslope ? 0 : FixedMul(abs(floorslope->zdelta), thing->radius*3/2))) + if (isflipped ? (thing->ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))) + : (thing->floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))) { - floorz = thing->floorz; - floorslope = NULL; + groundz = isflipped ? thing->ceilingz : thing->floorz; + groundslope = NULL; } #if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. - // Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz + // NOTE: this section was not updated to reflect reverse gravity support + // Check polyobjects and see if groundz needs to be altered, for rings only because they don't update floorz if (thing->type == MT_RING) { INT32 xl, xh, yl, yh, bx, by; @@ -1185,10 +1190,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) // We're inside it! Yess... z = po->lines[0]->backsector->ceilingheight; - if (z < thing->z+thing->height/2 && z > floorz) + if (z < thing->z+thing->height/2 && z > groundz) { - floorz = z; - floorslope = NULL; + groundz = z; + groundslope = NULL; } } plink = (polymaplink_t *)(plink->link.next); @@ -1198,9 +1203,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) #endif if (shadowslope != NULL) - *shadowslope = floorslope; + *shadowslope = groundslope; - return floorz; + return groundz; +#undef CHECKZ } static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) @@ -1211,14 +1217,15 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, INT32 light = 0; fixed_t scalemul; UINT8 trans; fixed_t floordiff; - fixed_t floorz; - pslope_t *floorslope; + fixed_t groundz; + pslope_t *groundslope; + boolean isflipped = thing->eflags & MFE_VERTICALFLIP; - floorz = R_GetShadowZ(thing, &floorslope); + groundz = R_GetShadowZ(thing, &groundslope); - if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes + if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes - floordiff = abs(thing->z - floorz); + floordiff = abs((isflipped ? thing->height : 0) + thing->z - groundz); trans = floordiff / (100*FRACUNIT) + 3; if (trans >= 9) return; @@ -1229,23 +1236,23 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, xscale = FixedDiv(projection, tz); yscale = FixedDiv(projectiony, tz); shadowxscale = FixedMul(thing->radius*2, scalemul); - shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); + shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(groundz - viewz), tz)); shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height); shadowxscale /= SHORT(patch->width); shadowskew = 0; - if (floorslope) + if (groundslope) { // haha let's try some dumb stuff fixed_t xslope, zslope; - angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - floorslope->xydirection) >> ANGLETOFINESHIFT; + angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT; - xslope = FixedMul(FINESINE(sloperelang), floorslope->zdelta); - zslope = FixedMul(FINECOSINE(sloperelang), floorslope->zdelta); + xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta); + zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta); //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); - if (viewz < floorz) + if (viewz < groundz) shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); else shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); @@ -1270,7 +1277,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->heightsec = vis->heightsec; shadow->thingheight = FRACUNIT; - shadow->pz = floorz; + shadow->pz = groundz + (isflipped ? -shadow->thingheight : 0); shadow->pzt = shadow->pz + shadow->thingheight; shadow->mobjflags = 0; @@ -1278,7 +1285,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->dispoffset = vis->dispoffset - 5; shadow->gx = thing->x; shadow->gy = thing->y; - shadow->gzt = shadow->pz + SHORT(patch->height) * shadowyscale / 2; + shadow->gzt = (isflipped ? shadow->pzt : shadow->pz) + SHORT(patch->height) * shadowyscale / 2; shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale; shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) @@ -1316,8 +1323,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, // R_GetPlaneLight won't work on sloped lights! for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { - fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) - : thing->subsector->sector->lightlist[lightnum].height; + fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y); if (h <= shadow->gzt) { light = lightnum - 1; break; @@ -1346,7 +1352,6 @@ static void R_ProjectSprite(mobj_t *thing) { mobj_t *oldthing = thing; fixed_t tr_x, tr_y; - fixed_t gxt, gyt; fixed_t tx, tz; fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -1359,7 +1364,7 @@ static void R_ProjectSprite(mobj_t *thing) #endif size_t lump; - size_t rot; + size_t frame, rot; UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); @@ -1399,21 +1404,16 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - - tz = gxt-gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance // thing is behind view plane? if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - basetx = tx = -(gyt + gxt); + basetx = tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? - if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later + if (!papersprite && abs(tx) > FixedMul(tz, fovtan)<<2) // papersprite clipping is handled later return; // aspect ratio stuff @@ -1426,7 +1426,7 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite); #endif - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; //Fab : 02-08-98: 'skin' override spritedef currently used for skin if (thing->skin && thing->sprite == SPR_PLAY) @@ -1435,15 +1435,15 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; #endif - if (rot >= sprdef->numframes) { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot)); + if (frame >= sprdef->numframes) { + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(frame)); thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; #ifdef ROTSPRITE sprinfo = NULL; #endif - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; } } else @@ -1453,10 +1453,10 @@ static void R_ProjectSprite(mobj_t *thing) sprinfo = NULL; #endif - if (rot >= sprdef->numframes) + if (frame >= sprdef->numframes) { CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), - sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); + sizeu1(frame), sizeu2(sprdef->numframes), sprnames[thing->sprite]); if (thing->sprite == thing->state->sprite && thing->frame == thing->state->frame) { thing->state->sprite = states[S_UNKNOWN].sprite; @@ -1465,11 +1465,11 @@ static void R_ProjectSprite(mobj_t *thing) thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; - rot = thing->frame&FF_FRAMEMASK; + frame = thing->frame&FF_FRAMEMASK; } } - sprframe = &sprdef->spriteframes[rot]; + sprframe = &sprdef->spriteframes[frame]; #ifdef PARANOIA if (!sprframe) @@ -1523,7 +1523,7 @@ static void R_ProjectSprite(mobj_t *thing) { rollangle = R_GetRollAngle(thing->rollangle); if (!(sprframe->rotsprite.cached & (1<<rot))) - R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); + R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { @@ -1561,17 +1561,9 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset, cosmul); tr_y += FixedMul(offset, sinmul); - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz = gxt-gyt; - yscale = FixedDiv(projectiony, tz); - //if (yscale < 64) return; // Fix some funky visuals + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); - xscale = FixedDiv(projection, tz); - x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // Get paperoffset (offset) and paperoffset (distance) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); @@ -1585,17 +1577,9 @@ static void R_ProjectSprite(mobj_t *thing) tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz2 = gxt-gyt; - yscale2 = FixedDiv(projectiony, tz2); - //if (yscale2 < 64) return; // ditto + tz2 = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx2 = -(gyt + gxt); - xscale2 = FixedDiv(projection, tz2); - x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); + tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; @@ -1606,24 +1590,31 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); tx += FixedDiv(tx2-tx, div); tz = FixedMul(MINZ, this_scale); - yscale = FixedDiv(projectiony, tz); - xscale = FixedDiv(projection, tz); - x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; } else if (tz2 < FixedMul(MINZ, this_scale)) { fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); tx2 += FixedDiv(tx-tx2, div); tz2 = FixedMul(MINZ, this_scale); - yscale2 = FixedDiv(projectiony, tz2); - xscale2 = FixedDiv(projection, tz2); - x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; } + if (tx2 < -(FixedMul(tz2, fovtan)<<2) || tx > FixedMul(tz, fovtan)<<2) // too far off the side? + return; + + yscale = FixedDiv(projectiony, tz); + xscale = FixedDiv(projection, tz); + + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + // off the right side? if (x1 > viewwidth) return; + yscale2 = FixedDiv(projectiony, tz2); + xscale2 = FixedDiv(projection, tz2); + + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; + // off the left side if (x2 < 0) return; @@ -1670,9 +1661,7 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - tz = gxt-gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); linkscale = FixedDiv(projectiony, tz); if (tz < FixedMul(MINZ, this_scale)) @@ -1688,7 +1677,7 @@ static void R_ProjectSprite(mobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) @@ -1723,8 +1712,7 @@ static void R_ProjectSprite(mobj_t *thing) // R_GetPlaneLight won't work on sloped lights! for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { - fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) - : thing->subsector->sector->lightlist[lightnum].height; + fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y); if (h <= gzt) { light = lightnum - 1; break; @@ -1873,7 +1861,6 @@ static void R_ProjectSprite(mobj_t *thing) static void R_ProjectPrecipitationSprite(precipmobj_t *thing) { fixed_t tr_x, tr_y; - fixed_t gxt, gyt; fixed_t tx, tz; fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -1894,21 +1881,16 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - gxt = FixedMul(tr_x, viewcos); - gyt = -FixedMul(tr_y, viewsin); - - tz = gxt - gyt; + tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance // thing is behind view plane? if (tz < MINZ) return; - gxt = -FixedMul(tr_x, viewsin); - gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? - if (abs(tx) > tz<<2) + if (abs(tx) > FixedMul(tz, fovtan)<<2) return; // aspect ratio stuff : @@ -1958,7 +1940,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) @@ -2377,12 +2359,8 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps continue; // Effective height may be different for each comparison in the case of slopes - if (r2->plane->slope) { - planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy); - planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy); - } - else - planeobjectz = planecameraz = r2->plane->height; + planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy, r2->plane->height); + planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy, r2->plane->height); if (rover->mobjflags & MF_NOCLIPHEIGHT) { @@ -2440,19 +2418,10 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (scale <= rover->sortscale) continue; - if (*r2->ffloor->t_slope) { - topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy); - topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy); - } - else - topplaneobjectz = topplanecameraz = *r2->ffloor->topheight; - - if (*r2->ffloor->b_slope) { - botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy); - botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy); - } - else - botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight; + topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); + topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); + botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); + botplanecameraz = P_GetFFloorBottomZAt(r2->ffloor, viewx, viewy); if ((topplanecameraz > viewz && botplanecameraz < viewz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || diff --git a/src/s_sound.c b/src/s_sound.c index d108363eb0b962be292f88bad40112626c3601ce..5ed9fd83a22d8f475c7400878db264d329a42bd1 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -134,6 +134,7 @@ consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_Y consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef HAVE_OPENMPT +openmpt_module *openmpt_mhandle = NULL; static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -1910,6 +1911,10 @@ UINT32 S_GetMusicPosition(void) /// In this section: mazmazz doesn't know how to do dynamic arrays or struct pointers! /// ------------------------ +char music_stack_nextmusname[7]; +boolean music_stack_noposition = false; +UINT32 music_stack_fadeout = 0; +UINT32 music_stack_fadein = 0; static musicstack_t *music_stacks = NULL; static musicstack_t *last_music_stack = NULL; diff --git a/src/s_sound.h b/src/s_sound.h index 119722af43a23e5910581be41a67d615b38061a4..3334fcb69d7bf18820776130c627ba948b1ecb52 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -22,7 +22,7 @@ #ifdef HAVE_OPENMPT #include "libopenmpt/libopenmpt.h" -openmpt_module *openmpt_mhandle; +extern openmpt_module *openmpt_mhandle; #endif // mask used to indicate sound origin is player item pickup @@ -262,10 +262,10 @@ typedef struct musicstack_s struct musicstack_s *next; } musicstack_t; -char music_stack_nextmusname[7]; -boolean music_stack_noposition; -UINT32 music_stack_fadeout; -UINT32 music_stack_fadein; +extern char music_stack_nextmusname[7]; +extern boolean music_stack_noposition; +extern UINT32 music_stack_fadeout; +extern UINT32 music_stack_fadein; void S_SetStackAdjustmentStart(void); void S_AdjustMusicStackTics(void); @@ -333,7 +333,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #ifdef MUSICSLOT_COMPATIBILITY // For compatibility with code/scripts relying on older versions // This is a list of all the "special" slot names and their associated numbers -const char *compat_special_music_slots[16]; +extern const char *compat_special_music_slots[16]; #endif #endif diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e5cdb32061c623ac256ad31ede32da617647f4aa..e358308b4cfccd3cc6e4ff6c567bbba18425d970 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -178,6 +178,8 @@ static char returnWadPath[256]; #include "../m_argv.h" +#include "../m_menu.h" + #ifdef MAC_ALERT #include "macosx/mac_alert.h" #endif @@ -2295,6 +2297,7 @@ void I_Quit(void) D_QuitNetGame(); CL_AbortDownloadResume(); + M_FreePlayerSetupColors(); I_ShutdownMusic(); I_ShutdownSound(); I_ShutdownCD(); @@ -2412,6 +2415,7 @@ void I_Error(const char *error, ...) D_QuitNetGame(); CL_AbortDownloadResume(); + M_FreePlayerSetupColors(); I_ShutdownMusic(); I_ShutdownSound(); I_ShutdownCD(); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ec7bfc1c4573776d438baf27fe1f388f838869c0..0abc9280c4012f8ce57bcba2c955ec879dab1ddf 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -217,7 +217,6 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool else { Impl_CreateWindow(fullscreen); - Impl_SetWindowIcon(); wasfullscreen = fullscreen; SDL_SetWindowSize(window, width, height); if (fullscreen) @@ -1632,12 +1631,15 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); + if (window == NULL) { CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError()); return SDL_FALSE; } + Impl_SetWindowIcon(); + return Impl_CreateContext(); } @@ -1654,12 +1656,8 @@ static void Impl_SetWindowName(const char *title) static void Impl_SetWindowIcon(void) { - if (window == NULL || icoSurface == NULL) - { - return; - } - //SDL2STUB(); // Monster Iestyn: why is this stubbed? - SDL_SetWindowIcon(window, icoSurface); + if (window && icoSurface) + SDL_SetWindowIcon(window, icoSurface); } static void Impl_VideoSetupSDLBuffer(void) @@ -1766,6 +1764,11 @@ void I_StartupGraphics(void) VID_StartupOpenGL(); #endif + // Window icon +#ifdef HAVE_IMAGE + icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); +#endif + // Fury: we do window initialization after GL setup to allow // SDL_GL_LoadLibrary to work well on Windows @@ -1784,11 +1787,6 @@ void I_StartupGraphics(void) #ifdef HAVE_TTF I_ShutdownTTF(); #endif - // Window icon -#ifdef HAVE_IMAGE - icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); -#endif - Impl_SetWindowIcon(); VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); diff --git a/src/st_stuff.c b/src/st_stuff.c index b6226d085e04a11da11a8f6dc575407a4a696676..086e80291275cbc174dbe700d5b248e5a78a23a6 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -456,7 +456,7 @@ boolean st_overlay; // // Supports different colors! woo! static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fixed_t s, INT32 a, - UINT32 num, patch_t **numpat, skincolors_t colornum) + UINT32 num, patch_t **numpat, skincolornum_t colornum) { fixed_t w = SHORT(numpat[0]->width)*s; const UINT8 *colormap; @@ -992,7 +992,7 @@ static void ST_drawLivesArea(void) static void ST_drawInput(void) { - const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); + const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? skincolors[stplyr->skincolor].ramp[4] : 0); INT32 col; UINT8 offs; @@ -1325,7 +1325,7 @@ void ST_drawTitleCard(void) { char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; - INT32 actnum = mapheaderinfo[gamemap-1]->actnum; + UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; INT32 lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; INT32 ttlscroll = FixedInt(lt_scroll); @@ -1382,7 +1382,12 @@ void ST_drawTitleCard(void) if (actnum) { if (!splitscreen) - V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + { + if (actnum > 9) // slightly offset the act diamond for two-digit act numbers + V_DrawMappedPatch(ttlnumxpos + (V_LevelActNumWidth(actnum)/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + else + V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + } V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum); } @@ -1695,14 +1700,14 @@ static void ST_drawNightsRecords(void) // 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold /*#define NUMLINKCOLORS 14 -static skincolors_t linkColor[NUMLINKCOLORS] = +static skincolornum_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ // 2.2 indev list: (unix time 1470866042) <Rob> Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot /*#define NUMLINKCOLORS 13 -static skincolors_t linkColor[NUMLINKCOLORS] = +static skincolornum_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};*/ @@ -1711,7 +1716,7 @@ static skincolors_t linkColor[NUMLINKCOLORS] = // [20:00:25] <baldobo> Also Icy for the link freeze text color // [20:04:03] <baldobo> I would start it on lime /*#define NUMLINKCOLORS 18 -static skincolors_t linkColor[NUMLINKCOLORS] = +static skincolornum_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_SKY, SKINCOLOR_SAPPHIRE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, @@ -1719,7 +1724,7 @@ static skincolors_t linkColor[NUMLINKCOLORS] = // 2.2+ list for real this time: https://wiki.srb2.org/wiki/User:Rob/Sandbox (check history around 31/10/17, spoopy) #define NUMLINKCOLORS 12 -static skincolors_t linkColor[2][NUMLINKCOLORS] = { +static skincolornum_t linkColor[2][NUMLINKCOLORS] = { {SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, {SKINCOLOR_SEAFOAM, SKINCOLOR_CYAN, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_VAPOR, SKINCOLOR_BUBBLEGUM, @@ -1730,7 +1735,7 @@ static void ST_drawNiGHTSLink(void) static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0); - skincolors_t colornum; + skincolornum_t colornum; fixed_t x, y, scale; if (sel != prevsel[q]) diff --git a/src/v_video.c b/src/v_video.c index 3ce0e79f51936a3465e4dc157e39a5b76aa5019f..5a985555fdd854d593480a145e600254dfd52171 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1040,7 +1040,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ // V_DrawContinueIcon // Draw a mini player! If we can, that is. Otherwise we draw a star. // -void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor) +void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT16 skincolor) { if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CONTINUE) { @@ -2952,13 +2952,19 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits) } // Draw an act number for a level title -// Todo: actually draw two-digit numbers as two act num patches -void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num) +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num) { - if (num < 0 || num > 19) + if (num > 99) return; // not supported - V_DrawScaledPatch(x, y, flags, ttlnum[num]); + while (num > 0) + { + if (num > 9) // if there are two digits, draw second digit first + V_DrawScaledPatch(x + (V_LevelActNumWidth(num) - V_LevelActNumWidth(num%10)), y, flags, ttlnum[num%10]); + else + V_DrawScaledPatch(x, y, flags, ttlnum[num]); + num = num/10; + } } // Write a string using the credit font @@ -3339,13 +3345,21 @@ INT32 V_LevelNameHeight(const char *string) } // For ST_drawTitleCard -// Returns the width of the act num patch -INT32 V_LevelActNumWidth(INT32 num) +// Returns the width of the act num patch(es) +INT16 V_LevelActNumWidth(UINT8 num) { - if (num < 0 || num > 19) - return 0; // not a valid number + INT16 result = 0; + + if (num == 0) + result = SHORT(ttlnum[num]->width); + + while (num > 0 && num <= 99) + { + result = result + SHORT(ttlnum[num%10]->width); + num = num/10; + } - return SHORT(ttlnum[num]->width); + return result; } // diff --git a/src/v_video.h b/src/v_video.h index ed623a57f4e771781f45fb32c50c210dd804c0f4..9f7a9a9e9c29dd8fb23ecfbfb4d1d09d1d7cba8d 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -160,7 +160,7 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue); void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap); void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); -void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor); +void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT16 skincolor); // Draw a linear block of pixels into the view buffer. void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const UINT8 *src); @@ -238,12 +238,12 @@ void V_DrawRightAlignedSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option // Draw tall nums, used for menu, HUD, intermission void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); -void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num); +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num); // Find string width from lt_font chars INT32 V_LevelNameWidth(const char *string); INT32 V_LevelNameHeight(const char *string); -INT32 V_LevelActNumWidth(INT32 num); // act number width +INT16 V_LevelActNumWidth(UINT8 num); // act number width void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string); INT32 V_CreditStringWidth(const char *string); diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index fb0742c5a9c8b935044e5019349f66058acc6b35..a374a2587b0b9d9c01786aa9696a4d58f34b2980 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -54,6 +54,8 @@ #include "../screen.h" +#include "../m_menu.h" + // Wheel support for Win95/WinNT3.51 #include <zmouse.h> @@ -652,6 +654,7 @@ void I_Error(const char *error, ...) D_QuitNetGame(); CL_AbortDownloadResume(); + M_FreePlayerSetupColors(); // shutdown everything that was started I_ShutdownSystem(); @@ -749,6 +752,8 @@ void I_Quit(void) D_QuitNetGame(); CL_AbortDownloadResume(); + M_FreePlayerSetupColors(); + // shutdown everything that was started I_ShutdownSystem(); diff --git a/src/y_inter.c b/src/y_inter.c index f1764a816d5f2049b5fe516ba6ae8f010f679d4e..2fe0de60519b7b965387dabd6f42912825d0a4f8 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -73,7 +73,7 @@ typedef union UINT32 score, total; // fake score, total UINT32 tics; // time - INT32 actnum; // act number being displayed + UINT8 actnum; // act number being displayed patch_t *ptotal; // TOTAL UINT8 gotlife; // Number of extra lives obtained } coop; @@ -99,7 +99,7 @@ typedef union UINT8 continues; patch_t *pcontinues; INT32 *playerchar; // Continue HUD - UINT8 *playercolor; + UINT16 *playercolor; UINT8 gotlife; // Number of extra lives obtained } spec; @@ -107,7 +107,7 @@ typedef union struct { UINT32 scores[MAXPLAYERS]; // Winner's score - UINT8 *color[MAXPLAYERS]; // Winner's color # + UINT16 *color[MAXPLAYERS]; // Winner's color # boolean spectator[MAXPLAYERS]; // Spectator list INT32 *character[MAXPLAYERS]; // Winner's character # INT32 num[MAXPLAYERS]; // Winner's player # @@ -121,7 +121,7 @@ typedef union struct { - UINT8 *color[MAXPLAYERS]; // Winner's color # + UINT16 *color[MAXPLAYERS]; // Winner's color # INT32 *character[MAXPLAYERS]; // Winner's character # INT32 num[MAXPLAYERS]; // Winner's player # char name[MAXPLAYERS][9]; // Winner's name