X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fgame%2Fg_game.pas;h=726d37038339aa875cda8b0af270090a4ed78324;hb=92b319e1feed5079e42c779aa49b12ffa8672f54;hp=8444232487b70404ff6b6575e96c4778e65fa51e;hpb=fb8592aa898a8da05a47bfe50ff8272de4fdc995;p=d2df-sdl.git diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 8444232..726d370 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -22,7 +22,7 @@ uses SysUtils, Classes, MAPDEF, g_basic, g_player, e_graphics, g_res_downloader, - g_sound, g_gui, utils, md5, xprofiler; + g_sound, g_gui, utils, md5, mempool, xprofiler; type TGameSettings = record @@ -49,6 +49,12 @@ type DEStr: String; end; + TChatSound = record + Sound: TPlayableSound; + Tags: Array of String; + FullWord: Boolean; + end; + TPlayerSettings = record Name: String; Model: String; @@ -114,6 +120,7 @@ procedure g_Game_PauseAllSounds(Enable: Boolean); procedure g_Game_StopAllSounds(all: Boolean); procedure g_Game_UpdateTriggerSounds(); function g_Game_GetMegaWADInfo(WAD: String): TMegaWADInfo; +procedure g_Game_ChatSound(Text: String; Taunt: Boolean = True); procedure g_Game_Announce_GoodShot(SpawnerUID: Word); procedure g_Game_Announce_KillCombo(Param: Integer); procedure g_Game_StartVote(Command, Initiator: string); @@ -303,6 +310,10 @@ var gVotesEnabled: Boolean = True; gEvents: Array of TGameEvent; gDelayedEvents: Array of TDelayedEvent; + gUseChatSounds: Boolean = True; + gChatSounds: Array of TChatSound; + + g_dbg_ignore_bounds: Boolean = false; // move button values: // bits 0-1: l/r state: @@ -340,12 +351,17 @@ function gPause (): Boolean; inline; implementation uses +{$IFDEF USE_NANOGL} + nanoGL, +{$ELSE} + GL, GLExt, +{$ENDIF} e_texture, 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, g_monsters, e_sound, CONFIG, g_language, g_net, - ENet, e_msg, g_netmsg, g_netmaster, GL, GLExt, + ENet, e_msg, g_netmsg, g_netmaster, sfs, wadreader, g_holmes; @@ -545,6 +561,7 @@ var EndingGameCounter: Byte = 0; MessageText: String; MessageTime: Word; + MessageLineLength: Integer = 80; MapList: SSArray = nil; MapIndex: Integer = -1; MegaWAD: record @@ -1532,6 +1549,8 @@ var reliableUpdate: Boolean; begin g_ResetDynlights(); + framePool.reset(); + // Ïîðà âûêëþ÷àòü èãðó: if gExit = EXIT_QUIT then Exit; @@ -1973,6 +1992,7 @@ begin e_WriteLog('Changing resolution', TMsgType.Notify); g_Game_ChangeResolution(gRC_Width, gRC_Height, gRC_FullScreen, gRC_Maximized); gResolutionChange := False; + g_ActiveWindow := nil; end; // Íóæíî ñìåíèòü ÿçûê: @@ -2047,6 +2067,63 @@ begin end; end; +procedure g_Game_LoadChatSounds(Resource: string); +var + WAD: TWADFile; + FileName, Snd: string; + p: Pointer; + len, cnt, tags, i, j: Integer; + cfg: TConfig; +begin + FileName := g_ExtractWadName(Resource); + + WAD := TWADFile.Create(); + WAD.ReadFile(FileName); + + if not WAD.GetResource(g_ExtractFilePathName(Resource), p, len) then + begin + gChatSounds := nil; + WAD.Free(); + Exit; + end; + + cfg := TConfig.CreateMem(p, len); + cnt := cfg.ReadInt('ChatSounds', 'Count', 0); + + SetLength(gChatSounds, cnt); + for i := 0 to Length(gChatSounds) - 1 do + begin + gChatSounds[i].Sound := nil; + Snd := Trim(cfg.ReadStr(IntToStr(i), 'Sound', '')); + tags := cfg.ReadInt(IntToStr(i), 'Tags', 0); + if (Snd = '') or (Tags <= 0) then + continue; + g_Sound_CreateWADEx('SOUND_CHAT_MACRO' + IntToStr(i), GameWAD+':'+Snd); + gChatSounds[i].Sound := TPlayableSound.Create(); + gChatSounds[i].Sound.SetByName('SOUND_CHAT_MACRO' + IntToStr(i)); + SetLength(gChatSounds[i].Tags, tags); + for j := 0 to tags - 1 do + gChatSounds[i].Tags[j] := toLowerCase1251(cfg.ReadStr(IntToStr(i), 'Tag' + IntToStr(j), '')); + gChatSounds[i].FullWord := cfg.ReadBool(IntToStr(i), 'FullWord', False); + end; + + cfg.Free(); + WAD.Free(); +end; + +procedure g_Game_FreeChatSounds(); +var + i: Integer; +begin + for i := 0 to Length(gChatSounds) - 1 do + begin + gChatSounds[i].Sound.Free(); + g_Sound_Delete('SOUND_CHAT_MACRO' + IntToStr(i)); + end; + SetLength(gChatSounds, 0); + gChatSounds := nil; +end; + procedure g_Game_LoadData(); var wl, hl: Integer; @@ -2096,6 +2173,7 @@ begin end; g_Frames_CreateWAD(nil, 'FRAMES_TELEPORT', GameWAD+':TEXTURES\TELEPORT', 64, 64, 10, False); + g_Frames_CreateWAD(nil, 'FRAMES_PUNCH', GameWAD+':TEXTURES\PUNCH', 64, 64, 4, False); g_Sound_CreateWADEx('SOUND_GAME_TELEPORT', GameWAD+':SOUNDS\TELEPORT'); g_Sound_CreateWADEx('SOUND_GAME_NOTELEPORT', GameWAD+':SOUNDS\NOTELEPORT'); g_Sound_CreateWADEx('SOUND_GAME_DOOROPEN', GameWAD+':SOUNDS\DOOROPEN'); @@ -2136,6 +2214,8 @@ begin killsnd[2].SetByName('SOUND_ANNOUNCER_KILL4X'); killsnd[3].SetByName('SOUND_ANNOUNCER_KILLMX'); + g_Game_LoadChatSounds(GameWAD+':CHATSND\SNDCFG'); + g_Game_SetLoadingText(_lc[I_LOAD_ITEMS_DATA], 0, False); g_Items_LoadData(); @@ -2170,6 +2250,7 @@ begin g_Texture_Delete('TEXTURE_PLAYER_TALKBUBBLE'); g_Texture_Delete('TEXTURE_PLAYER_INVULPENTA'); g_Frames_DeleteByName('FRAMES_TELEPORT'); + g_Frames_DeleteByName('FRAMES_PUNCH'); g_Sound_Delete('SOUND_GAME_TELEPORT'); g_Sound_Delete('SOUND_GAME_NOTELEPORT'); g_Sound_Delete('SOUND_GAME_DOOROPEN'); @@ -2201,6 +2282,8 @@ begin g_Sound_Delete('SOUND_ANNOUNCER_KILL4X'); g_Sound_Delete('SOUND_ANNOUNCER_KILLMX'); + g_Game_FreeChatSounds(); + DataLoaded := False; end; @@ -2924,8 +3007,11 @@ begin * glBlendFunc(GL_DST_ALPHA, GL_ONE); * draw all geometry up to and including walls (with alpha-testing, probably) -- this does lighting *) - +{$IFDEF USE_NANOGL} + wassc := false; // FIXIT +{$ELSE} wassc := (glIsEnabled(GL_SCISSOR_TEST) <> 0); +{$ENDIF} if wassc then glGetIntegerv(GL_SCISSOR_BOX, @scxywh[0]) else glGetIntegerv(GL_VIEWPORT, @scxywh[0]); // setup OpenGL parameters @@ -3176,7 +3262,7 @@ begin px := p.GameX + PLAYER_RECT_CX; py := p.GameY + PLAYER_RECT_CY+p.Obj.slopeUpLeft; - if (g_dbg_scale = 1.0) then + if (g_dbg_scale = 1.0) and (not g_dbg_ignore_bounds) then begin 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; @@ -3254,6 +3340,16 @@ begin //conwritefln('OLD: (%s,%s)-(%s,%s)', [sX, sY, sWidth, sHeight]); fixViewportForScale(); //conwritefln(' (%s,%s)-(%s,%s)', [sX, sY, sWidth, sHeight]); + if (g_dbg_scale <> 1.0) and (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; p.viewPortX := sX; p.viewPortY := sY; p.viewPortW := sWidth; @@ -3678,7 +3774,7 @@ begin g_PlayerModel_FreeData(); g_Texture_DeleteAll(); g_Frames_DeleteAll(); - g_Menu_Free(); + //g_Menu_Free(); //k8: this segfaults after resolution change; who cares? if NetInitDone then g_Net_Free; @@ -4120,6 +4216,10 @@ begin gPlayer2.Name := gPlayer2Settings.Name; end; + g_Game_SetLoadingText(_lc[I_LOAD_HOST], 0, False); + if NetForwardPorts then + g_Game_SetLoadingText(_lc[I_LOAD_PORTS], 0, False); + // Ñòàðòóåì ñåðâåð if not g_Net_Host(IPAddr, Port, NetMaxClients) then begin @@ -6884,10 +6984,76 @@ end; procedure g_Game_Message(Msg: string; Time: Word); begin - MessageText := b_Text_Format(Msg); + MessageLineLength := (gScreenWidth - 204) div e_CharFont_GetMaxWidth(gMenuFont); + MessageText := b_Text_Wrap(b_Text_Format(Msg), MessageLineLength); MessageTime := Time; end; +procedure g_Game_ChatSound(Text: String; Taunt: Boolean = True); +const + punct: Array[0..13] of String = + ('.', ',', ':', ';', '!', '?', '(', ')', '''', '"', '/', '\', '*', '^'); +var + i, j: Integer; + ok: Boolean; + fpText: String; + + function IsPunctuation(S: String): Boolean; + var + i: Integer; + begin + Result := False; + if Length(S) <> 1 then + Exit; + for i := Low(punct) to High(punct) do + if S = punct[i] then + begin + Result := True; + break; + end; + end; + function FilterPunctuation(S: String): String; + var + i: Integer; + begin + for i := Low(punct) to High(punct) do + S := StringReplace(S, punct[i], ' ', [rfReplaceAll]); + Result := S; + end; +begin + ok := False; + + if gUseChatSounds and Taunt and (gChatSounds <> nil) and (Pos(': ', Text) > 0) then + begin + // remove player name + Delete(Text, 1, Pos(': ', Text) + 2 - 1); + // for FullWord check + Text := toLowerCase1251(' ' + Text + ' '); + fpText := FilterPunctuation(Text); + + for i := 0 to Length(gChatSounds) - 1 do + begin + ok := True; + for j := 0 to Length(gChatSounds[i].Tags) - 1 do + begin + if gChatSounds[i].FullWord and (not IsPunctuation(gChatSounds[i].Tags[j])) then + ok := Pos(' ' + gChatSounds[i].Tags[j] + ' ', fpText) > 0 + else + ok := Pos(gChatSounds[i].Tags[j], Text) > 0; + if not ok then + break; + end; + if ok then + begin + gChatSounds[i].Sound.Play(); + break; + end; + end; + end; + if not ok then + g_Sound_PlayEx('SOUND_GAME_RADIO'); +end; + procedure g_Game_Announce_GoodShot(SpawnerUID: Word); var a: Integer; @@ -7387,7 +7553,9 @@ begin conRegVar('dbg_holmes', @g_holmes_enabled, 'enable/disable Holmes', 'Holmes', true); - conRegVar('dbg_scale', @g_dbg_scale, 0.01, 100.0, 'experimental deBUG scale mode', '', false); + 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('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');