X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_items.pas;h=27dbc75bf19abf1ced60905a43afd6212a3ac526;hb=b79ddd98d923ee15f4bfd1db5111e669fc19964a;hp=6d7cf5a10a7918ea8bc0480160d33c9769c0099e;hpb=cac277b4226c3de6401dae59c91dd35b77625304;p=d2df-sdl.git diff --git a/src/game/g_items.pas b/src/game/g_items.pas index 6d7cf5a..27dbc75 100644 --- a/src/game/g_items.pas +++ b/src/game/g_items.pas @@ -25,7 +25,8 @@ Type PItem = ^TItem; TItem = record private - treeNode: Integer; + //treeNode: Integer; + slotIsUsed: Boolean; arrIdx: Integer; // in ggItems public @@ -60,12 +61,12 @@ procedure g_Items_LoadState(var Mem: TBinMemoryReader); procedure g_Items_RestartRound (); -function g_ItemValidId (idx: Integer): Boolean; inline; -function g_ItemByIdx (idx: Integer): PItem; -function g_ItemObjByIdx (idx: Integer): PObj; +function g_Items_ValidId (idx: Integer): Boolean; inline; +function g_Items_ByIdx (idx: Integer): PItem; +function g_Items_ObjByIdx (idx: Integer): PObj; -procedure g_Item_EmitPickupSound (idx: Integer); // at item position -procedure g_Item_EmitPickupSoundAt (idx, x, y: Integer); +procedure g_Items_EmitPickupSound (idx: Integer); // at item position +procedure g_Items_EmitPickupSoundAt (idx, x, y: Integer); type @@ -85,91 +86,47 @@ uses g_basic, e_graphics, g_sound, g_main, g_gfx, g_map, Math, g_game, g_triggers, g_console, SysUtils, g_player, g_net, g_netmsg, e_log, - g_grid, z_aabbtree, binheap; + g_grid, binheap; -// ////////////////////////////////////////////////////////////////////////// // var - itemTree: TDynAABBTree = nil; ggItems: Array of TItem = nil; + + +// ////////////////////////////////////////////////////////////////////////// // +var freeIds: TBinaryHeapInt = nil; // free item ids // ////////////////////////////////////////////////////////////////////////// // -function g_ItemValidId (idx: Integer): Boolean; inline; +function g_Items_ValidId (idx: Integer): Boolean; inline; begin result := false; if (idx < 0) or (idx > High(ggItems)) then exit; - if (ggItems[idx].treeNode = -1) then exit; + if not ggItems[idx].slotIsUsed then exit; result := true; end; -function g_ItemByIdx (idx: Integer): PItem; +function g_Items_ByIdx (idx: Integer): PItem; begin if (idx < 0) or (idx > High(ggItems)) then raise Exception.Create('g_ItemObjByIdx: invalid index'); result := @ggItems[idx]; - if (result.treeNode = -1) then raise Exception.Create('g_ItemObjByIdx: requested inexistent item'); + if not result.slotIsUsed then raise Exception.Create('g_ItemObjByIdx: requested inexistent item'); end; -function g_ItemObjByIdx (idx: Integer): PObj; +function g_Items_ObjByIdx (idx: Integer): PObj; begin if (idx < 0) or (idx > High(ggItems)) then raise Exception.Create('g_ItemObjByIdx: invalid index'); - if (ggItems[idx].treeNode = -1) then raise Exception.Create('g_ItemObjByIdx: requested inexistent item'); + if not ggItems[idx].slotIsUsed then raise Exception.Create('g_ItemObjByIdx: requested inexistent item'); result := @ggItems[idx].Obj; end; -// ////////////////////////////////////////////////////////////////////////// // -type - TDynAABBTreeItem = class(TDynAABBTree) - function getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh; tag: Integer): Boolean; override; - end; - -function TDynAABBTreeItem.getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh; tag: Integer): Boolean; -var - it: PItem; -begin - result := false; - if (flesh = nil) then begin aabb := AABB2D.Create(0, 0, 0, 0); exit; end; - //if not g_ItemValidId(tag) then raise Exception.Create('DynTree: trying to get dimensions of inexistant item'); - if (tag < 0) or (tag > High(ggItems)) then raise Exception.Create('DynTree: trying to get dimensions of inexistant item'); - it := @ggItems[tag]; - if (it.Obj.Rect.Width < 1) or (it.Obj.Rect.Height < 1) then exit; - aabb := AABB2D.Create(it.Obj.X, it.Obj.Y, it.Obj.X+it.Obj.Rect.Width, it.Obj.Y+it.Obj.Rect.Height); - if not aabb.valid then raise Exception.Create('wutafuuuuuuu?!'); - result := true; -end; - - // ////////////////////////////////////////////////////////////////////////// // procedure TItem.positionChanged (); -var - x, y: Integer; begin - if (treeNode = -1) then - begin - treeNode := itemTree.insertObject(itemTree{doesn't matter}, arrIdx, true); // static object - itemTree.getNodeXY(treeNode, x, y); - {$IF DEFINED(D2F_DEBUG)}e_WriteLog(Format('item #%d: inserted into the tree; nodeid=%d; x=%d; y=%d', [arrIdx, treeNode, x, y]), MSG_NOTIFY);{$ENDIF} - end - else - begin - itemTree.getNodeXY(treeNode, x, y); - if (Obj.X = x) and (Obj.Y = y) then exit; // nothing to do - {$IF DEFINED(D2F_DEBUG)}e_WriteLog(Format('item #%d: updating tree; nodeid=%d; x=%d; y=%d', [arrIdx, treeNode, x, y]), MSG_NOTIFY);{$ENDIF} - - {$IFDEF TRUE} - itemTree.updateObject(treeNode); - {$ELSE} - itemTree.removeObject(treeNode); - treeNode := itemTree.insertObject(itemTree{doesn't matter}, arrIdx, true); // static object - {$ENDIF} - - itemTree.getNodeXY(treeNode, x, y); - {$IF DEFINED(D2F_DEBUG)}e_WriteLog(Format('item #%d: updated tree; nodeid=%d; x=%d; y=%d', [arrIdx, treeNode, x, y]), MSG_NOTIFY);{$ENDIF} - end; end; @@ -306,7 +263,6 @@ begin InitTextures(); - itemTree := TDynAABBTreeItem.Create(); freeIds := binHeapNewIntLess(); end; @@ -364,7 +320,6 @@ begin g_Texture_Delete('ITEM_MEDKIT_BLACK'); g_Texture_Delete('ITEM_JETPACK'); - itemTree.Free(); freeIds.Free(); end; @@ -375,10 +330,9 @@ var begin if (idx < 0) or (idx > High(ggItems)) then raise Exception.Create('releaseItem: invalid item id'); it := @ggItems[idx]; - if (it.treeNode = -1) then raise Exception.Create('releaseItem: trying to release unallocated item'); + if not it.slotIsUsed then raise Exception.Create('releaseItem: trying to release unallocated item'); if (it.arrIdx <> idx) then raise Exception.Create('releaseItem: arrIdx inconsistency'); - itemTree.removeObject(it.treeNode); - it.treeNode := -1; + it.slotIsUsed := false; if (it.Animation <> nil) then begin it.Animation.Free(); @@ -404,7 +358,7 @@ begin for i := olen to High(ggItems) do begin it := @ggItems[i]; - it.treeNode := -1; + it.slotIsUsed := false; it.arrIdx := i; it.ItemType := ITEM_NONE; it.Animation := nil; @@ -418,8 +372,8 @@ begin result := freeIds.front; freeIds.popFront(); - if (result > High(ggItems)) then raise Exception.Create('allocItem: freeid list corrupted'); - if (ggItems[result].arrIdx <> result) then raise Exception.Create('allocItem: arrIdx inconsistency'); + if (Integer(result) > High(ggItems)) then raise Exception.Create('allocItem: freeid list corrupted'); + if (ggItems[result].arrIdx <> Integer(result)) then raise Exception.Create('allocItem: arrIdx inconsistency'); end; @@ -441,7 +395,7 @@ begin for i := olen to High(ggItems) do begin it := @ggItems[i]; - it.treeNode := -1; + it.slotIsUsed := false; it.arrIdx := i; it.ItemType := ITEM_NONE; it.Animation := nil; @@ -454,7 +408,7 @@ begin end; it := @ggItems[slot]; - if (it.treeNode = -1) then + if not it.slotIsUsed then begin // this is unused slot; get it, and rebuild id list if rebuildFreeList then @@ -462,15 +416,14 @@ begin freeIds.clear(); for i := 0 to High(ggItems) do begin - if (i <> slot) and (ggItems[i].treeNode = -1) then freeIds.insert(i); + if (i <> slot) and (not it.slotIsUsed) then freeIds.insert(i); end; end; end else begin // it will be readded - itemTree.removeObject(it.treeNode); - it.treeNode := -1; + it.slotIsUsed := false; end; result := slot; @@ -497,7 +450,6 @@ begin for i := 0 to High(ggItems) do ggItems[i].Animation.Free(); ggItems := nil; end; - if (itemTree <> nil) then itemTree.reset(); freeIds.clear(); end; @@ -515,6 +467,10 @@ begin it := @ggItems[find_id]; + if (it.arrIdx <> Integer(find_id)) then raise Exception.Create('g_Items_Create: arrIdx inconsistency'); + //it.arrIdx := find_id; + it.slotIsUsed := true; + it.ItemType := ItemType; it.Respawnable := Respawnable; if g_Game_IsServer and (ITEM_RESPAWNTIME = 0) then it.Respawnable := False; @@ -525,11 +481,6 @@ begin it.Live := True; it.QuietRespawn := False; - if (it.treeNode <> -1) then raise Exception.Create('g_Items_Create: trying to reuse already allocated item'); - if (it.arrIdx <> find_id) then raise Exception.Create('g_Items_Create: arrIdx inconsistency'); - //it.treeNode := -1; - //it.arrIdx := find_id; - g_Obj_Init(@it.Obj); it.Obj.X := X; it.Obj.Y := Y; @@ -637,7 +588,7 @@ begin +2. I_MEGA,I_INVL,I_SUPER 3. I_STIM,I_MEDI,I_ARM1,I_ARM2,I_AQUA,I_KEYR,I_KEYG,I_KEYB,I_SUIT,I_RTORCH,I_GTORCH,I_BTORCH,I_GOR1,I_FCAN } - g_Item_EmitPickupSoundAt(i, gPlayers[j].Obj.X, gPlayers[j].Obj.Y); + g_Items_EmitPickupSoundAt(i, gPlayers[j].Obj.X, gPlayers[j].Obj.Y); // Íàäî óáðàòü ñ êàðòû, åñëè ýòî íå êëþ÷, êîòîðûì íóæíî ïîäåëèòüñÿ ñ äðóãèì èãðîêîì if r then @@ -737,15 +688,11 @@ procedure g_Items_Remove (ID: DWORD); var it: PItem; trig: Integer; - x, y: Integer; begin - if not g_ItemValidId(ID) then raise Exception.Create('g_Items_Remove: invalid item id'); + if not g_Items_ValidId(ID) then raise Exception.Create('g_Items_Remove: invalid item id'); it := @ggItems[ID]; - if (it.arrIdx <> ID) then raise Exception.Create('g_Items_Remove: arrIdx desync'); - - itemTree.getNodeXY(it.treeNode, x, y); - {$IF DEFINED(D2F_DEBUG)}e_WriteLog(Format('removing item #%d: updating tree; nodeid=%d; x=%d; y=%d (%d,%d)', [it.arrIdx, it.treeNode, x, y, it.Obj.X, it.Obj.Y]), MSG_NOTIFY);{$ENDIF} + if (it.arrIdx <> Integer(ID)) then raise Exception.Create('g_Items_Remove: arrIdx desync'); trig := it.SpawnTrigger; @@ -901,20 +848,20 @@ end; // ////////////////////////////////////////////////////////////////////////// // -procedure g_Item_EmitPickupSound (idx: Integer); +procedure g_Items_EmitPickupSound (idx: Integer); var it: PItem; begin - if not g_ItemValidId(idx) then exit; + if not g_Items_ValidId(idx) then exit; it := @ggItems[idx]; - g_Item_EmitPickupSoundAt(idx, it.Obj.X, it.Obj.Y); + g_Items_EmitPickupSoundAt(idx, it.Obj.X, it.Obj.Y); end; -procedure g_Item_EmitPickupSoundAt (idx, x, y: Integer); +procedure g_Items_EmitPickupSoundAt (idx, x, y: Integer); var it: PItem; begin - if not g_ItemValidId(idx) then exit; + if not g_Items_ValidId(idx) then exit; it := @ggItems[idx]; if gSoundEffectsDF then