X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=de559b7f008d25083f853e9f4486efef4c6db812;hb=52853ee4939a9c85c9e8aded0b60bdbc2d9d8821;hp=ffb5ce93e6aa5eb070dce8dfe2b5aa5c1735d484;hpb=563e770b462d67b2c8265b0e2b53384152afb7c1;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index ffb5ce9..de559b7 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -176,6 +176,7 @@ type FSavedState: TPlayerSavedState; FModel: TPlayerModel; + FPunchAnim: TAnimation; FActionPrior: Byte; FActionAnim: Byte; FActionForce: Boolean; @@ -213,6 +214,7 @@ type procedure SetAction(Action: Byte; Force: Boolean = False); procedure OnDamage(Angle: SmallInt); virtual; function firediry(): Integer; + procedure DoPunch(); procedure Run(Direction: TDirection); procedure NextWeapon(); @@ -229,6 +231,8 @@ type procedure doDamage (v: Integer); + function followCorpse(): Boolean; + public FDamageBuffer: Integer; @@ -306,6 +310,7 @@ type procedure DrawPickup(); procedure DrawRulez(); procedure DrawAim(); + procedure DrawIndicator(); procedure DrawBubble(); procedure DrawGUI(); procedure Update(); virtual; @@ -461,7 +466,7 @@ type PGib = ^TGib; TGib = record - alive: Boolean; + alive: Boolean; ID: DWORD; MaskID: DWORD; RAngle: Integer; @@ -499,6 +504,7 @@ type FDamage: Byte; FColor: TRGB; FObj: TObj; + FPlayerUID: Word; FAnimation: TAnimation; FAnimationMask: TAnimation; @@ -537,6 +543,7 @@ var gFly: Boolean = False; gAimLine: Boolean = False; gChatBubble: Byte = 0; + gPlayerIndicator: Boolean = True; gNumBots: Word = 0; gLMSPID1: Word = 0; gLMSPID2: Word = 0; @@ -586,10 +593,14 @@ procedure g_Bot_RemoveAll(); implementation uses +{$INCLUDE ../nogl/noGLuses.inc} +{$IFDEF ENABLE_HOLMES} + g_holmes, +{$ENDIF} e_log, g_map, g_items, g_console, g_gfx, Math, g_options, g_triggers, g_menu, g_game, g_grid, wadreader, g_main, g_monsters, CONFIG, g_language, - g_net, g_netmsg, g_window, GL, g_holmes, + g_net, g_netmsg, g_window, utils, xstreams; const PLR_SAVE_VERSION = 0; @@ -1503,11 +1514,20 @@ end; procedure g_Player_CreateCorpse(Player: TPlayer); var + i: Integer; find_id: DWORD; ok: Boolean; begin 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; + if Player.FObj.Y >= gMapInfo.Height+128 then Exit; @@ -1533,6 +1553,7 @@ begin gCorpses[find_id].FColor := FModel.Color; gCorpses[find_id].FObj.Vel := FObj.Vel; gCorpses[find_id].FObj.Accel := FObj.Accel; + gCorpses[find_id].FPlayerUID := FUID; end else g_Player_CreateGibs(FObj.X + PLAYER_RECT_CX, @@ -1592,11 +1613,13 @@ procedure g_Player_CreateGibs(fX, fY: Integer; ModelName: string; fColor: TRGB); var a: Integer; GibsArray: TGibsArray; + Blood: TModelBlood; begin if (gGibs = nil) or (Length(gGibs) = 0) then Exit; if not g_PlayerModel_GetGibs(ModelName, GibsArray) then Exit; + Blood := g_PlayerModel_GetBlood(ModelName); for a := 0 to High(GibsArray) do with gGibs[CurrentGib] do @@ -1615,7 +1638,7 @@ begin if gBloodCount > 0 then g_GFX_Blood(fX, fY, 16*gBloodCount+Random(5*gBloodCount), -16+Random(33), -16+Random(33), - Random(48), Random(48), 150, 0, 0); + Random(48), Random(48), Blood.R, Blood.G, Blood.B, Blood.Kind); if CurrentGib >= High(gGibs) then CurrentGib := 0 @@ -2246,10 +2269,31 @@ begin FJetSoundOn.Free(); FJetSoundOff.Free(); FModel.Free(); + if FPunchAnim <> nil then + FPunchAnim.Free(); inherited; end; +procedure TPlayer.DrawIndicator(); +var + indX, indY: Integer; + indW, indH: Word; + ID: DWORD; +begin + if FAlive then + begin + indX := FObj.X+FObj.Rect.X; + indY := FObj.Y - 12; + if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then + begin + e_GetTextureSize(ID, @indW, @indH); + e_Draw(ID, indX + indW div 2, indY, 0, True, False); + end; + end; + //e_TextureFontPrint(indX, indY, FName, gStdFont); // Shows player name overhead +end; + procedure TPlayer.DrawBubble(); var bubX, bubY: Integer; @@ -2336,9 +2380,26 @@ var ID: DWORD; w, h: Word; dr: Boolean; + Mirror: TMirrorType; begin if FAlive then begin + if Direction = TDirection.D_RIGHT then + Mirror := TMirrorType.None + else + Mirror := TMirrorType.Horizontal; + + 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); + if FPunchAnim.played then + begin + FPunchAnim.Free; + FPunchAnim := nil; + end; + end; + if (FMegaRulez[MR_INVUL] > gTime) and (gPlayerDrawn <> Self) then if g_Texture_Get('TEXTURE_PLAYER_INVULPENTA', ID) then begin @@ -2395,10 +2456,13 @@ procedure TPlayer.DrawAim(); var ex, ey: Integer; begin + +{$IFDEF ENABLE_HOLMES} if isValidViewPort and (self = gPlayer1) then begin g_Holmes_plrLaser(ax0, ay0, ax1, ay1); end; +{$ENDIF} e_DrawLine(sz, ax0, ay0, ax1, ay1, 255, 0, 0, 96); if (g_Map_traceToNearestWall(ax0, ay0, ax1, ay1, @ex, @ey) <> nil) then @@ -2773,6 +2837,27 @@ begin e_DrawFillQuad(0, 0, gPlayerScreenSize.X-1, gPlayerScreenSize.Y-1, 150, 200, 150, 255-h*50); end; +procedure TPlayer.DoPunch(); +var + id: DWORD; + st: String; +begin + if FPunchAnim <> nil then begin + FPunchAnim.reset(); + FPunchAnim.Free; + FPunchAnim := nil; + end; + st := 'FRAMES_PUNCH'; + if R_BERSERK in FRulez then + st := st + '_BERSERK'; + if FKeys[KEY_UP].Pressed then + st := st + '_UP' + else if FKeys[KEY_DOWN].Pressed then + st := st + '_DN'; + g_Frames_Get(id, st); + FPunchAnim := TAnimation.Create(id, False, 1); +end; + procedure TPlayer.Fire(); var f, DidFire: Boolean; @@ -2802,6 +2887,7 @@ begin case FCurrWeap of WEAPON_KASTET: begin + DoPunch(); if R_BERSERK in FRulez then begin //g_Weapon_punch(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, 75, FUID); @@ -3455,11 +3541,11 @@ begin g_GFX_Blood(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2)+8, FObj.Y+PLAYER_RECT.Y+(PLAYER_RECT.Height div 2), Count div 2, 3, -1, 16, (PLAYER_RECT.Height*2 div 3), - 150, 0, 0); + FModel.Blood.R, FModel.Blood.G, FModel.Blood.B, FModel.Blood.Kind); g_GFX_Blood(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2)-8, FObj.Y+PLAYER_RECT.Y+(PLAYER_RECT.Height div 2), Count div 2, -3, -1, 16, (PLAYER_RECT.Height*2) div 3, - 150, 0, 0); + FModel.Blood.R, FModel.Blood.G, FModel.Blood.B, FModel.Blood.Kind); end; procedure TPlayer.MakeBloodVector(Count: Word; VelX, VelY: Integer); @@ -3467,7 +3553,7 @@ begin g_GFX_Blood(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2), FObj.Y+PLAYER_RECT.Y+(PLAYER_RECT.Height div 2), Count, VelX, VelY, 16, (PLAYER_RECT.Height*2) div 3, - 150, 0, 0); + FModel.Blood.R, FModel.Blood.G, FModel.Blood.B, FModel.Blood.Kind); end; procedure TPlayer.QueueWeaponSwitch(Weapon: Byte); @@ -3609,7 +3695,7 @@ begin if not switchAllowed then begin //HACK for weapon cycling - if (FNextWeap and $7000) <> 0 then FNextWeap := 0; + if (FNextWeap and $E000) <> 0 then FNextWeap := 0; exit; end; @@ -4310,6 +4396,12 @@ var Anim: TAnimation; ID: DWORD; begin + FIncCam := 0; + FBFGFireCounter := -1; + FShellTimer := -1; + FPain := 0; + FLastHit := 0; + if not g_Game_IsServer then Exit; if FDummy then @@ -4414,12 +4506,6 @@ begin else FAngle := 0; - FIncCam := 0; - FBFGFireCounter := -1; - FShellTimer := -1; - FPain := 0; - FLastHit := 0; - SetAction(A_STAND, True); FModel.Direction := FDirection; @@ -4452,6 +4538,11 @@ begin FSpectatePlayer := -1; FSpawned := True; + if (gPlayer1 = nil) and (gLMSPID1 = FUID) then + gPlayer1 := self; + if (gPlayer2 = nil) and (gLMSPID2 = FUID) then + gPlayer2 := self; + if g_Game_IsNet then begin MH_SEND_PlayerPos(True, FUID, NET_EVERYONE); @@ -4711,6 +4802,30 @@ begin Result := 1; end; +function TPlayer.followCorpse(): Boolean; +var + i: Integer; +begin + Result := False; + if FAlive or FSpectator then + Exit; + if (gCorpses = nil) or (Length(gCorpses) = 0) then + Exit; + for i := 0 to High(gCorpses) do + if gCorpses[i] <> nil then + 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; + break; + end; +end; + procedure TPlayer.Update(); var b: Byte; @@ -4743,6 +4858,9 @@ begin FLoss := 0; end; + if FAlive and (FPunchAnim <> nil) then + FPunchAnim.Update(); + if FAlive and (gFly or FJetpack) then FlySmoke(); @@ -4784,7 +4902,8 @@ begin if FPhysics then begin - g_Obj_Move(@FObj, True, True, True); + if not followCorpse() then + g_Obj_Move(@FObj, True, True, True); positionChanged(); // this updates spatial accelerators end; @@ -4910,7 +5029,8 @@ begin if FPhysics then begin - g_Obj_Move(@FObj, True, True, True); + if not followCorpse() then + g_Obj_Move(@FObj, True, True, True); positionChanged(); // this updates spatial accelerators end else @@ -5254,6 +5374,7 @@ begin case FCurrWeap of WEAPON_KASTET: begin + DoPunch(); if R_BERSERK in FRulez then begin //g_Weapon_punch(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, 75, FUID); @@ -6154,6 +6275,7 @@ end; procedure TCorpse.Damage(Value: Word; vx, vy: Integer); var pm: TPlayerModel; + Blood: TModelBlood; begin if FState = CORPSE_STATE_REMOVEME then Exit; @@ -6176,16 +6298,23 @@ begin pm := g_PlayerModel_Get(FModelName); pm.PlaySound(MODELSOUND_DIE, 5, FObj.X, FObj.Y); pm.Free; + + // Çëîâåùèé ñìåõ: + if (gBodyKillEvent <> -1) + and gDelayedEvents[gBodyKillEvent].Pending then + gDelayedEvents[gBodyKillEvent].Pending := False; + gBodyKillEvent := g_Game_DelayEvent(DE_BODYKILL, 1050, 0); end; end else begin + Blood := g_PlayerModel_GetBlood(FModelName); FObj.Vel.X := FObj.Vel.X + vx; FObj.Vel.Y := FObj.Vel.Y + vy; g_GFX_Blood(FObj.X+PLAYER_CORPSERECT.X+(PLAYER_CORPSERECT.Width div 2), FObj.Y+PLAYER_CORPSERECT.Y+(PLAYER_CORPSERECT.Height div 2), Value, vx, vy, 16, (PLAYER_CORPSERECT.Height*2) div 3, - 150, 0, 0); + Blood.R, Blood.G, Blood.B, Blood.Kind); end; end; @@ -6259,6 +6388,7 @@ begin utils.writeInt(st, Byte(FColor.B)); // Îáúåêò òðóïà Obj_SaveState(st, @FObj); + utils.writeInt(st, Word(FPlayerUID)); // Åñòü ëè àíèìàöèÿ anim := (FAnimation <> nil); utils.writeBool(st, anim); @@ -6291,6 +6421,7 @@ begin FColor.B := utils.readByte(st); // Îáúåêò òðóïà Obj_LoadState(@FObj, st); + FPlayerUID := utils.readWord(st); // Åñòü ëè àíèìàöèÿ anim := utils.readBool(st); // Åñëè åñòü - çàãðóæàåì