forked from mirror/openmw-tes3mp
Add travel service support for creatures (Fixes #2432)
This commit is contained in:
parent
457c135097
commit
e30f240ba2
10 changed files with 140 additions and 42 deletions
|
@ -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;
|
||||||
|
|
33
components/esm/transport.cpp
Normal file
33
components/esm/transport.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
components/esm/transport.hpp
Normal file
36
components/esm/transport.hpp
Normal file
|
@ -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…
Reference in a new issue