Skip to content

Commit

Permalink
[core] Change dynamic targids to linearly ramp (#5213)
Browse files Browse the repository at this point in the history
* [core] Change dynamic targids to linearly ramp

* This is retail behavior, IDs are not recycled as soon as possible -- They appear to increase until they wrap.

* [core] Adjust dynamic ID long form ID calculation to match retail

* [core] More sane next dynamic targid lookup
  • Loading branch information
WinterSolstice8 authored Mar 2, 2024
1 parent 62f01f3 commit 02a6f7d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
40 changes: 29 additions & 11 deletions src/map/zone_entities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ namespace
typedef std::pair<float, CCharEntity*> CharScorePair;

CZoneEntities::CZoneEntities(CZone* zone)
: m_zone(zone)
: nextDynamicTargID(0x700) // Start of dynamic entity range // TODO: Make this into a constexpr somewhere.
, m_zone(zone)
, m_Transport(nullptr)
, lastCharComputeTargId(0)
, lastCharPersistTargId(0)
Expand Down Expand Up @@ -488,23 +489,40 @@ uint16 CZoneEntities::GetNewCharTargID()
void CZoneEntities::AssignDynamicTargIDandLongID(CBaseEntity* PEntity)
{
// NOTE: 0x0E (entity_update) entity updates are valid for 0 to 1023 and 1792 to 2303
uint16 targid = 0x700;
for (auto it : dynamicTargIds)
// Step targid up linearly from 0x700 one by one to 0x8FF unless that ID is already occupied.
uint16 targid = nextDynamicTargID;

// Wrap around 0x8FF to 0x700
if (targid > 0x8FF)
{
if (targid != it)
targid = 0x700;
}

uint16 counter = 0;

// Find next available targid, starting with the computed one above.
while (std::find(dynamicTargIds.begin(), dynamicTargIds.end(), targid) != dynamicTargIds.end())
{
targid++;
// Wrap around 0x8FF to 0x700
if (targid > 0x8FF)
{
targid = 0x700;
}

if (counter > 0x1FF)
{
ShowError(fmt::format("dynamicTargIds list full in zone {}!", m_zone->getName()));
targid = 0x900;
break;
}
targid++;
counter++;
}

auto id = 0x1000000 + (m_zone->GetID() << 12) + targid;
// We found our targid, the next dynamic entity will want to start searching at +1 of this.
nextDynamicTargID = targid + 1;

// Add 0x100 if targid is >= 0x800 -- observed on retail.
if (targid >= 0x800)
{
id += 0x100;
}
auto id = 0x01000000 | (m_zone->GetID() << 0x0C) | (targid + 0x0100);

dynamicTargIds.insert(targid);

Expand Down
5 changes: 3 additions & 2 deletions src/map/zone_entities.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ class CZoneEntities
EntityList_t m_npcList;
EntityList_t m_charList;

std::set<uint16> charTargIds; // sorted set of targids for characters
std::set<uint16> dynamicTargIds; // sorted set of targids for dynamic entities
uint16 nextDynamicTargID; // The next dynamic targ ID to chosen -- SE rotates them forwards and skips entries that already exist.
std::set<uint16> charTargIds; // sorted set of targids for characters
std::set<uint16> dynamicTargIds; // sorted set of targids for dynamic entities

std::vector<std::pair<uint16, time_point>> dynamicTargIdsToDelete; // list of targids pending deletion at a later date

Expand Down

0 comments on commit 02a6f7d

Please sign in to comment.