Browse Source

Invert player to vision relation

pull/6005/head
Anders Jenbo 3 years ago
parent
commit
e969a8ad01
  1. 2
      Source/items.cpp
  2. 4
      Source/levels/gendung.cpp
  3. 2
      Source/levels/gendung.h
  4. 122
      Source/lighting.cpp
  5. 11
      Source/lighting.h
  6. 31
      Source/loadsave.cpp
  7. 2
      Source/missiles.cpp
  8. 2
      Source/msg.cpp
  9. 2
      Source/objects.cpp
  10. 6
      Source/player.cpp
  11. 1
      Source/player.h

2
Source/items.cpp

@ -2661,7 +2661,7 @@ void CalcPlrItemVals(Player &player, bool loadgfx)
if (player._pLightRad != lrad) { if (player._pLightRad != lrad) {
ChangeLightRadius(player.lightId, lrad); ChangeLightRadius(player.lightId, lrad);
ChangeVisionRadius(player._pvid, lrad); ChangeVisionRadius(player.getId(), lrad);
player._pLightRad = lrad; player._pLightRad = lrad;
} }

4
Source/levels/gendung.cpp

@ -36,7 +36,7 @@ dungeon_type setlvltype;
Point ViewPosition; Point ViewPosition;
uint_fast8_t MicroTileLen; uint_fast8_t MicroTileLen;
int8_t TransVal; int8_t TransVal;
bool TransList[256]; std::array<bool, 256> TransList;
uint16_t dPiece[MAXDUNX][MAXDUNY]; uint16_t dPiece[MAXDUNX][MAXDUNY];
MICROS DPieceMicros[MAXTILES]; MICROS DPieceMicros[MAXTILES];
int8_t dTransVal[MAXDUNX][MAXDUNY]; int8_t dTransVal[MAXDUNX][MAXDUNY];
@ -501,7 +501,7 @@ void SetDungeonMicros()
void DRLG_InitTrans() void DRLG_InitTrans()
{ {
memset(dTransVal, 0, sizeof(dTransVal)); memset(dTransVal, 0, sizeof(dTransVal));
memset(TransList, 0, sizeof(TransList)); TransList = {}; // TODO duplicate reset in InitLighting()
TransVal = 1; TransVal = 1;
} }

2
Source/levels/gendung.h

@ -186,7 +186,7 @@ extern DVL_API_FOR_TEST Point ViewPosition;
extern uint_fast8_t MicroTileLen; extern uint_fast8_t MicroTileLen;
extern int8_t TransVal; extern int8_t TransVal;
/** Specifies the active transparency indices. */ /** Specifies the active transparency indices. */
extern bool TransList[256]; extern std::array<bool, 256> TransList;
/** Contains the piece IDs of each tile on the map. */ /** Contains the piece IDs of each tile on the map. */
extern DVL_API_FOR_TEST uint16_t dPiece[MAXDUNX][MAXDUNY]; extern DVL_API_FOR_TEST uint16_t dPiece[MAXDUNX][MAXDUNY];
/** Map of micros that comprises a full tile for any given dungeon piece. */ /** Map of micros that comprises a full tile for any given dungeon piece. */

122
Source/lighting.cpp

@ -16,11 +16,10 @@
namespace devilution { namespace devilution {
std::array<bool, MAXVISION> VisionActive;
Light VisionList[MAXVISION]; Light VisionList[MAXVISION];
int VisionCount;
int VisionId;
Light Lights[MAXLIGHTS]; Light Lights[MAXLIGHTS];
uint8_t ActiveLights[MAXLIGHTS]; std::array<uint8_t, MAXLIGHTS> ActiveLights;
int ActiveLightCount; int ActiveLightCount;
std::array<std::array<uint8_t, 256>, NumLightingLevels> LightTables; std::array<std::array<uint8_t, 256>, NumLightingLevels> LightTables;
std::array<uint8_t, 256> InfravisionTable; std::array<uint8_t, 256> InfravisionTable;
@ -451,19 +450,13 @@ void InitLighting()
ActiveLightCount = 0; ActiveLightCount = 0;
UpdateLighting = false; UpdateLighting = false;
UpdateVision = false; UpdateVision = false;
VisionCount = 0;
VisionId = 1;
#ifdef _DEBUG #ifdef _DEBUG
DisableLighting = false; DisableLighting = false;
#endif #endif
for (int i = 0; i < MAXLIGHTS; i++) { std::iota(ActiveLights.begin(), ActiveLights.end(), 0);
ActiveLights[i] = i; VisionActive = {};
} TransList = {};
for (int i = 0; i < TransVal; i++) {
TransList[i] = false;
}
} }
int AddLight(Point position, uint8_t radius) int AddLight(Point position, uint8_t radius)
@ -618,54 +611,36 @@ void SavePreLighting()
memcpy(dPreLight, dLight, sizeof(dPreLight)); memcpy(dPreLight, dLight, sizeof(dPreLight));
} }
int AddVision(Point position, int r, bool mine) void ActivateVision(Point position, int r, int id)
{ {
if (VisionCount >= MAXVISION) auto &vision = VisionList[id];
return -1;
auto &vision = VisionList[VisionCount];
vision.position.tile = position; vision.position.tile = position;
vision.radius = r; vision.radius = r;
vision._lid = VisionId;
vision.isInvalid = false; vision.isInvalid = false;
vision.hasChanged = false; vision.hasChanged = false;
vision._lflags = mine; VisionActive[id] = true;
VisionId++;
VisionCount++;
UpdateVision = true; UpdateVision = true;
return vision._lid;
} }
void ChangeVisionRadius(int id, int r) void ChangeVisionRadius(int id, int r)
{ {
for (int i = 0; i < VisionCount; i++) { auto &vision = VisionList[id];
auto &vision = VisionList[i]; vision.hasChanged = true;
if (vision._lid != id) vision.position.old = vision.position.tile;
continue; vision.oldRadius = vision.radius;
vision.radius = r;
vision.hasChanged = true; UpdateVision = true;
vision.position.old = vision.position.tile;
vision.oldRadius = vision.radius;
vision.radius = r;
UpdateVision = true;
}
} }
void ChangeVisionXY(int id, Point position) void ChangeVisionXY(int id, Point position)
{ {
for (int i = 0; i < VisionCount; i++) { auto &vision = VisionList[id];
auto &vision = VisionList[i]; vision.hasChanged = true;
if (vision._lid != id) vision.position.old = vision.position.tile;
continue; vision.oldRadius = vision.radius;
vision.position.tile = position;
vision.hasChanged = true; UpdateVision = true;
vision.position.old = vision.position.tile;
vision.oldRadius = vision.radius;
vision.position.tile = position;
UpdateVision = true;
}
} }
void ProcessVisionList() void ProcessVisionList()
@ -673,58 +648,33 @@ void ProcessVisionList()
if (!UpdateVision) if (!UpdateVision)
return; return;
for (int i = 0; i < VisionCount; i++) { for (int i = 0; i < TransVal; i++) {
auto &vision = VisionList[i]; TransList[i] = false;
if (vision.isInvalid) { }
for (const Player &player : Players) {
int id = player.getId();
if (!VisionActive[id])
continue;
Light &vision = VisionList[id];
if (!player.plractive || !player.isOnActiveLevel()) {
DoUnVision(vision.position.tile, vision.radius); DoUnVision(vision.position.tile, vision.radius);
VisionActive[id] = false;
continue;
} }
if (vision.hasChanged) { if (vision.hasChanged) {
DoUnVision(vision.position.old, vision.oldRadius); DoUnVision(vision.position.old, vision.oldRadius);
vision.hasChanged = false; vision.hasChanged = false;
} }
}
for (int i = 0; i < TransVal; i++) {
TransList[i] = false;
}
for (int i = 0; i < VisionCount; i++) {
auto &vision = VisionList[i];
if (vision.isInvalid)
continue;
MapExplorationType doautomap = MAP_EXP_SELF; MapExplorationType doautomap = MAP_EXP_SELF;
if (!vision._lflags) { if (&player != MyPlayer)
doautomap = MAP_EXP_OTHERS; doautomap = player.friendlyMode ? MAP_EXP_OTHERS : MAP_EXP_NONE;
for (const Player &player : Players) {
// Find player for this vision
if (!player.plractive || !player.isOnActiveLevel() || player._pvid != vision._lid)
continue;
// Check that player allows automap sharing
if (!player.friendlyMode)
doautomap = MAP_EXP_NONE;
break;
}
}
DoVision( DoVision(
vision.position.tile, vision.position.tile,
vision.radius, vision.radius,
doautomap, doautomap,
vision._lflags); &player == MyPlayer);
} }
bool delflag;
do {
delflag = false;
for (int i = 0; i < VisionCount; i++) {
auto &vision = VisionList[i];
if (!vision.isInvalid)
continue;
VisionCount--;
if (VisionCount > 0 && i != VisionCount) {
vision = VisionList[VisionCount];
}
delflag = true;
}
} while (delflag);
UpdateVision = false; UpdateVision = false;
} }

11
Source/lighting.h

@ -20,7 +20,7 @@
namespace devilution { namespace devilution {
#define MAXLIGHTS 32 #define MAXLIGHTS 32
#define MAXVISION 32 #define MAXVISION 4
/** @brief Number of supported light levels */ /** @brief Number of supported light levels */
constexpr size_t NumLightingLevels = 16; constexpr size_t NumLightingLevels = 16;
#define NO_LIGHT -1 #define NO_LIGHT -1
@ -39,15 +39,12 @@ struct Light {
uint8_t oldRadius; uint8_t oldRadius;
bool isInvalid; bool isInvalid;
bool hasChanged; bool hasChanged;
int _lid;
bool _lflags;
}; };
extern Light VisionList[MAXVISION]; extern Light VisionList[MAXVISION];
extern int VisionCount; extern std::array<bool, MAXVISION> VisionActive;
extern int VisionId;
extern Light Lights[MAXLIGHTS]; extern Light Lights[MAXLIGHTS];
extern uint8_t ActiveLights[MAXLIGHTS]; extern std::array<uint8_t, MAXLIGHTS> ActiveLights;
extern int ActiveLightCount; extern int ActiveLightCount;
constexpr char LightsMax = 15; constexpr char LightsMax = 15;
extern std::array<std::array<uint8_t, 256>, NumLightingLevels> LightTables; extern std::array<std::array<uint8_t, 256>, NumLightingLevels> LightTables;
@ -75,7 +72,7 @@ void ChangeLightOffset(int i, Displacement offset);
void ChangeLight(int i, Point position, uint8_t radius); void ChangeLight(int i, Point position, uint8_t radius);
void ProcessLightList(); void ProcessLightList();
void SavePreLighting(); void SavePreLighting();
int AddVision(Point position, int r, bool mine); void ActivateVision(Point position, int r, int id);
void ChangeVisionRadius(int id, int r); void ChangeVisionRadius(int id, int r);
void ChangeVisionXY(int id, Point position); void ChangeVisionXY(int id, Point position);
void ProcessVisionList(); void ProcessVisionList();

31
Source/loadsave.cpp

@ -356,7 +356,7 @@ void LoadPlayer(LoadHelper &file, Player &player)
player.AnimInfo.currentFrame = file.NextLENarrow<int32_t, int8_t>(-1); player.AnimInfo.currentFrame = file.NextLENarrow<int32_t, int8_t>(-1);
file.Skip<uint32_t>(3); // Skip _pAnimWidth, _pAnimWidth2, _peflag file.Skip<uint32_t>(3); // Skip _pAnimWidth, _pAnimWidth2, _peflag
player.lightId = file.NextLE<int32_t>(); player.lightId = file.NextLE<int32_t>();
player._pvid = file.NextLE<int32_t>(); file.Skip<int32_t>(); // _pvid
player.queuedSpell.spellId = static_cast<SpellID>(file.NextLE<int32_t>()); player.queuedSpell.spellId = static_cast<SpellID>(file.NextLE<int32_t>());
player.queuedSpell.spellType = static_cast<SpellType>(file.NextLE<int8_t>()); player.queuedSpell.spellType = static_cast<SpellType>(file.NextLE<int8_t>());
@ -871,7 +871,7 @@ void LoadLighting(LoadHelper *file, Light *pLight)
pLight->position.tile.x = file->NextLE<int32_t>(); pLight->position.tile.x = file->NextLE<int32_t>();
pLight->position.tile.y = file->NextLE<int32_t>(); pLight->position.tile.y = file->NextLE<int32_t>();
pLight->radius = file->NextLE<int32_t>(); pLight->radius = file->NextLE<int32_t>();
pLight->_lid = file->NextLE<int32_t>(); file->Skip<int32_t>(); // _lid
pLight->isInvalid = file->NextBool32(); pLight->isInvalid = file->NextBool32();
pLight->hasChanged = file->NextBool32(); pLight->hasChanged = file->NextBool32();
file->Skip(4); // Unused file->Skip(4); // Unused
@ -880,7 +880,7 @@ void LoadLighting(LoadHelper *file, Light *pLight)
pLight->oldRadius = file->NextLE<int32_t>(); pLight->oldRadius = file->NextLE<int32_t>();
pLight->position.offset.deltaX = file->NextLE<int32_t>(); pLight->position.offset.deltaX = file->NextLE<int32_t>();
pLight->position.offset.deltaY = file->NextLE<int32_t>(); pLight->position.offset.deltaY = file->NextLE<int32_t>();
pLight->_lflags = file->NextBool32(); file->Skip<uint32_t>(); // _lflags
} }
void LoadPortal(LoadHelper *file, int i) void LoadPortal(LoadHelper *file, int i)
@ -1134,7 +1134,7 @@ void SavePlayer(SaveHelper &file, const Player &player)
file.WriteLE<int32_t>(CalculateWidth2(animWidth)); file.WriteLE<int32_t>(CalculateWidth2(animWidth));
file.Skip<uint32_t>(); // Skip _peflag file.Skip<uint32_t>(); // Skip _peflag
file.WriteLE<int32_t>(player.lightId); file.WriteLE<int32_t>(player.lightId);
file.WriteLE<int32_t>(player._pvid); file.WriteLE<int32_t>(1); // _pvid
file.WriteLE<int32_t>(static_cast<int8_t>(player.queuedSpell.spellId)); file.WriteLE<int32_t>(static_cast<int8_t>(player.queuedSpell.spellId));
file.WriteLE<int8_t>(static_cast<int8_t>(player.queuedSpell.spellType)); file.WriteLE<int8_t>(static_cast<int8_t>(player.queuedSpell.spellType));
@ -1610,12 +1610,12 @@ void SaveQuest(SaveHelper *file, int i)
file->Skip(sizeof(int32_t)); // Skip DoomQuestState file->Skip(sizeof(int32_t)); // Skip DoomQuestState
} }
void SaveLighting(SaveHelper *file, Light *pLight) void SaveLighting(SaveHelper *file, Light *pLight, bool vision = false)
{ {
file->WriteLE<int32_t>(pLight->position.tile.x); file->WriteLE<int32_t>(pLight->position.tile.x);
file->WriteLE<int32_t>(pLight->position.tile.y); file->WriteLE<int32_t>(pLight->position.tile.y);
file->WriteLE<int32_t>(pLight->radius); file->WriteLE<int32_t>(pLight->radius);
file->WriteLE<int32_t>(pLight->_lid); file->WriteLE<int32_t>(vision ? 1 : 0); // _lid
file->WriteLE<uint32_t>(pLight->isInvalid ? 1 : 0); file->WriteLE<uint32_t>(pLight->isInvalid ? 1 : 0);
file->WriteLE<uint32_t>(pLight->hasChanged ? 1 : 0); file->WriteLE<uint32_t>(pLight->hasChanged ? 1 : 0);
file->Skip(4); // Unused file->Skip(4); // Unused
@ -1624,7 +1624,7 @@ void SaveLighting(SaveHelper *file, Light *pLight)
file->WriteLE<int32_t>(pLight->oldRadius); file->WriteLE<int32_t>(pLight->oldRadius);
file->WriteLE<int32_t>(pLight->position.offset.deltaX); file->WriteLE<int32_t>(pLight->position.offset.deltaX);
file->WriteLE<int32_t>(pLight->position.offset.deltaY); file->WriteLE<int32_t>(pLight->position.offset.deltaY);
file->WriteLE<uint32_t>(pLight->_lflags ? 1 : 0); file->WriteLE<uint32_t>(vision ? 1 : 0);
} }
void SavePortal(SaveHelper *file, int i) void SavePortal(SaveHelper *file, int i)
@ -2156,11 +2156,13 @@ void LoadGame(bool firstflag)
for (int i = 0; i < ActiveLightCount; i++) for (int i = 0; i < ActiveLightCount; i++)
LoadLighting(&file, &Lights[ActiveLights[i]]); LoadLighting(&file, &Lights[ActiveLights[i]]);
VisionId = file.NextBE<int32_t>(); file.Skip<int32_t>(); // VisionId
VisionCount = file.NextBE<int32_t>(); int visionCount = file.NextBE<int32_t>();
for (int i = 0; i < VisionCount; i++) for (int i = 0; i < visionCount; i++) {
LoadLighting(&file, &VisionList[i]); LoadLighting(&file, &VisionList[i]);
VisionActive[i] = true;
}
} }
LoadDroppedItems(file, savedItemCount); LoadDroppedItems(file, savedItemCount);
@ -2419,11 +2421,12 @@ void SaveGameData(SaveWriter &saveWriter)
for (int i = 0; i < ActiveLightCount; i++) for (int i = 0; i < ActiveLightCount; i++)
SaveLighting(&file, &Lights[ActiveLights[i]]); SaveLighting(&file, &Lights[ActiveLights[i]]);
file.WriteBE<int32_t>(VisionId); int visionCount = Players.size();
file.WriteBE<int32_t>(VisionCount); file.WriteBE<int32_t>(visionCount + 1); // VisionId
file.WriteBE<int32_t>(visionCount);
for (int i = 0; i < VisionCount; i++) for (const Player &player : Players)
SaveLighting(&file, &VisionList[i]); SaveLighting(&file, &VisionList[player.getId()], true);
} }
auto itemIndexes = SaveDroppedItems(file); auto itemIndexes = SaveDroppedItems(file);

2
Source/missiles.cpp

@ -3623,7 +3623,7 @@ void ProcessTeleport(Missile &missile)
dPlayer[player.position.tile.x][player.position.tile.y] = id + 1; dPlayer[player.position.tile.x][player.position.tile.y] = id + 1;
if (leveltype != DTYPE_TOWN) { if (leveltype != DTYPE_TOWN) {
ChangeLightXY(player.lightId, player.position.tile); ChangeLightXY(player.lightId, player.position.tile);
ChangeVisionXY(player._pvid, player.position.tile); ChangeVisionXY(player.getId(), player.position.tile);
} }
if (&player == MyPlayer) { if (&player == MyPlayer) {
ViewPosition = player.position.tile; ViewPosition = player.position.tile;

2
Source/msg.cpp

@ -2117,7 +2117,7 @@ size_t OnPlayerJoinLevel(const TCmd *pCmd, size_t pnum)
dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer; dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer;
} }
player._pvid = AddVision(player.position.tile, player._pLightRad, &player == MyPlayer); ActivateVision(player.position.tile, player._pLightRad, player.getId());
} }
} }

2
Source/objects.cpp

@ -4315,7 +4315,7 @@ void RedoPlayerVision()
{ {
for (const Player &player : Players) { for (const Player &player : Players) {
if (player.plractive && player.isOnActiveLevel()) { if (player.plractive && player.isOnActiveLevel()) {
ChangeVisionXY(player._pvid, player.position.tile); ChangeVisionXY(player.getId(), player.position.tile);
} }
} }
} }

6
Source/player.cpp

@ -506,7 +506,7 @@ bool DoWalk(Player &player, int variant)
// Update the coordinates for lighting and vision entries for the player // Update the coordinates for lighting and vision entries for the player
if (leveltype != DTYPE_TOWN) { if (leveltype != DTYPE_TOWN) {
ChangeLightXY(player.lightId, player.position.tile); ChangeLightXY(player.lightId, player.position.tile);
ChangeVisionXY(player._pvid, player.position.tile); ChangeVisionXY(player.getId(), player.position.tile);
} }
if (player.walkpath[0] != WALK_NONE) { if (player.walkpath[0] != WALK_NONE) {
@ -2581,7 +2581,7 @@ void InitPlayer(Player &player, bool firstTime)
} else { } else {
player.lightId = NO_LIGHT; player.lightId = NO_LIGHT;
} }
player._pvid = AddVision(player.position.tile, player._pLightRad, &player == MyPlayer); ActivateVision(player.position.tile, player._pLightRad, player.getId());
} }
SpellID s = PlayersData[static_cast<size_t>(player._pClass)].skill; SpellID s = PlayersData[static_cast<size_t>(player._pClass)].skill;
@ -2639,7 +2639,7 @@ void FixPlayerLocation(Player &player, Direction bDir)
ViewPosition = player.position.tile; ViewPosition = player.position.tile;
} }
ChangeLightXY(player.lightId, player.position.tile); ChangeLightXY(player.lightId, player.position.tile);
ChangeVisionXY(player._pvid, player.position.tile); ChangeVisionXY(player.getId(), player.position.tile);
} }
void StartStand(Player &player, Direction dir) void StartStand(Player &player, Direction dir)

1
Source/player.h

@ -237,7 +237,6 @@ struct Player {
Item HoldItem; Item HoldItem;
int lightId; int lightId;
int _pvid;
int _pNumInv; int _pNumInv;
int _pStrength; int _pStrength;

Loading…
Cancel
Save