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) {
ChangeLightRadius(player.lightId, lrad);
ChangeVisionRadius(player._pvid, lrad);
ChangeVisionRadius(player.getId(), lrad);
player._pLightRad = lrad;
}

4
Source/levels/gendung.cpp

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

2
Source/levels/gendung.h

@ -186,7 +186,7 @@ extern DVL_API_FOR_TEST Point ViewPosition;
extern uint_fast8_t MicroTileLen;
extern int8_t TransVal;
/** 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. */
extern DVL_API_FOR_TEST uint16_t dPiece[MAXDUNX][MAXDUNY];
/** Map of micros that comprises a full tile for any given dungeon piece. */

122
Source/lighting.cpp

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

11
Source/lighting.h

@ -20,7 +20,7 @@
namespace devilution {
#define MAXLIGHTS 32
#define MAXVISION 32
#define MAXVISION 4
/** @brief Number of supported light levels */
constexpr size_t NumLightingLevels = 16;
#define NO_LIGHT -1
@ -39,15 +39,12 @@ struct Light {
uint8_t oldRadius;
bool isInvalid;
bool hasChanged;
int _lid;
bool _lflags;
};
extern Light VisionList[MAXVISION];
extern int VisionCount;
extern int VisionId;
extern std::array<bool, MAXVISION> VisionActive;
extern Light Lights[MAXLIGHTS];
extern uint8_t ActiveLights[MAXLIGHTS];
extern std::array<uint8_t, MAXLIGHTS> ActiveLights;
extern int ActiveLightCount;
constexpr char LightsMax = 15;
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 ProcessLightList();
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 ChangeVisionXY(int id, Point position);
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);
file.Skip<uint32_t>(3); // Skip _pAnimWidth, _pAnimWidth2, _peflag
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.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.y = 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->hasChanged = file->NextBool32();
file->Skip(4); // Unused
@ -880,7 +880,7 @@ void LoadLighting(LoadHelper *file, Light *pLight)
pLight->oldRadius = file->NextLE<int32_t>();
pLight->position.offset.deltaX = 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)
@ -1134,7 +1134,7 @@ void SavePlayer(SaveHelper &file, const Player &player)
file.WriteLE<int32_t>(CalculateWidth2(animWidth));
file.Skip<uint32_t>(); // Skip _peflag
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<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
}
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.y);
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->hasChanged ? 1 : 0);
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->position.offset.deltaX);
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)
@ -2156,11 +2156,13 @@ void LoadGame(bool firstflag)
for (int i = 0; i < ActiveLightCount; i++)
LoadLighting(&file, &Lights[ActiveLights[i]]);
VisionId = file.NextBE<int32_t>();
VisionCount = file.NextBE<int32_t>();
file.Skip<int32_t>(); // VisionId
int visionCount = file.NextBE<int32_t>();
for (int i = 0; i < VisionCount; i++)
for (int i = 0; i < visionCount; i++) {
LoadLighting(&file, &VisionList[i]);
VisionActive[i] = true;
}
}
LoadDroppedItems(file, savedItemCount);
@ -2419,11 +2421,12 @@ void SaveGameData(SaveWriter &saveWriter)
for (int i = 0; i < ActiveLightCount; i++)
SaveLighting(&file, &Lights[ActiveLights[i]]);
file.WriteBE<int32_t>(VisionId);
file.WriteBE<int32_t>(VisionCount);
int visionCount = Players.size();
file.WriteBE<int32_t>(visionCount + 1); // VisionId
file.WriteBE<int32_t>(visionCount);
for (int i = 0; i < VisionCount; i++)
SaveLighting(&file, &VisionList[i]);
for (const Player &player : Players)
SaveLighting(&file, &VisionList[player.getId()], true);
}
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;
if (leveltype != DTYPE_TOWN) {
ChangeLightXY(player.lightId, player.position.tile);
ChangeVisionXY(player._pvid, player.position.tile);
ChangeVisionXY(player.getId(), player.position.tile);
}
if (&player == MyPlayer) {
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;
}
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) {
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
if (leveltype != DTYPE_TOWN) {
ChangeLightXY(player.lightId, player.position.tile);
ChangeVisionXY(player._pvid, player.position.tile);
ChangeVisionXY(player.getId(), player.position.tile);
}
if (player.walkpath[0] != WALK_NONE) {
@ -2581,7 +2581,7 @@ void InitPlayer(Player &player, bool firstTime)
} else {
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;
@ -2639,7 +2639,7 @@ void FixPlayerLocation(Player &player, Direction bDir)
ViewPosition = 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)

1
Source/player.h

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

Loading…
Cancel
Save