X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_game.pas;h=3be96517735e7b8f12b98fe79a453dadde11c3e2;hb=254041134b399e948e554ae99171174a7087ae40;hp=93368940da0d943a1223f77191f923c7432b5bfd;hpb=b7ff38d281991866c467f65974df53b305711281;p=d2df-sdl.git diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 9336894..3be9651 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -20,7 +20,7 @@ interface uses g_basic, g_player, e_graphics, Classes, g_res_downloader, - SysUtils, g_sound, g_gui, MAPSTRUCT, wadreader, md5, xprofiler; + SysUtils, g_sound, g_gui, MAPDEF, wadreader, md5, xprofiler; type TGameSettings = record @@ -63,14 +63,14 @@ type THearPoint = record Active: Boolean; - Coords: TPoint; + Coords: TDFPoint; end; function g_Game_IsNet(): Boolean; function g_Game_IsServer(): Boolean; function g_Game_IsClient(): Boolean; procedure g_Game_Init(); -procedure g_Game_Free(); +procedure g_Game_Free (freeTextures: Boolean=true); procedure g_Game_LoadData(); procedure g_Game_FreeData(); procedure g_Game_Update(); @@ -95,7 +95,7 @@ procedure g_Game_RestartLevel(); procedure g_Game_RestartRound(NoMapRestart: Boolean = False); procedure g_Game_ClientWAD(NewWAD: String; WHash: TMD5Digest); procedure g_Game_SaveOptions(); -function g_Game_StartMap(Map: String; Force: Boolean = False): Boolean; +function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean; procedure g_Game_ChangeMap(MapPath: String); procedure g_Game_ExitLevel(Map: Char16); function g_Game_GetFirstMap(WAD: String): String; @@ -209,9 +209,9 @@ var gPlayer1Settings: TPlayerSettings; gPlayer2Settings: TPlayerSettings; gGameOn: Boolean; - gPlayerScreenSize: TPoint; - gPlayer1ScreenCoord: TPoint; - gPlayer2ScreenCoord: TPoint; + gPlayerScreenSize: TDFPoint; + gPlayer1ScreenCoord: TDFPoint; + gPlayer2ScreenCoord: TDFPoint; gPlayer1: TPlayer = nil; gPlayer2: TPlayer = nil; gPlayerDrawn: TPlayer = nil; @@ -324,6 +324,8 @@ var g_rlayer_water: Boolean = true; g_rlayer_fore: Boolean = true; + g_dbg_scale: Single = 1.0; + procedure g_ResetDynlights (); procedure g_AddDynLight (x, y, radius: Integer; r, g, b, a: Single); @@ -338,7 +340,7 @@ uses g_textures, g_main, g_window, g_menu, e_input, e_log, g_console, g_items, g_map, g_panel, g_playermodel, g_gfx, g_options, g_weapons, Math, - g_triggers, MAPDEF, g_monsters, e_sound, CONFIG, + g_triggers, g_monsters, e_sound, CONFIG, BinEditor, g_language, g_net, SDL, ENet, e_msg, g_netmsg, g_netmaster, GL, GLExt, utils, sfs, g_holmes; @@ -792,7 +794,7 @@ begin {$IF DEFINED(D2F_DEBUG)} if gPlayer1 <> nil then gPlayer1.NoTarget := True; - gAimLine := true; + gAimLine := g_dbg_aimline_on; {$ENDIF} end; @@ -1297,12 +1299,12 @@ begin end; end; -procedure g_Game_Free(); +procedure g_Game_Free(freeTextures: Boolean=true); begin if NetMode = NET_CLIENT then g_Net_Disconnect(); if NetMode = NET_SERVER then g_Net_Host_Die(); - g_Map_Free(); + g_Map_Free(freeTextures); g_Player_Free(); g_Player_RemoveAllCorpses(); @@ -1485,20 +1487,30 @@ var function sendMonsPos (mon: TMonster): Boolean; begin result := false; // don't stop - if (mon.MonsterType = MONSTER_BARREL) then + // this will also reset "need-send" flag + if mon.gncNeedSend then + begin + MH_SEND_MonsterPos(mon.UID); + end + else if (mon.MonsterType = MONSTER_BARREL) then begin if (mon.GameVelX <> 0) or (mon.GameVelY <> 0) then MH_SEND_MonsterPos(mon.UID); end - else - if (mon.MonsterState <> MONSTATE_SLEEP) then - begin - if (mon.MonsterState <> MONSTATE_DEAD) or (mon.GameVelX <> 0) or (mon.GameVelY <> 0) then - begin - MH_SEND_MonsterPos(mon.UID); - end; - end; + else if (mon.MonsterState <> MONSTATE_SLEEP) then + begin + if (mon.MonsterState <> MONSTATE_DEAD) or (mon.GameVelX <> 0) or (mon.GameVelY <> 0) then MH_SEND_MonsterPos(mon.UID); + end; end; + function sendMonsPosUnexpected (mon: TMonster): Boolean; + begin + result := false; // don't stop + // this will also reset "need-send" flag + if mon.gncNeedSend then MH_SEND_MonsterPos(mon.UID); + end; + +var + reliableUpdate: Boolean; begin g_ResetDynlights(); // Ïîðà âûêëþ÷àòü èãðó: @@ -1842,13 +1854,16 @@ begin g_GFX_Update(); g_Player_UpdateAll(); g_Player_UpdatePhysicalObjects(); - if gGameSettings.GameType = GT_SERVER then - if Length(gMonstersSpawned) > 0 then + + // server: send newly spawned monsters unconditionally + if (gGameSettings.GameType = GT_SERVER) then + begin + if (Length(gMonstersSpawned) > 0) then begin - for I := 0 to High(gMonstersSpawned) do - MH_SEND_MonsterSpawn(gMonstersSpawned[I]); + for I := 0 to High(gMonstersSpawned) do MH_SEND_MonsterSpawn(gMonstersSpawned[I]); SetLength(gMonstersSpawned, 0); end; + end; if (gSoundTriggerTime > 8) then begin @@ -1856,49 +1871,65 @@ begin gSoundTriggerTime := 0; end else + begin Inc(gSoundTriggerTime); + end; if (NetMode = NET_SERVER) then begin Inc(NetTimeToUpdate); Inc(NetTimeToReliable); - if NetTimeToReliable >= NetRelupdRate then + + // send monster updates + if (NetTimeToReliable >= NetRelupdRate) or (NetTimeToUpdate >= NetUpdateRate) then begin + // send all monsters (periodic sync) + reliableUpdate := (NetTimeToReliable >= NetRelupdRate); + for I := 0 to High(gPlayers) do - if gPlayers[I] <> nil then - MH_SEND_PlayerPos(True, gPlayers[I].UID); + begin + if (gPlayers[I] <> nil) then MH_SEND_PlayerPos(reliableUpdate, gPlayers[I].UID); + end; g_Mons_ForEach(sendMonsPos); - NetTimeToReliable := 0; - NetTimeToUpdate := NetUpdateRate; + if reliableUpdate then + begin + NetTimeToReliable := 0; + NetTimeToUpdate := NetUpdateRate; + end + else + begin + NetTimeToUpdate := 0; + end; end - else if NetTimeToUpdate >= NetUpdateRate then + else begin - if gPlayers <> nil then - for I := 0 to High(gPlayers) do - if gPlayers[I] <> nil then - MH_SEND_PlayerPos(False, gPlayers[I].UID); - - g_Mons_ForEach(sendMonsPos); - - NetTimeToUpdate := 0; + // send only mosters with some unexpected changes + g_Mons_ForEach(sendMonsPosUnexpected); end; + // send unexpected platform changes + g_Map_NetSendInterestingPanels(); + if NetUseMaster then + begin if gTime >= NetTimeToMaster then begin if (NetMHost = nil) or (NetMPeer = nil) then - if not g_Net_Slist_Connect then - g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]); + begin + if not g_Net_Slist_Connect then g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]); + end; g_Net_Slist_Update; NetTimeToMaster := gTime + NetMasterRate; end; + end; end - else - if NetMode = NET_CLIENT then - MC_SEND_PlayerPos(); + else if (NetMode = NET_CLIENT) then + begin + MC_SEND_PlayerPos(); + end; end; // if gameOn ... // Àêòèâíî îêíî èíòåðôåéñà - ïåðåäàåì êëàâèøè åìó: @@ -2009,12 +2040,12 @@ begin g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDJET', GameWAD+':TEXTURES\JETBAR'); g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDBG', GameWAD+':TEXTURES\HUDBG'); g_Texture_CreateWADEx('TEXTURE_PLAYER_ARMORHUD', GameWAD+':TEXTURES\ARMORHUD'); - g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG', GameWAD+':TEXTURES\FLAGHUD_RB'); - g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_S', GameWAD+':TEXTURES\FLAGHUD_RS'); - g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_D', GameWAD+':TEXTURES\FLAGHUD_RD'); - g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG', GameWAD+':TEXTURES\FLAGHUD_BB'); - g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_S', GameWAD+':TEXTURES\FLAGHUD_BS'); - g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_D', GameWAD+':TEXTURES\FLAGHUD_BD'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG', GameWAD+':TEXTURES\FLAGHUD_RB', GameWAD+':TEXTURES\FLAGHUD_R_BASE'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_S', GameWAD+':TEXTURES\FLAGHUD_RS', GameWAD+':TEXTURES\FLAGHUD_R_STOLEN'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_D', GameWAD+':TEXTURES\FLAGHUD_RD', GameWAD+':TEXTURES\FLAGHUD_R_DROP'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG', GameWAD+':TEXTURES\FLAGHUD_BB', GameWAD+':TEXTURES\FLAGHUD_B_BASE'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_S', GameWAD+':TEXTURES\FLAGHUD_BS', GameWAD+':TEXTURES\FLAGHUD_B_STOLEN'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_D', GameWAD+':TEXTURES\FLAGHUD_BD', GameWAD+':TEXTURES\FLAGHUD_B_DROP'); g_Texture_CreateWADEx('TEXTURE_PLAYER_TALKBUBBLE', GameWAD+':TEXTURES\TALKBUBBLE'); g_Texture_CreateWADEx('TEXTURE_PLAYER_INVULPENTA', GameWAD+':TEXTURES\PENTA'); g_Frames_CreateWAD(nil, 'FRAMES_TELEPORT', GameWAD+':TEXTURES\TELEPORT', 64, 64, 10, False); @@ -2493,7 +2524,7 @@ var result := false; // don't stop with mon do begin - if Live then + if alive then begin // Ëåâûé âåðõíèé óãîë aX := Obj.X div ScaleSz + 1; @@ -2656,7 +2687,7 @@ begin // Ðèñóåì èãðîêîâ: for a := 0 to High(gPlayers) do if gPlayers[a] <> nil then with gPlayers[a] do - if Live then begin + if alive then begin // Ëåâûé âåðõíèé óãîë: aX := Obj.X div ScaleSz + 1; aY := Obj.Y div ScaleSz + 1; @@ -2794,7 +2825,14 @@ begin profileFrameDraw.sectionBegin('collect'); if gdbg_map_use_accel_render then begin - g_Map_CollectDrawPanels(sX, sY, sWidth, sHeight); + if (g_dbg_scale <> 1.0) then + begin + g_Map_CollectDrawPanels(sX, sY, round(sWidth/g_dbg_scale)+1, round(sHeight/g_dbg_scale)+1); + end + else + begin + g_Map_CollectDrawPanels(sX, sY, sWidth, sHeight); + end; end; profileFrameDraw.sectionEnd(); @@ -2802,7 +2840,11 @@ begin g_Map_DrawBack(backXOfs, backYOfs); profileFrameDraw.sectionEnd(); - if (setTransMatrix) then glTranslatef(transX, transY, 0); + if setTransMatrix then + begin + glScalef(g_dbg_scale, g_dbg_scale, 1.0); + glTranslatef(transX, transY, 0); + end; drawPanelType('*back', PANEL_BACK, g_rlayer_back); drawPanelType('*step', PANEL_STEP, g_rlayer_step); @@ -2857,7 +2899,6 @@ procedure DrawPlayer(p: TPlayer); var px, py, a, b, c, d: Integer; //R: TRect; - begin if (p = nil) or (p.FDummy) then begin @@ -2875,7 +2916,7 @@ begin glPushMatrix(); px := p.GameX + PLAYER_RECT_CX; - py := p.GameY + PLAYER_RECT_CY; + py := p.GameY + PLAYER_RECT_CY+p.Obj.slopeUpLeft; if px > (gPlayerScreenSize.X div 2) then a := -px+(gPlayerScreenSize.X div 2) else a := 0; if py > (gPlayerScreenSize.Y div 2) then b := -py+(gPlayerScreenSize.Y div 2) else b := 0; @@ -3211,16 +3252,26 @@ begin begin if (gState = STATE_MENU) then begin - if ((g_ActiveWindow = nil) or (g_ActiveWindow.BackTexture = '')) then + if (g_ActiveWindow = nil) or (g_ActiveWindow.BackTexture = '') then begin - if g_Texture_Get('MENU_BACKGROUND', ID) then - e_DrawSize(ID, 0, 0, 0, False, False, gScreenWidth, gScreenHeight) + if g_Texture_Get('MENU_BACKGROUND', ID) then e_DrawSize(ID, 0, 0, 0, False, False, gScreenWidth, gScreenHeight) else e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0); end; - if g_ActiveWindow <> nil then + // F3 at menu will show game loading dialog + if e_KeyPressed(IK_F3) then g_Menu_Show_LoadMenu(true); + if (g_ActiveWindow <> nil) then begin //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + end + else + begin + // F3 at titlepic will show game loading dialog + if e_KeyPressed(IK_F3) then + begin + g_Menu_Show_LoadMenu(true); + if (g_ActiveWindow <> nil) then e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + end; end; end; @@ -3971,7 +4022,7 @@ begin end; end; - ProcessLoading(); + ProcessLoading(true); e_PollInput(); @@ -4031,15 +4082,15 @@ begin MessageTime := 0; gGameOn := False; g_Game_ClearLoading(); - g_Game_StartMap(Map, True); + g_Game_StartMap(Map, True, gCurrentMapFileName); end; -function g_Game_StartMap(Map: String; Force: Boolean = False): Boolean; +function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean; var NewWAD, ResName: String; I: Integer; begin - g_Map_Free(); + g_Map_Free((Map <> gCurrentMapFileName) and (oldMapPath <> gCurrentMapFileName)); g_Player_RemoveAllCorpses(); if (not g_Game_IsClient) and @@ -5017,7 +5068,7 @@ procedure DebugCommands(P: SArray); var a, b: Integer; cmd: string; - //pt: TPoint; + //pt: TDFPoint; mon: TMonster; begin // Êîìàíäû îòëàäî÷íîãî ðåæèìà: @@ -5078,18 +5129,18 @@ begin end else if cmd = 'd_monster' then begin - if gGameOn and (gPlayer1 <> nil) and (gPlayer1.Live) and (not g_Game_IsNet) then + if gGameOn and (gPlayer1 <> nil) and (gPlayer1.alive) and (not g_Game_IsNet) then if Length(P) < 2 then begin g_Console_Add(cmd + ' [ID | Name] [behaviour]'); g_Console_Add('ID | Name'); for b := MONSTER_DEMON to MONSTER_MAN do - g_Console_Add(Format('%2d | %s', [b, g_Monsters_GetNameByID(b)])); + g_Console_Add(Format('%2d | %s', [b, g_Mons_NameByTypeId(b)])); end else begin a := StrToIntDef(P[1], 0); if (a < MONSTER_DEMON) or (a > MONSTER_MAN) then - a := g_Monsters_GetIDByName(P[1]); + a := g_Mons_TypeIdByName(P[1]); if (a < MONSTER_DEMON) or (a > MONSTER_MAN) then g_Console_Add(Format(_lc[I_MSG_NO_MONSTER], [P[1]])) @@ -5179,7 +5230,8 @@ begin begin g_Console_Add('player left the map'); gExitByTrigger := True; - g_Game_ExitLevel(gTriggers[a].Data.MapName); + //g_Game_ExitLevel(gTriggers[a].Data.MapName); + g_Game_ExitLevel(gTriggers[a].trigData.trigMapName); break; end; end; @@ -6048,7 +6100,8 @@ begin if gTriggers[a].TriggerType = TRIGGER_EXIT then begin gExitByTrigger := True; - gNextMap := gTriggers[a].Data.MapName; + //gNextMap := gTriggers[a].Data.MapName; + gNextMap := gTriggers[a].trigData.trigMapName; Break; end; // Èùåì ñëåäóþùóþ êàðòó â WAD ôàéëå @@ -6101,6 +6154,21 @@ begin Exit; end; end + else if cmd = 'suicide' then + begin + if gGameOn then + begin + if g_Game_IsClient then + MC_SEND_CheatRequest(NET_CHEAT_SUICIDE) + else + begin + if gPlayer1 <> nil then + gPlayer1.Damage(SUICIDE_DAMAGE, gPlayer1.UID, 0, 0, HIT_SELF); + if gPlayer2 <> nil then + gPlayer2.Damage(SUICIDE_DAMAGE, gPlayer2.UID, 0, 0, HIT_SELF); + end; + end; + end // Êîìàíäû Ñâîåé èãðû: else if gGameSettings.GameType in [GT_CUSTOM, GT_SERVER, GT_CLIENT] then begin @@ -6118,21 +6186,6 @@ begin else g_Bot_Add(TEAM_BLUE, 2); end - else if cmd = 'suicide' then - begin - if gGameOn then - begin - if g_Game_IsClient then - MC_SEND_CheatRequest(NET_CHEAT_SUICIDE) - else - begin - if gPlayer1 <> nil then - gPlayer1.Damage(SUICIDE_DAMAGE, gPlayer1.UID, 0, 0, HIT_SELF); - if gPlayer2 <> nil then - gPlayer2.Damage(SUICIDE_DAMAGE, gPlayer2.UID, 0, 0, HIT_SELF); - end; - end; - end else if cmd = 'spectate' then begin if not gGameOn then @@ -6439,17 +6492,17 @@ begin with gTriggers[i] do if (TriggerType = TRIGGER_SOUND) and (Sound <> nil) and - (Data.Local) and + (trigData.trigLocal) and Sound.IsPlaying() then begin if ((gPlayer1 <> nil) and g_CollidePoint(gPlayer1.GameX, gPlayer1.GameY, X, Y, Width, Height)) or ((gPlayer2 <> nil) and g_CollidePoint(gPlayer2.GameX, gPlayer2.GameY, X, Y, Width, Height)) then begin - Sound.SetPan(0.5 - Data.Pan/255.0); - Sound.SetVolume(Data.Volume/255.0); + Sound.SetPan(0.5 - trigData.trigPan/255.0); + Sound.SetVolume(trigData.trigVolume/255.0); end else - Sound.SetCoords(X+(Width div 2), Y+(Height div 2), Data.Volume/255.0); + Sound.SetCoords(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0); end; end; @@ -6737,7 +6790,7 @@ begin g_ActiveWindow := nil; - ProcessLoading; + ProcessLoading(true); end; procedure g_Game_StepLoading(); @@ -6749,7 +6802,7 @@ begin if (ShowCount > LOADING_SHOW_STEP) then begin ShowCount := 0; - ProcessLoading; + ProcessLoading(); end; end; end; @@ -7011,4 +7064,6 @@ begin conRegVar('mon_think', @gmon_debug_think, 'enable/disable monster thinking', 'monster thinking', true); conRegVar('dbg_holmes', @g_holmes_enabled, 'enable/disable Holmes', 'Holmes', true); + + conRegVar('dbg_scale', @g_dbg_scale, 0.01, 5.0, 'experimental deBUG scale mode', '', true); end.