X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=362c2833ecbe9a7393caf11622c1ccb5bbfdb67e;hb=cb61300b61ba18d486d19edf315f05b5b494fac3;hp=fe38642843d48311e9169bb13b93973c9fcfa0b5;hpb=73adc74fdf77fba9f9b683fb8484ccc22ab75339;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index fe38642..362c283 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -171,7 +171,6 @@ type FLastSpawnerUID: Word; FLastHit: Byte; FObj: TObj; - FXTo, FYTo: Integer; FSpectatePlayer: Integer; FFirePainTime: Integer; FFireAttacker: Word; @@ -186,7 +185,9 @@ type FActionChanged: Boolean; FAngle: SmallInt; FFireAngle: SmallInt; + FIncCamOld: Integer; FIncCam: Integer; + FSlopeOld: Integer; FShellTimer: Integer; FShellType: Byte; FSawSound: TPlayableSound; @@ -325,6 +326,7 @@ type procedure DrawIndicator(Color: TRGB); procedure DrawBubble(); procedure DrawGUI(); + procedure PreUpdate(); procedure Update(); virtual; procedure RememberState(); procedure RecallState(); @@ -332,8 +334,6 @@ type procedure LoadState (st: TStream); virtual; procedure PauseSounds(Enable: Boolean); procedure NetFire(Wpn: Byte; X, Y, AX, AY: Integer; WID: Integer = -1); - procedure DoLerp(Level: Integer = 2); - procedure SetLerp(XTo, YTo: Integer); procedure QueueWeaponSwitch(Weapon: Byte); procedure RealizeCurrentWeapon(); procedure FlamerOn; @@ -379,6 +379,8 @@ type property GameAccelX: Integer read FObj.Accel.X write FObj.Accel.X; property GameAccelY: Integer read FObj.Accel.Y write FObj.Accel.Y; property IncCam: Integer read FIncCam write FIncCam; + property IncCamOld: Integer read FIncCamOld write FIncCamOld; + property SlopeOld: Integer read FSlopeOld write FSlopeOld; property UID: Word read FUID write FUID; property JustTeleported: Boolean read FJustTeleported write FJustTeleported; property NetTime: LongWord read FNetTime write FNetTime; @@ -581,6 +583,7 @@ function g_Player_Create(ModelName: String; Color: TRGB; Team: Byte; Bot: Boole function g_Player_CreateFromState (st: TStream): Word; procedure g_Player_Remove(UID: Word); procedure g_Player_ResetTeams(); +procedure g_Player_PreUpdate(); procedure g_Player_UpdateAll(); procedure g_Player_DrawAll(); procedure g_Player_DrawDebug(p: TPlayer); @@ -1368,6 +1371,16 @@ begin SetLength(SavedStates, 0); end; +procedure g_Player_PreUpdate(); +var + i: Integer; +begin + if gPlayers = nil then Exit; + for i := 0 to High(gPlayers) do + if gPlayers[i] <> nil then + gPlayers[i].PreUpdate(); +end; + procedure g_Player_UpdateAll(); var i: Integer; @@ -1713,6 +1726,9 @@ begin if gGibs[i].alive then with gGibs[i] do begin + Obj.oldX := Obj.X; + Obj.oldY := Obj.Y; + vel := Obj.Vel; mr := g_Obj_Move(@Obj, True, False, True); positionChanged(); // this updates spatial accelerators @@ -1763,6 +1779,9 @@ begin if gShells[i].alive then with gShells[i] do begin + Obj.oldX := Obj.X; + Obj.oldY := Obj.Y; + vel := Obj.Vel; mr := g_Obj_Move(@Obj, True, False, True); positionChanged(); // this updates spatial accelerators @@ -1851,7 +1870,7 @@ procedure TShell.positionChanged (); inline; begin end; procedure g_Player_DrawCorpses(); var - i: Integer; + i, fX, fY: Integer; a: TDFPoint; begin if gGibs <> nil then @@ -1862,13 +1881,15 @@ begin if not g_Obj_Collide(sX, sY, sWidth, sHeight, @Obj) then Continue; + Obj.lerp(gLerpFactor, fX, fY); + a.X := Obj.Rect.X+(Obj.Rect.Width div 2); a.y := Obj.Rect.Y+(Obj.Rect.Height div 2); - e_DrawAdv(ID, Obj.X, Obj.Y, 0, True, False, RAngle, @a, TMirrorType.None); + e_DrawAdv(ID, fX, fY, 0, True, False, RAngle, @a, TMirrorType.None); e_Colors := Color; - e_DrawAdv(MaskID, Obj.X, Obj.Y, 0, True, False, RAngle, @a, TMirrorType.None); + e_DrawAdv(MaskID, fX, fY, 0, True, False, RAngle, @a, TMirrorType.None); e_Colors.R := 255; e_Colors.G := 255; e_Colors.B := 255; @@ -1882,7 +1903,7 @@ end; procedure g_Player_DrawShells(); var - i: Integer; + i, fX, fY: Integer; a: TDFPoint; begin if gShells <> nil then @@ -1893,10 +1914,12 @@ begin if not g_Obj_Collide(sX, sY, sWidth, sHeight, @Obj) then Continue; + Obj.lerp(gLerpFactor, fX, fY); + a.X := CX; a.Y := CY; - e_DrawAdv(SpriteID, Obj.X, Obj.Y, 0, True, False, RAngle, @a, TMirrorType.None); + e_DrawAdv(SpriteID, fX, fY, 0, True, False, RAngle, @a, TMirrorType.None); end; end; @@ -2338,7 +2361,7 @@ end; procedure TPlayer.DrawIndicator(Color: TRGB); var - indX, indY: Integer; + indX, indY, fX, fY, fSlope: Integer; indW, indH: Word; indA: Single; a: TDFPoint; @@ -2347,6 +2370,10 @@ var c: TRGB; begin if FAlive then + begin + FObj.lerp(gLerpFactor, fX, fY); + fSlope := nlerp(FSlopeOld, FObj.slopeUpLeft, gLerpFactor); + case gPlayerIndicatorStyle of 0: begin @@ -2359,31 +2386,32 @@ begin 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; + indX := fX + FObj.Rect.X + FObj.Rect.Width; + indY := fY + 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; + indX := fX + FObj.Rect.X - indH; + indY := fY + FObj.Rect.Y + (FObj.Rect.Height - indW) div 2; end - else if (fObj.Y - indH) < 0 then + 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; + indX := fX + FObj.Rect.X + (FObj.Rect.Width - indW) div 2; + indY := fY + 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; + indX := fX + FObj.Rect.X + (FObj.Rect.Width - indW) div 2; + indY := fY - indH; end; + indY := indY + fSlope; indX := EnsureRange(indX, 0, Max(gMapInfo.Width, gPlayerScreenSize.X) - indW); indY := EnsureRange(indY, 0, Max(gMapInfo.Height, gPlayerScreenSize.Y) - indH); @@ -2397,23 +2425,25 @@ begin 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; + indX := fX + FObj.Rect.X + (FObj.Rect.Width - Length(FName) * nW) div 2; + indY := fY - nH + fSlope; e_TextureFontPrintEx(indX, indY, FName, gStdFont, Color.R, Color.G, Color.B, 1.0, True); end; end; + end; end; procedure TPlayer.DrawBubble(); var - bubX, bubY: Integer; + bubX, bubY, fX, fY: Integer; ID: LongWord; Rb, Gb, Bb, Rw, Gw, Bw: SmallInt; Dot: Byte; begin - bubX := FObj.X+FObj.Rect.X + IfThen(FDirection = TDirection.D_LEFT, -4, 18); - bubY := FObj.Y+FObj.Rect.Y - 18; + FObj.lerp(gLerpFactor, fX, fY); + bubX := fX+FObj.Rect.X + IfThen(FDirection = TDirection.D_LEFT, -4, 18); + bubY := fY+FObj.Rect.Y - 18; Rb := 64; Gb := 64; Bb := 64; @@ -2423,8 +2453,8 @@ begin case gChatBubble of 1: // simple textual non-bubble begin - bubX := FObj.X+FObj.Rect.X - 11; - bubY := FObj.Y+FObj.Rect.Y - 17; + bubX := fX+FObj.Rect.X - 11; + bubY := fY+FObj.Rect.Y - 17; e_TextureFontPrint(bubX, bubY, '[...]', gStdFont); Exit; end; @@ -2491,7 +2521,11 @@ var w, h: Word; dr: Boolean; Mirror: TMirrorType; + fX, fY, fSlope: Integer; begin + FObj.lerp(gLerpFactor, fX, fY); + fSlope := nlerp(FSlopeOld, FObj.slopeUpLeft, gLerpFactor); + if FAlive then begin if Direction = TDirection.D_RIGHT then @@ -2501,8 +2535,8 @@ begin if FPunchAnim <> nil then begin - FPunchAnim.Draw(FObj.X+IfThen(Direction = TDirection.D_LEFT, 15-FObj.Rect.X, FObj.Rect.X-15), - FObj.Y+FObj.Rect.Y-11, Mirror); + FPunchAnim.Draw(fX+IfThen(Direction = TDirection.D_LEFT, 15-FObj.Rect.X, FObj.Rect.X-15), + fY+fSlope+FObj.Rect.Y-11, Mirror); if FPunchAnim.played then begin FPunchAnim.Free; @@ -2515,11 +2549,11 @@ begin begin e_GetTextureSize(ID, @w, @h); if FDirection = TDirection.D_LEFT then - e_Draw(ID, FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-(w div 2)+4, - FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2)-(h div 2)-7+FObj.slopeUpLeft, 0, True, False) + e_Draw(ID, fX+FObj.Rect.X+(FObj.Rect.Width div 2)-(w div 2)+4, + fY+FObj.Rect.Y+(FObj.Rect.Height div 2)-(h div 2)-7+fSlope, 0, True, False) else - e_Draw(ID, FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-(w div 2)-2, - FObj.Y+FObj.Rect.Y+(FObj.Rect.Height div 2)-(h div 2)-7+FObj.slopeUpLeft, 0, True, False); + e_Draw(ID, fX+FObj.Rect.X+(FObj.Rect.Width div 2)-(w div 2)-2, + fY+FObj.Rect.Y+(FObj.Rect.Height div 2)-(h div 2)-7+fSlope, 0, True, False); end; if FMegaRulez[MR_INVIS] > gTime then @@ -2532,15 +2566,15 @@ begin else dr := True; if dr then - FModel.Draw(FObj.X, FObj.Y+FObj.slopeUpLeft, 200) + FModel.Draw(fX, fY+fSlope, 200) else - FModel.Draw(FObj.X, FObj.Y+FObj.slopeUpLeft); + FModel.Draw(fX, fY+fSlope); end else - FModel.Draw(FObj.X, FObj.Y+FObj.slopeUpLeft, 254); + FModel.Draw(fX, fY+fSlope, 254); end else - FModel.Draw(FObj.X, FObj.Y+FObj.slopeUpLeft); + FModel.Draw(fX, fY+fSlope); end; if g_debug_Frames then @@ -4396,6 +4430,8 @@ begin ReleaseKeys(); FDamageBuffer := 0; + FSlopeOld := 0; + FIncCamOld := 0; FIncCam := 0; FBFGFireCounter := -1; FShellTimer := -1; @@ -4564,6 +4600,8 @@ var Anim: TAnimation; ID: DWORD; begin + FSlopeOld := 0; + FIncCamOld := 0; FIncCam := 0; FBFGFireCounter := -1; FShellTimer := -1; @@ -4665,6 +4703,8 @@ begin // Óñòàíîâêà êîîðäèíàò è ñáðîñ âñåõ ïàðàìåòðîâ: FObj.X := RespawnPoint.X-PLAYER_RECT.X; FObj.Y := RespawnPoint.Y-PLAYER_RECT.Y; + FObj.oldX := FObj.X; // don't interpolate after respawn + FObj.oldY := FObj.Y; FObj.Vel.X := 0; FObj.Vel.Y := 0; FObj.Accel.X := 0; @@ -4741,8 +4781,6 @@ begin GameX := gMapInfo.Width div 2; GameY := gMapInfo.Height div 2; end; - FXTo := GameX; - FYTo := GameY; FAlive := False; FSpectator := True; @@ -4775,11 +4813,7 @@ begin Exit; FGhost := not FGhost; FPhysics := not FGhost; - if FGhost then - begin - FXTo := FObj.X; - FYTo := FObj.Y; - end else + if not FGhost then begin FObj.Accel.X := 0; FObj.Accel.Y := 0; @@ -4922,11 +4956,8 @@ begin FObj.X := X-PLAYER_RECT.X; FObj.Y := Y-PLAYER_RECT.Y; - if FAlive and FGhost then - begin - FXTo := FObj.X; - FYTo := FObj.Y; - end; + FObj.oldX := FObj.X; // don't interpolate after respawn + FObj.oldY := FObj.Y; if not g_Game_IsNet then begin @@ -5004,6 +5035,14 @@ begin end; end; +procedure TPlayer.PreUpdate(); +begin + FSlopeOld := FObj.slopeUpLeft; + FIncCamOld := FIncCam; + FObj.oldX := FObj.X; + FObj.oldY := FObj.Y; +end; + procedure TPlayer.Update(); var b: Byte; @@ -5016,12 +5055,6 @@ begin NetServer := g_Game_IsNet and g_Game_IsServer; AnyServer := g_Game_IsServer; - if g_Game_IsClient and (NetInterpLevel > 0) then - DoLerp(NetInterpLevel + 1) - else - if FGhost then - DoLerp(4); - if NetServer then if FClientID >= 0 then begin @@ -5184,33 +5217,33 @@ begin begin if FKeys[KEY_UP].Pressed or FKeys[KEY_JUMP].Pressed then begin - FYTo := FObj.Y - 32; + FObj.Y := FObj.Y - 32; FSpectatePlayer := -1; end; if FKeys[KEY_DOWN].Pressed then begin - FYTo := FObj.Y + 32; + FObj.Y := FObj.Y + 32; FSpectatePlayer := -1; end; if FKeys[KEY_LEFT].Pressed then begin - FXTo := FObj.X - 32; + FObj.X := FObj.X - 32; FSpectatePlayer := -1; end; if FKeys[KEY_RIGHT].Pressed then begin - FXTo := FObj.X + 32; + FObj.X := FObj.X + 32; FSpectatePlayer := -1; end; - if (FXTo < -64) then - FXTo := -64 - else if (FXTo > gMapInfo.Width + 32) then - FXTo := gMapInfo.Width + 32; - if (FYTo < -72) then - FYTo := -72 - else if (FYTo > gMapInfo.Height + 32) then - FYTo := gMapInfo.Height + 32; + if (FObj.X < -64) then + FObj.X := -64 + else if (FObj.X > gMapInfo.Width + 32) then + FObj.X := gMapInfo.Width + 32; + if (FObj.Y < -72) then + FObj.Y := -72 + else if (FObj.Y > gMapInfo.Height + 32) then + FObj.Y := gMapInfo.Height + 32; end; if FPhysics then @@ -5228,8 +5261,8 @@ begin if gPlayers[FSpectatePlayer] <> nil then if gPlayers[FSpectatePlayer].alive then begin - FXTo := gPlayers[FSpectatePlayer].GameX; - FYTo := gPlayers[FSpectatePlayer].GameY; + FObj.X := gPlayers[FSpectatePlayer].GameX; + FObj.Y := gPlayers[FSpectatePlayer].GameY; end; end; @@ -5688,35 +5721,6 @@ begin else if (FAngle = ANGLE_LEFTUP) or (FAngle = ANGLE_RIGHTUP) then SetAction(A_ATTACKUP); end; -procedure TPlayer.DoLerp(Level: Integer = 2); -begin - if FObj.X <> FXTo then FObj.X := Lerp(FObj.X, FXTo, Level); - if FObj.Y <> FYTo then FObj.Y := Lerp(FObj.Y, FYTo, Level); -end; - -procedure TPlayer.SetLerp(XTo, YTo: Integer); -var - AX, AY: Integer; -begin - if NetInterpLevel < 1 then - begin - FObj.X := XTo; - FObj.Y := YTo; - end - else - begin - FXTo := XTo; - FYTo := YTo; - - AX := Abs(FXTo - FObj.X); - AY := Abs(FYTo - FObj.Y); - if (AX > 32) or (AX <= NetInterpLevel) then - FObj.X := FXTo; - if (AY > 32) or (AY <= NetInterpLevel) then - FObj.Y := FYTo; - end; -end; - function TPlayer.FullInLift(XInc, YInc: Integer): Integer; begin if g_Map_CollidePanel(FObj.X+PLAYER_RECT.X+XInc, FObj.Y+PLAYER_RECT.Y+YInc, @@ -5974,24 +5978,21 @@ begin SavedState.MaxAmmo[i] := FMaxAmmo[i]; SavedState.Rulez := FRulez - [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE]; - if FSavedStateNum < 0 then - begin - for i := Low(SavedStates) to High(SavedStates) do - if not SavedStates[i].Used then - begin - FSavedStateNum := i; - break; - end; - if FSavedStateNum < 0 then + FSavedStateNum := -1; + for i := Low(SavedStates) to High(SavedStates) do + if not SavedStates[i].Used then begin - SetLength(SavedStates, Length(SavedStates) + 1); - FSavedStateNum := High(SavedStates); + FSavedStateNum := i; + break; end; + if FSavedStateNum < 0 then + begin + SetLength(SavedStates, Length(SavedStates) + 1); + FSavedStateNum := High(SavedStates); end; - SavedState.Used := True; - SavedStates[i] := SavedState; + SavedStates[FSavedStateNum] := SavedState; end; procedure TPlayer.RecallState(); @@ -6589,17 +6590,21 @@ begin end; procedure TCorpse.Draw(); +var + fX, fY: Integer; begin if FState = CORPSE_STATE_REMOVEME then Exit; + FObj.lerp(gLerpFactor, fX, fY); + if FAnimation <> nil then - FAnimation.Draw(FObj.X, FObj.Y, TMirrorType.None); + FAnimation.Draw(fX, fY, TMirrorType.None); if FAnimationMask <> nil then begin e_Colors := FColor; - FAnimationMask.Draw(FObj.X, FObj.Y, TMirrorType.None); + FAnimationMask.Draw(fX, fY, TMirrorType.None); e_Colors.R := 255; e_Colors.G := 255; e_Colors.B := 255; @@ -6613,6 +6618,9 @@ begin if FState = CORPSE_STATE_REMOVEME then Exit; + FObj.oldX := FObj.X; + FObj.oldY := FObj.Y; + if gTime mod (GAME_TICK*2) <> 0 then begin g_Obj_Move(@FObj, True, True, True);