From 8abeae7805eb1350a5a12ced1074276d971162d6 Mon Sep 17 00:00:00 2001 From: wolfy852 <wolfy852@hotmail.com> Date: Fri, 15 Jun 2018 05:20:01 -0500 Subject: [PATCH 01/38] Chat Manager --- src/d_main.c | 1 + src/d_netcmd.c | 7 + src/doomdef.h | 1 + src/g_game.c | 26 ++ src/g_game.h | 1 + src/hardware/hw_draw.c | 105 +++++ src/hardware/hw_main.h | 1 + src/hu_stuff.c | 990 +++++++++++++++++++++++++++++++++++++---- src/hu_stuff.h | 6 + src/lua_baselib.c | 47 ++ src/lua_hook.h | 2 +- src/lua_hooklib.c | 19 +- src/v_video.c | 151 ++++++- src/v_video.h | 3 + 14 files changed, 1262 insertions(+), 98 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index b12dcdbf..367a0e08 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -184,6 +184,7 @@ void D_PostEvent_end(void) {}; UINT8 shiftdown = 0; // 0x1 left, 0x2 right UINT8 ctrldown = 0; // 0x1 left, 0x2 right UINT8 altdown = 0; // 0x1 left, 0x2 right +boolean capslock = 0; // jeez i wonder what this does. // // D_ModifierKeyResponder // Sets global shift/ctrl/alt variables, never actually eats events diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 2f2657d7..5a4227c3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -776,6 +776,13 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_usegamma); // m_menu.c + CV_RegisterVar(&cv_compactscoreboard); + CV_RegisterVar(&cv_chatheight); + CV_RegisterVar(&cv_chatwidth); + CV_RegisterVar(&cv_chattime); + CV_RegisterVar(&cv_chatspamprotection); + CV_RegisterVar(&cv_consolechat); + CV_RegisterVar(&cv_chatnotifications); CV_RegisterVar(&cv_crosshair); CV_RegisterVar(&cv_crosshair2); CV_RegisterVar(&cv_crosshair3); diff --git a/src/doomdef.h b/src/doomdef.h index 175838c0..278dc002 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -434,6 +434,7 @@ extern INT32 cv_debug; // Modifier key variables, accessible anywhere extern UINT8 shiftdown, ctrldown, altdown; +extern boolean capslock; // if we ever make our alloc stuff... #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) diff --git a/src/g_game.c b/src/g_game.c index bbce2d3e..9224ad84 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -397,6 +397,32 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, #endif #endif +// don't mind me putting these here, I was lazy to figure out where else I could put those without blowing up the compiler. + +// it automatically becomes compact with 20+ players, but if you like it, I guess you can turn that on! +consvar_t cv_compactscoreboard= {"compactscoreboard", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chat timer thingy +static CV_PossibleValue_t chattime_cons_t[] = {{5, "MIN"}, {999, "MAX"}, {0, NULL}}; +consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chatwidth +static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {150, "MAX"}, {0, NULL}}; +consvar_t cv_chatwidth = {"chatwidth", "150", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chatheight +static CV_PossibleValue_t chatheight_cons_t[] = {{6, "MIN"}, {22, "MAX"}, {0, NULL}}; +consvar_t cv_chatheight= {"chatheight", "8", CV_SAVE, chatheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chat notifications (do you want to hear beeps? I'd understand if you didn't.) +consvar_t cv_chatnotifications= {"chatnotifications", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chat spam protection (why would you want to disable that???) +consvar_t cv_chatspamprotection= {"chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// old shit console chat. (mostly exists for stuff like terminal, not because I cared if anyone liked the old chat.) +consvar_t cv_consolechat= {"consolechat", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair3 = {"crosshair3", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/g_game.h b/src/g_game.h index f59641fb..fa188824 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,6 +54,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu +extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_compactscoreboard; extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis; diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c142e74c..99cc3613 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -900,6 +900,111 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) PF_Modulated|PF_NoTexture|PF_NoDepthTest); } +// -------------------+ +// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that. +// -------------------+ +void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options) +{ + FOutVector v[4]; + FSurfaceInfo Surf; + float fx, fy, fw, fh; + + if (w < 0 || h < 0) + return; // consistency w/ software + +// 3--2 +// | /| +// |/ | +// 0--1 + + fx = (float)x; + fy = (float)y; + fw = (float)w; + fh = (float)h; + + if (!(options & V_NOSCALESTART)) + { + float dupx = (float)vid.dupx, dupy = (float)vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { + RGBA_t rgbaColour = V_GetColor(color); + FRGBAFloat clearColour; + clearColour.red = (float)rgbaColour.s.red / 255; + clearColour.green = (float)rgbaColour.s.green / 255; + clearColour.blue = (float)rgbaColour.s.blue / 255; + clearColour.alpha = 1; + HWD.pfnClearBuffer(true, false, &clearColour); + return; + } + + fx *= dupx; + fy *= dupy; + fw *= dupx; + fh *= dupy; + + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (options & V_SNAPTORIGHT) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(options & V_SNAPTOLEFT)) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (options & V_SNAPTOBOTTOM) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(options & V_SNAPTOTOP)) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (fx >= vid.width || fy >= vid.height) + return; + if (fx < 0) + { + fw += fx; + fx = 0; + } + if (fy < 0) + { + fh += fy; + fy = 0; + } + + if (fw <= 0 || fh <= 0) + return; + if (fx + fw > vid.width) + fw = (float)vid.width - fx; + if (fy + fh > vid.height) + fh = (float)vid.height - fy; + + fx = -1 + fx / (vid.width / 2); + fy = 1 - fy / (vid.height / 2); + fw = fw / (vid.width / 2); + fh = fh / (vid.height / 2); + + v[0].x = v[3].x = fx; + v[2].x = v[1].x = fx + fw; + v[0].y = v[1].y = fy; + v[2].y = v[3].y = fy - fh; + + //Hurdler: do we still use this argb color? if not, we should remove it + v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].sow = v[3].sow = 0.0f; + v[2].sow = v[1].sow = 1.0f; + v[0].tow = v[1].tow = 0.0f; + v[2].tow = v[3].tow = 1.0f; + + Surf.FlatColor.rgba = UINT2RGBA(color); + Surf.FlatColor.s.alpha = 0x80; + + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); +} + #ifdef HAVE_PNG #ifndef _MSC_VER diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index fce17062..f0efc1c5 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -52,6 +52,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); void HWR_PrepLevelCache(size_t pnumtextures); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); +void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right. void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); void HWR_AddCommands(void); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c3c04bed..135cedfc 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -76,6 +76,7 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; +static INT32 c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -336,6 +337,74 @@ void HU_Start(void) //====================================================================== #ifndef NONET + +// EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM + +static UINT32 chat_nummsg_log = 0; +static UINT32 chat_nummsg_min = 0; +static UINT32 chat_scroll = 0; +static tic_t chat_scrolltime = 0; + +static INT32 chat_maxscroll = 0; // how far can we scroll? + +//static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent. +//static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool. + +static char chat_log[CHAT_BUFSIZE][255]; // hold the last 48 or so messages in that log. +static char chat_mini[8][255]; // display up to 8 messages that will fade away / get overwritten +static tic_t chat_timers[8]; + +static boolean chat_scrollmedown = false; // force instant scroll down on the chat log. Happens when you open it / send a message. + +// remove text from minichat table + +static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away + +static void HU_removeChatText_Mini(void) +{ + // MPC: Don't create new arrays, just iterate through an existing one + int i; + for(i=0;i<chat_nummsg_min-1;i++) { + strcpy(chat_mini[i], chat_mini[i+1]); + chat_timers[i] = chat_timers[i+1]; + } + chat_nummsg_min--; // lost 1 msg. + + // use addy and make shit slide smoothly af. + addy += (vid.width < 640) ? 8 : 6; + +} + +// same but w the log. TODO: optimize this and maybe merge in a single func? im bad at C. +static void HU_removeChatText_Log(void) +{ + // MPC: Don't create new arrays, just iterate through an existing one + int i; + for(i=0;i<chat_nummsg_log-1;i++) { + strcpy(chat_log[i], chat_log[i+1]); + } + chat_nummsg_log--; // lost 1 msg. +} + +void HU_AddChatText(const char *text) +{ + + // TODO: check if we're oversaturating the log (we can only log CHAT_BUFSIZE messages.) + + if (chat_nummsg_log >= CHAT_BUFSIZE) + HU_removeChatText_Log(); + + strcpy(chat_log[chat_nummsg_log], text); + chat_nummsg_log++; + + if (chat_nummsg_min >= 8) + HU_removeChatText_Mini(); + + strcpy(chat_mini[chat_nummsg_min], text); + chat_timers[chat_nummsg_min] = TICRATE*cv_chattime.value; + chat_nummsg_min++; +} + /** Runs a say command, sending an ::XD_SAY message. * A say command consists of a signed 8-bit integer for the target, an * unsigned 8-bit flag variable, and then the message itself. @@ -364,14 +433,14 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) numwords = COM_Argc() - usedargs; I_Assert(numwords > 0); - if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) + if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // TODO: Per Player mute. { - CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); + HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85")); return; } // Only servers/admins can CSAY. - if(!server && IsPlayerAdmin(consoleplayer)) + if(!server && !(IsPlayerAdmin(consoleplayer))) flags &= ~HU_CSAY; // We handle HU_SERVER_SAY, not the caller. @@ -389,6 +458,52 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) strlcat(msg, " ", msgspace); strlcat(msg, COM_Argv(ix + usedargs), msgspace); } + + if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm + { + // what we're gonna do now is check if the node exists + // with that logic, characters 4 and 5 are our numbers: + int spc = 1; // used if nodenum[1] is a space. + char *nodenum = (char*) malloc(3); + strncpy(nodenum, msg+3, 5); + // check for undesirable characters in our "number" + if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) + { + // check if nodenum[1] is a space + if (nodenum[1] == ' ') + spc = 0; + // let it slide + else + { + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); + return; + } + } + // I'm very bad at C, I swear I am, additional checks eww! + if (spc != 0) + { + if (msg[5] != ' ') + { + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); + return; + } + } + + target = atoi((const char*) nodenum); // turn that into a number + //CONS_Printf("%d\n", target); + + // check for target player, if it doesn't exist then we can't send the message! + if (playeringame[target]) // player exists + target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work! + else + { + HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target)); // same + return; + } + buf[0] = target; + const char *newmsg = msg+5+spc; + memcpy(msg, newmsg, 255); + } SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf); } @@ -473,6 +588,7 @@ static void Command_CSay_f(void) DoSayCommand(0, 1, HU_CSAY); } +static tic_t stop_spamming_you_cunt[MAXPLAYERS]; /** Receives a message, processing an ::XD_SAY command. * \sa DoSayCommand @@ -486,7 +602,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) char *msg; boolean action = false; char *ptr; - + CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]); target = READSINT8(*p); @@ -494,7 +610,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) msg = (char *)*p; SKIPSTRING(*p); - if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !IsPlayerAdmin(playernum)) + if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) { CONS_Alert(CONS_WARNING, cv_mute.value ? M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), @@ -531,12 +647,31 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } } } - + + int spam_eatmsg = 0; + + // before we do anything, let's verify the guy isn't spamming, get this easier on us. + + //if (stop_spamming_you_cunt[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) + if (stop_spamming_you_cunt[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY)) + { + CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); + stop_spamming_you_cunt[playernum] = 4; + spam_eatmsg = 1; + } + else + stop_spamming_you_cunt[playernum] = 4; // you can hold off for 4 tics, can you? + + // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. + #ifdef HAVE_BLUA - if (LUAh_PlayerMsg(playernum, target, flags, msg)) + if (LUAh_PlayerMsg(playernum, target, flags, msg, spam_eatmsg)) return; #endif - + + if (spam_eatmsg) + return; // don't proceed if we were supposed to eat the message. + // If it's a CSAY, just CECHO and be done with it. if (flags & HU_CSAY) { @@ -576,18 +711,23 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) || target == 0 // To everyone || consoleplayer == target-1) // To you { - const char *cstart = "", *cend = "", *adminchar = "~", *remotechar = "@", *fmt; + const char *prefix = "", *cstart = "", *cend = "", *adminchar = "\x82~\x83", *remotechar = "\x82@\x83", *fmt, *fmt2; char *tempchar = NULL; - + // In CTF and team match, color the player's name. if (G_GametypeHasTeams()) { - cend = "\x80"; - if (players[playernum].ctfteam == 1) // red - cstart = "\x85"; + cend = ""; + if (players[playernum].ctfteam == 1) // red + cstart = "\x85"; else if (players[playernum].ctfteam == 2) // blue cstart = "\x84"; + } + + // player is a spectator? + if (players[playernum].spectator) + cstart = "\x86"; // grey name // Give admins and remote admins their symbols. if (playernum == serverplayer) @@ -596,11 +736,11 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(remotechar) + 1, PU_STATIC, NULL); if (tempchar) { - strcat(tempchar, cstart); if (playernum == serverplayer) strcat(tempchar, adminchar); else strcat(tempchar, remotechar); + strcat(tempchar, cstart); cstart = tempchar; } @@ -609,21 +749,61 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // name, color end, and the message itself. // '\4' makes the message yellow and beeps; '\3' just beeps. if (action) - fmt = "\4* %s%s%s \x82%s\n"; + { + fmt = "\3* %s%s%s%s \x82%s\n"; // don't make /me yellow, yellow will be for mentions and PMs! + fmt2 = "* %s%s%s%s \x82%s"; + } else if (target == 0) // To everyone - fmt = "\3<%s%s%s> %s\n"; + { + fmt = "\3%s\x83<%s%s%s\x83>\x80 %s\n"; + fmt2 = "%s\x83<%s%s%s\x83>\x80 %s"; + } else if (target-1 == consoleplayer) // To you - fmt = "\3*%s%s%s* %s\n"; + { + prefix = "\x82[PM]"; + cstart = "\x82"; + fmt = "\4%s<%s%s>%s\x80 %s\n"; // make this yellow, however. + fmt2 = "%s<%s%s>%s\x80 %s"; + } else if (target > 0) // By you, to another player { // Use target's name. dispname = player_names[target-1]; - fmt = "\3->*%s%s%s* %s\n"; + /*fmt = "\3\x82[TO]\x80%s%s%s* %s\n"; + fmt2 = "\x82[TO]\x80%s%s%s* %s";*/ + prefix = "\x82[TO]"; + cstart = "\x82"; + fmt = "\4%s<%s%s>%s\x80 %s\n"; // make this yellow, however. + fmt2 = "%s<%s%s>%s\x80 %s"; + } else // To your team - fmt = "\3>>%s%s%s<< (team) %s\n"; - - CONS_Printf(fmt, cstart, dispname, cend, msg); + { + if (players[playernum].ctfteam == 1) // red + prefix = "\x85[TEAM]"; + else if (players[playernum].ctfteam == 2) // blue + prefix = "\x84[TEAM]"; + else + prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes + + fmt = "\3%s<%s%s>\x80%s %s\n"; + fmt2 = "%s<%s%s>\x80%s %s"; + + } + + if (cv_consolechat.value) + { + CONS_Printf(fmt, prefix, cstart, dispname, cend, msg); + HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); // add it reguardless, in case we decide to change our mind about our chat type. + } + else + { + HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); + CON_LogMessage(va(fmt, prefix, cstart, dispname, cend, msg)); // save to log.txt + if (cv_chatnotifications.value) + S_StartSound(NULL, sfx_radio); + } + if (tempchar) Z_Free(tempchar); } @@ -650,19 +830,48 @@ static inline boolean HU_keyInChatString(char *s, char ch) l = strlen(s); if (l < HU_MAXMSGLEN - 1) { - s[l++] = ch; - s[l]=0; + if (c_input >= strlen(s)) // don't do anything complicated + { + s[l++] = ch; + s[l]=0; + } + else + { + + // move everything past c_input for new characters: + INT32 m = HU_MAXMSGLEN-1; + for (;(m>=c_input);m--) + { + if (s[m]) + s[m+1] = (s[m]); + } + s[c_input] = ch; // and replace this. + } + c_input++; return true; } return false; } else if (ch == KEY_BACKSPACE) { - l = strlen(s); - if (l) - s[--l] = 0; - else + if (c_input <= 0) return false; + size_t i = c_input; + if (!s[i-1]) + return false; + + if (i >= strlen(s)-1) + { + s[strlen(s)-1] = 0; + c_input--; + return false; + } + + for (; (i < HU_MAXMSGLEN); i++) + { + s[i-1] = s[i]; + } + c_input--; } else if (ch != KEY_ENTER) return false; // did not eat key @@ -686,29 +895,9 @@ void HU_Ticker(void) hu_showscores = false; } -#define QUEUESIZE 256 static boolean teamtalk = false; -static char chatchars[QUEUESIZE]; -static INT32 head = 0, tail = 0; - -// -// HU_dequeueChatChar -// -char HU_dequeueChatChar(void) -{ - char c; - - if (head != tail) - { - c = chatchars[tail]; - tail = (tail + 1) & (QUEUESIZE-1); - } - else - c = 0; - - return c; -} +// WHY DO YOU OVERCOMPLICATE EVERYTHING????????? // // @@ -719,79 +908,130 @@ static void HU_queueChatChar(char c) { char buf[2+256]; size_t ci = 2; - + char *msg = &buf[2]; do { - c = HU_dequeueChatChar(); + c = w_chat[-2+ci++]; if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. - buf[ci++]=c; + buf[ci-1]=c; } while (c); - + size_t i = 0; + for (;(i<HU_MAXMSGLEN);i++) + w_chat[i] = 0; // reset this. + + c_input = 0; + // last minute mute check if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) { - CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); + HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85")); return; } - + + INT32 target = 0; + + if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm + { + // what we're gonna do now is check if the node exists + // with that logic, characters 4 and 5 are our numbers: + + // teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko. + if (teamtalk) + { + HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85")); + return; + } + + int spc = 1; // used if nodenum[1] is a space. + char *nodenum = (char*) malloc(3); + strncpy(nodenum, msg+3, 5); + // check for undesirable characters in our "number" + if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) + { + // check if nodenum[1] is a space + if (nodenum[1] == ' ') + spc = 0; + // let it slide + else + { + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); + return; + } + } + // I'm very bad at C, I swear I am, additional checks eww! + if (spc != 0) + { + if (msg[5] != ' ') + { + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); + return; + } + } + + target = atoi((const char*) nodenum); // turn that into a number + //CONS_Printf("%d\n", target); + + // check for target player, if it doesn't exist then we can't send the message! + if (playeringame[target]) // player exists + target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work! + else + { + HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target)); // same + return; + } + // we need to get rid of the /pm<node> + const char *newmsg = msg+5+spc; + memcpy(msg, newmsg, 255); + } if (ci > 3) // don't send target+flags+empty message. { if (teamtalk) buf[0] = -1; // target else - buf[0] = 0; // target + buf[0] = target; + buf[1] = 0; // flags SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); } return; } - - if (((head + 1) & (QUEUESIZE-1)) == tail) - CONS_Printf(M_GetText("[Message unsent]\n")); // message not sent - else - { - if (c == KEY_BACKSPACE) - { - if (tail != head) - head = (head - 1) & (QUEUESIZE-1); - } - else - { - chatchars[head] = c; - head = (head + 1) & (QUEUESIZE-1); - } - } } void HU_clearChatChars(void) { - while (tail != head) - HU_queueChatChar(KEY_BACKSPACE); + size_t i = 0; + for (;i<HU_MAXMSGLEN;i++) + w_chat[i] = 0; // reset this. chat_on = false; + c_input = 0; } +static boolean justscrolleddown; +static boolean justscrolledup; + // // Returns true if key eaten // boolean HU_Responder(event_t *ev) { - UINT8 c; - + UINT8 c=0; + if (ev->type != ev_keydown) return false; // only KeyDown events now... - + if (!chat_on) { // enter chat mode if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) - && netgame && (!cv_mute.value || server || IsPlayerAdmin(consoleplayer))) + && netgame && (!cv_mute.value || server || (IsPlayerAdmin(consoleplayer)))) { if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) return false; chat_on = true; w_chat[0] = 0; teamtalk = false; + chat_scrollmedown = true; return true; } if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) @@ -802,11 +1042,13 @@ boolean HU_Responder(event_t *ev) chat_on = true; w_chat[0] = 0; teamtalk = true; + chat_scrollmedown = true; return true; } } else // if chat_on { + // Ignore modifier keys // Note that we do this here so users can still set // their chat keys to one of these, if they so desire. @@ -816,18 +1058,95 @@ boolean HU_Responder(event_t *ev) return true; c = (UINT8)ev->data1; - - // use console translations - if (shiftdown) + + // capslock + if (c && c == KEY_CAPSLOCK) // it's a toggle. + { + if (capslock) + capslock = false; + else + capslock = true; + return true; + } + + // use console translations + if (shiftdown ^ capslock) c = shiftxform[c]; - + + // TODO: make chat behave like the console, so that we can go back and edit stuff when we fuck up. + + // pasting. pasting is cool. chat is a bit limited, though :( + if ((c == 'v' || c == 'V') && ctrldown) + { + const char *paste = I_ClipboardPaste(); + + // create a dummy string real quickly + + if (paste == NULL) + return true; + + size_t chatlen = strlen(w_chat); + size_t pastelen = strlen(paste); + if (chatlen+pastelen > HU_MAXMSGLEN) + return true; // we can't paste this!! + + if (c_input >= strlen(w_chat)) // add it at the end of the string. + { + memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that. + c_input += pastelen; + /*size_t i = 0; + for (;i<pastelen;i++) + { + HU_queueChatChar(paste[i]); // queue it so that it's actually sent. (this chat write thing is REALLY messy.) + }*/ + return true; + } + else // otherwise, we need to shift everything and make space, etc etc + { + size_t i = HU_MAXMSGLEN-1; + for (; i>=c_input;i--) + { + if (w_chat[i]) + w_chat[i+pastelen] = w_chat[i]; + + } + memcpy(&w_chat[c_input], paste, pastelen); // copy all of that. + c_input += pastelen; + return true; + } + } + if (HU_keyInChatString(w_chat,c)) + { HU_queueChatChar(c); + } if (c == KEY_ENTER) + { chat_on = false; + c_input = 0; // reset input cursor + chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :) + } else if (c == KEY_ESCAPE) + { chat_on = false; - + c_input = 0; // reset input cursor + } + else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0) // CHAT SCROLLING YAYS! + { + chat_scroll--; + justscrolledup = true; + chat_scrolltime = 4; + } + else if ((c == KEY_DOWNARROW || c == KEY_MOUSEWHEELDOWN) && chat_scroll < chat_maxscroll && chat_maxscroll > 0) + { + chat_scroll++; + justscrolleddown = true; + chat_scrolltime = 4; + } + else if (c == KEY_LEFTARROW && c_input != 0) // i said go back + c_input--; + else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat)) + c_input++; return true; } return false; @@ -837,12 +1156,412 @@ boolean HU_Responder(event_t *ev) // HEADS UP DRAWING //====================================================================== +// Gets string colormap, used for 0x80 color codes +// +static UINT8 *CHAT_GetStringColormap(INT32 colorflags) // pasted from video.c, sorry for the mess. +{ + switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT) + { + case 1: // 0x81, purple + return purplemap; + case 2: // 0x82, yellow + return yellowmap; + case 3: // 0x83, lgreen + return lgreenmap; + case 4: // 0x84, blue + return bluemap; + case 5: // 0x85, red + return redmap; + case 6: // 0x86, gray + return graymap; + case 7: // 0x87, orange + return orangemap; + default: // reset + return NULL; + } +} + +// Precompile a wordwrapped string to any given width. +// This is a muuuch better method than V_WORDWRAP. +// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day. +// this one is simplified for the chat drawer. +char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) +{ + int c; + size_t chw, i, lastusablespace = 0; + size_t slen; + char *newstring = Z_StrDup(string); + INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4; + + slen = strlen(string); + x = 0; + + for (i = 0; i < slen; ++i) + { + c = newstring[i]; + if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09 + continue; + + if (c == '\n') + { + x = 0; + lastusablespace = 0; + continue; + } + + if (!(option & V_ALLOWLOWERCASE)) + c = toupper(c); + c -= HU_FONTSTART; + + if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) + { + chw = spacewidth; + lastusablespace = i; + } + else + chw = charwidth; + + x += chw; + + if (lastusablespace != 0 && x > w) + { + //CONS_Printf("Wrap at index %d\n", i); + newstring[lastusablespace] = '\n'; + i = lastusablespace+1; + lastusablespace = 0; + x = 0; + } + } + return newstring; +} + +INT16 chatx = 160, chaty = 16; // let's use this as our coordinates, shh + +// chat stuff by VincyTM LOL XD! + +// HU_DrawMiniChat + +static void HU_drawMiniChat(void) +{ + INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; + INT32 x = chatx+2, y = chaty+2, dx = 0, dy = 0; + size_t i = 0; + + for (i=0; i<chat_nummsg_min; i++) // iterate through our hot messages + { + + INT32 clrflag = 0; + + INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... + INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. + size_t j = 0; + const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + while(msg[j]) // iterate through msg + { + if (msg[j] < HU_FONTSTART) // don't draw + { + if (msg[j] == '\n') // get back down. + { + ++j; + dy += charheight; + dx = 0; + continue; + } + else if (msg[j] & 0x80) // stolen from video.c, nice. + { + clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; + ++j; + continue; + } + + ++j; + } + else + { + UINT8 *colormap = CHAT_GetStringColormap(clrflag); + V_DrawChatCharacter(x + dx + 2, y+dy+addy, msg[j++] |V_SNAPTOTOP|V_SNAPTORIGHT|transflag, !cv_allcaps.value, colormap); + } + + dx += charwidth; + if (dx >= cv_chatwidth.value) + { + dx = 0; + dy += charheight; + } + } + dy += charheight; + dx = 0; + } + + // decrement addy and make that shit smooth: + addy /= 2; + +} + +// HU_DrawUpArrow +// You see, we don't have arrow graphics in 2.1 and I'm too lazy to include a 2 bytes file for it. + +static void HU_DrawUpArrow(INT32 x, INT32 y, INT32 options) +{ + // Ok I'm super lazy so let's make this as the worst draw function: + V_DrawFill(x+2, y, 1, 1, 103|options); + V_DrawFill(x+1, y+1, 3, 1, 103|options); + V_DrawFill(x, y+2, 5, 1, 103|options); // that's the yellow part, I swear + + V_DrawFill(x+3, y, 1, 1, 26|options); + V_DrawFill(x+4, y+1, 1, 1, 26|options); + V_DrawFill(x+5, y+2, 1, 1, 26|options); + V_DrawFill(x, y+3, 6, 1, 26|options); // that's the black part. no racism intended. i swear. +} + +// HU_DrawDownArrow +// Should we talk about anime waifus to pass the time? This feels retarded. + +static void HU_DrawDownArrow(INT32 x, INT32 y, INT32 options) +{ + // Ok I'm super lazy so let's make this as the worst draw function: + V_DrawFill(x, y, 6, 1, 26|options); + V_DrawFill(x, y+1, 5, 1, 26|options); + V_DrawFill(x+1, y+2, 3, 1, 26|options); + V_DrawFill(x+2, y+3, 1, 1, 26|options); // that's the black part. no racism intended. i swear. + + V_DrawFill(x, y, 5, 1, 103|options); + V_DrawFill(x+1, y+1, 3, 1, 103|options); + V_DrawFill(x+2, y+2, 1, 1, 103|options); // that's the yellow part, I swear +} + +// HU_DrawChatLog +// TODO: fix dumb word wrapping issues + +static void HU_drawChatLog(void) +{ + + // before we do anything, make sure that our scroll position isn't "illegal"; + if (chat_scroll > chat_maxscroll) + chat_scroll = chat_maxscroll; + + INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; + INT32 x = chatx+2, y = chaty+2-(chat_scroll*charheight), dx = 0, dy = 0; + size_t i = 0; + boolean atbottom = false; + + V_DrawFillConsoleMap(chatx, chaty, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOTOP|V_SNAPTORIGHT); // INUT + + for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog + { + INT32 clrflag = 0; + size_t j = 0; + const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. + while(msg[j]) // iterate through msg + { + if (msg[j] < HU_FONTSTART) // don't draw + { + if (msg[j] == '\n') // get back down. + { + ++j; + dy += charheight; + dx = 0; + continue; + } + else if (msg[j] & 0x80) // stolen from video.c, nice. + { + clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; + ++j; + continue; + } + + ++j; + } + else + { + if ((y+dy > chaty) && (y+dy < (chaty+cv_chatheight.value*charheight))) + { + UINT8 *colormap = CHAT_GetStringColormap(clrflag); + V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOTOP|V_SNAPTORIGHT, !cv_allcaps.value, colormap); + } + else + j++; // don't forget to increment this or we'll get stuck in the limbo. + } + + dx += charwidth; + if (dx >= cv_chatwidth.value-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! + { + dx = 0; + dy += charheight; + } + } + dy += charheight; + dx = 0; + } + + if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling. + { + atbottom = true; // we should scroll + } + chat_scrollmedown = false; + + // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P + chat_maxscroll = (dy/charheight)-cv_chatheight.value; // welcome to C, we don't know what min() and max() are. + if (chat_maxscroll < 0) + chat_maxscroll = 0; + + // if we're not bound by the time, autoscroll for next frame: + if (atbottom) + chat_scroll = chat_maxscroll; + + // draw arrows to indicate that we can (or not) scroll. + + if (chat_scroll > 0) + HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chaty-1) : (chaty)), V_SNAPTOTOP | V_SNAPTORIGHT); + if (chat_scroll < chat_maxscroll) + HU_DrawDownArrow(chatx-8, chaty+(cv_chatheight.value*charheight)-((justscrolleddown) ? 3 : 4), V_SNAPTOTOP | V_SNAPTORIGHT); + + justscrolleddown = false; + justscrolledup = false; +} + // // HU_DrawChat // // Draw chat input // + +static INT16 typelines = 1; // number of drawfill lines we need. it's some weird hack and might be one frame off but I'm lazy to make another loop. static void HU_DrawChat(void) +{ + INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; + INT32 t = 0, c = 0, y = chaty + 4 + cv_chatheight.value*charheight; + size_t i = 0; + const char *ntalk = "Say: ", *ttalk = "Team: "; + const char *talk = ntalk; + + if (teamtalk) + { + talk = ttalk; +#if 0 + if (players[consoleplayer].ctfteam == 1) + t = 0x500; // Red + else if (players[consoleplayer].ctfteam == 2) + t = 0x400; // Blue +#endif + } + + HU_drawChatLog(); + V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (vid.width < 640 ) ? (typelines*charheight+2) : (typelines*charheight), 239 | V_SNAPTOTOP | V_SNAPTORIGHT); + + while (talk[i]) + { + if (talk[i] < HU_FONTSTART) + ++i; + else + V_DrawChatCharacter(chatx + c + 2, y, talk[i++] |V_SNAPTOTOP|V_SNAPTORIGHT, !cv_allcaps.value, NULL); + + c += charwidth; + } + + i = 0; + typelines = 1; + + if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) + V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOTOP|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); + + while (w_chat[i]) + { + + if (c_input == (i+1) && hu_tick < 4) + { + int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx); // we may have to go down. + int cursory = (cursorx != chatx) ? (y) : (y+charheight); + V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOTOP|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); + } + + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + ++i; + else + V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOTOP|V_SNAPTORIGHT | t, !cv_allcaps.value, NULL); + + c += charwidth; + if (c > cv_chatwidth.value-charwidth) + { + c = 0; + y += charheight; + typelines += 1; + } + } + + // handle /pm list. + if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai + { + i = 0; + int count = 0; + INT32 p_dispy = chaty+2; + V_DrawFillConsoleMap(chatx-50, p_dispy-2, 48, 2, 239 | V_SNAPTOTOP | V_SNAPTORIGHT); // top (don't mind me) + for(i=0; (i<MAXPLAYERS); i++) + { + + // filter: (code needs optimization pls help I'm bad with C) + if (w_chat[3]) + { + + // right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!) + if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' ')) + break; + + + char *nodenum = (char*) malloc(3); + strncpy(nodenum, w_chat+3, 4); + INT32 n = atoi((const char*) nodenum); // turn that into a number + // special cases: + + if ((n == 0) && !(w_chat[4] == '0')) + { + if (!(i<10)) + continue; + } + else if ((n == 1) && !(w_chat[3] == '0')) + { + if (!((i == 1) || ((i >= 10) && (i <= 19)))) + continue; + } + else if ((n == 2) && !(w_chat[3] == '0')) + { + if (!((i == 2) || ((i >= 20) && (i <= 29)))) + continue; + } + else if ((n == 3) && !(w_chat[3] == '0')) + { + if (!((i == 3) || ((i >= 30) && (i <= 31)))) + continue; + } + else // general case. + { + if (i != n) + continue; + } + } + + if ((playeringame[i])) + { + char name[MAXPLAYERNAME+1]; + strlcpy(name, player_names[i], 7); // shorten name to 7 characters. + V_DrawFillConsoleMap(chatx-50, p_dispy+ (6*count), 48, 6, 239 | V_SNAPTOTOP | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. + V_DrawSmallString(chatx-48, p_dispy+ (6*count), V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); + count++; + } + } + if (count == 0) // no results. + { + V_DrawFillConsoleMap(chatx-50, p_dispy+ (6*count), 48, 6, 239 | V_SNAPTOTOP | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. + V_DrawSmallString(chatx-48, p_dispy+ (6*count), V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE, "NO RESULT."); + } + } + +} + +// why the fuck would you use this... + +static void HU_DrawChat_Old(void) { INT32 t = 0, c = 0, y = HU_INPUTY; size_t i = 0; @@ -850,7 +1569,6 @@ static void HU_DrawChat(void) const char *talk = ntalk; INT32 charwidth = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; INT32 charheight = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor; - if (teamtalk) { talk = ttalk; @@ -876,10 +1594,21 @@ static void HU_DrawChat(void) } c += charwidth; } - + + if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) + V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); + i = 0; while (w_chat[i]) { + + if (c_input == (i+1) && hu_tick < 4) + { + int cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. + int cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight); + V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); + } + //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) { @@ -899,12 +1628,8 @@ static void HU_DrawChat(void) y += charheight; } } - - if (hu_tick < 4) - V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value); } - // draw the Crosshair, at the exact center of the view. // // Crosshairs are pre-cached at HU_Init @@ -1175,7 +1900,45 @@ void HU_Drawer(void) { // draw chat string plus cursor if (chat_on) - HU_DrawChat(); + { + // count down the scroll timer. + if (chat_scrolltime > 0) + chat_scrolltime--; + if (!cv_consolechat.value) + HU_DrawChat(); + else + HU_DrawChat_Old(); // why the fuck......................... + } + else + { + if (!cv_consolechat.value) + { + HU_drawMiniChat(); // draw messages in a cool fashion. + chat_scrolltime = 0; // do scroll anyway. + typelines = 0; // make sure that the chat doesn't have a weird blinking huge ass square if we typed a lot last time. + } + } + + if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh) + { + size_t i = 0; + + // handle spam while we're at it: + for(; (i<MAXPLAYERS); i++) + { + if (stop_spamming_you_cunt[i] > 0) + stop_spamming_you_cunt[i]--; + } + + // handle chat timers + for (i=0; (i<chat_nummsg_min); i++) + { + if (chat_timers[i] > 0) + chat_timers[i]--; + else + HU_removeChatText_Mini(); + } + } if (cechotimer) HU_DrawCEcho(); @@ -1319,6 +2082,40 @@ void HU_Erase(void) // IN-LEVEL MULTIPLAYER RANKINGS //====================================================================== +// +// HU_drawPing +// +void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) +{ + UINT8 numbars = 1; // how many ping bars do we draw? + UINT8 barcolor = 128; // color we use for the bars (green, yellow or red) + SINT8 i = 0; + SINT8 yoffset = 6; + if (ping < 128) + { + numbars = 3; + barcolor = 184; + } + else if (ping < 256) + { + numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it. + barcolor = 103; + } + + INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2); + if (!notext || vid.width >= 640) // how sad, we're using a shit resolution. + V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping)); + + for (i=0; (i<3); i++) // Draw the ping bar + { + V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31); + if (i < numbars) + V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor); + + yoffset -= 2; + } +} + // // HU_DrawTabRankings // @@ -1336,7 +2133,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I { if (players[tab[i].num].spectator) continue; //ignore them. - + + if (!splitscreen) // don't draw it on splitscreen, + { + if (!(tab[i].num == serverplayer)) + HU_drawPing(x+ 253, y+2, playerpingtable[tab[i].num], false); + } + V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_60TRANS) @@ -1493,6 +2296,11 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } V_DrawRightAlignedThinString(x+120, y-1, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + if (!splitscreen) + { + if (!(tab[i].num == serverplayer)) + HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false); + } } } @@ -1515,6 +2323,8 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline continue; //ignore them. strlcpy(name, tab[i].name, 9); + if (!(tab[i].num == serverplayer)) + HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 451cc8d8..2a99be4b 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -80,6 +80,11 @@ extern patch_t *tagico; extern patch_t *tallminus; extern patch_t *iconprefix[MAXSKINS]; +#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand. + +// some functions +void HU_AddChatText(const char *text); + // set true when entering a chat message extern boolean chat_on; @@ -105,6 +110,7 @@ char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); +void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard. void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer); void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b49cdd72..5cdd31f0 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -86,6 +86,51 @@ static int lib_print(lua_State *L) return 0; } +// Print stuff in the chat, or in the console if we can't. +static int lib_chatprint(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); // retrieve string + if (str == NULL) // error if we don't have a string! + return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprint")); + int len = strlen(str); + if (len > 255) // string is too long!!! + return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); + + if (cv_consolechat.value || !netgame) + CONS_Printf("%s\n", str); + else + HU_AddChatText(str); + return 0; +} + +// Same as above, but do it for only one player. +static int lib_chatprintf(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + player_t *plr; + if (n < 2) + return luaL_error(L, "chatprintf requires at least two arguments: player and text."); + + plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player + if (!plr) + return LUA_ErrInvalid(L, "player_t"); + if (plr != &players[consoleplayer]) + return 0; + + const char *str = luaL_checkstring(L, 2); // retrieve string + if (str == NULL) // error if we don't have a string! + return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprintf")); + int len = strlen(str); + if (len > 255) // string is too long!!! + return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); + + if (cv_consolechat.value || !netgame) + CONS_Printf("%s\n", str); + else + HU_AddChatText(str); + return 0; +} + static int lib_evalMath(lua_State *L) { const char *word = luaL_checkstring(L, 1); @@ -2165,6 +2210,8 @@ static int lib_kGetKartFlashing(lua_State *L) static luaL_Reg lib[] = { {"print", lib_print}, + {"chatprint", lib_chatprint}, + {"chatprintf", lib_chatprintf}, {"EvalMath", lib_evalMath}, // m_random diff --git a/src/lua_hook.h b/src/lua_hook.h index 53e0a7d8..7acc0d0f 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -74,7 +74,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Ho boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors -boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages +boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute); // Hook for chat messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index eadd0153..5b05b77c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -952,7 +952,9 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) } // Hook for player chat -boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) +// Added the "mute" field. It's set to true if the message was supposed to be eaten by spam protection. +// But for netgame consistency purposes, this hook is ran first reguardless, so this boolean allows for modders to adapt if they so desire. +boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) { hook_p hookp; boolean hooked = false; @@ -981,14 +983,19 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target } lua_pushstring(gL, msg); // msg + if (mute) + lua_pushboolean(gL, true); // the message was supposed to be eaten by spamprotecc. + else + lua_pushboolean(gL, false); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + 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 (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); diff --git a/src/v_video.c b/src/v_video.c index ac0eed17..44319dd7 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -303,7 +303,7 @@ void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT3 #endif } -//static UINT8 hudplusalpha[11] = { 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0}; +static UINT8 hudplusalpha[11] = { 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0}; static UINT8 hudminusalpha[11] = { 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5}; static const UINT8 *v_colormap = NULL; @@ -840,6 +840,129 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) memset(dest, (UINT8)(c&255), w * vid.bpp); } +// THANK YOU MPC!!! + +void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) +{ + UINT8 *dest; + INT32 u, v; + UINT32 alphalevel = 0; + + if (rendermode == render_none) + return; + +#ifdef HWRENDER + if (rendermode != render_soft && rendermode != render_none) + { + UINT32 hwcolor; + switch (cons_backcolor.value) + { + case 0: hwcolor = 0xffffff00; break; // White + case 1: hwcolor = 0x80808000; break; // Gray + case 2: hwcolor = 0x40201000; break; // Brown + case 3: hwcolor = 0xff000000; break; // Red + case 4: hwcolor = 0xff800000; break; // Orange + case 5: hwcolor = 0x80800000; break; // Yellow + case 6: hwcolor = 0x00800000; break; // Green + case 7: hwcolor = 0x0000ff00; break; // Blue + case 8: hwcolor = 0x4080ff00; break; // Cyan + // Default green + default: hwcolor = 0x00800000; break; + } + HWR_DrawConsoleFill(x, y, w, h, hwcolor, c); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this. + return; + } +#endif + + if (!(c & V_NOSCALESTART)) + { + INT32 dupx = vid.dupx, dupy = vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { // Clear the entire screen, from dest to deststop. Yes, this really works. + memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); + return; + } + + x *= dupx; + y *= dupy; + w *= dupx; + h *= dupy; + + // Center it if necessary + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (c & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(c & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (c & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(c & V_SNAPTOTOP)) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (x >= vid.width || y >= vid.height) + return; // off the screen + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + + if (w <= 0 || h <= 0) + return; // zero width/height wouldn't draw anything + if (x + w > vid.width) + w = vid.width-x; + if (y + h > vid.height) + h = vid.height-y; + + dest = screens[0] + y*vid.width + x; + + if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT))) + { + if (alphalevel == 13) + alphalevel = hudminusalpha[cv_translucenthud.value]; + else if (alphalevel == 14) + alphalevel = 10 - cv_translucenthud.value; + else if (alphalevel == 15) + alphalevel = hudplusalpha[cv_translucenthud.value]; + + if (alphalevel >= 10) + return; // invis + } + + c &= 255; + + if (!alphalevel) { + for (v = 0; v < h; v++, dest += vid.width) { + for (u = 0; u < w; u++) { + dest[u] = consolebgmap[dest[u]]; + } + } + } else { // mpc 12-04-2018 + const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)<<FF_TRANSSHIFT) + (c*256)); + #define clip(x,y) (x>y) ? y : x + w = clip(w,vid.width); + h = clip(h,vid.height); + for (v = 0; v < h; v++, dest += vid.width) { + for (u = 0; u < w; u++) { + dest[u] = fadetable[consolebgmap[dest[u]]]; + } + } + } +} + // // Fills a box of pixels using a flat texture as a pattern, scaled to screen size. // @@ -1060,6 +1183,32 @@ void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed) V_DrawScaledPatch(x, y, flags, hu_font[c]); } +// Writes a single character for the chat. (draw WHITE if bit 7 set) +// Essentially the same as the above but it's small or big depending on what resolution you've chosen to huge.. +// +void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap) +{ + INT32 w, flags; + //const UINT8 *colormap = V_GetStringColormap(c); + + flags = c & ~(V_CHARCOLORMASK | V_PARAMMASK); + c &= 0x7f; + if (lowercaseallowed) + c -= HU_FONTSTART; + else + c = toupper(c) - HU_FONTSTART; + if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) + return; + + w = (vid.width < 640 ) ? (SHORT(hu_font[c]->width)/2) : (SHORT(hu_font[c]->width)); // use normal sized characters if we're using a terribly low resolution. + if (x + w > vid.width) + return; + + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, (vid.width < 640) ? (FRACUNIT) : (FRACUNIT/2), flags, hu_font[c], colormap); + + +} + // Precompile a wordwrapped string to any given width. // This is a muuuch better method than V_WORDWRAP. char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) diff --git a/src/v_video.h b/src/v_video.h index 990f9b13..ffa1038c 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -139,6 +139,7 @@ void V_DrawScaledPic (INT32 px1, INT32 py1, INT32 scrn, INT32 lumpnum); // fill a box with a single color void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); +void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); // fill a box with a flat as a pattern void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); @@ -149,6 +150,8 @@ void V_DrawFadeConsBack(INT32 plines); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); +// draw a single character, but for the chat +void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap); void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string); From 823497ea0667d8e5148e1b821db46cb6bde88d95 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Tue, 24 Jul 2018 01:03:59 +0100 Subject: [PATCH 02/38] Fix accidentially tripped PARANOIA error for teamchanges. --- src/d_netcmd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a83f23b2..767f5729 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2531,8 +2531,8 @@ static void Command_Teamchange_f(void) return; } - if (players[consoleplayer].spectator && !(players[consoleplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam) - error = true; + if (players[consoleplayer].spectator && !NetPacket.packet.newteam) + error = !(players[consoleplayer].pflags & PF_WANTSTOJOIN); else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam) error = true; else if (G_GametypeHasSpectators() && !players[consoleplayer].spectator && NetPacket.packet.newteam == 3) @@ -2622,8 +2622,8 @@ static void Command_Teamchange2_f(void) return; } - if (players[secondarydisplayplayer].spectator && !(players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam) - error = true; + if (players[secondarydisplayplayer].spectator && !NetPacket.packet.newteam) + error = !(players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN); else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam) error = true; else if (G_GametypeHasSpectators() && !players[secondarydisplayplayer].spectator && NetPacket.packet.newteam == 3) @@ -2713,8 +2713,8 @@ static void Command_Teamchange3_f(void) return; } - if (players[thirddisplayplayer].spectator && !(players[thirddisplayplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam) - error = true; + if (players[thirddisplayplayer].spectator && !NetPacket.packet.newteam) + error = !(players[thirddisplayplayer].pflags & PF_WANTSTOJOIN); else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam) error = true; else if (G_GametypeHasSpectators() && !players[thirddisplayplayer].spectator && NetPacket.packet.newteam == 3) @@ -2804,8 +2804,8 @@ static void Command_Teamchange4_f(void) return; } - if (players[fourthdisplayplayer].spectator && !(players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam) - error = true; + if (players[fourthdisplayplayer].spectator && !NetPacket.packet.newteam) + error = !(players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN); else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam) error = true; else if (G_GametypeHasSpectators() && !players[fourthdisplayplayer].spectator && NetPacket.packet.newteam == 3) From 4f23b84f9260f9aa41a8303f8d10066b069e7500 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Tue, 24 Jul 2018 01:12:40 +0100 Subject: [PATCH 03/38] ...fix it properly instead of rushing into it at 1am --- src/d_netcmd.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 767f5729..1b6bf4b7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2531,12 +2531,12 @@ static void Command_Teamchange_f(void) return; } - if (players[consoleplayer].spectator && !NetPacket.packet.newteam) - error = !(players[consoleplayer].pflags & PF_WANTSTOJOIN); - else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam) - error = true; - else if (G_GametypeHasSpectators() && !players[consoleplayer].spectator && NetPacket.packet.newteam == 3) - error = true; + if (players[consoleplayer].spectator) + error = !(NetPacket.packet.newteam || (players[consoleplayer].pflags & PF_WANTSTOJOIN)); + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[consoleplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); @@ -2622,12 +2622,12 @@ static void Command_Teamchange2_f(void) return; } - if (players[secondarydisplayplayer].spectator && !NetPacket.packet.newteam) - error = !(players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN); - else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam) - error = true; - else if (G_GametypeHasSpectators() && !players[secondarydisplayplayer].spectator && NetPacket.packet.newteam == 3) - error = true; + if (players[secondarydisplayplayer].spectator) + error = !(NetPacket.packet.newteam || (players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN)); + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[secondarydisplayplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); @@ -2713,12 +2713,12 @@ static void Command_Teamchange3_f(void) return; } - if (players[thirddisplayplayer].spectator && !NetPacket.packet.newteam) - error = !(players[thirddisplayplayer].pflags & PF_WANTSTOJOIN); - else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam) - error = true; - else if (G_GametypeHasSpectators() && !players[thirddisplayplayer].spectator && NetPacket.packet.newteam == 3) - error = true; + if (players[thirddisplayplayer].spectator) + error = !(NetPacket.packet.newteam || (players[thirddisplayplayer].pflags & PF_WANTSTOJOIN)); + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[thirddisplayplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); @@ -2804,12 +2804,12 @@ static void Command_Teamchange4_f(void) return; } - if (players[fourthdisplayplayer].spectator && !NetPacket.packet.newteam) - error = !(players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN); - else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam) - error = true; - else if (G_GametypeHasSpectators() && !players[fourthdisplayplayer].spectator && NetPacket.packet.newteam == 3) - error = true; + if (players[fourthdisplayplayer].spectator) + error = !(NetPacket.packet.newteam || (players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN)); + else if (G_GametypeHasTeams()) + error = (NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam); + else if (G_GametypeHasSpectators() && !players[fourthdisplayplayer].spectator) + error = (NetPacket.packet.newteam == 3); #ifdef PARANOIA else I_Error("Invalid gametype after initial checks!"); From f98bc6f8513340de6492c107dc80451871b854b9 Mon Sep 17 00:00:00 2001 From: wolfy852 <wolfy852@hotmail.com> Date: Mon, 23 Jul 2018 19:50:28 -0500 Subject: [PATCH 04/38] Fix a minor conditional error in d_netcmd.c --- src/d_netcmd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1b6bf4b7..bd436485 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2532,7 +2532,7 @@ static void Command_Teamchange_f(void) } if (players[consoleplayer].spectator) - error = !(NetPacket.packet.newteam || (players[consoleplayer].pflags & PF_WANTSTOJOIN)); + error = !(NetPacket.packet.newteam && (players[consoleplayer].pflags & PF_WANTSTOJOIN)); else if (G_GametypeHasTeams()) error = (NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam); else if (G_GametypeHasSpectators() && !players[consoleplayer].spectator) @@ -2623,7 +2623,7 @@ static void Command_Teamchange2_f(void) } if (players[secondarydisplayplayer].spectator) - error = !(NetPacket.packet.newteam || (players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN)); + error = !(NetPacket.packet.newteam && (players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN)); else if (G_GametypeHasTeams()) error = (NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam); else if (G_GametypeHasSpectators() && !players[secondarydisplayplayer].spectator) @@ -2714,7 +2714,7 @@ static void Command_Teamchange3_f(void) } if (players[thirddisplayplayer].spectator) - error = !(NetPacket.packet.newteam || (players[thirddisplayplayer].pflags & PF_WANTSTOJOIN)); + error = !(NetPacket.packet.newteam && (players[thirddisplayplayer].pflags & PF_WANTSTOJOIN)); else if (G_GametypeHasTeams()) error = (NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam); else if (G_GametypeHasSpectators() && !players[thirddisplayplayer].spectator) @@ -2805,7 +2805,7 @@ static void Command_Teamchange4_f(void) } if (players[fourthdisplayplayer].spectator) - error = !(NetPacket.packet.newteam || (players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN)); + error = !(NetPacket.packet.newteam && (players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN)); else if (G_GametypeHasTeams()) error = (NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam); else if (G_GametypeHasSpectators() && !players[fourthdisplayplayer].spectator) From 4f1ddaaa7d5384c932f70829c350f18e634fefd3 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Tue, 24 Jul 2018 22:04:27 +0100 Subject: [PATCH 05/38] Fix buffer overrun and iteration clobbering in D_SetupVote by: * Decreasing number of writes - now the unchanging gametype is only written once, and both gametypes are written as UINT8s instead of UINT16s. * Increasing size of buffer to match new threshold. --- src/d_netcmd.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1b6bf4b7..6fe39b6f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1966,26 +1966,22 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese void D_SetupVote(void) { - char buf[8]; - char *p = buf; + UINT8 buf[6*2]; // five UINT16 maps (at twice the width of a UINT8), and two gametypes + UINT8 *p = buf; INT32 i; + UINT8 secondgt = G_SometimesGetDifferentGametype(); + + WRITEUINT8(p, gametype); + WRITEUINT8(p, secondgt); for (i = 0; i < 5; i++) { if (i == 2) // sometimes a different gametype - { - INT16 gt = G_SometimesGetDifferentGametype(); - WRITEUINT16(p, G_RandMap(G_TOLFlag(gt), prevmap, false, false, 0, true)); - WRITEUINT16(p, gt); - } + WRITEUINT16(p, G_RandMap(G_TOLFlag(secondgt), prevmap, false, false, 0, true)); + else if (i >= 3) // unknown-random and force-unknown MAP HELL + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, true, false, (i-2), (i < 4))); else - { - if (i >= 3) // unknown-random and force-unknown MAP HELL - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, true, false, (i-2), (i < 4))); - else - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, false, 0, true)); - WRITEUINT16(p, gametype); - } + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, false, 0, true)); } SendNetXCmd(XD_SETUPVOTE, buf, p - buf); @@ -4582,6 +4578,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) { INT32 i; + UINT8 gt, secondgt; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -4597,14 +4594,19 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) return; } + gt = (UINT8)READUINT8(*cp); + secondgt = (UINT8)READUINT8(*cp); + for (i = 0; i < 5; i++) { - votelevels[i][0] = (INT16)READUINT16(*cp); - votelevels[i][1] = (INT16)READUINT16(*cp); + votelevels[i][0] = (UINT16)READUINT16(*cp); + votelevels[i][1] = gt; if (!mapheaderinfo[votelevels[i][0]]) P_AllocMapHeader(votelevels[i][0]); } + votelevels[2][1] = secondgt; + G_SetGamestate(GS_VOTING); Y_StartVote(); } From b42d083b992361e99c8b2fd03e36716ebcf1506a Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Tue, 24 Jul 2018 22:47:09 -0400 Subject: [PATCH 06/38] Finishing touches on Ballhog - Ballhog has explosion + sound on death - Ballhog shrinks to nothing if it didn't hit anything - Replaced a Mario sound on Orbinaut - Fixed Jawz's sound effect - Fixed Mines not being removed on death pits --- src/d_netcmd.c | 2 +- src/dehacked.c | 18 ++++++++++++++ src/info.c | 67 +++++++++++++++++++++++++++++++++++++++++--------- src/info.h | 18 ++++++++++++++ src/k_kart.c | 4 +++ src/p_enemy.c | 18 +++++++++++++- src/p_map.c | 2 +- src/p_mobj.c | 23 +++++++++++------ src/sounds.c | 7 +++--- src/sounds.h | 7 +++--- 10 files changed, 138 insertions(+), 28 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index fd729d3e..e959f406 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5259,4 +5259,4 @@ static void KartComeback_OnChange(void) comeback = (boolean)cv_kartcomeback.value; } } -} \ No newline at end of file +} diff --git a/src/dehacked.c b/src/dehacked.c index 9cc06dfd..921cc2db 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1827,6 +1827,7 @@ static actionpointer_t actionpointers[] = {{A_JawzChase}, "A_JAWZCHASE"}, // SRB2kart {{A_JawzExplode}, "A_JAWZEXPLODE"}, // SRB2kart {{A_MineExplode}, "A_MINEEXPLODE"}, // SRB2kart + {{A_BallhogExplode}, "A_BALLHOGEXPLODE"}, // SRB2kart {{A_OrbitNights}, "A_ORBITNIGHTS"}, {{A_GhostMe}, "A_GHOSTME"}, {{A_SetObjectState}, "A_SETOBJECTSTATE"}, @@ -6415,6 +6416,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BALLHOG7", "S_BALLHOG8", "S_BALLHOG_DEAD", + "S_BALLHOGBOOM1", + "S_BALLHOGBOOM2", + "S_BALLHOGBOOM3", + "S_BALLHOGBOOM4", + "S_BALLHOGBOOM5", + "S_BALLHOGBOOM6", + "S_BALLHOGBOOM7", + "S_BALLHOGBOOM8", + "S_BALLHOGBOOM9", + "S_BALLHOGBOOM10", + "S_BALLHOGBOOM11", + "S_BALLHOGBOOM12", + "S_BALLHOGBOOM13", + "S_BALLHOGBOOM14", + "S_BALLHOGBOOM15", + "S_BALLHOGBOOM16", // Self-Propelled Bomb - just an explosion for now... "S_BLUELIGHTNING1", @@ -7173,6 +7190,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BOOMPARTICLE", "MT_BALLHOG", // Ballhog + "MT_BALLHOGBOOM", "MT_BLUELIGHTNING", // Grow/shrink stuff "MT_BLUEEXPLOSION", diff --git a/src/info.c b/src/info.c index 939efd44..8cfea02c 100644 --- a/src/info.c +++ b/src/info.c @@ -2725,15 +2725,31 @@ state_t states[NUMSTATES] = {SPR_KRBM, FF_FULLBRIGHT|8, 5, {NULL}, 0, 0, S_SLOWBOOM10}, // S_SLOWBOOM9 {SPR_KRBM, FF_FULLBRIGHT|9, 5, {NULL}, 0, 0, S_NULL}, // S_SLOWBOOM10 - {SPR_BHOG, 0, 3, {A_PlaySound}, sfx_s1bd, 1, S_BALLHOG2}, // S_BALLHOG1 - {SPR_BHOG, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BALLHOG3}, // S_BALLHOG2 - {SPR_BHOG, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_BALLHOG4}, // S_BALLHOG3 - {SPR_BHOG, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_BALLHOG5}, // S_BALLHOG4 - {SPR_BHOG, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_BALLHOG6}, // S_BALLHOG5 - {SPR_BHOG, 5, 2, {NULL}, 0, 0, S_BALLHOG7}, // S_BALLHOG6 - {SPR_BHOG, 6, 1, {NULL}, 0, 0, S_BALLHOG8}, // S_BALLHOG7 - {SPR_BHOG, 7, 1, {NULL}, 0, 0, S_BALLHOG1}, // S_BALLHOG8 - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_BALLHOG_DEAD + {SPR_BHOG, 0, 3, {A_PlaySound}, sfx_s1bd, 1, S_BALLHOG2}, // S_BALLHOG1 + {SPR_BHOG, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BALLHOG3}, // S_BALLHOG2 + {SPR_BHOG, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_BALLHOG4}, // S_BALLHOG3 + {SPR_BHOG, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_BALLHOG5}, // S_BALLHOG4 + {SPR_BHOG, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_BALLHOG6}, // S_BALLHOG5 + {SPR_BHOG, 5, 2, {NULL}, 0, 0, S_BALLHOG7}, // S_BALLHOG6 + {SPR_BHOG, 6, 1, {NULL}, 0, 0, S_BALLHOG8}, // S_BALLHOG7 + {SPR_BHOG, 7, 1, {NULL}, 0, 0, S_BALLHOG1}, // S_BALLHOG8 + {SPR_NULL, 0, 1, {A_BallhogExplode}, 0, 0, S_NULL}, // S_BALLHOG_DEAD + {SPR_BHOG, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BALLHOGBOOM2}, // S_BALLHOGBOOM1 + {SPR_BHOG, FF_FULLBRIGHT|9, 1, {NULL}, 0, 0, S_BALLHOGBOOM3}, // S_BALLHOGBOOM2 + {SPR_BHOG, FF_FULLBRIGHT|10, 1, {NULL}, 0, 0, S_BALLHOGBOOM4}, // S_BALLHOGBOOM3 + {SPR_BHOG, FF_FULLBRIGHT|11, 1, {NULL}, 0, 0, S_BALLHOGBOOM5}, // S_BALLHOGBOOM4 + {SPR_BHOG, FF_FULLBRIGHT|12, 1, {NULL}, 0, 0, S_BALLHOGBOOM6}, // S_BALLHOGBOOM5 + {SPR_BHOG, FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_BALLHOGBOOM7}, // S_BALLHOGBOOM6 + {SPR_BHOG, FF_FULLBRIGHT|14, 1, {NULL}, 0, 0, S_BALLHOGBOOM8}, // S_BALLHOGBOOM7 + {SPR_BHOG, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_BALLHOGBOOM9}, // S_BALLHOGBOOM8 + {SPR_BHOG, FF_FULLBRIGHT|16, 1, {NULL}, 0, 0, S_BALLHOGBOOM10}, // S_BALLHOGBOOM9 + {SPR_BHOG, FF_FULLBRIGHT|17, 1, {NULL}, 0, 0, S_BALLHOGBOOM11}, // S_BALLHOGBOOM10 + {SPR_BHOG, FF_FULLBRIGHT|18, 1, {NULL}, 0, 0, S_BALLHOGBOOM12}, // S_BALLHOGBOOM11 + {SPR_BHOG, FF_FULLBRIGHT|19, 1, {NULL}, 0, 0, S_BALLHOGBOOM13}, // S_BALLHOGBOOM12 + {SPR_BHOG, FF_FULLBRIGHT|20, 1, {NULL}, 0, 0, S_BALLHOGBOOM14}, // S_BALLHOGBOOM13 + {SPR_BHOG, FF_FULLBRIGHT|21, 1, {NULL}, 0, 0, S_BALLHOGBOOM15}, // S_BALLHOGBOOM14 + {SPR_BHOG, FF_FULLBRIGHT|22, 1, {NULL}, 0, 0, S_BALLHOGBOOM16}, // S_BALLHOGBOOM15 + {SPR_BHOG, FF_FULLBRIGHT|23, 1, {NULL}, 0, 0, S_NULL}, // S_BALLHOGBOOM16 {SPR_BLIG, 0, 2, {NULL}, 0, 0, S_BLUELIGHTNING2}, // S_BLUELIGHTNING1 {SPR_BLIG, 1, 2, {NULL}, 0, 0, S_BLUELIGHTNING3}, // S_BLUELIGHTNING2 @@ -14603,13 +14619,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // seestate sfx_tossed, // seesound 8, // reactiontime - sfx_mario1, // attacksound + sfx_s3k49, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_ORBINAUT_DEAD, // deathstate + S_ORBINAUT_DEAD,// deathstate S_NULL, // xdeathstate sfx_shbrk, // deathsound 64*FRACUNIT, // speed @@ -14935,7 +14951,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_BALLHOG_DEAD, // deathstate S_NULL, // xdeathstate - sfx_mario1, // deathsound + sfx_hogbom, // deathsound 0, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height @@ -14947,6 +14963,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BALLHOGBOOM + -1, // doomednum + S_BALLHOGBOOM1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags + S_NULL // raisestate + }, + { // MT_BLUELIGHTNING -1, // doomednum S_BLUELIGHTNING1, // spawnstate diff --git a/src/info.h b/src/info.h index 53552f4c..d24ba3a3 100644 --- a/src/info.h +++ b/src/info.h @@ -167,6 +167,7 @@ void A_ItemPop(); // SRB2kart void A_JawzChase(); // SRB2kart void A_JawzExplode(); // SRB2kart void A_MineExplode(); // SRB2kart +void A_BallhogExplode(); // SRB2kart void A_OrbitNights(); void A_GhostMe(); void A_SetObjectState(); @@ -3254,6 +3255,22 @@ typedef enum state S_BALLHOG7, S_BALLHOG8, S_BALLHOG_DEAD, + S_BALLHOGBOOM1, + S_BALLHOGBOOM2, + S_BALLHOGBOOM3, + S_BALLHOGBOOM4, + S_BALLHOGBOOM5, + S_BALLHOGBOOM6, + S_BALLHOGBOOM7, + S_BALLHOGBOOM8, + S_BALLHOGBOOM9, + S_BALLHOGBOOM10, + S_BALLHOGBOOM11, + S_BALLHOGBOOM12, + S_BALLHOGBOOM13, + S_BALLHOGBOOM14, + S_BALLHOGBOOM15, + S_BALLHOGBOOM16, // Self-Propelled Bomb - just an explosion for now... S_BLUELIGHTNING1, @@ -4029,6 +4046,7 @@ typedef enum mobj_type MT_BOOMPARTICLE, MT_BALLHOG, // Ballhog + MT_BALLHOGBOOM, MT_BLUELIGHTNING, // Grow/shrink stuff MT_BLUEEXPLOSION, diff --git a/src/k_kart.c b/src/k_kart.c index 8d64af57..464c4869 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2046,6 +2046,10 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle else th->color = SKINCOLOR_CLOUDY; } + else if (type == MT_JAWZ || type == MT_JAWZ_DUD) + { + S_StartSound(th, th->info->activesound); + } x = x + P_ReturnThrustX(source, an, source->radius + th->radius); y = y + P_ReturnThrustY(source, an, source->radius + th->radius); diff --git a/src/p_enemy.c b/src/p_enemy.c index 0c5f9d17..a9333777 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -191,6 +191,7 @@ void A_ItemPop(mobj_t *actor); // SRB2kart void A_JawzChase(mobj_t *actor); // SRB2kart void A_JawzExplode(mobj_t *actor); // SRB2kart void A_MineExplode(mobj_t *actor); // SRB2kart +void A_BallhogExplode(mobj_t *actor); // SRB2kart void A_OrbitNights(mobj_t *actor); void A_GhostMe(mobj_t *actor); void A_SetObjectState(mobj_t *actor); @@ -8092,7 +8093,7 @@ void A_ToggleFlameJet(mobj_t* actor) } } -//{ SRB2kart - A_ItemPop, A_JawzChase, A_JawzExplode, and A_MineExplode +//{ SRB2kart - A_ItemPop, A_JawzChase, A_JawzExplode, A_MineExplode, and A_BallhogExplode void A_ItemPop(mobj_t *actor) { mobj_t *remains; @@ -8361,6 +8362,21 @@ void A_MineExplode(mobj_t *actor) return; } + +void A_BallhogExplode(mobj_t *actor) +{ + mobj_t *mo2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_BallhogExplode", actor)) + return; +#endif + + mo2 = P_SpawnMobj(actor->x, actor->y, actor->z, MT_BALLHOGBOOM); + P_SetScale(mo2, actor->scale*2); + mo2->destscale = mo2->scale; + S_StartSound(mo2, actor->info->deathsound); + return; +} //} // Function: A_OrbitNights diff --git a/src/p_map.c b/src/p_map.c index d4ee7c90..e50fbb2c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -881,7 +881,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; if (tmthing->type == MT_BALLHOG && thing->type == MT_BALLHOG) - return true; // Fireballs don't collide with eachother + return true; // Ballhogs don't collide with eachother if (thing->player && thing->player->powers[pw_flashing]) return true; diff --git a/src/p_mobj.c b/src/p_mobj.c index 9e13db6d..d7ecbcae 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1723,14 +1723,22 @@ void P_XYMovement(mobj_t *mo) if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) P_PushableCheckBustables(mo); - //{ SRB2kart - Fireball + //{ SRB2kart - Ballhogs if (mo->type == MT_BALLHOG) { - mo->health--; - if (mo->health == 0) + if (mo->health) { - S_StartSound(mo, mo->info->deathsound); - P_SetMobjState(mo, mo->info->deathstate); + mo->health--; + if (mo->health == 0) + mo->destscale = 1; + } + else + { + if (mo->scale < mapheaderinfo[gamemap-1]->mobj_scale/16) + { + P_RemoveMobj(mo); + return; + } } } //} @@ -2336,6 +2344,7 @@ static boolean P_ZMovement(mobj_t *mo) case MT_JAWZ: case MT_JAWZ_DUD: case MT_BALLHOG: + case MT_SSMINE: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -8005,7 +8014,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->threshold > 0) mobj->threshold--; - if (leveltime % 7 == 0) + if (leveltime % TICRATE == 0) S_StartSound(mobj, mobj->info->activesound); if (gamespeed == 0) @@ -8079,7 +8088,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->threshold > 0) mobj->threshold--; - if (leveltime % 7 == 0) + if (leveltime % TICRATE == 0) S_StartSound(mobj, mobj->info->activesound); break; diff --git a/src/sounds.c b/src/sounds.c index 69fc8433..ffe0e479 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -147,9 +147,6 @@ sfxinfo_t S_sfx[NUMSFX] = {"drown", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"fizzle", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"gbeep", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Grenade beep - {"yeeeah", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"noooo1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"noooo2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"ghit" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"gloop", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"gspray", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, @@ -809,6 +806,10 @@ sfxinfo_t S_sfx[NUMSFX] = {"boing", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"smkinv", false, 140, 8, -1, NULL, 0, -1, -1, LUMPERROR}, {"screec", false, 52, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"yeeeah", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"noooo1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"noooo2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"hogbom", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // SRB2kart - Skin sounds {"kwin", false, 64, 0, -1, NULL, 0, SKSWIN, -1, LUMPERROR}, diff --git a/src/sounds.h b/src/sounds.h index 106e77df..0f8d5a3b 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -219,9 +219,6 @@ typedef enum sfx_drown, sfx_fizzle, sfx_gbeep, - sfx_yeeeah, - sfx_noooo1, - sfx_noooo2, sfx_ghit, sfx_gloop, sfx_gspray, @@ -881,6 +878,10 @@ typedef enum sfx_boing, sfx_smkinv, sfx_screec, + sfx_yeeeah, + sfx_noooo1, + sfx_noooo2, + sfx_hogbom, sfx_kwin, sfx_klose, From 0dc2c43a672b6199ac2904c2afee9e9793d40ba3 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Wed, 25 Jul 2018 12:49:30 -0400 Subject: [PATCH 07/38] Banana drag touches - Banana drag timer resets when placing one, for x3 & x10 bananas - Banana dragging spawns transulcent dust - Dragging bananas make them twitch up & down --- src/k_kart.c | 31 +++++++++++++++++++++++++------ src/k_kart.h | 2 +- src/lua_baselib.c | 3 ++- src/p_user.c | 2 +- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 464c4869..d2ded697 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2154,7 +2154,7 @@ void K_SpawnSparkleTrail(mobj_t *mo) } } -void K_SpawnWipeoutTrail(mobj_t *mo) +void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent) { mobj_t *dust; @@ -2168,6 +2168,9 @@ void K_SpawnWipeoutTrail(mobj_t *mo) dust->destscale = mo->scale; P_SetScale(dust, mo->scale); dust->eflags = (dust->eflags & ~MFE_VERTICALFLIP)|(mo->eflags & MFE_VERTICALFLIP); + + if (translucent) + dust->flags2 |= MF2_SHADOW; } // K_DriftDustHandling @@ -2280,8 +2283,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map mobj_t *mo; INT32 dir, PROJSPEED; angle_t newangle; - fixed_t newx; - fixed_t newy; + fixed_t newx, newy, newz; mobj_t *throwmo; if (!player) @@ -2393,10 +2395,13 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map { mobj_t *lasttrail = K_FindLastTrailMobj(player); + player->kartstuff[k_bananadrag] = 0; // RESET timer, for multiple bananas + if (lasttrail) { newx = lasttrail->x; newy = lasttrail->y; + newz = lasttrail->z; } else { @@ -2407,9 +2412,10 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, dropradius); newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, dropradius); + newz = player->mo->z; } - mo = P_SpawnMobj(newx, newy, player->mo->z, mapthing); + mo = P_SpawnMobj(newx, newy, newz, mapthing); if (P_MobjFlip(player->mo) < 0) mo->z = player->mo->z + player->mo->height - mo->height; @@ -2785,8 +2791,12 @@ static void K_MoveHeldObjects(player_t *player) if (P_IsObjectOnGround(player->mo) && player->speed > 0) { player->kartstuff[k_bananadrag]++; - if (player->kartstuff[k_bananadrag] > TICRATE && leveltime % 7 == 0) - S_StartSound(player->mo, sfx_cdfm70); + if (player->kartstuff[k_bananadrag] > TICRATE) + { + K_SpawnWipeoutTrail(player->mo, true); + if (leveltime % 6 == 0) + S_StartSound(player->mo, sfx_cdfm70); + } } while (cur && !P_MobjWasRemoved(cur)) @@ -2824,6 +2834,15 @@ static void K_MoveHeldObjects(player_t *player) cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy); + if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE + && P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false))/2))) + { + if (leveltime & 1) + targz += 8*(2*FRACUNIT)/7; + else + targz -= 8*(2*FRACUNIT)/7; + } + if (speed > dist) P_InstaThrust(cur, cur->angle, speed-dist); diff --git a/src/k_kart.h b/src/k_kart.h index 4a6a7e1a..9b3bdc1a 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -33,7 +33,7 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 void K_SpawnMineExplosion(mobj_t *source, UINT8 color); void K_SpawnBoostTrail(player_t *player); void K_SpawnSparkleTrail(mobj_t *mo); -void K_SpawnWipeoutTrail(mobj_t *mo); +void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent); void K_DriftDustHandling(mobj_t *spawner); void K_DoSneaker(player_t *player, boolean doPFlag); void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d86315c0..30285e0e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2135,10 +2135,11 @@ static int lib_kSpawnSparkleTrail(lua_State *L) static int lib_kSpawnWipeoutTrail(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + boolean translucent = luaL_checkboolean(L, 2); NOHUD if (!mo) return LUA_ErrInvalid(L, "mobj_t"); - K_SpawnWipeoutTrail(mo); + K_SpawnWipeoutTrail(mo, translucent); return 0; } diff --git a/src/p_user.c b/src/p_user.c index f612e81d..106b3645 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6938,7 +6938,7 @@ static void P_MovePlayer(player_t *player) K_SpawnSparkleTrail(player->mo); if (player->kartstuff[k_wipeoutslow] > 1 && (leveltime & 1)) - K_SpawnWipeoutTrail(player->mo); + K_SpawnWipeoutTrail(player->mo, false); K_DriftDustHandling(player->mo); From bd12658355098b78cc270a5e15d6f7d4ced98f88 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Wed, 25 Jul 2018 21:33:03 +0100 Subject: [PATCH 08/38] Added the ability to toggle the f-zero style elimination of last place specifically. Type `karteliminatelast off` to turn it off, and `karteliminatelast on` to... you know the rest. --- src/d_netcmd.c | 10 ++++++++++ src/d_netcmd.h | 2 ++ src/k_kart.c | 1 + src/p_inter.c | 37 ++++++++++++++++++++----------------- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e959f406..e0a31408 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -114,6 +114,7 @@ static void KartFrantic_OnChange(void); static void KartSpeed_OnChange(void); static void KartMirror_OnChange(void); static void KartComeback_OnChange(void); +static void KartEliminateLast_OnChange(void); #ifdef NETGAME_DEVMODE static void Fishcake_OnChange(void); @@ -366,6 +367,9 @@ consvar_t cv_kartmirror = {"kartmirror", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NO static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +// this might be a debug or it might be an undocumented regular feature +consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL, CV_OnOff, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; @@ -5260,3 +5264,9 @@ static void KartComeback_OnChange(void) } } } + +static void KartEliminateLast_OnChange(void) +{ + if (G_RaceGametype() && cv_karteliminatelast.value) + P_CheckRacers(); +} diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 0805a41f..009563af 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -127,6 +127,8 @@ extern consvar_t cv_kartcomeback; extern consvar_t cv_kartmirror; extern consvar_t cv_kartspeedometer; +extern consvar_t cv_karteliminatelast; + extern consvar_t cv_votetime; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugcheckpoint, cv_kartdebugshrink; diff --git a/src/k_kart.c b/src/k_kart.c index d2ded697..3b982756 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -403,6 +403,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartcomeback); CV_RegisterVar(&cv_kartmirror); CV_RegisterVar(&cv_kartspeedometer); + CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_kartdebugitem); diff --git a/src/p_inter.c b/src/p_inter.c index a0cecbb3..765c73f9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2068,29 +2068,32 @@ boolean P_CheckRacers(void) return true; } - for (j = 0; j < MAXPLAYERS; j++) + if (cv_karteliminatelast.value) { - if (!playeringame[j] || players[j].spectator) - continue; - numplayersingame++; - } - - if (numplayersingame > 1) // if there's more than one player in-game, this is safe to do - { - // check if we just got unlucky and there was only one guy who was a problem - for (j = i+1; j < MAXPLAYERS; j++) + for (j = 0; j < MAXPLAYERS; j++) { - if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives) + if (!playeringame[j] || players[j].spectator) continue; - - break; + numplayersingame++; } - if (j == MAXPLAYERS) // finish anyways, force a time over + if (numplayersingame > 1) // if there's more than one player in-game, this is safe to do { - P_DoTimeOver(&players[i]); - countdown = countdown2 = 0; - return true; + // check if we just got unlucky and there was only one guy who was a problem + for (j = i+1; j < MAXPLAYERS; j++) + { + if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives) + continue; + + break; + } + + if (j == MAXPLAYERS) // finish anyways, force a time over + { + P_DoTimeOver(&players[i]); + countdown = countdown2 = 0; + return true; + } } } From f9e5a11060c64611c4596d60a16874db3e41f522 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Thu, 26 Jul 2018 20:12:42 -0400 Subject: [PATCH 09/38] - Instashield on failed damge - Ballhog explosion separated onto another sprite - Disabled banana jitter --- src/d_player.h | 1 + src/dehacked.c | 19 ++++++++ src/info.c | 110 +++++++++++++++++++++++++++++++++++++--------- src/info.h | 21 +++++++++ src/k_kart.c | 47 +++++++++++++++++--- src/k_kart.h | 1 + src/lua_baselib.c | 11 +++++ src/p_inter.c | 9 ++-- src/p_map.c | 15 ++----- src/p_mobj.c | 14 ++++++ src/sounds.c | 2 +- 11 files changed, 208 insertions(+), 42 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index f184d4cf..7b5aeafc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -281,6 +281,7 @@ typedef enum k_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics k_voices, // Used to stop the player saying more voices than it should k_tauntvoices, // Used to specifically stop taunt voice spam + k_instashield, // Instashield no-damage animation timer k_floorboost, // Prevents Sneaker sounds for a breif duration when triggered by a floor panel k_spinouttype, // Determines whether to thrust forward or not while spinning out; 0 = move forwards, 1 = stay still diff --git a/src/dehacked.c b/src/dehacked.c index 921cc2db..03884474 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6625,6 +6625,21 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FIREDITEM3", "S_FIREDITEM4", + "S_INSTASHIELDA1", // No damage instashield effect + "S_INSTASHIELDA2", + "S_INSTASHIELDA3", + "S_INSTASHIELDA4", + "S_INSTASHIELDA5", + "S_INSTASHIELDA6", + "S_INSTASHIELDA7", + "S_INSTASHIELDB1", + "S_INSTASHIELDB2", + "S_INSTASHIELDB3", + "S_INSTASHIELDB4", + "S_INSTASHIELDB5", + "S_INSTASHIELDB6", + "S_INSTASHIELDB7", + "S_PLAYERARROW", // Above player arrow "S_PLAYERARROW_BOX", "S_PLAYERARROW_ITEM", @@ -7272,6 +7287,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FIREDITEM", + "MT_INSTASHIELDA", + "MT_INSTASHIELDB", + "MT_PLAYERARROW", "MT_PLAYERWANTED", @@ -7609,6 +7627,7 @@ static const char *const KARTSTUFF_LIST[] = { "CARDANIMATION", "VOICES", "TAUNTVOICES", + "INSTASHIELD", "FLOORBOOST", "SPINOUTTYPE", diff --git a/src/info.c b/src/info.c index 8cfea02c..41e89ae6 100644 --- a/src/info.c +++ b/src/info.c @@ -56,10 +56,10 @@ char sprnames[NUMSPRITES + 1][5] = "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", //SRB2kart Sprites "SPRG","BSPR","RNDM","RPOP","KFRE","KINV","KINF","WIPD","DRIF","DUST", - "FITM","BANA","ORBN","JAWZ","SSMN","KRBM","BHOG","BLIG","LIGH","SINK", - "SITR","KBLN","DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS", - "BUZB","CHOM","SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW", - "ARRO","ITEM","ITMI","ITMN","WANT","PBOM","VIEW" + "FITM","BANA","ORBN","JAWZ","SSMN","KRBM","BHOG","BHBM","BLIG","LIGH", + "SINK","SITR","KBLN","DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS", + "SPRS","BUZB","CHOM","SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS", + "PSHW","ISTA","ISTB","ARRO","ITEM","ITMI","ITMN","WANT","PBOM","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2734,22 +2734,22 @@ state_t states[NUMSTATES] = {SPR_BHOG, 6, 1, {NULL}, 0, 0, S_BALLHOG8}, // S_BALLHOG7 {SPR_BHOG, 7, 1, {NULL}, 0, 0, S_BALLHOG1}, // S_BALLHOG8 {SPR_NULL, 0, 1, {A_BallhogExplode}, 0, 0, S_NULL}, // S_BALLHOG_DEAD - {SPR_BHOG, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BALLHOGBOOM2}, // S_BALLHOGBOOM1 - {SPR_BHOG, FF_FULLBRIGHT|9, 1, {NULL}, 0, 0, S_BALLHOGBOOM3}, // S_BALLHOGBOOM2 - {SPR_BHOG, FF_FULLBRIGHT|10, 1, {NULL}, 0, 0, S_BALLHOGBOOM4}, // S_BALLHOGBOOM3 - {SPR_BHOG, FF_FULLBRIGHT|11, 1, {NULL}, 0, 0, S_BALLHOGBOOM5}, // S_BALLHOGBOOM4 - {SPR_BHOG, FF_FULLBRIGHT|12, 1, {NULL}, 0, 0, S_BALLHOGBOOM6}, // S_BALLHOGBOOM5 - {SPR_BHOG, FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_BALLHOGBOOM7}, // S_BALLHOGBOOM6 - {SPR_BHOG, FF_FULLBRIGHT|14, 1, {NULL}, 0, 0, S_BALLHOGBOOM8}, // S_BALLHOGBOOM7 - {SPR_BHOG, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_BALLHOGBOOM9}, // S_BALLHOGBOOM8 - {SPR_BHOG, FF_FULLBRIGHT|16, 1, {NULL}, 0, 0, S_BALLHOGBOOM10}, // S_BALLHOGBOOM9 - {SPR_BHOG, FF_FULLBRIGHT|17, 1, {NULL}, 0, 0, S_BALLHOGBOOM11}, // S_BALLHOGBOOM10 - {SPR_BHOG, FF_FULLBRIGHT|18, 1, {NULL}, 0, 0, S_BALLHOGBOOM12}, // S_BALLHOGBOOM11 - {SPR_BHOG, FF_FULLBRIGHT|19, 1, {NULL}, 0, 0, S_BALLHOGBOOM13}, // S_BALLHOGBOOM12 - {SPR_BHOG, FF_FULLBRIGHT|20, 1, {NULL}, 0, 0, S_BALLHOGBOOM14}, // S_BALLHOGBOOM13 - {SPR_BHOG, FF_FULLBRIGHT|21, 1, {NULL}, 0, 0, S_BALLHOGBOOM15}, // S_BALLHOGBOOM14 - {SPR_BHOG, FF_FULLBRIGHT|22, 1, {NULL}, 0, 0, S_BALLHOGBOOM16}, // S_BALLHOGBOOM15 - {SPR_BHOG, FF_FULLBRIGHT|23, 1, {NULL}, 0, 0, S_NULL}, // S_BALLHOGBOOM16 + {SPR_BHBM, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BALLHOGBOOM2}, // S_BALLHOGBOOM1 + {SPR_BHBM, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BALLHOGBOOM3}, // S_BALLHOGBOOM2 + {SPR_BHBM, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_BALLHOGBOOM4}, // S_BALLHOGBOOM3 + {SPR_BHBM, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_BALLHOGBOOM5}, // S_BALLHOGBOOM4 + {SPR_BHBM, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BALLHOGBOOM6}, // S_BALLHOGBOOM5 + {SPR_BHBM, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_BALLHOGBOOM7}, // S_BALLHOGBOOM6 + {SPR_BHBM, FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_BALLHOGBOOM8}, // S_BALLHOGBOOM7 + {SPR_BHBM, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_BALLHOGBOOM9}, // S_BALLHOGBOOM8 + {SPR_BHBM, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_BALLHOGBOOM10}, // S_BALLHOGBOOM9 + {SPR_BHBM, FF_FULLBRIGHT|9, 1, {NULL}, 0, 0, S_BALLHOGBOOM11}, // S_BALLHOGBOOM10 + {SPR_BHBM, FF_FULLBRIGHT|10, 1, {NULL}, 0, 0, S_BALLHOGBOOM12}, // S_BALLHOGBOOM11 + {SPR_BHBM, FF_FULLBRIGHT|11, 1, {NULL}, 0, 0, S_BALLHOGBOOM13}, // S_BALLHOGBOOM12 + {SPR_BHBM, FF_FULLBRIGHT|12, 1, {NULL}, 0, 0, S_BALLHOGBOOM14}, // S_BALLHOGBOOM13 + {SPR_BHBM, FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_BALLHOGBOOM15}, // S_BALLHOGBOOM14 + {SPR_BHBM, FF_FULLBRIGHT|14, 1, {NULL}, 0, 0, S_BALLHOGBOOM16}, // S_BALLHOGBOOM15 + {SPR_BHBM, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_NULL}, // S_BALLHOGBOOM16 {SPR_BLIG, 0, 2, {NULL}, 0, 0, S_BLUELIGHTNING2}, // S_BLUELIGHTNING1 {SPR_BLIG, 1, 2, {NULL}, 0, 0, S_BLUELIGHTNING3}, // S_BLUELIGHTNING2 @@ -2931,6 +2931,22 @@ state_t states[NUMSTATES] = {SPR_PSHW, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_FIREDITEM4}, // S_FIREDITEM3 {SPR_PSHW, FF_FULLBRIGHT|3, 3, {NULL}, 0, 0, S_NULL}, // S_FIREDITEM4 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30, 2, {NULL}, 0, 0, S_INSTASHIELDA2}, // S_INSTASHIELDA1 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|1, 2, {NULL}, 0, 0, S_INSTASHIELDA3}, // S_INSTASHIELDA2 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|2, 2, {NULL}, 0, 0, S_INSTASHIELDA4}, // S_INSTASHIELDA3 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|3, 2, {NULL}, 0, 0, S_INSTASHIELDA5}, // S_INSTASHIELDA4 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|4, 2, {NULL}, 0, 0, S_INSTASHIELDA6}, // S_INSTASHIELDA5 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|5, 2, {NULL}, 0, 0, S_INSTASHIELDA7}, // S_INSTASHIELDA6 + {SPR_ISTA, FF_FULLBRIGHT|FF_TRANS30|6, 2, {NULL}, 0, 0, S_NULL}, // S_INSTASHIELDA7 + + {SPR_ISTB, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_INSTASHIELDB2}, // S_INSTASHIELDB1 + {SPR_ISTB, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_INSTASHIELDB3}, // S_INSTASHIELDB2 + {SPR_ISTB, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_INSTASHIELDB4}, // S_INSTASHIELDB3 + {SPR_ISTB, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_INSTASHIELDB5}, // S_INSTASHIELDB4 + {SPR_ISTB, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_INSTASHIELDB6}, // S_INSTASHIELDB5 + {SPR_ISTB, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_INSTASHIELDB7}, // S_INSTASHIELDB6 + {SPR_ISTB, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_NULL}, // S_INSTASHIELDB7 + // Above player arrow {SPR_ARRO, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW {SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOX @@ -16637,6 +16653,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_INSTASHIELDA + -1, // doomednum + S_INSTASHIELDA1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_INSTASHIELDB + -1, // doomednum + S_INSTASHIELDB1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 2, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_PLAYERARROW -1, // doomednum S_PLAYERARROW, // spawnstate diff --git a/src/info.h b/src/info.h index d24ba3a3..3186fc88 100644 --- a/src/info.h +++ b/src/info.h @@ -597,6 +597,7 @@ typedef enum sprite SPR_SSMN, // SS Mine SPR_KRBM, // SS Mine BOOM SPR_BHOG, // Ballhog + SPR_BHBM, // Ballhog BOOM SPR_BLIG, // Self-Propelled Bomb SPR_LIGH, // Grow/shrink beams (Metallic Maddness) SPR_SINK, // Kitchen Sink @@ -624,6 +625,8 @@ typedef enum sprite SPR_FLEN, // Shell hit graphics stuff SPR_CLAS, // items clash SPR_PSHW, // thrown indicator + SPR_ISTA, // instashield layer A + SPR_ISTB, // instashield layer B SPR_ARRO, // player arrows SPR_ITEM, @@ -3464,6 +3467,21 @@ typedef enum state S_FIREDITEM3, S_FIREDITEM4, + S_INSTASHIELDA1, // No damage instashield effect + S_INSTASHIELDA2, + S_INSTASHIELDA3, + S_INSTASHIELDA4, + S_INSTASHIELDA5, + S_INSTASHIELDA6, + S_INSTASHIELDA7, + S_INSTASHIELDB1, + S_INSTASHIELDB2, + S_INSTASHIELDB3, + S_INSTASHIELDB4, + S_INSTASHIELDB5, + S_INSTASHIELDB6, + S_INSTASHIELDB7, + S_PLAYERARROW, // Above player arrow S_PLAYERARROW_BOX, S_PLAYERARROW_ITEM, @@ -4128,6 +4146,9 @@ typedef enum mobj_type MT_FIREDITEM, + MT_INSTASHIELDA, + MT_INSTASHIELDB, + MT_PLAYERARROW, MT_PLAYERWANTED, diff --git a/src/k_kart.c b/src/k_kart.c index 3b982756..41af9754 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1557,6 +1557,24 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove return finalspeed; } +void K_DoInstashield(player_t *player) +{ + mobj_t *layera; + mobj_t *layerb; + + if (player->kartstuff[k_instashield] > 0) + return; + + player->kartstuff[k_instashield] = 14; // length of instashield animation + S_StartSound(player->mo, sfx_cdpcm9); + + layera = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDA); + P_SetTarget(&layera->target, player->mo); + + layerb = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDB); + P_SetTarget(&layerb->target, player->mo); +} + void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem) { const UINT8 scoremultiply = ((K_IsPlayerWanted(player) && !trapitem) ? 2 : 1); @@ -1567,7 +1585,10 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0 || player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + { + K_DoInstashield(player); return; + } if (source && source != player->mo && source->player) K_PlayHitEmSound(source); @@ -1640,7 +1661,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source) if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + { + K_DoInstashield(player); return; + } player->kartstuff[k_sneakertimer] = 0; player->kartstuff[k_driftboost] = 0; @@ -1698,7 +1722,10 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0 || player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) + { + K_DoInstashield(player); return; + } player->mo->momz = 18*(mapheaderinfo[gamemap-1]->mobj_scale); player->mo->momx = player->mo->momy = 0; @@ -1772,12 +1799,15 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force) if (victim->kartstuff[k_bumper] <= 0) // || player->kartstuff[k_bumper] >= cv_kartbumpers.value+2 return; - if ((player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0 - || player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 - || (player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])) - || (victim->powers[pw_flashing] > 0 || victim->kartstuff[k_squishedtimer] > 0 || victim->kartstuff[k_spinouttimer] > 0 - || victim->kartstuff[k_invincibilitytimer] > 0 || victim->kartstuff[k_growshrinktimer] > 0 || victim->kartstuff[k_hyudorotimer] > 0)) + if (player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0) return; + + if (victim->powers[pw_flashing] > 0 || victim->kartstuff[k_squishedtimer] > 0 || victim->kartstuff[k_spinouttimer] > 0 + || victim->kartstuff[k_invincibilitytimer] > 0 || victim->kartstuff[k_growshrinktimer] > 0 || victim->kartstuff[k_hyudorotimer] > 0) + { + K_DoInstashield(victim); + return; + } } if (netgame) @@ -2835,14 +2865,14 @@ static void K_MoveHeldObjects(player_t *player) cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy); - if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE + /*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE && P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false))/2))) { if (leveltime & 1) targz += 8*(2*FRACUNIT)/7; else targz -= 8*(2*FRACUNIT)/7; - } + }*/ if (speed > dist) P_InstaThrust(cur, cur->angle, speed-dist); @@ -3036,6 +3066,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (P_IsObjectOnGround(player->mo)) player->kartstuff[k_waterskip] = 0; + if (player->kartstuff[k_instashield]) + player->kartstuff[k_instashield]--; + // ??? /* if (player->kartstuff[k_jmp] > 1 && onground) diff --git a/src/k_kart.h b/src/k_kart.h index 9b3bdc1a..c0810a86 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -25,6 +25,7 @@ void K_RespawnChecker(player_t *player); void K_KartMoveAnimation(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); +void K_DoInstashield(player_t *player); void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem); void K_SquishPlayer(player_t *player, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *source); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 30285e0e..9c5cfc4c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2038,6 +2038,16 @@ static int lib_kKartBouncing(lua_State *L) return 0; } +static int lib_kDoInstashield(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + K_DoInstashield(player); + return 0; +} + static int lib_kSpinPlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -2422,6 +2432,7 @@ static luaL_Reg lib[] = { {"K_IsPlayerLosing",lib_kIsPlayerLosing}, {"K_IsPlayerWanted",lib_kIsPlayerWanted}, {"K_KartBouncing",lib_kKartBouncing}, + {"K_DoInstashield",lib_kDoInstashield}, {"K_SpinPlayer",lib_kSpinPlayer}, {"K_SquishPlayer",lib_kSquishPlayer}, {"K_ExplodePlayer",lib_kExplodePlayer}, diff --git a/src/p_inter.c b/src/p_inter.c index 765c73f9..474cf148 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3079,7 +3079,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da #else static const boolean force = false; #endif - mobj_t *blueexplode; if (objectplacing) return false; @@ -3283,12 +3282,13 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Self-Propelled Bomb if (damage == 65) { + mobj_t *spbexplode; if (player == source->player) return false; // Just need to do this now! Being thrown upwards is done by the explosion. //P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUELIGHTNING); - blueexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); - P_SetTarget(&blueexplode->target, source); + spbexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); + P_SetTarget(&spbexplode->target, source); return true; } //} @@ -3315,7 +3315,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (damage == 10000) P_KillPlayer(player, source, damage); else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing]) + { + K_DoInstashield(player); return false; + } else { if (inflictor && (inflictor->type == MT_ORBINAUT || inflictor->type == MT_ORBINAUT_SHIELD diff --git a/src/p_map.c b/src/p_map.c index e50fbb2c..52ab6154 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1633,13 +1633,6 @@ static boolean PIT_CheckThing(mobj_t *thing) } else if (thing->player) // bounce when players collide { - const boolean tvulnerable = (!(thing->player->powers[pw_flashing] - || thing->player->kartstuff[k_invincibilitytimer] - || thing->player->kartstuff[k_spinouttimer])); - const boolean tmtvulnerable = (!(tmthing->player->powers[pw_flashing] - || tmthing->player->kartstuff[k_invincibilitytimer] - || tmthing->player->kartstuff[k_spinouttimer])); - // see if it went over / under if (tmthing->z > thing->z + thing->height) return true; // overhead @@ -1659,7 +1652,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (P_IsObjectOnGround(thing) && tmthing->momz < 0) { K_KartBouncing(tmthing, thing, true, false); - if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring] && tvulnerable) + if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring]) { K_StealBumper(tmthing->player, thing->player, false); K_SpinPlayer(thing->player, tmthing, 0, false); @@ -1668,7 +1661,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) { K_KartBouncing(thing, tmthing, true, false); - if (G_BattleGametype() && thing->player->kartstuff[k_pogospring] && tmtvulnerable) + if (G_BattleGametype() && thing->player->kartstuff[k_pogospring]) { K_StealBumper(thing->player, tmthing->player, false); K_SpinPlayer(tmthing->player, thing, 0, false); @@ -1679,12 +1672,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype()) { - if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && tmtvulnerable) + if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer])) { K_StealBumper(thing->player, tmthing->player, false); K_SpinPlayer(tmthing->player, thing, 0, false); } - else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && tvulnerable) + else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer])) { K_StealBumper(tmthing->player, thing->player, false); K_SpinPlayer(thing->player, tmthing, 0, false); diff --git a/src/p_mobj.c b/src/p_mobj.c index d7ecbcae..4ef5cff0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8200,6 +8200,20 @@ void P_MobjThinker(mobj_t *mobj) } P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); break; + case MT_INSTASHIELDB: + if (leveltime & 1) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + /* FALLTHRU */ + case MT_INSTASHIELDA: + if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield])) + { + P_RemoveMobj(mobj); + return; + } + P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + break; case MT_KARMAHITBOX: if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator || (G_RaceGametype() || mobj->target->player->kartstuff[k_bumper])) diff --git a/src/sounds.c b/src/sounds.c index ffe0e479..60cbb676 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -695,7 +695,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdpcm6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdpcm7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"cdpcm8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"cdpcm9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"cdpcm9", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // No damage taken // Knuckles Chaotix sounds {"kc2a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, From 22a87e5926bb13c2bbe89fff3ccd72552de96c38 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Fri, 27 Jul 2018 17:08:45 -0400 Subject: [PATCH 10/38] Experimental air speed cap Made very easy to revert if needed. tbh I can hardly notice it unless if I pay attention, and it most definitely never happens without Grow --- src/k_kart.c | 3 +++ src/p_user.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 41af9754..90743918 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1460,6 +1460,9 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) UINT8 kartspeed = player->kartspeed; fixed_t finalspeed; + if (doboostpower && !player->kartstuff[k_pogospring] && !P_IsObjectOnGround(player->mo)) + return (75*mapheaderinfo[gamemap-1]->mobj_scale); // air speed cap + switch (gamespeed) { case 0: diff --git a/src/p_user.c b/src/p_user.c index 106b3645..9d196268 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4901,7 +4901,7 @@ static void P_3dMovement(player_t *player) if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed) { fixed_t tempmomx, tempmomy; - if (oldMagnitude > K_GetKartSpeed(player, true)) //topspeed) + if (oldMagnitude > K_GetKartSpeed(player, true) && onground) // SRB2Kart: onground check for air speed cap { if (newMagnitude > oldMagnitude) { From ca115c1d71ad11ab50752d9ff39a78454f55933c Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Fri, 27 Jul 2018 17:22:51 -0400 Subject: [PATCH 11/38] 15 tic delay on first instashield --- src/k_kart.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 90743918..2628db2c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1568,7 +1568,7 @@ void K_DoInstashield(player_t *player) if (player->kartstuff[k_instashield] > 0) return; - player->kartstuff[k_instashield] = 14; // length of instashield animation + player->kartstuff[k_instashield] = 15; // length of instashield animation S_StartSound(player->mo, sfx_cdpcm9); layera = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDA); @@ -1651,6 +1651,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem if (player->mo->state != &states[S_KART_SPIN]) P_SetPlayerMobjState(player->mo, S_KART_SPIN); + player->kartstuff[k_instashield] = 15; return; } @@ -1712,6 +1713,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source) P_PlayRinglossSound(player->mo); + player->kartstuff[k_instashield] = 15; return; } @@ -1781,6 +1783,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju quake.time = 5; } + player->kartstuff[k_instashield] = 15; return; } @@ -1855,6 +1858,7 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force) /*victim->powers[pw_flashing] = K_GetKartFlashing(); victim->kartstuff[k_comebacktimer] = comebacktime;*/ + victim->kartstuff[k_instashield] = 15; return; } From 68aa98eb426f1ac7bec081f195ba663af959387e Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Fri, 27 Jul 2018 17:56:10 -0400 Subject: [PATCH 12/38] Better Grow odds --- src/k_kart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 2628db2c..f7288537 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -464,8 +464,8 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] = { //P-Odds 0 1 2 3 4 5 6 7 8 /*Sneaker*/ {20, 0, 0, 3, 6, 5, 0, 0, 0 }, // Sneaker - /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 3, 6, 5, 0 }, // Rocket Sneaker - /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 6, 8,16 }, // Invincibility + /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 2, 5, 4, 0 }, // Rocket Sneaker + /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 5, 6,16 }, // Invincibility /*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana /*Eggman Monitor*/ { 0, 4, 3, 2, 0, 0, 0, 0, 0 }, // Eggman Monitor /*Orbinaut*/ { 0, 6, 5, 4, 2, 0, 0, 0, 0 }, // Orbinaut @@ -473,13 +473,13 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] = /*Mine*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Mine /*Ballhog*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Ballhog /*Self-Propelled Bomb*/ { 0, 0, 1, 1, 1, 2, 2, 3, 2 }, // Self-Propelled Bomb - /*Grow*/ { 0, 0, 0, 0, 0, 0, 1, 2, 4 }, // Grow + /*Grow*/ { 0, 0, 0, 0, 0, 2, 4, 6, 4 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 1, 0 }, // Shrink /*Lightning Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Lightning Shield /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro /*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink - /*Sneaker x3*/ { 0, 0, 0, 0, 3, 7, 6, 4, 0 }, // Sneaker x3 + /*Sneaker x3*/ { 0, 0, 0, 0, 3, 6, 5, 3, 0 }, // Sneaker x3 /*Banana x3*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 /*Banana x10*/ { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10 /*Orbinaut x3*/ { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, // Orbinaut x3 From 8c8d7127f6827ceecde1c5a514982a0385c988be Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Fri, 27 Jul 2018 18:04:27 -0400 Subject: [PATCH 13/38] Actually, add another point here, too~ --- src/k_kart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index f7288537..c190deef 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -463,7 +463,7 @@ boolean K_IsPlayerWanted(player_t *player) static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] = { //P-Odds 0 1 2 3 4 5 6 7 8 - /*Sneaker*/ {20, 0, 0, 3, 6, 5, 0, 0, 0 }, // Sneaker + /*Sneaker*/ {20, 0, 0, 3, 5, 5, 0, 0, 0 }, // Sneaker /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 2, 5, 4, 0 }, // Rocket Sneaker /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 5, 6,16 }, // Invincibility /*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana @@ -473,7 +473,7 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] = /*Mine*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Mine /*Ballhog*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Ballhog /*Self-Propelled Bomb*/ { 0, 0, 1, 1, 1, 2, 2, 3, 2 }, // Self-Propelled Bomb - /*Grow*/ { 0, 0, 0, 0, 0, 2, 4, 6, 4 }, // Grow + /*Grow*/ { 0, 0, 0, 0, 1, 2, 4, 6, 4 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 1, 0 }, // Shrink /*Lightning Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Lightning Shield /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro From 25c344a6e895d0a39ca34cdcf5b73c237af2eb28 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Fri, 27 Jul 2018 21:59:00 -0400 Subject: [PATCH 14/38] A lot more safety checks on the voting screen for spectators - A new variable, voteclient.loaded, for keeping track of whenever or not voting data has been set up or not. Gets set to true in Y_StartVote, false in Y_UnloadVoteData. This is used to prevent drawing the screen in cases where it would crash, and preventing duplicate Y_EndVote calls. - The game checks for all spectator when transitioning to vote, to decide whenever or not it should skip it entirely or not. - Unrelated: made the roulette cheating much more common. Hopefully it's as cheaty as Mario Party now :p --- src/g_game.c | 15 +++++++++++++++ src/y_inter.c | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index a652e83f..fd2e92d4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3434,8 +3434,23 @@ void G_AfterIntermission(void) // void G_NextLevel(void) { + boolean dovote = false; + if ((cv_advancemap.value == 3 && gamestate != GS_VOTING) && !modeattacking && !skipstats && (multiplayer || netgame)) + { + UINT8 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + dovote = true; + break; + } + } + } + + if (dovote) gameaction = ga_startvote; else { diff --git a/src/y_inter.c b/src/y_inter.c index 4c5d9e26..65419789 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -142,6 +142,7 @@ typedef struct UINT8 roffset; UINT8 rsynctime; UINT8 rendoff; + boolean loaded; } y_voteclient; static y_votelvlinfo levelinfo[5]; @@ -954,6 +955,9 @@ void Y_VoteDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + if (!voteclient.loaded) + return; + if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), (vid.height / vid.dupy) - SHORT(widebgpatch->height), @@ -1200,8 +1204,11 @@ void Y_VoteTicker(void) if (votetic == voteendtic) { - Y_UnloadVoteData(); // Y_EndVote resets voteendtic too early apparently, causing the game to try to render patches that we just unloaded... - Y_FollowIntermission(); + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } return; } @@ -1242,14 +1249,17 @@ void Y_VoteTicker(void) if (numvotes < 1) // Whoops! Get outta here. { - Y_UnloadVoteData(); - Y_FollowIntermission(); + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } return; } voteclient.rtics--; - if (voteclient.rtics <= 0) + if (voteclient.rtics <= 0 && voteclient.loaded) { voteclient.roffset++; voteclient.rtics = min(20, (3*voteclient.roffset/4)+5); @@ -1270,7 +1280,7 @@ void Y_VoteTicker(void) if (tempvotes[((pickedvote + voteclient.roffset + i) % numvotes)] == pickedvote) { voteclient.rendoff = voteclient.roffset+i; - if (M_RandomChance(FRACUNIT/1024)) // Let it cheat occasionally~ + if (M_RandomChance(FRACUNIT/32)) // Let it cheat occasionally~ voteclient.rendoff++; S_ChangeMusicInternal("voteeb", false); break; @@ -1474,6 +1484,8 @@ void Y_StartVote(void) else levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); } + + voteclient.loaded = true; } // @@ -1493,6 +1505,8 @@ static void Y_UnloadVoteData(void) if (rendermode != render_soft) return; + voteclient.loaded = false; + UNLOAD(widebgpatch); UNLOAD(bgpatch); UNLOAD(cursor); @@ -1516,9 +1530,11 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) { if (pick == -1) // No other votes? We gotta get out of here, then! { - timer = 0; - Y_UnloadVoteData(); - Y_FollowIntermission(); + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } return; } @@ -1564,9 +1580,11 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) } else if (endtype == 0) // Might as well put this here, too. { - timer = 0; - Y_UnloadVoteData(); - Y_FollowIntermission(); + if (voteclient.loaded) + { + Y_EndVote(); + Y_FollowIntermission(); + } return; } else From 7073c9ede2a09e7dfc0208d902c3757bd6d2ff35 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Fri, 27 Jul 2018 22:16:56 -0400 Subject: [PATCH 15/38] Use joysticks 1-4 by default, restore KEY_BACKSPACE functionality These are both huge boons for gamepad functionality. If we can add a way to add a menu key, then all of the controller requirements for v1 will be covered. --- src/d_netcmd.c | 17 +++-------------- src/m_menu.c | 7 ++++--- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e0a31408..6d4aa65a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -273,26 +273,15 @@ INT32 cv_debug; consvar_t cv_usemouse = {"use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL}; -#if defined (DC) || defined (_XBOX) || defined (WMINPUT) || defined (_WII) //joystick 1 and 2 consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -#elif defined (PSP) || defined (GP2X) || defined (_NDS) //only one joystick -consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick2 = {"use_joystick2", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -#else //all esle, no joystick -consvar_t cv_usejoystick = {"use_joystick", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick2 = {"use_joystick2", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick3 = {"use_joystick3", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, +consvar_t cv_usejoystick3 = {"use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick3, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick4 = {"use_joystick4", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, +consvar_t cv_usejoystick4 = {"use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick4, 0, NULL, NULL, 0, 0, NULL}; -#endif + #if (defined (LJOYSTICK) || defined (HAVE_SDL)) #ifdef LJOYSTICK consvar_t cv_joyport = {"joyport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/m_menu.c b/src/m_menu.c index 48857e20..1ee24f47 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2687,9 +2687,10 @@ boolean M_Responder(event_t *ev) } // Why _does_ backspace go back anyway? - //currentMenu->lastOn = itemOn; - //if (currentMenu->prevMenu) - // M_SetupNextMenu(currentMenu->prevMenu); + // Sal: Because it supports gamepads better. And still makes sense for keyboard. + currentMenu->lastOn = itemOn; + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); return false; default: From a80c6ccf3977efe9d56685e2be5217e51b68f1a1 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Fri, 27 Jul 2018 22:21:13 -0400 Subject: [PATCH 16/38] Fix basenumlaps prints --- src/d_netcmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6d4aa65a..167457d1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5194,9 +5194,9 @@ static void BaseNumLaps_OnChange(void) if (gamestate == GS_LEVEL) { if (cv_basenumlaps.value) - CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n")); - else CONS_Printf(M_GetText("Number of laps will be changed to %d next round.\n"), cv_basenumlaps.value); + else + CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n")); } } From f0f9e204aa8594c751b65b9fc0bf972c11167c76 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Sat, 28 Jul 2018 02:37:00 -0400 Subject: [PATCH 17/38] Reverse gravity fixes pt 1: basic driving - Turning dust is spawned in the correct position - Turning dust sprites are flipped - Shadows display on the ceiling for flipped objects - Drift sparks display in the correct position for flipped players Will continue with item fixes tomorrow --- src/k_kart.c | 9 +++++++++ src/p_mobj.c | 22 ++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index c190deef..081a9492 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2264,6 +2264,10 @@ void K_DriftDustHandling(mobj_t *spawner) fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS; INT32 speedrange = 2; mobj_t *dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST); + if (spawner->eflags & MFE_VERTICALFLIP) + { + dust->z += spawner->height - dust->height; + } dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*FRACUNIT/4); dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*FRACUNIT/4); dust->momz = P_MobjFlip(spawner) * P_RandomRange(1, 4)<<FRACBITS; @@ -2279,6 +2283,11 @@ void K_DriftDustHandling(mobj_t *spawner) else dust->flags2 &= ~MF2_DONTDRAW; + if (spawner->eflags & MFE_VERTICALFLIP) + dust->eflags |= MFE_VERTICALFLIP; + else + dust->eflags &= ~MFE_VERTICALFLIP; + if (spawner->eflags & MFE_DRAWONLYFORP1) dust->eflags |= MFE_DRAWONLYFORP1; else diff --git a/src/p_mobj.c b/src/p_mobj.c index 4ef5cff0..9cf78ebf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6291,6 +6291,11 @@ void P_RunShadows(void) else mobj->flags2 &= ~MF2_DONTDRAW; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->eflags |= MFE_VERTICALFLIP; + else + mobj->eflags &= ~MFE_VERTICALFLIP; + if (mobj->target->eflags & MFE_DRAWONLYFORP1) // groooooaann... mobj->eflags |= MFE_DRAWONLYFORP1; else @@ -6316,12 +6321,13 @@ void P_RunShadows(void) P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); - if (mobj->floorz < mobj->z) + if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height)) + || (!(mobj->eflags & MFE_VERTICALFLIP) && (mobj->floorz < mobj->z))) { INT32 i; fixed_t prevz; - mobj->z = mobj->floorz; + mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : mobj->floorz); for (i = 0; i < MAXFFLOORS; i++) { @@ -6333,7 +6339,7 @@ void P_RunShadows(void) // Check new position to see if you should still be on that ledge P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->z); - mobj->z = mobj->floorz; + mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : mobj->floorz); if (mobj->z == prevz) break; @@ -6609,7 +6615,7 @@ void P_MobjThinker(mobj_t *mobj) { if (mobj->target && mobj->target->player && mobj->target->player->mo && mobj->target->player->health > 0 && !mobj->target->player->spectator) { - INT32 HEIGHT; + fixed_t HEIGHT; fixed_t radius; fixed_t dsone = K_GetKartDriftSparkValue(mobj->target->player); @@ -6679,15 +6685,15 @@ void P_MobjThinker(mobj_t *mobj) mobj->angle = ANGLE_180 + mobj->target->player->frameangle; // If the player is on the ceiling, then flip - if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP) + if (mobj->target->eflags & MFE_VERTICALFLIP) { mobj->eflags |= MFE_VERTICALFLIP; - HEIGHT = mobj->target->height; + HEIGHT = (16<<FRACBITS); } else { mobj->eflags &= ~MFE_VERTICALFLIP; - HEIGHT = mobj->target->height-mobj->target->height; + HEIGHT = 0; } // Shrink if the player shrunk too. @@ -6698,7 +6704,7 @@ void P_MobjThinker(mobj_t *mobj) const angle_t fa = mobj->angle>>ANGLETOFINESHIFT; mobj->x = mobj->target->x + FixedMul(finecosine[fa],radius); mobj->y = mobj->target->y + FixedMul(finesine[fa],radius); - mobj->z = mobj->target->z + HEIGHT; + mobj->z = mobj->target->z - HEIGHT; P_SetThingPosition(mobj); } } From 62c6bc0a13f3984e1da06efde55bc0ef311da475 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Sun, 29 Jul 2018 01:04:43 +0100 Subject: [PATCH 18/38] Change brightness of buffer fade in intermission (Oni-approved). --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index 65419789..a77c12a0 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -296,7 +296,7 @@ void Y_IntermissionDrawer(void) V_DrawPatchFill(bgtile); if (usebuffer) // Fade everything out - V_DrawFadeScreen(0xFF00, 16); + V_DrawFadeScreen(0xFF00, 20); if (!splitscreen) whiteplayer = demoplayback ? displayplayer : consoleplayer; From f1255730485d42f1a5b62f3a26605c65faf22d8b Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Sun, 29 Jul 2018 18:35:56 +0100 Subject: [PATCH 19/38] Some minor things to help draw sonicitems to a close. * "kartvoices" cvar. Possible values "Never", "Tasteful" (default), and "Meme". * Added a way to move quickly through the credits, rather than skip them entirely (hold spacebar or down arrow). * Fix a few mistakes in M_ChangeCvar, some of which I introduced and some of which were weird in the first place. * Tweak the offset of the arrows that let you know you can modify a cvar by pressing left or right (some via a patch.kart change, but others via tweaking the drawing location). --- src/d_netcmd.c | 2 ++ src/d_netcmd.h | 1 + src/f_finale.c | 17 ++++++++++++----- src/k_kart.c | 23 ++++++++++++++++------- src/m_menu.c | 33 ++++++++++++++++++--------------- src/p_user.c | 11 +++++++---- 6 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 167457d1..f7954747 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -355,6 +355,8 @@ consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV consvar_t cv_kartmirror = {"kartmirror", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartMirror_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}}; +consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // this might be a debug or it might be an undocumented regular feature consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL, CV_OnOff, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 009563af..371df720 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -126,6 +126,7 @@ extern consvar_t cv_kartfrantic; extern consvar_t cv_kartcomeback; extern consvar_t cv_kartmirror; extern consvar_t cv_kartspeedometer; +extern consvar_t cv_kartvoices; extern consvar_t cv_karteliminatelast; diff --git a/src/f_finale.c b/src/f_finale.c index e10ba1a6..ab79fa78 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -625,7 +625,7 @@ void F_CreditDrawer(void) y += 12<<FRACBITS; break; } - if (FixedMul(y,vid.dupy) > vid.height) + if (((y>>FRACBITS) * vid.dupy) > vid.height) break; } @@ -686,13 +686,20 @@ boolean F_CreditResponder(event_t *event) break; } - /*if (!(timesBeaten) && !(netgame || multiplayer)) - return false;*/ - if (event->type != ev_keydown) return false; - if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE) + if (key == KEY_DOWNARROW || key == KEY_SPACE) + { + if (!timetonext && !finalecount) + animtimer += 7; + return false; + } + + /*if (!(timesBeaten) && !(netgame || multiplayer)) + return false;*/ + + if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_BACKSPACE) return false; if (keypressed) diff --git a/src/k_kart.c b/src/k_kart.c index 081a9492..dc1f52ed 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -403,6 +403,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartcomeback); CV_RegisterVar(&cv_kartmirror); CV_RegisterVar(&cv_kartspeedometer); + CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_votetime); @@ -1338,18 +1339,21 @@ static void K_RegularVoiceTimers(player_t *player) static void K_PlayTauntSound(mobj_t *source) { - if (source->player && source->player->kartstuff[k_tauntvoices]) // Prevents taunt sounds from playing every time the button is pressed - return; + sfxenum_t pick = P_RandomKey(4); // Gotta roll the RNG every time this is called for sync reasons + boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]); - S_StartSound(source, sfx_taunt1+P_RandomKey(4)); + if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2)) + S_StartSound(source, sfx_taunt1+pick); + + if (!tasteful) + return; K_TauntVoiceTimers(source->player); } static void K_PlayOvertakeSound(mobj_t *source) { - if (source->player && source->player->kartstuff[k_voices]) // Prevents taunt sounds from playing every time the button is pressed - return; + boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]); if (!G_RaceGametype()) // Only in race return; @@ -1358,14 +1362,19 @@ static void K_PlayOvertakeSound(mobj_t *source) if (leveltime < starttime+(10*TICRATE)) return; - S_StartSound(source, sfx_slow); + if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2)) + S_StartSound(source, sfx_slow); + + if (!tasteful) + return; K_RegularVoiceTimers(source->player); } static void K_PlayHitEmSound(mobj_t *source) { - S_StartSound(source, sfx_hitem); + if (cv_kartvoices.value) + S_StartSound(source, sfx_hitem); K_RegularVoiceTimers(source->player); } diff --git a/src/m_menu.c b/src/m_menu.c index 1ee24f47..ce4e7486 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1337,9 +1337,10 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 70}, {IT_STRING|IT_CVAR, NULL, "Surround Sound", &surround, 80}, - {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 100}, + {IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 100}, + {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 110}, - {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 120}, + {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 130}, }; /*static menuitem_t OP_DataOptionsMenu[] = @@ -2203,29 +2204,30 @@ static void M_ChangeCvar(INT32 choice) if (cv == &cv_playercolor) { SINT8 skinno = R_SkinAvailable(cv_chooseskin.string); - if (skinno == -1) - return; - CV_SetValue(cv,skins[skinno].prefcolor); + if (skinno != -1) + CV_SetValue(cv,skins[skinno].prefcolor); + return; } - return; CV_Set(cv,cv->defaultvalue); return; } + choice = (choice<<1) - 1; + if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER) ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER) ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD)) { - CV_SetValue(cv,cv->value+(choice*2-1)); + CV_SetValue(cv,cv->value+choice); } else if (cv->flags & CV_FLOAT) { char s[20]; - sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice*2-1)*(1.0f/16.0f)); + sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f)); CV_Set(cv,s); } else - CV_AddValue(cv,choice*2-1); + CV_AddValue(cv,choice); } static boolean M_ChangeStringCvar(INT32 choice) @@ -2583,7 +2585,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef) + if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(0); } @@ -2593,7 +2595,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef) + if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(1); } @@ -2680,7 +2682,7 @@ boolean M_Responder(event_t *ev) || cv == &cv_newgametype) return true; - if (currentMenu != &OP_SoundOptionsDef) + if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(-1); return true; @@ -3127,7 +3129,7 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) if (ontop) { - V_DrawCharacter(x - 15 - (skullAnimCounter/5), y, + V_DrawCharacter(x - 16 - (skullAnimCounter/5), y, '\x1C' | highlightflags, false); // left arrow V_DrawCharacter(x+(SLIDER_RANGE*8) + 8 + (skullAnimCounter/5), y, '\x1D' | highlightflags, false); // right arrow @@ -4566,6 +4568,7 @@ static void M_DrawSkyRoom(void) break; } } + if (y) { y += currentMenu->y; @@ -4581,9 +4584,9 @@ static void M_DrawSkyRoom(void) if (lengthstring) { V_DrawCharacter(BASEVIDWIDTH - currentMenu->x - 10 - lengthstring - (skullAnimCounter/5), currentMenu->y+currentMenu->menuitems[itemOn].alphaKey, - '\x1C' | highlightflags, false); + '\x1C' | highlightflags, false); // left arrow V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y+currentMenu->menuitems[itemOn].alphaKey, - '\x1D' | highlightflags, false); + '\x1D' | highlightflags, false); // right arrow } } diff --git a/src/p_user.c b/src/p_user.c index 9d196268..f33aeffd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1708,10 +1708,13 @@ void P_DoPlayerExit(player_t *player) else if (!countdown) countdown = cv_countdowntime.value*TICRATE + 1; // Use cv_countdowntime - if (K_IsPlayerLosing(player)) - S_StartSound(player->mo, sfx_klose); - else - S_StartSound(player->mo, sfx_kwin); + if (cv_kartvoices.value) + { + if (K_IsPlayerLosing(player)) + S_StartSound(player->mo, sfx_klose); + else + S_StartSound(player->mo, sfx_kwin); + } player->exiting = 3*TICRATE; From 74e182237a49b5e2b08649fa87f2e32ed61be652 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Sun, 29 Jul 2018 15:09:20 -0400 Subject: [PATCH 20/38] Revert bad RNG --- src/k_kart.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index dc1f52ed..69d73e83 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1339,6 +1339,7 @@ static void K_RegularVoiceTimers(player_t *player) static void K_PlayTauntSound(mobj_t *source) { +#if 0 sfxenum_t pick = P_RandomKey(4); // Gotta roll the RNG every time this is called for sync reasons boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]); @@ -1349,10 +1350,19 @@ static void K_PlayTauntSound(mobj_t *source) return; K_TauntVoiceTimers(source->player); +#else + if (source->player && source->player->kartstuff[k_tauntvoices]) // Prevents taunt sounds from playing every time the button is pressed + return; + + S_StartSound(source, sfx_taunt1+P_RandomKey(4)); + + K_TauntVoiceTimers(source->player); +#endif } static void K_PlayOvertakeSound(mobj_t *source) { +#if 0 boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]); if (!G_RaceGametype()) // Only in race @@ -1369,6 +1379,21 @@ static void K_PlayOvertakeSound(mobj_t *source) return; K_RegularVoiceTimers(source->player); +#else + if (source->player && source->player->kartstuff[k_voices]) // Prevents taunt sounds from playing every time the button is pressed + return; + + if (!G_RaceGametype()) // Only in race + return; + + // 4 seconds from before race begins, 10 seconds afterwards + if (leveltime < starttime+(10*TICRATE)) + return; + + S_StartSound(source, sfx_slow); + + K_RegularVoiceTimers(source->player); +#endif } static void K_PlayHitEmSound(mobj_t *source) From 8d4fd5a1eacec477154d0c1ec11b77255d566265 Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Sun, 29 Jul 2018 15:59:35 -0400 Subject: [PATCH 21/38] sink --- src/k_kart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 69d73e83..50d03c1e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2550,6 +2550,7 @@ static void K_DoHyudoroSteal(player_t *player) INT32 playerswappable[MAXPLAYERS]; INT32 stealplayer = -1; // The player that's getting stolen from INT32 prandom = 0; + fixed_t sink = P_RandomChance(FRACUNIT/64); for (i = 0; i < MAXPLAYERS; i++) { @@ -2573,7 +2574,7 @@ static void K_DoHyudoroSteal(player_t *player) prandom = P_RandomFixed(); S_StartSound(player->mo, sfx_s3k92); - if (P_RandomChance(FRACUNIT/64)) // BEHOLD THE KITCHEN SINK + if (sink) // BEHOLD THE KITCHEN SINK { player->kartstuff[k_hyudorotimer] = hyudorotime; player->kartstuff[k_stealingtimer] = stealtime; From 0dddf7623a1afcfb8b9390a02fdbe5e9574c5a27 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Sun, 29 Jul 2018 23:07:10 +0100 Subject: [PATCH 22/38] Buggy netgame! Sorry yalls. * Fix free play on intermission. * Fix crash in killing/damaging mobj with null death/pain state. --- src/p_inter.c | 27 +++++++++++++++------------ src/y_inter.c | 21 ++------------------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 474cf148..6ca5e6c2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3492,22 +3492,25 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da break; } - target->reactiontime = 0; // we're awake now... - - if (source && source != target) + if (!P_MobjWasRemoved(target)) { - // if not intent on another player, - // chase after this one - P_SetTarget(&target->target, source); - if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) + target->reactiontime = 0; // we're awake now... + + if (source && source != target) { - if (player) + // if not intent on another player, + // chase after this one + P_SetTarget(&target->target, source); + if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); + if (player) + { + if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) + P_SetPlayerMobjState(target, target->info->seestate); + } + else + P_SetMobjState(target, target->info->seestate); } - else - P_SetMobjState(target, target->info->seestate); } } diff --git a/src/y_inter.c b/src/y_inter.c index a77c12a0..cb171ed9 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -493,25 +493,8 @@ void Y_IntermissionDrawer(void) dotimer: - if (netgame) // FREE PLAY? - { - i = MAXPLAYERS; - - if (!forcefreeplay) - { - // check to see if there's anyone else at all - for (i = 0; i < MAXPLAYERS; i++) - { - if (i == consoleplayer) - continue; - if (playeringame[i] && !stplyr->spectator) - break; - } - } - - if (i == MAXPLAYERS) - K_drawKartFreePlay(intertic); - } + if (netgame && forcefreeplay) // FREE PLAY? + K_drawKartFreePlay(intertic); if (timer) { From 65a956259b597fd15818d2b0b6b6c352df725b80 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Sun, 29 Jul 2018 23:51:08 +0100 Subject: [PATCH 23/38] * Re-enable kartvoices controls for K_PlayTauntSound and K_PlayOvertakeSound. * Make the three P_Play<?>Sounds from p_local.h actual functions that acknowledge the kartvoices cvar. --- src/k_kart.c | 4 ++-- src/p_local.h | 6 +++--- src/p_user.c | 25 +++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 50d03c1e..d546a06f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1339,7 +1339,7 @@ static void K_RegularVoiceTimers(player_t *player) static void K_PlayTauntSound(mobj_t *source) { -#if 0 +#if 1 sfxenum_t pick = P_RandomKey(4); // Gotta roll the RNG every time this is called for sync reasons boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]); @@ -1362,7 +1362,7 @@ static void K_PlayTauntSound(mobj_t *source) static void K_PlayOvertakeSound(mobj_t *source) { -#if 0 +#if 1 boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]); if (!G_RaceGametype()) // Only in race diff --git a/src/p_local.h b/src/p_local.h index 42b70543..3bf98bee 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -194,9 +194,9 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type); void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range); void P_PlayLivesJingle(player_t *player); -#define P_PlayRinglossSound(s) S_StartSound(s, (mariomode) ? sfx_mario8 : sfx_altow1 + P_RandomKey(4)); -#define P_PlayDeathSound(s) S_StartSound(s, sfx_altdi1 + P_RandomKey(4)); -#define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); +void P_PlayRinglossSound(mobj_t *source); +void P_PlayDeathSound(mobj_t *source); +void P_PlayVictorySound(mobj_t *source); // diff --git a/src/p_user.c b/src/p_user.c index f33aeffd..9ba02714 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1118,6 +1118,31 @@ void P_PlayLivesJingle(player_t *player) } } +void P_PlayRinglossSound(mobj_t *source) +{ + sfxenum_t key = P_RandomKey(4); + if (cv_kartvoices.value) + S_StartSound(source, (mariomode) ? sfx_mario8 : sfx_altow1 + key); + else + S_StartSound(source, sfx_slip); +} + +void P_PlayDeathSound(mobj_t *source) +{ + sfxenum_t key = P_RandomKey(4); + if (cv_kartvoices.value) + S_StartSound(source, sfx_altdi1 + key); + else + S_StartSound(source, sfx_s3k35); +} + +void P_PlayVictorySound(mobj_t *source) +{ + sfxenum_t key = P_RandomKey(4); + if (cv_kartvoices.value) + S_StartSound(source, sfx_victr1 + key); +} + // // P_EndingMusic // From 7f509c7c2737084dae76b39298af8d165bbe804a Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Mon, 30 Jul 2018 21:53:54 +0100 Subject: [PATCH 24/38] Some UI stuff. * Place FREE PLAY in a less contentous location. * Fix comeback timer being incorrectly offset from the center of the screen. * Prevent vote drawer from nuking itself (visual-wise) at the start of the level fade following it. --- src/k_kart.c | 25 ++++++++++++------------- src/y_inter.c | 10 +++++----- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index d546a06f..6792895a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5730,19 +5730,16 @@ static void K_drawBattleFullscreen(void) } else if (stplyr->kartstuff[k_bumper] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback) { - INT32 t = stplyr->kartstuff[k_comebacktimer]/TICRATE; - INT32 txoff = 0; + UINT16 t = stplyr->kartstuff[k_comebacktimer]/(10*TICRATE); + INT32 txoff, adjust = (splitscreen > 1) ? 4 : 6; // normal string is 8, kart string is 12, half of that for ease INT32 ty = (BASEVIDHEIGHT/2)+66; - if (t == 0) - txoff = 8; - else + txoff = adjust; + + while (t) { - while (t) - { - txoff += 8; - t /= 10; - } + txoff += adjust; + t /= 10; } if (splitscreen) @@ -5763,7 +5760,7 @@ static void K_drawBattleFullscreen(void) V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewait, NULL); if (splitscreen > 1) - V_DrawString(x-(txoff/2), ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); + V_DrawString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); else { V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutsticker, NULL); @@ -6054,11 +6051,13 @@ static void K_drawCheckpointDebugger(void) void K_drawKartFreePlay(UINT32 flashtime) { + // no splitscreen support because it's not FREE PLAY if you have more than one player in-game + if ((flashtime % TICRATE) < TICRATE/2) return; - V_DrawKartString(BASEVIDWIDTH/2 - (6*9), // horizontally centered, nice - LAPS_Y+3, V_SNAPTOBOTTOM, "FREE PLAY"); + V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy + LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY"); } void K_drawKartHUD(void) diff --git a/src/y_inter.c b/src/y_inter.c index cb171ed9..f07e8e2f 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -499,13 +499,13 @@ dotimer: if (timer) { INT32 tickdown = (timer+1)/TICRATE; - V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol|V_SNAPTOBOTTOM, + V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, va("start in %d second%s", tickdown, (tickdown == 1 ? "" : "s"))); } // Make it obvious that scrambling is happening next round. if (cv_scrambleonchange.value && cv_teamscramble.value && (intertic/TICRATE % 2 == 0)) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol|V_SNAPTOBOTTOM, M_GetText("Teams will be scrambled next round!")); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!")); } // @@ -936,11 +936,11 @@ void Y_VoteDrawer(void) if (votetic >= voteendtic && voteendtic != -1) return; - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - if (!voteclient.loaded) return; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), (vid.height / vid.dupy) - SHORT(widebgpatch->height), @@ -1138,7 +1138,7 @@ void Y_VoteDrawer(void) hilicol = V_SKYMAP; else //if (gametype == GT_MATCH) hilicol = V_REDMAP; - V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol|V_SNAPTOBOTTOM, + V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, va("Vote ends in %d second%s", tickdown, (tickdown == 1 ? "" : "s"))); } } From 057bc4120305a112ce57f4380c03ea8145feabb6 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Mon, 30 Jul 2018 22:07:28 +0100 Subject: [PATCH 25/38] Fix dropped else in tab rankings view, leading to the exiting text being drawn on top of other text for no good reason. --- src/hu_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index fd71470b..dd08d26e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1363,7 +1363,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I V_DrawRightAlignedString(x, y-4, hilicol, "FIN"); V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime)); } - if (players[tab[i].num].pflags & PF_TIMEOVER) + else if (players[tab[i].num].pflags & PF_TIMEOVER) V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "TIME OVER..."); else if (circuitmap) { From 731b05e26389bb847a9b72bd9e9971f096abc9c0 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Mon, 30 Jul 2018 23:17:01 +0100 Subject: [PATCH 26/38] More UI crap! * Fix minor additional error in tab rankings. * Remove FREE PLAY from intermission drawer, per Sal's request. * Remove "second%s" from the end of the "Start in %d"/"Vote ends in %d" string. * Rename cv_advancemap's "Off" value to "Same", to make the behaviour clearer. * Make the "Start in %d" string now begin with cv_advancemap's string (ie, "Vote in %d", "Same in %d", "Random in %d, Next in %d"... --- src/d_netcmd.c | 2 +- src/hu_stuff.c | 2 +- src/m_menu.c | 2 +- src/y_inter.c | 13 ++----------- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f7954747..78531be3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -432,7 +432,7 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {3, "Vote"}, {0, NULL}}; +static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Same"}, {1, "Next"}, {2, "Random"}, {3, "Vote"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Vote", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "All"}, {0, NULL}}; consvar_t cv_playersforexit = {"playersforexit", "One", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index dd08d26e..4122b398 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1376,7 +1376,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I #undef timestring } else - V_DrawRightAlignedString(x+rightoffset, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+rightoffset, y, 0, va("%u", tab[i].count)); y += 16; if (i == 9) diff --git a/src/m_menu.c b/src/m_menu.c index ce4e7486..63eae220 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1436,7 +1436,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 40}, {IT_STRING | IT_CVAR, NULL, "Voting Timer", &cv_votetime, 50}, - {IT_STRING | IT_CVAR, NULL, "Advance to Next Level", &cv_advancemap, 60}, + {IT_STRING | IT_CVAR, NULL, "Advance to Next Level", &cv_advancemap, 60}, #ifndef NONET {IT_STRING | IT_CVAR, NULL, "Max Player Count", &cv_maxplayers, 80}, diff --git a/src/y_inter.c b/src/y_inter.c index f07e8e2f..29c81df0 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -263,7 +263,6 @@ static void Y_CalculateMatchData(boolean rankingsmode, void (*comparison)(INT32) // void Y_IntermissionDrawer(void) { - boolean forcefreeplay = false; INT32 i, whiteplayer = MAXPLAYERS, x = 4, hilicol = V_YELLOWMAP; // fallback if (intertype == int_none || rendermode == render_none) @@ -370,11 +369,7 @@ void Y_IntermissionDrawer(void) if (data.match.rankingsmode) timeheader = "RANK"; else - { timeheader = (intertype == int_race ? "TIME" : "SCORE"); - if (data.match.numplayers <= 1) - forcefreeplay = true; - } // draw the level name V_DrawCenteredString(-4 + x + BASEVIDWIDTH/2, 20, 0, data.match.levelstring); @@ -492,15 +487,11 @@ void Y_IntermissionDrawer(void) } dotimer: - - if (netgame && forcefreeplay) // FREE PLAY? - K_drawKartFreePlay(intertic); - if (timer) { INT32 tickdown = (timer+1)/TICRATE; V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, - va("start in %d second%s", tickdown, (tickdown == 1 ? "" : "s"))); + va("%s in %d", cv_advancemap.string, tickdown)); } // Make it obvious that scrambling is happening next round. @@ -1139,7 +1130,7 @@ void Y_VoteDrawer(void) else //if (gametype == GT_MATCH) hilicol = V_REDMAP; V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, - va("Vote ends in %d second%s", tickdown, (tickdown == 1 ? "" : "s"))); + va("Vote ends in %d", tickdown)); } } From f2070ba6d1b9bb5aab42649c7cdbdc2cb2652e2f Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Mon, 30 Jul 2018 23:20:04 +0100 Subject: [PATCH 27/38] Some tidbits for countdowns. * Fix an inconsistency in timing re a time over that involves a single person (the number of tics exiting usually takes), versus a time over that involves multiple people (8*TICRATE). * Barebones preparatory work for F-Zero explosion, since I was futzing around in this already. --- src/p_user.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 9ba02714..86e404ac 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1747,8 +1747,8 @@ void P_DoPlayerExit(player_t *player) P_EndingMusic(player); // SRB2kart 120217 - if (!countdown2) - countdown2 = countdown + 8*TICRATE; + //if (!countdown2) + //countdown2 = countdown + 8*TICRATE; if (P_CheckRacers()) player->exiting = (14*TICRATE)/5 + 1; @@ -9088,6 +9088,12 @@ void P_DoTimeOver(player_t *player) player->lives = 0; P_EndingMusic(player); + +#if 0 + // sal, when you do the f-zero explosion, this is how you make sure the map doesn't end before it's done ^u^ ~toast + if (!countdown2) + countdown2 = 5*TICRATE; +#endif } // From 9109bb1ee77252410a9fc85ed1bdbaacd0f168c1 Mon Sep 17 00:00:00 2001 From: Latapostrophe <hyperclassic3@gmail.com> Date: Tue, 31 Jul 2018 23:35:16 +0200 Subject: [PATCH 28/38] Fix console leftover + positionning --- src/console.c | 16 ++++- src/hu_stuff.c | 154 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 125 insertions(+), 45 deletions(-) diff --git a/src/console.c b/src/console.c index 43d5df2d..e6ec039e 100644 --- a/src/console.c +++ b/src/console.c @@ -1037,7 +1037,17 @@ boolean CON_Responder(event_t *ev) else if (key == KEY_KPADSLASH) key = '/'; - if (shiftdown) + // capslock + if (key == KEY_CAPSLOCK) // it's a toggle. + { + if (capslock) + capslock = false; + else + capslock = true; + return true; + } + + if (capslock ^ shiftdown) // gets capslock to work because capslock is cool key = shiftxform[key]; // enter a char into the command prompt @@ -1045,7 +1055,7 @@ boolean CON_Responder(event_t *ev) return true; // even if key can't be printed, eat it anyway // add key to cmd line here - if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers + if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers key = key + 'a' - 'A'; if (input_sel != input_cur) @@ -1432,7 +1442,7 @@ static void CON_DrawHudlines(void) if (con_hudlines <= 0) return; - if (chat_on) + if (chat_on && (cv_consolechat.value || vid.width < 640)) y = charheight; // leave place for chat input in the first row of text else y = 0; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6114748b..29f9c356 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1167,7 +1167,7 @@ static UINT8 *CHAT_GetStringColormap(INT32 colorflags) // pasted from video.c, s case 2: // 0x82, yellow return yellowmap; case 3: // 0x83, lgreen - return lgreenmap; + return greenmap; case 4: // 0x84, blue return bluemap; case 5: // 0x85, red @@ -1176,6 +1176,8 @@ static UINT8 *CHAT_GetStringColormap(INT32 colorflags) // pasted from video.c, s return graymap; case 7: // 0x87, orange return orangemap; + case 8: // 0x88, sky + return skymap; default: // reset return NULL; } @@ -1235,7 +1237,9 @@ char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) return newstring; } -INT16 chatx = 160, chaty = 16; // let's use this as our coordinates, shh +// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense. + +INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh // chat stuff by VincyTM LOL XD! @@ -1243,19 +1247,75 @@ INT16 chatx = 160, chaty = 16; // let's use this as our coordinates, shh static void HU_drawMiniChat(void) { - INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; - INT32 x = chatx+2, y = chaty+2, dx = 0, dy = 0; - size_t i = 0; - for (i=0; i<chat_nummsg_min; i++) // iterate through our hot messages + if (!chat_nummsg_min) + return; // needless to say it's useless to do anything if we don't have anything to draw. + + + INT32 x = chatx+2; + INT32 charwidth = 4, charheight = 6; + INT32 dx = 0, dy = 0; + size_t i = chat_nummsg_min; + + INT32 msglines = 0; + // process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has... + + for (; i>0; i--) + { + const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); + size_t j = 0; + INT32 linescount = 0; + + while(msg[j]) // iterate through msg + { + if (msg[j] < HU_FONTSTART) // don't draw + { + if (msg[j] == '\n') // get back down. + { + ++j; + linescount += 1; + dx = 0; + continue; + } + else if (msg[j] & 0x80) // stolen from video.c, nice. + { + ++j; + continue; + } + + ++j; + } + else + { + j++; + } + + dx += charwidth; + if (dx >= cv_chatwidth.value) + { + dx = 0; + linescount += 1; + } + } + dy = 0; + dx = 0; + msglines += linescount+1; + } + + INT32 y = chaty - charheight*(msglines+1) - (cv_kartspeedometer.value ? 16 : 0); + dx = 0; + dy = 0; + i = 0; + + for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages { INT32 clrflag = 0; - INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. size_t j = 0; - const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + while(msg[j]) // iterate through msg { if (msg[j] < HU_FONTSTART) // don't draw @@ -1279,7 +1339,7 @@ static void HU_drawMiniChat(void) else { UINT8 *colormap = CHAT_GetStringColormap(clrflag); - V_DrawChatCharacter(x + dx + 2, y+dy+addy, msg[j++] |V_SNAPTOTOP|V_SNAPTORIGHT|transflag, !cv_allcaps.value, colormap); + V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); } dx += charwidth; @@ -1292,7 +1352,7 @@ static void HU_drawMiniChat(void) dy += charheight; dx = 0; } - + // decrement addy and make that shit smooth: addy /= 2; @@ -1333,25 +1393,27 @@ static void HU_DrawDownArrow(INT32 x, INT32 y, INT32 options) // HU_DrawChatLog // TODO: fix dumb word wrapping issues -static void HU_drawChatLog(void) +static void HU_drawChatLog(INT32 offset) { // before we do anything, make sure that our scroll position isn't "illegal"; if (chat_scroll > chat_maxscroll) chat_scroll = chat_maxscroll; - INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; - INT32 x = chatx+2, y = chaty+2-(chat_scroll*charheight), dx = 0, dy = 0; + INT32 charwidth = 4, charheight = 6; + INT32 x = chatx+2, y = chaty - offset*charheight - (chat_scroll*charheight) - cv_chatheight.value*charheight - 12 - (cv_kartspeedometer.value ? 16 : 0), dx = 0, dy = 0; size_t i = 0; + INT32 chat_topy = y + chat_scroll*charheight; + INT32 chat_bottomy = chat_topy + cv_chatheight.value*charheight; boolean atbottom = false; - V_DrawFillConsoleMap(chatx, chaty, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOTOP|V_SNAPTORIGHT); // INUT + V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog { INT32 clrflag = 0; size_t j = 0; - const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. + const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. while(msg[j]) // iterate through msg { if (msg[j] < HU_FONTSTART) // don't draw @@ -1374,10 +1436,10 @@ static void HU_drawChatLog(void) } else { - if ((y+dy > chaty) && (y+dy < (chaty+cv_chatheight.value*charheight))) + if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy))) { UINT8 *colormap = CHAT_GetStringColormap(clrflag); - V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOTOP|V_SNAPTORIGHT, !cv_allcaps.value, colormap); + V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap); } else j++; // don't forget to increment this or we'll get stuck in the limbo. @@ -1412,9 +1474,9 @@ static void HU_drawChatLog(void) // draw arrows to indicate that we can (or not) scroll. if (chat_scroll > 0) - HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chaty-1) : (chaty)), V_SNAPTOTOP | V_SNAPTORIGHT); + HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT); if (chat_scroll < chat_maxscroll) - HU_DrawDownArrow(chatx-8, chaty+(cv_chatheight.value*charheight)-((justscrolleddown) ? 3 : 4), V_SNAPTOTOP | V_SNAPTORIGHT); + HU_DrawDownArrow(chatx-8, chat_bottomy-((justscrolleddown) ? 3 : 4), V_SNAPTOBOTTOM | V_SNAPTOLEFT); justscrolleddown = false; justscrolledup = false; @@ -1429,8 +1491,8 @@ static void HU_drawChatLog(void) static INT16 typelines = 1; // number of drawfill lines we need. it's some weird hack and might be one frame off but I'm lazy to make another loop. static void HU_DrawChat(void) { - INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; - INT32 t = 0, c = 0, y = chaty + 4 + cv_chatheight.value*charheight; + INT32 charwidth = 4, charheight = 6; + INT32 t = 0, c = 0, y = chaty - (typelines*charheight) - (cv_kartspeedometer.value ? 16 : 0); size_t i = 0; const char *ntalk = "Say: ", *ttalk = "Team: "; const char *talk = ntalk; @@ -1446,15 +1508,14 @@ static void HU_DrawChat(void) #endif } - HU_drawChatLog(); - V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (vid.width < 640 ) ? (typelines*charheight+2) : (typelines*charheight), 239 | V_SNAPTOTOP | V_SNAPTORIGHT); + V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); while (talk[i]) { if (talk[i] < HU_FONTSTART) ++i; else - V_DrawChatCharacter(chatx + c + 2, y, talk[i++] |V_SNAPTOTOP|V_SNAPTORIGHT, !cv_allcaps.value, NULL); + V_DrawChatCharacter(chatx + c + 2, y, talk[i++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, NULL); c += charwidth; } @@ -1463,26 +1524,34 @@ static void HU_DrawChat(void) typelines = 1; if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) - V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOTOP|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); - + V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); + while (w_chat[i]) { - - if (c_input == (i+1) && hu_tick < 4) + boolean skippedline = false; + if (c_input == (i+1)) { - int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx); // we may have to go down. - int cursory = (cursorx != chatx) ? (y) : (y+charheight); - V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOTOP|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); + int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. + int cursory = (cursorx != chatx+1) ? (y) : (y+charheight); + if (hu_tick < 4) + V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); + + if (cursorx == chatx+1) // a weirdo hack + { + typelines += 1; + skippedline = true; + } + } //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) ++i; else - V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOTOP|V_SNAPTORIGHT | t, !cv_allcaps.value, NULL); + V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL); c += charwidth; - if (c > cv_chatwidth.value-charwidth) + if (c > cv_chatwidth.value-(charwidth*2) && !skippedline) { c = 0; y += charheight; @@ -1495,8 +1564,7 @@ static void HU_DrawChat(void) { i = 0; int count = 0; - INT32 p_dispy = chaty+2; - V_DrawFillConsoleMap(chatx-50, p_dispy-2, 48, 2, 239 | V_SNAPTOTOP | V_SNAPTORIGHT); // top (don't mind me) + INT32 p_dispy = chaty - charheight -1; for(i=0; (i<MAXPLAYERS); i++) { @@ -1541,22 +1609,24 @@ static void HU_DrawChat(void) } } - if ((playeringame[i])) + if (playeringame[i]) { char name[MAXPLAYERNAME+1]; strlcpy(name, player_names[i], 7); // shorten name to 7 characters. - V_DrawFillConsoleMap(chatx-50, p_dispy+ (6*count), 48, 6, 239 | V_SNAPTOTOP | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. - V_DrawSmallString(chatx-48, p_dispy+ (6*count), V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); + V_DrawFillConsoleMap(chatx+ cv_chatwidth.value + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud. + V_DrawSmallString(chatx+ cv_chatwidth.value + 4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); count++; } } if (count == 0) // no results. { - V_DrawFillConsoleMap(chatx-50, p_dispy+ (6*count), 48, 6, 239 | V_SNAPTOTOP | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. - V_DrawSmallString(chatx-48, p_dispy+ (6*count), V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE, "NO RESULT."); + V_DrawFillConsoleMap(chatx-50, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud. + V_DrawSmallString(chatx-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT."); } } + HU_drawChatLog(typelines-1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space. + } // why the fuck would you use this... @@ -1887,7 +1957,7 @@ void HU_Drawer(void) // count down the scroll timer. if (chat_scrolltime > 0) chat_scrolltime--; - if (!cv_consolechat.value) + if (!cv_consolechat.value && vid.width > 320) // don't even try using newchat sub 400p, I'm too fucking lazy HU_DrawChat(); else HU_DrawChat_Old(); // why the fuck......................... @@ -1898,7 +1968,7 @@ void HU_Drawer(void) { HU_drawMiniChat(); // draw messages in a cool fashion. chat_scrolltime = 0; // do scroll anyway. - typelines = 0; // make sure that the chat doesn't have a weird blinking huge ass square if we typed a lot last time. + typelines = 1; // make sure that the chat doesn't have a weird blinking huge ass square if we typed a lot last time. } } From ad119af07b7770ef15557ea28026deb9ddda0cef Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Thu, 2 Aug 2018 23:52:07 +0100 Subject: [PATCH 29/38] * Get chat to compile with errormode on. * Add chat options to the HUD and Sound Option menus. --- src/console.c | 8 +- src/g_game.c | 9 +- src/hu_stuff.c | 441 +++++++++++++++++++++++----------------------- src/lua_baselib.c | 1 + src/m_menu.c | 39 ++-- 5 files changed, 254 insertions(+), 244 deletions(-) diff --git a/src/console.c b/src/console.c index e6ec039e..eaa98550 100644 --- a/src/console.c +++ b/src/console.c @@ -1039,14 +1039,14 @@ boolean CON_Responder(event_t *ev) // capslock if (key == KEY_CAPSLOCK) // it's a toggle. - { + { if (capslock) capslock = false; - else + else capslock = true; return true; - } - + } + if (capslock ^ shiftdown) // gets capslock to work because capslock is cool key = shiftxform[key]; diff --git a/src/g_game.c b/src/g_game.c index 223e203d..762cac85 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -413,16 +413,17 @@ consvar_t cv_chatwidth = {"chatwidth", "150", CV_SAVE, chatwidth_cons_t, NULL, 0 // chatheight static CV_PossibleValue_t chatheight_cons_t[] = {{6, "MIN"}, {22, "MAX"}, {0, NULL}}; -consvar_t cv_chatheight= {"chatheight", "8", CV_SAVE, chatheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chatheight = {"chatheight", "8", CV_SAVE, chatheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // chat notifications (do you want to hear beeps? I'd understand if you didn't.) -consvar_t cv_chatnotifications= {"chatnotifications", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chatnotifications = {"chatnotifications", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // chat spam protection (why would you want to disable that???) -consvar_t cv_chatspamprotection= {"chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chatspamprotection = {"chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // old shit console chat. (mostly exists for stuff like terminal, not because I cared if anyone liked the old chat.) -consvar_t cv_consolechat= {"consolechat", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +//static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Box"}, {1, "Console"}, {0, NULL}}; -- for menu, but menu disabled... +consvar_t cv_consolechat = {"consolechat", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 29f9c356..dd0d61fe 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -76,7 +76,7 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; -static INT32 c_input = 0; // let's try to make the chat input less shitty. +static UINT32 c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -342,10 +342,10 @@ void HU_Start(void) static UINT32 chat_nummsg_log = 0; static UINT32 chat_nummsg_min = 0; -static UINT32 chat_scroll = 0; +static UINT32 chat_scroll = 0; static tic_t chat_scrolltime = 0; -static INT32 chat_maxscroll = 0; // how far can we scroll? +static UINT32 chat_maxscroll = 0; // how far can we scroll? //static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent. //static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool. @@ -358,12 +358,12 @@ static boolean chat_scrollmedown = false; // force instant scroll down on the ch // remove text from minichat table -static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away +static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away static void HU_removeChatText_Mini(void) { // MPC: Don't create new arrays, just iterate through an existing one - int i; + UINT32 i; for(i=0;i<chat_nummsg_min-1;i++) { strcpy(chat_mini[i], chat_mini[i+1]); chat_timers[i] = chat_timers[i+1]; @@ -379,27 +379,27 @@ static void HU_removeChatText_Mini(void) static void HU_removeChatText_Log(void) { // MPC: Don't create new arrays, just iterate through an existing one - int i; + UINT32 i; for(i=0;i<chat_nummsg_log-1;i++) { strcpy(chat_log[i], chat_log[i+1]); } chat_nummsg_log--; // lost 1 msg. } - + void HU_AddChatText(const char *text) { - + // TODO: check if we're oversaturating the log (we can only log CHAT_BUFSIZE messages.) - + if (chat_nummsg_log >= CHAT_BUFSIZE) HU_removeChatText_Log(); - + strcpy(chat_log[chat_nummsg_log], text); chat_nummsg_log++; - + if (chat_nummsg_min >= 8) HU_removeChatText_Mini(); - + strcpy(chat_mini[chat_nummsg_min], text); chat_timers[chat_nummsg_min] = TICRATE*cv_chattime.value; chat_nummsg_min++; @@ -458,7 +458,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) strlcat(msg, " ", msgspace); strlcat(msg, COM_Argv(ix + usedargs), msgspace); } - + if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm { // what we're gonna do now is check if the node exists @@ -468,30 +468,30 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) strncpy(nodenum, msg+3, 5); // check for undesirable characters in our "number" if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) - { + { // check if nodenum[1] is a space if (nodenum[1] == ' ') spc = 0; // let it slide else - { + { HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); return; - } + } } // I'm very bad at C, I swear I am, additional checks eww! if (spc != 0) - { + { if (msg[5] != ' ') { HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); return; } } - + target = atoi((const char*) nodenum); // turn that into a number //CONS_Printf("%d\n", target); - + // check for target player, if it doesn't exist then we can't send the message! if (playeringame[target]) // player exists target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work! @@ -502,7 +502,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) } buf[0] = target; const char *newmsg = msg+5+spc; - memcpy(msg, newmsg, 255); + memcpy(msg, newmsg, 252); } SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf); @@ -602,7 +602,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) char *msg; boolean action = false; char *ptr; - + CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]); target = READSINT8(*p); @@ -647,31 +647,31 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } } } - + int spam_eatmsg = 0; - + // before we do anything, let's verify the guy isn't spamming, get this easier on us. - + //if (stop_spamming_you_cunt[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) if (stop_spamming_you_cunt[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY)) - { + { CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); stop_spamming_you_cunt[playernum] = 4; spam_eatmsg = 1; } else stop_spamming_you_cunt[playernum] = 4; // you can hold off for 4 tics, can you? - + // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. - + #ifdef HAVE_BLUA if (LUAh_PlayerMsg(playernum, target, flags, msg, spam_eatmsg)) return; #endif - + if (spam_eatmsg) return; // don't proceed if we were supposed to eat the message. - + // If it's a CSAY, just CECHO and be done with it. if (flags & HU_CSAY) { @@ -713,18 +713,18 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) { const char *prefix = "", *cstart = "", *cend = "", *adminchar = "\x82~\x83", *remotechar = "\x82@\x83", *fmt, *fmt2; char *tempchar = NULL; - + // In CTF and team match, color the player's name. if (G_GametypeHasTeams()) { cend = ""; - if (players[playernum].ctfteam == 1) // red - cstart = "\x85"; + if (players[playernum].ctfteam == 1) // red + cstart = "\x85"; else if (players[playernum].ctfteam == 2) // blue cstart = "\x84"; - + } - + // player is a spectator? if (players[playernum].spectator) cstart = "\x86"; // grey name @@ -749,15 +749,15 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // name, color end, and the message itself. // '\4' makes the message yellow and beeps; '\3' just beeps. if (action) - { + { fmt = "\3* %s%s%s%s \x82%s\n"; // don't make /me yellow, yellow will be for mentions and PMs! fmt2 = "* %s%s%s%s \x82%s"; - } + } else if (target == 0) // To everyone { fmt = "\3%s\x83<%s%s%s\x83>\x80 %s\n"; fmt2 = "%s\x83<%s%s%s\x83>\x80 %s"; - } + } else if (target-1 == consoleplayer) // To you { prefix = "\x82[PM]"; @@ -775,35 +775,35 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) cstart = "\x82"; fmt = "\4%s<%s%s>%s\x80 %s\n"; // make this yellow, however. fmt2 = "%s<%s%s>%s\x80 %s"; - + } else // To your team { - if (players[playernum].ctfteam == 1) // red - prefix = "\x85[TEAM]"; + if (players[playernum].ctfteam == 1) // red + prefix = "\x85[TEAM]"; else if (players[playernum].ctfteam == 2) // blue prefix = "\x84[TEAM]"; else prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes - + fmt = "\3%s<%s%s>\x80%s %s\n"; fmt2 = "%s<%s%s>\x80%s %s"; - - } - + + } + if (cv_consolechat.value) - { - CONS_Printf(fmt, prefix, cstart, dispname, cend, msg); + { + CONS_Printf(fmt, prefix, cstart, dispname, cend, msg); HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); // add it reguardless, in case we decide to change our mind about our chat type. - } + } else - { + { HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); CON_LogMessage(va(fmt, prefix, cstart, dispname, cend, msg)); // save to log.txt if (cv_chatnotifications.value) S_StartSound(NULL, sfx_radio); - } - + } + if (tempchar) Z_Free(tempchar); } @@ -834,12 +834,12 @@ static inline boolean HU_keyInChatString(char *s, char ch) { s[l++] = ch; s[l]=0; - } + } else - { - + { + // move everything past c_input for new characters: - INT32 m = HU_MAXMSGLEN-1; + UINT32 m = HU_MAXMSGLEN-1; for (;(m>=c_input);m--) { if (s[m]) @@ -859,16 +859,16 @@ static inline boolean HU_keyInChatString(char *s, char ch) size_t i = c_input; if (!s[i-1]) return false; - + if (i >= strlen(s)-1) - { + { s[strlen(s)-1] = 0; c_input--; return false; - } - + } + for (; (i < HU_MAXMSGLEN); i++) - { + { s[i-1] = s[i]; } c_input--; @@ -901,7 +901,7 @@ static boolean teamtalk = false; // // -static void HU_queueChatChar(char c) +static void HU_queueChatChar(INT32 c) { // send automaticly the message (no more chat char) if (c == KEY_ENTER) @@ -917,59 +917,59 @@ static void HU_queueChatChar(char c) size_t i = 0; for (;(i<HU_MAXMSGLEN);i++) w_chat[i] = 0; // reset this. - + c_input = 0; - + // last minute mute check if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) { HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85")); return; } - + INT32 target = 0; - + if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm { // what we're gonna do now is check if the node exists // with that logic, characters 4 and 5 are our numbers: - + // teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko. if (teamtalk) { HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85")); return; - } - + } + int spc = 1; // used if nodenum[1] is a space. char *nodenum = (char*) malloc(3); strncpy(nodenum, msg+3, 5); // check for undesirable characters in our "number" if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) - { + { // check if nodenum[1] is a space if (nodenum[1] == ' ') spc = 0; // let it slide else - { + { HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); return; - } + } } // I'm very bad at C, I swear I am, additional checks eww! if (spc != 0) - { + { if (msg[5] != ' ') { HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'."); return; } } - + target = atoi((const char*) nodenum); // turn that into a number //CONS_Printf("%d\n", target); - + // check for target player, if it doesn't exist then we can't send the message! if (playeringame[target]) // player exists target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work! @@ -981,14 +981,14 @@ static void HU_queueChatChar(char c) // we need to get rid of the /pm<node> const char *newmsg = msg+5+spc; memcpy(msg, newmsg, 255); - } + } if (ci > 3) // don't send target+flags+empty message. { if (teamtalk) buf[0] = -1; // target else buf[0] = target; - + buf[1] = 0; // flags SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); } @@ -1013,13 +1013,13 @@ static boolean justscrolledup; // boolean HU_Responder(event_t *ev) { - UINT8 c=0; - + INT32 c=0; + if (ev->type != ev_keydown) return false; // only KeyDown events now... - + if (!chat_on) { // enter chat mode @@ -1048,7 +1048,7 @@ boolean HU_Responder(event_t *ev) } else // if chat_on { - + // Ignore modifier keys // Note that we do this here so users can still set // their chat keys to one of these, if they so desire. @@ -1057,39 +1057,39 @@ boolean HU_Responder(event_t *ev) || ev->data1 == KEY_LALT || ev->data1 == KEY_RALT) return true; - c = (UINT8)ev->data1; - + c = (INT32)ev->data1; + // capslock if (c && c == KEY_CAPSLOCK) // it's a toggle. - { + { if (capslock) capslock = false; - else + else capslock = true; return true; - } - - // use console translations + } + + // use console translations if (shiftdown ^ capslock) c = shiftxform[c]; - + // TODO: make chat behave like the console, so that we can go back and edit stuff when we fuck up. - + // pasting. pasting is cool. chat is a bit limited, though :( if ((c == 'v' || c == 'V') && ctrldown) { const char *paste = I_ClipboardPaste(); - + // create a dummy string real quickly - + if (paste == NULL) return true; - + size_t chatlen = strlen(w_chat); size_t pastelen = strlen(paste); if (chatlen+pastelen > HU_MAXMSGLEN) return true; // we can't paste this!! - + if (c_input >= strlen(w_chat)) // add it at the end of the string. { memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that. @@ -1102,43 +1102,43 @@ boolean HU_Responder(event_t *ev) return true; } else // otherwise, we need to shift everything and make space, etc etc - { + { size_t i = HU_MAXMSGLEN-1; for (; i>=c_input;i--) { if (w_chat[i]) w_chat[i+pastelen] = w_chat[i]; - + } memcpy(&w_chat[c_input], paste, pastelen); // copy all of that. c_input += pastelen; return true; } } - + if (HU_keyInChatString(w_chat,c)) - { + { HU_queueChatChar(c); - } + } if (c == KEY_ENTER) - { + { chat_on = false; c_input = 0; // reset input cursor chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :) - } + } else if (c == KEY_ESCAPE) - { + { chat_on = false; c_input = 0; // reset input cursor - } + } else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0) // CHAT SCROLLING YAYS! { chat_scroll--; justscrolledup = true; chat_scrolltime = 4; - } + } else if ((c == KEY_DOWNARROW || c == KEY_MOUSEWHEELDOWN) && chat_scroll < chat_maxscroll && chat_maxscroll > 0) - { + { chat_scroll++; justscrolleddown = true; chat_scrolltime = 4; @@ -1146,7 +1146,7 @@ boolean HU_Responder(event_t *ev) else if (c == KEY_LEFTARROW && c_input != 0) // i said go back c_input--; else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat)) - c_input++; + c_input++; return true; } return false; @@ -1187,7 +1187,7 @@ static UINT8 *CHAT_GetStringColormap(INT32 colorflags) // pasted from video.c, s // This is a muuuch better method than V_WORDWRAP. // again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day. // this one is simplified for the chat drawer. -char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) +static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) { int c; size_t chw, i, lastusablespace = 0; @@ -1229,7 +1229,7 @@ char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) { //CONS_Printf("Wrap at index %d\n", i); newstring[lastusablespace] = '\n'; - i = lastusablespace+1; + i = lastusablespace+1; lastusablespace = 0; x = 0; } @@ -1247,29 +1247,27 @@ INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh static void HU_drawMiniChat(void) { - if (!chat_nummsg_min) return; // needless to say it's useless to do anything if we don't have anything to draw. - - - INT32 x = chatx+2; - INT32 charwidth = 4, charheight = 6; + + INT32 x = chatx+2; + INT32 charwidth = 4, charheight = 6; INT32 dx = 0, dy = 0; size_t i = chat_nummsg_min; - + INT32 msglines = 0; // process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has... - + for (; i>0; i--) - { + { const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); size_t j = 0; INT32 linescount = 0; - + while(msg[j]) // iterate through msg - { + { if (msg[j] < HU_FONTSTART) // don't draw - { + { if (msg[j] == '\n') // get back down. { ++j; @@ -1282,14 +1280,14 @@ static void HU_drawMiniChat(void) ++j; continue; } - - ++j; + + ++j; } else { j++; } - + dx += charwidth; if (dx >= cv_chatwidth.value) { @@ -1301,25 +1299,24 @@ static void HU_drawMiniChat(void) dx = 0; msglines += linescount+1; } - + INT32 y = chaty - charheight*(msglines+1) - (cv_kartspeedometer.value ? 16 : 0); - dx = 0; + dx = 0; dy = 0; i = 0; - + for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages { - INT32 clrflag = 0; - INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... + INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. size_t j = 0; const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. - + while(msg[j]) // iterate through msg - { + { if (msg[j] < HU_FONTSTART) // don't draw - { + { if (msg[j] == '\n') // get back down. { ++j; @@ -1333,15 +1330,15 @@ static void HU_drawMiniChat(void) ++j; continue; } - - ++j; + + ++j; } else { UINT8 *colormap = CHAT_GetStringColormap(clrflag); V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); } - + dx += charwidth; if (dx >= cv_chatwidth.value) { @@ -1352,10 +1349,10 @@ static void HU_drawMiniChat(void) dy += charheight; dx = 0; } - + // decrement addy and make that shit smooth: addy /= 2; - + } // HU_DrawUpArrow @@ -1367,7 +1364,7 @@ static void HU_DrawUpArrow(INT32 x, INT32 y, INT32 options) V_DrawFill(x+2, y, 1, 1, 103|options); V_DrawFill(x+1, y+1, 3, 1, 103|options); V_DrawFill(x, y+2, 5, 1, 103|options); // that's the yellow part, I swear - + V_DrawFill(x+3, y, 1, 1, 26|options); V_DrawFill(x+4, y+1, 1, 1, 26|options); V_DrawFill(x+5, y+2, 1, 1, 26|options); @@ -1384,40 +1381,40 @@ static void HU_DrawDownArrow(INT32 x, INT32 y, INT32 options) V_DrawFill(x, y+1, 5, 1, 26|options); V_DrawFill(x+1, y+2, 3, 1, 26|options); V_DrawFill(x+2, y+3, 1, 1, 26|options); // that's the black part. no racism intended. i swear. - + V_DrawFill(x, y, 5, 1, 103|options); V_DrawFill(x+1, y+1, 3, 1, 103|options); V_DrawFill(x+2, y+2, 1, 1, 103|options); // that's the yellow part, I swear -} +} // HU_DrawChatLog // TODO: fix dumb word wrapping issues static void HU_drawChatLog(INT32 offset) { - + // before we do anything, make sure that our scroll position isn't "illegal"; if (chat_scroll > chat_maxscroll) chat_scroll = chat_maxscroll; - + INT32 charwidth = 4, charheight = 6; INT32 x = chatx+2, y = chaty - offset*charheight - (chat_scroll*charheight) - cv_chatheight.value*charheight - 12 - (cv_kartspeedometer.value ? 16 : 0), dx = 0, dy = 0; - size_t i = 0; + UINT32 i = 0; INT32 chat_topy = y + chat_scroll*charheight; INT32 chat_bottomy = chat_topy + cv_chatheight.value*charheight; boolean atbottom = false; - + V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box - + for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog { INT32 clrflag = 0; - size_t j = 0; + INT32 j = 0; const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. while(msg[j]) // iterate through msg - { + { if (msg[j] < HU_FONTSTART) // don't draw - { + { if (msg[j] == '\n') // get back down. { ++j; @@ -1431,20 +1428,20 @@ static void HU_drawChatLog(INT32 offset) ++j; continue; } - - ++j; + + ++j; } else { if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy))) - { + { UINT8 *colormap = CHAT_GetStringColormap(clrflag); V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap); } else j++; // don't forget to increment this or we'll get stuck in the limbo. } - + dx += charwidth; if (dx >= cv_chatwidth.value-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! { @@ -1455,32 +1452,34 @@ static void HU_drawChatLog(INT32 offset) dy += charheight; dx = 0; } - + if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling. { atbottom = true; // we should scroll } chat_scrollmedown = false; - + // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P - chat_maxscroll = (dy/charheight)-cv_chatheight.value; // welcome to C, we don't know what min() and max() are. - if (chat_maxscroll < 0) + chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are. + if (chat_maxscroll <= (UINT32)cv_chatheight.value) chat_maxscroll = 0; - + else + chat_maxscroll -= cv_chatheight.value; + // if we're not bound by the time, autoscroll for next frame: if (atbottom) chat_scroll = chat_maxscroll; - + // draw arrows to indicate that we can (or not) scroll. - + if (chat_scroll > 0) HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT); if (chat_scroll < chat_maxscroll) HU_DrawDownArrow(chatx-8, chat_bottomy-((justscrolleddown) ? 3 : 4), V_SNAPTOBOTTOM | V_SNAPTOLEFT); - + justscrolleddown = false; justscrolledup = false; -} +} // // HU_DrawChat @@ -1490,13 +1489,13 @@ static void HU_drawChatLog(INT32 offset) static INT16 typelines = 1; // number of drawfill lines we need. it's some weird hack and might be one frame off but I'm lazy to make another loop. static void HU_DrawChat(void) -{ +{ INT32 charwidth = 4, charheight = 6; INT32 t = 0, c = 0, y = chaty - (typelines*charheight) - (cv_kartspeedometer.value ? 16 : 0); - size_t i = 0; + UINT32 i = 0; const char *ntalk = "Say: ", *ttalk = "Team: "; const char *talk = ntalk; - + if (teamtalk) { talk = ttalk; @@ -1507,9 +1506,9 @@ static void HU_DrawChat(void) t = 0x400; // Blue #endif } - + V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); - + while (talk[i]) { if (talk[i] < HU_FONTSTART) @@ -1519,13 +1518,13 @@ static void HU_DrawChat(void) c += charwidth; } - + i = 0; typelines = 1; - + if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); - + while (w_chat[i]) { boolean skippedline = false; @@ -1534,16 +1533,16 @@ static void HU_DrawChat(void) int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. int cursory = (cursorx != chatx+1) ? (y) : (y+charheight); if (hu_tick < 4) - V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); - + V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); + if (cursorx == chatx+1) // a weirdo hack { typelines += 1; skippedline = true; - } - - } - + } + + } + //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) ++i; @@ -1561,56 +1560,56 @@ static void HU_DrawChat(void) // handle /pm list. if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai - { + { i = 0; - int count = 0; + INT32 count = 0; INT32 p_dispy = chaty - charheight -1; for(i=0; (i<MAXPLAYERS); i++) { - + // filter: (code needs optimization pls help I'm bad with C) if (w_chat[3]) { - + // right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!) if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' ')) break; - - + + char *nodenum = (char*) malloc(3); strncpy(nodenum, w_chat+3, 4); - INT32 n = atoi((const char*) nodenum); // turn that into a number + UINT32 n = atoi((const char*) nodenum); // turn that into a number // special cases: - + if ((n == 0) && !(w_chat[4] == '0')) - { + { if (!(i<10)) - continue; + continue; } else if ((n == 1) && !(w_chat[3] == '0')) - { + { if (!((i == 1) || ((i >= 10) && (i <= 19)))) continue; } else if ((n == 2) && !(w_chat[3] == '0')) - { + { if (!((i == 2) || ((i >= 20) && (i <= 29)))) continue; } else if ((n == 3) && !(w_chat[3] == '0')) - { + { if (!((i == 3) || ((i >= 30) && (i <= 31)))) continue; } else // general case. - { + { if (i != n) continue; } } - + if (playeringame[i]) - { + { char name[MAXPLAYERNAME+1]; strlcpy(name, player_names[i], 7); // shorten name to 7 characters. V_DrawFillConsoleMap(chatx+ cv_chatwidth.value + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud. @@ -1622,11 +1621,11 @@ static void HU_DrawChat(void) { V_DrawFillConsoleMap(chatx-50, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud. V_DrawSmallString(chatx-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT."); - } + } } - + HU_drawChatLog(typelines-1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space. - + } // why the fuck would you use this... @@ -1664,21 +1663,21 @@ static void HU_DrawChat_Old(void) } c += charwidth; } - + if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); - + i = 0; while (w_chat[i]) { - + if (c_input == (i+1) && hu_tick < 4) { int cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. int cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight); - V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); - } - + V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); + } + //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) { @@ -1953,8 +1952,8 @@ void HU_Drawer(void) { // draw chat string plus cursor if (chat_on) - { - // count down the scroll timer. + { + // count down the scroll timer. if (chat_scrolltime > 0) chat_scrolltime--; if (!cv_consolechat.value && vid.width > 320) // don't even try using newchat sub 400p, I'm too fucking lazy @@ -1965,27 +1964,27 @@ void HU_Drawer(void) else { if (!cv_consolechat.value) - { + { HU_drawMiniChat(); // draw messages in a cool fashion. chat_scrolltime = 0; // do scroll anyway. typelines = 1; // make sure that the chat doesn't have a weird blinking huge ass square if we typed a lot last time. - } + } } - + if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh) { size_t i = 0; - + // handle spam while we're at it: for(; (i<MAXPLAYERS); i++) - { + { if (stop_spamming_you_cunt[i] > 0) stop_spamming_you_cunt[i]--; - } - + } + // handle chat timers for (i=0; (i<chat_nummsg_min); i++) - { + { if (chat_timers[i] > 0) chat_timers[i]--; else @@ -2036,7 +2035,7 @@ void HU_Drawer(void) if (cv_crosshair2.value && !camera2.chase && !players[secondarydisplayplayer].spectator) HU_DrawCrosshair2(); - + if (cv_crosshair3.value && !camera3.chase && !players[thirddisplayplayer].spectator) HU_DrawCrosshair3(); @@ -2145,29 +2144,29 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) SINT8 i = 0; SINT8 yoffset = 6; if (ping < 128) - { + { numbars = 3; barcolor = 184; - } + } else if (ping < 256) - { + { numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it. barcolor = 103; - } - + } + INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2); if (!notext || vid.width >= 640) // how sad, we're using a shit resolution. V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping)); - + for (i=0; (i<3); i++) // Draw the ping bar - { + { V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31); if (i < numbars) V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor); - + yoffset -= 2; } -} +} // // HU_DrawTabRankings @@ -2192,13 +2191,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I { if (players[tab[i].num].spectator || !players[tab[i].num].mo) continue; //ignore them. - + if (!splitscreen) // don't draw it on splitscreen, { if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 253, y+2, playerpingtable[tab[i].num], false); - } - + } + V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? hilicol|V_ALLOWLOWERCASE @@ -2332,10 +2331,10 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } V_DrawRightAlignedThinString(x+120, y-1, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); if (!splitscreen) - { + { if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false); - } + } } } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 587f9514..068ae204 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -20,6 +20,7 @@ #include "m_random.h" #include "s_sound.h" #include "g_game.h" +#include "hu_stuff.h" #include "k_kart.h" #include "lua_script.h" diff --git a/src/m_menu.c b/src/m_menu.c index 63eae220..4428ab3a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1047,7 +1047,7 @@ static menuitem_t OP_MainMenu[] = {IT_SUBMENU|IT_STRING, NULL, "Video Options...", &OP_VideoOptionsDef, 30}, {IT_SUBMENU|IT_STRING, NULL, "Sound Options...", &OP_SoundOptionsDef, 40}, - {IT_SUBMENU|IT_STRING, NULL, "HUD Options...", &OP_HUDOptionsDef, 60}, + {IT_SUBMENU|IT_STRING, NULL, "HUD Options...", &OP_HUDOptionsDef, 60}, {IT_STRING|IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 70}, {IT_SUBMENU|IT_STRING, NULL, "Gameplay Options...", &OP_GameOptionsDef, 90}, @@ -1334,13 +1334,14 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CALL, NULL, "Restart Audio System", M_RestartAudio, 50}, - {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 70}, - {IT_STRING|IT_CVAR, NULL, "Surround Sound", &surround, 80}, + {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 65}, + {IT_STRING|IT_CVAR, NULL, "Surround Sound", &surround, 75}, + {IT_STRING|IT_CVAR, NULL, "Chat sounds", &cv_chatnotifications, 90}, {IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 100}, {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 110}, - {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 130}, + {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 125}, }; /*static menuitem_t OP_DataOptionsMenu[] = @@ -1393,19 +1394,27 @@ static menuitem_t OP_EraseDataMenu[] = static menuitem_t OP_HUDOptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 10}, + {IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 10}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "HUD Visibility", &cv_translucenthud, 20}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Minimap Visibility", &cv_kartminimap, 40}, - {IT_STRING | IT_CVAR, NULL, "Speedometer Display", &cv_kartspeedometer, 50}, - {IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", &cv_kartcheck, 60}, + NULL, "Minimap Visibility", &cv_kartminimap, 35}, + {IT_STRING | IT_CVAR, NULL, "Speedometer Display", &cv_kartspeedometer, 45}, + {IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", &cv_kartcheck, 55}, - {IT_STRING | IT_CVAR, NULL, "Console Color", &cons_backcolor, 80}, - {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 90}, + {IT_STRING | IT_CVAR, NULL, "Menu Highlights", &cons_menuhighlight, 70}, + // highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 80 (see M_DrawHUDOptions) - {IT_STRING | IT_CVAR, NULL, "Menu Highlights", &cons_menuhighlight, 110}, + //{IT_STRING | IT_CVAR, NULL, "Chat mode", &cv_consolechat, 95}, -- will ANYONE who doesn't know how to use the console want to touch this + {IT_STRING | IT_CVAR | IT_CV_SLIDER, + NULL, "Chat box width", &cv_chatwidth, 95}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, + NULL, "Chat box height", &cv_chatheight, 105}, + {IT_STRING | IT_CVAR, NULL, "Chat fadeout time", &cv_chattime, 115}, + + {IT_STRING | IT_CVAR, NULL, "Background Color", &cons_backcolor, 130}, + {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 140}, }; static menuitem_t OP_GameOptionsMenu[] = @@ -1420,7 +1429,7 @@ static menuitem_t OP_GameOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", &cv_countdowntime, 80}, //{IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 100}, - {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 100}, + {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 100}, {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 110}, {IT_STRING | IT_CVAR, NULL, "Force Character #", &cv_forceskin, 130}, @@ -1440,10 +1449,10 @@ static menuitem_t OP_ServerOptionsMenu[] = #ifndef NONET {IT_STRING | IT_CVAR, NULL, "Max Player Count", &cv_maxplayers, 80}, - {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 90}, + {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 90}, //{IT_STRING | IT_CVAR, NULL, "Join on Map Change", &cv_joinnextround, 100}, - {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 100}, + {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 100}, {IT_STRING | IT_CVAR, NULL, "Attempts to Resynch", &cv_resynchattempts, 110}, #endif }; @@ -8364,7 +8373,7 @@ static void M_DrawHUDOptions(void) const char *str1 = " Warning highlight"; const char *str2 = ","; const char *str3 = "Good highlight"; - INT32 x = BASEVIDWIDTH - currentMenu->x + 2, y = currentMenu->y + 120; + INT32 x = BASEVIDWIDTH - currentMenu->x + 2, y = currentMenu->y + 80; INT32 w0 = V_StringWidth(str0, 0), w1 = V_StringWidth(str1, 0), w2 = V_StringWidth(str2, 0), w3 = V_StringWidth(str3, 0); M_DrawGenericMenu(); x -= w0; From b319c2d9b848bfcf5fa83d4ac6ce2dd221a4d58f Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Fri, 3 Aug 2018 23:01:09 +0100 Subject: [PATCH 30/38] * Homogenise old chat mode detection, which includes `cv_consolechat.value`, `dedicated`, and `vid.width < 640`. * Make the chat notification sounds work in old chat mode. --- src/console.c | 2 +- src/hu_stuff.c | 26 ++++++++++---------------- src/hu_stuff.h | 2 ++ src/lua_baselib.c | 19 +++++++++++++------ 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/console.c b/src/console.c index eaa98550..212e6c8d 100644 --- a/src/console.c +++ b/src/console.c @@ -1442,7 +1442,7 @@ static void CON_DrawHudlines(void) if (con_hudlines <= 0) return; - if (chat_on && (cv_consolechat.value || vid.width < 640)) + if (chat_on && OLDCHAT) y = charheight; // leave place for chat input in the first row of text else y = 0; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index dd0d61fe..338fd26c 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -388,6 +388,8 @@ static void HU_removeChatText_Log(void) void HU_AddChatText(const char *text) { + if (cv_chatnotifications.value) + S_StartSound(NULL, sfx_radio); // TODO: check if we're oversaturating the log (we can only log CHAT_BUFSIZE messages.) @@ -791,18 +793,12 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } - if (cv_consolechat.value) - { + HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); // add it reguardless, in case we decide to change our mind about our chat type. + + if OLDCHAT CONS_Printf(fmt, prefix, cstart, dispname, cend, msg); - HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); // add it reguardless, in case we decide to change our mind about our chat type. - } else - { - HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); - CON_LogMessage(va(fmt, prefix, cstart, dispname, cend, msg)); // save to log.txt - if (cv_chatnotifications.value) - S_StartSound(NULL, sfx_radio); - } + CON_LogMessage(va(fmt, prefix, cstart, dispname, cend, msg)); // save to log.txt if (tempchar) Z_Free(tempchar); @@ -1956,19 +1952,17 @@ void HU_Drawer(void) // count down the scroll timer. if (chat_scrolltime > 0) chat_scrolltime--; - if (!cv_consolechat.value && vid.width > 320) // don't even try using newchat sub 400p, I'm too fucking lazy + if (!OLDCHAT) HU_DrawChat(); else HU_DrawChat_Old(); // why the fuck......................... } else { - if (!cv_consolechat.value) - { + chat_scrolltime = 0; // do scroll anyway. + typelines = 1; // make sure that the chat doesn't have a weird blinking huge ass square if we typed a lot last time. + if (!OLDCHAT) HU_drawMiniChat(); // draw messages in a cool fashion. - chat_scrolltime = 0; // do scroll anyway. - typelines = 1; // make sure that the chat doesn't have a weird blinking huge ass square if we typed a lot last time. - } } if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index b4a78338..90ffeb42 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -80,6 +80,8 @@ extern patch_t *iconprefix[MAXSKINS]; #define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand. +#define OLDCHAT (cv_consolechat.value || dedicated || vid.width < 640) + // some functions void HU_AddChatText(const char *text); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 068ae204..e13c1b0d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -21,6 +21,7 @@ #include "s_sound.h" #include "g_game.h" #include "hu_stuff.h" +#include "console.h" #include "k_kart.h" #include "lua_script.h" @@ -96,11 +97,14 @@ static int lib_chatprint(lua_State *L) int len = strlen(str); if (len > 255) // string is too long!!! return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); - - if (cv_consolechat.value || !netgame) + + HU_AddChatText(str); + + if OLDCHAT CONS_Printf("%s\n", str); else - HU_AddChatText(str); + CON_LogMessage(str); // save to log.txt + return 0; } @@ -124,11 +128,14 @@ static int lib_chatprintf(lua_State *L) int len = strlen(str); if (len > 255) // string is too long!!! return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); - - if (cv_consolechat.value || !netgame) + + HU_AddChatText(str); + + if OLDCHAT CONS_Printf("%s\n", str); else - HU_AddChatText(str); + CON_LogMessage(str); // save to log.txt + return 0; } From 97ec3852348a7f7ffdcfaf21e48b0452799664bb Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Sat, 4 Aug 2018 15:48:31 -0400 Subject: [PATCH 31/38] Thunder shield overlay --- src/d_netcmd.c | 2 +- src/d_netcmd.h | 2 +- src/d_player.h | 5 ++-- src/dehacked.c | 37 +++++++++++++++++++++++--- src/info.c | 59 ++++++++++++++++++++++++++++++++++++++--- src/info.h | 31 +++++++++++++++++++++- src/k_kart.c | 71 +++++++++++++++++++++++++++++--------------------- src/m_menu.c | 2 +- src/p_mobj.c | 8 ++++++ src/sounds.c | 2 +- 10 files changed, 175 insertions(+), 44 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f7954747..fb5234c9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -332,7 +332,7 @@ consvar_t cv_ballhog = {"ballhog", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NU consvar_t cv_selfpropelledbomb = {"selfpropelledbomb", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grow = {"grow", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_shrink = {"shrink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lightningshield = {"lightningshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_thundershield = {"thundershield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_hyudoro = {"hyudoro", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_pogospring = {"pogospring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 371df720..b2a57bc0 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -112,7 +112,7 @@ extern consvar_t cv_recycler;*/ extern consvar_t cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana; extern consvar_t cv_eggmanmonitor, cv_orbinaut, cv_jawz, cv_mine; extern consvar_t cv_ballhog, cv_selfpropelledbomb, cv_grow, cv_shrink; -extern consvar_t cv_lightningshield, cv_hyudoro, cv_pogospring; +extern consvar_t cv_thundershield, cv_hyudoro, cv_pogospring; extern consvar_t cv_triplesneaker, cv_triplebanana, cv_tripleorbinaut, cv_dualjawz; diff --git a/src/d_player.h b/src/d_player.h index 7b5aeafc..baa03f3e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -246,7 +246,7 @@ typedef enum KITEM_SPB, KITEM_GROW, KITEM_SHRINK, - KITEM_LIGHTNINGSHIELD, + KITEM_THUNDERSHIELD, KITEM_HYUDORO, KITEM_POGOSPRING, KITEM_KITCHENSINK, @@ -306,7 +306,8 @@ typedef enum k_itemheld, // Are you holding an item? // Some items use timers for their duration or effects - k_attractiontimer, // Duration of Lightning Shield's item-break and item box pull + //k_thunderanim, // Duration of Thunder Shield's use animation + k_curshield, // 0 = no shield, 1 = thunder shield k_hyudorotimer, // Duration of the Hyudoro offroad effect itself k_stealingtimer, // You are stealing an item, this is your timer k_stolentimer, // You are being stolen from, this is your timer diff --git a/src/dehacked.c b/src/dehacked.c index 03884474..70cf730f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6247,7 +6247,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_DRIFTDUST3", "S_DRIFTDUST4", - // Lightning Shield Burst + // Thunder Shield Burst // Sneaker Fire Trail "S_KARTFIRE1", @@ -6446,6 +6446,32 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_LIGHTNING3", "S_LIGHTNING4", + // Thunder Shield + "S_THUNDERSHIELD1", + "S_THUNDERSHIELD2", + "S_THUNDERSHIELD3", + "S_THUNDERSHIELD4", + "S_THUNDERSHIELD5", + "S_THUNDERSHIELD6", + "S_THUNDERSHIELD7", + "S_THUNDERSHIELD8", + "S_THUNDERSHIELD9", + "S_THUNDERSHIELD10", + "S_THUNDERSHIELD11", + "S_THUNDERSHIELD12", + "S_THUNDERSHIELD13", + "S_THUNDERSHIELD14", + "S_THUNDERSHIELD15", + "S_THUNDERSHIELD16", + "S_THUNDERSHIELD17", + "S_THUNDERSHIELD18", + "S_THUNDERSHIELD19", + "S_THUNDERSHIELD20", + "S_THUNDERSHIELD21", + "S_THUNDERSHIELD22", + "S_THUNDERSHIELD23", + "S_THUNDERSHIELD24", + // The legend "S_SINK", "S_SINKTRAIL1", @@ -7185,8 +7211,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FAKESHIELD", "MT_FAKEITEM", - "MT_BANANA", - "MT_BANANA_SHIELD", // Banana Stuff + "MT_BANANA", // Banana Stuff + "MT_BANANA_SHIELD", "MT_ORBINAUT", // Orbinaut stuff "MT_ORBINAUT_SHIELD", @@ -7211,6 +7237,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BLUEEXPLOSION", "MT_LIGHTNING", + "MT_THUNDERSHIELD", // Thunder Shield stuff + "MT_SINK", // Kitchen Sink Stuff "MT_SINKTRAIL", @@ -7652,7 +7680,8 @@ static const char *const KARTSTUFF_LIST[] = { "ITEMHELD", // Some items use timers for their duration or effects - "ATTRACTIONTIMER", + //"THUNDERANIM", + "CURSHIELD", "HYUDOROTIMER", "STEALINGTIMER", "STOLENTIMER", diff --git a/src/info.c b/src/info.c index 41e89ae6..0a3d0668 100644 --- a/src/info.c +++ b/src/info.c @@ -57,9 +57,10 @@ char sprnames[NUMSPRITES + 1][5] = //SRB2kart Sprites "SPRG","BSPR","RNDM","RPOP","KFRE","KINV","KINF","WIPD","DRIF","DUST", "FITM","BANA","ORBN","JAWZ","SSMN","KRBM","BHOG","BHBM","BLIG","LIGH", - "SINK","SITR","KBLN","DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS", - "SPRS","BUZB","CHOM","SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS", - "PSHW","ISTA","ISTB","ARRO","ITEM","ITMI","ITMN","WANT","PBOM","VIEW" + "THNS","SINK","SITR","KBLN","DEZL","POKE","AUDI","DECO","DOOD","SNES", + "GBAS","SPRS","BUZB","CHOM","SACO","CRAB","SHAD","BRNG","BUMP","FLEN", + "CLAS","PSHW","ISTA","ISTB","ARRO","ITEM","ITMI","ITMN","WANT","PBOM", + "VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2762,6 +2763,31 @@ state_t states[NUMSTATES] = {SPR_LIGH, 2, 2, {NULL}, 0, 0, S_LIGHTNING4}, // S_LIGHTNING3 {SPR_LIGH, 3, 2, {NULL}, 0, 0, S_NULL}, // S_LIGHTNING4 + {SPR_THNS, 0, 2, {NULL}, 0, 0, S_THUNDERSHIELD2}, // S_THUNDERSHIELD1 + {SPR_THNS, 1, 2, {NULL}, 0, 0, S_THUNDERSHIELD3}, // S_THUNDERSHIELD2 + {SPR_THNS, 2, 2, {NULL}, 0, 0, S_THUNDERSHIELD4}, // S_THUNDERSHIELD3 + {SPR_THNS, 3, 2, {NULL}, 0, 0, S_THUNDERSHIELD5}, // S_THUNDERSHIELD4 + {SPR_THNS, 4, 2, {NULL}, 0, 0, S_THUNDERSHIELD6}, // S_THUNDERSHIELD5 + {SPR_THNS, 5, 2, {NULL}, 0, 0, S_THUNDERSHIELD7}, // S_THUNDERSHIELD6 + {SPR_THNS, 6, 2, {NULL}, 0, 0, S_THUNDERSHIELD8}, // S_THUNDERSHIELD7 + {SPR_THNS, 7, 2, {NULL}, 0, 0, S_THUNDERSHIELD9}, // S_THUNDERSHIELD8 + {SPR_THNS, 8, 2, {NULL}, 0, 0, S_THUNDERSHIELD10}, // S_THUNDERSHIELD9 + {SPR_THNS, 9, 2, {NULL}, 0, 0, S_THUNDERSHIELD11}, // S_THUNDERSHIELD10 + {SPR_THNS, 10, 2, {NULL}, 0, 0, S_THUNDERSHIELD12}, // S_THUNDERSHIELD11 + {SPR_THNS, 11, 2, {NULL}, 0, 0, S_THUNDERSHIELD13}, // S_THUNDERSHIELD12 + {SPR_THNS, 8, 2, {NULL}, 0, 0, S_THUNDERSHIELD14}, // S_THUNDERSHIELD13 + {SPR_THNS, 7, 2, {NULL}, 0, 0, S_THUNDERSHIELD15}, // S_THUNDERSHIELD14 + {SPR_THNS, 6, 2, {NULL}, 0, 0, S_THUNDERSHIELD16}, // S_THUNDERSHIELD15 + {SPR_THNS, 5, 2, {NULL}, 0, 0, S_THUNDERSHIELD17}, // S_THUNDERSHIELD16 + {SPR_THNS, 4, 2, {NULL}, 0, 0, S_THUNDERSHIELD18}, // S_THUNDERSHIELD17 + {SPR_THNS, 3, 2, {NULL}, 0, 0, S_THUNDERSHIELD19}, // S_THUNDERSHIELD18 + {SPR_THNS, 2, 2, {NULL}, 0, 0, S_THUNDERSHIELD20}, // S_THUNDERSHIELD19 + {SPR_THNS, 1, 2, {NULL}, 0, 0, S_THUNDERSHIELD21}, // S_THUNDERSHIELD20 + {SPR_THNS, 0, 2, {NULL}, 0, 0, S_THUNDERSHIELD22}, // S_THUNDERSHIELD21 + {SPR_THNS, 9, 2, {NULL}, 0, 0, S_THUNDERSHIELD23}, // S_THUNDERSHIELD22 + {SPR_THNS, 10, 2, {NULL}, 0, 0, S_THUNDERSHIELD24}, // S_THUNDERSHIELD23 + {SPR_THNS, 11, 2, {NULL}, 0, 0, S_THUNDERSHIELD1}, // S_THUNDERSHIELD24 + {SPR_SINK, 0, 4, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK {SPR_SITR, 0, 1, {NULL}, 0, 0, S_SINKTRAIL2}, // S_SINKTRAIL1 {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 @@ -15087,6 +15113,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_THUNDERSHIELD + -1, // doomednum + S_THUNDERSHIELD1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 16*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_SINK -1, // doomednum S_SINK, // spawnstate diff --git a/src/info.h b/src/info.h index 3186fc88..ea07e2f3 100644 --- a/src/info.h +++ b/src/info.h @@ -600,6 +600,7 @@ typedef enum sprite SPR_BHBM, // Ballhog BOOM SPR_BLIG, // Self-Propelled Bomb SPR_LIGH, // Grow/shrink beams (Metallic Maddness) + SPR_THNS, // Thunder Shield SPR_SINK, // Kitchen Sink SPR_SITR, // Kitchen Sink Trail SPR_KBLN, // Battle Mode Bumper @@ -3282,12 +3283,38 @@ typedef enum state S_BLUELIGHTNING4, S_BLUEEXPLODE, - // Size-Down + // Grow/Shrink S_LIGHTNING1, S_LIGHTNING2, S_LIGHTNING3, S_LIGHTNING4, + // Thunder Shield + S_THUNDERSHIELD1, + S_THUNDERSHIELD2, + S_THUNDERSHIELD3, + S_THUNDERSHIELD4, + S_THUNDERSHIELD5, + S_THUNDERSHIELD6, + S_THUNDERSHIELD7, + S_THUNDERSHIELD8, + S_THUNDERSHIELD9, + S_THUNDERSHIELD10, + S_THUNDERSHIELD11, + S_THUNDERSHIELD12, + S_THUNDERSHIELD13, + S_THUNDERSHIELD14, + S_THUNDERSHIELD15, + S_THUNDERSHIELD16, + S_THUNDERSHIELD17, + S_THUNDERSHIELD18, + S_THUNDERSHIELD19, + S_THUNDERSHIELD20, + S_THUNDERSHIELD21, + S_THUNDERSHIELD22, + S_THUNDERSHIELD23, + S_THUNDERSHIELD24, + // The legend S_SINK, S_SINKTRAIL1, @@ -4070,6 +4097,8 @@ typedef enum mobj_type MT_BLUEEXPLOSION, MT_LIGHTNING, + MT_THUNDERSHIELD, // Thunder Shield stuff + MT_SINK, // Kitchen Sink Stuff MT_SINKTRAIL, diff --git a/src/k_kart.c b/src/k_kart.c index 50d03c1e..a1733f1b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -385,7 +385,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_selfpropelledbomb); CV_RegisterVar(&cv_grow); CV_RegisterVar(&cv_shrink); - CV_RegisterVar(&cv_lightningshield); + CV_RegisterVar(&cv_thundershield); CV_RegisterVar(&cv_hyudoro); CV_RegisterVar(&cv_pogospring); @@ -476,7 +476,7 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] = /*Self-Propelled Bomb*/ { 0, 0, 1, 1, 1, 2, 2, 3, 2 }, // Self-Propelled Bomb /*Grow*/ { 0, 0, 0, 0, 1, 2, 4, 6, 4 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 1, 0 }, // Shrink - /*Lightning Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Lightning Shield + /*Thunder Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro /*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink @@ -502,7 +502,7 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] = /*Self-Propelled Bomb*/ { 0, 0, 0, 0 }, // Self-Propelled Bomb /*Grow*/ { 4, 2, 0, 2 }, // Grow /*Shrink*/ { 0, 0, 0, 0 }, // Shrink - /*Lightning Shield*/ { 0, 0, 0, 0 }, // Lightning Shield + /*Thunder Shield*/ { 0, 0, 0, 0 }, // Thunder Shield /*Hyudoro*/ { 0, 0, 1, 0 }, // Hyudoro /*Pogo Spring*/ { 0, 0, 1, 0 }, // Pogo Spring /*Kitchen Sink*/ { 0, 0, 0, 0 }, // Kitchen Sink @@ -680,9 +680,9 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) || (indirectitemcooldown > 0) || (pingame-1 <= pexiting)) newodds = 0; break; - case KITEM_LIGHTNINGSHIELD: + case KITEM_THUNDERSHIELD: POWERITEMODDS(newodds); - if (!cv_lightningshield.value) newodds = 0; + if (!cv_thundershield.value) newodds = 0; break; case KITEM_HYUDORO: if (!cv_hyudoro.value) newodds = 0; @@ -899,7 +899,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) SETITEMRESULT(useodds, KITEM_SPB); // Self-Propelled Bomb SETITEMRESULT(useodds, KITEM_GROW); // Grow SETITEMRESULT(useodds, KITEM_SHRINK); // Shrink - SETITEMRESULT(useodds, KITEM_LIGHTNINGSHIELD); // Lightning Shield + SETITEMRESULT(useodds, KITEM_THUNDERSHIELD); // Thunder Shield SETITEMRESULT(useodds, KITEM_HYUDORO); // Hyudoro SETITEMRESULT(useodds, KITEM_POGOSPRING); // Pogo Spring //SETITEMRESULT(useodds, KITEM_KITCHENSINK); // Kitchen Sink @@ -2537,10 +2537,10 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map return mo; } -static void K_DoLightningShield(player_t *player) +static void K_DoThunderShield(player_t *player) { S_StartSound(player->mo, sfx_s3k45); - player->kartstuff[k_attractiontimer] = 35; + //player->kartstuff[k_thunderanim] = 35; P_NukeEnemies(player->mo, player->mo, RING_DIST/4); } @@ -2550,7 +2550,7 @@ static void K_DoHyudoroSteal(player_t *player) INT32 playerswappable[MAXPLAYERS]; INT32 stealplayer = -1; // The player that's getting stolen from INT32 prandom = 0; - fixed_t sink = P_RandomChance(FRACUNIT/64); + boolean sink = P_RandomChance(FRACUNIT/64); for (i = 0; i < MAXPLAYERS; i++) { @@ -2574,7 +2574,7 @@ static void K_DoHyudoroSteal(player_t *player) prandom = P_RandomFixed(); S_StartSound(player->mo, sfx_s3k92); - if (sink) // BEHOLD THE KITCHEN SINK + if (sink && numplayers > 0) // BEHOLD THE KITCHEN SINK { player->kartstuff[k_hyudorotimer] = hyudorotime; player->kartstuff[k_stealingtimer] = stealtime; @@ -3010,8 +3010,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing()) player->powers[pw_flashing]--; - if (player->kartstuff[k_attractiontimer]) - player->kartstuff[k_attractiontimer]--; + /*if (player->kartstuff[k_thunderanim]) + player->kartstuff[k_thunderanim]--;*/ if (player->kartstuff[k_sneakertimer]) player->kartstuff[k_sneakertimer]--; @@ -3538,7 +3538,9 @@ void K_StripItems(player_t *player) player->kartstuff[k_stealingtimer] = 0; player->kartstuff[k_stolentimer] = 0; - player->kartstuff[k_attractiontimer] = 0; + player->kartstuff[k_curshield] = 0; + //player->kartstuff[k_thunderanim] = 0; + player->kartstuff[k_bananadrag] = 0; player->kartstuff[k_sadtimer] = 0; } @@ -3871,10 +3873,16 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->kartstuff[k_itemamount]--; } break; - case KITEM_LIGHTNINGSHIELD: + case KITEM_THUNDERSHIELD: + if (player->kartstuff[k_curshield] <= 0) + { + mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD); + P_SetTarget(&shield->target, player->mo); + player->kartstuff[k_curshield] = 1; + } if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - K_DoLightningShield(player); + K_DoThunderShield(player); player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemamount]--; } @@ -3924,6 +3932,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (!player->kartstuff[k_itemamount] && !player->kartstuff[k_itemheld]) player->kartstuff[k_itemtype] = KITEM_NONE; + if (player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD) + player->kartstuff[k_curshield] = 0; + if (player->kartstuff[k_itemtype] == KITEM_SPB || player->kartstuff[k_itemtype] == KITEM_SHRINK || player->kartstuff[k_growshrinktimer] < 0 @@ -4384,7 +4395,7 @@ static patch_t *kp_ballhog[2]; static patch_t *kp_selfpropelledbomb[2]; static patch_t *kp_grow[2]; static patch_t *kp_shrink[2]; -static patch_t *kp_lightningshield[2]; +static patch_t *kp_thundershield[2]; static patch_t *kp_hyudoro[2]; static patch_t *kp_pogospring[2]; static patch_t *kp_kitchensink[2]; @@ -4494,7 +4505,7 @@ void K_LoadKartHUDGraphics(void) kp_selfpropelledbomb[0] = W_CachePatchName("K_ITSPB", PU_HUDGFX); kp_grow[0] = W_CachePatchName("K_ITGROW", PU_HUDGFX); kp_shrink[0] = W_CachePatchName("K_ITSHRK", PU_HUDGFX); - kp_lightningshield[0] = W_CachePatchName("K_ITLITS", PU_HUDGFX); + kp_thundershield[0] = W_CachePatchName("K_ITTHNS", PU_HUDGFX); kp_hyudoro[0] = W_CachePatchName("K_ITHYUD", PU_HUDGFX); kp_pogospring[0] = W_CachePatchName("K_ITPOGO", PU_HUDGFX); kp_kitchensink[0] = W_CachePatchName("K_ITSINK", PU_HUDGFX); @@ -4522,7 +4533,7 @@ void K_LoadKartHUDGraphics(void) kp_selfpropelledbomb[1] = W_CachePatchName("K_ISSPB", PU_HUDGFX); kp_grow[1] = W_CachePatchName("K_ISGROW", PU_HUDGFX); kp_shrink[1] = W_CachePatchName("K_ISSHRK", PU_HUDGFX); - kp_lightningshield[1] = W_CachePatchName("K_ISLITS", PU_HUDGFX); + kp_thundershield[1] = W_CachePatchName("K_ISTHNS", PU_HUDGFX); kp_hyudoro[1] = W_CachePatchName("K_ISHYUD", PU_HUDGFX); kp_pogospring[1] = W_CachePatchName("K_ISPOGO", PU_HUDGFX); kp_kitchensink[1] = W_CachePatchName("K_ISSINK", PU_HUDGFX); @@ -4756,22 +4767,22 @@ static void K_drawKartItem(void) switch((stplyr->kartstuff[k_itemroulette] % (13*3)) / 3) { // Each case is handled in threes, to give three frames of in-game time to see the item on the roulette - case 0: localpatch = kp_sneaker[offset]; break; // Sneaker + case 0: localpatch = kp_sneaker[offset]; break; // Sneaker case 1: localpatch = kp_banana[offset]; break; // Banana - case 2: localpatch = kp_orbinaut[offset]; break; // Orbinaut - case 3: localpatch = kp_mine[offset]; break; // Mine - case 4: localpatch = kp_grow[offset]; break; // Grow - case 5: localpatch = kp_hyudoro[offset]; break; // Hyudoro + case 2: localpatch = kp_orbinaut[offset]; break; // Orbinaut + case 3: localpatch = kp_mine[offset]; break; // Mine + case 4: localpatch = kp_grow[offset]; break; // Grow + case 5: localpatch = kp_hyudoro[offset]; break; // Hyudoro case 6: localpatch = kp_rocketsneaker[offset]; break; // Rocket Sneaker - case 7: localpatch = kp_jawz[offset]; break; // Jawz + case 7: localpatch = kp_jawz[offset]; break; // Jawz case 8: localpatch = kp_selfpropelledbomb[offset]; break; // Self-Propelled Bomb case 9: localpatch = kp_shrink[offset]; break; // Shrink - case 10: localpatch = localinv; break; // Invincibility + case 10: localpatch = localinv; break; // Invincibility case 11: localpatch = kp_eggman[offset]; break; // Eggman Monitor - case 12: localpatch = kp_ballhog[offset]; break; // Ballhog - case 13: localpatch = kp_lightningshield[offset]; break; // Lightning Shield - //case 14: localpatch = kp_pogospring[offset]; break; // Pogo Spring - //case 15: localpatch = kp_kitchensink[offset]; break; // Kitchen Sink + case 12: localpatch = kp_ballhog[offset]; break; // Ballhog + case 13: localpatch = kp_thundershield[offset]; break; // Thunder Shield + //case 14: localpatch = kp_pogospring[offset]; break; // Pogo Spring + //case 15: localpatch = kp_kitchensink[offset]; break; // Kitchen Sink default: break; } } @@ -4832,7 +4843,7 @@ static void K_drawKartItem(void) case KITEM_SPB: localpatch = kp_selfpropelledbomb[offset]; break; case KITEM_GROW: localpatch = kp_grow[offset]; break; case KITEM_SHRINK: localpatch = kp_shrink[offset]; break; - case KITEM_LIGHTNINGSHIELD: localpatch = kp_lightningshield[offset]; break; + case KITEM_THUNDERSHIELD: localpatch = kp_thundershield[offset]; break; case KITEM_HYUDORO: localpatch = kp_hyudoro[offset]; break; case KITEM_POGOSPRING: localpatch = kp_pogospring[offset]; break; case KITEM_KITCHENSINK: localpatch = kp_kitchensink[offset]; break; diff --git a/src/m_menu.c b/src/m_menu.c index ce4e7486..4364a0f5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1500,7 +1500,7 @@ static menuitem_t OP_MonitorToggleMenu[] = {IT_STRING | IT_CVAR, NULL, "Self-Propelled Bombs",&cv_selfpropelledbomb,114}, {IT_STRING | IT_CVAR, NULL, "Grow", &cv_grow, 122}, {IT_STRING | IT_CVAR, NULL, "Shrink", &cv_shrink, 130}, - {IT_STRING | IT_CVAR, NULL, "Lightning Shields", &cv_lightningshield, 138}, + {IT_STRING | IT_CVAR, NULL, "Thunder Shields", &cv_thundershield, 138}, {IT_STRING | IT_CVAR, NULL, "Hyudoros", &cv_hyudoro, 146}, {IT_STRING | IT_CVAR, NULL, "Pogo Springs", &cv_pogospring, 154}, }; diff --git a/src/p_mobj.c b/src/p_mobj.c index 9cf78ebf..c2c08f33 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8220,6 +8220,14 @@ void P_MobjThinker(mobj_t *mobj) } P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); break; + case MT_THUNDERSHIELD: + if (!mobj->target || !mobj->target->health || (mobj->target->player && mobj->target->player->kartstuff[k_curshield] != 1)) + { + P_RemoveMobj(mobj); + return; + } + P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + break; case MT_KARMAHITBOX: if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator || (G_RaceGametype() || mobj->target->player->kartstuff[k_bumper])) diff --git a/src/sounds.c b/src/sounds.c index 60cbb676..3b41dfa1 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -415,7 +415,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Lightning Shield use + {"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Thunder Shield use {"s3k46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, From ad15ad4b89c7731a1fcc02683eb5ba30708749ab Mon Sep 17 00:00:00 2001 From: TehRealSalt <tehrealsalt@gmail.com> Date: Sat, 4 Aug 2018 16:54:48 -0400 Subject: [PATCH 32/38] Orbinaut shield --- src/dehacked.c | 7 ++++++- src/info.c | 39 ++++++++++++++++++++++----------------- src/info.h | 7 ++++++- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 70cf730f..8fcf597d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6324,8 +6324,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ORBINAUT4", "S_ORBINAUT5", "S_ORBINAUT6", - "S_ORBINAUT_SHIELD", "S_ORBINAUT_DEAD", + "S_ORBINAUT_SHIELD1", + "S_ORBINAUT_SHIELD2", + "S_ORBINAUT_SHIELD3", + "S_ORBINAUT_SHIELD4", + "S_ORBINAUT_SHIELD5", + "S_ORBINAUT_SHIELD6", "S_ORBINAUT_SHIELDDEAD", //} //{ Jawz diff --git a/src/info.c b/src/info.c index 0a3d0668..8c6560fc 100644 --- a/src/info.c +++ b/src/info.c @@ -2610,7 +2610,7 @@ state_t states[NUMSTATES] = {SPR_WIPD, 3, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL5}, // S_WIPEOUTTRAIL4 {SPR_WIPD, 4, 3, {NULL}, 0, 0, S_NULL}, // S_WIPEOUTTRAIL5 - {SPR_FITM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 + {SPR_FITM, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 {SPR_FITM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2 {SPR_FITM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3 {SPR_FITM, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM5}, // S_FAKEITEM4 @@ -2634,20 +2634,25 @@ state_t states[NUMSTATES] = {SPR_FITM, 21|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22 // ***** {SPR_FITM, 22|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23 // ***** {SPR_FITM, 23|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM1}, // S_FAKEITEM24 // ***** - {SPR_FITM, 24|FF_FULLBRIGHT, 175, {NULL}, 0, 0, S_FAKEITEM1}, // S_DEADFAKEITEM + {SPR_FITM, FF_FULLBRIGHT, 175, {NULL}, 0, 0, S_FAKEITEM1}, // S_DEADFAKEITEM {SPR_BANA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BANANA - {SPR_BANA, 1, 175, {NULL}, 0, 0, S_NULL}, // S_BANANA_DEAD + {SPR_BANA, 0, 175, {NULL}, 0, 0, S_NULL}, // S_BANANA_DEAD - {SPR_ORBN, 0, 1, {NULL}, 0, 0, S_ORBINAUT2}, // S_ORBINAUT1 - {SPR_ORBN, 1, 1, {NULL}, 0, 0, S_ORBINAUT3}, // S_ORBINAUT2 - {SPR_ORBN, 2, 1, {NULL}, 0, 0, S_ORBINAUT4}, // S_ORBINAUT3 - {SPR_ORBN, 3, 1, {NULL}, 0, 0, S_ORBINAUT5}, // S_ORBINAUT4 - {SPR_ORBN, 4, 1, {NULL}, 0, 0, S_ORBINAUT6}, // S_ORBINAUT5 - {SPR_ORBN, 5, 1, {NULL}, 0, 0, S_ORBINAUT1}, // S_ORBINAUT6 - {SPR_ORBN, 7, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD}, // S_ORBINAUT_SHIELD - {SPR_ORBN, 6, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_DEAD - {SPR_ORBN, 8, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_SHIELDDEAD + {SPR_ORBN, 0, 1, {NULL}, 0, 0, S_ORBINAUT2}, // S_ORBINAUT1 + {SPR_ORBN, 1, 1, {NULL}, 0, 0, S_ORBINAUT3}, // S_ORBINAUT2 + {SPR_ORBN, 2, 1, {NULL}, 0, 0, S_ORBINAUT4}, // S_ORBINAUT3 + {SPR_ORBN, 3, 1, {NULL}, 0, 0, S_ORBINAUT5}, // S_ORBINAUT4 + {SPR_ORBN, 4, 1, {NULL}, 0, 0, S_ORBINAUT6}, // S_ORBINAUT5 + {SPR_ORBN, 5, 1, {NULL}, 0, 0, S_ORBINAUT1}, // S_ORBINAUT6 + {SPR_ORBN, 0, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_DEAD + {SPR_ORBN, 6, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD2}, // S_ORBINAUT_SHIELD1 + {SPR_ORBN, 7, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD3}, // S_ORBINAUT_SHIELD2 + {SPR_ORBN, 8, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD4}, // S_ORBINAUT_SHIELD3 + {SPR_ORBN, 9, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD5}, // S_ORBINAUT_SHIELD4 + {SPR_ORBN, 10, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD6}, // S_ORBINAUT_SHIELD5 + {SPR_ORBN, 11, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD1}, // S_ORBINAUT_SHIELD6 + {SPR_ORBN, 6, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_SHIELDDEAD {SPR_JAWZ, 0, 1, {A_JawzChase}, 0, 0, S_JAWZ2}, // S_JAWZ1 {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ3}, // S_JAWZ2 @@ -14669,7 +14674,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_ORBINAUT_DEAD,// deathstate S_NULL, // xdeathstate - sfx_shbrk, // deathsound + sfx_s3k5d, // deathsound 64*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height @@ -14683,7 +14688,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_ORBINAUT_SHIELD -1, // doomednum - S_ORBINAUT_SHIELD, // spawnstate + S_ORBINAUT_SHIELD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14723,7 +14728,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_JAWZ_DEAD1, // deathstate S_JAWZ_DEAD2, // xdeathstate - sfx_shbrk, // deathsound + sfx_s3k5d, // deathsound 7*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height @@ -14750,7 +14755,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_JAWZ_DEAD1, // deathstate S_JAWZ_DEAD2, // xdeathstate - sfx_shbrk, // deathsound + sfx_s3k5d, // deathsound 56*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height @@ -15155,7 +15160,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_shbrk, // deathsound + sfx_s3k5d, // deathsound 0, // speed 16*FRACUNIT, // radius 24*FRACUNIT, // height diff --git a/src/info.h b/src/info.h index ea07e2f3..4e2be267 100644 --- a/src/info.h +++ b/src/info.h @@ -3167,8 +3167,13 @@ typedef enum state S_ORBINAUT4, S_ORBINAUT5, S_ORBINAUT6, - S_ORBINAUT_SHIELD, S_ORBINAUT_DEAD, + S_ORBINAUT_SHIELD1, + S_ORBINAUT_SHIELD2, + S_ORBINAUT_SHIELD3, + S_ORBINAUT_SHIELD4, + S_ORBINAUT_SHIELD5, + S_ORBINAUT_SHIELD6, S_ORBINAUT_SHIELDDEAD, //} //{ Jawz From ee5ebd978a89611e02f04b0b3b031dd97298a733 Mon Sep 17 00:00:00 2001 From: Latapostrophe <hyperclassic3@gmail.com> Date: Sun, 5 Aug 2018 13:08:27 +0200 Subject: [PATCH 33/38] Chat wordwrap fix + Minichat bg highlight --- objs/Mingw/SDL/Release/.gitignore | 2 -- src/d_netcmd.c | 1 + src/g_game.c | 3 +++ src/g_game.h | 2 +- src/hu_stuff.c | 34 ++++++++++++++++++++++--------- src/m_menu.c | 5 +++-- 6 files changed, 32 insertions(+), 15 deletions(-) delete mode 100644 objs/Mingw/SDL/Release/.gitignore diff --git a/objs/Mingw/SDL/Release/.gitignore b/objs/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c..00000000 --- a/objs/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f87ebcfa..c7647e02 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -787,6 +787,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_chatspamprotection); CV_RegisterVar(&cv_consolechat); CV_RegisterVar(&cv_chatnotifications); + CV_RegisterVar(&cv_chatbackteint); CV_RegisterVar(&cv_crosshair); CV_RegisterVar(&cv_crosshair2); CV_RegisterVar(&cv_crosshair3); diff --git a/src/g_game.c b/src/g_game.c index 762cac85..7af11dc6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -421,6 +421,9 @@ consvar_t cv_chatnotifications = {"chatnotifications", "On", CV_SAVE, CV_OnOff, // chat spam protection (why would you want to disable that???) consvar_t cv_chatspamprotection = {"chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +// minichat text background +consvar_t cv_chatbackteint = {"chatbackteint", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + // old shit console chat. (mostly exists for stuff like terminal, not because I cared if anyone liked the old chat.) //static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Box"}, {1, "Console"}, {0, NULL}}; -- for menu, but menu disabled... consvar_t cv_consolechat = {"consolechat", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/g_game.h b/src/g_game.h index 47c51d93..08ac73f2 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,7 +54,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu -extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_compactscoreboard; +extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_compactscoreboard, cv_chatbackteint; extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 338fd26c..22dc7fc5 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1189,7 +1189,7 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) size_t chw, i, lastusablespace = 0; size_t slen; char *newstring = Z_StrDup(string); - INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4; + INT32 charwidth = 4; slen = strlen(string); x = 0; @@ -1213,7 +1213,7 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) { - chw = spacewidth; + chw = charwidth; lastusablespace = i; } else @@ -1250,13 +1250,14 @@ static void HU_drawMiniChat(void) INT32 charwidth = 4, charheight = 6; INT32 dx = 0, dy = 0; size_t i = chat_nummsg_min; + boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place. INT32 msglines = 0; // process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has... for (; i>0; i--) { - const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); + const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); size_t j = 0; INT32 linescount = 0; @@ -1267,8 +1268,12 @@ static void HU_drawMiniChat(void) if (msg[j] == '\n') // get back down. { ++j; - linescount += 1; - dx = 0; + if (!prev_linereturn) + { + linescount += 1; + dx = 0; + } + prev_linereturn = true; continue; } else if (msg[j] & 0x80) // stolen from video.c, nice. @@ -1283,7 +1288,7 @@ static void HU_drawMiniChat(void) { j++; } - + prev_linereturn = false; dx += charwidth; if (dx >= cv_chatwidth.value) { @@ -1300,6 +1305,7 @@ static void HU_drawMiniChat(void) dx = 0; dy = 0; i = 0; + prev_linereturn = false; for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages { @@ -1307,7 +1313,7 @@ static void HU_drawMiniChat(void) INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. size_t j = 0; - const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. while(msg[j]) // iterate through msg { @@ -1316,8 +1322,12 @@ static void HU_drawMiniChat(void) if (msg[j] == '\n') // get back down. { ++j; - dy += charheight; - dx = 0; + if (!prev_linereturn) + { + dy += charheight; + dx = 0; + } + prev_linereturn = true; continue; } else if (msg[j] & 0x80) // stolen from video.c, nice. @@ -1331,11 +1341,15 @@ static void HU_drawMiniChat(void) } else { + if (cv_chatbackteint.value) // on request of wolfy + V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); + UINT8 *colormap = CHAT_GetStringColormap(clrflag); V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); } dx += charwidth; + prev_linereturn = false; if (dx >= cv_chatwidth.value) { dx = 0; @@ -1406,7 +1420,7 @@ static void HU_drawChatLog(INT32 offset) { INT32 clrflag = 0; INT32 j = 0; - const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. + const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. while(msg[j]) // iterate through msg { if (msg[j] < HU_FONTSTART) // don't draw diff --git a/src/m_menu.c b/src/m_menu.c index 16d04af1..eb5ffb6c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1412,9 +1412,10 @@ static menuitem_t OP_HUDOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat box height", &cv_chatheight, 105}, {IT_STRING | IT_CVAR, NULL, "Chat fadeout time", &cv_chattime, 115}, + {IT_STRING | IT_CVAR, NULL, "Chat background teint", &cv_chatbackteint, 125}, - {IT_STRING | IT_CVAR, NULL, "Background Color", &cons_backcolor, 130}, - {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 140}, + {IT_STRING | IT_CVAR, NULL, "Background Color", &cons_backcolor, 140}, + {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 150}, }; static menuitem_t OP_GameOptionsMenu[] = From c1749b01b105725f3ca6763a6fc2e97ebba1de15 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Sun, 5 Aug 2018 16:34:51 +0100 Subject: [PATCH 34/38] * Tint, not Teint. * Update/rearrange menus a tad, to be more appealing and correct some categorisation in general. --- src/d_netcmd.c | 2 +- src/g_game.c | 2 +- src/g_game.h | 2 +- src/hu_stuff.c | 7 ++-- src/m_menu.c | 111 ++++++++++++++++++++++++++++--------------------- 5 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c7647e02..521f3c42 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -787,7 +787,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_chatspamprotection); CV_RegisterVar(&cv_consolechat); CV_RegisterVar(&cv_chatnotifications); - CV_RegisterVar(&cv_chatbackteint); + CV_RegisterVar(&cv_chatbacktint); CV_RegisterVar(&cv_crosshair); CV_RegisterVar(&cv_crosshair2); CV_RegisterVar(&cv_crosshair3); diff --git a/src/g_game.c b/src/g_game.c index 7af11dc6..4a1c84d3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -422,7 +422,7 @@ consvar_t cv_chatnotifications = {"chatnotifications", "On", CV_SAVE, CV_OnOff, consvar_t cv_chatspamprotection = {"chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // minichat text background -consvar_t cv_chatbackteint = {"chatbackteint", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chatbacktint = {"chatbacktint", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // old shit console chat. (mostly exists for stuff like terminal, not because I cared if anyone liked the old chat.) //static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Box"}, {1, "Console"}, {0, NULL}}; -- for menu, but menu disabled... diff --git a/src/g_game.h b/src/g_game.h index 08ac73f2..53c970d2 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,7 +54,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu -extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_compactscoreboard, cv_chatbackteint; +extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_compactscoreboard, cv_chatbacktint; extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 22dc7fc5..d8b6093c 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1341,10 +1341,11 @@ static void HU_drawMiniChat(void) } else { - if (cv_chatbackteint.value) // on request of wolfy - V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); - UINT8 *colormap = CHAT_GetStringColormap(clrflag); + + if (cv_chatbacktint.value) // on request of wolfy + V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); + V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); } diff --git a/src/m_menu.c b/src/m_menu.c index eb5ffb6c..7da112b0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -339,7 +339,6 @@ static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawControl(void); static void M_DrawVideoMenu(void); static void M_DrawVideoMode(void); -static void M_DrawHUDOptions(void); //static void M_DrawMonitorToggles(void); #ifdef HWRENDER static void M_OGL_DrawFogMenu(void); @@ -1246,23 +1245,49 @@ static menuitem_t OP_Mouse2OptionsMenu[] = static menuitem_t OP_VideoOptionsMenu[] = { {IT_STRING | IT_CALL, NULL, "Set Resolution...", M_VideoModeMenu, 10}, -#ifdef HWRENDER - {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 20}, -#endif #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 30}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 20}, #endif {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Gamma", &cv_usegamma, 50}, + NULL, "Gamma", &cv_usegamma, 30}, + + {IT_STRING | IT_CVAR, NULL, "Menu Highlights", &cons_menuhighlight, 45}, + // highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 55 (see M_DrawVideoMenu) {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 70}, //{IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist", &cv_drawdist_nights, 80}, - {IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 80}, + {IT_STRING | IT_CVAR, NULL, "Weather Draw Distance",&cv_drawdist_precip, 80}, {IT_STRING | IT_CVAR, NULL, "Weather Density", &cv_precipdensity, 90}, {IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 100}, - {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 120}, - {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 130}, + {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 115}, + {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 125}, + + {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 140}, + +#ifdef HWRENDER + {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 155}, +#endif +}; + +enum +{ + op_video_res = 0, +#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) + op_video_fullscreen, +#endif + op_video_gamma, + op_video_hili, + op_video_dd, + op_video_wdd, + op_video_wd, + op_video_skybox, + op_video_fps, + op_video_vsync, + op_video_consoletext, +#ifdef HWRENDER + op_video_ogl, +#endif }; static menuitem_t OP_VideoModeMenu[] = @@ -1403,19 +1428,14 @@ static menuitem_t OP_HUDOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Speedometer Display", &cv_kartspeedometer, 45}, {IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", &cv_kartcheck, 55}, - {IT_STRING | IT_CVAR, NULL, "Menu Highlights", &cons_menuhighlight, 70}, - // highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 80 (see M_DrawHUDOptions) - - //{IT_STRING | IT_CVAR, NULL, "Chat mode", &cv_consolechat, 95}, -- will ANYONE who doesn't know how to use the console want to touch this + //{IT_STRING | IT_CVAR, NULL, "Chat mode", &cv_consolechat, 70}, -- will ANYONE who doesn't know how to use the console want to touch this {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Chat box width", &cv_chatwidth, 95}, + NULL, "Chat box width", &cv_chatwidth, 70}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Chat box height", &cv_chatheight, 105}, - {IT_STRING | IT_CVAR, NULL, "Chat fadeout time", &cv_chattime, 115}, - {IT_STRING | IT_CVAR, NULL, "Chat background teint", &cv_chatbackteint, 125}, - - {IT_STRING | IT_CVAR, NULL, "Background Color", &cons_backcolor, 140}, - {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 150}, + NULL, "Chat box height", &cv_chatheight, 80}, + {IT_STRING | IT_CVAR, NULL, "Chat fadeout time", &cv_chattime, 90}, + {IT_STRING | IT_CVAR, NULL, "Show tint behind messages",&cv_chatbacktint, 100}, + {IT_STRING | IT_CVAR, NULL, "Background Color", &cons_backcolor, 110}, }; static menuitem_t OP_GameOptionsMenu[] = @@ -1445,8 +1465,8 @@ static menuitem_t OP_ServerOptionsMenu[] = #endif {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 40}, - {IT_STRING | IT_CVAR, NULL, "Voting Timer", &cv_votetime, 50}, - {IT_STRING | IT_CVAR, NULL, "Advance to Next Level", &cv_advancemap, 60}, + {IT_STRING | IT_CVAR, NULL, "Map Progression", &cv_advancemap, 50}, + {IT_STRING | IT_CVAR, NULL, "Voting Timer", &cv_votetime, 60}, #ifndef NONET {IT_STRING | IT_CVAR, NULL, "Max Player Count", &cv_maxplayers, 80}, @@ -1454,7 +1474,7 @@ static menuitem_t OP_ServerOptionsMenu[] = //{IT_STRING | IT_CVAR, NULL, "Join on Map Change", &cv_joinnextround, 100}, {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 100}, - {IT_STRING | IT_CVAR, NULL, "Attempts to Resynch", &cv_resynchattempts, 110}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 110}, #endif }; @@ -1886,7 +1906,7 @@ menu_t OP_VideoOptionsDef = &OP_MainDef, OP_VideoOptionsMenu, M_DrawVideoMenu, - 60, 30, + 30, 30, 0, NULL }; @@ -1910,7 +1930,7 @@ menu_t OP_SoundOptionsDef = &OP_MainDef, OP_SoundOptionsMenu, M_DrawSkyRoom, - 60, 30, + 30, 30, 0, NULL }; @@ -1921,7 +1941,7 @@ menu_t OP_HUDOptionsDef = sizeof (OP_HUDOptionsMenu)/sizeof (menuitem_t), &OP_MainDef, OP_HUDOptionsMenu, - M_DrawHUDOptions, + M_DrawGenericMenu, //M_DrawHUDOptions, 30, 30, 0, NULL @@ -3060,7 +3080,7 @@ void M_Init(void) #ifdef HWRENDER // Permanently hide some options based on render mode if (rendermode == render_soft) - OP_VideoOptionsMenu[1].status = IT_DISABLED; + OP_VideoOptionsMenu[op_video_ogl].status = IT_DISABLED; #endif #ifndef NONET @@ -8216,8 +8236,25 @@ static void M_VideoModeMenu(INT32 choice) static void M_DrawVideoMenu(void) { + const char *str0 = ")"; + const char *str1 = " Warning highlight"; + const char *str2 = ","; + const char *str3 = "Good highlight"; + INT32 x = BASEVIDWIDTH - currentMenu->x + 2, y = currentMenu->y + 55; + INT32 w0 = V_StringWidth(str0, 0), w1 = V_StringWidth(str1, 0), w2 = V_StringWidth(str2, 0), w3 = V_StringWidth(str3, 0); M_DrawGenericMenu(); + + x -= w0; + V_DrawString(x, y, highlightflags, str0); + x -= w1; + V_DrawString(x, y, warningflags, str1); + x -= w2; + V_DrawString(x, y, highlightflags, str2); + x -= w3; + V_DrawString(x, y, recommendedflags, str3); + V_DrawRightAlignedString(x, y, highlightflags, "("); + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + OP_VideoOptionsMenu[0].alphaKey, (SCR_IsAspectCorrect(vid.width, vid.height) ? recommendedflags : highlightflags), va("%dx%d", vid.width, vid.height)); @@ -8368,26 +8405,6 @@ static void M_HandleVideoMode(INT32 ch) } } -static void M_DrawHUDOptions(void) -{ - const char *str0 = ")"; - const char *str1 = " Warning highlight"; - const char *str2 = ","; - const char *str3 = "Good highlight"; - INT32 x = BASEVIDWIDTH - currentMenu->x + 2, y = currentMenu->y + 80; - INT32 w0 = V_StringWidth(str0, 0), w1 = V_StringWidth(str1, 0), w2 = V_StringWidth(str2, 0), w3 = V_StringWidth(str3, 0); - M_DrawGenericMenu(); - x -= w0; - V_DrawString(x, y, highlightflags, str0); - x -= w1; - V_DrawString(x, y, warningflags, str1); - x -= w2; - V_DrawString(x, y, highlightflags, str2); - x -= w3; - V_DrawString(x, y, recommendedflags, str3); - V_DrawRightAlignedString(x, y, highlightflags, "("); -} - // =============== // Monitor Toggles // =============== From fb5ddf44d6d0d133ccf08e4faaa7d2eea8bb4c6e Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Sun, 5 Aug 2018 16:35:33 +0100 Subject: [PATCH 35/38] Improve y_inter.c levelname setting. --- src/y_inter.c | 69 +++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 29c81df0..93459811 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -87,7 +87,7 @@ typedef union INT32 num[MAXPLAYERS]; // Winner's player # char *name[MAXPLAYERS]; // Winner's name INT32 numplayers; // Number of players being displayed - char levelstring[62]; // holds levelnames up to 32 characters + char levelstring[64]; // holds levelnames up to 64 characters // SRB2kart UINT8 increase[MAXPLAYERS]; //how much did the score increase by? UINT32 val[MAXPLAYERS]; //Gametype-specific value @@ -204,6 +204,39 @@ static void Y_CalculateMatchData(boolean rankingsmode, void (*comparison)(INT32) // Initialize variables if ((data.match.rankingsmode = rankingsmode)) sprintf(data.match.levelstring, "* Total Rankings *"); + else + { + // set up the levelstring + if (mapheaderinfo[prevmap]->levelflags & LF_NOZONE) + { + if (mapheaderinfo[prevmap]->actnum[0]) + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %s %s *", + mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); + else + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %s *", + mapheaderinfo[prevmap]->lvlttl); + } + else + { + const char *zonttl = (mapheaderinfo[prevmap]->zonttl[0] ? mapheaderinfo[prevmap]->zonttl : "ZONE"); + if (mapheaderinfo[prevmap]->actnum[0]) + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %s %s %s *", + mapheaderinfo[prevmap]->lvlttl, zonttl, mapheaderinfo[prevmap]->actnum); + else + snprintf(data.match.levelstring, + sizeof data.match.levelstring, + "* %s %s *", + mapheaderinfo[prevmap]->lvlttl, zonttl); + } + + data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; + } for (i = 0; i < MAXPLAYERS; i++) { @@ -491,7 +524,7 @@ dotimer: { INT32 tickdown = (timer+1)/TICRATE; V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, - va("%s in %d", cv_advancemap.string, tickdown)); + va("%s starts in %d", cv_advancemap.string, tickdown)); } // Make it obvious that scrambling is happening next round. @@ -750,38 +783,8 @@ void Y_StartIntermission(void) break; } - if (intertype == int_race || intertype == int_match) + //if (intertype == int_race || intertype == int_match) { - // set up the levelstring - if (strlen(mapheaderinfo[prevmap]->zonttl) > 0) - { - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s %.32s %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s %.32s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl); - } - else - { - if (strlen(mapheaderinfo[prevmap]->actnum) > 0) - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s %s *", - mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); - else - snprintf(data.match.levelstring, - sizeof data.match.levelstring, - "* %.32s *", - mapheaderinfo[prevmap]->lvlttl); - } - - data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - //bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); usetile = useinterpic = false; usebuffer = true; From 59c64e1ec700b983c55e3f92f10b86d5be9031ea Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Sun, 5 Aug 2018 16:38:46 +0100 Subject: [PATCH 36/38] * Change/add a handful of sounds. * Make Orbinaut Shields animate at 3 tics per frame, not 1. * Make dead items flash in and out of visibility. * Related to above, fix a few circumstances where returning was not properly handled after removing a mobj in mobjthinker. --- src/info.c | 14 +++++++------- src/k_kart.c | 13 +++++++++++-- src/p_mobj.c | 16 +++++++++++++++- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/info.c b/src/info.c index 8c6560fc..0fa1e1dd 100644 --- a/src/info.c +++ b/src/info.c @@ -2646,12 +2646,12 @@ state_t states[NUMSTATES] = {SPR_ORBN, 4, 1, {NULL}, 0, 0, S_ORBINAUT6}, // S_ORBINAUT5 {SPR_ORBN, 5, 1, {NULL}, 0, 0, S_ORBINAUT1}, // S_ORBINAUT6 {SPR_ORBN, 0, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_DEAD - {SPR_ORBN, 6, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD2}, // S_ORBINAUT_SHIELD1 - {SPR_ORBN, 7, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD3}, // S_ORBINAUT_SHIELD2 - {SPR_ORBN, 8, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD4}, // S_ORBINAUT_SHIELD3 - {SPR_ORBN, 9, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD5}, // S_ORBINAUT_SHIELD4 - {SPR_ORBN, 10, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD6}, // S_ORBINAUT_SHIELD5 - {SPR_ORBN, 11, 1, {NULL}, 0, 0, S_ORBINAUT_SHIELD1}, // S_ORBINAUT_SHIELD6 + {SPR_ORBN, 6, 3, {NULL}, 0, 0, S_ORBINAUT_SHIELD2}, // S_ORBINAUT_SHIELD1 + {SPR_ORBN, 7, 3, {NULL}, 0, 0, S_ORBINAUT_SHIELD3}, // S_ORBINAUT_SHIELD2 + {SPR_ORBN, 8, 3, {NULL}, 0, 0, S_ORBINAUT_SHIELD4}, // S_ORBINAUT_SHIELD3 + {SPR_ORBN, 9, 3, {NULL}, 0, 0, S_ORBINAUT_SHIELD5}, // S_ORBINAUT_SHIELD4 + {SPR_ORBN, 10, 3, {NULL}, 0, 0, S_ORBINAUT_SHIELD6}, // S_ORBINAUT_SHIELD5 + {SPR_ORBN, 11, 3, {NULL}, 0, 0, S_ORBINAUT_SHIELD1}, // S_ORBINAUT_SHIELD6 {SPR_ORBN, 6, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_SHIELDDEAD {SPR_JAWZ, 0, 1, {A_JawzChase}, 0, 0, S_JAWZ2}, // S_JAWZ1 @@ -14816,7 +14816,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 100, // mass 1, // damage - sfx_bomb, // activesound + sfx_s3k5c, // activesound MF_BOUNCE|MF_SHOOTABLE, // flags S_NULL // raisestate }, diff --git a/src/k_kart.c b/src/k_kart.c index 080e7a11..7442d85f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3647,6 +3647,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) //K_PlayTauntSound(player->mo); player->kartstuff[k_itemheld] = 1; player->pflags |= PF_ATTACKDOWN; + S_StartSound(player->mo, sfx_s254); for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) { @@ -3677,6 +3678,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->kartstuff[k_itemamount]--; player->kartstuff[k_eggmanheld] = 1; player->pflags |= PF_ATTACKDOWN; + S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FAKESHIELD); mo->threshold = 10; mo->movecount = 1; @@ -3782,6 +3784,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mobj_t *mo; player->kartstuff[k_itemheld] = 1; player->pflags |= PF_ATTACKDOWN; + S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SSMINE_SHIELD); mo->threshold = 10; mo->movecount = 1; @@ -3892,7 +3895,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->kartstuff[k_itemamount]--; player->pflags |= PF_ATTACKDOWN; - K_DoHyudoroSteal(player); + K_DoHyudoroSteal(player); // yes. yes they do. } break; case KITEM_POGOSPRING: @@ -4089,8 +4092,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) // Determine the outcome of your charge. if (leveltime > starttime && player->kartstuff[k_boostcharge]) { + // Not even trying? + if (player->kartstuff[k_boostcharge] < 35) + { + if (player->kartstuff[k_boostcharge] > 17) + S_StartSound(player->mo, sfx_cdfm00); // chosen instead of a conventional skid because it's more engine-like + } // Get an instant boost! - if (player->kartstuff[k_boostcharge] >= 35 && player->kartstuff[k_boostcharge] <= 50) + else if (player->kartstuff[k_boostcharge] <= 50) { player->kartstuff[k_sneakertimer] = -((21*(player->kartstuff[k_boostcharge]*player->kartstuff[k_boostcharge]))/425)+131; // max time is 70, min time is 7; yay parabooolas if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) diff --git a/src/p_mobj.c b/src/p_mobj.c index c2c08f33..016734bd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7462,12 +7462,23 @@ void P_MobjThinker(mobj_t *mobj) case MT_BANANA: case MT_FAKEITEM: if (mobj->z <= mobj->floorz) + { P_RemoveMobj(mobj); + return; + } + // fallthru + case MT_ORBINAUT_SHIELD: + case MT_BANANA_SHIELD: + case MT_FAKESHIELD: + mobj->flags2 ^= MF2_DONTDRAW; break; case MT_JAWZ: case MT_JAWZ_DUD: if (mobj->z <= mobj->floorz) P_SetMobjState(mobj, mobj->info->xdeathstate); + // fallthru + case MT_JAWZ_SHIELD: + mobj->flags2 ^= MF2_DONTDRAW; break; case MT_SSMINE: case MT_BLUEEXPLOSION: @@ -7477,11 +7488,14 @@ void P_MobjThinker(mobj_t *mobj) mobj->health = -100; } else + { P_RemoveMobj(mobj); + return; + } break; case MT_MINEEXPLOSIONSOUND: P_RemoveMobj(mobj); - break; + return; //} default: break; From 2abf256531cf37f47c2779e681557b090afcb1bd Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Mon, 6 Aug 2018 16:19:07 +0100 Subject: [PATCH 37/38] * Fix various instances where bananadrag might not be reset. * Improve K_KillBananaChain to be tail recursive. --- src/k_kart.c | 23 +++++++++++++++++------ src/p_inter.c | 3 +++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 7442d85f..a395ad1d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2440,6 +2440,8 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map } else { + player->kartstuff[k_bananadrag] = 0; // RESET timer, for multiple bananas + if (dir == 1 || dir == 2) { // Shoot forward @@ -2476,8 +2478,6 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map { mobj_t *lasttrail = K_FindLastTrailMobj(player); - player->kartstuff[k_bananadrag] = 0; // RESET timer, for multiple bananas - if (lasttrail) { newx = lasttrail->x; @@ -2724,10 +2724,10 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute) void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source) { - if (banana->hnext) - { - K_KillBananaChain(banana->hnext, inflictor, source); - } + mobj_t *cachenext; + +killnext: + cachenext = banana->hnext; if (banana->health) { @@ -2743,6 +2743,9 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source) if (inflictor) P_InstaThrust(banana, R_PointToAngle2(inflictor->x, inflictor->y, banana->x, banana->y)+ANGLE_90, 16*FRACUNIT); } + + if ((banana = cachenext)) + goto killnext; } void K_RepairOrbitChain(mobj_t *orbit) @@ -2796,6 +2799,14 @@ static void K_MoveHeldObjects(player_t *player) return; } + if (P_MobjWasRemoved(player->mo->hnext)) + { + // we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic... + P_SetTarget(&player->mo->hnext, NULL); + player->kartstuff[k_bananadrag] = 0; + return; + } + switch (player->mo->hnext->type) { case MT_ORBINAUT_SHIELD: // Kart orbit items diff --git a/src/p_inter.c b/src/p_inter.c index 6ca5e6c2..913d1722 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2183,6 +2183,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) if (!target->target->player->kartstuff[k_itemamount]) target->target->player->kartstuff[k_itemheld] = 0; + + if (target->target->hnext == target) + P_SetTarget(&target->target->hnext, NULL); } } // From c256f2ae299ced5b41ea5356bb430223bc83f0ff Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Mon, 6 Aug 2018 18:37:03 +0100 Subject: [PATCH 38/38] * Tweak battle odds in a few ways, as authorised by Sal. * Steal a point from Ballhog and give to Orbinaut. * Make it based on the maximum number of bumpers someone has, not the average for everyone. * Improve the odds a tad if you're Wanted. * Tweak the score multiplication to give three points for Wanted and two for removing the last bumper (both disabled if you get the hit with a fake item). * Allow Karma players to drop their Random box. * These boxes flicker out of existence after 15 seconds. * Causes a WAIT penalty, too. * Remove some redundant PF_ATTACKDOWN stuff, given under the conditions the flag would be applied, it has definitely *already* been applied. --- src/k_kart.c | 74 ++++++++++++++++++++++++++++++++------------------- src/p_enemy.c | 4 +-- src/p_mobj.c | 25 ++++++++++------- 3 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index a395ad1d..31cbbaea 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -495,10 +495,10 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] = /*Invincibility*/ { 4, 2, 1, 2 }, // Invincibility /*Banana*/ { 0, 0, 2, 0 }, // Banana /*Eggman Monitor*/ { 0, 0, 1, 0 }, // Eggman Monitor - /*Orbinaut*/ { 0, 1, 4, 0 }, // Orbinaut + /*Orbinaut*/ { 0, 1, 5, 0 }, // Orbinaut /*Jawz*/ { 1, 3, 2, 2 }, // Jawz /*Mine*/ { 1, 3, 2, 2 }, // Mine - /*Ballhog*/ { 1, 2, 2, 2 }, // Ballhog + /*Ballhog*/ { 1, 2, 1, 2 }, // Ballhog /*Self-Propelled Bomb*/ { 0, 0, 0, 0 }, // Self-Propelled Bomb /*Grow*/ { 4, 2, 0, 2 }, // Grow /*Shrink*/ { 0, 0, 0, 0 }, // Shrink @@ -732,7 +732,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) INT32 pdis = 0, useodds = 0; INT32 spawnchance[NUMKARTRESULTS * NUMKARTODDS]; INT32 chance = 0, numchoices = 0; - INT32 avgbumper = 0; + INT32 bestbumper = 0; boolean oddsvalid[9]; UINT8 disttable[14]; UINT8 distlen = 0; @@ -750,13 +750,10 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) if (!playeringame[i] || players[i].spectator) continue; pingame++; - if (players[i].kartstuff[k_bumper] > 0) - avgbumper += players[i].kartstuff[k_bumper]; + if (players[i].kartstuff[k_bumper] > bestbumper) + bestbumper = players[i].kartstuff[k_bumper]; } - if (pingame) - avgbumper /= pingame; - // This makes the roulette produce the random noises. if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player)) S_StartSound(NULL, sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8)); @@ -836,7 +833,9 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) useodds = 3; else { - SINT8 wantedpos = (player->kartstuff[k_bumper]-avgbumper)+2; // 0 is two bumpers below average, 2 is average + SINT8 wantedpos = (player->kartstuff[k_bumper]-bestbumper)+2; // 0 is two bumpers below best player's bumper count, 2 is best player's bumper count + if (K_IsPlayerWanted(player)) + wantedpos--; if (wantedpos > 2) wantedpos = 2; if (wantedpos < 0) @@ -1614,7 +1613,14 @@ void K_DoInstashield(player_t *player) void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem) { - const UINT8 scoremultiply = ((K_IsPlayerWanted(player) && !trapitem) ? 2 : 1); + UINT8 scoremultiply = 1; + if (!trapitem && G_BattleGametype()) + { + if (K_IsPlayerWanted(player)) + scoremultiply = 3; + else if (player->kartstuff[k_bumper] == 1) + scoremultiply = 2; + } if (player->health <= 0) return; @@ -1691,7 +1697,14 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem void K_SquishPlayer(player_t *player, mobj_t *source) { - const UINT8 scoremultiply = (K_IsPlayerWanted(player) ? 2 : 1); + UINT8 scoremultiply = 1; + if (G_BattleGametype()) + { + if (K_IsPlayerWanted(player)) + scoremultiply = 3; + else if (player->kartstuff[k_bumper] == 1) + scoremultiply = 2; + } if (player->health <= 0) return; @@ -1753,7 +1766,14 @@ void K_SquishPlayer(player_t *player, mobj_t *source) void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer { - const UINT8 scoremultiply = (K_IsPlayerWanted(player) ? 2 : 1); + UINT8 scoremultiply = 1; + if (G_BattleGametype()) + { + if (K_IsPlayerWanted(player)) + scoremultiply = 3; + else if (player->kartstuff[k_bumper] == 1) + scoremultiply = 2; + } if (player->health <= 0) return; @@ -3593,8 +3613,22 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player && player->mo && player->mo->health > 0 && !player->spectator && !(player->exiting || mapreset) && player->kartstuff[k_spinouttimer] == 0) { // First, the really specific, finicky items that function without the item being directly in your item slot. + // Karma item dropping + if (ATTACK_IS_DOWN && player->kartstuff[k_comebackmode] && !player->kartstuff[k_comebacktimer]) + { + mobj_t *newitem; + + player->kartstuff[k_comebackmode] = 0; + player->kartstuff[k_comebacktimer] = comebacktime; + S_StartSound(player->mo, sfx_s254); + + newitem = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RANDOMITEM); + newitem->flags2 = (player->mo->flags2 & MF2_OBJECTFLIP); + newitem->fuse = 15*TICRATE; // selected randomly. + newitem->threshold = 69; // selected "randomly". + } // Eggman Monitor throwing - if (ATTACK_IS_DOWN && player->kartstuff[k_eggmanheld]) + else if (ATTACK_IS_DOWN && player->kartstuff[k_eggmanheld]) { K_ThrowKartItem(player, false, MT_FAKEITEM, -1, false); K_PlayTauntSound(player->mo); @@ -3645,7 +3679,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) S_StartSound(player->mo, sfx_kinvnc); K_PlayTauntSound(player->mo); player->kartstuff[k_itemamount]--; - player->pflags |= PF_ATTACKDOWN; } break; case KITEM_BANANA: @@ -3657,7 +3690,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) //K_PlayTauntSound(player->mo); player->kartstuff[k_itemheld] = 1; - player->pflags |= PF_ATTACKDOWN; S_StartSound(player->mo, sfx_s254); for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) @@ -3676,7 +3708,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { K_ThrowKartItem(player, false, MT_BANANA, -1, false); K_PlayTauntSound(player->mo); - player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemamount]--; if (!player->kartstuff[k_itemamount]) player->kartstuff[k_itemheld] = 0; @@ -3688,7 +3719,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mobj_t *mo; player->kartstuff[k_itemamount]--; player->kartstuff[k_eggmanheld] = 1; - player->pflags |= PF_ATTACKDOWN; S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FAKESHIELD); mo->threshold = 10; @@ -3713,7 +3743,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) //K_PlayTauntSound(player->mo); player->kartstuff[k_itemheld] = 1; - player->pflags |= PF_ATTACKDOWN; S_StartSound(player->mo, sfx_s3k3a); for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) @@ -3737,7 +3766,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { K_ThrowKartItem(player, true, MT_ORBINAUT, 1, false); K_PlayTauntSound(player->mo); - player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemamount]--; if (!player->kartstuff[k_itemamount]) @@ -3756,7 +3784,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) //K_PlayTauntSound(player->mo); player->kartstuff[k_itemheld] = 1; - player->pflags |= PF_ATTACKDOWN; S_StartSound(player->mo, sfx_s3k3a); for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++) @@ -3782,7 +3809,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else if (player->kartstuff[k_throwdir] == -1) // Throwing backward gives you a dud that doesn't home in K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, false); K_PlayTauntSound(player->mo); - player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemamount]--; if (!player->kartstuff[k_itemamount]) @@ -3794,7 +3820,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { mobj_t *mo; player->kartstuff[k_itemheld] = 1; - player->pflags |= PF_ATTACKDOWN; S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SSMINE_SHIELD); mo->threshold = 10; @@ -3856,7 +3881,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) spbplayer = player-players; - player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemamount]--; K_PlayTauntSound(player->mo); @@ -3876,7 +3900,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (!cv_kartinvinsfx.value && !P_IsLocalPlayer(player)) S_StartSound(player->mo, sfx_kgrow); S_StartSound(player->mo, sfx_kc5a); - player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemamount]--; } break; @@ -3897,7 +3920,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { K_DoThunderShield(player); - player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemamount]--; } break; @@ -3905,7 +3927,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { player->kartstuff[k_itemamount]--; - player->pflags |= PF_ATTACKDOWN; K_DoHyudoroSteal(player); // yes. yes they do. } break; @@ -3915,7 +3936,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { K_PlayTauntSound(player->mo); K_DoPogoSpring(player->mo, 32<<FRACBITS, false); - player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_pogospring] = 1; player->kartstuff[k_itemamount]--; } diff --git a/src/p_enemy.c b/src/p_enemy.c index a9333777..1e66fb82 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8142,7 +8142,7 @@ void A_ItemPop(mobj_t *actor) remains->flags = actor->flags; // Transfer flags remains->flags2 = actor->flags2; // Transfer flags2 remains->fuse = actor->fuse; // Transfer respawn timer - remains->threshold = 68; + remains->threshold = (actor->threshold = 69 ? 69 : 68); remains->skin = NULL; remains->spawnpoint = actor->spawnpoint; @@ -8156,7 +8156,7 @@ void A_ItemPop(mobj_t *actor) remains->flags2 &= ~MF2_AMBUSH; - if (G_BattleGametype()) + if (G_BattleGametype() && actor->threshold != 69) numgotboxes++; P_RemoveMobj(actor); diff --git a/src/p_mobj.c b/src/p_mobj.c index 016734bd..5af79ae8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8572,19 +8572,24 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s return; case MT_RANDOMITEM: if (G_BattleGametype()) - break; - - // Respawn from mapthing if you have one! - if (mobj->spawnpoint) { - P_SpawnMapThing(mobj->spawnpoint); - newmobj = mobj->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing + if (mobj->threshold != 69) + break; } else - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); + { + // Respawn from mapthing if you have one! + if (mobj->spawnpoint) + { + P_SpawnMapThing(mobj->spawnpoint); + newmobj = mobj->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing + } + else + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); - // Transfer flags2 (strongbox, objectflip) - newmobj->flags2 = mobj->flags2; + // Transfer flags2 (strongbox, objectflip) + newmobj->flags2 = mobj->flags2; + } P_RemoveMobj(mobj); // make sure they disappear return; case MT_METALSONIC_BATTLE: @@ -8607,6 +8612,8 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s if (P_MobjWasRemoved(mobj)) return; } + else if (mobj->type == MT_RANDOMITEM && mobj->threshold == 69 && mobj->fuse <= TICRATE) + mobj->flags2 ^= MF2_DONTDRAW; } I_Assert(mobj != NULL);