mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 17:29:55 +00:00
Merge branch 'master' of http://github.com/zinnschlag/openmw
This commit is contained in:
commit
304692dc8e
21 changed files with 1198 additions and 642 deletions
|
@ -41,6 +41,14 @@ set(GAMEGUI
|
||||||
)
|
)
|
||||||
source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI})
|
source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI})
|
||||||
|
|
||||||
|
set(GAMEDIALOGUE_HEADER
|
||||||
|
mwdialogue/dialoguemanager.hpp
|
||||||
|
)
|
||||||
|
set(GAMEDIALOGUE
|
||||||
|
mwdialogue/dialoguemanager.cpp
|
||||||
|
)
|
||||||
|
source_group(apps\\openmw\\mwdialogue FILES ${GAMEDIALOGUE_HEADER} ${GAMEDIALOGUE})
|
||||||
|
|
||||||
set(GAMESCRIPT
|
set(GAMESCRIPT
|
||||||
mwscript/scriptmanager.cpp
|
mwscript/scriptmanager.cpp
|
||||||
mwscript/compilercontext.cpp
|
mwscript/compilercontext.cpp
|
||||||
|
@ -97,6 +105,7 @@ set(GAMEWORLD_HEADER
|
||||||
mwworld/action.hpp
|
mwworld/action.hpp
|
||||||
mwworld/nullaction.hpp
|
mwworld/nullaction.hpp
|
||||||
mwworld/actionteleport.hpp
|
mwworld/actionteleport.hpp
|
||||||
|
mwworld/containerstore.hpp
|
||||||
mwworld/actiontalk.hpp
|
mwworld/actiontalk.hpp
|
||||||
mwworld/actiontake.hpp
|
mwworld/actiontake.hpp
|
||||||
mwworld/containerstore.hpp
|
mwworld/containerstore.hpp
|
||||||
|
@ -164,11 +173,11 @@ set(GAMEMECHANICS_HEADER
|
||||||
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})
|
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})
|
||||||
|
|
||||||
set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD}
|
set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD}
|
||||||
${GAMECLASS} ${GAMEMECHANICS}
|
${GAMECLASS} ${GAMEMECHANICS} ${GAMEDIALOGUE}
|
||||||
)
|
)
|
||||||
set(OPENMW_HEADER ${GAME_HEADER} ${GAMEREND_HEADER} ${GAMEINPUT_HEADER} ${GAMESCRIPT_HEADER}
|
set(OPENMW_HEADER ${GAME_HEADER} ${GAMEREND_HEADER} ${GAMEINPUT_HEADER} ${GAMESCRIPT_HEADER}
|
||||||
${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER} ${GAMECLASS_HEADER}
|
${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER} ${GAMECLASS_HEADER}
|
||||||
${GAMEMECHANICS_HEADER}
|
${GAMEMECHANICS_HEADER} ${GAMEDIALOG_HEADERUE}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Main executable
|
# Main executable
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include "mwclass/classes.hpp"
|
#include "mwclass/classes.hpp"
|
||||||
|
|
||||||
|
#include "mwdialogue/dialoguemanager.hpp"
|
||||||
|
|
||||||
#include "mwmechanics/mechanicsmanager.hpp"
|
#include "mwmechanics/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
@ -117,6 +119,7 @@ OMW::Engine::~Engine()
|
||||||
delete mEnvironment.mSoundManager;
|
delete mEnvironment.mSoundManager;
|
||||||
delete mEnvironment.mGlobalScripts;
|
delete mEnvironment.mGlobalScripts;
|
||||||
delete mEnvironment.mMechanicsManager;
|
delete mEnvironment.mMechanicsManager;
|
||||||
|
delete mEnvironment.mDialogueManager;
|
||||||
delete mScriptManager;
|
delete mScriptManager;
|
||||||
delete mScriptContext;
|
delete mScriptContext;
|
||||||
}
|
}
|
||||||
|
@ -253,6 +256,9 @@ void OMW::Engine::go()
|
||||||
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (
|
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (
|
||||||
mEnvironment.mWorld->getStore(), *mEnvironment.mWindowManager);
|
mEnvironment.mWorld->getStore(), *mEnvironment.mWindowManager);
|
||||||
|
|
||||||
|
// Create dialog system
|
||||||
|
mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment);
|
||||||
|
|
||||||
// load cell
|
// load cell
|
||||||
ESM::Position pos;
|
ESM::Position pos;
|
||||||
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
||||||
|
|
|
@ -15,6 +15,14 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Creature::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Creature>();
|
||||||
|
|
||||||
|
return ref->base->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Creature::insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
void Creature::insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
||||||
MWWorld::Environment& environment) const
|
MWWorld::Environment& environment) const
|
||||||
{
|
{
|
||||||
|
@ -96,7 +104,7 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
return *ptr.getRefData().getContainerStore();
|
return *ptr.getRefData().getContainerStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Creature::getScript (const MWWorld::Ptr& ptr) const
|
std::string Creature::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,9 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return ID of \a ptr
|
||||||
|
|
||||||
virtual void insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
virtual void insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
||||||
MWWorld::Environment& environment) const;
|
MWWorld::Environment& environment) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
|
@ -16,6 +16,14 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Npc::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::NPC>();
|
||||||
|
|
||||||
|
return ref->base->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Npc::insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
void Npc::insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
||||||
MWWorld::Environment& environment) const
|
MWWorld::Environment& environment) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,9 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return ID of \a ptr
|
||||||
|
|
||||||
virtual void insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
virtual void insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
||||||
MWWorld::Environment& environment) const;
|
MWWorld::Environment& environment) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
@ -26,14 +29,14 @@ namespace MWClass
|
||||||
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
|
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return creature stats
|
///< Return creature stats
|
||||||
|
|
||||||
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
|
||||||
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
|
||||||
///< Generate action for activation
|
|
||||||
|
|
||||||
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
|
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
|
||||||
const MWWorld::Ptr& ptr) const;
|
const MWWorld::Ptr& ptr) const;
|
||||||
///< Return container store
|
///< Return container store
|
||||||
|
|
||||||
|
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
|
||||||
|
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
|
||||||
|
///< Generate action for activation
|
||||||
|
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
|
280
apps/openmw/mwdialogue/dialoguemanager.cpp
Normal file
280
apps/openmw/mwdialogue/dialoguemanager.cpp
Normal file
|
@ -0,0 +1,280 @@
|
||||||
|
|
||||||
|
#include "dialoguemanager.hpp"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <components/esm/loaddial.hpp>
|
||||||
|
|
||||||
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/environment.hpp"
|
||||||
|
#include "../mwworld/world.hpp"
|
||||||
|
#include "../mwworld/refdata.hpp"
|
||||||
|
|
||||||
|
#include "../mwgui/window_manager.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::string toLower (const std::string& name)
|
||||||
|
{
|
||||||
|
std::string lowerCase;
|
||||||
|
|
||||||
|
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
|
||||||
|
(int(*)(int)) std::tolower);
|
||||||
|
|
||||||
|
return lowerCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
bool selectCompare (char comp, T1 value1, T2 value2)
|
||||||
|
{
|
||||||
|
switch (comp)
|
||||||
|
{
|
||||||
|
case '0': return value1==value2;
|
||||||
|
case '1': return value1!=value2;
|
||||||
|
case '2': return value1>value2;
|
||||||
|
case '3': return value1>=value2;
|
||||||
|
case '4': return value1<value2;
|
||||||
|
case '5': return value1<=value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error ("unknown compare type in dialogue info select");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool checkLocal (char comp, const std::string& name, T value, const MWWorld::Ptr& actor,
|
||||||
|
const ESMS::ESMStore& store)
|
||||||
|
{
|
||||||
|
std::string scriptName = MWWorld::Class::get (actor).getScript (actor);
|
||||||
|
|
||||||
|
if (scriptName.empty())
|
||||||
|
return false; // no script
|
||||||
|
|
||||||
|
const ESM::Script *script = store.scripts.find (scriptName);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (; i<static_cast<int> (script->varNames.size()); ++i)
|
||||||
|
if (script->varNames[i]==name)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i>=static_cast<int> (script->varNames.size()))
|
||||||
|
return false; // script does not have a variable of this name
|
||||||
|
|
||||||
|
const MWScript::Locals& locals = actor.getRefData().getLocals();
|
||||||
|
|
||||||
|
if (i<script->data.numShorts)
|
||||||
|
return selectCompare (comp, locals.mShorts[i], value);
|
||||||
|
else
|
||||||
|
i -= script->data.numShorts;
|
||||||
|
|
||||||
|
if (i<script->data.numLongs)
|
||||||
|
return selectCompare (comp, locals.mLongs[i], value);
|
||||||
|
else
|
||||||
|
i -= script->data.numShorts;
|
||||||
|
|
||||||
|
return selectCompare (comp, locals.mFloats.at (i), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool checkGlobal (char comp, const std::string& name, T value, MWWorld::World& world)
|
||||||
|
{
|
||||||
|
switch (world.getGlobalVariableType (name))
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
|
||||||
|
return selectCompare (comp, value, world.getGlobalVariable (name).mShort);
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
|
||||||
|
return selectCompare (comp, value, world.getGlobalVariable (name).mLong);
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
|
||||||
|
return selectCompare (comp, value, world.getGlobalVariable (name).mFloat);
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
|
||||||
|
world.getGlobalVariable (name); // trigger exception
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
throw std::runtime_error ("unsupported gobal variable type");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWDialogue
|
||||||
|
{
|
||||||
|
bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
|
||||||
|
const ESM::DialInfo::SelectStruct& select) const
|
||||||
|
{
|
||||||
|
char type = select.selectRule[1];
|
||||||
|
|
||||||
|
if (type!='0')
|
||||||
|
{
|
||||||
|
char comp = select.selectRule[4];
|
||||||
|
std::string name = select.selectRule.substr (5);
|
||||||
|
|
||||||
|
// TODO types 4, 5, 6, 7, 8, 9, A, B, C
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case '1': // function
|
||||||
|
|
||||||
|
return false; // TODO implement functions
|
||||||
|
|
||||||
|
case '2': // global
|
||||||
|
|
||||||
|
if (select.type==ESM::VT_Short || select.type==ESM::VT_Int ||
|
||||||
|
select.type==ESM::VT_Long)
|
||||||
|
{
|
||||||
|
if (!checkGlobal (comp, toLower (name), select.i, *mEnvironment.mWorld))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (select.type==ESM::VT_Float)
|
||||||
|
{
|
||||||
|
if (!checkGlobal (comp, toLower (name), select.f, *mEnvironment.mWorld))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error (
|
||||||
|
"unsupported variable type in dialogue info select");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case '3': // local
|
||||||
|
|
||||||
|
if (select.type==ESM::VT_Short || select.type==ESM::VT_Int ||
|
||||||
|
select.type==ESM::VT_Long)
|
||||||
|
{
|
||||||
|
if (!checkLocal (comp, toLower (name), select.i, actor,
|
||||||
|
mEnvironment.mWorld->getStore()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (select.type==ESM::VT_Float)
|
||||||
|
{
|
||||||
|
if (!checkLocal (comp, toLower (name), select.f, actor,
|
||||||
|
mEnvironment.mWorld->getStore()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error (
|
||||||
|
"unsupported variable type in dialogue info select");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
|
||||||
|
{
|
||||||
|
// actor id
|
||||||
|
if (!info.actor.empty())
|
||||||
|
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!info.race.empty())
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
||||||
|
|
||||||
|
if (!cellRef)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (toLower (info.race)!=toLower (cellRef->base->race))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.clas.empty())
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
||||||
|
|
||||||
|
if (!cellRef)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (toLower (info.clas)!=toLower (cellRef->base->cls))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.npcFaction.empty())
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
||||||
|
|
||||||
|
if (!cellRef)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (toLower (info.npcFaction)!=toLower (cellRef->base->faction))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO check player faction
|
||||||
|
|
||||||
|
// check cell
|
||||||
|
if (!info.cell.empty())
|
||||||
|
if (mEnvironment.mWorld->getPlayerPos().getPlayer().getCell()->cell->name != info.cell)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO check DATAstruct
|
||||||
|
|
||||||
|
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
|
||||||
|
iter != info.selects.end(); ++iter)
|
||||||
|
if (!isMatching (actor, *iter))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::cout
|
||||||
|
<< "unchecked entries:" << std::endl
|
||||||
|
<< " player faction: " << info.pcFaction << std::endl
|
||||||
|
<< " DATAstruct" << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogueManager::DialogueManager (MWWorld::Environment& environment) : mEnvironment (environment) {}
|
||||||
|
|
||||||
|
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
|
||||||
|
{
|
||||||
|
std::cout << "talking with " << MWWorld::Class::get (actor).getName (actor) << std::endl;
|
||||||
|
|
||||||
|
const ESM::Dialogue *dialogue = mEnvironment.mWorld->getStore().dialogs.find ("hello");
|
||||||
|
|
||||||
|
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
|
||||||
|
iter!=dialogue->mInfo.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (isMatching (actor, *iter))
|
||||||
|
{
|
||||||
|
// start dialogue
|
||||||
|
std::cout << "found matching info record" << std::endl;
|
||||||
|
|
||||||
|
std::cout << "response: " << iter->response << std::endl;
|
||||||
|
|
||||||
|
if (!iter->sound.empty())
|
||||||
|
{
|
||||||
|
// TODO play sound
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iter->resultScript.empty())
|
||||||
|
{
|
||||||
|
std::cout << "script: " << iter->resultScript << std::endl;
|
||||||
|
// TODO execute script
|
||||||
|
}
|
||||||
|
|
||||||
|
mEnvironment.mWindowManager->setMode (MWGui::GM_Dialogue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
apps/openmw/mwdialogue/dialoguemanager.hpp
Normal file
32
apps/openmw/mwdialogue/dialoguemanager.hpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef GAME_MMDIALOG_DIALOGUEMANAGER_H
|
||||||
|
#define GAME_MWDIALOG_DIALOGUEMANAGER_H
|
||||||
|
|
||||||
|
#include <components/esm/loadinfo.hpp>
|
||||||
|
|
||||||
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class Environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWDialogue
|
||||||
|
{
|
||||||
|
class DialogueManager
|
||||||
|
{
|
||||||
|
MWWorld::Environment& mEnvironment;
|
||||||
|
|
||||||
|
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const;
|
||||||
|
|
||||||
|
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DialogueManager (MWWorld::Environment& environment);
|
||||||
|
|
||||||
|
void startDialogue (const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "environment.hpp"
|
#include "environment.hpp"
|
||||||
|
|
||||||
#include "../mwgui/window_manager.hpp"
|
#include "../mwdialogue/dialoguemanager.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,6 @@ namespace MWWorld
|
||||||
|
|
||||||
void ActionTalk::execute (Environment& environment)
|
void ActionTalk::execute (Environment& environment)
|
||||||
{
|
{
|
||||||
environment.mWindowManager->setMode (MWGui::GM_Dialogue);
|
environment.mDialogueManager->startDialogue (mActor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace MWWorld
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ActionTalk (const Ptr& actor);
|
ActionTalk (const Ptr& actor);
|
||||||
|
///< \param actor The actor the player is talking to
|
||||||
|
|
||||||
virtual void execute (Environment& environment);
|
virtual void execute (Environment& environment);
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,11 @@ namespace MWWorld
|
||||||
|
|
||||||
Class::~Class() {}
|
Class::~Class() {}
|
||||||
|
|
||||||
|
std::string Class::getId (const Ptr& ptr) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error ("class does not support ID retrieval");
|
||||||
|
}
|
||||||
|
|
||||||
void Class::insertObj (const Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
void Class::insertObj (const Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
||||||
MWWorld::Environment& environment) const
|
MWWorld::Environment& environment) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,6 +42,10 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual ~Class();
|
virtual ~Class();
|
||||||
|
|
||||||
|
virtual std::string getId (const Ptr& ptr) const;
|
||||||
|
///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
|
||||||
|
/// (default implementation: throw an exception)
|
||||||
|
|
||||||
virtual void insertObj (const Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
virtual void insertObj (const Ptr& ptr, MWRender::CellRenderImp& cellRender,
|
||||||
MWWorld::Environment& environment) const;
|
MWWorld::Environment& environment) const;
|
||||||
///< Add reference into a cell for rendering (default implementation: don't render anything).
|
///< Add reference into a cell for rendering (default implementation: don't render anything).
|
||||||
|
|
|
@ -21,17 +21,22 @@ namespace MWMechanics
|
||||||
class MechanicsManager;
|
class MechanicsManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace MWDialogue
|
||||||
|
{
|
||||||
|
class DialogueManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
class World;
|
class World;
|
||||||
|
|
||||||
///< Collection of script-accessable sub-systems
|
///< Collection of script-accessable sub-systems
|
||||||
class Environment
|
class Environment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Environment()
|
Environment()
|
||||||
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0),
|
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0),
|
||||||
mMechanicsManager (0), mFrameDuration (0)
|
mMechanicsManager (0), mDialogueManager (0), mFrameDuration (0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
World *mWorld;
|
World *mWorld;
|
||||||
|
@ -39,9 +44,9 @@ namespace MWWorld
|
||||||
MWScript::GlobalScripts *mGlobalScripts;
|
MWScript::GlobalScripts *mGlobalScripts;
|
||||||
MWGui::WindowManager *mWindowManager;
|
MWGui::WindowManager *mWindowManager;
|
||||||
MWMechanics::MechanicsManager *mMechanicsManager;
|
MWMechanics::MechanicsManager *mMechanicsManager;
|
||||||
|
MWDialogue::DialogueManager *mDialogueManager;
|
||||||
float mFrameDuration;
|
float mFrameDuration;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
|
||||||
SET(ICONV_FIND_QUIETLY TRUE)
|
SET(ICONV_FIND_QUIETLY TRUE)
|
||||||
ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
|
ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
SET(ICONV_INCLUDE_DIR $ENV{ICONV_INCLUDE_DIR})
|
||||||
|
SET(ICONV_LIBRARIES $ENV{ICONV_LIBRARIES})
|
||||||
|
ENDIF(WIN32)
|
||||||
|
|
||||||
FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
|
FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
|
||||||
|
|
||||||
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c)
|
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c)
|
||||||
|
|
|
@ -9,7 +9,10 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <iconv.h>
|
|
||||||
|
#ifndef __WIN32__
|
||||||
|
#include <iconv.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <libs/mangle/stream/stream.hpp>
|
#include <libs/mangle/stream/stream.hpp>
|
||||||
#include <libs/mangle/stream/servers/file_stream.hpp>
|
#include <libs/mangle/stream/servers/file_stream.hpp>
|
||||||
|
@ -618,89 +621,93 @@ public:
|
||||||
return convertToUTF8(res);
|
return convertToUTF8(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a string from the encoding used by Morrowind to UTF-8
|
// Convert a string from the encoding used by Morrowind to UTF-8
|
||||||
std::string convertToUTF8(std::string input)
|
std::string convertToUTF8 (std::string input)
|
||||||
{
|
|
||||||
std::string output = "";
|
|
||||||
|
|
||||||
//create convert description
|
|
||||||
iconv_t cd = iconv_open("UTF-8", "WINDOWS-1252");
|
|
||||||
|
|
||||||
if (cd == (iconv_t)-1) //error handling
|
|
||||||
{
|
{
|
||||||
std::string errMsg = "Creating description for UTF-8 converting failed: ";
|
#ifdef __WIN32__
|
||||||
|
return input;
|
||||||
|
#else
|
||||||
|
std::string output = "";
|
||||||
|
|
||||||
switch (errno) //detailed error messages (maybe it contains too much detail :)
|
//create convert description
|
||||||
{
|
iconv_t cd = iconv_open ("UTF-8", "WINDOWS-1252");
|
||||||
case EMFILE:
|
|
||||||
errMsg += "{OPEN_MAX} files descriptors are currently open in the calling process.";
|
|
||||||
case ENFILE:
|
|
||||||
errMsg += "Too many files are currently open in the system.";
|
|
||||||
case ENOMEM:
|
|
||||||
errMsg +="Insufficient storage space is available.";
|
|
||||||
case EINVAL:
|
|
||||||
errMsg += "The conversion specified by fromcode and tocode is not supported by the implementation.";
|
|
||||||
|
|
||||||
default:
|
if (cd == (iconv_t)-1) //error handling
|
||||||
errMsg += "Unknown Error\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
fail(errMsg);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const size_t inputSize = input.size();
|
|
||||||
|
|
||||||
if (inputSize) //input is not empty
|
|
||||||
{
|
|
||||||
//convert function doesn't accept const char *, therefore copy content into an char *
|
|
||||||
std::vector<char> inputBuffer(input.begin(), input.end());
|
|
||||||
char *inputBufferBegin = &inputBuffer[0];
|
|
||||||
|
|
||||||
size_t inputBytesLeft = inputSize; //bytes to convert
|
|
||||||
|
|
||||||
static const size_t outputSize = 1000;
|
|
||||||
size_t outputBytesLeft;
|
|
||||||
|
|
||||||
char outputBuffer[outputSize];
|
|
||||||
char *outputBufferBegin;
|
|
||||||
|
|
||||||
while (inputBytesLeft > 0 )
|
|
||||||
{
|
{
|
||||||
outputBytesLeft = outputSize;
|
std::string errMsg = "Creating description for UTF-8 converting failed: ";
|
||||||
outputBufferBegin = outputBuffer;
|
|
||||||
|
|
||||||
if (iconv(cd, &inputBufferBegin, &inputBytesLeft, &outputBufferBegin, &outputBytesLeft) == (size_t)-1)
|
switch (errno) //detailed error messages (maybe it contains too much detail :)
|
||||||
{
|
|
||||||
switch (errno)
|
|
||||||
{
|
{
|
||||||
case E2BIG: //outputBuffer is full
|
case EMFILE:
|
||||||
output += std::string(outputBuffer, outputSize);
|
errMsg += "{OPEN_MAX} files descriptors are currently open in the calling process.";
|
||||||
break;
|
case ENFILE:
|
||||||
case EILSEQ:
|
errMsg += "Too many files are currently open in the system.";
|
||||||
fail("Iconv: Invalid multibyte sequence.\n");
|
case ENOMEM:
|
||||||
break;
|
errMsg +="Insufficient storage space is available.";
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
fail("Iconv: Incomplete multibyte sequence.\n");
|
errMsg += "The conversion specified by fromcode and tocode is not supported by the implementation.";
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
fail("Iconv: Unknown Error\n");
|
errMsg += "Unknown Error\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
fail (errMsg);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t inputSize = input.size();
|
||||||
|
|
||||||
|
if (inputSize) //input is not empty
|
||||||
|
{
|
||||||
|
//convert function doesn't accept const char *, therefore copy content into an char *
|
||||||
|
std::vector<char> inputBuffer (input.begin(), input.end());
|
||||||
|
char *inputBufferBegin = &inputBuffer[0];
|
||||||
|
|
||||||
|
size_t inputBytesLeft = inputSize; //bytes to convert
|
||||||
|
|
||||||
|
static const size_t outputSize = 1000;
|
||||||
|
size_t outputBytesLeft;
|
||||||
|
|
||||||
|
char outputBuffer[outputSize];
|
||||||
|
char *outputBufferBegin;
|
||||||
|
|
||||||
|
while (inputBytesLeft > 0)
|
||||||
|
{
|
||||||
|
outputBytesLeft = outputSize;
|
||||||
|
outputBufferBegin = outputBuffer;
|
||||||
|
|
||||||
|
if (iconv (cd, &inputBufferBegin, &inputBytesLeft, &outputBufferBegin, &outputBytesLeft) == (size_t)-1)
|
||||||
|
{
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case E2BIG: //outputBuffer is full
|
||||||
|
output += std::string (outputBuffer, outputSize);
|
||||||
|
break;
|
||||||
|
case EILSEQ:
|
||||||
|
fail ("Iconv: Invalid multibyte sequence.\n");
|
||||||
|
break;
|
||||||
|
case EINVAL:
|
||||||
|
fail ("Iconv: Incomplete multibyte sequence.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fail ("Iconv: Unknown Error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//read only relevant bytes from outputBuffer
|
||||||
|
output += std::string (outputBuffer, outputSize - outputBytesLeft);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//read only relevant bytes from outputBuffer
|
iconv_close (cd);
|
||||||
output += std::string(outputBuffer, outputSize - outputBytesLeft);
|
|
||||||
|
|
||||||
}
|
return output;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
iconv_close (cd);
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
void skip(int bytes) { esm->seek(esm->tell()+bytes); }
|
void skip(int bytes) { esm->seek(esm->tell()+bytes); }
|
||||||
uint64_t getOffset() { return esm->tell(); }
|
uint64_t getOffset() { return esm->tell(); }
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#ifndef _ESM_DIAL_H
|
#ifndef _ESM_DIAL_H
|
||||||
#define _ESM_DIAL_H
|
#define _ESM_DIAL_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "esm_reader.hpp"
|
#include "esm_reader.hpp"
|
||||||
|
#include "loadinfo.hpp"
|
||||||
|
|
||||||
namespace ESM {
|
namespace ESM {
|
||||||
|
|
||||||
|
@ -23,6 +26,7 @@ struct Dialogue
|
||||||
};
|
};
|
||||||
|
|
||||||
char type;
|
char type;
|
||||||
|
std::vector<DialInfo> mInfo;
|
||||||
|
|
||||||
void load(ESMReader &esm)
|
void load(ESMReader &esm)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,13 +14,13 @@
|
||||||
#include "loadcont.hpp"
|
#include "loadcont.hpp"
|
||||||
#include "loadcrea.hpp"
|
#include "loadcrea.hpp"
|
||||||
#include "loadcrec.hpp"
|
#include "loadcrec.hpp"
|
||||||
|
#include "loadinfo.hpp"
|
||||||
#include "loaddial.hpp"
|
#include "loaddial.hpp"
|
||||||
#include "loaddoor.hpp"
|
#include "loaddoor.hpp"
|
||||||
#include "loadench.hpp"
|
#include "loadench.hpp"
|
||||||
#include "loadfact.hpp"
|
#include "loadfact.hpp"
|
||||||
#include "loadglob.hpp"
|
#include "loadglob.hpp"
|
||||||
#include "loadgmst.hpp"
|
#include "loadgmst.hpp"
|
||||||
#include "loadinfo.hpp"
|
|
||||||
#include "loadingr.hpp"
|
#include "loadingr.hpp"
|
||||||
#include "loadland.hpp"
|
#include "loadland.hpp"
|
||||||
#include "loadlevlist.hpp"
|
#include "loadlevlist.hpp"
|
||||||
|
|
|
@ -18,32 +18,70 @@ static string toStr(int i)
|
||||||
|
|
||||||
void ESMStore::load(ESMReader &esm)
|
void ESMStore::load(ESMReader &esm)
|
||||||
{
|
{
|
||||||
set<string> missing;
|
set<string> missing;
|
||||||
|
|
||||||
// Loop through all records
|
ESM::Dialogue *dialogue = 0;
|
||||||
while(esm.hasMoreRecs())
|
|
||||||
|
// Loop through all records
|
||||||
|
while(esm.hasMoreRecs())
|
||||||
{
|
{
|
||||||
NAME n = esm.getRecName();
|
NAME n = esm.getRecName();
|
||||||
esm.getRecHeader();
|
esm.getRecHeader();
|
||||||
|
|
||||||
// Look up the record type.
|
// Look up the record type.
|
||||||
RecListList::iterator it = recLists.find(n.val);
|
RecListList::iterator it = recLists.find(n.val);
|
||||||
|
|
||||||
if(it == recLists.end())
|
if(it == recLists.end())
|
||||||
{
|
{
|
||||||
// Not found (this would be an error later)
|
if (n.val==ESM::REC_INFO)
|
||||||
esm.skipRecord();
|
{
|
||||||
missing.insert(n.toString());
|
if (dialogue)
|
||||||
continue;
|
{
|
||||||
|
ESM::DialInfo info;
|
||||||
|
info.load (esm);
|
||||||
|
|
||||||
|
dialogue->mInfo.push_back (info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "error: info record without dialog" << std::endl;
|
||||||
|
esm.skipRecord();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not found (this would be an error later)
|
||||||
|
esm.skipRecord();
|
||||||
|
missing.insert(n.toString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Load it
|
||||||
|
std::string id = esm.getHNOString("NAME");
|
||||||
|
it->second->load(esm, id);
|
||||||
|
|
||||||
// Load it
|
if (n.val==ESM::REC_DIAL)
|
||||||
std::string id = esm.getHNOString("NAME");
|
{
|
||||||
it->second->load(esm, id);
|
RecListT<Dialogue>& recList = static_cast<RecListT<Dialogue>& > (*it->second);
|
||||||
|
|
||||||
// Insert the reference into the global lookup
|
id = recList.toLower (id);
|
||||||
if(!id.empty())
|
|
||||||
all[id] = n.val;
|
RecListT<Dialogue>::MapType::iterator iter = recList.list.find (id);
|
||||||
|
|
||||||
|
assert (iter!=recList.list.end());
|
||||||
|
|
||||||
|
dialogue = &iter->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dialogue = 0;
|
||||||
|
|
||||||
|
// Insert the reference into the global lookup
|
||||||
|
if(!id.empty())
|
||||||
|
all[id] = n.val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This information isn't needed on screen. But keep the code around
|
/* This information isn't needed on screen. But keep the code around
|
||||||
|
|
|
@ -69,7 +69,6 @@ namespace ESMS
|
||||||
// Lists that need special rules
|
// Lists that need special rules
|
||||||
CellList cells;
|
CellList cells;
|
||||||
RecIDListT<GameSetting> gameSettings;
|
RecIDListT<GameSetting> gameSettings;
|
||||||
//RecListT<DialInfo> dialInfos;
|
|
||||||
//RecListT<Land> lands;
|
//RecListT<Land> lands;
|
||||||
//RecListT<LandTexture> landTexts;
|
//RecListT<LandTexture> landTexts;
|
||||||
//RecListT<MagicEffect> magicEffects;
|
//RecListT<MagicEffect> magicEffects;
|
||||||
|
@ -92,7 +91,6 @@ namespace ESMS
|
||||||
|
|
||||||
ESMStore()
|
ESMStore()
|
||||||
{
|
{
|
||||||
recLists[REC_ACTI] = &activators;
|
|
||||||
recLists[REC_ACTI] = &activators;
|
recLists[REC_ACTI] = &activators;
|
||||||
recLists[REC_ALCH] = &potions;
|
recLists[REC_ALCH] = &potions;
|
||||||
recLists[REC_APPA] = &appas;
|
recLists[REC_APPA] = &appas;
|
||||||
|
@ -113,7 +111,6 @@ namespace ESMS
|
||||||
recLists[REC_FACT] = &factions;
|
recLists[REC_FACT] = &factions;
|
||||||
recLists[REC_GLOB] = &globals;
|
recLists[REC_GLOB] = &globals;
|
||||||
recLists[REC_GMST] = &gameSettings;
|
recLists[REC_GMST] = &gameSettings;
|
||||||
//recLists[REC_INFO] = &dialInfos;
|
|
||||||
recLists[REC_INGR] = &ingreds;
|
recLists[REC_INGR] = &ingreds;
|
||||||
//recLists[REC_LAND] = &lands;
|
//recLists[REC_LAND] = &lands;
|
||||||
recLists[REC_LEVC] = &creatureLists;
|
recLists[REC_LEVC] = &creatureLists;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,6 +27,27 @@
|
||||||
#include <OgreResource.h>
|
#include <OgreResource.h>
|
||||||
#include <OgreMesh.h>
|
#include <OgreMesh.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
class BoundsFinder;
|
||||||
|
|
||||||
|
namespace Nif
|
||||||
|
{
|
||||||
|
class Node;
|
||||||
|
class Transformation;
|
||||||
|
class NiTriShape;
|
||||||
|
class Vector;
|
||||||
|
class Matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Mangle
|
||||||
|
{
|
||||||
|
namespace VFS
|
||||||
|
{
|
||||||
|
class OgreVFS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Manual resource loader for NIF meshes. This is the main class
|
/** Manual resource loader for NIF meshes. This is the main class
|
||||||
responsible for translating the internal NIF mesh structure into
|
responsible for translating the internal NIF mesh structure into
|
||||||
|
@ -43,12 +64,66 @@
|
||||||
very resource intensive, and can safely be done for a large number
|
very resource intensive, and can safely be done for a large number
|
||||||
of meshes at load time.
|
of meshes at load time.
|
||||||
*/
|
*/
|
||||||
struct NIFLoader : Ogre::ManualResourceLoader
|
class NIFLoader : Ogre::ManualResourceLoader
|
||||||
{
|
{
|
||||||
void loadResource(Ogre::Resource *resource);
|
public:
|
||||||
|
static NIFLoader& getSingleton();
|
||||||
|
static NIFLoader* getSingletonPtr();
|
||||||
|
|
||||||
static Ogre::MeshPtr load(const std::string &name,
|
virtual void loadResource(Ogre::Resource *resource);
|
||||||
const std::string &group="General");
|
|
||||||
|
static Ogre::MeshPtr load(const std::string &name,
|
||||||
|
const std::string &group="General");
|
||||||
|
|
||||||
|
Ogre::Vector3 convertVector3(const Nif::Vector& vec);
|
||||||
|
Ogre::Quaternion convertRotation(const Nif::Matrix& rot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NIFLoader() : resourceGroup("General") {}
|
||||||
|
NIFLoader(NIFLoader& n) {}
|
||||||
|
|
||||||
|
void warn(std::string msg);
|
||||||
|
void fail(std::string msg);
|
||||||
|
|
||||||
|
void handleNode( Nif::Node *node, int flags,
|
||||||
|
const Nif::Transformation *trafo, BoundsFinder &bounds, Ogre::Bone *parentBone);
|
||||||
|
|
||||||
|
void handleNiTriShape(Nif::NiTriShape *shape, int flags, BoundsFinder &bounds);
|
||||||
|
|
||||||
|
void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material);
|
||||||
|
|
||||||
|
void createMaterial(const Ogre::String &name,
|
||||||
|
const Nif::Vector &ambient,
|
||||||
|
const Nif::Vector &diffuse,
|
||||||
|
const Nif::Vector &specular,
|
||||||
|
const Nif::Vector &emissive,
|
||||||
|
float glossiness, float alpha,
|
||||||
|
float alphaFlags, float alphaTest,
|
||||||
|
const Ogre::String &texName);
|
||||||
|
|
||||||
|
void findRealTexture(Ogre::String &texName);
|
||||||
|
|
||||||
|
Ogre::String getUniqueName(const Ogre::String &input);
|
||||||
|
|
||||||
|
//returns the skeleton name of this mesh
|
||||||
|
std::string getSkeletonName()
|
||||||
|
{
|
||||||
|
return resourceName + ".skel";
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the interface to the Ogre resource system. It allows us to
|
||||||
|
// load NIFs from BSAs, in the file system and in any other place we
|
||||||
|
// tell Ogre to look (eg. in zip or rar files.) It's also used to
|
||||||
|
// check for the existence of texture files, so we can exchange the
|
||||||
|
// extension from .tga to .dds if the texture is missing.
|
||||||
|
Mangle::VFS::OgreVFS *vfs;
|
||||||
|
|
||||||
|
std::string resourceName;
|
||||||
|
std::string resourceGroup;
|
||||||
|
|
||||||
|
// pointer to the ogre mesh which is currently build
|
||||||
|
Ogre::Mesh *mesh;
|
||||||
|
Ogre::SkeletonPtr skel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue