1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 18:19:55 +00:00

Merge remote-tracking branch 'upstream/master' into osgshadow-test

This commit is contained in:
AnyOldName3 2017-10-03 03:00:15 +01:00
commit ba1e2cab2f
226 changed files with 6546 additions and 3022 deletions

View file

@ -40,6 +40,7 @@ Programmers
Chris Robinson (KittyCat)
Cory F. Cohen (cfcohen)
Cris Mihalache (Mirceam)
crussell187
darkf
devnexen
Dieho
@ -105,6 +106,7 @@ Programmers
Michael Papageorgiou (werdanith)
Michał Bień (Glorf)
Michał Moroz (dragonee)
Miloslav Číž (drummyfish)
Miroslav Puda (pakanek)
MiroslavR
Mitchell Schwitzer (schwitzerm)

View file

@ -16,6 +16,8 @@ set(ESSIMPORTER_FILES
importjour.cpp
importscri.cpp
importscpt.cpp
importproj.cpp
importsplm.cpp
importercontext.cpp
converter.cpp
convertacdt.cpp

View file

@ -1,6 +1,7 @@
#include "converter.hpp"
#include <stdexcept>
#include <algorithm>
#include <osgDB/WriteFile>
@ -53,6 +54,36 @@ namespace
return true;
return false;
}
void splitIndexedRefId(const std::string& indexedRefId, int& refIndex, std::string& refId)
{
std::stringstream stream;
stream << std::hex << indexedRefId.substr(indexedRefId.size()-8,8);
stream >> refIndex;
refId = indexedRefId.substr(0,indexedRefId.size()-8);
}
int convertActorId(const std::string& indexedRefId, ESSImport::Context& context)
{
if (isIndexedRefId(indexedRefId))
{
int refIndex;
std::string refId;
splitIndexedRefId(indexedRefId, refIndex, refId);
auto it = context.mActorIdMap.find(std::make_pair(refIndex, refId));
if (it == context.mActorIdMap.end())
return -1;
return it->second;
}
else if (indexedRefId == "PlayerSaveGame")
{
return context.mPlayer.mObject.mCreatureStats.mActorId;
}
return -1;
}
}
namespace ESSImport
@ -322,12 +353,9 @@ namespace ESSImport
}
else
{
std::stringstream stream;
stream << std::hex << cellref.mIndexedRefId.substr(cellref.mIndexedRefId.size()-8,8);
int refIndex;
stream >> refIndex;
splitIndexedRefId(cellref.mIndexedRefId, refIndex, out.mRefID);
out.mRefID = cellref.mIndexedRefId.substr(0,cellref.mIndexedRefId.size()-8);
std::string idLower = Misc::StringUtils::lowerCase(out.mRefID);
std::map<std::pair<int, std::string>, NPCC>::const_iterator npccIt = mContext->mNpcChanges.find(
@ -347,6 +375,10 @@ namespace ESSImport
convertNpcData(cellref, objstate.mNpcStats);
convertNPCC(npccIt->second, objstate);
convertCellRef(cellref, objstate);
objstate.mCreatureStats.mActorId = mContext->generateActorId();
mContext->mActorIdMap.insert(std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId));
esm.writeHNT ("OBJE", ESM::REC_NPC_);
objstate.save(esm);
continue;
@ -383,6 +415,10 @@ namespace ESSImport
convertACSC(cellref.mACSC, objstate.mCreatureStats);
convertCREC(crecIt->second, objstate);
convertCellRef(cellref, objstate);
objstate.mCreatureStats.mActorId = mContext->generateActorId();
mContext->mActorIdMap.insert(std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId));
esm.writeHNT ("OBJE", ESM::REC_CREA);
objstate.save(esm);
continue;
@ -413,4 +449,73 @@ namespace ESSImport
}
}
void ConvertPROJ::read(ESM::ESMReader& esm)
{
mProj.load(esm);
}
void ConvertPROJ::write(ESM::ESMWriter& esm)
{
for (const PROJ::PNAM& pnam : mProj.mProjectiles)
{
if (!pnam.isMagic())
{
ESM::ProjectileState out;
convertBaseState(out, pnam);
out.mBowId = pnam.mBowId.toString();
out.mVelocity = pnam.mVelocity;
out.mAttackStrength = pnam.mAttackStrength;
esm.startRecord(ESM::REC_PROJ);
out.save(esm);
esm.endRecord(ESM::REC_PROJ);
}
else
{
ESM::MagicBoltState out;
convertBaseState(out, pnam);
auto it = std::find_if(mContext->mActiveSpells.begin(), mContext->mActiveSpells.end(),
[&pnam](const SPLM::ActiveSpell& spell) -> bool { return spell.mIndex == pnam.mSplmIndex; });
if (it == mContext->mActiveSpells.end())
{
std::cerr << "Warning: Skipped conversion for magic projectile \"" << pnam.mArrowId.toString() << "\" (invalid spell link)" << std::endl;
continue;
}
out.mSpellId = it->mSPDT.mId.toString();
out.mSpeed = pnam.mSpeed * 0.001f; // not sure where this factor comes from
esm.startRecord(ESM::REC_MPRJ);
out.save(esm);
esm.endRecord(ESM::REC_MPRJ);
}
}
}
void ConvertPROJ::convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam)
{
base.mId = pnam.mArrowId.toString();
base.mPosition = pnam.mPosition;
osg::Quat orient;
orient.makeRotate(osg::Vec3f(0,1,0), pnam.mVelocity);
base.mOrientation = orient;
base.mActorId = convertActorId(pnam.mActorId.toString(), *mContext);
}
void ConvertSPLM::read(ESM::ESMReader& esm)
{
mSPLM.load(esm);
mContext->mActiveSpells = mSPLM.mActiveSpells;
}
void ConvertSPLM::write(ESM::ESMWriter& esm)
{
std::cerr << "Warning: Skipped active spell conversion (not implemented)" << std::endl;
}
}

View file

@ -22,6 +22,7 @@
#include <components/esm/globalscript.hpp>
#include <components/esm/queststate.hpp>
#include <components/esm/stolenitems.hpp>
#include <components/esm/projectilestate.hpp>
#include "importcrec.hpp"
#include "importcntc.hpp"
@ -35,6 +36,8 @@
#include "importques.hpp"
#include "importjour.hpp"
#include "importscpt.hpp"
#include "importproj.h"
#include "importsplm.h"
#include "convertacdt.hpp"
#include "convertnpcc.hpp"
@ -593,6 +596,27 @@ private:
std::vector<ESM::GlobalScript> mScripts;
};
/// Projectile converter
class ConvertPROJ : public Converter
{
public:
virtual int getStage() override { return 2; }
virtual void read(ESM::ESMReader& esm) override;
virtual void write(ESM::ESMWriter& esm) override;
private:
void convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam);
PROJ mProj;
};
class ConvertSPLM : public Converter
{
public:
virtual void read(ESM::ESMReader& esm) override;
virtual void write(ESM::ESMWriter& esm) override;
private:
SPLM mSPLM;
};
}
#endif

View file

@ -271,6 +271,7 @@ namespace ESSImport
const unsigned int recSTLN = ESM::FourCC<'S','T','L','N'>::value;
const unsigned int recGAME = ESM::FourCC<'G','A','M','E'>::value;
const unsigned int recJOUR = ESM::FourCC<'J','O','U','R'>::value;
const unsigned int recSPLM = ESM::FourCC<'S','P','L','M'>::value;
std::map<unsigned int, std::shared_ptr<Converter> > converters;
converters[ESM::REC_GLOB] = std::shared_ptr<Converter>(new ConvertGlobal());
@ -303,12 +304,13 @@ namespace ESSImport
converters[ESM::REC_QUES] = std::shared_ptr<Converter>(new ConvertQUES());
converters[recJOUR ] = std::shared_ptr<Converter>(new ConvertJOUR());
converters[ESM::REC_SCPT] = std::shared_ptr<Converter>(new ConvertSCPT());
converters[ESM::REC_PROJ] = std::shared_ptr<Converter>(new ConvertPROJ());
converters[recSPLM] = std::shared_ptr<Converter>(new ConvertSPLM());
// TODO:
// - REGN (weather in certain regions?)
// - VFXM
// - SPLM (active spell effects)
// - PROJ (magic projectiles in air)
std::set<unsigned int> unknownRecords;
@ -420,6 +422,19 @@ namespace ESSImport
context.mPlayer.save(writer);
writer.endRecord(ESM::REC_PLAY);
writer.startRecord(ESM::REC_ACTC);
writer.writeHNT("COUN", context.mNextActorId);
writer.endRecord(ESM::REC_ACTC);
// Stage 2 requires cell references to be written / actors IDs assigned
for (std::map<unsigned int, std::shared_ptr<Converter> >::const_iterator it = converters.begin();
it != converters.end(); ++it)
{
if (it->second->getStage() != 2)
continue;
it->second->write(writer);
}
writer.startRecord (ESM::REC_DIAS);
context.mDialogueState.save(writer);
writer.endRecord(ESM::REC_DIAS);

View file

@ -15,7 +15,7 @@
#include "importcrec.hpp"
#include "importcntc.hpp"
#include "importplayer.hpp"
#include "importsplm.h"
@ -48,14 +48,20 @@ namespace ESSImport
std::map<std::pair<int, std::string>, NPCC> mNpcChanges;
std::map<std::pair<int, std::string>, CNTC> mContainerChanges;
std::map<std::pair<int, std::string>, int> mActorIdMap;
int mNextActorId;
std::map<std::string, ESM::Creature> mCreatures;
std::map<std::string, ESM::NPC> mNpcs;
std::vector<SPLM::ActiveSpell> mActiveSpells;
Context()
: mDay(0)
, mMonth(0)
, mYear(0)
, mHour(0.f)
, mNextActorId(0)
{
mPlayer.mAutoMove = 0;
ESM::CellId playerCellId;
@ -67,16 +73,23 @@ namespace ESSImport
= mPlayer.mLastKnownExteriorPosition[2]
= 0.0f;
mPlayer.mHasMark = 0;
mPlayer.mCurrentCrimeId = 0; // TODO
mPlayer.mCurrentCrimeId = -1; // TODO
mPlayer.mPaidCrimeId = -1;
mPlayer.mObject.blank();
mPlayer.mObject.mEnabled = true;
mPlayer.mObject.mRef.mRefID = "player"; // REFR.mRefID would be PlayerSaveGame
mPlayer.mObject.mCreatureStats.mActorId = generateActorId();
mGlobalMapState.mBounds.mMinX = 0;
mGlobalMapState.mBounds.mMaxX = 0;
mGlobalMapState.mBounds.mMinY = 0;
mGlobalMapState.mBounds.mMaxY = 0;
}
int generateActorId()
{
return mNextActorId++;
}
};
}

View file

@ -0,0 +1,18 @@
#include "importproj.h"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void ESSImport::PROJ::load(ESM::ESMReader& esm)
{
while (esm.isNextSub("PNAM"))
{
PNAM pnam;
esm.getHT(pnam);
mProjectiles.push_back(pnam);
}
}
}

View file

@ -0,0 +1,47 @@
#ifndef OPENMW_ESSIMPORT_IMPORTPROJ_H
#define OPENMW_ESSIMPORT_IMPORTPROJ_H
#include <vector>
#include <components/esm/esmcommon.hpp>
#include <components/esm/util.hpp>
namespace ESM
{
class ESMReader;
}
namespace ESSImport
{
struct PROJ
{
#pragma pack(push)
#pragma pack(1)
struct PNAM // 184 bytes
{
float mAttackStrength;
float mSpeed;
unsigned char mUnknown[4*2];
float mFlightTime;
int mSplmIndex; // reference to a SPLM record (0 for ballistic projectiles)
unsigned char mUnknown2[4];
ESM::Vector3 mVelocity;
ESM::Vector3 mPosition;
unsigned char mUnknown3[4*9];
ESM::NAME32 mActorId; // indexed refID (with the exception of "PlayerSaveGame")
ESM::NAME32 mArrowId;
ESM::NAME32 mBowId;
bool isMagic() const { return mSplmIndex != 0; }
};
#pragma pack(pop)
std::vector<PNAM> mProjectiles;
void load(ESM::ESMReader& esm);
};
}
#endif

View file

@ -0,0 +1,43 @@
#include "importsplm.h"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void SPLM::load(ESM::ESMReader& esm)
{
while (esm.isNextSub("NAME"))
{
ActiveSpell spell;
esm.getHT(spell.mIndex);
esm.getHNT(spell.mSPDT, "SPDT");
spell.mTarget = esm.getHNOString("TNAM");
while (esm.isNextSub("NPDT"))
{
ActiveEffect effect;
esm.getHT(effect.mNPDT);
// Effect-specific subrecords can follow:
// - INAM for disintegration and bound effects
// - CNAM for summoning and command effects
// - VNAM for vampirism
// NOTE: There can be multiple INAMs per effect.
// TODO: Needs more research.
esm.skipHSubUntil("NAM0"); // sentinel
esm.getSubName();
esm.skipHSub();
spell.mActiveEffects.push_back(effect);
}
unsigned char xnam; // sentinel
esm.getHNT(xnam, "XNAM");
mActiveSpells.push_back(spell);
}
}
}

View file

@ -0,0 +1,81 @@
#ifndef OPENMW_ESSIMPORT_IMPORTSPLM_H
#define OPENMW_ESSIMPORT_IMPORTSPLM_H
#include <vector>
#include <components/esm/esmcommon.hpp>
#include <components/esm/util.hpp>
namespace ESM
{
class ESMReader;
}
namespace ESSImport
{
struct SPLM
{
#pragma pack(push)
#pragma pack(1)
struct SPDT // 160 bytes
{
int mType; // 1 = spell, 2 = enchantment, 3 = potion
ESM::NAME32 mId; // base ID of a spell/enchantment/potion
unsigned char mUnknown[4*4];
ESM::NAME32 mCasterId;
ESM::NAME32 mSourceId; // empty for spells
unsigned char mUnknown2[4*11];
};
struct NPDT // 56 bytes
{
ESM::NAME32 mAffectedActorId;
unsigned char mUnknown[4*2];
int mMagnitude;
float mSecondsActive;
unsigned char mUnknown2[4*2];
};
struct INAM // 40 bytes
{
int mUnknown;
unsigned char mUnknown2;
ESM::FIXED_STRING<35> mItemId; // disintegrated item / bound item / item to re-equip after expiration
};
struct CNAM // 36 bytes
{
int mUnknown; // seems to always be 0
ESM::NAME32 mSummonedOrCommandedActor[32];
};
struct VNAM // 4 bytes
{
int mUnknown;
};
#pragma pack(pop)
struct ActiveEffect
{
NPDT mNPDT;
};
struct ActiveSpell
{
int mIndex;
SPDT mSPDT;
std::string mTarget;
std::vector<ActiveEffect> mActiveEffects;
};
std::vector<ActiveSpell> mActiveSpells;
void load(ESM::ESMReader& esm);
};
}
#endif

View file

@ -24,7 +24,7 @@ void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main)
main->addWidget (list);
QFontMetrics metrics (QApplication::font());
QFontMetrics metrics (QApplication::font(list));
int maxWidth = 1;

View file

@ -42,7 +42,7 @@ add_openmw_dir (mwgui
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
draganddrop timeadvancer jailscreen itemchargeview
draganddrop timeadvancer jailscreen itemchargeview keyboardnavigation
)
add_openmw_dir (mwdialogue
@ -57,7 +57,8 @@ add_openmw_dir (mwscript
)
add_openmw_dir (mwsound
soundmanagerimp openal_output ffmpeg_decoder sound sound_buffer sound_decoder sound_output loudness movieaudiofactory
soundmanagerimp openal_output ffmpeg_decoder sound sound_buffer sound_decoder sound_output
loudness movieaudiofactory alext efx efx-presets
)
add_openmw_dir (mwworld

View file

@ -161,11 +161,6 @@ void OMW::Engine::frame(float frametime)
// update GUI
mEnvironment.getWindowManager()->onFrame(frametime);
if (mEnvironment.getStateManager()->getState()!=
MWBase::StateManager::State_NoGame)
{
mEnvironment.getWindowManager()->update();
}
unsigned int frameNumber = mViewer->getFrameStamp()->getFrameNumber();
osg::Stats* stats = mViewer->getViewerStats();

View file

@ -2,6 +2,8 @@
#define GAME_MWBASE_DIALOGUEMANAGER_H
#include <string>
#include <vector>
#include <list>
#include <stdint.h>
@ -42,24 +44,29 @@ namespace MWBase
virtual bool isInChoice() const = 0;
virtual void startDialogue (const MWWorld::Ptr& actor) = 0;
typedef std::pair<std::string, std::string> Response; // title, text
virtual bool startDialogue (const MWWorld::Ptr& actor, Response& response) = 0;
virtual void addTopic (const std::string& topic) = 0;
virtual void askQuestion (const std::string& question,int choice) = 0;
virtual void addChoice (const std::string& text,int choice) = 0;
virtual const std::vector<std::pair<std::string, int> >& getChoices() = 0;
virtual bool isGoodbye() = 0;
virtual void goodbye() = 0;
virtual void say(const MWWorld::Ptr &actor, const std::string &topic) = 0;
//calbacks for the GUI
virtual void keywordSelected (const std::string& keyword) = 0;
virtual Response keywordSelected (const std::string& keyword) = 0;
virtual void goodbyeSelected() = 0;
virtual void questionAnswered (int answer) = 0;
virtual Response questionAnswered (int answer) = 0;
virtual bool checkServiceRefused () = 0;
virtual std::list<std::string> getAvailableTopics() = 0;
virtual void persuade (int type) = 0;
virtual bool checkServiceRefused (Response& response) = 0;
virtual Response persuade (int type) = 0;
virtual int getTemporaryDispositionChange () const = 0;
/// @note This change is temporary and gets discarded when dialogue ends.

View file

@ -225,6 +225,10 @@ namespace MWBase
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0;
virtual bool isAttackingOrSpell(const MWWorld::Ptr &ptr) const = 0;
/// Check if the target actor was detected by an observer
/// If the observer is a non-NPC, check all actors in AI processing distance as observers
virtual bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) = 0;
virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) = 0;
/// List the owners that the player has stolen this item from (the owner can be an NPC or a faction).
@ -234,7 +238,7 @@ namespace MWBase
/// Has the player stolen this item from the given owner?
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::ConstPtr& item, MWWorld::Ptr& victim) = 0;
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) = 0;
/// Turn actor into werewolf or normal form.
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;

View file

@ -18,54 +18,59 @@ namespace MWSound
class Stream;
struct Sound_Decoder;
typedef std::shared_ptr<Sound_Decoder> DecoderPtr;
/* These must all fit together */
enum class PlayMode {
Normal = 0, /* non-looping, affected by environment */
Loop = 1<<0, /* Sound will continually loop until explicitly stopped */
NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */
RemoveAtDistance = 1<<2, /* (3D only) If the listener gets further than 2000 units away
* from the sound source, the sound is removed.
* This is weird stuff but apparently how vanilla works for sounds
* played by the PlayLoopSound family of script functions. Perhaps
* we can make this cut off a more subtle fade later, but have to
* be careful to not change the overall volume of areas by too
* much. */
NoPlayerLocal = 1<<3, /* (3D only) Don't play the sound local to the listener even if the
* player is making it. */
LoopNoEnv = Loop | NoEnv,
LoopRemoveAtDistance = Loop | RemoveAtDistance
};
enum class Type {
Sfx = 1<<4, /* Normal SFX sound */
Voice = 1<<5, /* Voice sound */
Foot = 1<<6, /* Footstep sound */
Music = 1<<7, /* Music track */
Movie = 1<<8, /* Movie audio track */
Mask = Sfx | Voice | Foot | Music | Movie
};
// Used for creating a type mask for SoundManager::pauseSounds and resumeSounds
inline int operator~(Type a) { return ~static_cast<int>(a); }
inline int operator&(Type a, Type b) { return static_cast<int>(a) & static_cast<int>(b); }
inline int operator&(int a, Type b) { return a & static_cast<int>(b); }
inline int operator|(Type a, Type b) { return static_cast<int>(a) | static_cast<int>(b); }
}
namespace MWBase
{
typedef std::shared_ptr<MWSound::Sound> SoundPtr;
typedef std::shared_ptr<MWSound::Stream> SoundStreamPtr;
using Sound = MWSound::Sound;
using SoundStream = MWSound::Stream;
/// \brief Interface for sound manager (implemented in MWSound)
class SoundManager
{
public:
/* These must all fit together */
enum PlayMode {
Play_Normal = 0, /* non-looping, affected by environment */
Play_Loop = 1<<0, /* Sound will continually loop until explicitly stopped */
Play_NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */
Play_RemoveAtDistance = 1<<2, /* (3D only) If the listener gets further than 2000 units away
from the sound source, the sound is removed.
This is weird stuff but apparently how vanilla works for sounds
played by the PlayLoopSound family of script functions. Perhaps we
can make this cut off a more subtle fade later, but have to
be careful to not change the overall volume of areas by too much. */
Play_NoPlayerLocal = 1<<3, /* (3D only) Don't play the sound local to the listener even if the
player is making it. */
Play_LoopNoEnv = Play_Loop | Play_NoEnv,
Play_LoopRemoveAtDistance = Play_Loop | Play_RemoveAtDistance
};
enum PlayType {
Play_TypeSfx = 1<<4, /* Normal SFX sound */
Play_TypeVoice = 1<<5, /* Voice sound */
Play_TypeFoot = 1<<6, /* Footstep sound */
Play_TypeMusic = 1<<7, /* Music track */
Play_TypeMovie = 1<<8, /* Movie audio track */
Play_TypeMask = Play_TypeSfx|Play_TypeVoice|Play_TypeFoot|Play_TypeMusic|Play_TypeMovie
};
private:
SoundManager (const SoundManager&);
///< not implemented
SoundManager& operator= (const SoundManager&);
///< not implemented
protected:
using PlayMode = MWSound::PlayMode;
using Type = MWSound::Type;
public:
SoundManager() {}
virtual ~SoundManager() {}
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& settings) = 0;
@ -77,9 +82,6 @@ namespace MWBase
///< Play a soundifle
/// \param filename name of a sound file in "Music/" in the data directory.
virtual void startRandomTitle() = 0;
///< Starts a random track from the current playlist
virtual bool isMusicPlaying() = 0;
///< Returns true if music is playing
@ -106,34 +108,36 @@ namespace MWBase
/// and get an average loudness value (scale [0,1]) at the current time position.
/// If the actor is not saying anything, returns 0.
virtual SoundStreamPtr playTrack(const MWSound::DecoderPtr& decoder, PlayType type) = 0;
///< Play a 2D audio track, using a custom decoder
virtual SoundStream *playTrack(const MWSound::DecoderPtr& decoder, Type type) = 0;
///< Play a 2D audio track, using a custom decoder. The caller is expected to call
/// stopTrack with the returned handle when done.
virtual void stopTrack(SoundStreamPtr stream) = 0;
virtual void stopTrack(SoundStream *stream) = 0;
///< Stop the given audio track from playing
virtual double getTrackTimeDelay(SoundStreamPtr stream) = 0;
virtual double getTrackTimeDelay(SoundStream *stream) = 0;
///< Retives the time delay, in seconds, of the audio track (must be a sound
/// returned by \ref playTrack). Only intended to be called by the track
/// decoder's read method.
virtual SoundPtr playSound(const std::string& soundId, float volume, float pitch,
PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal,
float offset=0) = 0;
virtual Sound *playSound(const std::string& soundId, float volume, float pitch,
Type type=Type::Sfx, PlayMode mode=PlayMode::Normal,
float offset=0) = 0;
///< Play a sound, independently of 3D-position
///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal, float offset=0) = 0;
virtual Sound *playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, Type type=Type::Sfx,
PlayMode mode=PlayMode::Normal, float offset=0) = 0;
///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified.
///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal, float offset=0) = 0;
virtual Sound *playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, Type type=Type::Sfx,
PlayMode mode=PlayMode::Normal, float offset=0) = 0;
///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition.
virtual void stopSound(SoundPtr sound) = 0;
virtual void stopSound(Sound *sound) = 0;
///< Stop the given sound from playing
virtual void stopSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId) = 0;
@ -158,10 +162,10 @@ namespace MWBase
///< Is the given sound currently playing on the given object?
/// If you want to check if sound played with playSound is playing, use empty Ptr
virtual void pauseSounds(int types=Play_TypeMask) = 0;
virtual void pauseSounds(int types=static_cast<int>(Type::Mask)) = 0;
///< Pauses all currently playing sounds, including music.
virtual void resumeSounds(int types=Play_TypeMask) = 0;
virtual void resumeSounds(int types=static_cast<int>(Type::Mask)) = 0;
///< Resumes all previously paused sounds.
virtual void update(float duration) = 0;

View file

@ -7,6 +7,8 @@
#include <map>
#include <set>
#include <MyGUI_KeyCode.h>
#include "../mwgui/mode.hpp"
namespace Loading
@ -100,23 +102,17 @@ namespace MWBase
virtual ~WindowManager() {}
/**
* Should be called each frame to update windows/gui elements.
* This could mean updating sizes of gui elements or opening
* new dialogs.
*/
virtual void update() = 0;
/// @note This method will block until the video finishes playing
/// (and will continually update the window while doing so)
virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
virtual void setNewGame(bool newgame) = 0;
virtual void pushGuiMode (MWGui::GuiMode mode, const MWWorld::Ptr& arg) = 0;
virtual void pushGuiMode (MWGui::GuiMode mode) = 0;
virtual void popGuiMode() = 0;
virtual void popGuiMode(bool noSound=false) = 0;
virtual void removeGuiMode (MWGui::GuiMode mode) = 0;
virtual void removeGuiMode (MWGui::GuiMode mode, bool noSound=false) = 0;
///< can be anywhere in the stack
virtual void goToJail(int days) = 0;
@ -144,7 +140,6 @@ namespace MWBase
virtual bool isAllowed (MWGui::GuiWindow wnd) const = 0;
/// \todo investigate, if we really need to expose every single lousy UI element to the outside world
virtual MWGui::DialogueWindow* getDialogueWindow() = 0;
virtual MWGui::InventoryWindow* getInventoryWindow() = 0;
virtual MWGui::CountDialog* getCountDialog() = 0;
virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
@ -185,6 +180,7 @@ namespace MWBase
virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0;
virtual void setCursorVisible(bool visible) = 0;
virtual void setCursorActive(bool active) = 0;
virtual void getMousePosition(int &x, int &y) = 0;
virtual void getMousePosition(float &x, float &y) = 0;
virtual void setDragDrop(bool dragDrop) = 0;
@ -228,7 +224,7 @@ namespace MWBase
virtual void showCrosshair(bool show) = 0;
virtual bool getSubtitlesEnabled() = 0;
virtual bool toggleGui() = 0;
virtual bool toggleHud() = 0;
virtual void disallowMouse() = 0;
virtual void allowMouse() = 0;
@ -282,21 +278,6 @@ namespace MWBase
virtual bool getPlayerSleeping() = 0;
virtual void wakeUpPlayer() = 0;
virtual void showCompanionWindow(MWWorld::Ptr actor) = 0;
virtual void startSpellMaking(MWWorld::Ptr actor) = 0;
virtual void startEnchanting(MWWorld::Ptr actor) = 0;
virtual void startRecharge(MWWorld::Ptr soulgem) = 0;
virtual void startSelfEnchanting(MWWorld::Ptr soulgem) = 0;
virtual void startTraining(MWWorld::Ptr actor) = 0;
virtual void startRepair(MWWorld::Ptr actor) = 0;
virtual void startRepairItem(MWWorld::Ptr item) = 0;
virtual void startTravel(const MWWorld::Ptr& actor) = 0;
virtual void startSpellBuying(const MWWorld::Ptr& actor) = 0;
virtual void startTrade(const MWWorld::Ptr& actor) = 0;
virtual void openContainer(const MWWorld::Ptr& container, bool loot) = 0;
virtual void showBook(const MWWorld::Ptr& item, bool showTakeButton) = 0;
virtual void showScroll(const MWWorld::Ptr& item, bool showTakeButton) = 0;
virtual void showSoulgemDialog (MWWorld::Ptr item) = 0;
virtual void changePointer (const std::string& name) = 0;
@ -338,11 +319,11 @@ namespace MWBase
virtual void pinWindow (MWGui::GuiWindow window) = 0;
/// Fade the screen in, over \a time seconds
virtual void fadeScreenIn(const float time, bool clearQueue=true) = 0;
virtual void fadeScreenIn(const float time, bool clearQueue=true, float delay=0.f) = 0;
/// Fade the screen out to black, over \a time seconds
virtual void fadeScreenOut(const float time, bool clearQueue=true) = 0;
virtual void fadeScreenOut(const float time, bool clearQueue=true, float delay=0.f) = 0;
/// Fade the screen to a specified percentage of black, over \a time seconds
virtual void fadeScreenTo(const int percent, const float time, bool clearQueue=true) = 0;
virtual void fadeScreenTo(const int percent, const float time, bool clearQueue=true, float delay=0.f) = 0;
/// Darken the screen to a specified percentage
virtual void setBlindness(const int percent) = 0;
@ -368,6 +349,8 @@ namespace MWBase
virtual void writeFog(MWWorld::CellStore* cell) = 0;
virtual const MWGui::TextColours& getTextColours() = 0;
virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text) = 0;
};
}

View file

@ -487,8 +487,7 @@ namespace MWBase
virtual void castSpell (const MWWorld::Ptr& actor) = 0;
virtual void launchMagicBolt (const std::string& spellId, bool stack, const ESM::EffectList& effects,
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection) = 0;
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) = 0;

View file

@ -169,9 +169,7 @@ namespace MWClass
if(isTrapped)
{
ptr.getCellRef().setTrap("");
MWBase::Environment::get().getSoundManager()->playSound3D(ptr,
"Disarm Trap", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Normal);
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Disarm Trap", 1.0f, 1.0f);
isTrapped = false;
}
}

View file

@ -457,11 +457,11 @@ namespace MWClass
// by default user can loot friendly actors during death animation
if (canLoot && !stats.getAiSequence().isInCombat())
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr));
// otherwise wait until death animation
if(stats.isDeathAnimationFinished())
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr));
// death animation is not finished, do nothing
return std::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction(""));
@ -470,6 +470,9 @@ namespace MWClass
if(stats.getAiSequence().isInCombat())
return std::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction(""));
if(stats.getKnockedDown())
return std::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction(""));
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
}

View file

@ -163,9 +163,7 @@ namespace MWClass
if(isTrapped)
{
ptr.getCellRef().setTrap("");
MWBase::Environment::get().getSoundManager()->playSound3D(ptr,
"Disarm Trap", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Normal);
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Disarm Trap", 1.0f, 1.0f);
isTrapped = false;
}
}

View file

@ -49,8 +49,8 @@ namespace MWClass
if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault))
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop);
MWSound::Type::Sfx,
MWSound::PlayMode::Loop);
}
bool Light::useAnim() const

View file

@ -872,11 +872,11 @@ namespace MWClass
// by default user can loot friendly actors during death animation
if (canLoot && !stats.getAiSequence().isInCombat())
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr));
// otherwise wait until death animation
if(stats.isDeathAnimationFinished())
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr));
// death animation is not finished, do nothing
return std::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction(""));

View file

@ -5,6 +5,7 @@
#include <algorithm>
#include <iterator>
#include <list>
#include <iostream>
#include <components/esm/loaddial.hpp>
#include <components/esm/loadinfo.hpp>
@ -33,8 +34,6 @@
#include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwgui/dialogue.hpp"
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include "../mwscript/extensions.hpp"
@ -59,16 +58,8 @@ namespace MWDialogue
{
mChoice = -1;
mIsInChoice = false;
mGoodbye = false;
mCompilerContext.setExtensions (&extensions);
const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin();
for (; it != dialogs.end(); ++it)
{
mDialogueMap[Misc::StringUtils::lowerCase(it->mId)] = *it;
}
}
void DialogueManager::clear()
@ -108,17 +99,15 @@ namespace MWDialogue
if (mActorKnownTopics.count( topicId ))
mKnownTopics.insert( topicId );
}
updateTopics();
}
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
bool DialogueManager::startDialogue (const MWWorld::Ptr& actor, Response& response)
{
updateGlobals();
// Dialogue with dead actor (e.g. through script) should not be allowed.
if (actor.getClass().getCreatureStats(actor).isDead())
return;
return false;
mLastTopic = "";
mPermanentDispositionChange = 0;
@ -126,6 +115,8 @@ namespace MWDialogue
mChoice = -1;
mIsInChoice = false;
mGoodbye = false;
mChoices.clear();
mActor = actor;
@ -134,13 +125,6 @@ namespace MWDialogue
mActorKnownTopics.clear();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
// If the dialogue window was already open, keep the existing history
bool resetHistory = (!MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Dialogue));
win->startDialogue(actor, actor.getClass().getName (actor), resetHistory);
//greeting
const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
@ -154,9 +138,6 @@ namespace MWDialogue
// Search a response (we do not accept a fallback to "Info refusal" here)
if (const ESM::DialInfo *info = filter.search (*it, false))
{
//initialise the GUI
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
creatureStats.talkedToPlayer();
if (!info->mSound.empty())
@ -165,29 +146,23 @@ namespace MWDialogue
}
// first topics update so that parseText knows the keywords to highlight
updateTopics();
updateActorKnownTopics();
parseText (info->mResponse);
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addResponse (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext), "", false);
response = Response ("", Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript, mActor);
mLastTopic = Misc::StringUtils::lowerCase(it->mId);
mLastTopic = it->mId;
// update topics again to accommodate changes resulting from executeScript
updateTopics();
updateActorKnownTopics();
return;
return true;
}
}
}
// No greetings found. The dialogue window should not be shown.
// If this is a companion, we must show the companion window directly (used by BM_bear_be_unique).
bool isCompanion = !mActor.getClass().getScript(mActor).empty()
&& mActor.getRefData().getLocals().getIntVar(mActor.getClass().getScript(mActor), "companion");
if (isCompanion)
MWBase::Environment::get().getWindowManager()->showCompanionWindow(mActor);
return false;
}
bool DialogueManager::compile (const std::string& cmd, std::vector<Interpreter::Type_Code>& code, const MWWorld::Ptr& actor)
@ -265,8 +240,9 @@ namespace MWDialogue
}
}
void DialogueManager::executeTopic (const std::string& topic)
DialogueManager::Response DialogueManager::executeTopic (const std::string& topic)
{
DialogueManager::Response response;
Filter filter (mActor, mChoice, mTalkedTo);
const MWWorld::Store<ESM::Dialogue> &dialogues =
@ -274,8 +250,6 @@ namespace MWDialogue
const ESM::Dialogue& dialogue = *dialogues.find (topic);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
const ESM::DialInfo* info = filter.search(dialogue, true);
if (info)
{
@ -300,7 +274,7 @@ namespace MWDialogue
title = topic;
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addResponse (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext), title);
response = Response(title, Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
if (dialogue.mType == ESM::Dialogue::Topic)
{
@ -311,7 +285,7 @@ namespace MWDialogue
{
if (iter->mId == info->mId)
{
MWBase::Environment::get().getJournal()->addTopic (topic, info->mId, mActor);
MWBase::Environment::get().getJournal()->addTopic (Misc::StringUtils::lowerCase(topic), info->mId, mActor);
break;
}
}
@ -321,11 +295,12 @@ namespace MWDialogue
mLastTopic = topic;
}
else
{
// no response found, print a fallback text
win->addResponse ("", topic);
}
return response;
}
const ESM::Dialogue *DialogueManager::searchDialogue(const std::string& id)
{
return MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().search(id);
}
void DialogueManager::updateGlobals()
@ -333,19 +308,16 @@ namespace MWDialogue
MWBase::Environment::get().getWorld()->updateDialogueGlobals();
}
void DialogueManager::updateTopics()
void DialogueManager::updateActorKnownTopics()
{
updateGlobals();
std::list<std::string> keywordList;
int choice = mChoice;
mChoice = -1;
mActorKnownTopics.clear();
const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
Filter filter (mActor, mChoice, mTalkedTo);
Filter filter (mActor, -1, mTalkedTo);
for (MWWorld::Store<ESM::Dialogue>::iterator iter = dialogs.begin(); iter != dialogs.end(); ++iter)
{
@ -355,90 +327,42 @@ namespace MWDialogue
{
std::string lower = Misc::StringUtils::lowerCase(iter->mId);
mActorKnownTopics.insert (lower);
//does the player know the topic?
if (mKnownTopics.count(lower))
{
keywordList.push_back (iter->mId);
}
}
}
}
// check the available services of this actor
int services = 0;
if (mActor.getTypeName() == typeid(ESM::NPC).name())
}
std::list<std::string> DialogueManager::getAvailableTopics()
{
updateActorKnownTopics();
std::list<std::string> keywordList;
for (const std::string& topic : mActorKnownTopics)
{
MWWorld::LiveCellRef<ESM::NPC>* ref = mActor.get<ESM::NPC>();
if (ref->mBase->mHasAI)
services = ref->mBase->mAiData.mServices;
//does the player know the topic?
if (mKnownTopics.count(Misc::StringUtils::lowerCase(topic)))
keywordList.push_back(topic);
}
else if (mActor.getTypeName() == typeid(ESM::Creature).name())
{
MWWorld::LiveCellRef<ESM::Creature>* ref = mActor.get<ESM::Creature>();
if (ref->mBase->mHasAI)
services = ref->mBase->mAiData.mServices;
}
int windowServices = 0;
if (services & ESM::NPC::Weapon
|| services & ESM::NPC::Armor
|| services & ESM::NPC::Clothing
|| services & ESM::NPC::Books
|| services & ESM::NPC::Ingredients
|| services & ESM::NPC::Picks
|| services & ESM::NPC::Probes
|| services & ESM::NPC::Lights
|| services & ESM::NPC::Apparatus
|| services & ESM::NPC::RepairItem
|| services & ESM::NPC::Misc)
windowServices |= MWGui::DialogueWindow::Service_Trade;
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;
if (services & ESM::NPC::Spells)
windowServices |= MWGui::DialogueWindow::Service_BuySpells;
if (services & ESM::NPC::Spellmaking)
windowServices |= MWGui::DialogueWindow::Service_CreateSpells;
if (services & ESM::NPC::Training)
windowServices |= MWGui::DialogueWindow::Service_Training;
if (services & ESM::NPC::Enchanting)
windowServices |= MWGui::DialogueWindow::Service_Enchant;
if (services & ESM::NPC::Repair)
windowServices |= MWGui::DialogueWindow::Service_Repair;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->setServices (windowServices);
// sort again, because the previous sort was case-sensitive
keywordList.sort(Misc::StringUtils::ciLess);
win->setKeywords(keywordList);
mChoice = choice;
return keywordList;
}
void DialogueManager::keywordSelected (const std::string& keyword)
DialogueManager::Response DialogueManager::keywordSelected (const std::string& keyword)
{
Response response;
if(!mIsInChoice)
{
if(mDialogueMap.find(keyword) != mDialogueMap.end())
const ESM::Dialogue* dialogue = searchDialogue(keyword);
if (dialogue && dialogue->mType == ESM::Dialogue::Topic)
{
if (mDialogueMap[keyword].mType == ESM::Dialogue::Topic)
{
executeTopic (keyword);
}
response = executeTopic (keyword);
}
}
updateTopics();
return response;
}
bool DialogueManager::isInChoice() const
@ -448,8 +372,6 @@ namespace MWDialogue
void DialogueManager::goodbyeSelected()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
// Apply disposition change to NPC's base disposition
if (mActor.getClass().isNpc())
{
@ -465,37 +387,38 @@ namespace MWDialogue
mTemporaryDispositionChange = 0;
}
void DialogueManager::questionAnswered (int answer)
DialogueManager::Response DialogueManager::questionAnswered (int answer)
{
mChoice = answer;
DialogueManager::Response response;
if (mDialogueMap.find(mLastTopic) != mDialogueMap.end())
const ESM::Dialogue* dialogue = searchDialogue(mLastTopic);
if (dialogue)
{
Filter filter (mActor, mChoice, mTalkedTo);
if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic
|| mDialogueMap[mLastTopic].mType == ESM::Dialogue::Greeting)
if (dialogue->mType == ESM::Dialogue::Topic || dialogue->mType == ESM::Dialogue::Greeting)
{
if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic], true))
if (const ESM::DialInfo *info = filter.search (*dialogue, true))
{
std::string text = info->mResponse;
parseText (text);
mChoice = -1;
mIsInChoice = false;
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->clearChoices();
mChoices.clear();
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse (Interpreter::fixDefinesDialog(text, interpreterContext));
response = Response("", Interpreter::fixDefinesDialog(text, interpreterContext));
// Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group,
// in which case it should not be added to the journal.
for (ESM::Dialogue::InfoContainer::const_iterator iter = mDialogueMap[mLastTopic].mInfo.begin();
iter!=mDialogueMap[mLastTopic].mInfo.end(); ++iter)
for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue->mInfo.begin();
iter!=dialogue->mInfo.end(); ++iter)
{
if (iter->mId == info->mId)
{
MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId, mActor);
MWBase::Environment::get().getJournal()->addTopic (Misc::StringUtils::lowerCase(mLastTopic), info->mId, mActor);
break;
}
}
@ -506,32 +429,39 @@ namespace MWDialogue
{
mChoice = -1;
mIsInChoice = false;
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->clearChoices();
mChoices.clear();
}
}
}
updateTopics();
updateActorKnownTopics();
return response;
}
void DialogueManager::askQuestion (const std::string& question, int choice)
void DialogueManager::addChoice (const std::string& text, int choice)
{
mIsInChoice = true;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addChoice(question, choice);
mChoices.push_back(std::make_pair(text, choice));
}
const std::vector<std::pair<std::string, int> >& DialogueManager::getChoices()
{
return mChoices;
}
bool DialogueManager::isGoodbye()
{
return mGoodbye;
}
void DialogueManager::goodbye()
{
mIsInChoice = true;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->goodbye();
mIsInChoice = false;
mGoodbye = true;
}
void DialogueManager::persuade(int type)
DialogueManager::Response DialogueManager::persuade(int type)
{
bool success;
float temp, perm;
@ -580,7 +510,7 @@ namespace MWDialogue
text = "Bribe";
}
executeTopic (text + (success ? " Success" : " Fail"));
return executeTopic (text + (success ? " Success" : " Fail"));
}
int DialogueManager::getTemporaryDispositionChange() const
@ -593,7 +523,7 @@ namespace MWDialogue
mTemporaryDispositionChange += delta;
}
bool DialogueManager::checkServiceRefused()
bool DialogueManager::checkServiceRefused(Response& response)
{
Filter filter (mActor, mChoice, mTalkedTo);
@ -601,7 +531,6 @@ namespace MWDialogue
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
const ESM::Dialogue& dialogue = *dialogues.find ("Service Refusal");
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
std::vector<const ESM::DialInfo *> infos = filter.list (dialogue, false, false, true);
if (!infos.empty())
@ -615,8 +544,7 @@ namespace MWDialogue
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addResponse (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext),
gmsts.find ("sServiceRefusal")->getString());
response = Response(gmsts.find ("sServiceRefusal")->getString(), Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript, mActor);
return true;
@ -639,6 +567,12 @@ namespace MWDialogue
return;
}
if (actor.getClass().getCreatureStats(actor).getKnockedDown())
{
// Unconscious actors can not speak
return;
}
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Dialogue *dial = store.get<ESM::Dialogue>().find(topic);
@ -750,7 +684,7 @@ namespace MWDialogue
if (actor == mActor && !mLastTopic.empty())
{
MWBase::Environment::get().getJournal()->removeLastAddedTopicResponse(
mLastTopic, actor.getClass().getName(actor));
Misc::StringUtils::lowerCase(mLastTopic), actor.getClass().getName(actor));
}
}
}

View file

@ -22,7 +22,6 @@ namespace MWDialogue
{
class DialogueManager : public MWBase::DialogueManager
{
std::map<std::string, ESM::Dialogue> mDialogueMap;
std::set<std::string> mKnownTopics;// Those are the topics the player knows.
// Modified faction reactions. <Faction1, <Faction2, Difference> >
@ -42,19 +41,24 @@ namespace MWDialogue
int mChoice;
std::string mLastTopic; // last topic ID, lowercase
bool mIsInChoice;
bool mGoodbye;
std::vector<std::pair<std::string, int> > mChoices;
float mTemporaryDispositionChange;
float mPermanentDispositionChange;
void parseText (const std::string& text);
void updateTopics();
void updateActorKnownTopics();
void updateGlobals();
bool compile (const std::string& cmd, std::vector<Interpreter::Type_Code>& code, const MWWorld::Ptr& actor);
void executeScript (const std::string& script, const MWWorld::Ptr& actor);
void executeTopic (const std::string& topic);
Response executeTopic (const std::string& topic);
const ESM::Dialogue* searchDialogue(const std::string& id);
public:
@ -64,24 +68,29 @@ namespace MWDialogue
virtual bool isInChoice() const;
virtual void startDialogue (const MWWorld::Ptr& actor);
virtual bool startDialogue (const MWWorld::Ptr& actor, Response& response);
std::list<std::string> getAvailableTopics();
virtual void addTopic (const std::string& topic);
virtual void askQuestion (const std::string& question,int choice);
virtual void addChoice (const std::string& text,int choice);
const std::vector<std::pair<std::string, int> >& getChoices();
virtual bool isGoodbye();
virtual void goodbye();
virtual bool checkServiceRefused ();
virtual bool checkServiceRefused (Response& response);
virtual void say(const MWWorld::Ptr &actor, const std::string &topic);
//calbacks for the GUI
virtual void keywordSelected (const std::string& keyword);
virtual Response keywordSelected (const std::string& keyword);
virtual void goodbyeSelected();
virtual void questionAnswered (int answer);
virtual Response questionAnswered (int answer);
virtual void persuade (int type);
virtual Response persuade (int type);
virtual int getTemporaryDispositionChange () const;
/// @note This change is temporary and gets discarded when dialogue ends.

View file

@ -193,7 +193,8 @@ bool MWDialogue::Filter::testFunctionLocal(const MWDialogue::SelectWrapper& sele
return false; // shouldn't happen, we checked that variable has a type above, so must exist
const MWScript::Locals& locals = mActor.getRefData().getLocals();
if (locals.isEmpty())
return select.selectCompare(0);
switch (type)
{
case 's': return select.selectCompare (static_cast<int> (locals.mShorts[index]));

View file

@ -1,6 +1,8 @@
#include "alchemywindow.hpp"
#include <MyGUI_Gui.h>
#include <MyGUI_Button.h>
#include <MyGUI_EditBox.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -19,6 +21,7 @@
#include "sortfilteritemmodel.hpp"
#include "itemview.hpp"
#include "itemwidget.hpp"
#include "widgets.hpp"
namespace MWGui
{
@ -54,12 +57,19 @@ namespace MWGui
mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
mNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept);
center();
}
void AlchemyWindow::onAccept(MyGUI::EditBox* sender)
{
onCreateButtonClicked(sender);
}
void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Alchemy);
}
void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
@ -101,8 +111,9 @@ namespace MWGui
update();
}
void AlchemyWindow::open()
void AlchemyWindow::onOpen()
{
mAlchemy->clear();
mAlchemy->setAlchemist (MWMechanics::getPlayer());
InventoryItemModel* model = new InventoryItemModel(MWMechanics::getPlayer());
@ -127,12 +138,8 @@ namespace MWGui
}
update();
}
void AlchemyWindow::exit() {
mAlchemy->clear();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Alchemy);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Inventory);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit);
}
void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender)

View file

@ -5,7 +5,6 @@
#include "../mwmechanics/alchemy.hpp"
#include "widgets.hpp"
#include "windowbase.hpp"
namespace MWMechanics
@ -24,8 +23,9 @@ namespace MWGui
public:
AlchemyWindow();
virtual void open();
virtual void exit();
virtual void onOpen();
void onResChange(int, int) { center(); }
private:
std::string mSuggestedPotionName;
@ -43,6 +43,7 @@ namespace MWGui
void onCancelButtonClicked(MyGUI::Widget* _sender);
void onCreateButtonClicked(MyGUI::Widget* _sender);
void onIngredientSelected(MyGUI::Widget* _sender);
void onAccept(MyGUI::EditBox*);
void onSelectedItem(int index);

View file

@ -3,6 +3,7 @@
#include <MyGUI_ListBox.h>
#include <MyGUI_ImageBox.h>
#include <MyGUI_Gui.h>
#include <MyGUI_ScrollView.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -63,11 +64,12 @@ namespace MWGui
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
void BirthDialog::open()
void BirthDialog::onOpen()
{
WindowModal::open();
WindowModal::onOpen();
updateBirths();
updateSpells();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mBirthList);
}
@ -244,6 +246,11 @@ namespace MWGui
}
}
}
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mSpellArea->setVisibleVScroll(false);
mSpellArea->setCanvasSize(MyGUI::IntSize(mSpellArea->getWidth(), std::max(mSpellArea->getHeight(), coord.top)));
mSpellArea->setVisibleVScroll(true);
mSpellArea->setViewOffset(MyGUI::IntPoint(0, 0));
}
}

View file

@ -20,7 +20,9 @@ namespace MWGui
void setBirthId(const std::string &raceId);
void setNextButtonShow(bool shown);
virtual void open();
virtual void onOpen();
bool exit() { return false; }
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
@ -47,7 +49,7 @@ namespace MWGui
void updateSpells();
MyGUI::ListBox* mBirthList;
MyGUI::Widget* mSpellArea;
MyGUI::ScrollView* mSpellArea;
MyGUI::ImageBox* mBirthImage;
std::vector<MyGUI::Widget*> mSpellItems;

View file

@ -1,6 +1,7 @@
#include "bookwindow.hpp"
#include <MyGUI_TextBox.h>
#include <MyGUI_InputManager.h>
#include <components/esm/loadbook.hpp>
@ -11,6 +12,7 @@
#include "../mwmechanics/actorutil.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/class.hpp"
#include "formatting.hpp"
@ -51,6 +53,11 @@ namespace MWGui
mRightPage->setNeedMouseFocus(true);
mRightPage->eventMouseWheel += MyGUI::newDelegate(this, &BookWindow::onMouseWheel);
mNextPageButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &BookWindow::onKeyButtonPressed);
mPrevPageButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &BookWindow::onKeyButtonPressed);
mTakeButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &BookWindow::onKeyButtonPressed);
mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &BookWindow::onKeyButtonPressed);
if (mNextPageButton->getSize().width == 64)
{
// english button has a 7 pixel wide strip of garbage on its right edge
@ -74,15 +81,16 @@ namespace MWGui
mPages.clear();
}
void BookWindow::openBook (MWWorld::Ptr book, bool showTakeButton)
void BookWindow::setPtr (const MWWorld::Ptr& book)
{
mBook = book;
MWWorld::Ptr player = MWMechanics::getPlayer();
bool showTakeButton = book.getContainerStore() != &player.getClass().getContainerStore(player);
clearPages();
mCurrentPage = 0;
MWBase::Environment::get().getWindowManager()->playSound("book open");
MWWorld::LiveCellRef<ESM::Book> *ref = mBook.get<ESM::Book>();
Formatting::BookFormatter formatter;
@ -92,14 +100,8 @@ namespace MWGui
updatePages();
setTakeButtonShow(showTakeButton);
}
void BookWindow::exit()
{
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getWindowManager()->playSound("book close");
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
}
void BookWindow::setTakeButtonShow(bool show)
@ -108,6 +110,14 @@ namespace MWGui
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
void BookWindow::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character)
{
if (key == MyGUI::KeyCode::ArrowUp)
prevPage();
else if (key == MyGUI::KeyCode::ArrowDown)
nextPage();
}
void BookWindow::setInventoryAllowed(bool allowed)
{
mTakeButtonAllowed = allowed;
@ -116,7 +126,7 @@ namespace MWGui
void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
}
void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender)
@ -144,20 +154,16 @@ namespace MWGui
mLeftPageNumber->setCaption( MyGUI::utility::toString(mCurrentPage*2 + 1) );
mRightPageNumber->setCaption( MyGUI::utility::toString(mCurrentPage*2 + 2) );
//If it is the last page, hide the button "Next Page"
if ( (mCurrentPage+1)*2 == mPages.size()
|| (mCurrentPage+1)*2 == mPages.size() + 1)
{
mNextPageButton->setVisible(false);
} else {
mNextPageButton->setVisible(true);
}
//If it is the fist page, hide the button "Prev Page"
if (mCurrentPage == 0) {
mPrevPageButton->setVisible(false);
} else {
mPrevPageButton->setVisible(true);
}
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
bool nextPageVisible = (mCurrentPage+1)*2 < mPages.size();
mNextPageButton->setVisible(nextPageVisible);
bool prevPageVisible = mCurrentPage != 0;
mPrevPageButton->setVisible(prevPageVisible);
if (focus == mNextPageButton && !nextPageVisible && prevPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mPrevPageButton);
else if (focus == mPrevPageButton && !prevPageVisible && nextPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNextPageButton);
if (mPages.empty())
return;

View file

@ -14,11 +14,11 @@ namespace MWGui
public:
BookWindow();
virtual void exit();
void openBook(MWWorld::Ptr book, bool showTakeButton);
void setPtr(const MWWorld::Ptr& book);
void setInventoryAllowed(bool allowed);
void onResChange(int, int) { center(); }
protected:
void onNextPageButtonClicked (MyGUI::Widget* sender);
void onPrevPageButtonClicked (MyGUI::Widget* sender);
@ -27,6 +27,8 @@ namespace MWGui
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void setTakeButtonShow(bool show);
void onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character);
void nextPage();
void prevPage();

View file

@ -125,11 +125,12 @@ namespace MWGui
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
void PickClassDialog::open()
void PickClassDialog::onOpen()
{
WindowModal::open ();
WindowModal::onOpen ();
updateClasses();
updateStats();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mClassList);
}
@ -341,9 +342,9 @@ namespace MWGui
}
}
void InfoBoxDialog::open()
void InfoBoxDialog::onOpen()
{
WindowModal::open();
WindowModal::onOpen();
// Fix layout
layoutVertically(mTextBox, 4);
layoutVertically(mButtonBar, 6);
@ -730,9 +731,10 @@ namespace MWGui
exit();
}
void SelectSpecializationDialog::exit()
bool SelectSpecializationDialog::exit()
{
eventCancel();
return true;
}
/* SelectAttributeDialog */
@ -778,9 +780,10 @@ namespace MWGui
exit();
}
void SelectAttributeDialog::exit()
bool SelectAttributeDialog::exit()
{
eventCancel();
return true;
}
@ -869,9 +872,10 @@ namespace MWGui
exit();
}
void SelectSkillDialog::exit()
bool SelectSkillDialog::exit()
{
eventCancel();
return true;
}
/* DescriptionDialog */

View file

@ -21,7 +21,9 @@ namespace MWGui
std::string getText() const;
void setButtons(ButtonList &buttons);
virtual void open();
virtual void onOpen();
bool exit() { return false; }
// Events
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int;
@ -67,6 +69,8 @@ namespace MWGui
std::string getClassId() const;
void setClassId(const std::string &classId);
bool exit() { return false; }
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
@ -100,7 +104,9 @@ namespace MWGui
void setClassId(const std::string &classId);
void setNextButtonShow(bool shown);
virtual void open();
virtual void onOpen();
bool exit() { return false; }
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
@ -142,7 +148,7 @@ namespace MWGui
SelectSpecializationDialog();
~SelectSpecializationDialog();
virtual void exit();
virtual bool exit();
ESM::Class::Specialization getSpecializationId() const { return mSpecializationId; }
@ -175,7 +181,7 @@ namespace MWGui
SelectAttributeDialog();
~SelectAttributeDialog();
virtual void exit();
virtual bool exit();
ESM::Attribute::AttributeID getAttributeId() const { return mAttributeId; }
@ -206,7 +212,7 @@ namespace MWGui
SelectSkillDialog();
~SelectSkillDialog();
virtual void exit();
virtual bool exit();
ESM::Skill::SkillEnum getSkillId() const { return mSkillId; }
@ -262,6 +268,8 @@ namespace MWGui
CreateClassDialog();
virtual ~CreateClassDialog();
bool exit() { return false; }
std::string getName() const;
std::string getDescription() const;
ESM::Class::Specialization getSpecializationId() const;

View file

@ -13,6 +13,7 @@
#include "companionitemmodel.hpp"
#include "draganddrop.hpp"
#include "countdialog.hpp"
#include "widgets.hpp"
namespace
{
@ -103,7 +104,7 @@ void CompanionWindow::onBackgroundSelected()
}
}
void CompanionWindow::openCompanion(const MWWorld::Ptr& npc)
void CompanionWindow::setPtr(const MWWorld::Ptr& npc)
{
mPtr = npc;
updateEncumbranceBar();
@ -116,8 +117,9 @@ void CompanionWindow::openCompanion(const MWWorld::Ptr& npc)
setTitle(npc.getClass().getName(npc));
}
void CompanionWindow::onFrame()
void CompanionWindow::onFrame(float dt)
{
checkReferenceAvailable();
updateEncumbranceBar();
}
@ -139,10 +141,11 @@ void CompanionWindow::updateEncumbranceBar()
void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
exit();
if (exit())
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
}
void CompanionWindow::exit()
bool CompanionWindow::exit()
{
if (mModel && mModel->hasProfit(mPtr) && getProfit(mPtr) < 0)
{
@ -151,9 +154,9 @@ void CompanionWindow::exit()
buttons.push_back("#{sCompanionWarningButtonTwo}");
mMessageBoxManager->createInteractiveMessageBox("#{sCompanionWarningMessage}", buttons);
mMessageBoxManager->eventButtonPressed += MyGUI::newDelegate(this, &CompanionWindow::onMessageBoxButtonClicked);
return false;
}
else
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
return true;
}
void CompanionWindow::onMessageBoxButtonClicked(int button)
@ -162,7 +165,7 @@ void CompanionWindow::onMessageBoxButtonClicked(int button)
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
// Important for Calvus' contract script to work properly
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
}
}

View file

@ -1,12 +1,16 @@
#ifndef OPENMW_MWGUI_COMPANIONWINDOW_H
#define OPENMW_MWGUI_COMPANIONWINDOW_H
#include "widgets.hpp"
#include "windowbase.hpp"
#include "referenceinterface.hpp"
namespace MWGui
{
namespace Widgets
{
class MWDynamicStat;
}
class MessageBoxManager;
class ItemView;
class DragAndDrop;
@ -18,12 +22,13 @@ namespace MWGui
public:
CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager);
virtual void exit();
virtual bool exit();
virtual void resetReference();
void openCompanion(const MWWorld::Ptr& npc);
void onFrame ();
void setPtr(const MWWorld::Ptr& npc);
void onFrame (float dt);
void clear() { resetReference(); }
private:
ItemView* mItemView;

View file

@ -3,6 +3,9 @@
#include <MyGUI_Button.h>
#include <MyGUI_EditBox.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWGui
{
ConfirmationDialog::ConfirmationDialog() :
@ -16,14 +19,6 @@ namespace MWGui
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ConfirmationDialog::onOkButtonClicked);
}
void ConfirmationDialog::askForConfirmation(const std::string& message, const std::string& confirmMessage, const std::string& cancelMessage)
{
mCancelButton->setCaptionWithReplacing(cancelMessage);
mOkButton->setCaptionWithReplacing(confirmMessage);
askForConfirmation(message);
}
void ConfirmationDialog::askForConfirmation(const std::string& message)
{
setVisible(true);
@ -38,18 +33,21 @@ namespace MWGui
mMessage->setSize(mMessage->getWidth(), mMessage->getTextSize().height + 24);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton);
center();
}
void ConfirmationDialog::exit()
bool ConfirmationDialog::exit()
{
setVisible(false);
eventCancelClicked();
return true;
}
void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
{
setVisible(false);
exit();
}

View file

@ -10,8 +10,7 @@ namespace MWGui
public:
ConfirmationDialog();
void askForConfirmation(const std::string& message);
void askForConfirmation(const std::string& message, const std::string& confirmMessage, const std::string& cancelMessage);
virtual void exit();
virtual bool exit();
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;

View file

@ -145,25 +145,13 @@ namespace MWGui
mCompilerContext.setExtensions (&mExtensions);
}
void Console::open()
void Console::onOpen()
{
// Give keyboard focus to the combo box whenever the console is
// turned on
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCommandLine);
}
void Console::close()
{
// Apparently, hidden widgets can retain key focus
// Remove for MyGUI 3.2.2
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(NULL);
}
void Console::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Console);
}
void Console::setFont(const std::string &fntName)
{
mHistory->setFontName(fntName);
@ -227,6 +215,11 @@ namespace MWGui
}
}
void Console::clear()
{
resetReference();
}
void Console::keyPress(MyGUI::Widget* _sender,
MyGUI::KeyCode key,
MyGUI::Char _char)

View file

@ -39,10 +39,7 @@ namespace MWGui
Console(int w, int h, bool consoleOnlyScripts);
virtual void open();
virtual void close();
virtual void exit();
virtual void onOpen();
void setFont(const std::string &fntName);
@ -63,6 +60,8 @@ namespace MWGui
void executeFile (const std::string& path);
void clear();
virtual void resetReference ();
protected:

View file

@ -11,6 +11,7 @@
#include "../mwmechanics/actorutil.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/pickpocket.hpp"
#include "../mwmechanics/creaturestats.hpp"
@ -46,7 +47,6 @@ namespace MWGui
mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked);
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ContainerWindow::onKeyPressed);
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
setCoord(200,0,600,300);
@ -129,12 +129,14 @@ namespace MWGui
dropItem();
}
void ContainerWindow::openContainer(const MWWorld::Ptr& container, bool loot)
void ContainerWindow::setPtr(const MWWorld::Ptr& container)
{
mPickpocketDetected = false;
mPtr = container;
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot)
bool loot = mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead();
if (mPtr.getClass().isNpc() && !loot)
{
// we are stealing stuff
MWWorld::Ptr player = MWMechanics::getPlayer();
@ -156,14 +158,6 @@ namespace MWGui
setTitle(container.getClass().getName(container));
}
void ContainerWindow::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
{
if (_key == MyGUI::KeyCode::Space)
onCloseButtonClicked(mCloseButton);
if (_key == MyGUI::KeyCode::Return || _key == MyGUI::KeyCode::NumpadEnter)
onTakeAllButtonClicked(mTakeButton);
}
void ContainerWindow::resetReference()
{
ReferenceInterface::resetReference();
@ -172,9 +166,9 @@ namespace MWGui
mSortModel = NULL;
}
void ContainerWindow::close()
void ContainerWindow::onClose()
{
WindowBase::close();
WindowBase::onClose();
if (dynamic_cast<PickpocketItemModel*>(mModel)
// Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened)
@ -196,46 +190,55 @@ namespace MWGui
}
}
void ContainerWindow::exit()
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
}
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
if(mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop)
return;
// transfer everything into the player's inventory
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
mModel->update();
// unequip all items to avoid unequipping/reequipping
if (mPtr.getClass().hasInventoryStore(mPtr))
{
// transfer everything into the player's inventory
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
mModel->update();
MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr);
for (size_t i=0; i<mModel->getItemCount(); ++i)
{
if (i==0)
{
// play the sound of the first object
MWWorld::Ptr item = mModel->getItem(i).mBase;
std::string sound = item.getClass().getUpSoundId(item);
MWBase::Environment::get().getWindowManager()->playSound(sound);
}
const ItemStack& item = mModel->getItem(i);
if (invStore.isEquipped(item.mBase) == false)
continue;
if (!onTakeItem(item, item.mCount))
break;
invStore.unequipItem(item.mBase, mPtr);
}
}
mModel->moveItem(item, item.mCount, playerModel);
mModel->update();
for (size_t i=0; i<mModel->getItemCount(); ++i)
{
if (i==0)
{
// play the sound of the first object
MWWorld::Ptr item = mModel->getItem(i).mBase;
std::string sound = item.getClass().getUpSoundId(item);
MWBase::Environment::get().getWindowManager()->playSound(sound);
}
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
const ItemStack& item = mModel->getItem(i);
if (!onTakeItem(item, item.mCount))
break;
mModel->moveItem(item, item.mCount, playerModel);
}
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
@ -268,9 +271,8 @@ namespace MWGui
MWMechanics::Pickpocket pickpocket(player, mPtr);
if (pickpocket.pick(item.mBase, count))
{
int value = item.mBase.getClass().getValue(item.mBase) * count;
MWBase::Environment::get().getMechanicsManager()->commitCrime(
player, mPtr, MWBase::MechanicsManager::OT_Theft, value, true);
player, mPtr, MWBase::MechanicsManager::OT_Pickpocket, 0, true);
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
mPickpocketDetected = true;
return false;

View file

@ -33,13 +33,14 @@ namespace MWGui
public:
ContainerWindow(DragAndDrop* dragAndDrop);
void openContainer(const MWWorld::Ptr& container, bool loot=false);
virtual void close();
void setPtr(const MWWorld::Ptr& container);
virtual void onClose();
void clear() { resetReference(); }
void onFrame(float dt) { checkReferenceAvailable(); }
virtual void resetReference();
virtual void exit();
private:
DragAndDrop* mDragAndDrop;
@ -61,7 +62,6 @@ namespace MWGui
void onCloseButtonClicked(MyGUI::Widget* _sender);
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
void onDisposeCorpseButtonClicked(MyGUI::Widget* sender);
void onKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char);
/// @return is taking the item allowed?
bool onTakeItem(const ItemStack& item, int count);

View file

@ -56,19 +56,9 @@ namespace MWGui
mItemEdit->setValue(maxCount);
}
void CountDialog::cancel() //Keeping this here as I don't know if anything else relies on it.
{
exit();
}
void CountDialog::exit()
{
setVisible(false);
}
void CountDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
{
cancel();
setVisible(false);
}
void CountDialog::onOkButtonClicked(MyGUI::Widget* _sender)

View file

@ -15,8 +15,6 @@ namespace MWGui
public:
CountDialog();
void openCountDialog(const std::string& item, const std::string& message, const int maxCount);
void cancel();
virtual void exit();
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, int> EventHandle_WidgetInt;

View file

@ -3,6 +3,8 @@
#include <MyGUI_LanguageManager.h>
#include <MyGUI_Window.h>
#include <MyGUI_ProgressBar.h>
#include <MyGUI_ScrollBar.h>
#include <MyGUI_Button.h>
#include <components/widgets/list.hpp>
#include <components/translation/translation.hpp>
@ -20,7 +22,6 @@
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "widgets.hpp"
#include "bookpage.hpp"
#include "textcolours.hpp"
@ -52,7 +53,7 @@ namespace MWGui
void PersuasionDialog::onCancel(MyGUI::Widget *sender)
{
exit();
setVisible(false);
}
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
@ -68,14 +69,15 @@ namespace MWGui
else /*if (sender == mBribe1000Button)*/
type = MWBase::MechanicsManager::PT_Bribe1000;
MWBase::Environment::get().getDialogueManager()->persuade(type);
MWBase::DialogueManager::Response response = MWBase::Environment::get().getDialogueManager()->persuade(type);
eventPersuadeMsg(response.first, response.second);
setVisible(false);
}
void PersuasionDialog::open()
void PersuasionDialog::onOpen()
{
WindowModal::open();
center();
MWWorld::Ptr player = MWMechanics::getPlayer();
@ -86,11 +88,12 @@ namespace MWGui
mBribe1000Button->setEnabled (playerGold >= 1000);
mGoldLabel->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold));
WindowModal::onOpen();
}
void PersuasionDialog::exit()
MyGUI::Widget* PersuasionDialog::getDefaultKeyFocus()
{
setVisible(false);
return mAdmireButton;
}
// --------------------------------------------------------------------------------------------------
@ -219,31 +222,27 @@ namespace MWGui
void Choice::activated()
{
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId);
eventChoiceActivated(mChoiceId);
}
void Topic::activated()
{
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId));
eventTopicActivated(mTopicId);
}
void Goodbye::activated()
{
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
eventActivated();
}
// --------------------------------------------------------------------------------------------------
DialogueWindow::DialogueWindow()
: WindowBase("openmw_dialogue_window.layout")
, mServices(0)
, mEnabled(false)
, mIsCompanion(false)
, mGoodbye(false)
, mPersuasionDialog()
{
@ -251,17 +250,17 @@ namespace MWGui
center();
mPersuasionDialog.setVisible(false);
mPersuasionDialog.eventPersuadeMsg += MyGUI::newDelegate(this, &DialogueWindow::onPersuadeResult);
//History view
getWidget(mHistory, "History");
//Topics list
getWidget(mTopicsList, "TopicsList");
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectListItem);
MyGUI::Button* byeButton;
getWidget(byeButton, "ByeButton");
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
getWidget(mGoodbyeButton, "ByeButton");
mGoodbyeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
getWidget(mDispositionBar, "Disposition");
getWidget(mDispositionText,"DispositionText");
@ -276,18 +275,36 @@ namespace MWGui
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
}
void DialogueWindow::exit()
DialogueWindow::~DialogueWindow()
{
if ((!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
&& !mGoodbye)
mPersuasionDialog.eventPersuadeMsg.clear();
deleteLater();
for (Link* link : mLinks)
delete link;
for (auto link : mTopicLinks)
delete link.second;
for (auto history : mHistoryContents)
delete history;
}
void DialogueWindow::onTradeComplete()
{
addResponse("", MyGUI::LanguageManager::getInstance().replaceTags("#{sBarterDialog5}"));
}
bool DialogueWindow::exit()
{
if ((MWBase::Environment::get().getDialogueManager()->isInChoice()))
{
// in choice, not allowed to escape, but give access to main menu to allow loading other saves
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
return false;
}
else
{
resetReference();
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
mTopicsList->scrollToTop();
return true;
}
}
@ -312,12 +329,13 @@ namespace MWGui
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{
exit();
if (exit())
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
}
void DialogueWindow::onSelectTopic(const std::string& topic, int id)
void DialogueWindow::onSelectListItem(const std::string& topic, int id)
{
if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
if (mGoodbye || MWBase::Environment::get().getDialogueManager()->isInChoice())
return;
int separatorPos = 0;
@ -328,63 +346,83 @@ namespace MWGui
}
if (id >= separatorPos)
MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(topic));
{
onTopicActivated(topic);
if (mGoodbyeButton->getEnabled())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
}
else
{
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
MWBase::DialogueManager::Response response;
if (topic == gmst.find("sPersuasion")->getString())
mPersuasionDialog.setVisible(true);
else if (topic == gmst.find("sCompanionShare")->getString())
MWBase::Environment::get().getWindowManager()->showCompanionWindow(mPtr);
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion, mPtr);
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused(response))
{
if (topic == gmst.find("sBarter")->getString())
MWBase::Environment::get().getWindowManager()->startTrade(mPtr);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter, mPtr);
else if (topic == gmst.find("sSpells")->getString())
MWBase::Environment::get().getWindowManager()->startSpellBuying(mPtr);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellBuying, mPtr);
else if (topic == gmst.find("sTravel")->getString())
MWBase::Environment::get().getWindowManager()->startTravel(mPtr);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Travel, mPtr);
else if (topic == gmst.find("sSpellMakingMenuTitle")->getString())
MWBase::Environment::get().getWindowManager()->startSpellMaking (mPtr);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellCreation, mPtr);
else if (topic == gmst.find("sEnchanting")->getString())
MWBase::Environment::get().getWindowManager()->startEnchanting (mPtr);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting, mPtr);
else if (topic == gmst.find("sServiceTrainingTitle")->getString())
MWBase::Environment::get().getWindowManager()->startTraining (mPtr);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Training, mPtr);
else if (topic == gmst.find("sRepair")->getString())
MWBase::Environment::get().getWindowManager()->startRepair (mPtr);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair, mPtr);
}
else
addResponse(response.first, response.second);
}
}
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName, bool resetHistory)
void DialogueWindow::setPtr(const MWWorld::Ptr& actor)
{
MWBase::DialogueManager::Response response;
if (!MWBase::Environment::get().getDialogueManager()->startDialogue(actor, response))
{
// No greetings found. The dialogue window should not be shown.
// If this is a companion, we must show the companion window directly (used by BM_bear_be_unique).
if (isCompanion())
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Companion, mPtr);
return;
}
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
mGoodbye = false;
mEnabled = true;
bool sameActor = (mPtr == actor);
mPtr = actor;
mTopicsList->setEnabled(true);
setTitle(npcName);
clearChoices();
setTitle(mPtr.getClass().getName(mPtr));
mTopicsList->clear();
if (resetHistory || !sameActor)
if (!sameActor)
{
for (std::vector<DialogueText*>::iterator it = mHistoryContents.begin(); it != mHistoryContents.end(); ++it)
delete (*it);
mHistoryContents.clear();
mKeywords.clear();
updateTopicsPane();
}
for (std::vector<Link*>::iterator it = mLinks.begin(); it != mLinks.end(); ++it)
delete (*it);
mDeleteLater.push_back(*it); // Links are not deleted right away to prevent issues with event handlers
mLinks.clear();
updateOptions();
updateDisposition();
restock();
addResponse(response.first, response.second, false);
}
void DialogueWindow::restock()
@ -401,16 +439,35 @@ namespace MWGui
}
}
void DialogueWindow::deleteLater()
{
for (Link* link : mDeleteLater)
delete link;
mDeleteLater.clear();
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
if (mKeywords == keyWords && isCompanion() == mIsCompanion)
return;
mIsCompanion = isCompanion();
mKeywords = keyWords;
updateTopicsPane();
}
void DialogueWindow::updateTopicsPane()
{
mTopicsList->clear();
for (std::map<std::string, Link*>::iterator it = mTopicLinks.begin(); it != mTopicLinks.end(); ++it)
delete it->second;
mDeleteLater.push_back(it->second);
mTopicLinks.clear();
mKeywordSearch.clear();
bool isCompanion = !mPtr.getClass().getScript(mPtr).empty()
&& mPtr.getRefData().getLocals().getIntVar(mPtr.getClass().getScript(mPtr), "companion");
int services = mPtr.getClass().getServices(mPtr);
bool travel = (mPtr.getTypeName() == typeid(ESM::NPC).name() && !mPtr.get<ESM::NPC>()->mBase->getTransport().empty())
|| (mPtr.getTypeName() == typeid(ESM::Creature).name() && !mPtr.get<ESM::Creature>()->mBase->getTransport().empty());
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -418,39 +475,40 @@ namespace MWGui
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
mTopicsList->addItem(gmst.find("sPersuasion")->getString());
if (mServices & Service_Trade)
if (services & ESM::NPC::AllItems)
mTopicsList->addItem(gmst.find("sBarter")->getString());
if (mServices & Service_BuySpells)
if (services & ESM::NPC::Spells)
mTopicsList->addItem(gmst.find("sSpells")->getString());
if (mServices & Service_Travel)
if (travel)
mTopicsList->addItem(gmst.find("sTravel")->getString());
if (mServices & Service_CreateSpells)
if (services & ESM::NPC::Spellmaking)
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
if (mServices & Service_Enchant)
if (services & ESM::NPC::Enchanting)
mTopicsList->addItem(gmst.find("sEnchanting")->getString());
if (mServices & Service_Training)
if (services & ESM::NPC::Training)
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
if (mServices & Service_Repair)
if (services & ESM::NPC::Repair)
mTopicsList->addItem(gmst.find("sRepair")->getString());
if (isCompanion)
if (isCompanion())
mTopicsList->addItem(gmst.find("sCompanionShare")->getString());
if (mTopicsList->getItemCount() > 0)
mTopicsList->addSeparator();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
for(std::list<std::string>::iterator it = mKeywords.begin(); it != mKeywords.end(); ++it)
{
mTopicsList->addItem(*it);
Topic* t = new Topic(*it);
t->eventTopicActivated += MyGUI::newDelegate(this, &DialogueWindow::onTopicActivated);
mTopicLinks[Misc::StringUtils::lowerCase(*it)] = t;
mKeywordSearch.seed(Misc::StringUtils::lowerCase(*it), intptr_t(t));
@ -484,9 +542,11 @@ namespace MWGui
typesetter->sectionBreak(9);
// choices
const TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours();
for (std::vector<std::pair<std::string, int> >::iterator it = mChoices.begin(); it != mChoices.end(); ++it)
mChoices = MWBase::Environment::get().getDialogueManager()->getChoices();
for (std::vector<std::pair<std::string, int> >::const_iterator it = mChoices.begin(); it != mChoices.end(); ++it)
{
Choice* link = new Choice(it->second);
link->eventChoiceActivated += MyGUI::newDelegate(this, &DialogueWindow::onChoiceActivated);
mLinks.push_back(link);
typesetter->lineBreak();
@ -496,9 +556,11 @@ namespace MWGui
typesetter->write(questionStyle, to_utf8_span(it->first.c_str()));
}
mGoodbye = MWBase::Environment::get().getDialogueManager()->isGoodbye();
if (mGoodbye)
{
Goodbye* link = new Goodbye();
link->eventActivated += MyGUI::newDelegate(this, &DialogueWindow::onGoodbyeActivated);
mLinks.push_back(link);
std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString();
BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver,
@ -528,10 +590,11 @@ namespace MWGui
onScrollbarMoved(mScrollBar, 0);
}
MyGUI::Button* byeButton;
getWidget(byeButton, "ByeButton");
bool goodbyeEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() || mGoodbye;
byeButton->setEnabled(goodbyeEnabled);
bool goodbyeWasEnabled = mGoodbyeButton->getEnabled();
mGoodbyeButton->setEnabled(goodbyeEnabled);
if (goodbyeEnabled && !goodbyeWasEnabled)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
bool topicsEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye;
mTopicsList->setEnabled(topicsEnabled);
@ -542,32 +605,35 @@ namespace MWGui
reinterpret_cast<Link*>(link)->activated();
}
void DialogueWindow::onTopicActivated(const std::string &topicId)
{
MWBase::DialogueManager::Response response = MWBase::Environment::get().getDialogueManager()->keywordSelected(topicId);
addResponse(response.first, response.second);
}
void DialogueWindow::onChoiceActivated(int id)
{
MWBase::DialogueManager::Response response = MWBase::Environment::get().getDialogueManager()->questionAnswered(id);
addResponse(response.first, response.second);
}
void DialogueWindow::onGoodbyeActivated()
{
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
resetReference();
}
void DialogueWindow::onScrollbarMoved(MyGUI::ScrollBar *sender, size_t pos)
{
mHistory->setPosition(0, static_cast<int>(pos) * -1);
}
void DialogueWindow::addResponse(const std::string &text, const std::string &title, bool needMargin)
void DialogueWindow::addResponse(const std::string &title, const std::string &text, bool needMargin)
{
// This is called from the dialogue manager, so text is
// case-smashed - thus we have to retrieve the correct case
// of the title through the topic list.
std::string realTitle = title;
if (realTitle != "")
{
for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
{
std::string item = mTopicsList->getItemNameAt(i);
if (Misc::StringUtils::ciEqual(item, title))
{
realTitle = item;
break;
}
}
}
mHistoryContents.push_back(new Response(text, realTitle, needMargin));
mHistoryContents.push_back(new Response(text, title, needMargin));
updateHistory();
updateTopics();
}
void DialogueWindow::addMessageBox(const std::string& text)
@ -576,25 +642,10 @@ namespace MWGui
updateHistory();
}
void DialogueWindow::addChoice(const std::string& choice, int id)
void DialogueWindow::updateDisposition()
{
mChoices.push_back(std::make_pair(choice, id));
updateHistory();
}
void DialogueWindow::clearChoices()
{
mChoices.clear();
updateHistory();
}
void DialogueWindow::updateOptions()
{
//Clear the list of topics
mTopicsList->clear();
bool dispositionVisible = false;
if (mPtr.getClass().isNpc())
if (!mPtr.isEmpty() && mPtr.getClass().isNpc())
{
dispositionVisible = true;
mDispositionBar->setProgressRange(100);
@ -620,26 +671,38 @@ namespace MWGui
}
}
void DialogueWindow::goodbye()
{
mGoodbye = true;
mEnabled = false;
updateHistory();
}
void DialogueWindow::onReferenceUnavailable()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
}
void DialogueWindow::onFrame()
void DialogueWindow::onFrame(float dt)
{
if(mMainWidget->getVisible() && mPtr.getTypeName() == typeid(ESM::NPC).name())
{
int disp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr);
mDispositionBar->setProgressRange(100);
mDispositionBar->setProgressPosition(disp);
mDispositionText->setCaption(MyGUI::utility::toString(disp)+std::string("/100"));
}
checkReferenceAvailable();
if (mPtr.isEmpty())
return;
updateDisposition();
deleteLater();
if (mChoices != MWBase::Environment::get().getDialogueManager()->getChoices()
|| mGoodbye != MWBase::Environment::get().getDialogueManager()->isGoodbye())
updateHistory();
}
void DialogueWindow::updateTopics()
{
setKeywords(MWBase::Environment::get().getDialogueManager()->getAvailableTopics());
}
bool DialogueWindow::isCompanion()
{
return !mPtr.getClass().getScript(mPtr).empty()
&& mPtr.getRefData().getLocals().getIntVar(mPtr.getClass().getScript(mPtr), "companion");
}
void DialogueWindow::onPersuadeResult(const std::string &title, const std::string &text)
{
addResponse(title, text);
}
}

View file

@ -8,6 +8,8 @@
#include "../mwdialogue/keywordsearch.hpp"
#include <MyGUI_Delegate.h>
namespace Gui
{
class MWList;
@ -20,16 +22,17 @@ namespace MWGui
namespace MWGui
{
class DialogueHistoryViewModel;
class BookPage;
class PersuasionDialog : public WindowModal
{
public:
PersuasionDialog();
virtual void open();
virtual void exit();
typedef MyGUI::delegates::CMultiDelegate2<const std::string&, const std::string&> EventHandle_Result;
EventHandle_Result eventPersuadeMsg;
virtual void onOpen();
virtual MyGUI::Widget* getDefaultKeyFocus();
private:
MyGUI::Button* mCancelButton;
@ -54,6 +57,8 @@ namespace MWGui
struct Topic : Link
{
typedef MyGUI::delegates::CMultiDelegate1<const std::string&> EventHandle_TopicId;
EventHandle_TopicId eventTopicActivated;
Topic(const std::string& id) : mTopicId(id) {}
std::string mTopicId;
virtual void activated ();
@ -61,6 +66,8 @@ namespace MWGui
struct Choice : Link
{
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_ChoiceId;
EventHandle_ChoiceId eventChoiceActivated;
Choice(int id) : mChoiceId(id) {}
int mChoiceId;
virtual void activated ();
@ -68,6 +75,8 @@ namespace MWGui
struct Goodbye : Link
{
typedef MyGUI::delegates::CMultiDelegate0 Event_Activated;
Event_Activated eventActivated;
virtual void activated ();
};
@ -99,46 +108,41 @@ namespace MWGui
{
public:
DialogueWindow();
~DialogueWindow();
virtual void exit();
void onTradeComplete();
virtual bool exit();
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
void notifyLinkClicked (TypesetBook::InteractiveId link);
void startDialogue(MWWorld::Ptr actor, std::string npcName, bool resetHistory);
void setPtr(const MWWorld::Ptr& actor);
void setKeywords(std::list<std::string> keyWord);
void addResponse (const std::string& text, const std::string& title="", bool needMargin = true);
void addResponse (const std::string& title, const std::string& text, bool needMargin = true);
void addMessageBox(const std::string& text);
void addChoice(const std::string& choice, int id);
void clearChoices();
void goodbye();
void onFrame();
// make sure to call these before setKeywords()
void setServices(int services) { mServices = services; }
enum Services
{
Service_Trade = 0x01,
Service_BuySpells = 0x02,
Service_CreateSpells = 0x04,
Service_Enchant = 0x08,
Service_Training = 0x10,
Service_Travel = 0x20,
Service_Repair = 0x40
};
void onFrame(float dt);
void clear() { resetReference(); }
protected:
void onSelectTopic(const std::string& topic, int id);
void updateTopics();
void updateTopicsPane();
bool isCompanion();
void onPersuadeResult(const std::string& title, const std::string& text);
void onSelectListItem(const std::string& topic, int id);
void onByeClicked(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void onWindowResize(MyGUI::Window* _sender);
void onTopicActivated(const std::string& topicId);
void onChoiceActivated(int id);
void onGoodbyeActivated();
void onScrollbarMoved (MyGUI::ScrollBar* sender, size_t pos);
@ -147,21 +151,24 @@ namespace MWGui
virtual void onReferenceUnavailable();
private:
void updateOptions();
void updateDisposition();
void restock();
int mServices;
void deleteLater();
bool mEnabled;
bool mGoodbye;
bool mIsCompanion;
std::list<std::string> mKeywords;
std::vector<DialogueText*> mHistoryContents;
std::vector<std::pair<std::string, int> > mChoices;
bool mGoodbye;
std::vector<Link*> mLinks;
std::map<std::string, Link*> mTopicLinks;
std::vector<Link*> mDeleteLater;
KeywordSearchT mKeywordSearch;
BookPage* mHistory;
@ -169,6 +176,7 @@ namespace MWGui
MyGUI::ScrollBar* mScrollBar;
MyGUI::ProgressBar* mDispositionBar;
MyGUI::TextBox* mDispositionText;
MyGUI::Button* mGoodbyeButton;
PersuasionDialog mPersuasionDialog;

View file

@ -121,10 +121,18 @@ void DragAndDrop::drop(ItemModel *targetModel, ItemView *targetView)
mSourceView->update();
}
void DragAndDrop::onFrame()
{
if (mIsOnDragAndDrop && mItem.mBase.getRefData().getCount() == 0)
finish();
}
void DragAndDrop::finish()
{
mIsOnDragAndDrop = false;
mSourceSortModel->clearDragItems();
// since mSourceView doesn't get updated in drag()
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
MyGUI::Gui::getInstance().destroyWidget(mDraggedWidget);
mDraggedWidget = 0;

View file

@ -29,6 +29,7 @@ namespace MWGui
void startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count);
void drop (ItemModel* targetModel, ItemView* targetView);
void onFrame();
void finish();
};

View file

@ -4,11 +4,11 @@
#include <MyGUI_Button.h>
#include <MyGUI_ScrollView.h>
#include <MyGUI_EditBox.h>
#include <components/widgets/list.hpp>
#include <components/settings/settings.hpp>
#include "../mwbase/dialoguemanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
@ -53,6 +53,7 @@ namespace MWGui
mSoulBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectSoul);
mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onBuyButtonClicked);
mTypeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onTypeButtonClicked);
mName->eventEditSelectAccept += MyGUI::newDelegate(this, &EnchantingDialog::onAccept);
}
EnchantingDialog::~EnchantingDialog()
@ -60,9 +61,10 @@ namespace MWGui
delete mItemSelectionDialog;
}
void EnchantingDialog::open()
void EnchantingDialog::onOpen()
{
center();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mName);
}
void EnchantingDialog::setSoulGem(const MWWorld::Ptr &gem)
@ -100,11 +102,6 @@ namespace MWGui
}
}
void EnchantingDialog::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
}
void EnchantingDialog::updateLabels()
{
std::stringstream enchantCost;
@ -143,57 +140,41 @@ namespace MWGui
}
}
void EnchantingDialog::startEnchanting (MWWorld::Ptr actor)
void EnchantingDialog::setPtr (const MWWorld::Ptr& ptr)
{
mName->setCaption("");
mEnchanting.setSelfEnchanting(false);
mEnchanting.setEnchanter(actor);
if (ptr.getClass().isActor())
{
mEnchanting.setSelfEnchanting(false);
mEnchanting.setEnchanter(ptr);
mBuyButton->setCaptionWithReplacing("#{sBuy}");
mChanceLayout->setVisible(false);
mPtr = ptr;
setSoulGem(MWWorld::Ptr());
mPrice->setVisible(true);
mPriceText->setVisible(true);
}
else
{
mEnchanting.setSelfEnchanting(true);
mEnchanting.setEnchanter(MWMechanics::getPlayer());
mBuyButton->setCaptionWithReplacing("#{sCreate}");
bool enabled = Settings::Manager::getBool("show enchant chance","Game");
mChanceLayout->setVisible(enabled);
mPtr = MWMechanics::getPlayer();
setSoulGem(ptr);
mPrice->setVisible(false);
mPriceText->setVisible(false);
}
mBuyButton->setCaptionWithReplacing("#{sBuy}");
mChanceLayout->setVisible(false);
mPtr = actor;
setSoulGem(MWWorld::Ptr());
setItem(MWWorld::Ptr());
startEditing ();
mPrice->setVisible(true);
mPriceText->setVisible(true);
updateLabels();
}
void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem)
{
mName->setCaption("");
MWWorld::Ptr player = MWMechanics::getPlayer();
mEnchanting.setSelfEnchanting(true);
mEnchanting.setEnchanter(player);
mBuyButton->setCaptionWithReplacing("#{sCreate}");
bool enabled = Settings::Manager::getBool("show enchant chance","Game");
mChanceLayout->setVisible(enabled);
mPtr = player;
startEditing();
setSoulGem(soulgem);
setItem(MWWorld::Ptr());
mPrice->setVisible(false);
mPriceText->setVisible(false);
updateLabels();
}
void EnchantingDialog::onReferenceUnavailable ()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Dialogue);
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
resetReference();
}
@ -209,7 +190,7 @@ namespace MWGui
void EnchantingDialog::onCancelButtonClicked(MyGUI::Widget* sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Enchanting);
}
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
@ -304,6 +285,11 @@ namespace MWGui
updateEffectsView();
}
void EnchantingDialog::onAccept(MyGUI::EditBox *sender)
{
onBuyButtonClicked(sender);
}
void EnchantingDialog::onBuyButtonClicked(MyGUI::Widget* sender)
{
if (mEffects.size() <= 0)
@ -364,7 +350,7 @@ namespace MWGui
MWBase::Environment::get().getMechanicsManager()->confiscateStolenItemToOwner(player, item, mPtr, 1);
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
return;
}
}

View file

@ -19,15 +19,17 @@ namespace MWGui
EnchantingDialog();
virtual ~EnchantingDialog();
virtual void open();
virtual void onOpen();
virtual void exit();
void onFrame(float dt) { checkReferenceAvailable(); }
void clear() { resetReference(); }
void setSoulGem (const MWWorld::Ptr& gem);
void setItem (const MWWorld::Ptr& item);
void startEnchanting(MWWorld::Ptr actor);
void startSelfEnchanting(MWWorld::Ptr soulgem);
/// Actor Ptr: buy enchantment from this actor
/// Soulgem Ptr: player self-enchant
void setPtr(const MWWorld::Ptr& ptr);
virtual void resetReference();
@ -46,6 +48,7 @@ namespace MWGui
void onBuyButtonClicked(MyGUI::Widget* sender);
void updateLabels();
void onTypeButtonClicked(MyGUI::Widget* sender);
void onAccept(MyGUI::EditBox* sender);
ItemSelectionDialog* mItemSelectionDialog;
@ -58,7 +61,7 @@ namespace MWGui
MyGUI::Button* mTypeButton;
MyGUI::Button* mBuyButton;
MyGUI::TextBox* mName;
MyGUI::EditBox* mName;
MyGUI::TextBox* mEnchantmentPoints;
MyGUI::TextBox* mCastCost;
MyGUI::TextBox* mCharge;

View file

@ -406,10 +406,11 @@ namespace MWGui
MyGUI::EditBox* box = parent->createWidget<MyGUI::EditBox>("NormalText",
MyGUI::IntCoord(0, pag.getCurrentTop(), pag.getPageWidth(), 0), MyGUI::Align::Left | MyGUI::Align::Top,
parent->getName() + MyGUI::utility::toString(parent->getChildCount()));
box->setProperty("Static", "true");
box->setProperty("MultiLine", "true");
box->setProperty("WordWrap", "true");
box->setProperty("NeedMouse", "false");
box->setEditStatic(true);
box->setEditMultiLine(true);
box->setEditWordWrap(true);
box->setNeedMouseFocus(false);
box->setNeedKeyFocus(false);
box->setMaxTextLength(text.size());
box->setTextAlign(mBlockStyle.mAlign);
box->setTextColour(mTextStyle.mColour);

View file

@ -68,7 +68,7 @@ namespace MWGui
HUD::HUD(CustomMarkerCollection &customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender)
: Layout("openmw_hud.layout")
: WindowBase("openmw_hud.layout")
, LocalMapBase(customMarkers, localMapRender, Settings::Manager::getBool("local map hud fog of war", "Map"))
, mHealth(NULL)
, mMagicka(NULL)
@ -371,6 +371,20 @@ namespace MWGui
if (mIsDrowning)
mDrowningFlashTheta += dt * osg::PI*2;
mSpellIcons->updateWidgets(mEffectBox, true);
if (mEnemyActorId != -1 && mEnemyHealth->getVisible())
{
updateEnemyHealthBar();
}
if (mIsDrowning)
{
float intensity = (cos(mDrowningFlashTheta) + 2.0f) / 3.0f;
mDrowningFlash->setAlpha(intensity);
}
}
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
@ -602,23 +616,6 @@ namespace MWGui
}
void HUD::update()
{
mSpellIcons->updateWidgets(mEffectBox, true);
if (mEnemyActorId != -1 && mEnemyHealth->getVisible())
{
updateEnemyHealthBar();
}
if (mIsDrowning)
{
float intensity = (cos(mDrowningFlashTheta) + 2.0f) / 3.0f;
mDrowningFlash->setAlpha(intensity);
}
}
void HUD::setEnemy(const MWWorld::Ptr &enemy)
{
mEnemyActorId = enemy.getClass().getCreatureStats(enemy).getActorId();
@ -635,6 +632,13 @@ namespace MWGui
mEnemyHealthTimer = -1;
}
void HUD::clear()
{
unsetSelectedSpell();
unsetSelectedWeapon();
resetEnemy();
}
void HUD::customMarkerCreated(MyGUI::Widget *marker)
{
marker->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);

View file

@ -16,7 +16,7 @@ namespace MWGui
class SpellIcons;
class ItemWidget;
class HUD : public Layout, public LocalMapBase
class HUD : public WindowBase, public LocalMapBase
{
public:
HUD(CustomMarkerCollection& customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender);
@ -55,11 +55,11 @@ namespace MWGui
MyGUI::Widget* getEffectBox() { return mEffectBox; }
void update();
void setEnemy(const MWWorld::Ptr& enemy);
void resetEnemy();
void clear();
private:
MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning;
MyGUI::Widget* mHealthFrame;

View file

@ -1,5 +1,10 @@
#include "inventoryitemmodel.hpp"
#include <sstream>
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
@ -45,16 +50,33 @@ MWWorld::Ptr InventoryItemModel::copyItem (const ItemStack& item, size_t count,
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, mActor, setNewOwner);
}
void InventoryItemModel::removeItem (const ItemStack& item, size_t count)
{
MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor);
int removed = store.remove(item.mBase, count, mActor);
int removed = 0;
// Re-equipping makes sense only if a target has inventory
if (mActor.getClass().hasInventoryStore(mActor))
{
MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor);
removed = store.remove(item.mBase, count, mActor, true);
}
else
{
MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor);
removed = store.remove(item.mBase, count, mActor);
}
std::stringstream error;
if (removed == 0)
throw std::runtime_error("Item to remove not found in container store");
{
error << "Item '" << item.mBase.getCellRef().getRefId() << "' was not found in container store to remove";
throw std::runtime_error(error.str());
}
else if (removed < static_cast<int>(count))
throw std::runtime_error("Not enough items in the stack to remove");
{
error << "Not enough items '" << item.mBase.getCellRef().getRefId() << "' in the stack to remove (" << static_cast<int>(count) << " requested, " << removed << " found)";
throw std::runtime_error(error.str());
}
}
MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, ItemModel *otherModel)

View file

@ -363,7 +363,7 @@ namespace MWGui
dirtyPreview();
}
void InventoryWindow::open()
void InventoryWindow::onOpen()
{
if (!mPtr.isEmpty())
{
@ -589,11 +589,8 @@ namespace MWGui
mEncumbranceBar->setValue(static_cast<int>(encumbrance), static_cast<int>(capacity));
}
void InventoryWindow::onFrame()
void InventoryWindow::onFrame(float dt)
{
if (!mMainWidget->getVisible())
return;
updateEncumbranceBar();
}
@ -717,7 +714,9 @@ namespace MWGui
lastId = item.getCellRef().getRefId();
if (item.getClass().getTypeName() == typeid(ESM::Weapon).name() && isRightHandWeapon(item))
if (item.getClass().getTypeName() == typeid(ESM::Weapon).name() &&
isRightHandWeapon(item) &&
item.getClass().canBeEquipped(item, player).first)
{
found = true;
break;

View file

@ -35,12 +35,12 @@ namespace MWGui
public:
InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem);
virtual void open();
virtual void onOpen();
/// start trading, disables item drag&drop
void setTrading(bool trading);
void onFrame();
void onFrame(float dt);
void pickUpObject (MWWorld::Ptr object);

View file

@ -29,9 +29,10 @@ namespace MWGui
center();
}
void ItemSelectionDialog::exit()
bool ItemSelectionDialog::exit()
{
eventDialogCanceled();
return true;
}
void ItemSelectionDialog::openContainer(const MWWorld::Ptr& container)

View file

@ -21,7 +21,7 @@ namespace MWGui
public:
ItemSelectionDialog(const std::string& label);
virtual void exit();
virtual bool exit();
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item;

View file

@ -26,8 +26,6 @@ namespace MWGui
{
getWidget(mProgressBar, "ProgressBar");
setVisible(false);
mTimeAdvancer.eventProgressChanged += MyGUI::newDelegate(this, &JailScreen::onJailProgressChanged);
mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &JailScreen::onJailFinished);

View file

@ -14,6 +14,8 @@ namespace MWGui
void onFrame(float dt);
bool exit() { return false; }
private:
int mDays;

View file

@ -8,6 +8,7 @@
#include <MyGUI_TextBox.h>
#include <MyGUI_Button.h>
#include <MyGUI_InputManager.h>
#include <components/misc/stringops.hpp>
#include <components/widgets/imagebutton.hpp>
@ -44,7 +45,7 @@ namespace
static char const LeftTopicIndex [] = "LeftTopicIndex";
static char const RightTopicIndex [] = "RightTopicIndex";
struct JournalWindowImpl : MWGui::WindowBase, MWGui::JournalBooks, MWGui::JournalWindow
struct JournalWindowImpl : MWGui::JournalBooks, MWGui::JournalWindow
{
struct DisplayState
{
@ -84,19 +85,24 @@ namespace
void adviseButtonClick (char const * name, void (JournalWindowImpl::*Handler) (MyGUI::Widget* _sender))
{
getWidget <Gui::ImageButton> (name) ->
getWidget <MyGUI::Widget> (name) ->
eventMouseButtonClick += newDelegate(this, Handler);
}
void adviseKeyPress (char const * name, void (JournalWindowImpl::*Handler) (MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char character))
{
getWidget <MyGUI::Widget> (name) ->
eventKeyButtonPressed += newDelegate(this, Handler);
}
MWGui::BookPage* getPage (char const * name)
{
return getWidget <MWGui::BookPage> (name);
}
JournalWindowImpl (MWGui::JournalViewModel::Ptr Model, bool questList)
: WindowBase("openmw_journal.layout"), JournalBooks (Model)
: JournalBooks (Model), JournalWindow()
{
mMainWidget->setVisible(false);
center();
adviseButtonClick (OptionsBTN, &JournalWindowImpl::notifyOptions );
@ -112,6 +118,12 @@ namespace
adviseButtonClick (ShowAllBTN, &JournalWindowImpl::notifyShowAll );
adviseButtonClick (ShowActiveBTN, &JournalWindowImpl::notifyShowActive);
adviseKeyPress (OptionsBTN, &JournalWindowImpl::notifyKeyPress);
adviseKeyPress (PrevPageBTN, &JournalWindowImpl::notifyKeyPress);
adviseKeyPress (NextPageBTN, &JournalWindowImpl::notifyKeyPress);
adviseKeyPress (CloseBTN, &JournalWindowImpl::notifyKeyPress);
adviseKeyPress (JournalBTN, &JournalWindowImpl::notifyKeyPress);
Gui::MWList* list = getWidget<Gui::MWList>(QuestsList);
list->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyQuestClicked);
@ -211,7 +223,7 @@ namespace
button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0));
}
void open()
void onOpen()
{
if (!MWBase::Environment::get().getWindowManager ()->getJournalAllowed ())
{
@ -238,9 +250,11 @@ namespace
--page;
}
updateShowingPages();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(getWidget<MyGUI::Widget>(CloseBTN));
}
void close()
void onClose()
{
mModel->unload ();
@ -349,8 +363,19 @@ namespace
relPages = 0;
}
setVisible (PrevPageBTN, page > 0);
setVisible (NextPageBTN, relPages > 2);
MyGUI::Widget* nextPageBtn = getWidget<MyGUI::Widget>(NextPageBTN);
MyGUI::Widget* prevPageBtn = getWidget<MyGUI::Widget>(PrevPageBTN);
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
bool nextPageVisible = relPages > 2;
nextPageBtn->setVisible(nextPageVisible);
bool prevPageVisible = page > 0;
prevPageBtn->setVisible(prevPageVisible);
if (focus == nextPageBtn && !nextPageVisible && prevPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(prevPageBtn);
else if (focus == prevPageBtn && !prevPageVisible && nextPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nextPageBtn);
setVisible (PageOneNum, relPages > 0);
setVisible (PageTwoNum, relPages > 1);
@ -362,6 +387,14 @@ namespace
setText (PageTwoNum, page + 2);
}
void notifyKeyPress(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character)
{
if (key == MyGUI::KeyCode::ArrowUp)
notifyPrevPage(sender);
else if (key == MyGUI::KeyCode::ArrowDown)
notifyNextPage(sender);
}
void notifyTopicClicked (intptr_t linkId)
{
Book topicBook = createTopicBook (linkId);
@ -603,3 +636,9 @@ MWGui::JournalWindow * MWGui::JournalWindow::create (JournalViewModel::Ptr Model
{
return new JournalWindowImpl (Model, questList);
}
MWGui::JournalWindow::JournalWindow()
:WindowBase("openmw_journal.layout")
{
}

View file

@ -1,6 +1,8 @@
#ifndef MWGUI_JOURNAL_H
#define MWGUI_JOURNAL_H
#include "windowbase.hpp"
#include <memory>
namespace MWBase { class WindowManager; }
@ -9,8 +11,10 @@ namespace MWGui
{
struct JournalViewModel;
struct JournalWindow
struct JournalWindow : public WindowBase
{
JournalWindow();
/// construct a new instance of the one JournalWindow implementation
static JournalWindow * create (std::shared_ptr <JournalViewModel> Model, bool questList);

View file

@ -0,0 +1,283 @@
#include "keyboardnavigation.hpp"
#include <MyGUI_InputManager.h>
#include <MyGUI_WidgetManager.h>
#include <MyGUI_Button.h>
#include <MyGUI_Gui.h>
#include <MyGUI_Window.h>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
namespace MWGui
{
/// Recursively get all child widgets that accept keyboard input
void getKeyFocusWidgets(MyGUI::Widget* parent, std::vector<MyGUI::Widget*>& results)
{
if (!parent->getVisible() || !parent->getEnabled())
return;
MyGUI::EnumeratorWidgetPtr enumerator = parent->getEnumerator();
while (enumerator.next())
{
MyGUI::Widget* w = enumerator.current();
if (!w->getVisible() || !w->getEnabled())
continue;
if (w->getNeedKeyFocus())
results.push_back(w);
else
getKeyFocusWidgets(w, results);
}
}
bool shouldAcceptKeyFocus(MyGUI::Widget* w)
{
return w && !w->castType<MyGUI::Window>(false) && w->getInheritedEnabled() && w->getInheritedVisible() && w->getVisible() && w->getEnabled();
}
KeyboardNavigation::KeyboardNavigation()
: mCurrentFocus(nullptr)
, mModalWindow(nullptr)
{
MyGUI::WidgetManager::getInstance().registerUnlinker(this);
}
KeyboardNavigation::~KeyboardNavigation()
{
MyGUI::WidgetManager::getInstance().unregisterUnlinker(this);
}
void KeyboardNavigation::saveFocus(int mode)
{
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (shouldAcceptKeyFocus(focus))
{
mKeyFocus[mode] = focus;
}
else
{
mKeyFocus[mode] = mCurrentFocus;
}
}
void KeyboardNavigation::restoreFocus(int mode)
{
std::map<int, MyGUI::Widget*>::const_iterator found = mKeyFocus.find(mode);
if (found != mKeyFocus.end())
{
MyGUI::Widget* w = found->second;
if (w && w->getVisible() && w->getEnabled())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(found->second);
}
}
void KeyboardNavigation::_unlinkWidget(MyGUI::Widget *widget)
{
for (std::pair<const int, MyGUI::Widget*>& w : mKeyFocus)
if (w.second == widget)
w.second = nullptr;
if (widget == mCurrentFocus)
mCurrentFocus = nullptr;
}
void styleFocusedButton(MyGUI::Widget* w)
{
if (w)
{
if (MyGUI::Button* b = w->castType<MyGUI::Button>(false))
{
b->_setWidgetState("highlighted");
}
}
}
bool isRootParent(MyGUI::Widget* widget, MyGUI::Widget* root)
{
while (widget && widget->getParent())
widget = widget->getParent();
return widget == root;
}
void KeyboardNavigation::onFrame()
{
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (focus == mCurrentFocus)
{
styleFocusedButton(mCurrentFocus);
return;
}
// workaround incorrect key focus resets (fix in MyGUI TBD)
if (!shouldAcceptKeyFocus(focus) && shouldAcceptKeyFocus(mCurrentFocus) && (!mModalWindow || isRootParent(mCurrentFocus, mModalWindow)))
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCurrentFocus);
focus = mCurrentFocus;
}
// style highlighted button (won't be needed for MyGUI 3.2.3)
if (focus != mCurrentFocus)
{
if (mCurrentFocus)
{
if (MyGUI::Button* b = mCurrentFocus->castType<MyGUI::Button>(false))
b->_setWidgetState("normal");
}
mCurrentFocus = focus;
}
styleFocusedButton(mCurrentFocus);
}
void KeyboardNavigation::setDefaultFocus(MyGUI::Widget *window, MyGUI::Widget *defaultFocus)
{
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (!focus || !shouldAcceptKeyFocus(focus))
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus);
}
else
{
if (!isRootParent(focus, window))
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus);
}
}
void KeyboardNavigation::setModalWindow(MyGUI::Widget *window)
{
mModalWindow = window;
}
enum Direction
{
D_Left,
D_Up,
D_Right,
D_Down,
D_Next,
D_Prev
};
bool KeyboardNavigation::injectKeyPress(MyGUI::KeyCode key, unsigned int text)
{
switch (key.getValue())
{
case MyGUI::KeyCode::ArrowLeft:
return switchFocus(D_Left, false);
case MyGUI::KeyCode::ArrowRight:
return switchFocus(D_Right, false);
case MyGUI::KeyCode::ArrowUp:
return switchFocus(D_Up, false);
case MyGUI::KeyCode::ArrowDown:
return switchFocus(D_Down, false);
case MyGUI::KeyCode::Tab:
return switchFocus(MyGUI::InputManager::getInstance().isShiftPressed() ? D_Prev : D_Next, true);
case MyGUI::KeyCode::Return:
case MyGUI::KeyCode::NumpadEnter:
case MyGUI::KeyCode::Space:
return accept();
default:
return false;
}
}
bool KeyboardNavigation::switchFocus(int direction, bool wrap)
{
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
bool isCycle = (direction == D_Prev || direction == D_Next);
if ((focus && focus->getTypeName().find("Button") == std::string::npos) && !isCycle)
return false;
if (focus && isCycle && focus->getUserString("AcceptTab") == "true")
return false;
if ((!focus || !focus->getNeedKeyFocus()) && isCycle)
{
// if nothing is selected, select the first widget
return selectFirstWidget();
}
if (!focus)
return false;
MyGUI::Widget* window = focus;
while (window && window->getParent())
window = window->getParent();
MyGUI::VectorWidgetPtr keyFocusList;
getKeyFocusWidgets(window, keyFocusList);
if (keyFocusList.empty())
return false;
MyGUI::VectorWidgetPtr::iterator found = std::find(keyFocusList.begin(), keyFocusList.end(), focus);
if (found == keyFocusList.end())
{
if (isCycle)
return selectFirstWidget();
else
return false;
}
bool forward = (direction == D_Next || direction == D_Right || direction == D_Down);
int index = found - keyFocusList.begin();
index = forward ? (index+1) : (index-1);
if (wrap)
index = (index + keyFocusList.size())%keyFocusList.size();
else
index = std::min(std::max(0, index), static_cast<int>(keyFocusList.size())-1);
MyGUI::Widget* next = keyFocusList[index];
int vertdiff = next->getTop() - focus->getTop();
int horizdiff = next->getLeft() - focus->getLeft();
bool isVertical = std::abs(vertdiff) > std::abs(horizdiff);
if (direction == D_Right && (horizdiff <= 0 || isVertical))
return false;
else if (direction == D_Left && (horizdiff >= 0 || isVertical))
return false;
else if (direction == D_Down && (vertdiff <= 0 || !isVertical))
return false;
else if (direction == D_Up && (vertdiff >= 0 || !isVertical))
return false;
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[index]);
return true;
}
bool KeyboardNavigation::selectFirstWidget()
{
MyGUI::VectorWidgetPtr keyFocusList;
MyGUI::EnumeratorWidgetPtr enumerator = MyGUI::Gui::getInstance().getEnumerator();
if (mModalWindow)
enumerator = mModalWindow->getEnumerator();
while (enumerator.next())
getKeyFocusWidgets(enumerator.current(), keyFocusList);
if (!keyFocusList.empty())
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[0]);
return true;
}
return false;
}
bool KeyboardNavigation::accept()
{
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (!focus)
return false;
//MyGUI::Button* button = focus->castType<MyGUI::Button>(false);
//if (button && button->getEnabled())
if (focus->getTypeName().find("Button") != std::string::npos && focus->getEnabled())
{
focus->eventMouseButtonClick(focus);
return true;
}
return false;
}
}

View file

@ -0,0 +1,47 @@
#ifndef OPENMW_MWGUI_KEYBOARDNAVIGATION_H
#define OPENMW_MWGUI_KEYBOARDNAVIGATION_H
#include <MyGUI_KeyCode.h>
#include <MyGUI_IUnlinkWidget.h>
namespace MWGui
{
class KeyboardNavigation : public MyGUI::IUnlinkWidget
{
public:
KeyboardNavigation();
~KeyboardNavigation();
/// @return Was the key handled by this class?
bool injectKeyPress(MyGUI::KeyCode key, unsigned int text);
void saveFocus(int mode);
void restoreFocus(int mode);
void _unlinkWidget(MyGUI::Widget* widget);
void onFrame();
/// Set a key focus widget for this window, if one isn't already set.
void setDefaultFocus(MyGUI::Widget* window, MyGUI::Widget* defaultFocus);
void setModalWindow(MyGUI::Widget* window);
private:
bool switchFocus(int direction, bool wrap);
bool selectFirstWidget();
/// Send button press event to focused button
bool accept();
std::map<int, MyGUI::Widget*> mKeyFocus;
MyGUI::Widget* mCurrentFocus;
MyGUI::Widget* mModalWindow;
};
}
#endif

View file

@ -41,6 +41,7 @@ namespace MWGui
{
MyGUI::TextBox* t;
getWidget(t, "AttribVal" + MyGUI::utility::toString(i));
mAttributeValues.push_back(t);
MyGUI::Button* b;
getWidget(b, "Attrib" + MyGUI::utility::toString(i));
@ -48,10 +49,7 @@ namespace MWGui
b->eventMouseButtonClick += MyGUI::newDelegate(this, &LevelupDialog::onAttributeClicked);
mAttributes.push_back(b);
mAttributeValues.push_back(t);
getWidget(t, "AttribMultiplier" + MyGUI::utility::toString(i));
mAttributeMultipliers.push_back(t);
}
@ -128,7 +126,7 @@ namespace MWGui
setAttributeValues();
}
void LevelupDialog::open()
void LevelupDialog::onOpen()
{
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayerPtr();

View file

@ -11,7 +11,7 @@ namespace MWGui
public:
LevelupDialog();
virtual void open();
virtual void onOpen();
private:
MyGUI::Button* mOkButton;

View file

@ -51,8 +51,6 @@ namespace MWGui
mBackgroundImage = MyGUI::Gui::getInstance().createWidgetReal<BackgroundImage>("ImageBox", 0,0,1,1,
MyGUI::Align::Stretch, "Menu");
setVisible(false);
findSplashScreens();
}
@ -66,15 +64,27 @@ namespace MWGui
std::string pattern = "Splash/";
mVFS->normalizeFilename(pattern);
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
/* priority given to the left */
std::list<std::string> supported_extensions = {".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"};
auto found = index.lower_bound(pattern);
while (found != index.end())
{
const std::string& name = found->first;
if (name.size() >= pattern.size() && name.substr(0, pattern.size()) == pattern)
{
size_t pos = name.find_last_of('.');
if (pos != std::string::npos && name.compare(pos, name.size()-pos, ".tga") == 0)
mSplashScreens.push_back(found->first);
if (pos != std::string::npos)
{
for(auto const extension: supported_extensions)
{
if (name.compare(pos, name.size() - pos, extension) == 0)
{
mSplashScreens.push_back(found->first);
break; /* based on priority */
}
}
}
}
else
break;

View file

@ -22,7 +22,7 @@ namespace MWGui
{
MainMenu::MainMenu(int w, int h, const VFS::Manager* vfs, const std::string& versionDescription)
: Layout("openmw_mainmenu.layout")
: WindowBase("openmw_mainmenu.layout")
, mWidth (w), mHeight (h)
, mVFS(vfs), mButtonBox(0)
, mBackground(NULL)
@ -56,15 +56,31 @@ namespace MWGui
if (visible)
updateMenu();
showBackground(
MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) &&
MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame);
bool isMainMenu =
MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) &&
MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame;
showBackground(isMainMenu);
if (visible)
{
if (isMainMenu)
{
if (mButtons["loadgame"]->getVisible())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["loadgame"]);
else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["newgame"]);
}
else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["return"]);
}
Layout::setVisible (visible);
}
void MainMenu::onNewGameConfirmed()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu);
MWBase::Environment::get().getStateManager()->newGame();
}
@ -182,7 +198,7 @@ namespace MWGui
}
}
void MainMenu::update(float dt)
void MainMenu::onFrame(float dt)
{
if (mVideo)
{
@ -231,7 +247,8 @@ namespace MWGui
buttons.push_back("exitgame");
// Create new buttons if needed
for (std::vector<std::string>::iterator it = buttons.begin(); it != buttons.end(); ++it)
std::vector<std::string> allButtons { "return", "newgame", "savegame", "loadgame", "options", "credits", "exitgame"};
for (std::vector<std::string>::iterator it = allButtons.begin(); it != allButtons.end(); ++it)
{
if (mButtons.find(*it) == mButtons.end())
{

View file

@ -1,7 +1,7 @@
#ifndef OPENMW_GAME_MWGUI_MAINMENU_H
#define OPENMW_GAME_MWGUI_MAINMENU_H
#include "layout.hpp"
#include "windowbase.hpp"
namespace Gui
{
@ -20,7 +20,7 @@ namespace MWGui
class SaveGameDialog;
class VideoWidget;
class MainMenu : public Layout
class MainMenu : public WindowBase
{
int mWidth;
int mHeight;
@ -36,7 +36,7 @@ namespace MWGui
virtual void setVisible (bool visible);
void update(float dt);
void onFrame(float dt);
private:
const VFS::Manager* mVFS;

View file

@ -701,7 +701,7 @@ namespace MWGui
void MapWindow::onNoteEditDelete()
{
ConfirmationDialog* confirmation = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
confirmation->askForConfirmation("#{sDeleteNote}", "#{sYes}", "#{sNo}");
confirmation->askForConfirmation("#{sDeleteNote}");
confirmation->eventCancelClicked.clear();
confirmation->eventOkClicked.clear();
confirmation->eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditDeleteConfirm);
@ -943,7 +943,7 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Map);
}
void MapWindow::open()
void MapWindow::onOpen()
{
ensureGlobalMapLoaded();
@ -1002,6 +1002,9 @@ namespace MWGui
mGlobalMapOverlayTexture.reset(new osgMyGUI::OSGTexture(mGlobalMapRender->getOverlayTexture()));
mGlobalMapOverlay->setRenderItemTexture(mGlobalMapOverlayTexture.get());
mGlobalMapOverlay->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f));
// Redraw children in proper order
mGlobalMap->getParent()->_updateChilds();
}
}
@ -1104,18 +1107,13 @@ namespace MWGui
return MyGUI::TextIterator::getOnlyText(mTextEdit->getCaption());
}
void EditNoteDialog::open()
void EditNoteDialog::onOpen()
{
WindowModal::open();
WindowModal::onOpen();
center();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
}
void EditNoteDialog::exit()
{
setVisible(false);
}
void EditNoteDialog::onCancelButtonClicked(MyGUI::Widget *sender)
{
setVisible(false);

View file

@ -169,8 +169,7 @@ namespace MWGui
public:
EditNoteDialog();
virtual void open();
virtual void exit();
virtual void onOpen();
void showDeleteButton(bool show);
bool getDeleteButtonShown();
@ -218,7 +217,7 @@ namespace MWGui
void ensureGlobalMapLoaded();
virtual void open();
virtual void onOpen();
void onFrame(float dt);

View file

@ -32,7 +32,7 @@ MerchantRepair::MerchantRepair()
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onOkButtonClick);
}
void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
void MerchantRepair::setPtr(const MWWorld::Ptr &actor)
{
mActor = actor;
@ -111,18 +111,13 @@ void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
mList->setViewOffset(MyGUI::IntPoint(0, static_cast<int>(mList->getViewOffset().top + _rel*0.3f)));
}
void MerchantRepair::open()
void MerchantRepair::onOpen()
{
center();
// Reset scrollbars
mList->setViewOffset(MyGUI::IntPoint(0, 0));
}
void MerchantRepair::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_MerchantRepair);
}
void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
{
MWWorld::Ptr player = MWMechanics::getPlayer();
@ -145,12 +140,12 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
MWMechanics::CreatureStats& actorStats = mActor.getClass().getCreatureStats(mActor);
actorStats.setGoldPool(actorStats.getGoldPool() + price);
startRepair(mActor);
setPtr(mActor);
}
void MerchantRepair::onOkButtonClick(MyGUI::Widget *sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_MerchantRepair);
}
}

View file

@ -12,11 +12,9 @@ class MerchantRepair : public WindowBase
public:
MerchantRepair();
virtual void open();
virtual void onOpen();
virtual void exit();
void startRepair(const MWWorld::Ptr& actor);
void setPtr(const MWWorld::Ptr& actor);
private:
MyGUI::ScrollView* mList;

View file

@ -36,8 +36,13 @@ namespace MWGui
void MessageBoxManager::clear()
{
delete mInterMessageBoxe;
mInterMessageBoxe = NULL;
if (mInterMessageBoxe)
{
mInterMessageBoxe->setVisible(false);
delete mInterMessageBoxe;
mInterMessageBoxe = NULL;
}
std::vector<MessageBox*>::iterator it(mMessageBoxes.begin());
for (; it != mMessageBoxes.end(); ++it)
@ -77,6 +82,7 @@ namespace MWGui
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
mLastButtonPressed = mInterMessageBoxe->readPressedButton();
mInterMessageBoxe->setVisible(false);
delete mInterMessageBoxe;
mInterMessageBoxe = NULL;
MWBase::Environment::get().getInputManager()->changeInputMode(
@ -200,13 +206,14 @@ namespace MWGui
, mMessageBoxManager(parMessageBoxManager)
, mButtonPressed(-1)
{
WindowModal::open();
setVisible(true);
int textPadding = 10; // padding between text-widget and main-widget
int textButtonPadding = 10; // padding between the text-widget und the button-widget
int buttonLeftPadding = 10; // padding between the buttons if horizontal
int buttonTopPadding = 10; // ^-- if vertical
int buttonPadding = 5; // padding between button label and button itself
int buttonLabelLeftPadding = 12; // padding between button label and button itself, from left
int buttonLabelTopPadding = 4; // padding between button label and button itself, from top
int buttonMainPadding = 10; // padding between buttons and bottom of the main widget
mMarkedToDelete = false;
@ -228,8 +235,7 @@ namespace MWGui
int buttonHeight = 0;
MyGUI::IntCoord dummyCoord(0, 0, 0, 0);
std::vector<std::string>::const_iterator it;
for(it = buttons.begin(); it != buttons.end(); ++it)
for(std::vector<std::string>::const_iterator it = buttons.begin(); it != buttons.end(); ++it)
{
MyGUI::Button* button = mButtonsWidget->createWidget<MyGUI::Button>(
MyGUI::WidgetStyle::Child,
@ -245,10 +251,10 @@ namespace MWGui
if (buttonsWidth != 0)
buttonsWidth += buttonLeftPadding;
int buttonWidth = button->getTextSize().width + 2*buttonPadding;
int buttonWidth = button->getTextSize().width + 2*buttonLabelLeftPadding;
buttonsWidth += buttonWidth;
buttonHeight = button->getTextSize().height + 2*buttonPadding;
buttonHeight = button->getTextSize().height + 2*buttonLabelTopPadding;
if (buttonsHeight != 0)
buttonsHeight += buttonTopPadding;
@ -289,14 +295,13 @@ namespace MWGui
MyGUI::IntSize buttonSize(0, buttonHeight);
int left = (mainWidgetSize.width - buttonsWidth)/2;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
for(std::vector<MyGUI::Button*>::const_iterator button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonCord.left = left;
buttonCord.top = messageWidgetCoord.top + textSize.height + textButtonPadding;
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
buttonSize.width = (*button)->getTextSize().width + 2*buttonLabelLeftPadding;
buttonSize.height = (*button)->getTextSize().height + 2*buttonLabelTopPadding;
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
@ -319,11 +324,10 @@ namespace MWGui
int top = textPadding + textSize.height + textButtonPadding;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
for(std::vector<MyGUI::Button*>::const_iterator button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
buttonSize.width = (*button)->getTextSize().width + buttonLabelLeftPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonLabelTopPadding*2;
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2;
@ -354,25 +358,20 @@ namespace MWGui
}
// Set key focus to "Ok" button
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
std::vector<std::string> keywords { "sOk", "sYes" };
for(std::vector<MyGUI::Button*>::const_iterator button = mButtons.begin(); button != mButtons.end(); ++button)
{
if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok))
for (const std::string& keyword : keywords)
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(*button);
(*button)->eventKeyButtonPressed += MyGUI::newDelegate(this, &InteractiveMessageBox::onKeyPressed);
break;
if(Misc::StringUtils::ciEqual(MyGUI::LanguageManager::getInstance().replaceTags("#{" + keyword + "}"), (*button)->getCaption()))
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(*button);
return;
}
}
}
}
void InteractiveMessageBox::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
{
if (_key == MyGUI::KeyCode::Return || _key == MyGUI::KeyCode::NumpadEnter || _key == MyGUI::KeyCode::Space)
buttonActivated(_sender);
}
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
{
buttonActivated (pressed);

View file

@ -77,11 +77,12 @@ namespace MWGui
void mousePressed (MyGUI::Widget* _widget);
int readPressedButton ();
virtual bool exit() { return false; }
bool mMarkedToDelete;
private:
void buttonActivated (MyGUI::Widget* _widget);
void onKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char);
MessageBoxManager& mMessageBoxManager;
MyGUI::EditBox* mMessageWidget;

View file

@ -23,7 +23,6 @@ namespace MWGui
GM_Dialogue, // NPC interaction
GM_Barter,
GM_Rest,
GM_RestBed,
GM_SpellBuying,
GM_Travel,
GM_SpellCreation,

View file

@ -64,11 +64,6 @@ namespace MWGui
}
}
void QuickKeysMenu::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_QuickKeysMenu);
}
void QuickKeysMenu::clear()
{
mActivatedIndex = -1;
@ -449,11 +444,6 @@ namespace MWGui
center();
}
void QuickKeysMenuAssign::exit()
{
setVisible(false);
}
void QuickKeysMenu::write(ESM::ESMWriter &writer)
{
writer.startRecord(ESM::REC_KEYS);
@ -585,14 +575,15 @@ namespace MWGui
exit();
}
void MagicSelectionDialog::exit()
bool MagicSelectionDialog::exit()
{
mParent->onAssignMagicCancel();
return true;
}
void MagicSelectionDialog::open ()
void MagicSelectionDialog::onOpen ()
{
WindowModal::open();
WindowModal::onOpen();
mMagicList->setModel(new SpellModel(MWMechanics::getPlayer()));
mMagicList->resetScrollbars();

View file

@ -22,7 +22,7 @@ namespace MWGui
QuickKeysMenu();
~QuickKeysMenu();
virtual void exit();
void onResChange(int, int) { center(); }
void onItemButtonClicked(MyGUI::Widget* sender);
void onMagicButtonClicked(MyGUI::Widget* sender);
@ -77,7 +77,6 @@ namespace MWGui
{
public:
QuickKeysMenuAssign(QuickKeysMenu* parent);
virtual void exit();
private:
MyGUI::TextBox* mLabel;
@ -94,8 +93,8 @@ namespace MWGui
public:
MagicSelectionDialog(QuickKeysMenu* parent);
virtual void open();
virtual void exit();
virtual void onOpen();
virtual bool exit();
private:
MyGUI::Button* mCancelButton;

View file

@ -120,9 +120,9 @@ namespace MWGui
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
void RaceDialog::open()
void RaceDialog::onOpen()
{
WindowModal::open();
WindowModal::onOpen();
updateRaces();
updateSkills();
@ -163,6 +163,8 @@ namespace MWGui
size_t initialPos = mHeadRotate->getScrollRange()/2+mHeadRotate->getScrollRange()/10;
mHeadRotate->setScrollPosition(initialPos);
onHeadRotate(mHeadRotate, initialPos);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mRaceList);
}
void RaceDialog::setRaceId(const std::string &raceId)
@ -183,8 +185,10 @@ namespace MWGui
updateSpellPowers();
}
void RaceDialog::close()
void RaceDialog::onClose()
{
WindowModal::onClose();
mPreviewImage->setRenderItemTexture(NULL);
mPreviewTexture.reset(NULL);

View file

@ -51,8 +51,10 @@ namespace MWGui
void setGender(Gender gender) { mGenderIndex = gender == GM_Male ? 0 : 1; }
void setNextButtonShow(bool shown);
virtual void open();
virtual void close();
virtual void onOpen();
virtual void onClose();
bool exit() { return false; }
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;

View file

@ -21,7 +21,6 @@
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "widgets.hpp"
#include "itemwidget.hpp"
#include "itemchargeview.hpp"
#include "sortfilteritemmodel.hpp"
@ -46,11 +45,9 @@ Recharge::Recharge()
mBox->setDisplayMode(ItemChargeView::DisplayMode_EnchantmentCharge);
mGemIcon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onSelectItem);
setVisible(false);
}
void Recharge::open()
void Recharge::onOpen()
{
center();
@ -62,12 +59,7 @@ void Recharge::open()
mBox->resetScrollbars();
}
void Recharge::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Recharge);
}
void Recharge::start (const MWWorld::Ptr &item)
void Recharge::setPtr (const MWWorld::Ptr &item)
{
mGemIcon->setItem(item);
mGemIcon->setUserString("ToolTipType", "ItemPtr");
@ -107,7 +99,7 @@ void Recharge::updateView()
void Recharge::onCancel(MyGUI::Widget *sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Recharge);
}
void Recharge::onSelectItem(MyGUI::Widget *sender)

View file

@ -22,11 +22,9 @@ class Recharge : public WindowBase
public:
Recharge();
virtual void open();
virtual void onOpen();
virtual void exit();
void start (const MWWorld::Ptr& gem);
void setPtr (const MWWorld::Ptr& gem);
protected:
ItemChargeView* mBox;

View file

@ -1,14 +1,8 @@
#include "referenceinterface.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwmechanics/actorutil.hpp"
namespace MWGui
{
ReferenceInterface::ReferenceInterface()
: mCurrentPlayerCell(NULL)
{
}
@ -18,8 +12,6 @@ namespace MWGui
void ReferenceInterface::checkReferenceAvailable()
{
MWWorld::CellStore* playerCell = MWMechanics::getPlayer().getCell();
// check if count of the reference has become 0
if (!mPtr.isEmpty() && mPtr.getRefData().getCount() == 0)
{
@ -29,7 +21,5 @@ namespace MWGui
onReferenceUnavailable();
}
}
mCurrentPlayerCell = playerCell;
}
}

View file

@ -17,15 +17,12 @@ namespace MWGui
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
virtual void resetReference() { mPtr = MWWorld::Ptr(); mCurrentPlayerCell = NULL; }
virtual void resetReference() { mPtr = MWWorld::Ptr(); }
protected:
virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable
MWWorld::Ptr mPtr;
private:
MWWorld::CellStore* mCurrentPlayerCell;
};
}

View file

@ -17,8 +17,6 @@
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "widgets.hpp"
#include "itemwidget.hpp"
#include "itemchargeview.hpp"
#include "sortfilteritemmodel.hpp"
@ -46,7 +44,7 @@ Repair::Repair()
mToolIcon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onSelectItem);
}
void Repair::open()
void Repair::onOpen()
{
center();
@ -58,12 +56,7 @@ void Repair::open()
mRepairBox->resetScrollbars();
}
void Repair::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Repair);
}
void Repair::startRepairItem(const MWWorld::Ptr &item)
void Repair::setPtr(const MWWorld::Ptr &item)
{
MWBase::Environment::get().getWindowManager()->playSound("Item Repair Up");
@ -145,7 +138,7 @@ void Repair::onItemCancel()
void Repair::onCancel(MyGUI::Widget* /*sender*/)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Repair);
}
void Repair::onRepairItem(MyGUI::Widget* /*sender*/, const MWWorld::Ptr& ptr)

View file

@ -19,11 +19,9 @@ class Repair : public WindowBase
public:
Repair();
virtual void open();
virtual void onOpen();
virtual void exit();
void startRepairItem (const MWWorld::Ptr& item);
void setPtr (const MWWorld::Ptr& item);
protected:
ItemChargeView* mRepairBox;

View file

@ -101,9 +101,9 @@ namespace MWGui
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
}
void ReviewDialog::open()
void ReviewDialog::onOpen()
{
WindowModal::open();
WindowModal::onOpen();
mUpdateSkillArea = true;
}

View file

@ -31,6 +31,8 @@ namespace MWGui
ReviewDialog();
bool exit() { return false; }
void setPlayerName(const std::string &name);
void setRace(const std::string &raceId);
void setClass(const ESM::Class& class_);
@ -45,7 +47,7 @@ namespace MWGui
void configureSkills(const SkillList& major, const SkillList& minor);
void setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value);
virtual void open();
virtual void onOpen();
void onFrame(float duration);

View file

@ -29,7 +29,6 @@
#include "../mwstate/character.hpp"
#include "confirmationdialog.hpp"
#include "widgets.hpp"
namespace MWGui
{
@ -58,6 +57,9 @@ namespace MWGui
mSaveList->eventKeyButtonPressed += MyGUI::newDelegate(this, &SaveGameDialog::onKeyButtonPressed);
mSaveNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &SaveGameDialog::onEditSelectAccept);
mSaveNameEdit->eventEditTextChange += MyGUI::newDelegate(this, &SaveGameDialog::onSaveNameChanged);
// To avoid accidental deletions
mDeleteButton->setNeedKeyFocus(false);
}
void SaveGameDialog::onSlotActivated(MyGUI::ListBox *sender, size_t pos)
@ -106,6 +108,11 @@ namespace MWGui
}
}
void SaveGameDialog::onDeleteSlotCancel()
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
}
void SaveGameDialog::onSaveNameChanged(MyGUI::EditBox *sender)
{
// This might have previously been a save slot from the list. If so, that is no longer the case
@ -118,9 +125,9 @@ namespace MWGui
accept();
}
void SaveGameDialog::open()
void SaveGameDialog::onOpen()
{
WindowModal::open();
WindowModal::onOpen();
mSaveNameEdit->setCaption ("");
if (mSaving)
@ -191,11 +198,6 @@ namespace MWGui
}
void SaveGameDialog::exit()
{
setVisible(false);
}
void SaveGameDialog::setLoadOrSave(bool load)
{
mSaving = !load;
@ -217,7 +219,7 @@ namespace MWGui
void SaveGameDialog::onCancelButtonClicked(MyGUI::Widget *sender)
{
exit();
setVisible(false);
}
void SaveGameDialog::onDeleteButtonClicked(MyGUI::Widget *sender)
@ -231,6 +233,11 @@ namespace MWGui
accept(true);
}
void SaveGameDialog::onConfirmationCancel()
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
}
void SaveGameDialog::accept(bool reallySure)
{
// Remove for MyGUI 3.2.2
@ -246,6 +253,7 @@ namespace MWGui
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &SaveGameDialog::onConfirmationGiven);
dialog->eventCancelClicked.clear();
dialog->eventCancelClicked += MyGUI::newDelegate(this, &SaveGameDialog::onConfirmationCancel);
return;
}
if (mSaveNameEdit->getCaption().empty())
@ -266,6 +274,7 @@ namespace MWGui
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &SaveGameDialog::onConfirmationGiven);
dialog->eventCancelClicked.clear();
dialog->eventCancelClicked += MyGUI::newDelegate(this, &SaveGameDialog::onConfirmationCancel);
return;
}
}

View file

@ -17,9 +17,7 @@ namespace MWGui
public:
SaveGameDialog();
virtual void open();
virtual void exit();
virtual void onOpen();
void setLoadOrSave(bool load);
@ -39,10 +37,12 @@ namespace MWGui
void onSlotMouseClick(MyGUI::ListBox* sender, size_t pos);
void onDeleteSlotConfirmed();
void onDeleteSlotCancel();
void onEditSelectAccept (MyGUI::EditBox* sender);
void onSaveNameChanged (MyGUI::EditBox* sender);
void onConfirmationGiven();
void onConfirmationCancel();
void accept(bool reallySure=false);

View file

@ -6,12 +6,13 @@
namespace MWGui
{
FadeOp::FadeOp(ScreenFader * fader, float time, float targetAlpha)
FadeOp::FadeOp(ScreenFader * fader, float time, float targetAlpha, float delay)
: mFader(fader),
mRemainingTime(time),
mRemainingTime(time+delay),
mTargetTime(time),
mTargetAlpha(targetAlpha),
mStartAlpha(0.f),
mDelay(delay),
mRunning(false)
{
}
@ -26,7 +27,7 @@ namespace MWGui
if (mRunning)
return;
mRemainingTime = mTargetTime;
mRemainingTime = mTargetTime + mDelay;
mStartAlpha = mFader->getCurrentAlpha();
mRunning = true;
}
@ -42,6 +43,12 @@ namespace MWGui
return;
}
if (mRemainingTime > mTargetTime)
{
mRemainingTime -= dt;
return;
}
float currentAlpha = mFader->getCurrentAlpha();
if (mStartAlpha > mTargetAlpha)
{
@ -74,7 +81,6 @@ namespace MWGui
, mRepeat(false)
{
mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize());
setVisible(false);
MyGUI::ImageBox* imageBox = mMainWidget->castType<MyGUI::ImageBox>(false);
if (imageBox)
@ -104,19 +110,25 @@ namespace MWGui
mMainWidget->setAlpha(1.f-((1.f-mCurrentAlpha) * mFactor));
}
void ScreenFader::fadeIn(float time)
void ScreenFader::fadeIn(float time, float delay)
{
queue(time, 1.f);
queue(time, 1.f, delay);
}
void ScreenFader::fadeOut(const float time)
void ScreenFader::fadeOut(const float time, float delay)
{
queue(time, 0.f);
queue(time, 0.f, delay);
}
void ScreenFader::fadeTo(const int percent, const float time)
void ScreenFader::fadeTo(const int percent, const float time, float delay)
{
queue(time, percent/100.f);
queue(time, percent/100.f, delay);
}
void ScreenFader::clear()
{
clearQueue();
notifyAlphaChanged(0.f);
}
void ScreenFader::setFactor(float factor)
@ -130,7 +142,7 @@ namespace MWGui
mRepeat = repeat;
}
void ScreenFader::queue(float time, float targetAlpha)
void ScreenFader::queue(float time, float targetAlpha, float delay)
{
if (time < 0.f)
return;
@ -142,7 +154,7 @@ namespace MWGui
return;
}
mQueue.push_back(FadeOp::Ptr(new FadeOp(this, time, targetAlpha)));
mQueue.push_back(FadeOp::Ptr(new FadeOp(this, time, targetAlpha, delay)));
}
bool ScreenFader::isEmpty()

View file

@ -14,7 +14,7 @@ namespace MWGui
public:
typedef std::shared_ptr<FadeOp> Ptr;
FadeOp(ScreenFader * fader, float time, float targetAlpha);
FadeOp(ScreenFader * fader, float time, float targetAlpha, float delay);
bool isRunning();
@ -28,6 +28,7 @@ namespace MWGui
float mTargetTime;
float mTargetAlpha;
float mStartAlpha;
float mDelay;
bool mRunning;
};
@ -38,14 +39,16 @@ namespace MWGui
void update(float dt);
void fadeIn(const float time);
void fadeOut(const float time);
void fadeTo(const int percent, const float time);
void fadeIn(const float time, float delay=0);
void fadeOut(const float time, float delay=0);
void fadeTo(const int percent, const float time, float delay=0);
void clear();
void setFactor (float factor);
void setRepeat(bool repeat);
void queue(float time, float targetAlpha);
void queue(float time, float targetAlpha, float delay);
bool isEmpty();
void clearQueue();

View file

@ -12,6 +12,7 @@
#include "../mwmechanics/actorutil.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/class.hpp"
#include "formatting.hpp"
@ -46,16 +47,19 @@ namespace MWGui
adjustButton(mCloseButton);
adjustButton(mTakeButton);
mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ScrollWindow::onKeyButtonPressed);
mTakeButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ScrollWindow::onKeyButtonPressed);
center();
}
void ScrollWindow::openScroll (MWWorld::Ptr scroll, bool showTakeButton)
void ScrollWindow::setPtr (const MWWorld::Ptr& scroll)
{
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getWindowManager()->playSound("scroll");
mScroll = scroll;
MWWorld::Ptr player = MWMechanics::getPlayer();
bool showTakeButton = scroll.getContainerStore() != &player.getClass().getContainerStore(player);
MWWorld::LiveCellRef<ESM::Book> *ref = mScroll.get<ESM::Book>();
Formatting::BookFormatter formatter;
@ -65,21 +69,28 @@ namespace MWGui
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mTextView->setVisibleVScroll(false);
if (size.height > mTextView->getSize().height)
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
mTextView->setCanvasSize(mTextView->getWidth(), size.height);
else
mTextView->setCanvasSize(410, mTextView->getSize().height);
mTextView->setCanvasSize(mTextView->getWidth(), mTextView->getSize().height);
mTextView->setVisibleVScroll(true);
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
setTakeButtonShow(showTakeButton);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
}
void ScrollWindow::exit()
void ScrollWindow::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character)
{
MWBase::Environment::get().getWindowManager()->playSound("scroll");
int scroll = 0;
if (key == MyGUI::KeyCode::ArrowUp)
scroll = 40;
else if (key == MyGUI::KeyCode::ArrowDown)
scroll = -40;
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
if (scroll != 0)
mTextView->setViewOffset(mTextView->getViewOffset() + MyGUI::IntPoint(0, scroll));
}
void ScrollWindow::setTakeButtonShow(bool show)
@ -96,7 +107,7 @@ namespace MWGui
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
}
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
@ -106,6 +117,6 @@ namespace MWGui
MWWorld::ActionTake take(mScroll);
take.execute (MWMechanics::getPlayer());
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll, true);
}
}

View file

@ -17,14 +17,16 @@ namespace MWGui
public:
ScrollWindow ();
void openScroll (MWWorld::Ptr scroll, bool showTakeButton);
virtual void exit();
void setPtr (const MWWorld::Ptr& scroll);
void setInventoryAllowed(bool allowed);
void onResChange(int, int) { center(); }
protected:
void onCloseButtonClicked (MyGUI::Widget* _sender);
void onTakeButtonClicked (MyGUI::Widget* _sender);
void setTakeButtonShow(bool show);
void onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character);
private:
Gui::ImageButton* mCloseButton;

View file

@ -258,7 +258,7 @@ namespace MWGui
void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Settings);
}
void SettingsWindow::onResolutionSelected(MyGUI::ListBox* _sender, size_t index)
@ -353,24 +353,31 @@ namespace MWGui
}
bool supported = false;
int fallbackX = 0, fallbackY = 0;
for (unsigned int i=0; i<mResolutionList->getItemCount(); ++i)
{
std::string resStr = mResolutionList->getItemNameAt(i);
int resX, resY;
parseResolution (resX, resY, resStr);
if (i == 0)
{
fallbackX = resX;
fallbackY = resY;
}
if (resX == Settings::Manager::getInt("resolution x", "Video")
&& resY == Settings::Manager::getInt("resolution y", "Video"))
supported = true;
}
if (!supported)
if (!supported && mResolutionList->getItemCount())
{
std::string msg = "This resolution is not supported in Fullscreen mode. Please select a resolution from the list.";
MWBase::Environment::get().getWindowManager()->
messageBox(msg);
_sender->castType<MyGUI::Button>()->setCaption(off);
return;
if (fallbackX != 0 && fallbackY != 0)
{
Settings::Manager::setInt("resolution x", "Video", fallbackX);
Settings::Manager::setInt("resolution y", "Video", fallbackY);
}
}
mWindowBorderButton->setEnabled(!newState);
@ -553,17 +560,12 @@ namespace MWGui
updateControlsBox ();
}
void SettingsWindow::open()
void SettingsWindow::onOpen()
{
updateControlsBox ();
resetScrollbars();
}
void SettingsWindow::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Settings);
}
void SettingsWindow::onWindowResize(MyGUI::Window *_sender)
{
layoutControlsBox();

View file

@ -15,12 +15,12 @@ namespace MWGui
public:
SettingsWindow();
virtual void open();
virtual void exit();
virtual void onOpen();
void updateControlsBox();
void onResChange(int, int) { center(); }
protected:
MyGUI::TabControl* mSettingsTab;
MyGUI::Button* mOkButton;

View file

@ -59,15 +59,91 @@ namespace
if (mSortByType && left.mType != right.mType)
return left.mType < right.mType;
if (left.mBase.getTypeName() == right.mBase.getTypeName())
{
std::string leftName = Misc::StringUtils::lowerCase(left.mBase.getClass().getName(left.mBase));
std::string rightName = Misc::StringUtils::lowerCase(right.mBase.getClass().getName(right.mBase));
float result = 0;
return leftName.compare(rightName) < 0;
// compare items by type
std::string leftName = left.mBase.getTypeName();
std::string rightName = right.mBase.getTypeName();
if (leftName != rightName)
return compareType(leftName, rightName);
// compare items by name
leftName = Misc::StringUtils::lowerCase(left.mBase.getClass().getName(left.mBase));
rightName = Misc::StringUtils::lowerCase(right.mBase.getClass().getName(right.mBase));
result = leftName.compare(rightName);
if (result != 0)
return result < 0;
// compare items by enchantment:
// 1. enchanted items showed before non-enchanted
// 2. item with lesser charge percent comes after items with more charge percent
// 3. item with constant effect comes before items with non-constant effects
int leftChargePercent = -1;
int rightChargePercent = -1;
leftName = left.mBase.getClass().getEnchantment(left.mBase);
rightName = right.mBase.getClass().getEnchantment(right.mBase);
if (!leftName.empty())
{
const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().search(leftName);
if (ench)
{
if (ench->mData.mType == ESM::Enchantment::ConstantEffect)
leftChargePercent = 101;
else
leftChargePercent = (left.mBase.getCellRef().getEnchantmentCharge() == -1) ? 100
: static_cast<int>(left.mBase.getCellRef().getEnchantmentCharge() / static_cast<float>(ench->mData.mCharge) * 100);
}
}
else
return compareType(left.mBase.getTypeName(), right.mBase.getTypeName());
if (!rightName.empty())
{
const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().search(rightName);
if (ench)
{
if (ench->mData.mType == ESM::Enchantment::ConstantEffect)
rightChargePercent = 101;
else
rightChargePercent = (right.mBase.getCellRef().getEnchantmentCharge() == -1) ? 100
: static_cast<int>(right.mBase.getCellRef().getEnchantmentCharge() / static_cast<float>(ench->mData.mCharge) * 100);
}
}
result = leftChargePercent - rightChargePercent;
if (result != 0)
return result > 0;
// compare items by condition
if (left.mBase.getClass().hasItemHealth(left.mBase) && right.mBase.getClass().hasItemHealth(right.mBase))
{
result = left.mBase.getClass().getItemHealth(left.mBase) - right.mBase.getClass().getItemHealth(right.mBase);
if (result != 0)
return result > 0;
}
// compare items by remaining usage time
result = left.mBase.getClass().getRemainingUsageTime(left.mBase) - right.mBase.getClass().getRemainingUsageTime(right.mBase);
if (result != 0)
return result > 0;
// compare items by value
result = left.mBase.getClass().getValue(left.mBase) - right.mBase.getClass().getValue(right.mBase);
if (result != 0)
return result > 0;
// compare items by weight
result = left.mBase.getClass().getWeight(left.mBase) - right.mBase.getClass().getWeight(right.mBase);
if (result != 0)
return result > 0;
// compare items by Id
leftName = left.mBase.getCellRef().getRefId();
rightName = right.mBase.getCellRef().getRefId();
result = leftName.compare(rightName);
return result < 0;
}
};
}

View file

@ -22,13 +22,11 @@ namespace MWGui
{
if (button == 0)
{
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Recharge);
MWBase::Environment::get().getWindowManager()->startRecharge(mSoulgem);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Recharge, mSoulgem);
}
else
{
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting);
MWBase::Environment::get().getWindowManager()->startSelfEnchanting(mSoulgem);
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting, mSoulgem);
}
}

View file

@ -31,11 +31,6 @@ namespace MWGui
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked);
}
void SpellBuyingWindow::exit()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_SpellBuying);
}
bool SpellBuyingWindow::sortSpells (const ESM::Spell* left, const ESM::Spell* right)
{
std::string leftName = Misc::StringUtils::lowerCase(left->mName);
@ -88,7 +83,12 @@ namespace MWGui
mSpellsWidgetMap.clear();
}
void SpellBuyingWindow::startSpellBuying(const MWWorld::Ptr& actor, int startOffset)
void SpellBuyingWindow::setPtr(const MWWorld::Ptr &actor)
{
setPtr(actor, 0);
}
void SpellBuyingWindow::setPtr(const MWWorld::Ptr& actor, int startOffset)
{
center();
mPtr = actor;
@ -161,14 +161,14 @@ namespace MWGui
MWMechanics::CreatureStats& npcStats = mPtr.getClass().getCreatureStats(mPtr);
npcStats.setGoldPool(npcStats.getGoldPool() + price);
startSpellBuying(mPtr, mSpellsView->getViewOffset().top);
setPtr(mPtr, mSpellsView->getViewOffset().top);
MWBase::Environment::get().getWindowManager()->playSound("Item Gold Up");
}
void SpellBuyingWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
{
exit();
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_SpellBuying);
}
void SpellBuyingWindow::updateLabels()
@ -187,7 +187,7 @@ namespace MWGui
{
// remove both Spells and Dialogue (since you always trade with the NPC/creature that you have previously talked to)
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_SpellBuying);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
}
void SpellBuyingWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)

View file

@ -25,9 +25,13 @@ namespace MWGui
public:
SpellBuyingWindow();
void startSpellBuying(const MWWorld::Ptr& actor, int startOffset);
void setPtr(const MWWorld::Ptr& actor);
void setPtr(const MWWorld::Ptr& actor, int startOffset);
virtual void exit();
void onFrame(float dt) { checkReferenceAvailable(); }
void clear() { resetReference(); }
void onResChange(int, int) { center(); }
protected:
MyGUI::Button* mCancelButton;

Some files were not shown because too many files have changed in this diff Show more