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

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

@ -108,7 +108,7 @@ namespace ESSImport
}
std::vector<CellRef> cellrefs;
while (esm.hasMoreSubs())
while (esm.hasMoreSubs() && esm.isNextSub("FRMR"))
{
CellRef ref;
ref.load (esm);
@ -121,6 +121,36 @@ namespace ESSImport
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;
// FIXME: map by ID for exterior cells
@ -199,6 +229,13 @@ namespace ESSImport
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/loadglob.hpp>
#include <components/esm/cellstate.hpp>
#include <components/esm/custommarkerstate.hpp>
#include "importcrec.hpp"
#include "importercontext.hpp"
@ -240,6 +242,7 @@ private:
std::map<std::string, Cell> mCells;
std::vector<ESM::CustomMarker> mMarkers;
};
}

@ -49,6 +49,13 @@ namespace ESSImport
while (esm.isNextSub("FGTN"))
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
if (esm.isNextSub("PWPC"))
esm.skipHSub();

@ -7,7 +7,8 @@ namespace ESSImport
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
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_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();
it != converters.end(); ++it)
@ -232,7 +233,9 @@ namespace ESSImport
}
else
{
std::cerr << "unknown record " << n.toString() << std::endl;
if (unknownRecords.insert(n.val).second)
std::cerr << "unknown record " << n.toString() << std::endl;
esm.skipRecord();
}
}

@ -86,35 +86,16 @@ namespace
namespace MWGui
{
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");
}
// ------------------------------------------------------
void CustomMarkerCollection::addMarker(const CustomMarker &marker, bool triggerEvent)
void CustomMarkerCollection::addMarker(const ESM::CustomMarker &marker, bool triggerEvent)
{
mMarkers.push_back(marker);
if (triggerEvent)
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())
mMarkers.erase(it);
else
@ -123,9 +104,9 @@ namespace MWGui
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())
it->mNote = newNote;
else
@ -140,12 +121,12 @@ namespace MWGui
eventMarkersChanged();
}
std::vector<CustomMarker>::const_iterator CustomMarkerCollection::begin() const
std::vector<ESM::CustomMarker>::const_iterator CustomMarkerCollection::begin() const
{
return mMarkers.begin();
}
std::vector<CustomMarker>::const_iterator CustomMarkerCollection::end() const
std::vector<ESM::CustomMarker>::const_iterator CustomMarkerCollection::end() const
{
return mMarkers.end();
}
@ -295,9 +276,9 @@ namespace MWGui
MyGUI::Gui::getInstance().destroyWidget(*it);
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)
continue;
@ -654,7 +635,7 @@ namespace MWGui
void MapWindow::onCustomMarkerDoubleClicked(MyGUI::Widget *sender)
{
mEditingMarker = *sender->getUserData<CustomMarker>();
mEditingMarker = *sender->getUserData<ESM::CustomMarker>();
mEditNoteDialog.setText(mEditingMarker.mNote);
mEditNoteDialog.showDeleteButton(true);
mEditNoteDialog.setVisible(true);

@ -7,6 +7,8 @@
#include <components/esm/cellid.hpp>
#include <components/esm/custommarkerstate.hpp>
namespace MWRender
{
class GlobalMap;
@ -26,43 +28,25 @@ namespace Loading
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
{
public:
void addMarker(const CustomMarker& marker, bool triggerEvent=true);
void deleteMarker (const CustomMarker& marker);
void updateMarker(const CustomMarker& marker, const std::string& newNote);
void addMarker(const ESM::CustomMarker& marker, bool triggerEvent=true);
void deleteMarker (const ESM::CustomMarker& marker);
void updateMarker(const ESM::CustomMarker& marker, const std::string& newNote);
void clear();
size_t size() const;
std::vector<CustomMarker>::const_iterator begin() const;
std::vector<CustomMarker>::const_iterator end() const;
std::vector<ESM::CustomMarker>::const_iterator begin() const;
std::vector<ESM::CustomMarker>::const_iterator end() const;
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
EventHandle_Void eventMarkersChanged;
private:
std::vector<CustomMarker> mMarkers;
std::vector<ESM::CustomMarker> mMarkers;
};
class LocalMapBase
@ -233,7 +217,7 @@ namespace MWGui
MWRender::GlobalMap* mGlobalMapRender;
EditNoteDialog mEditNoteDialog;
CustomMarker mEditingMarker;
ESM::CustomMarker mEditingMarker;
virtual void onPinToggled();
virtual void onTitleDoubleClicked();

@ -1612,7 +1612,7 @@ namespace MWGui
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);
(*it).save(writer);
@ -1633,7 +1633,7 @@ namespace MWGui
}
else if (type == ESM::REC_MARK)
{
CustomMarker marker;
ESM::CustomMarker marker;
marker.load(reader);
mCustomMarkers.addMarker(marker, false);
}

@ -63,7 +63,7 @@ add_component_dir (esm
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
npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile
aisequence magiceffects util
aisequence magiceffects util custommarkerstate
)
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