Merge pull request #418 from TES3MP/0.6.3 while resolving conflicts

sol2-server-rewrite
David Cernat 6 years ago
commit c5f33e451f

@ -211,7 +211,6 @@ void QuickKeys::addQuickKey(const QuickKey &quickKey)
setChanged();
}
QuickKey QuickKeys::getQuickKey(int id) const
{
return QuickKey(player->quickKeyChanges.quickKeys.at(id));
@ -277,3 +276,103 @@ void QuickKey::setItemId(const std::string &itemId)
{
quickKey.itemId = itemId;
}
void MapTiles::Init(LuaState &lua)
{
lua.getState()->new_usertype<MapTiles>("MapTiles",
"addMapTile", &MapTiles::addMapTile,
"getMapTile", &MapTiles::getMapTile,
"setMapTile", &MapTiles::setMapTile,
"clear", &MapTiles::clear,
"size", &MapTiles::size
);
}
MapTiles::MapTiles(Player *player) : BaseMgr(player)
{
}
void MapTiles::processUpdate()
{
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP);
packet->setPlayer(player);
packet->Send(false);
clear();
}
void MapTiles::addMapTile(const MapTile &mapTile)
{
player->mapChanges.mapTiles.push_back(mapTile.mapTile);
setChanged();
}
MapTile MapTiles::getMapTile(int id) const
{
return MapTile(player->mapChanges.mapTiles.at(id));
}
void MapTiles::setMapTile(int id, const MapTile &mapTile)
{
player->mapChanges.mapTiles.at(id) = mapTile.mapTile;
setChanged();
}
void MapTiles::clear()
{
player->mapChanges.mapTiles.clear();
setChanged();
}
size_t MapTiles::size() const
{
return player->mapChanges.mapTiles.size();
}
void MapTile::Init(LuaState &lua)
{
lua.getState()->new_usertype<MapTile>("MapTile",
"cellX", sol::property(&MapTile::getCellX, &MapTile::setCellX),
"cellY", sol::property(&MapTile::getCellY, &MapTile::setCellY),
"loadImageFile", &MapTile::loadImageFile,
"saveImageFile", &MapTile::saveImageFile
);
}
MapTile::MapTile(mwmp::MapTile &mapTile) : mapTile(mapTile)
{
}
int MapTile::getCellX() const
{
return mapTile.x;
}
void MapTile::setCellX(int cellX)
{
mapTile.x = cellX;
}
int MapTile::getCellY() const
{
return mapTile.y;
}
void MapTile::setCellY(int cellY)
{
mapTile.y = cellY;
}
void MapTile::loadImageFile(const char* filePath)
{
std::ifstream inputFile(filePath, std::ios::binary);
mapTile.imageData = std::vector<char>(std::istreambuf_iterator<char>(inputFile), std::istreambuf_iterator<char>());
}
void MapTile::saveImageFile(const char* filePath)
{
std::ofstream outputFile(filePath, std::ios::binary);
std::ostream_iterator<char> outputIterator(outputFile);
std::copy(mapTile.imageData.begin(), mapTile.imageData.end(), outputIterator);
}

@ -84,3 +84,40 @@ public:
private:
void processUpdate() final;
};
class MapTile
{
friend class MapTiles;
public:
static void Init(LuaState &lua);
public:
explicit MapTile(mwmp::MapTile &mapTile);
int getCellX() const;
void setCellX(int cellX);
int getCellY() const;
void setCellY(int cellY);
void loadImageFile(const char* filePath);
void saveImageFile(const char *filePath);
mwmp::MapTile mapTile;
};
class MapTiles final: public BaseMgr
{
public:
static void Init(LuaState &lua);
public:
explicit MapTiles(Player *player);
void addMapTile(const MapTile &mapTile);
MapTile getMapTile(int id) const;
void setMapTile(int id, const MapTile &mapTile);
size_t size() const;
void clear();
private:
void processUpdate() final;
};

@ -92,6 +92,7 @@ void Player::Init(LuaState &lua)
"getQuests", &Player::getQuests,
"getSpells", &Player::getSpells,
"getQuickKeys", &Player::getQuickKeys,
"getMapTiles", &Player::getMapTiles,
"getWeatherMgr", &Player::getWeatherMgr,
"getMark", &Player::getMark,
@ -100,9 +101,9 @@ void Player::Init(LuaState &lua)
"getSelectedSpell", &Player::getSelectedSpell,
"setSelectedSpell", &Player::setSelectedSpell,
"getCellState", &Player::getCellState,
"cellStateSize", &Player::cellStateSize,
"addCellExplored", &Player::addCellExplored,
"getCellState", &Player::getCellState,
"setAuthority", &Player::setAuthority,
"storedData", &Player::storedData,
@ -119,7 +120,7 @@ void Player::Init(LuaState &lua)
Player::Player(RakNet::RakNetGUID guid) : BasePlayer(guid), NetActor(), changedMap(false), cClass(this),
settings(this), books(this), gui(this), dialogue(this), factions(this),
quests(this), spells(this), quickKeys(this), weatherMgr(this)
quests(this), spells(this), quickKeys(this), mapTiles(this), weatherMgr(this)
{
basePlayer = this;
netCreature = this;
@ -292,6 +293,7 @@ void Player::update()
quests.update();
spells.update();
quickKeys.update();
mapTiles.update();
weatherMgr.update();
resetUpdateFlags();
@ -833,6 +835,11 @@ QuickKeys &Player::getQuickKeys()
return quickKeys;
}
MapTiles &Player::getMapTiles()
{
return mapTiles;
}
WeatherMgr &Player::getWeatherMgr()
{
return weatherMgr;
@ -924,13 +931,6 @@ size_t Player::cellStateSize() const
return cellStateChanges.cellStates.size();
}
void Player::addCellExplored(const std::string &cellDescription)
{
auto cellExplored = Utils::getCellFromDescription(cellDescription);
mapChanges.cellsExplored.push_back(cellExplored);
changedMap = true;
}
CellState Player::getCellState(int i)
{
return CellState(cellStateChanges.cellStates.at(i));

@ -186,9 +186,8 @@ public:
std::string getSelectedSpell();
void setSelectedSpell(const std::string &newSelectedSpellId);
CellState getCellState(int i);
size_t cellStateSize() const;
void addCellExplored(const std::string &cellDescription);
CellState getCellState(int i);
CharClass &getCharClass(sol::this_state thisState);
GameSettings &getSettings();
@ -199,6 +198,7 @@ public:
Quests &getQuests();
Spells &getSpells();
QuickKeys &getQuickKeys();
MapTiles &getMapTiles();
WeatherMgr &getWeatherMgr();
void setAuthority();
@ -221,6 +221,7 @@ private:
Quests quests;
Spells spells;
QuickKeys quickKeys;
MapTiles mapTiles;
WeatherMgr weatherMgr;
sol::table storedData;
sol::table customData;

@ -178,6 +178,10 @@ LuaState::LuaState()
mwmp::Networking::getPtr()->setPluginEnforcementState(state);
});
lua->set_function("doesFileExist", [](const char *filePath) {
return boost::filesystem::exists(filePath);
});
lua->set_function("getCaseInsensitiveFilename", [](const char *folderPath, const char *filename) {
if (!boost::filesystem::exists(folderPath)) return "invalid";

@ -17,9 +17,7 @@ namespace mwmp
{
DEBUG_PRINTF(strPacketID.c_str());
// Not currently implemented
//
// To be dealt with later to save explored areas on local maps
Networking::get().getState().getEventCtrl().Call<CoreEvent::ON_PLAYER_MAP>(player.get());
}
};
}

@ -213,9 +213,10 @@ namespace MWBase
/*
Start of tes3mp addition
Allow setting a cell as explored from elsewhere in the code
Allow the setting of the image data for a global map tile from elsewhere
in the code
*/
virtual void setCellExplored(const MWWorld::CellStore* cell) = 0;
virtual void setGlobalMapImage(int cellX, int cellY, const std::vector<char>& imageData) = 0;
/*
End of tes3mp addition
*/

@ -323,7 +323,7 @@ namespace MWBase
Make it possible to set the physics framerate from elsewhere
*/
virtual void World::setPhysicsFramerate(float physFramerate) = 0;
virtual void setPhysicsFramerate(float physFramerate) = 0;
/*
End of tes3mp addition
*/

@ -941,6 +941,20 @@ namespace MWGui
}
}
/*
Start of tes3mp addition
Allow the setting of the image data for a global map tile from elsewhere
in the code
*/
void MapWindow::setGlobalMapImage(int cellX, int cellY, const std::vector<char>& imageData)
{
mGlobalMapRender->setImage(cellX, cellY, imageData);
}
/*
End of tes3mp addition
*/
void MapWindow::updateCustomMarkers()
{
LocalMapBase::updateCustomMarkers();

@ -266,6 +266,17 @@ namespace MWGui
void setGlobalMapPlayerPosition (float worldX, float worldY);
void setGlobalMapPlayerDir(const float x, const float y);
/*
Start of tes3mp addition
Allow the setting of the image data for a global map tile from elsewhere
in the code
*/
void setGlobalMapImage(int cellX, int cellY, const std::vector<char>& imageData);
/*
End of tes3mp addition
*/
void ensureGlobalMapLoaded();
virtual void onOpen();

@ -1005,11 +1005,12 @@ namespace MWGui
/*
Start of tes3mp addition
Allow setting a cell as explored from elsewhere in the code
Allow the setting of the image data for a global map tile from elsewhere
in the code
*/
void WindowManager::setCellExplored(const MWWorld::CellStore* cell)
void WindowManager::setGlobalMapImage(int cellX, int cellY, const std::vector<char>& imageData)
{
mMap->cellExplored(cell->getCell()->getGridX(), cell->getCell()->getGridY());
mMap->setGlobalMapImage(cellX, cellY, imageData);
}
/*
End of tes3mp addition

@ -246,9 +246,10 @@ namespace MWGui
/*
Start of tes3mp addition
Allow setting a cell as explored from elsewhere in the code
Allow the setting of the image data for a global map tile from elsewhere
in the code
*/
virtual void setCellExplored(const MWWorld::CellStore* cell);
virtual void setGlobalMapImage(int cellX, int cellY, const std::vector<char>& imageData);
/*
End of tes3mp addition
*/

@ -1119,7 +1119,7 @@ void LocalPlayer::setEquipment()
else
{
// Don't try to equip an item that is already equipped
if (!ptrInventory.getSlot(slot).isEqual(it))
if (ptrInventory.getSlot(slot) != it)
ptrInventory.equip(slot, it, ptrPlayer);
}
}
@ -1299,12 +1299,17 @@ void LocalPlayer::setBooks()
void LocalPlayer::setMapExplored()
{
for (const auto &cellExplored : mapChanges.cellsExplored)
MWWorld::Ptr ptrPlayer = getPlayerPtr();
MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer);
for (const auto &mapTile : mapChanges.mapTiles)
{
MWWorld::CellStore *ptrCellStore = Main::get().getCellController()->getCellStore(cellExplored);
const MWWorld::CellStore *cellStore = MWBase::Environment::get().getWorld()->getExterior(mapTile.x, mapTile.y);
if (ptrCellStore)
MWBase::Environment::get().getWindowManager()->setCellExplored(ptrCellStore);
if (!cellStore->getCell()->mName.empty())
MWBase::Environment::get().getWindowManager()->addVisitedLocation(cellStore->getCell()->mName, mapTile.x, mapTile.y);
MWBase::Environment::get().getWindowManager()->setGlobalMapImage(mapTile.x, mapTile.y, mapTile.imageData);
}
}
@ -1651,6 +1656,23 @@ void LocalPlayer::sendSelectedSpell(const std::string& newSelectedSpellId)
getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->Send();
}
void LocalPlayer::sendMapExplored(int x, int y, const std::vector<char>& imageData)
{
mapChanges.mapTiles.clear();
mwmp::MapTile mapTile;
mapTile.x = x;
mapTile.y = y;
mapTile.imageData = imageData;
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_PLAYER_MAP with x: %i, y: %i", x, y);
mapChanges.mapTiles.push_back(mapTile);
getNetworking()->getPlayerPacket(ID_PLAYER_MAP)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_MAP)->Send();
}
void LocalPlayer::clearCellStates()
{
cellStateChanges.cellStates.clear();

@ -64,10 +64,10 @@ namespace mwmp
void setFactions();
void setKills();
void setBooks();
void setMapExplored();
void setShapeshift();
void setMarkLocation();
void setSelectedSpell();
void setMapExplored();
void sendClass();
void sendInventory();
@ -90,6 +90,7 @@ namespace mwmp
void sendWerewolfState(bool isWerewolf);
void sendMarkLocation(const ESM::Cell& newMarkCell, const ESM::Position& newMarkPosition);
void sendSelectedSpell(const std::string& newSelectedSpellId);
void sendMapExplored(int x, int y, const std::vector<char>& imageData);
void clearCellStates();
void clearCurrentContainer();

@ -19,6 +19,18 @@
#include <components/esm/globalmap.hpp>
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
#include <components/openmw-mp/Log.hpp>
#include "../mwmp/Main.hpp"
#include "../mwmp/LocalPlayer.hpp"
/*
End of tes3mp addition
*/
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -96,6 +108,17 @@ namespace
namespace MWRender
{
/*
Start of tes3mp addition
Use maps to track which global map coordinates belong to which cell coordinates
without having to significantly change other methods
*/
std::map<int, int> originToCellX;
std::map<int, int> originToCellY;
/*
End of tes3mp addition
*/
class CreateMapWorkItem : public SceneUtil::WorkItem
{
@ -382,6 +405,17 @@ namespace MWRender
if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY)
return;
/*
Start of tes3mp addition
Track the cell coordinates corresponding to these map image coordinates
*/
originToCellX[originX] = cellX;
originToCellY[originY - mCellSize] = cellY;
/*
End of tes3mp addition
*/
requestOverlayTextureUpdate(originX, mHeight - originY, mCellSize, mCellSize, localMapTexture, false, true);
}
@ -598,6 +632,40 @@ namespace MWRender
ensureLoaded();
mOverlayImage->copySubImage(imageDest.mX, imageDest.mY, 0, imageDest.mImage);
/*
Start of tes3mp addition
Send an ID_PLAYER_MAP packet with this map tile to the server
*/
if (originToCellX.count(imageDest.mX) > 0 && originToCellY.count(imageDest.mY) > 0)
{
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "New global map tile corresponds to cell %i, %i", originToCellX.at(imageDest.mX), originToCellY.at(imageDest.mY));
osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png");
if (!readerwriter)
{
std::cerr << "Error: Can't write temporary map image, no '" << "png" << "' readerwriter found" << std::endl;
return;
}
std::ostringstream ostream;
osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*imageDest.mImage, ostream);
if (!result.success())
{
std::cerr << "Error: Can't write temporary map image: " << result.message() << " code " << result.status() << std::endl;
}
std::string stringData = ostream.str();
std::vector<char> vectorData = std::vector<char>(stringData.begin(), stringData.end());
mwmp::Main::get().getLocalPlayer()->sendMapExplored(originToCellX.at(imageDest.mX), originToCellY.at(imageDest.mY), vectorData);
}
/*
End of tes3mp addition
*/
it = mPendingImageDest.erase(it);
}
}
@ -607,4 +675,50 @@ namespace MWRender
cam->removeChildren(0, cam->getNumChildren());
mRoot->removeChild(cam);
}
/*
Start of tes3mp addition
Allow the setting of the image data for a global map tile from elsewhere
in the code
*/
void GlobalMap::setImage(int cellX, int cellY, const std::vector<char>& imageData)
{
Files::IMemStream istream(&imageData[0], imageData.size());
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("png");
if (!reader)
{
std::cerr << "Error: Failed to read map tile image data, no png readerwriter found" << std::endl;
return;
}
osgDB::ReaderWriter::ReadResult result = reader->readImage(istream);
if (!result.success())
{
std::cerr << "Error: Can't read map tile image: " << result.message() << " code " << result.status() << std::endl;
return;
}
osg::ref_ptr<osg::Image> image = result.getImage();
int posX = (cellX - mMinX) * mCellSize;
int posY = (cellY - mMinY + 1) * mCellSize;
if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY)
return;
osg::ref_ptr<osg::Texture2D> texture(new osg::Texture2D);
texture->setImage(image);
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
texture->setResizeNonPowerOfTwoHint(false);
requestOverlayTextureUpdate(posX, mHeight - posY, mCellSize, mCellSize, texture, true, false);
}
/*
End of tes3mp addition
*/
}

@ -60,6 +60,17 @@ namespace MWRender
void removeCamera(osg::Camera* cam);
/*
Start of tes3mp addition
Allow the setting of the image data for a global map tile from elsewhere
in the code
*/
void setImage(int cellX, int cellY, const std::vector<char>& imageData);
/*
End of tes3mp addition
*/
/**
* Mark a camera for cleanup in the next update. For internal use only.
*/

@ -422,7 +422,7 @@ namespace MWWorld
Make it possible to set the physics framerate from elsewhere
*/
void World::setPhysicsFramerate(float physFramerate);
void setPhysicsFramerate(float physFramerate);
/*
End of tes3mp addition
*/

@ -127,6 +127,13 @@ namespace mwmp
Type type;
};
struct MapTile
{
int x;
int y;
std::vector<char> imageData;
};
struct JournalChanges
{
std::vector<JournalItem> journalItems;
@ -154,7 +161,7 @@ namespace mwmp
struct MapChanges
{
std::vector<ESM::Cell> cellsExplored;
std::vector<MapTile> mapTiles;
};
struct SpellbookChanges

@ -13,22 +13,40 @@ void PacketPlayerMap::Packet(RakNet::BitStream *bs, bool send)
{
PlayerPacket::Packet(bs, send);
uint32_t count;
uint32_t changesCount;
if (send)
count = static_cast<uint32_t>(player->mapChanges.cellsExplored.size());
changesCount = static_cast<uint32_t>(player->mapChanges.mapTiles.size());
RW(count, send);
RW(changesCount, send);
if (!send)
{
player->mapChanges.cellsExplored.clear();
player->mapChanges.cellsExplored.resize(count);
player->mapChanges.mapTiles.clear();
player->mapChanges.mapTiles.resize(changesCount);
}
for (auto &&cellExplored : player->mapChanges.cellsExplored)
for (auto &&mapTile : player->mapChanges.mapTiles)
{
RW(cellExplored.mData, send, true);
RW(cellExplored.mName, send, true);
RW(mapTile.x, send);
RW(mapTile.y, send);
uint32_t imageDataCount;
if (send)
imageDataCount = static_cast<uint32_t>(mapTile.imageData.size());
RW(imageDataCount, send);
if (!send)
{
mapTile.imageData.clear();
mapTile.imageData.resize(imageDataCount);
}
for (auto &&imageChar : mapTile.imageData)
{
RW(imageChar, send);
}
}
}

Loading…
Cancel
Save