X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=d9dd8871a953815a003809dbeacb6d231539f1e7;hb=6820eae460a9c99136ab5e679ffe2f6236c3540f;hp=b99c03dd7533081b58204981872a584b8f55a46a;hpb=5c84a2c9f706bc450a00bda4f7d2afc858ce75b0;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index b99c03d..d9dd887 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -2,8 +2,7 @@ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -268,7 +267,9 @@ type FReady: Boolean; FDummy: Boolean; FFireTime: Integer; + FSpawnInvul: Integer; FHandicap: Integer; + FWaitForFirstSpawn: Boolean; // set to `true` in server, used to spawn a player on first full state request // debug: viewport offset viewPortX, viewPortY, viewPortW, viewPortH: Integer; @@ -283,6 +284,7 @@ type procedure ReleaseKeys(); procedure SetModel(ModelName: String); procedure SetColor(Color: TRGB); + function GetColor(): TRGB; procedure SetWeapon(W: Byte); function IsKeyPressed(K: Byte): Boolean; function GetKeys(): Byte; @@ -320,7 +322,7 @@ type procedure DrawPickup(); procedure DrawRulez(); procedure DrawAim(); - procedure DrawIndicator(); + procedure DrawIndicator(Color: TRGB); procedure DrawBubble(); procedure DrawGUI(); procedure Update(); virtual; @@ -554,11 +556,12 @@ var gTeamStat: TTeamStat; gFly: Boolean = False; gAimLine: Boolean = False; - gChatBubble: Byte = 0; - gPlayerIndicator: Boolean = True; + gChatBubble: Integer = 0; + gPlayerIndicator: Integer = 1; + gPlayerIndicatorStyle: Integer = 0; gNumBots: Word = 0; - gLMSPID1: Word = 0; - gLMSPID2: Word = 0; + gSpectLatchPID1: Word = 0; + gSpectLatchPID2: Word = 0; MAX_RUNVEL: Integer = 8; VEL_JUMP: Integer = 10; SHELL_TIMEOUT: Cardinal = 60000; @@ -611,7 +614,7 @@ uses g_holmes, {$ENDIF} e_log, g_map, g_items, g_console, g_gfx, Math, - g_options, g_triggers, g_menu, g_game, g_grid, + g_options, g_triggers, g_menu, g_game, g_grid, e_res, wadreader, g_main, g_monsters, CONFIG, g_language, g_net, g_netmsg, g_window, utils, xstreams; @@ -1069,12 +1072,6 @@ begin Break; end; -// Èìåíè íåò, çàäàåì ñëó÷àéíîå: - if _name = '' then - repeat - _name := Format('DFBOT%.2d', [Random(100)]); - until g_Player_ValidName(_name); - // Âûáèðàåì ñëó÷àéíóþ ìîäåëü: _model := m[Random(Length(m))]; @@ -1085,7 +1082,11 @@ begin Min(Random(9)*32, 255)), Team, True)) as TBot do begin - Name := _name; + // Åñëè èìåíè íåò, äåëàåì åãî èç UID áîòà + if _name = '' then + Name := Format('DFBOT%.5d', [UID]) + else + Name := _name; case Difficult of 1: FDifficult := DIFFICULT_EASY; @@ -1252,14 +1253,16 @@ var a, b: Integer; config: TConfig; sa: SSArray; + path: AnsiString; begin BotNames := nil; - if not FileExists(DataDir + BOTNAMES_FILENAME) then + path := BOTNAMES_FILENAME; + if e_FindResource(DataDirs, path) = false then Exit; // ×èòàåì âîçìîæíûå èìåíà áîòîâ èç ôàéëà: - AssignFile(F, DataDir + BOTNAMES_FILENAME); + AssignFile(F, path); Reset(F); while not EOF(F) do @@ -1280,7 +1283,7 @@ begin g_Bot_MixNames(); // ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ: - config := TConfig.CreateFile(DataDir + BOTLIST_FILENAME); + config := TConfig.CreateFile(path); BotList := nil; a := 0; @@ -2035,6 +2038,11 @@ begin if FModel <> nil then FModel.Color := Color; end; +function TPlayer.GetColor(): TRGB; +begin + result := FModel.Color; +end; + procedure TPlayer.SwitchTeam; begin if g_Game_IsClient then @@ -2172,6 +2180,8 @@ begin FJustTeleported := False; FNetTime := 0; + FWaitForFirstSpawn := false; + resetWeaponQueue(); end; @@ -2218,6 +2228,7 @@ begin FMegaRulez[MR_SUIT] := 0; FMegaRulez[MR_INVUL] := 0; FMegaRulez[MR_INVIS] := 0; + FSpawnInvul := 0; FBerserk := 0; end; @@ -2322,23 +2333,72 @@ begin inherited; end; -procedure TPlayer.DrawIndicator(); +procedure TPlayer.DrawIndicator(Color: TRGB); var indX, indY: Integer; indW, indH: Word; + indA: Single; + a: TDFPoint; + nW, nH: Byte; ID: DWORD; + c: TRGB; begin if FAlive then - begin - if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then + case gPlayerIndicatorStyle of + 0: + begin + if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then + begin + e_GetTextureSize(ID, @indW, @indH); + a.X := indW div 2; + a.Y := indH div 2; + + if (FObj.X + FObj.Rect.X) < 0 then + begin + indA := 90; + indX := FObj.X + FObj.Rect.X + FObj.Rect.Width; + indY := FObj.Y + FObj.Rect.Y + (FObj.Rect.Height - indW) div 2; + end + + else if (FObj.X + FObj.Rect.X + FObj.Rect.Width) > Max(gMapInfo.Width, gPlayerScreenSize.X) then + begin + indA := 270; + indX := FObj.X + FObj.Rect.X - indH; + indY := FObj.Y + FObj.Rect.Y + (FObj.Rect.Height - indW) div 2; + end + + else if (fObj.Y - indH) < 0 then + begin + indA := 180; + indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2; + indY := FObj.Y + FObj.Rect.Y + FObj.Rect.Height; + end + + else + begin + indA := 0; + indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2; + indY := FObj.Y - indH; + end; + + indX := EnsureRange(indX, 0, Max(gMapInfo.Width, gPlayerScreenSize.X) - indW); + indY := EnsureRange(indY, 0, Max(gMapInfo.Height, gPlayerScreenSize.Y) - indH); + + c := e_Colors; + e_Colors := Color; + e_DrawAdv(ID, indX, indY, 0, True, False, indA, @a); + e_Colors := c; + end; + end; + + 1: begin - e_GetTextureSize(ID, @indW, @indH); - indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2; - indY := FObj.Y; - e_Draw(ID, indX, indY - indH, 0, True, False); + e_TextureFontGetSize(gStdFont, nW, nH); + indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - Length(FName) * nW) div 2; + indY := FObj.Y - nH; + e_TextureFontPrintEx(indX, indY, FName, gStdFont, Color.R, Color.G, Color.B, 1.0, True); end; end; - //e_TextureFontPrint(indX, indY, FName, gStdFont); // Shows player name overhead end; procedure TPlayer.DrawBubble(); @@ -2447,7 +2507,7 @@ begin end; end; - if (FMegaRulez[MR_INVUL] > gTime) and (gPlayerDrawn <> Self) then + if (FMegaRulez[MR_INVUL] > gTime) and ((gPlayerDrawn <> Self) or (FSpawnInvul >= gTime)) then if g_Texture_Get('TEXTURE_PLAYER_INVULPENTA', ID) then begin e_GetTextureSize(ID, @w, @h); @@ -2706,7 +2766,14 @@ begin e_CharFont_PrintEx(gMenuSmallFont, X-16-tw, Y+32, s, _RGB(255, 0, 0)); end; - if gShowLives and (gGameSettings.MaxLives > 0) then + if gLMSRespawn = LMS_RESPAWN_WARMUP then + begin + s := _lc[I_GAME_WARMUP]; + e_CharFont_GetSize(gMenuFont, s, tw, th); + s := s + ': ' + IntToStr((gLMSRespawnTime - gTime) div 1000); + e_CharFont_PrintEx(gMenuFont, X-64-tw, SY-32, s, _RGB(0, 255, 0)); + end + else if gShowLives and (gGameSettings.MaxLives > 0) then begin s := IntToStr(Lives); e_CharFont_GetSize(gMenuFont, s, tw, th); @@ -2815,7 +2882,7 @@ var dr: Boolean; begin // Ïðè âçÿòèè íåóÿçâèìîñòè ðèñóåòñÿ èíâåðñèîííûé áåëûé ôîí - if FMegaRulez[MR_INVUL] >= gTime then + if (FMegaRulez[MR_INVUL] >= gTime) and (FSpawnInvul < gTime) then begin if (FMegaRulez[MR_INVUL]-gTime) <= 2100 then dr := not Odd((FMegaRulez[MR_INVUL]-gTime) div 300) @@ -3197,6 +3264,8 @@ begin exit; if (FMegaRulez[MR_SUIT] > gTime) or (FMegaRulez[MR_INVUL] > gTime) then exit; // Íå çàãîðàåìñÿ êîãäà åñòü çàùèòà + if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then + exit; // Íå ïîäãîðàåì â âîäå íà âñÿêèé ñëó÷àé if FFireTime <= 0 then g_Sound_PlayExAt('SOUND_IGNITE', FObj.X, FObj.Y); FFireTime := Timeout; @@ -3477,7 +3546,8 @@ begin PushItem(ITEM_JETPACK); // Âûáðîñ êëþ÷åé: - if not (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) then + if (not (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF])) or + (not LongBool(gGameSettings.Options and GAME_OPTION_DMKEYS)) then begin if R_KEY_RED in FRulez then PushItem(ITEM_KEY_RED); @@ -3597,7 +3667,7 @@ begin if srv and (OldLR = LMS_RESPAWN_NONE) and (gLMSRespawn > LMS_RESPAWN_NONE) then begin if NetMode = NET_SERVER then - MH_SEND_GameEvent(NET_EV_LMS_WARMUP, (gLMSRespawnTime - gTime) div 1000) + MH_SEND_GameEvent(NET_EV_LMS_WARMUP, gLMSRespawnTime - gTime) else g_Console_Add(Format(_lc[I_MSG_WARMUP_START], [(gLMSRespawnTime - gTime) div 1000]), True); end; @@ -3664,8 +3734,8 @@ begin result := false; case weapon of WEAPON_KASTET, WEAPON_SAW: result := true; - WEAPON_SHOTGUN1, WEAPON_SHOTGUN2: result := (FAmmo[A_SHELLS] > 0); - WEAPON_PISTOL, WEAPON_CHAINGUN, WEAPON_SUPERPULEMET: result := (FAmmo[A_BULLETS] > 0); + WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_SUPERPULEMET: result := (FAmmo[A_SHELLS] > 0); + WEAPON_PISTOL, WEAPON_CHAINGUN: result := (FAmmo[A_BULLETS] > 0); WEAPON_ROCKETLAUNCHER: result := (FAmmo[A_ROCKETS] > 0); WEAPON_PLASMA, WEAPON_BFG: result := (FAmmo[A_CELLS] > 0); WEAPON_FLAMETHROWER: result := (FAmmo[A_FUEL] > 0); @@ -4217,6 +4287,7 @@ begin if FMegaRulez[MR_INVUL] < gTime+PLAYER_INVUL_TIME then begin FMegaRulez[MR_INVUL] := gTime+PLAYER_INVUL_TIME; + FSpawnInvul := 0; Result := True; remove := True; if gFlash = 2 then Inc(FPickup, 5); @@ -4302,6 +4373,7 @@ begin FMonsterKills := 0; FDeath := 0; FSecrets := 0; + FSpawnInvul := 0; FReady := False; if FNoRespawn then begin @@ -4494,6 +4566,7 @@ begin FShellTimer := -1; FPain := 0; FLastHit := 0; + FSpawnInvul := 0; if not g_Game_IsServer then Exit; @@ -4572,7 +4645,8 @@ begin FMaxAmmo[A_CELLS] := AmmoLimits[0, A_CELLS]; FMaxAmmo[A_FUEL] := AmmoLimits[0, A_FUEL]; - if gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF] then + if (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) and + LongBool(gGameSettings.Options and GAME_OPTION_DMKEYS) then FRulez := [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE] else FRulez := []; @@ -4608,6 +4682,13 @@ begin for a := Low(FMegaRulez) to High(FMegaRulez) do FMegaRulez[a] := 0; +// Respawn invulnerability + if (gGameSettings.GameType <> GT_SINGLE) and (gGameSettings.SpawnInvul > 0) then + begin + FMegaRulez[MR_INVUL] := gTime + gGameSettings.SpawnInvul * 1000; + FSpawnInvul := FMegaRulez[MR_INVUL]; + end; + FDamageBuffer := 0; FJetpack := False; FCanJetpack := False; @@ -4632,9 +4713,9 @@ begin FSpectatePlayer := -1; FSpawned := True; - if (gPlayer1 = nil) and (gLMSPID1 = FUID) then + if (gPlayer1 = nil) and (gSpectLatchPID1 = FUID) then gPlayer1 := self; - if (gPlayer2 = nil) and (gLMSPID2 = FUID) then + if (gPlayer2 = nil) and (gSpectLatchPID2 = FUID) then gPlayer2 := self; if g_Game_IsNet then @@ -4671,12 +4752,12 @@ begin begin if Self = gPlayer1 then begin - gLMSPID1 := FUID; + gSpectLatchPID1 := FUID; gPlayer1 := nil; - end; - if Self = gPlayer2 then + end + else if Self = gPlayer2 then begin - gLMSPID2 := FUID; + gSpectLatchPID2 := FUID; gPlayer2 := nil; end; end; @@ -6229,6 +6310,7 @@ begin if FMegaRulez[MR_INVUL] < gTime+PLAYER_INVUL_TIME then begin FMegaRulez[MR_INVUL] := gTime+PLAYER_INVUL_TIME; + FSpawnInvul := 0; end; ITEM_INVIS: @@ -7886,4 +7968,6 @@ end; begin conRegVar('cheat_berserk_autoswitch', @gBerserkAutoswitch, 'autoswitch to fist when berserk pack taken', '', true, true); + conRegVar('player_indicator', @gPlayerIndicator, 'Draw indicator only for current player, also for teammates, or not at all', 'Draw indicator only for current player, also for teammates, or not at all'); + conRegVar('player_indicator_style', @gPlayerIndicatorStyle, 'Visual appearance of indicator', 'Visual appearance of indicator'); end.