diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index f4e3b0fff39acd98b14a65fa9bc9bcfe82bdb5d6..69cc9021fc74547423ced6a82f1c626c4155cb93 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
FDummy: Boolean;
FFireTime: Integer;
+ // debug: viewport offset
+ viewPortX, viewPortY, viewPortW, viewPortH: Integer;
+
+ function isValidViewPort (): Boolean; inline;
+
constructor Create(); virtual;
destructor Destroy(); override;
procedure Respawn(Silent: Boolean; Force: Boolean = False); virtual;
//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;
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, g_window, GL;
type
TBotProfile = record
{ T P l a y e r : }
+function TPlayer.isValidViewPort (): Boolean; inline; begin result := (viewPortW > 0) and (viewPortH > 0); end;
+
procedure TPlayer.BFGHit();
begin
g_Weapon_BFGHit(FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2),
constructor TPlayer.Create();
begin
+ viewPortX := 0;
+ viewPortY := 0;
+ viewPortW := 0;
+ viewPortH := 0;
+
FIamBot := False;
FDummy := False;
FSpawned := False;
DrawAim();
end;
+
+var
+ plrMouseX: Integer = -666;
+ plrMouseY: Integer = -666;
+ vpx, vpy: Integer;
+ //vpw, vph: Integer;
+ laserX0, laserY0, laserX1, laserY1: Integer;
+ monMarkedUID: Integer = -1;
+
+function pmsCurMapX (): Integer; inline; begin result := plrMouseX+vpx; end;
+function pmsCurMapY (): Integer; inline; begin result := plrMouseY+vpy; end;
+
+procedure plrDebugMouse (msx, msy, but: Integer; bstate: Integer);
+
+ function wallToggle (pan: TPanel; tag: Integer): Boolean;
+ begin
+ result := false; // don't stop
+ if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
+ end;
+
+ function monsAtDump (mon: TMonster; tag: Integer): Boolean;
+ begin
+ result := false; // don't stop
+ e_WriteLog(Format('monster #%d; UID=%d', [mon.arrIdx, mon.UID]), MSG_NOTIFY);
+ monMarkedUID := mon.UID;
+ //if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
+ end;
+
+begin
+ plrMouseX := msx;
+ plrMouseY := msy;
+ //e_WriteLog(Format('mouse: x=%d; y=%d; but=%d; bstate=%d', [msx, msy, but, bstate]), MSG_NOTIFY);
+ if (gPlayer1 = nil) then exit;
+
+ if (but = MouseLeft) then
+ begin
+ mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor));
+ exit;
+ end;
+
+ if (but = MouseRight) then
+ begin
+ monMarkedUID := -1;
+ e_WriteLog('===========================', MSG_NOTIFY);
+ monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, monsAtDump);
+ e_WriteLog('---------------------------', MSG_NOTIFY);
+ exit;
+ end;
+end;
+
+
+procedure plrDebugDrawMouse ();
+
+ 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(laserX0, laserY0, laserX1, laserY1, mx, my, mw, mh, ex, ey) then
+ begin
+ e_DrawPoint(8, ex, ey, 0, 255, 0);
+ end;
+ end;
+
+var
+ mon: TMonster;
+ mx, my, mw, mh: Integer;
+begin
+ e_DrawPoint(4, plrMouseX, plrMouseY, 255, 0, 255);
+ if (gPlayer1 = nil) then exit;
+
+ //e_WriteLog(Format('(%d,%d)-(%d,%d)', [laserX0, laserY0, laserX1, laserY1]), MSG_NOTIFY);
+
+ glPushMatrix();
+ glTranslatef(-vpx, -vpy, 0);
+
+ g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true);
+
+ if (monMarkedUID <> -1) then
+ begin
+ mon := g_Monsters_ByUID(monMarkedUID);
+ if (mon <> nil) then
+ begin
+ mon.getMapBox(mx, my, mw, mh);
+ e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 0, 0, 30);
+ end;
+ end;
+
+ //e_DrawPoint(16, laserX0, laserY0, 255, 255, 255);
+
+ glPopMatrix();
+end;
+
+
procedure TPlayer.DrawAim();
+ procedure drawCast (sz: Integer; ax0, ay0, ax1, ay1: Integer);
+
+ procedure drawTileGrid ();
+ var
+ x, y: Integer;
+ begin
+ y := mapGrid.gridY0;
+ while (y < mapGrid.gridY0+mapGrid.gridHeight) do
+ begin
+ x := mapGrid.gridX0;
+ while (x < mapGrid.gridX0+mapGrid.gridWidth) do
+ begin
+ if (x+mapGrid.tileSize > viewPortX) and (y+mapGrid.tileSize > viewPortY) and
+ (x < viewPortX+viewPortW) and (y < viewPortY+viewPortH) then
+ begin
+ e_DrawQuad(x, y, x+mapGrid.tileSize-1, y+mapGrid.tileSize-1, 96, 96, 96, 96);
+ end;
+ Inc(x, mapGrid.tileSize);
+ end;
+ Inc(y, mapGrid.tileSize);
+ end;
+ end;
+
+ var
+ ex, ey: Integer;
+ //mon: TMonster;
+ //mx, my, mw, mh: Integer;
+ begin
+ if isValidViewPort and (self = gPlayer1) then
+ begin
+ vpx := viewPortX;
+ vpy := viewPortY;
+ //vpw := viewPortW;
+ //vpy := viewPortH;
+ evMouseCB := plrDebugMouse;
+ postdrawMouse := plrDebugDrawMouse;
+ end;
+
+ laserX0 := ax0;
+ laserY0 := ay0;
+ laserX1 := ax1;
+ laserY1 := ay1;
+
+ e_DrawLine(sz, ax0, ay0, ax1, ay1, 255, 0, 0, 96);
+ if (g_Map_traceToNearestWall(ax0, ay0, ax1, ay1, @ex, @ey) <> nil) then
+ begin
+ e_DrawLine(sz, ax0, ay0, ex, ey, 0, 255, 0, 96);
+ 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;
+ }
+
+ drawTileGrid();
+ end;
+
var
wx, wy, xx, yy: Integer;
angle: SmallInt;
end;
xx := Trunc(Cos(-DegToRad(angle)) * len) + wx;
yy := Trunc(Sin(-DegToRad(angle)) * len) + wy;
+ {$IF DEFINED(D2F_DEBUG)}
+ drawCast(sz, wx, wy, xx, yy);
+ {$ELSE}
e_DrawLine(sz, wx, wy, xx, yy, 255, 0, 0, 96);
+ {$ENDIF}
end;
procedure TPlayer.DrawGUI();
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
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
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;
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,
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);
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;
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;
// Åñëè åñòü âîçìîæíûå öåëè:
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;
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;