Add travel service support for creatures (Fixes #2432)

celladd
scrawl 10 years ago
parent 457c135097
commit e30f240ba2

@ -6,6 +6,9 @@
#include <boost/format.hpp> #include <boost/format.hpp>
namespace
{
void printAIPackage(ESM::AIPackage p) void printAIPackage(ESM::AIPackage p)
{ {
std::cout << " AI Type: " << aiTypeLabel(p.mType) std::cout << " AI Type: " << aiTypeLabel(p.mType)
@ -149,6 +152,26 @@ void printEffectList(ESM::EffectList effects)
} }
} }
void printTransport(const std::vector<ESM::Transport::Dest>& transport)
{
std::vector<ESM::Transport::Dest>::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 { namespace EsmTool {
RecordBase * RecordBase *
@ -631,6 +654,8 @@ void Record<ESM::Creature>::print()
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
std::cout << " Spell: " << *sit << std::endl; std::cout << " Spell: " << *sit << std::endl;
printTransport(mData.getTransport());
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl;
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
@ -1042,20 +1067,7 @@ void Record<ESM::NPC>::print()
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
std::cout << " Spell: " << *sit << std::endl; std::cout << " Spell: " << *sit << std::endl;
std::vector<ESM::NPC::Dest>::iterator dit; printTransport(mData.getTransport());
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;
}
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl;

@ -383,7 +383,8 @@ namespace MWDialogue
|| services & ESM::NPC::Misc) || services & ESM::NPC::Misc)
windowServices |= MWGui::DialogueWindow::Service_Trade; windowServices |= MWGui::DialogueWindow::Service_Trade;
if(mActor.getTypeName() == typeid(ESM::NPC).name() && !mActor.get<ESM::NPC>()->mBase->mTransport.empty()) if((mActor.getTypeName() == typeid(ESM::NPC).name() && !mActor.get<ESM::NPC>()->mBase->getTransport().empty())
|| (mActor.getTypeName() == typeid(ESM::Creature).name() && !mActor.get<ESM::Creature>()->mBase->getTransport().empty()))
windowServices |= MWGui::DialogueWindow::Service_Travel; windowServices |= MWGui::DialogueWindow::Service_Travel;
if (services & ESM::NPC::Spells) if (services & ESM::NPC::Spells)

@ -111,20 +111,26 @@ namespace MWGui
mPtr = actor; mPtr = actor;
clearDestinations(); clearDestinations();
for(unsigned int i = 0;i<mPtr.get<ESM::NPC>()->mBase->mTransport.size();i++) std::vector<ESM::Transport::Dest> transport;
if (mPtr.getClass().isNpc())
transport = mPtr.get<ESM::NPC>()->mBase->getTransport();
else if (mPtr.getTypeName() == typeid(ESM::Creature).name())
transport = mPtr.get<ESM::Creature>()->mBase->getTransport();
for(unsigned int i = 0;i<transport.size();i++)
{ {
std::string cellname = mPtr.get<ESM::NPC>()->mBase->mTransport[i].mCellName; std::string cellname = transport[i].mCellName;
bool interior = true; bool interior = true;
int x,y; int x,y;
MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get<ESM::NPC>()->mBase->mTransport[i].mPos.pos[0], MWBase::Environment::get().getWorld()->positionToIndex(transport[i].mPos.pos[0],
mPtr.get<ESM::NPC>()->mBase->mTransport[i].mPos.pos[1],x,y); transport[i].mPos.pos[1],x,y);
if (cellname == "") if (cellname == "")
{ {
MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(x,y); MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(x,y);
cellname = MWBase::Environment::get().getWorld()->getCellName(cell); cellname = MWBase::Environment::get().getWorld()->getCellName(cell);
interior = false; interior = false;
} }
addDestination(cellname,mPtr.get<ESM::NPC>()->mBase->mTransport[i].mPos,interior); addDestination(cellname,transport[i].mPos,interior);
} }
updateLabels(); updateLabels();

@ -62,7 +62,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 inventorystate containerstate npcstate creaturestate dialoguestate statstate 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 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 add_component_dir (esmterrain

@ -15,6 +15,7 @@ namespace ESM {
mAiPackage.mList.clear(); mAiPackage.mList.clear();
mInventory.mList.clear(); mInventory.mList.clear();
mSpells.mList.clear(); mSpells.mList.clear();
mTransport.mList.clear();
mScale = 1.f; mScale = 1.f;
mHasAI = false; mHasAI = false;
@ -59,6 +60,10 @@ namespace ESM {
esm.getHExact(&mAiData, sizeof(mAiData)); esm.getHExact(&mAiData, sizeof(mAiData));
mHasAI = true; mHasAI = true;
break; 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_Wander:
case AI_Activate: case AI_Activate:
case AI_Escort: case AI_Escort:
@ -94,6 +99,7 @@ namespace ESM {
if (mHasAI) { if (mHasAI) {
esm.writeHNT("AIDT", mAiData, sizeof(mAiData)); esm.writeHNT("AIDT", mAiData, sizeof(mAiData));
} }
mTransport.save(esm);
mAiPackage.save(esm); mAiPackage.save(esm);
} }
@ -120,5 +126,11 @@ namespace ESM {
mAiData.blank(); mAiData.blank();
mAiData.mServices = 0; mAiData.mServices = 0;
mAiPackage.mList.clear(); mAiPackage.mList.clear();
mTransport.mList.clear();
}
const std::vector<Transport::Dest>& Creature::getTransport() const
{
return mTransport.mList;
} }
} }

@ -6,6 +6,7 @@
#include "loadcont.hpp" #include "loadcont.hpp"
#include "spelllist.hpp" #include "spelllist.hpp"
#include "aipackage.hpp" #include "aipackage.hpp"
#include "transport.hpp"
namespace ESM namespace ESM
{ {
@ -92,6 +93,9 @@ struct Creature
bool mHasAI; bool mHasAI;
AIData mAiData; AIData mAiData;
AIPackageList mAiPackage; AIPackageList mAiPackage;
Transport mTransport;
const std::vector<Transport::Dest>& getTransport() const;
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;

@ -14,7 +14,7 @@ namespace ESM
mSpells.mList.clear(); mSpells.mList.clear();
mInventory.mList.clear(); mInventory.mList.clear();
mTransport.clear(); mTransport.mList.clear();
mAiPackage.mList.clear(); mAiPackage.mList.clear();
bool hasNpdt = false; bool hasNpdt = false;
@ -81,14 +81,8 @@ namespace ESM
mHasAI= true; mHasAI= true;
break; break;
case ESM::FourCC<'D','O','D','T'>::value: 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: case ESM::FourCC<'D','N','A','M'>::value:
mTransport.back().mCellName = esm.getHString(); mTransport.add(esm);
break; break;
case AI_Wander: case AI_Wander:
case AI_Activate: case AI_Activate:
@ -131,11 +125,8 @@ namespace ESM
esm.writeHNT("AIDT", mAiData, sizeof(mAiData)); esm.writeHNT("AIDT", mAiData, sizeof(mAiData));
} }
typedef std::vector<Dest>::const_iterator DestIter; mTransport.save(esm);
for (DestIter it = mTransport.begin(); it != mTransport.end(); ++it) {
esm.writeHNT("DODT", it->mPos, sizeof(it->mPos));
esm.writeHNOCString("DNAM", it->mCellName);
}
mAiPackage.save(esm); mAiPackage.save(esm);
} }
@ -177,7 +168,7 @@ namespace ESM
mSpells.mList.clear(); mSpells.mList.clear();
mAiData.blank(); mAiData.blank();
mHasAI = false; mHasAI = false;
mTransport.clear(); mTransport.mList.clear();
mAiPackage.mList.clear(); mAiPackage.mList.clear();
mName.clear(); mName.clear();
mModel.clear(); mModel.clear();
@ -198,4 +189,9 @@ namespace ESM
else // NPC_DEFAULT else // NPC_DEFAULT
return mNpdt52.mRank; return mNpdt52.mRank;
} }
const std::vector<Transport::Dest>& NPC::getTransport() const
{
return mTransport.mList;
}
} }

@ -9,6 +9,7 @@
#include "aipackage.hpp" #include "aipackage.hpp"
#include "spelllist.hpp" #include "spelllist.hpp"
#include "loadskil.hpp" #include "loadskil.hpp"
#include "transport.hpp"
namespace ESM { namespace ESM {
@ -98,12 +99,6 @@ struct NPC
char mUnknown1, mUnknown2, mUnknown3; char mUnknown1, mUnknown2, mUnknown3;
int mGold; int mGold;
}; // 12 bytes }; // 12 bytes
struct Dest
{
Position mPos;
std::string mCellName;
};
#pragma pack(pop) #pragma pack(pop)
unsigned char mNpdtType; unsigned char mNpdtType;
@ -122,7 +117,10 @@ struct NPC
AIData mAiData; AIData mAiData;
bool mHasAI; bool mHasAI;
std::vector<Dest> mTransport; Transport mTransport;
const std::vector<Transport::Dest>& getTransport() const;
AIPackageList mAiPackage; AIPackageList mAiPackage;
std::string mId, mName, mModel, mRace, mClass, mFaction, mScript; std::string mId, mName, mModel, mRace, mClass, mFaction, mScript;

@ -0,0 +1,33 @@
#include "transport.hpp"
#include <components/esm/esmreader.hpp>
#include <components/esm/esmwriter.hpp>
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<Dest>::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);
}
}
}

@ -0,0 +1,36 @@
#ifndef OPENMW_COMPONENTS_ESM_TRANSPORT_H
#define OPENMW_COMPONENTS_ESM_TRANSPORT_H
#include <string>
#include <vector>
#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<Dest> mList;
/// Load one destination, assumes the subrecord name was already read
void add(ESMReader &esm);
void save(ESMWriter &esm) const;
};
}
#endif
Loading…
Cancel
Save