diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index d03247cdc5e4e3f2505078aa28ccd5f165f70f55..2b7fec91097ceb5f23aef7edde48d186ff294ab1 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
-{$MODE DELPHI}
+{$INCLUDE ../shared/a_modes.inc}
unit g_player;
interface
FObj: TObj;
FXTo, FYTo: Integer;
FSpectatePlayer: Integer;
+ FFirePainTime: Integer;
+ FFireAttacker: Word;
FSavedState: TPlayerSavedState;
function FullInLift(XInc, YInc: Integer): Integer;
{procedure CollideItem();}
procedure FlySmoke(Times: DWORD = 1);
+ procedure OnFireFlame(Times: DWORD = 1);
function GetAmmoByWeapon(Weapon: Byte): Word;
procedure SetAction(Action: Byte; Force: Boolean = False);
procedure OnDamage(Angle: SmallInt); virtual;
FPing: Word;
FLoss: Byte;
FDummy: Boolean;
+ FFireTime: Integer;
constructor Create(); virtual;
destructor Destroy(); override;
procedure SetWeapon(W: Byte);
function IsKeyPressed(K: Byte): Boolean;
function GetKeys(): Byte;
- function PickItem(ItemType: Byte; respawn: Boolean; var remove: Boolean): Boolean; virtual;
+ function PickItem(ItemType: Byte; arespawn: Boolean; var remove: Boolean): Boolean; virtual;
function Collide(X, Y: Integer; Width, Height: Word): Boolean; overload;
function Collide(Panel: TPanel): Boolean; overload;
function Collide(X, Y: Integer): Boolean; overload;
procedure RealizeCurrentWeapon();
procedure JetpackOn;
procedure JetpackOff;
+ procedure CatchFire(Attacker: Word);
+
+ //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!
property Name: String read FName write FName;
property Model: TPlayerModel read FModel;
function FullInStep(XInc, YInc: Integer): Boolean;
//function NeedItem(Item: Byte): Byte;
procedure SelectWeapon(Dist: Integer);
- procedure SetAIFlag(fName, fValue: String20);
- function GetAIFlag(fName: String20): String20;
- procedure RemoveAIFlag(fName: String20);
+ procedure SetAIFlag(aName, fValue: String20);
+ function GetAIFlag(aName: String20): String20;
+ procedure RemoveAIFlag(aName: String20);
function Healthy(): Byte;
procedure UpdateMove();
procedure UpdateCombat();
RAngle: Integer;
Color: TRGB;
Obj: TObj;
+
+ procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
end;
+
TShell = record
SpriteID: DWORD;
Live: Boolean;
Timeout: Cardinal;
CX, CY: Integer;
Obj: TObj;
+
+ procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
end;
TCorpse = class (TObject)
procedure SaveState(var Mem: TBinMemoryWriter);
procedure LoadState(var Mem: TBinMemoryReader);
+ procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
+
property Obj: TObj read FObj;
property State: Byte read FState;
property Mess: Boolean read FMess;
// WEAPON_CHAINGUN, WEAPON_SHOTGUN1, WEAPON_SAW,
// WEAPON_ROCKETLAUNCHER, WEAPON_PISTOL, WEAPON_KASTET);
WEAPON_RELOAD: Array [WP_FIRST..WP_LAST] of Byte =
- (5, 2, 6, 18, 36, 2, 12, 2, 14, 2, 0);
+ (5, 2, 6, 18, 36, 2, 12, 2, 14, 2, 2);
PLAYER_SIGNATURE = $52594C50; // 'PLYR'
CORPSE_SIGNATURE = $50524F43; // 'CORP'
BotNames: Array of String;
BotList: Array of TBotProfile;
+
+procedure TGib.positionChanged (); begin end;
+procedure TShell.positionChanged (); begin end;
+
+
function Lerp(X, Y, Factor: Integer): Integer;
begin
Result := X + ((Y - X) div Factor);
Obj.X := fX;
Obj.Y := fY;
g_Obj_Push(@Obj, dX + Random(4)-Random(4), dY-Random(4));
+ positionChanged(); // this updates spatial accelerators
RAngle := Random(360);
Timeout := gTime + SHELL_TIMEOUT;
Obj.X := fX-GibsArray[a].Rect.X-(GibsArray[a].Rect.Width div 2);
Obj.Y := fY-GibsArray[a].Rect.Y-(GibsArray[a].Rect.Height div 2);
g_Obj_PushA(@Obj, 25 + Random(10), Random(361));
+ positionChanged(); // this updates spatial accelerators
RAngle := Random(360);
if gBloodCount > 0 then
begin
vel := Obj.Vel;
mr := g_Obj_Move(@Obj, True, False, True);
+ positionChanged(); // this updates spatial accelerators
if WordBool(mr and MOVE_FALLOUT) then
begin
begin
vel := Obj.Vel;
mr := g_Obj_Move(@Obj, True, False, True);
+ positionChanged(); // this updates spatial accelerators
if WordBool(mr and MOVE_FALLOUT) or (gShells[i].Timeout < gTime) then
begin
procedure TPlayer.ChangeModel(ModelName: string);
var
- Model: TPlayerModel;
+ locModel: TPlayerModel;
begin
- Model := g_PlayerModel_Get(ModelName);
- if Model = nil then Exit;
+ locModel := g_PlayerModel_Get(ModelName);
+ if locModel = nil then Exit;
FModel.Free();
- FModel := Model;
+ FModel := locModel;
end;
procedure TPlayer.SetModel(ModelName: string);
FLoss := 0;
FSavedState.WaitRecall := False;
FShellTimer := -1;
+ FFireTime := 0;
+ FFirePainTime := 0;
+ FFireAttacker := 0;
FActualModelName := 'doomer';
resetWeaponQueue();
end;
+procedure TPlayer.positionChanged ();
+begin
+end;
+
procedure TPlayer.Damage(value: Word; SpawnerUID: Word; vx, vy: Integer; t: Byte);
var
c: Word;
var
f, DidFire: Boolean;
wx, wy, xd, yd: Integer;
- obj: TObj;
+ locobj: TObj;
begin
if g_Game_IsClient then Exit;
// FBFGFireCounter - âðåìÿ ïåðåä âûñòðåëîì (äëÿ BFG)
if R_BERSERK in FRulez then
begin
//g_Weapon_punch(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, 75, FUID);
- obj.X := FObj.X+FObj.Rect.X;
- obj.Y := FObj.Y+FObj.Rect.Y;
- obj.rect.X := 0;
- obj.rect.Y := 0;
- obj.rect.Width := 39;
- obj.rect.Height := 52;
- obj.Vel.X := (xd-wx) div 2;
- obj.Vel.Y := (yd-wy) div 2;
- obj.Accel.X := xd-wx;
- obj.Accel.y := yd-wy;
-
- if g_Weapon_Hit(@obj, 50, FUID, HIT_SOME) <> 0 then
+ locobj.X := FObj.X+FObj.Rect.X;
+ locobj.Y := FObj.Y+FObj.Rect.Y;
+ locobj.rect.X := 0;
+ locobj.rect.Y := 0;
+ locobj.rect.Width := 39;
+ locobj.rect.Height := 52;
+ locobj.Vel.X := (xd-wx) div 2;
+ locobj.Vel.Y := (yd-wy) div 2;
+ locobj.Accel.X := xd-wx;
+ locobj.Accel.y := yd-wy;
+
+ if g_Weapon_Hit(@locobj, 50, FUID, HIT_SOME) <> 0 then
g_Sound_PlayExAt('SOUND_WEAPON_HITBERSERK', FObj.X, FObj.Y)
else
g_Sound_PlayExAt('SOUND_WEAPON_MISSBERSERK', FObj.X, FObj.Y);
WEAPON_FLAMETHROWER:
if FAmmo[A_FUEL] > 0 then
begin
+ g_Weapon_flame(wx, wy, xd, yd, FUID);
FReloading[FCurrWeap] := WEAPON_RELOAD[FCurrWeap];
Dec(FAmmo[A_FUEL]);
FFireAngle := FAngle;
FJetSoundOff.PlayAt(FObj.X, FObj.Y);
end;
+procedure TPlayer.CatchFire(Attacker: Word);
+begin
+ FFireTime := 100;
+ FFireAttacker := Attacker;
+ if g_Game_IsNet and g_Game_IsServer then
+ MH_SEND_PlayerStats(FUID);
+end;
+
procedure TPlayer.Jump();
begin
if gFly or FJetpack then
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
- g_Obj_Push(@gItems[id].Obj, (FObj.Vel.X div 2)-7+Random(15),
- (FObj.Vel.Y div 2)-Random(9))
+ begin
+ 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
- g_Obj_Push(@gItems[id].Obj, (FObj.Vel.X div 2)-5+Random(11),
- (FObj.Vel.Y div 2)-Random(6))
+ begin
+ 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
- g_Obj_Push(@gItems[id].Obj, (FObj.Vel.X div 2)-3+Random(7),
- (FObj.Vel.Y div 2)-Random(4));
+ begin
+ g_Obj_Push(@it.Obj, (FObj.Vel.X div 2)-3+Random(7),
+ (FObj.Vel.Y div 2)-Random(4));
+ end;
+ it.positionChanged(); // this updates spatial accelerators
+ end;
if g_Game_IsNet and g_Game_IsServer then
MH_SEND_ItemSpawn(True, id);
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
begin
result := 255; // default result: "no switch"
// had weapon cycling on previous frame? remove that flag
- if (FNextWeap and $2000) <> 0 then begin FNextWeap := FNextWeap and $1FFF; FNextWeapDelay := 0; end;
+ if (FNextWeap and $2000) <> 0 then
+ begin
+ FNextWeap := FNextWeap and $1FFF;
+ FNextWeapDelay := 0;
+ end;
// cycling has priority
if (FNextWeap and $C000) <> 0 then
begin
- if (FNextWeap and $8000) <> 0 then dir := 1 else dir := -1;
+ if (FNextWeap and $8000) <> 0 then
+ dir := 1
+ else
+ dir := -1;
FNextWeap := FNextWeap or $2000; // we need this
- if FNextWeapDelay > 0 then exit; // cooldown time
+ if FNextWeapDelay > 0 then
+ exit; // cooldown time
cwi := FCurrWeap;
for i := 0 to High(FWeapon) do
begin
exit;
end;
// no cycling
- for i := 0 to High(wantThisWeapon) do wantThisWeapon[i] := false;
- for i := 0 to High(FWeapon) do if (FNextWeap and (1 shl i)) <> 0 then begin wantThisWeapon[i] := true; Inc(wwc); end;
+ for i := 0 to High(wantThisWeapon) do
+ wantThisWeapon[i] := false;
+ for i := 0 to High(FWeapon) do
+ if (FNextWeap and (1 shl i)) <> 0 then
+ begin
+ wantThisWeapon[i] := true;
+ Inc(wwc);
+ end;
// exclude currently selected weapon from the set
wantThisWeapon[FCurrWeap] := false;
// slow down alterations a little
begin
//e_WriteLog(Format(' FNextWeap=%x; delay=%d', [FNextWeap, FNextWeapDelay]), MSG_WARNING);
// more than one weapon requested, assume "alteration" and check alteration delay
- if FNextWeapDelay > 0 then begin FNextWeap := 0; exit; end; // yeah
+ if FNextWeapDelay > 0 then
+ begin
+ FNextWeap := 0;
+ exit;
+ end; // yeah
end;
// do not reset weapon queue, it will be done in `RealizeCurrentWeapon()`
// but clear all counters if no weapon should be switched
- if wwc < 1 then begin resetWeaponQueue(); exit; end;
+ if wwc < 1 then
+ begin
+ resetWeaponQueue();
+ exit;
+ end;
//e_WriteLog(Format('wwc=%d', [wwc]), MSG_WARNING);
// try weapons in descending order
for i := High(FWeapon) downto 0 do
resetWeaponQueue();
end;
-function TPlayer.PickItem(ItemType: Byte; respawn: Boolean; var remove: Boolean): Boolean;
+function TPlayer.PickItem(ItemType: Byte; arespawn: Boolean; var remove: Boolean): Boolean;
var
a: Boolean;
begin
if g_Game_IsClient then Exit;
// a = true - ìåñòî ñïàâíà ïðåäìåòà:
- a := LongBool(gGameSettings.Options and GAME_OPTION_WEAPONSTAY) and respawn;
+ a := LongBool(gGameSettings.Options and GAME_OPTION_WEAPONSTAY) and arespawn;
remove := not a;
case ItemType of
IncMax(FHealth, 10, PLAYER_HP_SOFT);
Result := True;
remove := True;
+ FFireTime := 0;
if gFlash = 2 then Inc(FPickup, 5);
end;
IncMax(FHealth, 25, PLAYER_HP_SOFT);
Result := True;
remove := True;
+ FFireTime := 0;
if gFlash = 2 then Inc(FPickup, 5);
end;
IncMax(FHealth, 100, PLAYER_HP_LIMIT);
Result := True;
remove := True;
+ FFireTime := 0;
if gFlash = 2 then Inc(FPickup, 5);
end;
FArmor := PLAYER_AP_LIMIT;
Result := True;
remove := True;
+ FFireTime := 0;
if gFlash = 2 then Inc(FPickup, 5);
end;
ITEM_WEAPON_SAW:
- if (not FWeapon[WEAPON_SAW]) or ((not respawn) and (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF])) then
+ if (not FWeapon[WEAPON_SAW]) or ((not arespawn) and (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF])) then
begin
FWeapon[WEAPON_SAW] := True;
Result := True;
FMegaRulez[MR_SUIT] := gTime+PLAYER_SUIT_TIME;
Result := True;
remove := True;
+ FFireTime := 0;
if gFlash = 2 then Inc(FPickup, 5);
end;
FBerserk := gTime+30000;
Result := True;
remove := True;
+ FFireTime := 0;
end;
if FHealth < PLAYER_HP_SOFT then
begin
FBerserk := gTime+30000;
Result := True;
remove := True;
+ FFireTime := 0;
end;
end;
IncMax(FHealth, 4, PLAYER_HP_LIMIT);
Result := True;
remove := True;
+ FFireTime := 0;
if gFlash = 2 then Inc(FPickup, 5);
end;
FDamageBuffer := 0;
FJetpack := False;
FCanJetpack := False;
+ FFireTime := 0;
+ FFirePainTime := 0;
+ FFireAttacker := 0;
// Àíèìàöèÿ âîçðîæäåíèÿ:
if (not gLoadGameMode) and (not Silent) then
b := Abs(FObj.Vel.X);
if b > 1 then b := b * (Random(8 div b) + 1);
for a := 0 to High(gGibs) do
+ begin
if gGibs[a].Live and
g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4,
FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then
+ begin
// Ïèíàåì êóñêè
if FObj.Vel.X < 0 then
+ begin
g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120) // íàëåâî
+ end
else
+ begin
g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // íàïðàâî
+ end;
+ gGibs[a].positionChanged(); // this updates spatial accelerators
+ end;
+ end;
end;
SetAction(A_WALK);
end;
if FPhysics then
+ begin
g_Obj_Move(@FObj, True, True, True);
+ positionChanged(); // this updates spatial accelerators
+ end;
Exit;
end;
end;
if FPhysics then
- g_Obj_Move(@FObj, True, True, True)
+ begin
+ g_Obj_Move(@FObj, True, True, True);
+ positionChanged(); // this updates spatial accelerators
+ end
else
begin
FObj.Vel.X := 0;
end else if FAir < AIR_DEF then
FAir := AIR_DEF;
+ if FFireTime > 0 then
+ begin
+ if BodyInLiquid(0, 0) then
+ begin
+ FFireTime := 0;
+ FFirePainTime := 0;
+ end
+ else if FMegaRulez[MR_SUIT] >= gTime then
+ begin
+ if FMegaRulez[MR_SUIT] = gTime then
+ FFireTime := 1;
+ FFirePainTime := 0;
+ end
+ else
+ begin
+ OnFireFlame(1);
+ if FFirePainTime <= 0 then
+ begin
+ if g_Game_IsServer then
+ Damage(5, FFireAttacker, 0, 0, HIT_FLAME);
+ FFirePainTime := 18;
+ end;
+ FFirePainTime := FFirePainTime - 1;
+ FFireTime := FFireTime - 1;
+ if (FFireTime = 0) and g_Game_IsNet and g_Game_IsServer then
+ MH_SEND_PlayerStats(FUID);
+ end;
+ end;
+
if FDamageBuffer > 0 then
begin
if FDamageBuffer >= 9 then
procedure TPlayer.NetFire(Wpn: Byte; X, Y, AX, AY: Integer; WID: Integer = -1);
var
- Obj: TObj;
+ locObj: TObj;
F: Boolean;
WX, WY, XD, YD: Integer;
begin
if R_BERSERK in FRulez then
begin
//g_Weapon_punch(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, 75, FUID);
- obj.X := FObj.X+FObj.Rect.X;
- obj.Y := FObj.Y+FObj.Rect.Y;
- obj.rect.X := 0;
- obj.rect.Y := 0;
- obj.rect.Width := 39;
- obj.rect.Height := 52;
- obj.Vel.X := (xd-wx) div 2;
- obj.Vel.Y := (yd-wy) div 2;
- obj.Accel.X := xd-wx;
- obj.Accel.y := yd-wy;
-
- if g_Weapon_Hit(@obj, 50, FUID, HIT_SOME) <> 0 then
+ locobj.X := FObj.X+FObj.Rect.X;
+ locobj.Y := FObj.Y+FObj.Rect.Y;
+ locobj.rect.X := 0;
+ locobj.rect.Y := 0;
+ locobj.rect.Width := 39;
+ locobj.rect.Height := 52;
+ locobj.Vel.X := (xd-wx) div 2;
+ locobj.Vel.Y := (yd-wy) div 2;
+ locobj.Accel.X := xd-wx;
+ locobj.Accel.y := yd-wy;
+
+ if g_Weapon_Hit(@locobj, 50, FUID, HIT_SOME) <> 0 then
g_Sound_PlayExAt('SOUND_WEAPON_HITBERSERK', FObj.X, FObj.Y)
else
g_Sound_PlayExAt('SOUND_WEAPON_MISSBERSERK', FObj.X, FObj.Y);
WEAPON_FLAMETHROWER:
begin
+ g_Weapon_flame(wx, wy, xd, yd, FUID, WID);
FFireAngle := FAngle;
f := True;
end;
Count := FLAG_TIME;
g_Obj_Push(@Obj, (FObj.Vel.X div 2)-2+Random(5),
(FObj.Vel.Y div 2)-2+Random(5));
+ positionChanged(); // this updates spatial accelerators
if FFlag = FLAG_RED then
s := _lc[I_PLAYER_FLAG_RED]
end;
end;
+procedure TPlayer.OnFireFlame(Times: DWORD = 1);
+var
+ id, i: DWORD;
+ Anim: TAnimation;
+begin
+ if (Random(10) = 1) and (Times = 1) then
+ Exit;
+
+ if g_Frames_Get(id, 'FRAMES_FLAME') then
+ begin
+ for i := 1 to Times do
+ begin
+ Anim := TAnimation.Create(id, False, 3);
+ Anim.Alpha := 0;
+ g_GFX_OnceAnim(Obj.X+Obj.Rect.X+Random(Obj.Rect.Width+Times*2)-(Anim.Width div 2),
+ Obj.Y+8+Random(8+Times*2), Anim, ONCEANIM_SMOKE);
+ Anim.Free();
+ end;
+ end;
+end;
+
procedure TPlayer.PauseSounds(Enable: Boolean);
begin
FSawSound.Pause(Enable);
inherited;
end;
+procedure TCorpse.positionChanged (); begin end;
+
procedure TCorpse.Damage(Value: Word; vx, vy: Integer);
var
pm: TPlayerModel;
if gTime mod (GAME_TICK*2) <> 0 then
begin
g_Obj_Move(@FObj, True, True, True);
-
+ positionChanged(); // this updates spatial accelerators
Exit;
end;
FObj.Vel.X := z_dec(FObj.Vel.X, 1);
st := g_Obj_Move(@FObj, True, True, True);
+ positionChanged(); // this updates spatial accelerators
if WordBool(st and MOVE_FALLOUT) then
begin
firew, fireh: Integer;
angle: SmallInt;
mon: TMonster;
- pla: TPlayer;
+ 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_PLAYER) and
vsPlayer then
begin // Èãðîê
- with g_Player_Get(Target.UID) do
- begin
- if (@FObj) <> nil then
+ tpla := g_Player_Get(Target.UID);
+ if tpla <> nil then
+ with tpla do
begin
- Target.X := FObj.X;
- Target.Y := FObj.Y;
+ if (@FObj) <> nil then
+ begin
+ Target.X := FObj.X;
+ Target.Y := FObj.Y;
+ end;
end;
- end;
Target.cX := Target.X + PLAYER_RECT_CX;
Target.cY := Target.Y + PLAYER_RECT_CY;
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;
Result := FKeys[Key].Pressed;
end;
-function TBot.GetAIFlag(fName: String20): String20;
+function TBot.GetAIFlag(aName: String20): String20;
var
a: Integer;
begin
Result := '';
- fName := LowerCase(fName);
+ aName := LowerCase(aName);
if FAIFlags <> nil then
for a := 0 to High(FAIFlags) do
- if LowerCase(FAIFlags[a].Name) = fName then
+ if LowerCase(FAIFlags[a].Name) = aName then
begin
Result := FAIFlags[a].Value;
Break;
end;
end;
-procedure TBot.RemoveAIFlag(fName: String20);
+procedure TBot.RemoveAIFlag(aName: String20);
var
a, b: Integer;
begin
if FAIFlags = nil then Exit;
- fName := LowerCase(fName);
+ aName := LowerCase(aName);
for a := 0 to High(FAIFlags) do
- if LowerCase(FAIFlags[a].Name) = fName then
+ if LowerCase(FAIFlags[a].Name) = aName then
begin
if a <> High(FAIFlags) then
for b := a to High(FAIFlags)-1 do
end;
end;
-procedure TBot.SetAIFlag(fName, fValue: String20);
+procedure TBot.SetAIFlag(aName, fValue: String20);
var
a: Integer;
ok: Boolean;
a := 0;
ok := False;
- fName := LowerCase(fName);
+ aName := LowerCase(aName);
if FAIFlags <> nil then
for a := 0 to High(FAIFlags) do
- if LowerCase(FAIFlags[a].Name) = fName then
+ if LowerCase(FAIFlags[a].Name) = aName then
begin
ok := True;
Break;
SetLength(FAIFlags, Length(FAIFlags)+1);
with FAIFlags[High(FAIFlags)] do
begin
- Name := fName;
+ Name := aName;
Value := fValue;
end;
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;