X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=8981721df6bbddeb5e0cde76baa242b1e8c0cab6;hb=b79ddd98d923ee15f4bfd1db5111e669fc19964a;hp=f4e3b0fff39acd98b14a65fa9bc9bcfe82bdb5d6;hpb=0fdf4d69047801a6a8d789df6def4a47015e9ae4;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index f4e3b0f..8981721 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -314,6 +314,8 @@ type //WARNING! this does nothing for now, but still call it! procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right! + procedure getMapBox (out x, y, w, h: Integer); inline; + property Name: String read FName write FName; property Model: TPlayerModel read FModel; property Health: Integer read FHealth write FHealth; @@ -517,8 +519,9 @@ implementation uses e_log, g_map, g_items, g_console, SysUtils, g_gfx, Math, - g_options, g_triggers, g_menu, MAPDEF, g_game, - wadreader, g_main, g_monsters, CONFIG, g_language, g_net, g_netmsg; + g_options, g_triggers, g_menu, MAPDEF, g_game, g_grid, + wadreader, g_main, g_monsters, CONFIG, g_language, + g_net, g_netmsg; type TBotProfile = record @@ -2301,6 +2304,58 @@ begin end; procedure TPlayer.DrawAim(); + procedure drawCast (sz: Integer; ax0, ay0, ax1, ay1: Integer); + + function monsCollector (mon: TMonster; tag: Integer): Boolean; + var + ex, ey: Integer; + mx, my, mw, mh: Integer; + begin + result := false; + mon.getMapBox(mx, my, mw, mh); + e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 255, 0, 96); + if lineAABBIntersects(ax0, ay0, ax1, ay1, mx, my, mw, mh, ex, ey) then + begin + e_DrawPoint(8, ex, ey, 0, 255, 0); + end; + end; + + var + ex, ey: Integer; + //mon: TMonster; + //mx, my, mw, mh: Integer; + begin + e_DrawLine(sz, ax0, ay0, ax1, ay1, 255, 0, 0, 96); + if g_Map_traceToNearestWall(ax0, ay0, ax1, ay1, @ex, @ey) then + begin + e_DrawLine(sz, ax0, ay0, ex, ey, 0, 255, 0, 96); + e_DrawPoint(4, ex, ey, 255, 127, 0); + end + else + begin + e_DrawLine(sz, ax0, ay0, ex, ey, 0, 0, 255, 96); + end; + + { + mon := g_Mons_ByIdx(0); + mon.getMapBox(mx, my, mw, mh); + ax1 := mx+mw div 2; + ay1 := my+mh div 2; + e_DrawLine(2, ax0, ay0, ax1, ay1, 0, 96, 96, 96); + + if lineAABBIntersects(ax0, ay0, ax1, ay1, mx, my, mw, mh, ex, ey) then + begin + e_DrawLine(2, ax0, ay0, ex, ey, 255, 255, 0, 96); + end + else + begin + e_DrawLine(2, ax0, ay0, ex, ey, 255, 127, 0, 96); + end; + } + + g_Mons_AlongLine(ax0, ay0, ax1, ay1, monsCollector, true); + end; + var wx, wy, xx, yy: Integer; angle: SmallInt; @@ -2387,7 +2442,11 @@ begin end; xx := Trunc(Cos(-DegToRad(angle)) * len) + wx; yy := Trunc(Sin(-DegToRad(angle)) * len) + wy; + {$IF FALSE} e_DrawLine(sz, wx, wy, xx, yy, 255, 0, 0, 96); + {$ELSE} + drawCast(sz, wx, wy, xx, yy); + {$ENDIF} end; procedure TPlayer.DrawGUI(); @@ -2973,31 +3032,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 +3180,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 @@ -4811,7 +4872,7 @@ begin DecMin(FPain, 5, 0); DecMin(FPickup, 1, 0); - if FLive and (FObj.Y > gMapInfo.Height+128) and AnyServer then + if FLive and (FObj.Y > Integer(gMapInfo.Height)+128) and AnyServer then begin // Îáíóëèòü äåéñòâèÿ ïðèìî÷åê, ÷òîáû ôîí ïðîïàë FMegaRulez[MR_SUIT] := 0; @@ -4996,6 +5057,14 @@ begin if FKeys[b].Time = 0 then FKeys[b].Pressed := False else Dec(FKeys[b].Time); end; +procedure TPlayer.getMapBox (out x, y, w, h: Integer); inline; +begin + x := FObj.X+PLAYER_RECT.X; + y := FObj.Y+PLAYER_RECT.Y; + w := PLAYER_RECT.Width; + h := 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 +6369,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 +6460,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 +6533,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 +6693,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 +7445,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;