diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index be9b03e80..2ee6c54bb 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -6,6 +6,9 @@ #include +namespace +{ + void printAIPackage(ESM::AIPackage p) { std::cout << " AI Type: " << aiTypeLabel(p.mType) @@ -149,6 +152,26 @@ void printEffectList(ESM::EffectList effects) } } +void printTransport(const std::vector& transport) +{ + std::vector::const_iterator dit; + for (dit = transport.begin(); dit != transport.end(); ++dit) + { + std::cout << " Destination Position: " + << boost::format("%12.3f") % dit->mPos.pos[0] << "," + << boost::format("%12.3f") % dit->mPos.pos[1] << "," + << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; + std::cout << " Destination Rotation: " + << boost::format("%9.6f") % dit->mPos.rot[0] << "," + << boost::format("%9.6f") % dit->mPos.rot[1] << "," + << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; + if (dit->mCellName != "") + std::cout << " Destination Cell: " << dit->mCellName << std::endl; + } +} + +} + namespace EsmTool { RecordBase * @@ -631,6 +654,8 @@ void Record::print() for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) std::cout << " Spell: " << *sit << std::endl; + printTransport(mData.getTransport()); + std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; @@ -1042,20 +1067,7 @@ void Record::print() for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) std::cout << " Spell: " << *sit << std::endl; - std::vector::iterator dit; - for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); ++dit) - { - std::cout << " Destination Position: " - << boost::format("%12.3f") % dit->mPos.pos[0] << "," - << boost::format("%12.3f") % dit->mPos.pos[1] << "," - << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; - std::cout << " Destination Rotation: " - << boost::format("%9.6f") % dit->mPos.rot[0] << "," - << boost::format("%9.6f") % dit->mPos.rot[1] << "," - << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; - if (dit->mCellName != "") - std::cout << " Destination Cell: " << dit->mCellName << std::endl; - } + printTransport(mData.getTransport()); std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index e8dcf535c..00e59e2a5 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -383,7 +383,8 @@ namespace MWDialogue || services & ESM::NPC::Misc) windowServices |= MWGui::DialogueWindow::Service_Trade; - if(mActor.getTypeName() == typeid(ESM::NPC).name() && !mActor.get()->mBase->mTransport.empty()) + if((mActor.getTypeName() == typeid(ESM::NPC).name() && !mActor.get()->mBase->getTransport().empty()) + || (mActor.getTypeName() == typeid(ESM::Creature).name() && !mActor.get()->mBase->getTransport().empty())) windowServices |= MWGui::DialogueWindow::Service_Travel; if (services & ESM::NPC::Spells) diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 6a45e6026..4da1ab33a 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -111,20 +111,26 @@ namespace MWGui mPtr = actor; clearDestinations(); - for(unsigned int i = 0;i()->mBase->mTransport.size();i++) + std::vector transport; + if (mPtr.getClass().isNpc()) + transport = mPtr.get()->mBase->getTransport(); + else if (mPtr.getTypeName() == typeid(ESM::Creature).name()) + transport = mPtr.get()->mBase->getTransport(); + + for(unsigned int i = 0;i()->mBase->mTransport[i].mCellName; + std::string cellname = transport[i].mCellName; bool interior = true; int x,y; - MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get()->mBase->mTransport[i].mPos.pos[0], - mPtr.get()->mBase->mTransport[i].mPos.pos[1],x,y); + MWBase::Environment::get().getWorld()->positionToIndex(transport[i].mPos.pos[0], + transport[i].mPos.pos[1],x,y); if (cellname == "") { MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(x,y); cellname = MWBase::Environment::get().getWorld()->getCellName(cell); interior = false; } - addDestination(cellname,mPtr.get()->mBase->mTransport[i].mPos,interior); + addDestination(cellname,transport[i].mPos,interior); } updateLabels(); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index a49e54dd3..971897619 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -62,7 +62,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 inventorystate containerstate npcstate creaturestate dialoguestate statstate npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile - aisequence magiceffects util custommarkerstate stolenitems + aisequence magiceffects util custommarkerstate stolenitems transport ) add_component_dir (esmterrain diff --git a/components/esm/loadcrea.cpp b/components/esm/loadcrea.cpp index 86eede34e..50c47349c 100644 --- a/components/esm/loadcrea.cpp +++ b/components/esm/loadcrea.cpp @@ -15,6 +15,7 @@ namespace ESM { mAiPackage.mList.clear(); mInventory.mList.clear(); mSpells.mList.clear(); + mTransport.mList.clear(); mScale = 1.f; mHasAI = false; @@ -59,6 +60,10 @@ namespace ESM { esm.getHExact(&mAiData, sizeof(mAiData)); mHasAI = true; break; + case ESM::FourCC<'D','O','D','T'>::value: + case ESM::FourCC<'D','N','A','M'>::value: + mTransport.add(esm); + break; case AI_Wander: case AI_Activate: case AI_Escort: @@ -94,6 +99,7 @@ namespace ESM { if (mHasAI) { esm.writeHNT("AIDT", mAiData, sizeof(mAiData)); } + mTransport.save(esm); mAiPackage.save(esm); } @@ -120,5 +126,11 @@ namespace ESM { mAiData.blank(); mAiData.mServices = 0; mAiPackage.mList.clear(); + mTransport.mList.clear(); + } + + const std::vector& Creature::getTransport() const + { + return mTransport.mList; } } diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index e459dded7..1b02aa0ab 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -6,6 +6,7 @@ #include "loadcont.hpp" #include "spelllist.hpp" #include "aipackage.hpp" +#include "transport.hpp" namespace ESM { @@ -92,6 +93,9 @@ struct Creature bool mHasAI; AIData mAiData; AIPackageList mAiPackage; + Transport mTransport; + + const std::vector& getTransport() const; void load(ESMReader &esm); void save(ESMWriter &esm) const; diff --git a/components/esm/loadnpc.cpp b/components/esm/loadnpc.cpp index 98cedbe42..751c7f252 100644 --- a/components/esm/loadnpc.cpp +++ b/components/esm/loadnpc.cpp @@ -14,7 +14,7 @@ namespace ESM mSpells.mList.clear(); mInventory.mList.clear(); - mTransport.clear(); + mTransport.mList.clear(); mAiPackage.mList.clear(); bool hasNpdt = false; @@ -81,14 +81,8 @@ namespace ESM mHasAI= true; break; case ESM::FourCC<'D','O','D','T'>::value: - { - Dest dodt; - esm.getHExact(&dodt.mPos, 24); - mTransport.push_back(dodt); - break; - } case ESM::FourCC<'D','N','A','M'>::value: - mTransport.back().mCellName = esm.getHString(); + mTransport.add(esm); break; case AI_Wander: case AI_Activate: @@ -131,11 +125,8 @@ namespace ESM esm.writeHNT("AIDT", mAiData, sizeof(mAiData)); } - typedef std::vector::const_iterator DestIter; - for (DestIter it = mTransport.begin(); it != mTransport.end(); ++it) { - esm.writeHNT("DODT", it->mPos, sizeof(it->mPos)); - esm.writeHNOCString("DNAM", it->mCellName); - } + mTransport.save(esm); + mAiPackage.save(esm); } @@ -177,7 +168,7 @@ namespace ESM mSpells.mList.clear(); mAiData.blank(); mHasAI = false; - mTransport.clear(); + mTransport.mList.clear(); mAiPackage.mList.clear(); mName.clear(); mModel.clear(); @@ -198,4 +189,9 @@ namespace ESM else // NPC_DEFAULT return mNpdt52.mRank; } + + const std::vector& NPC::getTransport() const + { + return mTransport.mList; + } } diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index 9dc3be513..b535b91b0 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -9,6 +9,7 @@ #include "aipackage.hpp" #include "spelllist.hpp" #include "loadskil.hpp" +#include "transport.hpp" namespace ESM { @@ -98,12 +99,6 @@ struct NPC char mUnknown1, mUnknown2, mUnknown3; int mGold; }; // 12 bytes - - struct Dest - { - Position mPos; - std::string mCellName; - }; #pragma pack(pop) unsigned char mNpdtType; @@ -122,7 +117,10 @@ struct NPC AIData mAiData; bool mHasAI; - std::vector mTransport; + Transport mTransport; + + const std::vector& getTransport() const; + AIPackageList mAiPackage; std::string mId, mName, mModel, mRace, mClass, mFaction, mScript; diff --git a/components/esm/transport.cpp b/components/esm/transport.cpp new file mode 100644 index 000000000..da0a5f767 --- /dev/null +++ b/components/esm/transport.cpp @@ -0,0 +1,33 @@ +#include "transport.hpp" + +#include +#include + +namespace ESM +{ + + void Transport::add(ESMReader &esm) + { + if (esm.retSubName().val == ESM::FourCC<'D','O','D','T'>::value) + { + Dest dodt; + esm.getHExact(&dodt.mPos, 24); + mList.push_back(dodt); + } + else if (esm.retSubName().val == ESM::FourCC<'D','N','A','M'>::value) + { + mList.back().mCellName = esm.getHString(); + } + } + + void Transport::save(ESMWriter &esm) const + { + typedef std::vector::const_iterator DestIter; + for (DestIter it = mList.begin(); it != mList.end(); ++it) + { + esm.writeHNT("DODT", it->mPos, sizeof(it->mPos)); + esm.writeHNOCString("DNAM", it->mCellName); + } + } + +} diff --git a/components/esm/transport.hpp b/components/esm/transport.hpp new file mode 100644 index 000000000..10d4013f7 --- /dev/null +++ b/components/esm/transport.hpp @@ -0,0 +1,36 @@ +#ifndef OPENMW_COMPONENTS_ESM_TRANSPORT_H +#define OPENMW_COMPONENTS_ESM_TRANSPORT_H + +#include +#include + +#include "defs.hpp" + +namespace ESM +{ + + class ESMReader; + class ESMWriter; + + /// List of travel service destination. Shared by CREA and NPC_ records. + struct Transport + { + + struct Dest + { + Position mPos; + std::string mCellName; + }; + + std::vector mList; + + /// Load one destination, assumes the subrecord name was already read + void add(ESMReader &esm); + + void save(ESMWriter &esm) const; + + }; + +} + +#endif