[General] Simultaneously send loads & unloads in ID_PLAYER_CELL_STATE

This commit is contained in:
David Cernat 2017-02-03 20:27:40 +02:00
parent 63974af131
commit c1427b2558
9 changed files with 80 additions and 52 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -1000,6 +1000,11 @@ void LocalPlayer::sendSpellbook()
Main::get().getNetworking()->getPlayerPacket(ID_GAME_SPELLBOOK)->Send(this); 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) void LocalPlayer::sendSpellAddition(std::string id)
{ {
if (id.find("$dynamic") != string::npos) // skip custom spells 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); 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) void LocalPlayer::sendAttack(Attack::TYPE type)
{ {
MWMechanics::DrawState_ state = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState(); MWMechanics::DrawState_ state = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState();
@ -1103,6 +1088,20 @@ void LocalPlayer::sendAttack(Attack::TYPE type)
getNetworking()->sendData(&bs); 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) void LocalPlayer::prepareAttack(Attack::TYPE type, bool state)
{ {
if (attack.pressed == state && type != Attack::MAGIC) if (attack.pressed == state && type != Attack::MAGIC)

View file

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

View file

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

View file

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

View file

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