Browse Source

Use user by reference

dyn-players
Anders Jenbo 4 years ago
parent
commit
d1189388f5
  1. 2
      Source/automap.cpp
  2. 4
      Source/controls/plrctrls.cpp
  3. 8
      Source/debug.cpp
  4. 7
      Source/diablo.cpp
  5. 10
      Source/levels/trigs.cpp
  6. 2
      Source/loadsave.cpp
  7. 18
      Source/missiles.cpp
  8. 133
      Source/monster.cpp
  9. 12
      Source/monster.h
  10. 54
      Source/msg.cpp
  11. 4
      Source/multi.cpp
  12. 25
      Source/objects.cpp
  13. 5
      Source/objects.h
  14. 207
      Source/player.cpp
  15. 19
      Source/player.h
  16. 2
      Source/quests.cpp
  17. 2
      Source/spells.cpp
  18. 9
      test/player_test.cpp

2
Source/automap.cpp

@ -737,7 +737,7 @@ void DrawAutomap(const Surface &out)
for (int playerId = 0; playerId < MAX_PLRS; playerId++) {
Player &player = Players[playerId];
if (player.isOnActiveLevel() && player.plractive && !player._pLvlChanging && (&player == &myPlayer || player.friendlyMode)) {
if (player.isOnActiveLevel() && player.plractive && !player._pLvlChanging && (&player == MyPlayer || player.friendlyMode)) {
DrawAutomapPlr(out, myPlayerOffset, playerId);
}
}

4
Source/controls/plrctrls.cpp

@ -1283,7 +1283,7 @@ void WalkInDir(int playerId, AxisDirection dir)
if (ControlMode == ControlTypes::VirtualGamepad) {
if (VirtualGamepadState.standButton.isHeld) {
if (player._pmode == PM_STAND)
StartStand(playerId, pdir);
StartStand(player, pdir);
return;
}
}
@ -1291,7 +1291,7 @@ void WalkInDir(int playerId, AxisDirection dir)
if (PosOkPlayer(player, delta) && IsPathBlocked(player.position.future, pdir)) {
if (player._pmode == PM_STAND)
StartStand(playerId, pdir);
StartStand(player, pdir);
return; // Don't start backtrack around obstacles
}

8
Source/debug.cpp

@ -207,7 +207,7 @@ std::string DebugCmdWarpToLevel(const string_view parameter)
if (!setlevel && myPlayer.isOnLevel(level))
return StrCat("I did nothing but fulfilled your wish. You are already at level ", level, ".");
StartNewLvl(MyPlayerId, (level != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, level);
StartNewLvl(myPlayer, (level != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, level);
return StrCat("Welcome to level ", level, ".");
}
@ -234,12 +234,12 @@ std::string DebugCmdLoadQuestMap(const string_view parameter)
continue;
if (!MyPlayer->isOnLevel(quest._qlevel)) {
StartNewLvl(MyPlayerId, (quest._qlevel != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, quest._qlevel);
StartNewLvl(*MyPlayer, (quest._qlevel != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, quest._qlevel);
ProcessMessages();
}
setlvltype = quest._qlvltype;
StartNewLvl(MyPlayerId, WM_DIABSETLVL, level);
StartNewLvl(*MyPlayer, WM_DIABSETLVL, level);
return StrCat("Welcome to ", QuestLevelNames[level], ".");
}
@ -283,7 +283,7 @@ std::string DebugCmdLoadMap(const string_view parameter)
setlvltype = static_cast<dungeon_type>(mapType);
ViewPosition = spawn;
StartNewLvl(MyPlayerId, WM_DIABSETLVL, SL_NONE);
StartNewLvl(*MyPlayer, WM_DIABSETLVL, SL_NONE);
return "Welcome to this unique place.";
}

7
Source/diablo.cpp

@ -2264,14 +2264,13 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
SyncPortals();
for (int i = 0; i < MAX_PLRS; i++) {
Player &player = Players[i];
for (Player &player : Players) {
if (player.plractive && player.isOnActiveLevel() && (!player._pLvlChanging || &player == MyPlayer)) {
if (player._pHitPoints > 0) {
if (!gbIsMultiplayer)
dPlayer[player.position.tile.x][player.position.tile.y] = i + 1;
dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1;
else
SyncInitPlrPos(i);
SyncInitPlrPos(player);
} else {
dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer;
}

10
Source/levels/trigs.cpp

@ -835,14 +835,14 @@ void CheckTriggers()
myPlayer.Say(HeroSpeech::NotAChance);
InitDiabloMsg(EMSG_NOT_IN_SHAREWARE);
} else {
StartNewLvl(MyPlayerId, trigs[i]._tmsg, currlevel + 1);
StartNewLvl(myPlayer, trigs[i]._tmsg, currlevel + 1);
}
break;
case WM_DIABPREVLVL:
StartNewLvl(MyPlayerId, trigs[i]._tmsg, currlevel - 1);
StartNewLvl(myPlayer, trigs[i]._tmsg, currlevel - 1);
break;
case WM_DIABRTNLVL:
StartNewLvl(MyPlayerId, trigs[i]._tmsg, ReturnLevel);
StartNewLvl(myPlayer, trigs[i]._tmsg, ReturnLevel);
break;
case WM_DIABTOWNWARP:
if (gbIsMultiplayer) {
@ -877,11 +877,11 @@ void CheckTriggers()
}
}
StartNewLvl(MyPlayerId, trigs[i]._tmsg, trigs[i]._tlvl);
StartNewLvl(myPlayer, trigs[i]._tmsg, trigs[i]._tlvl);
break;
case WM_DIABTWARPUP:
TWarpFrom = currlevel;
StartNewLvl(MyPlayerId, trigs[i]._tmsg, 0);
StartNewLvl(myPlayer, trigs[i]._tmsg, 0);
break;
default:
app_fatal("Unknown trigger msg");

2
Source/loadsave.cpp

@ -2078,7 +2078,7 @@ void LoadGame(bool firstflag)
}
LoadGameLevel(firstflag, ENTRY_LOAD);
SyncInitPlr(MyPlayerId);
SyncInitPlr(myPlayer);
SyncPlrAnim(myPlayer);
ViewPosition = { viewX, viewY };

18
Source/missiles.cpp

@ -245,14 +245,14 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, miss
monster.flags |= MFLAG_NOHEAL;
if (monster.hitPoints >> 6 <= 0) {
M_StartKill(monster, pnum);
M_StartKill(monster, player);
} else if (resist) {
PlayEffect(monster, 1);
} else {
if (monster.mode != MonsterMode::Petrified && MissilesData[t].mType == 0 && HasAnyOf(player._pIFlags, ItemSpecialEffect::Knockback))
M_GetKnockback(monster);
if (monster.type().type != MT_GOLEM)
M_StartHit(monster, pnum, dam);
M_StartHit(monster, player, dam);
}
if (monster.activeForTicks == 0) {
@ -354,7 +354,7 @@ bool Plr2PlrMHit(const Player &player, int p, int mindam, int maxdam, int dist,
} else {
if (&player == MyPlayer)
NetSendCmdDamage(true, p, dam);
StartPlrHit(p, dam, false);
StartPlrHit(target, dam, false);
}
return true;
@ -438,7 +438,7 @@ void CheckMissileCol(Missile &missile, int minDamage, int maxDamage, bool isDama
if (IsMissileBlockedByTile({ mx, my })) {
Object *object = ObjectAtPosition({ mx, my });
if (object != nullptr && object->IsBreakable()) {
BreakObject(-1, *object);
BreakObjectMissile(*object);
}
if (!dontDeleteOnCollision)
@ -683,7 +683,7 @@ bool IsMissileBlockedByTile(Point tile)
void GetDamageAmt(spell_id i, int *mind, int *maxd)
{
assert(MyPlayerId >= 0 && MyPlayerId < MAX_PLRS);
assert(MyPlayer != nullptr);
assert(i >= 0 && i < 64);
Player &myPlayer = *MyPlayer;
@ -873,7 +873,7 @@ bool MonsterTrapHit(int monsterId, int mindam, int maxdam, int dist, missile_id
monster.hitPoints = 0;
#endif
if (monster.hitPoints >> 6 <= 0) {
StartMonsterDeath(monster, -1, true);
MonsterDeath(monster, monster.direction, true);
} else if (resist) {
PlayEffect(monster, 1);
} else {
@ -1014,7 +1014,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, missil
}
if (player._pHitPoints >> 6 > 0) {
StartPlrHit(pnum, dam, false);
StartPlrHit(player, dam, false);
}
return true;
@ -2159,7 +2159,7 @@ void AddGolem(Missile &missile, const AddMissileParameter &parameter)
Monster &golem = Monsters[playerId];
if (golem.position.tile != GolemHoldingCell && &player == MyPlayer)
M_StartKill(golem, playerId);
M_StartKill(golem, player);
UseMana(player, SPL_GOLEM);
@ -2171,7 +2171,7 @@ void AddGolem(Missile &missile, const AddMissileParameter &parameter)
parameter.dst, 0, 5);
if (spawnPosition) {
SpawnGolem(playerId, *spawnPosition, missile);
SpawnGolem(player, golem, *spawnPosition, missile);
}
}
}

133
Source/monster.cpp

@ -1067,45 +1067,6 @@ void MonsterHitMonster(Monster &monster, int i, int dam)
HitMonster(monster, dam);
}
void MonsterDeath(Monster &monster, int pnum, Direction md, bool sendmsg)
{
if (pnum < MAX_PLRS) {
if (pnum >= 0)
monster.whoHit |= 1 << pnum;
if (monster.type().type != MT_GOLEM)
AddPlrMonstExper(monster.level, monster.exp, monster.whoHit);
}
MonsterKillCounts[monster.type().type]++;
monster.hitPoints = 0;
SetRndSeed(monster.rndItemSeed);
SpawnLoot(monster, sendmsg);
if (monster.type().type == MT_DIABLO)
DiabloDeath(monster, true);
else
PlayEffect(monster, 2);
if (monster.mode != MonsterMode::Petrified) {
if (monster.type().type == MT_GOLEM)
md = Direction::South;
NewMonsterAnim(monster, MonsterGraphic::Death, md, gGameLogicStep < GameLogicStep::ProcessMonsters ? AnimationDistributionFlags::ProcessAnimationPending : AnimationDistributionFlags::None);
monster.mode = MonsterMode::Death;
}
monster.goal = MonsterGoal::None;
monster.var1 = 0;
monster.position.offset = { 0, 0 };
monster.position.tile = monster.position.old;
monster.position.future = monster.position.old;
M_ClearSquares(monster);
dMonster[monster.position.tile.x][monster.position.tile.y] = monster.getId() + 1;
CheckQuestKill(monster, sendmsg);
M_FallenFear(monster.position.tile);
if (IsAnyOf(monster.type().type, MT_NACID, MT_RACID, MT_BACID, MT_XACID, MT_SPIDLORD))
AddMissile(monster.position.tile, { 0, 0 }, Direction::South, MIS_ACIDPUD, TARGET_PLAYERS, monster.getId(), monster.intelligence + 1, 0);
}
void StartDeathFromMonster(int i, int mid)
{
assert(static_cast<size_t>(i) < MaxMonsters);
@ -1116,8 +1077,12 @@ void StartDeathFromMonster(int i, int mid)
delta_kill_monster(monster, monster.position.tile, *MyPlayer);
NetSendCmdLocParam1(false, CMD_MONSTDEATH, monster.position.tile, mid);
if (killer.type().type == MT_GOLEM)
monster.whoHit |= 1 << i;
Direction md = GetDirection(monster.position.tile, killer.position.tile);
MonsterDeath(monster, i, md, true);
MonsterDeath(monster, md, true);
if (gbIsHellfire)
M_StartStand(killer, killer.direction);
}
@ -1279,9 +1244,9 @@ void CheckReflect(int monsterId, int pnum, int dam)
monster.hitPoints -= mdam;
dam = std::max(dam - mdam, 0);
if (monster.hitPoints >> 6 <= 0)
M_StartKill(monster, pnum);
M_StartKill(monster, player);
else
M_StartHit(monster, pnum, mdam);
M_StartHit(monster, player, mdam);
}
void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDam)
@ -1367,9 +1332,9 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa
int mdam = (GenerateRnd(3) + 1) << 6;
monster.hitPoints -= mdam;
if (monster.hitPoints >> 6 <= 0)
M_StartKill(monster, pnum);
M_StartKill(monster, player);
else
M_StartHit(monster, pnum, mdam);
M_StartHit(monster, player, mdam);
}
if ((monster.flags & MFLAG_NOLIFESTEAL) == 0 && monster.type().type == MT_SKING && gbIsMultiplayer)
@ -1379,10 +1344,10 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa
M_StartStand(monster, monster.direction);
return;
}
StartPlrHit(pnum, dam, false);
StartPlrHit(player, dam, false);
if ((monster.flags & MFLAG_KNOCKBACK) != 0) {
if (player._pmode != PM_GOTHIT)
StartPlrHit(pnum, 0, true);
StartPlrHit(player, 0, true);
Point newPosition = player.position.tile + monster.direction;
if (PosOkPlayer(player, newPosition)) {
@ -3115,7 +3080,7 @@ void LachdananAi(int monsterId)
if (!effect_is_playing(USFX_LACH3) && monster.goal == MonsterGoal::Talking) {
monster.talkMsg = TEXT_NONE;
Quests[Q_VEIL]._qactive = QUEST_DONE;
StartMonsterDeath(monster, -1, true);
MonsterDeath(monster, monster.direction, true);
}
}
}
@ -3907,16 +3872,15 @@ void M_StartHit(Monster &monster, int dam)
}
}
void M_StartHit(Monster &monster, int pnum, int dam)
void M_StartHit(Monster &monster, const Player &player, int dam)
{
monster.whoHit |= 1 << pnum;
Player &player = Players[pnum];
monster.whoHit |= 1 << player.getId();
if (&player == MyPlayer) {
delta_monster_hp(monster, *MyPlayer);
NetSendCmdMonDmg(false, monster.getId(), dam);
}
if (IsAnyOf(monster.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= monster.level + 3) {
monster.enemy = pnum;
monster.enemy = player.getId();
monster.enemyPosition = player.position.future;
monster.flags &= ~MFLAG_TARGETS_MONSTER;
monster.direction = GetMonsterDirection(monster);
@ -3925,27 +3889,64 @@ void M_StartHit(Monster &monster, int pnum, int dam)
M_StartHit(monster, dam);
}
void StartMonsterDeath(Monster &monster, int pnum, bool sendmsg)
void MonsterDeath(Monster &monster, Direction md, bool sendmsg)
{
if (monster.type().type != MT_GOLEM)
AddPlrMonstExper(monster.level, monster.exp, monster.whoHit);
MonsterKillCounts[monster.type().type]++;
monster.hitPoints = 0;
SetRndSeed(monster.rndItemSeed);
SpawnLoot(monster, sendmsg);
if (monster.type().type == MT_DIABLO)
DiabloDeath(monster, true);
else
PlayEffect(monster, 2);
if (monster.mode != MonsterMode::Petrified) {
if (monster.type().type == MT_GOLEM)
md = Direction::South;
NewMonsterAnim(monster, MonsterGraphic::Death, md, gGameLogicStep < GameLogicStep::ProcessMonsters ? AnimationDistributionFlags::ProcessAnimationPending : AnimationDistributionFlags::None);
monster.mode = MonsterMode::Death;
}
monster.goal = MonsterGoal::None;
monster.var1 = 0;
monster.position.offset = { 0, 0 };
monster.position.tile = monster.position.old;
monster.position.future = monster.position.old;
M_ClearSquares(monster);
dMonster[monster.position.tile.x][monster.position.tile.y] = monster.getId() + 1;
CheckQuestKill(monster, sendmsg);
M_FallenFear(monster.position.tile);
if (IsAnyOf(monster.type().type, MT_NACID, MT_RACID, MT_BACID, MT_XACID, MT_SPIDLORD))
AddMissile(monster.position.tile, { 0, 0 }, Direction::South, MIS_ACIDPUD, TARGET_PLAYERS, monster.getId(), monster.intelligence + 1, 0);
}
void StartMonsterDeath(Monster &monster, const Player &player, bool sendmsg)
{
Direction md = pnum >= 0 ? GetDirection(monster.position.tile, Players[pnum].position.tile) : monster.direction;
MonsterDeath(monster, pnum, md, sendmsg);
monster.whoHit |= 1 << player.getId();
Direction md = GetDirection(monster.position.tile, player.position.tile);
MonsterDeath(monster, md, sendmsg);
}
void M_StartKill(Monster &monster, int pnum)
void M_StartKill(Monster &monster, const Player &player)
{
if (pnum == MyPlayerId) {
if (&player == MyPlayer) {
delta_kill_monster(monster, monster.position.tile, *MyPlayer);
if (&monster != &Monsters[pnum]) {
NetSendCmdLocParam1(false, CMD_MONSTDEATH, monster.position.tile, monster.getId());
size_t monsterId = monster.getId();
if (monsterId != player.getId()) {
NetSendCmdLocParam1(false, CMD_MONSTDEATH, monster.position.tile, monsterId);
} else {
NetSendCmdLoc(MyPlayerId, false, CMD_KILLGOLEM, monster.position.tile);
}
}
StartMonsterDeath(monster, pnum, true);
StartMonsterDeath(monster, player, true);
}
void M_SyncStartKill(int monsterId, Point position, int pnum)
void M_SyncStartKill(int monsterId, Point position, const Player &player)
{
assert(static_cast<size_t>(monsterId) < MaxMonsters);
auto &monster = Monsters[monsterId];
@ -3960,7 +3961,7 @@ void M_SyncStartKill(int monsterId, Point position, int pnum)
monster.position.old = position;
}
StartMonsterDeath(monster, pnum, false);
StartMonsterDeath(monster, player, false);
}
void M_UpdateRelations(const Monster &monster)
@ -4584,7 +4585,7 @@ void MissToMonst(Missile &missile, Point position)
Player &player = Players[pnum];
if (player._pmode != PM_GOTHIT && player._pmode != PM_DEATH)
StartPlrHit(pnum, 0, true);
StartPlrHit(player, 0, true);
Point newPosition = oldPosition + monster.direction;
if (PosOkPlayer(player, newPosition)) {
player.position.tile = newPosition;
@ -4736,13 +4737,9 @@ void TalktoMonster(Monster &monster)
}
}
void SpawnGolem(int id, Point position, Missile &missile)
void SpawnGolem(Player &player, Monster &golem, Point position, Missile &missile)
{
assert(id >= 0 && id < MAX_PLRS);
Player &player = Players[id];
auto &golem = Monsters[id];
dMonster[position.x][position.y] = id + 1;
dMonster[position.x][position.y] = golem.getId() + 1;
golem.position.tile = position;
golem.position.future = position;
golem.position.old = position;

12
Source/monster.h

@ -26,6 +26,7 @@
namespace devilution {
struct Missile;
struct Player;
constexpr size_t MaxMonsters = 200;
constexpr size_t MaxLvlMTypes = 24;
@ -370,10 +371,11 @@ void M_StartStand(Monster &monster, Direction md);
void M_ClearSquares(const Monster &monster);
void M_GetKnockback(Monster &monster);
void M_StartHit(Monster &monster, int dam);
void M_StartHit(Monster &monster, int pnum, int dam);
void StartMonsterDeath(Monster &monster, int pnum, bool sendmsg);
void M_StartKill(Monster &monster, int pnum);
void M_SyncStartKill(int monsterId, Point position, int pnum);
void M_StartHit(Monster &monster, const Player &player, int dam);
void StartMonsterDeath(Monster &monster, const Player &player, bool sendmsg);
void MonsterDeath(Monster &monster, Direction md, bool sendmsg);
void M_StartKill(Monster &monster, const Player &player);
void M_SyncStartKill(int monsterId, Point position, const Player &player);
void M_UpdateRelations(const Monster &monster);
void DoEnding();
void PrepDoEnding();
@ -404,7 +406,7 @@ bool IsGoat(_monster_id mt);
bool SpawnSkeleton(Monster *monster, Point position);
Monster *PreSpawnSkeleton();
void TalktoMonster(Monster &monster);
void SpawnGolem(int id, Point position, Missile &missile);
void SpawnGolem(Player &player, Monster &golem, Point position, Missile &missile);
bool CanTalkToMonst(const Monster &monster);
int encode_enemy(Monster &monster);
void decode_enemy(Monster &monster, int enemyId);

54
Source/msg.cpp

@ -665,12 +665,6 @@ void DeltaOpenPortal(int pnum, Point position, uint8_t bLevel, dungeon_type bLTy
sgJunk.portal[pnum].setlvl = bSetLvl ? 1 : 0;
}
void CheckUpdatePlayer(int pnum)
{
if (gbIsMultiplayer && pnum == MyPlayerId)
pfile_update(true);
}
void NetSendCmdGItem2(bool usonly, _cmd_id bCmd, uint8_t mast, uint8_t pnum, const TCmdGItem &item)
{
TCmdGItem cmd;
@ -995,22 +989,25 @@ size_t OnPutItem(const TCmd *pCmd, int pnum)
} else if (IsPItemValid(message)) {
const Point position { message.x, message.y };
Player &player = Players[pnum];
bool isSelf = &player == MyPlayer;
if (player.isOnActiveLevel()) {
int ii;
if (&player == MyPlayer)
if (isSelf)
ii = InvPutItem(player, position, ItemLimbo);
else
ii = SyncPutItem(player, position, message.wIndx, message.wCI, message.dwSeed, message.bId, message.bDur, message.bMDur, message.bCh, message.bMCh, message.wValue, message.dwBuff, message.wToHit, message.wMaxDam, message.bMinStr, message.bMinMag, message.bMinDex, message.bAC);
if (ii != -1) {
PutItemRecord(message.dwSeed, message.wCI, message.wIndx);
DeltaPutItem(message, Items[ii].position, player);
CheckUpdatePlayer(pnum);
if (isSelf)
pfile_update(true);
}
return sizeof(message);
} else {
PutItemRecord(message.dwSeed, message.wCI, message.wIndx);
DeltaPutItem(message, position, player);
CheckUpdatePlayer(pnum);
if (isSelf)
pfile_update(true);
}
}
@ -1031,13 +1028,15 @@ size_t OnSyncPutItem(const TCmd *pCmd, int pnum)
if (ii != -1) {
PutItemRecord(message.dwSeed, message.wCI, message.wIndx);
DeltaPutItem(message, Items[ii].position, player);
CheckUpdatePlayer(pnum);
if (&player == MyPlayer)
pfile_update(true);
}
return sizeof(message);
} else {
PutItemRecord(message.dwSeed, message.wCI, message.wIndx);
DeltaPutItem(message, position, player);
CheckUpdatePlayer(pnum);
if (&player == MyPlayer)
pfile_update(true);
}
}
@ -1448,10 +1447,12 @@ size_t OnKnockback(const TCmd *pCmd, int pnum)
{
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd);
if (gbBufferMsgs != 1 && Players[pnum].isOnActiveLevel() && message.wParam1 < MaxMonsters) {
Player &player = Players[pnum];
if (gbBufferMsgs != 1 && player.isOnActiveLevel() && message.wParam1 < MaxMonsters) {
Monster &monster = Monsters[message.wParam1];
M_GetKnockback(monster);
M_StartHit(monster, pnum, 0);
M_StartHit(monster, player, 0);
}
return sizeof(message);
@ -1465,7 +1466,8 @@ size_t OnResurrect(const TCmd *pCmd, int pnum)
SendPacket(pnum, &message, sizeof(message));
} else if (message.wParam1 < MAX_PLRS) {
DoResurrect(pnum, message.wParam1);
CheckUpdatePlayer(pnum);
if (pnum == MyPlayerId)
pfile_update(true);
}
return sizeof(message);
@ -1515,7 +1517,7 @@ size_t OnNewLevel(const TCmd *pCmd, int pnum)
return sizeof(message);
}
StartNewLvl(pnum, mode, levelId);
StartNewLvl(Players[pnum], mode, levelId);
}
return sizeof(message);
@ -1528,7 +1530,7 @@ size_t OnWarp(const TCmd *pCmd, int pnum)
if (gbBufferMsgs == 1) {
SendPacket(pnum, &message, sizeof(message));
} else if (message.wParam1 < MAXPORTAL) {
StartWarpLvl(pnum, message.wParam1);
StartWarpLvl(Players[pnum], message.wParam1);
}
return sizeof(message);
@ -1544,7 +1546,7 @@ size_t OnMonstDeath(const TCmd *pCmd, int pnum)
if (&player != MyPlayer && InDungeonBounds(position) && message.wParam1 < MaxMonsters) {
Monster &monster = Monsters[message.wParam1];
if (player.isOnActiveLevel())
M_SyncStartKill(message.wParam1, position, pnum);
M_SyncStartKill(message.wParam1, position, player);
delta_kill_monster(monster, position, player);
}
} else {
@ -1564,7 +1566,7 @@ size_t OnKillGolem(const TCmd *pCmd, int pnum)
if (&player != MyPlayer && InDungeonBounds(position)) {
Monster &monster = Monsters[pnum];
if (player.isOnActiveLevel())
M_SyncStartKill(pnum, position, pnum);
M_SyncStartKill(pnum, position, player);
delta_kill_monster(monster, position, player);
}
} else {
@ -1634,7 +1636,7 @@ size_t OnPlayerDeath(const TCmd *pCmd, int pnum)
if (&player != MyPlayer)
StartPlayerKill(player, message.wParam1);
else
CheckUpdatePlayer(pnum);
pfile_update(true);
} else {
SendPacket(pnum, &message, sizeof(message));
}
@ -1722,16 +1724,16 @@ size_t OnPlayerOperateObject(const TCmd *pCmd, int pnum)
size_t OnBreakObject(const TCmd *pCmd, int pnum)
{
const auto &message = *reinterpret_cast<const TCmdParam2 *>(pCmd);
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd);
if (gbBufferMsgs == 1) {
SendPacket(pnum, &message, sizeof(message));
} else if (message.wParam1 < MAX_PLRS && message.wParam2 < MAXOBJECTS) {
} else if (message.wParam1 < MAXOBJECTS) {
Player &player = Players[pnum];
if (player.isOnActiveLevel()) {
SyncBreakObj(message.wParam1, Objects[message.wParam2]);
SyncBreakObj(player, Objects[message.wParam1]);
}
DeltaSyncObject(message.wParam2, CMD_BREAKOBJ, player);
DeltaSyncObject(message.wParam1, CMD_BREAKOBJ, player);
}
return sizeof(message);
@ -1866,9 +1868,9 @@ size_t OnPlayerJoinLevel(const TCmd *pCmd, int pnum)
player.setLevel(playerLevel);
ResetPlayerGFX(player);
if (player.isOnActiveLevel()) {
SyncInitPlr(pnum);
SyncInitPlr(player);
if ((player._pHitPoints >> 6) > 0) {
StartStand(pnum, Direction::South);
StartStand(player, Direction::South);
} else {
player._pgfxnum &= ~0xF;
player._pmode = PM_DEATH;
@ -1945,7 +1947,7 @@ size_t OnRestartTown(const TCmd *pCmd, int pnum)
MyPlayerIsDead = false;
gamemenu_off();
}
RestartTownLvl(pnum);
RestartTownLvl(Players[pnum]);
}
return sizeof(*pCmd);

4
Source/multi.cpp

@ -826,14 +826,14 @@ void recv_plrinfo(int pnum, const TCmdPlrInfoHdr &header, bool recv)
}
EventPlrMsg(fmt::format(fmt::runtime(szEvent), player._pName, player._pLevel));
SyncInitPlr(pnum);
SyncInitPlr(player);
if (!player.isOnActiveLevel()) {
return;
}
if (player._pHitPoints >> 6 > 0) {
StartStand(pnum, Direction::South);
StartStand(player, Direction::South);
return;
}

25
Source/objects.cpp

@ -1408,7 +1408,7 @@ void UpdateCircle(Object &circle)
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
ClrPlrPath(myPlayer);
StartStand(MyPlayerId, Direction::South);
StartStand(myPlayer, Direction::South);
}
}
@ -3815,11 +3815,11 @@ void BreakCrux(Object &crux)
ObjChangeMap(crux._oVar1, crux._oVar2, crux._oVar3, crux._oVar4);
}
void BreakBarrel(int pnum, Object &barrel, bool forcebreak, bool sendmsg)
void BreakBarrel(const Player &player, Object &barrel, bool forcebreak, bool sendmsg)
{
if (barrel._oSelFlag == 0)
return;
if (!forcebreak && pnum != MyPlayerId) {
if (!forcebreak && &player != MyPlayer) {
return;
}
@ -3851,7 +3851,7 @@ void BreakBarrel(int pnum, Object &barrel, bool forcebreak, bool sendmsg)
// don't really need to exclude large objects as explosive barrels are single tile objects, but using considerLargeObjects == false as this matches the old logic.
Object *adjacentObject = ObjectAtPosition({ xp, yp }, false);
if (adjacentObject != nullptr && adjacentObject->isExplosive() && !adjacentObject->IsBroken()) {
BreakBarrel(pnum, *adjacentObject, true, sendmsg);
BreakBarrel(player, *adjacentObject, true, sendmsg);
}
}
}
@ -3872,8 +3872,8 @@ void BreakBarrel(int pnum, Object &barrel, bool forcebreak, bool sendmsg)
if (barrel._oVar2 >= 8 && barrel._oVar4 >= 0)
SpawnSkeleton(&Monsters[barrel._oVar4], barrel.position);
}
if (pnum == MyPlayerId) {
NetSendCmdParam2(false, CMD_BREAKOBJ, pnum, static_cast<uint16_t>(barrel.GetId()));
if (&player == MyPlayer) {
NetSendCmdParam1(false, CMD_BREAKOBJ, static_cast<uint16_t>(barrel.GetId()));
}
}
@ -5144,10 +5144,15 @@ void SyncOpObject(int pnum, int cmd, int i)
}
}
void BreakObject(int pnum, Object &object)
void BreakObjectMissile(Object &object)
{
if (object.IsCrux())
BreakCrux(object);
}
void BreakObject(const Player &player, Object &object)
{
if (object.IsBarrel()) {
BreakBarrel(pnum, object, false, true);
BreakBarrel(player, object, false, true);
} else if (object.IsCrux()) {
BreakCrux(object);
}
@ -5167,10 +5172,10 @@ void DeltaSyncBreakObj(Object &object)
object._oAnimFrame = object._oAnimLen;
}
void SyncBreakObj(int pnum, Object &object)
void SyncBreakObj(const Player &player, Object &object)
{
if (object.IsBarrel()) {
BreakBarrel(pnum, object, true, false);
BreakBarrel(player, object, true, false);
}
}

5
Source/objects.h

@ -307,10 +307,11 @@ void ObjChangeMapResync(int x1, int y1, int x2, int y2);
int ItemMiscIdIdx(item_misc_id imiscid);
void OperateObject(int pnum, int i, bool TeleFlag);
void SyncOpObject(int pnum, int cmd, int i);
void BreakObject(int pnum, Object &object);
void BreakObjectMissile(Object &object);
void BreakObject(const Player &player, Object &object);
void DeltaSyncOpObject(int cmd, int i);
void DeltaSyncBreakObj(Object &object);
void SyncBreakObj(int pnum, Object &object);
void SyncBreakObj(const Player &player, Object &object);
void SyncObjectAnim(Object &object);
/**
* @brief Updates the text drawn in the info box to describe the given object

207
Source/player.cpp

@ -595,9 +595,8 @@ void DropHalfPlayersGold(Player &player)
player._pGold /= 2;
}
void InitLevelChange(int pnum)
void InitLevelChange(Player &player)
{
Player &player = Players[pnum];
Player &myPlayer = *MyPlayer;
RemovePlrMissiles(player);
@ -617,7 +616,7 @@ void InitLevelChange(int pnum)
FixPlrWalkTags(player);
SetPlayerOld(player);
if (&player == MyPlayer) {
dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1;
dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1;
} else {
player._pLvlVisited[player.plrlevel] = true;
}
@ -684,7 +683,7 @@ bool DoWalk(int pnum, int variant)
if (player.walkpath[0] != WALK_NONE) {
StartWalkStand(player);
} else {
StartStand(pnum, player.tempDirection);
StartStand(player, player.tempDirection);
}
ClearStateVariables(player);
@ -785,17 +784,12 @@ bool DamageWeapon(Player &player, unsigned damageFrequency)
return false;
}
bool PlrHitMonst(int pnum, size_t monsterId, bool adjacentDamage = false)
bool PlrHitMonst(Player &player, size_t monsterId, bool adjacentDamage = false)
{
int hper = 0;
Monster &monster = Monsters[monsterId];
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("PlrHitMonst: illegal player ", pnum));
}
Player &player = Players[pnum];
if (!monster.isPossibleToHit())
return false;
@ -826,7 +820,7 @@ bool PlrHitMonst(int pnum, size_t monsterId, bool adjacentDamage = false)
if (gbIsHellfire && HasAllOf(player._pIFlags, ItemSpecialEffect::FireDamage | ItemSpecialEffect::LightningDamage)) {
int midam = player._pIFMinDam + GenerateRnd(player._pIFMaxDam - player._pIFMinDam);
AddMissile(player.position.tile, player.position.temp, player._pdir, MIS_SPECARROW, TARGET_MONSTERS, pnum, midam, 0);
AddMissile(player.position.tile, player.position.temp, player._pdir, MIS_SPECARROW, TARGET_MONSTERS, player.getId(), midam, 0);
}
int mind = player._pIMinDam;
int maxd = player._pIMaxDam;
@ -957,22 +951,17 @@ bool PlrHitMonst(int pnum, size_t monsterId, bool adjacentDamage = false)
}
#endif
if ((monster.hitPoints >> 6) <= 0) {
M_StartKill(monster, pnum);
M_StartKill(monster, player);
} else {
if (monster.mode != MonsterMode::Petrified && HasAnyOf(player._pIFlags, ItemSpecialEffect::Knockback))
M_GetKnockback(monster);
M_StartHit(monster, pnum, dam);
M_StartHit(monster, player, dam);
}
return true;
}
bool PlrHitPlr(Player &attacker, int8_t p)
bool PlrHitPlr(Player &attacker, Player &target)
{
if (p < 0 || p >= MAX_PLRS) {
app_fatal(StrCat("PlrHitPlr: illegal target player ", p));
}
Player &target = Players[p];
if (target._pInvincible) {
return false;
}
@ -1029,17 +1018,17 @@ bool PlrHitPlr(Player &attacker, int8_t p)
drawhpflag = true;
}
if (&attacker == MyPlayer) {
NetSendCmdDamage(true, p, skdam);
NetSendCmdDamage(true, target.getId(), skdam);
}
StartPlrHit(p, skdam, false);
StartPlrHit(target, skdam, false);
return true;
}
bool PlrHitObj(int pnum, Object &targetObject)
bool PlrHitObj(const Player &player, Object &targetObject)
{
if (targetObject.IsBreakable()) {
BreakObject(pnum, targetObject);
BreakObject(player, targetObject);
return true;
}
@ -1081,13 +1070,13 @@ bool DoAttack(int pnum)
}
if (dMonster[dx][dy] != 0) {
didhit = PlrHitMonst(pnum, abs(dMonster[dx][dy]) - 1);
didhit = PlrHitMonst(player, abs(dMonster[dx][dy]) - 1);
} else if (dPlayer[dx][dy] != 0 && !player.friendlyMode) {
didhit = PlrHitPlr(player, abs(dPlayer[dx][dy]) - 1);
didhit = PlrHitPlr(player, Players[abs(dPlayer[dx][dy]) - 1]);
} else {
Object *object = ObjectAtPosition(position, false);
if (object != nullptr) {
didhit = PlrHitObj(pnum, *object);
didhit = PlrHitObj(player, *object);
}
}
if ((player._pClass == HeroClass::Monk
@ -1107,7 +1096,7 @@ bool DoAttack(int pnum)
int m = abs(dMonster[position.x][position.y]) - 1;
auto &monster = Monsters[m];
if (!CanTalkToMonst(monster) && monster.position.old == position) {
if (PlrHitMonst(pnum, m, true))
if (PlrHitMonst(player, m, true))
didhit = true;
}
}
@ -1116,21 +1105,21 @@ bool DoAttack(int pnum)
int m = abs(dMonster[position.x][position.y]) - 1;
auto &monster = Monsters[m];
if (!CanTalkToMonst(monster) && monster.position.old == position) {
if (PlrHitMonst(pnum, m, true))
if (PlrHitMonst(player, m, true))
didhit = true;
}
}
}
if (didhit && DamageWeapon(player, 30)) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
ClearStateVariables(player);
return true;
}
}
if (player.AnimInfo.currentFrame == player._pAFrames - 1) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
ClearStateVariables(player);
return true;
}
@ -1138,13 +1127,8 @@ bool DoAttack(int pnum)
return false;
}
bool DoRangeAttack(int pnum)
bool DoRangeAttack(Player &player)
{
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("PM_DoRangeAttack: illegal player ", pnum));
}
Player &player = Players[pnum];
int arrows = 0;
if (player.AnimInfo.currentFrame == player._pAFNum - 1) {
arrows = 1;
@ -1186,7 +1170,7 @@ bool DoRangeAttack(int pnum)
player._pdir,
mistype,
TARGET_MONSTERS,
pnum,
player.getId(),
dmg,
0);
@ -1195,14 +1179,14 @@ bool DoRangeAttack(int pnum)
}
if (DamageWeapon(player, 40)) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
ClearStateVariables(player);
return true;
}
}
if (player.AnimInfo.currentFrame >= player._pAFrames - 1) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
ClearStateVariables(player);
return true;
}
@ -1238,15 +1222,10 @@ void DamageParryItem(Player &player)
}
}
bool DoBlock(int pnum)
bool DoBlock(Player &player)
{
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("PM_DoBlock: illegal player ", pnum));
}
Player &player = Players[pnum];
if (player.AnimInfo.currentFrame >= player._pBFrames - 1) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
ClearStateVariables(player);
if (FlipCoin(10)) {
@ -1299,16 +1278,11 @@ void DamageArmor(Player &player)
CalcPlrInv(player, true);
}
bool DoSpell(int pnum)
bool DoSpell(Player &player)
{
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("PM_DoSpell: illegal player ", pnum));
}
Player &player = Players[pnum];
if (player.AnimInfo.currentFrame == player._pSFNum) {
CastSpell(
pnum,
player.getId(),
player._pSpell,
player.position.tile.x,
player.position.tile.y,
@ -1322,7 +1296,7 @@ bool DoSpell(int pnum)
}
if (player.AnimInfo.currentFrame >= player._pSFrames - 1) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
ClearStateVariables(player);
return true;
}
@ -1330,15 +1304,10 @@ bool DoSpell(int pnum)
return false;
}
bool DoGotHit(int pnum)
bool DoGotHit(Player &player)
{
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("PM_DoGotHit: illegal player ", pnum));
}
Player &player = Players[pnum];
if (player.AnimInfo.currentFrame >= player._pHFrames - 1) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
ClearStateVariables(player);
if (!FlipCoin(4)) {
DamageArmor(player);
@ -1524,7 +1493,7 @@ void CheckNewPath(int pnum, bool pmWillBeCalled)
player.walkpath[MaxPathLength - 1] = WALK_NONE;
if (player._pmode == PM_STAND) {
StartStand(pnum, player._pdir);
StartStand(player, player._pdir);
player.destAction = ACTION_NONE;
}
}
@ -1741,9 +1710,7 @@ bool PlrDeathModeOK(Player &player)
void ValidatePlayer()
{
if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) {
app_fatal(StrCat("ValidatePlayer: illegal player ", MyPlayerId));
}
assert(MyPlayer != nullptr);
Player &myPlayer = *MyPlayer;
if (myPlayer._pLevel > MaxCharacterLevel)
@ -1876,6 +1843,11 @@ void Player::RemoveSpdBarItem(int iv)
force_redraw = 255;
}
[[nodiscard]] size_t Player::getId() const
{
return std::distance<const Player *>(&Players[0], this);
}
int Player::GetBaseAttributeValue(CharacterAttribute attribute) const
{
switch (attribute) {
@ -2730,12 +2702,10 @@ void AddPlrMonstExper(int lvl, int exp, char pmask)
void InitPlayer(Player &player, bool firstTime)
{
Player &myPlayer = *MyPlayer;
if (firstTime) {
player._pRSplType = RSPLTYPE_INVALID;
player._pRSpell = SPL_INVALID;
if (&player == &myPlayer)
if (&player == MyPlayer)
LoadHotkeys();
player._pSBkSpell = SPL_INVALID;
player._pSpell = player._pRSpell;
@ -2766,7 +2736,7 @@ void InitPlayer(Player &player, bool firstTime)
player._pdir = Direction::South;
if (&player == &myPlayer) {
if (&player == MyPlayer) {
if (!firstTime || leveltype != DTYPE_TOWN) {
player.position.tile = ViewPosition;
}
@ -2782,13 +2752,13 @@ void InitPlayer(Player &player, bool firstTime)
player.walkpath[0] = WALK_NONE;
player.destAction = ACTION_NONE;
if (&player == &myPlayer) {
if (&player == MyPlayer) {
player._plid = AddLight(player.position.tile, player._pLightRad);
ChangeLightXY(player._plid, player.position.tile); // fix for a bug where old light is still visible at the entrance after reentering level
} else {
player._plid = NO_LIGHT;
}
player._pvid = AddVision(player.position.tile, player._pLightRad, &player == &myPlayer);
player._pvid = AddVision(player.position.tile, player._pLightRad, &player == MyPlayer);
}
if (player._pClass == HeroClass::Warrior) {
@ -2808,7 +2778,7 @@ void InitPlayer(Player &player, bool firstTime)
player._pNextExper = ExpLvlsTbl[player._pLevel];
player._pInvincible = false;
if (&player == &myPlayer) {
if (&player == MyPlayer) {
MyPlayerIsDead = false;
ScrollInfo.offset = { 0, 0 };
ScrollInfo._sdir = ScrollDirection::None;
@ -2817,12 +2787,8 @@ void InitPlayer(Player &player, bool firstTime)
void InitMultiView()
{
if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) {
app_fatal(StrCat("InitPlayer: illegal player ", MyPlayerId));
}
Player &myPlayer = *MyPlayer;
ViewPosition = myPlayer.position.tile;
assert(MyPlayer != nullptr);
ViewPosition = MyPlayer->position.tile;
}
void PlrClrTrans(Point position)
@ -2869,13 +2835,8 @@ void FixPlayerLocation(Player &player, Direction bDir)
ChangeVisionXY(player._pvid, player.position.tile);
}
void StartStand(int pnum, Direction dir)
void StartStand(Player &player, Direction dir)
{
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("StartStand: illegal player ", pnum));
}
Player &player = Players[pnum];
if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) {
SyncPlrKill(player, -1);
return;
@ -2885,7 +2846,7 @@ void StartStand(int pnum, Direction dir)
player._pmode = PM_STAND;
FixPlayerLocation(player, dir);
FixPlrWalkTags(player);
dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1;
dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1;
SetPlayerOld(player);
}
@ -2919,13 +2880,8 @@ void FixPlrWalkTags(const Player &player)
}
}
void StartPlrHit(int pnum, int dam, bool forcehit)
void StartPlrHit(Player &player, int dam, bool forcehit)
{
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("StartPlrHit: illegal player ", pnum));
}
Player &player = Players[pnum];
if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) {
SyncPlrKill(player, -1);
return;
@ -2963,7 +2919,7 @@ void StartPlrHit(int pnum, int dam, bool forcehit)
player._pmode = PM_GOTHIT;
FixPlayerLocation(player, pd);
FixPlrWalkTags(player);
dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1;
dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1;
SetPlayerOld(player);
}
@ -3147,7 +3103,7 @@ void RemovePlrMissiles(const Player &player)
if (leveltype != DTYPE_TOWN && &player == MyPlayer) {
Monster &golem = Monsters[MyPlayerId];
if (golem.position.tile.x != 1 || golem.position.tile.y != 0) {
M_StartKill(golem, MyPlayerId);
M_StartKill(golem, player);
AddCorpse(golem.position.tile, golem.type().corpseId, golem.direction);
int mx = golem.position.tile.x;
int my = golem.position.tile.y;
@ -3168,15 +3124,9 @@ void RemovePlrMissiles(const Player &player)
__attribute__((no_sanitize("shift-base")))
#endif
void
StartNewLvl(int pnum, interface_mode fom, int lvl)
StartNewLvl(Player &player, interface_mode fom, int lvl)
{
InitLevelChange(pnum);
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("StartNewLvl: illegal player ", pnum));
}
Player &player = Players[pnum];
Player &myPlayer = *MyPlayer;
InitLevelChange(player);
switch (fom) {
case WM_DIABNEXTLVL:
@ -3190,7 +3140,7 @@ StartNewLvl(int pnum, interface_mode fom, int lvl)
player.setLevel(setlvlnum);
break;
case WM_DIABTWARPUP:
myPlayer.pTownWarps |= 1 << (leveltype - 2);
MyPlayer->pTownWarps |= 1 << (leveltype - 2);
player.setLevel(lvl);
break;
case WM_DIABRETOWN:
@ -3209,13 +3159,9 @@ StartNewLvl(int pnum, interface_mode fom, int lvl)
}
}
void RestartTownLvl(int pnum)
void RestartTownLvl(Player &player)
{
InitLevelChange(pnum);
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("RestartTownLvl: illegal player ", pnum));
}
Player &player = Players[pnum];
InitLevelChange(player);
player.setLevel(0);
player._pInvincible = false;
@ -3234,11 +3180,9 @@ void RestartTownLvl(int pnum)
}
}
void StartWarpLvl(int pnum, int pidx)
void StartWarpLvl(Player &player, int pidx)
{
Player &player = Players[pnum];
InitLevelChange(pnum);
InitLevelChange(player);
if (gbIsMultiplayer) {
if (!player.isOnLevel(0)) {
@ -3261,9 +3205,7 @@ void StartWarpLvl(int pnum, int pidx)
void ProcessPlayers()
{
if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) {
app_fatal(StrCat("ProcessPlayers: illegal player ", MyPlayerId));
}
assert(MyPlayer != nullptr);
Player &myPlayer = *MyPlayer;
if (myPlayer.pLvlLoad > 0) {
@ -3331,16 +3273,16 @@ void ProcessPlayers()
tplayer = DoAttack(pnum);
break;
case PM_RATTACK:
tplayer = DoRangeAttack(pnum);
tplayer = DoRangeAttack(player);
break;
case PM_BLOCK:
tplayer = DoBlock(pnum);
tplayer = DoBlock(player);
break;
case PM_SPELL:
tplayer = DoSpell(pnum);
tplayer = DoSpell(player);
break;
case PM_GOTHIT:
tplayer = DoGotHit(pnum);
tplayer = DoGotHit(player);
break;
case PM_DEATH:
tplayer = DoDeath(player);
@ -3430,9 +3372,7 @@ void CheckPlrSpell(bool isShiftHeld, spell_id spellID, spell_type spellType)
{
bool addflag = false;
if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) {
app_fatal(StrCat("CheckPlrSpell: illegal player ", MyPlayerId));
}
assert(MyPlayer != nullptr);
Player &myPlayer = *MyPlayer;
if (!IsValidSpell(spellID)) {
@ -3569,10 +3509,8 @@ void SyncPlrAnim(Player &player)
ScrollViewPort(player, WalkSettings[static_cast<size_t>(player._pdir)].scrollDir);
}
void SyncInitPlrPos(int pnum)
void SyncInitPlrPos(Player &player)
{
Player &player = Players[pnum];
if (!gbIsMultiplayer || !player.isOnActiveLevel()) {
return;
}
@ -3596,7 +3534,7 @@ void SyncInitPlrPos(int pnum)
}();
player.position.tile = position;
dPlayer[position.x][position.y] = pnum + 1;
dPlayer[position.x][position.y] = player.getId() + 1;
if (&player == MyPlayer) {
player.position.future = position;
@ -3604,15 +3542,10 @@ void SyncInitPlrPos(int pnum)
}
}
void SyncInitPlr(int pnum)
void SyncInitPlr(Player &player)
{
if (pnum < 0 || pnum >= MAX_PLRS) {
app_fatal(StrCat("SyncInitPlr: illegal player ", pnum));
}
Player &player = Players[pnum];
SetPlrAnims(player);
SyncInitPlrPos(pnum);
SyncInitPlrPos(player);
if (&player != MyPlayer)
player._plid = NO_LIGHT;
}
@ -3787,9 +3720,7 @@ enum {
void PlayDungMsgs()
{
if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) {
app_fatal(StrCat("PlayDungMsgs: illegal player ", MyPlayerId));
}
assert(MyPlayer != nullptr);
Player &myPlayer = *MyPlayer;
if (currlevel == 1 && !myPlayer._pLvlVisited[1] && (myPlayer.pDungMsgs & DungMsgCathedral) == 0) {
@ -3828,9 +3759,9 @@ void PlayDungMsgs()
}
#ifdef BUILD_TESTING
bool TestPlayerDoGotHit(int pnum)
bool TestPlayerDoGotHit(Player &player)
{
return DoGotHit(pnum);
return DoGotHit(player);
}
#endif

19
Source/player.h

@ -368,6 +368,11 @@ struct Player {
*/
void RemoveInvItem(int iv, bool calcScrolls = true);
/**
* @brief Returns the network identifier for this player
*/
[[nodiscard]] size_t getId() const;
void RemoveSpdBarItem(int iv);
/**
@ -771,10 +776,10 @@ void PlrClrTrans(Point position);
void PlrDoTrans(Point position);
void SetPlayerOld(Player &player);
void FixPlayerLocation(Player &player, Direction bDir);
void StartStand(int pnum, Direction dir);
void StartStand(Player &player, Direction dir);
void StartPlrBlock(Player &player, Direction dir);
void FixPlrWalkTags(const Player &player);
void StartPlrHit(int pnum, int dam, bool forcehit);
void StartPlrHit(Player &player, int dam, bool forcehit);
void StartPlayerKill(Player &player, int earflag);
/**
* @brief Strip the top off gold piles that are larger than MaxGold
@ -782,9 +787,9 @@ void StartPlayerKill(Player &player, int earflag);
void StripTopGold(Player &player);
void SyncPlrKill(Player &player, int earflag);
void RemovePlrMissiles(const Player &player);
void StartNewLvl(int pnum, interface_mode fom, int lvl);
void RestartTownLvl(int pnum);
void StartWarpLvl(int pnum, int pidx);
void StartNewLvl(Player &player, interface_mode fom, int lvl);
void RestartTownLvl(Player &player);
void StartWarpLvl(Player &player, int pidx);
void ProcessPlayers();
void ClrPlrPath(Player &player);
bool PosOkPlayer(const Player &player, Point position);
@ -792,8 +797,8 @@ void MakePlrPath(Player &player, Point targetPosition, bool endspace);
void CalcPlrStaff(Player &player);
void CheckPlrSpell(bool isShiftHeld, spell_id spellID = MyPlayer->_pRSpell, spell_type spellType = MyPlayer->_pRSplType);
void SyncPlrAnim(Player &player);
void SyncInitPlrPos(int pnum);
void SyncInitPlr(int pnum);
void SyncInitPlrPos(Player &player);
void SyncInitPlr(Player &player);
void CheckStats(Player &player);
void ModifyPlrStr(Player &player, int l);
void ModifyPlrMag(Player &player, int l);

2
Source/quests.cpp

@ -365,7 +365,7 @@ void CheckQuests()
if (quest._qlvltype != DTYPE_NONE) {
setlvltype = quest._qlvltype;
}
StartNewLvl(MyPlayerId, WM_DIABSETLVL, quest._qslvl);
StartNewLvl(*MyPlayer, WM_DIABSETLVL, quest._qslvl);
}
}
}

2
Source/spells.cpp

@ -295,7 +295,7 @@ void DoResurrect(int pnum, uint16_t rid)
CalcPlrInv(target, true);
if (target.isOnActiveLevel()) {
StartStand(rid, target._pdir);
StartStand(target, target._pdir);
} else {
target._pmode = PM_STAND;
}

9
test/player_test.cpp

@ -5,21 +5,20 @@
using namespace devilution;
namespace devilution {
extern bool TestPlayerDoGotHit(int pnum);
extern bool TestPlayerDoGotHit(Player &player);
}
int RunBlockTest(int frames, ItemSpecialEffect flags)
{
int pnum = 0;
Player &player = Players[pnum];
Player &player = Players[0];
player._pHFrames = frames;
player._pIFlags = flags;
StartPlrHit(pnum, 5, false);
StartPlrHit(player, 5, false);
int i = 1;
for (; i < 100; i++) {
TestPlayerDoGotHit(pnum);
TestPlayerDoGotHit(player);
if (player._pmode != PM_GOTHIT)
break;
player.AnimInfo.currentFrame++;

Loading…
Cancel
Save