diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index 90588ba10e31d4be1d60592fad315687274c8aff..362c2833ecbe9a7393caf11622c1ccb5bbfdb67e 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
FLastSpawnerUID: Word;
FLastHit: Byte;
FObj: TObj;
- FXTo, FYTo: Integer;
FSpectatePlayer: Integer;
FFirePainTime: Integer;
FFireAttacker: Word;
FActionChanged: Boolean;
FAngle: SmallInt;
FFireAngle: SmallInt;
+ FIncCamOld: Integer;
FIncCam: Integer;
+ FSlopeOld: Integer;
FShellTimer: Integer;
FShellType: Byte;
FSawSound: TPlayableSound;
procedure DrawIndicator(Color: TRGB);
procedure DrawBubble();
procedure DrawGUI();
+ procedure PreUpdate();
procedure Update(); virtual;
procedure RememberState();
procedure RecallState();
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;
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;
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);
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;
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
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
procedure g_Player_DrawCorpses();
var
- i: Integer;
+ i, fX, fY: Integer;
a: TDFPoint;
begin
if gGibs <> nil then
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;
procedure g_Player_DrawShells();
var
- i: Integer;
+ i, fX, fY: Integer;
a: TDFPoint;
begin
if gShells <> nil then
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;
procedure TPlayer.DrawIndicator(Color: TRGB);
var
- indX, indY: Integer;
+ indX, indY, fX, fY, fSlope: Integer;
indW, indH: Word;
indA: Single;
a: TDFPoint;
c: TRGB;
begin
if FAlive then
+ begin
+ FObj.lerp(gLerpFactor, fX, fY);
+ fSlope := nlerp(FSlopeOld, FObj.slopeUpLeft, gLerpFactor);
+
case gPlayerIndicatorStyle of
0:
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);
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;
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;
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
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;
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
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
ReleaseKeys();
FDamageBuffer := 0;
+ FSlopeOld := 0;
+ FIncCamOld := 0;
FIncCam := 0;
FBFGFireCounter := -1;
FShellTimer := -1;
Anim: TAnimation;
ID: DWORD;
begin
+ FSlopeOld := 0;
+ FIncCamOld := 0;
FIncCam := 0;
FBFGFireCounter := -1;
FShellTimer := -1;
// Óñòàíîâêà êîîðäèíàò è ñáðîñ âñåõ ïàðàìåòðîâ:
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;
GameX := gMapInfo.Width div 2;
GameY := gMapInfo.Height div 2;
end;
- FXTo := GameX;
- FYTo := GameY;
FAlive := False;
FSpectator := True;
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;
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
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;
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
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
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;
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,
SavedState.MaxAmmo[i] := FMaxAmmo[i];
SavedState.Rulez := FRulez - [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE];
+ FSavedStateNum := -1;
for i := Low(SavedStates) to High(SavedStates) do
if not SavedStates[i].Used then
begin
end;
SavedState.Used := True;
- SavedStates[i] := SavedState;
+ SavedStates[FSavedStateNum] := SavedState;
end;
procedure TPlayer.RecallState();
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;
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);