forked from teamnwah/openmw-tes3coop
Merge remote branch 'upstream/master'
This commit is contained in:
commit
927879d23e
22 changed files with 482 additions and 40 deletions
|
@ -41,6 +41,14 @@ set(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
|
||||
mwscript/scriptmanager.cpp
|
||||
mwscript/compilercontext.cpp
|
||||
|
@ -97,6 +105,7 @@ set(GAMEWORLD_HEADER
|
|||
mwworld/action.hpp
|
||||
mwworld/nullaction.hpp
|
||||
mwworld/actionteleport.hpp
|
||||
mwworld/containerstore.hpp
|
||||
mwworld/actiontalk.hpp
|
||||
mwworld/actiontake.hpp
|
||||
mwworld/containerstore.hpp
|
||||
|
@ -164,11 +173,11 @@ set(GAMEMECHANICS_HEADER
|
|||
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})
|
||||
|
||||
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}
|
||||
${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER} ${GAMECLASS_HEADER}
|
||||
${GAMEMECHANICS_HEADER}
|
||||
${GAMEMECHANICS_HEADER} ${GAMEDIALOG_HEADERUE}
|
||||
)
|
||||
|
||||
# Main executable
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "mwclass/classes.hpp"
|
||||
|
||||
#include "mwdialogue/dialoguemanager.hpp"
|
||||
|
||||
#include "mwmechanics/mechanicsmanager.hpp"
|
||||
|
||||
#include <OgreRoot.h>
|
||||
|
@ -104,6 +106,7 @@ OMW::Engine::Engine()
|
|||
: mDebug (false)
|
||||
, mVerboseScripts (false)
|
||||
, mNewGame (false)
|
||||
, mUseSound (true)
|
||||
, mScriptManager (0)
|
||||
, mScriptContext (0)
|
||||
{
|
||||
|
@ -117,6 +120,7 @@ OMW::Engine::~Engine()
|
|||
delete mEnvironment.mSoundManager;
|
||||
delete mEnvironment.mGlobalScripts;
|
||||
delete mEnvironment.mMechanicsManager;
|
||||
delete mEnvironment.mDialogueManager;
|
||||
delete mScriptManager;
|
||||
delete mScriptContext;
|
||||
}
|
||||
|
@ -236,7 +240,8 @@ void OMW::Engine::go()
|
|||
mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre.getRoot(),
|
||||
mOgre.getCamera(),
|
||||
mEnvironment.mWorld->getStore(),
|
||||
(mDataDir / "Sound").file_string());
|
||||
(mDataDir / "Sound").file_string(),
|
||||
mUseSound);
|
||||
|
||||
// Create script system
|
||||
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full,
|
||||
|
@ -253,6 +258,9 @@ void OMW::Engine::go()
|
|||
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (
|
||||
mEnvironment.mWorld->getStore(), *mEnvironment.mWindowManager);
|
||||
|
||||
// Create dialog system
|
||||
mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment);
|
||||
|
||||
// load cell
|
||||
ESM::Position pos;
|
||||
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace OMW
|
|||
bool mDebug;
|
||||
bool mVerboseScripts;
|
||||
bool mNewGame;
|
||||
bool mUseSound;
|
||||
|
||||
MWWorld::Environment mEnvironment;
|
||||
MWScript::ScriptManager *mScriptManager;
|
||||
|
@ -115,6 +116,9 @@ namespace OMW
|
|||
/// Enable verbose script output
|
||||
void enableVerboseScripts();
|
||||
|
||||
/// Disable all sound
|
||||
void disableSound() { mUseSound = false; }
|
||||
|
||||
/// Start as a new game.
|
||||
void setNewGame();
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
|
|||
("master", bpo::value<std::string>()->default_value ("Morrowind"),
|
||||
"master file")
|
||||
( "debug", "debug mode" )
|
||||
( "nosound", "disable all sound" )
|
||||
( "script-verbose", "verbose script output" )
|
||||
( "new-game", "activate char gen/new game mechanics" )
|
||||
;
|
||||
|
@ -64,6 +65,9 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
|
|||
|
||||
if (variables.count ("debug"))
|
||||
engine.enableDebugMode();
|
||||
|
||||
if (variables.count ("nosound"))
|
||||
engine.disableSound();
|
||||
|
||||
if (variables.count ("script-verbose"))
|
||||
engine.enableVerboseScripts();
|
||||
|
|
|
@ -15,6 +15,14 @@
|
|||
|
||||
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,
|
||||
MWWorld::Environment& environment) const
|
||||
{
|
||||
|
@ -96,7 +104,7 @@ namespace MWClass
|
|||
}
|
||||
|
||||
return *ptr.getRefData().getContainerStore();
|
||||
}
|
||||
}
|
||||
|
||||
std::string Creature::getScript (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
|
|
|
@ -9,6 +9,9 @@ namespace MWClass
|
|||
{
|
||||
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,
|
||||
MWWorld::Environment& environment) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
|
||||
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,
|
||||
MWWorld::Environment& environment) const
|
||||
{
|
||||
|
|
|
@ -9,6 +9,9 @@ namespace MWClass
|
|||
{
|
||||
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,
|
||||
MWWorld::Environment& environment) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
@ -26,14 +29,14 @@ namespace MWClass
|
|||
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
|
||||
///< 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 (
|
||||
const MWWorld::Ptr& ptr) const;
|
||||
///< 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;
|
||||
///< Return name of the script attached to ptr
|
||||
|
||||
|
|
281
apps/openmw/mwdialogue/dialoguemanager.cpp
Normal file
281
apps/openmw/mwdialogue/dialoguemanager.cpp
Normal file
|
@ -0,0 +1,281 @@
|
|||
|
||||
#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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
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
|
|
@ -20,16 +20,22 @@ using namespace std;
|
|||
#ifdef OPENMW_USE_AUDIERE
|
||||
#include <mangle/sound/filters/openal_audiere.hpp>
|
||||
#define SOUND_FACTORY OpenAL_Audiere_Factory
|
||||
#define SOUND_OUT "OpenAL"
|
||||
#define SOUND_IN "Audiere"
|
||||
#endif
|
||||
|
||||
#ifdef OPENMW_USE_FFMPEG
|
||||
#include <mangle/sound/filters/openal_ffmpeg.hpp>
|
||||
#define SOUND_FACTORY OpenAL_FFMpeg_Factory
|
||||
#define SOUND_OUT "OpenAL"
|
||||
#define SOUND_IN "FFmpeg"
|
||||
#endif
|
||||
|
||||
#ifdef OPENMW_USE_MPG123
|
||||
#include <mangle/sound/filters/openal_sndfile_mpg123.hpp>
|
||||
#define SOUND_FACTORY OpenAL_SndFile_Mpg123_Factory
|
||||
#define SOUND_OUT "OpenAL"
|
||||
#define SOUND_IN "mpg123,sndfile"
|
||||
#endif
|
||||
|
||||
using namespace Mangle::Sound;
|
||||
|
@ -77,6 +83,9 @@ namespace MWSound
|
|||
, cameraTracker(mgr)
|
||||
, store(str)
|
||||
{
|
||||
cout << "Sound output: " << SOUND_OUT << endl;
|
||||
cout << "Sound decoder: " << SOUND_IN << endl;
|
||||
|
||||
// Attach the camera to the camera tracker
|
||||
cameraTracker.followCamera(camera);
|
||||
|
||||
|
@ -150,29 +159,37 @@ namespace MWSound
|
|||
|
||||
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
|
||||
const ESMS::ESMStore &store,
|
||||
const std::string &soundDir)
|
||||
const std::string &soundDir,
|
||||
bool useSound)
|
||||
: mData(NULL)
|
||||
{
|
||||
mData = new SoundImpl(root, camera, store, soundDir);
|
||||
if(useSound)
|
||||
mData = new SoundImpl(root, camera, store, soundDir);
|
||||
}
|
||||
|
||||
SoundManager::~SoundManager()
|
||||
{
|
||||
delete mData;
|
||||
if(mData)
|
||||
delete mData;
|
||||
}
|
||||
|
||||
void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename)
|
||||
{
|
||||
// The range values are not tested
|
||||
if(!mData) return;
|
||||
mData->add(filename, ptr, "_say_sound", 1, 1, 100, 10000, false);
|
||||
}
|
||||
|
||||
bool SoundManager::sayDone (MWWorld::Ptr ptr) const
|
||||
{
|
||||
if(!mData) return false;
|
||||
return !mData->isPlaying(ptr, "_say_sound");
|
||||
}
|
||||
|
||||
void SoundManager::streamMusic (const std::string& filename)
|
||||
{
|
||||
if(!mData) return;
|
||||
|
||||
// Play the sound and tell it to stream, if possible. TODO:
|
||||
// Store the reference, the jukebox will need to check status,
|
||||
// control volume etc.
|
||||
|
@ -184,6 +201,8 @@ namespace MWSound
|
|||
|
||||
void SoundManager::playSound (const std::string& soundId, float volume, float pitch)
|
||||
{
|
||||
if(!mData) return;
|
||||
|
||||
// Play and forget
|
||||
float min, max;
|
||||
const std::string &file = mData->lookup(soundId, volume, min, max);
|
||||
|
@ -199,6 +218,8 @@ namespace MWSound
|
|||
void SoundManager::playSound3D (MWWorld::Ptr ptr, const std::string& soundId,
|
||||
float volume, float pitch, bool loop)
|
||||
{
|
||||
if(!mData) return;
|
||||
|
||||
// Look up the sound in the ESM data
|
||||
float min, max;
|
||||
const std::string &file = mData->lookup(soundId, volume, min, max);
|
||||
|
@ -208,21 +229,28 @@ namespace MWSound
|
|||
|
||||
void SoundManager::stopSound3D (MWWorld::Ptr ptr, const std::string& soundId)
|
||||
{
|
||||
if(!mData) return;
|
||||
mData->remove(ptr, soundId);
|
||||
}
|
||||
|
||||
void SoundManager::stopSound (MWWorld::Ptr::CellStore *cell)
|
||||
{
|
||||
if(!mData) return;
|
||||
mData->removeCell(cell);
|
||||
}
|
||||
|
||||
bool SoundManager::getSoundPlaying (MWWorld::Ptr ptr, const std::string& soundId) const
|
||||
{
|
||||
// Mark all sounds as playing, otherwise the scripts will just
|
||||
// keep trying to play them every frame.
|
||||
if(!mData) return true;
|
||||
|
||||
return mData->isPlaying(ptr, soundId);
|
||||
}
|
||||
|
||||
void SoundManager::updateObject(MWWorld::Ptr ptr)
|
||||
{
|
||||
if(!mData) return;
|
||||
mData->updatePositions(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace MWSound
|
|||
|
||||
public:
|
||||
SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store,
|
||||
const std::string &soundDir);
|
||||
const std::string &soundDir, bool useSound);
|
||||
~SoundManager();
|
||||
|
||||
void say (MWWorld::Ptr reference, const std::string& filename);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "environment.hpp"
|
||||
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwdialogue/dialoguemanager.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
@ -11,6 +11,6 @@ namespace MWWorld
|
|||
|
||||
void ActionTalk::execute (Environment& environment)
|
||||
{
|
||||
environment.mWindowManager->setMode (MWGui::GM_Dialogue);
|
||||
environment.mDialogueManager->startDialogue (mActor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace MWWorld
|
|||
public:
|
||||
|
||||
ActionTalk (const Ptr& actor);
|
||||
///< \param actor The actor the player is talking to
|
||||
|
||||
virtual void execute (Environment& environment);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,11 @@ namespace MWWorld
|
|||
|
||||
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,
|
||||
MWWorld::Environment& environment) const
|
||||
{
|
||||
|
|
|
@ -42,6 +42,10 @@ namespace MWWorld
|
|||
|
||||
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,
|
||||
MWWorld::Environment& environment) const;
|
||||
///< Add reference into a cell for rendering (default implementation: don't render anything).
|
||||
|
|
|
@ -21,17 +21,22 @@ namespace MWMechanics
|
|||
class MechanicsManager;
|
||||
}
|
||||
|
||||
namespace MWDialogue
|
||||
{
|
||||
class DialogueManager;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class World;
|
||||
|
||||
///< Collection of script-accessable sub-systems
|
||||
class Environment
|
||||
{
|
||||
{
|
||||
public:
|
||||
Environment()
|
||||
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0),
|
||||
mMechanicsManager (0), mFrameDuration (0)
|
||||
mMechanicsManager (0), mDialogueManager (0), mFrameDuration (0)
|
||||
{}
|
||||
|
||||
World *mWorld;
|
||||
|
@ -39,9 +44,9 @@ namespace MWWorld
|
|||
MWScript::GlobalScripts *mGlobalScripts;
|
||||
MWGui::WindowManager *mWindowManager;
|
||||
MWMechanics::MechanicsManager *mMechanicsManager;
|
||||
MWDialogue::DialogueManager *mDialogueManager;
|
||||
float mFrameDuration;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#ifndef _ESM_DIAL_H
|
||||
#define _ESM_DIAL_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "esm_reader.hpp"
|
||||
#include "loadinfo.hpp"
|
||||
|
||||
namespace ESM {
|
||||
|
||||
|
@ -23,6 +26,7 @@ struct Dialogue
|
|||
};
|
||||
|
||||
char type;
|
||||
std::vector<DialInfo> mInfo;
|
||||
|
||||
void load(ESMReader &esm)
|
||||
{
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
#include "loadcont.hpp"
|
||||
#include "loadcrea.hpp"
|
||||
#include "loadcrec.hpp"
|
||||
#include "loadinfo.hpp"
|
||||
#include "loaddial.hpp"
|
||||
#include "loaddoor.hpp"
|
||||
#include "loadench.hpp"
|
||||
#include "loadfact.hpp"
|
||||
#include "loadglob.hpp"
|
||||
#include "loadgmst.hpp"
|
||||
#include "loadinfo.hpp"
|
||||
#include "loadingr.hpp"
|
||||
#include "loadland.hpp"
|
||||
#include "loadlevlist.hpp"
|
||||
|
|
|
@ -18,32 +18,70 @@ static string toStr(int i)
|
|||
|
||||
void ESMStore::load(ESMReader &esm)
|
||||
{
|
||||
set<string> missing;
|
||||
set<string> missing;
|
||||
|
||||
// Loop through all records
|
||||
while(esm.hasMoreRecs())
|
||||
ESM::Dialogue *dialogue = 0;
|
||||
|
||||
// Loop through all records
|
||||
while(esm.hasMoreRecs())
|
||||
{
|
||||
NAME n = esm.getRecName();
|
||||
esm.getRecHeader();
|
||||
NAME n = esm.getRecName();
|
||||
esm.getRecHeader();
|
||||
|
||||
// Look up the record type.
|
||||
RecListList::iterator it = recLists.find(n.val);
|
||||
// Look up the record type.
|
||||
RecListList::iterator it = recLists.find(n.val);
|
||||
|
||||
if(it == recLists.end())
|
||||
if(it == recLists.end())
|
||||
{
|
||||
// Not found (this would be an error later)
|
||||
esm.skipRecord();
|
||||
missing.insert(n.toString());
|
||||
continue;
|
||||
if (n.val==ESM::REC_INFO)
|
||||
{
|
||||
if (dialogue)
|
||||
{
|
||||
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
|
||||
std::string id = esm.getHNOString("NAME");
|
||||
it->second->load(esm, id);
|
||||
if (n.val==ESM::REC_DIAL)
|
||||
{
|
||||
RecListT<Dialogue>& recList = static_cast<RecListT<Dialogue>& > (*it->second);
|
||||
|
||||
// Insert the reference into the global lookup
|
||||
if(!id.empty())
|
||||
all[id] = n.val;
|
||||
id = recList.toLower (id);
|
||||
|
||||
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
|
||||
|
|
|
@ -69,7 +69,6 @@ namespace ESMS
|
|||
// Lists that need special rules
|
||||
CellList cells;
|
||||
RecIDListT<GameSetting> gameSettings;
|
||||
//RecListT<DialInfo> dialInfos;
|
||||
//RecListT<Land> lands;
|
||||
//RecListT<LandTexture> landTexts;
|
||||
//RecListT<MagicEffect> magicEffects;
|
||||
|
@ -92,7 +91,6 @@ namespace ESMS
|
|||
|
||||
ESMStore()
|
||||
{
|
||||
recLists[REC_ACTI] = &activators;
|
||||
recLists[REC_ACTI] = &activators;
|
||||
recLists[REC_ALCH] = &potions;
|
||||
recLists[REC_APPA] = &appas;
|
||||
|
@ -113,7 +111,6 @@ namespace ESMS
|
|||
recLists[REC_FACT] = &factions;
|
||||
recLists[REC_GLOB] = &globals;
|
||||
recLists[REC_GMST] = &gameSettings;
|
||||
//recLists[REC_INFO] = &dialInfos;
|
||||
recLists[REC_INGR] = &ingreds;
|
||||
//recLists[REC_LAND] = &lands;
|
||||
recLists[REC_LEVC] = &creatureLists;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit cd4ed4e6bfb23d736c4b1f30d6096ec164ba937b
|
||||
Subproject commit 200fab03efaa2cbe1b8fce4a742b0195f8912295
|
Loading…
Reference in a new issue