diff --git a/src/game/g_items.pas b/src/game/g_items.pas
index 07c4df2b1d8e929832c6ac67b97f548de27b3d4d..6c8041ddd97bfe0ba46c4e2081f5dd1ffd8ab866 100644 (file)
--- a/src/game/g_items.pas
+++ b/src/game/g_items.pas
procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
+ property used: Boolean read slotIsUsed;
property myid: Integer read arrIdx;
end;
property myid: Integer read arrIdx;
end;
function g_Items_Create(X, Y: Integer; ItemType: Byte;
Fall, Respawnable: Boolean; AdjCoord: Boolean = False; ForcedID: Integer = -1): DWORD;
procedure g_Items_SetDrop (ID: DWORD);
function g_Items_Create(X, Y: Integer; ItemType: Byte;
Fall, Respawnable: Boolean; AdjCoord: Boolean = False; ForcedID: Integer = -1): DWORD;
procedure g_Items_SetDrop (ID: DWORD);
+procedure g_Items_PreUpdate();
procedure g_Items_Update();
procedure g_Items_Update();
-procedure g_Items_Draw();
-procedure g_Items_DrawDrop();
procedure g_Items_Pick(ID: DWORD);
procedure g_Items_Remove(ID: DWORD);
procedure g_Items_SaveState (st: TStream);
procedure g_Items_Pick(ID: DWORD);
procedure g_Items_Remove(ID: DWORD);
procedure g_Items_SaveState (st: TStream);
var
gItemsTexturesID: Array [1..ITEM_MAX] of DWORD;
gMaxDist: Integer = 1; // for sounds
var
gItemsTexturesID: Array [1..ITEM_MAX] of DWORD;
gMaxDist: Integer = 1; // for sounds
- ITEM_RESPAWNTIME: Integer = 60 * 36;
+
+ var (* private state *)
+ ggItems: Array of TItem = nil;
implementation
uses
Math,
implementation
uses
Math,
- g_basic, e_graphics, g_sound, g_main, g_gfx, g_map,
+ g_basic, g_sound, g_gfx, g_map,
g_game, g_triggers, g_console, g_player, g_net, g_netmsg,
g_game, g_triggers, g_console, g_player, g_net, g_netmsg,
- e_log,
+ e_log, g_options,
g_grid, binheap, idpool, utils, xstreams;
g_grid, binheap, idpool, utils, xstreams;
-
-var
- ggItems: Array of TItem = nil;
-
-
// ////////////////////////////////////////////////////////////////////////// //
var
freeIds: TIdPool = nil;
// ////////////////////////////////////////////////////////////////////////// //
var
freeIds: TIdPool = nil;
it.slotIsUsed := true;
it.ItemType := ItemType;
it.slotIsUsed := true;
it.ItemType := ItemType;
- if g_Game_IsServer and ((ITEM_RESPAWNTIME = 0) or not LongBool(gGameSettings.Options and GAME_OPTION_RESPAWNITEMS)) then
- it.Respawnable := False
- else
- it.Respawnable := Respawnable;
+ it.Respawnable := Respawnable;
it.InitX := X;
it.InitY := Y;
it.RespawnTime := 0;
it.InitX := X;
it.InitY := Y;
it.RespawnTime := 0;
end;
end;
end;
end;
+ it.Obj.oldX := it.Obj.X;
+ it.Obj.oldY := it.Obj.Y;
+
// Óñòàíîâêà àíèìàöèè
case it.ItemType of
ITEM_ARMOR_GREEN: if g_Frames_Get(ID, 'FRAMES_ITEM_ARMORGREEN') then it.Animation := TAnimation.Create(ID, True, 20);
// Óñòàíîâêà àíèìàöèè
case it.ItemType of
ITEM_ARMOR_GREEN: if g_Frames_Get(ID, 'FRAMES_ITEM_ARMORGREEN') then it.Animation := TAnimation.Create(ID, True, 20);
result := find_id;
end;
result := find_id;
end;
+procedure g_Items_PreUpdate ();
+var
+ i: Integer;
+begin
+ if (ggItems = nil) then Exit;
+ for i := 0 to High(ggItems) do
+ if (ggItems[i].ItemType <> ITEM_NONE) and ggItems[i].slotIsUsed then
+ begin
+ ggItems[i].Obj.oldX := ggItems[i].Obj.X;
+ ggItems[i].Obj.oldY := ggItems[i].Obj.Y;
+ end;
+end;
procedure g_Items_Update ();
var
i, j, k: Integer;
ID: DWord;
Anim: TAnimation;
procedure g_Items_Update ();
var
i, j, k: Integer;
ID: DWord;
Anim: TAnimation;
- m: Word;
+ m, ItemRespawnTime: Word;
r, nxt: Boolean;
begin
if (ggItems = nil) then exit;
r, nxt: Boolean;
begin
if (ggItems = nil) then exit;
+ // respawn items in 15 seconds regardless of settings during warmup
+ ItemRespawnTime := IfThen(gLMSRespawn = LMS_RESPAWN_NONE, gGameSettings.ItemRespawnTime, 15);
+
for i := 0 to High(ggItems) do
begin
if (ggItems[i].ItemType = ITEM_NONE) then continue;
for i := 0 to High(ggItems) do
begin
if (ggItems[i].ItemType = ITEM_NONE) then continue;
// Íàäî óáðàòü ñ êàðòû, åñëè ýòî íå êëþ÷, êîòîðûì íóæíî ïîäåëèòüñÿ ñ äðóãèì èãðîêîì
if r then
begin
// Íàäî óáðàòü ñ êàðòû, åñëè ýòî íå êëþ÷, êîòîðûì íóæíî ïîäåëèòüñÿ ñ äðóãèì èãðîêîì
if r then
begin
- if not Respawnable then g_Items_Remove(i) else g_Items_Pick(i);
+ if not (Respawnable and (ItemRespawnTime > 0)) then
+ g_Items_Remove(i)
+ else
+ g_Items_Pick(i);
if g_Game_IsNet then MH_SEND_ItemDestroy(False, i);
nxt := True;
break;
if g_Game_IsNet then MH_SEND_ItemDestroy(False, i);
nxt := True;
break;
Anim.Free();
end;
Anim.Free();
end;
+ Obj.oldX := InitX;
+ Obj.oldY := InitY;
Obj.X := InitX;
Obj.Y := InitY;
Obj.Vel.X := 0;
Obj.X := InitX;
Obj.Y := InitY;
Obj.Vel.X := 0;
end;
end;
end;
end;
-
-procedure itemsDrawInternal (dropflag: Boolean);
-var
- i: Integer;
- it: PItem;
-begin
- if (ggItems = nil) then exit;
-
- for i := 0 to High(ggItems) do
- begin
- it := @ggItems[i];
- if (not it.slotIsUsed) or (it.ItemType = ITEM_NONE) then continue; // just in case
- if not it.alive then continue;
- if (it.dropped <> dropflag) then continue;
-
- with it^ do
- begin
- if g_Collide(Obj.X, Obj.Y, Obj.Rect.Width, Obj.Rect.Height, sX, sY, sWidth, sHeight) then
- begin
- if (Animation = nil) then
- begin
- e_Draw(gItemsTexturesID[ItemType], Obj.X, Obj.Y, 0, true, false);
- end
- else
- begin
- Animation.Draw(Obj.X, Obj.Y, TMirrorType.None);
- end;
-
- if g_debug_Frames then
- begin
- e_DrawQuad(Obj.X+Obj.Rect.X,
- Obj.Y+Obj.Rect.Y,
- Obj.X+Obj.Rect.X+Obj.Rect.Width-1,
- Obj.Y+Obj.Rect.Y+Obj.Rect.Height-1,
- 0, 255, 0);
- end;
- end;
- end;
- end;
-end;
-
-
-procedure g_Items_Draw ();
-begin
- itemsDrawInternal(false);
-end;
-
-procedure g_Items_DrawDrop ();
-begin
- itemsDrawInternal(true);
-end;
-
-
procedure g_Items_SetDrop (ID: DWORD);
begin
if (ID < Length(ggItems)) then
procedure g_Items_SetDrop (ID: DWORD);
begin
if (ID < Length(ggItems)) then
begin
if (ID < Length(ggItems)) then
begin
begin
if (ID < Length(ggItems)) then
begin
+ ggItems[ID].Obj.oldX := ggItems[ID].Obj.X;
+ ggItems[ID].Obj.oldY := ggItems[ID].Obj.Y;
ggItems[ID].alive := false;
ggItems[ID].alive := false;
- ggItems[ID].RespawnTime := ITEM_RESPAWNTIME;
+ ggItems[ID].RespawnTime := IfThen(gLMSRespawn = LMS_RESPAWN_NONE, gGameSettings.ItemRespawnTime, 15) * 36;
end;
end;
end;
end;
it := @ggItems[ID];
if (it.arrIdx <> Integer(ID)) then raise Exception.Create('g_Items_Remove: arrIdx desync');
it := @ggItems[ID];
if (it.arrIdx <> Integer(ID)) then raise Exception.Create('g_Items_Remove: arrIdx desync');
+ it.Obj.oldX := it.Obj.X;
+ it.Obj.oldY := it.Obj.Y;
trig := it.SpawnTrigger;
releaseItem(ID);
trig := it.SpawnTrigger;
releaseItem(ID);
for i := 0 to High(ggItems) do
begin
it := @ggItems[i];
for i := 0 to High(ggItems) do
begin
it := @ggItems[i];
+ it.Obj.oldX := it.Obj.X;
+ it.Obj.oldY := it.Obj.Y;
if not it.slotIsUsed then continue;
if it.Respawnable and (it.ItemType <> ITEM_NONE) then
begin
if not it.slotIsUsed then continue;
if it.Respawnable and (it.ItemType <> ITEM_NONE) then
begin