Merge remote-tracking branch 'refs/remotes/origin/master' into sonicitems

# Conflicts:
#	src/k_kart.c
#	src/k_kart.h
#	src/lua_baselib.c
#	src/p_inter.c
#	src/p_spec.c
This commit is contained in:
TehRealSalt 2018-03-31 00:44:03 -04:00
commit 00e913bbcc
25 changed files with 435 additions and 429 deletions

View file

@ -3082,7 +3082,7 @@ static void readmaincfg(MYFILE *f)
if (!GoodDataFileName(word2))
I_Error("Maincfg: bad data file name '%s'\n", word2);
G_SaveGameData();
G_SaveGameData(false);
DEH_WriteUndoline(word, gamedatafilename, UNDO_NONE);
strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
strlwr(gamedatafilename);
@ -6608,6 +6608,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAYERARROW_X",
"S_PLAYERBOMB", // Player bomb overlay
"S_PLAYERITEM", // Player item overlay
"S_PLAYERBOMB_WHEEL",
#ifdef SEENAMES

View file

@ -41,6 +41,7 @@ static INT32 timetonext; // Delay between screen changes
static INT32 continuetime; // Short delay when continuing
static tic_t animtimer; // Used for some animation timings
static tic_t credbgtimer; // Credits background
static INT32 roidtics; // Asteroid spinning
static tic_t stoptimer;
@ -451,128 +452,77 @@ boolean F_IntroResponder(event_t *event)
// CREDITS
// =========
static const char *credits[] = {
"\1Sonic Robo Blast II",
"\1SRB2 Kart",
"\1Credits",
"",
"\1Game Design",
"Ben \"Mystic\" Geyer",
"\"SSNTails\"",
"Johnny \"Sonikku\" Wallbank",
"\"Chaos Zero 64\"",
"\"Iceman404\" aka \"VelocitOni\"",
"\"ZarroTsu\"",
"",
"\1Programming",
"Alam \"GBC\" Arias",
"Logan \"GBA\" Arias",
"Tim \"RedEnchilada\" Bordelon",
"Callum Dickinson",
"Scott \"Graue\" Feeney",
"Nathan \"Jazz\" Giroux",
"Thomas \"Shadow Hog\" Igoe",
"Iestyn \"Monster Iestyn\" Jealous",
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
"John \"JTE\" Muniz",
"Ehab \"Wolfy\" Saeed",
"\"SSNTails\"",
"Matthew \"Inuyasha\" Walsh",
"",
"\1Programming",
"\1Assistance",
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
"Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick",
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
"\"Chaos Zero 64\"",
"Sally \"TehRealSalt\" Cochenour",
"Vivian \"toaster\" Grannell",
"Julio \"Chaos Zero 64\" Guir",
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
"Matthew \"Shuffle\" Marsalko",
"Steven \"StroggOnMeth\" McGranahan",
"\"Morph\"", // For SRB2Morphed stuff
"Colin \"Sonict\" Pfaff",
"Sean \"Sryder13\" Ryder",
"Ben \"Cue\" Woodford",
"\"Lat\'\"",
"\"Monster Iestyn\"",
"Sean \"Sryder\" Ryder",
"Ehab \"wolfs\" Saeed",
"\"ZarroTsu\"",
"",
"\1Sprite Artists",
"Odi \"Iceman404\" Atunzu",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Jim \"MotorRoach\" DeMello",
"\1Artists",
"\"Chaos Zero 64\"",
"Sally \"TehRealSalt\" Cochenour",
"Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins",
"Andrew \"Senku Niola\" Moran",
"David \"Instant Sonic\" Spencer Jr.",
"\"SSNTails\"",
"",
"\1Texture Artists",
"Ryan \"Blaze Hedgehog\" Bloom",
"Buddy \"KinkaJoy\" Fischer",
"Vivian \"toaster\" Grannell",
"Kepa \"Nev3r\" Iceta",
"Jarrett \"JEV3\" Voight",
"Sherman \"CoatRack\" DesJardin",
"Wesley \"Charyb\" Gillebaard",
"James \"SeventhSentinel\" Hall",
"\"Iceman404\"",
"\"MotorRoach\"",
"\"VAdaPEGA\"",
"\"ZarroTsu\"",
"",
"\1Music and Sound",
"\1Production",
"Malcolm \"RedXVI\" Brown",
"David \"Bulmybag\" Bulmer",
"Paul \"Boinciel\" Clempson",
"Cyan Helkaraxe",
"Kepa \"Nev3r\" Iceta",
"Iestyn \"Monster Iestyn\" Jealous",
"Jarel \"Arrow\" Jones",
"Stefan \"Stuf\" Rimalia",
"Shane Mychal Sexton",
"\"Spazzo\"",
"David \"Big Wave Dave\" Spencer Sr.",
"David \"Instant Sonic\" Spencer Jr.",
"\"SSNTails\"",
"Karl Brueggemann",
"Wesley \"Charyb\" Gillebaard",
"James \"SeventhSentinel\" Hall",
"\"MaxieDaMan\"",
"",
"\1Level Design",
"Matthew \"Fawfulfan\" Chapman",
"\"Blitz-T\"",
"\"D00D64-X\"",
"\"Chaos Zero 64\"",
"Paul \"Boinciel\" Clempson",
"Sally \"TehRealSalt\" Cochenour",
"Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins",
"Ben \"Mystic\" Geyer",
"Nathan \"Jazz\" Giroux",
"Dan \"Blitzzo\" Hagerstrand",
"Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe",
"Erik \"Torgo\" Nielsen",
"Wessel \"Spherallic\" Smit",
"\"Spazzo\"",
"\"SSNTails\"",
"Rob Tisdell",
"Jarrett \"JEV3\" Voight",
"Johnny \"Sonikku\" Wallbank",
"Matthew \"Inuyasha\" Walsh",
"Marco \"Digiku\" Zafra",
"",
"\1Boss Design",
"Ben \"Mystic\" Geyer",
"Thomas \"Shadow Hog\" Igoe",
"John \"JTE\" Muniz",
"Samuel \"Prime 2.0\" Peters",
"\"SSNTails\"",
"Johnny \"Sonikku\" Wallbank",
"Sherman \"CoatRack\" DesJardin",
"James \"SeventhSentinel\" Hall",
"Sean \"Sryder\" Ryder",
"\"Ryuspark\"",
"Jeffery \"Chromatian\" Scott",
"\"Simsmagic\"",
"\"Tyrannosaur Chao\" aka \"Chaotic Chao\"",
"\"ZarroTsu\"",
"",
"\1Testing",
"Hank \"FuriousFox\" Brannock",
"Cody \"SRB2 Playah\" Koester",
"Skye \"OmegaVelocity\" Meredith",
"Stephen \"HEDGESMFG\" Moellering",
"Nick \"ST218\" Molina",
"Samuel \"Prime 2.0\" Peters",
"Colin \"Sonict\" Pfaff",
"Bill \"Tets\" Reed",
"\"CyberIF\"",
"\"Dani\"",
"Karol \"Fooruman\" D""\x1E""browski", // Dąbrowski, <Sryder> accents in srb2 :ytho:
"Jesse \"Jeck Jims\" Emerick",
"\"VirtAnderson\"",
"",
"\1Special Thanks",
"Doom Legacy Project",
"iD Software",
"Alex \"MistaED\" Fuller",
"FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak
"Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
"Sonic Team Jr. & SRB2",
"Bandit \"Bobby\" Cochenour", // i <3 my dog
"\"Nev3r\"",
"\"Ritz\"",
"\"Spherallic\"",
"",
"\1Produced By",
"Sonic Team Junior",
"Kart Krew",
"",
"\1Published By",
"A 28K dialup modem",
"\1In Memory of",
"\"Tyler52\"",
"",
"\1Thank you",
"\1for playing!",
@ -583,7 +533,7 @@ static struct {
UINT32 x, y;
const char *patch;
} credits_pics[] = {
{ 8, 80+200* 1, "CREDIT01"},
/*{ 8, 80+200* 1, "CREDIT01"},
{ 4, 80+200* 2, "CREDIT13"},
{250, 80+200* 3, "CREDIT12"},
{ 8, 80+200* 4, "CREDIT03"},
@ -591,10 +541,8 @@ static struct {
{ 8, 80+200* 6, "CREDIT04"},
{112, 80+200* 7, "CREDIT10"},
{240, 80+200* 8, "CREDIT05"},
{120, 80+200* 9, "CREDIT06"},
{ 8, 80+200*10, "CREDIT07"},
{ 8, 80+200*11, "CREDIT08"},
{112, 80+200*12, "CREDIT09"},
{120, 80+200* 9, "CREDIT06"},*/
{112, 80+200*10, "TYLER52"},
{0, 0, NULL}
};
@ -636,7 +584,13 @@ void F_CreditDrawer(void)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
// Draw background pictures first
// Draw background
V_DrawSciencePatch(0, 0 - FixedMul(32<<FRACBITS, FixedDiv(credbgtimer%TICRATE, TICRATE)), V_SNAPTOTOP, W_CachePatchName("CREDTILE", PU_CACHE), FRACUNIT);
V_DrawSciencePatch(0, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP, W_CachePatchName("CREDZIGZ", PU_CACHE), FRACUNIT);
V_DrawSciencePatch(320<<FRACBITS, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP|V_FLIP, W_CachePatchName("CREDZIGZ", PU_CACHE), FRACUNIT);
// Draw pictures
for (i = 0; credits_pics[i].patch; i++)
V_DrawSciencePatch(credits_pics[i].x<<FRACBITS, (credits_pics[i].y<<FRACBITS) - 4*(animtimer<<FRACBITS)/5, 0, W_CachePatchName(credits_pics[i].patch, PU_CACHE), FRACUNIT>>1);
@ -677,6 +631,8 @@ void F_CreditTicker(void)
else
animtimer++;
credbgtimer++;
if (finalecount && --finalecount == 0)
F_StartGameEvaluation();
}
@ -718,8 +674,8 @@ boolean F_CreditResponder(event_t *event)
break;
}
if (!(timesBeaten) && !(netgame || multiplayer))
return false;
/*if (!(timesBeaten) && !(netgame || multiplayer))
return false;*/
if (event->type != ev_keydown)
return false;
@ -819,10 +775,10 @@ void F_GameEvaluationDrawer(void)
/*if (ultimatemode)
++timesBeatenUltimate;*/
if (M_UpdateUnlockablesAndExtraEmblems())
if (M_UpdateUnlockablesAndExtraEmblems(false))
S_StartSound(NULL, sfx_ncitem);
G_SaveGameData();
G_SaveGameData(false);
}
}

View file

@ -2259,10 +2259,10 @@ static inline void G_PlayerFinishLevel(INT32 player)
if (legitimateexit && !demoplayback) // (yes you're allowed to unlock stuff this way when the game is modified)
{
matchesplayed++;
if (M_UpdateUnlockablesAndExtraEmblems())
if (M_UpdateUnlockablesAndExtraEmblems(true))
{
S_StartSound(NULL, sfx_ncitem);
G_SaveGameData(); // only save if unlocked something
G_SaveGameData(true); // only save if unlocked something
}
}
@ -3385,12 +3385,8 @@ static void G_DoWorldDone(void)
{
if (server)
{
if (G_RaceGametype())
// SRB2kart: don't reset player between maps
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
else
// resetplayer in match/tag/CTF for more equality
D_MapChange(nextmap+1, gametype, ultimatemode, true, 0, false, false);
// SRB2kart: don't reset player between maps
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
}
gameaction = ga_nothing;
@ -3647,7 +3643,7 @@ void G_LoadGameData(void)
// G_SaveGameData
// Saves the main data file, which stores information such as emblems found, etc.
void G_SaveGameData(void)
void G_SaveGameData(boolean force)
{
size_t length;
INT32 i, j;
@ -3665,7 +3661,8 @@ void G_SaveGameData(void)
return;
}
if (modifiedgame && !savemoddata)
if (modifiedgame && !savemoddata
&& !force) // SRB2Kart: for enabling unlocks online in modified servers
{
free(savebuffer);
save_p = savebuffer = NULL;
@ -3967,6 +3964,7 @@ void G_SaveGame(UINT32 savegameslot)
//
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, UINT8 ssplayers, boolean FLS)
{
INT32 i;
UINT8 color = 0;
paused = false;
@ -3974,6 +3972,9 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, U
COM_BufAddText("stopdemo\n");
ghosts = NULL;
for (i = 0; i < NUMMAPS; i++)
randmapbuffer[i] = -1;
// this leave the actual game if needed
SV_StartSinglePlayerServer();

View file

@ -127,7 +127,7 @@ void G_DeferedPlayDemo(const char *demo);
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
void G_LoadGame(UINT32 slot, INT16 mapoverride);
void G_SaveGameData(void);
void G_SaveGameData(boolean force);
void G_SaveGame(UINT32 slot);

View file

@ -21,7 +21,7 @@
//------------------------------------
// heads up font
//------------------------------------
#define HU_FONTSTART '\x1F' // the first font character
#define HU_FONTSTART '\x1E' // the first font character
#define HU_FONTEND '~'
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)

View file

@ -2915,7 +2915,8 @@ state_t states[NUMSTATES] =
{SPR_ITMN, FF_FULLBRIGHT|10, -1, {NULL}, 16, 3, S_NULL}, // S_PLAYERARROW_X
{SPR_PBOM, FF_ANIMATE, -1, {NULL}, 3, 3, S_NULL}, // S_PLAYERBOMB
{SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERBOMB_WHEEL
{SPR_RNDM, FF_ANIMATE, -1, {NULL}, 23, 3, S_NULL}, // S_PLAYERITEM
{SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERWHEEL
#ifdef SEENAMES
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK

View file

@ -3440,7 +3440,8 @@ typedef enum state
S_PLAYERARROW_X,
S_PLAYERBOMB,
S_PLAYERBOMB_WHEEL,
S_PLAYERITEM,
S_PLAYERWHEEL,
#ifdef SEENAMES
S_NAMECHECK,

View file

@ -1012,7 +1012,7 @@ void K_LakituChecker(player_t *player)
player->kartstuff[k_lakitu]--;
// Quick! You only have three tics to boost!
if (cmd->buttons & BT_ACCELERATE)
K_DoSneaker(player, true, false);
K_DoSneaker(player, true);
}
}
}
@ -1458,8 +1458,8 @@ void K_SpinPlayer(player_t *player, mobj_t *source)
if (G_BattleGametype())
{
if (source && source->player && player != source->player)
P_AddPlayerScore(source->player, 1);
/*if (source && source->player && player != source->player)
P_AddPlayerScore(source->player, 1);*/
if (player->kartstuff[k_balloon] > 0)
{
@ -1516,8 +1516,8 @@ void K_SquishPlayer(player_t *player, mobj_t *source)
if (G_BattleGametype())
{
if (source && source->player && player != source->player)
P_AddPlayerScore(source->player, 1);
/*if (source && source->player && player != source->player)
P_AddPlayerScore(source->player, 1);*/
if (player->kartstuff[k_balloon] > 0)
{
@ -1573,7 +1573,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju
if (source->player->kartstuff[k_comebackpoints] >= 3)
K_StealBalloon(source->player, player, true);
}
P_AddPlayerScore(source->player, 1);
//P_AddPlayerScore(source->player, 1);
}
if (player->kartstuff[k_balloon] > 0)
@ -2230,14 +2230,10 @@ static void K_DoHyudoroSteal(player_t *player)
}
}
void K_DoSneaker(player_t *player, boolean doPFlag, boolean startboost)
void K_DoSneaker(player_t *player, boolean doPFlag)
{
sfxenum_t boostsound = sfx_mush;
if (startboost)
boostsound = sfx_sboost;
if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3)
S_StartSound(player->mo, boostsound);
S_StartSound(player->mo, sfx_mush);
player->kartstuff[k_sneakertimer] = sneakertime;
@ -2723,7 +2719,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
&& player->kartstuff[k_rocketsneakertimer] > 1)
{
K_DoSneaker(player, true, false);
K_DoSneaker(player, true);
player->kartstuff[k_rocketsneakertimer] -= 5;
if (player->kartstuff[k_rocketsneakertimer] < 1)
player->kartstuff[k_rocketsneakertimer] = 1;
@ -2735,7 +2731,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_SNEAKER:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO)
{
K_DoSneaker(player, true, false);
K_DoSneaker(player, true);
player->kartstuff[k_itemamount]--;
}
break;
@ -2743,7 +2739,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
&& player->kartstuff[k_rocketsneakertimer] == 0)
{
K_DoSneaker(player, true, false);
K_DoSneaker(player, true);
player->kartstuff[k_rocketsneakertimer] = itemtime;
player->kartstuff[k_itemamount]--;
}
@ -3131,14 +3127,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->kartstuff[k_hyudorotimer] > 0)
{
if ((player == &players[displayplayer]
|| (splitscreen && player == &players[secondarydisplayplayer])
|| (splitscreen > 1 && player == &players[thirddisplayplayer])
|| (splitscreen > 2 && player == &players[fourthdisplayplayer]))
|| (!(player == &players[displayplayer]
|| (splitscreen && player == &players[secondarydisplayplayer])
|| (splitscreen > 1 && player == &players[thirddisplayplayer])
|| (splitscreen > 2 && player == &players[fourthdisplayplayer]))
if ((player == &players[displayplayer] && !splitscreen)
|| (!(player == &players[displayplayer] && !splitscreen)
&& (player->kartstuff[k_hyudorotimer] < 1*TICRATE/2 || player->kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2))))
{
if (leveltime & 1)
@ -3172,6 +3162,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->kartstuff[k_comebacktimer] > 0)
{
if (player->mo->tracer->state != &states[S_PLAYERBOMB])
P_SetMobjState(player->mo->tracer, S_PLAYERBOMB);
if (player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1))
player->mo->tracer->flags2 &= ~MF2_DONTDRAW;
else
@ -3179,15 +3172,23 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->powers[pw_flashing] = player->kartstuff[k_comebacktimer];
}
else if (player->kartstuff[k_comebackmode] != 0)
player->mo->tracer->flags2 |= MF2_DONTDRAW;
else
{
if (player->kartstuff[k_comebackmode] == 0
&& player->mo->tracer->state != &states[S_PLAYERBOMB])
P_SetMobjState(player->mo->tracer, S_PLAYERBOMB);
else if (player->kartstuff[k_comebackmode] == 1
&& player->mo->tracer->state != &states[S_PLAYERITEM])
P_SetMobjState(player->mo->tracer, S_PLAYERITEM);
player->mo->tracer->flags2 &= ~MF2_DONTDRAW;
}
}
else if (G_RaceGametype() || player->kartstuff[k_balloon] > 0)
{
player->mo->flags2 &= ~MF2_SHADOW;
if (player->mo->tracer && player->mo->tracer->state == &states[S_PLAYERBOMB])
if (player->mo->tracer
&& (player->mo->tracer->state == &states[S_PLAYERBOMB]
|| player->mo->tracer->state == &states[S_PLAYERITEM]))
P_RemoveMobj(player->mo->tracer);
}
}
@ -3265,24 +3266,33 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (leveltime == (TICRATE)*4)
S_StartSound(NULL, sfx_lkt2);
// Start charging once you're given the opportunity.
if (leveltime >= 70 && leveltime <= 140 && cmd->buttons & BT_ACCELERATE && leveltime % 5 == 0)
if (leveltime >= 70 && leveltime <= 140 && cmd->buttons & BT_ACCELERATE)
player->kartstuff[k_boostcharge]++;
if (leveltime >= 70 && leveltime <= 140 && !(cmd->buttons & BT_ACCELERATE))
player->kartstuff[k_boostcharge] = 0;
// Increase your size while charging your engine.
if (leveltime < 150)
player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale) + (player->kartstuff[k_boostcharge]*655);
player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale) + (player->kartstuff[k_boostcharge]*131);
// Determine the outcome of your charge.
if (leveltime > 140 && player->kartstuff[k_boostcharge])
{
// Get an instant boost!
if (player->kartstuff[k_boostcharge] >= 7 && player->kartstuff[k_boostcharge] <= 10)
if (player->kartstuff[k_boostcharge] >= 35 && player->kartstuff[k_boostcharge] <= 50)
{
K_DoSneaker(player, false, true);
if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3)
S_StartSound(player->mo, sfx_sboost);
player->kartstuff[k_sneakertimer] = -((21*(player->kartstuff[k_boostcharge]*player->kartstuff[k_boostcharge]))/425)+131; // max time is 70, min time is 7; yay parabooolas
if (!player->kartstuff[k_sounds]) // Prevents taunt sounds from playing every time the button is pressed
{
K_PlayTauntSound(player->mo);
player->kartstuff[k_sounds] = 50;
}
}
// You overcharged your engine? Those things are expensive!!!
if (player->kartstuff[k_boostcharge] > 10)
else if (player->kartstuff[k_boostcharge] > 50)
{
player->powers[pw_nocontrol] = 40;
S_StartSound(player->mo, sfx_slip);
@ -3333,8 +3343,8 @@ void K_CheckBalloons(void)
if (playeringame[winnernum])
{
P_AddPlayerScore(&players[winnernum], numingame);
CONS_Printf(M_GetText("%s recieved %d points for winning!\n"), player_names[winnernum], numingame*2);
P_AddPlayerScore(&players[winnernum], 1);
CONS_Printf(M_GetText("%s recieved a point for winning!\n"));
}
for (i = 0; i < MAXPLAYERS; i++)
@ -4392,7 +4402,7 @@ static void K_drawKartMinimap(void)
x = MINI_X - (AutomapPic->width/2);
y = MINI_Y - (AutomapPic->height/2);
if (splitscreen == 2)
if (splitscreen)
splitflags = 0;
if (mirrormode)
@ -4400,7 +4410,7 @@ static void K_drawKartMinimap(void)
else
V_DrawScaledPatch(x, y, splitflags, AutomapPic);
if (splitscreen != 2)
if (!splitscreen)
{
splitflags &= ~minimaptrans;
splitflags |= V_HUDTRANSHALF;
@ -4409,13 +4419,28 @@ static void K_drawKartMinimap(void)
// Player's tiny icons on the Automap.
for (i = 0; i < MAXPLAYERS; i++)
{
if (i == displayplayer && splitscreen != 2)
if (i == displayplayer && !splitscreen)
continue; // Do displayplayer later
if (players[i].mo && !players[i].spectator)
{
if (G_BattleGametype() && players[i].kartstuff[k_balloon] <= 0)
continue;
if (players[i].kartstuff[k_hyudorotimer] > 0)
{
if ((players[i].kartstuff[k_hyudorotimer] < 1*TICRATE/2
|| players[i].kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2))
&& !(leveltime & 1))
;
else
continue;
}
K_drawKartMinimapHead(&players[i], x, y, splitflags, AutomapPic);
}
}
if (splitscreen == 2)
if (splitscreen)
return; // Don't need this for splits
splitflags &= ~V_HUDTRANSHALF;
@ -4428,13 +4453,18 @@ static void K_drawBattleFullscreen(void)
{
INT32 x = BASEVIDWIDTH/2;
INT32 y = -64+(stplyr->kartstuff[k_cardanimation]); // card animation goes from 0 to 164, 164 is the middle of the screen
INT32 splitflags = V_SNAPTOTOP; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead
fixed_t scale = FRACUNIT;
if (splitscreen)
{
if ((splitscreen == 1 && stplyr == &players[secondarydisplayplayer])
|| (splitscreen > 1 && (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer])))
|| (splitscreen > 1 && (stplyr == &players[thirddisplayplayer]
|| (stplyr == &players[fourthdisplayplayer] && splitscreen > 2))))
{
y = 232-(stplyr->kartstuff[k_cardanimation]/2);
splitflags = V_SNAPTOBOTTOM;
}
else
y = -32+(stplyr->kartstuff[k_cardanimation]/2);
@ -4442,7 +4472,8 @@ static void K_drawBattleFullscreen(void)
{
scale /= 2;
if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer])
if (stplyr == &players[secondarydisplayplayer]
|| (stplyr == &players[fourthdisplayplayer] && splitscreen > 2))
x = 3*BASEVIDWIDTH/4;
else
x = BASEVIDWIDTH/4;
@ -4461,9 +4492,9 @@ static void K_drawBattleFullscreen(void)
if (stplyr == &players[displayplayer])
V_DrawFadeScreen();
if (stplyr->kartstuff[k_balloon])
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, 0, kp_battlewin, NULL);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewin, NULL);
else if (splitscreen < 2)
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, 0, kp_battlelose, NULL);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlelose, NULL);
}
else if (stplyr->kartstuff[k_balloon] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback)
{
@ -4487,22 +4518,23 @@ static void K_drawBattleFullscreen(void)
if (splitscreen > 2)
ty = (BASEVIDHEIGHT/4)+33;
if ((splitscreen == 1 && stplyr == &players[secondarydisplayplayer])
|| stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer])
|| (stplyr == &players[thirddisplayplayer] && splitscreen > 1)
|| (stplyr == &players[fourthdisplayplayer] && splitscreen > 2))
ty += (BASEVIDHEIGHT/2);
}
else
V_DrawFadeScreen();
if (!comebackshowninfo)
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, 0, kp_battleinfo, NULL);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battleinfo, NULL);
else
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, 0, kp_battlewait, NULL);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewait, NULL);
if (splitscreen > 1)
V_DrawString(x-(txoff/2), ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
else
{
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, K_calcSplitFlags(0), kp_timeoutsticker, NULL);
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutsticker, NULL);
V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
}
}
@ -4625,6 +4657,9 @@ void K_drawKartHUD(void)
// This is handled by console/menu values
K_initKartHUD();
if (splitscreen == 2) // Player 4 in 3P is basically the minimap :p
K_drawKartMinimap();
// Draw full screen stuff that turns off the rest of the HUD
if ((G_BattleGametype())
&& (stplyr->exiting
@ -4653,8 +4688,8 @@ void K_drawKartHUD(void)
K_drawKartPlayerCheck();
}
if ((splitscreen == 0 && cv_kartminimap.value) || splitscreen == 2)
K_drawKartMinimap();
if (splitscreen == 0 && cv_kartminimap.value)
K_drawKartMinimap(); // 3P splitscreen is handled above
// Draw the item window
K_drawKartItem();

View file

@ -31,7 +31,7 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32
void K_SpawnMineExplosion(mobj_t *source, UINT8 color);
void K_SpawnDriftTrail(player_t *player);
void K_SpawnSparkleTrail(player_t *player);
void K_DoSneaker(player_t *player, boolean doPFlag, boolean startboost);
void K_DoSneaker(player_t *player, boolean doPFlag);
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed);
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);

View file

@ -2104,11 +2104,10 @@ static int lib_kDoSneaker(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean doPFlag = luaL_checkboolean(L, 2);
boolean startboost = luaL_checkboolean(L, 3);
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_DoSneaker(player, doPFlag, startboost);
K_DoSneaker(player, doPFlag);
return 0;
}

View file

@ -197,7 +197,7 @@ void M_ClearSecrets(void)
// ----------------------
// Condition set checking
// ----------------------
static UINT8 M_CheckCondition(condition_t *cn)
UINT8 M_CheckCondition(condition_t *cn)
{
switch (cn->type)
{
@ -295,13 +295,14 @@ void M_CheckUnlockConditions(void)
}
}
UINT8 M_UpdateUnlockablesAndExtraEmblems(void)
UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force)
{
INT32 i;
char cechoText[992] = "";
UINT8 cechoLines = 0;
if (modifiedgame && !savemoddata)
if (modifiedgame && !savemoddata
&& !force) // SRB2Kart: for enabling unlocks online in modified servers
return false;
M_CheckUnlockConditions();

View file

@ -151,7 +151,8 @@ void M_ClearSecrets(void);
// Updating conditions and unlockables
void M_CheckUnlockConditions(void);
UINT8 M_UpdateUnlockablesAndExtraEmblems(void);
UINT8 M_CheckCondition(condition_t *cn);
UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force);
void M_SilentUpdateUnlockablesAndEmblems(void);
UINT8 M_CheckLevelEmblems(void);

View file

@ -217,6 +217,7 @@ static void M_LevelSelectWarp(INT32 choice);
static void M_Credits(INT32 choice);
static void M_PandorasBox(INT32 choice);
static void M_EmblemHints(INT32 choice);
static char *M_GetConditionString(condition_t cond);
menu_t SR_MainDef, SR_UnlockChecklistDef;
// Misc. Main Menu
@ -4263,10 +4264,56 @@ static void M_LevelSelectWarp(INT32 choice)
UINT8 skyRoomMenuTranslations[MAXUNLOCKABLES];
#define NUMCHECKLIST 8
static char *M_GetConditionString(condition_t cond)
{
switch(cond.type)
{
case UC_PLAYTIME:
return va("Play for %i:%02i:%02i",
G_TicsToHours(cond.requirement),
G_TicsToMinutes(cond.requirement, false),
G_TicsToSeconds(cond.requirement));
case UC_MATCHESPLAYED:
return va("Play %d matches", cond.requirement);
case UC_GAMECLEAR:
if (cond.requirement > 1)
return va("Beat game %d times", cond.requirement);
else
return va("Beat the game");
case UC_ALLEMERALDS:
if (cond.requirement > 1)
return va("Beat game w/ all emeralds %d times", cond.requirement);
else
return va("Beat game w/ all emeralds");
case UC_OVERALLTIME:
return va("Get overall time of %i:%02i:%02i",
G_TicsToHours(cond.requirement),
G_TicsToMinutes(cond.requirement, false),
G_TicsToSeconds(cond.requirement));
case UC_MAPVISITED:
return va("Visit %s", G_BuildMapTitle(cond.requirement-1));
case UC_MAPBEATEN:
return va("Beat %s", G_BuildMapTitle(cond.requirement-1));
case UC_MAPALLEMERALDS:
return va("Beat %s w/ all emeralds", G_BuildMapTitle(cond.requirement-1));
case UC_MAPTIME:
return va("Beat %s in %i:%02i.%02i", G_BuildMapTitle(cond.extrainfo1-1),
G_TicsToMinutes(cond.requirement, true),
G_TicsToSeconds(cond.requirement),
G_TicsToCentiseconds(cond.requirement));
case UC_TOTALEMBLEMS:
return va("Get %d emblems", cond.requirement);
case UC_EXTRAEMBLEM:
return va("Get \"%s\" emblem", extraemblems[cond.requirement-1].name);
default:
return "";
}
}
#define NUMCHECKLIST 23
static void M_DrawChecklist(void)
{
INT32 i, j = 0;
INT32 i, line = 0, c, lastid;
for (i = 0; i < MAXUNLOCKABLES; i++)
{
@ -4274,18 +4321,47 @@ static void M_DrawChecklist(void)
|| !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS)
continue;
V_DrawString(8, 8+(24*j), V_RETURN8, unlockables[i].name);
V_DrawString(160, 8+(24*j), V_RETURN8, V_WordWrap(160, 292, 0, unlockables[i].objective));
++line;
V_DrawString(8, (line*8), V_RETURN8|(unlockables[i].unlocked ? V_GREENMAP : V_REDMAP), unlockables[i].name);
if (unlockables[i].unlocked)
V_DrawString(308, 8+(24*j), V_YELLOWMAP, "Y");
else
V_DrawString(308, 8+(24*j), V_YELLOWMAP, "N");
if (conditionSets[unlockables[i].conditionset - 1].numconditions)
{
c = 0;
lastid = -1;
if (++j >= NUMCHECKLIST)
for (c = 0; c < conditionSets[unlockables[i].conditionset - 1].numconditions; c++)
{
condition_t cond = conditionSets[unlockables[i].conditionset - 1].condition[c];
UINT8 achieved = M_CheckCondition(&cond);
char *str = M_GetConditionString(cond);
if (!str)
continue;
++line;
if (cond.id != lastid)
{
V_DrawString(16, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), "*");
V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), str);
}
else
{
V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), "&");
V_DrawString(48, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), str);
}
lastid = cond.id;
}
}
++line;
if (line >= NUMCHECKLIST)
break;
}
}
#undef NUMCHECKLIST
#define NUMHINTS 5
static void M_EmblemHints(INT32 choice)

View file

@ -3634,8 +3634,6 @@ void A_AttractChase(mobj_t *actor)
|| !P_CheckSight(actor, actor->tracer)) // You have to be able to SEE it...sorta
{
// Lost attracted rings don't through walls anymore.
if (actor->tracer && actor->tracer->player)
actor->tracer->player->kartstuff[k_comebackmode] = 0;
actor->flags &= ~MF_NOCLIP;
P_SetTarget(&actor->tracer, NULL);
return;
@ -8147,7 +8145,8 @@ void A_ItemPop(mobj_t *actor)
if (actor->info->deathsound)
S_StartSound(remains, actor->info->deathsound);
actor->target->player->kartstuff[k_itemroulette] = 1;
if (!(G_BattleGametype() && actor->target->player->kartstuff[k_balloon] <= 0))
actor->target->player->kartstuff[k_itemroulette] = 1;
remains->flags2 &= ~MF2_AMBUSH;

View file

@ -1787,8 +1787,8 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
break;
}
// Ignore popped monitors, too.
if (node->m_thing->flags & MF_MONITOR || node->m_thing->type == MT_RANDOMITEM
&& node->m_thing->threshold == 68)
if ((node->m_thing->flags & MF_MONITOR || node->m_thing->type == MT_RANDOMITEM)
&& node->m_thing->threshold == 68)
continue;
// Okay, we found something valid.
if (!thing // take either the first thing

View file

@ -152,23 +152,20 @@ void P_ResetStarposts(void)
//
boolean P_CanPickupItem(player_t *player, boolean weapon)
{
if (player->bot && weapon)
return false;
/*if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) // No balloons in Match
return false;*/
//if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] <= flashingtics)
// return false;
if (weapon)
{
if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer]
|| player->kartstuff[k_growshrinktimer] > 1 || player->kartstuff[k_rocketsneakertimer]) // Item-specific timer going off
return false;
if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) // No balloons in Match
return false;
if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer]
|| player->kartstuff[k_growshrinktimer] > 1 || player->kartstuff[k_rocketsneakertimer]) // Item-specific timer going off
return false;
if (player->kartstuff[k_itemroulette]
|| player->kartstuff[k_itemamount]
|| player->kartstuff[k_itemheld]) // Item slot already taken up
return false;
if (player->kartstuff[k_itemroulette]
|| player->kartstuff[k_itemamount]
|| player->kartstuff[k_itemheld]) // Item slot already taken up
return false;
}
return true;
}
@ -407,34 +404,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
switch (special->type)
{
case MT_RANDOMITEM: // SRB2kart
if (!P_CanPickupItem(player, true))
return;
if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0)
{
if (player->kartstuff[k_comebackmode] == 0 && !player->kartstuff[k_comebacktimer])
{
if (special->tracer)
return;
P_SetTarget(&special->tracer, toucher);
if (player->kartstuff[k_comebackmode] == 1 || player->kartstuff[k_comebacktimer])
return;
if (player->kartstuff[k_comebackmode] == 0)
player->kartstuff[k_comebackmode] = 1;
}
return;
}
if (!P_CanPickupItem(player, false) && special->tracer != toucher)
return;
if (G_BattleGametype() && special->tracer && special->tracer->player)
{
special->tracer->player->kartstuff[k_comebackmode] = 0;
special->tracer->player->kartstuff[k_comebackpoints]++;
if (netgame && cv_hazardlog.value)
CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[special->tracer->player-players], player_names[player-players]);
if (special->tracer->player->kartstuff[k_comebackpoints] >= 3)
K_StealBalloon(special->tracer->player, player, true);
special->tracer->player->kartstuff[k_comebacktimer] = comebacktime;
}
special->momx = special->momy = special->momz = 0;
@ -622,9 +600,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
emblemlocations[special->health-1].collected = true;
M_UpdateUnlockablesAndExtraEmblems();
M_UpdateUnlockablesAndExtraEmblems(false);
G_SaveGameData();
G_SaveGameData(false);
break;
}
@ -2104,7 +2082,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
P_SetTarget(&target->target, source);
source->player->numboxes++;
if ((cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer)))
if (cv_itemrespawn.value && (netgame || multiplayer))
{
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
}

View file

@ -211,7 +211,6 @@ extern size_t iquehead, iquetail;
extern consvar_t cv_gravity, cv_viewheight;
void P_RespawnSpecials(void);
void P_RespawnBattleSpecials(void);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);

View file

@ -1634,33 +1634,60 @@ static boolean PIT_CheckThing(mobj_t *thing)
|| thing->player->kartstuff[k_hyudorotimer] || thing->player->kartstuff[k_spinouttimer]
|| thing->player->kartstuff[k_invincibilitytimer] || thing->player->kartstuff[k_justbumped]
|| (G_BattleGametype() && (thing->player->kartstuff[k_balloon] <= 0
&& (thing->player->kartstuff[k_comebacktimer] || thing->player->kartstuff[k_comebackmode] == 1)))
&& (thing->player->kartstuff[k_comebacktimer])))
|| tmthing->player->kartstuff[k_growshrinktimer] || tmthing->player->kartstuff[k_squishedtimer]
|| tmthing->player->kartstuff[k_hyudorotimer] || tmthing->player->kartstuff[k_spinouttimer]
|| tmthing->player->kartstuff[k_invincibilitytimer] || tmthing->player->kartstuff[k_justbumped]
|| (G_BattleGametype() && (tmthing->player->kartstuff[k_balloon] <= 0
&& (tmthing->player->kartstuff[k_comebacktimer] || tmthing->player->kartstuff[k_comebackmode] == 1))))
&& (tmthing->player->kartstuff[k_comebacktimer]))))
{
return true;
}
if (G_BattleGametype())
{
if ((thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebackmode] == 0)
|| (tmthing->player->kartstuff[k_balloon] <= 0 && tmthing->player->kartstuff[k_comebackmode] == 0))
if (thing->player->kartstuff[k_balloon] <= 0 || tmthing->player->kartstuff[k_balloon] <= 0)
{
if (tmthing->player->kartstuff[k_balloon] > 0)
if (thing->player->kartstuff[k_comebackmode] == 0
&& tmthing->player->kartstuff[k_balloon] > 0)
{
K_ExplodePlayer(tmthing->player, thing);
thing->player->kartstuff[k_comebacktimer] = comebacktime;
return true;
}
else if (thing->player->kartstuff[k_balloon] > 0)
else if (tmthing->player->kartstuff[k_comebackmode] == 0
&& thing->player->kartstuff[k_balloon] > 0)
{
K_ExplodePlayer(thing->player, tmthing);
tmthing->player->kartstuff[k_comebacktimer] = comebacktime;
return true;
}
else if (thing->player->kartstuff[k_comebackmode] == 1
&& (tmthing->player->kartstuff[k_balloon] > 0 && P_CanPickupItem(tmthing->player, true)))
{
thing->player->kartstuff[k_comebackmode] = 0;
thing->player->kartstuff[k_comebackpoints]++;
if (netgame && cv_hazardlog.value)
CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[thing->player-players], player_names[tmthing->player-players]);
tmthing->player->kartstuff[k_itemroulette] = 1;
if (thing->player->kartstuff[k_comebackpoints] >= 3)
K_StealBalloon(thing->player, tmthing->player, true);
thing->player->kartstuff[k_comebacktimer] = comebacktime;
return true;
}
else if (tmthing->player->kartstuff[k_comebackmode] == 1
&& (thing->player->kartstuff[k_balloon] > 0 && P_CanPickupItem(thing->player, true)))
{
tmthing->player->kartstuff[k_comebackmode] = 0;
tmthing->player->kartstuff[k_comebackpoints]++;
if (netgame && cv_hazardlog.value)
CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[tmthing->player-players], player_names[thing->player-players]);
thing->player->kartstuff[k_itemroulette] = 1;
if (tmthing->player->kartstuff[k_comebackpoints] >= 3)
K_StealBalloon(tmthing->player, thing->player, true);
tmthing->player->kartstuff[k_comebacktimer] = comebacktime;
return true;
}
}
}

View file

@ -5969,13 +5969,6 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
if (!dest || dest->health <= 0 || !dest->player || !source->tracer)
return;
if (dest->player && dest->player->kartstuff[k_comebackmode] == 1)
{
P_TeleportMove(source, dest->x+dest->momx, dest->y+dest->momy, dest->z+dest->momz);
source->angle = dest->angle;
return;
}
// change angle
source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
@ -8329,6 +8322,9 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
P_RemoveMobj(mobj); // make sure they disappear
return;
case MT_RANDOMITEM:
if (G_BattleGametype())
break;
// Respawn from mapthing if you have one!
if (mobj->spawnpoint)
{
@ -9416,10 +9412,39 @@ void P_RespawnSpecials(void)
mobj_t *mo = NULL;
mapthing_t *mthing = NULL;
if (G_BattleGametype()) // Battle Mode vers
if (G_BattleGametype() && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way
{
P_RespawnBattleSpecials();
return;
thinker_t *th;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
mobj_t *box;
mobj_t *newmobj;
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // not a mobj
continue;
box = (mobj_t *)th;
if (box->type != MT_RANDOMITEM || box->threshold != 68 || box->fuse) // only popped items
continue;
// Respawn from mapthing if you have one!
if (box->spawnpoint)
{
P_SpawnMapThing(box->spawnpoint);
newmobj = box->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing
}
else
newmobj = P_SpawnMobj(box->x, box->y, box->z, box->type);
// Transfer flags2 (strongbox, objectflip)
newmobj->flags2 = box->flags2;
P_RemoveMobj(box); // make sure they disappear
continue;
}
numgotboxes = 0;
}
// only respawn items when cv_itemrespawn is on
@ -9513,97 +9538,6 @@ void P_RespawnSpecials(void)
iquetail = (iquetail+1)&(ITEMQUESIZE-1);
}
//
// P_RespawnBattleSpecials
//
void P_RespawnBattleSpecials(void)
{
fixed_t x, y, z;
subsector_t *ss;
mobj_t *mo = NULL;
mapthing_t *mthing = NULL;
// only respawn items when cv_itemrespawn is on
if (!cv_itemrespawn.value)
return;
// Didn't collect enough boxes
if (numgotboxes < (4*nummapboxes/5))
return;
// wait a teeeensy bit after collecting everything
if (leveltime - itemrespawntime[iquehead-1] < (tic_t)cv_itemrespawntime.value*(5*TICRATE))
return;
while (iquehead != iquetail) // respawn EVERYTHING in que!
{
mthing = itemrespawnque[iquetail];
#ifdef PARANOIA
if (!mthing)
I_Error("itemrespawnque[iquetail] is NULL!");
#endif
if (mthing)
{
mobjtype_t i;
x = mthing->x << FRACBITS;
y = mthing->y << FRACBITS;
ss = R_PointInSubsector(x, y);
// find which type to spawn
for (i = 0; i < NUMMOBJTYPES; i++)
if (mthing->type == mobjinfo[i].doomednum)
break;
//CTF rings should continue to respawn as normal rings outside of CTF.
if (gametype != GT_CTF)
{
if (i == MT_REDTEAMRING || i == MT_BLUETEAMRING)
i = MT_RING;
}
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
#endif
ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
z -= 24*FRACUNIT;
z -= mobjinfo[i].height; // Don't forget the height!
}
else
{
z = (
#ifdef ESLOPE
ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
#endif
ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
z += 24*FRACUNIT;
}
mo = P_SpawnMobj(x, y, z, i);
mo->spawnpoint = mthing;
mo->angle = ANGLE_45 * (mthing->angle/45);
if (mthing->options & MTF_OBJECTFLIP)
{
mo->eflags |= MFE_VERTICALFLIP;
mo->flags2 |= MF2_OBJECTFLIP;
}
}
// pull it from the que
iquetail = (iquetail+1)&(ITEMQUESIZE-1);
}
numgotboxes = 0;
}
//
// P_SpawnPlayer
// Called when a player is spawned on the level.

View file

@ -991,7 +991,7 @@ static void P_LoadThings(void)
|| mt->type == 1702) // MT_AXISTRANSFERLINE
continue; // These were already spawned
if (mt->type == MT_RANDOMITEM) // MT_RANDOMITEM
if (mt->type == mobjinfo[MT_RANDOMITEM].doomednum)
nummapboxes++;
mt->mobj = NULL;

View file

@ -3015,10 +3015,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
unlocktriggers |= 1 << trigid;
// Unlocked something?
if (M_UpdateUnlockablesAndExtraEmblems())
if (M_UpdateUnlockablesAndExtraEmblems(false))
{
S_StartSound(NULL, sfx_ncitem);
G_SaveGameData(); // only save if unlocked something
G_SaveGameData(false); // only save if unlocked something
}
}
}
@ -3966,7 +3966,7 @@ DoneSection2:
player->kartstuff[k_floorboost] = 3;
else
player->kartstuff[k_floorboost] = 2;
K_DoSneaker(player, false, false);
K_DoSneaker(player, false);
}
break;

View file

@ -1650,7 +1650,7 @@ void P_DoPlayerExit(player_t *player)
|| (splitscreen && player == &players[secondarydisplayplayer])
|| (splitscreen > 1 && player == &players[thirddisplayplayer])
|| (splitscreen > 2 && player == &players[fourthdisplayplayer]))
&& (!player->spectator && ((!modifiedgame || savemoddata) && !demoplayback)))
&& (!player->spectator && !demoplayback))
legitimateexit = true;
if (G_RaceGametype()) // If in Race Mode, allow
@ -9286,6 +9286,13 @@ void P_PlayerThink(player_t *player)
player->pflags |= PF_TIMEOVER;
if ((player == &players[consoleplayer]
|| (splitscreen && player == &players[secondarydisplayplayer])
|| (splitscreen > 1 && player == &players[thirddisplayplayer])
|| (splitscreen > 2 && player == &players[fourthdisplayplayer]))
&& !demoplayback)
legitimateexit = true; // SRB2kart: losing a race is still seeing it through to the end :p
if (player->pflags & PF_NIGHTSMODE)
{
P_DeNightserizePlayer(player);

View file

@ -585,6 +585,8 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
}
dontplay:
if (splitscreen > 1 && listenmobj3) // Copy the sound for the third player
{
// Check to see if it is audible, and if not, modify the params
@ -594,7 +596,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx);
if (!rc)
goto dontplay; // Maybe the other player can hear it...
goto dontplay3; // Maybe the other player can hear it...
if (origin->x == listener3.x && origin->y == listener3.y)
sep = NORM_SEP;
@ -603,7 +605,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay;
goto dontplay3;
else
sep = NORM_SEP;
@ -639,6 +641,8 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
}
dontplay3:
if (splitscreen > 2 && listenmobj4) // Copy the sound for the split player
{
// Check to see if it is audible, and if not, modify the params
@ -648,7 +652,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
rc = S_AdjustSoundParams(listenmobj4, origin, &volume, &sep, &pitch, sfx);
if (!rc)
goto dontplay; // Maybe the other player can hear it...
goto dontplay4; // Maybe the other player can hear it...
if (origin->x == listener4.x && origin->y == listener4.y)
sep = NORM_SEP;
@ -657,7 +661,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay;
goto dontplay4;
else
sep = NORM_SEP;
@ -693,7 +697,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
}
dontplay:
dontplay4:
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj)
@ -1015,83 +1019,69 @@ void S_UpdateSounds(void)
|| (splitscreen > 2 && c->origin != players[fourthdisplayplayer].mo)))
{
// Whomever is closer gets the sound, but only in splitscreen.
if (listenmobj && listenmobj2 && splitscreen)
if (splitscreen)
{
const mobj_t *soundmobj = c->origin;
fixed_t recdist = -1;
INT32 i, p = -1;
fixed_t dist1, dist2;
dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
dist2 = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y);
for (i = 0; i < 4; i++)
{
fixed_t thisdist = -1;
if (dist1 <= dist2)
{
// Player 1 gets the sound
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else
{
// Player 2 gets the sound
audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
if (i > splitscreen)
break;
if (i == 0 && listenmobj)
thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
else if (i == 1 && listenmobj2)
thisdist = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y);
else if (i == 2 && listenmobj3)
thisdist = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y);
else if (i == 3 && listenmobj4)
thisdist = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y);
else
continue;
if (recdist == -1 || (thisdist != -1 && thisdist < recdist))
{
recdist = thisdist;
p = i;
}
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
else
S_StopChannel(cnum);
}
else if (listenmobj && listenmobj3 && splitscreen > 1) // TODO: make 3/4P compare their distances with all players, not just the first player and themselves V:
{
const mobj_t *soundmobj = c->origin;
fixed_t dist1, dist2;
dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
dist2 = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y);
if (dist1 <= dist2)
if (p != -1)
{
// Player 1 gets the sound
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
if (p == 1)
{
// Player 2 gets the sound
audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else if (p == 2)
{
// Player 3 gets the sound
audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else
{
// Player 3 gets the sound
audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
}
else if (p == 3)
{
// Player 4 gets the sound
audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else
{
// Player 1 gets the sound
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
else
S_StopChannel(cnum);
}
else if (listenmobj && listenmobj4 && splitscreen > 2)
{
const mobj_t *soundmobj = c->origin;
fixed_t dist1, dist2;
dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
dist2 = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y);
if (dist1 <= dist2)
{
// Player 1 gets the sound
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
else
S_StopChannel(cnum);
}
else
{
// Player 4 gets the sound
audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
else
S_StopChannel(cnum);
}
else if (listenmobj && !splitscreen)
{

View file

@ -2770,7 +2770,7 @@ void I_Quit(void)
#ifndef NONET
D_SaveBan(); // save the ban list
#endif
G_SaveGameData(); // Tails 12-08-2002
G_SaveGameData(false); // Tails 12-08-2002
//added:16-02-98: when recording a demo, should exit using 'q' key,
// but sometimes we forget and use 'F10'.. so save here too.
@ -2853,7 +2853,7 @@ void I_Error(const char *error, ...)
if (errorcount == 9)
{
M_SaveConfig(NULL);
G_SaveGameData();
G_SaveGameData(false);
}
if (errorcount > 20)
{
@ -2887,7 +2887,7 @@ void I_Error(const char *error, ...)
#ifndef NONET
D_SaveBan(); // save the ban list
#endif
G_SaveGameData(); // Tails 12-08-2002
G_SaveGameData(false); // Tails 12-08-2002
// Shutdown. Here might be other errors.
if (demorecording)

View file

@ -781,10 +781,10 @@ void Y_Ticker(void)
// Update when done with tally
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback)
{
if (M_UpdateUnlockablesAndExtraEmblems())
if (M_UpdateUnlockablesAndExtraEmblems(false))
S_StartSound(NULL, sfx_ncitem);
G_SaveGameData();
G_SaveGameData(false);
}
}
else if (!(intertic & 1))
@ -848,10 +848,10 @@ void Y_Ticker(void)
// Update when done with tally
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback)
{
if (M_UpdateUnlockablesAndExtraEmblems())
if (M_UpdateUnlockablesAndExtraEmblems(false))
S_StartSound(NULL, sfx_ncitem);
G_SaveGameData();
G_SaveGameData(false);
}
}
else if (!(intertic & 1))