X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=f277a4e8ab74fa5ce9992b49c8af0b215c4e5e27;hb=4c4a0406b07cdfd5051e388e8b00f02e008ed140;hp=f4e3b0fff39acd98b14a65fa9bc9bcfe82bdb5d6;hpb=0fdf4d69047801a6a8d789df6def4a47015e9ae4;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index f4e3b0f..f277a4e 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -21,7 +21,7 @@ interface uses e_graphics, g_playermodel, g_basic, g_textures, g_weapons, g_phys, g_sound, g_saveload, MAPSTRUCT, - BinEditor, g_panel; + BinEditor, g_panel, z_aabbtree; const KEY_LEFT = 1; @@ -222,6 +222,8 @@ type procedure resetWeaponQueue (); function hasAmmoForWeapon (weapon: Byte): Boolean; + function getMapAABB (): AABB2D; + public FDamageBuffer: Integer; @@ -346,6 +348,8 @@ type property UID: Word read FUID write FUID; property JustTeleported: Boolean read FJustTeleported write FJustTeleported; property NetTime: LongWord read FNetTime write FNetTime; + + property mapAABB: AABB2D read getMapAABB; end; TDifficult = record @@ -2973,31 +2977,33 @@ var DoFrags: Boolean; OldLR: Byte; KP: TPlayer; + it: PItem; procedure PushItem(t: Byte); var id: DWORD; begin id := g_Items_Create(FObj.X, FObj.Y, t, True, False); + it := g_Items_ByIdx(id); if KillType = K_EXTRAHARDKILL then // -7..+7; -8..0 begin - g_Obj_Push(@gItems[id].Obj, (FObj.Vel.X div 2)-7+Random(15), - (FObj.Vel.Y div 2)-Random(9)); - gItems[id].positionChanged(); // this updates spatial accelerators + g_Obj_Push(@it.Obj, (FObj.Vel.X div 2)-7+Random(15), + (FObj.Vel.Y div 2)-Random(9)); + it.positionChanged(); // this updates spatial accelerators end else begin if KillType = K_HARDKILL then // -5..+5; -5..0 begin - g_Obj_Push(@gItems[id].Obj, (FObj.Vel.X div 2)-5+Random(11), - (FObj.Vel.Y div 2)-Random(6)); + g_Obj_Push(@it.Obj, (FObj.Vel.X div 2)-5+Random(11), + (FObj.Vel.Y div 2)-Random(6)); end else // -3..+3; -3..0 begin - g_Obj_Push(@gItems[id].Obj, (FObj.Vel.X div 2)-3+Random(7), - (FObj.Vel.Y div 2)-Random(4)); + g_Obj_Push(@it.Obj, (FObj.Vel.X div 2)-3+Random(7), + (FObj.Vel.Y div 2)-Random(4)); end; - gItems[id].positionChanged(); // this updates spatial accelerators + it.positionChanged(); // this updates spatial accelerators end; if g_Game_IsNet and g_Game_IsServer then @@ -3119,7 +3125,7 @@ begin end else if g_GetUIDType(SpawnerUID) = UID_MONSTER then begin // Óáèò ìîíñòðîì - mon := g_Monsters_Get(SpawnerUID); + mon := g_Monsters_ByUID(SpawnerUID); if mon = nil then s := '?' else @@ -4996,6 +5002,11 @@ begin if FKeys[b].Time = 0 then FKeys[b].Pressed := False else Dec(FKeys[b].Time); end; +function TPlayer.getMapAABB (): AABB2D; inline; +begin + result := AABB2D.CreateWH(FObj.X+PLAYER_RECT.X, FObj.Y+PLAYER_RECT.Y, PLAYER_RECT.Width, PLAYER_RECT.Height); +end; + function TPlayer.Collide(X, Y: Integer; Width, Height: Word): Boolean; begin Result := g_Collide(FObj.X+PLAYER_RECT.X, @@ -6300,6 +6311,41 @@ var mon: TMonster; pla, tpla: TPlayer; vsPlayer, vsMonster, ok: Boolean; + + + function monsUpdate (mon: TMonster): Boolean; + begin + result := false; // don't stop + if mon.Live and (mon.MonsterType <> MONSTER_BARREL) then + begin + if not TargetOnScreen(mon.Obj.X+mon.Obj.Rect.X, mon.Obj.Y+mon.Obj.Rect.Y) then exit; + + x2 := mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2); + y2 := mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2); + + // Åñëè ìîíñòð íà ýêðàíå è íå ïðèêðûò ñòåíîé + if g_TraceVector(x1, y1, x2, y2) then + begin + // Äîáàâëÿåì ê ñïèñêó âîçìîæíûõ öåëåé + SetLength(targets, Length(targets)+1); + with targets[High(targets)] do + begin + UID := mon.UID; + X := mon.Obj.X; + Y := mon.Obj.Y; + cX := x2; + cY := y2; + Rect := mon.Obj.Rect; + Dist := g_PatchLength(x1, y1, x2, y2); + Line := (y1+4 < Target.Y + mon.Obj.Rect.Y + mon.Obj.Rect.Height) and + (y1-4 > Target.Y + mon.Obj.Rect.Y); + Visible := True; + IsPlayer := False; + end; + end; + end; + end; + begin vsPlayer := LongBool(gGameSettings.Options and GAME_OPTION_BOTVSPLAYER); vsMonster := LongBool(gGameSettings.Options and GAME_OPTION_BOTVSMONSTER); @@ -6356,7 +6402,7 @@ begin if (g_GetUIDType(Target.UID) = UID_MONSTER) and vsMonster then begin // Ìîíñòð - mon := g_Monsters_Get(Target.UID); + mon := g_Monsters_ByUID(Target.UID); if mon <> nil then begin Target.X := mon.Obj.X; @@ -6429,41 +6475,7 @@ begin end; // Ìîíñòðû: - if vsMonster and (gMonsters <> nil) then - for a := 0 to High(gMonsters) do - if (gMonsters[a] <> nil) and (gMonsters[a].Live) and - (gMonsters[a].MonsterType <> MONSTER_BARREL) then - begin - mon := gMonsters[a]; - - if not TargetOnScreen(mon.Obj.X + mon.Obj.Rect.X, - mon.Obj.Y + mon.Obj.Rect.Y) then - Continue; - - x2 := mon.Obj.X + mon.Obj.Rect.X + (mon.Obj.Rect.Width div 2); - y2 := mon.Obj.Y + mon.Obj.Rect.Y + (mon.Obj.Rect.Height div 2); - - // Åñëè ìîíñòð íà ýêðàíå è íå ïðèêðûò ñòåíîé: - if g_TraceVector(x1, y1, x2, y2) then - begin - // Äîáàâëÿåì ê ñïèñêó âîçìîæíûõ öåëåé: - SetLength(targets, Length(targets)+1); - with targets[High(targets)] do - begin - UID := mon.UID; - X := mon.Obj.X; - Y := mon.Obj.Y; - cX := x2; - cY := y2; - Rect := mon.Obj.Rect; - Dist := g_PatchLength(x1, y1, x2, y2); - Line := (y1+4 < Target.Y + mon.Obj.Rect.Y + mon.Obj.Rect.Height) and - (y1-4 > Target.Y + mon.Obj.Rect.Y); - Visible := True; - IsPlayer := False; - end; - end; - end; + if vsMonster then g_Mons_ForEach(monsUpdate); end; // Åñëè åñòü âîçìîæíûå öåëè: @@ -6623,7 +6635,7 @@ begin end else begin // Öåëü - ìîíñòð - mon := g_Monsters_Get(Target.UID); + mon := g_Monsters_ByUID(Target.UID); if (mon = nil) or (not mon.Live) then Target.UID := 0; // òî çàáûòü öåëü end; @@ -7375,7 +7387,7 @@ begin if (g_GetUIDType(FLastSpawnerUID) = UID_MONSTER) and LongBool(gGameSettings.Options and GAME_OPTION_BOTVSMONSTER) then begin // Ìîíñòð - mon := g_Monsters_Get(FLastSpawnerUID); + mon := g_Monsters_ByUID(FLastSpawnerUID); ok := not TargetOnScreen(mon.Obj.X + mon.Obj.Rect.X, mon.Obj.Y + mon.Obj.Rect.Y); end;