mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 10:52:23 +00:00
Merge remote-tracking branch 'origin/next' into rotsprite2
This commit is contained in:
commit
c0390f5186
58 changed files with 7507 additions and 5810 deletions
src
d_clisrv.cd_main.cd_net.hd_netcmd.cdehacked.cdehacked.hdoomdef.hdoomstat.hf_finale.cf_finale.hf_wipe.cg_game.cg_game.h
hardware
hu_stuff.ci_system.hi_tcp.clua_baselib.clua_hook.hlua_hooklib.clua_hud.hlua_hudlib.clua_maplib.clua_script.clua_script.hm_anigif.cm_cheat.cm_menu.cm_menu.hm_misc.cp_enemy.cp_inter.cp_map.cp_mobj.cp_mobj.hp_saveg.cp_setup.cp_spec.cp_user.cr_data.cr_data.hr_defs.hr_plane.cr_state.hsdl
st_stuff.cv_video.cv_video.hw_wad.cw_wad.hy_inter.cy_inter.h
|
@ -70,7 +70,7 @@
|
|||
boolean server = true; // true or false but !server == client
|
||||
#define client (!server)
|
||||
boolean nodownload = false;
|
||||
static boolean serverrunning = false;
|
||||
boolean serverrunning = false;
|
||||
INT32 serverplayer = 0;
|
||||
char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support)
|
||||
|
||||
|
@ -1019,7 +1019,7 @@ static void SV_SendResynch(INT32 node)
|
|||
netbuffer->packettype = PT_RESYNCHEND;
|
||||
|
||||
netbuffer->u.resynchend.randomseed = P_GetRandSeed();
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
resynch_write_ctf(&netbuffer->u.resynchend);
|
||||
resynch_write_others(&netbuffer->u.resynchend);
|
||||
|
||||
|
@ -2105,10 +2105,10 @@ static void CL_ConnectToServer(boolean viams)
|
|||
|
||||
if (i != -1)
|
||||
{
|
||||
UINT8 num = serverlist[i].info.gametype;
|
||||
UINT16 num = serverlist[i].info.gametype;
|
||||
const char *gametypestr = NULL;
|
||||
CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername);
|
||||
if (num < NUMGAMETYPES)
|
||||
if (num < gametypecount)
|
||||
gametypestr = Gametype_Names[num];
|
||||
if (gametypestr)
|
||||
CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr);
|
||||
|
@ -2424,7 +2424,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
|||
}
|
||||
}
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you!
|
||||
|
||||
// If in a special stage, redistribute the player's spheres across
|
||||
|
@ -2480,6 +2480,17 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
|||
(void)reason;
|
||||
#endif
|
||||
|
||||
// don't look through someone's view who isn't there
|
||||
if (playernum == displayplayer)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
// Call ViewpointSwitch hooks here.
|
||||
// The viewpoint was forcibly changed.
|
||||
LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer], true);
|
||||
#endif
|
||||
displayplayer = consoleplayer;
|
||||
}
|
||||
|
||||
// Reset player data
|
||||
CL_ClearPlayer(playernum);
|
||||
|
||||
|
@ -2497,16 +2508,13 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
|||
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
|
||||
}
|
||||
|
||||
if (playernum == displayplayer)
|
||||
displayplayer = consoleplayer; // don't look through someone's view who isn't there
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_InvalidatePlayer(&players[playernum]);
|
||||
#endif
|
||||
|
||||
if (G_TagGametype()) //Check if you still have a game. Location flexible. =P
|
||||
P_CheckSurvivors();
|
||||
else if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
else if (gametyperules & GTR_RACE)
|
||||
P_CheckRacers();
|
||||
}
|
||||
|
||||
|
@ -3455,7 +3463,7 @@ void SV_StartSinglePlayerServer(void)
|
|||
server = true;
|
||||
netgame = false;
|
||||
multiplayer = false;
|
||||
gametype = GT_COOP;
|
||||
G_SetGametype(GT_COOP);
|
||||
|
||||
// no more tic the game with this settings!
|
||||
SV_StopServer();
|
||||
|
@ -3734,7 +3742,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
if (client)
|
||||
{
|
||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||
gametype = netbuffer->u.servercfg.gametype;
|
||||
G_SetGametype(netbuffer->u.servercfg.gametype);
|
||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
|
||||
|
@ -4118,7 +4126,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
|
||||
P_SetRandSeed(netbuffer->u.resynchend.randomseed);
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
resynch_read_ctf(&netbuffer->u.resynchend);
|
||||
resynch_read_others(&netbuffer->u.resynchend);
|
||||
|
||||
|
|
26
src/d_main.c
26
src/d_main.c
|
@ -274,7 +274,10 @@ static void D_Display(void)
|
|||
&& wipetypepre != UINT8_MAX)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
// Check for Mega Genesis fade
|
||||
wipestyleflags = WSF_FADEOUT;
|
||||
if (F_TryColormapFade(31))
|
||||
wipetypepost = -1; // Don't run the fade below this one
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
|
||||
}
|
||||
|
@ -488,6 +491,7 @@ static void D_Display(void)
|
|||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeEndScreen();
|
||||
|
||||
// Funny.
|
||||
if (WipeStageTitle && st_overlay)
|
||||
{
|
||||
|
@ -497,6 +501,14 @@ static void D_Display(void)
|
|||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
|
||||
F_WipeStartScreen();
|
||||
}
|
||||
|
||||
// Check for Mega Genesis fade
|
||||
if (F_ShouldColormapFade())
|
||||
{
|
||||
wipestyleflags |= WSF_FADEIN;
|
||||
wipestyleflags &= ~WSF_FADEOUT;
|
||||
}
|
||||
|
||||
F_RunWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
|
||||
}
|
||||
|
||||
|
@ -562,9 +574,6 @@ void D_SRB2Loop(void)
|
|||
|
||||
// Pushing of + parameters is now done back in D_SRB2Main, not here.
|
||||
|
||||
CONS_Printf("I_StartupKeyboard()...\n");
|
||||
I_StartupKeyboard();
|
||||
|
||||
#ifdef _WINDOWS
|
||||
CONS_Printf("I_StartupMouse()...\n");
|
||||
I_DoStartupMouse();
|
||||
|
@ -753,7 +762,7 @@ void D_StartTitle(void)
|
|||
|
||||
gameaction = ga_nothing;
|
||||
displayplayer = consoleplayer = 0;
|
||||
gametype = GT_COOP;
|
||||
G_SetGametype(GT_COOP);
|
||||
paused = false;
|
||||
advancedemo = false;
|
||||
F_InitMenuPresValues();
|
||||
|
@ -1288,9 +1297,10 @@ void D_SRB2Main(void)
|
|||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
S_InitSfxChannels(cv_soundvolume.value);
|
||||
S_InitMusicDefs();
|
||||
}
|
||||
|
||||
S_InitMusicDefs();
|
||||
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
||||
|
@ -1409,14 +1419,14 @@ void D_SRB2Main(void)
|
|||
if (newgametype == -1) // reached end of the list with no match
|
||||
{
|
||||
j = atoi(sgametype); // assume they gave us a gametype number, which is okay too
|
||||
if (j >= 0 && j < NUMGAMETYPES)
|
||||
if (j >= 0 && j < gametypecount)
|
||||
newgametype = (INT16)j;
|
||||
}
|
||||
|
||||
if (newgametype != -1)
|
||||
{
|
||||
j = gametype;
|
||||
gametype = newgametype;
|
||||
G_SetGametype(newgametype);
|
||||
D_GameTypeChanged(j);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ extern SINT8 nodetoplayer2[MAXNETNODES]; // Say the numplayer for this node if a
|
|||
extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen
|
||||
extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
|
||||
|
||||
extern boolean serverrunning;
|
||||
|
||||
INT32 Net_GetFreeAcks(boolean urgent);
|
||||
void Net_AckTicker(void);
|
||||
|
||||
|
|
|
@ -327,6 +327,10 @@ consvar_t cv_numlaps = {"numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_con
|
|||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Point and time limits for every gametype
|
||||
INT32 pointlimits[NUMGAMETYPES];
|
||||
INT32 timelimits[NUMGAMETYPES];
|
||||
|
||||
// log elemental hazards -- not a netvar, is local to current player
|
||||
consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -381,6 +385,9 @@ char timedemo_csv_id[256];
|
|||
boolean timedemo_quit;
|
||||
|
||||
INT16 gametype = GT_COOP;
|
||||
UINT32 gametyperules = 0;
|
||||
INT16 gametypecount = (GT_CTF + 1);
|
||||
|
||||
boolean splitscreen = false;
|
||||
boolean circuitmap = false;
|
||||
INT32 adminplayers[MAXPLAYERS];
|
||||
|
@ -823,6 +830,10 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_autobrake);
|
||||
CV_RegisterVar(&cv_autobrake2);
|
||||
|
||||
// Ported from kart
|
||||
CV_RegisterVar(&cv_deadzone);
|
||||
CV_RegisterVar(&cv_deadzone2);
|
||||
|
||||
// s_sound.c
|
||||
CV_RegisterVar(&cv_soundvolume);
|
||||
CV_RegisterVar(&cv_closedcaptioning);
|
||||
|
@ -1122,7 +1133,7 @@ UINT8 CanChangeSkin(INT32 playernum)
|
|||
return true;
|
||||
|
||||
// Can change skin during initial countdown.
|
||||
if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
|
||||
if ((gametyperules & GTR_RACE) && leveltime < 4*TICRATE)
|
||||
return true;
|
||||
|
||||
if (G_TagGametype())
|
||||
|
@ -1938,7 +1949,7 @@ static void Command_Map_f(void)
|
|||
if (isdigit(gametypename[0]))
|
||||
{
|
||||
d = atoi(gametypename);
|
||||
if (d >= 0 && d < NUMGAMETYPES)
|
||||
if (d >= 0 && d < gametypecount)
|
||||
newgametype = d;
|
||||
else
|
||||
{
|
||||
|
@ -1946,7 +1957,7 @@ static void Command_Map_f(void)
|
|||
"Gametype number %d is out of range. Use a number between"
|
||||
" 0 and %d inclusive. ...Or just use the name. :v\n",
|
||||
d,
|
||||
NUMGAMETYPES-1);
|
||||
gametypecount-1);
|
||||
Z_Free(realmapname);
|
||||
Z_Free(mapname);
|
||||
return;
|
||||
|
@ -2065,8 +2076,9 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
lastgametype = gametype;
|
||||
gametype = READUINT8(*cp);
|
||||
G_SetGametype(gametype); // I fear putting that macro as an argument
|
||||
|
||||
if (gametype < 0 || gametype >= NUMGAMETYPES)
|
||||
if (gametype < 0 || gametype >= gametypecount)
|
||||
gametype = lastgametype;
|
||||
else if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
||||
|
@ -2409,7 +2421,7 @@ static void Command_Teamchange_f(void)
|
|||
}
|
||||
|
||||
//additional check for hide and seek. Don't allow change of status after hidetime ends.
|
||||
if (gametype == GT_HIDEANDSEEK && leveltime >= (hidetime * TICRATE))
|
||||
if ((gametyperules & GTR_HIDEFROZEN) && leveltime >= (hidetime * TICRATE))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n"));
|
||||
return;
|
||||
|
@ -2506,7 +2518,7 @@ static void Command_Teamchange2_f(void)
|
|||
}
|
||||
|
||||
//additional check for hide and seek. Don't allow change of status after hidetime ends.
|
||||
if (gametype == GT_HIDEANDSEEK && leveltime >= (hidetime * TICRATE))
|
||||
if ((gametyperules & GTR_HIDEFROZEN) && leveltime >= (hidetime * TICRATE))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n"));
|
||||
return;
|
||||
|
@ -2635,7 +2647,7 @@ static void Command_ServerTeamChange_f(void)
|
|||
}
|
||||
|
||||
//additional check for hide and seek. Don't allow change of status after hidetime ends.
|
||||
if (gametype == GT_HIDEANDSEEK && leveltime >= (hidetime * TICRATE))
|
||||
if ((gametyperules & GTR_HIDEFROZEN) && leveltime >= (hidetime * TICRATE))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n"));
|
||||
return;
|
||||
|
@ -2724,6 +2736,16 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh
|
||||
if (!LUAh_TeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled))
|
||||
return;
|
||||
#endif
|
||||
|
||||
//no status changes after hidetime
|
||||
if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE)))
|
||||
error = true;
|
||||
|
||||
//Make sure that the right team number is sent. Keep in mind that normal clients cannot change to certain teams in certain gametypes.
|
||||
switch (gametype)
|
||||
{
|
||||
|
@ -2878,7 +2900,15 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
|
||||
//reset view if you are changed, or viewing someone who was changed.
|
||||
if (playernum == consoleplayer || displayplayer == playernum)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
// Call ViewpointSwitch hooks here.
|
||||
// The viewpoint was forcibly changed.
|
||||
if (displayplayer != consoleplayer) // You're already viewing yourself. No big deal.
|
||||
LUAh_ViewpointSwitch(&players[playernum], &players[displayplayer], true);
|
||||
#endif
|
||||
displayplayer = consoleplayer;
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
|
@ -3614,7 +3644,7 @@ static void Command_ShowGametype_f(void)
|
|||
}
|
||||
|
||||
// get name string for current gametype
|
||||
if (gametype >= 0 && gametype < NUMGAMETYPES)
|
||||
if (gametype >= 0 && gametype < gametypecount)
|
||||
gametypestr = Gametype_Names[gametype];
|
||||
|
||||
if (gametypestr)
|
||||
|
@ -3676,7 +3706,7 @@ void ItemFinder_OnChange(void)
|
|||
static void PointLimit_OnChange(void)
|
||||
{
|
||||
// Don't allow pointlimit in Single Player/Co-Op/Race!
|
||||
if (server && Playing() && G_PlatformGametype())
|
||||
if (server && Playing() && !(gametyperules & GTR_POINTLIMIT))
|
||||
{
|
||||
if (cv_pointlimit.value)
|
||||
CV_StealthSetValue(&cv_pointlimit, 0);
|
||||
|
@ -3839,7 +3869,7 @@ UINT32 timelimitintics = 0;
|
|||
static void TimeLimit_OnChange(void)
|
||||
{
|
||||
// Don't allow timelimit in Single Player/Co-Op/Race!
|
||||
if (server && Playing() && cv_timelimit.value != 0 && G_PlatformGametype())
|
||||
if (server && Playing() && cv_timelimit.value != 0 && !(gametyperules & GTR_TIMELIMIT))
|
||||
{
|
||||
CV_SetValue(&cv_timelimit, 0);
|
||||
return;
|
||||
|
@ -3875,9 +3905,9 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
{
|
||||
const char *oldgt = NULL, *newgt = NULL;
|
||||
|
||||
if (lastgametype >= 0 && lastgametype < NUMGAMETYPES)
|
||||
if (lastgametype >= 0 && lastgametype < gametypecount)
|
||||
oldgt = Gametype_Names[lastgametype];
|
||||
if (gametype >= 0 && lastgametype < NUMGAMETYPES)
|
||||
if (gametype >= 0 && lastgametype < gametypecount)
|
||||
newgt = Gametype_Names[gametype];
|
||||
|
||||
if (oldgt && newgt)
|
||||
|
@ -3931,11 +3961,20 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
if (!cv_itemrespawntime.changed)
|
||||
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
|
||||
break;
|
||||
default:
|
||||
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
|
||||
{
|
||||
CV_SetValue(&cv_timelimit, timelimits[gametype]);
|
||||
CV_SetValue(&cv_pointlimit, pointlimits[gametype]);
|
||||
}
|
||||
if (!cv_itemrespawntime.changed)
|
||||
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!multiplayer && !netgame)
|
||||
{
|
||||
gametype = GT_COOP;
|
||||
G_SetGametype(GT_COOP);
|
||||
// These shouldn't matter anymore
|
||||
//CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue);
|
||||
//CV_SetValue(&cv_itemrespawn, 0);
|
||||
|
@ -3944,7 +3983,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
// reset timelimit and pointlimit in race/coop, prevent stupid cheats
|
||||
if (server)
|
||||
{
|
||||
if (G_PlatformGametype())
|
||||
if (!(gametyperules & GTR_POINTLIMIT))
|
||||
{
|
||||
if (cv_timelimit.value)
|
||||
CV_SetValue(&cv_timelimit, 0);
|
||||
|
@ -3962,6 +4001,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
|
||||
// When swapping to a gametype that supports spectators,
|
||||
// make everyone a spectator initially.
|
||||
// Averted with GTR_NOSPECTATORSPAWN.
|
||||
if (!splitscreen && (G_GametypeHasSpectators()))
|
||||
{
|
||||
INT32 i;
|
||||
|
@ -3969,7 +4009,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
if (playeringame[i])
|
||||
{
|
||||
players[i].ctfteam = 0;
|
||||
players[i].spectator = true;
|
||||
players[i].spectator = (gametyperules & GTR_NOSPECTATORSPAWN) ? false : true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
600
src/dehacked.c
600
src/dehacked.c
|
@ -22,6 +22,7 @@
|
|||
#include "m_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "f_finale.h"
|
||||
#include "y_inter.h"
|
||||
#include "dehacked.h"
|
||||
#include "st_stuff.h"
|
||||
#include "i_system.h"
|
||||
|
@ -76,6 +77,7 @@ static UINT16 get_mus(const char *word, UINT8 dehacked_mode);
|
|||
static hudnum_t get_huditem(const char *word);
|
||||
static menutype_t get_menutype(const char *word);
|
||||
#ifndef HAVE_BLUA
|
||||
static INT16 get_gametype(const char *word);
|
||||
static powertype_t get_power(const char *word);
|
||||
#endif
|
||||
|
||||
|
@ -590,6 +592,16 @@ static void readfreeslots(MYFILE *f)
|
|||
} else
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
|
||||
}
|
||||
else if (fastcmp(type, "TOL"))
|
||||
{
|
||||
if (lastcustomtol > 31)
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
|
||||
else
|
||||
{
|
||||
G_AddTOL((1<<lastcustomtol), word);
|
||||
lastcustomtol++;
|
||||
}
|
||||
}
|
||||
else
|
||||
deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
|
||||
}
|
||||
|
@ -1093,10 +1105,10 @@ static void readsprite2(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
const UINT16 flag;
|
||||
} TYPEOFLEVEL[] = {
|
||||
INT32 numtolinfo = NUMBASETOL;
|
||||
UINT32 lastcustomtol = 13;
|
||||
|
||||
tolinfo_t TYPEOFLEVEL[NUMMAXTOL] = {
|
||||
{"SOLO",TOL_SP},
|
||||
{"SP",TOL_SP},
|
||||
{"SINGLEPLAYER",TOL_SP},
|
||||
|
@ -1112,8 +1124,6 @@ static const struct {
|
|||
{"TAG",TOL_TAG},
|
||||
{"CTF",TOL_CTF},
|
||||
|
||||
{"CUSTOM",TOL_CUSTOM},
|
||||
|
||||
{"2D",TOL_2D},
|
||||
{"MARIO",TOL_MARIO},
|
||||
{"NIGHTS",TOL_NIGHTS},
|
||||
|
@ -1126,6 +1136,216 @@ static const struct {
|
|||
{NULL, 0}
|
||||
};
|
||||
|
||||
// copypasted from readPlayer :sleep:
|
||||
static const char *const GAMETYPERULE_LIST[];
|
||||
static void readgametype(MYFILE *f, char *gtname)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2, *word2lwr = NULL;
|
||||
char *tmp;
|
||||
INT32 i, j;
|
||||
|
||||
INT16 newgtidx = 0;
|
||||
UINT32 newgtrules = 0;
|
||||
UINT32 newgttol = 0;
|
||||
INT32 newgtpointlimit = 0;
|
||||
INT32 newgttimelimit = 0;
|
||||
UINT8 newgtleftcolor = 0;
|
||||
UINT8 newgtrightcolor = 0;
|
||||
INT16 newgtrankingstype = -1;
|
||||
int newgtinttype = 0;
|
||||
char gtdescription[441];
|
||||
char gtconst[MAXLINELEN];
|
||||
|
||||
// Empty strings.
|
||||
gtdescription[0] = '\0';
|
||||
gtconst[0] = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
if (fastcmp(word, "DESCRIPTION"))
|
||||
{
|
||||
char *descr = NULL;
|
||||
|
||||
for (i = 0; i < MAXLINELEN-3; i++)
|
||||
{
|
||||
if (s[i] == '=')
|
||||
{
|
||||
descr = &s[i+2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (descr)
|
||||
{
|
||||
strcpy(gtdescription, descr);
|
||||
strcat(gtdescription, myhashfgets(descr, sizeof (gtdescription), f));
|
||||
}
|
||||
else
|
||||
strcpy(gtdescription, "");
|
||||
|
||||
// For some reason, cutting the string did not work above. Most likely due to strcpy or strcat...
|
||||
// It works down here, though.
|
||||
{
|
||||
INT32 numline = 0;
|
||||
for (i = 0; i < MAXLINELEN-1; i++)
|
||||
{
|
||||
if (numline < 20 && gtdescription[i] == '\n')
|
||||
numline++;
|
||||
|
||||
if (numline >= 20 || gtdescription[i] == '\0' || gtdescription[i] == '#')
|
||||
break;
|
||||
}
|
||||
}
|
||||
gtdescription[strlen(gtdescription)-1] = '\0';
|
||||
gtdescription[i] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
word2 = strtok(NULL, " = ");
|
||||
if (word2)
|
||||
{
|
||||
if (!word2lwr)
|
||||
word2lwr = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
strcpy(word2lwr, word2);
|
||||
strupr(word2);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
i = atoi(word2);
|
||||
|
||||
// Game type rules
|
||||
if (fastcmp(word, "RULES"))
|
||||
{
|
||||
// GTR_
|
||||
newgtrules = (UINT32)get_number(word2);
|
||||
}
|
||||
// Identifier
|
||||
else if (fastcmp(word, "IDENTIFIER"))
|
||||
{
|
||||
// GT_
|
||||
strncpy(gtconst, word2, MAXLINELEN);
|
||||
}
|
||||
// Point and time limits
|
||||
else if (fastcmp(word, "DEFAULTPOINTLIMIT"))
|
||||
newgtpointlimit = (INT32)i;
|
||||
else if (fastcmp(word, "DEFAULTTIMELIMIT"))
|
||||
newgttimelimit = (INT32)i;
|
||||
// Level platter
|
||||
else if (fastcmp(word, "HEADERCOLOR") || fastcmp(word, "HEADERCOLOUR"))
|
||||
newgtleftcolor = newgtrightcolor = (UINT8)get_number(word2);
|
||||
else if (fastcmp(word, "HEADERLEFTCOLOR") || fastcmp(word, "HEADERLEFTCOLOUR"))
|
||||
newgtleftcolor = (UINT8)get_number(word2);
|
||||
else if (fastcmp(word, "HEADERRIGHTCOLOR") || fastcmp(word, "HEADERRIGHTCOLOUR"))
|
||||
newgtrightcolor = (UINT8)get_number(word2);
|
||||
// Rankings type
|
||||
else if (fastcmp(word, "RANKINGTYPE"))
|
||||
{
|
||||
// Case insensitive
|
||||
newgtrankingstype = (int)get_number(word2);
|
||||
}
|
||||
// Intermission type
|
||||
else if (fastcmp(word, "INTERMISSIONTYPE"))
|
||||
{
|
||||
// Case sensitive
|
||||
newgtinttype = (int)get_number(word2lwr);
|
||||
}
|
||||
// Type of level
|
||||
else if (fastcmp(word, "TYPEOFLEVEL"))
|
||||
{
|
||||
if (i) // it's just a number
|
||||
newgttol = (UINT32)i;
|
||||
else
|
||||
{
|
||||
UINT16 tol = 0;
|
||||
tmp = strtok(word2,",");
|
||||
do {
|
||||
for (i = 0; TYPEOFLEVEL[i].name; i++)
|
||||
if (fasticmp(tmp, TYPEOFLEVEL[i].name))
|
||||
break;
|
||||
if (!TYPEOFLEVEL[i].name)
|
||||
deh_warning("readgametype %s: unknown typeoflevel flag %s\n", gtname, tmp);
|
||||
tol |= TYPEOFLEVEL[i].flag;
|
||||
} while((tmp = strtok(NULL,",")) != NULL);
|
||||
newgttol = tol;
|
||||
}
|
||||
}
|
||||
// The SOC probably provided gametype rules as words,
|
||||
// instead of using the RULES keyword.
|
||||
// Like for example "NOSPECTATORSPAWN = TRUE".
|
||||
// This is completely valid, and looks better anyway.
|
||||
else
|
||||
{
|
||||
UINT32 wordgt = 0;
|
||||
for (j = 0; GAMETYPERULE_LIST[j]; j++)
|
||||
if (fastcmp(word, GAMETYPERULE_LIST[j])) {
|
||||
if (!j) // GTR_CAMPAIGN
|
||||
wordgt |= 1;
|
||||
else
|
||||
wordgt |= (1<<j);
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
newgtrules |= wordgt;
|
||||
break;
|
||||
}
|
||||
if (!wordgt)
|
||||
deh_warning("readgametype %s: unknown word '%s'", gtname, word);
|
||||
}
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
// Free strings.
|
||||
Z_Free(s);
|
||||
if (word2lwr)
|
||||
Z_Free(word2lwr);
|
||||
|
||||
// Ran out of gametype slots
|
||||
if (gametypecount == NUMGAMETYPEFREESLOTS)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free gametype slots!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the new gametype
|
||||
newgtidx = G_AddGametype(newgtrules);
|
||||
G_AddGametypeTOL(newgtidx, newgttol);
|
||||
G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor);
|
||||
|
||||
// Not covered by G_AddGametype alone.
|
||||
if (newgtrankingstype == -1)
|
||||
newgtrankingstype = newgtidx;
|
||||
gametyperankings[newgtidx] = newgtrankingstype;
|
||||
intermissiontypes[newgtidx] = newgtinttype;
|
||||
pointlimits[newgtidx] = newgtpointlimit;
|
||||
timelimits[newgtidx] = newgttimelimit;
|
||||
|
||||
// Write the new gametype name.
|
||||
Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname);
|
||||
|
||||
// Write the constant name.
|
||||
if (gtconst[0] == '\0')
|
||||
strncpy(gtconst, gtname, MAXLINELEN);
|
||||
G_AddGametypeConstant(newgtidx, (const char *)gtconst);
|
||||
|
||||
// Update gametype_cons_t accordingly.
|
||||
G_UpdateGametypeSelections();
|
||||
|
||||
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
const mobjtype_t type;
|
||||
|
@ -1393,7 +1613,7 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
else if (fastcmp(word, "TYPEOFLEVEL"))
|
||||
{
|
||||
if (i) // it's just a number
|
||||
mapheaderinfo[num-1]->typeoflevel = (UINT16)i;
|
||||
mapheaderinfo[num-1]->typeoflevel = (UINT32)i;
|
||||
else
|
||||
{
|
||||
UINT16 tol = 0;
|
||||
|
@ -1518,10 +1738,27 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
deh_warning("Level header %d: invalid bonus type number %d", num, i);
|
||||
}
|
||||
|
||||
// Title card
|
||||
else if (fastcmp(word, "TITLECARDZIGZAG"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->ltzzpatch, word2,
|
||||
sizeof(mapheaderinfo[num-1]->ltzzpatch), va("Level header %d: title card zigzag patch name", num));
|
||||
}
|
||||
else if (fastcmp(word, "TITLECARDZIGZAGTEXT"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->ltzztext, word2,
|
||||
sizeof(mapheaderinfo[num-1]->ltzztext), va("Level header %d: title card zigzag text patch name", num));
|
||||
}
|
||||
else if (fastcmp(word, "TITLECARDACTDIAMOND"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->ltactdiamond, word2,
|
||||
sizeof(mapheaderinfo[num-1]->ltactdiamond), va("Level header %d: title card act diamond patch name", num));
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "MAXBONUSLIVES"))
|
||||
mapheaderinfo[num-1]->maxbonuslives = (SINT8)i;
|
||||
else if (fastcmp(word, "LEVELFLAGS"))
|
||||
mapheaderinfo[num-1]->levelflags = (UINT8)i;
|
||||
mapheaderinfo[num-1]->levelflags = (UINT16)i;
|
||||
else if (fastcmp(word, "MENUFLAGS"))
|
||||
mapheaderinfo[num-1]->menuflags = (UINT8)i;
|
||||
|
||||
|
@ -4151,6 +4388,7 @@ static void ignorelines(MYFILE *f)
|
|||
static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char textline[MAXLINELEN];
|
||||
char *word;
|
||||
char *word2;
|
||||
INT32 i;
|
||||
|
@ -4171,6 +4409,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
char *traverse;
|
||||
|
||||
myfgets(s, MAXLINELEN, f);
|
||||
memcpy(textline, s, MAXLINELEN);
|
||||
if (s[0] == '\n' || s[0] == '#')
|
||||
continue;
|
||||
|
||||
|
@ -4359,6 +4598,36 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "GAMETYPE"))
|
||||
{
|
||||
// Get the gametype name from textline
|
||||
// instead of word2, so that gametype names
|
||||
// aren't allcaps
|
||||
INT32 c;
|
||||
for (c = 0; c < MAXLINELEN; c++)
|
||||
{
|
||||
if (textline[c] == '\0')
|
||||
break;
|
||||
if (textline[c] == ' ')
|
||||
{
|
||||
char *gtname = (textline+c+1);
|
||||
if (gtname)
|
||||
{
|
||||
// remove funny characters
|
||||
INT32 j;
|
||||
for (j = 0; j < (MAXLINELEN - c); j++)
|
||||
{
|
||||
if (gtname[j] == '\0')
|
||||
break;
|
||||
if (gtname[j] < 32)
|
||||
gtname[j] = '\0';
|
||||
}
|
||||
readgametype(f, gtname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "CUTSCENE"))
|
||||
{
|
||||
if (i > 0 && i < 129)
|
||||
|
@ -4458,20 +4727,34 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
// Last I heard this crashes the game if you try to use it
|
||||
// so this is disabled for now
|
||||
// -- Monster Iestyn
|
||||
/* else if (fastcmp(word, "SRB2"))
|
||||
else if (fastcmp(word, "SRB2"))
|
||||
{
|
||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||
if (ver != PATCHVERSION)
|
||||
deh_warning("Patch is for SRB2 version %d,\nonly version %d is supported", ver, PATCHVERSION);
|
||||
if (isdigit(word2[0]))
|
||||
{
|
||||
i = atoi(word2);
|
||||
if (i != PATCHVERSION)
|
||||
{
|
||||
deh_warning(
|
||||
"Patch is for SRB2 version %d, "
|
||||
"only version %d is supported",
|
||||
i,
|
||||
PATCHVERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning(
|
||||
"SRB2 version definition has incorrect format, "
|
||||
"use \"SRB2 %d\"",
|
||||
PATCHVERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
// Clear all data in certain locations (mostly for unlocks)
|
||||
// Unless you REALLY want to piss people off,
|
||||
// define a custom gamedata /before/ doing this!!
|
||||
// (then again, modifiedgame will prevent game data saving anyway)
|
||||
*/
|
||||
else if (fastcmp(word, "CLEAR"))
|
||||
{
|
||||
boolean clearall = (fastcmp(word2, "ALL"));
|
||||
|
@ -8615,6 +8898,39 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
NULL // stop loop here.
|
||||
};
|
||||
|
||||
static const char *const GAMETYPERULE_LIST[] = {
|
||||
"CAMPAIGN",
|
||||
"RINGSLINGER",
|
||||
"SPECTATORS",
|
||||
"FRIENDLYFIRE",
|
||||
"LIVES",
|
||||
"TEAMS",
|
||||
"RACE",
|
||||
"TAG",
|
||||
"POINTLIMIT",
|
||||
"TIMELIMIT",
|
||||
"HIDETIME",
|
||||
"HIDEFROZEN",
|
||||
"BLINDFOLDED",
|
||||
"FIRSTPERSON",
|
||||
"MATCHEMERALDS",
|
||||
"TEAMFLAGS",
|
||||
"PITYSHIELD",
|
||||
"DEATHPENALTY",
|
||||
"NOSPECTATORSPAWN",
|
||||
"DEATHMATCHSTARTS",
|
||||
"SPECIALSTAGES",
|
||||
"EMERALDTOKENS",
|
||||
"EMERALDHUNT",
|
||||
"SPAWNENEMIES",
|
||||
"ALLOWEXIT",
|
||||
"NOTITLECARD",
|
||||
"OVERTIME",
|
||||
"HURTMESSAGES",
|
||||
"SPAWNINVUL",
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// Linedef flags
|
||||
static const char *const ML_LIST[16] = {
|
||||
|
@ -9030,21 +9346,6 @@ struct {
|
|||
{"tr_trans90",tr_trans90},
|
||||
{"NUMTRANSMAPS",NUMTRANSMAPS},
|
||||
|
||||
// Type of levels
|
||||
{"TOL_SP",TOL_SP},
|
||||
{"TOL_COOP",TOL_COOP},
|
||||
{"TOL_COMPETITION",TOL_COMPETITION},
|
||||
{"TOL_RACE",TOL_RACE},
|
||||
{"TOL_MATCH",TOL_MATCH},
|
||||
{"TOL_TAG",TOL_TAG},
|
||||
{"TOL_CTF",TOL_CTF},
|
||||
{"TOL_CUSTOM",TOL_CUSTOM},
|
||||
{"TOL_2D",TOL_2D},
|
||||
{"TOL_MARIO",TOL_MARIO},
|
||||
{"TOL_NIGHTS",TOL_NIGHTS},
|
||||
{"TOL_ERZ3",TOL_ERZ3},
|
||||
{"TOL_XMAS",TOL_XMAS},
|
||||
|
||||
// Level flags
|
||||
{"LF_SCRIPTISFILE",LF_SCRIPTISFILE},
|
||||
{"LF_SPEEDMUSIC",LF_SPEEDMUSIC},
|
||||
|
@ -9227,15 +9528,16 @@ struct {
|
|||
{"DMG_CANHURTSELF",DMG_CANHURTSELF},
|
||||
{"DMG_DEATHMASK",DMG_DEATHMASK},
|
||||
|
||||
// Gametypes, for use with global var "gametype"
|
||||
{"GT_COOP",GT_COOP},
|
||||
{"GT_COMPETITION",GT_COMPETITION},
|
||||
{"GT_RACE",GT_RACE},
|
||||
{"GT_MATCH",GT_MATCH},
|
||||
{"GT_TEAMMATCH",GT_TEAMMATCH},
|
||||
{"GT_TAG",GT_TAG},
|
||||
{"GT_HIDEANDSEEK",GT_HIDEANDSEEK},
|
||||
{"GT_CTF",GT_CTF},
|
||||
// Intermission types
|
||||
{"int_none",int_none},
|
||||
{"int_coop",int_coop},
|
||||
{"int_match",int_match},
|
||||
{"int_teammatch",int_teammatch},
|
||||
//{"int_tag",int_tag},
|
||||
{"int_ctf",int_ctf},
|
||||
{"int_spec",int_spec},
|
||||
{"int_race",int_race},
|
||||
{"int_comp",int_comp},
|
||||
|
||||
// Jingles (jingletype_t)
|
||||
{"JT_NONE",JT_NONE},
|
||||
|
@ -9526,7 +9828,7 @@ struct {
|
|||
};
|
||||
|
||||
static mobjtype_t get_mobjtype(const char *word)
|
||||
{ // Returns the vlaue of MT_ enumerations
|
||||
{ // Returns the value of MT_ enumerations
|
||||
mobjtype_t i;
|
||||
if (*word >= '0' && *word <= '9')
|
||||
return atoi(word);
|
||||
|
@ -9678,8 +9980,22 @@ static menutype_t get_menutype(const char *word)
|
|||
}
|
||||
|
||||
#ifndef HAVE_BLUA
|
||||
static INT16 get_gametype(const char *word)
|
||||
{ // Returns the value of GT_ enumerations
|
||||
INT16 i;
|
||||
if (*word >= '0' && *word <= '9')
|
||||
return atoi(word);
|
||||
if (fastncmp("GT_",word,3))
|
||||
word += 3; // take off the GT_
|
||||
for (i = 0; i < NUMGAMETYPES; i++)
|
||||
if (fastcmp(word, Gametype_ConstantNames[i]+3))
|
||||
return i;
|
||||
deh_warning("Couldn't find gametype named 'GT_%s'",word);
|
||||
return GT_COOP;
|
||||
}
|
||||
|
||||
static powertype_t get_power(const char *word)
|
||||
{ // Returns the vlaue of pw_ enumerations
|
||||
{ // Returns the value of pw_ enumerations
|
||||
powertype_t i;
|
||||
if (*word >= '0' && *word <= '9')
|
||||
return atoi(word);
|
||||
|
@ -9873,11 +10189,42 @@ static fixed_t find_const(const char **rword)
|
|||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("MN_",word,4)) {
|
||||
else if (fastncmp("MN_",word,3)) {
|
||||
r = get_menutype(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("GT_",word,4)) {
|
||||
r = get_gametype(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("GTR_", word, 4)) {
|
||||
char *p = word+4;
|
||||
for (i = 0; GAMETYPERULE_LIST[i]; i++)
|
||||
if (fastcmp(p, GAMETYPERULE_LIST[i])) {
|
||||
free(word);
|
||||
return (1<<i);
|
||||
}
|
||||
|
||||
// Not found error
|
||||
const_warning("game type rule",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("TOL_", word, 4)) {
|
||||
char *p = word+4;
|
||||
for (i = 0; TYPEOFLEVEL[i].name; i++)
|
||||
if (fastcmp(p, TYPEOFLEVEL[i].name)) {
|
||||
free(word);
|
||||
return TYPEOFLEVEL[i].flag;
|
||||
}
|
||||
|
||||
// Not found error
|
||||
const_warning("typeoflevel",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("HUD_",word,4)) {
|
||||
r = get_huditem(word);
|
||||
free(word);
|
||||
|
@ -10087,6 +10434,20 @@ static inline int lib_freeslot(lua_State *L)
|
|||
}
|
||||
r++;
|
||||
}
|
||||
else if (fastcmp(type, "TOL"))
|
||||
{
|
||||
if (lastcustomtol > 31)
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
|
||||
else
|
||||
{
|
||||
UINT32 newtol = (1<<lastcustomtol);
|
||||
CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word);
|
||||
G_AddTOL(newtol, word);
|
||||
lua_pushinteger(L, newtol);
|
||||
lastcustomtol++;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
Z_Free(s);
|
||||
lua_remove(L, 1);
|
||||
continue;
|
||||
|
@ -10191,6 +10552,36 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (mathlib) return luaL_error(L, "playerflag '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("GT_", word, 3)) {
|
||||
p = word;
|
||||
for (i = 0; Gametype_ConstantNames[i]; i++)
|
||||
if (fastcmp(p, Gametype_ConstantNames[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "gametype '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("GTR_", word, 4)) {
|
||||
p = word+4;
|
||||
for (i = 0; GAMETYPERULE_LIST[i]; i++)
|
||||
if (fastcmp(p, GAMETYPERULE_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "game type rule '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("TOL_", word, 4)) {
|
||||
p = word+4;
|
||||
for (i = 0; TYPEOFLEVEL[i].name; i++)
|
||||
if (fastcmp(p, TYPEOFLEVEL[i].name)) {
|
||||
lua_pushinteger(L, TYPEOFLEVEL[i].flag);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "typeoflevel '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("ML_", word, 3)) {
|
||||
p = word+3;
|
||||
for (i = 0; i < 16; i++)
|
||||
|
@ -10428,126 +10819,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
// DYNAMIC variables too!!
|
||||
// Try not to add anything that would break netgames or timeattack replays here.
|
||||
// You know, like consoleplayer, displayplayer, secondarydisplayplayer, or gametime.
|
||||
if (fastcmp(word,"gamemap")) {
|
||||
lua_pushinteger(L, gamemap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"maptol")) {
|
||||
lua_pushinteger(L, maptol);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"ultimatemode")) {
|
||||
lua_pushboolean(L, ultimatemode != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mariomode")) {
|
||||
lua_pushboolean(L, mariomode != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"twodlevel")) {
|
||||
lua_pushboolean(L, twodlevel != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"circuitmap")) {
|
||||
lua_pushboolean(L, circuitmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"netgame")) {
|
||||
lua_pushboolean(L, netgame);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"multiplayer")) {
|
||||
lua_pushboolean(L, multiplayer);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"modeattacking")) {
|
||||
lua_pushboolean(L, modeattacking);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"splitscreen")) {
|
||||
lua_pushboolean(L, splitscreen);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"gamecomplete")) {
|
||||
lua_pushboolean(L, gamecomplete);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"devparm")) {
|
||||
lua_pushboolean(L, devparm);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"modifiedgame")) {
|
||||
lua_pushboolean(L, modifiedgame && !savemoddata);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"menuactive")) {
|
||||
lua_pushboolean(L, menuactive);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"paused")) {
|
||||
lua_pushboolean(L, paused);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"titlemap")) {
|
||||
lua_pushinteger(L, titlemap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"titlemapinaction")) {
|
||||
lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF));
|
||||
return 1;
|
||||
} else if (fastcmp(word,"gametype")) {
|
||||
lua_pushinteger(L, gametype);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"leveltime")) {
|
||||
lua_pushinteger(L, leveltime);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"curWeather")) {
|
||||
lua_pushinteger(L, curWeather);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"globalweather")) {
|
||||
lua_pushinteger(L, globalweather);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"levelskynum")) {
|
||||
lua_pushinteger(L, levelskynum);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"globallevelskynum")) {
|
||||
lua_pushinteger(L, globallevelskynum);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mapmusname")) {
|
||||
lua_pushstring(L, mapmusname);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mapmusflags")) {
|
||||
lua_pushinteger(L, mapmusflags);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mapmusposition")) {
|
||||
lua_pushinteger(L, mapmusposition);
|
||||
return 1;
|
||||
// local player variables, by popular request
|
||||
} else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1)
|
||||
if (consoleplayer < 0 || !playeringame[consoleplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1)
|
||||
if (displayplayer < 0 || !playeringame[displayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[displayplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen
|
||||
if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER);
|
||||
return 1;
|
||||
// end local player variables
|
||||
} else if (fastcmp(word,"server")) {
|
||||
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array.
|
||||
LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)");
|
||||
if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer))
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"emeralds")) {
|
||||
lua_pushinteger(L, emeralds);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"gravity")) {
|
||||
lua_pushinteger(L, gravity);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"VERSIONSTRING")) {
|
||||
lua_pushstring(L, VERSIONSTRING);
|
||||
return 1;
|
||||
} else if (fastcmp(word, "token")) {
|
||||
lua_pushinteger(L, token);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return LUA_PushGlobals(L, word);
|
||||
}
|
||||
|
||||
int LUA_EnumLib(lua_State *L)
|
||||
|
@ -10614,6 +10886,8 @@ static int lib_getActionName(lua_State *L)
|
|||
return luaL_typerror(L, 1, "action userdata or Lua function");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int LUA_SOCLib(lua_State *L)
|
||||
{
|
||||
lua_register(L,"freeslot",lib_freeslot);
|
||||
|
|
|
@ -47,7 +47,7 @@ extern const char *superactions[MAXRECURSION];
|
|||
extern UINT8 superstack;
|
||||
|
||||
// If the dehacked patch does not match this version, we throw a warning
|
||||
#define PATCHVERSION 210
|
||||
#define PATCHVERSION 220
|
||||
|
||||
#define MAXLINELEN 1024
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
|
||||
#ifdef LOGMESSAGES
|
||||
extern FILE *logstream;
|
||||
extern char logfilename[1024];
|
||||
#endif
|
||||
|
||||
//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3
|
||||
|
@ -628,8 +629,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
#define ROTANGLES 72 // Needs to be a divisor of 360 (45, 60, 90, 120...)
|
||||
#define ROTANGDIFF (360 / ROTANGLES)
|
||||
|
||||
/// PNG support
|
||||
#ifndef HAVE_PNG
|
||||
#define NO_PNG_LUMPS
|
||||
#endif
|
||||
|
||||
/// Render flats on walls
|
||||
#define WALLFLATS
|
||||
|
||||
#endif // __DOOMDEF__
|
||||
|
|
112
src/doomstat.h
112
src/doomstat.h
|
@ -39,7 +39,7 @@ extern UINT32 mapmusposition;
|
|||
#define MUSIC_FORCERESET 0x4000 // -*--------------
|
||||
// Use other bits if necessary.
|
||||
|
||||
extern INT16 maptol;
|
||||
extern UINT32 maptol;
|
||||
extern UINT8 globalweather;
|
||||
extern INT32 curWeather;
|
||||
extern INT32 cursaveslot;
|
||||
|
@ -84,6 +84,9 @@ extern boolean addedtogame; // true after the server has added you
|
|||
extern boolean multiplayer;
|
||||
|
||||
extern INT16 gametype;
|
||||
extern UINT32 gametyperules;
|
||||
extern INT16 gametypecount;
|
||||
|
||||
extern boolean splitscreen;
|
||||
extern boolean circuitmap; // Does this level have 'circuit mode'?
|
||||
extern boolean fromlevelselect;
|
||||
|
@ -284,7 +287,7 @@ typedef struct
|
|||
char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
|
||||
char subttl[33]; ///< Subtitle for level
|
||||
UINT8 actnum; ///< Act number or 0 for none.
|
||||
UINT16 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
|
||||
char musname[7]; ///< Music track to play. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
|
@ -310,12 +313,17 @@ typedef struct
|
|||
SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.)
|
||||
SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.)
|
||||
|
||||
UINT8 levelflags; ///< LF_flags: merged booleans into one UINT8 for space, see below
|
||||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
|
||||
|
||||
char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
|
||||
UINT16 startrings; ///< Number of rings players start with.
|
||||
|
||||
// Title card.
|
||||
char ltzzpatch[8]; ///< Zig zag patch.
|
||||
char ltzztext[8]; ///< Zig zag text.
|
||||
char ltactdiamond[8]; ///< Act diamond.
|
||||
|
||||
// Freed animals stuff.
|
||||
UINT8 numFlickies; ///< Internal. For freed flicky support.
|
||||
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
|
||||
|
@ -361,6 +369,70 @@ typedef struct
|
|||
|
||||
extern mapheader_t* mapheaderinfo[NUMMAPS];
|
||||
|
||||
// Gametypes
|
||||
#define NUMGAMETYPEFREESLOTS 128
|
||||
enum GameType
|
||||
{
|
||||
GT_COOP = 0, // also used in single player
|
||||
GT_COMPETITION, // Classic "Race"
|
||||
GT_RACE,
|
||||
|
||||
GT_MATCH,
|
||||
GT_TEAMMATCH,
|
||||
|
||||
GT_TAG,
|
||||
GT_HIDEANDSEEK,
|
||||
|
||||
GT_CTF, // capture the flag
|
||||
|
||||
GT_FIRSTFREESLOT,
|
||||
GT_LASTFREESLOT = GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1,
|
||||
NUMGAMETYPES
|
||||
};
|
||||
// If you alter this list, update dehacked.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c
|
||||
|
||||
// Gametype rules
|
||||
enum GameTypeRules
|
||||
{
|
||||
GTR_CAMPAIGN = 1, // Linear Co-op map progression, don't allow random maps
|
||||
GTR_RINGSLINGER = 1<<1, // Outside of Co-op, Competition, and Race (overriden by cv_ringslinger)
|
||||
GTR_SPECTATORS = 1<<2, // Outside of Co-op, Competition, and Race
|
||||
GTR_FRIENDLYFIRE = 1<<3, // Always allow friendly fire
|
||||
GTR_LIVES = 1<<4, // Co-op and Competition
|
||||
GTR_TEAMS = 1<<5, // Team Match, CTF
|
||||
GTR_RACE = 1<<6, // Race and Competition
|
||||
GTR_TAG = 1<<7, // Tag and Hide and Seek
|
||||
GTR_POINTLIMIT = 1<<8, // Ringslinger point limit
|
||||
GTR_TIMELIMIT = 1<<9, // Ringslinger time limit
|
||||
GTR_HIDETIME = 1<<10, // Hide time (Tag and Hide and Seek)
|
||||
GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag)
|
||||
GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek)
|
||||
GTR_FIRSTPERSON = 1<<13, // First person camera
|
||||
GTR_MATCHEMERALDS = 1<<14, // Ringslinger emeralds (Match and CTF)
|
||||
GTR_TEAMFLAGS = 1<<15, // Gametype has team flags (CTF)
|
||||
GTR_PITYSHIELD = 1<<16, // Award pity shield
|
||||
GTR_DEATHPENALTY = 1<<17, // Death score penalty
|
||||
GTR_NOSPECTATORSPAWN = 1<<18, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators
|
||||
GTR_DEATHMATCHSTARTS = 1<<19, // Use deathmatch starts
|
||||
GTR_SPECIALSTAGES = 1<<20, // Allow special stages
|
||||
GTR_EMERALDTOKENS = 1<<21, // Spawn emerald tokens
|
||||
GTR_EMERALDHUNT = 1<<22, // Emerald Hunt
|
||||
GTR_SPAWNENEMIES = 1<<23, // Spawn enemies
|
||||
GTR_ALLOWEXIT = 1<<24, // Allow exit sectors
|
||||
GTR_NOTITLECARD = 1<<25, // Don't show the title card
|
||||
GTR_OVERTIME = 1<<26, // Allow overtime
|
||||
GTR_HURTMESSAGES = 1<<27, // Hit and death messages
|
||||
GTR_SPAWNINVUL = 1<<28, // Babysitting deterrent
|
||||
};
|
||||
|
||||
// String names for gametypes
|
||||
extern const char *Gametype_Names[NUMGAMETYPES];
|
||||
extern const char *Gametype_ConstantNames[NUMGAMETYPES];
|
||||
|
||||
// Point and time limits for every gametype
|
||||
extern INT32 pointlimits[NUMGAMETYPES];
|
||||
extern INT32 timelimits[NUMGAMETYPES];
|
||||
|
||||
enum TypeOfLevel
|
||||
{
|
||||
TOL_SP = 0x01, ///< Single Player
|
||||
|
@ -376,36 +448,26 @@ enum TypeOfLevel
|
|||
TOL_CTF = 0x40, ///< Capture the Flag
|
||||
// CTF default = 64
|
||||
|
||||
TOL_CUSTOM = 0x80, ///< Custom (Lua-scripted, etc.)
|
||||
// 0x80 was here
|
||||
|
||||
TOL_2D = 0x0100, ///< 2D
|
||||
TOL_MARIO = 0x0200, ///< Mario
|
||||
TOL_NIGHTS = 0x0400, ///< NiGHTS
|
||||
TOL_ERZ3 = 0x0800, ///< ERZ3
|
||||
TOL_XMAS = 0x1000 ///< Christmas NiGHTS
|
||||
TOL_XMAS = 0x1000, ///< Christmas NiGHTS
|
||||
};
|
||||
|
||||
// Gametypes
|
||||
enum GameType
|
||||
#define NUMBASETOL 18
|
||||
#define NUMMAXTOL (18 + NUMGAMETYPEFREESLOTS)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GT_COOP = 0, // also used in single player
|
||||
GT_COMPETITION, // Classic "Race"
|
||||
GT_RACE,
|
||||
|
||||
GT_MATCH,
|
||||
GT_TEAMMATCH,
|
||||
|
||||
GT_TAG,
|
||||
GT_HIDEANDSEEK,
|
||||
|
||||
GT_CTF, // capture the flag
|
||||
|
||||
NUMGAMETYPES
|
||||
};
|
||||
// If you alter this list, update dehacked.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c
|
||||
|
||||
// String names for gametypes
|
||||
extern const char *Gametype_Names[NUMGAMETYPES];
|
||||
const char *name;
|
||||
UINT32 flag;
|
||||
} tolinfo_t;
|
||||
extern tolinfo_t TYPEOFLEVEL[NUMMAXTOL];
|
||||
extern INT32 numtolinfo;
|
||||
extern UINT32 lastcustomtol;
|
||||
|
||||
extern tic_t totalplaytime;
|
||||
|
||||
|
|
|
@ -917,8 +917,9 @@ void F_IntroDrawer(void)
|
|||
{
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
wipestyleflags = WSF_FADEOUT;
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
F_TryColormapFade(31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -927,12 +928,11 @@ void F_IntroDrawer(void)
|
|||
}
|
||||
else if (intro_scenenum == 10)
|
||||
{
|
||||
// The only fade to white in the entire damn game.
|
||||
// (not true)
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
wipestyleflags = (WSF_FADEOUT|WSF_TOWHITE);
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(0);
|
||||
F_TryColormapFade(0);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -941,8 +941,9 @@ void F_IntroDrawer(void)
|
|||
{
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
wipestyleflags = WSF_FADEOUT;
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
F_TryColormapFade(31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -977,6 +978,7 @@ void F_IntroDrawer(void)
|
|||
|
||||
F_WipeStartScreen();
|
||||
wipegamestate = -1;
|
||||
wipestyleflags = WSF_CROSSFADE;
|
||||
animtimer = stoptimer = 0;
|
||||
}
|
||||
|
||||
|
@ -3596,6 +3598,8 @@ void F_StartContinue(void)
|
|||
return;
|
||||
}
|
||||
|
||||
wipestyleflags = WSF_FADEOUT;
|
||||
F_TryColormapFade(31);
|
||||
G_SetGamestate(GS_CONTINUING);
|
||||
gameaction = ga_nothing;
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ extern boolean WipeStageTitle;
|
|||
typedef enum
|
||||
{
|
||||
WIPESTYLE_NORMAL,
|
||||
WIPESTYLE_LEVEL
|
||||
WIPESTYLE_COLORMAP
|
||||
} wipestyle_t;
|
||||
extern wipestyle_t wipestyle;
|
||||
|
||||
|
@ -159,6 +159,11 @@ typedef enum
|
|||
} wipestyleflags_t;
|
||||
extern wipestyleflags_t wipestyleflags;
|
||||
|
||||
// Even my function names are borderline
|
||||
boolean F_ShouldColormapFade(void);
|
||||
boolean F_TryColormapFade(UINT8 wipecolor);
|
||||
void F_DecideWipeStyle(void);
|
||||
|
||||
#define FADECOLORMAPDIV 8
|
||||
#define FADECOLORMAPROWS (256/FADECOLORMAPDIV)
|
||||
|
||||
|
|
248
src/f_wipe.c
248
src/f_wipe.c
|
@ -56,7 +56,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
|
|||
|
||||
0, // wipe_level_toblack
|
||||
UINT8_MAX, // wipe_intermission_toblack
|
||||
UINT8_MAX, // wipe_continuing_toblack
|
||||
0, // wipe_continuing_toblack
|
||||
0, // wipe_titlescreen_toblack
|
||||
0, // wipe_timeattack_toblack
|
||||
99, // wipe_credits_toblack
|
||||
|
@ -161,7 +161,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
|
|||
{
|
||||
// Determine pixel to use from fademask
|
||||
pcolor = &pMasterPalette[*lump++];
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
if (wipestyle == WIPESTYLE_COLORMAP)
|
||||
*mask++ = pcolor->s.red / FADECOLORMAPDIV;
|
||||
else
|
||||
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
|
||||
|
@ -191,7 +191,7 @@ void F_WipeStageTitle(void)
|
|||
{
|
||||
// draw level title
|
||||
if ((WipeStageTitle && st_overlay)
|
||||
&& (wipestyle == WIPESTYLE_LEVEL)
|
||||
&& (wipestyle == WIPESTYLE_COLORMAP)
|
||||
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
|
||||
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0')
|
||||
{
|
||||
|
@ -282,7 +282,7 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
relativepos += vid.width;
|
||||
}
|
||||
}
|
||||
else if (*mask >= ((wipestyle == WIPESTYLE_LEVEL) ? FADECOLORMAPROWS : 10))
|
||||
else if (*mask >= 10)
|
||||
{
|
||||
// shortcut - memcpy target to work
|
||||
while (draw_linestogo--)
|
||||
|
@ -293,25 +293,8 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
{
|
||||
int nmask;
|
||||
UINT8 *fade = fadecolormap;
|
||||
|
||||
if (wipestyleflags & WSF_TOWHITE)
|
||||
fade = fadecolormap + (FADECOLORMAPROWS * 256);
|
||||
|
||||
nmask = *mask;
|
||||
if (wipestyleflags & WSF_FADEIN)
|
||||
nmask = (FADECOLORMAPROWS-1) - nmask;
|
||||
|
||||
transtbl = fade + (nmask * 256);
|
||||
}
|
||||
else
|
||||
{
|
||||
// pointer to transtable that this mask would use
|
||||
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
|
||||
}
|
||||
// pointer to transtable that this mask would use
|
||||
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
|
||||
|
||||
// DRAWING LOOP
|
||||
while (draw_linestogo--)
|
||||
|
@ -321,16 +304,113 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
e = e_base + relativepos;
|
||||
draw_rowstogo = draw_rowend - draw_rowstart;
|
||||
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
{
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[*e++];
|
||||
}
|
||||
else
|
||||
{
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
|
||||
}
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
|
||||
|
||||
relativepos += vid.width;
|
||||
}
|
||||
// END DRAWING LOOP
|
||||
}
|
||||
|
||||
if (++maskx >= fademask->width)
|
||||
++masky, maskx = 0;
|
||||
} while (++mask < maskend);
|
||||
|
||||
free(scrxpos);
|
||||
free(scrypos);
|
||||
}
|
||||
}
|
||||
|
||||
static void F_DoColormapWipe(fademask_t *fademask, UINT8 *colormap)
|
||||
{
|
||||
// Lactozilla: F_DoWipe for WIPESTYLE_COLORMAP
|
||||
{
|
||||
// wipe screen, start, end
|
||||
UINT8 *w = wipe_scr;
|
||||
const UINT8 *s = wipe_scr_start;
|
||||
const UINT8 *e = wipe_scr_end;
|
||||
|
||||
// first pixel for each screen
|
||||
UINT8 *w_base = w;
|
||||
const UINT8 *s_base = s;
|
||||
const UINT8 *e_base = e;
|
||||
|
||||
// mask data, end
|
||||
UINT8 *transtbl;
|
||||
const UINT8 *mask = fademask->mask;
|
||||
const UINT8 *maskend = mask + fademask->size;
|
||||
|
||||
// rectangle draw hints
|
||||
UINT32 draw_linestart, draw_rowstart;
|
||||
UINT32 draw_lineend, draw_rowend;
|
||||
UINT32 draw_linestogo, draw_rowstogo;
|
||||
|
||||
// rectangle coordinates, etc.
|
||||
UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16));
|
||||
UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
|
||||
UINT16 maskx, masky;
|
||||
UINT32 relativepos;
|
||||
|
||||
// ---
|
||||
// Screw it, we do the fixed point math ourselves up front.
|
||||
scrxpos[0] = 0;
|
||||
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
|
||||
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
|
||||
scrxpos[fademask->width] = vid.width;
|
||||
|
||||
scrypos[0] = 0;
|
||||
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
|
||||
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
|
||||
scrypos[fademask->height] = vid.height;
|
||||
// ---
|
||||
|
||||
maskx = masky = 0;
|
||||
do
|
||||
{
|
||||
draw_rowstart = scrxpos[maskx];
|
||||
draw_rowend = scrxpos[maskx + 1];
|
||||
draw_linestart = scrypos[masky];
|
||||
draw_lineend = scrypos[masky + 1];
|
||||
|
||||
relativepos = (draw_linestart * vid.width) + draw_rowstart;
|
||||
draw_linestogo = draw_lineend - draw_linestart;
|
||||
|
||||
if (*mask == 0)
|
||||
{
|
||||
// shortcut - memcpy source to work
|
||||
while (draw_linestogo--)
|
||||
{
|
||||
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
|
||||
relativepos += vid.width;
|
||||
}
|
||||
}
|
||||
else if (*mask >= FADECOLORMAPROWS)
|
||||
{
|
||||
// shortcut - memcpy target to work
|
||||
while (draw_linestogo--)
|
||||
{
|
||||
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
|
||||
relativepos += vid.width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int nmask = *mask;
|
||||
if (wipestyleflags & WSF_FADEIN)
|
||||
nmask = (FADECOLORMAPROWS-1) - nmask;
|
||||
|
||||
transtbl = colormap + (nmask * 256);
|
||||
|
||||
// DRAWING LOOP
|
||||
while (draw_linestogo--)
|
||||
{
|
||||
w = w_base + relativepos;
|
||||
s = s_base + relativepos;
|
||||
e = e_base + relativepos;
|
||||
draw_rowstogo = draw_rowend - draw_rowstart;
|
||||
|
||||
while (draw_rowstogo--)
|
||||
*w++ = transtbl[*e++];
|
||||
|
||||
relativepos += vid.width;
|
||||
}
|
||||
|
@ -382,6 +462,62 @@ void F_WipeEndScreen(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/** Verifies every condition for a colormapped fade.
|
||||
*/
|
||||
boolean F_ShouldColormapFade(void)
|
||||
{
|
||||
if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set
|
||||
&& !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading
|
||||
{
|
||||
// World
|
||||
return (gamestate == GS_LEVEL
|
||||
|| gamestate == GS_TITLESCREEN
|
||||
// Finales
|
||||
|| gamestate == GS_CONTINUING
|
||||
|| gamestate == GS_CREDITS
|
||||
|| gamestate == GS_EVALUATION
|
||||
|| gamestate == GS_INTRO
|
||||
|| gamestate == GS_ENDING
|
||||
// Menus
|
||||
|| gamestate == GS_TIMEATTACK);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Decides what wipe style to use.
|
||||
*/
|
||||
void F_DecideWipeStyle(void)
|
||||
{
|
||||
// Set default wipe style
|
||||
wipestyle = WIPESTYLE_NORMAL;
|
||||
|
||||
// Check for colormap wipe style
|
||||
if (F_ShouldColormapFade())
|
||||
wipestyle = WIPESTYLE_COLORMAP;
|
||||
}
|
||||
|
||||
/** Attempt to run a colormap fade,
|
||||
provided all the conditionals were properly met.
|
||||
Returns true if so.
|
||||
I demand you call F_RunWipe after this function.
|
||||
*/
|
||||
boolean F_TryColormapFade(UINT8 wipecolor)
|
||||
{
|
||||
if (F_ShouldColormapFade())
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
F_WipeColorFill(wipecolor);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
F_WipeColorFill(wipecolor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** After setting up the screens you want to wipe,
|
||||
* calling this will do a 'typical' wipe.
|
||||
*/
|
||||
|
@ -399,18 +535,10 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS);
|
||||
|
||||
// Init the wipe
|
||||
F_DecideWipeStyle();
|
||||
WipeInAction = true;
|
||||
wipe_scr = screens[0];
|
||||
|
||||
// don't know where else to put this.
|
||||
// this any good?
|
||||
if ((gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN)
|
||||
&& (wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set
|
||||
&& !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading
|
||||
wipestyle = WIPESTYLE_LEVEL;
|
||||
else
|
||||
wipestyle = WIPESTYLE_NORMAL;
|
||||
|
||||
// lastwipetic should either be 0 or the tic we last wiped
|
||||
// on for fade-to-black
|
||||
for (;;)
|
||||
|
@ -425,21 +553,39 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
I_Sleep();
|
||||
lastwipetic = nowtime;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
// Wipe styles
|
||||
if (wipestyle == WIPESTYLE_COLORMAP)
|
||||
{
|
||||
// send in the wipe type and wipe frame because we need to cache the graphic
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
// send in the wipe type and wipe frame because we need to cache the graphic
|
||||
HWR_DoTintedWipe(wipetype, wipeframe-1);
|
||||
}
|
||||
else
|
||||
HWR_DoWipe(wipetype, wipeframe-1);
|
||||
#endif
|
||||
{
|
||||
UINT8 *colormap = fadecolormap;
|
||||
if (wipestyleflags & WSF_TOWHITE)
|
||||
colormap += (FADECOLORMAPROWS * 256);
|
||||
F_DoColormapWipe(fmask, colormap);
|
||||
}
|
||||
|
||||
// Draw the title card above the wipe
|
||||
F_WipeStageTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
// send in the wipe type and wipe frame because we need to cache the graphic
|
||||
HWR_DoWipe(wipetype, wipeframe-1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
F_DoWipe(fmask);
|
||||
|
||||
if (wipestyle == WIPESTYLE_LEVEL)
|
||||
F_WipeStageTitle();
|
||||
F_DoWipe(fmask);
|
||||
}
|
||||
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
|
|
526
src/g_game.c
526
src/g_game.c
|
@ -79,7 +79,7 @@ UINT16 mapmusflags; // Track and reset bit
|
|||
UINT32 mapmusposition; // Position to jump to
|
||||
|
||||
INT16 gamemap = 1;
|
||||
INT16 maptol;
|
||||
UINT32 maptol;
|
||||
UINT8 globalweather = 0;
|
||||
INT32 curWeather = PRECIP_NONE;
|
||||
INT32 cursaveslot = 0; // Auto-save 1p savegame slot
|
||||
|
@ -275,6 +275,12 @@ static UINT8 *metalbuffer = NULL;
|
|||
static UINT8 *metal_p;
|
||||
static UINT16 metalversion;
|
||||
|
||||
typedef struct joystickvector2_s
|
||||
{
|
||||
INT32 xaxis;
|
||||
INT32 yaxis;
|
||||
} joystickvector2_t;
|
||||
|
||||
// extra data stuff (events registered this frame while recording)
|
||||
static struct {
|
||||
UINT8 flags; // EZT flags
|
||||
|
@ -394,6 +400,11 @@ consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, di
|
|||
consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t deadzone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_deadzone = {"deadzone", "0.25", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_deadzone2 = {"deadzone2", "0.25", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AXISNONE = 0,
|
||||
|
@ -401,7 +412,6 @@ typedef enum
|
|||
AXISMOVE,
|
||||
AXISLOOK,
|
||||
AXISSTRAFE,
|
||||
AXISDEAD, //Axises that don't want deadzones
|
||||
AXISJUMP,
|
||||
AXISSPIN,
|
||||
AXISFIRE,
|
||||
|
@ -882,12 +892,6 @@ static INT32 JoyAxis(axis_input_e axissel)
|
|||
retaxis = -JOYAXISRANGE;
|
||||
if (retaxis > (+JOYAXISRANGE))
|
||||
retaxis = +JOYAXISRANGE;
|
||||
if (!Joystick.bGamepadStyle && axissel < AXISDEAD)
|
||||
{
|
||||
const INT32 jdeadzone = JOYAXISRANGE/4;
|
||||
if (-jdeadzone < retaxis && retaxis < jdeadzone)
|
||||
return 0;
|
||||
}
|
||||
if (flp) retaxis = -retaxis; //flip it around
|
||||
return retaxis;
|
||||
}
|
||||
|
@ -955,16 +959,75 @@ static INT32 Joy2Axis(axis_input_e axissel)
|
|||
retaxis = -JOYAXISRANGE;
|
||||
if (retaxis > (+JOYAXISRANGE))
|
||||
retaxis = +JOYAXISRANGE;
|
||||
if (!Joystick2.bGamepadStyle && axissel < AXISDEAD)
|
||||
{
|
||||
const INT32 jdeadzone = JOYAXISRANGE/4;
|
||||
if (-jdeadzone < retaxis && retaxis < jdeadzone)
|
||||
return 0;
|
||||
}
|
||||
if (flp) retaxis = -retaxis; //flip it around
|
||||
return retaxis;
|
||||
}
|
||||
|
||||
// Take a magnitude of two axes, and adjust it to take out the deadzone
|
||||
// Will return a value between 0 and JOYAXISRANGE
|
||||
static INT32 G_BasicDeadZoneCalculation(INT32 magnitude, fixed_t deadZone)
|
||||
{
|
||||
const INT32 jdeadzone = (JOYAXISRANGE * deadZone) / FRACUNIT;
|
||||
INT32 deadzoneAppliedValue = 0;
|
||||
|
||||
if (jdeadzone > 0)
|
||||
{
|
||||
if (magnitude > jdeadzone)
|
||||
{
|
||||
INT32 adjustedMagnitude = abs(magnitude);
|
||||
adjustedMagnitude = min(adjustedMagnitude, JOYAXISRANGE);
|
||||
|
||||
adjustedMagnitude -= jdeadzone;
|
||||
|
||||
deadzoneAppliedValue = (adjustedMagnitude * JOYAXISRANGE) / (JOYAXISRANGE - jdeadzone);
|
||||
}
|
||||
}
|
||||
|
||||
return deadzoneAppliedValue;
|
||||
}
|
||||
|
||||
// Get the actual sensible radial value for a joystick axis when accounting for a deadzone
|
||||
static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvector)
|
||||
{
|
||||
INT32 gamepadStyle = Joystick.bGamepadStyle;
|
||||
fixed_t deadZone = cv_deadzone.value;
|
||||
|
||||
if (splitnum == 1)
|
||||
{
|
||||
gamepadStyle = Joystick2.bGamepadStyle;
|
||||
deadZone = cv_deadzone2.value;
|
||||
}
|
||||
|
||||
// When gamepadstyle is "true" the values are just -1, 0, or 1. This is done in the interface code.
|
||||
if (!gamepadStyle)
|
||||
{
|
||||
// Get the total magnitude of the 2 axes
|
||||
INT32 magnitude = (joystickvector->xaxis * joystickvector->xaxis) + (joystickvector->yaxis * joystickvector->yaxis);
|
||||
INT32 normalisedXAxis;
|
||||
INT32 normalisedYAxis;
|
||||
INT32 normalisedMagnitude;
|
||||
double dMagnitude = sqrt((double)magnitude);
|
||||
magnitude = (INT32)dMagnitude;
|
||||
|
||||
// Get the normalised xy values from the magnitude
|
||||
normalisedXAxis = (joystickvector->xaxis * magnitude) / JOYAXISRANGE;
|
||||
normalisedYAxis = (joystickvector->yaxis * magnitude) / JOYAXISRANGE;
|
||||
|
||||
// Apply the deadzone to the magnitude to give a correct value between 0 and JOYAXISRANGE
|
||||
normalisedMagnitude = G_BasicDeadZoneCalculation(magnitude, deadZone);
|
||||
|
||||
// Apply the deadzone to the xy axes
|
||||
joystickvector->xaxis = (normalisedXAxis * normalisedMagnitude) / JOYAXISRANGE;
|
||||
joystickvector->yaxis = (normalisedYAxis * normalisedMagnitude) / JOYAXISRANGE;
|
||||
|
||||
// Cap the values so they don't go above the correct maximum
|
||||
joystickvector->xaxis = min(joystickvector->xaxis, JOYAXISRANGE);
|
||||
joystickvector->xaxis = max(joystickvector->xaxis, -JOYAXISRANGE);
|
||||
joystickvector->yaxis = min(joystickvector->yaxis, JOYAXISRANGE);
|
||||
joystickvector->yaxis = max(joystickvector->yaxis, -JOYAXISRANGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// G_BuildTiccmd
|
||||
|
@ -985,12 +1048,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
{
|
||||
boolean forcestrafe = false;
|
||||
boolean forcefullinput = false;
|
||||
INT32 tspeed, forward, side, axis, altaxis, i;
|
||||
INT32 tspeed, forward, side, axis, strafeaxis, moveaxis, turnaxis, lookaxis, i;
|
||||
const INT32 speed = 1;
|
||||
// these ones used for multiple conditions
|
||||
boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming;
|
||||
player_t *player = &players[consoleplayer];
|
||||
camera_t *thiscam = &camera;
|
||||
joystickvector2_t movejoystickvector, lookjoystickvector;
|
||||
|
||||
static INT32 turnheld; // for accelerative turning
|
||||
static boolean keyboard_look; // true if lookup/down using keyboard
|
||||
|
@ -1002,7 +1066,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
// why build a ticcmd if we're paused?
|
||||
// Or, for that matter, if we're being reborn.
|
||||
// ...OR if we're blindfolded. No looking into the floor.
|
||||
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK)
|
||||
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametyperules & GTR_TAG)
|
||||
&& (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT)))))
|
||||
{
|
||||
cmd->angleturn = (INT16)(localangle >> 16);
|
||||
|
@ -1030,11 +1094,16 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
localaiming = 0;
|
||||
joyaiming = thisjoyaiming;
|
||||
|
||||
axis = JoyAxis(AXISTURN);
|
||||
if (gamepadjoystickmove && axis != 0)
|
||||
turnaxis = JoyAxis(AXISTURN);
|
||||
lookaxis = JoyAxis(AXISLOOK);
|
||||
lookjoystickvector.xaxis = turnaxis;
|
||||
lookjoystickvector.yaxis = lookaxis;
|
||||
G_HandleAxisDeadZone(0, &lookjoystickvector);
|
||||
|
||||
if (gamepadjoystickmove && lookjoystickvector.xaxis != 0)
|
||||
{
|
||||
turnright = turnright || (axis > 0);
|
||||
turnleft = turnleft || (axis < 0);
|
||||
turnright = turnright || (lookjoystickvector.xaxis > 0);
|
||||
turnleft = turnleft || (lookjoystickvector.xaxis < 0);
|
||||
}
|
||||
forward = side = 0;
|
||||
|
||||
|
@ -1074,10 +1143,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
if (turnleft)
|
||||
side -= sidemove[speed];
|
||||
|
||||
if (analogjoystickmove && axis != 0)
|
||||
if (analogjoystickmove && lookjoystickvector.xaxis != 0)
|
||||
{
|
||||
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
|
||||
side += ((axis * sidemove[1]) >> 10);
|
||||
side += ((lookjoystickvector.xaxis * sidemove[1]) >> 10);
|
||||
}
|
||||
}
|
||||
else if (cv_analog.value) // Analog
|
||||
|
@ -1094,41 +1163,44 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
else if (turnleft)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
|
||||
|
||||
if (analogjoystickmove && axis != 0)
|
||||
if (analogjoystickmove && lookjoystickvector.xaxis != 0)
|
||||
{
|
||||
// JOYAXISRANGE should be 1023 (divide by 1024)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG!
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((lookjoystickvector.xaxis * angleturn[1]) >> 10)); // ANALOG!
|
||||
}
|
||||
}
|
||||
|
||||
axis = JoyAxis(AXISSTRAFE);
|
||||
if (gamepadjoystickmove && axis != 0)
|
||||
strafeaxis = JoyAxis(AXISSTRAFE);
|
||||
moveaxis = JoyAxis(AXISMOVE);
|
||||
movejoystickvector.xaxis = strafeaxis;
|
||||
movejoystickvector.yaxis = moveaxis;
|
||||
G_HandleAxisDeadZone(0, &movejoystickvector);
|
||||
|
||||
if (gamepadjoystickmove && movejoystickvector.xaxis != 0)
|
||||
{
|
||||
if (axis < 0)
|
||||
if (movejoystickvector.xaxis > 0)
|
||||
side += sidemove[speed];
|
||||
else if (axis > 0)
|
||||
else if (movejoystickvector.xaxis < 0)
|
||||
side -= sidemove[speed];
|
||||
}
|
||||
else if (analogjoystickmove && axis != 0)
|
||||
else if (analogjoystickmove && movejoystickvector.xaxis != 0)
|
||||
{
|
||||
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
|
||||
side += ((axis * sidemove[1]) >> 10);
|
||||
side += ((movejoystickvector.xaxis * sidemove[1]) >> 10);
|
||||
}
|
||||
|
||||
// forward with key or button
|
||||
axis = JoyAxis(AXISMOVE);
|
||||
altaxis = JoyAxis(AXISLOOK);
|
||||
if (movefkey || (gamepadjoystickmove && axis < 0)
|
||||
if (movefkey || (gamepadjoystickmove && movejoystickvector.yaxis < 0)
|
||||
|| ((player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
&& (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0))))
|
||||
&& (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0))))
|
||||
forward = forwardmove[speed];
|
||||
if (movebkey || (gamepadjoystickmove && axis > 0)
|
||||
if (movebkey || (gamepadjoystickmove && movejoystickvector.yaxis > 0)
|
||||
|| ((player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
&& (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0))))
|
||||
&& (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0))))
|
||||
forward -= forwardmove[speed];
|
||||
|
||||
if (analogjoystickmove && axis != 0)
|
||||
forward -= ((axis * forwardmove[1]) >> 10); // ANALOG!
|
||||
if (analogjoystickmove && movejoystickvector.yaxis != 0)
|
||||
forward -= ((movejoystickvector.yaxis * forwardmove[1]) >> 10); // ANALOG!
|
||||
|
||||
// some people strafe left & right with mouse buttons
|
||||
// those people are weird
|
||||
|
@ -1211,9 +1283,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
localaiming += (mlooky<<19)*player_invert*screen_invert;
|
||||
}
|
||||
|
||||
axis = JoyAxis(AXISLOOK);
|
||||
if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis.value != 0)
|
||||
localaiming += (axis<<16) * screen_invert;
|
||||
if (analogjoystickmove && joyaiming && lookjoystickvector.yaxis != 0 && cv_lookaxis.value != 0)
|
||||
localaiming += (lookjoystickvector.yaxis<<16) * screen_invert;
|
||||
|
||||
// spring back if not using keyboard neither mouselookin'
|
||||
if (!keyboard_look && cv_lookaxis.value == 0 && !joyaiming && !mouseaiming)
|
||||
|
@ -1221,12 +1292,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
|
||||
if (!(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
{
|
||||
if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0))
|
||||
if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0))
|
||||
{
|
||||
localaiming += KB_LOOKSPEED * screen_invert;
|
||||
keyboard_look = true;
|
||||
}
|
||||
else if (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && axis > 0))
|
||||
else if (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0))
|
||||
{
|
||||
localaiming -= KB_LOOKSPEED * screen_invert;
|
||||
keyboard_look = true;
|
||||
|
@ -1308,7 +1379,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
|
|||
//Reset away view if a command is given.
|
||||
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
|
||||
&& displayplayer != consoleplayer)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
// Call ViewpointSwitch hooks here.
|
||||
// The viewpoint was forcibly changed.
|
||||
LUAh_ViewpointSwitch(player, &players[displayplayer], true);
|
||||
#endif
|
||||
displayplayer = consoleplayer;
|
||||
}
|
||||
}
|
||||
|
||||
// like the g_buildticcmd 1 but using mouse2, gamcontrolbis, ...
|
||||
|
@ -1316,12 +1394,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
{
|
||||
boolean forcestrafe = false;
|
||||
boolean forcefullinput = false;
|
||||
INT32 tspeed, forward, side, axis, altaxis, i;
|
||||
INT32 tspeed, forward, side, axis, strafeaxis, moveaxis, turnaxis, lookaxis, i;
|
||||
const INT32 speed = 1;
|
||||
// these ones used for multiple conditions
|
||||
boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming;
|
||||
player_t *player = &players[secondarydisplayplayer];
|
||||
camera_t *thiscam = (player->bot == 2 ? &camera : &camera2);
|
||||
joystickvector2_t movejoystickvector, lookjoystickvector;
|
||||
|
||||
static INT32 turnheld; // for accelerative turning
|
||||
static boolean keyboard_look; // true if lookup/down using keyboard
|
||||
|
@ -1359,11 +1438,16 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
localaiming2 = 0;
|
||||
joyaiming = thisjoyaiming;
|
||||
|
||||
axis = Joy2Axis(AXISTURN);
|
||||
if (gamepadjoystickmove && axis != 0)
|
||||
turnaxis = Joy2Axis(AXISTURN);
|
||||
lookaxis = Joy2Axis(AXISLOOK);
|
||||
lookjoystickvector.xaxis = turnaxis;
|
||||
lookjoystickvector.yaxis = lookaxis;
|
||||
G_HandleAxisDeadZone(1, &lookjoystickvector);
|
||||
|
||||
if (gamepadjoystickmove && lookjoystickvector.xaxis != 0)
|
||||
{
|
||||
turnright = turnright || (axis > 0);
|
||||
turnleft = turnleft || (axis < 0);
|
||||
turnright = turnright || (lookjoystickvector.xaxis > 0);
|
||||
turnleft = turnleft || (lookjoystickvector.xaxis < 0);
|
||||
}
|
||||
forward = side = 0;
|
||||
|
||||
|
@ -1404,10 +1488,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
if (turnleft)
|
||||
side -= sidemove[speed];
|
||||
|
||||
if (analogjoystickmove && axis != 0)
|
||||
if (analogjoystickmove && lookjoystickvector.xaxis != 0)
|
||||
{
|
||||
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
|
||||
side += ((axis * sidemove[1]) >> 10);
|
||||
side += ((lookjoystickvector.xaxis * sidemove[1]) >> 10);
|
||||
}
|
||||
}
|
||||
else if (cv_analog2.value) // Analog
|
||||
|
@ -1424,41 +1508,44 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
else if (turnleft)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
|
||||
|
||||
if (analogjoystickmove && axis != 0)
|
||||
if (analogjoystickmove && lookjoystickvector.xaxis != 0)
|
||||
{
|
||||
// JOYAXISRANGE should be 1023 (divide by 1024)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG!
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((lookjoystickvector.xaxis * angleturn[1]) >> 10)); // ANALOG!
|
||||
}
|
||||
}
|
||||
|
||||
axis = Joy2Axis(AXISSTRAFE);
|
||||
if (gamepadjoystickmove && axis != 0)
|
||||
strafeaxis = Joy2Axis(AXISSTRAFE);
|
||||
moveaxis = Joy2Axis(AXISMOVE);
|
||||
movejoystickvector.xaxis = strafeaxis;
|
||||
movejoystickvector.yaxis = moveaxis;
|
||||
G_HandleAxisDeadZone(1, &movejoystickvector);
|
||||
|
||||
if (gamepadjoystickmove && movejoystickvector.xaxis != 0)
|
||||
{
|
||||
if (axis < 0)
|
||||
if (movejoystickvector.xaxis > 0)
|
||||
side += sidemove[speed];
|
||||
else if (axis > 0)
|
||||
else if (movejoystickvector.xaxis < 0)
|
||||
side -= sidemove[speed];
|
||||
}
|
||||
else if (analogjoystickmove && axis != 0)
|
||||
else if (analogjoystickmove && movejoystickvector.xaxis != 0)
|
||||
{
|
||||
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
|
||||
side += ((axis * sidemove[1]) >> 10);
|
||||
side += ((movejoystickvector.xaxis * sidemove[1]) >> 10);
|
||||
}
|
||||
|
||||
// forward with key or button
|
||||
axis = Joy2Axis(AXISMOVE);
|
||||
altaxis = Joy2Axis(AXISLOOK);
|
||||
if (movefkey || (gamepadjoystickmove && axis < 0)
|
||||
if (movefkey || (gamepadjoystickmove && movejoystickvector.yaxis < 0)
|
||||
|| ((player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
&& (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0))))
|
||||
&& (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0))))
|
||||
forward = forwardmove[speed];
|
||||
if (movebkey || (gamepadjoystickmove && axis > 0)
|
||||
if (movebkey || (gamepadjoystickmove && movejoystickvector.yaxis > 0)
|
||||
|| ((player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
&& (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0))))
|
||||
&& (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0))))
|
||||
forward -= forwardmove[speed];
|
||||
|
||||
if (analogjoystickmove && axis != 0)
|
||||
forward -= ((axis * forwardmove[1]) >> 10); // ANALOG!
|
||||
if (analogjoystickmove && movejoystickvector.yaxis != 0)
|
||||
forward -= ((movejoystickvector.yaxis * forwardmove[1]) >> 10); // ANALOG!
|
||||
|
||||
// some people strafe left & right with mouse buttons
|
||||
// those people are (still) weird
|
||||
|
@ -1538,9 +1625,8 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
localaiming2 += (mlook2y<<19)*player_invert*screen_invert;
|
||||
}
|
||||
|
||||
axis = Joy2Axis(AXISLOOK);
|
||||
if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis2.value != 0)
|
||||
localaiming2 += (axis<<16) * screen_invert;
|
||||
if (analogjoystickmove && joyaiming && lookjoystickvector.yaxis != 0 && cv_lookaxis2.value != 0)
|
||||
localaiming2 += (lookjoystickvector.yaxis<<16) * screen_invert;
|
||||
|
||||
// spring back if not using keyboard neither mouselookin'
|
||||
if (!keyboard_look && cv_lookaxis2.value == 0 && !joyaiming && !mouseaiming)
|
||||
|
@ -1548,12 +1634,12 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
|
|||
|
||||
if (!(player->powers[pw_carry] == CR_NIGHTSMODE))
|
||||
{
|
||||
if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0))
|
||||
if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0))
|
||||
{
|
||||
localaiming2 += KB_LOOKSPEED * screen_invert;
|
||||
keyboard_look = true;
|
||||
}
|
||||
else if (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && axis > 0))
|
||||
else if (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0))
|
||||
{
|
||||
localaiming2 -= KB_LOOKSPEED * screen_invert;
|
||||
keyboard_look = true;
|
||||
|
@ -1804,12 +1890,9 @@ void G_DoLoadLevel(boolean resetplayer)
|
|||
//
|
||||
void G_StartTitleCard(void)
|
||||
{
|
||||
wipestyleflags |= WSF_FADEIN;
|
||||
wipestyleflags &= ~WSF_FADEOUT;
|
||||
|
||||
// The title card has been disabled for this map.
|
||||
// Oh well.
|
||||
if (mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
|
||||
if (!G_IsTitleCardAvailable())
|
||||
{
|
||||
WipeStageTitle = false;
|
||||
return;
|
||||
|
@ -1850,6 +1933,25 @@ void G_PreLevelTitleCard(void)
|
|||
if (takescreenshot) // Only take screenshots after drawing.
|
||||
M_DoScreenShot();
|
||||
}
|
||||
if (!cv_showhud.value)
|
||||
wipestyleflags = WSF_CROSSFADE;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns true if the current level has a title card.
|
||||
//
|
||||
boolean G_IsTitleCardAvailable(void)
|
||||
{
|
||||
// The current level header explicitly disabled the title card.
|
||||
if (mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)
|
||||
return false;
|
||||
|
||||
// The current gametype doesn't have a title card.
|
||||
if (gametyperules & GTR_NOTITLECARD)
|
||||
return false;
|
||||
|
||||
// The title card is available.
|
||||
return true;
|
||||
}
|
||||
|
||||
INT32 pausedelay = 0;
|
||||
|
@ -1942,6 +2044,11 @@ boolean G_Responder(event_t *ev)
|
|||
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
|
||||
{
|
||||
// ViewpointSwitch Lua hook.
|
||||
#ifdef HAVE_BLUA
|
||||
UINT8 canSwitchView = 0;
|
||||
#endif
|
||||
|
||||
if (splitscreen || !netgame)
|
||||
displayplayer = consoleplayer;
|
||||
else
|
||||
|
@ -1956,6 +2063,15 @@ boolean G_Responder(event_t *ev)
|
|||
if (!playeringame[displayplayer])
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// Call ViewpointSwitch hooks here.
|
||||
canSwitchView = LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer], false);
|
||||
if (canSwitchView == 1) // Set viewpoint to this player
|
||||
break;
|
||||
else if (canSwitchView == 2) // Skip this player
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (players[displayplayer].spectator)
|
||||
continue;
|
||||
|
||||
|
@ -2564,7 +2680,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
|||
|
||||
// -- CTF --
|
||||
// Order: CTF->DM->Coop
|
||||
if (gametype == GT_CTF && players[playernum].ctfteam)
|
||||
if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam)
|
||||
{
|
||||
if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start
|
||||
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
||||
|
@ -2573,7 +2689,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
|||
|
||||
// -- DM/Tag/CTF-spectator/etc --
|
||||
// Order: DM->CTF->Coop
|
||||
else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF
|
||||
else if ((gametyperules & GTR_DEATHMATCHSTARTS) || gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF
|
||||
|| ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT)))
|
||||
{
|
||||
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
|
||||
|
@ -2620,7 +2736,7 @@ mapthing_t *G_FindCTFStart(INT32 playernum)
|
|||
|
||||
if (!numredctfstarts && !numbluectfstarts) //why even bother, eh?
|
||||
{
|
||||
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
||||
if ((gametyperules & GTR_TEAMFLAGS) && (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer)))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("No CTF starts in this map!\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3026,7 +3142,7 @@ void G_ExitLevel(void)
|
|||
CV_SetValue(&cv_teamscramble, cv_scrambleonchange.value);
|
||||
}
|
||||
|
||||
if (gametype != GT_COOP)
|
||||
if (!(gametyperules & GTR_CAMPAIGN))
|
||||
CONS_Printf(M_GetText("The round has ended.\n"));
|
||||
|
||||
// Remove CEcho text on round end.
|
||||
|
@ -3058,6 +3174,221 @@ const char *Gametype_Names[NUMGAMETYPES] =
|
|||
"CTF" // GT_CTF
|
||||
};
|
||||
|
||||
// For dehacked
|
||||
const char *Gametype_ConstantNames[NUMGAMETYPES] =
|
||||
{
|
||||
"GT_COOP", // GT_COOP
|
||||
"GT_COMPETITION", // GT_COMPETITION
|
||||
"GT_RACE", // GT_RACE
|
||||
|
||||
"GT_MATCH", // GT_MATCH
|
||||
"GT_TEAMMATCH", // GT_TEAMMATCH
|
||||
|
||||
"GT_TAG", // GT_TAG
|
||||
"GT_HIDEANDSEEK", // GT_HIDEANDSEEK
|
||||
|
||||
"GT_CTF" // GT_CTF
|
||||
};
|
||||
|
||||
// Gametype rules
|
||||
UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
||||
{
|
||||
// Co-op
|
||||
GTR_CAMPAIGN|GTR_LIVES|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES,
|
||||
// Competition
|
||||
GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
|
||||
// Race
|
||||
GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
|
||||
|
||||
// Match
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD|GTR_DEATHPENALTY,
|
||||
// Team Match
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_PITYSHIELD,
|
||||
|
||||
// Tag
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL,
|
||||
// Hide and Seek
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL,
|
||||
|
||||
// CTF
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD,
|
||||
};
|
||||
|
||||
//
|
||||
// G_SetGametype
|
||||
//
|
||||
// Set a new gametype, also setting gametype rules accordingly. Yay!
|
||||
//
|
||||
void G_SetGametype(INT16 gtype)
|
||||
{
|
||||
gametype = gtype;
|
||||
gametyperules = gametypedefaultrules[gametype];
|
||||
}
|
||||
|
||||
//
|
||||
// G_AddGametype
|
||||
//
|
||||
// Add a gametype. Returns the new gametype number.
|
||||
//
|
||||
INT16 G_AddGametype(UINT32 rules)
|
||||
{
|
||||
INT16 newgtype = gametypecount;
|
||||
gametypecount++;
|
||||
|
||||
// Set gametype rules.
|
||||
gametypedefaultrules[newgtype] = rules;
|
||||
Gametype_Names[newgtype] = "???";
|
||||
|
||||
// Update gametype_cons_t accordingly.
|
||||
G_UpdateGametypeSelections();
|
||||
|
||||
return newgtype;
|
||||
}
|
||||
|
||||
//
|
||||
// G_AddGametypeConstant
|
||||
//
|
||||
// Self-explanatory. Filters out "bad" characters.
|
||||
//
|
||||
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
||||
{
|
||||
char *gtconst = Z_Malloc(strlen(newgtconst) + 3, PU_STATIC, NULL);
|
||||
// Copy GT_ and the gametype name.
|
||||
strcpy(gtconst, "GT_");
|
||||
strcat(gtconst, newgtconst);
|
||||
// Make uppercase.
|
||||
strupr(gtconst);
|
||||
// Remove characters.
|
||||
#define REMOVECHAR(chr) \
|
||||
{ \
|
||||
char *chrfind = strchr(gtconst, chr); \
|
||||
while (chrfind) \
|
||||
{ \
|
||||
*chrfind = '_'; \
|
||||
chrfind = strchr(chrfind, chr); \
|
||||
} \
|
||||
}
|
||||
|
||||
// Space
|
||||
REMOVECHAR(' ')
|
||||
// Used for operations
|
||||
REMOVECHAR('+')
|
||||
REMOVECHAR('-')
|
||||
REMOVECHAR('*')
|
||||
REMOVECHAR('/')
|
||||
REMOVECHAR('%')
|
||||
REMOVECHAR('^')
|
||||
// Part of Lua's syntax
|
||||
REMOVECHAR('#')
|
||||
REMOVECHAR('=')
|
||||
REMOVECHAR('~')
|
||||
REMOVECHAR('<')
|
||||
REMOVECHAR('>')
|
||||
REMOVECHAR('(')
|
||||
REMOVECHAR(')')
|
||||
REMOVECHAR('{')
|
||||
REMOVECHAR('}')
|
||||
REMOVECHAR('[')
|
||||
REMOVECHAR(']')
|
||||
REMOVECHAR(':')
|
||||
REMOVECHAR(';')
|
||||
REMOVECHAR(',')
|
||||
REMOVECHAR('.')
|
||||
|
||||
#undef REMOVECHAR
|
||||
|
||||
// Finally, set the constant string.
|
||||
Gametype_ConstantNames[gtype] = gtconst;
|
||||
}
|
||||
|
||||
//
|
||||
// G_UpdateGametypeSelections
|
||||
//
|
||||
// Updates gametype_cons_t.
|
||||
//
|
||||
void G_UpdateGametypeSelections(void)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < gametypecount; i++)
|
||||
{
|
||||
gametype_cons_t[i].value = i;
|
||||
gametype_cons_t[i].strvalue = Gametype_Names[i];
|
||||
}
|
||||
gametype_cons_t[NUMGAMETYPES].value = 0;
|
||||
gametype_cons_t[NUMGAMETYPES].strvalue = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// G_SetGametypeDescription
|
||||
//
|
||||
// Set a description for the specified gametype.
|
||||
// (Level platter)
|
||||
//
|
||||
void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor)
|
||||
{
|
||||
if (descriptiontext != NULL)
|
||||
strncpy(gametypedesc[gtype].notes, descriptiontext, 441);
|
||||
gametypedesc[gtype].col[0] = leftcolor;
|
||||
gametypedesc[gtype].col[1] = rightcolor;
|
||||
}
|
||||
|
||||
// Gametype rankings
|
||||
INT16 gametyperankings[NUMGAMETYPES] =
|
||||
{
|
||||
GT_COOP,
|
||||
GT_COMPETITION,
|
||||
GT_RACE,
|
||||
|
||||
GT_MATCH,
|
||||
GT_TEAMMATCH,
|
||||
|
||||
GT_TAG,
|
||||
GT_HIDEANDSEEK,
|
||||
|
||||
GT_CTF,
|
||||
};
|
||||
|
||||
// Gametype to TOL (Type Of Level)
|
||||
UINT32 gametypetol[NUMGAMETYPES] =
|
||||
{
|
||||
TOL_COOP, // Co-op
|
||||
TOL_COMPETITION, // Competition
|
||||
TOL_RACE, // Race
|
||||
|
||||
TOL_MATCH, // Match
|
||||
TOL_MATCH, // Team Match
|
||||
|
||||
TOL_TAG, // Tag
|
||||
TOL_TAG, // Hide and Seek
|
||||
|
||||
TOL_CTF, // CTF
|
||||
};
|
||||
|
||||
//
|
||||
// G_AddTOL
|
||||
//
|
||||
// Adds a type of level.
|
||||
//
|
||||
void G_AddTOL(UINT32 newtol, const char *tolname)
|
||||
{
|
||||
TYPEOFLEVEL[numtolinfo].name = Z_StrDup(tolname);
|
||||
TYPEOFLEVEL[numtolinfo].flag = newtol;
|
||||
numtolinfo++;
|
||||
|
||||
TYPEOFLEVEL[numtolinfo].name = NULL;
|
||||
TYPEOFLEVEL[numtolinfo].flag = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// G_AddTOL
|
||||
//
|
||||
// Assigns a type of level to a gametype.
|
||||
//
|
||||
void G_AddGametypeTOL(INT16 gtype, UINT32 newtol)
|
||||
{
|
||||
gametypetol[gtype] = newtol;
|
||||
}
|
||||
|
||||
//
|
||||
// G_GetGametypeByName
|
||||
//
|
||||
|
@ -3100,8 +3431,8 @@ boolean G_IsSpecialStage(INT32 mapnum)
|
|||
//
|
||||
boolean G_GametypeUsesLives(void)
|
||||
{
|
||||
// Coop, Competitive
|
||||
if ((gametype == GT_COOP || gametype == GT_COMPETITION)
|
||||
// Coop, Competitive
|
||||
if ((gametyperules & GTR_LIVES)
|
||||
&& !(modeattacking || metalrecording) // No lives in Time Attack
|
||||
&& !G_IsSpecialStage(gamemap)
|
||||
&& !(maptol & TOL_NIGHTS)) // No lives in NiGHTS
|
||||
|
@ -3117,7 +3448,7 @@ boolean G_GametypeUsesLives(void)
|
|||
//
|
||||
boolean G_GametypeHasTeams(void)
|
||||
{
|
||||
return (gametype == GT_TEAMMATCH || gametype == GT_CTF);
|
||||
return (gametyperules & GTR_TEAMS);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3128,7 +3459,7 @@ boolean G_GametypeHasTeams(void)
|
|||
//
|
||||
boolean G_GametypeHasSpectators(void)
|
||||
{
|
||||
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE);
|
||||
return (gametyperules & GTR_SPECTATORS);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3139,7 +3470,7 @@ boolean G_GametypeHasSpectators(void)
|
|||
//
|
||||
boolean G_RingSlingerGametype(void)
|
||||
{
|
||||
return ((gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE) || (cv_ringslinger.value));
|
||||
return ((gametyperules & GTR_RINGSLINGER) || (cv_ringslinger.value));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3149,7 +3480,7 @@ boolean G_RingSlingerGametype(void)
|
|||
//
|
||||
boolean G_PlatformGametype(void)
|
||||
{
|
||||
return (gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION);
|
||||
return (!(gametyperules & GTR_RINGSLINGER));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3159,7 +3490,7 @@ boolean G_PlatformGametype(void)
|
|||
//
|
||||
boolean G_TagGametype(void)
|
||||
{
|
||||
return (gametype == GT_TAG || gametype == GT_HIDEANDSEEK);
|
||||
return (gametyperules & GTR_TAG);
|
||||
}
|
||||
|
||||
/** Get the typeoflevel flag needed to indicate support of a gametype.
|
||||
|
@ -3170,18 +3501,9 @@ boolean G_TagGametype(void)
|
|||
*/
|
||||
INT16 G_TOLFlag(INT32 pgametype)
|
||||
{
|
||||
if (!multiplayer) return TOL_SP;
|
||||
if (pgametype == GT_COOP) return TOL_COOP;
|
||||
if (pgametype == GT_COMPETITION) return TOL_COMPETITION;
|
||||
if (pgametype == GT_RACE) return TOL_RACE;
|
||||
if (pgametype == GT_MATCH) return TOL_MATCH;
|
||||
if (pgametype == GT_TEAMMATCH) return TOL_MATCH;
|
||||
if (pgametype == GT_TAG) return TOL_TAG;
|
||||
if (pgametype == GT_HIDEANDSEEK) return TOL_TAG;
|
||||
if (pgametype == GT_CTF) return TOL_CTF;
|
||||
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Unknown gametype! %d\n"), pgametype);
|
||||
return INT16_MAX;
|
||||
if (!multiplayer)
|
||||
return TOL_SP;
|
||||
return gametypetol[pgametype];
|
||||
}
|
||||
|
||||
/** Select a random map with the given typeoflevel flags.
|
||||
|
@ -3192,7 +3514,7 @@ INT16 G_TOLFlag(INT32 pgametype)
|
|||
* has those flags.
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static INT16 RandMap(INT16 tolflags, INT16 pprevmap)
|
||||
static INT16 RandMap(UINT32 tolflags, INT16 pprevmap)
|
||||
{
|
||||
INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL);
|
||||
INT32 numokmaps = 0;
|
||||
|
@ -3350,10 +3672,10 @@ static void G_DoCompleted(void)
|
|||
I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1);
|
||||
|
||||
// wrap around in race
|
||||
if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametype == GT_RACE || gametype == GT_COMPETITION))
|
||||
if (nextmap >= 1100-1 && nextmap <= 1102-1 && !(gametyperules & GTR_CAMPAIGN))
|
||||
nextmap = (INT16)(spstage_start-1);
|
||||
|
||||
if ((gottoken = (gametype == GT_COOP && token)))
|
||||
if ((gottoken = ((gametyperules & GTR_SPECIALSTAGES) && token)))
|
||||
{
|
||||
token--;
|
||||
|
||||
|
@ -3373,7 +3695,7 @@ static void G_DoCompleted(void)
|
|||
|
||||
automapactive = false;
|
||||
|
||||
if (gametype != GT_COOP)
|
||||
if (!(gametyperules & GTR_CAMPAIGN))
|
||||
{
|
||||
if (cv_advancemap.value == 0) // Stay on same map.
|
||||
nextmap = prevmap;
|
||||
|
|
14
src/g_game.h
14
src/g_game.h
|
@ -72,6 +72,7 @@ extern consvar_t cv_useranalog, cv_useranalog2;
|
|||
extern consvar_t cv_analog, cv_analog2;
|
||||
extern consvar_t cv_directionchar, cv_directionchar2;
|
||||
extern consvar_t cv_autobrake, cv_autobrake2;
|
||||
extern consvar_t cv_deadzone, cv_deadzone2;
|
||||
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis;
|
||||
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2;
|
||||
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
|
||||
|
@ -142,6 +143,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,
|
|||
void G_DoLoadLevel(boolean resetplayer);
|
||||
void G_StartTitleCard(void);
|
||||
void G_PreLevelTitleCard(void);
|
||||
boolean G_IsTitleCardAvailable(void);
|
||||
void G_DeferedPlayDemo(const char *demo);
|
||||
|
||||
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
|
||||
|
@ -201,6 +203,18 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
|
|||
void G_StopDemo(void);
|
||||
boolean G_CheckDemoStatus(void);
|
||||
|
||||
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
|
||||
extern UINT32 gametypetol[NUMGAMETYPES];
|
||||
extern INT16 gametyperankings[NUMGAMETYPES];
|
||||
|
||||
void G_SetGametype(INT16 gametype);
|
||||
INT16 G_AddGametype(UINT32 rules);
|
||||
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst);
|
||||
void G_UpdateGametypeSelections(void);
|
||||
void G_AddTOL(UINT32 newtol, const char *tolname);
|
||||
void G_AddGametypeTOL(INT16 gtype, UINT32 newtol);
|
||||
void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor);
|
||||
|
||||
INT32 G_GetGametypeByName(const char *gametypestr);
|
||||
boolean G_IsSpecialStage(INT32 mapnum);
|
||||
boolean G_GametypeUsesLives(void);
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
#include "../r_patch.h"
|
||||
#include "../p_setup.h"
|
||||
|
||||
//Hurdler: 25/04/2000: used for new colormap code in hardware mode
|
||||
//static UINT8 *gr_colormap = NULL; // by default it must be NULL ! (because colormap tables are not initialized)
|
||||
boolean firetranslucent = false;
|
||||
|
||||
// Values set after a call to HWR_ResizeBlock()
|
||||
static INT32 blocksize, blockwidth, blockheight;
|
||||
|
||||
|
@ -122,18 +118,16 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
|
||||
texel = source[yfrac>>FRACBITS];
|
||||
|
||||
if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel))
|
||||
alpha = 0x80;
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if (mipmap->colormap)
|
||||
texel = mipmap->colormap[texel];
|
||||
|
||||
// transparent pixel
|
||||
if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)
|
||||
alpha = 0x00;
|
||||
else
|
||||
alpha = 0xff;
|
||||
|
||||
//Hurdler: not perfect, but better than holes
|
||||
if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED))
|
||||
texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX;
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
else if (mipmap->colormap)
|
||||
texel = mipmap->colormap[texel];
|
||||
|
||||
// hope compiler will get this switch out of the loops (dreams...)
|
||||
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
|
||||
// Alam: SRB2 uses Mingw, HUGS
|
||||
|
@ -236,18 +230,16 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
|
||||
texel = source[yfrac>>FRACBITS];
|
||||
|
||||
if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel))
|
||||
alpha = 0x80;
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if (mipmap->colormap)
|
||||
texel = mipmap->colormap[texel];
|
||||
|
||||
// transparent pixel
|
||||
if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)
|
||||
alpha = 0x00;
|
||||
else
|
||||
alpha = 0xff;
|
||||
|
||||
//Hurdler: not perfect, but better than holes
|
||||
if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED))
|
||||
texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX;
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
else if (mipmap->colormap)
|
||||
texel = mipmap->colormap[texel];
|
||||
|
||||
// hope compiler will get this switch out of the loops (dreams...)
|
||||
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
|
||||
// Alam: SRB2 uses Mingw, HUGS
|
||||
|
@ -576,7 +568,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
|
|||
{
|
||||
UINT8 *block;
|
||||
INT32 bpp, i;
|
||||
UINT16 bu16 = ((0x00 <<8) | HWR_CHROMAKEY_EQUIVALENTCOLORINDEX);
|
||||
UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX);
|
||||
|
||||
bpp = format2bpp[grMipmap->grInfo.format];
|
||||
block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data));
|
||||
|
@ -606,6 +598,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
|
|||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
patch_t *realpatch;
|
||||
UINT8 *pdata;
|
||||
|
||||
INT32 i;
|
||||
boolean skyspecial = false; //poor hack for Legacy large skies..
|
||||
|
@ -638,7 +631,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
|
|||
INT32 j;
|
||||
RGBA_t col;
|
||||
|
||||
col = V_GetColor(HWR_CHROMAKEY_EQUIVALENTCOLORINDEX);
|
||||
col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX);
|
||||
for (j = 0; j < blockheight; j++)
|
||||
{
|
||||
for (i = 0; i < blockwidth; i++)
|
||||
|
@ -654,19 +647,30 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
|
|||
// Composite the columns together.
|
||||
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
||||
{
|
||||
#ifndef NO_PNG_LUMPS
|
||||
boolean dealloc = true;
|
||||
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
|
||||
#endif
|
||||
realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
|
||||
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
|
||||
realpatch = (patch_t *)pdata;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
|
||||
else
|
||||
#endif
|
||||
HWR_DrawTexturePatchInCache(&grtex->mipmap,
|
||||
blockwidth, blockheight,
|
||||
texture, patch,
|
||||
realpatch);
|
||||
Z_Unlock(realpatch);
|
||||
#ifdef WALLFLATS
|
||||
if (texture->type == TEXTURETYPE_FLAT)
|
||||
realpatch = R_FlatToPatch(pdata, texture->width, texture->height, 0, 0, NULL, false);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
(void)lumplength;
|
||||
dealloc = false;
|
||||
}
|
||||
|
||||
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
|
||||
|
||||
if (dealloc)
|
||||
Z_Unlock(realpatch);
|
||||
}
|
||||
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
|
||||
if (format2bpp[grtex->mipmap.grInfo.format]==4)
|
||||
|
|
|
@ -42,7 +42,7 @@ typedef unsigned char FBOOLEAN;
|
|||
|
||||
// byte value for paletted graphics, which represent the transparent color
|
||||
#define HWR_PATCHES_CHROMAKEY_COLORINDEX 255
|
||||
#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 130
|
||||
//#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 130
|
||||
|
||||
// the chroma key color shows on border sprites, set it to black
|
||||
#define HWR_PATCHES_CHROMAKEY_COLORVALUE (0x00000000) //RGBA format as in grSstWinOpen()
|
||||
|
|
|
@ -128,6 +128,5 @@ extern consvar_t cv_grrounddown; // on/off
|
|||
|
||||
extern INT32 patchformat;
|
||||
extern INT32 textureformat;
|
||||
extern boolean firetranslucent;
|
||||
|
||||
#endif //_HW_GLOB_
|
||||
|
|
|
@ -963,7 +963,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
|
|||
for (grmip = gpatch->mipmap; grmip->nextcolormap; )
|
||||
{
|
||||
grmip = grmip->nextcolormap;
|
||||
if (grmip->colormap == colormap || grmip->tcindex == skinnum)
|
||||
if (grmip->colormap == colormap || (skinnum < TC_DEFAULT && grmip->tcindex == skinnum))
|
||||
{
|
||||
if (grmip->downloaded && grmip->grInfo.data)
|
||||
{
|
||||
|
|
|
@ -2066,7 +2066,7 @@ static void HU_drawGametype(void)
|
|||
{
|
||||
const char *strvalue = NULL;
|
||||
|
||||
if (gametype < 0 || gametype >= NUMGAMETYPES)
|
||||
if (gametype < 0 || gametype >= gametypecount)
|
||||
return; // not a valid gametype???
|
||||
|
||||
strvalue = Gametype_Names[gametype];
|
||||
|
@ -2371,7 +2371,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
|
||||
for (i = 0; i < scorelines; i++)
|
||||
{
|
||||
if (players[tab[i].num].spectator && gametype != GT_COOP)
|
||||
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP)
|
||||
continue; //ignore them.
|
||||
|
||||
greycheck = greycheckdef;
|
||||
|
@ -2434,7 +2434,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
}
|
||||
}
|
||||
|
||||
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
||||
if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives));
|
||||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||
{
|
||||
|
@ -2447,7 +2447,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED))
|
||||
V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon);
|
||||
|
||||
if (gametype == GT_RACE)
|
||||
if (gametyperankings[gametype] == GT_RACE)
|
||||
{
|
||||
if (circuitmap)
|
||||
{
|
||||
|
@ -2541,7 +2541,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
| (greycheck ? 0 : V_TRANSLUCENT)
|
||||
| V_ALLOWLOWERCASE, name);
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
{
|
||||
if (players[tab[i].num].gotflag & GF_REDFLAG) // Red
|
||||
V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, rflagico, 0);
|
||||
|
@ -2669,7 +2669,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
| (greycheck ? V_TRANSLUCENT : 0)
|
||||
| V_ALLOWLOWERCASE, name);
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
{
|
||||
if (players[tab[i].num].gotflag & GF_REDFLAG) // Red
|
||||
V_DrawSmallScaledPatch(x-28, y-4, 0, rflagico);
|
||||
|
@ -2726,7 +2726,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
|
||||
for (i = 0; i < scorelines; i++)
|
||||
{
|
||||
if (players[tab[i].num].spectator && gametype != GT_COOP)
|
||||
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP)
|
||||
continue; //ignore them.
|
||||
|
||||
greycheck = greycheckdef;
|
||||
|
@ -2743,7 +2743,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
| (greycheck ? V_TRANSLUCENT : 0)
|
||||
| V_ALLOWLOWERCASE, name);
|
||||
|
||||
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
||||
if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives));
|
||||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
|
||||
|
@ -2792,7 +2792,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
}
|
||||
|
||||
// All data drawn with thin string for space.
|
||||
if (gametype == GT_RACE)
|
||||
if (gametyperankings[gametype] == GT_RACE)
|
||||
{
|
||||
if (circuitmap)
|
||||
{
|
||||
|
@ -2832,7 +2832,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
|
|||
|
||||
for (i = 0; i < scorelines; i++)
|
||||
{
|
||||
if (players[tab[i].num].spectator && gametype != GT_COOP)
|
||||
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP)
|
||||
continue; //ignore them.
|
||||
|
||||
greycheck = greycheckdef;
|
||||
|
@ -2902,7 +2902,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
|
|||
}
|
||||
|
||||
// All data drawn with thin string for space.
|
||||
if (gametype == GT_RACE)
|
||||
if (gametyperankings[gametype] == GT_RACE)
|
||||
{
|
||||
if (circuitmap)
|
||||
{
|
||||
|
@ -3026,21 +3026,21 @@ static void HU_DrawRankings(void)
|
|||
// draw the current gametype in the lower right
|
||||
HU_drawGametype();
|
||||
|
||||
if (gametype != GT_RACE && gametype != GT_COMPETITION && gametype != GT_COOP)
|
||||
if (gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT))
|
||||
{
|
||||
if (cv_timelimit.value && timelimitintics > 0)
|
||||
if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0)
|
||||
{
|
||||
V_DrawCenteredString(64, 8, 0, "TIME");
|
||||
V_DrawCenteredString(64, 16, 0, va("%i:%02i", G_TicsToMinutes(stplyr->realtime, true), G_TicsToSeconds(stplyr->realtime)));
|
||||
}
|
||||
|
||||
if (cv_pointlimit.value > 0)
|
||||
if ((gametyperules & GTR_POINTLIMIT) && cv_pointlimit.value > 0)
|
||||
{
|
||||
V_DrawCenteredString(256, 8, 0, "POINT LIMIT");
|
||||
V_DrawCenteredString(256, 16, 0, va("%d", cv_pointlimit.value));
|
||||
}
|
||||
}
|
||||
else if (gametype == GT_COOP)
|
||||
else if (gametyperankings[gametype] == GT_COOP)
|
||||
{
|
||||
INT32 totalscore = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -3074,7 +3074,7 @@ static void HU_DrawRankings(void)
|
|||
tab[i].num = -1;
|
||||
tab[i].name = 0;
|
||||
|
||||
if (gametype == GT_RACE && !circuitmap)
|
||||
if (gametyperankings[gametype] == GT_RACE && !circuitmap)
|
||||
tab[i].count = INT32_MAX;
|
||||
}
|
||||
|
||||
|
@ -3083,7 +3083,7 @@ static void HU_DrawRankings(void)
|
|||
if (!playeringame[j])
|
||||
continue;
|
||||
|
||||
if (gametype != GT_COOP && players[j].spectator)
|
||||
if (!G_PlatformGametype() && players[j].spectator)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -3091,10 +3091,10 @@ static void HU_DrawRankings(void)
|
|||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
if (gametype != GT_COOP && players[i].spectator)
|
||||
if (!G_PlatformGametype() && players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (gametype == GT_RACE)
|
||||
if (gametyperankings[gametype] == GT_RACE)
|
||||
{
|
||||
if (circuitmap)
|
||||
{
|
||||
|
@ -3117,7 +3117,7 @@ static void HU_DrawRankings(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (gametype == GT_COMPETITION)
|
||||
else if (gametyperankings[gametype] == GT_COMPETITION)
|
||||
{
|
||||
// todo put something more fitting for the gametype here, such as current
|
||||
// number of categories led
|
||||
|
|
|
@ -184,10 +184,6 @@ void I_StartupMouse(void);
|
|||
*/
|
||||
void I_StartupMouse2(void);
|
||||
|
||||
/** \brief keyboard startup, shutdown, handler
|
||||
*/
|
||||
void I_StartupKeyboard(void);
|
||||
|
||||
/** \brief setup timer irq and user timer routine.
|
||||
*/
|
||||
void I_StartupTimer(void);
|
||||
|
|
35
src/i_tcp.c
35
src/i_tcp.c
|
@ -209,7 +209,8 @@ static size_t numbans = 0;
|
|||
static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1?
|
||||
static boolean init_tcp_driver = false;
|
||||
|
||||
static char port_name[8] = DEFAULTPORT;
|
||||
static const char *serverport_name = DEFAULTPORT;
|
||||
static const char *clientport_name;/* any port */
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
|
@ -887,6 +888,7 @@ static boolean UDP_Socket(void)
|
|||
#ifdef HAVE_IPV6
|
||||
const INT32 b_ipv6 = M_CheckParm("-ipv6");
|
||||
#endif
|
||||
const char *serv;
|
||||
|
||||
|
||||
for (s = 0; s < mysocketses; s++)
|
||||
|
@ -902,11 +904,16 @@ static boolean UDP_Socket(void)
|
|||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
if (serverrunning)
|
||||
serv = serverport_name;
|
||||
else
|
||||
serv = clientport_name;
|
||||
|
||||
if (M_CheckParm("-bindaddr"))
|
||||
{
|
||||
while (M_IsNextParm())
|
||||
{
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -927,7 +934,7 @@ static boolean UDP_Socket(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gaie = I_getaddrinfo("0.0.0.0", port_name, &hints, &ai);
|
||||
gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -942,8 +949,8 @@ static boolean UDP_Socket(void)
|
|||
#ifdef HAVE_MINIUPNPC
|
||||
if (UPNP_support)
|
||||
{
|
||||
I_UPnP_rem(port_name, "UDP");
|
||||
I_UPnP_add(NULL, port_name, "UDP");
|
||||
I_UPnP_rem(serverport_name, "UDP");
|
||||
I_UPnP_add(NULL, serverport_name, "UDP");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -960,7 +967,7 @@ static boolean UDP_Socket(void)
|
|||
{
|
||||
while (M_IsNextParm())
|
||||
{
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
|
||||
gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -981,7 +988,7 @@ static boolean UDP_Socket(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gaie = I_getaddrinfo("::", port_name, &hints, &ai);
|
||||
gaie = I_getaddrinfo("::", serv, &hints, &ai);
|
||||
if (gaie == 0)
|
||||
{
|
||||
runp = ai;
|
||||
|
@ -1421,15 +1428,19 @@ boolean I_InitTcpNetwork(void)
|
|||
if (!I_InitTcpDriver())
|
||||
return false;
|
||||
|
||||
if (M_CheckParm("-port"))
|
||||
if (M_CheckParm("-port") || M_CheckParm("-serverport"))
|
||||
// Combined -udpport and -clientport into -port
|
||||
// As it was really redundant having two seperate parms that does the same thing
|
||||
/* Sorry Steel, I'm adding these back. But -udpport is a stupid name. */
|
||||
{
|
||||
if (M_IsNextParm())
|
||||
strcpy(port_name, M_GetNextParm());
|
||||
else
|
||||
strcpy(port_name, "0");
|
||||
/*
|
||||
If it's NULL, that's okay! Because then
|
||||
we'll get a random port from getaddrinfo.
|
||||
*/
|
||||
serverport_name = M_GetNextParm();
|
||||
}
|
||||
if (M_CheckParm("-clientport"))
|
||||
clientport_name = M_GetNextParm();
|
||||
|
||||
// parse network game options,
|
||||
if (M_CheckParm("-server") || dedicated)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h" // So we can have P_SetupLevelSky
|
||||
#ifdef ESLOPE
|
||||
|
@ -23,6 +24,8 @@
|
|||
#include "m_random.h"
|
||||
#include "s_sound.h"
|
||||
#include "g_game.h"
|
||||
#include "m_menu.h"
|
||||
#include "y_inter.h"
|
||||
#include "hu_stuff.h" // HU_AddChatText
|
||||
#include "console.h"
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
|
@ -2630,6 +2633,145 @@ static int lib_sStartMusicCaption(lua_State *L)
|
|||
// G_GAME
|
||||
////////////
|
||||
|
||||
// Copypasted from lib_cvRegisterVar :]
|
||||
static int lib_gAddGametype(lua_State *L)
|
||||
{
|
||||
const char *k;
|
||||
lua_Integer i;
|
||||
|
||||
const char *gtname = NULL;
|
||||
const char *gtconst = NULL;
|
||||
const char *gtdescription = NULL;
|
||||
INT16 newgtidx = 0;
|
||||
UINT32 newgtrules = 0;
|
||||
UINT32 newgttol = 0;
|
||||
INT32 newgtpointlimit = 0;
|
||||
INT32 newgttimelimit = 0;
|
||||
UINT8 newgtleftcolor = 0;
|
||||
UINT8 newgtrightcolor = 0;
|
||||
INT16 newgtrankingstype = -1;
|
||||
int newgtinttype = 0;
|
||||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
|
||||
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||
|
||||
// Ran out of gametype slots
|
||||
if (gametypecount == NUMGAMETYPEFREESLOTS)
|
||||
return luaL_error(L, "Ran out of free gametype slots!");
|
||||
|
||||
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("G_AddGametype") " (%s)", e);
|
||||
#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
// stack: gametype table, key/index, value
|
||||
// 1 2 3
|
||||
i = 0;
|
||||
k = NULL;
|
||||
if (lua_isnumber(L, 2))
|
||||
i = lua_tointeger(L, 2);
|
||||
else if (lua_isstring(L, 2))
|
||||
k = lua_tostring(L, 2);
|
||||
|
||||
// Sorry, no gametype rules as key names.
|
||||
if (i == 1 || (k && fasticmp(k, "name"))) {
|
||||
if (!lua_isstring(L, 3))
|
||||
TYPEERROR("name", LUA_TSTRING)
|
||||
gtname = Z_StrDup(lua_tostring(L, 3));
|
||||
} else if (i == 2 || (k && fasticmp(k, "identifier"))) {
|
||||
if (!lua_isstring(L, 3))
|
||||
TYPEERROR("identifier", LUA_TSTRING)
|
||||
gtconst = Z_StrDup(lua_tostring(L, 3));
|
||||
} else if (i == 3 || (k && fasticmp(k, "rules"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("rules", LUA_TNUMBER)
|
||||
newgtrules = (UINT32)lua_tointeger(L, 3);
|
||||
} else if (i == 4 || (k && fasticmp(k, "typeoflevel"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("typeoflevel", LUA_TNUMBER)
|
||||
newgttol = (UINT32)lua_tointeger(L, 3);
|
||||
} else if (i == 5 || (k && fasticmp(k, "rankingtype"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("rankingtype", LUA_TNUMBER)
|
||||
newgtrankingstype = (INT16)lua_tointeger(L, 3);
|
||||
} else if (i == 6 || (k && fasticmp(k, "intermissiontype"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("intermissiontype", LUA_TNUMBER)
|
||||
newgtinttype = (int)lua_tointeger(L, 3);
|
||||
} else if (i == 7 || (k && fasticmp(k, "defaultpointlimit"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("defaultpointlimit", LUA_TNUMBER)
|
||||
newgtpointlimit = (INT32)lua_tointeger(L, 3);
|
||||
} else if (i == 8 || (k && fasticmp(k, "defaulttimelimit"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("defaulttimelimit", LUA_TNUMBER)
|
||||
newgttimelimit = (INT32)lua_tointeger(L, 3);
|
||||
} else if (i == 9 || (k && fasticmp(k, "description"))) {
|
||||
if (!lua_isstring(L, 3))
|
||||
TYPEERROR("description", LUA_TSTRING)
|
||||
gtdescription = Z_StrDup(lua_tostring(L, 3));
|
||||
} else if (i == 10 || (k && fasticmp(k, "headerleftcolor"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("headerleftcolor", LUA_TNUMBER)
|
||||
newgtleftcolor = (UINT8)lua_tointeger(L, 3);
|
||||
} else if (i == 11 || (k && fasticmp(k, "headerrightcolor"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("headerrightcolor", LUA_TNUMBER)
|
||||
newgtrightcolor = (UINT8)lua_tointeger(L, 3);
|
||||
// Key name specified
|
||||
} else if ((!i) && (k && fasticmp(k, "headercolor"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("headercolor", LUA_TNUMBER)
|
||||
newgtleftcolor = newgtrightcolor = (UINT8)lua_tointeger(L, 3);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
#undef FIELDERROR
|
||||
#undef TYPEERROR
|
||||
|
||||
// pop gametype table
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Set defaults
|
||||
if (gtname == NULL)
|
||||
gtname = Z_StrDup("Unnamed gametype");
|
||||
if (gtdescription == NULL)
|
||||
gtdescription = Z_StrDup("???");
|
||||
|
||||
// Add the new gametype
|
||||
newgtidx = G_AddGametype(newgtrules);
|
||||
G_AddGametypeTOL(newgtidx, newgttol);
|
||||
G_SetGametypeDescription(newgtidx, NULL, newgtleftcolor, newgtrightcolor);
|
||||
strncpy(gametypedesc[newgtidx].notes, gtdescription, 441);
|
||||
|
||||
// Not covered by G_AddGametype alone.
|
||||
if (newgtrankingstype == -1)
|
||||
newgtrankingstype = newgtidx;
|
||||
gametyperankings[newgtidx] = newgtrankingstype;
|
||||
intermissiontypes[newgtidx] = newgtinttype;
|
||||
pointlimits[newgtidx] = newgtpointlimit;
|
||||
timelimits[newgtidx] = newgttimelimit;
|
||||
|
||||
// Write the new gametype name.
|
||||
Gametype_Names[newgtidx] = gtname;
|
||||
|
||||
// Write the constant name.
|
||||
if (gtconst == NULL)
|
||||
gtconst = gtname;
|
||||
G_AddGametypeConstant(newgtidx, gtconst);
|
||||
|
||||
// Update gametype_cons_t accordingly.
|
||||
G_UpdateGametypeSelections();
|
||||
|
||||
// done
|
||||
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_gBuildMapName(lua_State *L)
|
||||
{
|
||||
INT32 map = luaL_optinteger(L, 1, gamemap);
|
||||
|
@ -2662,23 +2804,17 @@ static int lib_gSetCustomExitVars(lua_State *L)
|
|||
// Supported:
|
||||
// G_SetCustomExitVars(); [reset to defaults]
|
||||
// G_SetCustomExitVars(int) [nextmap override only]
|
||||
// G_SetCustomExitVars(bool) [skipstats only]
|
||||
// G_SetCustomExitVars(int, bool) [both of the above]
|
||||
// G_SetCustomExitVars(nil, int) [skipstats only]
|
||||
// G_SetCustomExitVars(int, int) [both of the above]
|
||||
|
||||
nextmapoverride = 0;
|
||||
skipstats = 0;
|
||||
|
||||
if (n >= 1)
|
||||
{
|
||||
if (lua_isnumber(L, 1) || n >= 2)
|
||||
{
|
||||
nextmapoverride = (INT16)luaL_checknumber(L, 1);
|
||||
lua_remove(L, 1); // remove nextmapoverride; skipstats now 1 if available
|
||||
}
|
||||
skipstats = luaL_optinteger(L, 2, 0);
|
||||
nextmapoverride = (INT16)luaL_optinteger(L, 1, 0);
|
||||
skipstats = (INT16)luaL_optinteger(L, 2, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextmapoverride = 0;
|
||||
skipstats = 0;
|
||||
}
|
||||
// ---
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2995,6 +3131,7 @@ static luaL_Reg lib[] = {
|
|||
{"S_StartMusicCaption", lib_sStartMusicCaption},
|
||||
|
||||
// g_game
|
||||
{"G_AddGametype", lib_gAddGametype},
|
||||
{"G_BuildMapName",lib_gBuildMapName},
|
||||
{"G_DoReborn",lib_gDoReborn},
|
||||
{"G_SetCustomExitVars",lib_gSetCustomExitVars},
|
||||
|
|
|
@ -51,6 +51,8 @@ enum hook {
|
|||
hook_PlayerCanDamage,
|
||||
hook_PlayerQuit,
|
||||
hook_IntermissionThinker,
|
||||
hook_TeamSwitch,
|
||||
hook_ViewpointSwitch,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -93,5 +95,7 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAft
|
|||
UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh....
|
||||
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,6 +62,8 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"PlayerCanDamage",
|
||||
"PlayerQuit",
|
||||
"IntermissionThinker",
|
||||
"TeamSwitch",
|
||||
"ViewpointSwitch",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -203,6 +205,8 @@ static int lib_addHook(lua_State *L)
|
|||
case hook_PlayerSpawn:
|
||||
case hook_FollowMobj:
|
||||
case hook_PlayerCanDamage:
|
||||
case hook_TeamSwitch:
|
||||
case hook_ViewpointSwitch:
|
||||
case hook_ShieldSpawn:
|
||||
case hook_ShieldSpecial:
|
||||
lastp = &playerhooks;
|
||||
|
@ -657,14 +661,16 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32
|
|||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damage);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
if (lua_pcall(gL, 4, 1, 0)) {
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
if (lua_pcall(gL, 5, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
|
@ -745,14 +751,16 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32
|
|||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damage);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
if (lua_pcall(gL, 4, 1, 0)) {
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
if (lua_pcall(gL, 5, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
|
@ -823,13 +831,15 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8
|
|||
LUA_PushUserdata(gL, target, META_MOBJ);
|
||||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
if (lua_pcall(gL, 3, 1, 0)) {
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
if (lua_pcall(gL, 4, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
|
@ -1346,4 +1356,101 @@ void LUAh_IntermissionThinker(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Hook for team switching
|
||||
// It's just an edit of LUAh_ViewpointSwitch.
|
||||
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble)
|
||||
{
|
||||
hook_p hookp;
|
||||
boolean canSwitchTeam = true;
|
||||
if (!gL || !(hooksAvailable[hook_TeamSwitch/8] & (1<<(hook_TeamSwitch%8))))
|
||||
return true;
|
||||
|
||||
lua_settop(gL, 0);
|
||||
|
||||
for (hookp = playerhooks; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type != hook_TeamSwitch)
|
||||
continue;
|
||||
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
lua_pushinteger(gL, newteam);
|
||||
lua_pushboolean(gL, fromspectators);
|
||||
lua_pushboolean(gL, tryingautobalance);
|
||||
lua_pushboolean(gL, tryingscramble);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
if (lua_pcall(gL, 5, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
continue;
|
||||
}
|
||||
if (!lua_isnil(gL, -1) && !lua_toboolean(gL, -1))
|
||||
canSwitchTeam = false; // Can't switch team
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
lua_settop(gL, 0);
|
||||
return canSwitchTeam;
|
||||
}
|
||||
|
||||
// Hook for spy mode
|
||||
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced)
|
||||
{
|
||||
hook_p hookp;
|
||||
UINT8 canSwitchView = 0; // 0 = default, 1 = force yes, 2 = force no.
|
||||
if (!gL || !(hooksAvailable[hook_ViewpointSwitch/8] & (1<<(hook_ViewpointSwitch%8))))
|
||||
return 0;
|
||||
|
||||
lua_settop(gL, 0);
|
||||
hud_running = true;
|
||||
|
||||
for (hookp = playerhooks; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type != hook_ViewpointSwitch)
|
||||
continue;
|
||||
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
LUA_PushUserdata(gL, newdisplayplayer, META_PLAYER);
|
||||
lua_pushboolean(gL, forced);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
if (lua_pcall(gL, 3, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
hookp->error = true;
|
||||
continue;
|
||||
}
|
||||
if (!lua_isnil(gL, -1))
|
||||
{ // if nil, leave canSwitchView = 0.
|
||||
if (lua_toboolean(gL, -1))
|
||||
canSwitchView = 1; // Force viewpoint switch
|
||||
else
|
||||
canSwitchView = 2; // Skip viewpoint switch
|
||||
}
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
lua_settop(gL, 0);
|
||||
hud_running = false;
|
||||
|
||||
return canSwitchView;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@ enum hud {
|
|||
// Match / CTF / Tag / Ringslinger
|
||||
hud_weaponrings,
|
||||
hud_powerstones,
|
||||
hud_teamscores,
|
||||
// NiGHTS mode
|
||||
hud_nightslink,
|
||||
hud_nightsdrill,
|
||||
|
@ -33,6 +34,9 @@ enum hud {
|
|||
hud_coopemeralds,
|
||||
hud_tokens,
|
||||
hud_tabemblems,
|
||||
// Intermission
|
||||
hud_intermissiontally,
|
||||
hud_intermissionmessages,
|
||||
hud_MAX
|
||||
};
|
||||
|
||||
|
@ -43,4 +47,5 @@ boolean LUA_HudEnabled(enum hud option);
|
|||
void LUAh_GameHUD(player_t *stplyr);
|
||||
void LUAh_ScoresHUD(void);
|
||||
void LUAh_TitleHUD(void);
|
||||
void LUAh_TitleCardHUD(player_t *stplyr);
|
||||
void LUAh_TitleCardHUD(player_t *stplayr);
|
||||
void LUAh_IntermissionHUD(void);
|
||||
|
|
|
@ -48,6 +48,7 @@ static const char *const hud_disable_options[] = {
|
|||
|
||||
"weaponrings",
|
||||
"powerstones",
|
||||
"teamscores",
|
||||
|
||||
"nightslink",
|
||||
"nightsdrill",
|
||||
|
@ -60,6 +61,9 @@ static const char *const hud_disable_options[] = {
|
|||
"coopemeralds",
|
||||
"tokens",
|
||||
"tabemblems",
|
||||
|
||||
"intermissiontally",
|
||||
"intermissionmessages",
|
||||
NULL};
|
||||
|
||||
enum hudinfo {
|
||||
|
@ -92,12 +96,14 @@ static const char *const patch_opt[] = {
|
|||
enum hudhook {
|
||||
hudhook_game = 0,
|
||||
hudhook_scores,
|
||||
hudhook_intermission,
|
||||
hudhook_title,
|
||||
hudhook_titlecard
|
||||
};
|
||||
static const char *const hudhook_opt[] = {
|
||||
"game",
|
||||
"scores",
|
||||
"intermission",
|
||||
"title",
|
||||
"titlecard",
|
||||
NULL};
|
||||
|
@ -1050,13 +1056,16 @@ int LUA_HudLib(lua_State *L)
|
|||
lua_rawseti(L, -2, 2); // HUD[2] = game rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 3); // HUD[2] = scores rendering functions array
|
||||
lua_rawseti(L, -2, 3); // HUD[3] = scores rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 4); // HUD[3] = title rendering functions array
|
||||
lua_rawseti(L, -2, 4); // HUD[4] = intermission rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 5); // HUD[4] = title card rendering functions array
|
||||
lua_rawseti(L, -2, 5); // HUD[5] = title rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 6); // HUD[6] = title card rendering functions array
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "HUD");
|
||||
|
||||
luaL_newmetatable(L, META_HUDINFO);
|
||||
|
@ -1228,4 +1237,29 @@ void LUAh_TitleCardHUD(player_t *stplayr)
|
|||
hud_running = false;
|
||||
}
|
||||
|
||||
void LUAh_IntermissionHUD(void)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_intermission)))
|
||||
return;
|
||||
|
||||
hud_running = true;
|
||||
lua_pop(gL, -1);
|
||||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 4); // HUD[4] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_remove(gL, -3); // pop HUD
|
||||
lua_pushnil(gL);
|
||||
while (lua_next(gL, -3) != 0) {
|
||||
lua_pushvalue(gL, -3); // graphics library (HUD[1])
|
||||
LUA_Call(gL, 1);
|
||||
}
|
||||
lua_pop(gL, -1);
|
||||
hud_running = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -445,7 +445,7 @@ static int sectorlines_get(lua_State *L)
|
|||
// get the "linecount" by shifting our retrieved memory address of "lines" to where "linecount" is in the sector_t, then dereferencing the result
|
||||
// we need this to determine the array's actual size, and therefore also the maximum value allowed as an index
|
||||
// this only works if seclines is actually a pointer to a sector's lines member in memory, oh boy
|
||||
numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
numoflines = (size_t)(*(size_t *)(((size_t)seclines) - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
|
||||
/* OLD HACK
|
||||
// check first linedef to figure which of its sectors owns this sector->lines pointer
|
||||
|
@ -479,7 +479,7 @@ static int sectorlines_num(lua_State *L)
|
|||
return luaL_error(L, "accessed sector_t.lines doesn't exist anymore.");
|
||||
|
||||
// see comments in the _get function above
|
||||
numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
numoflines = (size_t)(*(size_t *)(((size_t)seclines) - (offsetof(sector_t, lines) - offsetof(sector_t, linecount))));
|
||||
lua_pushinteger(L, numoflines);
|
||||
return 1;
|
||||
}
|
||||
|
@ -2071,6 +2071,12 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->levelselect);
|
||||
else if (fastcmp(field,"bonustype"))
|
||||
lua_pushinteger(L, header->bonustype);
|
||||
else if (fastcmp(field,"ltzzpatch"))
|
||||
lua_pushstring(L, header->ltzzpatch);
|
||||
else if (fastcmp(field,"ltzztext"))
|
||||
lua_pushstring(L, header->ltzztext);
|
||||
else if (fastcmp(field,"ltactdiamond"))
|
||||
lua_pushstring(L, header->ltactdiamond);
|
||||
else if (fastcmp(field,"maxbonuslives"))
|
||||
lua_pushinteger(L, header->maxbonuslives);
|
||||
else if (fastcmp(field,"levelflags"))
|
||||
|
|
240
src/lua_script.c
240
src/lua_script.c
|
@ -18,7 +18,9 @@
|
|||
#include "w_wad.h"
|
||||
#include "p_setup.h"
|
||||
#include "r_state.h"
|
||||
#include "r_sky.h"
|
||||
#include "g_game.h"
|
||||
#include "f_finale.h"
|
||||
#include "byteptr.h"
|
||||
#include "p_saveg.h"
|
||||
#include "p_local.h"
|
||||
|
@ -79,8 +81,239 @@ FUNCNORETURN static int LUA_Panic(lua_State *L)
|
|||
#endif
|
||||
}
|
||||
|
||||
// Moved here from lib_getenum.
|
||||
int LUA_PushGlobals(lua_State *L, const char *word)
|
||||
{
|
||||
if (fastcmp(word,"gamemap")) {
|
||||
lua_pushinteger(L, gamemap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"maptol")) {
|
||||
lua_pushinteger(L, maptol);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"ultimatemode")) {
|
||||
lua_pushboolean(L, ultimatemode != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mariomode")) {
|
||||
lua_pushboolean(L, mariomode != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"twodlevel")) {
|
||||
lua_pushboolean(L, twodlevel != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"circuitmap")) {
|
||||
lua_pushboolean(L, circuitmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"netgame")) {
|
||||
lua_pushboolean(L, netgame);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"multiplayer")) {
|
||||
lua_pushboolean(L, multiplayer);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"modeattacking")) {
|
||||
lua_pushboolean(L, modeattacking);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"splitscreen")) {
|
||||
lua_pushboolean(L, splitscreen);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"gamecomplete")) {
|
||||
lua_pushboolean(L, gamecomplete);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"devparm")) {
|
||||
lua_pushboolean(L, devparm);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"modifiedgame")) {
|
||||
lua_pushboolean(L, modifiedgame && !savemoddata);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"menuactive")) {
|
||||
lua_pushboolean(L, menuactive);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"paused")) {
|
||||
lua_pushboolean(L, paused);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"bluescore")) {
|
||||
lua_pushinteger(L, bluescore);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"redscore")) {
|
||||
lua_pushinteger(L, redscore);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"timelimit")) {
|
||||
lua_pushinteger(L, cv_timelimit.value);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"pointlimit")) {
|
||||
lua_pushinteger(L, cv_pointlimit.value);
|
||||
return 1;
|
||||
// begin map vars
|
||||
} else if (fastcmp(word,"spstage_start")) {
|
||||
lua_pushinteger(L, spstage_start);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"sstage_start")) {
|
||||
lua_pushinteger(L, sstage_start);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"sstage_end")) {
|
||||
lua_pushinteger(L, sstage_end);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"smpstage_start")) {
|
||||
lua_pushinteger(L, smpstage_start);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"smpstage_end")) {
|
||||
lua_pushinteger(L, smpstage_end);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"titlemap")) {
|
||||
lua_pushinteger(L, titlemap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"titlemapinaction")) {
|
||||
lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF));
|
||||
return 1;
|
||||
} else if (fastcmp(word,"bootmap")) {
|
||||
lua_pushinteger(L, bootmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"tutorialmap")) {
|
||||
lua_pushinteger(L, tutorialmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"tutorialmode")) {
|
||||
lua_pushboolean(L, tutorialmode);
|
||||
return 1;
|
||||
// end map vars
|
||||
// begin CTF colors
|
||||
} else if (fastcmp(word,"skincolor_redteam")) {
|
||||
lua_pushinteger(L, skincolor_redteam);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"skincolor_blueteam")) {
|
||||
lua_pushinteger(L, skincolor_blueteam);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"skincolor_redring")) {
|
||||
lua_pushinteger(L, skincolor_redring);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"skincolor_bluering")) {
|
||||
lua_pushinteger(L, skincolor_bluering);
|
||||
return 1;
|
||||
// end CTF colors
|
||||
// begin timers
|
||||
} else if (fastcmp(word,"invulntics")) {
|
||||
lua_pushinteger(L, invulntics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"sneakertics")) {
|
||||
lua_pushinteger(L, sneakertics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"flashingtics")) {
|
||||
lua_pushinteger(L, flashingtics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"tailsflytics")) {
|
||||
lua_pushinteger(L, tailsflytics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"underwatertics")) {
|
||||
lua_pushinteger(L, underwatertics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"spacetimetics")) {
|
||||
lua_pushinteger(L, spacetimetics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"extralifetics")) {
|
||||
lua_pushinteger(L, extralifetics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"nightslinktics")) {
|
||||
lua_pushinteger(L, nightslinktics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"gameovertics")) {
|
||||
lua_pushinteger(L, gameovertics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"ammoremovaltics")) {
|
||||
lua_pushinteger(L, ammoremovaltics);
|
||||
return 1;
|
||||
// end timers
|
||||
} else if (fastcmp(word,"gametype")) {
|
||||
lua_pushinteger(L, gametype);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"gametyperules")) {
|
||||
lua_pushinteger(L, gametyperules);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"leveltime")) {
|
||||
lua_pushinteger(L, leveltime);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"sstimer")) {
|
||||
lua_pushinteger(L, sstimer);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"curWeather")) {
|
||||
lua_pushinteger(L, curWeather);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"globalweather")) {
|
||||
lua_pushinteger(L, globalweather);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"levelskynum")) {
|
||||
lua_pushinteger(L, levelskynum);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"globallevelskynum")) {
|
||||
lua_pushinteger(L, globallevelskynum);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mapmusname")) {
|
||||
lua_pushstring(L, mapmusname);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mapmusflags")) {
|
||||
lua_pushinteger(L, mapmusflags);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mapmusposition")) {
|
||||
lua_pushinteger(L, mapmusposition);
|
||||
return 1;
|
||||
// local player variables, by popular request
|
||||
} else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1)
|
||||
if (consoleplayer < 0 || !playeringame[consoleplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1)
|
||||
if (displayplayer < 0 || !playeringame[displayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[displayplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen
|
||||
if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER);
|
||||
return 1;
|
||||
// end local player variables
|
||||
} else if (fastcmp(word,"server")) {
|
||||
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array.
|
||||
LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)");
|
||||
if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer))
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"emeralds")) {
|
||||
lua_pushinteger(L, emeralds);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"gravity")) {
|
||||
lua_pushinteger(L, gravity);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"VERSIONSTRING")) {
|
||||
lua_pushstring(L, VERSIONSTRING);
|
||||
return 1;
|
||||
} else if (fastcmp(word, "token")) {
|
||||
lua_pushinteger(L, token);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// See the above.
|
||||
int LUA_CheckGlobals(lua_State *L, const char *word)
|
||||
{
|
||||
if (fastcmp(word, "gametyperules"))
|
||||
gametyperules = (UINT32)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word, "redscore"))
|
||||
redscore = (UINT32)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word, "bluescore"))
|
||||
bluescore = (UINT32)luaL_checkinteger(L, 2);
|
||||
else
|
||||
return 0;
|
||||
|
||||
// Global variable set, so return and don't error.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This function decides which global variables you are allowed to set.
|
||||
static int noglobals(lua_State *L)
|
||||
static int setglobals(lua_State *L)
|
||||
{
|
||||
const char *csname;
|
||||
char *name;
|
||||
|
@ -106,6 +339,9 @@ static int noglobals(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (LUA_CheckGlobals(L, csname))
|
||||
return 0;
|
||||
|
||||
Z_Free(name);
|
||||
return luaL_error(L, "Implicit global " LUA_QS " prevented. Create a local variable instead.", csname);
|
||||
}
|
||||
|
@ -144,7 +380,7 @@ static void LUA_ClearState(void)
|
|||
|
||||
// lock the global namespace
|
||||
lua_getmetatable(L, LUA_GLOBALSINDEX);
|
||||
lua_pushcfunction(L, noglobals);
|
||||
lua_pushcfunction(L, setglobals);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
|
|
|
@ -54,6 +54,8 @@ void LUA_InvalidatePlayer(player_t *player);
|
|||
void LUA_Step(void);
|
||||
void LUA_Archive(void);
|
||||
void LUA_UnArchive(void);
|
||||
int LUA_PushGlobals(lua_State *L, const char *word);
|
||||
int LUA_CheckGlobals(lua_State *L, const char *word);
|
||||
void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
|
||||
void LUA_CVarChanged(const char *name); // lua_consolelib.c
|
||||
int Lua_optoption(lua_State *L, int narg,
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "i_video.h"
|
||||
#include "m_misc.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
||||
// GIFs are always little-endian
|
||||
#include "byteptr.h"
|
||||
|
||||
|
@ -29,6 +33,7 @@ consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0
|
|||
#ifdef HAVE_ANIGIF
|
||||
static boolean gif_optimize = false; // So nobody can do something dumb
|
||||
static boolean gif_downscale = false; // like changing cvars mid output
|
||||
static RGBA_t *gif_palette = NULL;
|
||||
|
||||
static FILE *gif_out = NULL;
|
||||
static INT32 gif_frames = 0;
|
||||
|
@ -428,10 +433,7 @@ static void GIF_headwrite(void)
|
|||
|
||||
// write color table
|
||||
{
|
||||
RGBA_t *pal = ((cv_screenshot_colorprofile.value)
|
||||
? pLocalPalette
|
||||
: pMasterPalette);
|
||||
|
||||
RGBA_t *pal = gif_palette;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
WRITEUINT8(p, pal[i].s.red);
|
||||
|
@ -457,6 +459,32 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by
|
|||
static UINT8 *gifframe_data = NULL;
|
||||
static size_t gifframe_size = 8192;
|
||||
|
||||
#ifdef HWRENDER
|
||||
static void hwrconvert(void)
|
||||
{
|
||||
UINT8 *linear = HWR_GetScreenshot();
|
||||
UINT8 *dest = screens[2];
|
||||
UINT8 r, g, b;
|
||||
INT32 x, y;
|
||||
size_t i = 0;
|
||||
|
||||
InitColorLUT(gif_palette);
|
||||
|
||||
for (y = 0; y < vid.height; y++)
|
||||
{
|
||||
for (x = 0; x < vid.width; x++, i += 3)
|
||||
{
|
||||
r = (UINT8)linear[i];
|
||||
g = (UINT8)linear[i + 1];
|
||||
b = (UINT8)linear[i + 2];
|
||||
dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
|
||||
}
|
||||
}
|
||||
|
||||
free(linear);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// GIF_framewrite
|
||||
// writes a frame into the file.
|
||||
|
@ -482,7 +510,12 @@ static void GIF_framewrite(void)
|
|||
GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith);
|
||||
|
||||
// blit to temp screen
|
||||
I_ReadScreen(movie_screen);
|
||||
if (rendermode == render_soft)
|
||||
I_ReadScreen(movie_screen);
|
||||
#ifdef HWRENDER
|
||||
else if (rendermode == render_opengl)
|
||||
hwrconvert();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -491,7 +524,18 @@ static void GIF_framewrite(void)
|
|||
blith = vid.height;
|
||||
|
||||
if (gif_frames == 0)
|
||||
I_ReadScreen(movie_screen);
|
||||
{
|
||||
if (rendermode == render_soft)
|
||||
I_ReadScreen(movie_screen);
|
||||
#ifdef HWRENDER
|
||||
else if (rendermode == render_opengl)
|
||||
{
|
||||
hwrconvert();
|
||||
VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
movie_screen = screens[0];
|
||||
}
|
||||
|
||||
|
@ -580,7 +624,7 @@ static void GIF_framewrite(void)
|
|||
//
|
||||
INT32 GIF_open(const char *filename)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
#if 0
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n"));
|
||||
|
@ -594,6 +638,16 @@ INT32 GIF_open(const char *filename)
|
|||
|
||||
gif_optimize = (!!cv_gif_optimize.value);
|
||||
gif_downscale = (!!cv_gif_downscale.value);
|
||||
|
||||
// GIF color table
|
||||
// In hardware mode, uses the master palette
|
||||
gif_palette = ((cv_screenshot_colorprofile.value
|
||||
#ifdef HWRENDER
|
||||
&& (rendermode == render_soft)
|
||||
#endif
|
||||
) ? pLocalPalette
|
||||
: pMasterPalette);
|
||||
|
||||
GIF_headwrite();
|
||||
gif_frames = 0;
|
||||
return 1;
|
||||
|
|
|
@ -778,7 +778,7 @@ void Command_CauseCfail_f(void)
|
|||
P_SetThingPosition(players[consoleplayer].mo);
|
||||
|
||||
// CTF consistency test
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
{
|
||||
if (blueflag) {
|
||||
P_RemoveMobj(blueflag);
|
||||
|
@ -1106,7 +1106,7 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
|||
#else
|
||||
fixed_t cheight = sec->ceilingheight;
|
||||
#endif
|
||||
mt->options = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS);
|
||||
mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1115,12 +1115,11 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
|||
#else
|
||||
fixed_t fheight = sec->floorheight;
|
||||
#endif
|
||||
mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS);
|
||||
mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS);
|
||||
}
|
||||
mt->options <<= ZSHIFT;
|
||||
mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle)));
|
||||
|
||||
mt->options |= (UINT16)cv_opflags.value;
|
||||
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
|
||||
return mt;
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1186,7 @@ void OP_NightsObjectplace(player_t *player)
|
|||
mt->options = (mt->options & ~(UINT16)cv_opflags.value) | (UINT16)cv_ophoopflags.value;
|
||||
mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8));
|
||||
|
||||
P_SpawnHoopsAndRings(mt, false);
|
||||
P_SpawnHoop(mt);
|
||||
}
|
||||
|
||||
// This places a bumper!
|
||||
|
@ -1250,7 +1249,7 @@ void OP_NightsObjectplace(player_t *player)
|
|||
return;
|
||||
|
||||
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_BLUESPHERE].doomednum, false);
|
||||
P_SpawnHoopsAndRings(mt, false);
|
||||
P_SpawnMapThing(mt);
|
||||
}
|
||||
|
||||
// This places a ring!
|
||||
|
@ -1261,7 +1260,7 @@ void OP_NightsObjectplace(player_t *player)
|
|||
return;
|
||||
|
||||
mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false);
|
||||
P_SpawnHoopsAndRings(mt, false);
|
||||
P_SpawnMapThing(mt);
|
||||
}
|
||||
|
||||
// This places a custom object as defined in the console cv_mapthingnum.
|
||||
|
@ -1293,15 +1292,10 @@ void OP_NightsObjectplace(player_t *player)
|
|||
mt = OP_CreateNewMapThing(player, (UINT16)cv_mapthingnum.value, false);
|
||||
mt->angle = angle;
|
||||
|
||||
if (mt->type == 300 // Ring
|
||||
|| mt->type == 308 || mt->type == 309 // Team Rings
|
||||
|| mt->type == 1706 // Sphere
|
||||
|| (mt->type >= 600 && mt->type <= 609) // Placement patterns
|
||||
|| mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops
|
||||
|| mt->type == 1800) // Mario Coin
|
||||
{
|
||||
P_SpawnHoopsAndRings(mt, false);
|
||||
}
|
||||
if (mt->type >= 600 && mt->type <= 609) // Placement patterns
|
||||
P_SpawnItemPattern(mt, false);
|
||||
else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops
|
||||
P_SpawnHoop(mt);
|
||||
else
|
||||
P_SpawnMapThing(mt);
|
||||
}
|
||||
|
@ -1438,15 +1432,10 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
return;
|
||||
|
||||
mt = OP_CreateNewMapThing(player, (UINT16)spawnthing, ceiling);
|
||||
if (mt->type == 300 // Ring
|
||||
|| mt->type == 308 || mt->type == 309 // Team Rings
|
||||
|| mt->type == 1706 // Nights Wing
|
||||
|| (mt->type >= 600 && mt->type <= 609) // Placement patterns
|
||||
|| mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops
|
||||
|| mt->type == 1800) // Mario Coin
|
||||
{
|
||||
P_SpawnHoopsAndRings(mt, false);
|
||||
}
|
||||
if (mt->type >= 600 && mt->type <= 609) // Placement patterns
|
||||
P_SpawnItemPattern(mt, false);
|
||||
else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops
|
||||
P_SpawnHoop(mt);
|
||||
else
|
||||
P_SpawnMapThing(mt);
|
||||
|
||||
|
|
29
src/m_menu.c
29
src/m_menu.c
|
@ -605,7 +605,7 @@ static menuitem_t MISC_ChangeTeamMenu[] =
|
|||
{IT_WHITESTRING|IT_CALL, NULL, "Confirm", M_ConfirmTeamChange, 90},
|
||||
};
|
||||
|
||||
static const gtdesc_t gametypedesc[] =
|
||||
gtdesc_t gametypedesc[NUMGAMETYPES] =
|
||||
{
|
||||
{{ 54, 54}, "Play through the single-player campaign with your friends, teaming up to beat Dr Eggman's nefarious challenges!"},
|
||||
{{103, 103}, "Speed your way through the main acts, competing in several different categories to see who's the best."},
|
||||
|
@ -1118,6 +1118,8 @@ static menuitem_t OP_Joystick1Menu[] =
|
|||
|
||||
{IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 120},
|
||||
{IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 130},
|
||||
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER,
|
||||
NULL, "Deadzone", &cv_deadzone, 140 },
|
||||
};
|
||||
|
||||
static menuitem_t OP_Joystick2Menu[] =
|
||||
|
@ -1134,6 +1136,8 @@ static menuitem_t OP_Joystick2Menu[] =
|
|||
|
||||
{IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2,120},
|
||||
{IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130},
|
||||
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER,
|
||||
NULL, "Deadzone", &cv_deadzone2, 140 },
|
||||
};
|
||||
|
||||
static menuitem_t OP_JoystickSetMenu[1+MAX_JOYSTICKS];
|
||||
|
@ -1305,18 +1309,18 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
|
|||
{IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32},
|
||||
|
||||
{IT_HEADER, NULL, "General", NULL, 51},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 62},
|
||||
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 72},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 82},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,92},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 63},
|
||||
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93},
|
||||
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 111},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 123},
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 112},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 124},
|
||||
#ifdef ALAM_LIGHTING
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 133},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 134},
|
||||
#endif
|
||||
#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)))
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 143},
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 144},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -3009,7 +3013,7 @@ boolean M_Responder(event_t *ev)
|
|||
}
|
||||
else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime())
|
||||
{
|
||||
const INT32 jdeadzone = JOYAXISRANGE/4;
|
||||
const INT32 jdeadzone = (JOYAXISRANGE * cv_deadzone.value) / FRACUNIT;
|
||||
if (ev->data3 != INT32_MAX)
|
||||
{
|
||||
if (Joystick.bGamepadStyle || abs(ev->data3) > jdeadzone)
|
||||
|
@ -4684,6 +4688,9 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt)
|
|||
if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
|
||||
return true;
|
||||
|
||||
if (gt > 0 && gt < gametypecount && (mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
case LLM_LEVELSELECT:
|
||||
|
@ -9932,7 +9939,7 @@ static void M_DrawConnectMenu(void)
|
|||
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
|
||||
|
||||
gt = "Unknown";
|
||||
if (serverlist[slindex].info.gametype < NUMGAMETYPES)
|
||||
if (serverlist[slindex].info.gametype < gametypecount)
|
||||
gt = Gametype_Names[serverlist[slindex].info.gametype];
|
||||
|
||||
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
|
||||
|
|
|
@ -371,6 +371,7 @@ typedef struct
|
|||
UINT8 col[2];
|
||||
char notes[441];
|
||||
} gtdesc_t;
|
||||
extern gtdesc_t gametypedesc[NUMGAMETYPES];
|
||||
|
||||
// mode descriptions for video mode menu
|
||||
typedef struct
|
||||
|
|
29
src/m_misc.c
29
src/m_misc.c
|
@ -1161,12 +1161,8 @@ void M_StartMovie(void)
|
|||
switch (cv_moviemode.value)
|
||||
{
|
||||
case MM_GIF:
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
moviemode = M_StartMovieGIF(pathname);
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
moviemode = M_StartMovieGIF(pathname);
|
||||
break;
|
||||
case MM_APNG:
|
||||
moviemode = M_StartMovieAPNG(pathname);
|
||||
break;
|
||||
|
@ -1783,7 +1779,7 @@ char *M_GetToken(const char *inputString)
|
|||
|| stringToUse[startPos] == '\r'
|
||||
|| stringToUse[startPos] == '\n'
|
||||
|| stringToUse[startPos] == '\0'
|
||||
|| stringToUse[startPos] == '"' // we're treating this as whitespace because SLADE likes adding it for no good reason
|
||||
|| stringToUse[startPos] == '=' || stringToUse[startPos] == ';' // UDMF TEXTMAP.
|
||||
|| inComment != 0)
|
||||
&& startPos < stringLength)
|
||||
{
|
||||
|
@ -1841,6 +1837,23 @@ char *M_GetToken(const char *inputString)
|
|||
texturesToken[1] = '\0';
|
||||
return texturesToken;
|
||||
}
|
||||
// Return entire string within quotes, except without the quotes.
|
||||
else if (stringToUse[startPos] == '"')
|
||||
{
|
||||
endPos = ++startPos;
|
||||
while (stringToUse[endPos] != '"' && endPos < stringLength)
|
||||
endPos++;
|
||||
|
||||
texturesTokenLength = endPos++ - startPos;
|
||||
// Assign the memory. Don't forget an extra byte for the end of the string!
|
||||
texturesToken = (char *)Z_Malloc((texturesTokenLength+1)*sizeof(char),PU_STATIC,NULL);
|
||||
// Copy the string.
|
||||
M_Memcpy(texturesToken, stringToUse+startPos, (size_t)texturesTokenLength);
|
||||
// Make the final character NUL.
|
||||
texturesToken[texturesTokenLength] = '\0';
|
||||
|
||||
return texturesToken;
|
||||
}
|
||||
|
||||
// Now find the end of the token. This includes several additional characters that are okay to capture as one character, but not trailing at the end of another token.
|
||||
endPos = startPos + 1;
|
||||
|
@ -1851,7 +1864,7 @@ char *M_GetToken(const char *inputString)
|
|||
&& stringToUse[endPos] != ','
|
||||
&& stringToUse[endPos] != '{'
|
||||
&& stringToUse[endPos] != '}'
|
||||
&& stringToUse[endPos] != '"' // see above
|
||||
&& stringToUse[endPos] != '=' && stringToUse[endPos] != ';' // UDMF TEXTMAP.
|
||||
&& inComment == 0)
|
||||
&& endPos < stringLength)
|
||||
{
|
||||
|
|
|
@ -4983,7 +4983,7 @@ void A_ThrownRing(mobj_t *actor)
|
|||
continue;
|
||||
|
||||
// Don't home in on teammates.
|
||||
if (gametype == GT_CTF
|
||||
if ((gametyperules & GTR_TEAMFLAGS)
|
||||
&& actor->target->player->ctfteam == player->ctfteam)
|
||||
continue;
|
||||
}
|
||||
|
@ -6589,7 +6589,7 @@ void A_OldRingExplode(mobj_t *actor) {
|
|||
|
||||
if (changecolor)
|
||||
{
|
||||
if (gametype != GT_CTF)
|
||||
if (!(gametyperules & GTR_TEAMFLAGS))
|
||||
mo->color = actor->target->color; //copy color
|
||||
else if (actor->target->player->ctfteam == 2)
|
||||
mo->color = skincolor_bluering;
|
||||
|
@ -6605,7 +6605,7 @@ void A_OldRingExplode(mobj_t *actor) {
|
|||
|
||||
if (changecolor)
|
||||
{
|
||||
if (gametype != GT_CTF)
|
||||
if (!(gametyperules & GTR_TEAMFLAGS))
|
||||
mo->color = actor->target->color; //copy color
|
||||
else if (actor->target->player->ctfteam == 2)
|
||||
mo->color = skincolor_bluering;
|
||||
|
@ -6620,7 +6620,7 @@ void A_OldRingExplode(mobj_t *actor) {
|
|||
|
||||
if (changecolor)
|
||||
{
|
||||
if (gametype != GT_CTF)
|
||||
if (!(gametyperules & GTR_TEAMFLAGS))
|
||||
mo->color = actor->target->color; //copy color
|
||||
else if (actor->target->player->ctfteam == 2)
|
||||
mo->color = skincolor_bluering;
|
||||
|
@ -13591,12 +13591,12 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
|
|||
}
|
||||
else
|
||||
{ //Player on the top of the tornado.
|
||||
P_ResetPlayer(player);
|
||||
thing->z = dustdevil->z + dustdevil->height;
|
||||
thrust = 20 * FRACUNIT;
|
||||
player->powers[pw_nocontrol] = 0;
|
||||
S_StartSound(thing, sfx_wdjump);
|
||||
P_SetPlayerMobjState(thing, S_PLAY_FALL);
|
||||
player->pflags &= ~PF_JUMPED;
|
||||
}
|
||||
|
||||
thing->momz = thrust;
|
||||
|
@ -14689,20 +14689,35 @@ void A_DragonWing(mobj_t *actor)
|
|||
void A_DragonSegment(mobj_t *actor)
|
||||
{
|
||||
mobj_t *target = actor->target;
|
||||
fixed_t dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z);
|
||||
fixed_t radius = actor->radius + target->radius;
|
||||
angle_t hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y);
|
||||
angle_t zangle = R_PointToAngle2(0, target->z, dist, actor->z);
|
||||
fixed_t hdist = P_ReturnThrustX(target, zangle, radius);
|
||||
fixed_t xdist = P_ReturnThrustX(target, hangle, hdist);
|
||||
fixed_t ydist = P_ReturnThrustY(target, hangle, hdist);
|
||||
fixed_t zdist = P_ReturnThrustY(target, zangle, radius);
|
||||
fixed_t dist;
|
||||
fixed_t radius;
|
||||
angle_t hangle;
|
||||
angle_t zangle;
|
||||
fixed_t hdist;
|
||||
fixed_t xdist;
|
||||
fixed_t ydist;
|
||||
fixed_t zdist;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_DragonSegment", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (target == NULL || !target->health)
|
||||
{
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z);
|
||||
radius = actor->radius + target->radius;
|
||||
hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y);
|
||||
zangle = R_PointToAngle2(0, target->z, dist, actor->z);
|
||||
hdist = P_ReturnThrustX(target, zangle, radius);
|
||||
xdist = P_ReturnThrustX(target, hangle, hdist);
|
||||
ydist = P_ReturnThrustY(target, hangle, hdist);
|
||||
zdist = P_ReturnThrustY(target, zangle, radius);
|
||||
|
||||
actor->angle = hangle;
|
||||
P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist);
|
||||
}
|
||||
|
|
|
@ -625,7 +625,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
P_AddPlayerScore(player, 1000);
|
||||
|
||||
if (gametype != GT_COOP || modeattacking) // score only?
|
||||
if (!(gametyperules & GTR_SPECIALSTAGES) || modeattacking) // score only?
|
||||
{
|
||||
S_StartSound(toucher, sfx_chchng);
|
||||
break;
|
||||
|
@ -1888,7 +1888,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
|||
char targetname[MAXPLAYERNAME+4];
|
||||
char sourcename[MAXPLAYERNAME+4];
|
||||
|
||||
if (G_PlatformGametype())
|
||||
if (!(gametyperules & (GTR_RINGSLINGER|GTR_HURTMESSAGES)))
|
||||
return; // Not in coop, etc.
|
||||
|
||||
if (!player)
|
||||
|
@ -2093,7 +2093,7 @@ void P_CheckTimeLimit(void)
|
|||
if (!(multiplayer || netgame))
|
||||
return;
|
||||
|
||||
if (G_PlatformGametype())
|
||||
if (!(gametyperules & GTR_TIMELIMIT))
|
||||
return;
|
||||
|
||||
if (leveltime < timelimitintics)
|
||||
|
@ -2124,7 +2124,7 @@ void P_CheckTimeLimit(void)
|
|||
}
|
||||
|
||||
//Optional tie-breaker for Match/CTF
|
||||
else if (cv_overtime.value)
|
||||
else if ((cv_overtime.value) && (gametyperules & GTR_OVERTIME))
|
||||
{
|
||||
INT32 playerarray[MAXPLAYERS];
|
||||
INT32 tempplayer = 0;
|
||||
|
@ -2206,7 +2206,7 @@ void P_CheckPointLimit(void)
|
|||
if (!(multiplayer || netgame))
|
||||
return;
|
||||
|
||||
if (G_PlatformGametype())
|
||||
if (!(gametyperules & GTR_POINTLIMIT))
|
||||
return;
|
||||
|
||||
// pointlimit is nonzero, check if it's been reached by this player
|
||||
|
@ -2389,7 +2389,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
{
|
||||
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
|
||||
G_StopMetalRecording(true);
|
||||
if (gametype == GT_MATCH // note, no team match suicide penalty
|
||||
if ((gametyperules & GTR_DEATHPENALTY) // note, no team match suicide penalty
|
||||
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
|
||||
{ // Suicide penalty
|
||||
if (target->player->score >= 50)
|
||||
|
@ -2978,7 +2978,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
|
|||
player->flyangle += 180; // Shuffle's BETTERNIGHTSMOVEMENT?
|
||||
player->flyangle %= 360;
|
||||
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
player->drillmeter -= 5*20;
|
||||
else
|
||||
{
|
||||
|
@ -3040,7 +3040,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
return false;
|
||||
|
||||
// Ignore IT players shooting each other, unless friendlyfire is on.
|
||||
if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) &&
|
||||
if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) &&
|
||||
source && source->player && source->player->pflags & PF_TAGIT)))
|
||||
{
|
||||
if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
|
||||
|
@ -3056,7 +3056,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
|
||||
// Don't allow players on the same team to hurt one another,
|
||||
// unless cv_friendlyfire is on.
|
||||
if (!(cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT))
|
||||
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT))
|
||||
{
|
||||
if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
|
||||
{
|
||||
|
@ -3141,7 +3141,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
|
|||
return false;
|
||||
|
||||
// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
|
||||
if (!cv_friendlyfire.value && (G_PlatformGametype()))
|
||||
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype()))
|
||||
{
|
||||
if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only
|
||||
{
|
||||
|
@ -3164,7 +3164,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
|
|||
{
|
||||
// Don't allow players on the same team to hurt one another,
|
||||
// unless cv_friendlyfire is on.
|
||||
if (!cv_friendlyfire.value && target->player->ctfteam == source->player->ctfteam)
|
||||
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && target->player->ctfteam == source->player->ctfteam)
|
||||
{
|
||||
if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
|
||||
{
|
||||
|
@ -3222,7 +3222,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate);
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
|
@ -3347,7 +3347,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
else
|
||||
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
|
@ -3381,7 +3381,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
|||
P_AddPlayerScore(source->player, 50);
|
||||
}
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
|
@ -3424,6 +3424,24 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
|
|||
if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super])
|
||||
return;
|
||||
|
||||
if (!cv_friendlyfire.value)
|
||||
{
|
||||
if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
|
||||
{
|
||||
if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers.
|
||||
{
|
||||
P_SwitchShield(player, SH_PINK);
|
||||
S_StartSound(player->mo, mobjinfo[MT_PITY_ICON].seesound);
|
||||
}
|
||||
}
|
||||
|
||||
if (source->player->ctfteam == player->ctfteam)
|
||||
return;
|
||||
}
|
||||
|
||||
if (inflictor->type == MT_LHRT)
|
||||
return;
|
||||
|
||||
if (player->powers[pw_shield] || player->bot) //If One-Hit Shield
|
||||
{
|
||||
P_RemoveShield(player);
|
||||
|
@ -3440,7 +3458,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
|
|||
|
||||
P_DoPlayerPain(player, inflictor, source);
|
||||
|
||||
if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))
|
||||
if ((gametyperules & GTR_TEAMFLAGS) && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))
|
||||
P_PlayerFlagBurst(player, false);
|
||||
|
||||
if (oldnightstime > 10*TICRATE
|
||||
|
@ -3591,7 +3609,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
{
|
||||
if (source == target)
|
||||
return false; // Don't hit yourself with your own paraloop, baka
|
||||
if (source && source->player && !cv_friendlyfire.value
|
||||
if (source && source->player && !(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE))
|
||||
&& (gametype == GT_COOP
|
||||
|| (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam)))
|
||||
return false; // Don't run eachother over in special stages and team games and such
|
||||
|
@ -3686,7 +3704,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
// by friendly fire. Spilling their rings and other items is enough.
|
||||
else if (!force && G_GametypeHasTeams()
|
||||
&& source && source->player && (source->player->ctfteam == player->ctfteam)
|
||||
&& cv_friendlyfire.value)
|
||||
&& (cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)))
|
||||
{
|
||||
damage = 0;
|
||||
P_ShieldDamage(player, inflictor, source, damage, damagetype);
|
||||
|
|
|
@ -615,7 +615,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
|||
// Why block opposing teams from tailsflying each other?
|
||||
// Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
|
||||
/*
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION
|
||||
if ((gametyperules & GTR_RACE)
|
||||
|| (netgame && (tails->spectator || sonic->spectator))
|
||||
|| (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
|
||||
|| (gametype == GT_MATCH)
|
||||
|
|
8732
src/p_mobj.c
8732
src/p_mobj.c
File diff suppressed because it is too large
Load diff
|
@ -452,8 +452,10 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
|
|||
void P_MovePlayerToStarpost(INT32 playernum);
|
||||
void P_AfterPlayerSpawn(INT32 playernum);
|
||||
|
||||
void P_SpawnMapThing(mapthing_t *mthing);
|
||||
void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime);
|
||||
mobj_t *P_SpawnMapThing(mapthing_t *mthing);
|
||||
void P_SpawnHoop(mapthing_t *mthing);
|
||||
void P_SetBonusTime(mobj_t *mobj);
|
||||
void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime);
|
||||
void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle);
|
||||
void P_SpawnPrecipitation(void);
|
||||
void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter);
|
||||
|
|
|
@ -777,14 +777,13 @@ static void P_NetArchiveWorld(void)
|
|||
size_t i;
|
||||
INT32 statsec = 0, statline = 0;
|
||||
const line_t *li = lines;
|
||||
const line_t *spawnli = spawnlines;
|
||||
const side_t *si;
|
||||
const side_t *spawnsi;
|
||||
UINT8 *put;
|
||||
|
||||
// reload the map just to see difference
|
||||
mapsector_t *ms;
|
||||
mapsidedef_t *msd;
|
||||
maplinedef_t *mld;
|
||||
const sector_t *ss = sectors;
|
||||
const sector_t *spawnss = spawnsectors;
|
||||
UINT8 diff, diff2, diff3;
|
||||
|
||||
// initialize colormap vars because paranoia
|
||||
|
@ -793,65 +792,45 @@ static void P_NetArchiveWorld(void)
|
|||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||
put = save_p;
|
||||
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
||||
{ // HACK: Open wad file rather quickly so we can get the data from the relevant lumps
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
#define retrieve_mapdata(d, f)\
|
||||
d = Z_Malloc((f)->size, PU_CACHE, NULL); \
|
||||
M_Memcpy(d, wadData + (f)->filepos, (f)->size)
|
||||
retrieve_mapdata(ms, fileinfo + ML_SECTORS);
|
||||
retrieve_mapdata(mld, fileinfo + ML_LINEDEFS);
|
||||
retrieve_mapdata(msd, fileinfo + ML_SIDEDEFS);
|
||||
#undef retrieve_mapdata
|
||||
Z_Free(wadData); // we're done with this now
|
||||
}
|
||||
else // phew it's just a WAD
|
||||
{
|
||||
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE);
|
||||
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
|
||||
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
|
||||
}
|
||||
|
||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||
for (i = 0; i < numsectors; i++, ss++, spawnss++)
|
||||
{
|
||||
diff = diff2 = diff3 = 0;
|
||||
if (ss->floorheight != SHORT(ms->floorheight)<<FRACBITS)
|
||||
if (ss->floorheight != spawnss->floorheight)
|
||||
diff |= SD_FLOORHT;
|
||||
if (ss->ceilingheight != SHORT(ms->ceilingheight)<<FRACBITS)
|
||||
if (ss->ceilingheight != spawnss->ceilingheight)
|
||||
diff |= SD_CEILHT;
|
||||
//
|
||||
// flats
|
||||
//
|
||||
if (ss->floorpic != P_CheckLevelFlat(ms->floorpic))
|
||||
if (ss->floorpic != spawnss->floorpic)
|
||||
diff |= SD_FLOORPIC;
|
||||
if (ss->ceilingpic != P_CheckLevelFlat(ms->ceilingpic))
|
||||
if (ss->ceilingpic != spawnss->ceilingpic)
|
||||
diff |= SD_CEILPIC;
|
||||
|
||||
if (ss->lightlevel != SHORT(ms->lightlevel))
|
||||
if (ss->lightlevel != spawnss->lightlevel)
|
||||
diff |= SD_LIGHT;
|
||||
if (ss->special != SHORT(ms->special))
|
||||
if (ss->special != spawnss->special)
|
||||
diff |= SD_SPECIAL;
|
||||
|
||||
if (ss->floor_xoffs != ss->spawn_flr_xoffs)
|
||||
if (ss->floor_xoffs != spawnss->floor_xoffs)
|
||||
diff2 |= SD_FXOFFS;
|
||||
if (ss->floor_yoffs != ss->spawn_flr_yoffs)
|
||||
if (ss->floor_yoffs != spawnss->floor_yoffs)
|
||||
diff2 |= SD_FYOFFS;
|
||||
if (ss->ceiling_xoffs != ss->spawn_ceil_xoffs)
|
||||
if (ss->ceiling_xoffs != spawnss->ceiling_xoffs)
|
||||
diff2 |= SD_CXOFFS;
|
||||
if (ss->ceiling_yoffs != ss->spawn_ceil_yoffs)
|
||||
if (ss->ceiling_yoffs != spawnss->ceiling_yoffs)
|
||||
diff2 |= SD_CYOFFS;
|
||||
if (ss->floorpic_angle != ss->spawn_flrpic_angle)
|
||||
if (ss->floorpic_angle != spawnss->floorpic_angle)
|
||||
diff2 |= SD_FLOORANG;
|
||||
if (ss->ceilingpic_angle != ss->spawn_flrpic_angle)
|
||||
if (ss->ceilingpic_angle != spawnss->ceilingpic_angle)
|
||||
diff2 |= SD_CEILANG;
|
||||
|
||||
if (ss->tag != SHORT(ms->tag))
|
||||
if (ss->tag != spawnss->tag)
|
||||
diff2 |= SD_TAG;
|
||||
if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag)
|
||||
if (ss->nexttag != spawnss->nexttag || ss->firsttag != spawnss->firsttag)
|
||||
diff3 |= SD_TAGLIST;
|
||||
|
||||
if (ss->extra_colormap != ss->spawn_extra_colormap)
|
||||
if (ss->extra_colormap != spawnss->extra_colormap)
|
||||
diff3 |= SD_COLORMAP;
|
||||
|
||||
// Check if any of the sector's FOFs differ from how they spawned
|
||||
|
@ -955,45 +934,41 @@ static void P_NetArchiveWorld(void)
|
|||
WRITEUINT16(put, 0xffff);
|
||||
|
||||
// do lines
|
||||
for (i = 0; i < numlines; i++, mld++, li++)
|
||||
for (i = 0; i < numlines; i++, spawnli++, li++)
|
||||
{
|
||||
diff = diff2 = diff3 = 0;
|
||||
|
||||
if (li->special != SHORT(mld->special))
|
||||
if (li->special != spawnli->special)
|
||||
diff |= LD_SPECIAL;
|
||||
|
||||
if (SHORT(mld->special) == 321 || SHORT(mld->special) == 322) // only reason li->callcount would be non-zero is if either of these are involved
|
||||
if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved
|
||||
diff |= LD_CLLCOUNT;
|
||||
|
||||
if (li->sidenum[0] != 0xffff)
|
||||
{
|
||||
si = &sides[li->sidenum[0]];
|
||||
if (si->textureoffset != SHORT(msd[li->sidenum[0]].textureoffset)<<FRACBITS)
|
||||
spawnsi = &spawnsides[li->sidenum[0]];
|
||||
if (si->textureoffset != spawnsi->textureoffset)
|
||||
diff |= LD_S1TEXOFF;
|
||||
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
|
||||
if (R_CheckTextureNumForName(msd[li->sidenum[0]].toptexture) != -1
|
||||
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[0]].toptexture))
|
||||
if (si->toptexture != spawnsi->toptexture)
|
||||
diff |= LD_S1TOPTEX;
|
||||
if (R_CheckTextureNumForName(msd[li->sidenum[0]].bottomtexture) != -1
|
||||
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[0]].bottomtexture))
|
||||
if (si->bottomtexture != spawnsi->bottomtexture)
|
||||
diff |= LD_S1BOTTEX;
|
||||
if (R_CheckTextureNumForName(msd[li->sidenum[0]].midtexture) != -1
|
||||
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[0]].midtexture))
|
||||
if (si->midtexture != spawnsi->midtexture)
|
||||
diff |= LD_S1MIDTEX;
|
||||
}
|
||||
if (li->sidenum[1] != 0xffff)
|
||||
{
|
||||
si = &sides[li->sidenum[1]];
|
||||
if (si->textureoffset != SHORT(msd[li->sidenum[1]].textureoffset)<<FRACBITS)
|
||||
spawnsi = &spawnsides[li->sidenum[1]];
|
||||
if (si->textureoffset != spawnsi->textureoffset)
|
||||
diff2 |= LD_S2TEXOFF;
|
||||
if (R_CheckTextureNumForName(msd[li->sidenum[1]].toptexture) != -1
|
||||
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[1]].toptexture))
|
||||
if (si->toptexture != spawnsi->toptexture)
|
||||
diff2 |= LD_S2TOPTEX;
|
||||
if (R_CheckTextureNumForName(msd[li->sidenum[1]].bottomtexture) != -1
|
||||
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[1]].bottomtexture))
|
||||
if (si->bottomtexture != spawnsi->bottomtexture)
|
||||
diff2 |= LD_S2BOTTEX;
|
||||
if (R_CheckTextureNumForName(msd[li->sidenum[1]].midtexture) != -1
|
||||
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[1]].midtexture))
|
||||
if (si->midtexture != spawnsi->midtexture)
|
||||
diff2 |= LD_S2MIDTEX;
|
||||
if (diff2)
|
||||
diff |= LD_DIFF2;
|
||||
|
@ -2557,7 +2532,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
|
||||
if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
|
||||
{
|
||||
P_SpawnHoopsAndRings(&mapthings[spawnpointnum], false);
|
||||
P_SpawnHoop(&mapthings[spawnpointnum]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
880
src/p_setup.c
880
src/p_setup.c
File diff suppressed because it is too large
Load diff
69
src/p_spec.c
69
src/p_spec.c
|
@ -138,6 +138,13 @@ static size_t maxanims;
|
|||
|
||||
static animdef_t *animdefs = NULL;
|
||||
|
||||
// Increase the size of animdefs to make room for a new animation definition
|
||||
static void GrowAnimDefs(void)
|
||||
{
|
||||
maxanims++;
|
||||
animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
// A prototype; here instead of p_spec.h, so they're "private"
|
||||
void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum);
|
||||
void P_ParseAnimationDefintion(SINT8 istexture);
|
||||
|
@ -347,8 +354,7 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
|||
if (i == maxanims)
|
||||
{
|
||||
// Increase the size to make room for the new animation definition
|
||||
maxanims++;
|
||||
animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL);
|
||||
GrowAnimDefs();
|
||||
strncpy(animdefs[i].startname, animdefsToken, 9);
|
||||
}
|
||||
|
||||
|
@ -434,8 +440,17 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
|||
}
|
||||
animdefs[i].speed = animSpeed;
|
||||
Z_Free(animdefsToken);
|
||||
}
|
||||
|
||||
#ifdef WALLFLATS
|
||||
// hehe... uhh.....
|
||||
if (!istexture)
|
||||
{
|
||||
GrowAnimDefs();
|
||||
M_Memcpy(&animdefs[maxanims-1], &animdefs[i], sizeof(animdef_t));
|
||||
animdefs[maxanims-1].istexture = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Checks for flats in levelflats that are part of a flat animation sequence
|
||||
* and sets them up for animation.
|
||||
|
@ -476,7 +491,8 @@ static inline void P_FindAnimatedFlat(INT32 animnum)
|
|||
atoi(sizeu1(i)), foundflats->name, foundflats->animseq,
|
||||
foundflats->numpics,foundflats->speed);
|
||||
}
|
||||
else if (foundflats->u.flat.lumpnum >= startflatnum && foundflats->u.flat.lumpnum <= endflatnum)
|
||||
else if ((!anims[animnum].istexture) && (foundflats->type == LEVELFLAT_FLAT)
|
||||
&& (foundflats->u.flat.lumpnum >= startflatnum && foundflats->u.flat.lumpnum <= endflatnum))
|
||||
{
|
||||
foundflats->u.flat.baselumpnum = startflatnum;
|
||||
foundflats->animseq = foundflats->u.flat.lumpnum - startflatnum;
|
||||
|
@ -1587,8 +1603,6 @@ static inline void P_InitTagLists(void)
|
|||
size_t j = (unsigned)sectors[i].tag % numsectors;
|
||||
sectors[i].nexttag = sectors[j].firsttag;
|
||||
sectors[j].firsttag = (INT32)i;
|
||||
sectors[i].spawn_nexttag = sectors[i].nexttag;
|
||||
sectors[j].spawn_firsttag = sectors[j].firsttag;
|
||||
}
|
||||
|
||||
for (i = numlines - 1; i != (size_t)-1; i--)
|
||||
|
@ -4678,7 +4692,7 @@ DoneSection2:
|
|||
}
|
||||
|
||||
case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return
|
||||
if (player->bot || !G_PlatformGametype())
|
||||
if (player->bot || !(gametyperules & GTR_ALLOWEXIT))
|
||||
break;
|
||||
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6)
|
||||
{
|
||||
|
@ -4713,7 +4727,7 @@ DoneSection2:
|
|||
break;
|
||||
|
||||
case 3: // Red Team's Base
|
||||
if (gametype == GT_CTF && P_IsObjectOnGround(player->mo))
|
||||
if ((gametyperules & GTR_TEAMFLAGS) && P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (player->ctfteam == 1 && (player->gotflag & GF_BLUEFLAG))
|
||||
{
|
||||
|
@ -4746,7 +4760,7 @@ DoneSection2:
|
|||
break;
|
||||
|
||||
case 4: // Blue Team's Base
|
||||
if (gametype == GT_CTF && P_IsObjectOnGround(player->mo))
|
||||
if ((gametyperules & GTR_TEAMFLAGS) && P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (player->ctfteam == 2 && (player->gotflag & GF_REDFLAG))
|
||||
{
|
||||
|
@ -5626,7 +5640,7 @@ void P_UpdateSpecials(void)
|
|||
if (foundflats->speed) // it is an animated flat
|
||||
{
|
||||
// update the levelflat texture number
|
||||
if (foundflats->type == LEVELFLAT_TEXTURE)
|
||||
if ((foundflats->type == LEVELFLAT_TEXTURE) && (foundflats->u.texture.basenum != -1))
|
||||
foundflats->u.texture.num = foundflats->u.texture.basenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
|
||||
// update the levelflat lump number
|
||||
else if ((foundflats->type == LEVELFLAT_FLAT) && (foundflats->u.flat.baselumpnum != LUMPERROR))
|
||||
|
@ -6389,22 +6403,16 @@ static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flata
|
|||
{
|
||||
if (!(master->flags & ML_NETONLY)) // Modify floor flat alignment unless ML_NETONLY flag is set
|
||||
{
|
||||
sector->spawn_flrpic_angle = sector->floorpic_angle = flatangle;
|
||||
sector->floorpic_angle = flatangle;
|
||||
sector->floor_xoffs += xoffs;
|
||||
sector->floor_yoffs += yoffs;
|
||||
// saved for netgames
|
||||
sector->spawn_flr_xoffs = sector->floor_xoffs;
|
||||
sector->spawn_flr_yoffs = sector->floor_yoffs;
|
||||
}
|
||||
|
||||
if (!(master->flags & ML_NONET)) // Modify ceiling flat alignment unless ML_NONET flag is set
|
||||
{
|
||||
sector->spawn_ceilpic_angle = sector->ceilingpic_angle = flatangle;
|
||||
sector->ceilingpic_angle = flatangle;
|
||||
sector->ceiling_xoffs += xoffs;
|
||||
sector->ceiling_yoffs += yoffs;
|
||||
// saved for netgames
|
||||
sector->spawn_ceil_xoffs = sector->ceiling_xoffs;
|
||||
sector->spawn_ceil_yoffs = sector->ceiling_yoffs;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6425,7 +6433,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
INT32 j;
|
||||
thinkerlist_t *secthinkers;
|
||||
thinker_t *th;
|
||||
|
||||
virtres_t* virt = NULL;
|
||||
// This used to be used, and *should* be used in the future,
|
||||
// but currently isn't.
|
||||
(void)fromnetsave;
|
||||
|
@ -7177,17 +7185,10 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
UINT8 *data;
|
||||
UINT16 b;
|
||||
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
||||
{ // HACK: Open wad file rather quickly so we can get the data from the sidedefs lump
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
fileinfo += ML_SIDEDEFS; // we only need the SIDEDEFS lump
|
||||
data = Z_Malloc(fileinfo->size, PU_STATIC, NULL);
|
||||
M_Memcpy(data, wadData + fileinfo->filepos, fileinfo->size); // copy data
|
||||
Z_Free(wadData); // we're done with this now
|
||||
}
|
||||
else // phew it's just a WAD
|
||||
data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC);
|
||||
if (!virt)
|
||||
virt = vres_GetMap(lastloadedmaplumpnum);
|
||||
|
||||
data = (UINT8*) vres_Find(virt, "SIDEDEFS")->data;
|
||||
|
||||
for (b = 0; b < (INT16)numsides; b++)
|
||||
{
|
||||
|
@ -7207,7 +7208,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
I_Error("Make-Your-Own-FOF (tag %d) needs a value in the linedef's second side upper texture field.", lines[i].tag);
|
||||
}
|
||||
}
|
||||
Z_Free(data);
|
||||
}
|
||||
else
|
||||
I_Error("Make-Your-Own FOF (tag %d) found without a 2nd linedef side!", lines[i].tag);
|
||||
|
@ -7224,14 +7224,14 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
|
||||
case 308: // Race-only linedef executor. Triggers once.
|
||||
if (gametype != GT_RACE && gametype != GT_COMPETITION)
|
||||
if (!(gametyperules & GTR_RACE))
|
||||
lines[i].special = 0;
|
||||
break;
|
||||
|
||||
// Linedef executor triggers for CTF teams.
|
||||
case 309:
|
||||
case 311:
|
||||
if (gametype != GT_CTF)
|
||||
if (!(gametyperules & GTR_TEAMFLAGS))
|
||||
lines[i].special = 0;
|
||||
break;
|
||||
|
||||
|
@ -7433,6 +7433,9 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
}
|
||||
}
|
||||
|
||||
if (virt)
|
||||
vres_Free(virt);
|
||||
|
||||
// Allocate each list
|
||||
for (i = 0; i < numsectors; i++)
|
||||
if(secthinkers[i].thinkers)
|
||||
|
|
67
src/p_user.c
67
src/p_user.c
|
@ -387,7 +387,7 @@ UINT8 P_FindLowestMare(void)
|
|||
mobj_t *mo2;
|
||||
UINT8 mare = UINT8_MAX;
|
||||
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
return 0;
|
||||
|
||||
// scan the thinkers
|
||||
|
@ -789,7 +789,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
P_RestoreMusic(player);
|
||||
}
|
||||
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
{
|
||||
if (player->drillmeter < 48*20)
|
||||
player->drillmeter = 48*20;
|
||||
|
@ -1596,7 +1596,7 @@ void P_RestoreMusic(player_t *player)
|
|||
P_PlayJingle(player, JT_SUPER);
|
||||
|
||||
// Invulnerability
|
||||
else if (player->powers[pw_invulnerability] > 1)
|
||||
else if (player->powers[pw_invulnerability] > 1 && !player->powers[pw_super])
|
||||
{
|
||||
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
|
||||
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
|
||||
|
@ -2177,7 +2177,7 @@ void P_DoPlayerExit(player_t *player)
|
|||
|
||||
if (cv_allowexitlevel.value == 0 && !G_PlatformGametype())
|
||||
return;
|
||||
else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow
|
||||
else if (gametyperules & GTR_RACE) // If in Race Mode, allow
|
||||
{
|
||||
if (!countdown) // a 60-second wait ala Sonic 2.
|
||||
countdown = (cv_countdowntime.value - 1)*TICRATE + 1; // Use cv_countdowntime
|
||||
|
@ -3106,7 +3106,7 @@ static void P_DoPlayerHeadSigns(player_t *player)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh).
|
||||
else if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh).
|
||||
{
|
||||
// Spawn a got-flag message over the head of the player that
|
||||
// has it (but not on your own screen if you have the flag).
|
||||
|
@ -4631,7 +4631,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
S_StartSound(player->mo, sfx_spin);
|
||||
break;
|
||||
}
|
||||
if (player->dashspeed < player->maxdash)
|
||||
if (player->dashspeed < player->maxdash && player->mindash != player->maxdash)
|
||||
{
|
||||
#define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash)
|
||||
fixed_t soundcalculation = chargecalculation;
|
||||
|
@ -4666,7 +4666,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
if (player->powers[pw_carry] == CR_BRAKGOOP)
|
||||
player->dashspeed = 0;
|
||||
|
||||
if (!((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE))
|
||||
if (!((gametyperules & GTR_RACE) && leveltime < 4*TICRATE))
|
||||
{
|
||||
if (player->dashspeed)
|
||||
{
|
||||
|
@ -5044,7 +5044,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
if (onground || player->climbing || player->powers[pw_carry])
|
||||
;
|
||||
else if (gametype == GT_CTF && player->gotflag)
|
||||
else if ((gametyperules & GTR_TEAMFLAGS) && player->gotflag)
|
||||
;
|
||||
else if (player->pflags & (PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player has used an ability previously
|
||||
;
|
||||
|
@ -5124,11 +5124,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
boolean elem = ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL);
|
||||
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
|
||||
if (elem)
|
||||
{
|
||||
player->pflags |= PF_NOJUMPDAMAGE;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
|
||||
S_StartSound(player->mo, sfx_s3k43);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->pflags &= ~PF_NOJUMPDAMAGE;
|
||||
|
@ -5269,7 +5265,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
player->secondjump = 0;
|
||||
player->pflags &= ~PF_THOKKED;
|
||||
}
|
||||
else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag))
|
||||
else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) || player->pflags & PF_SHIELDABILITY)
|
||||
;
|
||||
/*else if (P_SuperReady(player))
|
||||
{
|
||||
|
@ -5556,7 +5552,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
player->pflags |= PF_JUMPDOWN;
|
||||
|
||||
if ((gametype != GT_CTF || !player->gotflag) && !player->exiting)
|
||||
if ((!(gametyperules & GTR_TEAMFLAGS) || !player->gotflag) && !player->exiting)
|
||||
{
|
||||
if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP)
|
||||
{
|
||||
|
@ -7129,7 +7125,7 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
&& !player->exiting)
|
||||
player->nightstime--;
|
||||
}
|
||||
else if (gametype != GT_RACE && gametype != GT_COMPETITION
|
||||
else if (!(gametyperules & GTR_RACE)
|
||||
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
|
||||
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
|
||||
&& !(player->capsule && player->capsule->reactiontime)
|
||||
|
@ -7283,7 +7279,7 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
{
|
||||
player->mo->momx = player->mo->momy = 0;
|
||||
|
||||
if (gametype != GT_RACE && gametype != GT_COMPETITION)
|
||||
if (!(gametyperules & GTR_RACE))
|
||||
P_SetObjectMomZ(player->mo, FRACUNIT/2, (P_MobjFlip(player->mo)*player->mo->momz >= 0));
|
||||
else
|
||||
player->mo->momz = 0;
|
||||
|
@ -9521,12 +9517,12 @@ static void P_DeathThink(player_t *player)
|
|||
player->playerstate = PST_REBORN;
|
||||
}
|
||||
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame)))
|
||||
if ((gametyperules & GTR_RACE) || (gametype == GT_COOP && (multiplayer || netgame)))
|
||||
{
|
||||
// Keep time rolling in race mode
|
||||
if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock)
|
||||
{
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
{
|
||||
if (leveltime >= 4*TICRATE)
|
||||
player->realtime = leveltime - 4*TICRATE;
|
||||
|
@ -10350,6 +10346,11 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
else
|
||||
changeto = (P_RandomFixed() & 1) + 1;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (!LUAh_TeamSwitch(player, changeto, true, false, false))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (player->mo)
|
||||
{
|
||||
P_RemoveMobj(player->mo);
|
||||
|
@ -10361,7 +10362,14 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
|
||||
//Reset away view
|
||||
if (P_IsLocalPlayer(player) && displayplayer != consoleplayer)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
// Call ViewpointSwitch hooks here.
|
||||
// The viewpoint was forcibly changed.
|
||||
LUAh_ViewpointSwitch(player, &players[displayplayer], true);
|
||||
#endif
|
||||
displayplayer = consoleplayer;
|
||||
}
|
||||
|
||||
if (changeto == 1)
|
||||
CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x85', M_GetText("Red team"), '\x80');
|
||||
|
@ -10375,8 +10383,12 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
{
|
||||
// Exception for hide and seek. Don't join a game when you simply
|
||||
// respawn in place and sit there for the rest of the round.
|
||||
if (!(gametype == GT_HIDEANDSEEK && leveltime > (hidetime * TICRATE)))
|
||||
if (!((gametyperules & GTR_HIDEFROZEN) && leveltime > (hidetime * TICRATE)))
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (!LUAh_TeamSwitch(player, 3, true, false, false))
|
||||
return false;
|
||||
#endif
|
||||
if (player->mo)
|
||||
{
|
||||
P_RemoveMobj(player->mo);
|
||||
|
@ -10399,7 +10411,14 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
|
||||
//Reset away view
|
||||
if (P_IsLocalPlayer(player) && displayplayer != consoleplayer)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
// Call ViewpointSwitch hooks here.
|
||||
// The viewpoint was forcibly changed.
|
||||
LUAh_ViewpointSwitch(player, &players[displayplayer], true);
|
||||
#endif
|
||||
displayplayer = consoleplayer;
|
||||
}
|
||||
|
||||
if (gametype != GT_COOP)
|
||||
CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]);
|
||||
|
@ -10525,7 +10544,7 @@ void P_DoPityCheck(player_t *player)
|
|||
{
|
||||
// No pity outside of match or CTF.
|
||||
if (player->spectator
|
||||
|| !(gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF))
|
||||
|| !(gametyperules & GTR_PITYSHIELD))
|
||||
return;
|
||||
|
||||
// Apply pity shield if available.
|
||||
|
@ -11358,7 +11377,7 @@ void P_PlayerThink(player_t *player)
|
|||
I_Error("player %s is in PST_REBORN\n", sizeu1(playeri));
|
||||
#endif
|
||||
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
|
@ -11421,7 +11440,7 @@ void P_PlayerThink(player_t *player)
|
|||
player->exiting > 0 && player->exiting <= 1*TICRATE &&
|
||||
(!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) &&
|
||||
// don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop
|
||||
(gametype == GT_RACE || gametype == GT_COMPETITION ? countdown2 == 0 : true) && // don't fade on timeout
|
||||
((gametyperules & GTR_RACE) ? countdown2 == 0 : true) && // don't fade on timeout
|
||||
player->lives > 0 && // don't fade on game over (competition)
|
||||
P_IsLocalPlayer(player))
|
||||
{
|
||||
|
@ -11536,7 +11555,7 @@ void P_PlayerThink(player_t *player)
|
|||
player->lives = cv_startinglives.value;
|
||||
}
|
||||
|
||||
if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
|
||||
if ((gametyperules & GTR_RACE) && leveltime < 4*TICRATE)
|
||||
{
|
||||
cmd->buttons &= BT_USE; // Remove all buttons except BT_USE
|
||||
cmd->forwardmove = 0;
|
||||
|
@ -11546,7 +11565,7 @@ void P_PlayerThink(player_t *player)
|
|||
// Synchronizes the "real" amount of time spent in the level.
|
||||
if (!player->exiting && !stoppedclock)
|
||||
{
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
{
|
||||
if (leveltime >= 4*TICRATE)
|
||||
player->realtime = leveltime - 4*TICRATE;
|
||||
|
|
178
src/r_data.c
178
src/r_data.c
|
@ -441,7 +441,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
patch_t *realpatch;
|
||||
boolean dealloc = false;
|
||||
UINT8 *pdata;
|
||||
int x, x1, x2, i, width, height;
|
||||
size_t blocksize;
|
||||
column_t *patchcol;
|
||||
|
@ -469,12 +469,17 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
wadnum = patch->wad;
|
||||
lumpnum = patch->lump;
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); // can't use W_CachePatchNumPwad because OpenGL
|
||||
pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
realpatch = (patch_t *)pdata;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
goto multipatch;
|
||||
#endif
|
||||
#ifdef WALLFLATS
|
||||
if (texture->type == TEXTURETYPE_FLAT)
|
||||
goto multipatch;
|
||||
#endif
|
||||
|
||||
// Check the patch for holes.
|
||||
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
|
||||
|
@ -531,9 +536,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
}
|
||||
|
||||
// multi-patch textures (or 'composite')
|
||||
#ifndef NO_PNG_LUMPS
|
||||
multipatch:
|
||||
#endif
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
blocksize = (texture->width * 4) + (texture->width * texture->height);
|
||||
|
@ -552,6 +555,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
// Composite the columns together.
|
||||
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
||||
{
|
||||
boolean dealloc = true;
|
||||
static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer.
|
||||
if (patch->style != AST_COPY)
|
||||
ColumnDrawerPointer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
|
||||
|
@ -560,17 +564,25 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
|
||||
wadnum = patch->wad;
|
||||
lumpnum = patch->lump;
|
||||
pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
dealloc = false;
|
||||
realpatch = (patch_t *)pdata;
|
||||
dealloc = true;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
{
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
|
||||
dealloc = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef WALLFLATS
|
||||
if (texture->type == TEXTURETYPE_FLAT)
|
||||
realpatch = R_FlatToPatch(pdata, texture->width, texture->height, 0, 0, NULL, false);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
(void)lumplength;
|
||||
dealloc = false;
|
||||
}
|
||||
|
||||
x1 = patch->originx;
|
||||
width = SHORT(realpatch->width);
|
||||
|
@ -725,7 +737,6 @@ void R_LoadTextures(void)
|
|||
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||
{
|
||||
// Count the textures from TEXTURES lumps
|
||||
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
|
@ -734,7 +745,6 @@ void R_LoadTextures(void)
|
|||
}
|
||||
|
||||
// Count single-patch textures
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
|
@ -747,7 +757,11 @@ void R_LoadTextures(void)
|
|||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
#ifdef WALLFLATS
|
||||
goto countflats;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
|
@ -764,6 +778,40 @@ void R_LoadTextures(void)
|
|||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
|
||||
#ifdef WALLFLATS
|
||||
countflats:
|
||||
// Count flats
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between F_START and F_END
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// If no textures found by this point, bomb out
|
||||
|
@ -813,7 +861,11 @@ void R_LoadTextures(void)
|
|||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
#ifdef WALLFLATS
|
||||
goto checkflats;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
|
@ -857,6 +909,8 @@ void R_LoadTextures(void)
|
|||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height);
|
||||
}
|
||||
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
|
@ -875,6 +929,107 @@ void R_LoadTextures(void)
|
|||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
|
||||
#ifdef WALLFLATS
|
||||
checkflats:
|
||||
// Yes
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
UINT8 *flatlump;
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
size_t lumplength;
|
||||
size_t flatsize = 0;
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
switch (lumplength)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
flatsize = 2048;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
flatsize = 1024;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
flatsize = 512;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
flatsize = 256;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
flatsize = 128;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
flatsize = 32;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
flatsize = 64;
|
||||
break;
|
||||
}
|
||||
|
||||
//CONS_Printf("\n\"%s\" is a flat, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),flatsize,flatsize);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)flatlump, lumplength))
|
||||
{
|
||||
INT16 width, height;
|
||||
R_PNGDimensions((UINT8 *)flatlump, &width, &height, lumplength);
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
texture->width = texture->height = flatsize;
|
||||
|
||||
texture->type = TEXTURETYPE_FLAT;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = (UINT16)w;
|
||||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
Z_Unlock(flatlump);
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
@ -1191,6 +1346,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
|
|||
M_Memcpy(resultTexture->name, newTextureName, 8);
|
||||
resultTexture->width = newTextureWidth;
|
||||
resultTexture->height = newTextureHeight;
|
||||
resultTexture->type = TEXTURETYPE_COMPOSITE;
|
||||
}
|
||||
Z_Free(texturesToken);
|
||||
texturesToken = M_GetToken(NULL);
|
||||
|
|
14
src/r_data.h
14
src/r_data.h
|
@ -45,6 +45,17 @@ typedef struct
|
|||
enum patchalphastyle style;
|
||||
} texpatch_t;
|
||||
|
||||
// texture type
|
||||
enum
|
||||
{
|
||||
TEXTURETYPE_UNKNOWN,
|
||||
TEXTURETYPE_SINGLEPATCH,
|
||||
TEXTURETYPE_COMPOSITE,
|
||||
#ifdef WALLFLATS
|
||||
TEXTURETYPE_FLAT,
|
||||
#endif
|
||||
};
|
||||
|
||||
// A maptexturedef_t describes a rectangular texture,
|
||||
// which is composed of one or more mappatch_t structures
|
||||
// that arrange graphic patches.
|
||||
|
@ -52,6 +63,7 @@ typedef struct
|
|||
{
|
||||
// Keep name for switch changing, etc.
|
||||
char name[8];
|
||||
UINT8 type; // TEXTURETYPE_
|
||||
INT16 width, height;
|
||||
boolean holes;
|
||||
UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
|
||||
|
@ -159,6 +171,8 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
|
|||
#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
|
||||
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
||||
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
|
||||
extern INT32 numtextures;
|
||||
|
||||
#endif
|
||||
|
|
11
src/r_defs.h
11
src/r_defs.h
|
@ -384,17 +384,6 @@ typedef struct sector_s
|
|||
// for fade thinker
|
||||
INT16 spawn_lightlevel;
|
||||
|
||||
// these are saved for netgames, so do not let Lua touch these!
|
||||
INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed
|
||||
|
||||
// offsets sector spawned with (via linedef type 7)
|
||||
fixed_t spawn_flr_xoffs, spawn_flr_yoffs;
|
||||
fixed_t spawn_ceil_xoffs, spawn_ceil_yoffs;
|
||||
|
||||
// flag angles sector spawned with (via linedef type 7)
|
||||
angle_t spawn_flrpic_angle;
|
||||
angle_t spawn_ceilpic_angle;
|
||||
|
||||
// colormap structure
|
||||
extracolormap_t *spawn_extra_colormap;
|
||||
} sector_t;
|
||||
|
|
|
@ -788,6 +788,8 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo
|
|||
patch_t *patch = NULL;
|
||||
boolean texturechanged = (leveltexture ? (levelflat->u.texture.num != levelflat->u.texture.lastnum) : false);
|
||||
|
||||
(void)ispng;
|
||||
|
||||
// Check if the texture changed.
|
||||
if (leveltexture && (!texturechanged))
|
||||
{
|
||||
|
|
|
@ -63,6 +63,7 @@ extern seg_t *segs;
|
|||
|
||||
extern size_t numsectors;
|
||||
extern sector_t *sectors;
|
||||
extern sector_t *spawnsectors;
|
||||
|
||||
extern size_t numsubsectors;
|
||||
extern subsector_t *subsectors;
|
||||
|
@ -72,9 +73,11 @@ extern node_t *nodes;
|
|||
|
||||
extern size_t numlines;
|
||||
extern line_t *lines;
|
||||
extern line_t *spawnlines;
|
||||
|
||||
extern size_t numsides;
|
||||
extern side_t *sides;
|
||||
extern side_t *spawnsides;
|
||||
|
||||
//
|
||||
// POV data.
|
||||
|
|
|
@ -47,6 +47,7 @@ extern int SDL_main(int argc, char *argv[]);
|
|||
|
||||
#ifdef LOGMESSAGES
|
||||
FILE *logstream = NULL;
|
||||
char logfilename[1024];
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
@ -116,7 +117,6 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
{
|
||||
const char *logdir = NULL;
|
||||
char logfile[MAX_WADPATH];
|
||||
myargc = argc;
|
||||
myargv = argv; /// \todo pull out path to exe from this string
|
||||
|
||||
|
@ -141,7 +141,7 @@ int main(int argc, char **argv)
|
|||
timeinfo = localtime(&my_time);
|
||||
|
||||
strftime(buf, 26, "%Y-%m-%d %H-%M-%S", timeinfo);
|
||||
strcpy(logfile, va("log-%s.txt", buf));
|
||||
strcpy(logfilename, va("log-%s.txt", buf));
|
||||
|
||||
#ifdef DEFAULTDIR
|
||||
if (logdir)
|
||||
|
@ -149,14 +149,16 @@ int main(int argc, char **argv)
|
|||
// Create dirs here because D_SRB2Main() is too late.
|
||||
I_mkdir(va("%s%s"DEFAULTDIR, logdir, PATHSEP), 0755);
|
||||
I_mkdir(va("%s%s"DEFAULTDIR"%slogs",logdir, PATHSEP, PATHSEP), 0755);
|
||||
logstream = fopen(va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfile), "wt");
|
||||
strcpy(logfilename, va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfilename));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
I_mkdir("."PATHSEP"logs"PATHSEP, 0755);
|
||||
logstream = fopen(va("."PATHSEP"logs"PATHSEP"%s", logfile), "wt");
|
||||
strcpy(logfilename, va("."PATHSEP"logs"PATHSEP"%s", logfilename));
|
||||
}
|
||||
|
||||
logstream = fopen(logfilename, "wt");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -181,12 +183,13 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
MakeCodeWritable();
|
||||
#endif
|
||||
|
||||
// startup SRB2
|
||||
CONS_Printf("Setting up SRB2...\n");
|
||||
D_SRB2Main();
|
||||
#ifdef LOGMESSAGES
|
||||
if (!M_CheckParm("-nolog"))
|
||||
CONS_Printf("Logfile: %s\n", logfile);
|
||||
CONS_Printf("Logfile: %s\n", logfilename);
|
||||
#endif
|
||||
CONS_Printf("Entering main game loop...\n");
|
||||
// never return
|
||||
|
|
|
@ -102,6 +102,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON)
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#define NEWSIGNALHANDLER
|
||||
#endif
|
||||
|
||||
#ifndef NOMUMBLE
|
||||
#ifdef __linux__ // need -lrt
|
||||
#include <sys/mman.h>
|
||||
|
@ -229,13 +235,11 @@ SDL_bool framebuffer = SDL_FALSE;
|
|||
|
||||
UINT8 keyboard_started = false;
|
||||
|
||||
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
||||
static void I_ReportSignal(int num, int coredumped)
|
||||
{
|
||||
//static char msg[] = "oh no! back to reality!\r\n";
|
||||
const char * sigmsg;
|
||||
char sigdef[32];
|
||||
|
||||
D_QuitNetGame(); // Fix server freezes
|
||||
char msg[128];
|
||||
|
||||
switch (num)
|
||||
{
|
||||
|
@ -261,20 +265,41 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
|||
sigmsg = "SIGABRT - abnormal termination triggered by abort call";
|
||||
break;
|
||||
default:
|
||||
sprintf(sigdef,"signal number %d", num);
|
||||
sigmsg = sigdef;
|
||||
sprintf(msg,"signal number %d", num);
|
||||
if (coredumped)
|
||||
sigmsg = 0;
|
||||
else
|
||||
sigmsg = msg;
|
||||
}
|
||||
|
||||
I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg);
|
||||
if (coredumped)
|
||||
{
|
||||
if (sigmsg)
|
||||
sprintf(msg, "%s (core dumped)", sigmsg);
|
||||
else
|
||||
strcat(msg, " (core dumped)");
|
||||
|
||||
sigmsg = msg;
|
||||
}
|
||||
|
||||
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg);
|
||||
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
||||
"Signal caught",
|
||||
"Process killed by signal",
|
||||
sigmsg, NULL);
|
||||
}
|
||||
|
||||
#ifndef NEWSIGNALHANDLER
|
||||
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
||||
{
|
||||
D_QuitNetGame(); // Fix server freezes
|
||||
I_ReportSignal(num, 0);
|
||||
I_ShutdownSystem();
|
||||
signal(num, SIG_DFL); //default signal action
|
||||
raise(num);
|
||||
I_Quit();
|
||||
}
|
||||
#endif
|
||||
|
||||
FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
|
||||
{
|
||||
|
@ -650,7 +675,7 @@ static inline void I_ShutdownConsole(void){}
|
|||
//
|
||||
// StartupKeyboard
|
||||
//
|
||||
void I_StartupKeyboard (void)
|
||||
static void I_RegisterSignals (void)
|
||||
{
|
||||
#ifdef SIGINT
|
||||
signal(SIGINT , quit_handler);
|
||||
|
@ -664,10 +689,12 @@ void I_StartupKeyboard (void)
|
|||
|
||||
// If these defines don't exist,
|
||||
// then compilation would have failed above us...
|
||||
#ifndef NEWSIGNALHANDLER
|
||||
signal(SIGILL , signal_handler);
|
||||
signal(SIGSEGV , signal_handler);
|
||||
signal(SIGABRT , signal_handler);
|
||||
signal(SIGFPE , signal_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2139,6 +2166,85 @@ void I_Sleep(void)
|
|||
SDL_Delay(cv_sleep.value);
|
||||
}
|
||||
|
||||
#ifdef NEWSIGNALHANDLER
|
||||
static void newsignalhandler_Warn(const char *pr)
|
||||
{
|
||||
char text[128];
|
||||
|
||||
snprintf(text, sizeof text,
|
||||
"Error while setting up signal reporting: %s: %s",
|
||||
pr,
|
||||
strerror(errno)
|
||||
);
|
||||
|
||||
I_OutputMsg("%s\n", text);
|
||||
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
||||
"Startup error",
|
||||
text, NULL);
|
||||
|
||||
I_ShutdownConsole();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static void I_Fork(void)
|
||||
{
|
||||
int child;
|
||||
int status;
|
||||
int signum;
|
||||
int c;
|
||||
|
||||
child = fork();
|
||||
|
||||
switch (child)
|
||||
{
|
||||
case -1:
|
||||
newsignalhandler_Warn("fork()");
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
if (logstream)
|
||||
fclose(logstream);/* the child has this */
|
||||
|
||||
c = wait(&status);
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
/* By the way, exit closes files. */
|
||||
logstream = fopen(logfilename, "at");
|
||||
#else
|
||||
logstream = 0;
|
||||
#endif
|
||||
|
||||
if (c == -1)
|
||||
{
|
||||
kill(child, SIGKILL);
|
||||
newsignalhandler_Warn("wait()");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WIFSIGNALED (status))
|
||||
{
|
||||
signum = WTERMSIG (status);
|
||||
#ifdef WCOREDUMP
|
||||
I_ReportSignal(signum, WCOREDUMP (status));
|
||||
#else
|
||||
I_ReportSignal(signum, 0);
|
||||
#endif
|
||||
status = 128 + signum;
|
||||
}
|
||||
else if (WIFEXITED (status))
|
||||
{
|
||||
status = WEXITSTATUS (status);
|
||||
}
|
||||
|
||||
I_ShutdownConsole();
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif/*NEWSIGNALHANDLER*/
|
||||
|
||||
INT32 I_StartupSystem(void)
|
||||
{
|
||||
SDL_version SDLcompiled;
|
||||
|
@ -2146,6 +2252,10 @@ INT32 I_StartupSystem(void)
|
|||
SDL_VERSION(&SDLcompiled)
|
||||
SDL_GetVersion(&SDLlinked);
|
||||
I_StartupConsole();
|
||||
#ifdef NEWSIGNALHANDLER
|
||||
I_Fork();
|
||||
#endif
|
||||
I_RegisterSignals();
|
||||
I_OutputMsg("Compiled for SDL version: %d.%d.%d\n",
|
||||
SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch);
|
||||
I_OutputMsg("Linked with SDL version: %d.%d.%d\n",
|
||||
|
@ -2169,7 +2279,6 @@ void I_Quit(void)
|
|||
if (quiting) goto death;
|
||||
SDLforceUngrabMouse();
|
||||
quiting = SDL_FALSE;
|
||||
I_ShutdownConsole();
|
||||
M_SaveConfig(NULL); //save game config, cvars..
|
||||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
|
@ -2287,8 +2396,6 @@ void I_Error(const char *error, ...)
|
|||
I_OutputMsg("\nI_Error(): %s\n", buffer);
|
||||
// ---
|
||||
|
||||
I_ShutdownConsole();
|
||||
|
||||
M_SaveConfig(NULL); // save game config, cvars..
|
||||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
|
@ -2388,6 +2495,10 @@ void I_ShutdownSystem(void)
|
|||
{
|
||||
INT32 c;
|
||||
|
||||
#ifndef NEWSIGNALHANDLER
|
||||
I_ShutdownConsole();
|
||||
#endif
|
||||
|
||||
for (c = MAX_QUIT_FUNCS-1; c >= 0; c--)
|
||||
if (quit_funcs[c])
|
||||
(*quit_funcs[c])();
|
||||
|
|
|
@ -1441,6 +1441,7 @@ INT32 VID_SetMode(INT32 modeNum)
|
|||
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
||||
|
||||
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
|
||||
Impl_VideoSetupBuffer();
|
||||
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
|
@ -1449,8 +1450,6 @@ INT32 VID_SetMode(INT32 modeNum)
|
|||
SDL_FreeSurface(bufSurface);
|
||||
bufSurface = NULL;
|
||||
}
|
||||
|
||||
Impl_VideoSetupBuffer();
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
|
@ -1573,7 +1572,7 @@ static void Impl_VideoSetupSDLBuffer(void)
|
|||
static void Impl_VideoSetupBuffer(void)
|
||||
{
|
||||
// Set up game's software render buffer
|
||||
if (rendermode == render_soft)
|
||||
//if (rendermode == render_soft)
|
||||
{
|
||||
vid.rowbytes = vid.width * vid.bpp;
|
||||
vid.direct = NULL;
|
||||
|
|
|
@ -9,6 +9,26 @@
|
|||
/// \file
|
||||
/// \brief SDL Mixer interface for sound
|
||||
|
||||
#ifdef HAVE_LIBGME
|
||||
#ifdef HAVE_ZLIB
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _LFS64_LARGEFILE
|
||||
#define _LFS64_LARGEFILE
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 0
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
#endif // HAVE_ZLIB
|
||||
#endif // HAVE_LIBGME
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h" // menuactive
|
||||
|
||||
|
@ -57,24 +77,6 @@
|
|||
#include "gme/gme.h"
|
||||
#define GME_TREBLE 5.0f
|
||||
#define GME_BASS 1.0f
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _LFS64_LARGEFILE
|
||||
#define _LFS64_LARGEFILE
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 0
|
||||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
#endif // HAVE_ZLIB
|
||||
#endif // HAVE_LIBGME
|
||||
|
||||
static UINT16 BUFFERSIZE = 2048;
|
||||
|
|
155
src/st_stuff.c
155
src/st_stuff.c
|
@ -694,7 +694,7 @@ static void ST_drawTime(void)
|
|||
else
|
||||
{
|
||||
// Counting down the hidetime?
|
||||
if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (stplyr->realtime <= (hidetime*TICRATE)))
|
||||
if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime <= (hidetime*TICRATE)))
|
||||
{
|
||||
tics = (hidetime*TICRATE - stplyr->realtime);
|
||||
if (tics < 3*TICRATE)
|
||||
|
@ -705,11 +705,11 @@ static void ST_drawTime(void)
|
|||
else
|
||||
{
|
||||
// Hidetime finish!
|
||||
if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (stplyr->realtime < ((hidetime+1)*TICRATE)))
|
||||
if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime < ((hidetime+1)*TICRATE)))
|
||||
ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime);
|
||||
|
||||
// Time limit?
|
||||
if (gametype != GT_COOP && gametype != GT_RACE && gametype != GT_COMPETITION && cv_timelimit.value && timelimitintics > 0)
|
||||
if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0)
|
||||
{
|
||||
if (timelimitintics > stplyr->realtime)
|
||||
{
|
||||
|
@ -723,7 +723,7 @@ static void ST_drawTime(void)
|
|||
downwards = true;
|
||||
}
|
||||
// Post-hidetime normal.
|
||||
else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK)
|
||||
else if (gametyperules & GTR_TAG)
|
||||
tics = stplyr->realtime - hidetime*TICRATE;
|
||||
// "Shadow! What are you doing? Hurry and get back here
|
||||
// right now before the island blows up with you on it!"
|
||||
|
@ -912,7 +912,7 @@ static void ST_drawLivesArea(void)
|
|||
else if (stplyr->spectator)
|
||||
v_colmap = V_GRAYMAP;
|
||||
// Tag
|
||||
else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK)
|
||||
else if (gametyperules & GTR_TAG)
|
||||
{
|
||||
if (stplyr->pflags & PF_TAGIT)
|
||||
{
|
||||
|
@ -1177,21 +1177,33 @@ tic_t lt_exitticker = 0, lt_endtime = 0;
|
|||
|
||||
//
|
||||
// Load the graphics for the title card.
|
||||
// Don't let LJ see this
|
||||
//
|
||||
static void ST_cacheLevelTitle(void)
|
||||
{
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE))
|
||||
{
|
||||
lt_patches[0] = (patch_t *)W_CachePatchName("LTACTBLU", PU_HUDGFX);
|
||||
lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGZAG", PU_HUDGFX);
|
||||
lt_patches[2] = (patch_t *)W_CachePatchName("LTZZTEXT", PU_HUDGFX);
|
||||
}
|
||||
else // boss map
|
||||
{
|
||||
lt_patches[0] = (patch_t *)W_CachePatchName("LTACTRED", PU_HUDGFX);
|
||||
lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGRED", PU_HUDGFX);
|
||||
lt_patches[2] = (patch_t *)W_CachePatchName("LTZZWARN", PU_HUDGFX);
|
||||
}
|
||||
#define SETPATCH(default, warning, custom, idx) \
|
||||
{ \
|
||||
lumpnum_t patlumpnum = LUMPERROR; \
|
||||
if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \
|
||||
{ \
|
||||
patlumpnum = W_CheckNumForName(mapheaderinfo[gamemap-1]->custom); \
|
||||
if (patlumpnum != LUMPERROR) \
|
||||
lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \
|
||||
} \
|
||||
if (patlumpnum == LUMPERROR) \
|
||||
{ \
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \
|
||||
lt_patches[idx] = (patch_t *)W_CachePatchName(default, PU_HUDGFX); \
|
||||
else \
|
||||
lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \
|
||||
} \
|
||||
}
|
||||
|
||||
SETPATCH("LTACTBLU", "LTACTRED", ltactdiamond, 0)
|
||||
SETPATCH("LTZIGZAG", "LTZIGRED", ltzzpatch, 1)
|
||||
SETPATCH("LTZZTEXT", "LTZZWARN", ltzztext, 2)
|
||||
|
||||
#undef SETPATCH
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1216,6 +1228,9 @@ void ST_startTitleCard(void)
|
|||
//
|
||||
void ST_preDrawTitleCard(void)
|
||||
{
|
||||
if (!G_IsTitleCardAvailable())
|
||||
return;
|
||||
|
||||
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||
return;
|
||||
|
||||
|
@ -1231,6 +1246,9 @@ void ST_preDrawTitleCard(void)
|
|||
//
|
||||
void ST_runTitleCard(void)
|
||||
{
|
||||
if (!G_IsTitleCardAvailable())
|
||||
return;
|
||||
|
||||
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||
return;
|
||||
|
||||
|
@ -1284,6 +1302,9 @@ void ST_drawTitleCard(void)
|
|||
INT32 zzticker;
|
||||
patch_t *actpat, *zigzag, *zztext;
|
||||
|
||||
if (!G_IsTitleCardAvailable())
|
||||
return;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (!LUA_HudEnabled(hud_stagetitle))
|
||||
goto luahook;
|
||||
|
@ -1762,7 +1783,7 @@ static void ST_drawNiGHTSHUD(void)
|
|||
ST_drawNiGHTSLink();
|
||||
}
|
||||
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
{
|
||||
ST_drawScore();
|
||||
ST_drawTime();
|
||||
|
@ -2203,34 +2224,37 @@ static void ST_drawTextHUD(void)
|
|||
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
|
||||
else if (gametype == GT_COOP)
|
||||
else if (G_PlatformGametype())
|
||||
{
|
||||
if (stplyr->lives <= 0
|
||||
&& cv_cooplives.value == 2
|
||||
&& (netgame || multiplayer))
|
||||
if (gametype == GT_COOP)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (stplyr->lives <= 0
|
||||
&& cv_cooplives.value == 2
|
||||
&& (netgame || multiplayer))
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
if (&players[i] == stplyr)
|
||||
continue;
|
||||
if (&players[i] == stplyr)
|
||||
continue;
|
||||
|
||||
if (players[i].lives > 1)
|
||||
break;
|
||||
}
|
||||
if (players[i].lives > 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != MAXPLAYERS)
|
||||
textHUDdraw(M_GetText("You'll steal a life on respawn..."))
|
||||
if (i != MAXPLAYERS)
|
||||
textHUDdraw(M_GetText("You'll steal a life on respawn..."))
|
||||
else
|
||||
textHUDdraw(M_GetText("Wait to respawn..."))
|
||||
}
|
||||
else
|
||||
textHUDdraw(M_GetText("Wait to respawn..."))
|
||||
}
|
||||
else
|
||||
textHUDdraw(M_GetText("Wait to respawn..."))
|
||||
}
|
||||
else
|
||||
else if (G_GametypeHasSpectators())
|
||||
textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game"))
|
||||
}
|
||||
|
||||
|
@ -2273,13 +2297,14 @@ static void ST_drawTextHUD(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
|
||||
else if ((gametyperules & GTR_TAG) && (!stplyr->spectator))
|
||||
{
|
||||
if (leveltime < hidetime * TICRATE)
|
||||
{
|
||||
if (stplyr->pflags & PF_TAGIT)
|
||||
{
|
||||
textHUDdraw(M_GetText("\x82""You are blindfolded!"))
|
||||
if (gametyperules & GTR_BLINDFOLDED)
|
||||
textHUDdraw(M_GetText("\x82""You are blindfolded!"))
|
||||
textHUDdraw(M_GetText("Waiting for players to hide..."))
|
||||
}
|
||||
else if (gametype == GT_HIDEANDSEEK)
|
||||
|
@ -2294,7 +2319,8 @@ static void ST_drawTextHUD(void)
|
|||
textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view"))
|
||||
donef12 = true;
|
||||
}
|
||||
textHUDdraw(M_GetText("You cannot move while hiding."))
|
||||
if (gametyperules & GTR_HIDEFROZEN)
|
||||
textHUDdraw(M_GetText("You cannot move while hiding."))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2316,21 +2342,27 @@ static void ST_drawTeamHUD(void)
|
|||
if (F_GetPromptHideHud(0)) // y base is 0
|
||||
return;
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
p = bflagico;
|
||||
else
|
||||
p = bmatcico;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_HudEnabled(hud_teamscores))
|
||||
#endif
|
||||
V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p);
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
p = rflagico;
|
||||
else
|
||||
p = rmatcico;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_HudEnabled(hud_teamscores))
|
||||
#endif
|
||||
V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p);
|
||||
|
||||
if (gametype != GT_CTF)
|
||||
if (!(gametyperules & GTR_TEAMFLAGS))
|
||||
goto num;
|
||||
{
|
||||
INT32 i;
|
||||
|
@ -2339,28 +2371,53 @@ static void ST_drawTeamHUD(void)
|
|||
// Show which flags aren't at base.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base
|
||||
if (players[i].gotflag & GF_BLUEFLAG // Blue flag isn't at base
|
||||
#ifdef HAVE_BLUA
|
||||
&& LUA_HudEnabled(hud_teamscores)
|
||||
#endif
|
||||
)
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(nonicon->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon);
|
||||
if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base
|
||||
|
||||
if (players[i].gotflag & GF_REDFLAG // Red flag isn't at base
|
||||
#ifdef HAVE_BLUA
|
||||
&& LUA_HudEnabled(hud_teamscores)
|
||||
#endif
|
||||
)
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(nonicon2->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon2);
|
||||
|
||||
whichflag |= players[i].gotflag;
|
||||
|
||||
if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG))
|
||||
break; // both flags were found, let's stop early
|
||||
}
|
||||
|
||||
// Display a countdown timer showing how much time left until the flag returns to base.
|
||||
{
|
||||
if (blueflag && blueflag->fuse > 1)
|
||||
if (blueflag && blueflag->fuse > 1
|
||||
#ifdef HAVE_BLUA
|
||||
&& LUA_HudEnabled(hud_teamscores)
|
||||
#endif
|
||||
)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (blueflag->fuse / TICRATE)));
|
||||
|
||||
if (redflag && redflag->fuse > 1)
|
||||
if (redflag && redflag->fuse > 1
|
||||
#ifdef HAVE_BLUA
|
||||
&& LUA_HudEnabled(hud_teamscores)
|
||||
#endif
|
||||
)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (redflag->fuse / TICRATE)));
|
||||
}
|
||||
}
|
||||
|
||||
num:
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_HudEnabled(hud_teamscores))
|
||||
#endif
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", bluescore));
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_HudEnabled(hud_teamscores))
|
||||
#endif
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", redscore));
|
||||
|
||||
#undef SEP
|
||||
|
@ -2633,7 +2690,7 @@ static void ST_overlayDrawer(void)
|
|||
}
|
||||
|
||||
// If you are in overtime, put a big honkin' flashin' message on the screen.
|
||||
if (G_RingSlingerGametype() && cv_overtime.value
|
||||
if (((gametyperules & GTR_TIMELIMIT) && (gametyperules & GTR_OVERTIME)) && cv_overtime.value
|
||||
&& (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0))
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER, M_GetText("OVERTIME!"));
|
||||
|
||||
|
@ -2648,7 +2705,7 @@ static void ST_overlayDrawer(void)
|
|||
ST_drawMatchHUD();
|
||||
|
||||
// Race HUD Stuff
|
||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||
if (gametyperules & GTR_RACE)
|
||||
ST_drawRaceHUD();
|
||||
|
||||
// Emerald Hunt Indicators
|
||||
|
@ -2753,7 +2810,7 @@ void ST_Drawer(void)
|
|||
if (rendermode != render_none) ST_doPaletteStuff();
|
||||
|
||||
// Blindfold!
|
||||
if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK)
|
||||
if ((gametyperules & GTR_BLINDFOLDED)
|
||||
&& (leveltime < hidetime * TICRATE))
|
||||
{
|
||||
if (players[displayplayer].pflags & PF_TAGIT)
|
||||
|
|
|
@ -3244,6 +3244,29 @@ Unoptimized version
|
|||
#endif
|
||||
}
|
||||
|
||||
// Taken from my videos-in-SRB2 project
|
||||
// Generates a color look-up table
|
||||
// which has up to 64 colors at each channel
|
||||
// (see the defines in v_video.h)
|
||||
|
||||
UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE];
|
||||
|
||||
void InitColorLUT(RGBA_t *palette)
|
||||
{
|
||||
UINT8 r, g, b;
|
||||
static boolean clutinit = false;
|
||||
static RGBA_t *lastpalette = NULL;
|
||||
if ((!clutinit) || (lastpalette != palette))
|
||||
{
|
||||
for (r = 0; r < CLUTSIZE; r++)
|
||||
for (g = 0; g < CLUTSIZE; g++)
|
||||
for (b = 0; b < CLUTSIZE; b++)
|
||||
colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS);
|
||||
clutinit = true;
|
||||
lastpalette = palette;
|
||||
}
|
||||
}
|
||||
|
||||
// V_Init
|
||||
// old software stuff, buffers are allocated at video mode setup
|
||||
// here we set the screens[x] pointers accordingly
|
||||
|
@ -3255,13 +3278,9 @@ void V_Init(void)
|
|||
const INT32 screensize = vid.rowbytes * vid.height;
|
||||
|
||||
LoadMapPalette();
|
||||
// hardware modes do not use screens[] pointers
|
||||
|
||||
for (i = 0; i < NUMSCREENS; i++)
|
||||
screens[i] = NULL;
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
return; // be sure to cause a NULL read/write error so we detect it, in case of..
|
||||
}
|
||||
|
||||
// start address of NUMSCREENS * width*height vidbuffers
|
||||
if (base)
|
||||
|
|
|
@ -37,6 +37,18 @@ cv_allcaps;
|
|||
// Allocates buffer screens, call before R_Init.
|
||||
void V_Init(void);
|
||||
|
||||
// Taken from my videos-in-SRB2 project
|
||||
// Generates a color look-up table
|
||||
// which has up to 64 colors at each channel
|
||||
|
||||
#define COLORBITS 6
|
||||
#define SHIFTCOLORBITS (8-COLORBITS)
|
||||
#define CLUTSIZE (1<<COLORBITS)
|
||||
|
||||
extern UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE];
|
||||
|
||||
void InitColorLUT(RGBA_t *palette);
|
||||
|
||||
// Set the current RGB palette lookup to use for palettized graphics
|
||||
void V_SetPalette(INT32 palettenum);
|
||||
|
||||
|
|
150
src/w_wad.c
150
src/w_wad.c
|
@ -11,6 +11,24 @@
|
|||
/// \file w_wad.c
|
||||
/// \brief Handles WAD file header, directory, lump I/O
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _LFS64_LARGEFILE
|
||||
#define _LFS64_LARGEFILE
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 0
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
@ -22,22 +40,6 @@
|
|||
#include "lzf.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 0
|
||||
#endif
|
||||
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#ifndef _LFS64_LARGEFILE
|
||||
#define _LFS64_LARGEFILE
|
||||
#endif
|
||||
|
||||
//#ifdef HAVE_ZLIB
|
||||
#include "zlib.h"
|
||||
//#endif // HAVE_ZLIB
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomtype.h"
|
||||
|
@ -77,24 +79,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _LFS64_LARGEFILE
|
||||
#define _LFS64_LARGEFILE
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 0
|
||||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -1888,3 +1872,101 @@ int W_VerifyNMUSlumps(const char *filename)
|
|||
};
|
||||
return W_VerifyFile(filename, NMUSlist, false);
|
||||
}
|
||||
|
||||
/** \brief Generates a virtual resource used for level data loading.
|
||||
*
|
||||
* \param lumpnum_t reference
|
||||
* \return Virtual resource
|
||||
*
|
||||
*/
|
||||
virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
||||
{
|
||||
UINT32 i;
|
||||
virtres_t* vres = NULL;
|
||||
virtlump_t* vlumps = NULL;
|
||||
size_t numlumps = 0;
|
||||
|
||||
if (W_IsLumpWad(lumpnum))
|
||||
{
|
||||
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
|
||||
UINT8 *wadData = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
numlumps = ((wadinfo_t *)wadData)->numlumps;
|
||||
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
|
||||
// Build the lumps.
|
||||
for (i = 0; i < numlumps; i++)
|
||||
{
|
||||
vlumps[i].size = (size_t)(((filelump_t *)(fileinfo + i))->size);
|
||||
// Play it safe with the name in this case.
|
||||
memcpy(vlumps[i].name, (fileinfo + i)->name, 8);
|
||||
vlumps[i].name[8] = '\0';
|
||||
vlumps[i].data = Z_Malloc(vlumps[i].size, PU_LEVEL, NULL); // This is memory inefficient, sorry about that.
|
||||
memcpy(vlumps[i].data, wadData + (fileinfo + i)->filepos, vlumps[i].size);
|
||||
}
|
||||
|
||||
Z_Free(wadData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Count number of lumps until the end of resource OR up until next "MAPXX" lump.
|
||||
lumpnum_t lumppos = lumpnum + 1;
|
||||
for (i = LUMPNUM(lumppos); i < wadfiles[WADFILENUM(lumpnum)]->numlumps; i++, lumppos++, numlumps++)
|
||||
if (memcmp(W_CheckNameForNum(lumppos), "MAP", 3) == 0)
|
||||
break;
|
||||
numlumps++;
|
||||
|
||||
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
for (i = 0; i < numlumps; i++, lumpnum++)
|
||||
{
|
||||
vlumps[i].size = W_LumpLength(lumpnum);
|
||||
memcpy(vlumps[i].name, W_CheckNameForNum(lumpnum), 8);
|
||||
vlumps[i].name[8] = '\0';
|
||||
vlumps[i].data = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||
}
|
||||
}
|
||||
vres = Z_Malloc(sizeof(virtres_t), PU_LEVEL, NULL);
|
||||
vres->vlumps = vlumps;
|
||||
vres->numlumps = numlumps;
|
||||
|
||||
return vres;
|
||||
}
|
||||
|
||||
/** \brief Frees zone memory for a given virtual resource.
|
||||
*
|
||||
* \param Virtual resource
|
||||
*/
|
||||
void vres_Free(virtres_t* vres)
|
||||
{
|
||||
while (vres->numlumps--)
|
||||
Z_Free(vres->vlumps[vres->numlumps].data);
|
||||
Z_Free(vres->vlumps);
|
||||
Z_Free(vres);
|
||||
}
|
||||
|
||||
/** (Debug) Prints lumps from a virtual resource into console.
|
||||
*/
|
||||
/*
|
||||
static void vres_Diag(const virtres_t* vres)
|
||||
{
|
||||
UINT32 i;
|
||||
for (i = 0; i < vres->numlumps; i++)
|
||||
CONS_Printf("%s\n", vres->vlumps[i].name);
|
||||
}
|
||||
*/
|
||||
|
||||
/** \brief Finds a lump in a given virtual resource.
|
||||
*
|
||||
* \param Virtual resource
|
||||
* \param Lump name to look for
|
||||
* \return Virtual lump if found, NULL otherwise
|
||||
*
|
||||
*/
|
||||
virtlump_t* vres_Find(const virtres_t* vres, const char* name)
|
||||
{
|
||||
UINT32 i;
|
||||
for (i = 0; i < vres->numlumps; i++)
|
||||
if (fastcmp(name, vres->vlumps[i].name))
|
||||
return &vres->vlumps[i];
|
||||
return NULL;
|
||||
}
|
||||
|
|
19
src/w_wad.h
19
src/w_wad.h
|
@ -72,6 +72,25 @@ typedef struct
|
|||
compmethod compression; // lump compression method
|
||||
} lumpinfo_t;
|
||||
|
||||
// =========================================================================
|
||||
// 'VIRTUAL' RESOURCES
|
||||
// =========================================================================
|
||||
|
||||
typedef struct {
|
||||
char name[9];
|
||||
UINT8* data;
|
||||
size_t size;
|
||||
} virtlump_t;
|
||||
|
||||
typedef struct {
|
||||
size_t numlumps;
|
||||
virtlump_t* vlumps;
|
||||
} virtres_t;
|
||||
|
||||
virtres_t* vres_GetMap(lumpnum_t);
|
||||
void vres_Free(virtres_t*);
|
||||
virtlump_t* vres_Find(const virtres_t*, const char*);
|
||||
|
||||
// =========================================================================
|
||||
// DYNAMIC WAD LOADING
|
||||
// =========================================================================
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
#include "m_cond.h" // condition sets
|
||||
#include "lua_hook.h" // IntermissionThinker hook
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h"
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
@ -164,6 +168,7 @@ static INT32 tallydonetic = -1;
|
|||
static INT32 endtic = -1;
|
||||
|
||||
intertype_t intertype = int_none;
|
||||
intertype_t intermissiontypes[NUMGAMETYPES];
|
||||
|
||||
static void Y_RescaleScreenBuffer(void);
|
||||
static void Y_AwardCoopBonuses(void);
|
||||
|
@ -318,9 +323,17 @@ void Y_IntermissionDrawer(void)
|
|||
// Bonus loops
|
||||
INT32 i;
|
||||
|
||||
if (intertype == int_none || rendermode == render_none)
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
||||
if (intertype == int_none)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_IntermissionHUD();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (!usebuffer)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
|
@ -358,6 +371,12 @@ void Y_IntermissionDrawer(void)
|
|||
else
|
||||
V_DrawPatchFill(bgtile);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_IntermissionHUD();
|
||||
if (!LUA_HudEnabled(hud_intermissiontally))
|
||||
goto skiptallydrawer;
|
||||
#endif
|
||||
|
||||
if (intertype == int_coop)
|
||||
{
|
||||
INT32 bonusy;
|
||||
|
@ -907,6 +926,12 @@ void Y_IntermissionDrawer(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
skiptallydrawer:
|
||||
if (!LUA_HudEnabled(hud_intermissionmessages))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (timer)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP,
|
||||
va("start in %d seconds", timer/TICRATE));
|
||||
|
@ -1187,7 +1212,9 @@ void Y_StartIntermission(void)
|
|||
timer = 1;
|
||||
}
|
||||
|
||||
if (gametype == GT_COOP)
|
||||
if (intermissiontypes[gametype] != int_none)
|
||||
intertype = intermissiontypes[gametype];
|
||||
else if (gametype == GT_COOP)
|
||||
intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
|
||||
else if (gametype == GT_TEAMMATCH)
|
||||
intertype = int_teammatch;
|
||||
|
|
|
@ -31,3 +31,4 @@ typedef enum
|
|||
int_comp, // Competition
|
||||
} intertype_t;
|
||||
extern intertype_t intertype;
|
||||
extern intertype_t intermissiontypes[NUMGAMETYPES];
|
||||
|
|
Loading…
Reference in a new issue