Merge branch 'blankart-dev' into newinput
This commit is contained in:
commit
e61c43a852
39 changed files with 1004 additions and 440 deletions
|
|
@ -803,10 +803,6 @@ keywords
|
|||
Returns the best position of all non-CPU players.\n
|
||||
Intended for branching camera movement in podium maps.";
|
||||
|
||||
PodiumFinish = "void PodiumFinish(void)\n
|
||||
Brings up final Grand Prix results screen in podium maps.\n
|
||||
Does nothing in standard maps.";
|
||||
|
||||
SetLineRenderStyle = "void SetLineRenderStyle(int tag, int blend, fixed alpha)\n
|
||||
Changes the rendering of the tagged linedefs' middle textures.\n
|
||||
- tag: The linedef tag to change.\n
|
||||
|
|
@ -849,18 +845,17 @@ keywords
|
|||
Ends the level.
|
||||
- showintermission: Whether to show the results screen. If omitted, use the default behavior.";
|
||||
|
||||
Music_Play = "void Music_Play(str tune, [bool onlyforactivator])\n
|
||||
Play a tune. If it's already playing, restarting from the beginning.\n
|
||||
- tune: The ID of the tune. Note: this is separate from the music lump.\n
|
||||
- onlyforactivator: Only play the tune for the activator (if activator is a player).";
|
||||
Music_Play = "void Music_Play(str song, [bool onlyforactivator])\n
|
||||
Play a song. If it's already playing, restarting from the beginning.\n
|
||||
- song: The name of the song lump, without 'O_' at the beginning and without a file extension.\n
|
||||
- onlyforactivator: Only play the song for the activator (if activator is a player).";
|
||||
|
||||
Music_StopAll = "void Music_StopAll([bool onlyforactivator])\n
|
||||
Stop every tune that is currently playing.\n
|
||||
Stop the music that is currently playing.\n
|
||||
- onlyforactivator: Only stop for the activator (if activator is a player).";
|
||||
|
||||
Music_Remap = "void Music_Remap(str tune, str song, [bool onlyforactivator])\n
|
||||
Change the actual song lump that a tune will play.\n
|
||||
- tune: The ID of the tune.\n
|
||||
Music_Remap = "void Music_Remap(str song, [bool onlyforactivator])\n
|
||||
Change the song thats playing while keeping its position.\n
|
||||
- song: The name of the song lump, without 'O_' at the beginning and without a file extension.\n
|
||||
- onlyforactivator: Only remap for the activator (if activator is a player).";
|
||||
|
||||
|
|
@ -869,61 +864,6 @@ keywords
|
|||
- fade: Time (tics) to fade between full volume and silence.\n
|
||||
- duration: Silent duration (tics) (not including fade in and fade out), -1 = infinite (default if omitted).";
|
||||
|
||||
Freeze = "void Freeze(bool value)\n
|
||||
Pauses or unpauses the level's thinkers.\n
|
||||
- value: True to freeze, false to unfreeze.";
|
||||
|
||||
Dialogue_SetSpeaker = "void Dialogue_SetSpeaker(str character, int sprite)\n
|
||||
Display a new dialogue box, using a player skin.\n
|
||||
- character: The name of the skin to use.\n
|
||||
- sprite: Which frame of the TALK sprite to display.";
|
||||
|
||||
Dialogue_SetCustomSpeaker = "void Dialogue_SetCustomSpeaker(str nametag, str graphic, [str color, str voice])\n
|
||||
Display a new dialogue box, using a custom nametag, graphic, and voice.\n
|
||||
- nametag: The name to display on the dialogue box.\n
|
||||
- graphic: The name of the graphic lump to display.\n
|
||||
- color: The name of a skincolor to use for the graphic. Defaults to 'None'.\n
|
||||
- voice: The name of the voice sound effect to use. Defaults to 'sfx_ktalk'.";
|
||||
|
||||
Dialogue_NewText = "void Dialogue_NewText(str text)\n
|
||||
Set the text to start displaying on the current dialogue box.\n
|
||||
- text: The contents of the dialogue box.";
|
||||
|
||||
Dialogue_WaitForDismiss = "void Dialogue_WaitForDismiss(void)\n
|
||||
Pause the current script until the current dialogue box\n
|
||||
has been dismissed by the player.";
|
||||
|
||||
Dialogue_WaitForText = "void Dialogue_WaitForText(void)\n
|
||||
Pause the current script until the current dialogue box\n
|
||||
finishes rendering all of its text.";
|
||||
|
||||
Dialogue_NewDismissText = "void Dialogue_NewDismissText(str text)\n
|
||||
Sets new text to display on the dialogue box, and then waits for\n
|
||||
the player to dismiss it. This is exactly equivalent to calling\n
|
||||
Dialogue_NewText and then Dialogue_WaitForDismiss immediately after.\n
|
||||
- text: The contents of the dialogue box.";
|
||||
|
||||
Dialogue_AutoDismiss = "void Dialogue_AutoDismiss(void)\n
|
||||
Dismisses the current dialogue (including from other threads).";
|
||||
|
||||
AddMessage = "void AddMessage(str message, bool interrupt, bool persist)\n
|
||||
Display a message at the top of every player's HUD.\n
|
||||
- message: Text of the message.\n
|
||||
- interrupt: True to interrupt other messages, False to display when they're done.\n
|
||||
- persist: True to last forever (Tutorial objectives), False to disappear after a time limit.";
|
||||
|
||||
AddMessageForPlayer = "void AddMessageForPlayer(str message, bool interrupt, bool persist)\n
|
||||
Display a message at the top of the triggering player's HUD.\n
|
||||
- message: Text of the message.\n
|
||||
- interrupt: True to interrupt other messages, False to display when they're done.\n
|
||||
- persist: True to last forever (Tutorial objectives), False to disappear after a time limit.";
|
||||
|
||||
ClearPersistentMessages = "void ClearPersistentMessages(void)\n
|
||||
Remove all HUD messages (AddMessage, AddMessageForPlayer) that are set to persist, for all players.\n";
|
||||
|
||||
ClearPersistentMessagesForPlayer = "void ClearPersistentMessagesForPlayer(void)\n
|
||||
Remove the triggering player's HUD messages (AddMessage, AddMessageForPlayer) that are set to persist.\n";
|
||||
|
||||
FinishLine = "void FinishLine([bool flip])\n
|
||||
Increments the current lap of the activating player, like when crossing the finish line.\n
|
||||
If called from an activating line and from the wrong side, then it will decrement a lap instead.\n
|
||||
|
|
@ -949,9 +889,6 @@ keywords
|
|||
- BOT_CONTROLLER_FASTFALL: Bots will try to fastfall when they're in the air.\n
|
||||
- forcedir: Force the bots to drive in an exact angle. Requires BOT_CONTROLLER_FORCEDIR to be set.";
|
||||
|
||||
DismountFlyingObject = "void DismountFlyingObject(void)\n
|
||||
Makes the activator player dismount their Dead Line Rocket or Rideroid.";
|
||||
|
||||
GetLineProperty = "any GetLineProperty(int tag, int property)\n
|
||||
Gets the value of a line property directly.\n
|
||||
- tag: The line tag to retrieve the property from. 0 uses the activating line, if it exists.\n
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ special
|
|||
|
||||
void -500:CameraWait(1, int),
|
||||
int -501:PodiumPosition(0),
|
||||
void -502:PodiumFinish(0),
|
||||
//void -502:PodiumFinish(0),
|
||||
void -503:SetLineRenderStyle(3, int, int, fixed),
|
||||
void -504:MapWarp(2, str, bool),
|
||||
int -505:AddBot(0, str, int, int),
|
||||
|
|
|
|||
|
|
@ -3189,7 +3189,7 @@ bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::W
|
|||
/*--------------------------------------------------
|
||||
bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Play a tune. If it's already playing, restart from the
|
||||
Play a song. If it's already playing, restart from the
|
||||
beginning.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
|
@ -3204,7 +3204,7 @@ bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::W
|
|||
return false;
|
||||
}
|
||||
|
||||
S_ChangeMusicEx(map->getString(argV[0])->str, 0, false, mapmusposition, 0, 0);
|
||||
S_ChangeMusicEx(map->getString(argV[0])->str, 0, true, mapmusposition, 0, 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3232,22 +3232,22 @@ bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM
|
|||
/*--------------------------------------------------
|
||||
bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Change the actual song lump that a tune will play.
|
||||
Change the song while keeping the same music posititon.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
ACSVM::MapScope *map = thread->scopeMap;
|
||||
UINT32 lastmapmusposition = mapmusposition;
|
||||
|
||||
// 0: str tune - id for the tune to play
|
||||
// 1: str song - lump name for the song to map to
|
||||
// 2: [bool foractivator] - only do this if the activator is a player and is being viewed
|
||||
// 0: str song - lump name for the song to map to
|
||||
// 1: [bool foractivator] - only do this if the activator is a player and is being viewed
|
||||
|
||||
if (argC > 2 && argV[2] && !ACS_ActivatorIsLocal(thread))
|
||||
if (argC > 1 && argV[1] && !ACS_ActivatorIsLocal(thread))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
S_ChangeMusicEx(map->getString(argV[1])->str, 0, false, mapmusposition, 0, 0);
|
||||
S_ChangeMusicEx(map->getString(argV[0])->str, 0, true, lastmapmusposition, 0, 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,15 +144,10 @@ void ACS_LoadLevelScripts(size_t mapID)
|
|||
|
||||
// Insert BEHAVIOR lump into the list.
|
||||
{
|
||||
|
||||
static const char *maplumpname;
|
||||
|
||||
maplumpname = G_BuildMapName(gamemap);
|
||||
|
||||
ACSVM::ModuleName name = ACSVM::ModuleName(
|
||||
env->getString( maplumpname ),
|
||||
env->getString( mapheaderinfo[mapID]->lumpname ),
|
||||
nullptr,
|
||||
W_CheckNumForMap(maplumpname)
|
||||
mapheaderinfo[mapID]->lumpnum
|
||||
);
|
||||
|
||||
modules.push_back(env->getModule(name));
|
||||
|
|
@ -275,11 +270,11 @@ void ACS_RunLapScript(mobj_t *mo, line_t *line)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunPositionScript(void)
|
||||
void ACS_RunPlayerFinishScript(player_t *player)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void ACS_RunPositionScript(void)
|
||||
void ACS_RunPlayerFinishScript(player_t *player)
|
||||
{
|
||||
Environment *env = &ACSEnv;
|
||||
|
||||
|
|
@ -287,7 +282,30 @@ void ACS_RunPositionScript(void)
|
|||
ACSVM::HubScope *const hub = global->getHubScope(0);
|
||||
ACSVM::MapScope *const map = hub->getMapScope(0);
|
||||
|
||||
map->scriptStartType(ACS_ST_POSITION, {});
|
||||
ACSVM::MapScope::ScriptStartInfo scriptInfo;
|
||||
ThreadInfo info;
|
||||
|
||||
P_SetTarget(&info.mo, player->mo);
|
||||
|
||||
scriptInfo.info = &info;
|
||||
|
||||
map->scriptStartTypeForced(ACS_ST_FINISH, scriptInfo);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunRaceStartScript(void)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void ACS_RunRaceStartScript(void)
|
||||
{
|
||||
Environment *env = &ACSEnv;
|
||||
|
||||
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
|
||||
ACSVM::HubScope *const hub = global->getHubScope(0);
|
||||
ACSVM::MapScope *const map = hub->getMapScope(0);
|
||||
|
||||
map->scriptStartType(ACS_ST_RACESTART, {});
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -306,29 +324,6 @@ void ACS_RunOvertimeScript(void)
|
|||
map->scriptStartType(ACS_ST_OVERTIME, {});
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunEmeraldScript(mobj_t *mo)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void ACS_RunEmeraldScript(mobj_t *mo)
|
||||
{
|
||||
Environment *env = &ACSEnv;
|
||||
|
||||
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
|
||||
ACSVM::HubScope *const hub = global->getHubScope(0);
|
||||
ACSVM::MapScope *const map = hub->getMapScope(0);
|
||||
|
||||
ACSVM::MapScope::ScriptStartInfo scriptInfo;
|
||||
ThreadInfo info;
|
||||
|
||||
P_SetTarget(&info.mo, mo);
|
||||
|
||||
scriptInfo.info = &info;
|
||||
|
||||
map->scriptStartTypeForced(ACS_ST_EMERALD, scriptInfo);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunGameOverScript(void)
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,20 @@ void ACS_RunPlayerDeathScript(player_t *player);
|
|||
|
||||
void ACS_RunPlayerEnterScript(player_t *player);
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunPlayerFinishScript(player_t *player);
|
||||
|
||||
Runs the map's special script for a player
|
||||
finishing (P_DoPlayerExit).
|
||||
|
||||
Input Arguments:-
|
||||
player: The player to run the script for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void ACS_RunPlayerFinishScript(player_t *player);
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunLapScript(mobj_t *mo, line_t *line);
|
||||
|
|
@ -157,13 +171,13 @@ void ACS_RunLapScript(mobj_t *mo, line_t *line);
|
|||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunPositionScript(void);
|
||||
void ACS_RunRaceStartScript(void);
|
||||
|
||||
Runs the map's special script for when the level
|
||||
goes past the POSITION period.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void ACS_RunPositionScript(void);
|
||||
void ACS_RunRaceStartScript(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -176,16 +190,6 @@ void ACS_RunPositionScript(void);
|
|||
void ACS_RunOvertimeScript(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunEmeraldScript(mobj_t *mo);
|
||||
|
||||
Runs the map's special script for when the
|
||||
Special Stage Chaos Emerald is collected.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void ACS_RunEmeraldScript(mobj_t *mo);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunGameOverScript(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,11 +38,10 @@ enum acs_scriptType_e
|
|||
ACS_ST_DEATH = 3, // DEATH: Runs when a player dies.
|
||||
ACS_ST_ENTER = 4, // ENTER: Runs when a player enters the game; both on start of the level, and when un-spectating.
|
||||
ACS_ST_LAP = 5, // LAP: Runs when a player's lap increases from crossing the finish line.
|
||||
ACS_ST_POSITION = 6, // POSITION: Runs when the POSITION period ends.
|
||||
ACS_ST_OVERTIME = 7, // OVERTIME: Runs when Overtime starts in timed game modes.
|
||||
ACS_ST_UFO = 8, // UFO: Runs when the UFO Catcher is destroyed in a Special Stage.
|
||||
ACS_ST_EMERALD = 9, // EMERALD: Runs when the Chaos Emerald is collected in a Special Stage.
|
||||
ACS_ST_GAMEOVER = 10, // GAMEOVER: Runs when the level ends due to a losing condition and no player has an extra life.
|
||||
ACS_ST_RACESTART = 6, // RACESTART: Runs when the RACE starts.
|
||||
ACS_ST_OVERTIME = 8, // OVERTIME: Runs when Overtime starts in timed game modes.
|
||||
ACS_ST_GAMEOVER = 9, // GAMEOVER: Runs when the level ends due to a losing condition and no player has an extra life.
|
||||
ACS_ST_FINISH = 10, // FINISH: Runs when a player finishes
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1890,7 +1890,7 @@ void CON_Drawer(void)
|
|||
|
||||
if (con_curlines > 0)
|
||||
CON_DrawConsole();
|
||||
else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS
|
||||
else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS || gamestate == GS_BLANCREDITS
|
||||
|| gamestate == GS_VOTING || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS)
|
||||
CON_DrawHudlines();
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "k_boss.h"
|
||||
#include "doomstat.h"
|
||||
#include "s_sound.h" // sfx_syfail
|
||||
#include "r_fps.h"
|
||||
|
||||
// cl loading screen
|
||||
#include "v_video.h"
|
||||
|
|
@ -5600,6 +5601,8 @@ boolean TryRunTics(tic_t realtics)
|
|||
}
|
||||
else
|
||||
{
|
||||
boolean tickInterp = true;
|
||||
|
||||
// run the count * tics
|
||||
while (neededtic > gametic)
|
||||
{
|
||||
|
|
@ -5627,7 +5630,17 @@ boolean TryRunTics(tic_t realtics)
|
|||
P_PostLoadLevel();
|
||||
}
|
||||
|
||||
G_Ticker((gametic % NEWTICRATERATIO) == 0);
|
||||
boolean run = (gametic % NEWTICRATERATIO) == 0;
|
||||
|
||||
if (run && tickInterp)
|
||||
{
|
||||
// Update old view state BEFORE ticking so resetting
|
||||
// the old interpolation state from game logic works.
|
||||
R_UpdateViewInterpolation();
|
||||
tickInterp = false; // do not update again in sped-up tics
|
||||
}
|
||||
|
||||
G_Ticker(run);
|
||||
}
|
||||
|
||||
if (Playing() && netgame && (gametic % TICRATE == 0))
|
||||
|
|
|
|||
|
|
@ -437,6 +437,12 @@ static bool D_Display(void)
|
|||
HU_Drawer();
|
||||
break;
|
||||
|
||||
case GS_BLANCREDITS:
|
||||
F_BlanCreditDrawer();
|
||||
HU_Erase();
|
||||
HU_Drawer();
|
||||
break;
|
||||
|
||||
case GS_WAITINGPLAYERS:
|
||||
// The clientconnect drawer is independent...
|
||||
if (netgame)
|
||||
|
|
|
|||
|
|
@ -469,6 +469,7 @@ consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off",
|
|||
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
|
||||
consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
|
||||
consvar_t cv_kartdebuglap = CVAR_INIT ("kartdebuglap", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
|
||||
consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
|
|
@ -5399,7 +5400,7 @@ static void Command_ExitLevel_f(void)
|
|||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
else if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demo.playback)
|
||||
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS && gamestate != GS_BLANCREDITS ) || demo.playback)
|
||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||
else
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ extern consvar_t cv_votetime;
|
|||
|
||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;
|
||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
|
||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebuglap,cv_kartdebugbotpredict;
|
||||
|
||||
extern consvar_t cv_itemfinder;
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ typedef enum
|
|||
PF_UPDATEMYRESPAWN = 1<<19,
|
||||
|
||||
PF_FLIPCAM = 1<<20,
|
||||
//free = 1<<21,
|
||||
PF_TRUSTWAYPOINTS = 1<<21, // Do not activate lap cheat prevention next time finish line distance is updated
|
||||
|
||||
PF_HITFINISHLINE = 1<<22, // Already hit the finish line this tic
|
||||
PF_WRONGWAY = 1<<23, // Moving the wrong way with respect to waypoints?
|
||||
|
|
@ -548,6 +548,7 @@ struct player_t
|
|||
UINT32 distancetofinishprev;
|
||||
waypoint_t *currentwaypoint;
|
||||
waypoint_t *nextwaypoint;
|
||||
UINT16 bigwaypointgap;
|
||||
tic_t airtime; // Keep track of how long you've been in the air
|
||||
UINT8 startboost; // (0 to 125) - Boost you get from start of race or respawn drop dash
|
||||
|
||||
|
|
@ -657,6 +658,9 @@ struct player_t
|
|||
|
||||
UINT16 breathTimer; // Holding your breath underwater
|
||||
|
||||
UINT8 lastsafelap;
|
||||
UINT8 lastsafestarpost;
|
||||
|
||||
//
|
||||
|
||||
SINT8 lives;
|
||||
|
|
|
|||
|
|
@ -1408,6 +1408,8 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
mapheaderinfo[num]->encorepal = (UINT16)i;
|
||||
else if (fastcmp(word, "NUMLAPS"))
|
||||
mapheaderinfo[num]->numlaps = (UINT8)i;
|
||||
else if (fastcmp(word, "LAPSPERSECTION"))
|
||||
mapheaderinfo[num]->lapspersection = max((UINT8)i, 1u);
|
||||
else if (fastcmp(word, "UNLOCKABLE"))
|
||||
{
|
||||
if (i >= 0 && i <= MAXUNLOCKABLES) // 0 for no unlock required, anything else requires something
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ const char *const PLAYERFLAG_LIST[] = {
|
|||
"UPDATEMYRESPAWN",
|
||||
|
||||
"FLIPCAM",
|
||||
"\x01",
|
||||
"TRUSTWAYPOINTS",
|
||||
|
||||
"HITFINISHLINE", // Already hit the finish line this tic
|
||||
"WRONGWAY", // Moving the wrong way with respect to waypoints?
|
||||
|
|
@ -1315,6 +1315,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"GS_CUTSCENE",GS_CUTSCENE},
|
||||
{"GS_DEDICATEDSERVER",GS_DEDICATEDSERVER},
|
||||
{"GS_WAITINGPLAYERS",GS_WAITINGPLAYERS},
|
||||
{"GS_BLANCREDITS",GS_BLANCREDITS},
|
||||
|
||||
// SRB2Kart
|
||||
// kartitems_t
|
||||
|
|
|
|||
|
|
@ -412,6 +412,7 @@ struct mapheader_t
|
|||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden.
|
||||
UINT8 lapspersection; ///< Number of laps per section in hybrid section-circuit maps.
|
||||
fixed_t gravity; ///< Map-wide gravity.
|
||||
|
||||
// Music information
|
||||
|
|
|
|||
337
src/f_finale.c
337
src/f_finale.c
|
|
@ -271,7 +271,7 @@ static void F_TitleBGScroll(INT32 scrollspeed)
|
|||
// =============
|
||||
// INTRO SCENE
|
||||
// =============
|
||||
#define NUMINTROSCENES 1
|
||||
#define NUMINTROSCENES 2
|
||||
INT32 intro_scenenum = 0;
|
||||
INT32 intro_curtime = 0;
|
||||
|
||||
|
|
@ -279,7 +279,8 @@ const char *introtext[NUMINTROSCENES];
|
|||
|
||||
static tic_t introscenetime[NUMINTROSCENES] =
|
||||
{
|
||||
4*TICRATE, // KART KR(eW
|
||||
2*TICRATE, // KART KR(eW
|
||||
3*TICRATE, // Stuff :)
|
||||
};
|
||||
|
||||
// custom intros
|
||||
|
|
@ -338,6 +339,12 @@ static void F_IntroDrawScene(void)
|
|||
highres = true;
|
||||
}
|
||||
|
||||
if (intro_scenenum == 1)
|
||||
{
|
||||
background = W_CachePatchName("BLANKART", PU_CACHE);
|
||||
highres = false;
|
||||
}
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
|
||||
|
||||
if (background)
|
||||
|
|
@ -372,10 +379,6 @@ void F_IntroTicker(void)
|
|||
|
||||
timetonext--;
|
||||
|
||||
if (intro_scenenum == 0)
|
||||
{
|
||||
if (timetonext <= 0)
|
||||
{
|
||||
#if 0 // The necessary apparatus for constructing more elaborate intros...
|
||||
intro_scenenum++;
|
||||
F_NewCutscene(introtext[intro_scenenum]);
|
||||
|
|
@ -383,6 +386,42 @@ void F_IntroTicker(void)
|
|||
wipegamestate = -1;
|
||||
animtimer = stoptimer = 0;
|
||||
#endif
|
||||
|
||||
if (intro_scenenum == 0)
|
||||
{
|
||||
if (timetonext <= 0)
|
||||
{
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99, true);
|
||||
}
|
||||
|
||||
intro_scenenum++;
|
||||
F_NewCutscene(introtext[intro_scenenum]);
|
||||
timetonext = introscenetime[intro_scenenum];
|
||||
wipegamestate = -1;
|
||||
animtimer = stoptimer = 0;
|
||||
}
|
||||
|
||||
if (finalecount == 16)
|
||||
S_StartSound(NULL, sfx_vroom);
|
||||
else if (finalecount == 47)
|
||||
{
|
||||
// Need to use M_Random otherwise it always uses the same sound
|
||||
INT32 rskin = M_RandomKey(numskins);
|
||||
UINT8 rtaunt = M_RandomKey(2);
|
||||
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
|
||||
S_StartSound(NULL, rsound);
|
||||
}
|
||||
}
|
||||
|
||||
if (intro_scenenum == 1)
|
||||
{
|
||||
if (timetonext <= 0)
|
||||
{
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
|
|
@ -395,7 +434,7 @@ void F_IntroTicker(void)
|
|||
{
|
||||
tic_t nowtime, quittime, lasttime;
|
||||
nowtime = lasttime = I_GetTime();
|
||||
quittime = nowtime + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds
|
||||
quittime = nowtime + NEWTICRATE; // Shortened the quit time, used to be 2 seconds
|
||||
while (quittime > nowtime)
|
||||
{
|
||||
while (!((nowtime = I_GetTime()) - lasttime))
|
||||
|
|
@ -424,14 +463,10 @@ void F_IntroTicker(void)
|
|||
D_StartTitle();
|
||||
return;
|
||||
}
|
||||
if (finalecount == 8)
|
||||
S_StartSound(NULL, sfx_vroom);
|
||||
else if (finalecount == 47)
|
||||
if (finalecount == 80)
|
||||
{
|
||||
// Need to use M_Random otherwise it always uses the same sound
|
||||
INT32 rskin = M_RandomKey(numskins);
|
||||
UINT8 rtaunt = M_RandomKey(2);
|
||||
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
|
||||
sfxenum_t rsound = skins[1].soundsid[SKSKWIN];
|
||||
S_StartSound(NULL, sfx_flgcap);
|
||||
S_StartSound(NULL, rsound);
|
||||
}
|
||||
}
|
||||
|
|
@ -516,43 +551,62 @@ static const char *credits[] = {
|
|||
"\1Lead Programming",
|
||||
"Sally \"TehRealSalt\" Cochenour",
|
||||
"Vivian \"toaster\" Grannell",
|
||||
"Ronald \"Eidolon\" Kinard",
|
||||
"James Robert Roman",
|
||||
"Sean \"Sryder\" Ryder",
|
||||
"Ehab \"wolfs\" Saeed",
|
||||
"\"ZarroTsu\"",
|
||||
"",
|
||||
"\1Support Programming",
|
||||
"Colette \"fickleheart\" Bordelon",
|
||||
"James R.",
|
||||
"\"Lach\"",
|
||||
"\"Lat\'\"",
|
||||
"AJ \"Tyron\" Martinez",
|
||||
"\"Monster Iestyn\"",
|
||||
"\"Shuffle\"",
|
||||
"\"SteelT\"",
|
||||
"",
|
||||
"\1External Programming",
|
||||
"Alam Ed Arias",
|
||||
"\"alphaRexJames\"",
|
||||
"\"Ashnal\"",
|
||||
"\"filpAM\"",
|
||||
"\"FlykeSpice\"",
|
||||
"\"Hannu Hanhi\"",
|
||||
"\"himie\"",
|
||||
"\"JugadorXEI\"",
|
||||
"\"Kimberly\"",
|
||||
"\"Lighto97\"",
|
||||
"\"Lonsfor\"",
|
||||
"\"mazmazz\"",
|
||||
"\"minenice\"",
|
||||
"\"Shuffle\"",
|
||||
"\"Snu\"",
|
||||
"\"X.organic\"",
|
||||
"",
|
||||
"\1Lead Artists",
|
||||
"Desmond \"Blade\" DesJardins",
|
||||
"\"VelocitOni\"",
|
||||
"",
|
||||
"\1Support Artists",
|
||||
"Sally \"TehRealSalt\" Cochenour",
|
||||
"\"Chengi\"",
|
||||
"\"Chrispy\"",
|
||||
"Sherman \"CoatRack\" DesJardins",
|
||||
"\"DrTapeworm\"",
|
||||
"Jesse \"Jeck Jims\" Emerick",
|
||||
"Wesley \"Charyb\" Gillebaard",
|
||||
"\"Nev3r\"",
|
||||
"Vivian \"toaster\" Grannell",
|
||||
"James \"SeventhSentinel\" Hall",
|
||||
"\"Lat\'\"",
|
||||
"\"rairai104n\"",
|
||||
"\"Tyrannosaur Chao\"",
|
||||
"\"ZarroTsu\"",
|
||||
"",
|
||||
"\1External Artists",
|
||||
"\"1-Up Mason\"",
|
||||
"\"Chengi\"",
|
||||
"\"Chrispy\"",
|
||||
"\"DirkTheHusky\"",
|
||||
"\"LJSTAR\"",
|
||||
"\"MotorRoach\"",
|
||||
"\"Nev3r\"",
|
||||
"\"rairai104n\"",
|
||||
"\"Ritz\"",
|
||||
"\"Rob\"",
|
||||
"\"SmithyGNC\"",
|
||||
|
|
@ -569,7 +623,7 @@ static const char *credits[] = {
|
|||
"\"VAdaPEGA\"",
|
||||
"\"VelocitOni\"",
|
||||
"",
|
||||
"\1Music",
|
||||
"\1Original Music",
|
||||
"\"DrTapeworm\"",
|
||||
"Wesley \"Charyb\" Gillebaard",
|
||||
"James \"SeventhSentinel\" Hall",
|
||||
|
|
@ -587,7 +641,6 @@ static const char *credits[] = {
|
|||
"\"DrTapeworm\"",
|
||||
"Paul \"Boinciel\" Clempson",
|
||||
"Sherman \"CoatRack\" DesJardins",
|
||||
"Colette \"fickleheart\" Bordelon",
|
||||
"Vivian \"toaster\" Grannell",
|
||||
"\"Gunla\"",
|
||||
"James \"SeventhSentinel\" Hall",
|
||||
|
|
@ -597,16 +650,19 @@ static const char *credits[] = {
|
|||
"Sean \"Sryder\" Ryder",
|
||||
"\"Ryuspark\"",
|
||||
"\"Simsmagic\"",
|
||||
"Ivo Solarin",
|
||||
"\"SP47\"",
|
||||
"\"TG\"",
|
||||
"\"Victor Rush Turbo\"",
|
||||
"\"ZarroTsu\"",
|
||||
"",
|
||||
"\1Testing",
|
||||
"RKH License holders",
|
||||
"The KCS",
|
||||
"\"CyberIF\"",
|
||||
"\"Dani\"",
|
||||
"Karol \"Fooruman\" D""\x1E""browski", // Dąbrowski, <Sryder> accents in srb2 :ytho:
|
||||
"\"VirtAnderson\"",
|
||||
"\"Virt\"",
|
||||
"",
|
||||
"\1Special Thanks",
|
||||
"SEGA",
|
||||
|
|
@ -621,8 +677,8 @@ static const char *credits[] = {
|
|||
"\"Tyler52\"",
|
||||
"",
|
||||
"",
|
||||
"\1Thank you ",
|
||||
"\1for playing! ",
|
||||
"\1Thank you",
|
||||
"\1for playing!",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -635,33 +691,31 @@ static struct {
|
|||
UINT8 colorize;
|
||||
} credits_pics[] = {
|
||||
// We don't have time to be fancy, let's just colorize some item sprites :V
|
||||
{224, 80+(200* 1), "K_ITJAWZ", SKINCOLOR_CREAMSICLE},
|
||||
{224, 80+(200* 2), "K_ITSPB", SKINCOLOR_GARDEN},
|
||||
{224, 80+(200* 3), "K_ITBANA", SKINCOLOR_LILAC},
|
||||
{224, 80+(200* 4), "K_ITHYUD", SKINCOLOR_DREAM},
|
||||
{224, 80+(200* 5), "K_ITBHOG", SKINCOLOR_TANGERINE},
|
||||
{224, 80+(200* 6), "K_ITSHRK", SKINCOLOR_JAWZ},
|
||||
{224, 80+(200* 7), "K_ITSHOE", SKINCOLOR_MINT},
|
||||
{224, 80+(200* 8), "K_ITGROW", SKINCOLOR_RUBY},
|
||||
{224, 80+(200* 9), "K_ITPOGO", SKINCOLOR_SAPPHIRE},
|
||||
{224, 80+(200*10), "K_ITRSHE", SKINCOLOR_YELLOW},
|
||||
{224, 80+(200*11), "K_ITORB4", SKINCOLOR_DUSK},
|
||||
{224, 80+(200*12), "K_ITEGGM", SKINCOLOR_GREEN},
|
||||
{224, 80+(200*13), "K_ITMINE", SKINCOLOR_BRONZE},
|
||||
{224, 80+(200*14), "K_ITTHNS", SKINCOLOR_RASPBERRY},
|
||||
{224, 80+(200*15), "K_ITINV1", SKINCOLOR_GREY},
|
||||
{224, 80+(216* 1), "K_ITJAWZ", SKINCOLOR_CREAMSICLE},
|
||||
{224, 80+(216* 2), "K_ITSPB", SKINCOLOR_GARDEN},
|
||||
{224, 80+(216* 3), "K_ITBANA", SKINCOLOR_LILAC},
|
||||
{224, 80+(216* 4), "K_ITHYUD", SKINCOLOR_DREAM},
|
||||
{224, 80+(216* 5), "K_ITBHOG", SKINCOLOR_TANGERINE},
|
||||
{224, 80+(216* 6), "K_ITSHRK", SKINCOLOR_JAWZ},
|
||||
{224, 80+(216* 7), "K_ITSHOE", SKINCOLOR_MINT},
|
||||
{224, 80+(216* 8), "K_ITGROW", SKINCOLOR_RUBY},
|
||||
{224, 80+(216* 9), "K_ITPOGO", SKINCOLOR_SAPPHIRE},
|
||||
{224, 80+(216*10), "K_ITRSHE", SKINCOLOR_YELLOW},
|
||||
{224, 80+(216*11), "K_ITORB4", SKINCOLOR_DUSK},
|
||||
{224, 80+(216*12), "K_ITEGGM", SKINCOLOR_GREEN},
|
||||
{224, 80+(216*13), "K_ITMINE", SKINCOLOR_BRONZE},
|
||||
{224, 80+(216*14), "K_ITTHNS", SKINCOLOR_RASPBERRY},
|
||||
{224, 80+(216*15), "K_ITINV1", SKINCOLOR_GREY},
|
||||
// This Tyler52 gag is troublesome
|
||||
// Alignment should be ((spaces+1 * 100) + (headers+1 * 38) + (lines * 15))
|
||||
// Current max image spacing: (200*17)
|
||||
{112, (15*100)+(17*38)+(88*15), "TYLER52", SKINCOLOR_NONE}
|
||||
// Current max image spacing: (216*17)
|
||||
{112, (16*100)+(19*38)+(103*15), "TYLER52", SKINCOLOR_NONE},
|
||||
{0, 0, NULL, SKINCOLOR_NONE}
|
||||
};
|
||||
|
||||
#undef CREDITS_LEFT
|
||||
#undef CREDITS_RIGHT
|
||||
|
||||
static UINT32 credits_height = 0;
|
||||
static const UINT8 credits_numpics = sizeof(credits_pics)/sizeof(credits_pics[0]) - 1;
|
||||
|
||||
void F_StartCredits(void)
|
||||
{
|
||||
G_SetGamestate(GS_CREDITS);
|
||||
|
|
@ -692,9 +746,9 @@ void F_StartCredits(void)
|
|||
void F_CreditDrawer(void)
|
||||
{
|
||||
UINT16 i;
|
||||
fixed_t y = (80<<FRACBITS) - (animtimer<<FRACBITS>>1);
|
||||
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
|
||||
|
||||
//V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
// Draw background
|
||||
V_DrawSciencePatch(0, 0 - FixedMul(32<<FRACBITS, FixedDiv(credbgtimer%TICRATE, TICRATE)), V_SNAPTOTOP, W_CachePatchName("CREDTILE", PU_CACHE), FRACUNIT);
|
||||
|
|
@ -703,7 +757,7 @@ void F_CreditDrawer(void)
|
|||
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; i < credits_numpics; i++)
|
||||
for (i = 0; credits_pics[i].patch; i++)
|
||||
{
|
||||
UINT8 *colormap = NULL;
|
||||
fixed_t sc = FRACUNIT>>1;
|
||||
|
|
@ -717,6 +771,9 @@ void F_CreditDrawer(void)
|
|||
V_DrawFixedPatch(credits_pics[i].x<<FRACBITS, (credits_pics[i].y<<FRACBITS) - 4*(animtimer<<FRACBITS)/5, sc, 0, W_CachePatchName(credits_pics[i].patch, PU_CACHE), colormap);
|
||||
}
|
||||
|
||||
// Dim the background
|
||||
//V_DrawFadeScreen();
|
||||
|
||||
// Draw credits text on top
|
||||
for (i = 0; credits[i]; i++)
|
||||
{
|
||||
|
|
@ -730,11 +787,6 @@ void F_CreditDrawer(void)
|
|||
V_DrawCreditString((160 - (V_CreditStringWidth(&credits[i][1])>>1))<<FRACBITS, y, 0, &credits[i][1]);
|
||||
y += 30<<FRACBITS;
|
||||
break;
|
||||
case 2:
|
||||
if (y>>FRACBITS > -10)
|
||||
V_DrawStringAtFixed((BASEVIDWIDTH-V_StringWidth(&credits[i][1], V_ALLOWLOWERCASE|V_YELLOWMAP))<<FRACBITS>>1, y, V_ALLOWLOWERCASE|V_YELLOWMAP, &credits[i][1]);
|
||||
y += 12<<FRACBITS;
|
||||
break;
|
||||
default:
|
||||
if (y>>FRACBITS > -10)
|
||||
V_DrawStringAtFixed(32<<FRACBITS, y, V_ALLOWLOWERCASE, credits[i]);
|
||||
|
|
@ -750,22 +802,7 @@ void F_CreditTicker(void)
|
|||
{
|
||||
// "Simulate" the drawing of the credits so that dedicated mode doesn't get stuck
|
||||
UINT16 i;
|
||||
fixed_t y = (80<<FRACBITS) - (animtimer<<FRACBITS>>1);
|
||||
|
||||
// Calculate credits height to display art properly
|
||||
if (credits_height == 0)
|
||||
{
|
||||
for (i = 0; credits[i]; i++)
|
||||
{
|
||||
switch(credits[i][0])
|
||||
{
|
||||
case 0: credits_height += 80; break;
|
||||
case 1: credits_height += 30; break;
|
||||
default: credits_height += 12; break;
|
||||
}
|
||||
}
|
||||
credits_height = 131*credits_height/80; // account for scroll speeds. This is a guess now, so you may need to update this if you change the credits length.
|
||||
}
|
||||
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
|
||||
|
||||
// Draw credits text on top
|
||||
for (i = 0; credits[i]; i++)
|
||||
|
|
@ -858,6 +895,165 @@ boolean F_CreditResponder(event_t *event)
|
|||
return true;
|
||||
}
|
||||
|
||||
// ============
|
||||
// BLANCREDITS
|
||||
// ============
|
||||
|
||||
static const char *blancredits[] = {
|
||||
"\1BlanKart",
|
||||
"\1Credits",
|
||||
"",
|
||||
"\1Lead Programming",
|
||||
"\"NepDisk\"",
|
||||
"\"GenericHeroGuy\"",
|
||||
"\"Alug\"",
|
||||
"\"Indev\"",
|
||||
"",
|
||||
"\1Support Programming",
|
||||
"\"hayaunderscore\" aka \"DeltaKaynx\"",
|
||||
"\"WumboSpasm\"",
|
||||
"",
|
||||
"\1External Programming",
|
||||
"\"xyzzy\"",
|
||||
"\"SuperJustinBros\"",
|
||||
"",
|
||||
"\1Ring Racers Programming",
|
||||
"Kart Krew Dev",
|
||||
"",
|
||||
"\1New Graphics Creation",
|
||||
"\"Spee\"",
|
||||
"\"Jin\"",
|
||||
"\"NepDisk\"",
|
||||
"",
|
||||
"\1Special Thanks",
|
||||
"\"Sunflower\" aka \"AnimeSonic\"",
|
||||
"Sunflower's Garden",
|
||||
"The Moe Mansion and Birdhouse Team",
|
||||
"",
|
||||
"",
|
||||
"\1Thank you",
|
||||
"\1for playing!",
|
||||
|
||||
NULL,
|
||||
};
|
||||
|
||||
void F_BlanStartCredits(void)
|
||||
{
|
||||
G_SetGamestate(GS_BLANCREDITS);
|
||||
|
||||
// Just in case they're open ... somehow
|
||||
M_ClearMenus(true);
|
||||
|
||||
if (creditscutscene)
|
||||
{
|
||||
F_StartCustomCutscene(creditscutscene - 1, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
|
||||
S_ChangeMusicInternal("KMAP04", true);
|
||||
S_ShowMusicCredit();
|
||||
|
||||
finalecount = 0;
|
||||
animtimer = 0;
|
||||
timetonext = 2*TICRATE;
|
||||
}
|
||||
|
||||
static void F_DrawDiagCubes(void)
|
||||
{
|
||||
INT32 j;
|
||||
for (j = -4; j < 5; j++)
|
||||
{
|
||||
//Up Cubes
|
||||
V_DrawFill(-((credbgtimer % 128)+1)+(32*j)+32-20, ((credbgtimer % 128)+1)-(32*j), 32, 32, 31|V_SNAPTOBOTTOM|V_SNAPTORIGHT);
|
||||
V_DrawFill(-((credbgtimer % 128)+1)+(32*j)+32-20, ((credbgtimer % 128)+1)-(32*j), 32, 32, 31|V_SNAPTOTOP|V_SNAPTOLEFT);
|
||||
V_DrawFill(-((credbgtimer % 128)+1)+(32*j)-20, ((credbgtimer % 128)+1)-(32*j), 32, 32, 31|V_SNAPTOTOP|V_SNAPTOLEFT);
|
||||
V_DrawFill(-((credbgtimer % 128)+1)+(32*j)-32-20, ((credbgtimer % 128)+1)-(32*j), 32, 32, 31|V_SNAPTOTOP|V_SNAPTOLEFT);
|
||||
|
||||
//Down Cubes
|
||||
V_DrawFill(-((credbgtimer % 128)+1)+(32*j)+320+20, ((credbgtimer % 128)+1)-(32*j)+168, 32, 32, 31|V_SNAPTOBOTTOM|V_SNAPTORIGHT);
|
||||
V_DrawFill(-((credbgtimer % 128)+1)+(32*j)+288+20, ((credbgtimer % 128)+1)-(32*j)+168, 32, 32, 31|V_SNAPTOBOTTOM|V_SNAPTORIGHT);
|
||||
V_DrawFill(-((credbgtimer % 128)+1)+(32*j)+288+20, ((credbgtimer % 128)+1)-(32*j)+136, 32, 32, 31|V_SNAPTOBOTTOM|V_SNAPTORIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
void F_BlanCreditDrawer(void)
|
||||
{
|
||||
UINT8 i;
|
||||
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
|
||||
fixed_t yscroll = FixedMul(32<<FRACBITS, FixedDiv(credbgtimer%TICRATE, TICRATE));
|
||||
|
||||
V_DrawSciencePatch(0, 0 - yscroll, V_SNAPTOTOP, W_CachePatchName("CREDTILE", PU_CACHE), FRACUNIT);
|
||||
V_DrawFillConsoleMap(0,0,vid.width, vid.height,0);
|
||||
|
||||
// Draw credits text on top
|
||||
for (i = 0; blancredits[i]; i++)
|
||||
{
|
||||
switch(blancredits[i][0])
|
||||
{
|
||||
case 0:
|
||||
y += 80<<FRACBITS;
|
||||
break;
|
||||
case 1:
|
||||
if (y>>FRACBITS > -20)
|
||||
V_DrawCenteredStringAtFixed(160<<FRACBITS, y, 0, &blancredits[i][1]);
|
||||
y += 20<<FRACBITS;
|
||||
break;
|
||||
default:
|
||||
if (y>>FRACBITS > -10)
|
||||
V_DrawCenteredStringAtFixed(160<<FRACBITS, y, V_ALLOWLOWERCASE, blancredits[i]);
|
||||
y += 12<<FRACBITS;
|
||||
break;
|
||||
}
|
||||
F_DrawDiagCubes();
|
||||
|
||||
if (((y>>FRACBITS) * vid.dupy) > vid.height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void F_BlanCreditTicker(void)
|
||||
{
|
||||
// "Simulate" the drawing of the credits so that dedicated mode doesn't get stuck
|
||||
UINT16 i;
|
||||
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
|
||||
|
||||
// Draw credits text on top
|
||||
for (i = 0; blancredits[i]; i++)
|
||||
{
|
||||
switch(blancredits[i][0])
|
||||
{
|
||||
case 0: y += 80<<FRACBITS; break;
|
||||
case 1: y += 20<<FRACBITS; break;
|
||||
default: y += 12<<FRACBITS; break;
|
||||
}
|
||||
if (FixedMul(y,vid.dupy) > vid.height)
|
||||
break;
|
||||
}
|
||||
|
||||
// Do this here rather than in the drawer you doofus! (this is why dedicated mode broke at credits)
|
||||
if (!blancredits[i] && y <= 120<<FRACBITS && !finalecount)
|
||||
{
|
||||
timetonext = 5*TICRATE+1;
|
||||
finalecount = 5*TICRATE;
|
||||
}
|
||||
|
||||
if (timetonext)
|
||||
timetonext--;
|
||||
else
|
||||
animtimer++;
|
||||
|
||||
credbgtimer++;
|
||||
|
||||
if (finalecount && --finalecount == 0)
|
||||
F_StartGameEvaluation();
|
||||
}
|
||||
|
||||
// ============
|
||||
// EVALUATION
|
||||
// ============
|
||||
|
|
@ -1345,6 +1541,7 @@ void F_TitleScreenTicker(boolean run)
|
|||
S_ChangeMusic(menupres[MN_MAIN].musname, menupres[MN_MAIN].mustrack, menupres[MN_MAIN].muslooping);
|
||||
else
|
||||
S_ChangeMusicInternal("titles", looptitle);
|
||||
S_StartSound(NULL, sfx_s23c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ void F_EndingTicker(void);
|
|||
void F_CreditTicker(void);
|
||||
void F_CreditDrawer(void);
|
||||
|
||||
void F_BlanCreditTicker(void);
|
||||
void F_BlanCreditDrawer(void);
|
||||
|
||||
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer);
|
||||
void F_CutsceneDrawer(void);
|
||||
void F_EndCutScene(void);
|
||||
|
|
@ -74,6 +77,7 @@ void F_StartGameEnd(void);
|
|||
void F_StartIntro(void);
|
||||
void F_StartTitleScreen(void);
|
||||
void F_StartCredits(void);
|
||||
void F_BlanStartCredits(void);
|
||||
|
||||
extern INT32 finalecount;
|
||||
extern INT32 titlescrollxspeed;
|
||||
|
|
|
|||
266
src/g_demo.c
266
src/g_demo.c
|
|
@ -52,6 +52,7 @@
|
|||
#include "k_bot.h"
|
||||
#include "k_color.h"
|
||||
#include "k_follower.h"
|
||||
#include "k_grandprix.h"
|
||||
|
||||
static CV_PossibleValue_t recordmultiplayerdemos_cons_t[] = {{0, "Disabled"}, {1, "Manual Save"}, {2, "Auto Save"}, {0, NULL}};
|
||||
consvar_t cv_recordmultiplayerdemos = CVAR_INIT ("netdemo_record", "Manual Save", CV_SAVE, recordmultiplayerdemos_cons_t, NULL);
|
||||
|
|
@ -124,10 +125,12 @@ demoghost *ghosts = NULL;
|
|||
#define DF_ATTACKSHIFT 1
|
||||
#define DF_ENCORE 0x40
|
||||
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
|
||||
#define DF_GRANDPRIX 0x0100
|
||||
|
||||
#define DEMO_SPECTATOR 0x01
|
||||
#define DEMO_KICKSTART 0x02
|
||||
#define DEMO_SHRINKME 0x04
|
||||
#define DEMO_BOT 0x08
|
||||
|
||||
// For demos
|
||||
#define ZT_FWD 0x0001
|
||||
|
|
@ -255,13 +258,73 @@ void G_ReadDemoExtraData(void)
|
|||
{
|
||||
extradata = READUINT8(demobuf.p);
|
||||
|
||||
if (extradata & DXD_RESPAWN)
|
||||
if (extradata & DXD_JOINDATA)
|
||||
{
|
||||
if (players[p].mo)
|
||||
if (!playeringame[p])
|
||||
{
|
||||
// Is this how this should work..?
|
||||
P_DamageMobj(players[p].mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||
G_AddPlayer(p, p);
|
||||
}
|
||||
|
||||
players[p].bot = !!(READUINT8(demobuf.p));
|
||||
if (players[p].bot)
|
||||
{
|
||||
players[p].botvars.difficulty = READUINT8(demobuf.p);
|
||||
players[p].botvars.diffincrease = READUINT8(demobuf.p); // needed to avoid having to duplicate logic
|
||||
players[p].botvars.rival = (boolean)READUINT8(demobuf.p);
|
||||
}
|
||||
}
|
||||
if (extradata & DXD_PLAYSTATE)
|
||||
{
|
||||
i = READUINT8(demobuf.p);
|
||||
|
||||
switch (i) {
|
||||
case DXD_PST_PLAYING:
|
||||
if (players[p].spectator == true)
|
||||
{
|
||||
if (players[p].bot)
|
||||
{
|
||||
players[p].spectator = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
players[p].pflags |= PF_WANTSTOJOIN;
|
||||
}
|
||||
}
|
||||
//CONS_Printf("player %s is despectating on tic %d\n", player_names[p], leveltime);
|
||||
break;
|
||||
|
||||
case DXD_PST_SPECTATING:
|
||||
if (players[p].spectator)
|
||||
{
|
||||
players[p].pflags &= ~PF_WANTSTOJOIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[p].mo)
|
||||
{
|
||||
P_DamageMobj(players[p].mo, NULL, NULL, 1, DMG_SPECTATOR);
|
||||
}
|
||||
P_SetPlayerSpectator(p);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DXD_PST_LEFT:
|
||||
CL_RemovePlayer(p, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
G_ResetViews();
|
||||
|
||||
// maybe these are necessary?
|
||||
K_CheckBumpers();
|
||||
P_CheckRacers();
|
||||
}
|
||||
if (extradata & DXD_NAME)
|
||||
{
|
||||
// Name
|
||||
M_Memcpy(player_names[p],demobuf.p,16);
|
||||
demobuf.p += 16;
|
||||
}
|
||||
if (extradata & DXD_SKIN)
|
||||
{
|
||||
|
|
@ -295,12 +358,6 @@ void G_ReadDemoExtraData(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (extradata & DXD_NAME)
|
||||
{
|
||||
// Name
|
||||
M_Memcpy(player_names[p],demobuf.p,16);
|
||||
demobuf.p += 16;
|
||||
}
|
||||
if (extradata & DXD_FOLLOWER)
|
||||
{
|
||||
// Set our follower
|
||||
|
|
@ -320,47 +377,13 @@ void G_ReadDemoExtraData(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (extradata & DXD_PLAYSTATE)
|
||||
if (extradata & DXD_RESPAWN)
|
||||
{
|
||||
i = READUINT8(demobuf.p);
|
||||
|
||||
switch (i) {
|
||||
case DXD_PST_PLAYING:
|
||||
players[p].pflags |= PF_WANTSTOJOIN; // fuck you
|
||||
//CONS_Printf("player %s is despectating on tic %d\n", player_names[p], leveltime);
|
||||
break;
|
||||
|
||||
case DXD_PST_SPECTATING:
|
||||
players[p].pflags &= ~PF_WANTSTOJOIN; // double-fuck you
|
||||
if (!playeringame[p])
|
||||
{
|
||||
CL_ClearPlayer(p);
|
||||
playeringame[p] = true;
|
||||
G_AddPlayer(p, p);
|
||||
players[p].spectator = true;
|
||||
//CONS_Printf("player %s is joining server on tic %d\n", player_names[p], leveltime);
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONS_Printf("player %s is spectating on tic %d\n", player_names[p], leveltime);
|
||||
players[p].spectator = true;
|
||||
if (players[p].mo)
|
||||
P_DamageMobj(players[p].mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||
else
|
||||
players[p].playerstate = PST_REBORN;
|
||||
}
|
||||
break;
|
||||
|
||||
case DXD_PST_LEFT:
|
||||
CL_RemovePlayer(p, 0);
|
||||
break;
|
||||
if (players[p].mo)
|
||||
{
|
||||
// Is this how this should work..?
|
||||
P_DamageMobj(players[p].mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||
}
|
||||
|
||||
G_ResetViews();
|
||||
|
||||
// maybe these are necessary?
|
||||
K_CheckBumpers();
|
||||
P_CheckRacers();
|
||||
}
|
||||
if (extradata & DXD_WEAPONPREF)
|
||||
{
|
||||
|
|
@ -413,7 +436,44 @@ void G_WriteDemoExtraData(void)
|
|||
WRITEUINT8(demobuf.p, i);
|
||||
WRITEUINT8(demobuf.p, demo_extradata[i]);
|
||||
|
||||
//if (demo_extradata[i] & DXD_RESPAWN) has no extra data
|
||||
if (demo_extradata[i] & DXD_JOINDATA)
|
||||
{
|
||||
WRITEUINT8(demobuf.p, (UINT8)players[i].bot);
|
||||
if (players[i].bot)
|
||||
{
|
||||
WRITEUINT8(demobuf.p, players[i].botvars.difficulty);
|
||||
WRITEUINT8(demobuf.p, players[i].botvars.diffincrease); // needed to avoid having to duplicate logic
|
||||
WRITEUINT8(demobuf.p, (UINT8)players[i].botvars.rival);
|
||||
}
|
||||
}
|
||||
if (demo_extradata[i] & DXD_PLAYSTATE)
|
||||
{
|
||||
UINT8 pst = DXD_PST_PLAYING;
|
||||
|
||||
demo_writerng = 1;
|
||||
|
||||
if (!playeringame[i])
|
||||
{
|
||||
pst = DXD_PST_LEFT;
|
||||
}
|
||||
else if (
|
||||
players[i].spectator &&
|
||||
!(players[i].pflags & PF_WANTSTOJOIN) // <= fuck you specifically
|
||||
)
|
||||
{
|
||||
pst = DXD_PST_SPECTATING;
|
||||
}
|
||||
|
||||
WRITEUINT8(demobuf.p, pst);
|
||||
}
|
||||
if (demo_extradata[i] & DXD_NAME)
|
||||
{
|
||||
// Name
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, player_names[i], 16);
|
||||
M_Memcpy(demobuf.p,name,16);
|
||||
demobuf.p += 16;
|
||||
}
|
||||
if (demo_extradata[i] & DXD_SKIN)
|
||||
{
|
||||
// Skin
|
||||
|
|
@ -434,14 +494,6 @@ void G_WriteDemoExtraData(void)
|
|||
M_Memcpy(demobuf.p,name,16);
|
||||
demobuf.p += 16;
|
||||
}
|
||||
if (demo_extradata[i] & DXD_NAME)
|
||||
{
|
||||
// Name
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, player_names[i], 16);
|
||||
M_Memcpy(demobuf.p,name,16);
|
||||
demobuf.p += 16;
|
||||
}
|
||||
if (demo_extradata[i] & DXD_FOLLOWER)
|
||||
{
|
||||
// write follower
|
||||
|
|
@ -460,19 +512,7 @@ void G_WriteDemoExtraData(void)
|
|||
demobuf.p += 16;
|
||||
|
||||
}
|
||||
if (demo_extradata[i] & DXD_PLAYSTATE)
|
||||
{
|
||||
demo_writerng = 1;
|
||||
if (!playeringame[i])
|
||||
WRITEUINT8(demobuf.p, DXD_PST_LEFT);
|
||||
else if (
|
||||
players[i].spectator &&
|
||||
!(players[i].pflags & PF_WANTSTOJOIN) // <= fuck you specifically
|
||||
)
|
||||
WRITEUINT8(demobuf.p, DXD_PST_SPECTATING);
|
||||
else
|
||||
WRITEUINT8(demobuf.p, DXD_PST_PLAYING);
|
||||
}
|
||||
//if (demo_extradata[i] & DXD_RESPAWN) has no extra data
|
||||
if (demo_extradata[i] & DXD_WEAPONPREF)
|
||||
{
|
||||
WeaponPref_Save(&demobuf.p, i);
|
||||
|
|
@ -1164,23 +1204,27 @@ void G_GhostTicker(void)
|
|||
UINT16 ziptic = READUINT8(g->p);
|
||||
UINT8 xziptic = 0;
|
||||
|
||||
if (g->done)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
while (ziptic != DW_END) // Get rid of extradata stuff
|
||||
{
|
||||
if (ziptic < MAXPLAYERS)
|
||||
{
|
||||
#ifdef DEVELOP
|
||||
UINT8 playerid = ziptic;
|
||||
#endif
|
||||
// We want to skip *any* player extradata because some demos have extradata for bogus players,
|
||||
// but if there is tic data later for those players *then* we'll consider it invalid.
|
||||
|
||||
ziptic = READUINT8(g->p);
|
||||
if (ziptic & DXD_SKIN)
|
||||
g->p += 18; // We _could_ read this info, but it shouldn't change anything in record attack...
|
||||
if (ziptic & DXD_COLOR)
|
||||
g->p += 16; // Same tbh
|
||||
if (ziptic & DXD_NAME)
|
||||
g->p += 16; // yea
|
||||
if (ziptic & DXD_FOLLOWER)
|
||||
g->p += 32; // ok (32 because there's both the skin and the colour)
|
||||
if (ziptic & DXD_JOINDATA)
|
||||
{
|
||||
if (READUINT8(g->p) != 0)
|
||||
I_Error("Ghost is not a record attack ghost (bot JOINDATA)");
|
||||
}
|
||||
if (ziptic & DXD_PLAYSTATE)
|
||||
{
|
||||
UINT8 playstate = READUINT8(g->p);
|
||||
|
|
@ -1192,6 +1236,14 @@ void G_GhostTicker(void)
|
|||
;
|
||||
}
|
||||
}
|
||||
if (ziptic & DXD_NAME)
|
||||
g->p += 16; // yea
|
||||
if (ziptic & DXD_SKIN)
|
||||
g->p += 16; // We _could_ read this info, but it shouldn't change anything in record attack...
|
||||
if (ziptic & DXD_COLOR)
|
||||
g->p += 16; // Same tbh
|
||||
if (ziptic & DXD_FOLLOWER)
|
||||
g->p += 32; // ok (32 because there's both the skin and the colour)
|
||||
if (ziptic & DXD_WEAPONPREF)
|
||||
g->p++; // ditto
|
||||
}
|
||||
|
|
@ -2129,6 +2181,13 @@ void G_BeginRecording(void)
|
|||
|
||||
// Save netvar data
|
||||
CV_SaveDemoVars(&demobuf.p);
|
||||
|
||||
if ((demoflags & DF_GRANDPRIX))
|
||||
{
|
||||
WRITEUINT8(demobuf.p, grandprixinfo.gamespeed);
|
||||
WRITEUINT8(demobuf.p, grandprixinfo.masterbots == true);
|
||||
WRITEUINT8(demobuf.p, grandprixinfo.eventmode);
|
||||
}
|
||||
|
||||
// Save "mapmusrng" used for altmusic selection
|
||||
WRITEUINT8(demobuf.p, mapmusrng);
|
||||
|
|
@ -2152,8 +2211,17 @@ void G_BeginRecording(void)
|
|||
i |= DEMO_KICKSTART;
|
||||
if (player->pflags & PF_SHRINKME)
|
||||
i |= DEMO_SHRINKME;
|
||||
if (player->bot == true)
|
||||
i |= DEMO_BOT;
|
||||
WRITEUINT8(demobuf.p, i);
|
||||
|
||||
if (i & DEMO_BOT)
|
||||
{
|
||||
WRITEUINT8(demobuf.p, player->botvars.difficulty);
|
||||
WRITEUINT8(demobuf.p, player->botvars.diffincrease); // needed to avoid having to duplicate logic
|
||||
WRITEUINT8(demobuf.p, (UINT8)player->botvars.rival);
|
||||
}
|
||||
|
||||
// Name
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, player_names[p], 16);
|
||||
|
|
@ -2806,7 +2874,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
UINT32 randseed;
|
||||
char msg[1024];
|
||||
|
||||
boolean spectator;
|
||||
boolean spectator, bot;
|
||||
UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0;
|
||||
|
||||
#if defined(SKIPERRORS) && !defined(DEVELOP)
|
||||
|
|
@ -3083,6 +3151,15 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
// net var data
|
||||
CV_LoadDemoVars(&demobuf.p);
|
||||
|
||||
memset(&grandprixinfo, 0, sizeof grandprixinfo);
|
||||
if ((demoflags & DF_GRANDPRIX))
|
||||
{
|
||||
grandprixinfo.gp = true;
|
||||
grandprixinfo.gamespeed = READUINT8(demobuf.p);
|
||||
grandprixinfo.masterbots = READUINT8(demobuf.p) != 0;
|
||||
grandprixinfo.eventmode = READUINT8(demobuf.p);
|
||||
}
|
||||
|
||||
// Load "mapmusrng" used for altmusic selection
|
||||
mapmusrng = READUINT8(demobuf.p);
|
||||
|
|
@ -3135,12 +3212,13 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
UINT8 flags = READUINT8(demobuf.p);
|
||||
|
||||
spectator = !!(flags & DEMO_SPECTATOR);
|
||||
bot = !!(flags & DEMO_BOT);
|
||||
|
||||
if (spectator == true)
|
||||
if ((spectator || bot))
|
||||
{
|
||||
if (modeattacking)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
|
||||
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with %s, and is thus invalid.\n"), pdemoname, (bot ? "bots" : "spectators"));
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
|
|
@ -3184,6 +3262,13 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
K_UpdateShrinkCheat(&players[p]);
|
||||
|
||||
if ((players[p].bot = bot) == true)
|
||||
{
|
||||
players[p].botvars.difficulty = READUINT8(demobuf.p);
|
||||
players[p].botvars.diffincrease = READUINT8(demobuf.p); // needed to avoid having to duplicate logic
|
||||
players[p].botvars.rival = (boolean)READUINT8(demobuf.p);
|
||||
}
|
||||
|
||||
// Name
|
||||
M_Memcpy(player_names[p],demobuf.p,16);
|
||||
demobuf.p += 16;
|
||||
|
|
@ -3435,6 +3520,11 @@ void G_AddGhost(char *defdemoname)
|
|||
p++;
|
||||
}
|
||||
|
||||
if ((flags & DF_GRANDPRIX))
|
||||
{
|
||||
p += 3;
|
||||
}
|
||||
|
||||
// Skip mapmusrng
|
||||
p++;
|
||||
|
||||
|
|
@ -3449,9 +3539,10 @@ void G_AddGhost(char *defdemoname)
|
|||
p++; // player number - doesn't really need to be checked, TODO maybe support adding multiple players' ghosts at once
|
||||
|
||||
// any invalidating flags?
|
||||
if ((READUINT8(p) & (DEMO_SPECTATOR)) != 0)
|
||||
i = READUINT8(p);
|
||||
if ((i & (DEMO_SPECTATOR|DEMO_BOT)) != 0)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot. (Spectator)\n"), pdemoname);
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot (spectator/bot)\n"), defdemoname);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(buffer);
|
||||
return;
|
||||
|
|
@ -3656,9 +3747,16 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
|||
p++; // stealth
|
||||
}
|
||||
|
||||
if ((flags & DF_GRANDPRIX))
|
||||
{
|
||||
p += 3;
|
||||
}
|
||||
|
||||
// Assert first player is in and then read name
|
||||
if (READUINT8(p) != 0)
|
||||
goto fail;
|
||||
if (READUINT8(p) & (DEMO_SPECTATOR|DEMO_BOT))
|
||||
goto fail;
|
||||
M_Memcpy(dummystaffname, p,16);
|
||||
dummystaffname[16] = '\0';
|
||||
|
||||
|
|
|
|||
15
src/g_demo.h
15
src/g_demo.h
|
|
@ -116,13 +116,14 @@ typedef enum
|
|||
extern UINT8 demo_extradata[MAXPLAYERS];
|
||||
extern UINT8 demo_writerng;
|
||||
|
||||
#define DXD_RESPAWN 0x01 // "respawn" command in console
|
||||
#define DXD_SKIN 0x02 // skin changed
|
||||
#define DXD_NAME 0x04 // name changed
|
||||
#define DXD_COLOR 0x08 // color changed
|
||||
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
|
||||
#define DXD_FOLLOWER 0x20 // follower was changed
|
||||
#define DXD_WEAPONPREF 0x40 // netsynced playsim settings were changed
|
||||
#define DXD_JOINDATA 0x01 // join-specific data
|
||||
#define DXD_PLAYSTATE 0x02 // state changed between playing, spectating, or not in-game
|
||||
#define DXD_NAME 0x04 // name changed
|
||||
#define DXD_SKIN 0x08 // skin changed
|
||||
#define DXD_COLOR 0x10 // color changed
|
||||
#define DXD_FOLLOWER 0x20 // follower was changed
|
||||
#define DXD_RESPAWN 0x40 // "respawn" command in console
|
||||
#define DXD_WEAPONPREF 0x80 // netsynced playsim settings were changed
|
||||
|
||||
#define DXD_PST_PLAYING 0x01
|
||||
#define DXD_PST_SPECTATING 0x02
|
||||
|
|
|
|||
45
src/g_game.c
45
src/g_game.c
|
|
@ -1177,7 +1177,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
*kbl = false;
|
||||
|
||||
// looking up/down
|
||||
cmd->aiming += (mlooky<<19)*player_invert*screen_invert;
|
||||
cmd->aiming += (mlooky<<3)*player_invert*screen_invert;
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
@ -1185,7 +1185,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
INT32 axis = G_PlayerInputAnalog(forplayer, gc_lookup, false) - G_PlayerInputAnalog(forplayer, gc_lookdown, false);
|
||||
|
||||
if (axis != 0 && spectating)
|
||||
cmd->aiming += (axis<<16) * screen_invert;
|
||||
cmd->aiming += axis * screen_invert;
|
||||
|
||||
// spring back if not using keyboard neither mouselookin'
|
||||
/*
|
||||
|
|
@ -1570,6 +1570,24 @@ boolean G_Responder(event_t *ev)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
else if (gamestate == GS_BLANCREDITS)
|
||||
{
|
||||
if (HU_Responder(ev))
|
||||
{
|
||||
hu_keystrokes = true;
|
||||
return true; // chat ate the event
|
||||
}
|
||||
|
||||
if (F_CreditResponder(ev))
|
||||
{
|
||||
// Skip credits for everyone
|
||||
if (! netgame)
|
||||
F_StartGameEvaluation();
|
||||
else if (server || IsPlayerAdmin(consoleplayer))
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (gamestate == GS_CONTINUING)
|
||||
{
|
||||
return true;
|
||||
|
|
@ -1978,7 +1996,7 @@ void G_Ticker(boolean run)
|
|||
}
|
||||
}
|
||||
|
||||
D_MapChange(gamemap, gametype, (cv_kartencore.value == 1), false, 1, false, false);
|
||||
D_MapChange(gamemap, gametype, encoremode, false, 1, false, false);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -2098,6 +2116,12 @@ void G_Ticker(boolean run)
|
|||
HU_Ticker();
|
||||
break;
|
||||
|
||||
case GS_BLANCREDITS:
|
||||
if (run)
|
||||
F_BlanCreditTicker();
|
||||
HU_Ticker();
|
||||
break;
|
||||
|
||||
case GS_TITLESCREEN:
|
||||
if (titlemapinaction)
|
||||
P_Ticker(run);
|
||||
|
|
@ -2260,6 +2284,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
UINT16 nocontrol;
|
||||
INT32 kickstartaccel;
|
||||
boolean enteredGame;
|
||||
UINT8 lastsafelap;
|
||||
UINT8 lastsafestarpost;
|
||||
UINT16 bigwaypointgap;
|
||||
|
||||
score = players[player].score;
|
||||
lives = players[player].lives;
|
||||
|
|
@ -2313,6 +2340,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
wanted = 0;
|
||||
rings = 10;
|
||||
kickstartaccel = 0;
|
||||
lastsafelap = 0;
|
||||
lastsafestarpost = 0;
|
||||
bigwaypointgap = 0;
|
||||
nocontrol = 0;
|
||||
laps = 0;
|
||||
latestlap = 0;
|
||||
|
|
@ -2380,6 +2410,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
prevcheck = players[player].nextcheck;
|
||||
|
||||
pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_LOSTLIFE|PF_FLIPCAM));
|
||||
|
||||
lastsafelap = players[player].lastsafelap;
|
||||
lastsafestarpost = players[player].lastsafestarpost;
|
||||
bigwaypointgap = players[player].bigwaypointgap;
|
||||
}
|
||||
|
||||
if (!betweenmaps)
|
||||
|
|
@ -2414,6 +2448,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->splitscreenindex = splitscreenindex;
|
||||
p->spectator = spectator;
|
||||
p->angleturn = playerangleturn;
|
||||
p->lastsafelap = lastsafelap;
|
||||
p->lastsafestarpost = lastsafestarpost;
|
||||
p->bigwaypointgap = bigwaypointgap;
|
||||
|
||||
// save player config truth reborn
|
||||
p->skincolor = skincolor;
|
||||
|
|
@ -3071,7 +3108,7 @@ void G_FinishExitLevel(void)
|
|||
|
||||
// Don't save demos immediately here! Let standings write first
|
||||
}
|
||||
else if (gamestate == GS_CREDITS)
|
||||
else if (gamestate == GS_CREDITS || gamestate == GS_BLANCREDITS)
|
||||
{
|
||||
F_StartGameEvaluation();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ void weaponPrefChange3(void);
|
|||
void weaponPrefChange4(void);
|
||||
|
||||
// mouseaiming (looking up/down with the mouse or keyboard)
|
||||
#define KB_LOOKSPEED (1<<25)
|
||||
#define KB_LOOKSPEED (1<<9)
|
||||
#define MAXPLMOVE (50)
|
||||
#define SLOWTURNTICS (cv_turnsmooth.value * 3)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,10 @@ typedef enum
|
|||
|
||||
// Not fadable
|
||||
GS_DEDICATEDSERVER, // new state for dedicated server
|
||||
GS_WAITINGPLAYERS // waiting for players in a net game
|
||||
GS_WAITINGPLAYERS, // waiting for players in a net game
|
||||
|
||||
// New
|
||||
GS_BLANCREDITS, // BlanKart: Credits for BlanKart
|
||||
} gamestate_t;
|
||||
|
||||
typedef enum
|
||||
|
|
|
|||
|
|
@ -2143,7 +2143,9 @@ void HU_Drawer(void)
|
|||
|| gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION
|
||||
|| gamestate == GS_GAMEEND
|
||||
|| gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS) // SRB2kart
|
||||
|| gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS
|
||||
|| gamestate == GS_BLANCREDITS
|
||||
) // SRB2kart
|
||||
return;
|
||||
|
||||
// draw multiplayer rankings
|
||||
|
|
|
|||
|
|
@ -568,9 +568,12 @@ _(ISTB) // instashield layer B
|
|||
_(PWCL) // Invinc/grow clash VFX
|
||||
|
||||
_(ARRO) // player arrows
|
||||
_(ITEM)
|
||||
_(ITMO)
|
||||
_(ITMI)
|
||||
_(ITEM) // base item
|
||||
_(ITMO) // Multi-Orbinaut
|
||||
_(ITMI) // Invincibility
|
||||
_(ITSN) // Multi-Sneaker
|
||||
_(ITBA) // Multi-Banana
|
||||
_(ITJA) // Multi-Jawz
|
||||
_(ITMN)
|
||||
_(WANT)
|
||||
|
||||
|
|
|
|||
|
|
@ -717,17 +717,6 @@ void K_ThunderShieldAttack(mobj_t *actor, fixed_t size)
|
|||
|
||||
boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
if (t1->type == MT_PLAYER)
|
||||
{
|
||||
// Bubble Shield already has a hitbox, and it gets
|
||||
// teleported every tic so the Bubble itself will
|
||||
// always make contact with other objects.
|
||||
//
|
||||
// Therefore, we don't need a second, smaller hitbox
|
||||
// on the player.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t2->type == MT_PLAYER)
|
||||
{
|
||||
// Counter desyncs
|
||||
|
|
@ -745,7 +734,7 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
|
|||
return true;
|
||||
|
||||
// Player Damage
|
||||
P_DamageMobj(t2, t1->target, t1, 1, DMG_NORMAL);
|
||||
P_DamageMobj(t2, ((t1->type == MT_BUBBLESHIELD) ? t1->target : t1), t1, 1, DMG_NORMAL);
|
||||
|
||||
if (t1->target->player)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4299,6 +4299,11 @@ static void K_DrawWaypointDebugger(void)
|
|||
if (stplyr != &players[displayplayers[0]]) // only for p1
|
||||
return;
|
||||
|
||||
if (stplyr->bigwaypointgap)
|
||||
{
|
||||
V_DrawString(8, 146, 0, va("Auto Respawn Timer: %d", stplyr->bigwaypointgap));
|
||||
}
|
||||
|
||||
V_DrawString(8, 156, 0, va("Current Waypoint ID: %d", K_GetWaypointID(stplyr->currentwaypoint)));
|
||||
V_DrawString(8, 166, 0, va("Next Waypoint ID: %d", K_GetWaypointID(stplyr->nextwaypoint)));
|
||||
V_DrawString(8, 176, 0, va("Finishline Distance: %d", stplyr->distancetofinish));
|
||||
|
|
|
|||
122
src/k_kart.c
122
src/k_kart.c
|
|
@ -238,6 +238,7 @@ void K_RegisterKartStuff(void)
|
|||
CV_RegisterVar(&cv_kartdebugdistribution);
|
||||
CV_RegisterVar(&cv_kartdebughuddrop);
|
||||
CV_RegisterVar(&cv_kartdebugwaypoints);
|
||||
CV_RegisterVar(&cv_kartdebuglap);
|
||||
CV_RegisterVar(&cv_kartdebugbotpredict);
|
||||
|
||||
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
||||
|
|
@ -7025,6 +7026,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
if (player->checkskip)
|
||||
player->checkskip--;
|
||||
|
||||
if (player->bigwaypointgap && (player->bigwaypointgap > AUTORESPAWN_THRESHOLD || !P_PlayerInPain(player)))
|
||||
{
|
||||
player->bigwaypointgap--;
|
||||
if (!player->bigwaypointgap)
|
||||
P_KillMobj(player->mo, NULL, NULL, DMG_INSTAKILL);
|
||||
else if (player->bigwaypointgap == AUTORESPAWN_THRESHOLD)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s26d);
|
||||
CONS_Printf("You are going the wrong way! You will automatically respawn in 7 seconds.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (player->growshrinktimer != 0)
|
||||
{
|
||||
if (player->growshrinktimer > 0)
|
||||
|
|
@ -7891,7 +7904,24 @@ static boolean K_SetPlayerNextWaypoint(player_t *player)
|
|||
continue;
|
||||
}
|
||||
|
||||
bestwaypoint = waypoint->prevwaypoints[i];
|
||||
if ((waypoint->nextwaypoints != NULL) && (waypoint->numnextwaypoints > 0U))
|
||||
{
|
||||
for (size_t j = 0U; j < waypoint->numnextwaypoints; j++)
|
||||
{
|
||||
if (!K_GetWaypointIsEnabled(waypoint->nextwaypoints[j]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (waypoint->nextwaypoints[j] == waypoint)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bestwaypoint = waypoint->nextwaypoints[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nextbestdelta = angledelta;
|
||||
nextbestmomdelta = momdelta;
|
||||
|
|
@ -8117,7 +8147,7 @@ static void K_UpdateDistanceFromFinishLine(player_t *player)
|
|||
const mapheader_t *mapheader = mapheaderinfo[gamemap - 1];
|
||||
if ((mapheader->levelflags & LF_SECTIONRACE) == 0U)
|
||||
{
|
||||
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps);
|
||||
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps) / mapheader->lapspersection;
|
||||
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
||||
}
|
||||
}
|
||||
|
|
@ -8166,24 +8196,59 @@ static void K_UpdatePlayerWaypoints(player_t *const player)
|
|||
boolean updaterespawn = K_SetPlayerNextWaypoint(player);
|
||||
|
||||
// Update prev value (used for grief prevention code)
|
||||
K_UpdateDistanceFromFinishLine(player);
|
||||
player->distancetofinishprev = player->distancetofinish;
|
||||
K_UpdateDistanceFromFinishLine(player);
|
||||
|
||||
// Respawning should be a full reset.
|
||||
UINT32 delta = u32_delta(player->distancetofinish, player->distancetofinishprev);
|
||||
if (!player->respawn && delta > distance_threshold)
|
||||
if (delta > distance_threshold &&
|
||||
!player->respawn && // Respawning should be a full reset.
|
||||
old_currentwaypoint != NULL && // So should touching the first waypoint ever.
|
||||
player->laps != 0 && // POSITION rooms may have unorthodox waypoints to guide bots.
|
||||
!(player->pflags & PF_TRUSTWAYPOINTS)) // Special exception.
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %s: waypoint ID %d too far away (%u > %u)\n",
|
||||
sizeu1(player - players), K_GetWaypointID(player->nextwaypoint), delta, distance_threshold);
|
||||
#define debug_args "Player %s: waypoint ID %d too far away (%u > %u)\n", \
|
||||
sizeu1(player - players), K_GetWaypointID(player->nextwaypoint), delta, distance_threshold
|
||||
if (cv_kartdebuglap.value)
|
||||
CONS_Printf(debug_args);
|
||||
else
|
||||
CONS_Debug(DBG_GAMELOGIC, debug_args);
|
||||
#undef debug_args
|
||||
|
||||
// Distance jump is too great, keep the old waypoints and recalculate distance.
|
||||
player->currentwaypoint = old_currentwaypoint;
|
||||
player->nextwaypoint = old_nextwaypoint;
|
||||
player->distancetofinish = player->distancetofinishprev;
|
||||
if (!cv_kartdebuglap.value)
|
||||
{
|
||||
// Distance jump is too great, keep the old waypoints and old distance.
|
||||
player->currentwaypoint = old_currentwaypoint;
|
||||
player->nextwaypoint = old_nextwaypoint;
|
||||
player->distancetofinish = player->distancetofinishprev;
|
||||
|
||||
// Start the auto respawn timer when the distance jumps.
|
||||
if (!player->bigwaypointgap)
|
||||
{
|
||||
player->bigwaypointgap = AUTORESPAWN_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset the auto respawn timer if distance changes are back to normal.
|
||||
if (player->bigwaypointgap && player->bigwaypointgap <= AUTORESPAWN_THRESHOLD + 1)
|
||||
{
|
||||
player->bigwaypointgap = 0;
|
||||
|
||||
// While the player was in the "bigwaypointgap" state, laps did not change from crossing finish lines.
|
||||
// So reset the lap back to normal, in case they were able to get behind the line.
|
||||
player->laps = player->lastsafelap;
|
||||
if (numbosswaypoints == 0)
|
||||
{
|
||||
player->starpostnum = player->lastsafestarpost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Respawn point should only be updated when we're going to a nextwaypoint
|
||||
if ((updaterespawn) &&
|
||||
(player->bigwaypointgap == 0) &&
|
||||
(!player->respawn) &&
|
||||
(player->nextwaypoint != old_nextwaypoint) &&
|
||||
(K_GetWaypointIsSpawnpoint(player->nextwaypoint)) &&
|
||||
|
|
@ -8192,6 +8257,9 @@ static void K_UpdatePlayerWaypoints(player_t *const player)
|
|||
if (!(player->pflags & PF_WRONGWAY))
|
||||
player->grieftime = 0;
|
||||
|
||||
player->lastsafelap = player->laps;
|
||||
player->lastsafestarpost = player->starpostnum;
|
||||
|
||||
// Check if respawn is safe. If not then goto next spawnpoint and respawn there.
|
||||
if (K_SafeRespawnPosition(player->mo))
|
||||
{
|
||||
|
|
@ -8207,12 +8275,14 @@ static void K_UpdatePlayerWaypoints(player_t *const player)
|
|||
}
|
||||
else
|
||||
{
|
||||
mobj_t *currentwaypoint = player->currentwaypoint->mobj;
|
||||
mobj_t *safewaypoint = player->nextwaypoint->mobj;
|
||||
angle_t respawnangle = R_PointToAngle2(currentwaypoint->x, currentwaypoint->y, safewaypoint->x, safewaypoint->y);
|
||||
|
||||
player->starposttime = player->realtime;
|
||||
player->starpostz = safewaypoint->spawnpoint->z >> FRACBITS;
|
||||
player->starpostflip = (safewaypoint->flags2 & MF2_OBJECTFLIP);
|
||||
player->starpostangle = safewaypoint->spawnpoint ? FixedAngle(safewaypoint->spawnpoint->angle * FRACUNIT) : player->mo->angle;
|
||||
player->starpostangle = respawnangle;
|
||||
|
||||
// Then do x and y
|
||||
player->starpostx = safewaypoint->x >> FRACBITS;
|
||||
|
|
@ -8225,6 +8295,8 @@ static void K_UpdatePlayerWaypoints(player_t *const player)
|
|||
K_FudgeRespawn(player, player->nextwaypoint);
|
||||
}
|
||||
}
|
||||
|
||||
player->pflags &= ~PF_TRUSTWAYPOINTS; // clear special exception
|
||||
}
|
||||
|
||||
INT32 K_GetKartRingPower(player_t *player, boolean boosted)
|
||||
|
|
@ -8800,6 +8872,16 @@ void K_UpdateAllPlayerPositions(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (player->respawn > 0 && player->lastsafelap != player->laps)
|
||||
{
|
||||
player->laps = player->lastsafelap;
|
||||
|
||||
if (numbosswaypoints == 0)
|
||||
{
|
||||
player->starpostnum = player->lastsafestarpost;
|
||||
}
|
||||
}
|
||||
|
||||
K_UpdatePlayerWaypoints(player);
|
||||
}
|
||||
|
||||
|
|
@ -10034,9 +10116,9 @@ UINT8 K_GetInvincibilityItemFrame(void)
|
|||
return ((leveltime % (7*3)) / 3);
|
||||
}
|
||||
|
||||
UINT8 K_GetOrbinautItemFrame(UINT8 count)
|
||||
UINT8 K_GetMultItemFrame(UINT8 count, UINT8 max)
|
||||
{
|
||||
return min(count - 1, 3);
|
||||
return min(count - 1, max);
|
||||
}
|
||||
|
||||
boolean K_IsSPBInGame(void)
|
||||
|
|
@ -10092,9 +10174,21 @@ void K_UpdateMobjItemOverlay(mobj_t *part, SINT8 itemType, UINT8 itemCount)
|
|||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case KITEM_SNEAKER:
|
||||
part->sprite = SPR_ITSN;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetMultItemFrame(itemCount, 2);
|
||||
break;
|
||||
case KITEM_ORBINAUT:
|
||||
part->sprite = SPR_ITMO;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(itemCount);
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetMultItemFrame(itemCount, 3);
|
||||
break;
|
||||
case KITEM_BANANA:
|
||||
part->sprite = SPR_ITBA;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetMultItemFrame(itemCount, 3);
|
||||
break;
|
||||
case KITEM_JAWZ:
|
||||
part->sprite = SPR_ITJA;
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetMultItemFrame(itemCount, 1);
|
||||
break;
|
||||
case KITEM_INVINCIBILITY:
|
||||
part->sprite = SPR_ITMI;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ Make sure this matches the actual number of states
|
|||
#define GROW_SCALE ((3*FRACUNIT)/2)
|
||||
#define SHRINK_SCALE ((6*FRACUNIT)/8)
|
||||
|
||||
#define AUTORESPAWN_TIME (10 * TICRATE)
|
||||
#define AUTORESPAWN_THRESHOLD (7 * TICRATE)
|
||||
|
||||
// Used for respawning checks.
|
||||
|
||||
typedef struct respawnresult_s
|
||||
|
|
@ -166,7 +169,7 @@ SINT8 K_Sliptiding(player_t *player);
|
|||
void K_MoveKartPlayer(player_t *player, boolean onground);
|
||||
void K_CheckSpectateStatus(boolean considermapreset);
|
||||
UINT8 K_GetInvincibilityItemFrame(void);
|
||||
UINT8 K_GetOrbinautItemFrame(UINT8 count);
|
||||
UINT8 K_GetMultItemFrame(UINT8 count, UINT8 max);
|
||||
boolean K_IsSPBInGame(void);
|
||||
|
||||
// sound stuff for lua
|
||||
|
|
|
|||
|
|
@ -2609,6 +2609,8 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->palette);
|
||||
else if (fastcmp(field,"numlaps"))
|
||||
lua_pushinteger(L, header->numlaps);
|
||||
else if (fastcmp(field,"lapspersection"))
|
||||
lua_pushinteger(L, header->lapspersection);
|
||||
else if (fastcmp(field,"unlockrequired"))
|
||||
lua_pushinteger(L, header->unlockrequired);
|
||||
else if (fastcmp(field,"levelselect"))
|
||||
|
|
|
|||
|
|
@ -388,6 +388,12 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->confirmVictimDelay);
|
||||
else if (fastcmp(field,"glanceDir"))
|
||||
lua_pushinteger(L, plr->glanceDir);
|
||||
else if (fastcmp(field,"breathTimer"))
|
||||
lua_pushinteger(L, plr->breathTimer);
|
||||
else if (fastcmp(field,"lastsafelap"))
|
||||
lua_pushinteger(L, plr->lastsafelap);
|
||||
else if (fastcmp(field,"laststarpost"))
|
||||
lua_pushinteger(L, plr->lastsafestarpost);
|
||||
else if (fastcmp(field,"roundscore"))
|
||||
plr->roundscore = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"marescore"))
|
||||
|
|
@ -799,6 +805,12 @@ static int player_set(lua_State *L)
|
|||
plr->confirmVictimDelay = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"glanceDir"))
|
||||
plr->glanceDir = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"breathTimer"))
|
||||
plr->breathTimer = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"lastsafelap"))
|
||||
plr->lastsafelap = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"lastsafestarpost"))
|
||||
plr->lastsafestarpost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"roundscore"))
|
||||
lua_pushinteger(L, plr->roundscore);
|
||||
else if (fastcmp(field,"marescore"))
|
||||
|
|
|
|||
144
src/m_menu.c
144
src/m_menu.c
|
|
@ -225,6 +225,7 @@ static void M_GetAllEmeralds(INT32 choice);
|
|||
static void M_DestroyRobots(INT32 choice);
|
||||
//static void M_LevelSelectWarp(INT32 choice);
|
||||
static void M_Credits(INT32 choice);
|
||||
static void M_BlanCredits(INT32 choice);
|
||||
static void M_PandorasBox(INT32 choice);
|
||||
static void M_EmblemHints(INT32 choice);
|
||||
static char *M_GetConditionString(condition_t cond);
|
||||
|
|
@ -303,6 +304,10 @@ static void M_AssignJoystick(INT32 choice);
|
|||
static void M_ChangeControl(INT32 choice);
|
||||
static void M_ResetControls(INT32 choice);
|
||||
|
||||
//camera options menu
|
||||
menu_t OP_CamOptionsDef;
|
||||
menu_t OP_Player1CamOptionsDef, OP_Player2CamOptionsDef, OP_Player3CamOptionsDef, OP_Player4CamOptionsDef;
|
||||
|
||||
// Video & Sound
|
||||
menu_t OP_VideoOptionsDef, OP_VideoModeDef;
|
||||
#ifdef HWRENDER
|
||||
|
|
@ -1071,19 +1076,85 @@ enum
|
|||
// Prefix: OP_
|
||||
static menuitem_t OP_MainMenu[] =
|
||||
{
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Control Setup...", {.submenu = &OP_ControlsDef}, 10},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Control Setup...", {.submenu = &OP_ControlsDef}, 10},
|
||||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Video Options...", {.submenu = &OP_VideoOptionsDef}, 30},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Sound Options...", {.submenu = &OP_SoundOptionsDef}, 40},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Video Options...", {.submenu = &OP_VideoOptionsDef}, 30},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Sound Options...", {.submenu = &OP_SoundOptionsDef}, 40},
|
||||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "HUD Options...", {.submenu = &OP_HUDOptionsDef}, 60},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Gameplay Options...", {.submenu = &OP_GameOptionsDef}, 70},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Server Options...", {.submenu = &OP_ServerOptionsDef}, 80},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "HUD Options...", {.submenu = &OP_HUDOptionsDef}, 60},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Camera Options...", {.submenu = &OP_CamOptionsDef}, 70},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Gameplay Options...", {.submenu = &OP_GameOptionsDef}, 80},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Server Options...", {.submenu = &OP_ServerOptionsDef}, 90},
|
||||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Data Options...", {.submenu = &OP_DataOptionsDef}, 100},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Data Options...", {.submenu = &OP_DataOptionsDef}, 110},
|
||||
|
||||
{IT_CALL|IT_STRING, NULL, "Tricks & Secrets (F1)", {.routine = M_Manual}, 120},
|
||||
{IT_CALL|IT_STRING, NULL, "Play Credits", {.routine = M_Credits}, 130},
|
||||
{IT_CALL|IT_STRING, NULL, "Tricks & Secrets (F1)", {.routine = M_Manual}, 130},
|
||||
{IT_CALL|IT_STRING, NULL, "Play Kart Credits", {.routine = M_Credits}, 140},
|
||||
{IT_CALL|IT_STRING, NULL, "Play BlanKart Credits", {.routine = M_BlanCredits}, 150},
|
||||
};
|
||||
|
||||
static menuitem_t OP_CamOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Camera Options", {NULL}, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Lagless Camera", {.cvar = &cv_laglesscam}, 20},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Player 1 Camera options...", {.submenu = &OP_Player1CamOptionsDef}, 40},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Player 2 Camera options...", {.submenu = &OP_Player2CamOptionsDef}, 50},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Player 3 Camera options...", {.submenu = &OP_Player3CamOptionsDef}, 60},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Player 4 Camera options...", {.submenu = &OP_Player4CamOptionsDef}, 70},
|
||||
};
|
||||
|
||||
static menuitem_t OP_Player1CamOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Player 1 Camera Options", {NULL}, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[0]}, 30},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[0]}, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[0]}, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[0]}, 60},
|
||||
//{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[0]}, 85},
|
||||
};
|
||||
|
||||
static menuitem_t OP_Player2CamOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Player 2 Camera Options", {NULL}, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[1]}, 30},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[1]}, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[1]}, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[1]}, 60},
|
||||
//{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[1]}, 85},
|
||||
};
|
||||
|
||||
static menuitem_t OP_Player3CamOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Player 3 Camera Options", {NULL}, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[2]}, 30},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[2]}, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[2]}, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[2]}, 60},
|
||||
//{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[2]}, 85},
|
||||
};
|
||||
|
||||
static menuitem_t OP_Player4CamOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Player 4 Camera Options", {NULL}, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[3]}, 30},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[3]}, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[3]}, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[3]}, 60},
|
||||
//{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[3]}, 85},
|
||||
};
|
||||
|
||||
static menuitem_t OP_ControlsMenu[] =
|
||||
|
|
@ -1990,6 +2061,12 @@ menu_t OP_HUDOptionsDef =
|
|||
NULL
|
||||
};
|
||||
|
||||
menu_t OP_CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_CamOptionsMenu, &OP_MainDef, 30, 30);
|
||||
menu_t OP_Player1CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player1CamOptionsMenu, &OP_CamOptionsDef, 30, 30);
|
||||
menu_t OP_Player2CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player2CamOptionsMenu, &OP_CamOptionsDef, 30, 30);
|
||||
menu_t OP_Player3CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player3CamOptionsMenu, &OP_CamOptionsDef, 30, 30);
|
||||
menu_t OP_Player4CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player4CamOptionsMenu, &OP_CamOptionsDef, 30, 30);
|
||||
|
||||
menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 30);
|
||||
|
||||
menu_t OP_GameOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_GAME", OP_GameOptionsMenu, &OP_MainDef, 30, 30);
|
||||
|
|
@ -2364,33 +2441,23 @@ static void M_ChangeCvar(INT32 choice)
|
|||
|
||||
choice = (choice<<1) - 1;
|
||||
|
||||
if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER)
|
||||
||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER)
|
||||
||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD))
|
||||
if (cv->flags & CV_FLOAT)
|
||||
{
|
||||
if (cv == &cv_digmusicvolume || cv == &cv_soundvolume)
|
||||
if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER)
|
||||
||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER)
|
||||
||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD)
|
||||
|| !(currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP))
|
||||
{
|
||||
choice *= 5;
|
||||
char s[20];
|
||||
float n = FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f);
|
||||
sprintf(s,"%ld%s",(long)n,M_Ftrim(n));
|
||||
CV_Set(cv,s);
|
||||
}
|
||||
|
||||
CV_SetValue(cv,cv->value+choice);
|
||||
}
|
||||
else if (cv->flags & CV_FLOAT)
|
||||
{
|
||||
char s[20];
|
||||
sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f));
|
||||
CV_Set(cv,s);
|
||||
else
|
||||
CV_SetValue(cv,FIXED_TO_FLOAT(cv->value)+(choice));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cv == &cv_nettimeout || cv == &cv_jointimeout)
|
||||
choice *= (TICRATE/7);
|
||||
else if (cv == &cv_maxsend)
|
||||
choice *= 512;
|
||||
else if (cv == &cv_maxping)
|
||||
choice *= 50;
|
||||
CV_AddValue(cv,choice);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean M_ChangeStringCvar(INT32 choice)
|
||||
|
|
@ -2494,7 +2561,9 @@ boolean M_Responder(event_t *ev)
|
|||
|
||||
if (dedicated || (demo.playback && demo.title)
|
||||
|| gamestate == GS_INTRO || gamestate == GS_CUTSCENE || gamestate == GS_GAMEEND
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION
|
||||
|| gamestate == GS_BLANCREDITS
|
||||
)
|
||||
return false;
|
||||
|
||||
if (CON_Ready() && gamestate != GS_WAITINGPLAYERS)
|
||||
|
|
@ -6270,9 +6339,10 @@ static void M_Options(INT32 choice)
|
|||
(void)choice;
|
||||
|
||||
// if the player is not admin or server, disable gameplay & server options
|
||||
OP_MainMenu[4].status = OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||
OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||
|
||||
OP_MainMenu[8].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // Play credits
|
||||
OP_MainMenu[9].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // Play credits
|
||||
OP_MainMenu[10].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // Play credits
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
OP_DataOptionsMenu[4].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); // Erase data
|
||||
|
|
@ -6773,6 +6843,14 @@ static void M_Credits(INT32 choice)
|
|||
F_StartCredits();
|
||||
}
|
||||
|
||||
static void M_BlanCredits(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
cursaveslot = -2;
|
||||
M_ClearMenus(true);
|
||||
F_BlanStartCredits();
|
||||
}
|
||||
|
||||
/*static void M_CustomLevelSelect(INT32 choice)
|
||||
{
|
||||
INT32 ul = skyRoomMenuTranslations[choice-1];
|
||||
|
|
|
|||
37
src/p_mobj.c
37
src/p_mobj.c
|
|
@ -4151,8 +4151,20 @@ static void P_RefreshItemCapsuleParts(mobj_t *mobj)
|
|||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case KITEM_SNEAKER:
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 2))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_ORBINAUT: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetOrbinautItemFrame(mobj->movecount))
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 3))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_BANANA: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 3))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_JAWZ: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 1))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_SUPERRING: // always display the number, and multiply it by 5
|
||||
|
|
@ -6048,25 +6060,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
|
||||
switch (mobj->target->player->itemtype)
|
||||
{
|
||||
case KITEM_ORBINAUT:
|
||||
mobj->tracer->sprite = SPR_ITMO;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|K_GetOrbinautItemFrame(mobj->target->player->itemamount);
|
||||
break;
|
||||
case KITEM_INVINCIBILITY:
|
||||
mobj->tracer->sprite = SPR_ITMI;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|K_GetInvincibilityItemFrame();
|
||||
break;
|
||||
case KITEM_SAD:
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT;
|
||||
break;
|
||||
default:
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|(mobj->target->player->itemtype);
|
||||
break;
|
||||
}
|
||||
K_UpdateMobjItemOverlay(mobj->tracer, mobj->target->player->itemtype,mobj->target->player->itemamount);
|
||||
|
||||
if (mobj->target->player->itemflags & IF_ITEMOUT)
|
||||
{
|
||||
|
|
@ -6322,6 +6316,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
|
|||
{
|
||||
case MT_PLAYER:
|
||||
/// \todo Have the player's dead body completely finish its animation even if they've already respawned.
|
||||
|
||||
if (!mobj->fuse)
|
||||
{ // Go away.
|
||||
/// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it.
|
||||
|
|
@ -7410,9 +7405,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->extravalue2 = mobj->target->player->bubbleblowup;
|
||||
P_SetScale(mobj, (mobj->destscale = scale));
|
||||
|
||||
mobj->flags &= ~(MF_NOCLIPTHING);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
mobj->flags |= MF_NOCLIPTHING;
|
||||
break;
|
||||
}
|
||||
case MT_FLAMESHIELD:
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
WRITEUINT32(save->p, players[i].distancetofinishprev);
|
||||
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].currentwaypoint));
|
||||
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
|
||||
WRITEUINT16(save->p, players[i].bigwaypointgap);
|
||||
WRITEUINT32(save->p, players[i].airtime);
|
||||
WRITEUINT8(save->p, players[i].startboost);
|
||||
|
||||
|
|
@ -348,6 +349,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
|
||||
WRITEUINT16(save->p, players[i].breathTimer);
|
||||
|
||||
WRITEUINT8(save->p, players[i].lastsafelap);
|
||||
WRITEUINT8(save->p, players[i].lastsafestarpost);
|
||||
|
||||
WRITEUINT8(save->p, players[i].typing_timer);
|
||||
WRITEUINT8(save->p, players[i].typing_duration);
|
||||
|
||||
|
|
@ -552,7 +556,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].distancetofinish = READUINT32(save->p);
|
||||
players[i].distancetofinishprev = READUINT32(save->p);
|
||||
players[i].currentwaypoint = (waypoint_t *)(size_t)READUINT32(save->p);
|
||||
|
||||
players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save->p);
|
||||
players[i].bigwaypointgap = READUINT16(save->p);
|
||||
players[i].airtime = READUINT32(save->p);
|
||||
players[i].startboost = READUINT8(save->p);
|
||||
|
||||
|
|
@ -655,6 +661,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
|
||||
players[i].breathTimer = READUINT16(save->p);
|
||||
|
||||
players[i].lastsafelap = READUINT8(save->p);
|
||||
players[i].lastsafestarpost = READUINT8(save->p);
|
||||
|
||||
players[i].typing_timer = READUINT8(save->p);
|
||||
players[i].typing_duration = READUINT8(save->p);
|
||||
|
||||
|
|
|
|||
|
|
@ -427,6 +427,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
|
|||
mapheaderinfo[num]->palette = UINT16_MAX;
|
||||
mapheaderinfo[num]->encorepal = UINT16_MAX;
|
||||
mapheaderinfo[num]->numlaps = NUMLAPS_DEFAULT;
|
||||
mapheaderinfo[num]->lapspersection = 1;
|
||||
mapheaderinfo[num]->unlockrequired = -1;
|
||||
mapheaderinfo[num]->levelselect = 0;
|
||||
mapheaderinfo[num]->levelflags = 0;
|
||||
|
|
@ -7726,7 +7727,7 @@ static boolean P_SetMapNamespace(void)
|
|||
else if(fastcmp(tkn, "ringracers"))
|
||||
{
|
||||
mapnamespace = MNS_RINGRACERS;
|
||||
CONS_Alert(CONS_WARNING, "Ring Racers Map deteced. BlanKart has basic support for Ring Racers maps but does not fully support them. Consider converting your map to BlanKart format, consult documentation for help.\n");
|
||||
CONS_Alert(CONS_WARNING, "Ring Racers Map detected. BlanKart has basic support for Ring Racers maps but does not fully support them. Consider converting your map to BlanKart format, consult documentation for help.\n");
|
||||
}
|
||||
else if (fastcmp(tkn, "srb2"))
|
||||
{
|
||||
|
|
|
|||
18
src/p_spec.c
18
src/p_spec.c
|
|
@ -1970,11 +1970,23 @@ void P_SwitchWeather(preciptype_t newWeather)
|
|||
P_SpawnPrecipitation();
|
||||
}
|
||||
|
||||
static boolean K_IgnoreFinishLine(player_t *player)
|
||||
{
|
||||
// If potential lap cheating has been detected, do not
|
||||
// interact with the finish line at all.
|
||||
if (player->bigwaypointgap)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Passed over the finish line forwards
|
||||
static void K_HandleLapIncrement(player_t *player)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
if (K_IgnoreFinishLine(player))
|
||||
return;
|
||||
if (((numbosswaypoints > 0) ? (player->starpostnum >= (numstarposts - (numstarposts/2))) : (player->starpostnum == numstarposts)) || (player->laps == 0))
|
||||
{
|
||||
size_t i = 0;
|
||||
|
|
@ -1992,6 +2004,9 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
|
||||
player->starposttime = player->realtime;
|
||||
player->starpostnum = 0;
|
||||
player->lastsafestarpost = 0;
|
||||
player->laps++;
|
||||
|
||||
|
||||
if (mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||
{
|
||||
|
|
@ -2010,7 +2025,8 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
player->starpostangle = player->starpostx = player->starposty = player->starpostz = player->starpostflip = 0;
|
||||
}
|
||||
|
||||
player->laps++;
|
||||
if (!cv_kartdebuglap.value && player->laps == 1)
|
||||
player->pflags |= PF_TRUSTWAYPOINTS;
|
||||
K_UpdateAllPlayerPositions();
|
||||
|
||||
// Set up lap animation vars
|
||||
|
|
|
|||
52
src/p_tick.c
52
src/p_tick.c
|
|
@ -665,13 +665,6 @@ void P_Ticker(boolean run)
|
|||
players[i].jointime++;
|
||||
}
|
||||
|
||||
if (run)
|
||||
{
|
||||
// Update old view state BEFORE ticking so resetting
|
||||
// the old interpolation state from game logic works.
|
||||
R_UpdateViewInterpolation();
|
||||
}
|
||||
|
||||
if (objectplacing)
|
||||
{
|
||||
if (OP_FreezeObjectplace())
|
||||
|
|
@ -776,30 +769,33 @@ void P_Ticker(boolean run)
|
|||
// Plays the music after the starting countdown.
|
||||
else
|
||||
{
|
||||
if (!(gametyperules & GTR_FREEROAM) && !(titlemapinaction == TITLEMAP_RUNNING))
|
||||
if (!(titlemapinaction == TITLEMAP_RUNNING))
|
||||
{
|
||||
if (leveltime == starttime-(3*TICRATE))
|
||||
if (!(gametyperules & GTR_FREEROAM))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3ka7); // 3,
|
||||
if (leveltime == starttime-(3*TICRATE))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3ka7); // 3,
|
||||
}
|
||||
else if ((leveltime == starttime-(2*TICRATE)) || (leveltime == starttime-TICRATE))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3ka7); // 2, 1,
|
||||
}
|
||||
else if (leveltime == starttime)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3kad); // GO!
|
||||
}
|
||||
}
|
||||
else if ((leveltime == starttime-(2*TICRATE)) || (leveltime == starttime-TICRATE))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3ka7); // 2, 1,
|
||||
}
|
||||
else if (leveltime == starttime)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3kad); // GO!
|
||||
}
|
||||
}
|
||||
|
||||
if (!(gametyperules & GTR_FREEROAM) && leveltime < starttime) // SRB2Kart
|
||||
S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); // yes this will be spammed otherwise encore and some stuff WILL overwrite it
|
||||
else if (leveltime == starttime) // The GO! sound stops the level start ambience
|
||||
S_StopMusic();
|
||||
else if (leveltime == starttime + (TICRATE/2)) // Plays the music after the starting countdown.
|
||||
{
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
S_ShowMusicCredit();
|
||||
if (!(gametyperules & GTR_FREEROAM) && leveltime < starttime) // SRB2Kart
|
||||
S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); // yes this will be spammed otherwise encore and some stuff WILL overwrite it
|
||||
else if (leveltime == starttime) // The GO! sound stops the level start ambience
|
||||
S_StopMusic();
|
||||
else if (leveltime == starttime + (TICRATE/2)) // Plays the music after the starting countdown.
|
||||
{
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
S_ShowMusicCredit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -824,7 +820,7 @@ void P_Ticker(boolean run)
|
|||
|
||||
if (starttime > introtime && leveltime == starttime)
|
||||
{
|
||||
ACS_RunPositionScript();
|
||||
ACS_RunRaceStartScript();
|
||||
}
|
||||
|
||||
if (timelimitintics > 0 && leveltime == (timelimitintics + starttime + 1))
|
||||
|
|
|
|||
93
src/p_user.c
93
src/p_user.c
|
|
@ -61,6 +61,8 @@
|
|||
#include "k_color.h"
|
||||
#include "k_follower.h"
|
||||
|
||||
#include "acs/interface.h"
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
#endif
|
||||
|
|
@ -1324,6 +1326,8 @@ void P_DoPlayerExit(player_t *player)
|
|||
|
||||
if (player == &players[consoleplayer])
|
||||
demo.savebutton = leveltime;
|
||||
|
||||
ACS_RunPlayerFinishScript(player);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1832,8 +1836,6 @@ static void P_3dMovement(player_t *player)
|
|||
// Do not let the player control movement if not onground.
|
||||
// SRB2Kart: pogo spring and speed bumps are supposed to control like you're on the ground
|
||||
onground = (P_IsObjectOnGround(player->mo) || (player->pogospring));
|
||||
|
||||
player->aiming = cmd->aiming<<FRACBITS;
|
||||
|
||||
// Forward movement
|
||||
if (!((player->exiting || mapreset) || (P_PlayerInPain(player) && !onground)))
|
||||
|
|
@ -1954,24 +1956,60 @@ static void P_3dMovement(player_t *player)
|
|||
|
||||
boolean P_CanPlayerTurn(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
if (player->spectator || objectplacing) // Spectators come first.
|
||||
if (player->spectator || objectplacing)
|
||||
{
|
||||
// Spectators come first.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(gametyperules & GTR_FREEROAM) && !(leveltime > starttime)) // You can't move yet.
|
||||
return false;
|
||||
|
||||
if ((cmd->buttons & BT_ACCELERATE) && (cmd->buttons & BT_BRAKE)) // You are rubberburn turning.
|
||||
return true;
|
||||
|
||||
if (player->respawn) // You are Respawning.
|
||||
return true;
|
||||
|
||||
if (player->mo && player->speed == 0) // You need to be moving.
|
||||
if (((gametyperules & GTR_FREEROAM) || (leveltime > starttime))
|
||||
&& (cmd->buttons & BT_ACCELERATE)
|
||||
&& (cmd->buttons & BT_BRAKE))
|
||||
{
|
||||
// You are rubberburn turning.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player->respawn)
|
||||
{
|
||||
// You are Respawning.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player->mo && player->speed == 0)
|
||||
{
|
||||
// You need to be moving.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void P_UpdatePlayerAiming(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
int i;
|
||||
|
||||
if (!cv_allowmlook.value || player->spectator == false)
|
||||
{
|
||||
player->aiming = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->aiming += (cmd->aiming << TICCMD_REDUCE);
|
||||
player->aiming = G_ClipAimingPitch((INT32*) &player->aiming);
|
||||
}
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
localaiming[i] = player->aiming;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_UpdatePlayerAngle
|
||||
//
|
||||
|
|
@ -1983,7 +2021,6 @@ static void P_UpdatePlayerAngle(player_t *player)
|
|||
boolean add_delta = true;
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
angle_t anglechange = player->angleturn;
|
||||
int i;
|
||||
|
||||
// Kart: store the current turn range for later use
|
||||
if (P_CanPlayerTurn(player, cmd))
|
||||
|
|
@ -2031,14 +2068,7 @@ static void P_UpdatePlayerAngle(player_t *player)
|
|||
player->angleturn = anglechange;
|
||||
player->mo->angle = player->angleturn;
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
localaiming[i] = player->aiming;
|
||||
break;
|
||||
}
|
||||
}
|
||||
P_UpdatePlayerAiming(player);
|
||||
}
|
||||
|
||||
static void P_UpdateBotAngle(player_t* player)
|
||||
|
|
@ -2058,6 +2088,7 @@ static void P_SpectatorMovement(player_t *player)
|
|||
ticcmd_t *cmd = &player->cmd;
|
||||
|
||||
player->mo->angle = cmd->angle<<16;
|
||||
P_UpdatePlayerAiming(player);
|
||||
|
||||
ticruned++;
|
||||
if (!(cmd->flags & TICCMD_RECEIVED))
|
||||
|
|
@ -2586,6 +2617,24 @@ static void P_DeathThink(player_t *player)
|
|||
else
|
||||
player->karthud[khud_timeovercam] = 0;
|
||||
|
||||
// Set players next respawn point to the next waypoint
|
||||
// If they die while still in respawn state for extra safety.
|
||||
if (player->nextwaypoint && player->respawn > 0)
|
||||
{
|
||||
mobj_t *currentwaypoint = player->currentwaypoint->mobj;
|
||||
mobj_t *safewaypoint = player->nextwaypoint->mobj;
|
||||
angle_t respawnangle = R_PointToAngle2(currentwaypoint->x, currentwaypoint->y, safewaypoint->x, safewaypoint->y);
|
||||
|
||||
player->starposttime = player->realtime;
|
||||
player->starpostz = safewaypoint->spawnpoint->z >> FRACBITS;
|
||||
player->starpostflip = (safewaypoint->flags2 & MF2_OBJECTFLIP);
|
||||
player->starpostangle = respawnangle;
|
||||
|
||||
// Then do x and y
|
||||
player->starpostx = safewaypoint->x >> FRACBITS;
|
||||
player->starposty = safewaypoint->y >> FRACBITS;
|
||||
}
|
||||
|
||||
K_KartPlayerHUDUpdate(player);
|
||||
|
||||
if (player->pflags & PF_NOCONTEST)
|
||||
|
|
|
|||
|
|
@ -2539,6 +2539,12 @@ void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, con
|
|||
V_DrawThinStringAtFixed(x, y, option, string);
|
||||
}
|
||||
|
||||
void V_DrawCenteredStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
|
||||
{
|
||||
x -= (V_StringWidth(string, option) / 2) * FRACUNIT;
|
||||
V_DrawStringAtFixed(x, y, option, string);
|
||||
}
|
||||
|
||||
// Draws a number using the PING font thingy.
|
||||
// TODO: Merge number drawing functions into one with "font name" selection.
|
||||
|
||||
|
|
|
|||
|
|
@ -281,6 +281,9 @@ void V_DrawCenteredSmallString(INT32 x, INT32 y, INT32 option, const char *strin
|
|||
void V_DrawCenteredSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
// Draw a centered string.
|
||||
void V_DrawCenteredStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
|
||||
|
||||
// draw a string using the tny_font
|
||||
#define V_DrawThinString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,TINY_FONT,string)
|
||||
|
|
|
|||
Loading…
Reference in a new issue