X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=0cde3c089c1dfe4d0a5d9098721c4e4717d07e4e;hb=5b8e9b87a2b3372fd94fdeefdd78c7d483199da1;hp=6bfc34c0de5302e5291f7d323429e2df16249fbb;hpb=06667349c1efd05099ff0617dfdf17dc7a097828;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index 6bfc34c..0cde3c0 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 @@ -97,6 +96,8 @@ const SUICIDE_DAMAGE = 112; WEAPON_DELAY = 5; + PLAYER_BURN_TIME = 110; + PLAYER1_DEF_COLOR: TRGB = (R:64; G:175; B:48); PLAYER2_DEF_COLOR: TRGB = (R:96; G:96; B:96); @@ -267,6 +268,7 @@ type FDummy: Boolean; FFireTime: 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; @@ -281,6 +283,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; @@ -318,7 +321,7 @@ type procedure DrawPickup(); procedure DrawRulez(); procedure DrawAim(); - procedure DrawIndicator(); + procedure DrawIndicator(Color: TRGB); procedure DrawBubble(); procedure DrawGUI(); procedure Update(); virtual; @@ -336,7 +339,7 @@ type procedure FlamerOff; procedure JetpackOn; procedure JetpackOff; - procedure CatchFire(Attacker: Word); + procedure CatchFire(Attacker: Word; Timeout: Integer = PLAYER_BURN_TIME); //WARNING! this does nothing for now, but still call it! procedure positionChanged (); //WARNING! call this after entity position was changed, or coldet will not work right! @@ -552,8 +555,9 @@ 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; @@ -609,7 +613,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; @@ -1250,14 +1254,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 @@ -1278,7 +1284,7 @@ begin g_Bot_MixNames(); // ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ: - config := TConfig.CreateFile(DataDir + BOTLIST_FILENAME); + config := TConfig.CreateFile(path); BotList := nil; a := 0; @@ -2033,6 +2039,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 @@ -2170,6 +2181,8 @@ begin FJustTeleported := False; FNetTime := 0; + FWaitForFirstSpawn := false; + resetWeaponQueue(); end; @@ -2320,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 - indX := FObj.X+FObj.Rect.X; - indY := FObj.Y; - if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then + case gPlayerIndicatorStyle of + 0: begin - e_GetTextureSize(ID, @indW, @indH); - e_Draw(ID, indX + indW div 2, indY - indH, 0, True, False); + 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_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(); @@ -3189,13 +3251,17 @@ begin FJetSoundOff.PlayAt(FObj.X, FObj.Y); end; -procedure TPlayer.CatchFire(Attacker: Word); +procedure TPlayer.CatchFire(Attacker: Word; Timeout: Integer = PLAYER_BURN_TIME); begin + if Timeout <= 0 then + 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 := 100; + FFireTime := Timeout; FFireAttacker := Attacker; if g_Game_IsNet and g_Game_IsServer then MH_SEND_PlayerStats(FUID); @@ -3660,8 +3726,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); @@ -3851,9 +3917,9 @@ begin case ItemType of ITEM_MEDKIT_SMALL: - if FHealth < PLAYER_HP_SOFT then + if (FHealth < PLAYER_HP_SOFT) or (FFireTime > 0) then begin - IncMax(FHealth, 10, PLAYER_HP_SOFT); + if FHealth < PLAYER_HP_SOFT then IncMax(FHealth, 10, PLAYER_HP_SOFT); Result := True; remove := True; FFireTime := 0; @@ -3861,9 +3927,9 @@ begin end; ITEM_MEDKIT_LARGE: - if FHealth < PLAYER_HP_SOFT then + if (FHealth < PLAYER_HP_SOFT) or (FFireTime > 0) then begin - IncMax(FHealth, 25, PLAYER_HP_SOFT); + if FHealth < PLAYER_HP_SOFT then IncMax(FHealth, 25, PLAYER_HP_SOFT); Result := True; remove := True; FFireTime := 0; @@ -3889,9 +3955,9 @@ begin end; ITEM_SPHERE_BLUE: - if FHealth < PLAYER_HP_LIMIT then + if (FHealth < PLAYER_HP_LIMIT) or (FFireTime > 0) then begin - IncMax(FHealth, 100, PLAYER_HP_LIMIT); + if FHealth < PLAYER_HP_LIMIT then IncMax(FHealth, 100, PLAYER_HP_LIMIT); Result := True; remove := True; FFireTime := 0; @@ -3899,7 +3965,7 @@ begin end; ITEM_SPHERE_WHITE: - if (FHealth < PLAYER_HP_LIMIT) or (FArmor < PLAYER_AP_LIMIT) then + if (FHealth < PLAYER_HP_LIMIT) or (FArmor < PLAYER_AP_LIMIT) or (FFireTime > 0) then begin if FHealth < PLAYER_HP_LIMIT then FHealth := PLAYER_HP_LIMIT; @@ -4104,7 +4170,7 @@ begin (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or (FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS]) or (FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) or - (FMaxAmmo[A_FUEL] < AmmoLimits[1, A_FUEL]) then + (FAmmo[A_FUEL] < FMaxAmmo[A_FUEL]) then begin FMaxAmmo[A_BULLETS] := AmmoLimits[1, A_BULLETS]; FMaxAmmo[A_SHELLS] := AmmoLimits[1, A_SHELLS]; @@ -4120,6 +4186,8 @@ begin IncMax(FAmmo[A_ROCKETS], 1, FMaxAmmo[A_ROCKETS]); if FAmmo[A_CELLS] < FMaxAmmo[A_CELLS] then IncMax(FAmmo[A_CELLS], 40, FMaxAmmo[A_CELLS]); + if FAmmo[A_FUEL] < FMaxAmmo[A_FUEL] then + IncMax(FAmmo[A_FUEL], 50, FMaxAmmo[A_FUEL]); FRulez := FRulez + [R_ITEM_BACKPACK]; Result := True; @@ -4197,9 +4265,9 @@ begin remove := True; FFireTime := 0; end; - if FHealth < PLAYER_HP_SOFT then + if (FHealth < PLAYER_HP_SOFT) or (FFireTime > 0) then begin - FHealth := PLAYER_HP_SOFT; + if FHealth < PLAYER_HP_SOFT then FHealth := PLAYER_HP_SOFT; FBerserk := gTime+30000; Result := True; remove := True; @@ -4217,9 +4285,9 @@ begin end; ITEM_BOTTLE: - if FHealth < PLAYER_HP_LIMIT then + if (FHealth < PLAYER_HP_LIMIT) or (FFireTime > 0) then begin - IncMax(FHealth, 4, PLAYER_HP_LIMIT); + if FHealth < PLAYER_HP_LIMIT then IncMax(FHealth, 4, PLAYER_HP_LIMIT); Result := True; remove := True; FFireTime := 0; @@ -5276,11 +5344,13 @@ begin if FFirePainTime <= 0 then begin if g_Game_IsServer then - Damage(6, FFireAttacker, 0, 0, HIT_FLAME); - FFirePainTime := 18; + Damage(2, FFireAttacker, 0, 0, HIT_FLAME); + FFirePainTime := 12 - FFireTime div 12; end; FFirePainTime := FFirePainTime - 1; FFireTime := FFireTime - 1; + if ((FFireTime mod 33) = 0) and (FMegaRulez[MR_INVUL] < gTime) then + FModel.PlaySound(MODELSOUND_PAIN, 1, FObj.X, FObj.Y); if (FFireTime = 0) and g_Game_IsNet and g_Game_IsServer then MH_SEND_PlayerStats(FUID); end; @@ -5312,7 +5382,7 @@ begin else if FHealth > -50 then Kill(K_HARDKILL, FLastSpawnerUID, FLastHit) else Kill(K_EXTRAHARDKILL, FLastSpawnerUID, FLastHit); - if FAlive then + if FAlive and ((FLastHit <> HIT_FLAME) or (FFireTime <= 0)) then begin if FDamageBuffer <= 20 then FModel.PlaySound(MODELSOUND_PAIN, 1, FObj.X, FObj.Y) else if FDamageBuffer <= 55 then FModel.PlaySound(MODELSOUND_PAIN, 2, FObj.X, FObj.Y) @@ -7878,4 +7948,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.