Browse Source

Reduce use of sgLevels

pull/4727/head
obligaron 4 years ago committed by Anders Jenbo
parent
commit
316279fdd2
  1. 151
      Source/msg.cpp

151
Source/msg.cpp

@ -73,6 +73,18 @@ Item ItemLimbo;
/** @brief Last sent player command for the local player. */
TCmdLocParam4 lastSentPlayerCmd;
/** @brief Gets a delta level. */
DLevel &GetDeltaLevel(uint8_t level)
{
return sgLevels[level];
}
/** @brief Gets a delta level. */
DLevel &GetDeltaLevel(const Player &player)
{
return GetDeltaLevel(player.plrlevel);
}
/**
* @brief Throttles that a player command is only sent once per game tick.
* This is a workaround for a desync that happens when a command is processed in different game ticks for different clients. See https://github.com/diasurgical/devilutionX/issues/2681 for details.
@ -362,9 +374,10 @@ void DeltaImportData(_cmd_id cmd, DWORD recvOffset)
DeltaImportJunk(src);
} else if (cmd >= CMD_DLEVEL_0 && cmd <= CMD_DLEVEL_24) {
uint8_t i = cmd - CMD_DLEVEL_0;
src += DeltaImportItem(src, sgLevels[i].item);
src += DeltaImportObject(src, sgLevels[i].object);
DeltaImportMonster(src, sgLevels[i].monster);
DLevel &deltaLevel = GetDeltaLevel(i);
src += DeltaImportItem(src, deltaLevel.item);
src += DeltaImportObject(src, deltaLevel.object);
DeltaImportMonster(src, deltaLevel.monster);
} else {
app_fatal("Unkown network message type: %i", cmd);
}
@ -420,7 +433,7 @@ void DeltaSyncGolem(const TCmdGolem &message, int pnum, uint8_t level)
return;
sgbDeltaChanged = true;
DMonsterStr &monster = sgLevels[level].monster[pnum];
DMonsterStr &monster = GetDeltaLevel(level).monster[pnum];
monster._mx = message._mx;
monster._my = message._my;
monster._mactive = UINT8_MAX;
@ -438,13 +451,15 @@ void DeltaLeaveSync(uint8_t bLevel)
return;
}
DLevel &deltaLevel = GetDeltaLevel(bLevel);
for (int i = 0; i < ActiveMonsterCount; i++) {
int ma = ActiveMonsters[i];
auto &monster = Monsters[ma];
if (monster._mhitpoints == 0)
continue;
sgbDeltaChanged = true;
DMonsterStr &delta = sgLevels[bLevel].monster[ma];
DMonsterStr &delta = deltaLevel.monster[ma];
delta._mx = monster.position.tile.x;
delta._my = monster.position.tile.y;
delta._mdir = monster._mdir;
@ -462,7 +477,7 @@ void DeltaSyncObject(int oi, _cmd_id bCmd, uint8_t bLevel)
return;
sgbDeltaChanged = true;
sgLevels[bLevel].object[oi].bCmd = bCmd;
GetDeltaLevel(bLevel).object[oi].bCmd = bCmd;
}
bool DeltaGetItem(const TCmdGItem &message, uint8_t bLevel)
@ -470,7 +485,9 @@ bool DeltaGetItem(const TCmdGItem &message, uint8_t bLevel)
if (!gbIsMultiplayer)
return true;
for (TCmdPItem &item : sgLevels[bLevel].item) {
DLevel &deltaLevel = GetDeltaLevel(bLevel);
for (TCmdPItem &item : deltaLevel.item) {
if (item.bCmd == CMD_INVALID || item.wIndx != message.wIndx || item.wCI != message.wCI || item.dwSeed != message.dwSeed)
continue;
@ -494,7 +511,7 @@ bool DeltaGetItem(const TCmdGItem &message, uint8_t bLevel)
if ((message.wCI & CF_PREGEN) == 0)
return false;
for (TCmdPItem &item : sgLevels[bLevel].item) {
for (TCmdPItem &item : deltaLevel.item) {
if (item.bCmd == CMD_INVALID) {
sgbDeltaChanged = true;
item.bCmd = TCmdPItem::PickedUpItem;
@ -527,7 +544,9 @@ void DeltaPutItem(const TCmdPItem &message, Point position, uint8_t bLevel)
if (!gbIsMultiplayer)
return;
for (const TCmdPItem &item : sgLevels[bLevel].item) {
DLevel &deltaLevel = GetDeltaLevel(bLevel);
for (const TCmdPItem &item : deltaLevel.item) {
if (item.bCmd != TCmdPItem::PickedUpItem
&& item.bCmd != CMD_INVALID
&& item.wIndx == message.wIndx
@ -539,7 +558,7 @@ void DeltaPutItem(const TCmdPItem &message, Point position, uint8_t bLevel)
}
}
for (TCmdPItem &item : sgLevels[bLevel].item) {
for (TCmdPItem &item : deltaLevel.item) {
if (item.bCmd == CMD_INVALID) {
sgbDeltaChanged = true;
memcpy(&item, &message, sizeof(TCmdPItem));
@ -2084,9 +2103,10 @@ void DeltaExportData(int pnum)
for (int i = 0; i < NUMLEVELS; i++) {
std::unique_ptr<byte[]> dst { new byte[sizeof(DLevel) + 1] };
byte *dstEnd = &dst.get()[1];
dstEnd = DeltaExportItem(dstEnd, sgLevels[i].item);
dstEnd = DeltaExportObject(dstEnd, sgLevels[i].object);
dstEnd = DeltaExportMonster(dstEnd, sgLevels[i].monster);
DLevel &deltaLevel = sgLevels[i];
dstEnd = DeltaExportItem(dstEnd, deltaLevel.item);
dstEnd = DeltaExportObject(dstEnd, deltaLevel.object);
dstEnd = DeltaExportMonster(dstEnd, deltaLevel.monster);
uint32_t size = CompressData(dst.get(), dstEnd);
dthread_send_delta(pnum, static_cast<_cmd_id>(i + CMD_DLEVEL_0), std::move(dst), size);
}
@ -2117,7 +2137,7 @@ void delta_kill_monster(int mi, Point position, uint8_t bLevel)
return;
sgbDeltaChanged = true;
DMonsterStr *pD = &sgLevels[bLevel].monster[mi];
DMonsterStr *pD = &GetDeltaLevel(bLevel).monster[mi];
pD->_mx = position.x;
pD->_my = position.y;
pD->_mdir = Monsters[mi]._mdir;
@ -2130,7 +2150,7 @@ void delta_monster_hp(int mi, int hp, uint8_t bLevel)
return;
sgbDeltaChanged = true;
DMonsterStr *pD = &sgLevels[bLevel].monster[mi];
DMonsterStr *pD = &GetDeltaLevel(bLevel).monster[mi];
if (pD->_mhitpoints > hp)
pD->_mhitpoints = hp;
}
@ -2143,7 +2163,7 @@ void delta_sync_monster(const TSyncMonster &monsterSync, uint8_t level)
assert(level < NUMLEVELS);
sgbDeltaChanged = true;
DMonsterStr &monster = sgLevels[level].monster[monsterSync._mndx];
DMonsterStr &monster = GetDeltaLevel(level).monster[monsterSync._mndx];
if (monster._mhitpoints == 0)
return;
@ -2190,7 +2210,9 @@ void DeltaAddItem(int ii)
if (!gbIsMultiplayer)
return;
for (const TCmdPItem &item : sgLevels[currlevel].item) {
DLevel &deltaLevel = GetDeltaLevel(currlevel);
for (const TCmdPItem &item : deltaLevel.item) {
if (item.bCmd != CMD_INVALID
&& item.wIndx == Items[ii].IDidx
&& item.wCI == Items[ii]._iCreateInfo
@ -2200,7 +2222,7 @@ void DeltaAddItem(int ii)
}
}
for (TCmdPItem &item : sgLevels[currlevel].item) {
for (TCmdPItem &item : deltaLevel.item) {
if (item.bCmd != CMD_INVALID)
continue;
@ -2270,23 +2292,24 @@ void DeltaLoadLevel()
return;
deltaload = true;
DLevel &deltaLevel = GetDeltaLevel(currlevel);
if (leveltype != DTYPE_TOWN) {
for (int i = 0; i < ActiveMonsterCount; i++) {
if (sgLevels[currlevel].monster[i]._mx == 0xFF)
if (deltaLevel.monster[i]._mx == 0xFF)
continue;
M_ClearSquares(i);
int x = sgLevels[currlevel].monster[i]._mx;
int y = sgLevels[currlevel].monster[i]._my;
int x = deltaLevel.monster[i]._mx;
int y = deltaLevel.monster[i]._my;
auto &monster = Monsters[i];
monster.position.tile = { x, y };
monster.position.old = { x, y };
monster.position.future = { x, y };
if (sgLevels[currlevel].monster[i]._mhitpoints != -1) {
monster._mhitpoints = sgLevels[currlevel].monster[i]._mhitpoints;
monster.mWhoHit = sgLevels[currlevel].monster[i].mWhoHit;
if (deltaLevel.monster[i]._mhitpoints != -1) {
monster._mhitpoints = deltaLevel.monster[i]._mhitpoints;
monster.mWhoHit = deltaLevel.monster[i].mWhoHit;
}
if (sgLevels[currlevel].monster[i]._mhitpoints == 0) {
if (deltaLevel.monster[i]._mhitpoints == 0) {
M_ClearSquares(i);
if (monster._mAi != AI_DIABLO) {
if (monster._uniqtype == 0) {
@ -2299,7 +2322,7 @@ void DeltaLoadLevel()
monster._mDelFlag = true;
M_UpdateLeader(i);
} else {
decode_enemy(monster, sgLevels[currlevel].monster[i]._menemy);
decode_enemy(monster, deltaLevel.monster[i]._menemy);
if (monster.position.tile != Point { 0, 0 } && monster.position.tile != GolemHoldingCell)
dMonster[monster.position.tile.x][monster.position.tile.y] = i + 1;
if (monster.MType->mtype == MT_GOLEM) {
@ -2308,21 +2331,21 @@ void DeltaLoadLevel()
} else {
M_StartStand(monster, monster._mdir);
}
monster._msquelch = sgLevels[currlevel].monster[i]._mactive;
monster._msquelch = deltaLevel.monster[i]._mactive;
}
}
memcpy(AutomapView, &sgLocals[currlevel], sizeof(AutomapView));
}
for (int i = 0; i < MAXITEMS; i++) {
if (sgLevels[currlevel].item[i].bCmd == CMD_INVALID)
if (deltaLevel.item[i].bCmd == CMD_INVALID)
continue;
if (sgLevels[currlevel].item[i].bCmd == TCmdPItem::PickedUpItem) {
if (deltaLevel.item[i].bCmd == TCmdPItem::PickedUpItem) {
int activeItemIndex = FindGetItem(
sgLevels[currlevel].item[i].dwSeed,
sgLevels[currlevel].item[i].wIndx,
sgLevels[currlevel].item[i].wCI);
deltaLevel.item[i].dwSeed,
deltaLevel.item[i].wIndx,
deltaLevel.item[i].wCI);
if (activeItemIndex != -1) {
const auto &position = Items[ActiveItems[activeItemIndex]].position;
if (dItem[position.x][position.y] == ActiveItems[activeItemIndex] + 1)
@ -2330,46 +2353,46 @@ void DeltaLoadLevel()
DeleteItem(activeItemIndex);
}
}
if (sgLevels[currlevel].item[i].bCmd == TCmdPItem::DroppedItem) {
if (deltaLevel.item[i].bCmd == TCmdPItem::DroppedItem) {
int ii = AllocateItem();
auto &item = Items[ii];
if (sgLevels[currlevel].item[i].wIndx == IDI_EAR) {
if (deltaLevel.item[i].wIndx == IDI_EAR) {
RecreateEar(
item,
sgLevels[currlevel].item[i].wCI,
sgLevels[currlevel].item[i].dwSeed,
sgLevels[currlevel].item[i].bId,
sgLevels[currlevel].item[i].bDur,
sgLevels[currlevel].item[i].bMDur,
sgLevels[currlevel].item[i].bCh,
sgLevels[currlevel].item[i].bMCh,
sgLevels[currlevel].item[i].wValue,
sgLevels[currlevel].item[i].dwBuff);
deltaLevel.item[i].wCI,
deltaLevel.item[i].dwSeed,
deltaLevel.item[i].bId,
deltaLevel.item[i].bDur,
deltaLevel.item[i].bMDur,
deltaLevel.item[i].bCh,
deltaLevel.item[i].bMCh,
deltaLevel.item[i].wValue,
deltaLevel.item[i].dwBuff);
} else {
RecreateItem(
item,
sgLevels[currlevel].item[i].wIndx,
sgLevels[currlevel].item[i].wCI,
sgLevels[currlevel].item[i].dwSeed,
sgLevels[currlevel].item[i].wValue,
(sgLevels[currlevel].item[i].dwBuff & CF_HELLFIRE) != 0);
if (sgLevels[currlevel].item[i].bId != 0)
deltaLevel.item[i].wIndx,
deltaLevel.item[i].wCI,
deltaLevel.item[i].dwSeed,
deltaLevel.item[i].wValue,
(deltaLevel.item[i].dwBuff & CF_HELLFIRE) != 0);
if (deltaLevel.item[i].bId != 0)
item._iIdentified = true;
item._iDurability = sgLevels[currlevel].item[i].bDur;
item._iMaxDur = sgLevels[currlevel].item[i].bMDur;
item._iCharges = sgLevels[currlevel].item[i].bCh;
item._iMaxCharges = sgLevels[currlevel].item[i].bMCh;
item._iPLToHit = sgLevels[currlevel].item[i].wToHit;
item._iMaxDam = sgLevels[currlevel].item[i].wMaxDam;
item._iMinStr = sgLevels[currlevel].item[i].bMinStr;
item._iMinMag = sgLevels[currlevel].item[i].bMinMag;
item._iMinDex = sgLevels[currlevel].item[i].bMinDex;
item._iAC = sgLevels[currlevel].item[i].bAC;
item.dwBuff = sgLevels[currlevel].item[i].dwBuff;
item._iDurability = deltaLevel.item[i].bDur;
item._iMaxDur = deltaLevel.item[i].bMDur;
item._iCharges = deltaLevel.item[i].bCh;
item._iMaxCharges = deltaLevel.item[i].bMCh;
item._iPLToHit = deltaLevel.item[i].wToHit;
item._iMaxDam = deltaLevel.item[i].wMaxDam;
item._iMinStr = deltaLevel.item[i].bMinStr;
item._iMinMag = deltaLevel.item[i].bMinMag;
item._iMinDex = deltaLevel.item[i].bMinDex;
item._iAC = deltaLevel.item[i].bAC;
item.dwBuff = deltaLevel.item[i].dwBuff;
}
int x = sgLevels[currlevel].item[i].x;
int y = sgLevels[currlevel].item[i].y;
int x = deltaLevel.item[i].x;
int y = deltaLevel.item[i].y;
item.position = GetItemPosition({ x, y });
dItem[item.position.x][item.position.y] = ii + 1;
RespawnItem(Items[ii], false);
@ -2378,12 +2401,12 @@ void DeltaLoadLevel()
if (leveltype != DTYPE_TOWN) {
for (int i = 0; i < MAXOBJECTS; i++) {
switch (sgLevels[currlevel].object[i].bCmd) {
switch (deltaLevel.object[i].bCmd) {
case CMD_OPENDOOR:
case CMD_CLOSEDOOR:
case CMD_OPERATEOBJ:
case CMD_PLROPOBJ:
SyncOpObject(-1, sgLevels[currlevel].object[i].bCmd, i);
SyncOpObject(-1, deltaLevel.object[i].bCmd, i);
break;
case CMD_BREAKOBJ:
SyncBreakObj(-1, Objects[i]);

Loading…
Cancel
Save