mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Merge remote-tracking branch 'origin/master' into f_wipes
This commit is contained in:
commit
6be45ec241
17 changed files with 220 additions and 169 deletions
|
@ -345,6 +345,40 @@ size_t COM_CheckParm(const char *check)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** \brief COM_CheckParm, but checks only the start of each argument.
|
||||
* E.g. checking for "-no" would match "-noerror" too.
|
||||
*/
|
||||
size_t COM_CheckPartialParm(const char *check)
|
||||
{
|
||||
int len;
|
||||
size_t i;
|
||||
|
||||
len = strlen(check);
|
||||
|
||||
for (i = 1; i < com_argc; i++)
|
||||
{
|
||||
if (strncasecmp(check, com_argv[i], len) == 0)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Find the first argument that starts with a hyphen (-).
|
||||
* \return The index of the argument, or 0
|
||||
* if there are no such arguments.
|
||||
*/
|
||||
size_t COM_FirstOption(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i < com_argc; i++)
|
||||
{
|
||||
if (com_argv[i][0] == '-')/* options start with a hyphen */
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Parses a string into command-line tokens.
|
||||
*
|
||||
* \param ptext A null-terminated string. Does not need to be
|
||||
|
|
|
@ -29,6 +29,8 @@ size_t COM_Argc(void);
|
|||
const char *COM_Argv(size_t arg); // if argv > argc, returns empty string
|
||||
char *COM_Args(void);
|
||||
size_t COM_CheckParm(const char *check); // like M_CheckParm :)
|
||||
size_t COM_CheckPartialParm(const char *check);
|
||||
size_t COM_FirstOption(void);
|
||||
|
||||
// match existing command or NULL
|
||||
const char *COM_CompleteCommand(const char *partial, INT32 skips);
|
||||
|
|
170
src/d_netcmd.c
170
src/d_netcmd.c
|
@ -1736,56 +1736,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
}
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
MAP_COMMAND_FORCE_OPTION,
|
||||
MAP_COMMAND_GAMETYPE_OPTION,
|
||||
MAP_COMMAND_NORESETPLAYERS_OPTION,
|
||||
|
||||
NUM_MAP_COMMAND_OPTIONS
|
||||
};
|
||||
|
||||
static size_t CheckOptions(
|
||||
int num_options,
|
||||
size_t *first_argumentp,
|
||||
size_t *user_options,
|
||||
const char ***option_names,
|
||||
int *option_num_arguments
|
||||
)
|
||||
{
|
||||
int arguments_used;
|
||||
size_t first_argument;
|
||||
|
||||
int i;
|
||||
const char **pp;
|
||||
const char *name;
|
||||
size_t n;
|
||||
|
||||
arguments_used = 0;
|
||||
first_argument = COM_Argc();
|
||||
|
||||
for (i = 0; i < num_options; ++i)
|
||||
{
|
||||
pp = option_names[i];
|
||||
name = *pp;
|
||||
do
|
||||
{
|
||||
if (( n = COM_CheckParm(name) ))
|
||||
{
|
||||
user_options[i] = n;
|
||||
arguments_used += 1 + option_num_arguments[i];
|
||||
if (n < first_argument)
|
||||
first_argument = n;
|
||||
}
|
||||
}
|
||||
while (( name = *++pp )) ;
|
||||
}
|
||||
|
||||
(*first_argumentp) = first_argument;
|
||||
|
||||
return arguments_used;
|
||||
}
|
||||
|
||||
static char *
|
||||
ConcatCommandArgv (int start, int end)
|
||||
{
|
||||
|
@ -1829,43 +1779,10 @@ ConcatCommandArgv (int start, int end)
|
|||
//
|
||||
static void Command_Map_f(void)
|
||||
{
|
||||
const char *force_option_names[] =
|
||||
{
|
||||
"-force",
|
||||
"-f",
|
||||
NULL
|
||||
};
|
||||
const char *gametype_option_names[] =
|
||||
{
|
||||
"-gametype",
|
||||
"-g",
|
||||
"-gt",
|
||||
NULL
|
||||
};
|
||||
const char *noresetplayers_option_names[] =
|
||||
{
|
||||
"-noresetplayers",
|
||||
NULL
|
||||
};
|
||||
const char **option_names[] =
|
||||
{
|
||||
force_option_names,
|
||||
gametype_option_names,
|
||||
noresetplayers_option_names,
|
||||
};
|
||||
int option_num_arguments[] =
|
||||
{
|
||||
0,/* -force */
|
||||
1,/* -gametype */
|
||||
0,/* -noresetplayers */
|
||||
};
|
||||
|
||||
size_t acceptableargc;/* (this includes the command name itself!) */
|
||||
size_t first_argument;
|
||||
|
||||
size_t user_options [NUM_MAP_COMMAND_OPTIONS] = {0};
|
||||
|
||||
const char *arg_gametype;
|
||||
size_t first_option;
|
||||
size_t option_force;
|
||||
size_t option_gametype;
|
||||
const char *gametypename;
|
||||
boolean newresetplayers;
|
||||
|
||||
boolean mustmodifygame;
|
||||
|
@ -1888,18 +1805,15 @@ static void Command_Map_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* map name + options */
|
||||
acceptableargc = 2 + CheckOptions(NUM_MAP_COMMAND_OPTIONS,
|
||||
&first_argument,
|
||||
user_options, option_names, option_num_arguments);
|
||||
|
||||
newresetplayers = !user_options[MAP_COMMAND_NORESETPLAYERS_OPTION];
|
||||
option_force = COM_CheckPartialParm("-f");
|
||||
option_gametype = COM_CheckPartialParm("-g");
|
||||
newresetplayers = ! COM_CheckParm("-noresetplayers");
|
||||
|
||||
mustmodifygame =
|
||||
!( netgame || multiplayer ) &&
|
||||
(!modifiedgame || savemoddata );
|
||||
|
||||
if (mustmodifygame && !user_options[MAP_COMMAND_FORCE_OPTION])
|
||||
if (mustmodifygame && !option_force)
|
||||
{
|
||||
/* May want to be more descriptive? */
|
||||
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
|
||||
|
@ -1912,26 +1826,37 @@ static void Command_Map_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (user_options[MAP_COMMAND_GAMETYPE_OPTION] && !multiplayer)
|
||||
if (option_gametype)
|
||||
{
|
||||
CONS_Printf(M_GetText("You can't switch gametypes in single player!\n"));
|
||||
return;
|
||||
if (!multiplayer)
|
||||
{
|
||||
CONS_Printf(M_GetText(
|
||||
"You can't switch gametypes in single player!\n"));
|
||||
return;
|
||||
}
|
||||
else if (COM_Argc() < option_gametype + 2)/* no argument after? */
|
||||
{
|
||||
CONS_Alert(CONS_ERROR,
|
||||
"No gametype name follows parameter '%s'.\n",
|
||||
COM_Argv(option_gametype));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the first argument is an option, you fucked up. */
|
||||
if (COM_Argc() < acceptableargc || first_argument == 1)
|
||||
if (!( first_option = COM_FirstOption() ))
|
||||
first_option = COM_Argc();
|
||||
|
||||
if (first_option < 2)
|
||||
{
|
||||
/* I'm going over the fucking lines and I DON'T CAREEEEE */
|
||||
CONS_Printf("map <name / [MAP]code / number> [-gametype <type>] [-force]:\n");
|
||||
CONS_Printf(M_GetText(
|
||||
"Warp to a map, by its name, two character code, with optional \"MAP\" prefix, or by its number (though why would you).\n"
|
||||
"All parameters are case-insensitive.\n"
|
||||
"* \"-force\" may be shortened to \"-f\".\n"
|
||||
"* \"-gametype\" may be shortened to \"-g\" or \"-gt\".\n"));
|
||||
"All parameters are case-insensitive and may be abbreviated.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
mapname = ConcatCommandArgv(1, first_argument);
|
||||
mapname = ConcatCommandArgv(1, first_option);
|
||||
mapnamelen = strlen(mapname);
|
||||
|
||||
if (mapnamelen == 2)/* maybe two digit code */
|
||||
|
@ -1982,30 +1907,42 @@ static void Command_Map_f(void)
|
|||
realmapname = G_BuildMapTitle(newmapnum);
|
||||
}
|
||||
|
||||
if (mustmodifygame && user_options[MAP_COMMAND_FORCE_OPTION])
|
||||
if (mustmodifygame && option_force)
|
||||
{
|
||||
G_SetGameModified(false);
|
||||
}
|
||||
|
||||
// new gametype value
|
||||
// use current one by default
|
||||
if (user_options[MAP_COMMAND_GAMETYPE_OPTION])
|
||||
if (option_gametype)
|
||||
{
|
||||
arg_gametype = COM_Argv(user_options[MAP_COMMAND_GAMETYPE_OPTION] + 1);
|
||||
gametypename = COM_Argv(option_gametype + 1);
|
||||
|
||||
newgametype = G_GetGametypeByName(arg_gametype);
|
||||
newgametype = G_GetGametypeByName(gametypename);
|
||||
|
||||
if (newgametype == -1) // reached end of the list with no match
|
||||
{
|
||||
d = atoi(arg_gametype);
|
||||
// assume they gave us a gametype number, which is okay too
|
||||
if (d >= 0 && d < NUMGAMETYPES)
|
||||
newgametype = d;
|
||||
/* Did they give us a gametype number? That's okay too! */
|
||||
if (isdigit(gametypename[0]))
|
||||
{
|
||||
d = atoi(gametypename);
|
||||
if (d >= 0 && d < NUMGAMETYPES)
|
||||
newgametype = d;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR,
|
||||
"'%s' is not a gametype.\n",
|
||||
gametypename);
|
||||
Z_Free(realmapname);
|
||||
Z_Free(mapname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// don't use a gametype the map doesn't support
|
||||
if (cv_debug || user_options[MAP_COMMAND_FORCE_OPTION] || cv_skipmapcheck.value)
|
||||
if (cv_debug || option_force || cv_skipmapcheck.value)
|
||||
fromlevelselect = false; // The player wants us to trek on anyway. Do so.
|
||||
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
|
||||
else
|
||||
|
@ -2060,7 +1997,6 @@ static void Command_Map_f(void)
|
|||
|
||||
Z_Free(realmapname);
|
||||
}
|
||||
#undef CHECKPARM
|
||||
|
||||
/** Receives a map command and changes the map.
|
||||
*
|
||||
|
@ -3907,13 +3843,17 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
// There will always be a server, and this only needs to be done once.
|
||||
if (server && (multiplayer || netgame))
|
||||
{
|
||||
if (gametype == GT_COMPETITION || gametype == GT_COOP)
|
||||
if (gametype == GT_COMPETITION)
|
||||
CV_SetValue(&cv_itemrespawn, 0);
|
||||
else if (!cv_itemrespawn.changed)
|
||||
else if (!cv_itemrespawn.changed || lastgametype == GT_COMPETITION)
|
||||
CV_SetValue(&cv_itemrespawn, 1);
|
||||
|
||||
switch (gametype)
|
||||
{
|
||||
case GT_COOP:
|
||||
if (!cv_itemrespawntime.changed)
|
||||
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
|
||||
break;
|
||||
case GT_MATCH:
|
||||
case GT_TEAMMATCH:
|
||||
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
|
||||
|
|
|
@ -4866,6 +4866,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
// Snailer
|
||||
"S_SNAILER1",
|
||||
"S_SNAILER_FLICKY",
|
||||
|
||||
// Vulture
|
||||
"S_VULTURE_STND",
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
// Stage of animation:
|
||||
// 0 = text, 1 = art screen
|
||||
static INT32 finalecount;
|
||||
INT32 finalecount;
|
||||
INT32 titlescrollxspeed = 20;
|
||||
INT32 titlescrollyspeed = 0;
|
||||
UINT8 titlemapinaction = TITLEMAP_OFF;
|
||||
|
@ -2506,7 +2506,7 @@ static void F_LoadAlacroixGraphics(SINT8 newttscale)
|
|||
if (!ttloaded[newttscale])
|
||||
{
|
||||
for (j = 0; j < 22; j++)
|
||||
sprintf(&lumpnames[j][0], "T%.1hu%s", (UINT8)newttscale+1, names[j]);
|
||||
sprintf(&lumpnames[j][0], "T%.1hu%s", (UINT16)( (UINT8)newttscale+1 ), names[j]);
|
||||
|
||||
LOADTTGFX(ttembl[newttscale], lumpnames[0], TTMAX_ALACROIX)
|
||||
LOADTTGFX(ttribb[newttscale], lumpnames[1], TTMAX_ALACROIX)
|
||||
|
@ -2574,6 +2574,8 @@ void F_TitleScreenDrawer(void)
|
|||
{
|
||||
boolean hidepics;
|
||||
fixed_t sc = FRACUNIT / max(1, curttscale);
|
||||
INT32 whitefade = 0;
|
||||
UINT8 *whitecol[2] = {NULL, NULL};
|
||||
|
||||
if (modeattacking)
|
||||
return; // We likely came here from retrying. Don't do a damn thing.
|
||||
|
@ -2659,16 +2661,40 @@ void F_TitleScreenDrawer(void)
|
|||
//
|
||||
if (finalecount <= 29)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
// Flash at tic 30, timed to O__TITLE percussion. Hold the flash until tic 34.
|
||||
// After tic 34, fade the flash until tic 44.
|
||||
else
|
||||
{
|
||||
if (finalecount > 29 && finalecount < 35)
|
||||
V_DrawFadeScreen(0, (whitefade = 9));
|
||||
else if (finalecount > 34 && 44-finalecount > 0 && 44-finalecount < 10)
|
||||
V_DrawFadeScreen(0, 44-finalecount);
|
||||
if (39-finalecount > 0)
|
||||
{
|
||||
whitefade = (9 - (39-finalecount))<<V_ALPHASHIFT;
|
||||
whitecol[0] = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SUPERGOLD3, GTC_CACHE);
|
||||
whitecol[1] = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw emblem
|
||||
V_DrawSciencePatch(40<<FRACBITS, 20<<FRACBITS, 0, TTEMBL[0], sc);
|
||||
|
||||
if (whitecol[0])
|
||||
{
|
||||
V_DrawFixedPatch(40<<FRACBITS, 20<<FRACBITS, sc, whitefade, TTEMBL[0], whitecol[0]);
|
||||
V_DrawFixedPatch(40<<FRACBITS, 20<<FRACBITS, sc, V_TRANSLUCENT + ((whitefade/2) & V_ALPHAMASK), TTEMBL[0], whitecol[1]);
|
||||
}
|
||||
|
||||
// Animate SONIC ROBO BLAST 2 before the white flash at tic 30.
|
||||
if (finalecount <= 29)
|
||||
{
|
||||
// Ribbon unfurls, revealing SONIC text, from tic 0 to tic 24. SONIC text is pre-baked into this ribbon graphic.
|
||||
V_DrawSciencePatch(39<<FRACBITS, 88<<FRACBITS, 0, TTRIBB[min(max(0, finalecount), 24)], sc);
|
||||
|
||||
// Darken non-text things.
|
||||
V_DrawFadeScreen(0xFF00, 12);
|
||||
|
||||
// Animate SONIC text while the ribbon unfurls, from tic 0 to tic 28.
|
||||
if(finalecount >= 0)
|
||||
V_DrawSciencePatch(89<<FRACBITS, 92<<FRACBITS, 0, TTSONT[min(finalecount, 28)], sc);
|
||||
|
@ -2693,6 +2719,7 @@ void F_TitleScreenDrawer(void)
|
|||
case 8: case 7: fadeval = V_30TRANS; break;
|
||||
case 6: case 5: fadeval = V_20TRANS; break;
|
||||
case 4: case 3: fadeval = V_10TRANS; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
V_DrawSciencePatch(79<<FRACBITS, 132<<FRACBITS, fadeval, TTROBO[0], sc);
|
||||
|
@ -3113,9 +3140,15 @@ void F_TitleScreenDrawer(void)
|
|||
// After tic 34, starting when the flash fades,
|
||||
// draw the combined ribbon and SONIC ROBO BLAST 2 logo. Note the different Y value, because this
|
||||
// graphic is cropped differently from the unfurling ribbon.
|
||||
if (finalecount > 34)
|
||||
if (finalecount > 29)
|
||||
V_DrawSciencePatch(39<<FRACBITS, 93<<FRACBITS, 0, TTRBTX[0], sc);
|
||||
|
||||
if (whitecol[0])
|
||||
{
|
||||
V_DrawFixedPatch(39<<FRACBITS, 93<<FRACBITS, sc, whitefade, TTRBTX[0], whitecol[0]);
|
||||
V_DrawFixedPatch(39<<FRACBITS, 93<<FRACBITS, sc, V_TRANSLUCENT + ((whitefade/2) & V_ALPHAMASK), TTRBTX[0], whitecol[1]);
|
||||
}
|
||||
|
||||
//
|
||||
// FRONT LAYER CHARACTERS
|
||||
//
|
||||
|
@ -3254,13 +3287,6 @@ void F_TitleScreenDrawer(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Flash at tic 30, timed to O__TITLE percussion. Hold the flash until tic 34.
|
||||
// After tic 34, fade the flash until tic 44.
|
||||
if (finalecount > 29 && finalecount < 35)
|
||||
V_DrawFadeScreen(0, 9);
|
||||
else if (finalecount > 34 && 44-finalecount > 0 && 44-finalecount < 10)
|
||||
V_DrawFadeScreen(0, 44-finalecount);
|
||||
|
||||
#undef CHARSTART
|
||||
#undef SONICSTART
|
||||
#undef SONICIDLE
|
||||
|
|
|
@ -74,6 +74,7 @@ void F_StartContinue(void);
|
|||
void F_ContinueTicker(void);
|
||||
void F_ContinueDrawer(void);
|
||||
|
||||
extern INT32 finalecount;
|
||||
extern INT32 titlescrollxspeed;
|
||||
extern INT32 titlescrollyspeed;
|
||||
|
||||
|
|
|
@ -1717,7 +1717,7 @@ boolean G_Responder(event_t *ev)
|
|||
if (gameaction == ga_nothing && !singledemo &&
|
||||
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
|
||||
{
|
||||
if (ev->type == ev_keydown && ev->data1 != 301)
|
||||
if (ev->type == ev_keydown && ev->data1 != 301 && !(gamestate == GS_TITLESCREEN && finalecount < TICRATE))
|
||||
{
|
||||
M_StartControlPanel();
|
||||
return true;
|
||||
|
|
31
src/info.c
31
src/info.c
|
@ -986,6 +986,7 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// Snailer
|
||||
{SPR_SNLR, 0, 1, {A_SnailerThink}, 0, 0, S_SNAILER1}, // S_SNAILER1
|
||||
{SPR_BOM1, 0, 0, {A_FlickySpawn}, 1<<17, 0, S_XPLD1}, // S_SNAILER_FLICKY
|
||||
|
||||
// Vulture
|
||||
{SPR_VLTR, 4, 35, {A_Look}, 1, 0, S_VULTURE_STND}, // S_VULTURE_STND
|
||||
|
@ -1836,18 +1837,18 @@ state_t states[NUMSTATES] =
|
|||
{SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4
|
||||
|
||||
// Level End Sign
|
||||
{SPR_SIGN, 0, -1, {A_SignPlayer}, -3, 0, S_NULL}, // S_SIGN
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN2}, // S_SIGNSPIN1
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4}, // S_SIGNSPIN3
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN5}, // S_SIGNSPIN4
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1}, // S_SIGNSPIN6
|
||||
{SPR_SIGN, 0, 1, {A_SignPlayer}, -1, 0, S_SIGNSLOW}, // S_SIGNPLAYER
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSLOW}, // S_SIGNSLOW
|
||||
{SPR_SIGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNSTOP
|
||||
{SPR_SIGN, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNBOARD
|
||||
{SPR_SIGN, FF_PAPERSPRITE|1, -1, {NULL}, 0, 29, S_NULL}, // S_EGGMANSIGN
|
||||
{SPR_SIGN, 0, -1, {A_SignPlayer}, -3, 0, S_NULL}, // S_SIGN
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN2}, // S_SIGNSPIN1
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4}, // S_SIGNSPIN3
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN5}, // S_SIGNSPIN4
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1}, // S_SIGNSPIN6
|
||||
{SPR_SIGN, 0, 1, {A_SignPlayer}, -1, 0, S_SIGNSLOW}, // S_SIGNPLAYER
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSLOW}, // S_SIGNSLOW
|
||||
{SPR_SIGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNSTOP
|
||||
{SPR_SIGN, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNBOARD
|
||||
{SPR_SIGN, FF_PAPERSPRITE|1, -1, {NULL}, 0, 29, S_NULL}, // S_EGGMANSIGN
|
||||
|
||||
// Spike Ball
|
||||
{SPR_SPIK, 0, 1, {NULL}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1
|
||||
|
@ -4575,7 +4576,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_XPLD_FLICKY, // deathstate
|
||||
S_SNAILER_FLICKY, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_pop, // deathsound
|
||||
FRACUNIT, // speed
|
||||
|
@ -7725,12 +7726,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // attacksound
|
||||
S_SIGNPLAYER, // painstate
|
||||
MT_SPARK, // painchance
|
||||
sfx_None, // painsound
|
||||
sfx_s3kb8, // painsound
|
||||
S_EGGMANSIGN, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SIGNSTOP, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
sfx_s3k64, // deathsound
|
||||
8, // speed
|
||||
36*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
|
|
|
@ -1180,6 +1180,7 @@ typedef enum state
|
|||
|
||||
// Snailer
|
||||
S_SNAILER1,
|
||||
S_SNAILER_FLICKY,
|
||||
|
||||
// Vulture
|
||||
S_VULTURE_STND,
|
||||
|
|
|
@ -2985,6 +2985,9 @@ boolean M_Responder(event_t *ev)
|
|||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND)
|
||||
return false;
|
||||
|
||||
if (gamestate == GS_TITLESCREEN && finalecount < TICRATE)
|
||||
return false;
|
||||
|
||||
if (noFurtherInput)
|
||||
{
|
||||
// Ignore input after enter/escape/other buttons
|
||||
|
|
|
@ -5042,7 +5042,6 @@ void A_UnsetSolidSteam(mobj_t *actor)
|
|||
void A_SignSpin(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
INT16 i;
|
||||
angle_t rotateangle = FixedAngle(locvar1 << FRACBITS);
|
||||
|
||||
|
@ -5053,6 +5052,11 @@ void A_SignSpin(mobj_t *actor)
|
|||
|
||||
if (P_IsObjectOnGround(actor) && P_MobjFlip(actor) * actor->momz <= 0)
|
||||
{
|
||||
if (actor->flags2 & MF2_BOSSFLEE)
|
||||
{
|
||||
S_StartSound(actor, actor->info->deathsound);
|
||||
actor->flags2 &= ~MF2_BOSSFLEE;
|
||||
}
|
||||
if (actor->spawnpoint)
|
||||
{
|
||||
angle_t mapangle = FixedAngle(actor->spawnpoint->angle << FRACBITS);
|
||||
|
@ -5069,14 +5073,20 @@ void A_SignSpin(mobj_t *actor)
|
|||
}
|
||||
else // no mapthing? just finish in your current angle
|
||||
{
|
||||
P_SetMobjState(actor, locvar2);
|
||||
P_SetMobjState(actor, actor->info->deathstate);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(actor->flags2 & MF2_BOSSFLEE))
|
||||
{
|
||||
S_StartSound(actor, actor->info->painsound);
|
||||
actor->flags2 |= MF2_BOSSFLEE;
|
||||
}
|
||||
actor->movedir = rotateangle;
|
||||
}
|
||||
|
||||
actor->angle += actor->movedir;
|
||||
if (actor->tracer == NULL || P_MobjWasRemoved(actor->tracer)) return;
|
||||
for (i = -1; i < 2; i += 2)
|
||||
|
@ -5166,15 +5176,31 @@ void A_SignPlayer(mobj_t *actor)
|
|||
// I turned this function into a fucking mess. I'm so sorry. -Lach
|
||||
if (locvar1 == -2) // next skin
|
||||
{
|
||||
player_t *player = actor->target ? actor->target->player : NULL;
|
||||
UINT8 skinnum;
|
||||
#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0)
|
||||
if (ov->skin == NULL) // pick a random skin to start with!
|
||||
skin = &skins[P_RandomKey(numskins)];
|
||||
{
|
||||
UINT8 skincount = 0;
|
||||
for (skincount = 0; skincount < numskins; skincount++)
|
||||
if (!skincheck(skincount))
|
||||
skincount++;
|
||||
skinnum = P_RandomKey(skincount);
|
||||
for (skincount = 0; skincount < numskins; skincount++)
|
||||
{
|
||||
if (skincheck(skincount))
|
||||
skinnum++;
|
||||
if (skincount > skinnum)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // otherwise, advance 1 skin
|
||||
{
|
||||
UINT8 skinnum = (skin_t*)ov->skin-skins;
|
||||
player_t *player = actor->target ? actor->target->player : NULL;
|
||||
while ((skinnum = (skinnum + 1) % numskins) && (player ? !R_SkinUsable(player-players, skinnum) : skins[skinnum].availability > 0));
|
||||
skin = &skins[skinnum];
|
||||
skinnum = (skin_t*)ov->skin-skins;
|
||||
while ((skinnum = (skinnum + 1) % numskins) && skincheck(skinnum));
|
||||
}
|
||||
#undef skincheck
|
||||
skin = &skins[skinnum];
|
||||
}
|
||||
else // specific skin
|
||||
{
|
||||
|
@ -11671,9 +11697,10 @@ void A_SpawnFreshCopy(mobj_t *actor)
|
|||
}
|
||||
|
||||
// Internal Flicky spawning function.
|
||||
mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers)
|
||||
mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward)
|
||||
{
|
||||
mobj_t *flicky;
|
||||
fixed_t offsx = 0, offsy = 0;
|
||||
|
||||
if (!flickytype)
|
||||
{
|
||||
|
@ -11686,7 +11713,14 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
|
|||
}
|
||||
}
|
||||
|
||||
flicky = P_SpawnMobjFromMobj(actor, 0, 0, 0, flickytype);
|
||||
if (moveforward)
|
||||
{
|
||||
fixed_t scal = mobjinfo[flickytype].radius*((fixed_t)moveforward);
|
||||
offsx = P_ReturnThrustX(actor, actor->angle, scal);
|
||||
offsy = P_ReturnThrustY(actor, actor->angle, scal);
|
||||
}
|
||||
|
||||
flicky = P_SpawnMobjFromMobj(actor, offsx, offsy, 0, flickytype);
|
||||
flicky->angle = actor->angle;
|
||||
|
||||
if (flickytype == MT_SEED)
|
||||
|
@ -11712,24 +11746,30 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
|
|||
//
|
||||
// var1:
|
||||
// lower 16 bits: if 0, spawns random flicky based on level header. Else, spawns the designated thing type.
|
||||
// upper 16 bits: if 0, no sound is played. Else, A_Scream is called.
|
||||
// bit 17: if 0, no sound is played. Else, A_Scream is called.
|
||||
// bit 18: if 1, spawn flicky slightly forward from spawn position, to avoid being stuck in wall. doesn't stack with 19. (snailers)
|
||||
// bit 19: if 1, spawn flicky slightly backward from spawn position. doesn't stack with 18.
|
||||
// var2 = upwards thrust for spawned flicky. If zero, default value is provided.
|
||||
//
|
||||
void A_FlickySpawn(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar1 = var1 & 65535;
|
||||
INT32 locvar2 = var2;
|
||||
INT32 test = (var1 >> 16);
|
||||
SINT8 moveforward = 0;
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_FlickySpawn", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (locvar1 >> 16) {
|
||||
if (test & 1)
|
||||
A_Scream(actor); // A shortcut for the truly lazy.
|
||||
locvar1 &= 65535;
|
||||
}
|
||||
if (test & 2)
|
||||
moveforward = 1;
|
||||
else if (test & 4)
|
||||
moveforward = -1;
|
||||
|
||||
P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true);
|
||||
P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true, moveforward);
|
||||
}
|
||||
|
||||
// Internal Flicky color setting
|
||||
|
@ -11793,7 +11833,7 @@ void A_FlickyCenter(mobj_t *actor)
|
|||
|
||||
if (!actor->tracer)
|
||||
{
|
||||
mobj_t *flicky = P_InternalFlickySpawn(actor, locvar1, 1, false);
|
||||
mobj_t *flicky = P_InternalFlickySpawn(actor, locvar1, 1, false, 0);
|
||||
P_SetTarget(&flicky->target, actor);
|
||||
P_SetTarget(&actor->tracer, flicky);
|
||||
|
||||
|
|
|
@ -2404,7 +2404,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
{
|
||||
P_SetTarget(&target->target, source);
|
||||
source->player->numboxes++;
|
||||
if ((cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer)))
|
||||
if (cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer))
|
||||
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
|
||||
}
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ boolean P_CheckMissileRange(mobj_t *actor);
|
|||
void P_NewChaseDir(mobj_t *actor);
|
||||
boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist);
|
||||
|
||||
mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers);
|
||||
mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward);
|
||||
void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo);
|
||||
#define P_IsFlickyCenter(type) (type > MT_FLICKY_01 && type < MT_SEED && (type - MT_FLICKY_01) % 2 ? 1 : 0)
|
||||
void P_InternalFlickyBubble(mobj_t *actor);
|
||||
|
|
13
src/p_mobj.c
13
src/p_mobj.c
|
@ -8227,8 +8227,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
break;
|
||||
case MT_EGGTRAP: // Egg Capsule animal release
|
||||
if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7)
|
||||
&& (mobj->fuse & 3))
|
||||
if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7))
|
||||
{
|
||||
INT32 i;
|
||||
fixed_t x,y,z;
|
||||
|
@ -8236,7 +8235,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj_t *mo2;
|
||||
mobj_t *flicky;
|
||||
|
||||
z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT);
|
||||
z = mobj->subsector->sector->floorheight + FRACUNIT + (P_RandomKey(64)<<FRACBITS);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK;
|
||||
|
@ -8249,18 +8248,18 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
ns = 4 * FRACUNIT;
|
||||
mo2->momx = FixedMul(FINESINE(fa),ns);
|
||||
mo2->momy = FixedMul(FINECOSINE(fa),ns);
|
||||
mo2->angle = fa << ANGLETOFINESHIFT;
|
||||
|
||||
if (P_RandomChance(FRACUNIT/4)) // I filled a spreadsheet trying to get the equivalent chance to the original P_RandomByte hack!
|
||||
if (!i && !(mobj->fuse & 2))
|
||||
S_StartSound(mo2, mobj->info->deathsound);
|
||||
|
||||
flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false);
|
||||
flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false, -1);
|
||||
if (!flicky)
|
||||
break;
|
||||
|
||||
P_SetTarget(&flicky->target, mo2);
|
||||
flicky->momx = mo2->momx;
|
||||
flicky->momy = mo2->momy;
|
||||
flicky->angle = fa << ANGLETOFINESHIFT;
|
||||
}
|
||||
|
||||
mobj->fuse--;
|
||||
|
@ -11011,7 +11010,7 @@ void P_RespawnSpecials(void)
|
|||
|
||||
// only respawn items when cv_itemrespawn is on
|
||||
if (!(netgame || multiplayer) // Never respawn in single player
|
||||
|| gametype == GT_COOP // Never respawn in co-op gametype
|
||||
|| (maptol & TOL_NIGHTS) // Never respawn in NiGHTs
|
||||
|| !cv_itemrespawn.value) // cvar is turned off
|
||||
return;
|
||||
|
||||
|
|
|
@ -2223,7 +2223,10 @@ static void P_LevelInitStuff(void)
|
|||
tokenbits = 0;
|
||||
runemeraldmanager = false;
|
||||
emeraldspawndelay = 60*TICRATE;
|
||||
nummaprings = mapheaderinfo[gamemap-1]->startrings;
|
||||
if ((netgame || multiplayer) && !G_IsSpecialStage(gamemap))
|
||||
nummaprings = -1;
|
||||
else
|
||||
nummaprings = mapheaderinfo[gamemap-1]->startrings;
|
||||
|
||||
// emerald hunt
|
||||
hunt1 = hunt2 = hunt3 = NULL;
|
||||
|
|
|
@ -6906,7 +6906,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
{
|
||||
/*for (i = 0; i < 16; i++)
|
||||
{
|
||||
mobj_t *flicky = P_InternalFlickySpawn(player->capsule, 0, ((i%4) + 1)*2*FRACUNIT, true);
|
||||
mobj_t *flicky = P_InternalFlickySpawn(player->capsule, 0, ((i%4) + 1)*2*FRACUNIT, true, 0);
|
||||
flicky->z += player->capsule->height/2;
|
||||
flicky->angle = (i*(ANGLE_MAX/16));
|
||||
P_InstaThrust(flicky, flicky->angle, 8*FRACUNIT);
|
||||
|
|
|
@ -578,7 +578,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3kb5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Clink"},
|
||||
{"s3kb6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spin launch"},
|
||||
{"s3kb7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tumbler"},
|
||||
{"s3kb8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling signpost"},
|
||||
{"s3kb8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spinning signpost"},
|
||||
{"s3kb9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ring loss"},
|
||||
{"s3kba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flight"},
|
||||
{"s3kbb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tired flight"},
|
||||
|
|
Loading…
Reference in a new issue