ESSImport: convert custom map markers, not working for interiors yet

openmw-35
scrawl 10 years ago
parent 19ed047dec
commit f9cf31fcd5

@ -108,7 +108,7 @@ namespace ESSImport
} }
std::vector<CellRef> cellrefs; std::vector<CellRef> cellrefs;
while (esm.hasMoreSubs()) while (esm.hasMoreSubs() && esm.isNextSub("FRMR"))
{ {
CellRef ref; CellRef ref;
ref.load (esm); ref.load (esm);
@ -121,6 +121,36 @@ namespace ESSImport
cellrefs.push_back(ref); cellrefs.push_back(ref);
} }
while (esm.isNextSub("MPCD"))
{
float notepos[3];
esm.getHT(notepos, 3*sizeof(float));
// Markers seem to be arranged in a 32*32 grid, notepos has grid-indices.
// This seems to be the reason markers can't be placed everywhere in interior cells,
// i.e. when the grid is exceeded.
// Converting the interior markers correctly could be rather tricky, but is probably similar logic
// as used for the FoW texture placement, which we need to figure out anyway
notepos[1] += 31.f;
notepos[0] += 0.5;
notepos[1] += 0.5;
notepos[0] = 8192 * notepos[0] / 32.f;
notepos[1] = 8192 * notepos[1] / 32.f;
if (cell.isExterior())
{
notepos[0] += 8192 * cell.mData.mX;
notepos[1] += 8192 * cell.mData.mY;
}
// TODO: what encoding is this in?
std::string note = esm.getHNString("MPNT");
ESM::CustomMarker marker;
marker.mWorldX = notepos[0];
marker.mWorldY = notepos[1];
marker.mNote = note;
marker.mCell = cell.getCellId();
mMarkers.push_back(marker);
}
newcell.mRefs = cellrefs; newcell.mRefs = cellrefs;
// FIXME: map by ID for exterior cells // FIXME: map by ID for exterior cells
@ -199,6 +229,13 @@ namespace ESSImport
esm.endRecord(ESM::REC_CSTA); esm.endRecord(ESM::REC_CSTA);
} }
for (std::vector<ESM::CustomMarker>::const_iterator it = mMarkers.begin(); it != mMarkers.end(); ++it)
{
esm.startRecord(ESM::REC_MARK);
it->save(esm);
esm.endRecord(ESM::REC_MARK);
}
} }
} }

@ -9,6 +9,8 @@
#include <components/esm/loadclas.hpp> #include <components/esm/loadclas.hpp>
#include <components/esm/loadglob.hpp> #include <components/esm/loadglob.hpp>
#include <components/esm/cellstate.hpp> #include <components/esm/cellstate.hpp>
#include <components/esm/custommarkerstate.hpp>
#include "importcrec.hpp" #include "importcrec.hpp"
#include "importercontext.hpp" #include "importercontext.hpp"
@ -240,6 +242,7 @@ private:
std::map<std::string, Cell> mCells; std::map<std::string, Cell> mCells;
std::vector<ESM::CustomMarker> mMarkers;
}; };
} }

@ -49,6 +49,13 @@ namespace ESSImport
while (esm.isNextSub("FGTN")) while (esm.isNextSub("FGTN"))
esm.getHString(); // fight target? esm.getHString(); // fight target?
// unsure at which point between TGTN and CRED
if (esm.isNextSub("AADT"))
{
// occured when a creature was in the middle of its attack, 44 bytes
esm.skipHSub();
}
// unsure at which point between FGTN and CHRD // unsure at which point between FGTN and CHRD
if (esm.isNextSub("PWPC")) if (esm.isNextSub("PWPC"))
esm.skipHSub(); esm.skipHSub();

@ -7,7 +7,8 @@ namespace ESSImport
void CellRef::load(ESM::ESMReader &esm) void CellRef::load(ESM::ESMReader &esm)
{ {
esm.getHNT(mRefNum.mIndex, "FRMR"); // (FRMR subrecord name is already read by the loop in ConvertCell)
esm.getHT(mRefNum.mIndex); // FRMR
// this is required since openmw supports more than 255 content files // this is required since openmw supports more than 255 content files
int pluginIndex = (mRefNum.mIndex & 0xff000000) >> 24; int pluginIndex = (mRefNum.mIndex & 0xff000000) >> 24;

@ -213,6 +213,7 @@ namespace ESSImport
converters[ESM::REC_LEVC] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::CreatureLevList>()); converters[ESM::REC_LEVC] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::CreatureLevList>());
converters[ESM::REC_LEVI] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::ItemLevList>()); converters[ESM::REC_LEVI] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::ItemLevList>());
std::set<unsigned int> unknownRecords;
for (std::map<unsigned int, boost::shared_ptr<Converter> >::const_iterator it = converters.begin(); for (std::map<unsigned int, boost::shared_ptr<Converter> >::const_iterator it = converters.begin();
it != converters.end(); ++it) it != converters.end(); ++it)
@ -232,7 +233,9 @@ namespace ESSImport
} }
else else
{ {
if (unknownRecords.insert(n.val).second)
std::cerr << "unknown record " << n.toString() << std::endl; std::cerr << "unknown record " << n.toString() << std::endl;
esm.skipRecord(); esm.skipRecord();
} }
} }

@ -86,35 +86,16 @@ namespace
namespace MWGui namespace MWGui
{ {
void CustomMarker::save(ESM::ESMWriter &esm) const void CustomMarkerCollection::addMarker(const ESM::CustomMarker &marker, bool triggerEvent)
{
esm.writeHNT("POSX", mWorldX);
esm.writeHNT("POSY", mWorldY);
mCell.save(esm);
if (!mNote.empty())
esm.writeHNString("NOTE", mNote);
}
void CustomMarker::load(ESM::ESMReader &esm)
{
esm.getHNT(mWorldX, "POSX");
esm.getHNT(mWorldY, "POSY");
mCell.load(esm);
mNote = esm.getHNOString("NOTE");
}
// ------------------------------------------------------
void CustomMarkerCollection::addMarker(const CustomMarker &marker, bool triggerEvent)
{ {
mMarkers.push_back(marker); mMarkers.push_back(marker);
if (triggerEvent) if (triggerEvent)
eventMarkersChanged(); eventMarkersChanged();
} }
void CustomMarkerCollection::deleteMarker(const CustomMarker &marker) void CustomMarkerCollection::deleteMarker(const ESM::CustomMarker &marker)
{ {
std::vector<CustomMarker>::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker); std::vector<ESM::CustomMarker>::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker);
if (it != mMarkers.end()) if (it != mMarkers.end())
mMarkers.erase(it); mMarkers.erase(it);
else else
@ -123,9 +104,9 @@ namespace MWGui
eventMarkersChanged(); eventMarkersChanged();
} }
void CustomMarkerCollection::updateMarker(const CustomMarker &marker, const std::string &newNote) void CustomMarkerCollection::updateMarker(const ESM::CustomMarker &marker, const std::string &newNote)
{ {
std::vector<CustomMarker>::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker); std::vector<ESM::CustomMarker>::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker);
if (it != mMarkers.end()) if (it != mMarkers.end())
it->mNote = newNote; it->mNote = newNote;
else else
@ -140,12 +121,12 @@ namespace MWGui
eventMarkersChanged(); eventMarkersChanged();
} }
std::vector<CustomMarker>::const_iterator CustomMarkerCollection::begin() const std::vector<ESM::CustomMarker>::const_iterator CustomMarkerCollection::begin() const
{ {
return mMarkers.begin(); return mMarkers.begin();
} }
std::vector<CustomMarker>::const_iterator CustomMarkerCollection::end() const std::vector<ESM::CustomMarker>::const_iterator CustomMarkerCollection::end() const
{ {
return mMarkers.end(); return mMarkers.end();
} }
@ -295,9 +276,9 @@ namespace MWGui
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
mCustomMarkerWidgets.clear(); mCustomMarkerWidgets.clear();
for (std::vector<CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) for (std::vector<ESM::CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it)
{ {
const CustomMarker& marker = *it; const ESM::CustomMarker& marker = *it;
if (marker.mCell.mPaged != !mInterior) if (marker.mCell.mPaged != !mInterior)
continue; continue;
@ -654,7 +635,7 @@ namespace MWGui
void MapWindow::onCustomMarkerDoubleClicked(MyGUI::Widget *sender) void MapWindow::onCustomMarkerDoubleClicked(MyGUI::Widget *sender)
{ {
mEditingMarker = *sender->getUserData<CustomMarker>(); mEditingMarker = *sender->getUserData<ESM::CustomMarker>();
mEditNoteDialog.setText(mEditingMarker.mNote); mEditNoteDialog.setText(mEditingMarker.mNote);
mEditNoteDialog.showDeleteButton(true); mEditNoteDialog.showDeleteButton(true);
mEditNoteDialog.setVisible(true); mEditNoteDialog.setVisible(true);

@ -7,6 +7,8 @@
#include <components/esm/cellid.hpp> #include <components/esm/cellid.hpp>
#include <components/esm/custommarkerstate.hpp>
namespace MWRender namespace MWRender
{ {
class GlobalMap; class GlobalMap;
@ -26,43 +28,25 @@ namespace Loading
namespace MWGui namespace MWGui
{ {
struct CustomMarker
{
float mWorldX;
float mWorldY;
ESM::CellId mCell;
std::string mNote;
bool operator == (const CustomMarker& other)
{
return mNote == other.mNote && mCell == other.mCell && mWorldX == other.mWorldX && mWorldY == other.mWorldY;
}
void load (ESM::ESMReader& reader);
void save (ESM::ESMWriter& writer) const;
};
class CustomMarkerCollection class CustomMarkerCollection
{ {
public: public:
void addMarker(const CustomMarker& marker, bool triggerEvent=true); void addMarker(const ESM::CustomMarker& marker, bool triggerEvent=true);
void deleteMarker (const CustomMarker& marker); void deleteMarker (const ESM::CustomMarker& marker);
void updateMarker(const CustomMarker& marker, const std::string& newNote); void updateMarker(const ESM::CustomMarker& marker, const std::string& newNote);
void clear(); void clear();
size_t size() const; size_t size() const;
std::vector<CustomMarker>::const_iterator begin() const; std::vector<ESM::CustomMarker>::const_iterator begin() const;
std::vector<CustomMarker>::const_iterator end() const; std::vector<ESM::CustomMarker>::const_iterator end() const;
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
EventHandle_Void eventMarkersChanged; EventHandle_Void eventMarkersChanged;
private: private:
std::vector<CustomMarker> mMarkers; std::vector<ESM::CustomMarker> mMarkers;
}; };
class LocalMapBase class LocalMapBase
@ -233,7 +217,7 @@ namespace MWGui
MWRender::GlobalMap* mGlobalMapRender; MWRender::GlobalMap* mGlobalMapRender;
EditNoteDialog mEditNoteDialog; EditNoteDialog mEditNoteDialog;
CustomMarker mEditingMarker; ESM::CustomMarker mEditingMarker;
virtual void onPinToggled(); virtual void onPinToggled();
virtual void onTitleDoubleClicked(); virtual void onTitleDoubleClicked();

@ -1612,7 +1612,7 @@ namespace MWGui
writer.endRecord(ESM::REC_ASPL); writer.endRecord(ESM::REC_ASPL);
} }
for (std::vector<CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) for (std::vector<ESM::CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it)
{ {
writer.startRecord(ESM::REC_MARK); writer.startRecord(ESM::REC_MARK);
(*it).save(writer); (*it).save(writer);
@ -1633,7 +1633,7 @@ namespace MWGui
} }
else if (type == ESM::REC_MARK) else if (type == ESM::REC_MARK)
{ {
CustomMarker marker; ESM::CustomMarker marker;
marker.load(reader); marker.load(reader);
mCustomMarkers.addMarker(marker, false); mCustomMarkers.addMarker(marker, false);
} }

@ -63,7 +63,7 @@ add_component_dir (esm
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate
npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
aisequence magiceffects util aisequence magiceffects util custommarkerstate
) )
add_component_dir (esmterrain add_component_dir (esmterrain

@ -0,0 +1,26 @@
#include "custommarkerstate.hpp"
#include "esmwriter.hpp"
#include "esmreader.hpp"
namespace ESM
{
void CustomMarker::save(ESM::ESMWriter &esm) const
{
esm.writeHNT("POSX", mWorldX);
esm.writeHNT("POSY", mWorldY);
mCell.save(esm);
if (!mNote.empty())
esm.writeHNString("NOTE", mNote);
}
void CustomMarker::load(ESM::ESMReader &esm)
{
esm.getHNT(mWorldX, "POSX");
esm.getHNT(mWorldY, "POSY");
mCell.load(esm);
mNote = esm.getHNOString("NOTE");
}
}

@ -0,0 +1,30 @@
#ifndef OPENMW_ESM_CUSTOMMARKERSTATE_H
#define OPENMW_ESM_CUSTOMMARKERSTATE_H
#include "cellid.hpp"
namespace ESM
{
// format 0, saved games only
struct CustomMarker
{
float mWorldX;
float mWorldY;
ESM::CellId mCell;
std::string mNote;
bool operator == (const CustomMarker& other)
{
return mNote == other.mNote && mCell == other.mCell && mWorldX == other.mWorldX && mWorldY == other.mWorldY;
}
void load (ESM::ESMReader& reader);
void save (ESM::ESMWriter& writer) const;
};
}
#endif
Loading…
Cancel
Save