diff --git a/CMakeLists.txt b/CMakeLists.txt index bc4f6ec6b..0d37514f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") # Set EXE names so the assets CMakeLists can refer to its target -set(SRB2_SDL2_EXE_NAME srb2kart CACHE STRING "Executable binary output name") +set(SRB2_SDL2_EXE_NAME ringracers CACHE STRING "Executable binary output name") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) @@ -146,7 +146,7 @@ if("${SRB2_CPACK_GENERATOR}" STREQUAL "") endif() set(CPACK_GENERATOR ${SRB2_CPACK_GENERATOR}) -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2 Kart" CACHE STRING "Program name for display purposes") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Dr. Robotnik's Ring Racers" CACHE STRING "Program name for display purposes") set(CPACK_PACKAGE_VENDOR "Kart Krew" CACHE STRING "Vendor name for display purposes") #set(CPACK_PACKAGE_DESCRIPTION_FILE ) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") diff --git a/srb2.png b/srb2.png index fccde9c3f..dd84db0a0 100644 Binary files a/srb2.png and b/srb2.png differ diff --git a/srb2banner.png b/srb2banner.png index 9c13eae9a..ee4d3230e 100644 Binary files a/srb2banner.png and b/srb2banner.png differ diff --git a/src/Makefile b/src/Makefile index 9659a4994..904aa0bbe 100644 --- a/src/Makefile +++ b/src/Makefile @@ -235,7 +235,7 @@ bin:=../bin endif # default EXENAME (usually set by platform) -EXENAME?=srb2 +EXENAME?=ringracers DBGNAME?=$(EXENAME).debug exe:=$(bin)/$(EXENAME) diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk index 98703e769..97bcf018e 100644 --- a/src/Makefile.d/nix.mk +++ b/src/Makefile.d/nix.mk @@ -2,8 +2,6 @@ # Makefile options for unices (linux, bsd...) # -EXENAME?=lsdl2srb2kart - opts+=-DUNIXCOMMON -DLUA_USE_POSIX libs+=-lm diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index 83edc3c45..3f93ddeaf 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -3,9 +3,9 @@ # ifndef MINGW64 -EXENAME?=srb2kart.exe +EXENAME?=ringracers.exe else -EXENAME?=srb2kart64.exe +EXENAME?=ringracers64.exe endif # disable dynamicbase if under msys2 diff --git a/src/console.c b/src/console.c index cfdede56c..7cbcb85a9 100644 --- a/src/console.c +++ b/src/console.c @@ -1553,7 +1553,7 @@ void CONS_Error(const char *msg) #if defined(RPC_NO_WINDOWS_H) && defined(_WINDOWS) if (!graphics_started) { - MessageBoxA(vid.WndParent, msg, "SRB2Kart Warning", MB_OK); + MessageBoxA(vid.WndParent, msg, "Dr. Robotnik's Ring Racers Warning", MB_OK); return; } #endif diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 5a947531a..14570e22d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1515,7 +1515,7 @@ static boolean CL_FinishedFileList(void) M_StartMessage(M_GetText( "You have too many WAD files loaded\n" "to add ones the server is using.\n" - "Please restart SRB2Kart before connecting.\n\n" + "Please restart Ring Racers before connecting.\n\n" "Press ESC\n" ), NULL, MM_NOTHING); return false; @@ -1529,7 +1529,7 @@ static boolean CL_FinishedFileList(void) "You have the wrong addons loaded.\n\n" "To play on this server, restart\n" "the game and don't load any addons.\n" - "SRB2Kart will automatically add\n" + "Ring Racers will automatically add\n" "everything you need when you join.\n\n" "Press ESC\n" ), NULL, MM_NOTHING); @@ -3116,7 +3116,7 @@ static void Joinable_OnChange(void) // called one time at init void D_ClientServerInit(void) { - DEBFILE(va("- - -== SRB2Kart v%d.%d "VERSIONSTRING" debugfile ==- - -\n", + DEBFILE(va("- - -== Ring Racers v%d.%d "VERSIONSTRING" debugfile ==- - -\n", VERSION, SUBVERSION)); #ifndef NONET @@ -3464,7 +3464,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum) { INT16 newplayernum; UINT8 skinnum = 0; - UINT8 difficulty = MAXBOTDIFFICULTY; + UINT8 difficulty = DIFFICULTBOT; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -3768,10 +3768,10 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, "Incompatible packet formats."); else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION, sizeof netbuffer->u.clientcfg.application)) - SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible."); + SV_SendRefuse(node, "Different Ring Racers modifications\nare not compatible."); else if (netbuffer->u.clientcfg.version != VERSION || netbuffer->u.clientcfg.subversion != SUBVERSION) - SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d)"), VERSION, SUBVERSION)); + SV_SendRefuse(node, va(M_GetText("Different Ring Racers versions cannot\nplay a netgame!\n(server version %d.%d)"), VERSION, SUBVERSION)); else if (!cv_allownewplayer.value && node) SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment.")); else if (D_NumPlayers() >= maxplayers) @@ -4195,7 +4195,8 @@ static void HandlePacketFromAwayNode(SINT8 node) static boolean CheckForSpeedHacks(UINT8 p) { if (netcmds[maketic%BACKUPTICS][p].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][p].forwardmove < -MAXPLMOVE - || netcmds[maketic%BACKUPTICS][p].turning > KART_FULLTURN || netcmds[maketic%BACKUPTICS][p].turning < -KART_FULLTURN) + || netcmds[maketic%BACKUPTICS][p].turning > KART_FULLTURN || netcmds[maketic%BACKUPTICS][p].turning < -KART_FULLTURN + || netcmds[maketic%BACKUPTICS][p].throwdir > KART_FULLTURN || netcmds[maketic%BACKUPTICS][p].throwdir < -KART_FULLTURN) { CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), playernode[p]); //D_Clearticcmd(k); @@ -5144,6 +5145,8 @@ static void SV_Maketic(void) { INT32 i; + ps_botticcmd_time = 0; + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) @@ -5151,7 +5154,9 @@ static void SV_Maketic(void) if (K_PlayerUsesBotMovement(&players[i])) { + precise_t t = I_GetPreciseTime(); K_BuildBotTiccmd(&players[i], &netcmds[maketic%BACKUPTICS][i]); + ps_botticcmd_time += I_GetPreciseTime() - t; continue; } diff --git a/src/d_main.c b/src/d_main.c index 55b55c15c..51cab6a30 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1237,8 +1237,8 @@ void D_SRB2Main(void) // Print GPL notice for our console users (Linux) CONS_Printf( - "\n\nSonic Robo Blast 2 Kart\n" - "Copyright (C) 1998-2020 by Kart Krew & STJr\n\n" + "\n\nDr. Robotnik's Ring Racers\n" + "Copyright (C) 1998-2022 by Kart Krew & STJr\n\n" "This program comes with ABSOLUTELY NO WARRANTY.\n\n" "This is free software, and you are welcome to redistribute it\n" "and/or modify it under the terms of the GNU General Public License\n" diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b4fb2f938..735a79f04 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -373,7 +373,7 @@ consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR|CV_CHEAT, CV consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_thundershield = CVAR_INIT ("thundershield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_lightningshield = CVAR_INIT ("lightningshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); @@ -418,9 +418,13 @@ static CV_PossibleValue_t kartbot_cons_t[] = { {7, "Lv.7"}, {8, "Lv.8"}, {9, "Lv.9"}, + {10,"Lv.10"}, + {11,"Lv.11"}, + {12,"Lv.12"}, + {13,"Lv.MAX"}, {0, NULL} }; -consvar_t cv_kartbot = CVAR_INIT ("kartbot", "0", CV_NETVAR|CV_CHEAT, kartbot_cons_t, NULL); +consvar_t cv_kartbot = CVAR_INIT ("kartbot", "0", CV_NETVAR, kartbot_cons_t, NULL); consvar_t cv_karteliminatelast = CVAR_INIT ("karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL, CV_YesNo, KartEliminateLast_OnChange); @@ -4321,9 +4325,9 @@ static void Command_ListDoomednums_f(void) static void Command_Version_f(void) { #ifdef DEVELOP - CONS_Printf("SRB2Kart %s-%s (%s %s)\n", compbranch, comprevision, compdate, comptime); + CONS_Printf("Ring Racers %s-%s (%s %s)\n", compbranch, comprevision, compdate, comptime); #else - CONS_Printf("SRB2Kart %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch); + CONS_Printf("Ring Racers %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch); #endif // Base library diff --git a/src/d_netcmd.h b/src/d_netcmd.h index fb3a5ab03..e9c9b8f32 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -72,7 +72,7 @@ extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_ingamecap, cv_res extern consvar_t cv_superring, cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana; extern consvar_t cv_eggmanmonitor, cv_orbinaut, cv_jawz, cv_mine, cv_landmine, cv_droptarget; extern consvar_t cv_ballhog, cv_selfpropelledbomb, cv_grow, cv_shrink; -extern consvar_t cv_thundershield, cv_bubbleshield, cv_flameshield; +extern consvar_t cv_lightningshield, cv_bubbleshield, cv_flameshield; extern consvar_t cv_hyudoro, cv_pogospring, cv_kitchensink; extern consvar_t cv_dualsneaker, cv_triplesneaker, cv_triplebanana, cv_decabanana; diff --git a/src/d_netfil.c b/src/d_netfil.c index 18b07b94c..2f18dfc27 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1725,7 +1725,7 @@ void CURLPrepareFile(const char* url, int dfilenum) // Only allow HTTP and HTTPS curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); - curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d", VERSION, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. + curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("Ring Racers/v%d.%d", VERSION, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. // Authenticate if the user so wishes login = CURLGetLogin(url, NULL); diff --git a/src/d_player.h b/src/d_player.h index 60ca7c4bd..10f86f719 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -145,7 +145,7 @@ Run this macro, then #undef FOREACH afterward FOREACH (SPB, 11),\ FOREACH (GROW, 12),\ FOREACH (SHRINK, 13),\ - FOREACH (THUNDERSHIELD, 14),\ + FOREACH (LIGHTNINGSHIELD, 14),\ FOREACH (BUBBLESHIELD, 15),\ FOREACH (FLAMESHIELD, 16),\ FOREACH (HYUDORO, 17),\ @@ -177,7 +177,7 @@ typedef enum typedef enum { KSHIELD_NONE = 0, - KSHIELD_THUNDER = 1, + KSHIELD_LIGHTNING = 1, KSHIELD_BUBBLE = 2, KSHIELD_FLAME = 3, NUMKARTSHIELDS @@ -402,6 +402,8 @@ typedef struct player_s UINT8 justbumped; // Prevent players from endlessly bumping into each other UINT8 tumbleBounces; UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu + boolean justDI; // Directional Influence ended, true until letting go of turn + boolean flipDI; // Bananas flip the DI direction. Was a bug, but it made bananas much more interesting. SINT8 drift; // (-5 to 5) - Drifting Left or Right, plus a bigger counter = sharper turn fixed_t driftcharge; // Charge your drift so you can release a burst of speed diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index c806f2642..637f3fc71 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -26,18 +26,16 @@ // Button/action code definitions. typedef enum { - BT_ACCELERATE = 1, // Accelerate - BT_DRIFT = 1<<2, // Drift (direction is cmd->turning) - BT_BRAKE = 1<<3, // Brake - BT_ATTACK = 1<<4, // Use Item - BT_FORWARD = 1<<5, // Aim Item Forward - BT_BACKWARD = 1<<6, // Aim Item Backward - BT_LOOKBACK = 1<<7, // Look Backward + BT_ACCELERATE = 1, // Accelerate + BT_DRIFT = 1<<2, // Drift (direction is cmd->turning) + BT_BRAKE = 1<<3, // Brake + BT_ATTACK = 1<<4, // Use Item + BT_LOOKBACK = 1<<5, // Look Backward BT_EBRAKEMASK = (BT_ACCELERATE|BT_BRAKE), BT_SPINDASHMASK = (BT_ACCELERATE|BT_BRAKE|BT_DRIFT), - // free: 1<<9 to 1<<12 + // free: 1<<6 to 1<<12 // Lua garbage BT_LUAA = 1<<13, @@ -66,6 +64,7 @@ typedef struct { SINT8 forwardmove; // -MAXPLMOVE to MAXPLMOVE (50) INT16 turning; // Turn speed + INT16 throwdir; // Aiming direction INT16 aiming; // vertical aiming, see G_BuildTicCmd UINT16 buttons; UINT8 latency; // Netgames: how many tics ago was this ticcmd generated from this player's end? diff --git a/src/deh_lua.c b/src/deh_lua.c index 6d5c0135f..9ac218c26 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -436,16 +436,6 @@ static inline int lib_getenum(lua_State *L) } return luaL_error(L, "karthud '%s' could not be found.\n", word); } - else if (fastncmp("HUD_",word,4)) { - p = word+4; - for (i = 0; i < NUMHUDITEMS; i++) - if (fastcmp(p, HUDITEMS_LIST[i])) { - lua_pushinteger(L, i); - return 1; - } - if (mathlib) return luaL_error(L, "huditem '%s' could not be found.\n", word); - return 0; - } else if (fastncmp("SKINCOLOR_",word,10)) { p = word+10; for (i = 0; i < NUMCOLORFREESLOTS; i++) { diff --git a/src/deh_soc.c b/src/deh_soc.c index a1586cf2a..525b7e1d2 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2026,66 +2026,6 @@ void readtextprompt(MYFILE *f, INT32 num) Z_Free(s); } -void readhuditem(MYFILE *f, INT32 num) -{ - char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - char *word = s; - char *word2; - char *tmp; - INT32 i; - - do - { - if (myfgets(s, MAXLINELEN, f)) - { - if (s[0] == '\n') - break; - - // First remove trailing newline, if there is one - tmp = strchr(s, '\n'); - if (tmp) - *tmp = '\0'; - - tmp = strchr(s, '#'); - if (tmp) - *tmp = '\0'; - if (s == tmp) - continue; // Skip comment lines, but don't break. - - // Get the part before the " = " - tmp = strchr(s, '='); - if (tmp) - *(tmp-1) = '\0'; - else - break; - strupr(word); - - // Now get the part after - word2 = tmp += 2; - strupr(word2); - - i = atoi(word2); // used for numerical settings - - if (fastcmp(word, "X")) - { - hudinfo[num].x = i; - } - else if (fastcmp(word, "Y")) - { - hudinfo[num].y = i; - } - else if (fastcmp(word, "F")) - { - hudinfo[num].f = i; - } - else - deh_warning("Level header %d: unknown word '%s'", num, word); - } - } while (!myfeof(f)); // finish when the line is empty - - Z_Free(s); -} - void readframe(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -3064,7 +3004,9 @@ void readmaincfg(MYFILE *f) ttname[0] = 0; hidetitlepics = true; } - else // if (fastcmp(word2, "OLD") || fastcmp(word2, "SSNTAILS")) + else if (fastcmp(word2, "RINGRACERS")) + ttmode = TTMODE_RINGRACERS; + else if (fastcmp(word2, "OLD") || fastcmp(word2, "SSNTAILS")) ttmode = TTMODE_OLD; titlechanged = true; } @@ -3829,20 +3771,6 @@ sfxenum_t get_sfx(const char *word) return sfx_None; } -hudnum_t get_huditem(const char *word) -{ // Returns the value of HUD_ enumerations - hudnum_t i; - if (*word >= '0' && *word <= '9') - return atoi(word); - if (fastncmp("HUD_",word,4)) - word += 4; // take off the HUD_ - for (i = 0; i < NUMHUDITEMS; i++) - if (fastcmp(word, HUDITEMS_LIST[i])) - return i; - deh_warning("Couldn't find huditem named 'HUD_%s'",word); - return HUD_LIVES; -} - /*static INT16 get_gametype(const char *word) { // Returns the value of GT_ enumerations INT16 i; @@ -4072,11 +4000,6 @@ static fixed_t find_const(const char **rword) free(word); return 0; } - else if (fastncmp("HUD_",word,4)) { - r = get_huditem(word); - free(word); - return r; - } else if (fastncmp("GRADE_",word,6)) { char *p = word+6; diff --git a/src/deh_soc.h b/src/deh_soc.h index a055d96d5..1b92e9402 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -52,7 +52,6 @@ statenum_t get_state(const char *word); spritenum_t get_sprite(const char *word); playersprite_t get_sprite2(const char *word); sfxenum_t get_sfx(const char *word); -hudnum_t get_huditem(const char *word); //INT16 get_gametype(const char *word); //powertype_t get_power(const char *word); skincolornum_t get_skincolor(const char *word); diff --git a/src/deh_tables.c b/src/deh_tables.c index 421a2ecbd..c378d7acb 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3640,31 +3640,31 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SPB20", "S_SPB_DEAD", - // 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", + // Lightning Shield + "S_LIGHTNINGSHIELD1", + "S_LIGHTNINGSHIELD2", + "S_LIGHTNINGSHIELD3", + "S_LIGHTNINGSHIELD4", + "S_LIGHTNINGSHIELD5", + "S_LIGHTNINGSHIELD6", + "S_LIGHTNINGSHIELD7", + "S_LIGHTNINGSHIELD8", + "S_LIGHTNINGSHIELD9", + "S_LIGHTNINGSHIELD10", + "S_LIGHTNINGSHIELD11", + "S_LIGHTNINGSHIELD12", + "S_LIGHTNINGSHIELD13", + "S_LIGHTNINGSHIELD14", + "S_LIGHTNINGSHIELD15", + "S_LIGHTNINGSHIELD16", + "S_LIGHTNINGSHIELD17", + "S_LIGHTNINGSHIELD18", + "S_LIGHTNINGSHIELD19", + "S_LIGHTNINGSHIELD20", + "S_LIGHTNINGSHIELD21", + "S_LIGHTNINGSHIELD22", + "S_LIGHTNINGSHIELD23", + "S_LIGHTNINGSHIELD24", // Bubble Shield "S_BUBBLESHIELD1", @@ -3955,6 +3955,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_INSTASHIELDB6", "S_INSTASHIELDB7", + "S_POWERCLASH", // Invinc/Grow no damage collide VFX + "S_PLAYERARROW", // Above player arrow "S_PLAYERARROW_BOX", "S_PLAYERARROW_ITEM", @@ -4047,7 +4049,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_BATTLEPOINT3H", "S_BATTLEPOINT3I", - // Thunder shield use stuff; + // Lightning shield use stuff; "S_KSPARK1", // Sparkling Radius "S_KSPARK2", "S_KSPARK3", @@ -4413,6 +4415,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_BATTLECAPSULE_SUPPORT", "S_BATTLECAPSULE_SUPPORTFLY", + "S_WAYPOINTORB", + "S_WAYPOINTSPLAT", "S_EGOORB", "S_WATERTRAIL1", @@ -5304,7 +5308,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SPB", // Self-Propelled Bomb "MT_SPBEXPLOSION", - "MT_THUNDERSHIELD", // Shields + "MT_LIGHTNINGSHIELD", // Shields "MT_BUBBLESHIELD", "MT_FLAMESHIELD", "MT_FLAMESHIELDUNDERLAY", @@ -5384,6 +5388,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_INSTASHIELDA", "MT_INSTASHIELDB", + "MT_POWERCLASH", // Invinc/Grow no damage clash VFX + "MT_PLAYERARROW", "MT_PLAYERWANTED", @@ -6450,8 +6456,6 @@ struct int_const_s const INT_CONST[] = { {"BT_DRIFT",BT_DRIFT}, {"BT_BRAKE",BT_BRAKE}, {"BT_ATTACK",BT_ATTACK}, - {"BT_FORWARD",BT_FORWARD}, - {"BT_BACKWARD",BT_BACKWARD}, {"BT_LUAA",BT_LUAA}, // Lua customizable {"BT_LUAB",BT_LUAB}, // Lua customizable {"BT_LUAC",BT_LUAC}, // Lua customizable @@ -6611,7 +6615,7 @@ struct int_const_s const INT_CONST[] = { // kartshields_t {"KSHIELD_NONE",KSHIELD_NONE}, - {"KSHIELD_THUNDER",KSHIELD_THUNDER}, + {"KSHIELD_LIGHTNING",KSHIELD_LIGHTNING}, {"KSHIELD_BUBBLE",KSHIELD_BUBBLE}, {"KSHIELD_FLAME",KSHIELD_FLAME}, {"NUMKARTSHIELDS",NUMKARTSHIELDS}, diff --git a/src/dehacked.c b/src/dehacked.c index def220c61..ca933b7dc 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -485,18 +485,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ignorelines(f); } } - else if (fastcmp(word, "HUDITEM")) - { - if (i == 0 && word2[0] != '0') // If word2 isn't a number - i = get_huditem(word2); // find a huditem by name - if (i >= 0 && i < NUMHUDITEMS) - readhuditem(f, i); - else - { - deh_warning("HUD item number %d out of range (0 - %d)", i, NUMHUDITEMS-1); - ignorelines(f); - } - } else if (fastcmp(word, "UNLOCKABLE")) { if (!mainfile && !gamedataadded) @@ -566,7 +554,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) readcupheader(f, cup); } - else if (fastcmp(word, "SRB2KART")) + else if (fastcmp(word, "RINGRACERS")) { if (isdigit(word2[0])) { @@ -574,7 +562,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (i != PATCHVERSION) { deh_warning( - "Patch is for SRB2Kart version %d, " + "Patch is for Ring Racers version %d, " "only version %d is supported", i, PATCHVERSION @@ -584,12 +572,16 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) else { deh_warning( - "SRB2Kart version definition has incorrect format, " - "use \"SRB2KART %d\"", + "Ring Racers version definition has incorrect format, " + "use \"RINGRACERS %d\"", PATCHVERSION ); } } + else if (fastcmp(word, "SRB2KART")) + { + deh_warning("Patch is only compatible with SRB2Kart."); + } else if (fastcmp(word, "SRB2")) { deh_warning("Patch is only compatible with base SRB2."); diff --git a/src/discord.c b/src/discord.c index 7b3b0bec8..17dbf745c 100644 --- a/src/discord.c +++ b/src/discord.c @@ -32,7 +32,7 @@ #include "doomdef.h" // Feel free to provide your own, if you care enough to create another Discord app for this :P -#define DISCORD_APPID "503531144395096085" +#define DISCORD_APPID "977470696852684833" // length of IP strings #define IP_SIZE 21 diff --git a/src/doomdef.h b/src/doomdef.h index 5a9f542aa..7e1213be2 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -168,7 +168,7 @@ extern char logfilename[1024]; // The string used in the alert that pops up in the event of an update being available. // Please change to apply to your modification (we don't want everyone asking where your mod is on SRB2.org!). #define UPDATE_ALERT_STRING \ -"A new update is available for SRB2Kart.\n"\ +"A new update is available for Ring Racers.\n"\ "Please visit kartkrew.org to download it.\n"\ "\n"\ "You are using version: %s\n"\ @@ -444,9 +444,9 @@ enum { // Name of local directory for config files and savegames #if (((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON)) && !defined (__CYGWIN__)) && !defined (__APPLE__) -#define DEFAULTDIR ".srb2kart" +#define DEFAULTDIR ".ringracers" #else -#define DEFAULTDIR "srb2kart" +#define DEFAULTDIR "ringracers" #endif #include "g_state.h" diff --git a/src/f_finale.c b/src/f_finale.c index 14a353bef..481476363 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -46,7 +46,7 @@ // Stage of animation: // 0 = text, 1 = art screen INT32 finalecount; -INT32 titlescrollxspeed = 5; +INT32 titlescrollxspeed = 16; INT32 titlescrollyspeed = 0; UINT8 titlemapinaction = TITLEMAP_OFF; @@ -59,15 +59,13 @@ static tic_t stoptimer; static boolean keypressed = false; -static tic_t xscrolltimer; -static tic_t yscrolltimer; static INT32 menuanimtimer; // Title screen: background animation timing mobj_t *titlemapcameraref = NULL; // menu presentation state char curbgname[9]; SINT8 curfadevalue; -INT32 curbgcolor = 31; // Please stop assaulting my eyes. +INT32 curbgcolor = -1; // Please stop assaulting my eyes. INT32 curbgxspeed; INT32 curbgyspeed; boolean curbghide; @@ -82,7 +80,7 @@ static UINT32 demoIdleLeft; // customizable title screen graphics -ttmode_enum ttmode = TTMODE_OLD; +ttmode_enum ttmode = TTMODE_RINGRACERS; UINT8 ttscale = 1; // FRACUNIT / ttscale // ttmode user vars char ttname[9]; @@ -109,6 +107,13 @@ static patch_t *ttcheckers; // *vroom* KART static patch_t *ttkflash; // flash screen */ +static patch_t *kts_bumper; // DR ROBOTNIKS RING RACERS +static patch_t *kts_eggman; // dr. robotnik himself +static patch_t *kts_tails; // tails himself +static patch_t *kts_tails_tails; // tails' tails +static patch_t *kts_electricity[6]; // ring o' electricity +static patch_t *kts_copyright; // (C) SEGA + #define NOWAY #ifdef NOWAY @@ -522,7 +527,7 @@ boolean F_IntroResponder(event_t *event) // CREDITS // ========= static const char *credits[] = { - "\1SRB2Kart", + "\1Dr. Robotnik's Ring Racers", "\1Credits", "", "\1Game Design", @@ -1680,6 +1685,28 @@ void F_GameEndTicker(void) // TITLE SCREEN // ============== +static void F_InitMenuPresValues(void) +{ + menuanimtimer = 0; + + // Set defaults for presentation values + strncpy(curbgname, "TITLESKY", 9); + curfadevalue = 16; + curbgcolor = -1; + curbgxspeed = titlescrollxspeed; + curbgyspeed = titlescrollyspeed; + curbghide = false; + + curhidepics = hidetitlepics; + curttmode = ttmode; + curttscale = ttscale; + strncpy(curttname, ttname, 9); + curttx = ttx; + curtty = tty; + curttloop = ttloop; + curtttics = tttics; +} + // // F_SkyScroll // @@ -1693,24 +1720,26 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) INT32 pw, ph; // scaled by dupz patch_t *pat; INT32 i, j; + INT32 xscrolltimer, yscrolltimer; if (rendermode == render_none) return; + V_DrawFill(0, 0, vid.width, vid.height, 31); + if (!patchname || !patchname[0]) { - V_DrawFill(0, 0, vid.width, vid.height, 31); - return; - } - - if (!scrollxspeed && !scrollyspeed) - { - V_DrawPatchFill(W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY)); return; } pat = W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY); + if (scrollxspeed == 0 && scrollyspeed == 0) + { + V_DrawPatchFill(pat); + return; + } + patwidth = pat->width; patheight = pat->height; pw = patwidth * dupz; @@ -1740,8 +1769,6 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) V_NOSCALESTART, pat); } } - - W_UnlockCachedPatch(pat); } #define LOADTTGFX(arr, name, maxf) \ @@ -1772,15 +1799,30 @@ else \ static void F_CacheTitleScreen(void) { + UINT16 i; + switch(curttmode) { - case TTMODE_OLD: case TTMODE_NONE: break; + case TTMODE_OLD: + break; // idk do we still want this? + + case TTMODE_RINGRACERS: + kts_bumper = W_CachePatchName("KTSBUMPR1", PU_PATCH_LOWPRIORITY); + kts_eggman = W_CachePatchName("KTSEGG01", PU_PATCH_LOWPRIORITY); + kts_tails = W_CachePatchName("KTSTAL01", PU_PATCH_LOWPRIORITY); + kts_tails_tails = W_CachePatchName("KTSTAL02", PU_PATCH_LOWPRIORITY); + for (i = 0; i < 6; i++) + { + kts_electricity[i] = W_CachePatchName(va("KTSELCT%.1d", i+1), PU_PATCH_LOWPRIORITY); + } + kts_copyright = W_CachePatchName("KTSCR", PU_PATCH_LOWPRIORITY); + break; + case TTMODE_USER: { - UINT16 i; lumpnum_t lumpnum; char lumpname[9]; @@ -1868,6 +1910,7 @@ void F_StartTitleScreen(void) demoDelayLeft = demoDelayTime; demoIdleLeft = demoIdleTime; + F_InitMenuPresValues(); F_CacheTitleScreen(); } @@ -1884,6 +1927,8 @@ void F_TitleScreenDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS) F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + else + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Don't draw outside of the title screen, or if the patch isn't there. if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) @@ -1902,8 +1947,46 @@ void F_TitleScreenDrawer(void) switch(curttmode) { - case TTMODE_OLD: case TTMODE_NONE: + break; + + case TTMODE_RINGRACERS: + { + const char *eggName = "eggman"; + INT32 eggSkin = R_SkinAvailable(eggName); + skincolornum_t eggColor = SKINCOLOR_RED; + UINT8 *eggColormap = NULL; + + const char *tailsName = "tails"; + INT32 tailsSkin = R_SkinAvailable(tailsName); + skincolornum_t tailsColor = SKINCOLOR_ORANGE; + UINT8 *tailsColormap = NULL; + + if (eggSkin != -1) + { + eggColor = skins[eggSkin].prefcolor; + } + eggColormap = R_GetTranslationColormap(TC_DEFAULT, eggColor, GTC_MENUCACHE); + + if (tailsSkin != -1) + { + tailsColor = skins[tailsSkin].prefcolor; + } + tailsColormap = R_GetTranslationColormap(TC_DEFAULT, tailsColor, GTC_MENUCACHE); + + V_DrawFixedPatch(0, 0, FRACUNIT, 0, kts_tails_tails, tailsColormap); + V_DrawFixedPatch(0, 0, FRACUNIT, V_ADD, kts_electricity[finalecount % 6], NULL); + + V_DrawFixedPatch(0, 0, FRACUNIT, 0, kts_eggman, eggColormap); + V_DrawFixedPatch(0, 0, FRACUNIT, 0, kts_tails, tailsColormap); + + V_DrawFixedPatch(0, 0, FRACUNIT, 0, kts_bumper, NULL); + + V_DrawFixedPatch(0, 0, FRACUNIT, 0, kts_copyright, NULL); + break; + } + + case TTMODE_OLD: /* if (finalecount < 50) { @@ -1944,7 +2027,7 @@ void F_TitleScreenDrawer(void) V_DrawSmallScaledPatch(84, 36, transval<start; for (i = 0; i < fnt->size; ++i, ++c) { - fnt->font[i] = HU_CachePatch( + HU_UpdateOrBlankPatch(&fnt->font[i], + false, "%s%.*d", fnt->prefix, fnt->digits, @@ -57,7 +58,7 @@ Font_DumbRegister (const font_t *sfnt) memcpy(fnt, sfnt, sizeof (font_t)); - if (!( fnt->font = ZZ_Alloc(sfnt->size * sizeof (patch_t *)) )) + if (!( fnt->font = ZZ_Calloc(sfnt->size * sizeof (patch_t *)) )) return -1; return fontc++; diff --git a/src/g_demo.c b/src/g_demo.c index 23fa24c69..22f87c2f3 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -128,13 +128,16 @@ demoghost *ghosts = NULL; #define DEMO_SHRINKME 0x04 // For demos -#define ZT_FWD 0x01 -#define ZT_SIDE 0x02 -#define ZT_TURNING 0x04 -#define ZT_BUTTONS 0x08 -#define ZT_AIMING 0x10 -#define ZT_LATENCY 0x20 -#define ZT_FLAGS 0x40 +#define ZT_FWD 0x01 +#define ZT_SIDE 0x02 +#define ZT_TURNING 0x04 +#define ZT_THROWDIR 0x08 +#define ZT_BUTTONS 0x10 +#define ZT_AIMING 0x20 +#define ZT_LATENCY 0x40 +#define ZT_FLAGS 0x80 +// OUT OF ZIPTICS... + #define DEMOMARKER 0x80 // demoend UINT8 demo_extradata[MAXPLAYERS]; @@ -524,6 +527,8 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) oldcmd[playernum].forwardmove = READSINT8(demo_p); if (ziptic & ZT_TURNING) oldcmd[playernum].turning = READINT16(demo_p); + if (ziptic & ZT_THROWDIR) + oldcmd[playernum].throwdir = READINT16(demo_p); if (ziptic & ZT_BUTTONS) oldcmd[playernum].buttons = READUINT16(demo_p); if (ziptic & ZT_AIMING) @@ -567,6 +572,13 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum) ziptic |= ZT_TURNING; } + if (cmd->throwdir != oldcmd[playernum].throwdir) + { + WRITEINT16(demo_p,cmd->throwdir); + oldcmd[playernum].throwdir = cmd->throwdir; + ziptic |= ZT_THROWDIR; + } + if (cmd->buttons != oldcmd[playernum].buttons) { WRITEUINT16(demo_p,cmd->buttons); @@ -1128,6 +1140,8 @@ void G_GhostTicker(void) g->p++; if (ziptic & ZT_TURNING) g->p += 2; + if (ziptic & ZT_THROWDIR) + g->p += 2; if (ziptic & ZT_BUTTONS) g->p += 2; if (ziptic & ZT_AIMING) @@ -2520,7 +2534,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo) if (memcmp(info_p, DEMOHEADER, 12)) { - CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath); + CONS_Alert(CONS_ERROR, M_GetText("%s is not a Ring Racers replay file.\n"), pdemo->filepath); pdemo->type = MD_INVALID; sprintf(pdemo->title, "INVALID REPLAY"); Z_Free(infobuffer); @@ -2760,7 +2774,7 @@ void G_DoPlayDemo(char *defdemoname) demo.playback = true; if (memcmp(demo_p, DEMOHEADER, 12)) { - snprintf(msg, 1024, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname); + snprintf(msg, 1024, M_GetText("%s is not a Ring Racers replay file.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); diff --git a/src/g_game.c b/src/g_game.c index 56653599a..436d4ec9b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1011,14 +1011,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } // But forward/backward IS used for aiming. - if (joystickvector.yaxis < 0) + if (joystickvector.yaxis != 0) { - cmd->buttons |= BT_FORWARD; - } - - if (joystickvector.yaxis > 0) - { - cmd->buttons |= BT_BACKWARD; + cmd->throwdir -= (joystickvector.yaxis * KART_FULLTURN) >> 10; } } @@ -1121,6 +1116,11 @@ aftercmdinput: else if (cmd->turning < -KART_FULLTURN) cmd->turning = -KART_FULLTURN; + if (cmd->throwdir > KART_FULLTURN) + cmd->throwdir = KART_FULLTURN; + else if (cmd->throwdir < -KART_FULLTURN) + cmd->throwdir = -KART_FULLTURN; + // Reset away view if a command is given. if ((cmd->forwardmove || cmd->buttons) && !r_splitscreen && displayplayers[0] != consoleplayer && ssplayer == 1) @@ -1144,6 +1144,7 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) { dest[i].forwardmove = src[i].forwardmove; dest[i].turning = (INT16)SHORT(src[i].turning); + dest[i].throwdir = (INT16)SHORT(src[i].throwdir); dest[i].aiming = (INT16)SHORT(src[i].aiming); dest[i].buttons = (UINT16)SHORT(src[i].buttons); dest[i].latency = src[i].latency; @@ -3921,7 +3922,7 @@ void G_LoadGameData(void) // Version check if (READUINT32(save_p) != 0xFCAFE211) { - const char *gdfolder = "the SRB2Kart folder"; + const char *gdfolder = "the Ring Racers folder"; if (strcmp(srb2home,".")) gdfolder = srb2home; @@ -4011,7 +4012,7 @@ void G_LoadGameData(void) // Landing point for corrupt gamedata datacorrupt: { - const char *gdfolder = "the SRB2Kart folder"; + const char *gdfolder = "the Ring Racers folder"; if (strcmp(srb2home,".")) gdfolder = srb2home; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 3c86b9b6a..a90ceb130 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -75,8 +75,6 @@ patch_t *pinggfx[5]; // small ping graphic patch_t *mping[5]; // smaller ping graphic -patch_t *tc_font[2][LT_FONTSIZE]; // Special font stuff for titlecard - patch_t *framecounter; patch_t *frameslash; // framerate stuff. Used in screen.c @@ -89,24 +87,12 @@ static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; -patch_t *rflagico; -patch_t *bflagico; -patch_t *rmatcico; -patch_t *bmatcico; -patch_t *tagico; -patch_t *tallminus; -patch_t *tallinfin; - -//------------------------------------------- -// coop hud -//------------------------------------------- - -static patch_t *emblemicon; - //------------------------------------------- // misc vars //------------------------------------------- +patch_t *missingpat; + // song credits static patch_t *songcreditbg; @@ -184,51 +170,25 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum); void HU_LoadGraphics(void) { - char buffer[9]; - INT32 i, j; + INT32 i; if (dedicated) return; Font_Load(); - // minus for negative tallnums - tallminus = HU_CachePatch("STTMINUS"); - - emblemicon = HU_CachePatch("EMBLICON"); - songcreditbg = HU_CachePatch("K_SONGCR"); - - // Cache titlecard font - j = LT_FONTSTART; - for (i = 0; i < LT_FONTSIZE; i++, j++) - { - // cache the titlecard font - - // Bottom layer - sprintf(buffer, "GTOL%.3d", j); - if (W_CheckNumForName(buffer) == LUMPERROR) - tc_font[0][i] = NULL; - else - tc_font[0][i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); - - // Top layer - sprintf(buffer, "GTFN%.3d", j); - if (W_CheckNumForName(buffer) == LUMPERROR) - tc_font[1][i] = NULL; - else - tc_font[1][i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); - } + HU_UpdatePatch(&songcreditbg, "K_SONGCR"); // cache ping gfx: for (i = 0; i < 5; i++) { - pinggfx[i] = HU_CachePatch("PINGGFX%d", i+1); - mping[i] = HU_CachePatch("MPING%d", i+1); + HU_UpdatePatch(&pinggfx[i], "PINGGFX%d", i+1); + HU_UpdatePatch(&mping[i], "MPING%d", i+1); } // fps stuff - framecounter = HU_CachePatch("FRAMER"); - frameslash = HU_CachePatch("FRAMESL");; + HU_UpdatePatch(&framecounter, "FRAMER"); + HU_UpdatePatch(&frameslash, "FRAMESL"); } // Initialise Heads up @@ -246,6 +206,16 @@ void HU_Init(void) RegisterNetXCmd(XD_SAY, Got_Saycmd); #endif + // only allocate if not present, to save us a lot of headache + if (missingpat == NULL) + { + lumpnum_t missingnum = W_GetNumForName("MISSING"); + if (missingnum == LUMPERROR) + I_Error("HU_LoadGraphics: \"MISSING\" patch not present in resource files."); + + missingpat = W_CachePatchNum(missingnum, PU_STATIC); + } + // set shift translation table shiftxform = english_shiftxform; @@ -278,6 +248,16 @@ void HU_Init(void) PR ("CRFNT"); REG; + DIG (3); + + ADIM (LT); + + PR ("GTOL"); + REG; + + PR ("GTFN"); + REG; + DIG (1); DIM (0, 10); @@ -325,19 +305,52 @@ void HU_Init(void) HU_LoadGraphics(); } -patch_t *HU_CachePatch(const char *format, ...) +patch_t *HU_UpdateOrBlankPatch(patch_t **user, boolean required, const char *format, ...) { va_list ap; char buffer[9]; + lumpnum_t lump; + patch_t *patch; + va_start (ap, format); - vsprintf(buffer, format, ap); + vsnprintf(buffer, sizeof buffer, format, ap); va_end (ap); - if (W_CheckNumForName(buffer) == LUMPERROR) - return NULL; + if (user && p_adding_file != INT16_MAX) + { + lump = W_CheckNumForNamePwad(buffer, p_adding_file, 0); + + /* no update in this wad */ + if (lump == INT16_MAX) + return *user; + + lump |= (p_adding_file << 16); + } else - return (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + { + lump = W_CheckNumForName(buffer); + + if (lump == LUMPERROR) + { + if (required == true) + *user = missingpat; + + return *user; + } + } + + patch = W_CachePatchNum(lump, PU_HUDGFX); + + if (user) + { + if (*user) + Patch_Free(*user); + + *user = patch; + } + + return patch; } static inline void HU_Stop(void) @@ -2168,10 +2181,10 @@ void HU_Drawer(void) if (modeattacking && pausedelay > 0 && !pausebreakkey) { INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); - INT32 y = hudinfo[HUD_LIVES].y - 13; + INT32 x = BASEVIDWIDTH/2, y = BASEVIDHEIGHT/2; // obviously incorrect values while we scrap hudinfo - V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, - hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_SKYMAP : V_BLUEMAP), + V_DrawThinString(x, y, + ((leveltime & 4) ? V_SKYMAP : V_BLUEMAP), "HOLD TO RETRY..."); if (strength > 9) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index db1de2447..1fc5611d3 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -44,11 +44,6 @@ #define LT_FONTEND 'z' // the last font characters #define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1) -// Under regular circumstances, we'd use the built in font stuff, however this font is a bit messy because of how we're gonna draw shit. -// tc_font[0][n] is used for the "bottom" layer -// tc_font[1][n] is used for the "top" layer -extern patch_t *tc_font[2][LT_FONTSIZE]; - #define CRED_FONTSTART '!' // the first font character #define CRED_FONTEND 'Z' // the last font character #define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1) @@ -63,6 +58,9 @@ enum X (LT), X (CRED), + X (GTOL), + X (GTFN), + X (TALLNUM), X (NIGHTSNUM), X (PINGNUM), @@ -117,14 +115,6 @@ extern patch_t *pinggfx[5]; extern patch_t *framecounter; extern patch_t *frameslash; -extern patch_t *rflagico; -extern patch_t *bflagico; -extern patch_t *rmatcico; -extern patch_t *bmatcico; -extern patch_t *tagico; -extern patch_t *tallminus; -extern patch_t *tallinfin; - // set true whenever the tab rankings are being shown for any reason extern boolean hu_showscores; @@ -133,8 +123,10 @@ void HU_Init(void); void HU_LoadGraphics(void); -// Load a HUDGFX patch or NULL. -patch_t *HU_CachePatch(const char *format, ...); +// Load a HUDGFX patch or NULL/missingpat (dependent on required boolean). +patch_t *HU_UpdateOrBlankPatch(patch_t **user, boolean required, const char *format, ...); +//#define HU_CachePatch(...) HU_UpdateOrBlankPatch(NULL, false, __VA_ARGS__) -- not sure how to default the missingpat here plus not currently used +#define HU_UpdatePatch(user, ...) HU_UpdateOrBlankPatch(user, true, __VA_ARGS__) // reset heads up when consoleplayer respawns. void HU_Start(void); diff --git a/src/info.c b/src/info.c index 8d3b31f52..3cb1f8f77 100644 --- a/src/info.c +++ b/src/info.c @@ -24,6 +24,7 @@ #include "lzf.h" // Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c! +// EXCEPT HW_LIGHT.C DOESN'T EXIST ANYMORE LOVE CONTINUOUSLY FALLING ON MY ASS THROUGHOUT THIS CODEBASE - Tyron 2022-05-12 // For the sake of constant merge conflicts, let's spread this out char sprnames[NUMSPRITES + 1][5] = { @@ -561,7 +562,7 @@ char sprnames[NUMSPRITES + 1][5] = "BHOG", // Ballhog "BHBM", // Ballhog BOOM "SPBM", // Self-Propelled Bomb - "THNS", // Thunder Shield + "THNS", // Lightning Shield "BUBS", // Bubble Shield (not Bubs) "BWVE", // Bubble Shield waves "FLMS", // Flame Shield @@ -600,6 +601,8 @@ char sprnames[NUMSPRITES + 1][5] = "ISTA", // instashield layer A "ISTB", // instashield layer B + "PWCL", // Invinc/grow clash VFX + "ARRO", // player arrows "ITEM", "ITMO", @@ -739,6 +742,7 @@ char sprnames[NUMSPRITES + 1][5] = "DBOS", // Drift boost flame + "WAYP", "EGOO", "WTRL", // Water Trail @@ -4194,30 +4198,30 @@ state_t states[NUMSTATES] = {SPR_SPBM, 8, 1, {A_SPBChase}, 0, 0, S_SPB1}, // S_SPB20 {SPR_SPBM, 8, 175, {NULL}, 0, 0, S_NULL}, // S_SPB_DEAD - {SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_THUNDERSHIELD2}, // S_THUNDERSHIELD1 - {SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_THUNDERSHIELD3}, // S_THUNDERSHIELD2 - {SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_THUNDERSHIELD4}, // S_THUNDERSHIELD3 - {SPR_THNS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_THUNDERSHIELD5}, // S_THUNDERSHIELD4 - {SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_THUNDERSHIELD6}, // S_THUNDERSHIELD5 - {SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_THUNDERSHIELD7}, // S_THUNDERSHIELD6 - {SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_THUNDERSHIELD8}, // S_THUNDERSHIELD7 - {SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_THUNDERSHIELD9}, // S_THUNDERSHIELD8 - {SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_THUNDERSHIELD10}, // S_THUNDERSHIELD9 - {SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_THUNDERSHIELD11}, // S_THUNDERSHIELD10 - {SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_THUNDERSHIELD12}, // S_THUNDERSHIELD11 - {SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_THUNDERSHIELD13}, // S_THUNDERSHIELD12 - {SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_THUNDERSHIELD14}, // S_THUNDERSHIELD13 - {SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_THUNDERSHIELD15}, // S_THUNDERSHIELD14 - {SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_THUNDERSHIELD16}, // S_THUNDERSHIELD15 - {SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_THUNDERSHIELD17}, // S_THUNDERSHIELD16 - {SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_THUNDERSHIELD18}, // S_THUNDERSHIELD17 - {SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_THUNDERSHIELD19}, // S_THUNDERSHIELD18 - {SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_THUNDERSHIELD20}, // S_THUNDERSHIELD19 - {SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_THUNDERSHIELD21}, // S_THUNDERSHIELD20 - {SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_THUNDERSHIELD22}, // S_THUNDERSHIELD21 - {SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_THUNDERSHIELD23}, // S_THUNDERSHIELD22 - {SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_THUNDERSHIELD24}, // S_THUNDERSHIELD23 - {SPR_THNS, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_THUNDERSHIELD1}, // S_THUNDERSHIELD24 + {SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD2}, // S_LIGHTNINGSHIELD1 + {SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD3}, // S_LIGHTNINGSHIELD2 + {SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD4}, // S_LIGHTNINGSHIELD3 + {SPR_THNS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD5}, // S_LIGHTNINGSHIELD4 + {SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD6}, // S_LIGHTNINGSHIELD5 + {SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD7}, // S_LIGHTNINGSHIELD6 + {SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD8}, // S_LIGHTNINGSHIELD7 + {SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD9}, // S_LIGHTNINGSHIELD8 + {SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD10}, // S_LIGHTNINGSHIELD9 + {SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD11}, // S_LIGHTNINGSHIELD10 + {SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD12}, // S_LIGHTNINGSHIELD11 + {SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD13}, // S_LIGHTNINGSHIELD12 + {SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD14}, // S_LIGHTNINGSHIELD13 + {SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD15}, // S_LIGHTNINGSHIELD14 + {SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD16}, // S_LIGHTNINGSHIELD15 + {SPR_THNS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD17}, // S_LIGHTNINGSHIELD16 + {SPR_THNS, FF_FULLBRIGHT|7, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD18}, // S_LIGHTNINGSHIELD17 + {SPR_THNS, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD19}, // S_LIGHTNINGSHIELD18 + {SPR_THNS, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD20}, // S_LIGHTNINGSHIELD19 + {SPR_THNS, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD21}, // S_LIGHTNINGSHIELD20 + {SPR_THNS, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD22}, // S_LIGHTNINGSHIELD21 + {SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD23}, // S_LIGHTNINGSHIELD22 + {SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD24}, // S_LIGHTNINGSHIELD23 + {SPR_THNS, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD1}, // S_LIGHTNINGSHIELD24 {SPR_BUBS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_BUBBLESHIELD2}, // S_BUBBLESHIELD1 {SPR_BUBS, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_BUBBLESHIELD3}, // S_BUBBLESHIELD2 @@ -4498,6 +4502,8 @@ state_t states[NUMSTATES] = {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 + {SPR_PWCL, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, 10, {NULL}, 9, 1, S_NULL}, // S_POWERCLASH + // 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 @@ -4991,6 +4997,8 @@ state_t states[NUMSTATES] = {SPR_CAPS, 4, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLECAPSULE_SUPPORT {SPR_CAPS, FF_ANIMATE|5, -1, {NULL}, 3, 1, S_NULL}, // S_BATTLECAPSULE_SUPPORTFLY + {SPR_WAYP, 0, 1, {NULL}, 0, 0, S_NULL}, // S_WAYPOINTORB + {SPR_WAYP, 1|FF_FLOORSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_WAYPOINTSPLAT {SPR_EGOO, 0, 1, {NULL}, 0, 0, S_NULL}, // S_EGOORB // Water Trail @@ -7557,7 +7565,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MT_FLINGRING, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + MT_RING, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -7608,10 +7616,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_FLINGRING, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - MT_RING, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -23711,9 +23719,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_THUNDERSHIELD + { // MT_LIGHTNINGSHIELD -1, // doomednum - S_THUNDERSHIELD1, // spawnstate + S_LIGHTNINGSHIELD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -25358,6 +25366,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_POWERCLASH + -1, // doomednum + S_POWERCLASH, // 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|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_PLAYERARROW -1, // doomednum S_PLAYERARROW, // spawnstate diff --git a/src/info.h b/src/info.h index 5e4ef6418..8520b89e3 100644 --- a/src/info.h +++ b/src/info.h @@ -1147,6 +1147,8 @@ typedef enum sprite SPR_ISTA, // instashield layer A SPR_ISTB, // instashield layer B + SPR_PWCL, // Invinc/grow clash VFX + SPR_ARRO, // player arrows SPR_ITEM, SPR_ITMO, @@ -1286,6 +1288,7 @@ typedef enum sprite SPR_DBOS, // Drift boost flame + SPR_WAYP, SPR_EGOO, SPR_WTRL, // Water Trail @@ -4624,30 +4627,30 @@ typedef enum state S_SPB_DEAD, // 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, + S_LIGHTNINGSHIELD1, + S_LIGHTNINGSHIELD2, + S_LIGHTNINGSHIELD3, + S_LIGHTNINGSHIELD4, + S_LIGHTNINGSHIELD5, + S_LIGHTNINGSHIELD6, + S_LIGHTNINGSHIELD7, + S_LIGHTNINGSHIELD8, + S_LIGHTNINGSHIELD9, + S_LIGHTNINGSHIELD10, + S_LIGHTNINGSHIELD11, + S_LIGHTNINGSHIELD12, + S_LIGHTNINGSHIELD13, + S_LIGHTNINGSHIELD14, + S_LIGHTNINGSHIELD15, + S_LIGHTNINGSHIELD16, + S_LIGHTNINGSHIELD17, + S_LIGHTNINGSHIELD18, + S_LIGHTNINGSHIELD19, + S_LIGHTNINGSHIELD20, + S_LIGHTNINGSHIELD21, + S_LIGHTNINGSHIELD22, + S_LIGHTNINGSHIELD23, + S_LIGHTNINGSHIELD24, // Bubble Shield S_BUBBLESHIELD1, @@ -4938,6 +4941,8 @@ typedef enum state S_INSTASHIELDB6, S_INSTASHIELDB7, + S_POWERCLASH, // Grow/Invinc clash VFX + S_PLAYERARROW, // Above player arrow S_PLAYERARROW_BOX, S_PLAYERARROW_ITEM, @@ -5416,6 +5421,8 @@ typedef enum state S_BATTLECAPSULE_SUPPORT, S_BATTLECAPSULE_SUPPORTFLY, + S_WAYPOINTORB, + S_WAYPOINTSPLAT, S_EGOORB, S_WATERTRAIL1, @@ -6324,7 +6331,7 @@ typedef enum mobj_type MT_SPB, // SPB stuff MT_SPBEXPLOSION, - MT_THUNDERSHIELD, // Shields + MT_LIGHTNINGSHIELD, // Shields MT_BUBBLESHIELD, MT_FLAMESHIELD, MT_FLAMESHIELDUNDERLAY, @@ -6404,6 +6411,8 @@ typedef enum mobj_type MT_INSTASHIELDA, MT_INSTASHIELDB, + MT_POWERCLASH, // Grow/Invinc clash VFX + MT_PLAYERARROW, MT_PLAYERWANTED, diff --git a/src/k_bot.c b/src/k_bot.c index 9e1212b1f..3481f8156 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -167,7 +167,7 @@ void K_UpdateMatchRaceBots(void) } } - if (difficulty == 0 || bossinfo.boss == true) + if (difficulty == 0 || !(gametyperules & GTR_BOTS) || bossinfo.boss == true) { wantedbots = 0; } @@ -294,6 +294,67 @@ boolean K_BotCanTakeCut(player_t *player) return false; } +/*-------------------------------------------------- + static fixed_t K_BotSpeedScaled(player_t *player, fixed_t speed) + + Gets the bot's speed value, adjusted for predictions. + Mainly to make bots brake earlier when on friction sectors. + + Input Arguments:- + player - The bot player to calculate speed for. + speed - Raw speed value. + + Return:- + The bot's speed value for calculations. +--------------------------------------------------*/ +static fixed_t K_BotSpeedScaled(player_t *player, fixed_t speed) +{ + fixed_t result = speed; + + if (player->mo->movefactor != FRACUNIT) + { + fixed_t moveFactor = player->mo->movefactor; + + if (moveFactor == 0) + { + moveFactor = 1; + } + + // Reverse against friction. Allows for bots to + // acknowledge they'll be moving faster on ice, + // and to steer harder / brake earlier. + moveFactor = FixedDiv(FRACUNIT, moveFactor); + + // The full value is way too strong, reduce it. + moveFactor -= (moveFactor - FRACUNIT)*3/4; + + result = FixedMul(result, moveFactor); + } + + if (player->mo->standingslope != NULL) + { + const pslope_t *slope = player->mo->standingslope; + + if (!(slope->flags & SL_NOPHYSICS) && abs(slope->zdelta) >= FRACUNIT/21) + { + fixed_t slopeMul = FRACUNIT; + angle_t angle = K_MomentumAngle(player->mo) - slope->xydirection; + + if (P_MobjFlip(player->mo) * slope->zdelta < 0) + angle ^= ANGLE_180; + + // Going uphill: 0 + // Going downhill: FRACUNIT*2 + slopeMul = FRACUNIT + FINECOSINE(angle >> ANGLETOFINESHIFT); + + // Range: 0.9 to 1.1 + result = FixedMul(result, (FRACUNIT*9/10) + (slopeMul/10)); + } + } + + return result; +} + /*-------------------------------------------------- static line_t *K_FindBotController(mobj_t *mo) @@ -426,7 +487,7 @@ static UINT32 K_BotRubberbandDistance(player_t *player) fixed_t K_BotRubberband(player_t *player) { fixed_t rubberband = FRACUNIT; - fixed_t max, min; + fixed_t rubbermax, rubbermin; player_t *firstplace = NULL; line_t *botController = NULL; UINT8 i; @@ -477,32 +538,34 @@ fixed_t K_BotRubberband(player_t *player) if (wanteddist > player->distancetofinish) { // Whoa, you're too far ahead! Slow back down a little. - rubberband += (MAXBOTDIFFICULTY - player->botvars.difficulty) * (distdiff / 3); + rubberband += (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty)) * (distdiff / 3); } else { // Catch up to your position! - rubberband += (2*player->botvars.difficulty) * distdiff; + rubberband += player->botvars.difficulty * distdiff; } } - // Lv. 1: x1.0 max - // Lv. 5: x1.5 max - // Lv. 9: x2.0 max - max = FRACUNIT + ((FRACUNIT * (player->botvars.difficulty - 1)) / (MAXBOTDIFFICULTY - 1)); + // Lv. 1: x1.0 max + // Lv. 5: x1.4 max + // Lv. 9: x1.8 max + // Lv. MAX: x2.2 max + rubbermax = FRACUNIT + ((FRACUNIT * (player->botvars.difficulty - 1)) / 10); - // Lv. 1: x0.75 min - // Lv. 5: x0.875 min - // Lv. 9: x1.0 min - min = FRACUNIT - (((FRACUNIT/4) * (MAXBOTDIFFICULTY - player->botvars.difficulty)) / (MAXBOTDIFFICULTY - 1)); + // Lv. 1: x0.75 min + // Lv. 5: x0.875 min + // Lv. 9: x1.0 min + // Lv. MAX: x1.0 min + rubbermin = FRACUNIT - (((FRACUNIT/4) * (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty))) / (DIFFICULTBOT - 1)); - if (rubberband > max) + if (rubberband > rubbermax) { - rubberband = max; + rubberband = rubbermax; } - else if (rubberband < min) + else if (rubberband < rubbermin) { - rubberband = min; + rubberband = rubbermin; } return rubberband; @@ -573,8 +636,9 @@ fixed_t K_BotTopSpeedRubberband(player_t *player) --------------------------------------------------*/ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) { + const fixed_t value = 20776; fixed_t rubberband = K_BotRubberband(player) - FRACUNIT; - fixed_t origFrict, newFrict; + fixed_t newFrict = frict; if (rubberband <= 0) { @@ -584,30 +648,11 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) if (player->tiregrease > 0) { - // This isn't great -- it means rubberbanding will slow down when they hit a spring - // But it's better than the opposite where they accelerate into hyperspace :V - // (would appreciate an actual fix though ... could try being additive instead of multiplicative) + // Bots will lose all of their momentum without this. return frict; } - origFrict = FixedDiv(ORIG_FRICTION, FRACUNIT + (rubberband / 2)); - - if (frict == ORIG_FRICTION) - { - newFrict = origFrict; - } - else - { - // Do some mumbo jumbo to make our friction value - // relative to what it WOULD be for ORIG_FRICTION. - // (I hate multiplicative friction :/) - - fixed_t offset = ORIG_FRICTION - frict; - fixed_t ratio = FixedDiv(frict, ORIG_FRICTION); - - offset = FixedDiv(offset, ratio); - newFrict = frict + offset; - } + newFrict = frict - FixedMul(value, rubberband); if (newFrict < 0) newFrict = 0; @@ -673,7 +718,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) const INT16 normal = KART_FULLTURN; // "Standard" handling to compare to const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict - const fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy); + const fixed_t speed = K_BotSpeedScaled(player, P_AproxDistance(player->mo->momx, player->mo->momy)); const INT32 startDist = (768 * mapobjectscale) / FRACUNIT; const INT32 distance = ((speed / FRACUNIT) * futuresight) + startDist; @@ -851,7 +896,7 @@ static UINT8 K_TrySpindash(player_t *player) { INT32 boosthold = starttime - K_GetSpindashChargeTime(player); - boosthold -= (MAXBOTDIFFICULTY - player->botvars.difficulty) * difficultyModifier; + boosthold -= (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty)) * difficultyModifier; if (leveltime >= (unsigned)boosthold) { @@ -1008,15 +1053,273 @@ static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController) cmd->turning = -KART_FULLTURN; break; case 3: - cmd->buttons |= BT_FORWARD; + cmd->throwdir = KART_FULLTURN; break; case 4: - cmd->buttons |= BT_BACKWARD; + cmd->throwdir = -KART_FULLTURN; break; } } } +/*-------------------------------------------------- + static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *predict) + + Determines inputs for standard track driving. + + Input Arguments:- + player - Player to generate the ticcmd for. + cmd - The player's ticcmd to modify. + predict - Pointer to the bot's prediction. + + Return:- + New value for turn amount. +--------------------------------------------------*/ +static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *predict, angle_t destangle) +{ + // Handle steering towards waypoints! + INT32 turnamt = 0; + SINT8 turnsign = 0; + angle_t moveangle, angle; + INT16 anglediff; + + I_Assert(predict != NULL); + + moveangle = player->mo->angle; + angle = (moveangle - destangle); + + if (angle < ANGLE_180) + { + turnsign = -1; // Turn right + anglediff = AngleFixed(angle)>>FRACBITS; + } + else + { + turnsign = 1; // Turn left + anglediff = 360-(AngleFixed(angle)>>FRACBITS); + } + + anglediff = abs(anglediff); + turnamt = KART_FULLTURN * turnsign; + + if (anglediff > 90) + { + // Wrong way! + cmd->forwardmove = -MAXPLMOVE; + cmd->buttons |= BT_BRAKE; + } + else + { + const fixed_t playerwidth = (player->mo->radius * 2); + fixed_t realrad = predict->radius - (playerwidth * 4); // Remove a "safe" distance away from the edges of the road + fixed_t rad = realrad; + fixed_t dirdist = K_DistanceOfLineFromPoint( + player->mo->x, player->mo->y, + player->mo->x + FINECOSINE(moveangle >> ANGLETOFINESHIFT), player->mo->y + FINESINE(moveangle >> ANGLETOFINESHIFT), + predict->x, predict->y + ); + + if (realrad < player->mo->radius) + { + realrad = player->mo->radius; + } + + if (anglediff > 0) + { + // Become more precise based on how hard you need to turn + // This makes predictions into turns a little nicer + // Facing 90 degrees away from the predicted point gives you a 1/3 radius + rad = FixedMul(rad, ((135 - anglediff) * FRACUNIT) / 135); + } + + if (rad > realrad) + { + rad = realrad; + } + else if (rad < playerwidth) + { + rad = playerwidth; + } + + cmd->buttons |= BT_ACCELERATE; + + // Full speed ahead! + cmd->forwardmove = MAXPLMOVE; + + if (dirdist <= rad) + { + fixed_t speedmul = FixedDiv(K_BotSpeedScaled(player, player->speed), K_GetKartSpeed(player, false)); + fixed_t speedrad = rad/4; + + if (speedmul > FRACUNIT) + { + speedmul = FRACUNIT; + } + + // Increase radius with speed + // At low speed, the CPU will try to be more accurate + // At high speed, they're more likely to lawnmower + speedrad += FixedMul(speedmul, rad - speedrad); + + if (speedrad < playerwidth) + { + speedrad = playerwidth; + } + + if (dirdist <= speedrad) + { + // Don't turn at all + turnamt = 0; + } + } + } + + return turnamt; +} + +/*-------------------------------------------------- + static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t *predict) + + Determines inputs for reversing. + + Input Arguments:- + player - Player to generate the ticcmd for. + cmd - The player's ticcmd to modify. + predict - Pointer to the bot's prediction. + + Return:- + New value for turn amount. +--------------------------------------------------*/ +static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t *predict, angle_t destangle) +{ + // Handle steering towards waypoints! + INT32 turnamt = 0; + SINT8 turnsign = 0; + angle_t moveangle, angle; + INT16 anglediff, momdiff; + + if (predict != NULL) + { + // TODO: Should we reverse through bot controllers? + return K_HandleBotTrack(player, cmd, predict, destangle); + } + + if (player->nextwaypoint == NULL + || player->nextwaypoint->mobj == NULL + || P_MobjWasRemoved(player->nextwaypoint->mobj)) + { + // No data available... + return 0; + } + + if ((player->nextwaypoint->prevwaypoints != NULL) + && (player->nextwaypoint->numprevwaypoints > 0U)) + { + size_t i; + for (i = 0U; i < player->nextwaypoint->numprevwaypoints; i++) + { + if (!K_GetWaypointIsEnabled(player->nextwaypoint->prevwaypoints[i])) + { + continue; + } + + destangle = R_PointToAngle2( + player->nextwaypoint->prevwaypoints[i]->mobj->x, player->nextwaypoint->prevwaypoints[i]->mobj->y, + player->nextwaypoint->mobj->x, player->nextwaypoint->mobj->y + ); + + break; + } + } + + // Calculate turn direction first. + moveangle = player->mo->angle; + angle = (moveangle - destangle); + + if (angle < ANGLE_180) + { + turnsign = -1; // Turn right + anglediff = AngleFixed(angle)>>FRACBITS; + } + else + { + turnsign = 1; // Turn left + anglediff = 360-(AngleFixed(angle)>>FRACBITS); + } + + anglediff = abs(anglediff); + turnamt = KART_FULLTURN * turnsign; + + // Now calculate momentum + momdiff = 180; + if (player->speed > player->mo->scale) + { + momdiff = 0; + moveangle = K_MomentumAngle(player->mo); + angle = (moveangle - destangle); + + if (angle < ANGLE_180) + { + momdiff = AngleFixed(angle)>>FRACBITS; + } + else + { + momdiff = 360-(AngleFixed(angle)>>FRACBITS); + } + + momdiff = abs(momdiff); + } + + if (anglediff > 90 || momdiff < 90) + { + // We're not facing the track, + // or we're going too fast. + // Let's E-Brake. + cmd->forwardmove = 0; + cmd->buttons |= BT_ACCELERATE|BT_BRAKE; + } + else + { + fixed_t slopeMul = FRACUNIT; + + if (player->mo->standingslope != NULL) + { + const pslope_t *slope = player->mo->standingslope; + + if (!(slope->flags & SL_NOPHYSICS) && abs(slope->zdelta) >= FRACUNIT/21) + { + angle_t sangle = player->mo->angle - slope->xydirection; + + if (P_MobjFlip(player->mo) * slope->zdelta < 0) + sangle ^= ANGLE_180; + + slopeMul = FRACUNIT - FINECOSINE(sangle >> ANGLETOFINESHIFT); + } + } + +#define STEEP_SLOPE (FRACUNIT*11/10) + if (slopeMul > STEEP_SLOPE) + { + // Slope is too steep to reverse -- EBrake. + cmd->forwardmove = 0; + cmd->buttons |= BT_ACCELERATE|BT_BRAKE; + } + else + { + cmd->forwardmove = -MAXPLMOVE; + cmd->buttons |= BT_BRAKE; //|BT_LOOKBACK + } +#undef STEEP_SLOPE + + if (anglediff < 10) + { + turnamt = 0; + } + } + + return turnamt; +} + /*-------------------------------------------------- void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) @@ -1026,6 +1329,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) { botprediction_t *predict = NULL; boolean trySpindash = true; + angle_t destangle = 0; UINT8 spindash = 0; INT32 turnamt = 0; line_t *botController = NULL; @@ -1039,13 +1343,11 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) // Remove any existing controls memset(cmd, 0, sizeof(ticcmd_t)); - if ( - gamestate != GS_LEVEL + if (gamestate != GS_LEVEL || player->mo->scale <= 1 || player->playerstate == PST_DEAD || leveltime <= introtime - || (player->exiting && !(gametyperules & GTR_CIRCUIT)) - ) + || !(gametyperules & GTR_BOTS)) { // No need to do anything else. return; @@ -1067,170 +1369,133 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) return; } - if ((player->nextwaypoint != NULL - && player->nextwaypoint->mobj != NULL - && !P_MobjWasRemoved(player->nextwaypoint->mobj)) - || (botController != NULL)) + destangle = player->mo->angle; + + if (botController != NULL && (botController->flags & ML_EFFECT1)) { - // Handle steering towards waypoints! - SINT8 turnsign = 0; - angle_t destangle, moveangle, angle; - INT16 anglediff; + const fixed_t dist = (player->mo->radius * 4); - if (botController != NULL && (botController->flags & ML_EFFECT1)) - { - const fixed_t dist = (player->mo->radius * 4); + // X Offset: Movement direction + destangle = FixedAngle(sides[botController->sidenum[0]].textureoffset); - // X Offset: Movement direction - destangle = FixedAngle(sides[botController->sidenum[0]].textureoffset); + // Overwritten prediction + predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL); - // Overwritten prediction - predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL); - - predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT)); - predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT)); - predict->radius = (DEFAULT_WAYPOINT_RADIUS / 4) * mapobjectscale; - } - else - { - predict = K_CreateBotPrediction(player); - - K_NudgePredictionTowardsObjects(predict, player); - - destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y); - } - - moveangle = player->mo->angle; - angle = (moveangle - destangle); - - if (angle < ANGLE_180) - { - turnsign = -1; // Turn right - anglediff = AngleFixed(angle)>>FRACBITS; - } - else - { - turnsign = 1; // Turn left - anglediff = 360-(AngleFixed(angle)>>FRACBITS); - } - - anglediff = abs(anglediff); - turnamt = KART_FULLTURN * turnsign; - - if (anglediff > 90) - { - // Wrong way! - cmd->forwardmove = -MAXPLMOVE; - cmd->buttons |= BT_BRAKE; - } - else - { - const fixed_t playerwidth = (player->mo->radius * 2); - fixed_t realrad = predict->radius - (playerwidth * 4); // Remove a "safe" distance away from the edges of the road - fixed_t rad = realrad; - fixed_t dirdist = K_DistanceOfLineFromPoint( - player->mo->x, player->mo->y, - player->mo->x + FINECOSINE(moveangle >> ANGLETOFINESHIFT), player->mo->y + FINESINE(moveangle >> ANGLETOFINESHIFT), - predict->x, predict->y - ); - - if (anglediff > 0) - { - // Become more precise based on how hard you need to turn - // This makes predictions into turns a little nicer - // Facing 90 degrees away from the predicted point gives you a 1/3 radius - rad = FixedMul(rad, ((135 - anglediff) * FRACUNIT) / 135); - } - - if (rad > realrad) - { - rad = realrad; - } - else if (rad < playerwidth) - { - rad = playerwidth; - } - - cmd->buttons |= BT_ACCELERATE; - - // Full speed ahead! - cmd->forwardmove = MAXPLMOVE; - - if (dirdist <= rad) - { - fixed_t speedmul = FixedDiv(player->speed, K_GetKartSpeed(player, false)); - fixed_t speedrad = rad/4; - - if (speedmul > FRACUNIT) - { - speedmul = FRACUNIT; - } - - // Increase radius with speed - // At low speed, the CPU will try to be more accurate - // At high speed, they're more likely to lawnmower - speedrad += FixedMul(speedmul, rad - speedrad); - - if (speedrad < playerwidth) - { - speedrad = playerwidth; - } - - if (dirdist <= speedrad) - { - // Don't turn at all - turnamt = 0; - } - } - } + predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT)); + predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT)); + predict->radius = (DEFAULT_WAYPOINT_RADIUS / 4) * mapobjectscale; } if (leveltime <= starttime && finishBeamLine != NULL) { + // Handle POSITION!! const fixed_t distBase = 384*mapobjectscale; const fixed_t distAdjust = 64*mapobjectscale; const fixed_t closeDist = distBase + (distAdjust * (9 - player->kartweight)); const fixed_t farDist = closeDist + (distAdjust * 2); + const tic_t futureSight = (TICRATE >> 1); + fixed_t distToFinish = K_DistanceOfLineFromPoint( finishBeamLine->v1->x, finishBeamLine->v1->y, finishBeamLine->v2->x, finishBeamLine->v2->y, player->mo->x, player->mo->y - ) - player->speed; + ) - (K_BotSpeedScaled(player, player->speed) * futureSight); // Don't run the spindash code at all until we're in the right place trySpindash = false; - // If you're too far, enable spindash & stay still. - // If you're too close, start backing up. - if (distToFinish < closeDist) { - // Silly way of getting us to reverse, but it respects the above code - // where we figure out what the shape of the track looks like. - UINT16 oldButtons = cmd->buttons; - - cmd->buttons &= ~(BT_ACCELERATE|BT_BRAKE); - - if (oldButtons & BT_ACCELERATE) - { - cmd->buttons |= BT_BRAKE; - } - - if (oldButtons & BT_BRAKE) - { - cmd->buttons |= BT_ACCELERATE; - } - - cmd->forwardmove = -cmd->forwardmove; + // We're too close, we need to start backing up. + turnamt = K_HandleBotReverse(player, cmd, predict, destangle); } else if (distToFinish < farDist) { - // We're in about the right place, spindash now. - cmd->forwardmove = 0; - trySpindash = true; + INT32 bullyTurn = INT32_MAX; + + // We're in about the right place, let's do whatever we want to. + + if (player->kartspeed >= 5) + { + // Faster characters want to spindash. + // Slower characters will use their momentum. + trySpindash = true; + } + + // Look for characters to bully. + bullyTurn = K_PositionBully(player); + if (bullyTurn == INT32_MAX) + { + // No one to bully, just go for a spindash as anyone. + if (predict == NULL) + { + // Create a prediction. + if (player->nextwaypoint != NULL + && player->nextwaypoint->mobj != NULL + && !P_MobjWasRemoved(player->nextwaypoint->mobj)) + { + predict = K_CreateBotPrediction(player); + K_NudgePredictionTowardsObjects(predict, player); + destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y); + } + } + + turnamt = K_HandleBotTrack(player, cmd, predict, destangle); + cmd->buttons &= ~(BT_ACCELERATE|BT_BRAKE); + cmd->forwardmove = 0; + trySpindash = true; + } + else + { + turnamt = bullyTurn; + + // If already spindashing, wait until we get a relatively OK charge first. + if (player->spindash == 0 || player->spindash > TICRATE) + { + trySpindash = false; + cmd->buttons |= BT_ACCELERATE; + cmd->forwardmove = MAXPLMOVE; + } + } } + else + { + // Too far away, we need to just drive up. + if (predict == NULL) + { + // Create a prediction. + if (player->nextwaypoint != NULL + && player->nextwaypoint->mobj != NULL + && !P_MobjWasRemoved(player->nextwaypoint->mobj)) + { + predict = K_CreateBotPrediction(player); + K_NudgePredictionTowardsObjects(predict, player); + destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y); + } + } + + turnamt = K_HandleBotTrack(player, cmd, predict, destangle); + } + } + else + { + // Handle steering towards waypoints! + if (predict == NULL) + { + // Create a prediction. + if (player->nextwaypoint != NULL + && player->nextwaypoint->mobj != NULL + && !P_MobjWasRemoved(player->nextwaypoint->mobj)) + { + predict = K_CreateBotPrediction(player); + K_NudgePredictionTowardsObjects(predict, player); + destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y); + } + } + + turnamt = K_HandleBotTrack(player, cmd, predict, destangle); } if (trySpindash == true) @@ -1315,4 +1580,3 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) Z_Free(predict); } } - diff --git a/src/k_bot.h b/src/k_bot.h index a04d5c174..d608fe367 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -18,7 +18,10 @@ #include "r_defs.h" // Maximum value of botvars.difficulty -#define MAXBOTDIFFICULTY 9 +#define MAXBOTDIFFICULTY 13 + +// Level of a "difficult" bot. The max bot level was increased, but this keeps all of the same calculations. +#define DIFFICULTBOT 9 // How many tics in a row do you need to turn in this direction before we'll let you turn. // Made it as small as possible without making it look like the bots are twitching constantly. @@ -220,6 +223,21 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player); +/*-------------------------------------------------- + INT32 K_PositionBully(player_t *player) + + Calculates a turn value to reach a player that can be bullied. + + Input Arguments:- + player - Bot to run this for. + + Return:- + INT32_MAX if couldn't find anything, otherwise a steering value. +--------------------------------------------------*/ + +INT32 K_PositionBully(player_t *player); + + /*-------------------------------------------------- void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd); diff --git a/src/k_botitem.c b/src/k_botitem.c index 6f8e82034..465c45adb 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -332,15 +332,7 @@ static boolean K_BotGenericPressItem(player_t *player, ticcmd_t *cmd, SINT8 dir) return false; } - if (dir == 1) - { - cmd->buttons |= BT_FORWARD; - } - else if (dir == -1) - { - cmd->buttons |= BT_BACKWARD; - } - + cmd->throwdir = KART_FULLTURN * dir; cmd->buttons |= BT_ATTACK; player->botvars.itemconfirm = 0; return true; @@ -1021,9 +1013,9 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) } /*-------------------------------------------------- - static void K_BotItemThunder(player_t *player, ticcmd_t *cmd) + static void K_BotItemLightning(player_t *player, ticcmd_t *cmd) - Item usage for Thunder Shield. + Item usage for Lightning Shield. Input Arguments:- player - Bot to do this for. @@ -1032,7 +1024,7 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) Return:- None --------------------------------------------------*/ -static void K_BotItemThunder(player_t *player, ticcmd_t *cmd) +static void K_BotItemLightning(player_t *player, ticcmd_t *cmd) { if (K_BotUseItemNearPlayer(player, cmd, 192*player->mo->scale) == false) { @@ -1355,8 +1347,8 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) K_BotItemDropTarget(player, cmd); } break; - case KITEM_THUNDERSHIELD: - K_BotItemThunder(player, cmd); + case KITEM_LIGHTNINGSHIELD: + K_BotItemLightning(player, cmd); break; case KITEM_BUBBLESHIELD: K_BotItemBubble(player, cmd); diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 6e256a9e5..07935d79c 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -40,6 +40,9 @@ struct globalsmuggle INT64 avoidAvgX[2], avoidAvgY[2]; UINT32 avoidObjs[2]; + fixed_t annoyscore; + mobj_t *annoymo; + fixed_t closestlinedist; fixed_t eggboxx, eggboxy; @@ -478,7 +481,7 @@ static boolean K_FindObjectsForNudging(mobj_t *thing) if ((RINGTOTAL(globalsmuggle.botmo->player) < 20 && !(globalsmuggle.botmo->player->pflags & PF_RINGLOCK) && P_CanPickupItem(globalsmuggle.botmo->player, 0)) && !thing->extravalue1 - && (globalsmuggle.botmo->player->itemtype != KITEM_THUNDERSHIELD)) + && (globalsmuggle.botmo->player->itemtype != KITEM_LIGHTNINGSHIELD)) { K_AddAttackObject(thing, side, (RINGTOTAL(globalsmuggle.botmo->player) < 3) ? 5 : 1); } @@ -505,10 +508,10 @@ static boolean K_FindObjectsForNudging(mobj_t *thing) { break; } - // Thunder Shield + // Lightning Shield else if (K_PlayerAttackSteer(thing, side, 20, - globalsmuggle.botmo->player->itemtype == KITEM_THUNDERSHIELD, - thing->player->itemtype == KITEM_THUNDERSHIELD + globalsmuggle.botmo->player->itemtype == KITEM_LIGHTNINGSHIELD, + thing->player->itemtype == KITEM_LIGHTNINGSHIELD )) { break; @@ -771,3 +774,151 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player) } } } + +/*-------------------------------------------------- + static boolean K_FindPlayersToBully(mobj_t *thing) + + Blockmap search function. + Finds players around the bot to bump. + + Input Arguments:- + thing - Object passed in from iteration. + + Return:- + true continues searching, false ends the search early. +--------------------------------------------------*/ +static boolean K_FindPlayersToBully(mobj_t *thing) +{ + INT16 anglediff; + fixed_t fulldist; + fixed_t ourweight, theirweight, weightdiff; + angle_t ourangle, destangle, angle; + + if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player) + { + return false; + } + + if (thing->health <= 0) + { + return true; + } + + if (!thing->player) + { + return true; + } + + if (globalsmuggle.botmo == thing) + { + return true; + } + + fulldist = R_PointToDist2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y) - thing->radius; + + if (fulldist > globalsmuggle.distancetocheck) + { + return true; + } + + if (P_CheckSight(globalsmuggle.botmo, thing) == false) + { + return true; + } + + ourangle = globalsmuggle.botmo->angle; + destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y); + angle = (ourangle - destangle); + + if (angle < ANGLE_180) + { + anglediff = AngleFixed(angle)>>FRACBITS; + } + else + { + anglediff = 360-(AngleFixed(angle)>>FRACBITS); + } + + anglediff = abs(anglediff); + + ourweight = K_GetMobjWeight(globalsmuggle.botmo, thing); + theirweight = K_GetMobjWeight(thing, globalsmuggle.botmo); + weightdiff = 0; + + if (anglediff >= 90) + { + weightdiff = theirweight - ourweight; + } + else + { + weightdiff = ourweight - theirweight; + } + + if (weightdiff > mapobjectscale && weightdiff > globalsmuggle.annoyscore) + { + globalsmuggle.annoyscore = weightdiff; + globalsmuggle.annoymo = thing; + } + + return true; +} + +/*-------------------------------------------------- + INT32 K_PositionBully(player_t *player) + + See header file for description. +--------------------------------------------------*/ +INT32 K_PositionBully(player_t *player) +{ + INT32 xl, xh, yl, yh, bx, by; + + angle_t ourangle, destangle, angle; + INT16 anglediff; + + globalsmuggle.botmo = player->mo; + globalsmuggle.distancetocheck = 1024*player->mo->scale; + + globalsmuggle.annoymo = NULL; + globalsmuggle.annoyscore = 0; + + xl = (unsigned)(globalsmuggle.botmo->x - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT; + xh = (unsigned)(globalsmuggle.botmo->x + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT; + yl = (unsigned)(globalsmuggle.botmo->y - globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT; + yh = (unsigned)(globalsmuggle.botmo->y + globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + for (bx = xl; bx <= xh; bx++) + { + for (by = yl; by <= yh; by++) + { + P_BlockThingsIterator(bx, by, K_FindPlayersToBully); + } + } + + if (globalsmuggle.annoymo == NULL) + { + return INT32_MAX; + } + + ourangle = globalsmuggle.botmo->angle; + destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, globalsmuggle.annoymo->x, globalsmuggle.annoymo->y); + angle = (ourangle - destangle); + + if (angle < ANGLE_180) + { + anglediff = AngleFixed(angle)>>FRACBITS; + } + else + { + anglediff = 360-(AngleFixed(angle)>>FRACBITS); + } + + if (anglediff < 30) + return 0; + + if (anglediff < 0) + return -KART_FULLTURN; + + return KART_FULLTURN; +} diff --git a/src/k_brightmap.c b/src/k_brightmap.c index f481938f2..c62d645e6 100644 --- a/src/k_brightmap.c +++ b/src/k_brightmap.c @@ -37,7 +37,7 @@ static size_t maxBrightmapStorage = 0; static brightmapStorage_t *K_NewBrightmap(void) { maxBrightmapStorage++; - brightmapStorage = (brightmapStorage_t *)Z_Realloc(brightmapStorage, sizeof(brightmapStorage_t) * (maxBrightmapStorage + 1), PU_STATIC, NULL); + brightmapStorage = (brightmapStorage_t *)Z_Realloc(brightmapStorage, sizeof(brightmapStorage_t) * (maxBrightmapStorage + 1), PU_STATIC, &brightmapStorage); return &brightmapStorage[ maxBrightmapStorage - 1 ]; } @@ -63,6 +63,7 @@ static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex) --------------------------------------------------*/ static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName) { + UINT32 checkHash = quickncasehash(checkName, 8); size_t i; if (maxBrightmapStorage == 0) @@ -74,7 +75,7 @@ static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkN { brightmapStorage_t *bms = &brightmapStorage[i]; - if (stricmp(checkName, bms->textureName) == 0) + if (checkHash == bms->textureHash) { // Name matches. return bms; @@ -119,6 +120,7 @@ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) { bms = K_NewBrightmap(); strncpy(bms->textureName, tkn, 9); + bms->textureHash = quickncasehash(bms->textureName, 8); } Z_Free(tkn); @@ -128,6 +130,7 @@ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) if (tkn && pos < size) { strncpy(bms->brightmapName, tkn, 9); + bms->brightmapHash = quickncasehash(bms->brightmapName, 8); } else { @@ -163,57 +166,45 @@ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) } /*-------------------------------------------------- - void K_InitBrightmaps(void) + void K_InitBrightmapsPwad(INT32 wadNum) See header file for description. --------------------------------------------------*/ -void K_InitBrightmaps(void) +void K_InitBrightmapsPwad(INT32 wadNum) { - INT32 wadNum; + UINT16 lumpNum; size_t i; I_Assert(brightmapStorage == NULL); - maxBrightmapStorage = 0; - for (wadNum = 0; wadNum < numwadfiles; wadNum++) + // Find BRIGHT lump in the WAD + lumpNum = W_CheckNumForNamePwad("BRIGHT", wadNum, 0); + + while (lumpNum != INT16_MAX) { - UINT16 lumpNum; + UINT8 *data = (UINT8 *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_CACHE); - // Find BRIGHT lump in the WAD - lumpNum = W_CheckNumForNamePwad("BRIGHT", wadNum, 0); - - while (lumpNum != INT16_MAX) + if (data != NULL) { - UINT8 *data; - data = (UINT8 *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); + lumpinfo_t *lump_p = &wadfiles[wadNum]->lumpinfo[lumpNum]; + size_t size = W_LumpLengthPwad(wadNum, lumpNum); - // If that didn't exist, we have nothing to do here. - if (data == NULL) - { - lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); - continue; - } - else - { - lumpinfo_t *lump_p = &wadfiles[wadNum]->lumpinfo[lumpNum]; - size_t size = W_LumpLengthPwad(wadNum, lumpNum); + size_t nameLength = strlen(wadfiles[wadNum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name + char *name = malloc(nameLength + 1); - size_t nameLength = strlen(wadfiles[wadNum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name - char *name = malloc(nameLength + 1); + sprintf(name, "%s|%s", wadfiles[wadNum]->filename, lump_p->fullname); + name[nameLength] = '\0'; - sprintf(name, "%s|%s", wadfiles[wadNum]->filename, lump_p->fullname); - name[nameLength] = '\0'; + size = W_LumpLengthPwad(wadNum, lumpNum); - size = W_LumpLengthPwad(wadNum, lumpNum); + CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name); + K_BRIGHTLumpParser(data, size); - CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name); - K_BRIGHTLumpParser(data, size); - - free(name); - } - - lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); + free(name); + Z_Free(data); } + + lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); } if (maxBrightmapStorage == 0) @@ -237,14 +228,7 @@ void K_InitBrightmaps(void) if (texNum != -1) { bmNum = R_CheckTextureNumForName(bms->brightmapName); - if (bmNum == -1) - { - texturebrightmaps[texNum] = 0; - } - else - { - texturebrightmaps[texNum] = bmNum; - } + R_UpdateTextureBrightmap(texNum, (bmNum == -1 ? 0 : bmNum)); } } @@ -253,4 +237,20 @@ void K_InitBrightmaps(void) // Clear brightmapStorage now that we're done with it. Z_Free(brightmapStorage); brightmapStorage = NULL; + maxBrightmapStorage = 0; +} + +/*-------------------------------------------------- + void K_InitBrightmaps(void) + + See header file for description. +--------------------------------------------------*/ +void K_InitBrightmaps(void) +{ + INT32 wadNum; + + for (wadNum = 0; wadNum < numwadfiles; wadNum++) + { + K_InitBrightmapsPwad(wadNum); + } } diff --git a/src/k_brightmap.h b/src/k_brightmap.h index 8d33ae5cb..72bc7e9df 100644 --- a/src/k_brightmap.h +++ b/src/k_brightmap.h @@ -24,9 +24,20 @@ typedef struct brightmapStorage_s // before putting them into texturebrightmaps. char textureName[9]; // The texture's name. + UINT32 textureHash; // The texture name's hash. + char brightmapName[9]; // The brightmap's name. + UINT32 brightmapHash; // The brightmap name's hash. } brightmapStorage_t; +/*-------------------------------------------------- + void K_InitBrightmapsPwad(INT32 wadNum); + + Finds all BRIGHT lumps for one WAD/PK3 and processes them. +--------------------------------------------------*/ + +void K_InitBrightmapsPwad(INT32 wadNum); + /*-------------------------------------------------- void K_InitBrightmaps(void); diff --git a/src/k_collide.c b/src/k_collide.c index 665a3ff0a..92c4bd7fd 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -352,10 +352,10 @@ void K_DoMineSearch(mobj_t *actor, fixed_t size) explodedist = FixedMul(size, actor->scale); grenade = actor; - yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; - yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; - xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; - xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; + yh = (unsigned)(actor->y + (explodedist + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - (explodedist + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + (explodedist + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - (explodedist + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT; BMBOUNDFIX (xl, xh, yl, yh); @@ -664,6 +664,85 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2) return true; } +static mobj_t *lightningSource; +static fixed_t lightningDist; + +static inline boolean PIT_LightningShieldAttack(mobj_t *thing) +{ + if (lightningSource == NULL || P_MobjWasRemoved(lightningSource)) + { + // Invalid? + return false; + } + + if (thing == lightningSource) + { + // Don't explode yourself!! + return true; + } + + if (thing->health <= 0) + { + // Dead + return true; + } + + if (!(thing->flags & MF_SHOOTABLE) || (thing->flags & MF_SCENERY)) + { + // Not shootable + return true; + } + + if (thing->player && thing->player->spectator) + { + // Spectator + return true; + } + + if ((lightningSource->eflags & MFE_VERTICALFLIP) + ? (thing->z > lightningSource->z + lightningSource->height) + : (thing->z + thing->height < lightningSource->z)) + { + // Underneath + return true; + } + + if (P_AproxDistance(thing->x - lightningSource->x, thing->y - lightningSource->y) > lightningDist + thing->radius) + { + // Too far away + return true; + } + + if (P_CheckSight(lightningSource, thing) == false) + { + // Not in sight + return true; + } + + P_DamageMobj(thing, lightningSource, lightningSource, 1, DMG_NORMAL|DMG_CANTHURTSELF|DMG_WOMBO); + return true; +} + +void K_LightningShieldAttack(mobj_t *actor, fixed_t size) +{ + INT32 bx, by, xl, xh, yl, yh; + + lightningDist = FixedMul(size, actor->scale); + lightningSource = actor; + + // Use blockmap to check for nearby shootables + yh = (unsigned)(actor->y + lightningDist - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - lightningDist - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + lightningDist - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - lightningDist - bmaporgx)>>MAPBLOCKSHIFT; + + BMBOUNDFIX (xl, xh, yl, yh); + + for (by = yl; by <= yh; by++) + for (bx = xl; bx <= xh; bx++) + P_BlockThingsIterator(bx, by, PIT_LightningShieldAttack); +} + boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2) { if (t2->type == MT_PLAYER) @@ -788,24 +867,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) boolean stungT1 = false; boolean stungT2 = false; - // Grow damage - t1Condition = (t1->scale > t2->scale + (mapobjectscale/8)); - t2Condition = (t2->scale > t1->scale + (mapobjectscale/8)); - - if (t1Condition == true && t2Condition == false) - { - P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE); - return true; - } - else if (t1Condition == false && t2Condition == true) - { - P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); - return true; - } - - // Invincibility damage - t1Condition = (t1->player->invincibilitytimer > 0); - t2Condition = (t2->player->invincibilitytimer > 0); + t1Condition = (t1->scale > t2->scale + (mapobjectscale/8)) || (t1->player->invincibilitytimer > 0); + t2Condition = (t2->scale > t1->scale + (mapobjectscale/8)) || (t2->player->invincibilitytimer > 0); if (t1Condition == true && t2Condition == false) { @@ -816,6 +879,9 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) { P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); return true; + } else if (t1Condition == true && t2Condition == true) { + K_DoPowerClash(t1->player, t2->player); + return false; } // Flame Shield dash damage diff --git a/src/k_collide.h b/src/k_collide.h index 49cc3fa08..cf1ee5dc7 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -19,6 +19,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2); boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2); +void K_LightningShieldAttack(mobj_t *actor, fixed_t size); boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2); boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); diff --git a/src/k_grandprix.c b/src/k_grandprix.c index c07bf2a81..740730c6f 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -95,6 +95,25 @@ INT16 K_CalculateGPRankPoints(UINT8 position, UINT8 numplayers) return points; } +/*-------------------------------------------------- + SINT8 K_BotDefaultSkin(void) + + See header file for description. +--------------------------------------------------*/ +SINT8 K_BotDefaultSkin(void) +{ + const char *defaultbotskinname = "eggrobo"; + SINT8 defaultbotskin = R_SkinAvailable(defaultbotskinname); + + if (defaultbotskin == -1) + { + // This shouldn't happen, but just in case + defaultbotskin = 0; + } + + return defaultbotskin; +} + /*-------------------------------------------------- void K_InitGrandPrixBots(void) @@ -102,8 +121,7 @@ INT16 K_CalculateGPRankPoints(UINT8 position, UINT8 numplayers) --------------------------------------------------*/ void K_InitGrandPrixBots(void) { - const char *defaultbotskinname = "eggrobo"; - SINT8 defaultbotskin = R_SkinAvailable(defaultbotskinname); + const SINT8 defaultbotskin = K_BotDefaultSkin(); const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed); UINT8 difficultylevels[MAXPLAYERS]; @@ -121,12 +139,6 @@ void K_InitGrandPrixBots(void) UINT8 newplayernum = 0; UINT8 i, j; - if (defaultbotskin == -1) - { - // This shouldn't happen, but just in case - defaultbotskin = 0; - } - memset(competitors, MAXPLAYERS, sizeof (competitors)); memset(botskinlist, defaultbotskin, sizeof (botskinlist)); @@ -144,7 +156,7 @@ void K_InitGrandPrixBots(void) } #if MAXPLAYERS != 16 - I_Error("GP bot difficulty levels need rebalacned for the new player count!\n"); + I_Error("GP bot difficulty levels need rebalanced for the new player count!\n"); #endif if (grandprixinfo.masterbots) @@ -500,6 +512,126 @@ void K_IncreaseBotDifficulty(player_t *bot) } } +/*-------------------------------------------------- + void K_RetireBots(void) + + See header file for description. +--------------------------------------------------*/ +void K_RetireBots(void) +{ + const SINT8 defaultbotskin = K_BotDefaultSkin(); + SINT8 newDifficulty; + + boolean skinusable[MAXSKINS]; + + UINT8 i; + + if (grandprixinfo.gp == true && grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) + { + // Was last map, no replacement. + return; + } + + // init usable bot skins list + for (i = 0; i < MAXSKINS; i++) + { + if (i < numskins) + { + skinusable[i] = true; + } + else + { + skinusable[i] = false; + } + } + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + skinusable[players[i].skin] = false; + } + } + + if (!grandprixinfo.gp) // Sure, let's let this happen all the time :) + { + newDifficulty = cv_kartbot.value; + } + else + { + const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed); + newDifficulty = startingdifficulty - 4 + grandprixinfo.roundnum; + } + + if (newDifficulty > MAXBOTDIFFICULTY) + { + newDifficulty = MAXBOTDIFFICULTY; + } + else if (newDifficulty < 1) + { + newDifficulty = 1; + } + + for (i = 0; i < MAXPLAYERS; i++) + { + player_t *bot = NULL; + + if (!playeringame[i] || !players[i].bot) + { + continue; + } + + bot = &players[i]; + + if (bot->spectator) + { + continue; + } + + if (bot->pflags & PF_NOCONTEST) + { + UINT8 skinnum = P_RandomKey(numskins); + UINT8 loops = 0; + + while (!skinusable[skinnum]) + { + if (loops >= numskins) + { + // no more skins + break; + } + + skinnum++; + + if (skinnum >= numskins) + { + skinnum = 0; + } + + loops++; + } + + if (loops >= numskins) + { + // Use default skin + skinnum = defaultbotskin; + } + + skinusable[skinnum] = false; + + bot->botvars.difficulty = newDifficulty; + bot->botvars.diffincrease = 0; + + SetPlayerSkinByNum(bot - players, skinnum); + bot->skincolor = skins[skinnum].prefcolor; + sprintf(player_names[bot - players], "%s", skins[skinnum].realname); + + bot->score = 0; + bot->pflags &= ~PF_NOCONTEST; + } + } +} + /*-------------------------------------------------- void K_FakeBotResults(player_t *bot) diff --git a/src/k_grandprix.h b/src/k_grandprix.h index 9f27b485b..bd20d3894 100644 --- a/src/k_grandprix.h +++ b/src/k_grandprix.h @@ -62,6 +62,16 @@ UINT8 K_BotStartingDifficulty(SINT8 value); INT16 K_CalculateGPRankPoints(UINT8 position, UINT8 numplayers); +/*-------------------------------------------------- + SINT8 K_BotDefaultSkin(void); + + Returns the skin number of the skin the game + uses as a fallback option. +--------------------------------------------------*/ + +SINT8 K_BotDefaultSkin(void); + + /*-------------------------------------------------- void K_InitGrandPrixBots(void); @@ -95,6 +105,16 @@ void K_UpdateGrandPrixBots(void); void K_IncreaseBotDifficulty(player_t *bot); +/*-------------------------------------------------- + void K_RetireBots(void); + + Replaces PF_NOCONTEST bots, by refreshing their difficulty + and changing their skin. +--------------------------------------------------*/ + +void K_RetireBots(void); + + /*-------------------------------------------------- void K_FakeBotResults(player_t *bot); @@ -136,7 +156,7 @@ void K_PlayerLoseLife(player_t *player); None Return:- - None + true if can change important gameplay rules, otherwise false. --------------------------------------------------*/ boolean K_CanChangeRules(void); diff --git a/src/k_hud.c b/src/k_hud.c index 1b67abc75..0f3ed8b7d 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -126,7 +126,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_thundershield[2]; +static patch_t *kp_lightningshield[2]; static patch_t *kp_bubbleshield[2]; static patch_t *kp_flameshield[2]; static patch_t *kp_hyudoro[2]; @@ -179,24 +179,24 @@ void K_LoadKartHUDGraphics(void) char buffer[9]; // Null Stuff - kp_nodraw = W_CachePatchName("K_TRNULL", PU_HUDGFX); + HU_UpdatePatch(&kp_nodraw, "K_TRNULL"); // Stickers - kp_timesticker = W_CachePatchName("K_STTIME", PU_HUDGFX); - kp_timestickerwide = W_CachePatchName("K_STTIMW", PU_HUDGFX); - kp_lapsticker = W_CachePatchName("K_STLAPS", PU_HUDGFX); - kp_lapstickerwide = W_CachePatchName("K_STLAPW", PU_HUDGFX); - kp_lapstickernarrow = W_CachePatchName("K_STLAPN", PU_HUDGFX); - kp_splitlapflag = W_CachePatchName("K_SPTLAP", PU_HUDGFX); - kp_bumpersticker = W_CachePatchName("K_STBALN", PU_HUDGFX); - kp_bumperstickerwide = W_CachePatchName("K_STBALW", PU_HUDGFX); - kp_capsulesticker = W_CachePatchName("K_STCAPN", PU_HUDGFX); - kp_capsulestickerwide = W_CachePatchName("K_STCAPW", PU_HUDGFX); - kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX); - kp_spheresticker = W_CachePatchName("K_STBSMT", PU_HUDGFX); - kp_splitspheresticker = W_CachePatchName("K_SPBSMT", PU_HUDGFX); - kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX); - kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX); + HU_UpdatePatch(&kp_timesticker, "K_STTIME"); + HU_UpdatePatch(&kp_timestickerwide, "K_STTIMW"); + HU_UpdatePatch(&kp_lapsticker, "K_STLAPS"); + HU_UpdatePatch(&kp_lapstickerwide, "K_STLAPW"); + HU_UpdatePatch(&kp_lapstickernarrow, "K_STLAPN"); + HU_UpdatePatch(&kp_splitlapflag, "K_SPTLAP"); + HU_UpdatePatch(&kp_bumpersticker, "K_STBALN"); + HU_UpdatePatch(&kp_bumperstickerwide, "K_STBALW"); + HU_UpdatePatch(&kp_capsulesticker, "K_STCAPN"); + HU_UpdatePatch(&kp_capsulestickerwide, "K_STCAPW"); + HU_UpdatePatch(&kp_karmasticker, "K_STKARM"); + HU_UpdatePatch(&kp_spheresticker, "K_STBSMT"); + HU_UpdatePatch(&kp_splitspheresticker, "K_SPBSMT"); + HU_UpdatePatch(&kp_splitkarmabomb, "K_SPTKRM"); + HU_UpdatePatch(&kp_timeoutsticker, "K_STTOUT"); // Pre-start countdown bulbs sprintf(buffer, "K_BULBxx"); @@ -204,7 +204,7 @@ void K_LoadKartHUDGraphics(void) { buffer[6] = '0'+((i+1)/10); buffer[7] = '0'+((i+1)%10); - kp_prestartbulb[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_prestartbulb[i], "%s", buffer); } sprintf(buffer, "K_SBLBxx"); @@ -212,68 +212,68 @@ void K_LoadKartHUDGraphics(void) { buffer[6] = '0'+((i+1)/10); buffer[7] = '0'+((i+1)%10); - kp_prestartbulb_split[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_prestartbulb_split[i], "%s", buffer); } // Pre-start position letters - kp_prestartletters[0] = W_CachePatchName("K_PL_P", PU_HUDGFX); - kp_prestartletters[1] = W_CachePatchName("K_PL_O", PU_HUDGFX); - kp_prestartletters[2] = W_CachePatchName("K_PL_S", PU_HUDGFX); - kp_prestartletters[3] = W_CachePatchName("K_PL_I", PU_HUDGFX); - kp_prestartletters[4] = W_CachePatchName("K_PL_T", PU_HUDGFX); - kp_prestartletters[5] = W_CachePatchName("K_PL_N", PU_HUDGFX); - kp_prestartletters[6] = W_CachePatchName("K_PL_EX", PU_HUDGFX); + HU_UpdatePatch(&kp_prestartletters[0], "K_PL_P"); + HU_UpdatePatch(&kp_prestartletters[1], "K_PL_O"); + HU_UpdatePatch(&kp_prestartletters[2], "K_PL_S"); + HU_UpdatePatch(&kp_prestartletters[3], "K_PL_I"); + HU_UpdatePatch(&kp_prestartletters[4], "K_PL_T"); + HU_UpdatePatch(&kp_prestartletters[5], "K_PL_N"); + HU_UpdatePatch(&kp_prestartletters[6], "K_PL_EX"); - kp_prestartletters_split[0] = W_CachePatchName("K_SPL_P", PU_HUDGFX); - kp_prestartletters_split[1] = W_CachePatchName("K_SPL_O", PU_HUDGFX); - kp_prestartletters_split[2] = W_CachePatchName("K_SPL_S", PU_HUDGFX); - kp_prestartletters_split[3] = W_CachePatchName("K_SPL_I", PU_HUDGFX); - kp_prestartletters_split[4] = W_CachePatchName("K_SPL_T", PU_HUDGFX); - kp_prestartletters_split[5] = W_CachePatchName("K_SPL_N", PU_HUDGFX); - kp_prestartletters_split[6] = W_CachePatchName("K_SPL_EX", PU_HUDGFX); + HU_UpdatePatch(&kp_prestartletters_split[0], "K_SPL_P"); + HU_UpdatePatch(&kp_prestartletters_split[1], "K_SPL_O"); + HU_UpdatePatch(&kp_prestartletters_split[2], "K_SPL_S"); + HU_UpdatePatch(&kp_prestartletters_split[3], "K_SPL_I"); + HU_UpdatePatch(&kp_prestartletters_split[4], "K_SPL_T"); + HU_UpdatePatch(&kp_prestartletters_split[5], "K_SPL_N"); + HU_UpdatePatch(&kp_prestartletters_split[6], "K_SPL_EX"); // Starting countdown - kp_startcountdown[0] = W_CachePatchName("K_CNT3A", PU_HUDGFX); - kp_startcountdown[1] = W_CachePatchName("K_CNT2A", PU_HUDGFX); - kp_startcountdown[2] = W_CachePatchName("K_CNT1A", PU_HUDGFX); - kp_startcountdown[3] = W_CachePatchName("K_CNTGOA", PU_HUDGFX); - kp_startcountdown[4] = W_CachePatchName("K_DUEL1", PU_HUDGFX); - kp_startcountdown[5] = W_CachePatchName("K_CNT3B", PU_HUDGFX); - kp_startcountdown[6] = W_CachePatchName("K_CNT2B", PU_HUDGFX); - kp_startcountdown[7] = W_CachePatchName("K_CNT1B", PU_HUDGFX); - kp_startcountdown[8] = W_CachePatchName("K_CNTGOB", PU_HUDGFX); - kp_startcountdown[9] = W_CachePatchName("K_DUEL2", PU_HUDGFX); + HU_UpdatePatch(&kp_startcountdown[0], "K_CNT3A"); + HU_UpdatePatch(&kp_startcountdown[1], "K_CNT2A"); + HU_UpdatePatch(&kp_startcountdown[2], "K_CNT1A"); + HU_UpdatePatch(&kp_startcountdown[3], "K_CNTGOA"); + HU_UpdatePatch(&kp_startcountdown[4], "K_DUEL1"); + HU_UpdatePatch(&kp_startcountdown[5], "K_CNT3B"); + HU_UpdatePatch(&kp_startcountdown[6], "K_CNT2B"); + HU_UpdatePatch(&kp_startcountdown[7], "K_CNT1B"); + HU_UpdatePatch(&kp_startcountdown[8], "K_CNTGOB"); + HU_UpdatePatch(&kp_startcountdown[9], "K_DUEL2"); // Splitscreen - kp_startcountdown[10] = W_CachePatchName("K_SMC3A", PU_HUDGFX); - kp_startcountdown[11] = W_CachePatchName("K_SMC2A", PU_HUDGFX); - kp_startcountdown[12] = W_CachePatchName("K_SMC1A", PU_HUDGFX); - kp_startcountdown[13] = W_CachePatchName("K_SMCGOA", PU_HUDGFX); - kp_startcountdown[14] = W_CachePatchName("K_SDUEL1", PU_HUDGFX); - kp_startcountdown[15] = W_CachePatchName("K_SMC3B", PU_HUDGFX); - kp_startcountdown[16] = W_CachePatchName("K_SMC2B", PU_HUDGFX); - kp_startcountdown[17] = W_CachePatchName("K_SMC1B", PU_HUDGFX); - kp_startcountdown[18] = W_CachePatchName("K_SMCGOB", PU_HUDGFX); - kp_startcountdown[19] = W_CachePatchName("K_SDUEL2", PU_HUDGFX); + HU_UpdatePatch(&kp_startcountdown[10], "K_SMC3A"); + HU_UpdatePatch(&kp_startcountdown[11], "K_SMC2A"); + HU_UpdatePatch(&kp_startcountdown[12], "K_SMC1A"); + HU_UpdatePatch(&kp_startcountdown[13], "K_SMCGOA"); + HU_UpdatePatch(&kp_startcountdown[14], "K_SDUEL1"); + HU_UpdatePatch(&kp_startcountdown[15], "K_SMC3B"); + HU_UpdatePatch(&kp_startcountdown[16], "K_SMC2B"); + HU_UpdatePatch(&kp_startcountdown[17], "K_SMC1B"); + HU_UpdatePatch(&kp_startcountdown[18], "K_SMCGOB"); + HU_UpdatePatch(&kp_startcountdown[19], "K_SDUEL2"); // Fault - kp_racefault[0] = W_CachePatchName("K_FAULTA", PU_HUDGFX); - kp_racefault[1] = W_CachePatchName("K_FAULTB", PU_HUDGFX); + HU_UpdatePatch(&kp_racefault[0], "K_FAULTA"); + HU_UpdatePatch(&kp_racefault[1], "K_FAULTB"); // Splitscreen - kp_racefault[2] = W_CachePatchName("K_SMFLTA", PU_HUDGFX); - kp_racefault[3] = W_CachePatchName("K_SMFLTB", PU_HUDGFX); + HU_UpdatePatch(&kp_racefault[2], "K_SMFLTA"); + HU_UpdatePatch(&kp_racefault[3], "K_SMFLTB"); // 2P splitscreen - kp_racefault[4] = W_CachePatchName("K_2PFLTA", PU_HUDGFX); - kp_racefault[5] = W_CachePatchName("K_2PFLTB", PU_HUDGFX); + HU_UpdatePatch(&kp_racefault[4], "K_2PFLTA"); + HU_UpdatePatch(&kp_racefault[5], "K_2PFLTB"); // Finish - kp_racefinish[0] = W_CachePatchName("K_FINA", PU_HUDGFX); - kp_racefinish[1] = W_CachePatchName("K_FINB", PU_HUDGFX); + HU_UpdatePatch(&kp_racefinish[0], "K_FINA"); + HU_UpdatePatch(&kp_racefinish[1], "K_FINB"); // Splitscreen - kp_racefinish[2] = W_CachePatchName("K_SMFINA", PU_HUDGFX); - kp_racefinish[3] = W_CachePatchName("K_SMFINB", PU_HUDGFX); + HU_UpdatePatch(&kp_racefinish[2], "K_SMFINA"); + HU_UpdatePatch(&kp_racefinish[3], "K_SMFINB"); // 2P splitscreen - kp_racefinish[4] = W_CachePatchName("K_2PFINA", PU_HUDGFX); - kp_racefinish[5] = W_CachePatchName("K_2PFINB", PU_HUDGFX); + HU_UpdatePatch(&kp_racefinish[4], "K_2PFINA"); + HU_UpdatePatch(&kp_racefinish[5], "K_2PFINB"); // Position numbers sprintf(buffer, "K_POSNxx"); @@ -284,7 +284,7 @@ void K_LoadKartHUDGraphics(void) { //sprintf(buffer, "K_POSN%d%d", i, j); buffer[7] = '0'+j; - kp_positionnum[i][j] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_positionnum[i][j], "%s", buffer); } } @@ -292,7 +292,7 @@ void K_LoadKartHUDGraphics(void) for (i = 0; i < NUMWINFRAMES; i++) { buffer[7] = '0'+i; - kp_winnernum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_winnernum[i], "%s", buffer); } sprintf(buffer, "OPPRNKxx"); @@ -300,129 +300,129 @@ void K_LoadKartHUDGraphics(void) { buffer[6] = '0'+(i/10); buffer[7] = '0'+(i%10); - kp_facenum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_facenum[i], "%s", buffer); } sprintf(buffer, "K_CHILIx"); for (i = 0; i < 8; i++) { buffer[7] = '0'+(i+1); - kp_facehighlight[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_facehighlight[i], "%s", buffer); } - kp_spbminimap = W_CachePatchName("SPBMMAP", PU_HUDGFX); + HU_UpdatePatch(&kp_spbminimap, "SPBMMAP"); // Rings & Lives - kp_ringsticker[0] = W_CachePatchName("RNGBACKA", PU_HUDGFX); - kp_ringsticker[1] = W_CachePatchName("RNGBACKB", PU_HUDGFX); + HU_UpdatePatch(&kp_ringsticker[0], "RNGBACKA"); + HU_UpdatePatch(&kp_ringsticker[1], "RNGBACKB"); sprintf(buffer, "K_RINGx"); for (i = 0; i < 6; i++) { buffer[6] = '0'+(i+1); - kp_ring[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_ring[i], "%s", buffer); } - kp_ringdebtminus = W_CachePatchName("RDEBTMIN", PU_HUDGFX); + HU_UpdatePatch(&kp_ringdebtminus, "RDEBTMIN"); sprintf(buffer, "SPBRNGxx"); for (i = 0; i < 16; i++) { buffer[6] = '0'+((i+1) / 10); buffer[7] = '0'+((i+1) % 10); - kp_ringspblock[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_ringspblock[i], "%s", buffer); } - kp_ringstickersplit[0] = W_CachePatchName("SMRNGBGA", PU_HUDGFX); - kp_ringstickersplit[1] = W_CachePatchName("SMRNGBGB", PU_HUDGFX); + HU_UpdatePatch(&kp_ringstickersplit[0], "SMRNGBGA"); + HU_UpdatePatch(&kp_ringstickersplit[1], "SMRNGBGB"); sprintf(buffer, "K_SRINGx"); for (i = 0; i < 6; i++) { buffer[7] = '0'+(i+1); - kp_smallring[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_smallring[i], "%s", buffer); } - kp_ringdebtminussmall = W_CachePatchName("SRDEBTMN", PU_HUDGFX); + HU_UpdatePatch(&kp_ringdebtminussmall, "SRDEBTMN"); sprintf(buffer, "SPBRGSxx"); for (i = 0; i < 16; i++) { buffer[6] = '0'+((i+1) / 10); buffer[7] = '0'+((i+1) % 10); - kp_ringspblocksmall[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_ringspblocksmall[i], "%s", buffer); } // Speedometer - kp_speedometersticker = W_CachePatchName("K_SPDMBG", PU_HUDGFX); + HU_UpdatePatch(&kp_speedometersticker, "K_SPDMBG"); sprintf(buffer, "K_SPDMLx"); for (i = 0; i < 4; i++) { buffer[7] = '0'+(i+1); - kp_speedometerlabel[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_speedometerlabel[i], "%s", buffer); } // Extra ranking icons - kp_rankbumper = W_CachePatchName("K_BLNICO", PU_HUDGFX); - kp_tinybumper[0] = W_CachePatchName("K_BLNA", PU_HUDGFX); - kp_tinybumper[1] = W_CachePatchName("K_BLNB", PU_HUDGFX); - kp_ranknobumpers = W_CachePatchName("K_NOBLNS", PU_HUDGFX); - kp_rankcapsule = W_CachePatchName("K_CAPICO", PU_HUDGFX); - kp_rankemerald = W_CachePatchName("K_EMERC", PU_HUDGFX); - kp_rankemeraldflash = W_CachePatchName("K_EMERW", PU_HUDGFX); - kp_rankemeraldback = W_CachePatchName("K_EMERBK", PU_HUDGFX); + HU_UpdatePatch(&kp_rankbumper, "K_BLNICO"); + HU_UpdatePatch(&kp_tinybumper[0], "K_BLNA"); + HU_UpdatePatch(&kp_tinybumper[1], "K_BLNB"); + HU_UpdatePatch(&kp_ranknobumpers, "K_NOBLNS"); + HU_UpdatePatch(&kp_rankcapsule, "K_CAPICO"); + HU_UpdatePatch(&kp_rankemerald, "K_EMERC"); + HU_UpdatePatch(&kp_rankemeraldflash, "K_EMERW"); + HU_UpdatePatch(&kp_rankemeraldback, "K_EMERBK"); // Battle graphics - kp_battlewin = W_CachePatchName("K_BWIN", PU_HUDGFX); - kp_battlecool = W_CachePatchName("K_BCOOL", PU_HUDGFX); - kp_battlelose = W_CachePatchName("K_BLOSE", PU_HUDGFX); - kp_battlewait = W_CachePatchName("K_BWAIT", PU_HUDGFX); - kp_battleinfo = W_CachePatchName("K_BINFO", PU_HUDGFX); - kp_wanted = W_CachePatchName("K_WANTED", PU_HUDGFX); - kp_wantedsplit = W_CachePatchName("4PWANTED", PU_HUDGFX); - kp_wantedreticle = W_CachePatchName("MMAPWANT", PU_HUDGFX); + HU_UpdatePatch(&kp_battlewin, "K_BWIN"); + HU_UpdatePatch(&kp_battlecool, "K_BCOOL"); + HU_UpdatePatch(&kp_battlelose, "K_BLOSE"); + HU_UpdatePatch(&kp_battlewait, "K_BWAIT"); + HU_UpdatePatch(&kp_battleinfo, "K_BINFO"); + HU_UpdatePatch(&kp_wanted, "K_WANTED"); + HU_UpdatePatch(&kp_wantedsplit, "4PWANTED"); + HU_UpdatePatch(&kp_wantedreticle, "MMAPWANT"); // Kart Item Windows - kp_itembg[0] = W_CachePatchName("K_ITBG", PU_HUDGFX); - kp_itembg[1] = W_CachePatchName("K_ITBGD", PU_HUDGFX); - kp_itemtimer[0] = W_CachePatchName("K_ITIMER", PU_HUDGFX); - kp_itemmulsticker[0] = W_CachePatchName("K_ITMUL", PU_HUDGFX); - kp_itemx = W_CachePatchName("K_ITX", PU_HUDGFX); + HU_UpdatePatch(&kp_itembg[0], "K_ITBG"); + HU_UpdatePatch(&kp_itembg[1], "K_ITBGD"); + HU_UpdatePatch(&kp_itemtimer[0], "K_ITIMER"); + HU_UpdatePatch(&kp_itemmulsticker[0], "K_ITMUL"); + HU_UpdatePatch(&kp_itemx, "K_ITX"); - kp_superring[0] = W_CachePatchName("K_ITRING", PU_HUDGFX); - kp_sneaker[0] = W_CachePatchName("K_ITSHOE", PU_HUDGFX); - kp_rocketsneaker[0] = W_CachePatchName("K_ITRSHE", PU_HUDGFX); + HU_UpdatePatch(&kp_superring[0], "K_ITRING"); + HU_UpdatePatch(&kp_sneaker[0], "K_ITSHOE"); + HU_UpdatePatch(&kp_rocketsneaker[0], "K_ITRSHE"); sprintf(buffer, "K_ITINVx"); for (i = 0; i < 7; i++) { buffer[7] = '1'+i; - kp_invincibility[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_invincibility[i], "%s", buffer); } - kp_banana[0] = W_CachePatchName("K_ITBANA", PU_HUDGFX); - kp_eggman[0] = W_CachePatchName("K_ITEGGM", PU_HUDGFX); + HU_UpdatePatch(&kp_banana[0], "K_ITBANA"); + HU_UpdatePatch(&kp_eggman[0], "K_ITEGGM"); sprintf(buffer, "K_ITORBx"); for (i = 0; i < 4; i++) { buffer[7] = '1'+i; - kp_orbinaut[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_orbinaut[i], "%s", buffer); } - kp_jawz[0] = W_CachePatchName("K_ITJAWZ", PU_HUDGFX); - kp_mine[0] = W_CachePatchName("K_ITMINE", PU_HUDGFX); - kp_landmine[0] = W_CachePatchName("K_ITLNDM", PU_HUDGFX); - kp_droptarget[0] = W_CachePatchName("K_ITDTRG", PU_HUDGFX); - kp_ballhog[0] = W_CachePatchName("K_ITBHOG", PU_HUDGFX); - 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_thundershield[0] = W_CachePatchName("K_ITTHNS", PU_HUDGFX); - kp_bubbleshield[0] = W_CachePatchName("K_ITBUBS", PU_HUDGFX); - kp_flameshield[0] = W_CachePatchName("K_ITFLMS", 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); - kp_sadface[0] = W_CachePatchName("K_ITSAD", PU_HUDGFX); + HU_UpdatePatch(&kp_jawz[0], "K_ITJAWZ"); + HU_UpdatePatch(&kp_mine[0], "K_ITMINE"); + HU_UpdatePatch(&kp_landmine[0], "K_ITLNDM"); + HU_UpdatePatch(&kp_droptarget[0], "K_ITDTRG"); + HU_UpdatePatch(&kp_ballhog[0], "K_ITBHOG"); + HU_UpdatePatch(&kp_selfpropelledbomb[0], "K_ITSPB"); + HU_UpdatePatch(&kp_grow[0], "K_ITGROW"); + HU_UpdatePatch(&kp_shrink[0], "K_ITSHRK"); + HU_UpdatePatch(&kp_lightningshield[0], "K_ITTHNS"); + HU_UpdatePatch(&kp_bubbleshield[0], "K_ITBUBS"); + HU_UpdatePatch(&kp_flameshield[0], "K_ITFLMS"); + HU_UpdatePatch(&kp_hyudoro[0], "K_ITHYUD"); + HU_UpdatePatch(&kp_pogospring[0], "K_ITPOGO"); + HU_UpdatePatch(&kp_kitchensink[0], "K_ITSINK"); + HU_UpdatePatch(&kp_sadface[0], "K_ITSAD"); sprintf(buffer, "FSMFGxxx"); for (i = 0; i < 104; i++) @@ -430,7 +430,7 @@ void K_LoadKartHUDGraphics(void) buffer[5] = '0'+((i+1)/100); buffer[6] = '0'+(((i+1)/10)%10); buffer[7] = '0'+((i+1)%10); - kp_flameshieldmeter[i][0] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_flameshieldmeter[i][0], "%s", buffer); } sprintf(buffer, "FSMBG0xx"); @@ -438,42 +438,42 @@ void K_LoadKartHUDGraphics(void) { buffer[6] = '0'+((i+1)/10); buffer[7] = '0'+((i+1)%10); - kp_flameshieldmeter_bg[i][0] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_flameshieldmeter_bg[i][0], "%s", buffer); } // Splitscreen - kp_itembg[2] = W_CachePatchName("K_ISBG", PU_HUDGFX); - kp_itembg[3] = W_CachePatchName("K_ISBGD", PU_HUDGFX); - kp_itemtimer[1] = W_CachePatchName("K_ISIMER", PU_HUDGFX); - kp_itemmulsticker[1] = W_CachePatchName("K_ISMUL", PU_HUDGFX); + HU_UpdatePatch(&kp_itembg[2], "K_ISBG"); + HU_UpdatePatch(&kp_itembg[3], "K_ISBGD"); + HU_UpdatePatch(&kp_itemtimer[1], "K_ISIMER"); + HU_UpdatePatch(&kp_itemmulsticker[1], "K_ISMUL"); - kp_superring[1] = W_CachePatchName("K_ISRING", PU_HUDGFX); - kp_sneaker[1] = W_CachePatchName("K_ISSHOE", PU_HUDGFX); - kp_rocketsneaker[1] = W_CachePatchName("K_ISRSHE", PU_HUDGFX); + HU_UpdatePatch(&kp_superring[1], "K_ISRING"); + HU_UpdatePatch(&kp_sneaker[1], "K_ISSHOE"); + HU_UpdatePatch(&kp_rocketsneaker[1], "K_ISRSHE"); sprintf(buffer, "K_ISINVx"); for (i = 0; i < 6; i++) { buffer[7] = '1'+i; - kp_invincibility[i+7] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_invincibility[i+7], "%s", buffer); } - kp_banana[1] = W_CachePatchName("K_ISBANA", PU_HUDGFX); - kp_eggman[1] = W_CachePatchName("K_ISEGGM", PU_HUDGFX); - kp_orbinaut[4] = W_CachePatchName("K_ISORBN", PU_HUDGFX); - kp_jawz[1] = W_CachePatchName("K_ISJAWZ", PU_HUDGFX); - kp_mine[1] = W_CachePatchName("K_ISMINE", PU_HUDGFX); - kp_landmine[1] = W_CachePatchName("K_ISLNDM", PU_HUDGFX); - kp_droptarget[1] = W_CachePatchName("K_ISDTRG", PU_HUDGFX); - kp_ballhog[1] = W_CachePatchName("K_ISBHOG", PU_HUDGFX); - 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_thundershield[1] = W_CachePatchName("K_ISTHNS", PU_HUDGFX); - kp_bubbleshield[1] = W_CachePatchName("K_ISBUBS", PU_HUDGFX); - kp_flameshield[1] = W_CachePatchName("K_ISFLMS", 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); - kp_sadface[1] = W_CachePatchName("K_ISSAD", PU_HUDGFX); + HU_UpdatePatch(&kp_banana[1], "K_ISBANA"); + HU_UpdatePatch(&kp_eggman[1], "K_ISEGGM"); + HU_UpdatePatch(&kp_orbinaut[4], "K_ISORBN"); + HU_UpdatePatch(&kp_jawz[1], "K_ISJAWZ"); + HU_UpdatePatch(&kp_mine[1], "K_ISMINE"); + HU_UpdatePatch(&kp_landmine[1], "K_ISLNDM"); + HU_UpdatePatch(&kp_droptarget[1], "K_ISDTRG"); + HU_UpdatePatch(&kp_ballhog[1], "K_ISBHOG"); + HU_UpdatePatch(&kp_selfpropelledbomb[1], "K_ISSPB"); + HU_UpdatePatch(&kp_grow[1], "K_ISGROW"); + HU_UpdatePatch(&kp_shrink[1], "K_ISSHRK"); + HU_UpdatePatch(&kp_lightningshield[1], "K_ISTHNS"); + HU_UpdatePatch(&kp_bubbleshield[1], "K_ISBUBS"); + HU_UpdatePatch(&kp_flameshield[1], "K_ISFLMS"); + HU_UpdatePatch(&kp_hyudoro[1], "K_ISHYUD"); + HU_UpdatePatch(&kp_pogospring[1], "K_ISPOGO"); + HU_UpdatePatch(&kp_kitchensink[1], "K_ISSINK"); + HU_UpdatePatch(&kp_sadface[1], "K_ISSAD"); sprintf(buffer, "FSMFSxxx"); for (i = 0; i < 104; i++) @@ -481,7 +481,7 @@ void K_LoadKartHUDGraphics(void) buffer[5] = '0'+((i+1)/100); buffer[6] = '0'+(((i+1)/10)%10); buffer[7] = '0'+((i+1)%10); - kp_flameshieldmeter[i][1] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_flameshieldmeter[i][1], "%s", buffer); } sprintf(buffer, "FSMBS0xx"); @@ -489,7 +489,7 @@ void K_LoadKartHUDGraphics(void) { buffer[6] = '0'+((i+1)/10); buffer[7] = '0'+((i+1)%10); - kp_flameshieldmeter_bg[i][1] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_flameshieldmeter_bg[i][1], "%s", buffer); } // CHECK indicators @@ -497,7 +497,7 @@ void K_LoadKartHUDGraphics(void) for (i = 0; i < 6; i++) { buffer[7] = '1'+i; - kp_check[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_check[i], "%s", buffer); } // Rival indicators @@ -505,7 +505,7 @@ void K_LoadKartHUDGraphics(void) for (i = 0; i < 2; i++) { buffer[7] = '1'+i; - kp_rival[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_rival[i], "%s", buffer); } // Rival indicators @@ -516,33 +516,33 @@ void K_LoadKartHUDGraphics(void) for (j = 0; j < 2; j++) { buffer[7] = '1'+j; - kp_localtag[i][j] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_localtag[i][j], "%s", buffer); } } // Typing indicator - kp_talk = W_CachePatchName("K_TALK", PU_HUDGFX); - kp_typdot = W_CachePatchName("K_TYPDOT", PU_HUDGFX); + HU_UpdatePatch(&kp_talk, "K_TALK"); + HU_UpdatePatch(&kp_typdot, "K_TYPDOT"); // Eggman warning numbers sprintf(buffer, "K_EGGNx"); for (i = 0; i < 4; i++) { buffer[6] = '0'+i; - kp_eggnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_eggnum[i], "%s", buffer); } // First person mode - kp_fpview[0] = W_CachePatchName("VIEWA0", PU_HUDGFX); - kp_fpview[1] = W_CachePatchName("VIEWB0D0", PU_HUDGFX); - kp_fpview[2] = W_CachePatchName("VIEWC0E0", PU_HUDGFX); + HU_UpdatePatch(&kp_fpview[0], "VIEWA0"); + HU_UpdatePatch(&kp_fpview[1], "VIEWB0D0"); + HU_UpdatePatch(&kp_fpview[2], "VIEWC0E0"); // Input UI Wheel sprintf(buffer, "K_WHEELx"); for (i = 0; i < 5; i++) { buffer[7] = '0'+i; - kp_inputwheel[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_inputwheel[i], "%s", buffer); } // HERE COMES A NEW CHALLENGER @@ -551,7 +551,7 @@ void K_LoadKartHUDGraphics(void) { buffer[6] = '0'+((i+1)/10); buffer[7] = '0'+((i+1)%10); - kp_challenger[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_challenger[i], "%s", buffer); } // Lap start animation @@ -559,7 +559,7 @@ void K_LoadKartHUDGraphics(void) for (i = 0; i < 7; i++) { buffer[6] = '0'+(i+1); - kp_lapanim_lap[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_lapanim_lap[i], "%s", buffer); } sprintf(buffer, "K_LAPFxx"); @@ -567,7 +567,7 @@ void K_LoadKartHUDGraphics(void) { buffer[6] = '0'+((i+1)/10); buffer[7] = '0'+((i+1)%10); - kp_lapanim_final[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_lapanim_final[i], "%s", buffer); } sprintf(buffer, "K_LAPNxx"); @@ -577,7 +577,7 @@ void K_LoadKartHUDGraphics(void) for (j = 0; j < 3; j++) { buffer[7] = '0'+(j+1); - kp_lapanim_number[i][j] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_lapanim_number[i][j], "%s", buffer); } } @@ -585,53 +585,53 @@ void K_LoadKartHUDGraphics(void) for (i = 0; i < 2; i++) { buffer[7] = '0'+(i+1); - kp_lapanim_emblem[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_lapanim_emblem[i], "%s", buffer); } sprintf(buffer, "K_LAPH0x"); for (i = 0; i < 3; i++) { buffer[7] = '0'+(i+1); - kp_lapanim_hand[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_lapanim_hand[i], "%s", buffer); } - kp_yougotem = (patch_t *) W_CachePatchName("YOUGOTEM", PU_HUDGFX); - kp_itemminimap = (patch_t *) W_CachePatchName("MMAPITEM", PU_HUDGFX); + HU_UpdatePatch(&kp_yougotem, "YOUGOTEM"); + HU_UpdatePatch(&kp_itemminimap, "MMAPITEM"); sprintf(buffer, "ALAGLESx"); for (i = 0; i < 10; ++i) { buffer[7] = '0'+i; - kp_alagles[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_alagles[i], "%s", buffer); } sprintf(buffer, "BLAGLESx"); for (i = 0; i < 6; ++i) { buffer[7] = '0'+i; - kp_blagles[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_blagles[i], "%s", buffer); } - kp_cpu = (patch_t *) W_CachePatchName("K_CPU", PU_HUDGFX); + HU_UpdatePatch(&kp_cpu, "K_CPU"); - kp_nametagstem = (patch_t *) W_CachePatchName("K_NAMEST", PU_HUDGFX); + HU_UpdatePatch(&kp_nametagstem, "K_NAMEST"); + + HU_UpdatePatch(&kp_trickcool[0], "K_COOL1"); + HU_UpdatePatch(&kp_trickcool[1], "K_COOL2"); sprintf(buffer, "K_BOSB0x"); for (i = 0; i < 8; i++) { buffer[7] = '0'+((i+1)%10); - kp_bossbar[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_bossbar[i], "%s", buffer); } sprintf(buffer, "K_BOSR0x"); for (i = 0; i < 4; i++) { buffer[7] = '0'+((i+1)%10); - kp_bossret[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + HU_UpdatePatch(&kp_bossret[i], "%s", buffer); } - - kp_trickcool[0] = W_CachePatchName("K_COOL1", PU_HUDGFX); - kp_trickcool[1] = W_CachePatchName("K_COOL2", PU_HUDGFX); } // For the item toggle menu @@ -672,7 +672,7 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny) return (tiny ? "K_ISGROW" : "K_ITGROW"); case KITEM_SHRINK: return (tiny ? "K_ISSHRK" : "K_ITSHRK"); - case KITEM_THUNDERSHIELD: + case KITEM_LIGHTNINGSHIELD: return (tiny ? "K_ISTHNS" : "K_ITTHNS"); case KITEM_BUBBLESHIELD: return (tiny ? "K_ISBUBS" : "K_ITBUBS"); @@ -1172,8 +1172,8 @@ static void K_drawKartItem(void) localpatch = kp_ballhog[offset]; //localcolor = SKINCOLOR_LILAC; break; - case 13: // Thunder Shield - localpatch = kp_thundershield[offset]; + case 13: // Lightning Shield + localpatch = kp_lightningshield[offset]; //localcolor = SKINCOLOR_CYAN; break; case 14: // Super Ring @@ -1292,8 +1292,8 @@ static void K_drawKartItem(void) case KITEM_SHRINK: localpatch = kp_shrink[offset]; break; - case KITEM_THUNDERSHIELD: - localpatch = kp_thundershield[offset]; + case KITEM_LIGHTNINGSHIELD: + localpatch = kp_lightningshield[offset]; localbg = kp_itembg[offset+1]; break; case KITEM_BUBBLESHIELD: @@ -4580,7 +4580,7 @@ static void K_drawDistributionDebugger(void) kp_selfpropelledbomb[1], kp_grow[1], kp_shrink[1], - kp_thundershield[1], + kp_lightningshield[1], kp_bubbleshield[1], kp_flameshield[1], kp_hyudoro[1], diff --git a/src/k_kart.c b/src/k_kart.c index 1071f0371..bd6077a35 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -36,6 +36,7 @@ #include "k_hud.h" #include "k_terrain.h" #include "k_director.h" +#include "k_collide.h" // SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H: // gamespeed is cc (0 for easy, 1 for normal, 2 for hard) @@ -220,7 +221,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_selfpropelledbomb); CV_RegisterVar(&cv_grow); CV_RegisterVar(&cv_shrink); - CV_RegisterVar(&cv_thundershield); + CV_RegisterVar(&cv_lightningshield); CV_RegisterVar(&cv_bubbleshield); CV_RegisterVar(&cv_flameshield); CV_RegisterVar(&cv_hyudoro); @@ -327,7 +328,7 @@ consvar_t *KartItemCVars[NUMKARTRESULTS-1] = &cv_selfpropelledbomb, &cv_grow, &cv_shrink, - &cv_thundershield, + &cv_lightningshield, &cv_bubbleshield, &cv_flameshield, &cv_hyudoro, @@ -362,7 +363,7 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = /*Self-Propelled Bomb*/ { 0, 0, 0, 0, 0, 2, 4, 0 }, // Self-Propelled Bomb /*Grow*/ { 0, 0, 0, 1, 2, 3, 0, 0 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink - /*Thunder Shield*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield + /*Lightning Shield*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Lightning Shield /*Bubble Shield*/ { 0, 1, 2, 1, 0, 0, 0, 0 }, // Bubble Shield /*Flame Shield*/ { 0, 0, 0, 0, 0, 1, 3, 5 }, // Flame Shield /*Hyudoro*/ { 0, 0, 0, 1, 1, 0, 0, 0 }, // Hyudoro @@ -395,7 +396,7 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = /*Self-Propelled Bomb*/ { 0, 0 }, // Self-Propelled Bomb /*Grow*/ { 2, 1 }, // Grow /*Shrink*/ { 0, 0 }, // Shrink - /*Thunder Shield*/ { 4, 0 }, // Thunder Shield + /*Lightning Shield*/ { 4, 0 }, // Lightning Shield /*Bubble Shield*/ { 1, 0 }, // Bubble Shield /*Flame Shield*/ { 0, 0 }, // Flame Shield /*Hyudoro*/ { 2, 0 }, // Hyudoro @@ -437,7 +438,7 @@ INT32 K_GetShieldFromItem(INT32 item) { switch (item) { - case KITEM_THUNDERSHIELD: return KSHIELD_THUNDER; + case KITEM_LIGHTNINGSHIELD: return KSHIELD_LIGHTNING; case KITEM_BUBBLESHIELD: return KSHIELD_BUBBLE; case KITEM_FLAMESHIELD: return KSHIELD_FLAME; default: return KSHIELD_NONE; @@ -733,7 +734,7 @@ INT32 K_KartGetItemOdds( if (pingame-1 <= pexiting) newodds = 0; break; - case KITEM_THUNDERSHIELD: + case KITEM_LIGHTNINGSHIELD: cooldownOnStart = true; powerItem = true; @@ -1759,9 +1760,9 @@ static void K_UpdateDraft(player_t *player) UINT8 leniency; UINT8 i; - if (player->itemtype == KITEM_FLAMESHIELD) + if (player->itemtype == KITEM_LIGHTNINGSHIELD) { - // Flame Shield gets infinite draft distance as its passive effect. + // Lightning Shield gets infinite draft distance as its (other) passive effect. draftdistance = 0; } else @@ -3105,7 +3106,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) if (K_PlayerUsesBotMovement(player)) { // Increase bot speed by 1-10% depending on difficulty - fixed_t add = (player->botvars.difficulty * (FRACUNIT/10)) / MAXBOTDIFFICULTY; + fixed_t add = (player->botvars.difficulty * (FRACUNIT/10)) / DIFFICULTBOT; finalspeed = FixedMul(finalspeed, FRACUNIT + add); if (player->botvars.rival == true) @@ -3312,6 +3313,13 @@ void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) mo->hitlag += tics; mo->hitlag = min(mo->hitlag, MAXHITLAGTICS); + if (mo->player != NULL) + { + // Reset each time. We want to explicitly set this for bananas afterwards, + // so make sure an old value doesn't possibly linger. + mo->player->flipDI = false; + } + if (fromDamage == true) { // Dunno if this should flat-out &~ the flag out too. @@ -3361,7 +3369,7 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDam } K_AddHitLag(mo1, finalTics, fromDamage); - K_AddHitLag(mo2, finalTics, fromDamage); + K_AddHitLag(mo2, finalTics, false); // mo2 is the inflictor, so don't use the damage property. } void K_DoInstashield(player_t *player) @@ -3388,6 +3396,28 @@ void K_DoInstashield(player_t *player) P_SetTarget(&layerb->target, player->mo); } +void K_DoPowerClash(player_t *t1, player_t *t2) { + mobj_t *clash; + + // short-circuit instashield for vfx visibility + t1->instashield = 1; + t2->instashield = 1; + + S_StartSound(t1->mo, sfx_parry); + K_AddHitLag(t1->mo, 6, false); + K_AddHitLag(t2->mo, 6, false); + + clash = P_SpawnMobj((t1->mo->x/2) + (t2->mo->x/2), (t1->mo->y/2) + (t2->mo->y/2), (t1->mo->z/2) + (t2->mo->z/2), MT_POWERCLASH); + + // needs to handle mixed scale collisions (t1 grow t2 invinc)... + clash->z = clash->z + (t1->mo->height/4) + (t2->mo->height/4); + clash->angle = R_PointToAngle2(clash->x, clash->y, t1->mo->x, t1->mo->y) + ANGLE_90; + + // Shrink over time (accidental behavior that looked good) + clash->destscale = (t1->mo->scale/2) + (t2->mo->scale/2); + P_SetScale(clash, 3*clash->destscale/2); +} + void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved) { UINT8 points = 1; @@ -3538,6 +3568,7 @@ static boolean K_LastTumbleBounceCondition(player_t *player) static void K_HandleTumbleBounce(player_t *player) { fixed_t gravityadjust; + player->tumbleBounces++; player->tumbleHeight = (player->tumbleHeight * ((player->tumbleHeight > 100) ? 3 : 4)) / 5; player->pflags &= ~PF_TUMBLESOUND; @@ -3568,6 +3599,10 @@ static void K_HandleTumbleBounce(player_t *player) } } + // A bit of damage hitlag. + // This gives a window for DI!! + K_AddHitLag(player->mo, 6, true); + if (P_IsDisplayPlayer(player) && player->tumbleHeight >= 40) P_StartQuake((player->tumbleHeight*3/2)<mo, sfx_zio3); - P_NukeEnemies(player->mo, player->mo, RING_DIST/4); + K_LightningShieldAttack(player->mo, (THUNDERRADIUS + THUNDERSPRITE) * FRACUNIT); // spawn vertical bolt mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK); @@ -5277,6 +5317,7 @@ static void K_DoThunderShield(player_t *player) } #undef THUNDERRADIUS +#undef THUNDERSPRITE static void K_FlameDashLeftoverSmoke(mobj_t *src) { @@ -5686,9 +5727,9 @@ void K_DropHnextList(player_t *player, boolean keepshields) if (shield != KSHIELD_NONE && !keepshields) { - if (shield == KSHIELD_THUNDER) + if (shield == KSHIELD_LIGHTNING) { - K_DoThunderShield(player); + K_DoLightningShield(player); } player->curshield = KSHIELD_NONE; @@ -6966,39 +7007,85 @@ void K_KartPlayerHUDUpdate(player_t *player) // SRB2Kart: blockmap iterate for attraction shield users static mobj_t *attractmo; static fixed_t attractdist; +static fixed_t attractzdist; + static inline boolean PIT_AttractingRings(mobj_t *thing) { - if (!attractmo || P_MobjWasRemoved(attractmo)) + if (attractmo == NULL || P_MobjWasRemoved(attractmo) || attractmo->player == NULL) + { return false; + } - if (!attractmo->player) - return false; // not a player + if (thing == NULL || P_MobjWasRemoved(thing)) + { + return true; // invalid + } - if (thing->health <= 0 || !thing) - return true; // dead + if (thing == attractmo) + { + return true; // invalid + } - if (thing->type != MT_RING && thing->type != MT_FLINGRING) + if (!(thing->type == MT_RING || thing->type == MT_FLINGRING)) + { return true; // not a ring + } + + if (thing->health <= 0) + { + return true; // dead + } if (thing->extravalue1) + { return true; // in special ring animation + } - if (thing->cusval) + if (thing->tracer != NULL && P_MobjWasRemoved(thing->tracer) == false) + { return true; // already attracted + } // see if it went over / under - if (attractmo->z - (attractdist>>2) > thing->z + thing->height) + if (attractmo->z - attractzdist > thing->z + thing->height) + { return true; // overhead - if (attractmo->z + attractmo->height + (attractdist>>2) < thing->z) + } + + if (attractmo->z + attractmo->height + attractzdist < thing->z) + { return true; // underneath + } - if (P_AproxDistance(attractmo->x - thing->x, attractmo->y - thing->y) < attractdist) + if (P_AproxDistance(attractmo->x - thing->x, attractmo->y - thing->y) > attractdist + thing->radius) + { return true; // Too far away + } + + if (RINGTOTAL(attractmo->player) >= 20 || (attractmo->player->pflags & PF_RINGLOCK)) + { + // Already reached max -- just joustle rings around. + + // Regular ring -> fling ring + if (thing->info->reactiontime && thing->type != (mobjtype_t)thing->info->reactiontime) + { + thing->type = thing->info->reactiontime; + thing->info = &mobjinfo[thing->type]; + thing->flags = thing->info->flags; + + P_InstaThrust(thing, P_RandomRange(0,7) * ANGLE_45, 2 * thing->scale); + P_SetObjectMomZ(thing, 8<fuse = 120*TICRATE; + + thing->cusval = 0; // Reset attraction flag + } + } + else + { + // set target + P_SetTarget(&thing->tracer, attractmo); + } - // set target - P_SetTarget(&thing->tracer, attractmo); - // flag to show it's been attracted once before - thing->cusval = 1; return true; // find other rings } @@ -7010,15 +7097,18 @@ static inline boolean PIT_AttractingRings(mobj_t *thing) static void K_LookForRings(mobj_t *pmo) { INT32 bx, by, xl, xh, yl, yh; - attractdist = FixedMul(RING_DIST, pmo->scale)>>2; - - // Use blockmap to check for nearby rings - yh = (unsigned)(pmo->y + attractdist - bmaporgy)>>MAPBLOCKSHIFT; - yl = (unsigned)(pmo->y - attractdist - bmaporgy)>>MAPBLOCKSHIFT; - xh = (unsigned)(pmo->x + attractdist - bmaporgx)>>MAPBLOCKSHIFT; - xl = (unsigned)(pmo->x - attractdist - bmaporgx)>>MAPBLOCKSHIFT; attractmo = pmo; + attractdist = (400 * pmo->scale); + attractzdist = attractdist >> 2; + + // Use blockmap to check for nearby rings + yh = (unsigned)(pmo->y + (attractdist + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(pmo->y - (attractdist + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(pmo->x + (attractdist + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(pmo->x - (attractdist + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); for (by = yl; by <= yh; by++) for (bx = xl; bx <= xh; bx++) @@ -7440,12 +7530,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } - if (player->itemtype == KITEM_THUNDERSHIELD) - { - if (RINGTOTAL(player) < 20 && !(player->pflags & PF_RINGLOCK)) - K_LookForRings(player->mo); - } - if (player->itemtype == KITEM_BUBBLESHIELD) { if (player->bubblecool) @@ -7656,6 +7740,11 @@ void K_KartPlayerAfterThink(player_t *player) player->lastjawztarget = -1; player->jawztargetdelay = 0; } + + if (player->itemtype == KITEM_LIGHTNINGSHIELD) + { + K_LookForRings(player->mo); + } } /*-------------------------------------------------- @@ -8024,7 +8113,7 @@ INT32 K_GetKartRingPower(player_t *player, boolean boosted) if (boosted == true && K_PlayerUsesBotMovement(player)) { // Double for Lv. 9 - ringPower += (player->botvars.difficulty * ringPower) / MAXBOTDIFFICULTY; + ringPower += (player->botvars.difficulty * ringPower) / DIFFICULTBOT; } return ringPower; @@ -8149,6 +8238,12 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return 0; } + if (player->justDI == true) + { + // No turning until you let go after DI-ing. + return 0; + } + currentSpeed = FixedHypot(player->mo->momx, player->mo->momy); if ((currentSpeed <= 0) // Not moving @@ -9729,23 +9824,23 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayPowerGloatSound(player->mo); } break; - case KITEM_THUNDERSHIELD: - if (player->curshield != KSHIELD_THUNDER) + case KITEM_LIGHTNINGSHIELD: + if (player->curshield != KSHIELD_LIGHTNING) { - mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD); + mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_LIGHTNINGSHIELD); P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); P_SetTarget(&shield->target, player->mo); S_StartSound(player->mo, sfx_s3k41); - player->curshield = KSHIELD_THUNDER; + player->curshield = KSHIELD_LIGHTNING; } if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - K_DoThunderShield(player); + K_DoLightningShield(player); if (player->itemamount > 0) { // Why is this a conditional? - // Thunder shield: the only item that allows you to + // Lightning shield: the only item that allows you to // activate a mine while you're out of its radius, // the SAME tic it sets your itemamount to 0 // ...:dumbestass: @@ -10093,7 +10188,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_trickPanelTimingVisual(player, momz); } - else if (player->throwdir == 1) + else if (cmd->throwdir > 0) { if (player->mo->momz * P_MobjFlip(player->mo) > 0) { @@ -10108,7 +10203,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_trickPanelTimingVisual(player, momz); } - else if (player->throwdir == -1) + else if (cmd->throwdir < 0) { boolean relative = true; @@ -10316,4 +10411,102 @@ boolean K_IsSPBInGame(void) return false; } +void K_HandleDirectionalInfluence(player_t *player) +{ + fixed_t strength = FRACUNIT >> 1; // 1.0 == 45 degrees + + ticcmd_t *cmd = NULL; + angle_t sideAngle = ANGLE_MAX; + + INT16 inputX, inputY; + INT16 inputLen; + + fixed_t diX, diY; + fixed_t diLen; + fixed_t diMul; + + fixed_t dot, invDot; + + fixed_t finalX, finalY; + fixed_t finalLen; + fixed_t speed; + + if (player->playerstate != PST_LIVE || player->spectator) + { + // ded + return; + } + + // DI attempted!! + player->justDI = true; + + cmd = &player->cmd; + + inputX = cmd->throwdir; + inputY = -cmd->turning; + + if (player->flipDI == true) + { + // Bananas flip the DI direction. + // Otherwise, DIing bananas is a little brain-dead easy :p + inputX = -inputX; + inputY = -inputY; + } + + if (inputX == 0 && inputY == 0) + { + // No DI input, no need to do anything else. + return; + } + + inputLen = FixedHypot(inputX, inputY); + if (inputLen > KART_FULLTURN) + { + inputLen = KART_FULLTURN; + } + + if (player->tumbleBounces > 0) + { + // Very strong DI for tumble. + strength *= 3; + } + + sideAngle = player->mo->angle - ANGLE_90; + + diX = FixedMul(inputX, FINECOSINE(player->mo->angle >> ANGLETOFINESHIFT)) + FixedMul(inputY, FINECOSINE(sideAngle >> ANGLETOFINESHIFT)); + diY = FixedMul(inputX, FINESINE(player->mo->angle >> ANGLETOFINESHIFT)) + FixedMul(inputY, FINESINE(sideAngle >> ANGLETOFINESHIFT)); + diLen = FixedHypot(diX, diY); + + // Normalize + diMul = (KART_FULLTURN * FRACUNIT) / inputLen; + if (diLen > 0) + { + diX = FixedMul(diMul, FixedDiv(diX, diLen)); + diY = FixedMul(diMul, FixedDiv(diY, diLen)); + } + + // Now that we got the DI direction, we can + // actually preform the velocity redirection. + + speed = FixedHypot(player->mo->momx, player->mo->momy); + finalX = FixedDiv(player->mo->momx, speed); + finalY = FixedDiv(player->mo->momy, speed); + + dot = FixedMul(diX, finalX) + FixedMul(diY, finalY); + invDot = FRACUNIT - abs(dot); + + finalX += FixedMul(FixedMul(diX, invDot), strength); + finalY += FixedMul(FixedMul(diY, invDot), strength); + finalLen = FixedHypot(finalX, finalY); + + if (finalLen > 0) + { + finalX = FixedDiv(finalX, finalLen); + finalY = FixedDiv(finalY, finalLen); + } + + player->mo->momx = FixedMul(speed, finalX); + player->mo->momy = FixedMul(speed, finalY); +} + //} diff --git a/src/k_kart.h b/src/k_kart.h index aef18b19e..89f176d29 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -67,6 +67,7 @@ angle_t K_MomentumAngle(mobj_t *mo); void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage); void K_DoInstashield(player_t *player); +void K_DoPowerClash(player_t *t1, player_t *t2); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); @@ -142,6 +143,7 @@ UINT8 K_GetInvincibilityItemFrame(void); UINT8 K_GetOrbinautItemFrame(UINT8 count); boolean K_IsSPBInGame(void); void K_KartEbrakeVisuals(player_t *p); +void K_HandleDirectionalInfluence(player_t *player); // sound stuff for lua void K_PlayAttackTaunt(mobj_t *source); diff --git a/src/k_menudef.c b/src/k_menudef.c index 3a570b74a..cbeb1599e 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -983,7 +983,7 @@ menuitem_t OPTIONS_GameplayItems[] = {IT_KEYHANDLER | IT_NOTHING, NULL, "Ballhogs", NULL, {.routine = M_HandleItemToggles}, KITEM_BALLHOG, 0}, {IT_KEYHANDLER | IT_NOTHING, NULL, "Drop Targets", NULL, {.routine = M_HandleItemToggles}, KITEM_DROPTARGET, sfx_s258}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Thunder Shields", NULL, {.routine = M_HandleItemToggles}, KITEM_THUNDERSHIELD, 0}, + {IT_KEYHANDLER | IT_NOTHING, NULL, "Lightning Shields", NULL, {.routine = M_HandleItemToggles}, KITEM_LIGHTNINGSHIELD, 0}, {IT_KEYHANDLER | IT_NOTHING, NULL, "Bubble Shields", NULL, {.routine = M_HandleItemToggles}, KITEM_BUBBLESHIELD, 0}, {IT_KEYHANDLER | IT_NOTHING, NULL, "Flame Shields", NULL, {.routine = M_HandleItemToggles}, KITEM_FLAMESHIELD, 0}, {IT_KEYHANDLER | IT_NOTHING, NULL, "Hyudoros", NULL, {.routine = M_HandleItemToggles}, KITEM_HYUDORO, 0}, diff --git a/src/k_pathfind.c b/src/k_pathfind.c index eb91dda2b..857f0343a 100644 --- a/src/k_pathfind.c +++ b/src/k_pathfind.c @@ -427,7 +427,7 @@ boolean K_PathfindAStar(path_t *const path, pathfindsetup_t *const pathfindsetup else { // skip this node if it isn't traversable - if (pathfindsetup->gettraversable(checknodedata) == false) + if (pathfindsetup->gettraversable(checknodedata, currentnode->nodedata) == false) { continue; } diff --git a/src/k_pathfind.h b/src/k_pathfind.h index ba0e38f47..7b7f1475f 100644 --- a/src/k_pathfind.h +++ b/src/k_pathfind.h @@ -27,7 +27,7 @@ typedef UINT32*(*getnodeconnectioncostsfunc)(void*); typedef UINT32(*getnodeheuristicfunc)(void*, void*); // function pointer for getting if a node is traversable from its base data -typedef boolean(*getnodetraversablefunc)(void*); +typedef boolean(*getnodetraversablefunc)(void*, void*); // A pathfindnode contains information about a node from the pathfinding diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 903e66e2a..06d0a1a84 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -558,11 +558,9 @@ static void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *c --------------------------------------------------*/ static void K_DebugWaypointDrawRadius(waypoint_t *const waypoint) { + const fixed_t spriteRadius = 96*FRACUNIT; mobj_t *radiusOrb; mobj_t *waypointmobj; - const INT32 numRadiusMobjs = 64; - INT32 i = 0; - angle_t spawnAngle = 0U; fixed_t spawnX= 0; fixed_t spawnY= 0; fixed_t spawnZ= 0; @@ -572,22 +570,21 @@ static void K_DebugWaypointDrawRadius(waypoint_t *const waypoint) waypointmobj = waypoint->mobj; - for (i = 0; i < numRadiusMobjs; i++) - { - spawnAngle = (ANGLE_MAX / numRadiusMobjs) * i; + spawnX = waypointmobj->x; + spawnY = waypointmobj->y; + spawnZ = waypointmobj->z + 16*mapobjectscale; - spawnZ = waypointmobj->z; - spawnX = waypointmobj->x + P_ReturnThrustX(waypointmobj, spawnAngle, waypointmobj->radius); - spawnY = waypointmobj->y + P_ReturnThrustY(waypointmobj, spawnAngle, waypointmobj->radius); + radiusOrb = P_SpawnMobj(spawnX, spawnY, spawnZ, MT_SPARK); - radiusOrb = P_SpawnMobj(spawnX, spawnY, spawnZ, MT_SPARK); - P_SetMobjState(radiusOrb, S_THOK); - radiusOrb->tics = 1; - radiusOrb->frame &= ~FF_TRANSMASK; - radiusOrb->frame |= FF_FULLBRIGHT; - radiusOrb->color = SKINCOLOR_PURPLE; - radiusOrb->scale = radiusOrb->scale / 4; - } + P_SetMobjState(radiusOrb, S_WAYPOINTSPLAT); + radiusOrb->tics = 1; + + radiusOrb->frame &= ~FF_TRANSMASK; + radiusOrb->frame |= FF_FULLBRIGHT; + radiusOrb->color = SKINCOLOR_PURPLE; + + radiusOrb->destscale = FixedDiv(waypointmobj->radius, spriteRadius); + P_SetScale(radiusOrb, radiusOrb->destscale); } /*-------------------------------------------------- @@ -620,10 +617,10 @@ void K_DebugWaypointsVisualise(void) waypoint = K_SearchWaypointHeapForMobj(waypointmobj); debugmobj = P_SpawnMobj(waypointmobj->x, waypointmobj->y, waypointmobj->z, MT_SPARK); - P_SetMobjState(debugmobj, S_THOK); + P_SetMobjState(debugmobj, S_WAYPOINTORB); debugmobj->frame &= ~FF_TRANSMASK; - debugmobj->frame |= FF_TRANS20|FF_FULLBRIGHT; + debugmobj->frame |= FF_FULLBRIGHT; //FF_TRANS20 // There's a waypoint setup for this mobj! So draw that it's a valid waypoint and draw lines to its connections if (waypoint != NULL) @@ -648,6 +645,11 @@ void K_DebugWaypointsVisualise(void) else { debugmobj->color = SKINCOLOR_BLUE; + + if (K_GetWaypointIsShortcut(waypoint)) + { + debugmobj->color = SKINCOLOR_PINK; + } } if (!K_GetWaypointIsEnabled(waypoint)) @@ -655,6 +657,11 @@ void K_DebugWaypointsVisualise(void) debugmobj->color = SKINCOLOR_GREY; } + if (!K_GetWaypointIsSpawnpoint(waypoint)) + { + debugmobj->frame |= FF_TRANS40; + } + // Valid waypoint, so draw lines of SPARKLES to its next or previous waypoints if (cv_kartdebugwaypoints.value == 1) { @@ -975,10 +982,12 @@ static UINT32 K_WaypointPathfindGetHeuristic(void *data1, void *data2) Return:- True if the waypoint is traversable, false otherwise. --------------------------------------------------*/ -static boolean K_WaypointPathfindTraversableAllEnabled(void *data) +static boolean K_WaypointPathfindTraversableAllEnabled(void *data, void *prevdata) { boolean traversable = false; + (void)prevdata; + if (data == NULL) { CONS_Debug(DBG_GAMELOGIC, "K_WaypointPathfindTraversableAllEnabled received NULL data.\n"); @@ -1004,18 +1013,21 @@ static boolean K_WaypointPathfindTraversableAllEnabled(void *data) Return:- True if the waypoint is traversable, false otherwise. --------------------------------------------------*/ -static boolean K_WaypointPathfindTraversableNoShortcuts(void *data) +static boolean K_WaypointPathfindTraversableNoShortcuts(void *data, void *prevdata) { boolean traversable = false; - if (data == NULL) + if (data == NULL || prevdata == NULL) { CONS_Debug(DBG_GAMELOGIC, "K_WaypointPathfindTraversableNoShortcuts received NULL data.\n"); } else { waypoint_t *waypoint = (waypoint_t *)data; - traversable = ((K_GetWaypointIsShortcut(waypoint) == false) && (K_GetWaypointIsEnabled(waypoint) == true)); + waypoint_t *prevWaypoint = (waypoint_t *)prevdata; + + traversable = ((K_GetWaypointIsEnabled(waypoint) == true) + && (K_GetWaypointIsShortcut(waypoint) == false || K_GetWaypointIsShortcut(prevWaypoint) == true)); // Allow shortcuts to be used if the starting waypoint is already a shortcut. } return traversable; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 4d334a9a4..319448593 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -213,7 +213,6 @@ static const struct { {META_BBOX, "bbox"}, - {META_HUDINFO, "hudinfo_t"}, {META_PATCH, "patch_t"}, {META_COLORMAP, "colormap"}, {META_CAMERA, "camera_t"}, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 75a84ed18..b5e3d1acc 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -14,7 +14,7 @@ #include "fastcmp.h" #include "r_defs.h" #include "r_local.h" -#include "st_stuff.h" // hudinfo[] +#include "st_stuff.h" #include "g_game.h" #include "i_video.h" // rendermode #include "p_local.h" // camera_t @@ -63,18 +63,6 @@ static const char *const hud_disable_options[] = { "intermissionmessages", NULL}; -enum hudinfo { - hudinfo_x = 0, - hudinfo_y, - hudinfo_f -}; - -static const char *const hudinfo_opt[] = { - "x", - "y", - "f", - NULL}; - enum patch { patch_valid = 0, patch_width, @@ -182,73 +170,6 @@ static const char *const camera_opt[] = { "pnum", NULL}; -static int lib_getHudInfo(lua_State *L) -{ - UINT32 i; - lua_remove(L, 1); - - i = luaL_checkinteger(L, 1); - if (i >= NUMHUDITEMS) - return luaL_error(L, "hudinfo[] index %d out of range (0 - %d)", i, NUMHUDITEMS-1); - LUA_PushUserdata(L, &hudinfo[i], META_HUDINFO); - return 1; -} - -static int lib_hudinfolen(lua_State *L) -{ - lua_pushinteger(L, NUMHUDITEMS); - return 1; -} - -static int hudinfo_get(lua_State *L) -{ - hudinfo_t *info = *((hudinfo_t **)luaL_checkudata(L, 1, META_HUDINFO)); - enum hudinfo field = luaL_checkoption(L, 2, hudinfo_opt[0], hudinfo_opt); - I_Assert(info != NULL); // huditems are always valid - - switch(field) - { - case hudinfo_x: - lua_pushinteger(L, info->x); - break; - case hudinfo_y: - lua_pushinteger(L, info->y); - break; - case hudinfo_f: - lua_pushinteger(L, info->f); - break; - } - return 1; -} - -static int hudinfo_set(lua_State *L) -{ - hudinfo_t *info = *((hudinfo_t **)luaL_checkudata(L, 1, META_HUDINFO)); - enum hudinfo field = luaL_checkoption(L, 2, hudinfo_opt[0], hudinfo_opt); - I_Assert(info != NULL); - - switch(field) - { - case hudinfo_x: - info->x = (INT32)luaL_checkinteger(L, 3); - break; - case hudinfo_y: - info->y = (INT32)luaL_checkinteger(L, 3); - break; - case hudinfo_f: - info->f = (INT32)luaL_checkinteger(L, 3); - break; - } - return 0; -} - -static int hudinfo_num(lua_State *L) -{ - hudinfo_t *info = *((hudinfo_t **)luaL_checkudata(L, 1, META_HUDINFO)); - lua_pushinteger(L, info-hudinfo); - return 1; -} - static int colormap_get(lua_State *L) { const UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); @@ -1307,27 +1228,6 @@ int LUA_HudLib(lua_State *L) lua_rawseti(L, -2, 6); // HUD[6] = title card rendering functions array lua_setfield(L, LUA_REGISTRYINDEX, "HUD"); - luaL_newmetatable(L, META_HUDINFO); - lua_pushcfunction(L, hudinfo_get); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, hudinfo_set); - lua_setfield(L, -2, "__newindex"); - - lua_pushcfunction(L, hudinfo_num); - lua_setfield(L, -2, "__len"); - lua_pop(L,1); - - lua_newuserdata(L, 0); - lua_createtable(L, 0, 2); - lua_pushcfunction(L, lib_getHudInfo); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, lib_hudinfolen); - lua_setfield(L, -2, "__len"); - lua_setmetatable(L, -2); - lua_setglobal(L, "hudinfo"); - luaL_newmetatable(L, META_COLORMAP); lua_pushcfunction(L, colormap_get); lua_setfield(L, -2, "__index"); diff --git a/src/lua_libs.h b/src/lua_libs.h index c02964467..a6580622b 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -81,7 +81,6 @@ extern lua_State *gL; #define META_BBOX "BOUNDING_BOX" -#define META_HUDINFO "HUDINFO_T*" #define META_PATCH "PATCH_T*" #define META_COLORMAP "COLORMAP" #define META_CAMERA "CAMERA_T*" diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 3d05d9c15..506d6b96a 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -238,6 +238,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->tumbleBounces); else if (fastcmp(field,"tumbleHeight")) lua_pushinteger(L, plr->tumbleHeight); + else if (fastcmp(field,"justDI")) + lua_pushboolean(L, plr->justDI); + else if (fastcmp(field,"flipDI")) + lua_pushboolean(L, plr->flipDI); else if (fastcmp(field,"drift")) lua_pushinteger(L, plr->drift); else if (fastcmp(field,"driftcharge")) @@ -584,6 +588,10 @@ static int player_set(lua_State *L) plr->tumbleBounces = luaL_checkinteger(L, 3); else if (fastcmp(field,"tumbleHeight")) plr->tumbleHeight = luaL_checkinteger(L, 3); + else if (fastcmp(field,"justDI")) + plr->justDI = luaL_checkboolean(L, 3); + else if (fastcmp(field,"flipDI")) + plr->flipDI = luaL_checkboolean(L, 3); else if (fastcmp(field,"drift")) plr->drift = luaL_checkinteger(L, 3); else if (fastcmp(field,"driftcharge")) @@ -891,6 +899,8 @@ static int ticcmd_get(lua_State *L) lua_pushinteger(L, cmd->forwardmove); else if (fastcmp(field,"turning")) lua_pushinteger(L, cmd->turning); + else if (fastcmp(field,"throwdir")) + lua_pushinteger(L, cmd->throwdir); else if (fastcmp(field,"aiming")) lua_pushinteger(L, cmd->aiming); else if (fastcmp(field,"buttons")) @@ -919,6 +929,8 @@ static int ticcmd_set(lua_State *L) cmd->forwardmove = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"turning")) cmd->turning = (INT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"throwdir")) + cmd->throwdir = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"aiming")) cmd->aiming = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"buttons")) diff --git a/src/m_misc.c b/src/m_misc.c index c00d7ee70..50021c18e 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -776,7 +776,7 @@ void M_SaveConfig(const char *filename) } // header message - fprintf(f, "// SRB2Kart configuration file.\n"); + fprintf(f, "// Dr. Robotnik's Ring Racers configuration file.\n"); // print execversion FIRST, because subsequent consvars need to be filtered // always print current EXECVERSION @@ -815,20 +815,20 @@ static void M_CreateScreenShotPalette(void) #if NUMSCREENS > 2 static const char *Newsnapshotfile(const char *pathname, const char *ext) { - static char freename[13] = "kartXXXX.ext"; + static char freename[19] = "ringracersXXXX.ext"; int i = 5000; // start in the middle: num screenshots divided by 2 int add = i; // how much to add or subtract if wrong; gets divided by 2 each time int result; // -1 = guess too high, 0 = correct, 1 = guess too low // find a file name to save it to - strcpy(freename+9,ext); + strcpy(freename+15,ext); for (;;) { - freename[4] = (char)('0' + (char)(i/1000)); - freename[5] = (char)('0' + (char)((i/100)%10)); - freename[6] = (char)('0' + (char)((i/10)%10)); - freename[7] = (char)('0' + (char)(i%10)); + freename[10] = (char)('0' + (char)(i/1000)); + freename[11] = (char)('0' + (char)((i/100)%10)); + freename[12] = (char)('0' + (char)((i/10)%10)); + freename[13] = (char)('0' + (char)(i%10)); if (FIL_WriteFileOK(va(pandf,pathname,freename))) // access succeeds result = 1; // too low @@ -837,10 +837,10 @@ static const char *Newsnapshotfile(const char *pathname, const char *ext) if (!i) break; // not too high, so it must be equal! YAY! - freename[4] = (char)('0' + (char)((i-1)/1000)); - freename[5] = (char)('0' + (char)(((i-1)/100)%10)); - freename[6] = (char)('0' + (char)(((i-1)/10)%10)); - freename[7] = (char)('0' + (char)((i-1)%10)); + freename[10] = (char)('0' + (char)((i-1)/1000)); + freename[11] = (char)('0' + (char)(((i-1)/100)%10)); + freename[12] = (char)('0' + (char)(((i-1)/10)%10)); + freename[13] = (char)('0' + (char)((i-1)%10)); if (!FIL_WriteFileOK(va(pandf,pathname,freename))) // access fails result = -1; // too high else @@ -858,10 +858,10 @@ static const char *Newsnapshotfile(const char *pathname, const char *ext) return NULL; } - freename[4] = (char)('0' + (char)(i/1000)); - freename[5] = (char)('0' + (char)((i/100)%10)); - freename[6] = (char)('0' + (char)((i/10)%10)); - freename[7] = (char)('0' + (char)(i%10)); + freename[10] = (char)('0' + (char)(i/1000)); + freename[11] = (char)('0' + (char)((i/100)%10)); + freename[12] = (char)('0' + (char)((i/10)%10)); + freename[13] = (char)('0' + (char)(i%10)); return freename; } @@ -921,10 +921,10 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png char keytxt[SRB2PNGTXT][12] = { "Title", "Description", "Playername", "Mapnum", "Mapname", "Location", "Interface", "Render Mode", "Revision", "Build Date", "Build Time"}; - char titletxt[] = "SRB2Kart " VERSIONSTRING; + char titletxt[] = "Dr. Robotnik's Ring Racers " VERSIONSTRING; png_charp playertxt = cv_playername[0].zstring; - char desctxt[] = "SRB2Kart Screenshot"; - char Movietxt[] = "SRB2Kart Movie"; + char desctxt[] = "Ring Racers Screenshot"; + char Movietxt[] = "Ring Racers Movie"; size_t i; char interfacetxt[] = #ifdef HAVE_SDL diff --git a/src/m_perfstats.c b/src/m_perfstats.c index b58599b6d..03930f495 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -46,6 +46,7 @@ static precise_t ps_frametime = 0; precise_t ps_tictime = 0; precise_t ps_playerthink_time = 0; +precise_t ps_botticcmd_time = 0; precise_t ps_thinkertime = 0; precise_t ps_thlist_times[NUM_THINKERLISTS]; @@ -363,6 +364,7 @@ static void M_DrawTickStats(void) perfstatrow_t extra_thinker_time_row[] = { {"lthinkf", "LUAh_ThinkFrame:", &ps_lua_thinkframe_time}, + {"botcmd ", "Bot logic: ", &ps_botticcmd_time}, {"other ", "Other: ", &extratime}, {0} }; diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 1ca71957f..dae2f2030 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -19,6 +19,7 @@ extern precise_t ps_tictime; extern precise_t ps_playerthink_time; +extern precise_t ps_botticcmd_time; extern precise_t ps_thinkertime; extern precise_t ps_thlist_times[]; diff --git a/src/mserv.c b/src/mserv.c index 85c546f9a..b1af77379 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -73,7 +73,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ms.kartkrew.org/ms/api", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); consvar_t cv_rendezvousserver = CVAR_INIT ("rendezvousserver", "relay.kartkrew.org", CV_SAVE|CV_CALL, NULL, RendezvousServer_OnChange); -consvar_t cv_servername = CVAR_INIT ("servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters); +consvar_t cv_servername = CVAR_INIT ("servername", "Ring Racers server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters); consvar_t cv_server_contact = CVAR_INIT ("server_contact", "", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters); consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, MasterClient_Ticker); diff --git a/src/p_enemy.c b/src/p_enemy.c index 7b6d12983..65f00e116 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4044,57 +4044,76 @@ void A_AttractChase(mobj_t *actor) actor->renderflags &= ~RF_DONTDRAW; // spilled rings get capped to a certain speed - if (actor->type == (mobjtype_t)actor->info->reactiontime) + if (actor->info->reactiontime && actor->type == (mobjtype_t)actor->info->reactiontime) { - const fixed_t maxspeed = 4<scale; fixed_t oldspeed = R_PointToDist2(0, 0, actor->momx, actor->momy); if (oldspeed > maxspeed) { - fixed_t newspeed = max(maxspeed, oldspeed-FRACUNIT); + fixed_t newspeed = max(maxspeed, oldspeed - actor->scale); actor->momx = FixedMul(FixedDiv(actor->momx, oldspeed), newspeed); actor->momy = FixedMul(FixedDiv(actor->momy, oldspeed), newspeed); } } - if (actor->tracer && actor->tracer->player && actor->tracer->health - //&& P_CheckSight(actor, actor->tracer) - && actor->tracer->player->itemtype == KITEM_THUNDERSHIELD - && RINGTOTAL(actor->tracer->player) < 20 - && !(actor->tracer->player->pflags & PF_RINGLOCK)) + if (actor->tracer != NULL && P_MobjWasRemoved(actor->tracer) == false) { - fixed_t dist; - angle_t hang, vang; + // Set attraction flag + actor->cusval = 1; - // If a flung ring gets attracted by a shield, change it into a normal ring. - if (actor->type == (mobjtype_t)actor->info->reactiontime) + if ( + actor->tracer->player && actor->tracer->health + && actor->tracer->player->itemtype == KITEM_LIGHTNINGSHIELD + && RINGTOTAL(actor->tracer->player) < 20 + && !(actor->tracer->player->pflags & PF_RINGLOCK) + //&& P_CheckSight(actor, actor->tracer) + ) { - P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->painchance); - P_RemoveMobj(actor); - return; + fixed_t dist; + angle_t hang, vang; + + // If a flung ring gets attracted by a shield, change it into a normal ring. + if (actor->info->painchance && actor->type != (mobjtype_t)actor->info->painchance) + { +#if 0 // old + P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->painchance); + P_RemoveMobj(actor); + return; +#else // new + actor->type = actor->info->painchance; + actor->info = &mobjinfo[actor->type]; + actor->flags = actor->info->flags; +#endif + } + + // Keep stuff from going down inside floors and junk + actor->flags &= ~MF_NOCLIPHEIGHT; + + // Let attracted rings move through walls and such. + actor->flags |= MF_NOCLIP; + + // P_Attract is too "smart" for Kart; keep it simple, stupid! + dist = P_AproxDistance(P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z); + hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y); + vang = R_PointToAngle2(actor->z, 0, actor->tracer->z, dist); + + actor->momx -= actor->momx>>4, actor->momy -= actor->momy>>4, actor->momz -= actor->momz>>4; + actor->momx += FixedMul(FINESINE(vang>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(hang>>ANGLETOFINESHIFT), 4*actor->scale)); + actor->momy += FixedMul(FINESINE(vang>>ANGLETOFINESHIFT), FixedMul(FINESINE(hang>>ANGLETOFINESHIFT), 4*actor->scale)); + actor->momz += FixedMul(FINECOSINE(vang>>ANGLETOFINESHIFT), 4*actor->scale); + } + else + { + P_SetTarget(&actor->tracer, NULL); } - - // Keep stuff from going down inside floors and junk - actor->flags &= ~MF_NOCLIPHEIGHT; - - // Let attracted rings move through walls and such. - actor->flags |= MF_NOCLIP; - - // P_Attract is too "smart" for Kart; keep it simple, stupid! - dist = P_AproxDistance(P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z); - hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y); - vang = R_PointToAngle2(actor->z , 0, actor->tracer->z, dist); - - actor->momx -= actor->momx>>4, actor->momy -= actor->momy>>4, actor->momz -= actor->momz>>4; - actor->momx += FixedMul(FINESINE(vang>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(hang>>ANGLETOFINESHIFT), 4*actor->scale)); - actor->momy += FixedMul(FINESINE(vang>>ANGLETOFINESHIFT), FixedMul(FINESINE(hang>>ANGLETOFINESHIFT), 4*actor->scale)); - actor->momz += FixedMul(FINECOSINE(vang>>ANGLETOFINESHIFT), 4*actor->scale); } else { // Turn rings back into flung rings if lost if (actor->cusval && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime) { +#if 0 // old mobj_t *newring; newring = P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->reactiontime); P_InstaThrust(newring, P_RandomRange(0,7) * ANGLE_45, 2<fuse = 120*TICRATE; P_RemoveMobj(actor); return; +#else // new + actor->type = actor->info->reactiontime; + actor->info = &mobjinfo[actor->type]; + actor->flags = actor->info->flags; + + P_InstaThrust(actor, P_RandomRange(0,7) * ANGLE_45, 2 * actor->scale); + P_SetObjectMomZ(actor, 8<fuse = 120*TICRATE; +#endif } - /*else - P_LookForShield(actor);*/ - // SRB2Kart: now it's the PLAYER'S job to use the blockmap to find rings, not the ring's. + + actor->cusval = 0; // Reset attraction flag } } } diff --git a/src/p_inter.c b/src/p_inter.c index aceb8336c..9e98a8808 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2095,6 +2095,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player->instashield = 15; K_SetHitLagForObjects(target, inflictor, laglength, true); + + if (inflictor && !P_MobjWasRemoved(inflictor) && inflictor->type == MT_BANANA) + { + player->flipDI = true; + } + return true; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 155f9bf3e..1db80bb09 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5897,8 +5897,8 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->tracer->frame = KITEM_BALLHOG; //localcolor = SKINCOLOR_LILAC; break; - case 13: // Thunder Shield - mobj->tracer->frame = KITEM_THUNDERSHIELD; + case 13: // Lightning Shield + mobj->tracer->frame = KITEM_LIGHTNINGSHIELD; //localcolor = SKINCOLOR_CYAN; break; case 14: // Super Ring @@ -6500,6 +6500,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) // No need to check water. Who cares? P_RingThinker(mobj); + if (mobj->flags2 & MF2_NIGHTSPULL) P_NightsItemChase(mobj); else @@ -7378,11 +7379,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->renderflags = (mobj->renderflags & ~RF_TRANSMASK)|(trans << RF_TRANSSHIFT); } break; - case MT_THUNDERSHIELD: + case MT_LIGHTNINGSHIELD: { fixed_t destx, desty; if (!mobj->target || !mobj->target->health || !mobj->target->player - || mobj->target->player->curshield != KSHIELD_THUNDER) + || mobj->target->player->curshield != KSHIELD_LIGHTNING) { P_RemoveMobj(mobj); return false; @@ -7401,7 +7402,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) else viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, camera[0].x, camera[0].y); - if (curstate > S_THUNDERSHIELD15 && curstate <= S_THUNDERSHIELD24) + if (curstate > S_LIGHTNINGSHIELD15 && curstate <= S_LIGHTNINGSHIELD24) viewingangle += ANGLE_180; destx = mobj->target->x + P_ReturnThrustX(mobj->target, viewingangle, mobj->scale>>4); @@ -9143,6 +9144,11 @@ void P_MobjThinker(mobj_t *mobj) mobj->spriteyscale = 5*FRACUNIT; } + if (mobj->player != NULL && mobj->hitlag == 0 && (mobj->eflags & MFE_DAMAGEHITLAG)) + { + K_HandleDirectionalInfluence(mobj->player); + } + return; } @@ -9331,10 +9337,13 @@ void P_MobjThinker(mobj_t *mobj) || mobj->type == MT_FALLINGROCK || mobj->type == MT_ORBINAUT || mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD - || (mobj->type == MT_DROPTARGET && mobj->reactiontime)) { + || (mobj->type == MT_DROPTARGET && mobj->reactiontime)) + { P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly + if (P_MobjWasRemoved(mobj)) // anything that calls checkposition can be lethal return; + //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); P_ButteredSlope(mobj); } @@ -9661,7 +9670,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) thing->shadowscale = 5*FRACUNIT/4; thing->whiteshadow = true; break; - case MT_THUNDERSHIELD: + case MT_LIGHTNINGSHIELD: case MT_BUBBLESHIELD: case MT_BUBBLESHIELDTRAP: case MT_FLAMESHIELD: diff --git a/src/p_saveg.c b/src/p_saveg.c index bebc5c161..84157decb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -244,6 +244,9 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].tumbleBounces); WRITEUINT16(save_p, players[i].tumbleHeight); + WRITEUINT8(save_p, players[i].justDI); + WRITEUINT8(save_p, players[i].flipDI); + WRITESINT8(save_p, players[i].drift); WRITEFIXED(save_p, players[i].driftcharge); WRITEUINT8(save_p, players[i].driftboost); @@ -514,6 +517,9 @@ static void P_NetUnArchivePlayers(void) players[i].tumbleBounces = READUINT8(save_p); players[i].tumbleHeight = READUINT16(save_p); + players[i].justDI = (boolean)READUINT8(save_p); + players[i].flipDI = (boolean)READUINT8(save_p); + players[i].drift = READSINT8(save_p); players[i].driftcharge = READFIXED(save_p); players[i].driftboost = READUINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index f2da9c0f8..b788d40e0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4607,6 +4607,8 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l return lumpinfo; } +UINT16 p_adding_file = INT16_MAX; + // // Add a wadfile to the active wad files, // replace sounds, musics, patches, textures, sprites and maps @@ -4644,6 +4646,8 @@ boolean P_AddWadFile(const char *wadfilename) else wadnum = (UINT16)(numwadfiles-1); + p_adding_file = wadnum; + switch(wadfiles[wadnum]->type) { case RET_PK3: @@ -4740,16 +4744,16 @@ boolean P_AddWadFile(const char *wadfilename) // Reload it all anyway, just in case they // added some textures but didn't insert a // TEXTURES/etc. list. - R_LoadTextures(); // numtexture changes + R_LoadTexturesPwad(wadnum); // numtexture changes // Reload ANIMDEFS P_InitPicAnims(); // Reload BRIGHT - K_InitBrightmaps(); + K_InitBrightmapsPwad(wadnum); // Flush and reload HUD graphics - ST_UnloadGraphics(); + //ST_UnloadGraphics(); HU_LoadGraphics(); ST_LoadGraphics(); @@ -4765,11 +4769,6 @@ boolean P_AddWadFile(const char *wadfilename) // S_LoadMusicDefs(wadnum); - // - // edit music defs - // - S_LoadMusicDefs(wadnum); - // // search for maps // @@ -4829,5 +4828,7 @@ boolean P_AddWadFile(const char *wadfilename) refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_GAMEDATA to disappear the next frame, but it's a bit too dangerous for that... + p_adding_file = INT16_MAX; + return true; } diff --git a/src/p_setup.h b/src/p_setup.h index dfa79da14..548d9e7c0 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -96,6 +96,8 @@ INT32 P_CheckLevelFlat(const char *flatname); extern size_t nummapthings; extern mapthing_t *mapthings; +extern UINT16 p_adding_file; + void P_SetupLevelSky(const char *skytexname, boolean global); #ifdef SCANTHINGS void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); diff --git a/src/p_spec.c b/src/p_spec.c index da318a8eb..cc1a0f8a9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -164,6 +164,9 @@ void P_ParseAnimationDefintion(SINT8 istexture); * \sa P_FindAnimatedFlat, P_SetupLevelFlatAnims * \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs), JTE (had to rewrite it to handle multiple WADs _correctly_) */ + +static boolean animdeftempflats = false; // only until ANIMDEFS flats are removed + void P_InitPicAnims(void) { // Init animation @@ -183,6 +186,7 @@ void P_InitPicAnims(void) while (animdefsLumpNum != INT16_MAX) { + animdeftempflats = ((p_adding_file == INT16_MAX) || p_adding_file == w); P_ParseANIMDEFSLump(w, animdefsLumpNum); animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", (UINT16)w, animdefsLumpNum + 1); } @@ -204,7 +208,7 @@ void P_InitPicAnims(void) lastanim = anims; for (i = 0; animdefs[i].istexture != -1; i++) { - if (animdefs[i].istexture) + if (animdefs[i].istexture == 1) { if (R_CheckTextureNumForName(animdefs[i].startname) == -1) continue; @@ -213,6 +217,14 @@ void P_InitPicAnims(void) lastanim->basepic = R_TextureNumForName(animdefs[i].startname); } else + { + if (animdefs[i].istexture == 2) + { + CONS_Alert(CONS_WARNING, "ANIMDEFS flats are disabled; flat support in general will be removed soon! (%s, %s)\n", animdefs[i].startname, animdefs[i].endname); + } + continue; + } +#if 0 { if ((W_CheckNumForName(animdefs[i].startname)) == LUMPERROR) continue; @@ -220,6 +232,7 @@ void P_InitPicAnims(void) lastanim->picnum = R_GetFlatNumForName(animdefs[i].endname); lastanim->basepic = R_GetFlatNumForName(animdefs[i].startname); } +#endif lastanim->istexture = animdefs[i].istexture; lastanim->numpics = lastanim->picnum - lastanim->basepic + 1; @@ -367,7 +380,10 @@ void P_ParseAnimationDefintion(SINT8 istexture) Z_Free(animdefsToken); // set texture type - animdefs[i].istexture = istexture; + if (istexture) + animdefs[i].istexture = 1; + else + animdefs[i].istexture = (animdeftempflats ? 2 : 0); // "RANGE" animdefsToken = M_GetToken(NULL); diff --git a/src/p_user.c b/src/p_user.c index bdc45a844..d2ca62ee9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2095,6 +2095,11 @@ void P_MovePlayer(player_t *player) P_3dMovement(player); + if (cmd->turning == 0) + { + player->justDI = false; + } + // Kart frames if (player->tumbleBounces > 0) { @@ -2507,7 +2512,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (mo->flags & MF_BOSS) //don't OHKO bosses nor players! P_DamageMobj(mo, inflictor, source, 1, DMG_NORMAL|DMG_CANTHURTSELF); - else if (mo->type == MT_PLAYER) // Thunder shield: Combo players. + else if (mo->type == MT_PLAYER) // Lightning shield: Combo players. P_DamageMobj(mo, inflictor, source, 1, DMG_NORMAL|DMG_CANTHURTSELF|DMG_WOMBO); else P_DamageMobj(mo, inflictor, source, 1000, DMG_NORMAL|DMG_CANTHURTSELF); @@ -4334,10 +4339,10 @@ void P_PlayerThink(player_t *player) } // Track airtime - if (P_IsObjectOnGround(player->mo)) + if (P_IsObjectOnGround(player->mo) + && !P_PlayerInPain(player)) // This isn't airtime, but it's control loss all the same. { - if (!P_PlayerInPain(player)) - player->airtime = 0; + player->airtime = 0; } else { @@ -4349,17 +4354,20 @@ void P_PlayerThink(player_t *player) // SRB2kart // Save the dir the player is holding // to allow items to be thrown forward or backward. - if (cmd->buttons & BT_FORWARD) { - player->throwdir = 1; - } - else if (cmd->buttons & BT_BACKWARD) - { - player->throwdir = -1; - } - else - { - player->throwdir = 0; + const INT16 threshold = 0; //(KART_FULLTURN / 2); + if (cmd->throwdir > threshold) + { + player->throwdir = 1; + } + else if (cmd->throwdir < -threshold) + { + player->throwdir = -1; + } + else + { + player->throwdir = 0; + } } // Accessibility - kickstart your acceleration diff --git a/src/r_defs.h b/src/r_defs.h index a466c856c..93353a775 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -691,6 +691,8 @@ typedef struct #endif } patch_t; +extern patch_t *missingpat; + #if defined(_MSC_VER) #pragma pack(1) #endif diff --git a/src/r_patch.c b/src/r_patch.c index 1a08d1892..544c15ae8 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -76,8 +76,7 @@ static void Patch_FreeData(patch_t *patch) for (i = 0; i < 4; i++) { - if (patch->flats[i]) - Z_Free(patch->flats[i]); + Z_Free(patch->flats[i]); } #ifdef ROTSPRITE @@ -96,14 +95,14 @@ static void Patch_FreeData(patch_t *patch) } #endif - if (patch->columnofs) - Z_Free(patch->columnofs); - if (patch->columns) - Z_Free(patch->columns); + Z_Free(patch->columnofs); + Z_Free(patch->columns); } void Patch_Free(patch_t *patch) { + if (patch == missingpat) + return; Patch_FreeData(patch); Z_Free(patch); } diff --git a/src/r_textures.c b/src/r_textures.c index 3b6e561b5..d04935b3e 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -944,28 +944,53 @@ Rloadtextures (INT32 i, INT32 w) return i; } -// -// R_LoadTextures -// Initializes the texture list with the textures from the world map. -// -void R_LoadTextures(void) +static INT32 +count_range +( const char * marker_start, + const char * marker_end, + const char * folder, + UINT16 wadnum) { - INT32 i, w; UINT16 j; - UINT16 texstart, texend, texturesLumpPos; + UINT16 texstart, texend; + INT32 count = 0; - // Free previous memory before numtextures change. - if (numtextures) + // Count flats + if (wadfiles[wadnum]->type == RET_PK3) { - for (i = 0; i < numtextures; i++) - { - Z_Free(textures[i]); - Z_Free(texturecache[i]); - } - Z_Free(texturebrightmaps); - Z_Free(texturetranslation); - Z_Free(textures); + texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0); + texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart); } + else + { + texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0); + texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart); + } + + if (texstart != INT16_MAX && texend != INT16_MAX) + { + // PK3s have subfolders, so we can't just make a simple sum + if (wadfiles[wadnum]->type == RET_PK3) + { + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it + count++; + } + } + else // Add all the textures between markers + { + count += (texend - texstart); + } + } + + return count; +} + +static INT32 R_CountTextures(UINT16 wadnum) +{ + UINT16 texturesLumpPos; + INT32 count = 0; // Load patches and textures. @@ -974,111 +999,99 @@ void R_LoadTextures(void) // the markers. // This system will allocate memory for all duplicate/patched textures even if it never uses them, // but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures. - for (w = 0, numtextures = 0; w < numwadfiles; w++) - { + #ifdef WALLFLATS - // Count flats - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); - } - else - { - texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0); - texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); - } + count += count_range("F_START", "F_END", "flats/", wadnum); +#endif - if (!( texstart == INT16_MAX || texend == INT16_MAX )) - { - // PK3s have subfolders, so we can't just make a simple sum - if (wadfiles[w]->type == RET_PK3) - { - for (j = texstart; j < texend; j++) - { - if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it - numtextures++; - } - } - else // Add all the textures between F_START and F_END - { - numtextures += (UINT32)(texend - texstart); - } - } -#endif/*WALLFLATS*/ + // Count the textures from TEXTURES lumps + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, 0); - // Count the textures from TEXTURES lumps - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - while (texturesLumpPos != INT16_MAX) - { - numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); - } - - // Count single-patch textures - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - } - else - { - texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0); - texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); - } - - if (texstart == INT16_MAX || texend == INT16_MAX) - continue; - - // PK3s have subfolders, so we can't just make a simple sum - if (wadfiles[w]->type == RET_PK3) - { - for (j = texstart; j < texend; j++) - { - if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it - numtextures++; - } - } - else // Add all the textures between TX_START and TX_END - { - numtextures += (UINT32)(texend - texstart); - } + while (texturesLumpPos != INT16_MAX) + { + count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, texturesLumpPos + 1); } - // If no textures found by this point, bomb out - if (!numtextures) - I_Error("No textures detected in any WADs!\n"); + // Count single-patch textures + count += count_range(TX_START, TX_END, "textures/", wadnum); + + return count; +} + +static void +recallocuser +( void * user, + size_t old, + size_t new) +{ + char *p = Z_Realloc(*(void**)user, + new, PU_STATIC, user); + + if (new > old) + memset(&p[old], 0, (new - old)); +} + +static void R_AllocateTextures(INT32 add) +{ + const INT32 newtextures = (numtextures + add); + const size_t newsize = newtextures * sizeof (void*); + const size_t oldsize = numtextures * sizeof (void*); + + INT32 i; // Allocate memory and initialize to 0 for all the textures we are initialising. - // There are actually 5 buffers allocated in one for convenience. - textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); + recallocuser(&textures, oldsize, newsize); // Allocate texture column offset table. - texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); + recallocuser(&texturecolumnofs, oldsize, newsize); // Allocate texture referencing cache. - texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); + recallocuser(&texturecache, oldsize, newsize); // Allocate texture width table. - texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); + recallocuser(&texturewidth, oldsize, newsize); // Allocate texture height table. - textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); + recallocuser(&textureheight, oldsize, newsize); // Create translation table for global animation. - texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); + Z_Realloc(texturetranslation, (newtextures + 1) * sizeof(*texturetranslation), PU_STATIC, &texturetranslation); // Create brightmap texture table. - texturebrightmaps = Z_Malloc((numtextures + 1) * sizeof(*texturebrightmaps), PU_STATIC, NULL); + Z_Realloc(texturebrightmaps, (newtextures + 1) * sizeof(*texturebrightmaps), PU_STATIC, &texturebrightmaps); - for (i = 0; i < numtextures; i++) + for (i = 0; i < numtextures; ++i) + { + // R_FlushTextureCache relies on the user for + // Z_Free, texturecache has been reallocated so the + // user is now garbage memory. + Z_SetUser(texturecache[i], + (void**)&texturecache[i]); + } + + while (i < newtextures) { texturetranslation[i] = i; texturebrightmaps[i] = 0; + i++; } +} - for (i = 0, w = 0; w < numwadfiles; w++) - { +void R_UpdateTextureBrightmap(INT32 tx, INT32 bm) +{ + I_Assert(tx > 0 && tx < numtextures); + I_Assert(bm >= 0 && bm < numtextures); + + texturebrightmaps[tx] = bm; +} + +static INT32 R_DefineTextures(INT32 i, UINT16 w) +{ #ifdef WALLFLATS - i = Rloadflats(i, w); + i = Rloadflats(i, w); #endif - i = Rloadtextures(i, w); - } + return Rloadtextures(i, w); +} + +static void R_FinishLoadingTextures(INT32 add) +{ + numtextures += add; #ifdef HWRENDER if (rendermode == render_opengl) @@ -1086,6 +1099,43 @@ void R_LoadTextures(void) #endif } +// +// R_LoadTextures +// Initializes the texture list with the textures from the world map. +// +void R_LoadTextures(void) +{ + INT32 i, w; + INT32 newtextures = 0; + + for (w = 0; w < numwadfiles; w++) + { + newtextures += R_CountTextures((UINT16)w); + } + + // If no textures found by this point, bomb out + if (!newtextures) + I_Error("No textures detected in any WADs!\n"); + + R_AllocateTextures(newtextures); + + for (i = 0, w = 0; w < numwadfiles; w++) + { + i = R_DefineTextures(i, w); + } + + R_FinishLoadingTextures(newtextures); +} + +void R_LoadTexturesPwad(UINT16 wadnum) +{ + INT32 newtextures = R_CountTextures(wadnum); + + R_AllocateTextures(newtextures); + R_DefineTextures(numtextures, wadnum); + R_FinishLoadingTextures(newtextures); +} + static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) { char *texturesToken; diff --git a/src/r_textures.h b/src/r_textures.h index a4e208eb3..007da38ac 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -77,6 +77,7 @@ extern UINT8 **texturecache; // graphics data for each generated full-size textu // Load TEXTURES definitions, create lookup tables void R_LoadTextures(void); +void R_LoadTexturesPwad(UINT16 wadnum); void R_FlushTextureCache(void); // Texture generation @@ -95,6 +96,8 @@ void *R_GetFlat(lumpnum_t flatnum); boolean R_CheckPowersOfTwo(void); void R_CheckFlatLength(size_t size); +void R_UpdateTextureBrightmap(INT32 tx, INT32 bm); + // Returns the texture number for the texture name. INT32 R_TextureNumForName(const char *name); INT32 R_CheckTextureNumForName(const char *name); diff --git a/src/r_things.c b/src/r_things.c index 0b0885852..157abf141 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -261,7 +261,9 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 for (l = startlump; l < endlump; l++) { - if (memcmp(lumpinfo[l].name,sprname,4)==0) + if (memcmp(lumpinfo[l].name,sprname,4)) + continue; + { INT32 width, height; INT16 topoffset, leftoffset; diff --git a/src/sdl/SDL_icon.xpm b/src/sdl/SDL_icon.xpm index 0acac88ec..b0ae75d5b 100644 --- a/src/sdl/SDL_icon.xpm +++ b/src/sdl/SDL_icon.xpm @@ -1,100 +1,97 @@ /* XPM */ -static const char *SDL_icon_xpm[] = { -/* columns rows colors chars-per-pixel */ -"64 64 32 1", +static const char * SDL_icon_xpm[] = { +"64 64 30 1", " c None", -". c #E7E7E7", -"+ c #DFDFDF", -"@ c #AFAFAF", -"# c #979797", -"$ c #8F8F8F", -"% c #B7B7B7", -"& c #F7F7F7", -"* c #D7D7D7", -"= c #4F4F4F", -"- c #0F0F0F", -"; c #070707", -"> c #575757", -", c #C7C7C7", -"' c #676767", -") c #7F7F7F", -"! c #5F5F5F", -"~ c #777777", -"{ c #474747", -"] c #878787", -"^ c #6F6F6F", +". c #000000", +"+ c #FFFFFF", +"@ c #B37347", +"# c #E39767", +"$ c #FFCB97", +"% c #7F532F", +"& c #FFCFB3", +"* c #533F1F", +"= c #874307", +"- c #752900", +"; c #5F0000", +"> c #414183", +", c #9B5B13", +"' c #5252FF", +") c #21224E", +"! c #FF3F3F", +"~ c #AF0000", +"{ c #FF5F5F", +"] c #470000", +"^ c #FFB78B", "/ c #BFBFBF", -"( c #373737", -"_ c #1F1F1F", -": c #272727", -"< c #2F2F2F", -"[ c #3F3F3F", -"} c #EFEFEF", -"| c #A7A7A7", -"1 c #9F9F9F", -"2 c #171717", -"3 c #CFCFCF", -" ", -" .................... ", -" ...+@##$$$$###@%&....... ", -" ..*=-;;;-;;;;;;;;@........ ", -" ..+-;;;;--;;;;;;;>.......... ", -" ...,')!!'~>{!)$)>'....*]>^%&.. ", -" ../(__(>:{<)$![[[%&...^!!!!!~*. ", -" ..@;;;;;({=]:;;;;;~..*_;;;;;;;_.. ", -" .}>;;;;;^#=;;;;;;>...<;;;;;;;;;|.. ", -" ..*1)))))%]))))))%&..1])))))))))#}. ", -" ..%[;;;;;[2;;;;;;;:..#;;;2[[-;;;;;=.. ", -" .&:;[{;;;{;;;~={:;^.._;;'}...>;;;;;,. ", -" .}<;;:{;_:2!'-;;;]*.&(_].|{=@.~___[/.. ", -" ..*$))]@%//,111111}..|1*.@1111@.3111|&. ", -" .,:;;;;;'#^;;;;;;;]./;;+);;;;;;$*;;;;.. ", -" .^;;;;;;));;;;;;;;$.~;$*;;;;;;;-+^;;;#. ", -" ..$;;;;;;>;;;;;;;;>}.^-.!;;;;;;;;)*:;;|. ", -" .&@$|#)))|)))1||#]+..$/}]))))))))$.3))#.. ", -" .#;;;[{;->;-^[;;;;].~;@];;;;;;;;;;1#;;-}. ", -" .{;;;;{<[:(~-;;;;;$.(-.<;;;;;;;;;;{};;;3. ", -" ..);;;;;~~[!;;;;;;-/.>=.>;;;;;;;;;;2}^;:3. ", -" .&#)))))$}@)))))))@.}]3.*))))))))))).,)).. ", -" .3;;;;;;;);;;;;;;;2+|;%.';;;;;;;;;;;]1;;1. ", -" .1_(:;;;;{;;;[=[:;;.];}.);;;;;;;;;;;=,;;]. ", -" .%2-(!2;2{;_':;;;;).1;..+:;;;;;;;;;;_.;;1. ", -" .+))))@1$1#@))))))3.,@...1))))))))))].1#3. ", -" .{;;;;;^<>);;;;;;;-.[). .-;;;;;;;;;;;3{;#. ", -" ._;;;;;-~];;;;;;;;;};#. ._;;;;;;;;;;;/^;#. ", -" .$'!!!!!1]!!!!!!!!%}[,. .'[[[[[[[[[[[,|>}. ", -" ..'{::___!{___:(>___:[@...~[[[[[[[[[[[1#{,. ", -" .+;-<=(;;[:;;(=-;;;;;;;;;;;;;;;;;;;;;;;;;). ", -" .*;;;;[=;[_;{(;;;;;;;;;;;;;;;;;;;;;;;;;;-#. ", -" .&)!!!!)$]~)$!!!!!!!!!!!!!!!!!!!!!!!!!!!^+. ", -" .&(_____!$)!____________________________<3. ", -" .%;;;;;;;@|;;;;;;;;;;;;==))))))))))))))]*&. ", -" .*22;;;;;({;;;;;_-;;;;%.&.................. ", -" .&+~#]!!!~]!=[!^>[[[[{}... ", -" ../__:^^:(!_[$>[[[[[[{+. ", -" .<;;;;<^2{;'2;;;;;;;;]. ", -" .;;;;;;:~=>:;;;;;;;;;]. ", -" .@!!!!!!]3|!!!!!!!!!!*. ", -" .#_______#_____:<____~.. ", -" .^_{[_;;;=2;;;<<-;;;;;,.................. ", -" .@<;;{~2;_>;;((;;;;;;;3,-----------|.$-!. ", -" ..@))))|@)|)$|)))))))#}&/))))))))))}./)/. ", -" .&:;;;;;=>>;^;;;;;;;;;_.[;;;;;;;;;;^.{;|. ", -" ..2;;;;;;{#<[;;;;;;;;;;+';;;;;;;;;;~*;;.. ", -" .^;;;;;;;'%;;;;;;;;;;{&}#;;;;;;;;[+|;-.. ", -" .&3$1$))))%))))1]))))]+&}$))))))@&./)@. ", -" ..(;_<'{;;(-;;[2;;;;;;-@3;;;;;;;_}};;~. ", -" .=;;;;:~<-(;-[;;;;;;;;:.=;;;;;;>.!;;,. ", -" ./:;;;;;!!!;=-;;;;;;;;>.+$;;;;[.&_;=.. ", -" ..&|)))))$,|%)))))))))]1&.|]]@&.|]]}. ", -" .&;;;;;;;:@=;;;;;;;;;;;-/....3:;;;}. ", -" ..!;;;;;;;([;;;;_2;;;;;;;>)){;;;;^.. ", -" ..=2_:-;;;(;;;2<;;;;;;;;;;;;;;-).. ", -" ...%$#@%#)#))|))))))))))))))|}&. ", -" ..!;;;2!]{_-[;;;;;;;;;;;;;;;&.. ", -" ..^-;;;;^)(:;;;;;;;;;;;;;;'.. ", -" ..*'-;;;:]-;;;;;;;;;;;;-$.. ", -" ....}./1))))))))))))]/... ", -" ........}3||1#$$$]1... ", -" ................... ", -" "}; +"( c #E4E4E4", +"_ c #979797", +": c #7F0000", +"< c #C39B2F", +"[ c #DF0000", +"} c #EBDB57", +"| c #FFFF00", +"1 c #000000", +" ++++++++++++++++ ", +" ++++++++++++++++ ", +" ++++++++++++++++ ", +" ++++++++++++++++ ", +" ++++++++@@@@@@@@@@@@@@@@++++++++ ", +" ++++++++@@@@@@@@@@@@@@@@++++++++ ", +" ++++++++@@@@@@@@@@@@@@@@++++++++ ", +" ++++++++@@@@@@@@@@@@@@@@++++++++ ", +" ++++@@@@####$$$$$$$$$$$$$$$$####@@@@++++ ", +" ++++@@@@####$$$$$$$$$$$$$$$$####@@@@++++ ", +" ++++@@@@####$$$$$$$$$$$$$$$$####@@@@++++ ", +" ++++@@@@####$$$$$$$$$$$$$$$$####@@@@++++ ", +" ++++%%%%####$$$$&&&&++++++++&&&&$$$$####%%%%++++ ", +" ++++%%%%####$$$$&&&&++++++++&&&&$$$$####%%%%++++ ", +" ++++%%%%####$$$$&&&&++++++++&&&&$$$$####%%%%++++ ", +" ++++%%%%####$$$$&&&&++++++++&&&&$$$$####%%%%++++ ", +"++++++++****@@@@$$$$$$$$$$$$&&&&&&&&$$$$$$$$$$$$@@@@****++++++++", +"++++++++****@@@@$$$$$$$$$$$$&&&&&&&&$$$$$$$$$$$$@@@@****++++++++", +"++++++++****@@@@$$$$$$$$$$$$&&&&&&&&$$$$$$$$$$$$@@@@****++++++++", +"++++++++****@@@@$$$$$$$$$$$$&&&&&&&&$$$$$$$$$$$$@@@@****++++++++", +"====----;;;;####$$$$>>>>>>>>$$$$$$$$>>>>>>>>$$$$####;;;;----====", +"====----;;;;####$$$$>>>>>>>>$$$$$$$$>>>>>>>>$$$$####;;;;----====", +"====----;;;;####$$$$>>>>>>>>$$$$$$$$>>>>>>>>$$$$####;;;;----====", +"====----;;;;####$$$$>>>>>>>>$$$$$$$$>>>>>>>>$$$$####;;;;----====", +",,,,,,,,====----@@@@''''''''########''''''''@@@@----====,,,,,,,,", +",,,,,,,,====----@@@@''''''''########''''''''@@@@----====,,,,,,,,", +",,,,,,,,====----@@@@''''''''########''''''''@@@@----====,,,,,,,,", +",,,,,,,,====----@@@@''''''''########''''''''@@@@----====,,,,,,,,", +"----====,,,,====----))))))))!!!!!!!!))))))))----====,,,,====----", +"----====,,,,====----))))))))!!!!!!!!))))))))----====,,,,====----", +"----====,,,,====----))))))))!!!!!!!!))))))))----====,,,,====----", +"----====,,,,====----))))))))!!!!!!!!))))))))----====,,,,====----", +",,,,,,,,,,,,,,,,,,,,====~~~~{{{{{{{{~~~~====,,,,,,,,,,,,,,,,,,,,", +",,,,,,,,,,,,,,,,,,,,====~~~~{{{{{{{{~~~~====,,,,,,,,,,,,,,,,,,,,", +",,,,,,,,,,,,,,,,,,,,====~~~~{{{{{{{{~~~~====,,,,,,,,,,,,,,,,,,,,", +",,,,,,,,,,,,,,,,,,,,====~~~~{{{{{{{{~~~~====,,,,,,,,,,,,,,,,,,,,", +"----------------------------{{{{{{{{----------------------------", +"----------------------------{{{{{{{{----------------------------", +"----------------------------{{{{{{{{----------------------------", +"----------------------------{{{{{{{{----------------------------", +"]]]];;;;----^^^^////((((____((((((((____((((////^^^^----;;;;]]]]", +"]]]];;;;----^^^^////((((____((((((((____((((////^^^^----;;;;]]]]", +"]]]];;;;----^^^^////((((____((((((((____((((////^^^^----;;;;]]]]", +"]]]];;;;----^^^^////((((____((((((((____((((////^^^^----;;;;]]]]", +"::::::::<<<<@@@@^^^^++++////++++++++////++++^^^^@@@@<<<<::::::::", +"::::::::<<<<@@@@^^^^++++////++++++++////++++^^^^@@@@<<<<::::::::", +"::::::::<<<<@@@@^^^^++++////++++++++////++++^^^^@@@@<<<<::::::::", +"::::::::<<<<@@@@^^^^++++////++++++++////++++^^^^@@@@<<<<::::::::", +"::::::::<<<<<<<<----####^^^^$$$$$$$$^^^^####----<<<<<<<<::::::::", +"::::::::<<<<<<<<----####^^^^$$$$$$$$^^^^####----<<<<<<<<::::::::", +"::::::::<<<<<<<<----####^^^^$$$$$$$$^^^^####----<<<<<<<<::::::::", +"::::::::<<<<<<<<----####^^^^$$$$$$$$^^^^####----<<<<<<<<::::::::", +"~~~~[[[[}}}}||||||||@@@@----------------@@@@||||||||}}}}[[[[~~~~", +"~~~~[[[[}}}}||||||||@@@@----------------@@@@||||||||}}}}[[[[~~~~", +"~~~~[[[[}}}}||||||||@@@@----------------@@@@||||||||}}}}[[[[~~~~", +"~~~~[[[[}}}}||||||||@@@@----------------@@@@||||||||}}}}[[[[~~~~", +"[[[[[[[[||||||||<<<<~~~~~~~~~~~~~~~~~~~~~~~~<<<<||||||||[[[[[[[[", +"[[[[[[[[||||||||<<<<~~~~~~~~~~~~~~~~~~~~~~~~<<<<||||||||[[[[[[[[", +"[[[[[[[[||||||||<<<<~~~~~~~~~~~~~~~~~~~~~~~~<<<<||||||||[[[[[[[[", +"[[[[[[[[||||||||<<<<~~~~~~~~~~~~~~~~~~~~~~~~<<<<||||||||[[[[[[[[", +"[[[[[[[[||||<<<<~~~~[[[[[[[[[[[[[[[[[[[[[[[[~~~~<<<<||||[[[[[[[[", +"[[[[[[[[||||<<<<~~~~[[[[[[[[[[[[[[[[[[[[[[[[~~~~<<<<||||[[[[[[[[", +"[[[[[[[[||||<<<<~~~~[[[[[[[[[[[[[[[[[[[[[[[[~~~~<<<<||||[[[[[[[[", +"[[[[[[[[||||<<<<~~~~[[[[[[[[[[[[[[[[[[[[[[[[~~~~<<<<||||[[[[[[[["}; diff --git a/src/sdl/Srb2SDL.ico b/src/sdl/Srb2SDL.ico index 4e3f81336..f9caf642c 100644 Binary files a/src/sdl/Srb2SDL.ico and b/src/sdl/Srb2SDL.ico differ diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 5b205503e..de3ea3c9a 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -269,7 +269,7 @@ int main(int argc, char **argv) #endif // startup SRB2 - CONS_Printf("Setting up SRB2Kart...\n"); + CONS_Printf("Setting up Dr. Robotnik's Ring Racers...\n"); D_SRB2Main(); #ifdef LOGMESSAGES if (!M_CheckParm("-nolog")) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index ac1d6f0e3..80990673d 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -145,10 +145,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); // Locations for searching for main.kart #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart" -#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2Kart" -#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2Kart" -#define DEFAULTWADLOCATION4 "/usr/games/SRB2Kart" +#define DEFAULTWADLOCATION1 "/usr/local/share/games/RingRacers" +#define DEFAULTWADLOCATION2 "/usr/local/games/RingRacers" +#define DEFAULTWADLOCATION3 "/usr/share/games/RingRacers" +#define DEFAULTWADLOCATION4 "/usr/games/RingRacers" #define DEFAULTSEARCHPATH1 "/usr/local/games" #define DEFAULTSEARCHPATH2 "/usr/games" #define DEFAULTSEARCHPATH3 "/usr/local" @@ -292,8 +292,8 @@ static void write_backtrace(INT32 signal) void *array[BT_SIZE]; char timestr[STR_SIZE]; - const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; - const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr. + const char *error = "An error occurred within Dr. Robotnik's Ring Racers! Send this stack trace to someone who can help!\n"; + const char *error2 = "(Or find crash-log.txt in your Ring Racers directory.)\n"; // Shown only to stderr. fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR); @@ -727,7 +727,7 @@ static void I_StartupConsole(void) if (gotConsole) { - SetConsoleTitleA("SRB2Kart Console"); + SetConsoleTitleA("Dr. Robotnik's Ring Racers Console"); consolevent = SDL_TRUE; } @@ -1423,8 +1423,8 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) return; if(mumble->uiVersion != 2) { - wcsncpy(mumble->name, L"SRB2Kart "VERSIONSTRINGW, 256); - wcsncpy(mumble->description, L"Sonic Robo Blast 2 Kart with integrated Mumble Link support.", 2048); + wcsncpy(mumble->name, L"Dr. Robotnik's Ring Racers "VERSIONSTRINGW, 256); + wcsncpy(mumble->description, L"Dr. Robotnik's Ring Racers with integrated Mumble Link support.", 2048); mumble->uiVersion = 2; } mumble->uiTick++; @@ -1763,7 +1763,7 @@ INT32 I_StartupSystem(void) I_OutputMsg("Linked with SDL version: %d.%d.%d\n", SDLlinked.major, SDLlinked.minor, SDLlinked.patch); if (SDL_Init(0) < 0) - I_Error("SRB2: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... + I_Error("Dr. Robotnik's Ring Racers: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... #ifndef NOMUMBLE I_SetupMumble(); #endif @@ -1887,7 +1887,7 @@ void I_Error(const char *error, ...) // on the target system if (!M_CheckParm("-dedicated")) SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "SRB2Kart "VERSIONSTRING" Recursive Error", + "Dr. Robotnik's Ring Racers "VERSIONSTRING" Recursive Error", buffer, NULL); W_Shutdown(); @@ -1936,7 +1936,7 @@ void I_Error(const char *error, ...) // on the target system if (!M_CheckParm("-dedicated")) SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "SRB2Kart "VERSIONSTRING" Error", + "Dr. Robotnik's Ring Racers "VERSIONSTRING" Error", buffer, NULL); // Note that SDL_ShowSimpleMessageBox does *not* require SDL to be diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5008bfb66..3afbd23f0 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1668,7 +1668,7 @@ INT32 VID_SetMode(INT32 modeNum) src_rect.w = vid.width; src_rect.h = vid.height; - //Impl_SetWindowName("SRB2Kart "VERSIONSTRING); + //Impl_SetWindowName("Dr. Robotnik's Ring Racers "VERSIONSTRING); VID_CheckRenderer(); return SDL_TRUE; } @@ -1695,7 +1695,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #endif // Create a window - window = SDL_CreateWindow("SRB2Kart "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + window = SDL_CreateWindow("Dr. Robotnik's Ring Racers "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); @@ -1871,7 +1871,7 @@ void I_StartupGraphics(void) // Create window //Impl_CreateWindow(USE_FULLSCREEN); - //Impl_SetWindowName("SRB2Kart "VERSIONSTRING); + //Impl_SetWindowName("Dr. Robotnik's Ring Racers "VERSIONSTRING); VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); vid.width = BASEVIDWIDTH; // Default size for startup diff --git a/src/sdl/srb2icon.png b/src/sdl/srb2icon.png index 2aca4b204..17de4468e 100644 Binary files a/src/sdl/srb2icon.png and b/src/sdl/srb2icon.png differ diff --git a/src/sdl12/Srb2SDL.ico b/src/sdl12/Srb2SDL.ico index 4e3f81336..f9caf642c 100644 Binary files a/src/sdl12/Srb2SDL.ico and b/src/sdl12/Srb2SDL.ico differ diff --git a/src/sdl12/i_main.c b/src/sdl12/i_main.c index adcaae2fd..2cf2753aa 100644 --- a/src/sdl12/i_main.c +++ b/src/sdl12/i_main.c @@ -44,7 +44,7 @@ static char netmask[16] = {0}; #include PSP_HEAP_SIZE_KB(24*1024); PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU); -PSP_MAIN_THREAD_NAME("SRB2Kart"); +PSP_MAIN_THREAD_NAME("Dr. Robotnik's Ring Racers"); PSP_MAIN_THREAD_STACK_SIZE_KB(256); #endif @@ -228,7 +228,7 @@ int main(int argc, char **argv) #endif #endif // startup SRB2 - CONS_Printf("%s", M_GetText("Setting up SRB2...\n")); + CONS_Printf("%s", M_GetText("Setting up Dr. Robotnik's Ring Racers...\n")); D_SRB2Main(); CONS_Printf("%s", M_GetText("Entering main game loop...\n")); // never return diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c index 14d183748..b388a9bf5 100644 --- a/src/sdl12/i_system.c +++ b/src/sdl12/i_system.c @@ -155,9 +155,9 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? //#define DEFAULTSEARCHPATH3 "/pc/home/alam/srb2code/data" #elif defined (GP2X) #define DEFAULTWADLOCATION1 "/mnt/sd" -#define DEFAULTWADLOCATION2 "/mnt/sd/SRB2Kart" +#define DEFAULTWADLOCATION2 "/mnt/sd/RingRacers" #define DEFAULTWADLOCATION3 "/tmp/mnt/sd" -#define DEFAULTWADLOCATION4 "/tmp/mnt/sd/SRB2Kart" +#define DEFAULTWADLOCATION4 "/tmp/mnt/sd/RingRacers" #define DEFAULTSEARCHPATH1 "/mnt/sd" #define DEFAULTSEARCHPATH2 "/tmp/mnt/sd" #elif defined (_WII) @@ -184,10 +184,10 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #define DEFAULTSEARCHPATH1 "host0:/" #define DEFAULTSEARCHPATH2 "ms0:/PSP/GAME/SRB2PSP" #elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart" -#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2Kart" -#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2Kart" -#define DEFAULTWADLOCATION4 "/usr/games/SRB2Kart" +#define DEFAULTWADLOCATION1 "/usr/local/share/games/RingRacers" +#define DEFAULTWADLOCATION2 "/usr/local/games/RingRacers" +#define DEFAULTWADLOCATION3 "/usr/share/games/RingRacers" +#define DEFAULTWADLOCATION4 "/usr/games/RingRacers" #define DEFAULTSEARCHPATH1 "/usr/local/games" #define DEFAULTSEARCHPATH2 "/usr/games" #define DEFAULTSEARCHPATH3 "/usr/local" @@ -196,21 +196,21 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #ifdef __GNUC__ #include #endif -#define DEFAULTWADLOCATION1 "c:\\srb2kart" -#define DEFAULTWADLOCATION2 "d:\\srb2kart" -#define DEFAULTWADLOCATION3 "e:\\srb2kart" -#define DEFAULTWADLOCATION4 "f:\\srb2kart" -#define DEFAULTWADLOCATION5 "g:\\srb2kart" -#define DEFAULTWADLOCATION6 "h:\\srb2kart" -#define DEFAULTWADLOCATION7 "i:\\srb2kart" +#define DEFAULTWADLOCATION1 "c:\\ringracers" +#define DEFAULTWADLOCATION2 "d:\\ringracers" +#define DEFAULTWADLOCATION3 "e:\\ringracers" +#define DEFAULTWADLOCATION4 "f:\\ringracers" +#define DEFAULTWADLOCATION5 "g:\\ringracers" +#define DEFAULTWADLOCATION6 "h:\\ringracers" +#define DEFAULTWADLOCATION7 "i:\\ringracers" #elif defined (_WIN32_WCE) #define NOCWD #define NOHOME -#define DEFAULTWADLOCATION1 "\\Storage Card\\SRB2Kart" +#define DEFAULTWADLOCATION1 "\\Storage Card\\RingRacers" #define DEFAULTSEARCHPATH1 "\\Storage Card" #elif defined (_WIN32) -#define DEFAULTWADLOCATION1 "c:\\games\\srb2kart" -#define DEFAULTWADLOCATION2 "\\games\\srb2kart" +#define DEFAULTWADLOCATION1 "c:\\games\\ringracers" +#define DEFAULTWADLOCATION2 "\\games\\ringracers" #define DEFAULTSEARCHPATH1 "c:\\games" #define DEFAULTSEARCHPATH2 "\\games" #endif @@ -701,7 +701,7 @@ static void I_StartupConsole(void) if (gotConsole) { - SetConsoleTitleA("SRB2Kart Console"); + SetConsoleTitleA("Dr. Robotnik's Ring Racers Console"); consolevent = SDL_TRUE; } @@ -2333,8 +2333,8 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) return; if(mumble->uiVersion != 2) { - wcsncpy(mumble->name, L"SRB2Kart "VERSIONSTRING, 256); - wcsncpy(mumble->description, L"Sonic Robo Blast 2 Kart with integrated Mumble Link support.", 2048); + wcsncpy(mumble->name, L"Dr. Robotnik's Ring Racers "VERSIONSTRING, 256); + wcsncpy(mumble->description, L"Dr. Robotnik's Ring Racers with integrated Mumble Link support.", 2048); mumble->uiVersion = 2; } mumble->uiTick++; @@ -2905,7 +2905,7 @@ void I_StartupTimer(void) I_AddExitFunc(I_ShutdownTimer); #elif 0 //#elif !defined (_arch_dreamcast) && !defined(GP2X) // the DC have it own timer and GP2X have broken pthreads? if (SDL_InitSubSystem(SDL_INIT_TIMER) < 0) - I_Error("SRB2: Needs SDL_Timer, Error: %s", SDL_GetError()); + I_Error("Dr. Robotnik's Ring Racers: Needs SDL_Timer, Error: %s", SDL_GetError()); #endif } @@ -2925,13 +2925,13 @@ INT32 I_StartupSystem(void) const SDL_version *SDLlinked; #ifdef _XBOX #ifdef __GNUC__ - char DP[] =" Sonic Robo Blast 2!\n"; + char DP[] =" Dr. Robotnik's Ring Racers!\n"; debugPrint(DP); #endif - unlink("e:/Games/SRB2/stdout.txt"); - freopen("e:/Games/SRB2/stdout.txt", "w+", stdout); - unlink("e:/Games/SRB2/stderr.txt"); - freopen("e:/Games/SRB2/stderr.txt", "w+", stderr); + unlink("e:/Games/RingRacers/stdout.txt"); + freopen("e:/Games/RingRacers/stdout.txt", "w+", stdout); + unlink("e:/Games/RingRacers/stderr.txt"); + freopen("e:/Games/RingRacers/stderr.txt", "w+", stderr); #endif #ifdef _arch_dreamcast #ifdef _DEBUG @@ -2954,7 +2954,7 @@ INT32 I_StartupSystem(void) #else if (SDL_Init(SDL_INIT_NOPARACHUTE) < 0) #endif - I_Error("SRB2: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... + I_Error("Dr. Robotnik's Ring Racers: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... #ifndef NOMUMBLE I_SetupMumble(); #endif @@ -3106,7 +3106,7 @@ void I_Error(const char *error, ...) } #endif OutputDebugStringA(buffer); - MessageBoxA(vid.WndParent, buffer, "SRB2 Recursive Error", MB_OK|MB_ICONERROR); + MessageBoxA(vid.WndParent, buffer, "Dr. Robotnik's Ring Racers Recursive Error", MB_OK|MB_ICONERROR); #else // Don't print garbage va_start(argptr, error); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 45ce67cf5..e32885a3c 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1719,7 +1719,7 @@ INT32 VID_SetMode(INT32 modeNum) BitsPerPixel = (Uint8)cv_scr_depth.value; //vid.bpp = BitsPerPixel==8?1:2; // Window title - SDL_WM_SetCaption("SRB2Kart "VERSIONSTRING, "SRB2Kart"); + SDL_WM_SetCaption("Dr. Robotnik's Ring Racers "VERSIONSTRING, "Dr. Robotnik's Ring Racers"); if (render_soft == rendermode) { @@ -1881,9 +1881,9 @@ void I_StartupGraphics(void) // Window title #ifdef _WIN32_WCE - SDL_WM_SetCaption("SRB2Kart "VERSIONSTRING, "SRB2Kart"); + SDL_WM_SetCaption("Dr. Robotnik's Ring Racers "VERSIONSTRING, "Dr. Robotnik's Ring Racers"); #else - SDL_WM_SetCaption("SRB2Kart: Starting up", "SRB2Kart"); + SDL_WM_SetCaption("Dr. Robotnik's Ring Racers: Starting up", "Dr. Robotnik's Ring Racers"); #endif // Window icon diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c index 1a7525fee..eebcb65df 100644 --- a/src/sdl12/sdl_sound.c +++ b/src/sdl12/sdl_sound.c @@ -154,16 +154,16 @@ static SDL_mutex *Msc_Mutex = NULL; #ifdef _arch_dreamcast #define MIDI_PATH "/ram" #elif defined(GP2X) -#define MIDI_PATH "/mnt/sd/srb2" -#define MIDI_PATH2 "/tmp/mnt/sd/srb2" +#define MIDI_PATH "/mnt/sd/ringracers" +#define MIDI_PATH2 "/tmp/mnt/sd/ringracers" #else #define MIDI_PATH srb2home #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define MIDI_PATH2 "/tmp" #endif #endif -#define MIDI_TMPFILE "srb2music" -#define MIDI_TMPFILE2 "srb2wav" +#define MIDI_TMPFILE "ringracersmusic" +#define MIDI_TMPFILE2 "ringracerswav" static INT32 musicvol = 62; #if SDL_MIXER_VERSION_ATLEAST(1,2,2) @@ -1932,7 +1932,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) loopstartDig = 0.0l; #else if (looping && strcmp(data, "OggS") == 0) - I_OutputMsg("I_StartDigSong: SRB2 was not compiled with looping music support(no Mix_FadeInMusicPos)\n"); + I_OutputMsg("I_StartDigSong: Ring Racers was not compiled with looping music support(no Mix_FadeInMusicPos)\n"); #endif if (!LoadSong(data, lumplength, 1)) diff --git a/src/sounds.c b/src/sounds.c index 851c69518..761fa109c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1108,6 +1108,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"kdtrg2", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Medium energy, SF_X8AWAYSOUND {"kdtrg3", false, 64, 80, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // High energy, SF_X2AWAYSOUND|SF_X8AWAYSOUND + // SRB2kart - Grow/invinc clash + {"parry", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND + // SRB2Kart - Engine sounds // Engine class A {"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""}, diff --git a/src/sounds.h b/src/sounds.h index 0686cab46..336cd8b74 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1172,6 +1172,9 @@ typedef enum sfx_kdtrg2, sfx_kdtrg3, + // SRB2Kart - Powerup clash SFX + sfx_parry, + // Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy... // Engine class A - Low Speed, Low Weight sfx_krta00, diff --git a/src/st_stuff.c b/src/st_stuff.c index 11560c89c..6a98cb2b0 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -63,77 +63,6 @@ patch_t *faceprefix[MAXSKINS][NUMFACES]; // status bar overlay // ------------------------------------------ -// icons for overlay -patch_t *sboscore; // Score logo -patch_t *sbotime; // Time logo -patch_t *sbocolon; // Colon for time -patch_t *sboperiod; // Period for time centiseconds -patch_t *livesback; // Lives icon background -patch_t *stlivex; -static patch_t *nrec_timer; // Timer for NiGHTS records -static patch_t *sborings; -static patch_t *slidgame; -static patch_t *slidtime; -static patch_t *slidover; -static patch_t *sboredrings; -static patch_t *sboredtime; -static patch_t *getall; // Special Stage HUD -static patch_t *timeup; // Special Stage HUD -static patch_t *hunthoming[6]; -static patch_t *itemhoming[6]; -static patch_t *race1; -static patch_t *race2; -static patch_t *race3; -static patch_t *racego; -static patch_t *nightslink; -static patch_t *curweapon; -static patch_t *normring; -static patch_t *bouncering; -static patch_t *infinityring; -static patch_t *autoring; -static patch_t *explosionring; -static patch_t *scatterring; -static patch_t *grenadering; -static patch_t *railring; -static patch_t *jumpshield; -static patch_t *forceshield; -static patch_t *ringshield; -static patch_t *watershield; -static patch_t *bombshield; -static patch_t *pityshield; -static patch_t *pinkshield; -static patch_t *flameshield; -static patch_t *bubbleshield; -static patch_t *thundershield; -static patch_t *invincibility; -static patch_t *sneakers; -static patch_t *gravboots; -static patch_t *nonicon; -static patch_t *nonicon2; -static patch_t *bluestat; -static patch_t *byelstat; -static patch_t *orngstat; -static patch_t *redstat; -static patch_t *yelstat; -static patch_t *nbracket; -static patch_t *nring; -static patch_t *nhud[12]; -static patch_t *nsshud; -static patch_t *nbon[12]; -static patch_t *nssbon; -static patch_t *narrow[9]; -static patch_t *nredar[8]; // Red arrow -static patch_t *drillbar; -static patch_t *drillfill[3]; -static patch_t *capsulebar; -static patch_t *capsulefill; -patch_t *ngradeletters[7]; -static patch_t *minus5sec; -static patch_t *minicaps; -static patch_t *gotrflag; -static patch_t *gotbflag; -static patch_t *fnshico; - // Midnight Channel: static patch_t *hud_tv1; static patch_t *hud_tv2; @@ -143,38 +72,6 @@ static patch_t *hud_tv2; static patch_t *envelope; #endif -// SRB2kart - -hudinfo_t hudinfo[NUMHUDITEMS] = -{ - { 16, 176, V_SNAPTOLEFT|V_SNAPTOBOTTOM}, // HUD_LIVES - - { 16, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGS - { 96, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUM - { 120, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUMTICS - - { 16, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORE - { 120, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORENUM - - { 16, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIME - { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_MINUTES - { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMECOLON - { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SECONDS - { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMETICCOLON - { 120, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TICS - - { 0, 56, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SS_TOTALRINGS - - { 110, 93, 0}, // HUD_GETRINGS - { 160, 93, 0}, // HUD_GETRINGSNUM - { 124, 160, 0}, // HUD_TIMELEFT - { 168, 176, 0}, // HUD_TIMELEFTNUM - { 130, 93, 0}, // HUD_TIMEUP - { 152, 168, 0}, // HUD_HUNTPICS - - { 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS -}; - // // STATUS BAR CODE // @@ -249,8 +146,6 @@ void ST_UnloadGraphics(void) void ST_LoadGraphics(void) { - int i; - // SRB2 border patch // st_borderpatchnum = W_GetNumForName("GFZFLR01"); // scr_borderpatch = W_CacheLumpNum(st_borderpatchnum, PU_HUDGFX); @@ -260,116 +155,15 @@ void ST_LoadGraphics(void) // but load them in R_AddSkins, that gets called // first anyway // cache the status bar overlay icons (fullscreen mode) - - // Prefix "STT" is whitelisted (doesn't trigger ISGAMEMODIFIED), btw - sborings = W_CachePatchName("STTRINGS", PU_HUDGFX); - sboredrings = W_CachePatchName("STTRRING", PU_HUDGFX); - sboscore = W_CachePatchName("STTSCORE", PU_HUDGFX); - sbotime = W_CachePatchName("STTTIME", PU_HUDGFX); // Time logo - sboredtime = W_CachePatchName("STTRTIME", PU_HUDGFX); - sbocolon = W_CachePatchName("STTCOLON", PU_HUDGFX); // Colon for time - sboperiod = W_CachePatchName("STTPERIO", PU_HUDGFX); // Period for time centiseconds - - slidgame = W_CachePatchName("SLIDGAME", PU_HUDGFX); - slidtime = W_CachePatchName("SLIDTIME", PU_HUDGFX); - slidover = W_CachePatchName("SLIDOVER", PU_HUDGFX); - - stlivex = W_CachePatchName("STLIVEX", PU_HUDGFX); - livesback = W_CachePatchName("STLIVEBK", PU_HUDGFX); - nrec_timer = W_CachePatchName("NGRTIMER", PU_HUDGFX); // Timer for NiGHTS - getall = W_CachePatchName("GETALL", PU_HUDGFX); // Special Stage HUD - timeup = W_CachePatchName("TIMEUP", PU_HUDGFX); // Special Stage HUD - race1 = W_CachePatchName("RACE1", PU_HUDGFX); - race2 = W_CachePatchName("RACE2", PU_HUDGFX); - race3 = W_CachePatchName("RACE3", PU_HUDGFX); - racego = W_CachePatchName("RACEGO", PU_HUDGFX); - nightslink = W_CachePatchName("NGHTLINK", PU_HUDGFX); - - for (i = 0; i < 6; ++i) - { - hunthoming[i] = W_CachePatchName(va("HOMING%d", i+1), PU_HUDGFX); - itemhoming[i] = W_CachePatchName(va("HOMITM%d", i+1), PU_HUDGFX); - } - - curweapon = W_CachePatchName("CURWEAP", PU_HUDGFX); - normring = W_CachePatchName("RINGIND", PU_HUDGFX); - bouncering = W_CachePatchName("BNCEIND", PU_HUDGFX); - infinityring = W_CachePatchName("INFNIND", PU_HUDGFX); - autoring = W_CachePatchName("AUTOIND", PU_HUDGFX); - explosionring = W_CachePatchName("BOMBIND", PU_HUDGFX); - scatterring = W_CachePatchName("SCATIND", PU_HUDGFX); - grenadering = W_CachePatchName("GRENIND", PU_HUDGFX); - railring = W_CachePatchName("RAILIND", PU_HUDGFX); - jumpshield = W_CachePatchName("TVWWICON", PU_HUDGFX); - forceshield = W_CachePatchName("TVFOICON", PU_HUDGFX); - ringshield = W_CachePatchName("TVATICON", PU_HUDGFX); - watershield = W_CachePatchName("TVELICON", PU_HUDGFX); - bombshield = W_CachePatchName("TVARICON", PU_HUDGFX); - pityshield = W_CachePatchName("TVPIICON", PU_HUDGFX); - pinkshield = W_CachePatchName("TVPPICON", PU_HUDGFX); - flameshield = W_CachePatchName("TVFLICON", PU_HUDGFX); - bubbleshield = W_CachePatchName("TVBBICON", PU_HUDGFX); - thundershield = W_CachePatchName("TVZPICON", PU_HUDGFX); - invincibility = W_CachePatchName("TVIVICON", PU_HUDGFX); - sneakers = W_CachePatchName("TVSSICON", PU_HUDGFX); - gravboots = W_CachePatchName("TVGVICON", PU_HUDGFX); - - tagico = W_CachePatchName("TAGICO", PU_HUDGFX); - rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); - bflagico = W_CachePatchName("BFLAGICO", PU_HUDGFX); - rmatcico = W_CachePatchName("RMATCICO", PU_HUDGFX); - bmatcico = W_CachePatchName("BMATCICO", PU_HUDGFX); - gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX); - gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX); - fnshico = W_CachePatchName("FNSHICO", PU_HUDGFX); - nonicon = W_CachePatchName("NONICON", PU_HUDGFX); - nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX); - - // NiGHTS HUD things - bluestat = W_CachePatchName("BLUESTAT", PU_HUDGFX); - byelstat = W_CachePatchName("BYELSTAT", PU_HUDGFX); - orngstat = W_CachePatchName("ORNGSTAT", PU_HUDGFX); - redstat = W_CachePatchName("REDSTAT", PU_HUDGFX); - yelstat = W_CachePatchName("YELSTAT", PU_HUDGFX); - nbracket = W_CachePatchName("NBRACKET", PU_HUDGFX); - nring = W_CachePatchName("NRNG1", PU_HUDGFX); - for (i = 0; i < 12; ++i) - { - nhud[i] = W_CachePatchName(va("NHUD%d", i+1), PU_HUDGFX); - nbon[i] = W_CachePatchName(va("NBON%d", i+1), PU_HUDGFX); - } - nsshud = W_CachePatchName("NSSHUD", PU_HUDGFX); - nssbon = W_CachePatchName("NSSBON", PU_HUDGFX); - minicaps = W_CachePatchName("MINICAPS", PU_HUDGFX); - - for (i = 0; i < 8; ++i) - { - narrow[i] = W_CachePatchName(va("NARROW%d", i+1), PU_HUDGFX); - nredar[i] = W_CachePatchName(va("NREDAR%d", i+1), PU_HUDGFX); - } - - // non-animated version - narrow[8] = W_CachePatchName("NARROW9", PU_HUDGFX); - - drillbar = W_CachePatchName("DRILLBAR", PU_HUDGFX); - for (i = 0; i < 3; ++i) - drillfill[i] = W_CachePatchName(va("DRILLFI%d", i+1), PU_HUDGFX); - capsulebar = W_CachePatchName("CAPSBAR", PU_HUDGFX); - capsulefill = W_CachePatchName("CAPSFILL", PU_HUDGFX); - minus5sec = W_CachePatchName("MINUS5", PU_HUDGFX); - - for (i = 0; i < 7; ++i) - ngradeletters[i] = W_CachePatchName(va("GRADE%d", i), PU_HUDGFX); - K_LoadKartHUDGraphics(); // Midnight Channel: - hud_tv1 = W_CachePatchName("HUD_TV1", PU_HUDGFX); - hud_tv2 = W_CachePatchName("HUD_TV2", PU_HUDGFX); + HU_UpdatePatch(&hud_tv1, "HUD_TV1"); + HU_UpdatePatch(&hud_tv2, "HUD_TV2"); #ifdef HAVE_DISCORDRPC // Discord Rich Presence - envelope = W_CachePatchName("K_REQUES", PU_HUDGFX); + HU_UpdatePatch(&envelope, "K_REQUES"); #endif } @@ -547,17 +341,6 @@ static INT32 SCR(INT32 r) // ========================================================================= // INTERNAL DRAWING // ========================================================================= -#define ST_DrawTopLeftOverlayPatch(x,y,p) V_DrawScaledPatch(SCX(hudinfo[h+!!r_splitscreen].x), SCY(hudinfo[h+!!r_splitscreen].y), V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p) -#define ST_DrawOverlayNum(x,y,n) V_DrawTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPaddedOverlayNum(x,y,n,d) V_DrawPaddedTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n, d) -#define ST_DrawOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p) -#define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p, c) -#define ST_DrawNumFromHud(h,n) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, n, q) -#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, p) -#define ST_DrawNumFromHudWS(h,n) V_DrawTallNum(SCX(hudinfo[h+!!r_splitscreen].x), SCY(hudinfo[h+!!r_splitscreen].y), V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPadNumFromHudWS(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h+!!r_splitscreen].x), SCY(hudinfo[h+!!r_splitscreen].y), V_NOSCALESTART|V_HUDTRANS, n, q) -#define ST_DrawPatchFromHudWS(h,p) V_DrawScaledPatch(SCX(hudinfo[h+!!r_splitscreen].x), SCY(hudinfo[h+!!r_splitscreen].y), V_NOSCALESTART|V_HUDTRANS, p) // Devmode information static void ST_drawDebugInfo(void) @@ -807,7 +590,7 @@ void ST_runTitleCard(void) char c = toupper(bossinfo.enemyname[bossinfo.titleshow]); bossinfo.titleshow++; c -= LT_FONTSTART; - if (c < 0 || c >= LT_FONTSIZE || !tc_font[1][(INT32)c] || !bossinfo.titlesound) + if (c < 0 || c >= LT_FONTSIZE || !fontv[GTFN_FONT].font[(INT32)c] || !bossinfo.titlesound) { ; } diff --git a/src/st_stuff.h b/src/st_stuff.h index a17f72c1f..e24343551 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -81,54 +81,7 @@ extern UINT32 st_translucency; extern lumpnum_t st_borderpatchnum; // patches, also used in intermission -extern patch_t *sboscore; -extern patch_t *sbotime; -extern patch_t *sbocolon; -extern patch_t *sboperiod; extern patch_t *faceprefix[MAXSKINS][NUMFACES]; -extern patch_t *livesback; -extern patch_t *stlivex; -extern patch_t *ngradeletters[7]; - -/** HUD location information (don't move this comment) - */ -typedef struct -{ - INT32 x, y, f; -} hudinfo_t; - -typedef enum -{ - HUD_LIVES, - - HUD_RINGS, - HUD_RINGSNUM, - HUD_RINGSNUMTICS, - - HUD_SCORE, - HUD_SCORENUM, - - HUD_TIME, - HUD_MINUTES, - HUD_TIMECOLON, - HUD_SECONDS, - HUD_TIMETICCOLON, - HUD_TICS, - - HUD_SS_TOTALRINGS, - - HUD_GETRINGS, - HUD_GETRINGSNUM, - HUD_TIMELEFT, - HUD_TIMELEFTNUM, - HUD_TIMEUP, - HUD_HUNTPICS, - HUD_POWERUPS, - - NUMHUDITEMS -} hudnum_t; - -extern hudinfo_t hudinfo[NUMHUDITEMS]; extern UINT16 objectsdrawn; diff --git a/src/v_video.c b/src/v_video.c index 1d2085f7a..0c260f6be 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1703,13 +1703,13 @@ INT32 V_TitleCardStringWidth(const char *str) c -= LT_FONTSTART; // check if character exists, if not, it's a space. - if (c < 0 || c >= LT_FONTSIZE || !tc_font[0][(INT32)c]) + if (c < 0 || c >= LT_FONTSIZE || !fontv[GTOL_FONT].font[(INT32)c]) { xoffs += 10; continue; } - pp = tc_font[1][(INT32)c]; + pp = fontv[GTFN_FONT].font[(INT32)c]; xoffs += pp->width-5; } @@ -1770,14 +1770,14 @@ void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boole c -= LT_FONTSTART; // check if character exists, if not, it's a space. - if (c < 0 || c >= LT_FONTSIZE || !tc_font[1][(INT32)c]) + if (c < 0 || c >= LT_FONTSIZE || !fontv[GTFN_FONT].font[(INT32)c]) { xoffs += 10; continue; } - ol = tc_font[0][(INT32)c]; - pp = tc_font[1][(INT32)c]; + ol = fontv[GTOL_FONT].font[(INT32)c]; + pp = fontv[GTFN_FONT].font[(INT32)c]; if (bossmode) { @@ -2641,8 +2641,8 @@ void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num) } while (num); // draw a minus sign if necessary - if (neg) - V_DrawScaledPatch(x - w, y, flags, tallminus); // Tails + //if (neg) + //V_DrawScaledPatch(x - w, y, flags, tallminus); // Tails } // Draws a number with a set number of digits. diff --git a/src/w_wad.c b/src/w_wad.c index e1cb6b1aa..879c75063 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1796,7 +1796,7 @@ void *W_CachePatchName(const char *name, INT32 tag) num = W_CheckNumForName(name); if (num == LUMPERROR) - return W_CachePatchNum(W_GetNumForName("MISSING"), tag); + return missingpat; return W_CachePatchNum(num, tag); } @@ -1807,7 +1807,7 @@ void *W_CachePatchLongName(const char *name, INT32 tag) num = W_CheckNumForLongName(name); if (num == LUMPERROR) - return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag); + return missingpat; return W_CachePatchNum(num, tag); } diff --git a/src/win32/Srb2win.ico b/src/win32/Srb2win.ico index 4e3f81336..f9caf642c 100644 Binary files a/src/win32/Srb2win.ico and b/src/win32/Srb2win.ico differ diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index b3925c873..dbd11991a 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -94,16 +94,16 @@ BEGIN BEGIN BLOCK "04090000" BEGIN - VALUE "Comments", "Go go-karting with Dr. Eggman!\0" + VALUE "Comments", "Go go-karting with Dr. Robotnik!\0" VALUE "CompanyName", "Kart Krew\0" - VALUE "FileDescription", "SRB2Kart\0" + VALUE "FileDescription", "Dr. Robotnik's Ring Racers\0" VALUE "FileVersion", VERSIONSTRING_RC - VALUE "InternalName", "srb2kart\0" + VALUE "InternalName", "drrr\0" VALUE "LegalCopyright", "Copyright 2018-2020 by Kart Krew\0" - VALUE "LegalTrademarks", "Dr. Eggman and related characters are trademarks of Sega.\0" - VALUE "OriginalFilename", "srb2kart.exe\0" + VALUE "LegalTrademarks", "Dr. Robotnik and related characters are trademarks of Sega.\0" + VALUE "OriginalFilename", "drrr.exe\0" VALUE "PrivateBuild", "\0" - VALUE "ProductName", "SRB2Kart\0" + VALUE "ProductName", "Dr. Robotnik's Ring Racers\0" VALUE "ProductVersion", VERSIONSTRING_RC VALUE "SpecialBuild", "\0" END diff --git a/src/win32/win_dbg.c b/src/win32/win_dbg.c index 4230e962f..b5e3767dc 100644 --- a/src/win32/win_dbg.c +++ b/src/win32/win_dbg.c @@ -74,7 +74,7 @@ BOOL InitBugTrap(void) if (g_hmodBugTrap) { - lpfnBT_SetAppName(TEXT("Sonic Robo Blast 2")); + lpfnBT_SetAppName(TEXT("Dr. Robotnik's Ring Racers")); lpfnBT_SetAppVersion(TEXT(VERSIONSTRING)); lpfnBT_SetFlags(BTF_DETAILEDMODE | BTF_ATTACHREPORT); lpfnBT_SetSupportURL(TEXT("http://www.srb2.org/")); @@ -454,7 +454,7 @@ LONG WINAPI RecordExceptionInfo(PEXCEPTION_POINTERS data/*, LPCSTR Message, LPST FPrintf(fileHandle, "Email Sonic Team Junior so we can fix the bugs\r\n"); // Tails FPrintf(fileHandle, "Make sure you tell us what you were doing to cause the crash, and if possible, record a demo!\r\n"); // Tails FPrintf(fileHandle, "\r\n\r\n\r\n\r\n"); - FPrintf(fileHandle, "SRB2Kart %s -ERROR LOG-\r\n\r\n", VERSIONSTRING); + FPrintf(fileHandle, "Dr. Robotnik's Ring Racers %s -ERROR LOG-\r\n\r\n", VERSIONSTRING); FPrintf(fileHandle, "\r\n"); // VirtualQuery can be used to get the allocation base associated with a // code address, which is the same as the ModuleHandle. This can be used diff --git a/src/win32/win_main.c b/src/win32/win_main.c index 54b489751..70b0d7201 100644 --- a/src/win32/win_main.c +++ b/src/win32/win_main.c @@ -325,8 +325,8 @@ static inline VOID OpenTextConsole(VOID) { if (AllocConsole()) //Let get the real console HANDLEs, because Mingw's Bash is bad! { - SetConsoleTitleA("SRB2Kart Console"); - CONS_Printf(M_GetText("Hello, it's me, SRB2Kart's Console Window\n")); + SetConsoleTitleA("Dr. Robotnik's Ring Racers Console"); + CONS_Printf(M_GetText("Hello, it's me, Dr. Robotnik's Ring Racers' Console Window\n")); } else { @@ -612,7 +612,7 @@ static int WINAPI HandledWinMain(HINSTANCE hInstance) #endif // open a dummy window, both OpenGL and DirectX need one. - if ((hWndMain = OpenMainWindow(hInstance, va("SRB2Kart "VERSIONSTRING))) == INVALID_HANDLE_VALUE) + if ((hWndMain = OpenMainWindow(hInstance, va("Dr. Robotnik's Ring Racers "VERSIONSTRING))) == INVALID_HANDLE_VALUE) { tlErrorMessage(TEXT("Couldn't open window")); return FALSE; @@ -624,7 +624,7 @@ static int WINAPI HandledWinMain(HINSTANCE hInstance) MakeCodeWritable(); // startup SRB2 - CONS_Printf("Setting up SRB2Kart...\n"); + CONS_Printf("Setting up Dr. Robotnik's Ring Racers...\n"); D_SRB2Main(); CONS_Printf("Entering main game loop...\n"); // never return diff --git a/src/win32/win_net.c b/src/win32/win_net.c index c06919550..4e958da60 100644 --- a/src/win32/win_net.c +++ b/src/win32/win_net.c @@ -33,7 +33,7 @@ boolean I_InitNetwork(void) { if (M_CheckParm ("-net")) { - I_Error("The Win32 version of SRB2Kart doesn't work with external drivers like ipxsetup, sersetup, or doomatic\n" + I_Error("The Win32 version of Dr. Robotnik's Ring Racers doesn't work with external drivers like ipxsetup, sersetup, or doomatic\n" "Read the documentation about \"-server\" and \"-connect\" parameters or just use the launcher\n"); } diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index b3f4f0f1a..d80c79b64 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -514,7 +514,7 @@ static void signal_handler(int num) } #endif - MessageBoxA(hWndMain, va("signal_handler(): %s", sigmsg), "SRB2Kart error", MB_OK|MB_ICONERROR); + MessageBoxA(hWndMain, va("signal_handler(): %s", sigmsg), "Dr. Robotnik's Ring Racers error", MB_OK|MB_ICONERROR); signal(num, SIG_DFL); // default signal action raise(num); @@ -631,7 +631,7 @@ void I_Error(const char *error, ...) va_end(argptr); OutputDebugStringA(txt); - MessageBoxA(hWndMain, txt, "SRB2Kart Recursive Error", MB_OK|MB_ICONERROR); + MessageBoxA(hWndMain, txt, "Dr. Robotnik's Ring Racers Recursive Error", MB_OK|MB_ICONERROR); W_Shutdown(); exit(-1); // recursive errors detected } @@ -674,7 +674,7 @@ void I_Error(const char *error, ...) } #endif - MessageBoxA(hWndMain, txt, "SRB2Kart Error", MB_OK|MB_ICONERROR); + MessageBoxA(hWndMain, txt, "Dr. Robotnik's Ring Racers Error", MB_OK|MB_ICONERROR); W_Shutdown(); exit(-1); @@ -3093,8 +3093,8 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) return; if(mumble->uiVersion != 2) { - wcsncpy(mumble->name, L"SRB2Kart "VERSIONSTRINGW, 256); - wcsncpy(mumble->description, L"SRB2Kart with integrated Mumble Link support.", 2048); + wcsncpy(mumble->name, L"Dr. Robotnik's Ring Racers "VERSIONSTRINGW, 256); + wcsncpy(mumble->description, L"Dr. Robotnik's Ring Racers with integrated Mumble Link support.", 2048); mumble->uiVersion = 2; } mumble->uiTick++; diff --git a/src/y_inter.c b/src/y_inter.c index f52fe7dd8..d5b94551c 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -300,25 +300,27 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) data.pos[data.numplayers] = data.numplayers+1; } - if ((powertype == PWRLV_DISABLED) - && (!rankingsmode) - && !(players[i].pflags & PF_NOCONTEST) - && (data.pos[data.numplayers] < (numplayersingame + numgriefers))) + if (!rankingsmode) { - // Online rank is handled further below in this file. - data.increase[i] = K_CalculateGPRankPoints(data.pos[data.numplayers], numplayersingame + numgriefers); - players[i].score += data.increase[i]; - } + if ((powertype == PWRLV_DISABLED) + && !(players[i].pflags & PF_NOCONTEST) + && (data.pos[data.numplayers] < (numplayersingame + numgriefers))) + { + // Online rank is handled further below in this file. + data.increase[i] = K_CalculateGPRankPoints(data.pos[data.numplayers], numplayersingame + numgriefers); + players[i].score += data.increase[i]; + } - if (demo.recording && !rankingsmode) - { - G_WriteStanding( - data.pos[data.numplayers], - data.name[data.numplayers], - *data.character[data.numplayers], - *data.color[data.numplayers], - data.val[data.numplayers] - ); + if (demo.recording) + { + G_WriteStanding( + data.pos[data.numplayers], + data.name[data.numplayers], + *data.character[data.numplayers], + *data.color[data.numplayers], + data.val[data.numplayers] + ); + } } data.numplayers++; @@ -448,6 +450,12 @@ void Y_IntermissionDrawer(void) V_DrawScaledPatch(x+16, y-4, 0, W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE)); } + if ((players[data.num[i]].pflags & PF_NOCONTEST) && players[data.num[i]].bot) + { + // RETIRED!! + V_DrawScaledPatch(x+12, y-7, 0, W_CachePatchName("K_NOBLNS", PU_CACHE)); + } + STRBUFCPY(strtime, data.name[i]); y2 = y; @@ -674,6 +682,7 @@ void Y_Ticker(void) { if (!data.rankingsmode && sorttic != -1 && (intertic >= sorttic + 8)) { + K_RetireBots(); Y_CalculateMatchData(1, Y_CompareRank); } @@ -1022,6 +1031,7 @@ void Y_StartIntermission(void) // void Y_EndIntermission(void) { + K_RetireBots(); Y_UnloadData(); endtic = -1;