[General] Simultaneously send loads & unloads in ID_PLAYER_CELL_STATE

coverity_scan^2
David Cernat 8 years ago
parent 63974af131
commit c1427b2558

@ -180,7 +180,7 @@ void Networking::processPlayerPacket(RakNet::Packet *packet)
myPacket->Read(player);
Script::Call<Script::CallbackIdentity("OnPlayerCellState")>(player->getId(), player->cellStateChanges.action);
Script::Call<Script::CallbackIdentity("OnPlayerCellState")>(player->getId());
break;
}

@ -16,6 +16,14 @@ unsigned int CellFunctions::GetCellStateChangesSize(unsigned short pid) noexcept
return player->cellStateChanges.count;
}
unsigned int CellFunctions::GetCellStateType(unsigned short pid, unsigned int i) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->cellStateChanges.cellStates.at(i).type;
}
const char *CellFunctions::GetCellStateDescription(unsigned short pid, unsigned int i) noexcept
{
Player *player;
@ -24,7 +32,7 @@ const char *CellFunctions::GetCellStateDescription(unsigned short pid, unsigned
if (i >= player->cellStateChanges.count)
return "invalid";
string cellDescription = player->cellStateChanges.cells.at(i).getDescription();
string cellDescription = player->cellStateChanges.cellStates.at(i).cell.getDescription();
static vector<char> cstrDescription;
cstrDescription.reserve(cellDescription.size() + 1);

@ -6,6 +6,7 @@
#define CELLAPI \
{"GetCellStateChangesSize", CellFunctions::GetCellStateChangesSize},\
\
{"GetCellStateType", CellFunctions::GetCellStateType},\
{"GetCellStateDescription", CellFunctions::GetCellStateDescription},\
\
{"GetCell", CellFunctions::GetCell},\
@ -23,6 +24,7 @@ class CellFunctions
public:
static unsigned int GetCellStateChangesSize(unsigned short pid) noexcept;
static unsigned int GetCellStateType(unsigned short pid, unsigned int i) noexcept;
static const char *GetCellStateDescription(unsigned short pid, unsigned int i) noexcept;
static const char *GetCell(unsigned short pid) noexcept;

@ -109,7 +109,7 @@ public:
{"OnPlayerDeath", Function<void, unsigned short, short, unsigned short>()},
{"OnPlayerResurrect", Function<void, unsigned short>()},
{"OnPlayerCellChange", Function<void, unsigned short>()},
{"OnPlayerCellState", Function<void, unsigned short, int>()},
{"OnPlayerCellState", Function<void, unsigned short>()},
{"OnPlayerAttributesChange", Function<void, unsigned short>()},
{"OnPlayerSkillsChange", Function<void, unsigned short>()},
{"OnPlayerLevelChange", Function<void, unsigned short>()},

@ -1000,6 +1000,11 @@ void LocalPlayer::sendSpellbook()
Main::get().getNetworking()->getPlayerPacket(ID_GAME_SPELLBOOK)->Send(this);
}
void LocalPlayer::sendCellStates()
{
Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(this);
}
void LocalPlayer::sendSpellAddition(std::string id)
{
if (id.find("$dynamic") != string::npos) // skip custom spells
@ -1072,26 +1077,6 @@ void LocalPlayer::sendJournalIndex(const std::string& quest, int index)
Main::get().getNetworking()->getPlayerPacket(ID_GAME_JOURNAL)->Send(this);
}
void LocalPlayer::sendCellLoad(ESM::Cell cellLoaded)
{
cellStateChanges.cells.clear();
cellStateChanges.cells.push_back(cellLoaded);
cellStateChanges.action = CellStateChanges::LOAD;
Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(this);
}
void LocalPlayer::sendCellUnload(ESM::Cell cellUnloaded)
{
cellStateChanges.cells.clear();
cellStateChanges.cells.push_back(cellUnloaded);
cellStateChanges.action = CellStateChanges::UNLOAD;
Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(this);
}
void LocalPlayer::sendAttack(Attack::TYPE type)
{
MWMechanics::DrawState_ state = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState();
@ -1103,6 +1088,20 @@ void LocalPlayer::sendAttack(Attack::TYPE type)
getNetworking()->sendData(&bs);
}
void LocalPlayer::clearCellStates()
{
cellStateChanges.cellStates.clear();
}
void LocalPlayer::storeCellState(ESM::Cell cell, int stateType)
{
CellState cellState;
cellState.cell = cell;
cellState.type = stateType;
cellStateChanges.cellStates.push_back(cellState);
}
void LocalPlayer::prepareAttack(Attack::TYPE type, bool state)
{
if (attack.pressed == state && type != Attack::MAGIC)

@ -58,16 +58,19 @@ namespace mwmp
void sendClass();
void sendInventory();
void sendSpellbook();
void sendCellStates();
void sendSpellAddition(std::string id);
void sendSpellAddition(const ESM::Spell &spell);
void sendSpellRemoval(std::string id);
void sendSpellRemoval(const ESM::Spell &spell);
void sendJournalEntry(const std::string& id, int index, const MWWorld::Ptr& actor);
void sendJournalIndex(const std::string& id, int index);
void sendCellLoad(ESM::Cell cellLoaded);
void sendCellUnload(ESM::Cell cellUnloaded);
void sendAttack(Attack::TYPE type);
void clearCellStates();
void storeCellState(ESM::Cell cell, int stateType);
void prepareAttack(Attack::TYPE type, bool state);
private:

@ -246,9 +246,8 @@ namespace MWWorld
// Added by tes3mp
//
// LocalPlayer has unloaded a cell, so send a packet with it, but only if CharGen is over
if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen())
mwmp::Main::get().getLocalPlayer()->sendCellUnload(*(*iter)->getCell());
// LocalPlayer has unloaded a cell, so store it
mwmp::Main::get().getLocalPlayer()->storeCellState(*(*iter)->getCell(), 1);
}
void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn)
@ -316,9 +315,8 @@ namespace MWWorld
// Added by tes3mp
//
// LocalPlayer has loaded a cell, so send a packet with it, but only if CharGen is over
if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen())
mwmp::Main::get().getLocalPlayer()->sendCellLoad(*cell->getCell());
// LocalPlayer has loaded a cell, so store it
mwmp::Main::get().getLocalPlayer()->storeCellState(*cell->getCell(), 0);
}
mPreloader->notifyLoaded(cell);
@ -356,6 +354,9 @@ namespace MWWorld
void Scene::changeCellGrid (int X, int Y, bool changeEvent)
{
// Added by tes3mp
mwmp::Main::get().getLocalPlayer()->clearCellStates();
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
Loading::ScopedLoad load(loadingListener);
@ -433,6 +434,10 @@ namespace MWWorld
}
}
// Added by tes3mp
if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen())
mwmp::Main::get().getLocalPlayer()->sendCellStates();
CellStore* current = MWBase::Environment::get().getWorld()->getExterior(X,Y);
MWBase::Environment::get().getWindowManager()->changeCell(current);
@ -512,6 +517,9 @@ namespace MWWorld
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
{
// Added by tes3mp
mwmp::Main::get().getLocalPlayer()->clearCellStates();
CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
bool loadcell = (mCurrentCell == NULL);
if(!loadcell)
@ -559,6 +567,10 @@ namespace MWWorld
// Load cell.
loadCell (cell, loadingListener, changeEvent);
// Added by tes3mp
if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen())
mwmp::Main::get().getLocalPlayer()->sendCellStates();
changePlayerCell(cell, position, adjustPlayerPos);
// adjust fog

@ -62,6 +62,19 @@ namespace mwmp
int type; // 0 - An entire entry, 1 - An index
};
struct CellState
{
ESM::Cell cell;
enum CELl_STATE_ACTION
{
LOAD = 0,
UNLOAD = 1
};
int type; // 0 - Cell load, 1 - Cell unload
};
struct JournalChanges
{
std::vector<JournalItem> journalItems;
@ -96,16 +109,8 @@ namespace mwmp
struct CellStateChanges
{
std::vector<ESM::Cell> cells;
std::vector<CellState> cellStates;
unsigned int count;
enum ACTION_TYPE
{
LOAD = 0,
UNLOAD = 1
};
int action; // 0 - Load a cell, 1 - Unload a cell
};
class BasePlayer

@ -13,32 +13,31 @@ void mwmp::PacketPlayerCellState::Packet(RakNet::BitStream *bs, mwmp::BasePlayer
{
PlayerPacket::Packet(bs, player, send);
RW(player->cellStateChanges.action, send);
if (!send)
player->cellStateChanges.cells.clear();
player->cellStateChanges.cellStates.clear();
else
player->cellStateChanges.count = (unsigned int)(player->cellStateChanges.cells.size());
player->cellStateChanges.count = (unsigned int)(player->cellStateChanges.cellStates.size());
RW(player->cellStateChanges.count, send);
for (unsigned int i = 0; i < player->cellStateChanges.count; i++)
{
ESM::Cell cell;
CellState cellState;
if (send)
{
cell = player->cellStateChanges.cells[i];
cellState = player->cellStateChanges.cellStates[i];
}
RW(cell.mData.mFlags, send);
RW(cell.mData.mX, send);
RW(cell.mData.mY, send);
RW(cell.mName, send);
RW(cellState.type, send);
RW(cellState.cell.mData.mFlags, send);
RW(cellState.cell.mData.mX, send);
RW(cellState.cell.mData.mY, send);
RW(cellState.cell.mName, send);
if (!send)
{
player->cellStateChanges.cells.push_back(cell);
player->cellStateChanges.cellStates.push_back(cellState);
}
}
}

Loading…
Cancel
Save