diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index b34e2ef0c57ad0ff74121bb5cf99997ed7a8230d..0395bf4c9f05bae2fc2a68023d795d51d2867c05 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
TimeLimit: Word;
GoalLimit: Word;
WarmupTime: Word;
+ SpawnInvul: Word;
MaxLives: Byte;
Options: LongWord;
WAD: String;
GAME_OPTION_MONSTERS = 16;
GAME_OPTION_BOTVSPLAYER = 32;
GAME_OPTION_BOTVSMONSTER = 64;
+ GAME_OPTION_DMKEYS = 128;
STATE_NONE = 0;
STATE_MENU = 1;
gMapToDelete: String;
gTempDelete: Boolean = False;
gLastMap: Boolean = False;
- gWinSizeX, gWinSizeY: Integer;
+ gScreenWidth: Word;
+ gScreenHeight: Word;
gResolutionChange: Boolean = False;
gRC_Width, gRC_Height: Integer;
gRC_FullScreen, gRC_Maximized: Boolean;
AssignFile(s, fname);
try
Rewrite(s);
- // line 1: stats version, datetime, server name, map name, game mode, time limit, score limit, dmflags, game time, number of players
+ // line 1: stats ver, datetime, server name, map name, game mode, time limit, score limit, dmflags, game time, num players
if g_Game_IsNet then fname := NetServerName else fname := '';
map := g_ExtractWadNameNoPath(gMapInfo.Map) + ':/' + g_ExtractFileName(gMapInfo.Map);
mode := g_Game_ModeToText(Stat.GameMode);
- etime := Format('%d:%.2d:%.2d', [Stat.GameTime div 1000 div 3600,
- (Stat.GameTime div 1000 div 60) mod 60,
- Stat.GameTime div 1000 mod 60]);
+ etime := Format('%d:%.2d:%.2d', [
+ Stat.GameTime div 1000 div 3600,
+ (Stat.GameTime div 1000 div 60) mod 60,
+ Stat.GameTime div 1000 mod 60
+ ]);
WriteLn(s, 'stats_ver,datetime,server,map,mode,timelimit,scorelimit,dmflags,time,num_players');
- WriteLn(s,
- Format('%d,%s,%s,%s,%s,%u,%u,%u,%s,%d',
- [STATFILE_VERSION, StatDate, fname, map, mode, gGameSettings.TimeLimit, gGameSettings.GoalLimit, gGameSettings.Options, etime, Length(Stat.PlayerStat)]));
+ WriteLn(s, Format('%d,%s,%s,%s,%s,%u,%u,%u,%s,%d', [
+ STATFILE_VERSION,
+ StatDate,
+ dquoteStr(fname),
+ dquoteStr(map),
+ mode,
+ gGameSettings.TimeLimit,
+ gGameSettings.GoalLimit,
+ gGameSettings.Options,
+ etime,
+ Length(Stat.PlayerStat)
+ ]));
// line 2: game specific shit
// if it's a team game: red score, blue score
// if it's a coop game: monsters killed, monsters total, secrets found, secrets total
// otherwise nothing
if Stat.GameMode in [GM_TDM, GM_CTF] then
- WriteLn(s, Format('red_score,blue_score' + LineEnding + '%d,%d', [Stat.TeamStat[TEAM_RED].Goals, Stat.TeamStat[TEAM_BLUE].Goals]))
+ WriteLn(s,
+ Format('red_score,blue_score' + LineEnding + '%d,%d', [Stat.TeamStat[TEAM_RED].Goals, Stat.TeamStat[TEAM_BLUE].Goals]))
else if Stat.GameMode in [GM_COOP, GM_SINGLE] then
- WriteLn(s, Format('mon_killed,mon_total,secrets_found,secrets_total' + LineEnding + '%d,%d,%d,%d', [gCoopMonstersKilled, gTotalMonsters, gCoopSecretsFound, gSecretsCount]));
+ WriteLn(s,
+ Format('mon_killed,mon_total,secrets_found,secrets_total' + LineEnding + '%d,%d,%d,%d',[gCoopMonstersKilled, gTotalMonsters, gCoopSecretsFound, gSecretsCount]));
// lines 3-...: team, player name, frags, deaths
WriteLn(s, 'team,name,frags,deaths');
for I := Low(Stat.PlayerStat) to High(Stat.PlayerStat) do
with Stat.PlayerStat[I] do
- WriteLn(s, Format('%d,%s,%d,%d', [Team, Name, Frags, Deaths]));
+ WriteLn(s, Format('%d,%s,%d,%d', [Team, dquoteStr(Name), Frags, Deaths]));
except
g_Console_Add(Format(_lc[I_CONSOLE_ERROR_WRITE], [fname]));
end;
SortGameStat(CustomStat.PlayerStat);
- if gSaveStats or gScreenshotStats then
+ if (gSaveStats or gScreenshotStats) and (Length(CustomStat.PlayerStat) > 1) then
begin
t := Now;
if g_Game_IsNet then StatFilename := NetServerName else StatFilename := 'local';
StatDate := FormatDateTime('yymmdd_hhnnss', t);
StatFilename := StatFilename + '_' + CustomStat.Map + '_' + g_Game_ModeToText(CustomStat.GameMode);
StatFilename := sanitizeFilename(StatFilename) + '_' + StatDate;
- if gSaveStats then SaveGameStat(CustomStat, FormatDateTime('yyyy"/"mm"/"dd', t));
+ if gSaveStats then
+ SaveGameStat(CustomStat, FormatDateTime('yyyy"/"mm"/"dd', t));
end;
StatShotDone := False;
end;
// HACK: take stats screenshot immediately after the first frame of the stats showing
- if gScreenshotStats and not StatShotDone then
+ if gScreenshotStats and (not StatShotDone) and (Length(CustomStat.PlayerStat) > 1) then
begin
g_TakeScreenShot('stats/' + StatFilename);
StatShotDone := True;
end
else
begin
- glScissor(0, 0, gWinSizeX, gWinSizeY);
+ glScissor(0, 0, gScreenWidth, gScreenHeight);
end;
// no need to clear stencil buffer, light blitting will do it for us... but only for normal scale
if (g_dbg_scale <> 1.0) then glClear(GL_STENCIL_BUFFER_BIT);
b := -py+(gPlayerScreenSize.Y div 2);
end;
- if p.IncCam <> 0 then
- begin
- if py > gMapInfo.Height-(gPlayerScreenSize.Y div 2) then
- begin
- if p.IncCam > 120-(py-(gMapInfo.Height-(gPlayerScreenSize.Y div 2))) then
- begin
- p.IncCam := 120-(py-(gMapInfo.Height-(gPlayerScreenSize.Y div 2)));
- end;
- end;
-
- if py < gPlayerScreenSize.Y div 2 then
- begin
- if p.IncCam < -120+((gPlayerScreenSize.Y div 2)-py) then
- begin
- p.IncCam := -120+((gPlayerScreenSize.Y div 2)-py);
- end;
- end;
-
- if p.IncCam < 0 then
- begin
- while (py+(gPlayerScreenSize.Y div 2)-p.IncCam > gMapInfo.Height) and (p.IncCam < 0) do p.IncCam := p.IncCam+1; //Inc(p.IncCam);
- end;
-
- if p.IncCam > 0 then
- begin
- while (py-(gPlayerScreenSize.Y div 2)-p.IncCam < 0) and (p.IncCam > 0) do p.IncCam := p.IncCam-1; //Dec(p.IncCam);
- end;
- end;
-
- if (px < gPlayerScreenSize.X div 2) or (gMapInfo.Width-gPlayerScreenSize.X <= 256) then c := 0
- else if (px > gMapInfo.Width-(gPlayerScreenSize.X div 2)) then c := gBackSize.X-gPlayerScreenSize.X
- else c := round((px-(gPlayerScreenSize.X div 2))/(gMapInfo.Width-gPlayerScreenSize.X)*(gBackSize.X-gPlayerScreenSize.X));
-
- if (py-p.IncCam <= gPlayerScreenSize.Y div 2) or (gMapInfo.Height-gPlayerScreenSize.Y <= 256) then d := 0
- else if (py-p.IncCam >= gMapInfo.Height-(gPlayerScreenSize.Y div 2)) then d := gBackSize.Y-gPlayerScreenSize.Y
- else d := round((py-p.IncCam-(gPlayerScreenSize.Y div 2))/(gMapInfo.Height-gPlayerScreenSize.Y)*(gBackSize.Y-gPlayerScreenSize.Y));
-
sX := -a;
- sY := -(b+p.IncCam);
+ sY := -b;
sWidth := gPlayerScreenSize.X;
sHeight := gPlayerScreenSize.Y;
+ fixViewportForScale();
- //glTranslatef(a, b+p.IncCam, 0);
-
- //if (p = gPlayer1) and (g_dbg_scale >= 1.0) then g_Holmes_plrViewSize(sWidth, sHeight);
+ i := py - (sY + sHeight div 2);
+ if (p.IncCam > 0) then
+ begin
+ // clamp to level bounds
+ if (sY - p.IncCam < 0) then
+ p.IncCam := nclamp(sY, 0, 120);
+ // clamp around player position
+ if (i > 0) then
+ p.IncCam := nclamp(p.IncCam, 0, max(0, 120 - i));
+ end
+ else if (p.IncCam < 0) then
+ begin
+ // clamp to level bounds
+ if (sY + sHeight - p.IncCam > gMapInfo.Height) then
+ p.IncCam := nclamp(sY + sHeight - gMapInfo.Height, -120, 0);
+ // clamp around player position
+ if (i < 0) then
+ p.IncCam := nclamp(p.IncCam, min(0, -120 - i), 0);
+ end;
- //conwritefln('OLD: (%s,%s)-(%s,%s)', [sX, sY, sWidth, sHeight]);
- fixViewportForScale();
- //conwritefln(' (%s,%s)-(%s,%s)', [sX, sY, sWidth, sHeight]);
+ sY := sY - p.IncCam;
- if (g_dbg_scale <> 1.0) and (not g_dbg_ignore_bounds) then
+ if (not g_dbg_ignore_bounds) then
begin
if (sX+sWidth > gMapInfo.Width) then sX := gMapInfo.Width-sWidth;
if (sY+sHeight > gMapInfo.Height) then sY := gMapInfo.Height-sHeight;
if (sX < 0) then sX := 0;
if (sY < 0) then sY := 0;
-
- if (gBackSize.X <= gPlayerScreenSize.X) or (gMapInfo.Width <= sWidth) then c := 0 else c := trunc((gBackSize.X-gPlayerScreenSize.X)*sX/(gMapInfo.Width-sWidth));
- if (gBackSize.Y <= gPlayerScreenSize.Y) or (gMapInfo.Height <= sHeight) then d := 0 else d := trunc((gBackSize.Y-gPlayerScreenSize.Y)*sY/(gMapInfo.Height-sHeight));
end;
+ if (gBackSize.X <= gPlayerScreenSize.X) or (gMapInfo.Width <= sWidth) then c := 0 else c := trunc((gBackSize.X-gPlayerScreenSize.X)*sX/(gMapInfo.Width-sWidth));
+ if (gBackSize.Y <= gPlayerScreenSize.Y) or (gMapInfo.Height <= sHeight) then d := 0 else d := trunc((gBackSize.Y-gPlayerScreenSize.Y)*sY/(gMapInfo.Height-sHeight));
+
//r_smallmap_h: 0: left; 1: center; 2: right
//r_smallmap_v: 0: top; 1: center; 2: bottom
// horiz small map?
// Ñòàðòóåì ñåðâåð
if not g_Net_Host(IPAddr, Port, NetMaxClients) then
begin
- g_FatalError(_lc[I_NET_MSG] + _lc[I_NET_ERR_HOST]);
+ g_FatalError(_lc[I_NET_MSG] + Format(_lc[I_NET_ERR_HOST], [Port]));
Exit;
end;
ResName := Map;
end;
+ gTime := 0;
+
//writeln('********: gsw=', gGameSettings.WAD, '; rn=', ResName);
result := false;
if (ResName <> '') and (NewWAD <> '') then
gExit := 0;
gPauseMain := false;
gPauseHolmes := false;
- gTime := 0;
NetTimeToUpdate := 1;
NetTimeToReliable := 0;
NetTimeToMaster := NetMasterRate;
if g_Game_IsNet then MH_SEND_GameSettings;
end;
end
+ else if (cmd = 'g_dm_keys') and not g_Game_IsClient then
+ begin
+ with gGameSettings do
+ begin
+ if (Length(P) > 1) and
+ ((P[1] = '1') or (P[1] = '0')) then
+ begin
+ if (P[1][1] = '1') then
+ Options := Options or GAME_OPTION_DMKEYS
+ else
+ Options := Options and (not GAME_OPTION_DMKEYS);
+ end;
+
+ if (LongBool(Options and GAME_OPTION_DMKEYS)) then
+ g_Console_Add(_lc[I_MSG_DMKEYS_ON])
+ else
+ g_Console_Add(_lc[I_MSG_DMKEYS_OFF]);
+
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
+ end
else if (cmd = 'g_warmuptime') and not g_Game_IsClient then
begin
if Length(P) > 1 then
[gGameSettings.WarmupTime]));
g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
end
+ else if (cmd = 'g_spawn_invul') and not g_Game_IsClient then
+ begin
+ if Length(P) > 1 then
+ begin
+ if StrToIntDef(P[1], gGameSettings.SpawnInvul) = 0 then
+ gGameSettings.SpawnInvul := 0
+ else
+ gGameSettings.SpawnInvul := StrToIntDef(P[1], gGameSettings.SpawnInvul);
+ end;
+
+ g_Console_Add(Format(_lc[I_MSG_SPAWNINVUL],
+ [gGameSettings.SpawnInvul]));
+ g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
+ end
else if cmd = 'net_interp' then
begin
if (Length(P) > 1) then
if cmd = 'd_window' then
begin
g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
- g_Console_Add(Format('gWinSizeX = %d, gWinSizeY = %d', [gWinSizeX, gWinSizeY]));
+ g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
end
else if cmd = 'd_sounds' then
begin
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
+ else if cmd = 'centerprint' then
+ begin
+ if (Length(P) > 2) and (P[1] <> '') then
+ begin
+ chstr := '';
+ for a := 2 to High(P) do
+ chstr := chstr + P[a] + ' ';
+
+ if Length(chstr) > 200 then SetLength(chstr, 200);
+
+ if Length(chstr) < 1 then
+ begin
+ g_Console_Add('centerprint <timeout> <text>');
+ Exit;
+ end;
+
+ a := StrToIntDef(P[1], 100);
+ chstr := b_Text_Format(chstr);
+ g_Game_Message(chstr, a);
+ if g_Game_IsNet and g_Game_IsServer then
+ MH_SEND_GameEvent(NET_EV_BIGTEXT, a, chstr);
+ end
+ else g_Console_Add('centerprint <timeout> <text>');
+ end
else if (cmd = 'overtime') and not g_Game_IsClient then
begin
if (Length(P) = 1) or (StrToIntDef(P[1], -1) <= 0) then
conRegVar('dbg_ignore_level_bounds', @g_dbg_ignore_bounds, 'ignore level bounds', '', false);
conRegVar('r_scale', @g_dbg_scale, 0.01, 100.0, 'render scale', '', false);
+ conRegVar('r_resolution_scale', @r_pixel_scale, 0.01, 100.0, 'upscale factor', '', false);
conRegVar('light_enabled', @gwin_k8_enable_light_experiments, 'enable/disable dynamic lighting', 'lighting');
conRegVar('light_player_halo', @g_playerLight, 'enable/disable player halo', 'player light halo');