2014-03-15 16:59:03 +00:00
|
|
|
// SONIC ROBO BLAST 2
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
|
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
2020-02-19 22:08:45 +00:00
|
|
|
// Copyright (C) 1999-2020 by Sonic Team Junior.
|
2014-03-15 16:59:03 +00:00
|
|
|
//
|
|
|
|
// This program is free software distributed under the
|
|
|
|
// terms of the GNU General Public License, version 2.
|
|
|
|
// See the 'LICENSE' file for more details.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// \file g_game.h
|
|
|
|
/// \brief Game loop, events handling.
|
|
|
|
|
|
|
|
#ifndef __G_GAME__
|
|
|
|
#define __G_GAME__
|
|
|
|
|
|
|
|
#include "doomdef.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "d_event.h"
|
2020-03-19 20:09:55 +00:00
|
|
|
#include "g_demo.h"
|
2020-09-06 09:33:17 +00:00
|
|
|
#include "m_cheat.h" // objectplacing
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
extern char gamedatafilename[64];
|
|
|
|
extern char timeattackfolder[64];
|
|
|
|
extern char customversionstring[32];
|
|
|
|
#define GAMEDATASIZE (4*8192)
|
|
|
|
|
|
|
|
extern player_t *seenplayer;
|
2020-09-01 03:08:22 +00:00
|
|
|
extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
|
|
|
extern INT32 player_name_changes[MAXPLAYERS];
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
extern player_t players[MAXPLAYERS];
|
|
|
|
extern boolean playeringame[MAXPLAYERS];
|
|
|
|
|
|
|
|
// gametic at level start
|
|
|
|
extern tic_t levelstarttic;
|
|
|
|
|
|
|
|
// for modding?
|
|
|
|
extern INT16 prevmap, nextmap;
|
|
|
|
extern INT32 gameovertics;
|
2019-08-26 23:07:17 +00:00
|
|
|
extern UINT8 ammoremovaltics;
|
2014-03-15 16:59:03 +00:00
|
|
|
extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display)
|
|
|
|
extern INT16 rw_maximums[NUM_WEAPONS];
|
2018-06-13 23:58:28 +00:00
|
|
|
extern INT32 pausedelay;
|
2018-11-21 16:10:18 +00:00
|
|
|
extern boolean pausebreakkey;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2019-07-29 13:55:36 +00:00
|
|
|
extern boolean promptactive;
|
|
|
|
|
2019-03-11 21:57:11 +00:00
|
|
|
extern consvar_t cv_pauseifunfocused;
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
// used in game menu
|
2018-11-13 00:10:41 +00:00
|
|
|
extern consvar_t cv_tutorialprompt;
|
2018-08-19 08:58:29 +00:00
|
|
|
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
2014-03-15 16:59:03 +00:00
|
|
|
extern consvar_t cv_crosshair, cv_crosshair2;
|
2018-11-22 22:04:24 +00:00
|
|
|
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove;
|
|
|
|
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2;
|
2019-12-30 21:05:24 +00:00
|
|
|
|
2019-12-30 20:01:14 +00:00
|
|
|
extern consvar_t cv_useranalog[2], cv_analog[2];
|
|
|
|
extern consvar_t cv_directionchar[2];
|
2019-12-30 21:05:24 +00:00
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
CS_LEGACY,
|
|
|
|
CS_LMAOGALOG,
|
|
|
|
CS_STANDARD,
|
|
|
|
CS_SIMPLE = CS_LMAOGALOG|CS_STANDARD,
|
|
|
|
} controlstyle_e;
|
2020-09-06 09:33:17 +00:00
|
|
|
#define G_ControlStyle(ssplayer) (cv_directionchar[(ssplayer)-1].value == 3 ? CS_LMAOGALOG : ((!objectplacing && cv_analog[(ssplayer)-1].value ? CS_LMAOGALOG : 0) | (cv_directionchar[(ssplayer)-1].value ? CS_STANDARD : 0)))
|
2019-12-30 21:05:24 +00:00
|
|
|
#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0))
|
|
|
|
|
2017-09-15 19:34:46 +00:00
|
|
|
extern consvar_t cv_autobrake, cv_autobrake2;
|
2019-12-15 01:41:54 +00:00
|
|
|
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone;
|
|
|
|
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2;
|
2014-03-15 16:59:03 +00:00
|
|
|
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
|
|
|
|
|
2019-12-08 20:17:48 +00:00
|
|
|
// hi here's some new controls
|
2019-12-30 21:15:37 +00:00
|
|
|
extern consvar_t cv_cam_shiftfacing[2], cv_cam_turnfacing[2],
|
2019-12-11 04:01:17 +00:00
|
|
|
cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2],
|
2019-12-15 01:17:41 +00:00
|
|
|
cv_cam_centertoggle[2], cv_cam_lockedinput[2], cv_cam_lockonboss[2];
|
2019-12-08 20:17:48 +00:00
|
|
|
|
2019-12-13 05:03:51 +00:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
LOCK_BOSS = 1<<0,
|
|
|
|
LOCK_ENEMY = 1<<1,
|
|
|
|
LOCK_INTERESTS = 1<<2,
|
|
|
|
} lockassist_e;
|
|
|
|
|
|
|
|
|
2021-03-24 08:54:11 +00:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
JA_NONE = 0,
|
|
|
|
JA_TURN,
|
|
|
|
JA_MOVE,
|
|
|
|
JA_LOOK,
|
|
|
|
JA_STRAFE,
|
|
|
|
|
|
|
|
JA_DIGITAL, // axes below this use digital deadzone
|
|
|
|
|
|
|
|
JA_JUMP,
|
|
|
|
JA_SPIN,
|
|
|
|
JA_FIRE,
|
|
|
|
JA_FIRENORMAL,
|
|
|
|
} joyaxis_e;
|
|
|
|
|
|
|
|
INT32 JoyAxis(joyaxis_e axissel);
|
|
|
|
INT32 Joy2Axis(joyaxis_e axissel);
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
// mouseaiming (looking up/down with the mouse or keyboard)
|
|
|
|
#define KB_LOOKSPEED (1<<25)
|
|
|
|
#define MAXPLMOVE (50)
|
|
|
|
#define SLOWTURNTICS (6)
|
|
|
|
|
|
|
|
// build an internal map name MAPxx from map number
|
|
|
|
const char *G_BuildMapName(INT32 map);
|
2019-12-10 02:21:32 +00:00
|
|
|
|
2020-05-28 09:03:35 +00:00
|
|
|
extern INT16 ticcmd_oldangleturn[2];
|
2019-12-12 03:09:23 +00:00
|
|
|
extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player
|
2019-12-12 06:48:15 +00:00
|
|
|
extern mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object?
|
2019-12-08 19:27:11 +00:00
|
|
|
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// copy ticcmd_t to and fro the normal way
|
|
|
|
ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
|
|
|
|
// copy ticcmd_t to and fro network packets
|
|
|
|
ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
|
|
|
|
|
|
|
|
// clip the console player aiming to the view
|
|
|
|
INT16 G_ClipAimingPitch(INT32 *aiming);
|
|
|
|
INT16 G_SoftwareClipAimingPitch(INT32 *aiming);
|
|
|
|
|
|
|
|
extern angle_t localangle, localangle2;
|
|
|
|
extern INT32 localaiming, localaiming2; // should be an angle_t but signed
|
|
|
|
|
|
|
|
//
|
|
|
|
// GAME
|
|
|
|
//
|
|
|
|
void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo);
|
|
|
|
void G_DoReborn(INT32 playernum);
|
2019-09-18 15:06:13 +00:00
|
|
|
void G_PlayerReborn(INT32 player, boolean betweenmaps);
|
2014-03-15 16:59:03 +00:00
|
|
|
void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer,
|
2017-02-01 21:31:35 +00:00
|
|
|
boolean skipprecutscene, boolean FLS);
|
2014-03-15 16:59:03 +00:00
|
|
|
char *G_BuildMapTitle(INT32 mapnum);
|
|
|
|
|
2019-02-24 05:25:53 +00:00
|
|
|
struct searchdim
|
|
|
|
{
|
|
|
|
UINT8 pos;
|
|
|
|
UINT8 siz;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
INT16 mapnum;
|
|
|
|
UINT8 matchc;
|
|
|
|
struct searchdim *matchd;/* offset that a pattern was matched */
|
|
|
|
UINT8 keywhc;
|
|
|
|
struct searchdim *keywhd;/* ...in KEYWORD */
|
|
|
|
UINT8 total;/* total hits */
|
|
|
|
}
|
|
|
|
mapsearchfreq_t;
|
|
|
|
|
|
|
|
INT32 G_FindMap(const char *query, char **foundmapnamep,
|
|
|
|
mapsearchfreq_t **freqp, INT32 *freqc);
|
|
|
|
void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc);
|
|
|
|
|
2019-12-29 10:14:02 +00:00
|
|
|
/* Match map name by search + 2 digit map code or map number. */
|
|
|
|
INT32 G_FindMapByNameOrCode(const char *query, char **foundmapnamep);
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
// XMOD spawning
|
|
|
|
mapthing_t *G_FindCTFStart(INT32 playernum);
|
|
|
|
mapthing_t *G_FindMatchStart(INT32 playernum);
|
|
|
|
mapthing_t *G_FindCoopStart(INT32 playernum);
|
2020-01-22 02:19:15 +00:00
|
|
|
mapthing_t *G_FindMapStart(INT32 playernum);
|
|
|
|
void G_MovePlayerToSpawnOrStarpost(INT32 playernum);
|
|
|
|
void G_SpawnPlayer(INT32 playernum);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// Can be called by the startup code or M_Responder.
|
|
|
|
// A normal game starts at map 1, but a warp test can start elsewhere
|
|
|
|
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,
|
|
|
|
boolean SSSG, boolean FLS);
|
|
|
|
void G_DoLoadLevel(boolean resetplayer);
|
2019-11-18 15:56:41 +00:00
|
|
|
void G_StartTitleCard(void);
|
2019-12-05 04:58:19 +00:00
|
|
|
void G_PreLevelTitleCard(void);
|
2019-12-24 19:22:25 +00:00
|
|
|
boolean G_IsTitleCardAvailable(void);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
|
|
|
|
void G_LoadGame(UINT32 slot, INT16 mapoverride);
|
|
|
|
|
|
|
|
void G_SaveGameData(void);
|
|
|
|
|
Special saves!
All this refactoring, just to resolve #162. Specifically, it engages savegame events not at level load (except for savefile start) but on level completion, just after you've gotten all the intermission bonuses but before the intermission actually starts.
Also fixes a never-before-discovered bug where if the titlemap has LF_SAVEGAME, your save file will be overwritten upon returning to the title screen. This game is a mess of hacks, I swear...
One unintended side effect: It may actually be faster in some speedrun circumstances in mods with cutscenes to complete the map, exit back to the title screen, and reload the file. It's a common feature of optimal runs in games with cutscenes, though, and Marathon Run has a toggle for cutscenes, so I'm not particularly bothered.
2020-06-22 18:00:47 +00:00
|
|
|
void G_SaveGame(UINT32 slot, INT16 mapnum);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2017-08-20 12:14:17 +00:00
|
|
|
void G_SaveGameOver(UINT32 slot, boolean modifylives);
|
2017-08-17 23:58:16 +00:00
|
|
|
|
2019-12-18 17:57:42 +00:00
|
|
|
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
|
2019-12-18 16:24:10 +00:00
|
|
|
extern UINT32 gametypetol[NUMGAMETYPES];
|
2019-12-19 01:02:37 +00:00
|
|
|
extern INT16 gametyperankings[NUMGAMETYPES];
|
2019-12-18 16:24:10 +00:00
|
|
|
|
2019-12-18 04:25:57 +00:00
|
|
|
void G_SetGametype(INT16 gametype);
|
2019-12-18 16:24:10 +00:00
|
|
|
INT16 G_AddGametype(UINT32 rules);
|
2019-12-19 05:13:09 +00:00
|
|
|
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst);
|
2019-12-18 18:41:03 +00:00
|
|
|
void G_UpdateGametypeSelections(void);
|
2019-12-18 16:24:10 +00:00
|
|
|
void G_AddTOL(UINT32 newtol, const char *tolname);
|
2019-12-18 18:41:03 +00:00
|
|
|
void G_AddGametypeTOL(INT16 gtype, UINT32 newtol);
|
|
|
|
void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor);
|
2019-12-18 15:23:42 +00:00
|
|
|
|
2017-06-25 16:28:07 +00:00
|
|
|
INT32 G_GetGametypeByName(const char *gametypestr);
|
2014-03-15 16:59:03 +00:00
|
|
|
boolean G_IsSpecialStage(INT32 mapnum);
|
|
|
|
boolean G_GametypeUsesLives(void);
|
2019-12-27 20:08:20 +00:00
|
|
|
boolean G_GametypeUsesCoopLives(void);
|
2019-12-27 20:14:56 +00:00
|
|
|
boolean G_GametypeUsesCoopStarposts(void);
|
2014-03-15 16:59:03 +00:00
|
|
|
boolean G_GametypeHasTeams(void);
|
|
|
|
boolean G_GametypeHasSpectators(void);
|
|
|
|
boolean G_RingSlingerGametype(void);
|
|
|
|
boolean G_PlatformGametype(void);
|
2020-02-29 03:57:22 +00:00
|
|
|
boolean G_CoopGametype(void);
|
2014-03-15 16:59:03 +00:00
|
|
|
boolean G_TagGametype(void);
|
2019-12-27 15:28:00 +00:00
|
|
|
boolean G_CompetitionGametype(void);
|
2019-11-15 14:35:28 +00:00
|
|
|
boolean G_EnoughPlayersFinished(void);
|
2014-03-15 16:59:03 +00:00
|
|
|
void G_ExitLevel(void);
|
|
|
|
void G_NextLevel(void);
|
|
|
|
void G_Continue(void);
|
|
|
|
void G_UseContinue(void);
|
|
|
|
void G_AfterIntermission(void);
|
2017-05-18 15:54:58 +00:00
|
|
|
void G_EndGame(void); // moved from y_inter.c/h and renamed
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
void G_Ticker(boolean run);
|
|
|
|
boolean G_Responder(event_t *ev);
|
|
|
|
|
|
|
|
void G_AddPlayer(INT32 playernum);
|
|
|
|
|
|
|
|
void G_SetExitGameFlag(void);
|
|
|
|
void G_ClearExitGameFlag(void);
|
|
|
|
boolean G_GetExitGameFlag(void);
|
2019-11-23 21:15:09 +00:00
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
void G_SetRetryFlag(void);
|
|
|
|
void G_ClearRetryFlag(void);
|
|
|
|
boolean G_GetRetryFlag(void);
|
|
|
|
|
2019-11-23 21:15:09 +00:00
|
|
|
void G_SetModeAttackRetryFlag(void);
|
|
|
|
void G_ClearModeAttackRetryFlag(void);
|
|
|
|
boolean G_GetModeAttackRetryFlag(void);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
void G_LoadGameData(void);
|
|
|
|
void G_LoadGameSettings(void);
|
|
|
|
|
|
|
|
void G_SetGameModified(boolean silent);
|
|
|
|
|
|
|
|
void G_SetGamestate(gamestate_t newstate);
|
|
|
|
|
|
|
|
// Gamedata record shit
|
|
|
|
void G_AllocMainRecordData(INT16 i);
|
|
|
|
void G_AllocNightsRecordData(INT16 i);
|
|
|
|
void G_ClearRecords(void);
|
|
|
|
|
|
|
|
UINT32 G_GetBestScore(INT16 map);
|
|
|
|
tic_t G_GetBestTime(INT16 map);
|
|
|
|
UINT16 G_GetBestRings(INT16 map);
|
|
|
|
UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare);
|
|
|
|
tic_t G_GetBestNightsTime(INT16 map, UINT8 mare);
|
|
|
|
UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare);
|
|
|
|
|
|
|
|
void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare);
|
|
|
|
void G_SetNightsRecords(void);
|
|
|
|
|
|
|
|
FUNCMATH INT32 G_TicsToHours(tic_t tics);
|
|
|
|
FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full);
|
|
|
|
FUNCMATH INT32 G_TicsToSeconds(tic_t tics);
|
|
|
|
FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics);
|
|
|
|
FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
|
|
|
|
|
|
|
|
// Don't split up TOL handling
|
2020-03-02 03:20:53 +00:00
|
|
|
UINT32 G_TOLFlag(INT32 pgametype);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
#endif
|