diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 89b96a0d7..d7e7d3087 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1314,7 +1314,7 @@ static boolean CL_AskFileList(INT32 firstfile) netbuffer->packettype = PT_TELLFILESNEEDED; netbuffer->u.filesneedednum = firstfile; - return HSendPacket(servernode, true, 0, sizeof (INT32)); + return HSendPacket(servernode, false, 0, sizeof (INT32)); } /** Sends a special packet to declare how many players in local @@ -1989,11 +1989,11 @@ static boolean CL_FinishedFileList(void) CL_Reset(); D_StartTitle(); M_StartMessage(M_GetText( - "You have WAD files loaded or have\n" - "modified the game in some way, and\n" - "your file list does not match\n" - "the server's file list.\n" - "Please restart SRB2Kart before connecting.\n\n" + "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" + "everything you need when you join.\n\n" "Press ESC\n" ), NULL, MM_NOTHING); return false; @@ -2014,11 +2014,12 @@ static boolean CL_FinishedFileList(void) CL_Reset(); D_StartTitle(); M_StartMessage(M_GetText( - "You cannot connect to this server\n" - "because you cannot download the files\n" - "that you are missing from the server.\n\n" - "See the console or log file for\n" - "more details.\n\n" + "An error occured when trying to\n" + "download missing addons.\n" + "(This is almost always a problem\n" + "with the server, not your game.)\n\n" + "See the console or log file\n" + "for additional details.\n\n" "Press ESC\n" ), NULL, MM_NOTHING); return false; diff --git a/src/d_netfil.c b/src/d_netfil.c index 45c711fba..8e885f977 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1084,7 +1084,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.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. + 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. // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); diff --git a/src/g_game.c b/src/g_game.c index 4f52cf317..207c8ca5f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -6344,7 +6344,9 @@ void G_BeginRecording(void) demoflags |= DF_ENCORE; #ifdef HAVE_BLUA - demoflags |= DF_LUAVARS; + if (!modeattacking) // Ghosts don't read luavars, and you shouldn't ever need to save Lua in replays, you doof! + // SERIOUSLY THOUGH WHY WOULD YOU LOAD HOSTMOD AND RECORD A GHOST WITH IT !???? + demoflags |= DF_LUAVARS; #endif // Setup header. @@ -6477,8 +6479,9 @@ void G_BeginRecording(void) WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing #ifdef HAVE_BLUA - // player lua vars, always saved even if empty - LUA_ArchiveDemo(); + // player lua vars, always saved even if empty... Unless it's record attack. + if (!modeattacking) + LUA_ArchiveDemo(); #endif memset(&oldcmd,0,sizeof(oldcmd)); @@ -7431,6 +7434,7 @@ void G_DoPlayDemo(char *defdemoname) if (!gL) // No Lua state! ...I guess we'll just start one... LUA_ClearState(); + // No modeattacking check, DF_LUAVARS won't be present here. LUA_UnArchiveDemo(); } #endif diff --git a/src/k_kart.c b/src/k_kart.c index ce092fa43..1307d9201 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3944,7 +3944,8 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) if (!thismine || P_MobjWasRemoved(thismine)) return; - if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine + //This guarantees you hit a mine being dragged + if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine, and clean up the old one { mine = P_SpawnMobj(thismine->x, thismine->y, thismine->z, MT_SSMINE); P_SetTarget(&mine->target, thismine->target); @@ -3952,7 +3953,19 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) mine->flags2 = thismine->flags2; mine->floorz = thismine->floorz; mine->ceilingz = thismine->ceilingz; + + //Since we aren't using P_KillMobj, we need to clean up the hnext reference + { + P_SetTarget(&thismine->target->hnext, NULL); //target is the player who owns the mine + thismine->target->player->kartstuff[k_bananadrag] = 0; + thismine->target->player->kartstuff[k_itemheld] = 0; + + if (--thismine->target->player->kartstuff[k_itemamount] <= 0) + thismine->target->player->kartstuff[k_itemtype] = KITEM_NONE; + } + P_RemoveMobj(thismine); + } else mine = thismine; @@ -4574,6 +4587,62 @@ void K_DropItems(player_t *player) K_StripItems(player); } +void K_DropRocketSneaker(player_t *player) +{ + mobj_t *shoe = player->mo; + fixed_t flingangle; + boolean leftshoe = true; //left shoe is first + + if (!(player->mo && !P_MobjWasRemoved(player->mo) && player->mo->hnext && !P_MobjWasRemoved(player->mo->hnext))) + return; + + while ((shoe = shoe->hnext) && !P_MobjWasRemoved(shoe)) + { + if (shoe->type != MT_ROCKETSNEAKER) + return; //woah, not a rocketsneaker, bail! safeguard in case this gets used when you're holding non-rocketsneakers + + shoe->flags2 &= ~MF2_DONTDRAW; + shoe->flags &= ~MF_NOGRAVITY; + shoe->angle += ANGLE_45; + + if (shoe->eflags & MFE_VERTICALFLIP) + shoe->z -= shoe->height; + else + shoe->z += shoe->height; + + //left shoe goes off tot eh left, right shoe off to the right + if (leftshoe) + flingangle = -(ANG60); + else + flingangle = ANG60; + + S_StartSound(shoe, shoe->info->deathsound); + P_SetObjectMomZ(shoe, 8*FRACUNIT, false); + P_InstaThrust(shoe, R_PointToAngle2(shoe->target->x, shoe->target->y, shoe->x, shoe->y)+flingangle, 16*FRACUNIT); + shoe->momx += shoe->target->momx; + shoe->momy += shoe->target->momy; + shoe->momz += shoe->target->momz; + shoe->extravalue2 = 1; + + leftshoe = false; + } + P_SetTarget(&player->mo->hnext, NULL); + player->kartstuff[k_rocketsneakertimer] = 0; +} + +void K_DropKitchenSink(player_t *player) +{ + if (!(player->mo && !P_MobjWasRemoved(player->mo) && player->mo->hnext && !P_MobjWasRemoved(player->mo->hnext))) + return; + + if (player->mo->hnext->type != MT_SINK_SHIELD) + return; //so we can just call this function regardless of what is being held + + P_KillMobj(player->mo->hnext, NULL, NULL); + + P_SetTarget(&player->mo->hnext, NULL); +} + // When an item in the hnext chain dies. void K_RepairOrbitChain(mobj_t *orbit) { @@ -6864,12 +6933,12 @@ void K_KartUpdatePosition(player_t *player) // void K_StripItems(player_t *player) { + K_DropRocketSneaker(player); + K_DropKitchenSink(player); player->kartstuff[k_itemtype] = KITEM_NONE; player->kartstuff[k_itemamount] = 0; player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_rocketsneakertimer] = 0; - if (!player->kartstuff[k_itemroulette] || player->kartstuff[k_roulettetype] != 2) { player->kartstuff[k_itemroulette] = 0; diff --git a/src/k_kart.h b/src/k_kart.h index 695ca3f65..67d7a3495 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -68,6 +68,7 @@ INT32 K_GetKartDriftSparkValue(player_t *player); void K_SpawnDriftBoostExplosion(player_t *player, int stage); void K_KartUpdatePosition(player_t *player); void K_DropItems(player_t *player); +void K_DropRocketSneaker(player_t *player); void K_StripItems(player_t *player); void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 436a7161b..bc11d4ca7 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -119,7 +119,7 @@ static int lib_iterateDisplayplayers(lua_State *L) for (i++; i < MAXSPLITSCREENPLAYERS; i++) { - if (!playeringame[displayplayers[i]] || i > splitscreen) + if (i > splitscreen || !playeringame[displayplayers[i]]) return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers. if (!players[displayplayers[i]].mo) @@ -140,6 +140,8 @@ static int lib_getDisplayplayers(lua_State *L) lua_Integer i = luaL_checkinteger(L, 2); if (i < 0 || i >= MAXSPLITSCREENPLAYERS) return luaL_error(L, "displayplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1); + if (i > splitscreen) + return 0; if (!playeringame[displayplayers[i]]) return 0; if (!players[displayplayers[i]].mo) diff --git a/src/m_menu.c b/src/m_menu.c index b4302d90a..129dbef6b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4857,7 +4857,7 @@ static boolean M_AddonsRefresh(void) else if (majormods && !prevmajormods) { S_StartSound(NULL, sfx_s221); - message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + message = va("%c%s\x80\nYou've loaded a gameplay-modifying addon.\n\nRecord Attack has been disabled, but you\ncan still play alone in local Multiplayer.\n\nIf you wish to play Record Attack mode, restart the game to disable loaded addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); prevmajormods = majormods; } @@ -8685,7 +8685,7 @@ static void M_ConnectMenuModChecks(INT32 choice) if (modifiedgame) { - M_StartMessage(M_GetText("Addons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing addons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER); + M_StartMessage(M_GetText("You have addons loaded.\nYou won't be able to join netgames!\n\nTo play online, restart the game\nand don't load any addons.\nSRB2Kart will automatically add\neverything you need when you join.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER); return; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 1b19a9c79..748d3a40a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8861,18 +8861,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->extravalue2) { - if (mobj->eflags & MFE_VERTICALFLIP) - mobj->z -= mobj->height; - else - mobj->z += mobj->height; - - S_StartSound(mobj, mobj->info->deathsound); - P_SetObjectMomZ(mobj, 8*FRACUNIT, false); - P_InstaThrust(mobj, R_PointToAngle2(mobj->target->x, mobj->target->y, mobj->x, mobj->y)+ANGLE_90, 16*FRACUNIT); - mobj->momx += mobj->target->momx; - mobj->momy += mobj->target->momy; - mobj->momz += mobj->target->momz; - mobj->extravalue2 = 1; + K_DropRocketSneaker(mobj->target->player); } else if (P_IsObjectOnGround(mobj)) { diff --git a/src/p_setup.c b/src/p_setup.c index eb64639c2..73a25fe51 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1450,7 +1450,7 @@ static void P_LoadRawSideDefs2(void *data) UINT16 i; INT32 num; size_t j; - UINT32 cr, cg, cb; + RGBA_t color; for (i = 0; i < numsides; i++) { @@ -1532,23 +1532,21 @@ static void P_LoadRawSideDefs2(void *data) // encore mode colormaps! // do it like software by aproximating a color to a palette index, and then convert it to its encore variant and then back to a color code. // do this for both the start and fade colormaps. - - cr = (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0); - cg = (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8); - cb = (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); + + color.s.red = (HEX2INT(col[1]) << 4) + HEX2INT(col[2]); + color.s.green = (HEX2INT(col[3]) << 4) + HEX2INT(col[4]); + color.s.blue = (HEX2INT(col[5]) << 4) + HEX2INT(col[6]); #ifdef GLENCORE if (encoremap) { - j = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)]; + j = encoremap[NearestColor(color.s.red, color.s.green, color.s.blue)]; //CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation - cr = pLocalPalette[j].s.red; - cg = pLocalPalette[j].s.green; - cb = pLocalPalette[j].s.blue; + color = pLocalPalette[j]; // note: this sets alpha to 255, we will reset it below } #endif - - sec->extra_colormap->rgba = cr + cg + cb; + color.s.alpha = 0; // reset/init the alpha, so the addition below will work correctly + sec->extra_colormap->rgba = color.rgba; // alpha if (msd->toptexture[7]) @@ -1575,23 +1573,21 @@ static void P_LoadRawSideDefs2(void *data) col = msd->bottomtexture; // do the exact same thing as above here. - - cr = (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0); - cg = (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8); - cb = (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); + + color.s.red = (HEX2INT(col[1]) << 4) + HEX2INT(col[2]); + color.s.green = (HEX2INT(col[3]) << 4) + HEX2INT(col[4]); + color.s.blue = (HEX2INT(col[5]) << 4) + HEX2INT(col[6]); #ifdef GLENCORE if (encoremap) { - j = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)]; + j = encoremap[NearestColor(color.s.red, color.s.green, color.s.blue)]; //CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation - cr = pLocalPalette[j].s.red; - cg = pLocalPalette[j].s.green; - cb = pLocalPalette[j].s.blue; + color = pLocalPalette[j]; // note: this sets alpha to 255, we will reset it below } #endif - - sec->extra_colormap->fadergba = cr + cg + cb; + color.s.alpha = 0; // reset/init the alpha, so the addition below will work correctly + sec->extra_colormap->fadergba = color.rgba; // alpha if (msd->bottomtexture[7]) diff --git a/src/p_tick.c b/src/p_tick.c index d57a6dc43..0c7f5b1dc 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -711,9 +711,9 @@ void P_Ticker(boolean run) if (exitcountdown > 1) exitcountdown--; - if (indirectitemcooldown > 1) + if (indirectitemcooldown > 0) indirectitemcooldown--; - if (hyubgone > 1) + if (hyubgone > 0) hyubgone--; if (G_BattleGametype()) diff --git a/src/w_wad.c b/src/w_wad.c index 54ae7fb26..7fd7ac125 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1319,8 +1319,8 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si { size = 0; zerr(zErr); - (void)inflateEnd(&strm); } + (void)inflateEnd(&strm); } else {