X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=a66b064efcdc0abbaaf7bd0f8b8be727d16bc40b;hb=52c1edc4aba4aa850742200a391845a91f3451ef;hp=db39cb84b0961e1260f840fb8a885e710648b1a8;hpb=dffafd305d0df029f317cc92c1968ba0065c0cd8;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index db39cb8..a66b064 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -188,6 +188,7 @@ type FFireAngle: SmallInt; FIncCamOld: Integer; FIncCam: Integer; + FSlopeOld: Integer; FShellTimer: Integer; FShellType: Byte; FSawSound: TPlayableSound; @@ -238,7 +239,7 @@ type procedure doDamage (v: Integer); - function followCorpse(): Boolean; + function refreshCorpse(): Boolean; public FDamageBuffer: Integer; @@ -271,6 +272,7 @@ type FSpawnInvul: Integer; FHandicap: Integer; FWaitForFirstSpawn: Boolean; // set to `true` in server, used to spawn a player on first full state request + FCorpse: Integer; // debug: viewport offset viewPortX, viewPortY, viewPortW, viewPortH: Integer; @@ -350,6 +352,8 @@ type procedure getMapBox (out x, y, w, h: Integer); inline; procedure moveBy (dx, dy: Integer); inline; + function getCameraObj(): TObj; + public property Vel: TPoint2i read FObj.Vel; property Obj: TObj read FObj; @@ -382,6 +386,7 @@ type 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; @@ -528,7 +533,7 @@ type public constructor Create(X, Y: Integer; ModelName: String; aMess: Boolean); destructor Destroy(); override; - procedure Damage(Value: Word; vx, vy: Integer); + procedure Damage(Value: Word; SpawnerUID: Word; vx, vy: Integer); procedure Update(); procedure Draw(); procedure SaveState (st: TStream); @@ -595,7 +600,7 @@ function g_Player_Get(UID: Word): TPlayer; function g_Player_GetCount(): Byte; function g_Player_GetStats(): TPlayerStatArray; function g_Player_ValidName(Name: String): Boolean; -procedure g_Player_CreateCorpse(Player: TPlayer); +function g_Player_CreateCorpse(Player: TPlayer): Integer; procedure g_Player_CreateGibs(fX, fY: Integer; ModelName: String; fColor: TRGB); procedure g_Player_CreateShell(fX, fY, dX, dY: Integer; T: Byte); procedure g_Player_UpdatePhysicalObjects(); @@ -1435,6 +1440,8 @@ begin e_TextureFontPrint(0, fH * 3, 'Vel Y: ' + IntToStr(p.FObj.Vel.Y), gStdFont); e_TextureFontPrint(0, fH * 4, 'Acc X: ' + IntToStr(p.FObj.Accel.X), gStdFont); e_TextureFontPrint(0, fH * 5, 'Acc Y: ' + IntToStr(p.FObj.Accel.Y), gStdFont); + e_TextureFontPrint(0, fH * 6, 'Old X: ' + IntToStr(p.FObj.oldX), gStdFont); + e_TextureFontPrint(0, fH * 7, 'Old Y: ' + IntToStr(p.FObj.oldY), gStdFont); end; procedure g_Player_DrawHealth(); @@ -1568,21 +1575,24 @@ begin end; end; -procedure g_Player_CreateCorpse(Player: TPlayer); +function g_Player_CreateCorpse(Player: TPlayer): Integer; var i: Integer; find_id: DWORD; ok: Boolean; begin + Result := -1; + if Player.alive then Exit; // Ðàçðûâàåì ñâÿçü ñ ïðåæíèì òðóïîì: - if gCorpses <> nil then - for i := 0 to High(gCorpses) do - if gCorpses[i] <> nil then - if gCorpses[i].FPlayerUID = Player.FUID then - gCorpses[i].FPlayerUID := 0; + i := Player.FCorpse; + if (i >= 0) and (i < Length(gCorpses)) then + begin + if (gCorpses[i] <> nil) and (gCorpses[i].FPlayerUID = Player.FUID) then + gCorpses[i].FPlayerUID := 0; + end; if Player.FObj.Y >= gMapInfo.Height+128 then Exit; @@ -1610,6 +1620,8 @@ begin gCorpses[find_id].FObj.Vel := FObj.Vel; gCorpses[find_id].FObj.Accel := FObj.Accel; gCorpses[find_id].FPlayerUID := FUID; + + Result := find_id; end else g_Player_CreateGibs(FObj.X + PLAYER_RECT_CX, @@ -2197,6 +2209,7 @@ begin FFirePainTime := 0; FFireAttacker := 0; FHandicap := 100; + FCorpse := -1; FActualModelName := 'doomer'; @@ -2362,7 +2375,7 @@ end; procedure TPlayer.DrawIndicator(Color: TRGB); var - indX, indY, fX, fY: Integer; + indX, indY, fX, fY, fSlope: Integer; indW, indH: Word; indA: Single; a: TDFPoint; @@ -2373,6 +2386,8 @@ begin if FAlive then begin FObj.lerp(gLerpFactor, fX, fY); + fSlope := nlerp(FSlopeOld, FObj.slopeUpLeft, gLerpFactor); + case gPlayerIndicatorStyle of 0: begin @@ -2410,6 +2425,7 @@ begin 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); @@ -2424,7 +2440,7 @@ begin begin e_TextureFontGetSize(gStdFont, nW, nH); indX := fX + FObj.Rect.X + (FObj.Rect.Width - Length(FName) * nW) div 2; - indY := fY - nH; + indY := fY - nH + fSlope; e_TextureFontPrintEx(indX, indY, FName, gStdFont, Color.R, Color.G, Color.B, 1.0, True); end; end; @@ -2438,8 +2454,11 @@ var Rb, Gb, Bb, Rw, Gw, Bw: SmallInt; Dot: Byte; + CObj: TObj; begin - FObj.lerp(gLerpFactor, fX, fY); + CObj := getCameraObj(); + CObj.lerp(gLerpFactor, fX, fY); + // NB: _F_Obj.Rect is used to keep the bubble higher; this is not a mistake bubX := fX+FObj.Rect.X + IfThen(FDirection = TDirection.D_LEFT, -4, 18); bubY := fY+FObj.Rect.Y - 18; Rb := 64; @@ -2519,9 +2538,10 @@ var w, h: Word; dr: Boolean; Mirror: TMirrorType; - fX, fY: Integer; + fX, fY, fSlope: Integer; begin FObj.lerp(gLerpFactor, fX, fY); + fSlope := nlerp(FSlopeOld, FObj.slopeUpLeft, gLerpFactor); if FAlive then begin @@ -2533,7 +2553,7 @@ begin if FPunchAnim <> nil then begin FPunchAnim.Draw(fX+IfThen(Direction = TDirection.D_LEFT, 15-FObj.Rect.X, FObj.Rect.X-15), - fY+FObj.Rect.Y-11, Mirror); + fY+fSlope+FObj.Rect.Y-11, Mirror); if FPunchAnim.played then begin FPunchAnim.Free; @@ -2547,10 +2567,10 @@ begin e_GetTextureSize(ID, @w, @h); if FDirection = TDirection.D_LEFT then 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+FObj.slopeUpLeft, 0, True, False) + fY+FObj.Rect.Y+(FObj.Rect.Height div 2)-(h div 2)-7+fSlope, 0, True, False) else 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+FObj.slopeUpLeft, 0, True, False); + fY+FObj.Rect.Y+(FObj.Rect.Height div 2)-(h div 2)-7+fSlope, 0, True, False); end; if FMegaRulez[MR_INVIS] > gTime then @@ -2563,15 +2583,15 @@ begin else dr := True; if dr then - FModel.Draw(fX, fY+FObj.slopeUpLeft, 200) + FModel.Draw(fX, fY+fSlope, 200) else - FModel.Draw(fX, fY+FObj.slopeUpLeft); + FModel.Draw(fX, fY+fSlope); end else - FModel.Draw(fX, fY+FObj.slopeUpLeft, 254); + FModel.Draw(fX, fY+fSlope, 254); end else - FModel.Draw(fX, fY+FObj.slopeUpLeft); + FModel.Draw(fX, fY+fSlope); end; if g_debug_Frames then @@ -3597,7 +3617,7 @@ begin DropFlag(KillType = K_FALLKILL); end; - g_Player_CreateCorpse(Self); + FCorpse := g_Player_CreateCorpse(Self); if Srv and (gGameSettings.MaxLives > 0) and FNoRespawn and (gLMSRespawn = LMS_RESPAWN_NONE) then @@ -4408,6 +4428,7 @@ begin FDeath := 0; FSecrets := 0; FSpawnInvul := 0; + FCorpse := -1; FReady := False; if FNoRespawn then begin @@ -4427,6 +4448,7 @@ begin ReleaseKeys(); FDamageBuffer := 0; + FSlopeOld := 0; FIncCamOld := 0; FIncCam := 0; FBFGFireCounter := -1; @@ -4596,6 +4618,7 @@ var Anim: TAnimation; ID: DWORD; begin + FSlopeOld := 0; FIncCamOld := 0; FIncCam := 0; FBFGFireCounter := -1; @@ -4603,6 +4626,7 @@ begin FPain := 0; FLastHit := 0; FSpawnInvul := 0; + FCorpse := -1; if not g_Game_IsServer then Exit; @@ -4785,6 +4809,7 @@ begin FPhysics := False; FWantsInGame := False; FSpawned := False; + FCorpse := -1; if FNoRespawn then begin @@ -5017,11 +5042,12 @@ begin Result := 1; end; -function TPlayer.followCorpse(): Boolean; +function TPlayer.refreshCorpse(): Boolean; var i: Integer; begin Result := False; + FCorpse := -1; if FAlive or FSpectator then Exit; if (gCorpses = nil) or (Length(gCorpses) = 0) then @@ -5031,18 +5057,29 @@ begin if gCorpses[i].FPlayerUID = FUID then begin Result := True; - FObj.X := gCorpses[i].FObj.X; - FObj.Y := gCorpses[i].FObj.Y; - FObj.Vel.X := gCorpses[i].FObj.Vel.X; - FObj.Vel.Y := gCorpses[i].FObj.Vel.Y; - FObj.Accel.X := gCorpses[i].FObj.Accel.X; - FObj.Accel.Y := gCorpses[i].FObj.Accel.Y; + FCorpse := i; break; end; end; +function TPlayer.getCameraObj(): TObj; +begin + if (not FAlive) and (not FSpectator) and + (FCorpse >= 0) and (FCorpse < Length(gCorpses)) and + (gCorpses[FCorpse] <> nil) and (gCorpses[FCorpse].FPlayerUID = FUID) then + begin + gCorpses[FCorpse].FObj.slopeUpLeft := FObj.slopeUpLeft; + Result := gCorpses[FCorpse].FObj; + end + else + begin + Result := FObj; + end; +end; + procedure TPlayer.PreUpdate(); begin + FSlopeOld := FObj.slopeUpLeft; FIncCamOld := FIncCam; FObj.oldX := FObj.X; FObj.oldY := FObj.Y; @@ -5060,8 +5097,11 @@ begin NetServer := g_Game_IsNet and g_Game_IsServer; AnyServer := g_Game_IsServer; - if FGhost then - DoLerp(4); + if g_Game_IsClient and (NetInterpLevel > 0) then + DoLerp(NetInterpLevel + 1) + else + if FGhost then + DoLerp(4); if NetServer then if FClientID >= 0 then @@ -5121,8 +5161,7 @@ begin if FPhysics then begin - if not followCorpse() then - g_Obj_Move(@FObj, True, True, True); + g_Obj_Move(@FObj, True, True, True); positionChanged(); // this updates spatial accelerators end; @@ -5256,8 +5295,7 @@ begin if FPhysics then begin - if not followCorpse() then - g_Obj_Move(@FObj, True, True, True); + g_Obj_Move(@FObj, True, True, True); positionChanged(); // this updates spatial accelerators end else @@ -5739,6 +5777,8 @@ procedure TPlayer.SetLerp(XTo, YTo: Integer); var AX, AY: Integer; begin + FXTo := XTo; + FYTo := YTo; if NetInterpLevel < 1 then begin FObj.X := XTo; @@ -5746,9 +5786,6 @@ begin end else begin - FXTo := XTo; - FYTo := YTo; - AX := Abs(FXTo - FObj.X); AY := Abs(FYTo - FObj.Y); if (AX > 32) or (AX <= NetInterpLevel) then @@ -6580,7 +6617,7 @@ begin end; -procedure TCorpse.Damage(Value: Word; vx, vy: Integer); +procedure TCorpse.Damage(Value: Word; SpawnerUID: Word; vx, vy: Integer); var pm: TPlayerModel; Blood: TModelBlood; @@ -6611,7 +6648,7 @@ begin if (gBodyKillEvent <> -1) and gDelayedEvents[gBodyKillEvent].Pending then gDelayedEvents[gBodyKillEvent].Pending := False; - gBodyKillEvent := g_Game_DelayEvent(DE_BODYKILL, 1050, 0); + gBodyKillEvent := g_Game_DelayEvent(DE_BODYKILL, 1050, SpawnerUID); end; end else