Merge remote-tracking branch 'kcat/animations' into ref

This commit is contained in:
Marc Zinnschlag 2013-04-25 20:12:14 +02:00
commit 2c1796cc74
99 changed files with 10193 additions and 9948 deletions

View file

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version
set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 22)
set (OPENMW_VERSION_MINOR 23)
set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")

View file

@ -439,7 +439,7 @@ void Record<ESM::Apparatus>::print()
template<>
void Record<ESM::BodyPart>::print()
{
std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Race: " << mData.mRace << std::endl;
std::cout << " Model: " << mData.mModel << std::endl;
std::cout << " Type: " << meshTypeLabel(mData.mData.mType)
<< " (" << (int)mData.mData.mType << ")" << std::endl;

View file

@ -102,3 +102,9 @@ if (BUILD_WITH_CODE_COVERAGE)
add_definitions (--coverage)
target_link_libraries(omwlauncher gcov)
endif()
# Workaround for binutil => 2.23 problem when linking, should be fixed eventually upstream
if (UNIX AND NOT APPLE)
target_link_libraries(omwlauncher dl Xt)
endif()

View file

@ -96,15 +96,15 @@ bool GameSettings::readFile(QTextStream &stream)
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
while (!stream.atEnd()) {
QString line = stream.readLine().simplified();
QString line = stream.readLine();
if (line.isEmpty() || line.startsWith("#"))
continue;
if (keyRe.indexIn(line) != -1) {
QString key = keyRe.cap(1).simplified();
QString value = keyRe.cap(2).simplified();
QString key = keyRe.cap(1);
QString value = keyRe.cap(2);
// Don't remove existing data entries
if (key != QLatin1String("data"))

View file

@ -52,7 +52,7 @@ public:
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
while (!stream.atEnd()) {
QString line = stream.readLine().simplified();
QString line = stream.readLine();
if (line.isEmpty() || line.startsWith("#"))
continue;
@ -65,8 +65,8 @@ public:
if (keyRe.indexIn(line) != -1) {
QString key = keyRe.cap(1).simplified();
QString value = keyRe.cap(2).simplified();
QString key = keyRe.cap(1);
QString value = keyRe.cap(2);
if (!sectionPrefix.isEmpty())
key.prepend(sectionPrefix);

View file

@ -122,6 +122,12 @@ if (UNIX AND NOT APPLE)
target_link_libraries(openmw ${CMAKE_THREAD_LIBS_INIT})
endif()
# Workaround for binutil => 2.23 problem when linking, should be fixed eventually upstream
if (UNIX AND NOT APPLE)
target_link_libraries(openmw dl Xt)
endif()
if(APPLE)
find_library(CARBON_FRAMEWORK Carbon)
find_library(COCOA_FRAMEWORK Cocoa)

View file

@ -99,6 +99,9 @@ namespace MWBase
float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) = 0;
///< Perform a persuasion action on NPC
virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0;
///< Forces an object to refresh its animation state.
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number=1) = 0;
///< Run animation for a MW-reference. Calls to this function for references that are currently not
/// in the scene should be ignored.

View file

@ -49,6 +49,67 @@ namespace
{
return new CustomData (*this);
}
void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats)
{
// race bonus
const ESM::Race *race =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace);
bool male = (npc->mFlags & ESM::NPC::Female) == 0;
int level = creatureStats.getLevel();
for (int i=0; i<ESM::Attribute::Length; ++i)
{
const ESM::Race::MaleFemale& attribute = race->mData.mAttributeValues[i];
creatureStats.getAttribute(i).setBase (male ? attribute.mMale : attribute.mFemale);
}
// class bonus
const ESM::Class *class_ =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc->mClass);
for (int i=0; i<2; ++i)
{
int attribute = class_->mData.mAttribute[i];
if (attribute>=0 && attribute<8)
{
creatureStats.getAttribute(attribute).setBase (
creatureStats.getAttribute(attribute).getBase() + 10);
}
}
// skill bonus
for (int attribute=0; attribute<ESM::Attribute::Length; ++attribute)
{
float modifierSum = 0;
for (int j=0; j<ESM::Skill::Length; ++j)
{
const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(j);
if (skill->mData.mAttribute != attribute)
continue;
// is this a minor or major skill?
float add=0.2;
for (int k=0; k<5; ++k)
{
if (class_->mData.mSkills[k][0] == j)
add=0.5;
}
for (int k=0; k<5; ++k)
{
if (class_->mData.mSkills[k][1] == j)
add=1.0;
}
modifierSum += add;
}
creatureStats.getAttribute(attribute).setBase ( std::min(creatureStats.getAttribute(attribute).getBase()
+ static_cast<int>((level-1) * modifierSum+0.5), 100) );
}
}
}
namespace MWClass
@ -126,15 +187,14 @@ namespace MWClass
}
else
{
for (int i=0; i<8; ++i)
data->mCreatureStats.getAttribute (i).set (10);
for (int i=0; i<3; ++i)
data->mCreatureStats.setDynamic (i, 10);
data->mCreatureStats.setLevel(ref->mBase->mNpdt12.mLevel);
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt12.mDisposition);
data->mNpcStats.setReputation(ref->mBase->mNpdt12.mReputation);
autoCalculateAttributes(ref->mBase, data->mCreatureStats);
}
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);

View file

@ -426,6 +426,7 @@ namespace MWDialogue
void DialogueManager::questionAnswered (const std::string& answer)
{
if (mChoiceMap.find(answer) != mChoiceMap.end())
{
mChoice = mChoiceMap[answer];
@ -442,6 +443,10 @@ namespace MWDialogue
std::string text = info->mResponse;
parseText (text);
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext));
MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId);
@ -449,9 +454,6 @@ namespace MWDialogue
mLastDialogue = *info;
}
}
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
}
updateTopics();

View file

@ -73,6 +73,11 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
if (iter->second < info.mData.mRank)
return false;
}
else if (info.mData.mRank != -1)
{
// if there is a rank condition, but the NPC is not in a faction, always fail
return false;
}
// Gender
if (!isCreature)

View file

@ -27,7 +27,7 @@ namespace MWDialogue
static std::string idFromIndex (const std::string& topic, int index);
};
/// \biref A quest entry with a timestamp.
/// \brief A quest entry with a timestamp.
struct StampedJournalEntry : public JournalEntry
{
int mDay;

View file

@ -8,8 +8,6 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/containerstore.hpp"
namespace
{

View file

@ -10,7 +10,6 @@
namespace MWGui
{
class AlchemyWindow : public WindowBase, public ContainerBase
{
public:

View file

@ -3,30 +3,28 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "widgets.hpp"
using namespace MWGui;
using namespace Widgets;
namespace
{
bool sortBirthSigns(const std::pair<std::string, const ESM::BirthSign*>& left, const std::pair<std::string, const ESM::BirthSign*>& right)
{
bool sortBirthSigns(const std::pair<std::string, const ESM::BirthSign*>& left, const std::pair<std::string, const ESM::BirthSign*>& right)
{
return left.second->mName.compare (right.second->mName) < 0;
}
}
}
BirthDialog::BirthDialog()
: WindowModal("openmw_chargen_birth.layout")
namespace MWGui
{
BirthDialog::BirthDialog()
: WindowModal("openmw_chargen_birth.layout")
{
// Centre dialog
center();
@ -51,10 +49,10 @@ BirthDialog::BirthDialog()
updateBirths();
updateSpells();
}
}
void BirthDialog::setNextButtonShow(bool shown)
{
void BirthDialog::setNextButtonShow(bool shown)
{
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
@ -62,18 +60,18 @@ void BirthDialog::setNextButtonShow(bool shown)
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
else
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
}
void BirthDialog::open()
{
void BirthDialog::open()
{
WindowModal::open();
updateBirths();
updateSpells();
}
}
void BirthDialog::setBirthId(const std::string &birthId)
{
void BirthDialog::setBirthId(const std::string &birthId)
{
mCurrentBirthId = birthId;
mBirthList->setIndexSelected(MyGUI::ITEM_NONE);
size_t count = mBirthList->getItemCount();
@ -89,24 +87,24 @@ void BirthDialog::setBirthId(const std::string &birthId)
}
updateSpells();
}
}
// widget controls
// widget controls
void BirthDialog::onOkClicked(MyGUI::Widget* _sender)
{
void BirthDialog::onOkClicked(MyGUI::Widget* _sender)
{
if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE)
return;
eventDone(this);
}
}
void BirthDialog::onBackClicked(MyGUI::Widget* _sender)
{
void BirthDialog::onBackClicked(MyGUI::Widget* _sender)
{
eventBack();
}
}
void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
{
void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
{
if (_index == MyGUI::ITEM_NONE)
return;
@ -119,12 +117,12 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
mCurrentBirthId = *birthId;
updateSpells();
}
}
// update widget content
// update widget content
void BirthDialog::updateBirths()
{
void BirthDialog::updateBirths()
{
mBirthList->removeAllItems();
const MWWorld::Store<ESM::BirthSign> &signs =
@ -155,10 +153,10 @@ void BirthDialog::updateBirths()
mBirthList->setIndexSelected(index);
}
}
}
}
void BirthDialog::updateSpells()
{
void BirthDialog::updateSpells()
{
for (std::vector<MyGUI::Widget*>::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
@ -168,7 +166,7 @@ void BirthDialog::updateSpells()
if (mCurrentBirthId.empty())
return;
MWSpellPtr spellWidget;
Widgets::MWSpellPtr spellWidget;
const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, mSpellArea->getWidth(), 18);
@ -179,7 +177,7 @@ void BirthDialog::updateSpells()
store.get<ESM::BirthSign>().find(mCurrentBirthId);
std::string texturePath = std::string("textures\\") + birth->mTexture;
fixTexturePath(texturePath);
Widgets::fixTexturePath(texturePath);
mBirthImage->setImageTexture(texturePath);
std::vector<std::string> abilities, powers, spells;
@ -229,7 +227,7 @@ void BirthDialog::updateSpells()
for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != end; ++it)
{
const std::string &spellId = *it;
spellWidget = mSpellArea->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i));
spellWidget = mSpellArea->createWidget<Widgets::MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i));
spellWidget->setSpellId(spellId);
mSpellItems.push_back(spellWidget);
@ -237,11 +235,13 @@ void BirthDialog::updateSpells()
MyGUI::IntCoord spellCoord = coord;
spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template?
spellWidget->createEffectWidgets(mSpellItems, mSpellArea, spellCoord, (category == 0) ? MWEffectList::EF_Constant : 0);
spellWidget->createEffectWidgets(mSpellItems, mSpellArea, spellCoord, (category == 0) ? Widgets::MWEffectList::EF_Constant : 0);
coord.top = spellCoord.top;
++i;
}
}
}
}
}

View file

@ -12,13 +12,14 @@
#include "formatting.hpp"
using namespace MWGui;
namespace MWGui
{
BookWindow::BookWindow ()
BookWindow::BookWindow ()
: WindowBase("openmw_book.layout")
, mTakeButtonShow(true)
, mTakeButtonAllowed(true)
{
{
getWidget(mCloseButton, "CloseButton");
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);
@ -38,20 +39,20 @@ BookWindow::BookWindow ()
getWidget(mRightPage, "RightPage");
center();
}
}
void BookWindow::clearPages()
{
void BookWindow::clearPages()
{
for (std::vector<MyGUI::Widget*>::iterator it=mPages.begin();
it!=mPages.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
mPages.clear();
}
}
void BookWindow::open (MWWorld::Ptr book)
{
void BookWindow::open (MWWorld::Ptr book)
{
mBook = book;
clearPages();
@ -83,40 +84,40 @@ void BookWindow::open (MWWorld::Ptr book)
updatePages();
setTakeButtonShow(true);
}
}
void BookWindow::setTakeButtonShow(bool show)
{
void BookWindow::setTakeButtonShow(bool show)
{
mTakeButtonShow = show;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
}
void BookWindow::setInventoryAllowed(bool allowed)
{
void BookWindow::setInventoryAllowed(bool allowed)
{
mTakeButtonAllowed = allowed;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
}
void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender)
{
void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender)
{
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
}
}
void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender)
{
void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender)
{
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
MWWorld::ActionTake take(mBook);
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
}
}
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
{
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
{
if ((mCurrentPage+1)*2 < mPages.size())
{
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
@ -125,10 +126,10 @@ void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
updatePages();
}
}
}
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
{
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
{
if (mCurrentPage > 0)
{
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
@ -137,10 +138,10 @@ void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
updatePages();
}
}
}
void BookWindow::updatePages()
{
void BookWindow::updatePages()
{
mLeftPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 1) );
mRightPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 2) );
@ -156,4 +157,6 @@ void BookWindow::updatePages()
}
++i;
}
}
}

View file

@ -5,8 +5,6 @@
#include "class.hpp"
#include "birth.hpp"
#include "review.hpp"
#include "dialogue.hpp"
#include "mode.hpp"
#include "inventorywindow.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
@ -45,9 +43,10 @@ namespace
};
}
using namespace MWGui;
namespace MWGui
{
CharacterCreation::CharacterCreation()
CharacterCreation::CharacterCreation()
: mNameDialog(0)
, mRaceDialog(0)
, mClassChoiceDialog(0)
@ -58,12 +57,12 @@ CharacterCreation::CharacterCreation()
, mBirthSignDialog(0)
, mReviewDialog(0)
, mGenerateClassStep(0)
{
{
mCreationStage = CSE_NotStarted;
}
}
void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
if (mReviewDialog)
{
static const char *ids[] =
@ -79,10 +78,10 @@ void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat
mReviewDialog->setAttribute(ESM::Attribute::AttributeID(i), value);
}
}
}
}
void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
if (mReviewDialog)
{
if (id == "HBar")
@ -98,22 +97,22 @@ void CharacterCreation::setValue (const std::string& id, const MWMechanics::Dyna
mReviewDialog->setFatigue (value);
}
}
}
}
void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{
void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{
if (mReviewDialog)
mReviewDialog->setSkillValue(parSkill, value);
}
}
void CharacterCreation::configureSkills (const SkillList& major, const SkillList& minor)
{
void CharacterCreation::configureSkills (const SkillList& major, const SkillList& minor)
{
if (mReviewDialog)
mReviewDialog->configureSkills(major, minor);
}
}
void CharacterCreation::spawnDialog(const char id)
{
void CharacterCreation::spawnDialog(const char id)
{
switch (id)
{
case GM_Name:
@ -237,41 +236,41 @@ void CharacterCreation::spawnDialog(const char id)
mCreationStage = CSE_BirthSignChosen;
break;
}
}
}
void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat<float>& value)
{
void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat<float>& value)
{
mPlayerHealth = value;
}
}
void CharacterCreation::setPlayerMagicka (const MWMechanics::DynamicStat<float>& value)
{
void CharacterCreation::setPlayerMagicka (const MWMechanics::DynamicStat<float>& value)
{
mPlayerMagicka = value;
}
}
void CharacterCreation::setPlayerFatigue (const MWMechanics::DynamicStat<float>& value)
{
void CharacterCreation::setPlayerFatigue (const MWMechanics::DynamicStat<float>& value)
{
mPlayerFatigue = value;
}
}
void CharacterCreation::onReviewDialogDone(WindowBase* parWindow)
{
void CharacterCreation::onReviewDialogDone(WindowBase* parWindow)
{
MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog);
mReviewDialog = 0;
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
void CharacterCreation::onReviewDialogBack()
{
void CharacterCreation::onReviewDialogBack()
{
MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog);
mReviewDialog = 0;
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Birth);
}
}
void CharacterCreation::onReviewActivateDialog(int parDialog)
{
void CharacterCreation::onReviewActivateDialog(int parDialog)
{
MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog);
mReviewDialog = 0;
mCreationStage = CSE_ReviewNext;
@ -292,10 +291,10 @@ void CharacterCreation::onReviewActivateDialog(int parDialog)
case ReviewDialog::BIRTHSIGN_DIALOG:
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Birth);
};
}
}
void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
{
void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
{
if (mPickClassDialog)
{
const std::string &classId = mPickClassDialog->getClassId();
@ -329,10 +328,10 @@ void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
mCreationStage = CSE_ClassChosen;
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
}
void CharacterCreation::onPickClassDialogBack()
{
void CharacterCreation::onPickClassDialogBack()
{
if (mPickClassDialog)
{
const std::string classId = mPickClassDialog->getClassId();
@ -344,10 +343,10 @@ void CharacterCreation::onPickClassDialogBack()
MWBase::Environment::get().getWindowManager()->popGuiMode();
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
}
}
void CharacterCreation::onClassChoice(int _index)
{
void CharacterCreation::onClassChoice(int _index)
{
MWBase::Environment::get().getWindowManager()->removeDialog(mClassChoiceDialog);
mClassChoiceDialog = 0;
@ -369,10 +368,10 @@ void CharacterCreation::onClassChoice(int _index)
break;
};
}
}
void CharacterCreation::onNameDialogDone(WindowBase* parWindow)
{
void CharacterCreation::onNameDialogDone(WindowBase* parWindow)
{
if (mNameDialog)
{
mPlayerName = mNameDialog->getTextInput();
@ -397,10 +396,10 @@ void CharacterCreation::onNameDialogDone(WindowBase* parWindow)
mCreationStage = CSE_NameChosen;
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
}
void CharacterCreation::onRaceDialogBack()
{
void CharacterCreation::onRaceDialogBack()
{
if (mRaceDialog)
{
const ESM::NPC &data = mRaceDialog->getResult();
@ -419,10 +418,10 @@ void CharacterCreation::onRaceDialogBack()
MWBase::Environment::get().getWindowManager()->popGuiMode();
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Name);
}
}
void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
{
void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
{
if (mRaceDialog)
{
const ESM::NPC &data = mRaceDialog->getResult();
@ -456,10 +455,10 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
mCreationStage = CSE_RaceChosen;
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
}
void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
{
void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
{
if (mBirthSignDialog)
{
mPlayerBirthSignId = mBirthSignDialog->getBirthId();
@ -479,10 +478,10 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
mCreationStage = CSE_BirthSignChosen;
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
}
void CharacterCreation::onBirthSignDialogBack()
{
void CharacterCreation::onBirthSignDialogBack()
{
if (mBirthSignDialog)
{
MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mBirthSignDialog->getBirthId());
@ -492,10 +491,10 @@ void CharacterCreation::onBirthSignDialogBack()
MWBase::Environment::get().getWindowManager()->popGuiMode();
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
}
}
void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
{
void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
{
if (mCreateClassDialog)
{
ESM::Class klass;
@ -542,19 +541,19 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
mCreationStage = CSE_ClassChosen;
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
}
void CharacterCreation::onCreateClassDialogBack()
{
void CharacterCreation::onCreateClassDialogBack()
{
MWBase::Environment::get().getWindowManager()->removeDialog(mCreateClassDialog);
mCreateClassDialog = 0;
MWBase::Environment::get().getWindowManager()->popGuiMode();
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
}
}
void CharacterCreation::onClassQuestionChosen(int _index)
{
void CharacterCreation::onClassQuestionChosen(int _index)
{
MWBase::Environment::get().getSoundManager()->stopSay();
MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassQuestionDialog);
@ -576,10 +575,10 @@ void CharacterCreation::onClassQuestionChosen(int _index)
++mGenerateClassSpecializations[2];
++mGenerateClassStep;
showClassQuestionDialog();
}
}
void CharacterCreation::showClassQuestionDialog()
{
void CharacterCreation::showClassQuestionDialog()
{
if (mGenerateClassStep == 10)
{
static boost::array<ClassPoint, 23> classes = { {
@ -669,10 +668,10 @@ void CharacterCreation::showClassQuestionDialog()
mGenerateClassQuestionDialog->setVisible(true);
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps(mGenerateClassStep).mSound);
}
}
void CharacterCreation::onGenerateClassBack()
{
void CharacterCreation::onGenerateClassBack()
{
MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassResultDialog);
mGenerateClassResultDialog = 0;
@ -680,10 +679,10 @@ void CharacterCreation::onGenerateClassBack()
MWBase::Environment::get().getWindowManager()->popGuiMode();
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
}
}
void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
{
void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
{
MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassResultDialog);
mGenerateClassResultDialog = 0;
@ -710,10 +709,10 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
mCreationStage = CSE_ClassChosen;
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
}
CharacterCreation::~CharacterCreation()
{
CharacterCreation::~CharacterCreation()
{
delete mNameDialog;
delete mRaceDialog;
delete mClassChoiceDialog;
@ -723,4 +722,6 @@ CharacterCreation::~CharacterCreation()
delete mCreateClassDialog;
delete mBirthSignDialog;
delete mReviewDialog;
}
}

View file

@ -1,11 +1,6 @@
#include "class.hpp"
#include <iterator>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -16,13 +11,14 @@
#undef min
#undef max
using namespace MWGui;
/* GenerateClassResultDialog */
GenerateClassResultDialog::GenerateClassResultDialog()
: WindowModal("openmw_chargen_generate_class_result.layout")
namespace MWGui
{
/* GenerateClassResultDialog */
GenerateClassResultDialog::GenerateClassResultDialog()
: WindowModal("openmw_chargen_generate_class_result.layout")
{
// Centre dialog
center();
@ -39,37 +35,37 @@ GenerateClassResultDialog::GenerateClassResultDialog()
getWidget(okButton, "OKButton");
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked);
}
}
std::string GenerateClassResultDialog::getClassId() const
{
std::string GenerateClassResultDialog::getClassId() const
{
return mClassName->getCaption();
}
}
void GenerateClassResultDialog::setClassId(const std::string &classId)
{
void GenerateClassResultDialog::setClassId(const std::string &classId)
{
mCurrentClassId = classId;
mClassImage->setImageTexture(std::string("textures\\levelup\\") + mCurrentClassId + ".dds");
mClassName->setCaption(MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(mCurrentClassId)->mName);
}
}
// widget controls
// widget controls
void GenerateClassResultDialog::onOkClicked(MyGUI::Widget* _sender)
{
void GenerateClassResultDialog::onOkClicked(MyGUI::Widget* _sender)
{
eventDone(this);
}
}
void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender)
{
void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender)
{
eventBack();
}
}
/* PickClassDialog */
/* PickClassDialog */
PickClassDialog::PickClassDialog()
PickClassDialog::PickClassDialog()
: WindowModal("openmw_chargen_class.layout")
{
{
// Centre dialog
center();
@ -103,10 +99,10 @@ PickClassDialog::PickClassDialog()
updateClasses();
updateStats();
}
}
void PickClassDialog::setNextButtonShow(bool shown)
{
void PickClassDialog::setNextButtonShow(bool shown)
{
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
@ -114,18 +110,18 @@ void PickClassDialog::setNextButtonShow(bool shown)
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
else
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
}
void PickClassDialog::open()
{
void PickClassDialog::open()
{
WindowModal::open ();
updateClasses();
updateStats();
}
}
void PickClassDialog::setClassId(const std::string &classId)
{
void PickClassDialog::setClassId(const std::string &classId)
{
mCurrentClassId = classId;
mClassList->setIndexSelected(MyGUI::ITEM_NONE);
size_t count = mClassList->getItemCount();
@ -141,24 +137,24 @@ void PickClassDialog::setClassId(const std::string &classId)
}
updateStats();
}
}
// widget controls
// widget controls
void PickClassDialog::onOkClicked(MyGUI::Widget* _sender)
{
void PickClassDialog::onOkClicked(MyGUI::Widget* _sender)
{
if(mClassList->getIndexSelected() == MyGUI::ITEM_NONE)
return;
eventDone(this);
}
}
void PickClassDialog::onBackClicked(MyGUI::Widget* _sender)
{
void PickClassDialog::onBackClicked(MyGUI::Widget* _sender)
{
eventBack();
}
}
void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index)
{
void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index)
{
if (_index == MyGUI::ITEM_NONE)
return;
@ -171,12 +167,12 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index)
mCurrentClassId = *classId;
updateStats();
}
}
// update widget content
// update widget content
void PickClassDialog::updateClasses()
{
void PickClassDialog::updateClasses()
{
mClassList->removeAllItems();
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
@ -202,10 +198,10 @@ void PickClassDialog::updateClasses()
}
++index;
}
}
}
void PickClassDialog::updateStats()
{
void PickClassDialog::updateStats()
{
if (mCurrentClassId.empty())
return;
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
@ -238,22 +234,22 @@ void PickClassDialog::updateStats()
}
mClassImage->setImageTexture(std::string("textures\\levelup\\") + mCurrentClassId + ".dds");
}
}
/* InfoBoxDialog */
/* InfoBoxDialog */
void InfoBoxDialog::fitToText(MyGUI::TextBox* widget)
{
void InfoBoxDialog::fitToText(MyGUI::TextBox* widget)
{
MyGUI::IntCoord inner = widget->getTextRegion();
MyGUI::IntCoord outer = widget->getCoord();
MyGUI::IntSize size = widget->getTextSize();
size.width += outer.width - inner.width;
size.height += outer.height - inner.height;
widget->setSize(size);
}
}
void InfoBoxDialog::layoutVertically(MyGUI::Widget* widget, int margin)
{
void InfoBoxDialog::layoutVertically(MyGUI::Widget* widget, int margin)
{
size_t count = widget->getChildCount();
int pos = 0;
pos += margin;
@ -270,34 +266,34 @@ void InfoBoxDialog::layoutVertically(MyGUI::Widget* widget, int margin)
}
width += margin*2;
widget->setSize(width, pos);
}
}
InfoBoxDialog::InfoBoxDialog()
InfoBoxDialog::InfoBoxDialog()
: WindowModal("openmw_infobox.layout")
, mCurrentButton(-1)
{
{
getWidget(mTextBox, "TextBox");
getWidget(mText, "Text");
mText->getSubWidgetText()->setWordWrap(true);
getWidget(mButtonBar, "ButtonBar");
center();
}
}
void InfoBoxDialog::setText(const std::string &str)
{
void InfoBoxDialog::setText(const std::string &str)
{
mText->setCaption(str);
mTextBox->setVisible(!str.empty());
fitToText(mText);
}
}
std::string InfoBoxDialog::getText() const
{
std::string InfoBoxDialog::getText() const
{
return mText->getCaption();
}
}
void InfoBoxDialog::setButtons(ButtonList &buttons)
{
void InfoBoxDialog::setButtons(ButtonList &buttons)
{
for (std::vector<MyGUI::Button*>::iterator it = this->mButtons.begin(); it != this->mButtons.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
@ -320,10 +316,10 @@ void InfoBoxDialog::setButtons(ButtonList &buttons)
coord.top += button->getHeight();
this->mButtons.push_back(button);
}
}
}
void InfoBoxDialog::open()
{
void InfoBoxDialog::open()
{
WindowModal::open();
// Fix layout
layoutVertically(mTextBox, 4);
@ -331,15 +327,15 @@ void InfoBoxDialog::open()
layoutVertically(mMainWidget, 4 + 6);
center();
}
}
int InfoBoxDialog::getChosenButton() const
{
int InfoBoxDialog::getChosenButton() const
{
return mCurrentButton;
}
}
void InfoBoxDialog::onButtonClicked(MyGUI::Widget* _sender)
{
void InfoBoxDialog::onButtonClicked(MyGUI::Widget* _sender)
{
std::vector<MyGUI::Button*>::const_iterator end = mButtons.end();
int i = 0;
for (std::vector<MyGUI::Button*>::const_iterator it = mButtons.begin(); it != end; ++it)
@ -352,13 +348,13 @@ void InfoBoxDialog::onButtonClicked(MyGUI::Widget* _sender)
}
++i;
}
}
}
/* ClassChoiceDialog */
/* ClassChoiceDialog */
ClassChoiceDialog::ClassChoiceDialog()
ClassChoiceDialog::ClassChoiceDialog()
: InfoBoxDialog()
{
{
setText("");
ButtonList buttons;
buttons.push_back(MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu1", ""));
@ -366,17 +362,17 @@ ClassChoiceDialog::ClassChoiceDialog()
buttons.push_back(MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu3", ""));
buttons.push_back(MWBase::Environment::get().getWindowManager()->getGameSettingString("sBack", ""));
setButtons(buttons);
}
}
/* CreateClassDialog */
/* CreateClassDialog */
CreateClassDialog::CreateClassDialog()
CreateClassDialog::CreateClassDialog()
: WindowModal("openmw_chargen_create_class.layout")
, mSpecDialog(NULL)
, mAttribDialog(NULL)
, mSkillDialog(NULL)
, mDescDialog(NULL)
{
{
// Centre dialog
center();
@ -444,18 +440,18 @@ CreateClassDialog::CreateClassDialog()
setSpecialization(0);
update();
}
}
CreateClassDialog::~CreateClassDialog()
{
CreateClassDialog::~CreateClassDialog()
{
delete mSpecDialog;
delete mAttribDialog;
delete mSkillDialog;
delete mDescDialog;
}
}
void CreateClassDialog::update()
{
void CreateClassDialog::update()
{
for (int i = 0; i < 5; ++i)
{
ToolTips::createSkillToolTip(mMajorSkill[i], mMajorSkill[i]->getSkillId());
@ -464,53 +460,53 @@ void CreateClassDialog::update()
ToolTips::createAttributeToolTip(mFavoriteAttribute0, mFavoriteAttribute0->getAttributeId());
ToolTips::createAttributeToolTip(mFavoriteAttribute1, mFavoriteAttribute1->getAttributeId());
}
}
std::string CreateClassDialog::getName() const
{
std::string CreateClassDialog::getName() const
{
return mEditName->getOnlyText();
}
}
std::string CreateClassDialog::getDescription() const
{
std::string CreateClassDialog::getDescription() const
{
return mDescription;
}
}
ESM::Class::Specialization CreateClassDialog::getSpecializationId() const
{
ESM::Class::Specialization CreateClassDialog::getSpecializationId() const
{
return mSpecializationId;
}
}
std::vector<int> CreateClassDialog::getFavoriteAttributes() const
{
std::vector<int> CreateClassDialog::getFavoriteAttributes() const
{
std::vector<int> v;
v.push_back(mFavoriteAttribute0->getAttributeId());
v.push_back(mFavoriteAttribute1->getAttributeId());
return v;
}
}
std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMajorSkills() const
{
std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMajorSkills() const
{
std::vector<ESM::Skill::SkillEnum> v;
for(int i = 0; i < 5; i++)
{
v.push_back(mMajorSkill[i]->getSkillId());
}
return v;
}
}
std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMinorSkills() const
{
std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMinorSkills() const
{
std::vector<ESM::Skill::SkillEnum> v;
for(int i=0; i < 5; i++)
{
v.push_back(mMinorSkill[i]->getSkillId());
}
return v;
}
}
void CreateClassDialog::setNextButtonShow(bool shown)
{
void CreateClassDialog::setNextButtonShow(bool shown)
{
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
@ -518,12 +514,12 @@ void CreateClassDialog::setNextButtonShow(bool shown)
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
else
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
}
// widget controls
// widget controls
void CreateClassDialog::onDialogCancel()
{
void CreateClassDialog::onDialogCancel()
{
MWBase::Environment::get().getWindowManager()->removeDialog(mSpecDialog);
mSpecDialog = 0;
@ -535,28 +531,28 @@ void CreateClassDialog::onDialogCancel()
MWBase::Environment::get().getWindowManager()->removeDialog(mDescDialog);
mDescDialog = 0;
}
}
void CreateClassDialog::onSpecializationClicked(MyGUI::Widget* _sender)
{
void CreateClassDialog::onSpecializationClicked(MyGUI::Widget* _sender)
{
delete mSpecDialog;
mSpecDialog = new SelectSpecializationDialog();
mSpecDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
mSpecDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected);
mSpecDialog->setVisible(true);
}
}
void CreateClassDialog::onSpecializationSelected()
{
void CreateClassDialog::onSpecializationSelected()
{
mSpecializationId = mSpecDialog->getSpecializationId();
setSpecialization(mSpecializationId);
MWBase::Environment::get().getWindowManager()->removeDialog(mSpecDialog);
mSpecDialog = 0;
}
}
void CreateClassDialog::setSpecialization(int id)
{
void CreateClassDialog::setSpecialization(int id)
{
mSpecializationId = (ESM::Class::Specialization) id;
static const char *specIds[3] = {
"sSpecializationCombat",
@ -566,20 +562,20 @@ void CreateClassDialog::setSpecialization(int id)
std::string specName = MWBase::Environment::get().getWindowManager()->getGameSettingString(specIds[mSpecializationId], specIds[mSpecializationId]);
mSpecializationName->setCaption(specName);
ToolTips::createSpecializationToolTip(mSpecializationName, specName, mSpecializationId);
}
}
void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{
void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{
delete mAttribDialog;
mAttribDialog = new SelectAttributeDialog();
mAffectedAttribute = _sender;
mAttribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
mAttribDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected);
mAttribDialog->setVisible(true);
}
}
void CreateClassDialog::onAttributeSelected()
{
void CreateClassDialog::onAttributeSelected()
{
ESM::Attribute::AttributeID id = mAttribDialog->getAttributeId();
if (mAffectedAttribute == mFavoriteAttribute0)
{
@ -596,20 +592,20 @@ void CreateClassDialog::onAttributeSelected()
mAttribDialog = 0;
update();
}
}
void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{
void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{
delete mSkillDialog;
mSkillDialog = new SelectSkillDialog();
mAffectedSkill = _sender;
mSkillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
mSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected);
mSkillDialog->setVisible(true);
}
}
void CreateClassDialog::onSkillSelected()
{
void CreateClassDialog::onSkillSelected()
{
ESM::Skill::SkillEnum id = mSkillDialog->getSkillId();
// Avoid duplicate skills by swapping any skill field that matches the selected one
@ -629,40 +625,40 @@ void CreateClassDialog::onSkillSelected()
MWBase::Environment::get().getWindowManager()->removeDialog(mSkillDialog);
mSkillDialog = 0;
update();
}
}
void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender)
{
void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender)
{
mDescDialog = new DescriptionDialog();
mDescDialog->setTextInput(mDescription);
mDescDialog->eventDone += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered);
mDescDialog->setVisible(true);
}
}
void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
{
void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
{
mDescription = mDescDialog->getTextInput();
MWBase::Environment::get().getWindowManager()->removeDialog(mDescDialog);
mDescDialog = 0;
}
}
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
{
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
{
if(getName().size() <= 0)
return;
eventDone(this);
}
}
void CreateClassDialog::onBackClicked(MyGUI::Widget* _sender)
{
void CreateClassDialog::onBackClicked(MyGUI::Widget* _sender)
{
eventBack();
}
}
/* SelectSpecializationDialog */
/* SelectSpecializationDialog */
SelectSpecializationDialog::SelectSpecializationDialog()
SelectSpecializationDialog::SelectSpecializationDialog()
: WindowModal("openmw_chargen_select_specialization.layout")
{
{
// Centre dialog
center();
@ -691,16 +687,16 @@ SelectSpecializationDialog::SelectSpecializationDialog()
getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked);
}
}
SelectSpecializationDialog::~SelectSpecializationDialog()
{
}
SelectSpecializationDialog::~SelectSpecializationDialog()
{
}
// widget controls
// widget controls
void SelectSpecializationDialog::onSpecializationClicked(MyGUI::Widget* _sender)
{
void SelectSpecializationDialog::onSpecializationClicked(MyGUI::Widget* _sender)
{
if (_sender == mSpecialization0)
mSpecializationId = ESM::Class::Combat;
else if (_sender == mSpecialization1)
@ -711,18 +707,18 @@ void SelectSpecializationDialog::onSpecializationClicked(MyGUI::Widget* _sender)
return;
eventItemSelected();
}
}
void SelectSpecializationDialog::onCancelClicked(MyGUI::Widget* _sender)
{
void SelectSpecializationDialog::onCancelClicked(MyGUI::Widget* _sender)
{
eventCancel();
}
}
/* SelectAttributeDialog */
/* SelectAttributeDialog */
SelectAttributeDialog::SelectAttributeDialog()
SelectAttributeDialog::SelectAttributeDialog()
: WindowModal("openmw_chargen_select_attribute.layout")
{
{
// Centre dialog
center();
@ -743,32 +739,32 @@ SelectAttributeDialog::SelectAttributeDialog()
getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked);
}
}
SelectAttributeDialog::~SelectAttributeDialog()
{
}
SelectAttributeDialog::~SelectAttributeDialog()
{
}
// widget controls
// widget controls
void SelectAttributeDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{
void SelectAttributeDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{
// TODO: Change MWAttribute to set and get AttributeID enum instead of int
mAttributeId = static_cast<ESM::Attribute::AttributeID>(_sender->getAttributeId());
eventItemSelected();
}
}
void SelectAttributeDialog::onCancelClicked(MyGUI::Widget* _sender)
{
void SelectAttributeDialog::onCancelClicked(MyGUI::Widget* _sender)
{
eventCancel();
}
}
/* SelectSkillDialog */
/* SelectSkillDialog */
SelectSkillDialog::SelectSkillDialog()
SelectSkillDialog::SelectSkillDialog()
: WindowModal("openmw_chargen_select_skill.layout")
{
{
// Centre dialog
center();
@ -835,30 +831,30 @@ SelectSkillDialog::SelectSkillDialog()
getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked);
}
}
SelectSkillDialog::~SelectSkillDialog()
{
}
SelectSkillDialog::~SelectSkillDialog()
{
}
// widget controls
// widget controls
void SelectSkillDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{
void SelectSkillDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{
mSkillId = _sender->getSkillId();
eventItemSelected();
}
}
void SelectSkillDialog::onCancelClicked(MyGUI::Widget* _sender)
{
void SelectSkillDialog::onCancelClicked(MyGUI::Widget* _sender)
{
eventCancel();
}
}
/* DescriptionDialog */
/* DescriptionDialog */
DescriptionDialog::DescriptionDialog()
DescriptionDialog::DescriptionDialog()
: WindowModal("openmw_chargen_class_description.layout")
{
{
// Centre dialog
center();
@ -871,15 +867,17 @@ DescriptionDialog::DescriptionDialog()
// Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
}
DescriptionDialog::~DescriptionDialog()
{
}
DescriptionDialog::~DescriptionDialog()
{
}
// widget controls
// widget controls
void DescriptionDialog::onOkClicked(MyGUI::Widget* _sender)
{
void DescriptionDialog::onOkClicked(MyGUI::Widget* _sender)
{
eventDone(this);
}
}

View file

@ -2,7 +2,6 @@
#include <boost/lexical_cast.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/dialoguemanager.hpp"

View file

@ -1,10 +1,5 @@
#include "confirmationdialog.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWGui
{
ConfirmationDialog::ConfirmationDialog() :

View file

@ -1,13 +1,7 @@
#include "console.hpp"
#include <algorithm>
#include <fstream>
#include <components/compiler/exception.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwscript/extensions.hpp"
#include "../mwbase/environment.hpp"
@ -284,16 +278,15 @@ namespace MWGui
std::string Console::complete( std::string input, std::vector<std::string> &matches )
{
using namespace std;
string output=input;
string tmp=input;
std::string output = input;
std::string tmp = input;
bool has_front_quote = false;
/* Does the input string contain things that don't have to be completed? If yes erase them. */
/* Are there quotation marks? */
if( tmp.find('"') != string::npos ) {
if( tmp.find('"') != std::string::npos ) {
int numquotes=0;
for(string::iterator it=tmp.begin(); it < tmp.end(); ++it) {
for(std::string::iterator it=tmp.begin(); it < tmp.end(); ++it) {
if( *it == '"' )
numquotes++;
}
@ -305,7 +298,7 @@ namespace MWGui
}
else {
size_t pos;
if( ( ((pos = tmp.rfind(' ')) != string::npos ) ) && ( pos > tmp.rfind('"') ) ) {
if( ( ((pos = tmp.rfind(' ')) != std::string::npos ) ) && ( pos > tmp.rfind('"') ) ) {
tmp.erase( 0, tmp.rfind(' ')+1);
}
else {
@ -317,7 +310,7 @@ namespace MWGui
/* No quotation marks. Are there spaces?*/
else {
size_t rpos;
if( (rpos=tmp.rfind(' ')) != string::npos ) {
if( (rpos=tmp.rfind(' ')) != std::string::npos ) {
if( rpos == 0 ) {
tmp.clear();
}
@ -336,7 +329,7 @@ namespace MWGui
}
/* Iterate through the vector. */
for(vector<string>::iterator it=mNames.begin(); it < mNames.end();++it) {
for(std::vector<std::string>::iterator it=mNames.begin(); it < mNames.end();++it) {
bool string_different=false;
/* Is the string shorter than the input string? If yes skip it. */
@ -344,7 +337,7 @@ namespace MWGui
continue;
/* Is the beginning of the string different from the input string? If yes skip it. */
for( string::iterator iter=tmp.begin(), iter2=(*it).begin(); iter < tmp.end();iter++, iter2++) {
for( std::string::iterator iter=tmp.begin(), iter2=(*it).begin(); iter < tmp.end();iter++, iter2++) {
if( tolower(*iter) != tolower(*iter2) ) {
string_different=true;
break;
@ -367,24 +360,24 @@ namespace MWGui
/* Only one match. We're done. */
if( matches.size() == 1 ) {
/* Adding quotation marks when the input string started with a quotation mark or has spaces in it*/
if( ( matches.front().find(' ') != string::npos ) ) {
if( ( matches.front().find(' ') != std::string::npos ) ) {
if( !has_front_quote )
output.append(string("\""));
return output.append(matches.front() + string("\" "));
output.append(std::string("\""));
return output.append(matches.front() + std::string("\" "));
}
else if( has_front_quote ) {
return output.append(matches.front() + string("\" "));
return output.append(matches.front() + std::string("\" "));
}
else {
return output.append(matches.front() + string(" "));
return output.append(matches.front() + std::string(" "));
}
}
/* Check if all matching strings match further than input. If yes complete to this match. */
int i = tmp.length();
for(string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) {
for(vector<string>::iterator it=matches.begin(); it < matches.end();++it) {
for(std::string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) {
for(std::vector<std::string>::iterator it=matches.begin(); it < matches.end();++it) {
if( tolower((*it)[i]) != tolower(*iter) ) {
/* Append the longest match to the end of the output string*/
output.append(matches.front().substr( 0, i));

View file

@ -1,11 +1,5 @@
#include "container.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <cassert>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
@ -13,23 +7,13 @@
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwclass/container.hpp"
#include "widgets.hpp"
#include "countdialog.hpp"
#include "tradewindow.hpp"
#include "inventorywindow.hpp"
using namespace MWGui;
using namespace Widgets;
namespace
{
bool compareType(std::string type1, std::string type2)
@ -80,30 +64,32 @@ namespace
}
}
namespace MWGui
{
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop)
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop)
: mDragAndDrop(dragAndDrop)
, mFilter(ContainerBase::Filter_All)
, mDisplayEquippedItems(true)
, mHighlightEquippedItems(true)
{
}
{
}
void ContainerBase::setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView)
{
void ContainerBase::setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView)
{
mContainerWidget = containerWidget;
mItemView = itemView;
mContainerWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onContainerClicked);
mContainerWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerWindow::onMouseWheel);
}
}
ContainerBase::~ContainerBase()
{
}
ContainerBase::~ContainerBase()
{
}
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
{
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
{
mSelectedItem = _sender;
if (mDragAndDrop && !isTrading())
@ -194,10 +180,10 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
{
onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>());
}
}
}
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
{
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
{
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
if (isInventory())
@ -217,10 +203,10 @@ void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
drawItems();
}
}
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
{
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
{
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
if (isInventory())
@ -240,10 +226,10 @@ void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
drawItems();
}
}
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
{
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
{
mDragAndDrop->mIsOnDragAndDrop = true;
mSelectedItem->detachFromWidget();
mSelectedItem->attachToWidget(mDragAndDrop->mDragAndDropWidget);
@ -266,10 +252,10 @@ void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
drawItems();
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
}
}
void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
{
void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
{
if (mDragAndDrop == NULL) return;
if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
@ -343,29 +329,29 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
}
}
}
void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mItemView->getViewOffset().left + _rel*0.3 > 0)
mItemView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
}
}
void ContainerBase::setFilter(int filter)
{
void ContainerBase::setFilter(int filter)
{
mFilter = filter;
drawItems();
}
}
void ContainerBase::openContainer(MWWorld::Ptr container)
{
void ContainerBase::openContainer(MWWorld::Ptr container)
{
mPtr = container;
}
}
void ContainerBase::drawItems()
{
void ContainerBase::drawItems()
{
while (mContainerWidget->getChildCount())
{
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
@ -570,28 +556,28 @@ void ContainerBase::drawItems()
mContainerWidget->setSize(size);
notifyContentChanged();
}
}
std::string ContainerBase::getCountString(const int count)
{
std::string ContainerBase::getCountString(const int count)
{
if (count == 1)
return "";
if (count > 9999)
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
else
return boost::lexical_cast<std::string>(count);
}
}
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
{
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
{
int origCount = item.getRefData().getCount();
item.getRefData().setCount(count);
MWWorld::ContainerStoreIterator it = mBoughtItems.add(item);
item.getRefData().setCount(origCount - count);
}
}
void ContainerBase::addItem(MWWorld::Ptr item, int count)
{
void ContainerBase::addItem(MWWorld::Ptr item, int count)
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
int origCount = item.getRefData().getCount();
@ -600,28 +586,28 @@ void ContainerBase::addItem(MWWorld::Ptr item, int count)
MWWorld::ContainerStoreIterator it = containerStore.add(item);
item.getRefData().setCount(origCount - count);
}
}
void ContainerBase::transferBoughtItems()
{
void ContainerBase::transferBoughtItems()
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
{
containerStore.add(*it);
}
}
}
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
{
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
{
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
{
store.add(*it);
}
}
}
std::vector<MWWorld::Ptr> ContainerBase::getEquippedItems()
{
std::vector<MWWorld::Ptr> ContainerBase::getEquippedItems()
{
if (mPtr.getTypeName() != typeid(ESM::NPC).name())
return std::vector<MWWorld::Ptr>();
@ -639,20 +625,20 @@ std::vector<MWWorld::Ptr> ContainerBase::getEquippedItems()
}
return items;
}
}
MWWorld::ContainerStore& ContainerBase::getContainerStore()
{
MWWorld::ContainerStore& ContainerBase::getContainerStore()
{
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
return store;
}
}
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
: ContainerBase(dragAndDrop)
, WindowBase("openmw_container_window.layout")
{
{
getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
getWidget(mTakeButton, "TakeButton");
getWidget(mCloseButton, "CloseButton");
@ -670,19 +656,19 @@ ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ContainerWindow::onWindowResize);
setCoord(200,0,600,300);
}
}
ContainerWindow::~ContainerWindow()
{
}
ContainerWindow::~ContainerWindow()
{
}
void ContainerWindow::onWindowResize(MyGUI::Window* window)
{
void ContainerWindow::onWindowResize(MyGUI::Window* window)
{
drawItems();
}
}
void ContainerWindow::open(MWWorld::Ptr container, bool loot)
{
void ContainerWindow::open(MWWorld::Ptr container, bool loot)
{
mDisplayEquippedItems = true;
mHighlightEquippedItems = false;
if (container.getTypeName() == typeid(ESM::NPC).name() && !loot)
@ -696,18 +682,18 @@ void ContainerWindow::open(MWWorld::Ptr container, bool loot)
openContainer(container);
setTitle(MWWorld::Class::get(container).getName(container));
drawItems();
}
}
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
}
}
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
{
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
// transfer everything into the player's inventory
@ -741,10 +727,10 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
}
}
void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
{
void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
onTakeAllButtonClicked(mTakeButton);
@ -757,9 +743,11 @@ void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
mPtr = MWWorld::Ptr();
}
}
}
void ContainerWindow::onReferenceUnavailable()
{
void ContainerWindow::onReferenceUnavailable()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
}

View file

@ -2,9 +2,6 @@
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWGui
{
CountDialog::CountDialog() :

View file

@ -2,13 +2,11 @@
#include <MyGUI_PointerManager.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_RenderManager.h>
#include <MyGUI_RotatingSkin.h>
#include <MyGUI_Gui.h>
#include <OgreMath.h>
namespace MWGui
{

View file

@ -1,18 +1,11 @@
#include "dialogue.hpp"
#include <iostream>
#include <iterator>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/dialoguemanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwmechanics/npcstats.hpp"
@ -26,38 +19,37 @@
#include "inventorywindow.hpp"
#include "travelwindow.hpp"
using namespace MWGui;
using namespace Widgets;
/**
*Copied from the internet.
*/
namespace {
std::string lower_string(const std::string& str)
namespace
{
std::string lower_string(const std::string& str)
{
std::string lowerCase = Misc::StringUtils::lowerCase (str);
return lowerCase;
}
}
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
return lower_string(str).find(lower_string(substr),pos);
}
}
bool sortByLength (const std::string& left, const std::string& right)
{
bool sortByLength (const std::string& left, const std::string& right)
{
return left.size() > right.size();
}
}
}
PersuasionDialog::PersuasionDialog()
: WindowModal("openmw_persuasion_dialog.layout")
namespace MWGui
{
PersuasionDialog::PersuasionDialog()
: WindowModal("openmw_persuasion_dialog.layout")
{
getWidget(mCancelButton, "CancelButton");
getWidget(mAdmireButton, "AdmireButton");
getWidget(mIntimidateButton, "IntimidateButton");
@ -74,15 +66,15 @@ PersuasionDialog::PersuasionDialog()
mBribe10Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mBribe100Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mBribe1000Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
}
}
void PersuasionDialog::onCancel(MyGUI::Widget *sender)
{
void PersuasionDialog::onCancel(MyGUI::Widget *sender)
{
setVisible(false);
}
}
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
{
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
{
MWBase::MechanicsManager::PersuasionType type;
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
@ -106,10 +98,10 @@ void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
MWBase::Environment::get().getDialogueManager()->persuade(type);
setVisible(false);
}
}
void PersuasionDialog::open()
{
void PersuasionDialog::open()
{
WindowModal::open();
center();
@ -120,16 +112,16 @@ void PersuasionDialog::open()
mBribe1000Button->setEnabled (playerGold >= 1000);
mGoldLabel->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
}
}
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
DialogueWindow::DialogueWindow()
DialogueWindow::DialogueWindow()
: WindowBase("openmw_dialogue_window.layout")
, mPersuasionDialog()
, mEnabled(false)
, mServices(0)
{
{
// Centre dialog
center();
@ -159,10 +151,10 @@ DialogueWindow::DialogueWindow()
getWidget(mDispositionText,"DispositionText");
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
}
}
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
{
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
{
MyGUI::ISubWidgetText* t = mHistory->getClient()->getSubWidgetText();
if(t == NULL)
return;
@ -206,28 +198,28 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
if(color == "#572D21")
MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key));
}
}
}
void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
{
void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
{
mTopicsList->adjustSize();
}
}
void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mHistory->getVScrollPosition() - _rel*0.3 < 0)
mHistory->setVScrollPosition(0);
else
mHistory->setVScrollPosition(mHistory->getVScrollPosition() - _rel*0.3);
}
}
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
}
}
void DialogueWindow::onSelectTopic(const std::string& topic, int id)
{
void DialogueWindow::onSelectTopic(const std::string& topic, int id)
{
if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
return;
@ -293,10 +285,10 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id)
}
}
}
}
}
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
{
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
{
mEnabled = true;
mPtr = actor;
mTopicsList->setEnabled(true);
@ -306,10 +298,10 @@ void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
mHyperLinks.clear();
mHistory->setCaption("");
updateOptions();
}
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
mTopicsList->clear();
bool isCompanion = !MWWorld::Class::get(mPtr).getScript(mPtr).empty()
@ -356,19 +348,19 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
mTopicsList->addItem(*it);
}
mTopicsList->adjustSize();
}
}
void DialogueWindow::removeKeyword(std::string keyWord)
{
void DialogueWindow::removeKeyword(std::string keyWord)
{
if(mTopicsList->hasItem(keyWord))
{
mTopicsList->removeItem(keyWord);
}
mTopicsList->adjustSize();
}
}
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
{
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
{
size_t pos = 0;
while((pos = find_str_ci(str,keyword, pos)) != std::string::npos)
{
@ -394,10 +386,10 @@ void addColorInString(std::string& str, const std::string& keyword,std::string c
str.insert(pos,color2);
pos+= color2.length();
}
}
}
std::string DialogueWindow::parseText(const std::string& text)
{
std::string DialogueWindow::parseText(const std::string& text)
{
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
std::vector<std::string> topics;
@ -471,20 +463,20 @@ std::string DialogueWindow::parseText(const std::string& text)
}
return result;
}
}
void DialogueWindow::addText(std::string text)
{
void DialogueWindow::addText(std::string text)
{
mHistory->addDialogText("#B29154"+parseText(text)+"#B29154");
}
}
void DialogueWindow::addMessageBox(const std::string& text)
{
void DialogueWindow::addMessageBox(const std::string& text)
{
mHistory->addDialogText("\n#FFFFFF"+text+"#B29154");
}
}
void DialogueWindow::addTitle(std::string text)
{
void DialogueWindow::addTitle(std::string text)
{
// This is called from the dialogue manager, so text is
// case-smashed - thus we have to retrieve the correct case
// of the text through the topic list.
@ -496,15 +488,15 @@ void DialogueWindow::addTitle(std::string text)
}
mHistory->addDialogHeading(text);
}
}
void DialogueWindow::askQuestion(std::string question)
{
void DialogueWindow::askQuestion(std::string question)
{
mHistory->addDialogText("#572D21"+question+"#B29154"+" ");
}
}
void DialogueWindow::updateOptions()
{
void DialogueWindow::updateOptions()
{
//Clear the list of topics
mTopicsList->clear();
mHyperLinks.clear();
@ -517,22 +509,22 @@ void DialogueWindow::updateOptions()
mDispositionText->eraseText(0, mDispositionText->getTextLength());
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100")+"#B29154");
}
}
}
void DialogueWindow::goodbye()
{
void DialogueWindow::goodbye()
{
mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString());
mTopicsList->setEnabled(false);
mEnabled = false;
}
}
void DialogueWindow::onReferenceUnavailable()
{
void DialogueWindow::onReferenceUnavailable()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
}
}
void DialogueWindow::onFrame()
{
void DialogueWindow::onFrame()
{
if(mMainWidget->getVisible() && mEnabled && mPtr.getTypeName() == typeid(ESM::NPC).name())
{
int disp = std::max(0, std::min(100,
@ -543,4 +535,5 @@ void DialogueWindow::onFrame()
mDispositionText->eraseText(0, mDispositionText->getTextLength());
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(disp)+std::string("/100")+"#B29154");
}
}
}

View file

@ -12,11 +12,11 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
using namespace MWGui;
using namespace Widgets;
MyGUI::UString DialogueHistory::getColorAtPos(size_t _pos)
namespace MWGui
{
MyGUI::UString DialogueHistory::getColorAtPos(size_t _pos)
{
MyGUI::UString colour = MyGUI::TextIterator::convertTagColour(getTextColour());
MyGUI::TextIterator iterator(getCaption());
while(iterator.moveNext())
@ -29,10 +29,10 @@ MyGUI::UString DialogueHistory::getColorAtPos(size_t _pos)
break;
}
return colour;
}
}
MyGUI::UString DialogueHistory::getColorTextAt(size_t _pos)
{
MyGUI::UString DialogueHistory::getColorTextAt(size_t _pos)
{
bool breakOnNext = false;
MyGUI::UString colour = MyGUI::TextIterator::convertTagColour(getTextColour());
MyGUI::UString colour2 = colour;
@ -59,18 +59,20 @@ MyGUI::UString DialogueHistory::getColorTextAt(size_t _pos)
}
}
return "";
}
}
void DialogueHistory::addDialogHeading(const MyGUI::UString& parText)
{
void DialogueHistory::addDialogHeading(const MyGUI::UString& parText)
{
MyGUI::UString head("\n#D8C09A");
head.append(parText);
head.append("#B29154\n");
addText(head);
}
}
void DialogueHistory::addDialogText(const MyGUI::UString& parText)
{
void DialogueHistory::addDialogText(const MyGUI::UString& parText)
{
addText(parText);
addText("\n");
}
}

View file

@ -3,15 +3,12 @@
#include <components/interpreter/defines.hpp>
#include "../mwscript/interpretercontext.hpp"
#include "../mwworld/ptr.hpp"
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/lexical_cast.hpp>
#include <OgreUTFString.h>
using namespace MWGui;
namespace
{
int convertFromHex(std::string hex)
@ -79,8 +76,11 @@ namespace
}
}
std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
namespace MWGui
{
std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
{
using Ogre::UTFString;
std::vector<std::string> result;
@ -178,23 +178,23 @@ std::vector<std::string> BookTextParser::split(std::string utf8Text, const int w
}
return result;
}
}
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const
{
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const
{
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
return MyGUI::FontManager::getInstance().getByName(fontName)
->getGlyphInfo(unicodeChar)->width;
}
}
float BookTextParser::currentFontHeight() const
{
float BookTextParser::currentFontHeight() const
{
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
}
}
MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width)
{
MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width)
{
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
text = Interpreter::fixDefinesBook(text, interpreterContext);
@ -213,8 +213,8 @@ MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, co
boost::algorithm::replace_all(text, "<P>", "\n\n");
// remove leading newlines
// while (text[0] == '\n')
// text.erase(0);
// while (text[0] == '\n')
// text.erase(0);
// remove trailing "
if (text[text.size()-1] == '\"')
@ -222,10 +222,10 @@ MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, co
parseSubText(text);
return MyGUI::IntSize(mWidth, mHeight);
}
}
void BookTextParser::parseImage(std::string tag, bool createWidget)
{
void BookTextParser::parseImage(std::string tag, bool createWidget)
{
int src_start = tag.find("SRC=")+5;
std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start);
@ -254,10 +254,10 @@ void BookTextParser::parseImage(std::string tag, bool createWidget)
mWidth = std::max(mWidth, width);
mHeight += height;
}
}
void BookTextParser::parseDiv(std::string tag)
{
void BookTextParser::parseDiv(std::string tag)
{
if (tag.find("ALIGN=") == std::string::npos)
return;
@ -267,10 +267,10 @@ void BookTextParser::parseDiv(std::string tag)
mTextStyle.mTextAlign = MyGUI::Align::HCenter;
else if (align == "LEFT")
mTextStyle.mTextAlign = MyGUI::Align::Left;
}
}
void BookTextParser::parseFont(std::string tag)
{
void BookTextParser::parseFont(std::string tag)
{
if (tag.find("COLOR=") != std::string::npos)
{
int color_start = tag.find("COLOR=")+7;
@ -293,10 +293,10 @@ void BookTextParser::parseFont(std::string tag)
{
/// \todo
}
}
}
void BookTextParser::parseSubText(std::string text)
{
void BookTextParser::parseSubText(std::string text)
{
if (text[0] == '<')
{
const size_t tagStart = 1;
@ -362,4 +362,6 @@ void BookTextParser::parseSubText(std::string text)
{
parseSubText(text.substr(tagStart, text.size()));
}
}
}

View file

@ -1,30 +1,21 @@
#include "hud.hpp"
#include <cmath>
#include <MyGUI_Widget.h>
#include <MyGUI_RenderManager.h>
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwgui/widgets.hpp"
#include "inventorywindow.hpp"
#include "container.hpp"
#include "console.hpp"
#include "spellicons.hpp"
using namespace MWGui;
namespace MWGui
{
HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
: Layout("openmw_hud.layout")
, mHealth(NULL)
, mMagicka(NULL)
@ -53,7 +44,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
, mWeaponVisible(true)
, mSpellVisible(true)
, mWorldMouseOver(false)
{
{
setCoord(0,0, width, height);
// Energy bars
@ -113,15 +104,15 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
mSpellIcons = new SpellIcons();
}
}
HUD::~HUD()
{
HUD::~HUD()
{
delete mSpellIcons;
}
}
void HUD::setFpsLevel(int level)
{
void HUD::setFpsLevel(int level)
{
mFpsCounter = 0;
MyGUI::Widget* fps;
@ -142,26 +133,26 @@ void HUD::setFpsLevel(int level)
mFpsBox->setVisible(true);
getWidget(mFpsCounter, "FPSCounter");
}
}
}
void HUD::setFPS(float fps)
{
void HUD::setFPS(float fps)
{
if (mFpsCounter)
mFpsCounter->setCaption(boost::lexical_cast<std::string>((int)fps));
}
}
void HUD::setTriangleCount(unsigned int count)
{
void HUD::setTriangleCount(unsigned int count)
{
mTriangleCounter->setCaption(boost::lexical_cast<std::string>(count));
}
}
void HUD::setBatchCount(unsigned int count)
{
void HUD::setBatchCount(unsigned int count)
{
mBatchCounter->setCaption(boost::lexical_cast<std::string>(count));
}
}
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
static const char *ids[] =
{
"HBar", "MBar", "FBar", 0
@ -194,10 +185,10 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>&
break;
}
}
}
}
void HUD::onWorldClicked(MyGUI::Widget* _sender)
{
void HUD::onWorldClicked(MyGUI::Widget* _sender)
{
if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ())
return;
@ -254,10 +245,10 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender)
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object);
}
}
}
}
void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
{
void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
{
if (mDragAndDrop->mIsOnDragAndDrop)
{
mWorldMouseOver = false;
@ -283,36 +274,36 @@ void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
mWorldMouseOver = true;
}
}
}
void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new)
{
void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new)
{
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
mWorldMouseOver = false;
}
}
void HUD::onHMSClicked(MyGUI::Widget* _sender)
{
void HUD::onHMSClicked(MyGUI::Widget* _sender)
{
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Stats);
}
}
void HUD::onMapClicked(MyGUI::Widget* _sender)
{
void HUD::onMapClicked(MyGUI::Widget* _sender)
{
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Map);
}
}
void HUD::onWeaponClicked(MyGUI::Widget* _sender)
{
void HUD::onWeaponClicked(MyGUI::Widget* _sender)
{
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Inventory);
}
}
void HUD::onMagicClicked(MyGUI::Widget* _sender)
{
void HUD::onMagicClicked(MyGUI::Widget* _sender)
{
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Magic);
}
}
void HUD::setCellName(const std::string& cellName)
{
void HUD::setCellName(const std::string& cellName)
{
if (mCellName != cellName)
{
mCellNameTimer = 5.0f;
@ -321,25 +312,25 @@ void HUD::setCellName(const std::string& cellName)
mCellNameBox->setCaptionWithReplacing("#{sCell=" + mCellName + "}");
mCellNameBox->setVisible(mMapVisible);
}
}
}
void HUD::onFrame(float dt)
{
void HUD::onFrame(float dt)
{
mCellNameTimer -= dt;
mWeaponSpellTimer -= dt;
if (mCellNameTimer < 0)
mCellNameBox->setVisible(false);
if (mWeaponSpellTimer < 0)
mWeaponSpellBox->setVisible(false);
}
}
void HUD::onResChange(int width, int height)
{
void HUD::onResChange(int width, int height)
{
setCoord(0, 0, width, height);
}
}
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
const ESM::Spell* spell =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
@ -371,10 +362,10 @@ void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
icon = std::string("icons\\") + icon;
Widgets::fixTexturePath(icon);
mSpellImage->setImageTexture(icon);
}
}
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
{
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
{
std::string itemName = MWWorld::Class::get(item).getName(item);
if (itemName != mSpellName && mSpellVisible)
{
@ -402,10 +393,10 @@ void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
Widgets::fixTexturePath(path);
itemBox->setImageTexture(path);
itemBox->setNeedMouseFocus(false);
}
}
void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
{
void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
{
std::string itemName = MWWorld::Class::get(item).getName(item);
if (itemName != mWeaponName && mWeaponVisible)
{
@ -438,10 +429,10 @@ void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
}
else
mWeapImage->setImageTexture(path);
}
}
void HUD::unsetSelectedSpell()
{
void HUD::unsetSelectedSpell()
{
std::string spellName = "#{sNone}";
if (spellName != mSpellName && mSpellVisible)
{
@ -457,10 +448,10 @@ void HUD::unsetSelectedSpell()
mSpellStatus->setProgressPosition(0);
mSpellImage->setImageTexture("");
mSpellBox->clearUserStrings();
}
}
void HUD::unsetSelectedWeapon()
{
void HUD::unsetSelectedWeapon()
{
std::string itemName = "#{sSkillHandtohand}";
if (itemName != mWeaponName && mWeaponVisible)
{
@ -476,47 +467,47 @@ void HUD::unsetSelectedWeapon()
mWeapStatus->setProgressPosition(0);
mWeapImage->setImageTexture("icons\\k\\stealth_handtohand.dds");
mWeapBox->clearUserStrings();
}
}
void HUD::setCrosshairVisible(bool visible)
{
void HUD::setCrosshairVisible(bool visible)
{
mCrosshair->setVisible (visible);
}
}
void HUD::setHmsVisible(bool visible)
{
void HUD::setHmsVisible(bool visible)
{
mHealth->setVisible(visible);
mMagicka->setVisible(visible);
mStamina->setVisible(visible);
updatePositions();
}
}
void HUD::setWeapVisible(bool visible)
{
void HUD::setWeapVisible(bool visible)
{
mWeapBox->setVisible(visible);
updatePositions();
}
}
void HUD::setSpellVisible(bool visible)
{
void HUD::setSpellVisible(bool visible)
{
mSpellBox->setVisible(visible);
updatePositions();
}
}
void HUD::setEffectVisible(bool visible)
{
void HUD::setEffectVisible(bool visible)
{
mEffectBox->setVisible (visible);
updatePositions();
}
}
void HUD::setMinimapVisible(bool visible)
{
void HUD::setMinimapVisible(bool visible)
{
mMinimapBox->setVisible (visible);
updatePositions();
}
}
void HUD::updatePositions()
{
void HUD::updatePositions()
{
int weapDx = 0, spellDx = 0;
if (!mHealth->getVisible())
spellDx = weapDx = mWeapBoxBaseLeft - mHealthManaStaminaBaseLeft;
@ -541,9 +532,11 @@ void HUD::updatePositions()
mMapVisible = mMinimapBox->getVisible ();
mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop());
}
}
void HUD::update()
{
void HUD::update()
{
mSpellIcons->updateWidgets(mEffectBox, true);
}
}

View file

@ -1,28 +1,15 @@
#include "inventorywindow.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <cassert>
#include <boost/lexical_cast.hpp>
#include <components/compiler/locals.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/inventorystore.hpp"
#include "widgets.hpp"
#include "bookwindow.hpp"
#include "scrollwindow.hpp"
#include "spellwindow.hpp"

View file

@ -4,9 +4,6 @@
#include "../mwbase/world.hpp"
#include "../mwbase/journal.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwdialogue/journalentry.hpp"
namespace
{

View file

@ -8,12 +8,10 @@
#include "../mwworld/player.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/fallback.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/stat.hpp"
namespace MWGui
{

View file

@ -5,18 +5,21 @@
#include <MyGUI_ImageBox.h>
#include <MyGUI_ScrollBar.h>
using namespace MWGui;
using namespace MWGui::Widgets;
namespace MWGui
{
MWList::MWList() :
namespace Widgets
{
MWList::MWList() :
mClient(0)
, mScrollView(0)
, mItemHeight(0)
{
}
{
}
void MWList::initialiseOverride()
{
void MWList::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(mClient, "Client");
@ -26,25 +29,25 @@ void MWList::initialiseOverride()
mScrollView = mClient->createWidgetReal<MWGui::Widgets::MWScrollView>(
"MW_ScrollView", MyGUI::FloatCoord(0.0, 0.0, 1.0, 1.0),
MyGUI::Align::Top | MyGUI::Align::Left | MyGUI::Align::Stretch, getName() + "_ScrollView");
}
}
void MWList::addItem(const std::string& name)
{
void MWList::addItem(const std::string& name)
{
mItems.push_back(name);
}
}
void MWList::addSeparator()
{
void MWList::addSeparator()
{
mItems.push_back("");
}
}
void MWList::adjustSize()
{
void MWList::adjustSize()
{
redraw();
}
}
void MWList::redraw(bool scrollbarShown)
{
void MWList::redraw(bool scrollbarShown)
{
const int _scrollBarWidth = 24; // fetch this from skin?
const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
const int spacing = 3;
@ -97,67 +100,70 @@ void MWList::redraw(bool scrollbarShown)
if(scrollbarPosition > scrollbarRange)
scrollbarPosition = scrollbarRange;
mScrollView->setScrollPosition(scrollbarPosition);
}
}
bool MWList::hasItem(const std::string& name)
{
bool MWList::hasItem(const std::string& name)
{
return (std::find(mItems.begin(), mItems.end(), name) != mItems.end());
}
}
unsigned int MWList::getItemCount()
{
unsigned int MWList::getItemCount()
{
return mItems.size();
}
}
std::string MWList::getItemNameAt(unsigned int at)
{
std::string MWList::getItemNameAt(unsigned int at)
{
assert(at < mItems.size() && "List item out of bounds");
return mItems[at];
}
}
void MWList::removeItem(const std::string& name)
{
void MWList::removeItem(const std::string& name)
{
assert( std::find(mItems.begin(), mItems.end(), name) != mItems.end() );
mItems.erase( std::find(mItems.begin(), mItems.end(), name) );
}
}
void MWList::clear()
{
void MWList::clear()
{
mItems.clear();
}
}
void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
//NB view offset is negative
if (mScrollView->getViewOffset().top + _rel*0.3 > 0)
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mScrollView->setViewOffset(MyGUI::IntPoint(0, mScrollView->getViewOffset().top + _rel*0.3));
}
}
void MWList::onItemSelected(MyGUI::Widget* _sender)
{
void MWList::onItemSelected(MyGUI::Widget* _sender)
{
std::string name = static_cast<MyGUI::Button*>(_sender)->getCaption();
int id = *_sender->getUserData<int>();
eventItemSelected(name, id);
eventWidgetSelected(_sender);
}
}
MyGUI::Widget* MWList::getItemWidget(const std::string& name)
{
MyGUI::Widget* MWList::getItemWidget(const std::string& name)
{
return mScrollView->findWidget (getName() + "_item_" + name);
}
}
size_t MWScrollView::getScrollPosition()
{
size_t MWScrollView::getScrollPosition()
{
return getVScroll()->getScrollPosition();
}
}
void MWScrollView::setScrollPosition(size_t position)
{
void MWScrollView::setScrollPosition(size_t position)
{
getVScroll()->setScrollPosition(position);
}
size_t MWScrollView::getScrollRange()
{
}
size_t MWScrollView::getScrollRange()
{
return getVScroll()->getScrollRange();
}
}
}

View file

@ -1,25 +1,16 @@
#include "loadingscreen.hpp"
#include <OgreRenderWindow.h>
#include <OgreRoot.h>
#include <OgreCompositorManager.h>
#include <OgreCompositorChain.h>
#include <OgreMaterial.h>
#include <boost/algorithm/string.hpp>
#include <openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include <components/esm/records.hpp>
namespace MWGui
{

View file

@ -3,7 +3,6 @@
#include <OgreRoot.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"

View file

@ -2,12 +2,8 @@
#include <boost/lexical_cast.hpp>
#include <OgreVector2.h>
#include <OgreTextureManager.h>
#include <OgreSceneNode.h>
#include <MyGUI_Gui.h>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
@ -17,9 +13,10 @@
#include "widgets.hpp"
using namespace MWGui;
namespace MWGui
{
LocalMapBase::LocalMapBase()
LocalMapBase::LocalMapBase()
: mCurX(0)
, mCurY(0)
, mInterior(false)
@ -34,11 +31,11 @@ LocalMapBase::LocalMapBase()
, mLastDirectionX(0.0f)
, mLastDirectionY(0.0f)
, mCompass(NULL)
{
}
{
}
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
{
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
{
mLocalMap = widget;
mLayout = layout;
mMapDragAndDrop = mapDragAndDrop;
@ -68,22 +65,22 @@ void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEn
mFogWidgets.push_back(fog);
}
}
}
}
void LocalMapBase::setCellPrefix(const std::string& prefix)
{
void LocalMapBase::setCellPrefix(const std::string& prefix)
{
mPrefix = prefix;
mChanged = true;
}
}
void LocalMapBase::toggleFogOfWar()
{
void LocalMapBase::toggleFogOfWar()
{
mFogOfWar = !mFogOfWar;
applyFogOfWar();
}
}
void LocalMapBase::applyFogOfWar()
{
void LocalMapBase::applyFogOfWar()
{
for (int mx=0; mx<3; ++mx)
{
for (int my=0; my<3; ++my)
@ -101,20 +98,20 @@ void LocalMapBase::applyFogOfWar()
}
}
notifyMapChanged ();
}
}
void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
{
void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
{
applyFogOfWar ();
}
}
void LocalMapBase::onMarkerUnfocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
{
void LocalMapBase::onMarkerUnfocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
{
applyFogOfWar ();
}
}
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
{
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
{
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
// clear all previous markers
@ -222,11 +219,11 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
std::string tex = "textures\\compass.dds";
mCompass->setImageTexture("");
mCompass->setImageTexture(tex);
}
}
void LocalMapBase::setPlayerPos(const float x, const float y)
{
void LocalMapBase::setPlayerPos(const float x, const float y)
{
if (x == mLastPositionX && y == mLastPositionY)
return;
@ -241,10 +238,10 @@ void LocalMapBase::setPlayerPos(const float x, const float y)
mCompass->setPosition(MyGUI::IntPoint(512+x*512-16, 512+y*512-16));
mLastPositionX = x;
mLastPositionY = y;
}
}
void LocalMapBase::setPlayerDir(const float x, const float y)
{
void LocalMapBase::setPlayerDir(const float x, const float y)
{
if (x == mLastDirectionX && y == mLastDirectionY)
return;
@ -258,14 +255,14 @@ void LocalMapBase::setPlayerDir(const float x, const float y)
mLastDirectionX = x;
mLastDirectionY = y;
}
}
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
MapWindow::MapWindow(const std::string& cacheDir)
MapWindow::MapWindow(const std::string& cacheDir)
: MWGui::WindowPinnableBase("openmw_map_window.layout")
, mGlobal(false)
{
{
setCoord(500,0,320,300);
mGlobalMapRender = new MWRender::GlobalMap(cacheDir);
@ -295,20 +292,20 @@ MapWindow::MapWindow(const std::string& cacheDir)
mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
LocalMapBase::init(mLocalMap, mPlayerArrowLocal, this);
}
}
MapWindow::~MapWindow()
{
MapWindow::~MapWindow()
{
delete mGlobalMapRender;
}
}
void MapWindow::setCellName(const std::string& cellName)
{
void MapWindow::setCellName(const std::string& cellName)
{
setTitle("#{sCell=" + cellName + "}");
}
}
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
{
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
{
float worldX, worldY;
mGlobalMapRender->cellTopLeftCornerToImageSpace (x, y, worldX, worldY);
@ -333,21 +330,21 @@ void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", name);
}
}
void MapWindow::cellExplored(int x, int y)
{
void MapWindow::cellExplored(int x, int y)
{
mGlobalMapRender->exploreCell(x,y);
}
}
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
if (_id!=MyGUI::MouseButton::Left) return;
mLastDragPos = MyGUI::IntPoint(_left, _top);
}
}
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
if (_id!=MyGUI::MouseButton::Left) return;
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
@ -359,10 +356,10 @@ void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::
mLastDragPos = MyGUI::IntPoint(_left, _top);
}
}
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
{
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
{
mGlobal = !mGlobal;
mGlobalMap->setVisible(mGlobal);
mLocalMap->setVisible(!mGlobal);
@ -372,15 +369,15 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
if (mGlobal)
globalMapUpdatePlayer ();
}
}
void MapWindow::onPinToggled()
{
void MapWindow::onPinToggled()
{
MWBase::Environment::get().getWindowManager()->setMinimapVisibility(!mPinned);
}
}
void MapWindow::open()
{
void MapWindow::open()
{
mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
@ -393,10 +390,10 @@ void MapWindow::open()
globalMapUpdatePlayer();
mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds");
}
}
void MapWindow::globalMapUpdatePlayer ()
{
void MapWindow::globalMapUpdatePlayer ()
{
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
@ -424,15 +421,15 @@ void MapWindow::globalMapUpdatePlayer ()
MyGUI::IntPoint viewoffs(0.5*viewsize.width - worldX, 0.5*viewsize.height - worldY);
mGlobalMap->setViewOffset(viewoffs);
}
}
}
void MapWindow::notifyPlayerUpdate ()
{
void MapWindow::notifyPlayerUpdate ()
{
globalMapUpdatePlayer ();
}
}
void MapWindow::notifyMapChanged ()
{
void MapWindow::notifyMapChanged ()
{
// workaround to prevent the map from drawing on top of the button
MyGUI::IntCoord oldCoord = mButton->getCoord ();
MyGUI::Gui::getInstance().destroyWidget (mButton);
@ -443,4 +440,6 @@ void MapWindow::notifyMapChanged ()
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
"#{sWorld}");
}
}

View file

@ -9,10 +9,7 @@
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "list.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"

View file

@ -5,17 +5,18 @@
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/inputmanager.hpp"
using namespace MWGui;
MessageBoxManager::MessageBoxManager ()
namespace MWGui
{
MessageBoxManager::MessageBoxManager ()
{
// defines
mMessageBoxSpeed = 0.1;
mInterMessageBoxe = NULL;
}
}
void MessageBoxManager::onFrame (float frameDuration)
{
void MessageBoxManager::onFrame (float frameDuration)
{
std::vector<MessageBoxManagerTimer>::iterator it;
for(it = mTimers.begin(); it != mTimers.end();)
{
@ -65,10 +66,10 @@ void MessageBoxManager::onFrame (float frameDuration)
MWBase::Environment::get().getInputManager()->changeInputMode(
MWBase::Environment::get().getWindowManager()->isGuiMode());
}
}
}
void MessageBoxManager::createMessageBox (const std::string& message)
{
void MessageBoxManager::createMessageBox (const std::string& message)
{
MessageBox *box = new MessageBox(*this, message);
removeMessageBox(message.length()*mMessageBoxSpeed, box);
@ -87,10 +88,10 @@ void MessageBoxManager::createMessageBox (const std::string& message)
(*it)->update(height);
height += (*it)->getHeight();
}
}
}
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
{
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
{
if(mInterMessageBoxe != NULL) {
throw std::runtime_error("There is a message box already");
}
@ -98,25 +99,25 @@ bool MessageBoxManager::createInteractiveMessageBox (const std::string& message,
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
return true;
}
}
bool MessageBoxManager::isInteractiveMessageBox ()
{
bool MessageBoxManager::isInteractiveMessageBox ()
{
return mInterMessageBoxe != NULL;
}
}
void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox)
{
void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox)
{
MessageBoxManagerTimer timer;
timer.current = 0;
timer.max = time;
timer.messageBox = msgbox;
mTimers.insert(mTimers.end(), timer);
}
}
bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
{
bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
{
std::vector<MessageBox*>::iterator it;
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
{
@ -128,36 +129,36 @@ bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
}
}
return false;
}
}
void MessageBoxManager::setMessageBoxSpeed (int speed)
{
void MessageBoxManager::setMessageBoxSpeed (int speed)
{
mMessageBoxSpeed = speed;
}
}
void MessageBoxManager::enterPressed ()
{
void MessageBoxManager::enterPressed ()
{
if(mInterMessageBoxe != NULL)
mInterMessageBoxe->enterPressed();
}
}
int MessageBoxManager::readPressedButton ()
{
int MessageBoxManager::readPressedButton ()
{
if(mInterMessageBoxe != NULL)
{
return mInterMessageBoxe->readPressedButton();
}
return -1;
}
}
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
: Layout("openmw_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager)
, mMessage(message)
{
{
// defines
mFixedWidth = 300;
mBottomPadding = 20;
@ -186,10 +187,10 @@ MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::strin
mMainWidget->setSize(size);
size.width -= 15; // this is to center the text (see messagebox.layout, Widget type="Edit" position="-2 -3 0 0")
mMessageWidget->setSize(size);
}
}
void MessageBox::update (int height)
{
void MessageBox::update (int height)
{
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntCoord coord;
coord.left = (gameWindowSize.width - mFixedWidth)/2;
@ -202,20 +203,20 @@ void MessageBox::update (int height)
mMainWidget->setCoord(coord);
mMainWidget->setSize(size);
mMainWidget->setVisible(true);
}
}
int MessageBox::getHeight ()
{
int MessageBox::getHeight ()
{
return mHeight+mNextBoxPadding; // 20 is the padding between this and the next MessageBox
}
}
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
: WindowModal("openmw_interactive_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager)
, mButtonPressed(-1)
{
{
WindowModal::open();
int fixedWidth = 500;
@ -366,10 +367,10 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
}
}
}
}
void InteractiveMessageBox::enterPressed()
{
void InteractiveMessageBox::enterPressed()
{
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
std::vector<MyGUI::Button*>::const_iterator button;
@ -383,15 +384,15 @@ void InteractiveMessageBox::enterPressed()
}
}
}
}
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
{
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
{
buttonActivated (pressed);
}
}
void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
{
void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
{
mMarkedToDelete = true;
int index = 0;
std::vector<MyGUI::Button*>::const_iterator button;
@ -405,11 +406,13 @@ void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
}
index++;
}
}
}
int InteractiveMessageBox::readPressedButton ()
{
int InteractiveMessageBox::readPressedButton ()
{
int pressed = mButtonPressed;
mButtonPressed = -1;
return pressed;
}
}

View file

@ -2,13 +2,9 @@
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/spellsuccess.hpp"
#include "../mwgui/inventorywindow.hpp"
#include "../mwgui/bookwindow.hpp"

View file

@ -1,76 +1,38 @@
#include "race.hpp"
#include <iostream>
#include <iterator>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "widgets.hpp"
#include "tooltips.hpp"
using namespace MWGui;
using namespace Widgets;
namespace
{
int wrap(int index, int max)
{
int wrap(int index, int max)
{
if (index < 0)
return max - 1;
else if (index >= max)
return 0;
else
return index;
}
}
int countParts(const std::string &part, const std::string &race, bool male)
namespace MWGui
{
/// \todo loop through the whole store for appropriate bodyparts instead of looking for fixed IDs
const MWWorld::Store<ESM::BodyPart> &store =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
std::string prefix =
"b_n_" + race + ((male) ? "_m_" : "_f_") + part;
std::string suffix;
suffix.reserve(prefix.size() + 3);
int count = -1;
do {
++count;
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
}
while (store.search(prefix + suffix) != 0);
if (count == 0 && part == "hair") {
count = -1;
do {
++count;
suffix = (boost::format("%02d") % (count + 1)).str();
}
while (store.search(prefix + suffix) != 0);
}
return count;
}
}
RaceDialog::RaceDialog()
RaceDialog::RaceDialog()
: WindowModal("openmw_chargen_race.layout")
, mGenderIndex(0)
, mFaceIndex(0)
, mHairIndex(0)
, mFaceCount(10)
, mHairCount(14)
, mCurrentAngle(0)
{
{
// Centre dialog
center();
@ -128,10 +90,10 @@ RaceDialog::RaceDialog()
updateRaces();
updateSkills();
updateSpellPowers();
}
}
void RaceDialog::setNextButtonShow(bool shown)
{
void RaceDialog::setNextButtonShow(bool shown)
{
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
@ -139,10 +101,10 @@ void RaceDialog::setNextButtonShow(bool shown)
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
else
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
}
void RaceDialog::open()
{
void RaceDialog::open()
{
WindowModal::open();
updateRaces();
@ -164,11 +126,11 @@ void RaceDialog::open()
mHairIndex = boost::lexical_cast<int>(index) - 1;
mPreviewImage->setImageTexture ("CharacterHeadPreview");
}
}
void RaceDialog::setRaceId(const std::string &raceId)
{
void RaceDialog::setRaceId(const std::string &raceId)
{
mCurrentRaceId = raceId;
mRaceList->setIndexSelected(MyGUI::ITEM_NONE);
size_t count = mRaceList->getItemCount();
@ -185,117 +147,78 @@ void RaceDialog::setRaceId(const std::string &raceId)
updateSkills();
updateSpellPowers();
}
}
void RaceDialog::close()
{
void RaceDialog::close()
{
delete mPreview;
mPreview = 0;
}
}
// widget controls
// widget controls
void RaceDialog::onOkClicked(MyGUI::Widget* _sender)
{
void RaceDialog::onOkClicked(MyGUI::Widget* _sender)
{
if(mRaceList->getIndexSelected() == MyGUI::ITEM_NONE)
return;
eventDone(this);
}
}
void RaceDialog::onBackClicked(MyGUI::Widget* _sender)
{
void RaceDialog::onBackClicked(MyGUI::Widget* _sender)
{
eventBack();
}
}
void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position)
{
void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position)
{
float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2;
float diff = angle - mCurrentAngle;
mPreview->update (diff);
mCurrentAngle += diff;
}
}
void RaceDialog::onSelectPreviousGender(MyGUI::Widget*)
{
void RaceDialog::onSelectPreviousGender(MyGUI::Widget*)
{
mGenderIndex = wrap(mGenderIndex - 1, 2);
recountParts();
updatePreview();
}
}
void RaceDialog::onSelectNextGender(MyGUI::Widget*)
{
void RaceDialog::onSelectNextGender(MyGUI::Widget*)
{
mGenderIndex = wrap(mGenderIndex + 1, 2);
recountParts();
updatePreview();
}
}
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
{
do
mFaceIndex = wrap(mFaceIndex - 1, mFaceCount);
while (!isFacePlayable());
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
{
mFaceIndex = wrap(mFaceIndex - 1, mAvailableHeads.size());
updatePreview();
}
}
void RaceDialog::onSelectNextFace(MyGUI::Widget*)
{
do
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
while (!isFacePlayable());
void RaceDialog::onSelectNextFace(MyGUI::Widget*)
{
mFaceIndex = wrap(mFaceIndex + 1, mAvailableHeads.size());
updatePreview();
}
}
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
{
do
mHairIndex = wrap(mHairIndex - 1, mHairCount);
while (!isHairPlayable());
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
{
mHairIndex = wrap(mHairIndex - 1, mAvailableHairs.size());
updatePreview();
}
}
void RaceDialog::onSelectNextHair(MyGUI::Widget*)
{
do
mHairIndex = wrap(mHairIndex + 1, mHairCount);
while (!isHairPlayable());
void RaceDialog::onSelectNextHair(MyGUI::Widget*)
{
mHairIndex = wrap(mHairIndex + 1, mAvailableHairs.size());
updatePreview();
}
}
bool RaceDialog::isFacePlayable()
{
std::string prefix =
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
const MWWorld::Store<ESM::BodyPart> &parts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
if (parts.search(prefix + "head_" + headIndex) == 0)
return !(parts.find(prefix + "head" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
else
return !(parts.find(prefix + "head_" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
}
bool RaceDialog::isHairPlayable()
{
std::string prefix =
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
const MWWorld::Store<ESM::BodyPart> &parts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
if (parts.search(prefix + "hair_" + hairIndex) == 0)
return !(parts.find(prefix + "hair" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
else
return !(parts.find(prefix + "hair_" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
}
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
{
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
{
if (_index == MyGUI::ITEM_NONE)
return;
@ -312,50 +235,61 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
updatePreview();
updateSkills();
updateSpellPowers();
}
}
void RaceDialog::recountParts()
{
mFaceCount = countParts("head", mCurrentRaceId, mGenderIndex == 0);
mHairCount = countParts("hair", mCurrentRaceId, mGenderIndex == 0);
void RaceDialog::getBodyParts (int part, std::vector<std::string>& out)
{
out.clear();
const MWWorld::Store<ESM::BodyPart> &store =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
for (MWWorld::Store<ESM::BodyPart>::iterator it = store.begin(); it != store.end(); ++it)
{
const ESM::BodyPart& bodypart = *it;
if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable)
continue;
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
continue;
if (bodypart.mData.mPart != static_cast<ESM::BodyPart::MeshPart>(part))
continue;
if (mGenderIndex != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
continue;
bool firstPerson = (bodypart.mId.size() >= 3)
&& bodypart.mId[bodypart.mId.size()-3] == '1'
&& bodypart.mId[bodypart.mId.size()-2] == 's'
&& bodypart.mId[bodypart.mId.size()-1] == 't';
if (firstPerson)
continue;
if (Misc::StringUtils::ciEqual(bodypart.mRace, mCurrentRaceId))
out.push_back(bodypart.mId);
}
}
void RaceDialog::recountParts()
{
getBodyParts(ESM::BodyPart::MP_Hair, mAvailableHairs);
getBodyParts(ESM::BodyPart::MP_Head, mAvailableHeads);
mFaceIndex = 0;
mHairIndex = 0;
}
while (!isHairPlayable())
mHairIndex = wrap(mHairIndex + 1, mHairCount);
while (!isFacePlayable())
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
}
// update widget content
// update widget content
void RaceDialog::updatePreview()
{
void RaceDialog::updatePreview()
{
ESM::NPC record = mPreview->getPrototype();
record.mRace = mCurrentRaceId;
record.setIsMale(mGenderIndex == 0);
std::string prefix =
"b_n_" + mCurrentRaceId + ((record.isMale()) ? "_m_" : "_f_");
record.mHead = mAvailableHeads[mFaceIndex];
record.mHair = mAvailableHairs[mHairIndex];
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
record.mHead = prefix + "head_" + headIndex;
record.mHair = prefix + "hair_" + hairIndex;
const MWWorld::Store<ESM::BodyPart> &parts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
if (parts.search(record.mHair) == 0) {
record.mHair = prefix + "hair" + hairIndex;
}
mPreview->setPrototype(record);
}
}
void RaceDialog::updateRaces()
{
void RaceDialog::updateRaces()
{
mRaceList->removeAllItems();
const MWWorld::Store<ESM::Race> &races =
@ -375,10 +309,10 @@ void RaceDialog::updateRaces()
mRaceList->setIndexSelected(index);
++index;
}
}
}
void RaceDialog::updateSkills()
{
void RaceDialog::updateSkills()
{
for (std::vector<MyGUI::Widget*>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
@ -388,7 +322,7 @@ void RaceDialog::updateSkills()
if (mCurrentRaceId.empty())
return;
MWSkillPtr skillWidget;
Widgets::MWSkillPtr skillWidget;
const int lineHeight = 18;
MyGUI::IntCoord coord1(0, 0, mSkillList->getWidth(), 18);
@ -401,10 +335,10 @@ void RaceDialog::updateSkills()
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
continue;
skillWidget = mSkillList->createWidget<MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
skillWidget = mSkillList->createWidget<Widgets::MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
std::string("Skill") + boost::lexical_cast<std::string>(i));
skillWidget->setSkillNumber(skillId);
skillWidget->setSkillValue(MWSkill::SkillValue(race->mData.mBonus[i].mBonus));
skillWidget->setSkillValue(Widgets::MWSkill::SkillValue(race->mData.mBonus[i].mBonus));
ToolTips::createSkillToolTip(skillWidget, skillId);
@ -412,10 +346,10 @@ void RaceDialog::updateSkills()
coord1.top += lineHeight;
}
}
}
void RaceDialog::updateSpellPowers()
{
void RaceDialog::updateSpellPowers()
{
for (std::vector<MyGUI::Widget*>::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
@ -425,7 +359,7 @@ void RaceDialog::updateSpellPowers()
if (mCurrentRaceId.empty())
return;
MWSpellPtr spellPowerWidget;
Widgets::MWSpellPtr spellPowerWidget;
const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, mSpellPowerList->getWidth(), 18);
@ -437,7 +371,7 @@ void RaceDialog::updateSpellPowers()
for (int i = 0; it != end; ++it)
{
const std::string &spellpower = *it;
spellPowerWidget = mSpellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
spellPowerWidget = mSpellPowerList->createWidget<Widgets::MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
spellPowerWidget->setSpellId(spellpower);
spellPowerWidget->setUserString("ToolTipType", "Spell");
spellPowerWidget->setUserString("Spell", spellpower);
@ -447,4 +381,5 @@ void RaceDialog::updateSpellPowers()
coord.top += lineHeight;
++i;
}
}
}

View file

@ -76,8 +76,10 @@ namespace MWGui
void updatePreview();
void recountParts();
bool isHairPlayable();
bool isFacePlayable();
void getBodyParts (int part, std::vector<std::string>& out);
std::vector<std::string> mAvailableHeads;
std::vector<std::string> mAvailableHairs;
MyGUI::ImageBox* mPreviewImage;
MyGUI::ListBox* mRaceList;
@ -90,7 +92,6 @@ namespace MWGui
std::vector<MyGUI::Widget*> mSpellPowerItems;
int mGenderIndex, mFaceIndex, mHairIndex;
int mFaceCount, mHairCount;
std::string mCurrentRaceId;

View file

@ -18,18 +18,18 @@ namespace MWGui
void ReferenceInterface::checkReferenceAvailable()
{
if (mPtr.isEmpty())
return;
MWWorld::Ptr::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell();
// check if player has changed cell, or count of the reference has become 0
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|| mPtr.getRefData().getCount() == 0)
|| (!mPtr.isEmpty() && mPtr.getRefData().getCount() == 0))
{
if (!mPtr.isEmpty())
{
mPtr = MWWorld::Ptr();
onReferenceUnavailable();
}
}
mCurrentPlayerCell = playerCell;
}

View file

@ -1,31 +1,25 @@
#include "review.hpp"
#include <cmath>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "widgets.hpp"
#include "tooltips.hpp"
#undef min
#undef max
using namespace MWGui;
using namespace Widgets;
namespace MWGui
{
const int ReviewDialog::sLineHeight = 18;
const int ReviewDialog::sLineHeight = 18;
ReviewDialog::ReviewDialog()
ReviewDialog::ReviewDialog()
: WindowModal("openmw_chargen_review.layout")
, mLastPos(0)
{
{
// Centre dialog
center();
@ -66,13 +60,13 @@ ReviewDialog::ReviewDialog()
// Setup attributes
MWAttributePtr attribute;
Widgets::MWAttributePtr attribute;
for (int idx = 0; idx < ESM::Attribute::Length; ++idx)
{
getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx));
mAttributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::sAttributeIds[idx]), attribute));
attribute->setAttributeId(ESM::Attribute::sAttributeIds[idx]);
attribute->setAttributeValue(MWAttribute::AttributeValue(0, 0));
attribute->setAttributeValue(Widgets::MWAttribute::AttributeValue(0, 0));
}
// Setup skills
@ -92,21 +86,21 @@ ReviewDialog::ReviewDialog()
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
}
}
void ReviewDialog::open()
{
void ReviewDialog::open()
{
WindowModal::open();
updateSkillArea();
}
}
void ReviewDialog::setPlayerName(const std::string &name)
{
void ReviewDialog::setPlayerName(const std::string &name)
{
mNameWidget->setCaption(name);
}
}
void ReviewDialog::setRace(const std::string &raceId)
{
void ReviewDialog::setRace(const std::string &raceId)
{
mRaceId = raceId;
const ESM::Race *race =
@ -116,17 +110,17 @@ void ReviewDialog::setRace(const std::string &raceId)
ToolTips::createRaceToolTip(mRaceWidget, race);
mRaceWidget->setCaption(race->mName);
}
}
}
void ReviewDialog::setClass(const ESM::Class& class_)
{
void ReviewDialog::setClass(const ESM::Class& class_)
{
mKlass = class_;
mClassWidget->setCaption(mKlass.mName);
ToolTips::createClassToolTip(mClassWidget, mKlass);
}
}
void ReviewDialog::setBirthSign(const std::string& signId)
{
void ReviewDialog::setBirthSign(const std::string& signId)
{
mBirthSignId = signId;
const ESM::BirthSign *sign =
@ -136,40 +130,40 @@ void ReviewDialog::setBirthSign(const std::string& signId)
mBirthSignWidget->setCaption(sign->mName);
ToolTips::createBirthsignToolTip(mBirthSignWidget, mBirthSignId);
}
}
}
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<float>& value)
{
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<float>& value)
{
mHealth->setValue(value.getCurrent(), value.getModified());
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
}
}
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<float>& value)
{
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<float>& value)
{
mMagicka->setValue(value.getCurrent(), value.getModified());
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
mMagicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
}
}
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<float>& value)
{
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<float>& value)
{
mFatigue->setValue(value.getCurrent(), value.getModified());
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
}
}
void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
{
std::map<int, MWAttributePtr>::iterator attr = mAttributeWidgets.find(static_cast<int>(attributeId));
void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
{
std::map<int, Widgets::MWAttributePtr>::iterator attr = mAttributeWidgets.find(static_cast<int>(attributeId));
if (attr == mAttributeWidgets.end())
return;
attr->second->setAttributeValue(value);
}
}
void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value)
{
void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value)
{
mSkillValues[skillId] = value;
MyGUI::TextBox* widget = mSkillWidgetMap[skillId];
if (widget)
@ -186,10 +180,10 @@ void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanic
widget->_setWidgetState(state);
}
}
}
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
{
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
{
mMajorSkills = major;
mMinorSkills = minor;
@ -207,10 +201,10 @@ void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vec
}
updateSkillArea();
}
}
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::ImageBox* separator = mSkillView->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
@ -218,10 +212,10 @@ void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2
coord1.top += separator->getHeight();
coord2.top += separator->getHeight();
}
}
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* groupWidget = mSkillView->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
groupWidget->setCaption(label);
@ -229,10 +223,10 @@ void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, M
coord1.top += sLineHeight;
coord2.top += sLineHeight;
}
}
MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* skillNameWidget;
MyGUI::TextBox* skillValueWidget;
@ -252,10 +246,10 @@ MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::s
coord2.top += sLineHeight;
return skillValueWidget;
}
}
void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* skillNameWidget;
skillNameWidget = mSkillView->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
@ -266,10 +260,10 @@ void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyG
coord1.top += sLineHeight;
coord2.top += sLineHeight;
}
}
void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
// Add a line separator if there are items above
if (!mSkillWidgets.empty())
{
@ -304,10 +298,10 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId
mSkillWidgetMap[skillId] = widget;
}
}
}
void ReviewDialog::updateSkillArea()
{
void ReviewDialog::updateSkillArea()
{
for (std::vector<MyGUI::Widget*>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
@ -330,44 +324,46 @@ void ReviewDialog::updateSkillArea()
mClientHeight = coord1.top;
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), mClientHeight));
}
}
// widget controls
// widget controls
void ReviewDialog::onOkClicked(MyGUI::Widget* _sender)
{
void ReviewDialog::onOkClicked(MyGUI::Widget* _sender)
{
eventDone(this);
}
}
void ReviewDialog::onBackClicked(MyGUI::Widget* _sender)
{
void ReviewDialog::onBackClicked(MyGUI::Widget* _sender)
{
eventBack();
}
}
void ReviewDialog::onNameClicked(MyGUI::Widget* _sender)
{
void ReviewDialog::onNameClicked(MyGUI::Widget* _sender)
{
eventActivateDialog(NAME_DIALOG);
}
}
void ReviewDialog::onRaceClicked(MyGUI::Widget* _sender)
{
void ReviewDialog::onRaceClicked(MyGUI::Widget* _sender)
{
eventActivateDialog(RACE_DIALOG);
}
}
void ReviewDialog::onClassClicked(MyGUI::Widget* _sender)
{
void ReviewDialog::onClassClicked(MyGUI::Widget* _sender)
{
eventActivateDialog(CLASS_DIALOG);
}
}
void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender)
{
void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender)
{
eventActivateDialog(BIRTHSIGN_DIALOG);
}
}
void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mSkillView->getViewOffset().top + _rel*0.3 > 0)
mSkillView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mSkillView->setViewOffset(MyGUI::IntPoint(0, mSkillView->getViewOffset().top + _rel*0.3));
}
}

View file

@ -10,13 +10,14 @@
#include "formatting.hpp"
using namespace MWGui;
namespace MWGui
{
ScrollWindow::ScrollWindow ()
ScrollWindow::ScrollWindow ()
: WindowBase("openmw_scroll.layout")
, mTakeButtonShow(true)
, mTakeButtonAllowed(true)
{
{
getWidget(mTextView, "TextView");
getWidget(mCloseButton, "CloseButton");
@ -26,10 +27,10 @@ ScrollWindow::ScrollWindow ()
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
center();
}
}
void ScrollWindow::open (MWWorld::Ptr scroll)
{
void ScrollWindow::open (MWWorld::Ptr scroll)
{
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
@ -48,33 +49,34 @@ void ScrollWindow::open (MWWorld::Ptr scroll)
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
setTakeButtonShow(true);
}
}
void ScrollWindow::setTakeButtonShow(bool show)
{
void ScrollWindow::setTakeButtonShow(bool show)
{
mTakeButtonShow = show;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
}
void ScrollWindow::setInventoryAllowed(bool allowed)
{
void ScrollWindow::setInventoryAllowed(bool allowed)
{
mTakeButtonAllowed = allowed;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
}
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
}
}
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
MWWorld::ActionTake take(mScroll);
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
}
}

View file

@ -1,24 +1,18 @@
#include "settingswindow.hpp"
#include <OgreRoot.h>
#include <OgreRenderSystem.h>
#include <OgrePlugin.h>
#include <OgreString.h>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/math/common_factor_rt.hpp>
#include <components/settings/settings.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "confirmationdialog.hpp"
namespace

View file

@ -1,6 +1,5 @@
#include "soulgemdialog.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "messagebox.hpp"

View file

@ -1,7 +1,5 @@
#include "spellbuyingwindow.hpp"
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
@ -11,9 +9,7 @@
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "inventorywindow.hpp"

View file

@ -4,22 +4,14 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/class.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/spellsuccess.hpp"
#include "tooltips.hpp"
#include "widgets.hpp"
#include "class.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"

View file

@ -1,9 +1,5 @@
#include "spellicons.hpp"
#include <MyGUI_Widget.h>
#include <MyGUI_Gui.h>
#include <MyGUI_ImageBox.h>
#include <boost/lexical_cast.hpp>
#include "../mwbase/world.hpp"
@ -14,7 +10,6 @@
#include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/activespells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "tooltips.hpp"

View file

@ -1,22 +1,14 @@
#include "spellwindow.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/spellsuccess.hpp"
#include "spellicons.hpp"

View file

@ -1,14 +1,9 @@
#include "statswindow.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/player.hpp"
@ -18,11 +13,12 @@
#include "tooltips.hpp"
namespace MWGui
{
using namespace MWGui;
const int StatsWindow::sLineHeight = 18;
const int StatsWindow::sLineHeight = 18;
StatsWindow::StatsWindow ()
StatsWindow::StatsWindow ()
: WindowPinnableBase("openmw_stats_window.layout")
, mSkillView(NULL)
, mClientHeight(0)
@ -38,7 +34,7 @@ StatsWindow::StatsWindow ()
, mBounty(0)
, mSkillWidgets()
, mChanged(true)
{
{
setCoord(0,0,498, 342);
const char *names[][2] =
@ -72,25 +68,25 @@ StatsWindow::StatsWindow ()
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize);
}
}
void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mSkillView->getViewOffset().top + _rel*0.3 > 0)
mSkillView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mSkillView->setViewOffset(MyGUI::IntPoint(0, mSkillView->getViewOffset().top + _rel*0.3));
}
}
void StatsWindow::onWindowResize(MyGUI::Window* window)
{
void StatsWindow::onWindowResize(MyGUI::Window* window)
{
mLeftPane->setCoord( MyGUI::IntCoord(0, 0, 0.44*window->getSize().width, window->getSize().height) );
mRightPane->setCoord( MyGUI::IntCoord(0.44*window->getSize().width, 0, 0.56*window->getSize().width, window->getSize().height) );
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), mClientHeight));
}
}
void StatsWindow::setBar(const std::string& name, const std::string& tname, int val, int max)
{
void StatsWindow::setBar(const std::string& name, const std::string& tname, int val, int max)
{
MyGUI::ProgressPtr pt;
getWidget(pt, name);
pt->setProgressRange(max);
@ -99,16 +95,16 @@ void StatsWindow::setBar(const std::string& name, const std::string& tname, int
std::stringstream out;
out << val << "/" << max;
setText(tname, out.str().c_str());
}
}
void StatsWindow::setPlayerName(const std::string& playerName)
{
void StatsWindow::setPlayerName(const std::string& playerName)
{
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(playerName);
adjustWindowCaption();
}
}
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
static const char *ids[] =
{
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
@ -135,10 +131,10 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>&
break;
}
}
}
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
static const char *ids[] =
{
"HBar", "MBar", "FBar",
@ -172,30 +168,30 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicSta
}
}
}
}
}
void StatsWindow::setValue (const std::string& id, const std::string& value)
{
void StatsWindow::setValue (const std::string& id, const std::string& value)
{
if (id=="name")
setPlayerName (value);
else if (id=="race")
setText ("RaceText", value);
else if (id=="class")
setText ("ClassText", value);
}
}
void StatsWindow::setValue (const std::string& id, int value)
{
void StatsWindow::setValue (const std::string& id, int value)
{
if (id=="level")
{
std::ostringstream text;
text << value;
setText("LevelText", text.str());
}
}
}
void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{
void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{
mSkillValues[parSkill] = value;
MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill];
if (widget)
@ -211,10 +207,10 @@ void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechani
widget->setCaption(text);
widget->_setWidgetState(state);
}
}
}
void StatsWindow::configureSkills (const std::vector<int>& major, const std::vector<int>& minor)
{
void StatsWindow::configureSkills (const std::vector<int>& major, const std::vector<int>& minor)
{
mMajorSkills = major;
mMinorSkills = minor;
@ -232,10 +228,10 @@ void StatsWindow::configureSkills (const std::vector<int>& major, const std::vec
}
updateSkillArea();
}
}
void StatsWindow::onFrame ()
{
void StatsWindow::onFrame ()
{
if (!mMainWidget->getVisible())
return;
@ -263,37 +259,37 @@ void StatsWindow::onFrame ()
if (mChanged)
updateSkillArea();
}
}
void StatsWindow::setFactions (const FactionList& factions)
{
void StatsWindow::setFactions (const FactionList& factions)
{
if (mFactions != factions)
{
mFactions = factions;
mChanged = true;
}
}
}
void StatsWindow::setExpelled (const std::set<std::string>& expelled)
{
void StatsWindow::setExpelled (const std::set<std::string>& expelled)
{
if (mExpelled != expelled)
{
mExpelled = expelled;
mChanged = true;
}
}
}
void StatsWindow::setBirthSign (const std::string& signId)
{
void StatsWindow::setBirthSign (const std::string& signId)
{
if (signId != mBirthSignId)
{
mBirthSignId = signId;
mChanged = true;
}
}
}
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::ImageBox* separator = mSkillView->createWidget<MyGUI::ImageBox>("MW_HLine",
MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
@ -302,10 +298,10 @@ void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
coord1.top += separator->getHeight();
coord2.top += separator->getHeight();
}
}
void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* groupWidget = mSkillView->createWidget<MyGUI::TextBox>("SandBrightText",
MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
@ -315,10 +311,10 @@ void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, My
coord1.top += sLineHeight;
coord2.top += sLineHeight;
}
}
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox *skillNameWidget, *skillValueWidget;
skillNameWidget = mSkillView->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
@ -337,10 +333,10 @@ MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::st
coord2.top += sLineHeight;
return skillValueWidget;
}
}
MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* skillNameWidget;
skillNameWidget = mSkillView->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
@ -353,10 +349,10 @@ MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &co
coord2.top += sLineHeight;
return skillNameWidget;
}
}
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
// Add a line separator if there are items above
if (!mSkillWidgets.empty())
{
@ -413,10 +409,10 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId,
mSkillWidgetMap[skillId] = widget;
}
}
}
void StatsWindow::updateSkillArea()
{
void StatsWindow::updateSkillArea()
{
mChanged = false;
for (std::vector<MyGUI::Widget*>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
@ -572,9 +568,10 @@ void StatsWindow::updateSkillArea()
mClientHeight = coord1.top;
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), mClientHeight));
}
}
void StatsWindow::onPinToggled()
{
void StatsWindow::onPinToggled()
{
MWBase::Environment::get().getWindowManager()->setHMSVisibility(!mPinned);
}
}

View file

@ -3,11 +3,12 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
using namespace MWGui;
TextInputDialog::TextInputDialog()
: WindowModal("openmw_text_input.layout")
namespace MWGui
{
TextInputDialog::TextInputDialog()
: WindowModal("openmw_text_input.layout")
{
// Centre dialog
center();
@ -20,10 +21,10 @@ TextInputDialog::TextInputDialog()
// Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
}
void TextInputDialog::setNextButtonShow(bool shown)
{
void TextInputDialog::setNextButtonShow(bool shown)
{
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
@ -31,24 +32,24 @@ void TextInputDialog::setNextButtonShow(bool shown)
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
else
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
}
void TextInputDialog::setTextLabel(const std::string &label)
{
void TextInputDialog::setTextLabel(const std::string &label)
{
setText("LabelT", label);
}
}
void TextInputDialog::open()
{
void TextInputDialog::open()
{
WindowModal::open();
// Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
}
// widget controls
// widget controls
void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
{
void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
{
if (mTextEdit->getCaption() == "")
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
@ -56,10 +57,10 @@ void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
}
else
eventDone(this);
}
}
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
{
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
{
if (mTextEdit->getCaption() == "")
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
@ -67,4 +68,6 @@ void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
}
else
eventDone(this);
}
}

View file

@ -2,24 +2,17 @@
#include <boost/lexical_cast.hpp>
#include <OgreResourceGroupManager.h>
#include <components/settings/settings.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/class.hpp"
#include "mapwindow.hpp"
#include "widgets.hpp"
#include "inventorywindow.hpp"
using namespace MWGui;
using namespace MyGUI;
namespace MWGui
{
ToolTips::ToolTips() :
ToolTips::ToolTips() :
Layout("openmw_tooltips.layout")
, mGameMode(true)
, mFullHelp(false)
@ -31,7 +24,7 @@ ToolTips::ToolTips() :
, mLastMouseX(0)
, mLastMouseY(0)
, mHorizontalScrollIndex(0)
{
{
getWidget(mDynamicToolTipBox, "DynamicToolTipBox");
mDynamicToolTipBox->setVisible(false);
@ -48,15 +41,15 @@ ToolTips::ToolTips() :
{
mMainWidget->getChildAt(i)->setVisible(false);
}
}
}
void ToolTips::setEnabled(bool enabled)
{
void ToolTips::setEnabled(bool enabled)
{
mEnabled = enabled;
}
}
void ToolTips::onFrame(float frameDuration)
{
void ToolTips::onFrame(float frameDuration)
{
while (mDynamicToolTipBox->getChildCount())
{
@ -69,7 +62,7 @@ void ToolTips::onFrame(float frameDuration)
mMainWidget->getChildAt(i)->setVisible(false);
}
const IntSize &viewSize = RenderManager::getInstance().getViewSize();
const MyGUI::IntSize &viewSize = MyGUI::RenderManager::getInstance().getViewSize();
if (!mEnabled)
{
@ -78,7 +71,7 @@ void ToolTips::onFrame(float frameDuration)
if (!mGameMode)
{
const MyGUI::IntPoint& mousePos = InputManager::getInstance().getMousePosition();
const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition();
if (MWBase::Environment::get().getWindowManager()->getWorldMouseOver() && ((MWBase::Environment::get().getWindowManager()->getMode() == GM_Console)
|| (MWBase::Environment::get().getWindowManager()->getMode() == GM_Container)
@ -91,7 +84,7 @@ void ToolTips::onFrame(float frameDuration)
const MWWorld::Class& objectclass = MWWorld::Class::get (mFocusObject);
IntSize tooltipSize;
MyGUI::IntSize tooltipSize;
if ((!objectclass.hasToolTip(mFocusObject))&&(MWBase::Environment::get().getWindowManager()->getMode() == GM_Console))
{
setCoord(0, 0, 300, 300);
@ -104,7 +97,7 @@ void ToolTips::onFrame(float frameDuration)
else
tooltipSize = getToolTipViaPtr(true);
IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24);
MyGUI::IntPoint tooltipPosition = MyGUI::InputManager::getInstance().getMousePosition() + MyGUI::IntPoint(0, 24);
// make the tooltip stay completely in the viewport
if ((tooltipPosition.left + tooltipSize.width) > viewSize.width)
@ -121,7 +114,7 @@ void ToolTips::onFrame(float frameDuration)
else
{
const MyGUI::IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
const MyGUI::IntPoint& lastPressed = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
if (mousePos == lastPressed) // mouseclick makes tooltip disappear
return;
@ -142,11 +135,11 @@ void ToolTips::onFrame(float frameDuration)
if (mRemainingDelay > 0)
return;
Widget* focus = InputManager::getInstance().getMouseFocusWidget();
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getMouseFocusWidget();
if (focus == 0)
return;
IntSize tooltipSize;
MyGUI::IntSize tooltipSize;
// try to go 1 level up until there is a widget that has tooltip
// this is necessary because some skin elements are actually separate widgets
@ -259,7 +252,7 @@ void ToolTips::onFrame(float frameDuration)
else
throw std::runtime_error ("unknown tooltip type");
IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24);
MyGUI::IntPoint tooltipPosition = MyGUI::InputManager::getInstance().getMousePosition() + MyGUI::IntPoint(0, 24);
// make the tooltip stay completely in the viewport
if ((tooltipPosition.left + tooltipSize.width) > viewSize.width)
@ -278,7 +271,7 @@ void ToolTips::onFrame(float frameDuration)
{
if (!mFocusObject.isEmpty())
{
IntSize tooltipSize = getToolTipViaPtr();
MyGUI::IntSize tooltipSize = getToolTipViaPtr();
setCoord(viewSize.width/2 - tooltipSize.width/2,
std::max(0, int(mFocusToolTipY*viewSize.height - tooltipSize.height)),
@ -288,29 +281,29 @@ void ToolTips::onFrame(float frameDuration)
mDynamicToolTipBox->setVisible(true);
}
}
}
}
void ToolTips::enterGameMode()
{
void ToolTips::enterGameMode()
{
mGameMode = true;
}
}
void ToolTips::enterGuiMode()
{
void ToolTips::enterGuiMode()
{
mGameMode = false;
}
}
void ToolTips::setFocusObject(const MWWorld::Ptr& focus)
{
void ToolTips::setFocusObject(const MWWorld::Ptr& focus)
{
mFocusObject = focus;
}
}
IntSize ToolTips::getToolTipViaPtr (bool image)
{
MyGUI::IntSize ToolTips::getToolTipViaPtr (bool image)
{
// this the maximum width of the tooltip before it starts word-wrapping
setCoord(0, 0, 300, 300);
IntSize tooltipSize;
MyGUI::IntSize tooltipSize;
const MWWorld::Class& object = MWWorld::Class::get (mFocusObject);
if (!object.hasToolTip(mFocusObject))
@ -328,10 +321,10 @@ IntSize ToolTips::getToolTipViaPtr (bool image)
}
return tooltipSize;
}
}
void ToolTips::findImageExtension(std::string& image)
{
void ToolTips::findImageExtension(std::string& image)
{
int len = image.size();
if (len < 4) return;
@ -342,10 +335,10 @@ void ToolTips::findImageExtension(std::string& image)
image[len-2] = 'd';
image[len-1] = 's';
}
}
}
IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
{
MyGUI::IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
{
mDynamicToolTipBox->setVisible(true);
std::string caption = info.caption;
@ -378,7 +371,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
// this the maximum width of the tooltip before it starts word-wrapping
setCoord(0, 0, 300, 300);
const IntPoint padding(8, 8);
const MyGUI::IntPoint padding(8, 8);
const int maximumWidth = 500;
@ -388,32 +381,32 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
std::string realImage = "icons\\" + image;
findImageExtension(realImage);
EditBox* captionWidget = mDynamicToolTipBox->createWidget<EditBox>("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption");
MyGUI::EditBox* captionWidget = mDynamicToolTipBox->createWidget<MyGUI::EditBox>("NormalText", MyGUI::IntCoord(0, 0, 300, 300), MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipCaption");
captionWidget->setProperty("Static", "true");
captionWidget->setCaptionWithReplacing(caption);
IntSize captionSize = captionWidget->getTextSize();
MyGUI::IntSize captionSize = captionWidget->getTextSize();
int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize);
EditBox* textWidget = mDynamicToolTipBox->createWidget<EditBox>("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText");
MyGUI::EditBox* textWidget = mDynamicToolTipBox->createWidget<MyGUI::EditBox>("SandText", MyGUI::IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), MyGUI::Align::Stretch, "ToolTipText");
textWidget->setProperty("Static", "true");
textWidget->setProperty("MultiLine", "true");
textWidget->setProperty("WordWrap", info.wordWrap ? "true" : "false");
textWidget->setCaptionWithReplacing(text);
textWidget->setTextAlign(Align::HCenter | Align::Top);
IntSize textSize = textWidget->getTextSize();
textWidget->setTextAlign(MyGUI::Align::HCenter | MyGUI::Align::Top);
MyGUI::IntSize textSize = textWidget->getTextSize();
captionSize += IntSize(imageSize, 0); // adjust for image
IntSize totalSize = IntSize( std::min(std::max(textSize.width,captionSize.width + ((image != "") ? imageCaptionHPadding : 0)),maximumWidth),
captionSize += MyGUI::IntSize(imageSize, 0); // adjust for image
MyGUI::IntSize totalSize = MyGUI::IntSize( std::min(std::max(textSize.width,captionSize.width + ((image != "") ? imageCaptionHPadding : 0)),maximumWidth),
((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight );
if (!info.effects.empty())
{
Widget* effectArea = mDynamicToolTipBox->createWidget<Widget>("",
IntCoord(0, totalSize.height, 300, 300-totalSize.height),
Align::Stretch, "ToolTipEffectArea");
MyGUI::Widget* effectArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
MyGUI::IntCoord(0, totalSize.height, 300, 300-totalSize.height),
MyGUI::Align::Stretch, "ToolTipEffectArea");
IntCoord coord(0, 6, totalSize.width, 24);
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
/**
* \todo
@ -422,7 +415,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
*/
Widgets::MWEffectListPtr effectsWidget = effectArea->createWidget<Widgets::MWEffectList>
("MW_StatName", coord, Align::Default, "ToolTipEffectsWidget");
("MW_StatName", coord, MyGUI::Align::Default, "ToolTipEffectsWidget");
effectsWidget->setEffectList(info.effects);
std::vector<MyGUI::Widget*> effectItems;
@ -434,14 +427,14 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
if (info.enchant != "")
{
assert(enchant);
Widget* enchantArea = mDynamicToolTipBox->createWidget<Widget>("",
IntCoord(0, totalSize.height, 300, 300-totalSize.height),
Align::Stretch, "ToolTipEnchantArea");
MyGUI::Widget* enchantArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
MyGUI::IntCoord(0, totalSize.height, 300, 300-totalSize.height),
MyGUI::Align::Stretch, "ToolTipEnchantArea");
IntCoord coord(0, 6, totalSize.width, 24);
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget<Widgets::MWEffectList>
("MW_StatName", coord, Align::Default, "ToolTipEnchantWidget");
("MW_StatName", coord, MyGUI::Align::Default, "ToolTipEnchantWidget");
enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->mEffects));
std::vector<MyGUI::Widget*> enchantEffectItems;
@ -458,7 +451,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
const int chargeWidth = 204;
TextBox* chargeText = enchantArea->createWidget<TextBox>("SandText", IntCoord(0, 0, 10, 18), Align::Default, "ToolTipEnchantChargeText");
MyGUI::TextBox* chargeText = enchantArea->createWidget<MyGUI::TextBox>("SandText", MyGUI::IntCoord(0, 0, 10, 18), MyGUI::Align::Default, "ToolTipEnchantChargeText");
chargeText->setCaptionWithReplacing("#{sCharges}");
const int chargeTextWidth = chargeText->getTextSize().width + 5;
@ -469,18 +462,18 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
chargeText->setCoord((totalSize.width - chargeAndTextWidth)/2, coord.top+6, chargeTextWidth, 18);
IntCoord chargeCoord;
MyGUI::IntCoord chargeCoord;
if (totalSize.width < chargeWidth)
{
totalSize.width = chargeWidth;
chargeCoord = IntCoord(0, coord.top+6, chargeWidth, 18);
chargeCoord = MyGUI::IntCoord(0, coord.top+6, chargeWidth, 18);
}
else
{
chargeCoord = IntCoord((totalSize.width - chargeAndTextWidth)/2 + chargeTextWidth, coord.top+6, chargeWidth, 18);
chargeCoord = MyGUI::IntCoord((totalSize.width - chargeAndTextWidth)/2 + chargeTextWidth, coord.top+6, chargeWidth, 18);
}
Widgets::MWDynamicStatPtr chargeWidget = enchantArea->createWidget<Widgets::MWDynamicStat>
("MW_ChargeBar", chargeCoord, Align::Default, "ToolTipEnchantCharge");
("MW_ChargeBar", chargeCoord, MyGUI::Align::Default, "ToolTipEnchantCharge");
chargeWidget->setValue(charge, charge);
totalSize.height += 24;
}
@ -504,83 +497,83 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
}else{
horizontal_scroll = 80 - mHorizontalScrollIndex;
}
captionWidget->setPosition (IntPoint(horizontal_scroll, captionWidget->getPosition().top + padding.top));
captionWidget->setPosition (MyGUI::IntPoint(horizontal_scroll, captionWidget->getPosition().top + padding.top));
} else {
captionWidget->setPosition (captionWidget->getPosition() + padding);
}
textWidget->setPosition (textWidget->getPosition() + IntPoint(0, padding.top)); // only apply vertical padding, the horizontal works automatically due to Align::HCenter
textWidget->setPosition (textWidget->getPosition() + MyGUI::IntPoint(0, padding.top)); // only apply vertical padding, the horizontal works automatically due to Align::HCenter
if (image != "")
{
ImageBox* imageWidget = mDynamicToolTipBox->createWidget<ImageBox>("ImageBox",
IntCoord((totalSize.width - captionSize.width - imageCaptionHPadding)/2, 0, imageSize, imageSize),
Align::Left | Align::Top, "ToolTipImage");
MyGUI::ImageBox* imageWidget = mDynamicToolTipBox->createWidget<MyGUI::ImageBox>("ImageBox",
MyGUI::IntCoord((totalSize.width - captionSize.width - imageCaptionHPadding)/2, 0, imageSize, imageSize),
MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipImage");
imageWidget->setImageTexture(realImage);
imageWidget->setPosition (imageWidget->getPosition() + padding);
}
totalSize += IntSize(padding.left*2, padding.top*2);
totalSize += MyGUI::IntSize(padding.left*2, padding.top*2);
return totalSize;
}
}
std::string ToolTips::toString(const float value)
{
std::string ToolTips::toString(const float value)
{
std::ostringstream stream;
stream << std::setprecision(3) << value;
return stream.str();
}
}
std::string ToolTips::toString(const int value)
{
std::string ToolTips::toString(const int value)
{
std::ostringstream stream;
stream << value;
return stream.str();
}
}
std::string ToolTips::getValueString(const int value, const std::string& prefix)
{
std::string ToolTips::getValueString(const int value, const std::string& prefix)
{
if (value == 0)
return "";
else
return "\n" + prefix + ": " + toString(value);
}
}
std::string ToolTips::getMiscString(const std::string& text, const std::string& prefix)
{
std::string ToolTips::getMiscString(const std::string& text, const std::string& prefix)
{
if (text == "")
return "";
else
return "\n" + prefix + ": " + text;
}
}
std::string ToolTips::getCountString(const int value)
{
std::string ToolTips::getCountString(const int value)
{
if (value == 1)
return "";
else
return " (" + boost::lexical_cast<std::string>(value) + ")";
}
}
void ToolTips::toggleFullHelp()
{
void ToolTips::toggleFullHelp()
{
mFullHelp = !mFullHelp;
}
}
bool ToolTips::getFullHelp() const
{
bool ToolTips::getFullHelp() const
{
return mFullHelp;
}
}
void ToolTips::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
{
void ToolTips::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
{
mFocusToolTipX = (min_x + max_x) / 2;
mFocusToolTipY = min_y;
}
}
void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId)
{
void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId)
{
if (skillId == -1)
return;
@ -602,10 +595,10 @@ void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId)
widget->setUserString("Caption_SkillNoProgressDescription", skill->mDescription);
widget->setUserString("Caption_SkillNoProgressAttribute", "#{sGoverningAttribute}: #{" + attr->mName + "}");
widget->setUserString("ImageTexture_SkillNoProgressImage", icon);
}
}
void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId)
{
void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId)
{
if (attributeId == -1)
return;
@ -618,10 +611,10 @@ void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId)
widget->setUserString("Caption_AttributeName", "#{"+name+"}");
widget->setUserString("Caption_AttributeDescription", "#{"+desc+"}");
widget->setUserString("ImageTexture_AttributeImage", icon);
}
}
void ToolTips::createSpecializationToolTip(MyGUI::Widget* widget, const std::string& name, int specId)
{
void ToolTips::createSpecializationToolTip(MyGUI::Widget* widget, const std::string& name, int specId)
{
widget->setUserString("Caption_CenteredCaption", name);
std::string specText;
// get all skills of this specialisation
@ -637,10 +630,10 @@ void ToolTips::createSpecializationToolTip(MyGUI::Widget* widget, const std::str
widget->setUserString("Caption_CenteredCaptionText", specText);
widget->setUserString("ToolTipLayout", "TextWithCenteredCaptionToolTip");
widget->setUserString("ToolTipType", "Layout");
}
}
void ToolTips::createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId)
{
void ToolTips::createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId)
{
const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore();
@ -705,18 +698,18 @@ void ToolTips::createBirthsignToolTip(MyGUI::Widget* widget, const std::string&
}
widget->setUserString("Caption_BirthSignText", text);
}
}
void ToolTips::createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace)
{
void ToolTips::createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace)
{
widget->setUserString("Caption_CenteredCaption", playerRace->mName);
widget->setUserString("Caption_CenteredCaptionText", playerRace->mDescription);
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "TextWithCenteredCaptionToolTip");
}
}
void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass)
{
void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass)
{
if (playerClass.mName == "")
return;
@ -734,10 +727,10 @@ void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playe
widget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr);
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "ClassToolTip");
}
}
void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id)
{
void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id)
{
const ESM::MagicEffect* effect =
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::MagicEffect>().find(id);
const std::string &name = ESM::MagicEffect::effectIdToString (id);
@ -767,10 +760,12 @@ void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id)
widget->setUserString("Caption_MagicEffectDescription", effect->mDescription);
widget->setUserString("Caption_MagicEffectSchool", "#{sSchool}: " + schools[effect->mData.mSchool]);
widget->setUserString("ImageTexture_MagicEffectImage", icon);
}
}
void ToolTips::setDelay(float delay)
{
void ToolTips::setDelay(float delay)
{
mDelay = delay;
mRemainingDelay = mDelay;
}
}

View file

@ -9,7 +9,6 @@
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/dialoguemanager.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwmechanics/creaturestats.hpp"

View file

@ -1,22 +1,15 @@
#include "travelwindow.hpp"
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <libs/openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"

View file

@ -1,7 +1,5 @@
#include "waitdialog.hpp"
#include <cmath>
#include <boost/lexical_cast.hpp>
#include <libs/openengine/ogre/fader.hpp>
@ -11,9 +9,7 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/timestamp.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp"
#include "../mwmechanics/creaturestats.hpp"

View file

@ -9,61 +9,61 @@
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/esmstore.hpp"
#undef min
#undef max
using namespace MWGui;
using namespace MWGui::Widgets;
namespace MWGui
{
namespace Widgets
{
/* Helper functions */
/* Helper functions */
/*
/*
* Fixes the filename of a texture path to use the correct .dds extension.
* This is needed on some ESM entries which point to a .tga file instead.
*/
void MWGui::Widgets::fixTexturePath(std::string &path)
{
void fixTexturePath(std::string &path)
{
int offset = path.rfind(".");
if (offset < 0)
return;
path.replace(offset, path.length() - offset, ".dds");
}
}
/* MWSkill */
/* MWSkill */
MWSkill::MWSkill()
MWSkill::MWSkill()
: mSkillId(ESM::Skill::Length)
, mSkillNameWidget(NULL)
, mSkillValueWidget(NULL)
{
}
{
}
void MWSkill::setSkillId(ESM::Skill::SkillEnum skill)
{
void MWSkill::setSkillId(ESM::Skill::SkillEnum skill)
{
mSkillId = skill;
updateWidgets();
}
}
void MWSkill::setSkillNumber(int skill)
{
void MWSkill::setSkillNumber(int skill)
{
if (skill < 0)
setSkillId(ESM::Skill::Length);
else if (skill < ESM::Skill::Length)
setSkillId(static_cast<ESM::Skill::SkillEnum>(skill));
else
throw new std::runtime_error("Skill number out of range");
}
}
void MWSkill::setSkillValue(const SkillValue& value)
{
void MWSkill::setSkillValue(const SkillValue& value)
{
mValue = value;
updateWidgets();
}
}
void MWSkill::updateWidgets()
{
void MWSkill::updateWidgets()
{
if (mSkillNameWidget)
{
if (mSkillId == ESM::Skill::Length)
@ -87,19 +87,19 @@ void MWSkill::updateWidgets()
else
mSkillValueWidget->_setWidgetState("normal");
}
}
}
void MWSkill::onClicked(MyGUI::Widget* _sender)
{
void MWSkill::onClicked(MyGUI::Widget* _sender)
{
eventClicked(this);
}
}
MWSkill::~MWSkill()
{
}
MWSkill::~MWSkill()
{
}
void MWSkill::initialiseOverride()
{
void MWSkill::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(mSkillNameWidget, "StatName");
@ -120,36 +120,36 @@ void MWSkill::initialiseOverride()
mSkillNameWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked);
}
}
}
/* MWAttribute */
/* MWAttribute */
MWAttribute::MWAttribute()
MWAttribute::MWAttribute()
: mId(-1)
, mAttributeNameWidget(NULL)
, mAttributeValueWidget(NULL)
{
}
{
}
void MWAttribute::setAttributeId(int attributeId)
{
void MWAttribute::setAttributeId(int attributeId)
{
mId = attributeId;
updateWidgets();
}
}
void MWAttribute::setAttributeValue(const AttributeValue& value)
{
void MWAttribute::setAttributeValue(const AttributeValue& value)
{
mValue = value;
updateWidgets();
}
}
void MWAttribute::onClicked(MyGUI::Widget* _sender)
{
void MWAttribute::onClicked(MyGUI::Widget* _sender)
{
eventClicked(this);
}
}
void MWAttribute::updateWidgets()
{
void MWAttribute::updateWidgets()
{
if (mAttributeNameWidget)
{
if (mId < 0 || mId >= 8)
@ -183,14 +183,14 @@ void MWAttribute::updateWidgets()
else
mAttributeValueWidget->_setWidgetState("normal");
}
}
}
MWAttribute::~MWAttribute()
{
}
MWAttribute::~MWAttribute()
{
}
void MWAttribute::initialiseOverride()
{
void MWAttribute::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(mAttributeNameWidget, "StatName");
@ -211,23 +211,23 @@ void MWAttribute::initialiseOverride()
mAttributeValueWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked);
}
}
}
/* MWSpell */
/* MWSpell */
MWSpell::MWSpell()
MWSpell::MWSpell()
: mSpellNameWidget(NULL)
{
}
{
}
void MWSpell::setSpellId(const std::string &spellId)
{
void MWSpell::setSpellId(const std::string &spellId)
{
mId = spellId;
updateWidgets();
}
}
void MWSpell::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags)
{
void MWSpell::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags)
{
const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore();
@ -254,10 +254,10 @@ void MWSpell::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::W
coord.top += effect->getHeight();
coord.width = std::max(coord.width, effect->getRequestedWidth());
}
}
}
void MWSpell::updateWidgets()
{
void MWSpell::updateWidgets()
{
if (mSpellNameWidget && MWBase::Environment::get().getWindowManager())
{
const MWWorld::ESMStore &store =
@ -269,34 +269,34 @@ void MWSpell::updateWidgets()
else
static_cast<MyGUI::TextBox*>(mSpellNameWidget)->setCaption("");
}
}
}
void MWSpell::initialiseOverride()
{
void MWSpell::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(mSpellNameWidget, "StatName");
}
}
MWSpell::~MWSpell()
{
}
MWSpell::~MWSpell()
{
}
/* MWEffectList */
/* MWEffectList */
MWEffectList::MWEffectList()
MWEffectList::MWEffectList()
: mEffectList(0)
{
}
{
}
void MWEffectList::setEffectList(const SpellEffectList& list)
{
void MWEffectList::setEffectList(const SpellEffectList& list)
{
mEffectList = list;
updateWidgets();
}
}
void MWEffectList::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags)
{
void MWEffectList::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags)
{
// We don't know the width of all the elements beforehand, so we do it in
// 2 steps: first, create all widgets and check their width....
MWSpellEffectPtr effect = NULL;
@ -334,23 +334,23 @@ void MWEffectList::createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyG
// inform the parent about width
coord.width = maxwidth;
}
}
void MWEffectList::updateWidgets()
{
}
void MWEffectList::updateWidgets()
{
}
void MWEffectList::initialiseOverride()
{
void MWEffectList::initialiseOverride()
{
Base::initialiseOverride();
}
}
MWEffectList::~MWEffectList()
{
}
MWEffectList::~MWEffectList()
{
}
SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
{
SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
{
SpellEffectList result;
std::vector<ESM::ENAMstruct>::const_iterator end = effects->mList.end();
for (std::vector<ESM::ENAMstruct>::const_iterator it = effects->mList.begin(); it != end; ++it)
@ -367,25 +367,25 @@ SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
result.push_back(params);
}
return result;
}
}
/* MWSpellEffect */
/* MWSpellEffect */
MWSpellEffect::MWSpellEffect()
MWSpellEffect::MWSpellEffect()
: mImageWidget(NULL)
, mTextWidget(NULL)
, mRequestedWidth(0)
{
}
{
}
void MWSpellEffect::setSpellEffect(const SpellEffectParams& params)
{
void MWSpellEffect::setSpellEffect(const SpellEffectParams& params)
{
mEffectParams = params;
updateWidgets();
}
}
void MWSpellEffect::updateWidgets()
{
void MWSpellEffect::updateWidgets()
{
if (!mEffectParams.mKnown)
{
mTextWidget->setCaption ("?");
@ -462,33 +462,33 @@ void MWSpellEffect::updateWidgets()
std::string path = std::string("icons\\") + magicEffect->mIcon;
fixTexturePath(path);
mImageWidget->setImageTexture(path);
}
}
MWSpellEffect::~MWSpellEffect()
{
}
MWSpellEffect::~MWSpellEffect()
{
}
void MWSpellEffect::initialiseOverride()
{
void MWSpellEffect::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(mTextWidget, "Text");
assignWidget(mImageWidget, "Image");
}
}
/* MWDynamicStat */
/* MWDynamicStat */
MWDynamicStat::MWDynamicStat()
: mValue(0)
, mMax(1)
, mTextWidget(NULL)
, mBarWidget(NULL)
, mBarTextWidget(NULL)
{
}
MWDynamicStat::MWDynamicStat()
: mValue(0)
, mMax(1)
, mTextWidget(NULL)
, mBarWidget(NULL)
, mBarTextWidget(NULL)
{
}
void MWDynamicStat::setValue(int cur, int max)
{
void MWDynamicStat::setValue(int cur, int max)
{
mValue = cur;
mMax = max;
@ -510,33 +510,33 @@ void MWDynamicStat::setValue(int cur, int max)
else
static_cast<MyGUI::TextBox*>(mBarTextWidget)->setCaption("");
}
}
void MWDynamicStat::setTitle(const std::string& text)
{
}
void MWDynamicStat::setTitle(const std::string& text)
{
if (mTextWidget)
static_cast<MyGUI::TextBox*>(mTextWidget)->setCaption(text);
}
}
MWDynamicStat::~MWDynamicStat()
{
}
MWDynamicStat::~MWDynamicStat()
{
}
void MWDynamicStat::initialiseOverride()
{
void MWDynamicStat::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(mTextWidget, "Text");
assignWidget(mBarWidget, "Bar");
assignWidget(mBarTextWidget, "BarText");
}
}
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w)
{
void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w)
{
if (w->getParent () != 0)
{
Box* b = dynamic_cast<Box*>(w->getParent());
@ -552,23 +552,23 @@ void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w)
w->setSize(getRequestedSize ());
}
}
}
}
MyGUI::IntSize AutoSizedTextBox::getRequestedSize()
{
MyGUI::IntSize AutoSizedTextBox::getRequestedSize()
{
return getTextSize();
}
}
void AutoSizedTextBox::setCaption(const MyGUI::UString& _value)
{
void AutoSizedTextBox::setCaption(const MyGUI::UString& _value)
{
TextBox::setCaption(_value);
notifySizeChange (this);
}
}
void AutoSizedTextBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
void AutoSizedTextBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
if (_key == "ExpandDirection")
{
mExpandDirection = MyGUI::Align::parse (_value);
@ -577,24 +577,24 @@ void AutoSizedTextBox::setPropertyOverride(const std::string& _key, const std::s
{
TextBox::setPropertyOverride (_key, _value);
}
}
}
MyGUI::IntSize AutoSizedEditBox::getRequestedSize()
{
MyGUI::IntSize AutoSizedEditBox::getRequestedSize()
{
if (getAlign().isHStretch())
throw std::runtime_error("AutoSizedEditBox can't have HStretch align (" + getName() + ")");
return MyGUI::IntSize(getSize().width, getTextSize().height);
}
}
void AutoSizedEditBox::setCaption(const MyGUI::UString& _value)
{
void AutoSizedEditBox::setCaption(const MyGUI::UString& _value)
{
EditBox::setCaption(_value);
notifySizeChange (this);
}
}
void AutoSizedEditBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
void AutoSizedEditBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
if (_key == "ExpandDirection")
{
mExpandDirection = MyGUI::Align::parse (_value);
@ -603,25 +603,25 @@ void AutoSizedEditBox::setPropertyOverride(const std::string& _key, const std::s
{
EditBox::setPropertyOverride (_key, _value);
}
}
}
MyGUI::IntSize AutoSizedButton::getRequestedSize()
{
MyGUI::IntSize AutoSizedButton::getRequestedSize()
{
MyGUI::IntSize size = getTextSize() + MyGUI::IntSize(24,0);
size.height = std::max(24, size.height);
return size;
}
}
void AutoSizedButton::setCaption(const MyGUI::UString& _value)
{
void AutoSizedButton::setCaption(const MyGUI::UString& _value)
{
Button::setCaption(_value);
notifySizeChange (this);
}
}
void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::string& _value)
{
void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::string& _value)
{
if (_key == "ExpandDirection")
{
mExpandDirection = MyGUI::Align::parse (_value);
@ -630,33 +630,33 @@ void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::st
{
Button::setPropertyOverride (_key, _value);
}
}
}
Box::Box()
Box::Box()
: mSpacing(4)
, mPadding(0)
, mAutoResize(false)
{
{
}
}
void Box::notifyChildrenSizeChanged ()
{
void Box::notifyChildrenSizeChanged ()
{
align();
}
}
void Box::_setPropertyImpl(const std::string& _key, const std::string& _value)
{
void Box::_setPropertyImpl(const std::string& _key, const std::string& _value)
{
if (_key == "Spacing")
mSpacing = MyGUI::utility::parseValue<int>(_value);
else if (_key == "Padding")
mPadding = MyGUI::utility::parseValue<int>(_value);
else if (_key == "AutoResize")
mAutoResize = MyGUI::utility::parseValue<bool>(_value);
}
}
void HBox::align ()
{
void HBox::align ()
{
unsigned int count = getChildCount ();
size_t h_stretched_count = 0;
int total_width = 0;
@ -718,32 +718,32 @@ void HBox::align ()
if (i != count-1)
curX += mSpacing;
}
}
}
void HBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
void HBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
Box::_setPropertyImpl (_key, _value);
}
}
void HBox::setSize (const MyGUI::IntSize& _value)
{
void HBox::setSize (const MyGUI::IntSize& _value)
{
MyGUI::Widget::setSize (_value);
align();
}
}
void HBox::setCoord (const MyGUI::IntCoord& _value)
{
void HBox::setCoord (const MyGUI::IntCoord& _value)
{
MyGUI::Widget::setCoord (_value);
align();
}
}
void HBox::onWidgetCreated(MyGUI::Widget* _widget)
{
void HBox::onWidgetCreated(MyGUI::Widget* _widget)
{
align();
}
}
MyGUI::IntSize HBox::getRequestedSize ()
{
MyGUI::IntSize HBox::getRequestedSize ()
{
MyGUI::IntSize size(0,0);
for (unsigned int i = 0; i < getChildCount (); ++i)
{
@ -771,13 +771,13 @@ MyGUI::IntSize HBox::getRequestedSize ()
size.width += mPadding*2;
}
return size;
}
}
void VBox::align ()
{
void VBox::align ()
{
unsigned int count = getChildCount ();
size_t v_stretched_count = 0;
int total_height = 0;
@ -839,27 +839,27 @@ void VBox::align ()
if (i != count-1)
curY += mSpacing;
}
}
}
void VBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
void VBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
Box::_setPropertyImpl (_key, _value);
}
}
void VBox::setSize (const MyGUI::IntSize& _value)
{
void VBox::setSize (const MyGUI::IntSize& _value)
{
MyGUI::Widget::setSize (_value);
align();
}
}
void VBox::setCoord (const MyGUI::IntCoord& _value)
{
void VBox::setCoord (const MyGUI::IntCoord& _value)
{
MyGUI::Widget::setCoord (_value);
align();
}
}
MyGUI::IntSize VBox::getRequestedSize ()
{
MyGUI::IntSize VBox::getRequestedSize ()
{
MyGUI::IntSize size(0,0);
for (unsigned int i = 0; i < getChildCount (); ++i)
{
@ -887,9 +887,11 @@ MyGUI::IntSize VBox::getRequestedSize ()
size.width += mPadding*2;
}
return size;
}
}
void VBox::onWidgetCreated(MyGUI::Widget* _widget)
{
void VBox::onWidgetCreated(MyGUI::Widget* _widget)
{
align();
}
}
}

View file

@ -1,7 +1,5 @@
#include "windowbase.hpp"
#include <components/settings/settings.hpp>
#include "../mwbase/windowmanager.hpp"
using namespace MWGui;

View file

@ -1,39 +1,20 @@
#include "windowmanagerimp.hpp"
#include <cassert>
#include <iterator>
#include <MyGUI_UString.h>
#include <openengine/ogre/renderer.hpp>
#include <openengine/gui/manager.hpp>
#include <components/settings/settings.hpp>
#include <components/translation/translation.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/cellstore.hpp"
#include "console.hpp"
#include "journalwindow.hpp"
#include "charactercreation.hpp"
#include "textinput.hpp"
#include "review.hpp"
#include "dialogue.hpp"
#include "dialoguehistory.hpp"
#include "mapwindow.hpp"
#include "statswindow.hpp"
#include "messagebox.hpp"
#include "container.hpp"
#include "inventorywindow.hpp"
#include "tooltips.hpp"
#include "scrollwindow.hpp"
#include "bookwindow.hpp"
#include "list.hpp"
#include "hud.hpp"
#include "mainmenu.hpp"
#include "countdialog.hpp"
@ -48,21 +29,20 @@
#include "loadingscreen.hpp"
#include "levelupdialog.hpp"
#include "waitdialog.hpp"
#include "spellcreationdialog.hpp"
#include "enchantingdialog.hpp"
#include "trainingwindow.hpp"
#include "imagebutton.hpp"
#include "exposedwindow.hpp"
#include "cursor.hpp"
#include "spellicons.hpp"
#include "merchantrepair.hpp"
#include "repair.hpp"
#include "soulgemdialog.hpp"
#include "companionwindow.hpp"
#include "inventorywindow.hpp"
using namespace MWGui;
namespace MWGui
{
WindowManager::WindowManager(
WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *ogre,
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
Translation::Storage& translationDataStorage)
@ -120,7 +100,7 @@ WindowManager::WindowManager(
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
, mHudEnabled(true)
, mTranslationDataStorage (translationDataStorage)
{
{
// Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath);
mGui = mGuiManager->getGui();
@ -223,10 +203,10 @@ WindowManager::WindowManager(
// Set up visibility
updateVisible();
}
}
WindowManager::~WindowManager()
{
WindowManager::~WindowManager()
{
delete mConsole;
delete mMessageBoxManager;
delete mHud;
@ -265,10 +245,10 @@ WindowManager::~WindowManager()
cleanupGarbage();
delete mGuiManager;
}
}
void WindowManager::cleanupGarbage()
{
void WindowManager::cleanupGarbage()
{
// Delete any dialogs which are no longer in use
if (!mGarbageDialogs.empty())
{
@ -278,10 +258,10 @@ void WindowManager::cleanupGarbage()
}
mGarbageDialogs.clear();
}
}
}
void WindowManager::update()
{
void WindowManager::update()
{
cleanupGarbage();
mHud->setFPS(mFPS);
@ -291,10 +271,10 @@ void WindowManager::update()
mHud->update();
mCursor->update();
}
}
void WindowManager::updateVisible()
{
void WindowManager::updateVisible()
{
// Start out by hiding everything except the HUD
mMap->setVisible(false);
mMenu->setVisible(false);
@ -477,10 +457,10 @@ void WindowManager::updateVisible()
// Unsupported mode, switch back to game
break;
}
}
}
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
mStatsWindow->setValue (id, value);
mCharGen->setValue(id, value);
@ -507,20 +487,20 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int
mPlayerAttributes[attributes[i]] = value;
break;
}
}
}
void WindowManager::setValue (int parSkill, const MWMechanics::Stat<float>& value)
{
void WindowManager::setValue (int parSkill, const MWMechanics::Stat<float>& value)
{
/// \todo Don't use the skill enum as a parameter type (we will have to drop it anyway, once we
/// allow custom skills.
mStatsWindow->setValue(static_cast<ESM::Skill::SkillEnum> (parSkill), value);
mCharGen->setValue(static_cast<ESM::Skill::SkillEnum> (parSkill), value);
mPlayerSkillValues[parSkill] = value;
}
}
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
mStatsWindow->setValue (id, value);
mHud->setValue (id, value);
mCharGen->setValue(id, value);
@ -539,72 +519,72 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicS
mPlayerFatigue = value;
mCharGen->setPlayerFatigue (value);
}
}
}
#if 0
MWMechanics::DynamicStat<int> WindowManager::getValue(const std::string& id)
{
#if 0
MWMechanics::DynamicStat<int> WindowManager::getValue(const std::string& id)
{
if(id == "HBar")
return layerHealth;
else if (id == "MBar")
return mPlayerMagicka;
else if (id == "FBar")
return mPlayerFatigue;
}
#endif
}
#endif
void WindowManager::setValue (const std::string& id, const std::string& value)
{
void WindowManager::setValue (const std::string& id, const std::string& value)
{
mStatsWindow->setValue (id, value);
if (id=="name")
mPlayerName = value;
else if (id=="race")
mPlayerRaceId = value;
}
}
void WindowManager::setValue (const std::string& id, int value)
{
void WindowManager::setValue (const std::string& id, int value)
{
mStatsWindow->setValue (id, value);
}
}
void WindowManager::setPlayerClass (const ESM::Class &class_)
{
void WindowManager::setPlayerClass (const ESM::Class &class_)
{
mStatsWindow->setValue("class", class_.mName);
}
}
void WindowManager::configureSkills (const SkillList& major, const SkillList& minor)
{
void WindowManager::configureSkills (const SkillList& major, const SkillList& minor)
{
mStatsWindow->configureSkills (major, minor);
mCharGen->configureSkills(major, minor);
mPlayerMajorSkills = major;
mPlayerMinorSkills = minor;
}
}
void WindowManager::setReputation (int reputation)
{
void WindowManager::setReputation (int reputation)
{
mStatsWindow->setReputation (reputation);
}
}
void WindowManager::setBounty (int bounty)
{
void WindowManager::setBounty (int bounty)
{
mStatsWindow->setBounty (bounty);
}
}
void WindowManager::updateSkillArea()
{
void WindowManager::updateSkillArea()
{
mStatsWindow->updateSkillArea();
}
}
void WindowManager::removeDialog(OEngine::GUI::Layout*dialog)
{
void WindowManager::removeDialog(OEngine::GUI::Layout*dialog)
{
if (!dialog)
return;
dialog->setVisible(false);
mGarbageDialogs.push_back(dialog);
}
}
void WindowManager::messageBox (const std::string& message, const std::vector<std::string>& buttons)
{
void WindowManager::messageBox (const std::string& message, const std::vector<std::string>& buttons)
{
if(buttons.empty()){
/* If there are no buttons, and there is a dialogue window open, messagebox goes to the dialogue window */
if(!mGuiModes.empty() && mGuiModes.back() == GM_Dialogue)
@ -618,20 +598,20 @@ void WindowManager::messageBox (const std::string& message, const std::vector<st
mMessageBoxManager->createInteractiveMessageBox(message, buttons);
MWBase::Environment::get().getInputManager()->changeInputMode(isGuiMode());
}
}
}
void WindowManager::enterPressed ()
{
void WindowManager::enterPressed ()
{
mMessageBoxManager->enterPressed();
}
}
int WindowManager::readPressedButton ()
{
int WindowManager::readPressedButton ()
{
return mMessageBoxManager->readPressedButton();
}
}
std::string WindowManager::getGameSettingString(const std::string &id, const std::string &default_)
{
std::string WindowManager::getGameSettingString(const std::string &id, const std::string &default_)
{
const ESM::GameSetting *setting =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().search(id);
@ -639,10 +619,10 @@ std::string WindowManager::getGameSettingString(const std::string &id, const std
return setting->mValue.getString();
return default_;
}
}
void WindowManager::onDialogueWindowBye()
{
void WindowManager::onDialogueWindowBye()
{
if (mDialogueWindow)
{
//FIXME set some state and stuff?
@ -650,10 +630,10 @@ void WindowManager::onDialogueWindowBye()
mDialogueWindow->setVisible(false);
}
removeGuiMode(GM_Dialogue);
}
}
void WindowManager::onFrame (float frameDuration)
{
void WindowManager::onFrame (float frameDuration)
{
mMessageBoxManager->onFrame(frameDuration);
mToolTips->onFrame(frameDuration);
@ -686,10 +666,10 @@ void WindowManager::onFrame (float frameDuration)
mContainerWindow->checkReferenceAvailable();
mCompanionWindow->checkReferenceAvailable();
mConsole->checkReferenceAvailable();
}
}
void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
{
void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
{
if (cell->mCell->isExterior())
{
std::string name;
@ -726,86 +706,86 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
mHud->setCellPrefix( cell->mCell->mName );
}
}
}
void WindowManager::setInteriorMapTexture(const int x, const int y)
{
void WindowManager::setInteriorMapTexture(const int x, const int y)
{
mMap->setActiveCell(x,y, true);
mHud->setActiveCell(x,y, true);
}
}
void WindowManager::setPlayerPos(const float x, const float y)
{
void WindowManager::setPlayerPos(const float x, const float y)
{
mMap->setPlayerPos(x,y);
mHud->setPlayerPos(x,y);
}
}
void WindowManager::setPlayerDir(const float x, const float y)
{
void WindowManager::setPlayerDir(const float x, const float y)
{
mMap->setPlayerDir(x,y);
mHud->setPlayerDir(x,y);
}
}
void WindowManager::setHMSVisibility(bool visible)
{
void WindowManager::setHMSVisibility(bool visible)
{
mHud->setHmsVisible (visible);
}
}
void WindowManager::setMinimapVisibility(bool visible)
{
void WindowManager::setMinimapVisibility(bool visible)
{
mHud->setMinimapVisible (visible);
}
}
void WindowManager::toggleFogOfWar()
{
void WindowManager::toggleFogOfWar()
{
mMap->toggleFogOfWar();
mHud->toggleFogOfWar();
}
}
void WindowManager::setFocusObject(const MWWorld::Ptr& focus)
{
void WindowManager::setFocusObject(const MWWorld::Ptr& focus)
{
mToolTips->setFocusObject(focus);
}
}
void WindowManager::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
{
void WindowManager::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
{
mToolTips->setFocusObjectScreenCoords(min_x, min_y, max_x, max_y);
}
}
void WindowManager::toggleFullHelp()
{
void WindowManager::toggleFullHelp()
{
mToolTips->toggleFullHelp();
}
}
bool WindowManager::getFullHelp() const
{
bool WindowManager::getFullHelp() const
{
return mToolTips->getFullHelp();
}
}
void WindowManager::setWeaponVisibility(bool visible)
{
void WindowManager::setWeaponVisibility(bool visible)
{
mHud->setWeapVisible (visible);
}
}
void WindowManager::setSpellVisibility(bool visible)
{
void WindowManager::setSpellVisibility(bool visible)
{
mHud->setSpellVisible (visible);
mHud->setEffectVisible (visible);
}
}
void WindowManager::setMouseVisible(bool visible)
{
void WindowManager::setMouseVisible(bool visible)
{
mCursor->setVisible(visible);
}
}
void WindowManager::setDragDrop(bool dragDrop)
{
void WindowManager::setDragDrop(bool dragDrop)
{
mToolTips->setEnabled(!dragDrop);
MWBase::Environment::get().getInputManager()->setDragDrop(dragDrop);
}
}
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
{
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
{
std::string tag(_tag);
std::string tokenToFind = "sCell=";
@ -825,10 +805,10 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r
else
_result = tag;
}
}
}
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
{
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
{
mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD"));
mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI"));
@ -873,10 +853,10 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
mGuiManager->updateWindow (mRendering->getWindow ());
mLoadingScreen->updateWindow (mRendering->getWindow ());
}
}
}
void WindowManager::pushGuiMode(GuiMode mode)
{
void WindowManager::pushGuiMode(GuiMode mode)
{
if (mode==GM_Inventory && mAllowed==GW_None)
return;
@ -893,10 +873,10 @@ void WindowManager::pushGuiMode(GuiMode mode)
MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
updateVisible();
}
}
void WindowManager::popGuiMode()
{
void WindowManager::popGuiMode()
{
if (!mGuiModes.empty())
mGuiModes.pop_back();
@ -904,10 +884,10 @@ void WindowManager::popGuiMode()
MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
updateVisible();
}
}
void WindowManager::removeGuiMode(GuiMode mode)
{
void WindowManager::removeGuiMode(GuiMode mode)
{
std::vector<GuiMode>::iterator it = mGuiModes.begin();
while (it != mGuiModes.end())
{
@ -921,103 +901,103 @@ void WindowManager::removeGuiMode(GuiMode mode)
MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
updateVisible();
}
}
void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
mHud->setSelectedSpell(spellId, successChancePercent);
const ESM::Spell* spell =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
mSpellWindow->setTitle(spell->mName);
}
}
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item)
{
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item)
{
const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>()
.find(MWWorld::Class::get(item).getEnchantment(item));
int chargePercent = item.getCellRef().mEnchantmentCharge / static_cast<float>(ench->mData.mCharge) * 100;
mHud->setSelectedEnchantItem(item, chargePercent);
mSpellWindow->setTitle(MWWorld::Class::get(item).getName(item));
}
}
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item)
{
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item)
{
int durabilityPercent = item.getCellRef().mCharge / static_cast<float>(MWWorld::Class::get(item).getItemMaxHealth(item)) * 100;
mHud->setSelectedWeapon(item, durabilityPercent);
mInventoryWindow->setTitle(MWWorld::Class::get(item).getName(item));
}
}
void WindowManager::unsetSelectedSpell()
{
void WindowManager::unsetSelectedSpell()
{
mHud->unsetSelectedSpell();
mSpellWindow->setTitle("#{sNone}");
}
}
void WindowManager::unsetSelectedWeapon()
{
void WindowManager::unsetSelectedWeapon()
{
mHud->unsetSelectedWeapon();
mInventoryWindow->setTitle("#{sSkillHandtohand}");
}
}
void WindowManager::getMousePosition(int &x, int &y)
{
void WindowManager::getMousePosition(int &x, int &y)
{
const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition();
x = pos.left;
y = pos.top;
}
}
void WindowManager::getMousePosition(float &x, float &y)
{
void WindowManager::getMousePosition(float &x, float &y)
{
const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition();
x = pos.left;
y = pos.top;
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
x /= viewSize.width;
y /= viewSize.height;
}
}
bool WindowManager::getWorldMouseOver()
{
bool WindowManager::getWorldMouseOver()
{
return mHud->getWorldMouseOver();
}
}
void WindowManager::executeInConsole (const std::string& path)
{
void WindowManager::executeInConsole (const std::string& path)
{
mConsole->executeFile (path);
}
}
void WindowManager::wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount)
{
void WindowManager::wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount)
{
mFPS = fps;
mTriangleCount = triangleCount;
mBatchCount = batchCount;
}
}
MyGUI::Gui* WindowManager::getGui() const { return mGui; }
MyGUI::Gui* WindowManager::getGui() const { return mGui; }
MWGui::DialogueWindow* WindowManager::getDialogueWindow() { return mDialogueWindow; }
MWGui::ContainerWindow* WindowManager::getContainerWindow() { return mContainerWindow; }
MWGui::InventoryWindow* WindowManager::getInventoryWindow() { return mInventoryWindow; }
MWGui::BookWindow* WindowManager::getBookWindow() { return mBookWindow; }
MWGui::ScrollWindow* WindowManager::getScrollWindow() { return mScrollWindow; }
MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; }
MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; }
MWGui::TradeWindow* WindowManager::getTradeWindow() { return mTradeWindow; }
MWGui::SpellBuyingWindow* WindowManager::getSpellBuyingWindow() { return mSpellBuyingWindow; }
MWGui::TravelWindow* WindowManager::getTravelWindow() { return mTravelWindow; }
MWGui::SpellWindow* WindowManager::getSpellWindow() { return mSpellWindow; }
MWGui::Console* WindowManager::getConsole() { return mConsole; }
MWGui::DialogueWindow* WindowManager::getDialogueWindow() { return mDialogueWindow; }
MWGui::ContainerWindow* WindowManager::getContainerWindow() { return mContainerWindow; }
MWGui::InventoryWindow* WindowManager::getInventoryWindow() { return mInventoryWindow; }
MWGui::BookWindow* WindowManager::getBookWindow() { return mBookWindow; }
MWGui::ScrollWindow* WindowManager::getScrollWindow() { return mScrollWindow; }
MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; }
MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; }
MWGui::TradeWindow* WindowManager::getTradeWindow() { return mTradeWindow; }
MWGui::SpellBuyingWindow* WindowManager::getSpellBuyingWindow() { return mSpellBuyingWindow; }
MWGui::TravelWindow* WindowManager::getTravelWindow() { return mTravelWindow; }
MWGui::SpellWindow* WindowManager::getSpellWindow() { return mSpellWindow; }
MWGui::Console* WindowManager::getConsole() { return mConsole; }
bool WindowManager::isAllowed (GuiWindow wnd) const
{
bool WindowManager::isAllowed (GuiWindow wnd) const
{
return mAllowed & wnd;
}
}
void WindowManager::allow (GuiWindow wnd)
{
void WindowManager::allow (GuiWindow wnd)
{
mAllowed = (GuiWindow)(mAllowed | wnd);
if (wnd & GW_Inventory)
@ -1027,176 +1007,178 @@ void WindowManager::allow (GuiWindow wnd)
}
updateVisible();
}
}
void WindowManager::disallowAll()
{
void WindowManager::disallowAll()
{
mAllowed = GW_None;
mBookWindow->setInventoryAllowed (false);
mScrollWindow->setInventoryAllowed (false);
updateVisible();
}
}
void WindowManager::toggleVisible (GuiWindow wnd)
{
void WindowManager::toggleVisible (GuiWindow wnd)
{
mShown = (mShown & wnd) ? (GuiWindow) (mShown & ~wnd) : (GuiWindow) (mShown | wnd);
updateVisible();
}
}
bool WindowManager::isGuiMode() const
{
bool WindowManager::isGuiMode() const
{
return !mGuiModes.empty() || mMessageBoxManager->isInteractiveMessageBox();
}
}
bool WindowManager::isConsoleMode() const
{
bool WindowManager::isConsoleMode() const
{
if (!mGuiModes.empty() && mGuiModes.back()==GM_Console)
return true;
return false;
}
}
MWGui::GuiMode WindowManager::getMode() const
{
MWGui::GuiMode WindowManager::getMode() const
{
if (mGuiModes.empty())
return GM_None;
return mGuiModes.back();
}
}
std::map<int, MWMechanics::Stat<float> > WindowManager::getPlayerSkillValues()
{
std::map<int, MWMechanics::Stat<float> > WindowManager::getPlayerSkillValues()
{
return mPlayerSkillValues;
}
}
std::map<int, MWMechanics::Stat<int> > WindowManager::getPlayerAttributeValues()
{
std::map<int, MWMechanics::Stat<int> > WindowManager::getPlayerAttributeValues()
{
return mPlayerAttributes;
}
}
WindowManager::SkillList WindowManager::getPlayerMinorSkills()
{
WindowManager::SkillList WindowManager::getPlayerMinorSkills()
{
return mPlayerMinorSkills;
}
}
WindowManager::SkillList WindowManager::getPlayerMajorSkills()
{
WindowManager::SkillList WindowManager::getPlayerMajorSkills()
{
return mPlayerMajorSkills;
}
}
void WindowManager::disallowMouse()
{
void WindowManager::disallowMouse()
{
mInputBlocker->setVisible (true);
}
}
void WindowManager::allowMouse()
{
void WindowManager::allowMouse()
{
mInputBlocker->setVisible (!isGuiMode ());
}
}
void WindowManager::notifyInputActionBound ()
{
void WindowManager::notifyInputActionBound ()
{
mSettingsWindow->updateControlsBox ();
allowMouse();
}
}
void WindowManager::showCrosshair (bool show)
{
void WindowManager::showCrosshair (bool show)
{
mHud->setCrosshairVisible (show && mCrosshairEnabled);
}
}
void WindowManager::activateQuickKey (int index)
{
void WindowManager::activateQuickKey (int index)
{
mQuickKeysMenu->activateQuickKey(index);
}
}
bool WindowManager::getSubtitlesEnabled ()
{
bool WindowManager::getSubtitlesEnabled ()
{
return mSubtitlesEnabled;
}
}
void WindowManager::toggleHud ()
{
void WindowManager::toggleHud ()
{
mHudEnabled = !mHudEnabled;
mHud->setVisible (mHudEnabled);
}
}
void WindowManager::setLoadingProgress (const std::string& stage, int depth, int current, int total)
{
void WindowManager::setLoadingProgress (const std::string& stage, int depth, int current, int total)
{
mLoadingScreen->setLoadingProgress (stage, depth, current, total);
}
}
void WindowManager::loadingDone ()
{
void WindowManager::loadingDone ()
{
mLoadingScreen->loadingDone ();
}
}
bool WindowManager::getPlayerSleeping ()
{
bool WindowManager::getPlayerSleeping ()
{
return mWaitDialog->getSleeping();
}
}
void WindowManager::wakeUpPlayer()
{
void WindowManager::wakeUpPlayer()
{
mWaitDialog->wakeUp();
}
}
void WindowManager::addVisitedLocation(const std::string& name, int x, int y)
{
void WindowManager::addVisitedLocation(const std::string& name, int x, int y)
{
mMap->addVisitedLocation (name, x, y);
}
}
void WindowManager::startSpellMaking(MWWorld::Ptr actor)
{
void WindowManager::startSpellMaking(MWWorld::Ptr actor)
{
mSpellCreationDialog->startSpellMaking (actor);
}
}
void WindowManager::startEnchanting (MWWorld::Ptr actor)
{
void WindowManager::startEnchanting (MWWorld::Ptr actor)
{
mEnchantingDialog->startEnchanting (actor);
}
}
void WindowManager::startSelfEnchanting(MWWorld::Ptr soulgem)
{
void WindowManager::startSelfEnchanting(MWWorld::Ptr soulgem)
{
mEnchantingDialog->startSelfEnchanting(soulgem);
}
}
void WindowManager::startTraining(MWWorld::Ptr actor)
{
void WindowManager::startTraining(MWWorld::Ptr actor)
{
mTrainingWindow->startTraining(actor);
}
}
void WindowManager::startRepair(MWWorld::Ptr actor)
{
void WindowManager::startRepair(MWWorld::Ptr actor)
{
mMerchantRepair->startRepair(actor);
}
}
void WindowManager::startRepairItem(MWWorld::Ptr item)
{
void WindowManager::startRepairItem(MWWorld::Ptr item)
{
mRepair->startRepairItem(item);
}
}
const Translation::Storage& WindowManager::getTranslationDataStorage() const
{
const Translation::Storage& WindowManager::getTranslationDataStorage() const
{
return mTranslationDataStorage;
}
}
void WindowManager::showCompanionWindow(MWWorld::Ptr actor)
{
void WindowManager::showCompanionWindow(MWWorld::Ptr actor)
{
mCompanionWindow->open(actor);
}
}
void WindowManager::changePointer(const std::string &name)
{
void WindowManager::changePointer(const std::string &name)
{
mCursor->onCursorChange(name);
}
}
void WindowManager::showSoulgemDialog(MWWorld::Ptr item)
{
void WindowManager::showSoulgemDialog(MWWorld::Ptr item)
{
mSoulgemDialog->show(item);
}
}
void WindowManager::frameStarted (float dt)
{
void WindowManager::frameStarted (float dt)
{
mInventoryWindow->doRenderUpdate ();
}
}

View file

@ -1,22 +1,20 @@
#include "windowpinnablebase.hpp"
#include "../mwbase/windowmanager.hpp"
#include "exposedwindow.hpp"
using namespace MWGui;
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout)
: WindowBase(parLayout), mPinned(false), mVisible(false)
namespace MWGui
{
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout)
: WindowBase(parLayout), mPinned(false), mVisible(false)
{
ExposedWindow* window = static_cast<ExposedWindow*>(mMainWidget);
mPinButton = window->getSkinWidget ("Button");
mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked);
}
}
void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
{
void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
{
mPinned = !mPinned;
if (mPinned)
@ -25,4 +23,5 @@ void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
mPinButton->changeWidgetSkin ("PinUp");
onPinToggled();
}
}

View file

@ -290,6 +290,13 @@ namespace MWMechanics
return 0;
}
void Actors::forceStateUpdate(const MWWorld::Ptr & ptr)
{
PtrControllerMap::iterator iter = mActors.find(ptr);
if(iter != mActors.end())
iter->second.forceStateUpdate();
}
void Actors::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{
PtrControllerMap::iterator iter = mActors.find(ptr);

View file

@ -78,6 +78,8 @@ namespace MWMechanics
int countDeaths (const std::string& id) const;
///< Return the number of deaths for actors with the given ID.
void forceStateUpdate(const MWWorld::Ptr &ptr);
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
void skipAnimation(const MWWorld::Ptr& ptr);
};

View file

@ -103,14 +103,13 @@ static void getStateInfo(CharacterState state, std::string *group)
CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop)
: mPtr(ptr), mAnimation(anim), mState(state), mSkipAnim(false)
: mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false)
{
if(!mAnimation)
return;
mAnimation->setController(this);
getStateInfo(mState, &mCurrentGroup);
std::string group;
getStateInfo(mCharState, &group);
if(MWWorld::Class::get(mPtr).isActor())
{
/* Accumulate along X/Y only for now, until we can figure out how we should
@ -122,19 +121,8 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
/* Don't accumulate with non-actors. */
mAnimation->setAccumulation(Ogre::Vector3(0.0f));
}
if(mAnimation->hasAnimation(mCurrentGroup))
mAnimation->play(mCurrentGroup, "stop", "stop", loop);
}
CharacterController::CharacterController(const CharacterController &rhs)
: mPtr(rhs.mPtr), mAnimation(rhs.mAnimation), mAnimQueue(rhs.mAnimQueue)
, mCurrentGroup(rhs.mCurrentGroup), mState(rhs.mState)
, mSkipAnim(rhs.mSkipAnim)
{
if(!mAnimation)
return;
/* We've been copied. Update the animation with the new controller. */
mAnimation->setController(this);
if(mAnimation->hasAnimation(group))
mMovingAnim = mAnimation->play(group, "start", "stop", 1.0f, loop ? (~(size_t)0) : 0);
}
CharacterController::~CharacterController()
@ -148,31 +136,6 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
}
void CharacterController::markerEvent(float time, const std::string &evt)
{
if(evt == "stop")
{
if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1])
{
mAnimQueue.pop_front();
mAnimation->play(mCurrentGroup, "loop start", "stop", false);
}
else if(mAnimQueue.size() > 0)
{
mAnimQueue.pop_front();
if(mAnimQueue.size() > 0)
{
mCurrentGroup = mAnimQueue.front();
mAnimation->play(mCurrentGroup, "start", "stop", false);
}
}
return;
}
std::cerr<< "Unhandled animation event: "<<evt <<std::endl;
}
void CharacterController::update(float duration, Movement &movement)
{
float speed = 0.0f;
@ -214,11 +177,13 @@ void CharacterController::update(float duration, Movement &movement)
if(vec.x > 0.0f)
setState(inwater ? (isrunning ? CharState_SwimRunRight : CharState_SwimWalkRight)
: (sneak ? CharState_SneakRight : (isrunning ? CharState_RunRight : CharState_WalkRight)), true);
else if(vec.x < 0.0f)
setState(inwater ? (isrunning ? CharState_SwimRunLeft : CharState_SwimWalkLeft)
: (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true);
// If this animation isn't moving us sideways, do it manually
if(!mMovingAnim)
movement.mPosition[0] += vec.x * (speed*duration);
// Apply any forward/backward movement manually
movement.mPosition[1] += vec.y * (speed*duration);
}
@ -227,12 +192,15 @@ void CharacterController::update(float duration, Movement &movement)
if(vec.y > 0.0f)
setState(inwater ? (isrunning ? CharState_SwimRunForward : CharState_SwimWalkForward)
: (sneak ? CharState_SneakForward : (isrunning ? CharState_RunForward : CharState_WalkForward)), true);
else if(vec.y < 0.0f)
setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack)
: (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true);
// Apply any sideways movement manually
movement.mPosition[0] += vec.x * (speed*duration);
// If this animation isn't moving us forward/backward, do it manually
if(!mMovingAnim)
movement.mPosition[1] += vec.y * (speed*duration);
}
else if(rot.z != 0.0f && !inwater && !sneak)
{
@ -241,8 +209,18 @@ void CharacterController::update(float duration, Movement &movement)
else if(rot.z < 0.0f)
setState(CharState_TurnLeft, true);
}
else if(mAnimQueue.size() == 0)
else if(getState() != CharState_SpecialIdle || !mAnimation->isPlaying(0))
{
if(mAnimQueue.size() == 0)
setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true);
else
{
mMovingAnim = mAnimation->play(mAnimQueue.front().first,
"start", "stop", 0.0f,
mAnimQueue.front().second);
mAnimQueue.pop_front();
}
}
movement.mRotation[0] += rot.x * duration;
movement.mRotation[1] += rot.y * duration;
@ -268,20 +246,17 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
else
{
count = std::max(count, 1);
if(mode != 0 || mAnimQueue.size() == 0)
if(mode != 0 || getState() != CharState_SpecialIdle)
{
mAnimQueue.clear();
while(count-- > 0)
mAnimQueue.push_back(groupname);
mCurrentGroup = groupname;
mState = CharState_SpecialIdle;
mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), "stop", false);
mCharState = CharState_SpecialIdle;
mLooping = false;
mMovingAnim = mAnimation->play(groupname, ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1);
}
else if(mode == 0)
{
mAnimQueue.resize(1);
while(count-- > 0)
mAnimQueue.push_back(groupname);
mAnimQueue.clear();
mAnimQueue.push_back(std::make_pair(groupname, count-1));
}
}
}
@ -294,25 +269,24 @@ void CharacterController::skipAnim()
void CharacterController::setState(CharacterState state, bool loop)
{
if(mState == state)
{
if(mAnimation)
mAnimation->setLooping(loop);
if(mCharState == state)
return;
}
mState = state;
mCharState = state;
mLooping = loop;
forceStateUpdate();
}
void CharacterController::forceStateUpdate()
{
if(!mAnimation)
return;
mAnimQueue.clear();
std::string anim;
getStateInfo(mState, &anim);
if(mAnimation->hasAnimation(anim))
{
mCurrentGroup = anim;
mAnimation->play(mCurrentGroup, "start", "stop", loop);
}
getStateInfo(mCharState, &anim);
if((mMovingAnim=mAnimation->hasAnimation(anim)) != false)
mMovingAnim = mAnimation->play(anim, "start", "stop", 0.0f, mLooping ? (~(size_t)0) : 0);
}
}

View file

@ -72,22 +72,17 @@ class CharacterController
MWWorld::Ptr mPtr;
MWRender::Animation *mAnimation;
typedef std::deque<std::string> AnimationQueue;
typedef std::deque<std::pair<std::string,size_t> > AnimationQueue;
AnimationQueue mAnimQueue;
std::string mCurrentGroup;
CharacterState mState;
CharacterState mCharState;
bool mLooping;
bool mSkipAnim;
protected:
/* Called by the animation whenever a new text key is reached. */
void markerEvent(float time, const std::string &evt);
friend class MWRender::Animation;
bool mMovingAnim;
public:
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop);
CharacterController(const CharacterController &rhs);
virtual ~CharacterController();
void updatePtr(const MWWorld::Ptr &ptr);
@ -99,7 +94,9 @@ public:
void setState(CharacterState state, bool loop);
CharacterState getState() const
{ return mState; }
{ return mCharState; }
void forceStateUpdate();
};
}

View file

@ -548,7 +548,7 @@ namespace MWMechanics
float bribeMod;
if (type == PT_Bribe10) bribeMod = gmst.find("fBribe10Mod")->getFloat();
if (type == PT_Bribe100) bribeMod = gmst.find("fBribe100Mod")->getFloat();
else if (type == PT_Bribe100) bribeMod = gmst.find("fBribe100Mod")->getFloat();
else bribeMod = gmst.find("fBribe1000Mod")->getFloat();
float target3 = d * (playerRating3 - npcRating3 + 50) + bribeMod;
@ -654,6 +654,12 @@ namespace MWMechanics
}
}
void MechanicsManager::forceStateUpdate(const MWWorld::Ptr &ptr)
{
if(MWWorld::Class::get(ptr).isActor())
mActors.forceStateUpdate(ptr);
}
void MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{
if(MWWorld::Class::get(ptr).isActor())

View file

@ -96,6 +96,8 @@ namespace MWMechanics
void toLower(std::string npcFaction);
///< Perform a persuasion action on NPC
virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
virtual void skipAnimation(const MWWorld::Ptr& ptr);
};

View file

@ -1,5 +1,5 @@
#include "pathfinding.hpp"
#include <boost/graph/astar_search.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/adjacency_list.hpp>
#include "boost/tuple/tuple.hpp"
#include "OgreMath.h"
@ -55,7 +55,7 @@ namespace
struct found_path {};
class goalVisited : public boost::default_astar_visitor
/*class goalVisited : public boost::default_astar_visitor
{
public:
goalVisited(PointID goal) : mGoal(goal) {}
@ -69,7 +69,7 @@ namespace
PointID mGoal;
};
class DistanceHeuristic : public boost::astar_heuristic <PathGridGraph, float>
class DistanceHeuristic : public boost::atasr_heuristic <PathGridGraph, float>
{
public:
DistanceHeuristic(const PathGridGraph & l, PointID goal)
@ -87,11 +87,23 @@ namespace
private:
const PathGridGraph & mGraph;
PointID mGoal;
};
}
};*/
class goalVisited : public boost::default_dijkstra_visitor
{
public:
goalVisited(PointID goal) : mGoal(goal) {}
void examine_vertex(PointID u, const PathGridGraph g)
{
if(u == mGoal)
throw found_path();
}
private:
PointID mGoal;
};
namespace MWMechanics
{
PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0)
{
PathGridGraph graph;
@ -126,11 +138,10 @@ namespace MWMechanics
std::list<ESM::Pathgrid::Point> shortest_path;
try {
boost::astar_search
boost::dijkstra_shortest_paths
(
graph,
start,
DistanceHeuristic(graph,end),
boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph))
);
@ -146,6 +157,10 @@ namespace MWMechanics
//end of helpers functions
}
namespace MWMechanics
{
PathFinder::PathFinder()
{
mIsPathConstructed = false;

View file

@ -1,10 +1,5 @@
#include "activatoranimation.hpp"
#include <OgreEntity.h>
#include <OgreParticleSystem.h>
#include <OgreSceneManager.h>
#include <OgreSubEntity.h>
#include "renderconst.hpp"
#include "../mwbase/world.hpp"
@ -24,28 +19,10 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
assert (ref->mBase != NULL);
if(!ref->mBase->mModel.empty())
{
std::string mesh = "meshes\\" + ref->mBase->mModel;
const std::string name = "meshes\\"+ref->mBase->mModel;
createObjectList(mPtr.getRefData().getBaseNode(), mesh);
for(size_t i = 0;i < mObjectList.mEntities.size();i++)
{
Ogre::Entity *ent = mObjectList.mEntities[i];
ent->setVisibilityFlags(RV_Misc);
for(unsigned int j=0; j < ent->getNumSubEntities(); ++j)
{
Ogre::SubEntity* subEnt = ent->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
}
for(size_t i = 0;i < mObjectList.mParticles.size();i++)
{
Ogre::ParticleSystem *part = mObjectList.mParticles[i];
part->setVisibilityFlags(RV_Misc);
part->setRenderQueueGroup(RQG_Alpha);
}
setAnimationSource(mesh);
addObjectList(mPtr.getRefData().getBaseNode(), name, false);
setRenderProperties(mObjects.back().mObjectList, RV_Misc, RQG_Main, RQG_Alpha);
}
}

View file

@ -94,6 +94,9 @@ void Actors::insertActivator (const MWWorld::Ptr& ptr)
bool Actors::deleteObject (const MWWorld::Ptr& ptr)
{
if (mAllActors.find(ptr) == mAllActors.end())
return false;
mRendering->removeWaterRippleEmitter (ptr);
delete mAllActors[ptr];
@ -139,6 +142,7 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store)
Ogre::SceneNode *base = celliter->second;
base->removeAndDestroyAllChildren();
mRend.getScene()->destroySceneNode(base);
mCellSceneNodes.erase(celliter);
}
}

View file

@ -3,6 +3,8 @@
#include <OgreSkeletonManager.h>
#include <OgreSkeletonInstance.h>
#include <OgreEntity.h>
#include <OgreSubEntity.h>
#include <OgreParticleSystem.h>
#include <OgreBone.h>
#include <OgreSubMesh.h>
#include <OgreSceneManager.h>
@ -16,6 +18,32 @@
namespace MWRender
{
Animation::AnimLayer::AnimLayer()
: mControllers(NULL)
, mTextKeys(NULL)
, mTime(0.0f)
, mPlaying(false)
, mLoopCount(0)
{
}
Ogre::Real Animation::AnimationValue::getValue() const
{
size_t idx = mIndex;
while(idx > 0 && mAnimation->mLayer[idx].mGroupName.empty())
idx--;
if(!mAnimation->mLayer[idx].mGroupName.empty())
return mAnimation->mLayer[idx].mTime;
return 0.0f;
}
void Animation::AnimationValue::setValue(Ogre::Real value)
{
mAnimation->mLayer[mIndex].mTime = value;
}
void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects)
{
for(size_t i = 0;i < objects.mParticles.size();i++)
@ -31,22 +59,22 @@ void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectL
Animation::Animation(const MWWorld::Ptr &ptr)
: mPtr(ptr)
, mController(NULL)
, mInsert(NULL)
, mSkelBase(NULL)
, mAccumRoot(NULL)
, mNonAccumRoot(NULL)
, mAccumulate(Ogre::Vector3::ZERO)
, mNonAccumCtrl(NULL)
, mAccumulate(0.0f)
, mLastPosition(0.0f)
, mCurrentControllers(NULL)
, mCurrentKeys(NULL)
, mCurrentAnim(NULL)
, mCurrentTime(0.0f)
, mStopTime(0.0f)
, mPlaying(false)
, mLooping(false)
, mAnimVelocity(0.0f)
, mAnimSpeedMult(1.0f)
{
for(size_t i = 0;i < sMaxLayers;i++)
mAnimationValuePtr[i].bind(OGRE_NEW AnimationValue(this, i));
/* As long as we remain under 128 active controllers, we can avoid
* reallocations. */
mActiveCtrls.reserve(128);
}
Animation::~Animation()
@ -54,105 +82,34 @@ Animation::~Animation()
if(mInsert)
{
Ogre::SceneManager *sceneMgr = mInsert->getCreator();
destroyObjectList(sceneMgr, mObjectList);
for(size_t i = 0;i < mAnimationSources.size();i++)
destroyObjectList(sceneMgr, mAnimationSources[i]);
mAnimationSources.clear();
for(size_t i = 0;i < mObjects.size();i++)
destroyObjectList(sceneMgr, mObjects[i].mObjectList);
mObjects.clear();
}
}
void Animation::setAnimationSources(const std::vector<std::string> &names)
void Animation::addObjectList(Ogre::SceneNode *node, const std::string &model, bool baseonly)
{
if(!mObjectList.mSkelBase)
return;
Ogre::SceneManager *sceneMgr = mInsert->getCreator();
mCurrentControllers = &mObjectList.mControllers;
mCurrentAnim = NULL;
mCurrentKeys = NULL;
mAnimVelocity = 0.0f;
mAccumRoot = NULL;
mNonAccumRoot = NULL;
mTextKeys.clear();
for(size_t i = 0;i < mAnimationSources.size();i++)
destroyObjectList(sceneMgr, mAnimationSources[i]);
mAnimationSources.clear();
Ogre::SharedPtr<Ogre::ControllerValue<Ogre::Real> > ctrlval(OGRE_NEW AnimationValue(this));
Ogre::SkeletonInstance *skelinst = mObjectList.mSkelBase->getSkeleton();
std::vector<std::string>::const_iterator nameiter;
for(nameiter = names.begin();nameiter != names.end();nameiter++)
if(!mInsert)
{
mAnimationSources.push_back(NifOgre::Loader::createObjectBase(sceneMgr, *nameiter));
if(!mAnimationSources.back().mSkelBase)
{
std::cerr<< "Failed to get skeleton source "<<*nameiter <<std::endl;
destroyObjectList(sceneMgr, mAnimationSources.back());
mAnimationSources.pop_back();
continue;
}
NifOgre::ObjectList &objects = mAnimationSources.back();
for(size_t i = 0;i < objects.mControllers.size();i++)
{
NifOgre::NodeTargetValue<Ogre::Real> *dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(objects.mControllers[i].getDestination().getPointer());
if(!dstval) continue;
const Ogre::String &trgtname = dstval->getNode()->getName();
if(!skelinst->hasBone(trgtname)) continue;
Ogre::Bone *bone = skelinst->getBone(trgtname);
dstval->setNode(bone);
}
for(size_t i = 0;i < objects.mControllers.size();i++)
{
if(objects.mControllers[i].getSource().isNull())
objects.mControllers[i].setSource(ctrlval);
}
Ogre::Entity *ent = objects.mSkelBase;
Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(ent->getSkeleton()->getName());
Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
while(boneiter.hasMoreElements())
{
Ogre::Bone *bone = boneiter.getNext();
Ogre::UserObjectBindings &bindings = bone->getUserObjectBindings();
const Ogre::Any &data = bindings.getUserAny(NifOgre::sTextKeyExtraDataID);
if(data.isEmpty() || !Ogre::any_cast<bool>(data))
continue;
if(!mNonAccumRoot)
{
mAccumRoot = mInsert;
mNonAccumRoot = mObjectList.mSkelBase->getSkeleton()->getBone(bone->getName());
}
for(int i = 0;i < skel->getNumAnimations();i++)
{
Ogre::Animation *anim = skel->getAnimation(i);
const Ogre::Any &groupdata = bindings.getUserAny(std::string(NifOgre::sTextKeyExtraDataID)+
"@"+anim->getName());
if(!groupdata.isEmpty())
mTextKeys[anim->getName()] = Ogre::any_cast<NifOgre::TextKeyMap>(groupdata);
}
break;
}
}
}
void Animation::createObjectList(Ogre::SceneNode *node, const std::string &model)
{
mInsert = node->createChildSceneNode();
assert(mInsert);
}
mObjectList = NifOgre::Loader::createObjects(mInsert, model);
if(mObjectList.mSkelBase)
mObjects.push_back(ObjectInfo());
ObjectInfo &obj = mObjects.back();
obj.mActiveLayers = 0;
obj.mObjectList = (!baseonly ? NifOgre::Loader::createObjects(mInsert, model) :
NifOgre::Loader::createObjectBase(mInsert, model));
NifOgre::ObjectList &objlist = obj.mObjectList;
if(objlist.mSkelBase)
{
Ogre::AnimationStateSet *aset = mObjectList.mSkelBase->getAllAnimationStates();
if(mObjects.size() == 1)
mSkelBase = objlist.mSkelBase;
Ogre::AnimationStateSet *aset = objlist.mSkelBase->getAllAnimationStates();
Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator();
while(asiter.hasMoreElements())
{
@ -164,27 +121,184 @@ void Animation::createObjectList(Ogre::SceneNode *node, const std::string &model
// Set the bones as manually controlled since we're applying the
// transformations manually (needed if we want to apply an animation
// from one skeleton onto another).
Ogre::SkeletonInstance *skelinst = mObjectList.mSkelBase->getSkeleton();
Ogre::SkeletonInstance *skelinst = objlist.mSkelBase->getSkeleton();
Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator();
while(boneiter.hasMoreElements())
boneiter.getNext()->setManuallyControlled(true);
}
Ogre::SharedPtr<Ogre::ControllerValue<Ogre::Real> > ctrlval(OGRE_NEW AnimationValue(this));
for(size_t i = 0;i < mObjectList.mControllers.size();i++)
if(objlist.mSkelBase && mSkelBase)
{
if(mObjectList.mControllers[i].getSource().isNull())
mObjectList.mControllers[i].setSource(ctrlval);
Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
if(mSkelBase == objlist.mSkelBase)
{
if(objlist.mTextKeys.size() > 0)
{
mAccumRoot = mInsert;
mNonAccumRoot = baseinst->getBone(objlist.mTextKeys.begin()->first);
}
}
else
{
for(size_t i = 0;i < objlist.mControllers.size();i++)
{
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(objlist.mControllers[i].getDestination().getPointer());
if(!dstval) continue;
const Ogre::String &trgtname = dstval->getNode()->getName();
if(!baseinst->hasBone(trgtname)) continue;
Ogre::Bone *bone = baseinst->getBone(trgtname);
dstval->setNode(bone);
}
}
}
for(size_t i = 0;i < objlist.mControllers.size();i++)
{
if(objlist.mControllers[i].getSource().isNull())
objlist.mControllers[i].setSource(mAnimationValuePtr[0]);
}
mActiveCtrls.insert(mActiveCtrls.end(), objlist.mControllers.begin(), objlist.mControllers.end());
}
void Animation::setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue)
{
for(size_t i = 0;i < objlist.mEntities.size();i++)
{
Ogre::Entity *ent = objlist.mEntities[i];
if(visflags != 0)
ent->setVisibilityFlags(visflags);
for(unsigned int j = 0;j < ent->getNumSubEntities();++j)
{
Ogre::SubEntity* subEnt = ent->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? transqueue : solidqueue);
}
}
for(size_t i = 0;i < objlist.mParticles.size();i++)
{
Ogre::ParticleSystem *part = objlist.mParticles[i];
if(visflags != 0)
part->setVisibilityFlags(visflags);
// TODO: Check particle material for actual transparency
part->setRenderQueueGroup(transqueue);
}
}
void Animation::clearExtraSources()
{
for(size_t layer = 0;layer < sMaxLayers;layer++)
{
mLayer[layer].mGroupName.clear();
mLayer[layer].mTextKeys = NULL;
mLayer[layer].mControllers = NULL;
mLayer[layer].mTime = 0.0f;
mLayer[layer].mLoopCount = 0;
mLayer[layer].mPlaying = false;
}
mNonAccumCtrl = NULL;
mAnimVelocity = 0.0f;
mLastPosition = Ogre::Vector3(0.0f);
if(mAccumRoot)
mAccumRoot->setPosition(mLastPosition);
if(mObjects.size() > 1)
{
mObjects.resize(1);
mObjects[0].mActiveLayers = 0;
NifOgre::ObjectList &objlist = mObjects[0].mObjectList;
mActiveCtrls.clear();
mActiveCtrls.insert(mActiveCtrls.end(), objlist.mControllers.begin(), objlist.mControllers.end());
}
}
void Animation::updateActiveControllers()
{
mActiveCtrls.clear();
/* First, get all controllers that don't target a node, or that target
* nodes that don't belong to any particular layer.
*/
std::vector<ObjectInfo>::iterator obj(mObjects.begin());
for(;obj != mObjects.end();obj++)
{
std::vector<Ogre::Controller<Ogre::Real> >::const_iterator ctrl(obj->mObjectList.mControllers.begin());
for(;ctrl != obj->mObjectList.mControllers.end();ctrl++)
{
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrl->getDestination().getPointer());
if(dstval)
{
/*if(getLayerByName(dstval->getNode()->getName()) >= 0)*/
continue;
}
mActiveCtrls.insert(mActiveCtrls.end(), *ctrl);
}
}
std::vector<Ogre::Controller<Ogre::Real> > *ctrls = NULL;
size_t layer = 0;
while(layer < sMaxLayers)
{
/* Now get controllers that target nodes that belong to this layer from
* whatever objectlist is active on this layer.
*/
std::vector<ObjectInfo>::iterator obj(mObjects.begin());
for(;obj != mObjects.end();obj++)
{
if((obj->mActiveLayers&(1<<layer)))
{
ctrls = &obj->mObjectList.mControllers;
break;
}
}
if(ctrls == NULL)
{
layer++;
continue;
}
/* Check if any objectlists are active on subsequent layers. Include
* those layers if not.
*/
size_t nextlayer = layer+1;
for(;nextlayer < sMaxLayers;nextlayer++)
{
for(obj = mObjects.begin();obj != mObjects.end();obj++)
{
if((obj->mActiveLayers&(1<<nextlayer)))
break;
}
}
std::vector<Ogre::Controller<Ogre::Real> >::const_iterator ctrl(ctrls->begin());
for(;ctrl != ctrls->end();ctrl++)
{
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrl->getDestination().getPointer());
if(dstval)
{
/*ssize_t idx = getLayerByName(dstval->getNode()->getName());
if(idx >= (ssize_t)layer && idx < (ssize_t)nextlayer)*/
mActiveCtrls.insert(mActiveCtrls.end(), *ctrl);
}
}
layer = nextlayer;
}
mCurrentControllers = &mObjectList.mControllers;
}
Ogre::Node *Animation::getNode(const std::string &name)
{
if(mObjectList.mSkelBase)
if(mSkelBase)
{
Ogre::SkeletonInstance *skel = mObjectList.mSkelBase->getSkeleton();
Ogre::SkeletonInstance *skel = mSkelBase->getSkeleton();
if(skel->hasBone(name))
return skel->getBone(name);
}
@ -192,20 +306,34 @@ Ogre::Node *Animation::getNode(const std::string &name)
}
bool Animation::hasAnimation(const std::string &anim)
NifOgre::TextKeyMap::const_iterator Animation::findGroupStart(const NifOgre::TextKeyMap &keys, const std::string &groupname)
{
for(std::vector<NifOgre::ObjectList>::const_iterator iter(mAnimationSources.begin());iter != mAnimationSources.end();iter++)
NifOgre::TextKeyMap::const_iterator iter(keys.begin());
for(;iter != keys.end();iter++)
{
if(iter->mSkelBase->hasAnimationState(anim))
return true;
if(iter->second.compare(0, groupname.size(), groupname) == 0 &&
iter->second.compare(groupname.size(), 2, ": ") == 0)
break;
}
return false;
return iter;
}
void Animation::setController(MWMechanics::CharacterController *controller)
bool Animation::hasAnimation(const std::string &anim)
{
mController = controller;
if(!mSkelBase)
return false;
for(std::vector<ObjectInfo>::const_iterator iter(mObjects.begin());iter != mObjects.end();iter++)
{
if(iter->mObjectList.mTextKeys.size() == 0)
continue;
const NifOgre::TextKeyMap &keys = iter->mObjectList.mTextKeys.begin()->second;
if(findGroupStart(keys, anim) != keys.end())
return true;
}
return false;
}
@ -221,10 +349,6 @@ void Animation::setSpeed(float speed)
mAnimSpeedMult = speed / mAnimVelocity;
}
void Animation::setLooping(bool loop)
{
mLooping = loop;
}
void Animation::updatePtr(const MWWorld::Ptr &ptr)
{
@ -232,47 +356,36 @@ void Animation::updatePtr(const MWWorld::Ptr &ptr)
}
void Animation::calcAnimVelocity()
float Animation::calcAnimVelocity(const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const Ogre::Vector3 &accum, const std::string &groupname)
{
const Ogre::NodeAnimationTrack *track = 0;
Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator();
while(!track && trackiter.hasMoreElements())
const std::string start = groupname+": start";
const std::string loopstart = groupname+": loop start";
const std::string loopstop = groupname+": loop stop";
const std::string stop = groupname+": stop";
float starttime = std::numeric_limits<float>::max();
float stoptime = 0.0f;
NifOgre::TextKeyMap::const_iterator keyiter(keys.begin());
while(keyiter != keys.end())
{
const Ogre::NodeAnimationTrack *cur = trackiter.getNext();
if(cur->getAssociatedNode()->getName() == mNonAccumRoot->getName())
track = cur;
}
if(track && track->getNumKeyFrames() > 1)
if(keyiter->second == start || keyiter->second == loopstart)
starttime = keyiter->first;
else if(keyiter->second == loopstop || keyiter->second == stop)
{
float loopstarttime = 0.0f;
float loopstoptime = mCurrentAnim->getLength();
NifOgre::TextKeyMap::const_iterator keyiter = mCurrentKeys->begin();
while(keyiter != mCurrentKeys->end())
{
if(keyiter->second == "loop start")
loopstarttime = keyiter->first;
else if(keyiter->second == "loop stop")
{
loopstoptime = keyiter->first;
stoptime = keyiter->first;
break;
}
keyiter++;
}
if(loopstoptime > loopstarttime)
if(stoptime > starttime)
{
Ogre::TransformKeyFrame startkf(0, loopstarttime);
Ogre::TransformKeyFrame endkf(0, loopstoptime);
Ogre::Vector3 startpos = nonaccumctrl->getTranslation(starttime) * accum;
Ogre::Vector3 endpos = nonaccumctrl->getTranslation(stoptime) * accum;
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(loopstarttime), &startkf);
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(loopstoptime), &endkf);
return startpos.distance(endpos) / (stoptime-starttime);
}
mAnimVelocity = startkf.getTranslate().distance(endkf.getTranslate()) /
(loopstoptime-loopstarttime);
}
}
return 0.0f;
}
static void updateBoneTree(const Ogre::SkeletonInstance *skelsrc, Ogre::Bone *bone)
@ -313,93 +426,90 @@ void Animation::updateSkeletonInstance(const Ogre::SkeletonInstance *skelsrc, Og
}
Ogre::Vector3 Animation::updatePosition()
void Animation::updatePosition(Ogre::Vector3 &position)
{
Ogre::Vector3 posdiff;
Ogre::TransformKeyFrame kf(0, mCurrentTime);
Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator();
while(trackiter.hasMoreElements())
{
const Ogre::NodeAnimationTrack *track = trackiter.getNext();
if(track->getAssociatedNode()->getName() == mNonAccumRoot->getName())
{
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(mCurrentTime), &kf);
break;
}
}
/* Get the non-accumulation root's difference from the last update. */
posdiff = (kf.getTranslate() - mLastPosition) * mAccumulate;
/* Get the non-accumulation root's difference from the last update, and move the position
* accordingly.
*/
posdiff = (mNonAccumCtrl->getTranslation(mLayer[0].mTime) - mLastPosition) * mAccumulate;
position += posdiff;
/* Translate the accumulation root back to compensate for the move. */
mLastPosition += posdiff;
mAccumRoot->setPosition(-mLastPosition);
return posdiff;
}
void Animation::reset(const std::string &start, const std::string &stop)
bool Animation::reset(size_t layeridx, const NifOgre::TextKeyMap &keys, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint)
{
mNextKey = mCurrentKeys->begin();
while(mNextKey != mCurrentKeys->end() && mNextKey->second != start)
mNextKey++;
if(mNextKey != mCurrentKeys->end())
mCurrentTime = mNextKey->first;
else
std::string tag = groupname+": "+start;
NifOgre::TextKeyMap::const_iterator startkey(keys.begin());
while(startkey != keys.end() && startkey->second != tag)
startkey++;
if(startkey == keys.end() && start == "loop start")
{
mNextKey = mCurrentKeys->begin();
while(mNextKey != mCurrentKeys->end() && mNextKey->second != "start")
mNextKey++;
if(mNextKey != mCurrentKeys->end())
mCurrentTime = mNextKey->first;
else
{
mNextKey = mCurrentKeys->begin();
mCurrentTime = 0.0f;
tag = groupname+": start";
startkey = keys.begin();
while(startkey != keys.end() && startkey->second != tag)
startkey++;
}
if(startkey == keys.end())
return false;
tag = groupname+": "+stop;
NifOgre::TextKeyMap::const_iterator stopkey(startkey);
while(stopkey != keys.end() && stopkey->second != tag)
stopkey++;
if(stopkey == keys.end())
return false;
if(startkey == stopkey)
return false;
mLayer[layeridx].mStartKey = startkey;
mLayer[layeridx].mLoopStartKey = startkey;
mLayer[layeridx].mStopKey = stopkey;
mLayer[layeridx].mNextKey = startkey;
mLayer[layeridx].mTime = mLayer[layeridx].mStartKey->first + ((mLayer[layeridx].mStopKey->first-
mLayer[layeridx].mStartKey->first) * startpoint);
tag = groupname+": loop start";
while(mLayer[layeridx].mNextKey->first <= mLayer[layeridx].mTime && mLayer[layeridx].mNextKey != mLayer[layeridx].mStopKey)
{
if(mLayer[layeridx].mNextKey->second == tag)
mLayer[layeridx].mLoopStartKey = mLayer[layeridx].mNextKey;
mLayer[layeridx].mNextKey++;
}
if(stop.length() > 0)
{
NifOgre::TextKeyMap::const_iterator stopKey = mNextKey;
while(stopKey != mCurrentKeys->end() && stopKey->second != stop)
stopKey++;
if(stopKey != mCurrentKeys->end())
mStopTime = stopKey->first;
else
mStopTime = mCurrentAnim->getLength();
}
if(layeridx == 0 && nonaccumctrl)
mLastPosition = nonaccumctrl->getTranslation(mLayer[layeridx].mTime) * mAccumulate;
if(mNonAccumRoot)
{
const Ogre::NodeAnimationTrack *track = 0;
Ogre::Animation::NodeTrackIterator trackiter = mCurrentAnim->getNodeTrackIterator();
while(!track && trackiter.hasMoreElements())
{
const Ogre::NodeAnimationTrack *cur = trackiter.getNext();
if(cur->getAssociatedNode()->getName() == mNonAccumRoot->getName())
track = cur;
}
if(track)
{
Ogre::TransformKeyFrame kf(0, mCurrentTime);
track->getInterpolatedKeyFrame(mCurrentAnim->_getTimeIndex(mCurrentTime), &kf);
mLastPosition = kf.getTranslate() * mAccumulate;
}
}
}
bool Animation::handleEvent(float time, const std::string &evt)
{
if(evt == "start" || evt == "loop start")
{
/* Do nothing */
return true;
}
}
bool Animation::doLoop(size_t layeridx)
{
if(mLayer[layeridx].mLoopCount == 0)
return false;
mLayer[layeridx].mLoopCount--;
mLayer[layeridx].mTime = mLayer[layeridx].mLoopStartKey->first;
mLayer[layeridx].mNextKey = mLayer[layeridx].mLoopStartKey;
mLayer[layeridx].mNextKey++;
mLayer[layeridx].mPlaying = true;
if(layeridx == 0 && mNonAccumCtrl)
mLastPosition = mNonAccumCtrl->getTranslation(mLayer[layeridx].mTime) * mAccumulate;
return true;
}
bool Animation::handleTextKey(size_t layeridx, const NifOgre::TextKeyMap::const_iterator &key)
{
float time = key->first;
const std::string &evt = key->second;
if(evt.compare(0, 7, "sound: ") == 0)
{
@ -414,105 +524,214 @@ bool Animation::handleEvent(float time, const std::string &evt)
return true;
}
if(evt == "loop stop")
if(evt.compare(0, mLayer[layeridx].mGroupName.size(), mLayer[layeridx].mGroupName) != 0 ||
evt.compare(mLayer[layeridx].mGroupName.size(), 2, ": ") != 0)
{
if(mLooping)
// Not ours, skip it
return true;
}
size_t off = mLayer[layeridx].mGroupName.size()+2;
size_t len = evt.size() - off;
if(evt.compare(off, len, "start") == 0 || evt.compare(off, len, "loop start") == 0)
{
reset("loop start", "");
if(mCurrentTime >= time)
mLayer[layeridx].mLoopStartKey = key;
return true;
}
if(evt.compare(off, len, "loop stop") == 0 || evt.compare(off, len, "stop") == 0)
{
if(doLoop(layeridx))
{
if(mLayer[layeridx].mTime >= time)
return false;
}
return true;
}
if(evt == "stop")
{
if(mLooping)
{
reset("loop start", "");
if(mCurrentTime >= time)
return false;
return true;
}
// fall-through
}
if(mController)
mController->markerEvent(time, evt);
std::cerr<< "Unhandled animation textkey: "<<evt <<std::endl;
return true;
}
void Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop)
bool Animation::play(const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, size_t loops)
{
try {
bool found = false;
// TODO: parameterize this
size_t layeridx = 0;
if(!mSkelBase)
return false;
for(std::vector<ObjectInfo>::iterator iter(mObjects.begin());iter != mObjects.end();iter++)
iter->mActiveLayers &= ~(1<<layeridx);
mLayer[layeridx].mGroupName.clear();
mLayer[layeridx].mTextKeys = NULL;
mLayer[layeridx].mControllers = NULL;
mLayer[layeridx].mTime = 0.0f;
mLayer[layeridx].mLoopCount = 0;
mLayer[layeridx].mPlaying = false;
bool movinganim = false;
bool foundanim = false;
/* Look in reverse; last-inserted source has priority. */
for(std::vector<NifOgre::ObjectList>::reverse_iterator iter(mAnimationSources.rbegin());iter != mAnimationSources.rend();iter++)
for(std::vector<ObjectInfo>::reverse_iterator iter(mObjects.rbegin());iter != mObjects.rend();iter++)
{
if(iter->mSkelBase->hasAnimationState(groupname))
NifOgre::ObjectList &objlist = iter->mObjectList;
if(objlist.mTextKeys.size() == 0)
continue;
const NifOgre::TextKeyMap &keys = objlist.mTextKeys.begin()->second;
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL;
if(layeridx == 0 && mNonAccumRoot)
{
mCurrentAnim = iter->mSkelBase->getSkeleton()->getAnimation(groupname);
mCurrentKeys = &mTextKeys[groupname];
mCurrentControllers = &iter->mControllers;
mAnimVelocity = 0.0f;
if(mNonAccumRoot)
calcAnimVelocity();
found = true;
for(size_t i = 0;i < objlist.mControllers.size();i++)
{
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(objlist.mControllers[i].getDestination().getPointer());
if(dstval && dstval->getNode() == mNonAccumRoot)
{
nonaccumctrl = dstval;
break;
}
}
if(!found)
throw std::runtime_error("Failed to find animation "+groupname);
}
reset(start, stop);
setLooping(loop);
mPlaying = true;
if(!foundanim)
{
if(!reset(layeridx, keys, nonaccumctrl, groupname, start, stop, startpoint))
continue;
mLayer[layeridx].mGroupName = groupname;
mLayer[layeridx].mTextKeys = &keys;
mLayer[layeridx].mControllers = &objlist.mControllers;
mLayer[layeridx].mLoopCount = loops;
mLayer[layeridx].mPlaying = true;
if(layeridx == 0)
{
mNonAccumCtrl = nonaccumctrl;
mAnimVelocity = 0.0f;
}
catch(std::exception &e) {
std::cerr<< e.what() <<std::endl;
iter->mActiveLayers |= (1<<layeridx);
foundanim = true;
if(mAccumulate == Ogre::Vector3(0.0f))
break;
}
if(!nonaccumctrl)
break;
mAnimVelocity = calcAnimVelocity(keys, nonaccumctrl, mAccumulate, groupname);
if(mAnimVelocity > 1.0f)
{
movinganim = (nonaccumctrl==mNonAccumCtrl);
break;
}
}
if(!foundanim)
std::cerr<< "Failed to find animation "<<groupname <<std::endl;
updateActiveControllers();
return movinganim;
}
Ogre::Vector3 Animation::runAnimation(float timepassed)
void Animation::disable(size_t layeridx)
{
if(mLayer[layeridx].mGroupName.empty())
return;
for(std::vector<ObjectInfo>::iterator iter(mObjects.begin());iter != mObjects.end();iter++)
iter->mActiveLayers &= ~(1<<layeridx);
mLayer[layeridx].mGroupName.clear();
mLayer[layeridx].mTextKeys = NULL;
mLayer[layeridx].mControllers = NULL;
mLayer[layeridx].mTime = 0.0f;
mLayer[layeridx].mLoopCount = 0;
mLayer[layeridx].mPlaying = false;
updateActiveControllers();
}
bool Animation::getInfo(size_t layeridx, float *complete, std::string *groupname, std::string *start, std::string *stop) const
{
if(mLayer[layeridx].mGroupName.empty())
{
if(complete) *complete = 0.0f;
if(groupname) *groupname = "";
if(start) *start = "";
if(stop) *stop = "";
return false;
}
if(complete) *complete = (mLayer[layeridx].mTime - mLayer[layeridx].mStartKey->first) /
(mLayer[layeridx].mStopKey->first - mLayer[layeridx].mStartKey->first);
if(groupname) *groupname = mLayer[layeridx].mGroupName;
if(start) *start = mLayer[layeridx].mStartKey->second.substr(mLayer[layeridx].mGroupName.size()+2);
if(stop) *stop = mLayer[layeridx].mStopKey->second.substr(mLayer[layeridx].mGroupName.size()+2);
return true;
}
Ogre::Vector3 Animation::runAnimation(float duration)
{
Ogre::Vector3 movement(0.0f);
timepassed *= mAnimSpeedMult;
while(mCurrentAnim && mPlaying)
duration *= mAnimSpeedMult;
for(size_t layeridx = 0;layeridx < sMaxLayers;layeridx++)
{
float targetTime = mCurrentTime + timepassed;
if(mNextKey == mCurrentKeys->end() || mNextKey->first > targetTime)
if(mLayer[layeridx].mGroupName.empty())
continue;
float timepassed = duration;
while(mLayer[layeridx].mPlaying)
{
mCurrentTime = std::min(mStopTime, targetTime);
if(mNonAccumRoot)
movement += updatePosition();
mPlaying = (mLooping || mStopTime > mCurrentTime);
timepassed = targetTime - mCurrentTime;
float targetTime = mLayer[layeridx].mTime + timepassed;
if(mLayer[layeridx].mNextKey->first > targetTime)
{
mLayer[layeridx].mTime = targetTime;
if(layeridx == 0 && mNonAccumCtrl)
updatePosition(movement);
break;
}
float time = mNextKey->first;
const std::string &evt = mNextKey->second;
mNextKey++;
NifOgre::TextKeyMap::const_iterator key(mLayer[layeridx].mNextKey++);
mLayer[layeridx].mTime = key->first;
if(layeridx == 0 && mNonAccumCtrl)
updatePosition(movement);
mCurrentTime = time;
if(mNonAccumRoot)
movement += updatePosition();
mPlaying = (mLooping || mStopTime > mCurrentTime);
timepassed = targetTime - mCurrentTime;
mLayer[layeridx].mPlaying = (key != mLayer[layeridx].mStopKey);
timepassed = targetTime - mLayer[layeridx].mTime;
if(!handleEvent(time, evt))
if(!handleTextKey(layeridx, key))
break;
}
for(size_t i = 0;i < mCurrentControllers->size();i++)
(*mCurrentControllers)[i].update();
}
if(mObjectList.mSkelBase)
for(size_t i = 0;i < mActiveCtrls.size();i++)
mActiveCtrls[i].update();
if(mSkelBase)
{
const Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
for(std::vector<ObjectInfo>::iterator iter(mObjects.begin());iter != mObjects.end();iter++)
{
Ogre::Entity *ent = iter->mObjectList.mSkelBase;
if(!ent) continue;
Ogre::SkeletonInstance *inst = ent->getSkeleton();
if(baseinst != inst)
updateSkeletonInstance(baseinst, inst);
// HACK: Dirty the animation state set so that Ogre will apply the
// transformations to entities this skeleton instance is shared with.
mObjectList.mSkelBase->getAllAnimationStates()->_notifyDirty();
ent->getAllAnimationStates()->_notifyDirty();
}
}
return movement;

View file

@ -8,10 +8,6 @@
#include "../mwworld/ptr.hpp"
namespace MWMechanics
{
class CharacterController;
}
namespace MWRender
{
@ -23,48 +19,67 @@ protected:
{
private:
Animation *mAnimation;
size_t mIndex;
public:
AnimationValue(Animation *anim) : mAnimation(anim)
AnimationValue(Animation *anim, size_t layeridx)
: mAnimation(anim), mIndex(layeridx)
{ }
virtual Ogre::Real getValue() const
{
return mAnimation->mCurrentTime;
}
virtual Ogre::Real getValue() const;
virtual void setValue(Ogre::Real value);
};
virtual void setValue(Ogre::Real value)
{
mAnimation->mCurrentTime = value;
}
struct ObjectInfo {
NifOgre::ObjectList mObjectList;
/* Bit-field specifying which animation layers this object list is
* explicitly animating on (1 = layer 0, 2 = layer 1, 4 = layer 2.
* etc).
*/
int mActiveLayers;
};
struct AnimLayer {
std::string mGroupName;
std::vector<Ogre::Controller<Ogre::Real> > *mControllers;
const NifOgre::TextKeyMap *mTextKeys;
NifOgre::TextKeyMap::const_iterator mStartKey;
NifOgre::TextKeyMap::const_iterator mLoopStartKey;
NifOgre::TextKeyMap::const_iterator mStopKey;
NifOgre::TextKeyMap::const_iterator mNextKey;
float mTime;
bool mPlaying;
size_t mLoopCount;
AnimLayer();
};
MWWorld::Ptr mPtr;
MWMechanics::CharacterController *mController;
Ogre::SceneNode* mInsert;
NifOgre::ObjectList mObjectList;
std::map<std::string,NifOgre::TextKeyMap> mTextKeys;
Ogre::SceneNode *mInsert;
Ogre::Entity *mSkelBase;
std::vector<ObjectInfo> mObjects;
Ogre::Node *mAccumRoot;
Ogre::Bone *mNonAccumRoot;
NifOgre::NodeTargetValue<Ogre::Real> *mNonAccumCtrl;
Ogre::Vector3 mAccumulate;
Ogre::Vector3 mLastPosition;
std::vector<NifOgre::ObjectList> mAnimationSources;
std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers;
NifOgre::TextKeyMap *mCurrentKeys;
NifOgre::TextKeyMap::const_iterator mNextKey;
Ogre::Animation *mCurrentAnim;
float mCurrentTime;
float mStopTime;
bool mPlaying;
bool mLooping;
std::vector<Ogre::Controller<Ogre::Real> > mActiveCtrls;
float mAnimVelocity;
float mAnimSpeedMult;
void calcAnimVelocity();
static const size_t sMaxLayers = 1;
AnimLayer mLayer[sMaxLayers];
Ogre::SharedPtr<Ogre::ControllerValue<Ogre::Real> > mAnimationValuePtr[sMaxLayers];
static float calcAnimVelocity(const NifOgre::TextKeyMap &keys,
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
const Ogre::Vector3 &accum,
const std::string &groupname);
/* Updates a skeleton instance so that all bones matching the source skeleton (based on
* bone names) are positioned identically. */
@ -72,34 +87,39 @@ protected:
/* Updates the position of the accum root node for the current time, and
* returns the wanted movement vector from the previous update. */
Ogre::Vector3 updatePosition();
void updatePosition(Ogre::Vector3 &position);
static NifOgre::TextKeyMap::const_iterator findGroupStart(const NifOgre::TextKeyMap &keys, const std::string &groupname);
/* Resets the animation to the time of the specified start marker, without
* moving anything, and set the end time to the specified stop marker. If
* the marker is not found, it resets to the beginning or end respectively.
* the marker is not found, or if the markers are the same, it returns
* false.
*/
void reset(const std::string &start, const std::string &stop);
bool reset(size_t layeridx, const NifOgre::TextKeyMap &keys,
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
const std::string &groupname, const std::string &start, const std::string &stop,
float startpoint);
bool handleEvent(float time, const std::string &evt);
bool doLoop(size_t layeridx);
/* Specifies a list of skeleton names to use as animation sources. */
void setAnimationSources(const std::vector<std::string> &names);
bool handleTextKey(size_t layeridx, const NifOgre::TextKeyMap::const_iterator &key);
/* Specifies a single skeleton name to use as an animation source. */
void setAnimationSource(const std::string &name)
{
std::vector<std::string> names(1, name);
setAnimationSources(names);
}
void createObjectList(Ogre::SceneNode *node, const std::string &model);
void addObjectList(Ogre::SceneNode *node, const std::string &model, bool baseonly);
static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects);
static void setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue);
void updateActiveControllers();
public:
Animation(const MWWorld::Ptr &ptr);
virtual ~Animation();
void setController(MWMechanics::CharacterController *controller);
/** Clears all ObjectLists except the first one. As a consequence, any
* playing animations are stopped.
*/
void clearExtraSources();
void updatePtr(const MWWorld::Ptr &ptr);
@ -112,10 +132,38 @@ public:
void setSpeed(float speed);
void setLooping(bool loop);
/** Plays an animation.
* \param groupname Name of the animation group to play.
* \param start Key marker from which to start.
* \param stop Key marker to stop at.
* \param startpoint How far in between the two markers to start. 0 starts
* at the start marker, 1 starts at the stop marker.
* \param loops How many times to loop the animation. This will use the
* "loop start" and "loop stop" markers if they exist,
* otherwise it will use "start" and "stop".
* \return Boolean specifying whether the animation will return movement
* for the character at all.
*/
bool play(const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, size_t loops);
void play(const std::string &groupname, const std::string &start, const std::string &stop, bool loop);
virtual Ogre::Vector3 runAnimation(float timepassed);
/** Stops and removes the animation from the given layer. */
void disable(size_t layeridx);
/** Gets info about the given animation layer.
* \param layeridx Layer index to get info about.
* \param complete Stores completion amount (0 = at start key, 0.5 = half way between start and stop keys), etc.
* \param groupname Stores animation group being played.
* \param start Stores the start key
* \param stop Stores the stop key
* \return True if an animation is active on the layer, false otherwise.
*/
bool getInfo(size_t layeridx, float *complete=NULL, std::string *groupname=NULL, std::string *start=NULL, std::string *stop=NULL) const;
virtual Ogre::Vector3 runAnimation(float duration);
/* Returns if there's an animation playing on the given layer. */
bool isPlaying(size_t layeridx) const
{ return mLayer[layeridx].mPlaying; }
Ogre::Node *getNode(const std::string &name);
};

View file

@ -21,13 +21,15 @@ namespace MWRender
CharacterPreview::CharacterPreview(MWWorld::Ptr character, int sizeX, int sizeY, const std::string& name,
Ogre::Vector3 position, Ogre::Vector3 lookAt)
: mSizeX(sizeX)
, mSizeY(sizeY)
, mName(name)
: mSceneMgr (0)
, mPosition(position)
, mLookAt(lookAt)
, mCharacter(character)
, mAnimation(NULL)
, mName(name)
, mSizeX(sizeX)
, mSizeY(sizeY)
{
}
@ -87,17 +89,21 @@ namespace MWRender
}
CharacterPreview::~CharacterPreview ()
{
if (mSceneMgr)
{
//Ogre::TextureManager::getSingleton().remove(mName);
mSceneMgr->destroyCamera (mName);
mSceneMgr->destroyAllCameras();
delete mAnimation;
Ogre::Root::getSingleton().destroySceneManager(mSceneMgr);
}
}
void CharacterPreview::rebuild()
{
assert(mAnimation);
delete mAnimation;
mAnimation = 0;
mAnimation = new NpcAnimation(mCharacter, mNode, MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter),
0, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal));
@ -149,7 +155,7 @@ namespace MWRender
if (!mSelectionBuffer)
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0);
mAnimation->play("inventoryhandtohand", "start", "stop", false);
mAnimation->play("inventoryhandtohand", "start", "stop", 0.0f, 0);
}
// --------------------------------------------------------------------------------------------------
@ -183,7 +189,7 @@ namespace MWRender
void RaceSelectionPreview::onSetup ()
{
mAnimation->play("idle", "start", "stop", false);
mAnimation->play("idle", "start", "stop", 0.0f, 0);
updateCamera();
}

View file

@ -1,10 +1,5 @@
#include "creatureanimation.hpp"
#include <OgreEntity.h>
#include <OgreParticleSystem.h>
#include <OgreSceneManager.h>
#include <OgreSubEntity.h>
#include "renderconst.hpp"
#include "../mwbase/world.hpp"
@ -26,31 +21,11 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
{
std::string model = "meshes\\"+ref->mBase->mModel;
createObjectList(mPtr.getRefData().getBaseNode(), model);
for(size_t i = 0;i < mObjectList.mEntities.size();i++)
{
Ogre::Entity *ent = mObjectList.mEntities[i];
ent->setVisibilityFlags(RV_Actors);
for(unsigned int j=0; j < ent->getNumSubEntities(); ++j)
{
Ogre::SubEntity* subEnt = ent->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
}
for(size_t i = 0;i < mObjectList.mParticles.size();i++)
{
Ogre::ParticleSystem *part = mObjectList.mParticles[i];
part->setVisibilityFlags(RV_Actors);
part->setRenderQueueGroup(RQG_Alpha);
}
std::vector<std::string> names;
if((ref->mBase->mFlags&ESM::Creature::Biped))
names.push_back("meshes\\base_anim.nif");
names.push_back(model);
setAnimationSources(names);
addObjectList(mPtr.getRefData().getBaseNode(), "meshes\\base_anim.nif", true);
addObjectList(mPtr.getRefData().getBaseNode(), model, false);
setRenderProperties(mObjects.back().mObjectList, RV_Actors, RQG_Main, RQG_Alpha);
}
}

View file

@ -11,6 +11,7 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "renderconst.hpp"
@ -96,39 +97,24 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif");
createObjectList(node, smodel);
for(size_t i = 0;i < mObjectList.mEntities.size();i++)
{
Ogre::Entity *base = mObjectList.mEntities[i];
base->getUserObjectBindings().setUserAny(Ogre::Any(-1));
if (mVisibilityFlags != 0)
base->setVisibilityFlags(mVisibilityFlags);
for(unsigned int j=0; j < base->getNumSubEntities(); ++j)
{
Ogre::SubEntity* subEnt = base->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
}
for(size_t i = 0;i < mObjectList.mParticles.size();i++)
{
Ogre::ParticleSystem *part = mObjectList.mParticles[i];
part->getUserObjectBindings().setUserAny(Ogre::Any(-1));
if(mVisibilityFlags != 0)
part->setVisibilityFlags(mVisibilityFlags);
part->setRenderQueueGroup(RQG_Alpha);
}
std::vector<std::string> skelnames(1, smodel);
if(!mNpc->isMale() && !isBeast)
skelnames.push_back("meshes\\base_anim_female.nif");
else if(mBodyPrefix.find("argonian") != std::string::npos)
skelnames.push_back("meshes\\argonian_swimkna.nif");
addObjectList(node, smodel, true);
if(mBodyPrefix.find("argonian") != std::string::npos)
addObjectList(node, "meshes\\argonian_swimkna.nif", true);
else if(!mNpc->isMale() && !isBeast)
addObjectList(node, "meshes\\base_anim_female.nif", true);
if(mNpc->mModel.length() > 0)
skelnames.push_back("meshes\\"+Misc::StringUtils::lowerCase(mNpc->mModel));
setAnimationSources(skelnames);
addObjectList(node, "meshes\\"+mNpc->mModel, true);
if(mViewMode == VM_FirstPerson)
{
/* A bit counter-intuitive, but unlike third-person anims, it seems
* beast races get both base_anim.1st.nif and base_animkna.1st.nif.
*/
addObjectList(node, "meshes\\base_anim.1st.nif", true);
if(isBeast)
addObjectList(node, "meshes\\base_animkna.1st.nif", true);
if(!mNpc->isMale() && !isBeast)
addObjectList(node, "meshes\\base_anim_female.1st.nif", true);
}
forceUpdate();
}
@ -138,28 +124,31 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
assert(viewMode != VM_HeadOnly);
mViewMode = viewMode;
/* FIXME: Enable this once first-person animations work. */
#if 0
Ogre::SceneNode *node = mInsert->getParentSceneNode();
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif");
std::vector<std::string> skelnames(1, smodel);
if(!mNpc->isMale() && !isBeast)
skelnames.push_back("meshes\\base_anim_female.nif");
else if(mBodyPrefix.find("argonian") != std::string::npos)
skelnames.push_back("meshes\\argonian_swimkna.nif");
clearExtraSources();
if(mBodyPrefix.find("argonian") != std::string::npos)
addObjectList(node, "meshes\\argonian_swimkna.nif", true);
else if(!mNpc->isMale() && !isBeast)
addObjectList(node, "meshes\\base_anim_female.nif", true);
if(mNpc->mModel.length() > 0)
skelnames.push_back("meshes\\"+Misc::StringUtils::lowerCase(mNpc->mModel));
addObjectList(node, "meshes\\"+mNpc->mModel, true);
if(mViewMode == VM_FirstPerson)
{
smodel = (!isBeast ? "meshes\\base_anim.1st.nif" : "meshes\\base_animkna.1st.nif");
skelnames.push_back(smodel);
/* A bit counter-intuitive, but unlike third-person anims, it seems
* beast races get both base_anim.1st.nif and base_animkna.1st.nif.
*/
addObjectList(node, "meshes\\base_anim.1st.nif", true);
if(isBeast)
addObjectList(node, "meshes\\base_animkna.1st.nif", true);
if(!mNpc->isMale() && !isBeast)
addObjectList(node, "meshes\\base_anim_female.1st.nif", true);
}
setAnimationSources(skelnames);
#endif
MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr);
for(size_t i = 0;i < sPartListSize;i++)
removeIndividualPart(i);
@ -305,81 +294,95 @@ void NpcAnimation::updateParts(bool forceupdate)
if(mViewMode == VM_HeadOnly)
return;
static const struct {
ESM::PartReferenceType type;
const char name[2][12];
} PartTypeList[] = {
{ ESM::PRT_Neck, { "neck", "" } },
{ ESM::PRT_Cuirass, { "chest", "" } },
{ ESM::PRT_Groin, { "groin", "" } },
{ ESM::PRT_RHand, { "hand", "hands" } },
{ ESM::PRT_LHand, { "hand", "hands" } },
{ ESM::PRT_RWrist, { "wrist", "" } },
{ ESM::PRT_LWrist, { "wrist", "" } },
{ ESM::PRT_RForearm, { "forearm", "" } },
{ ESM::PRT_LForearm, { "forearm", "" } },
{ ESM::PRT_RUpperarm, { "upper arm", "" } },
{ ESM::PRT_LUpperarm, { "upper arm", "" } },
{ ESM::PRT_RFoot, { "foot", "feet" } },
{ ESM::PRT_LFoot, { "foot", "feet" } },
{ ESM::PRT_RAnkle, { "ankle", "" } },
{ ESM::PRT_LAnkle, { "ankle", "" } },
{ ESM::PRT_RKnee, { "knee", "" } },
{ ESM::PRT_LKnee, { "knee", "" } },
{ ESM::PRT_RLeg, { "upper leg", "" } },
{ ESM::PRT_LLeg, { "upper leg", "" } },
{ ESM::PRT_Tail, { "tail", "" } }
};
std::map<int, int> bodypartMap;
bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck;
bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest;
bodypartMap[ESM::PRT_Groin] = ESM::BodyPart::MP_Groin;
bodypartMap[ESM::PRT_RHand] = ESM::BodyPart::MP_Hand;
bodypartMap[ESM::PRT_LHand] = ESM::BodyPart::MP_Hand;
bodypartMap[ESM::PRT_RWrist] = ESM::BodyPart::MP_Wrist;
bodypartMap[ESM::PRT_LWrist] = ESM::BodyPart::MP_Wrist;
bodypartMap[ESM::PRT_RForearm] = ESM::BodyPart::MP_Forearm;
bodypartMap[ESM::PRT_LForearm] = ESM::BodyPart::MP_Forearm;
bodypartMap[ESM::PRT_RUpperarm] = ESM::BodyPart::MP_Upperarm;
bodypartMap[ESM::PRT_LUpperarm] = ESM::BodyPart::MP_Upperarm;
bodypartMap[ESM::PRT_RFoot] = ESM::BodyPart::MP_Foot;
bodypartMap[ESM::PRT_LFoot] = ESM::BodyPart::MP_Foot;
bodypartMap[ESM::PRT_RAnkle] = ESM::BodyPart::MP_Ankle;
bodypartMap[ESM::PRT_LAnkle] = ESM::BodyPart::MP_Ankle;
bodypartMap[ESM::PRT_RKnee] = ESM::BodyPart::MP_Knee;
bodypartMap[ESM::PRT_LKnee] = ESM::BodyPart::MP_Knee;
bodypartMap[ESM::PRT_RLeg] = ESM::BodyPart::MP_Upperleg;
bodypartMap[ESM::PRT_LLeg] = ESM::BodyPart::MP_Upperleg;
bodypartMap[ESM::PRT_Tail] = ESM::BodyPart::MP_Tail;
const char *ext = (mViewMode == VM_FirstPerson) ? ".1st" : "";
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
for(size_t i = 0;i < sizeof(PartTypeList)/sizeof(PartTypeList[0]);i++)
const int Flag_Female = 0x01;
const int Flag_FirstPerson = 0x02;
int flags = 0;
if (!mNpc->isMale())
flags |= Flag_Female;
if (mViewMode == VM_FirstPerson)
flags |= Flag_FirstPerson;
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
static std::map< std::pair<std::string, int> , std::vector<const ESM::BodyPart*> > sRaceMapping;
std::string race = Misc::StringUtils::lowerCase(mNpc->mRace);
std::pair<std::string, int> thisCombination = std::make_pair(race, flags);
if (sRaceMapping.find(thisCombination) == sRaceMapping.end())
{
if(mPartPriorities[PartTypeList[i].type] < 1)
{
const ESM::BodyPart *part = NULL;
sRaceMapping[thisCombination].resize(ESM::PRT_Count);
for (int i=0; i<ESM::PRT_Count; ++i)
sRaceMapping[thisCombination][i] = NULL;
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
if(!mNpc->isMale())
for (MWWorld::Store<ESM::BodyPart>::iterator it = partStore.begin(); it != partStore.end(); ++it)
{
part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[0]+ext);
if(part == 0)
part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[1]+ext);
const ESM::BodyPart& bodypart = *it;
if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable)
continue;
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
{
continue;
}
if(part == 0)
part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[0]+ext);
if(part == 0)
part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[1]+ext);
if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
continue;
if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace))
continue;
if(part)
addOrReplaceIndividualPart(PartTypeList[i].type, -1,1, "meshes\\"+part->mModel);
bool firstPerson = (bodypart.mId.size() >= 3)
&& bodypart.mId[bodypart.mId.size()-3] == '1'
&& bodypart.mId[bodypart.mId.size()-2] == 's'
&& bodypart.mId[bodypart.mId.size()-1] == 't';
if (firstPerson != (mViewMode == VM_FirstPerson))
continue;
for (std::map<int, int>::iterator bIt = bodypartMap.begin(); bIt != bodypartMap.end(); ++bIt )
if (bIt->second == bodypart.mData.mPart)
sRaceMapping[thisCombination][bIt->first] = &*it;
}
}
for (int part = ESM::PRT_Neck; part < ESM::PRT_Count; ++part)
{
const ESM::BodyPart* bodypart = sRaceMapping[thisCombination][part];
if (mPartPriorities[part] < 1 && bodypart)
addOrReplaceIndividualPart(part, -1,1, "meshes\\"+bodypart->mModel);
}
}
NifOgre::ObjectList NpcAnimation::insertBoundedPart(const std::string &model, int group, const std::string &bonename)
{
NifOgre::ObjectList objects = NifOgre::Loader::createObjects(mObjectList.mSkelBase, bonename,
mInsert, model);
for(size_t i = 0;i < objects.mEntities.size();i++)
{
objects.mEntities[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
if(mVisibilityFlags != 0)
objects.mEntities[i]->setVisibilityFlags(mVisibilityFlags);
NifOgre::ObjectList objects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model);
setRenderProperties(objects, mVisibilityFlags, RQG_Main, RQG_Alpha);
for(unsigned int j=0; j < objects.mEntities[i]->getNumSubEntities(); ++j)
{
Ogre::SubEntity* subEnt = objects.mEntities[i]->getSubEntity(j);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
}
for(size_t i = 0;i < objects.mEntities.size();i++)
objects.mEntities[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
for(size_t i = 0;i < objects.mParticles.size();i++)
{
objects.mParticles[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
if(mVisibilityFlags != 0)
objects.mParticles[i]->setVisibilityFlags(mVisibilityFlags);
objects.mParticles[i]->setRenderQueueGroup(RQG_Alpha);
}
if(objects.mSkelBase)
{
Ogre::AnimationStateSet *aset = objects.mSkelBase->getAllAnimationStates();
@ -395,6 +398,7 @@ NifOgre::ObjectList NpcAnimation::insertBoundedPart(const std::string &model, in
while(boneiter.hasMoreElements())
boneiter.getNext()->setManuallyControlled(true);
}
return objects;
}
@ -408,14 +412,16 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
mTimeToChange -= timepassed;
Ogre::Vector3 ret = Animation::runAnimation(timepassed);
const Ogre::SkeletonInstance *skelsrc = mObjectList.mSkelBase->getSkeleton();
Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
for(size_t i = 0;i < sPartListSize;i++)
{
Ogre::Entity *ent = mObjectParts[i].mSkelBase;
if(!ent) continue;
updateSkeletonInstance(skelsrc, ent->getSkeleton());
updateSkeletonInstance(baseinst, ent->getSkeleton());
ent->getAllAnimationStates()->_notifyDirty();
}
return ret;
}

View file

@ -30,6 +30,8 @@
#include "../mwbase/inputmanager.hpp" // FIXME
#include "../mwbase/windowmanager.hpp" // FIXME
#include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/player.hpp"
@ -315,13 +317,15 @@ void RenderingManager::update (float duration, bool paused)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude;
mRendering.getFader()->setFactor(1.f-(blind / 100.f));
setAmbientMode();
// player position
MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
MWWorld::RefData &data = player.getRefData();
float *_playerPos = data.getPosition().pos;
Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]);
@ -597,8 +601,15 @@ void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
{
mRendering.getScene()->setAmbientLight(colour);
mTerrainManager->setAmbient(colour);
mAmbientColor = colour;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
int nightEye = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::NightEye)).mMagnitude;
Ogre::ColourValue final = colour;
final += Ogre::ColourValue(0.7,0.7,0.7,0) * std::min(1.f, (nightEye/100.f));
mRendering.getScene()->setAmbientLight(final);
mTerrainManager->setAmbient(final);
}
void RenderingManager::sunEnable(bool real)

View file

@ -788,8 +788,8 @@ void VideoState::decode_thread_loop(VideoState *self)
// main decode loop
while(!self->quit)
{
if((self->audio_st >= 0 && self->audioq.size > MAX_AUDIOQ_SIZE) ||
(self->video_st >= 0 && self->videoq.size > MAX_VIDEOQ_SIZE))
if((self->audio_st && self->audioq.size > MAX_AUDIOQ_SIZE) ||
(self->video_st && self->videoq.size > MAX_VIDEOQ_SIZE))
{
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
continue;

View file

@ -13,8 +13,8 @@ namespace ESM
namespace MWWorld
{
/// List all (Ogre-)handles.
struct ListHandles
/// List all (Ogre-)handles, then reset RefData::mBaseNode to 0.
struct ListAndResetHandles
{
std::vector<Ogre::SceneNode*> mHandles;
@ -23,6 +23,8 @@ namespace MWWorld
Ogre::SceneNode* handle = data.getBaseNode();
if (handle)
mHandles.push_back (handle);
data.setBaseNode(0);
return true;
}
};

View file

@ -193,6 +193,8 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
{
count = std::abs(count); /// \todo implement item restocking (indicated by negative count)
try
{
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id);
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
@ -247,6 +249,13 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
ref.getPtr().getCellRef().mOwner = owner;
addImp (ref.getPtr());
}
}
catch (std::logic_error& e)
{
// Vanilla doesn't fail on nonexistent items in levelled lists
std::cerr << "Warning: ignoring nonexistent item '" << id << "'" << std::endl;
return;
}
}
void MWWorld::ContainerStore::clear()

View file

@ -76,16 +76,18 @@ namespace MWWorld
void Scene::unloadCell (CellStoreCollection::iterator iter)
{
std::cout << "Unloading cell\n";
ListHandles functor;
ListAndResetHandles functor;
(*iter)->forEach<ListHandles>(functor);
(*iter)->forEach<ListAndResetHandles>(functor);
{
// silence annoying g++ warning
for (std::vector<Ogre::SceneNode*>::const_iterator iter2 (functor.mHandles.begin());
iter2!=functor.mHandles.end(); ++iter2){
iter2!=functor.mHandles.end(); ++iter2)
{
Ogre::SceneNode* node = *iter2;
mPhysics->removeObject (node->getName());
}
}
if ((*iter)->mCell->isExterior())
{
@ -97,7 +99,6 @@ namespace MWWorld
if (land)
mPhysics->removeHeightField( (*iter)->mCell->getGridX(), (*iter)->mCell->getGridY() );
}
}
mRendering.removeCell(*iter);

View file

@ -415,8 +415,18 @@ namespace MWWorld
}
};
struct DynamicExtCmp
{
bool operator()(const std::pair<int, int> &left, const std::pair<int, int> &right) const {
if (left.first == right.first) {
return left.second < right.second;
}
return left.first < right.first;
}
};
typedef std::map<std::string, ESM::Cell> DynamicInt;
typedef std::map<std::pair<int, int>, ESM::Cell> DynamicExt;
typedef std::map<std::pair<int, int>, ESM::Cell, DynamicExtCmp> DynamicExt;
DynamicInt mInt;
DynamicExt mExt;
@ -465,7 +475,7 @@ namespace MWWorld
cell.mData.mX = x, cell.mData.mY = y;
std::pair<int, int> key(x, y);
std::map<std::pair<int, int>, ESM::Cell>::const_iterator it = mExt.find(key);
DynamicExt::const_iterator it = mExt.find(key);
if (it != mExt.end()) {
return &(it->second);
}
@ -483,7 +493,7 @@ namespace MWWorld
cell.mData.mX = x, cell.mData.mY = y;
std::pair<int, int> key(x, y);
std::map<std::pair<int, int>, ESM::Cell>::const_iterator it = mExt.find(key);
DynamicExt::const_iterator it = mExt.find(key);
if (it != mExt.end()) {
return &(it->second);
}
@ -524,7 +534,7 @@ namespace MWWorld
void setUp() {
//typedef std::vector<ESM::Cell>::iterator Iterator;
typedef std::map<std::pair<int, int>, ESM::Cell>::iterator ExtIterator;
typedef DynamicExt::iterator ExtIterator;
typedef std::map<std::string, ESM::Cell>::iterator IntIterator;
//std::sort(mInt.begin(), mInt.end(), RecordCmp());
@ -862,7 +872,28 @@ namespace MWWorld
}
void setUp() {
std::sort(mStatic.begin(), mStatic.end(), Compare());
/// \note This method sorts indexed values for further
/// searches. Every loaded item is present in storage, but
/// latest loaded shadows any previous while searching.
/// If memory cost will be too high, it is possible to remove
/// unused values.
Compare cmp;
std::stable_sort(mStatic.begin(), mStatic.end(), cmp);
typename std::vector<T>::iterator first, next;
next = first = mStatic.begin();
while (first != mStatic.end() && ++next != mStatic.end()) {
while (next != mStatic.end() && !cmp(*first, *next)) {
++next;
}
if (first != --next) {
std::swap(*first, *next);
}
first = ++next;
}
}
const T *search(int index) const {

View file

@ -38,7 +38,9 @@ enum PartReferenceType
PRT_RPauldron = 23,
PRT_LPauldron = 24,
PRT_Weapon = 25,
PRT_Tail = 26
PRT_Tail = 26,
PRT_Count = 27
};
// Reference to body parts

View file

@ -9,13 +9,13 @@ namespace ESM
void BodyPart::load(ESMReader &esm)
{
mModel = esm.getHNString("MODL");
mName = esm.getHNString("FNAM");
mRace = esm.getHNString("FNAM");
esm.getHNT(mData, "BYDT", 4);
}
void BodyPart::save(ESMWriter &esm)
{
esm.writeHNCString("MODL", mModel);
esm.writeHNCString("FNAM", mName);
esm.writeHNCString("FNAM", mRace);
esm.writeHNT("BYDT", mData, 4);
}

View file

@ -27,7 +27,9 @@ struct BodyPart
MP_Knee = 11,
MP_Upperleg = 12,
MP_Clavicle = 13,
MP_Tail = 14
MP_Tail = 14,
MP_Count = 15
};
enum Flags
@ -52,7 +54,7 @@ struct BodyPart
};
BYDTstruct mData;
std::string mId, mModel, mName;
std::string mId, mModel, mRace;
void load(ESMReader &esm);
void save(ESMWriter &esm);

View file

@ -303,5 +303,28 @@ public:
}
};
class NiFlipController : public Controller
{
public:
int mTexSlot;
float mDelta; // Time between two flips. delta = (start_time - stop_time) / num_sources
NiSourceTextureList mSources;
void read(NIFStream *nif)
{
Controller::read(nif);
mTexSlot = nif->getUInt();
/*unknown=*/nif->getUInt();/*0?*/
mDelta = nif->getFloat();
mSources.read(nif);
}
void post(NIFFile *nif)
{
Controller::post(nif);
mSources.post(nif);
}
};
} // Namespace
#endif

View file

@ -208,7 +208,7 @@ static const RecordFactoryEntry recordFactories [] = {
{ "NiNode", &construct <NiNode >, RC_NiNode },
{ "AvoidNode", &construct <NiNode >, RC_NiNode },
{ "NiBSParticleNode", &construct <NiNode >, RC_NiNode },
{ "NiBSParticleNode", &construct <NiNode >, RC_NiBSParticleNode },
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiBSAnimationNode },
{ "NiBillboardNode", &construct <NiNode >, RC_NiNode },
{ "NiTriShape", &construct <NiTriShape >, RC_NiTriShape },
@ -235,6 +235,7 @@ static const RecordFactoryEntry recordFactories [] = {
{ "NiMaterialColorController", &construct <NiMaterialColorController >, RC_NiMaterialColorController },
{ "NiBSPArrayController", &construct <NiBSPArrayController >, RC_NiBSPArrayController },
{ "NiParticleSystemController", &construct <NiParticleSystemController >, RC_NiParticleSystemController },
{ "NiFlipController", &construct <NiFlipController >, RC_NiFlipController },
{ "NiAmbientLight", &construct <NiLight >, RC_NiLight },
{ "NiDirectionalLight", &construct <NiLight >, RC_NiLight },
{ "NiTextureEffect", &construct <NiTextureEffect >, RC_NiTextureEffect },

View file

@ -128,13 +128,17 @@ struct NiNode : Node
NodeList children;
NodeList effects;
/* Known NiNode flags:
0x01 hidden
0x02 use mesh for collision
0x04 use bounding box for collision (?)
0x08 unknown, but common
0x20, 0x40, 0x80 unknown
*/
enum Flags {
Flag_Hidden = 0x0001,
Flag_MeshCollision = 0x0002,
Flag_BBoxCollision = 0x0004
};
enum BSAnimFlags {
AnimFlag_AutoPlay = 0x0020
};
enum BSParticleFlags {
ParticleFlag_AutoPlay = 0x0020
};
void read(NIFStream *nif)
{

View file

@ -39,6 +39,7 @@ enum RecordType
RC_NiTriShape,
RC_NiRotatingParticles,
RC_NiAutoNormalParticles,
RC_NiBSParticleNode,
RC_NiCamera,
RC_NiTexturingProperty,
RC_NiMaterialProperty,
@ -59,6 +60,7 @@ enum RecordType
RC_NiMaterialColorController,
RC_NiBSPArrayController,
RC_NiParticleSystemController,
RC_NiFlipController,
RC_NiBSAnimationNode,
RC_NiLight,
RC_NiTextureEffect,

View file

@ -163,6 +163,7 @@ typedef RecordPtrT<NiAutoNormalParticlesData> NiAutoNormalParticlesDataPtr;
typedef RecordListT<Node> NodeList;
typedef RecordListT<Property> PropertyList;
typedef RecordListT<NiSourceTexture> NiSourceTextureList;
} // Namespace
#endif

View file

@ -255,9 +255,9 @@ void ManualBulletShapeLoader::handleNiTriShape(btTriangleMesh* mesh, const Nif::
assert(shape != NULL);
// Interpret flags
bool hidden = (flags & 0x01) != 0; // Not displayed
bool collide = (flags & 0x02) != 0; // Use mesh for collision
bool bbcollide = (flags & 0x04) != 0; // Use bounding box for collision
bool hidden = (flags&Nif::NiNode::Flag_Hidden) != 0;
bool collide = (flags&Nif::NiNode::Flag_MeshCollision) != 0;
bool bbcollide = (flags&Nif::NiNode::Flag_BBoxCollision) != 0;
// If the object was marked "NCO" earlier, it shouldn't collide with
// anything. So don't do anything.

View file

@ -109,13 +109,26 @@ NIFMeshLoader::LoaderMap NIFMeshLoader::sLoaders;
void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape)
{
Ogre::SkeletonPtr skel;
const Nif::NiTriShapeData *data = shape->data.getPtr();
const Nif::NiSkinInstance *skin = (shape->skin.empty() ? NULL : shape->skin.getPtr());
std::vector<Ogre::Vector3> srcVerts = data->vertices;
std::vector<Ogre::Vector3> srcNorms = data->normals;
Ogre::HardwareBuffer::Usage vertUsage = Ogre::HardwareBuffer::HBU_STATIC;
bool vertShadowBuffer = false;
if(!shape->controller.empty())
{
Nif::ControllerPtr ctrl = shape->controller;
do {
if(ctrl->recType == Nif::RC_NiGeomMorpherController)
{
vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
vertShadowBuffer = true;
break;
}
} while(!(ctrl=ctrl->next).empty());
}
if(skin != NULL)
{
vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
@ -125,10 +138,6 @@ void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape
// explicitly attached later.
mesh->setSkeletonName(mName);
// Get the skeleton resource, so vertices can be transformed into the bones' initial state.
Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
skel = skelMgr->getByName(mName);
// Convert vertices and normals to bone space from bind position. It would be
// better to transform the bones into bind position, but there doesn't seem to
// be a reliable way to do that.
@ -139,11 +148,10 @@ void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape
const Nif::NodeList &bones = skin->bones;
for(size_t b = 0;b < bones.length();b++)
{
Ogre::Bone *bone = skel->getBone(bones[b]->name);
Ogre::Matrix4 mat;
mat.makeTransform(data->bones[b].trafo.trans, Ogre::Vector3(data->bones[b].trafo.scale),
Ogre::Quaternion(data->bones[b].trafo.rotation));
mat = bone->_getFullTransform() * mat;
mat = bones[b]->getWorldTransform() * mat;
const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[b].weights;
for(size_t i = 0;i < weights.size();i++)
@ -260,13 +268,24 @@ void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape
// Texture UV coordinates
size_t numUVs = data->uvlist.size();
for(size_t i = 0;i < numUVs;i++)
if (numUVs)
{
vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2),
srcVerts.size(), Ogre::HardwareBuffer::HBU_STATIC);
vbuf->writeData(0, vbuf->getSizeInBytes(), &data->uvlist[i][0], true);
size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
for(size_t i = 0; i < numUVs; i++)
decl->addElement(nextBuf, elemSize*i, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, i);
vbuf = hwBufMgr->createVertexBuffer(decl->getVertexSize(nextBuf), srcVerts.size(),
Ogre::HardwareBuffer::HBU_STATIC);
std::vector<Ogre::Vector2> allUVs;
allUVs.reserve(srcVerts.size()*numUVs);
for (size_t vert = 0; vert<srcVerts.size(); ++vert)
for(size_t i = 0; i < numUVs; i++)
allUVs.push_back(data->uvlist[i][vert]);
vbuf->writeData(0, elemSize*srcVerts.size()*numUVs, &allUVs[0], true);
decl->addElement(nextBuf, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, i);
bind->setBinding(nextBuf++, vbuf);
}
@ -285,6 +304,8 @@ void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape
// Assign bone weights for this TriShape
if(skin != NULL)
{
Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(mName);
const Nif::NiSkinData *data = skin->data.getPtr();
const Nif::NodeList &bones = skin->bones;
for(size_t i = 0;i < bones.length();i++)

View file

@ -44,15 +44,6 @@
#include "material.hpp"
#include "mesh.hpp"
namespace std
{
// TODO: Do something useful
ostream& operator<<(ostream &o, const NifOgre::TextKeyMap&)
{ return o; }
}
namespace NifOgre
{
@ -74,11 +65,7 @@ public:
, mStopTime(ctrl->timeStop)
{
if(mDeltaInput)
{
mDeltaCount = mPhase;
while(mDeltaCount < mStartTime)
mDeltaCount += (mStopTime-mStartTime);
}
}
virtual Ogre::Real calculate(Ogre::Real value)
@ -86,6 +73,9 @@ public:
if(mDeltaInput)
{
mDeltaCount += value*mFrequency;
if(mDeltaCount < mStartTime)
mDeltaCount = mStopTime - std::fmod(mStartTime - mDeltaCount,
mStopTime - mStartTime);
mDeltaCount = std::fmod(mDeltaCount - mStartTime,
mStopTime - mStartTime) + mStartTime;
return mDeltaCount;
@ -104,7 +94,7 @@ public:
private:
std::vector<Nif::NiVisData::VisData> mData;
virtual bool calculate(Ogre::Real time)
bool calculate(Ogre::Real time) const
{
if(mData.size() == 0)
return true;
@ -144,10 +134,19 @@ public:
, mData(data->mVis)
{ }
virtual Ogre::Quaternion getRotation(float time) const
{ return Ogre::Quaternion(); }
virtual Ogre::Vector3 getTranslation(float time) const
{ return Ogre::Vector3(0.0f); }
virtual Ogre::Vector3 getScale(float time) const
{ return Ogre::Vector3(1.0f); }
virtual Ogre::Real getValue() const
{
// Should not be called
return 1.0f;
return 0.0f;
}
virtual void setValue(Ogre::Real time)
@ -170,6 +169,60 @@ public:
Nif::Vector3KeyList mTranslations;
Nif::FloatKeyList mScales;
static float interpKey(const Nif::FloatKeyList::VecType &keys, float time)
{
if(time <= keys.front().mTime)
return keys.front().mValue;
Nif::FloatKeyList::VecType::const_iterator iter(keys.begin()+1);
for(;iter != keys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::FloatKeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
return last->mValue + ((iter->mValue - last->mValue)*a);
}
return keys.back().mValue;
}
static Ogre::Vector3 interpKey(const Nif::Vector3KeyList::VecType &keys, float time)
{
if(time <= keys.front().mTime)
return keys.front().mValue;
Nif::Vector3KeyList::VecType::const_iterator iter(keys.begin()+1);
for(;iter != keys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::Vector3KeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
return last->mValue + ((iter->mValue - last->mValue)*a);
}
return keys.back().mValue;
}
static Ogre::Quaternion interpKey(const Nif::QuaternionKeyList::VecType &keys, float time)
{
if(time <= keys.front().mTime)
return keys.front().mValue;
Nif::QuaternionKeyList::VecType::const_iterator iter(keys.begin()+1);
for(;iter != keys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::QuaternionKeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
return Ogre::Quaternion::nlerp(a, last->mValue, iter->mValue);
}
return keys.back().mValue;
}
public:
Value(Ogre::Node *target, const Nif::NiKeyframeData *data)
: NodeTargetValue<Ogre::Real>(target)
@ -178,6 +231,27 @@ public:
, mScales(data->mScales)
{ }
virtual Ogre::Quaternion getRotation(float time) const
{
if(mRotations.mKeys.size() > 0)
return interpKey(mRotations.mKeys, time);
return mNode->getOrientation();
}
virtual Ogre::Vector3 getTranslation(float time) const
{
if(mTranslations.mKeys.size() > 0)
return interpKey(mTranslations.mKeys, time);
return mNode->getPosition();
}
virtual Ogre::Vector3 getScale(float time) const
{
if(mScales.mKeys.size() > 0)
return Ogre::Vector3(interpKey(mScales.mKeys, time));
return mNode->getScale();
}
virtual Ogre::Real getValue() const
{
// Should not be called
@ -187,68 +261,11 @@ public:
virtual void setValue(Ogre::Real time)
{
if(mRotations.mKeys.size() > 0)
{
if(time <= mRotations.mKeys.front().mTime)
mNode->setOrientation(mRotations.mKeys.front().mValue);
else if(time >= mRotations.mKeys.back().mTime)
mNode->setOrientation(mRotations.mKeys.back().mValue);
else
{
Nif::QuaternionKeyList::VecType::const_iterator iter(mRotations.mKeys.begin()+1);
for(;iter != mRotations.mKeys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::QuaternionKeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
mNode->setOrientation(Ogre::Quaternion::nlerp(a, last->mValue, iter->mValue));
break;
}
}
}
mNode->setOrientation(interpKey(mRotations.mKeys, time));
if(mTranslations.mKeys.size() > 0)
{
if(time <= mTranslations.mKeys.front().mTime)
mNode->setPosition(mTranslations.mKeys.front().mValue);
else if(time >= mTranslations.mKeys.back().mTime)
mNode->setPosition(mTranslations.mKeys.back().mValue);
else
{
Nif::Vector3KeyList::VecType::const_iterator iter(mTranslations.mKeys.begin()+1);
for(;iter != mTranslations.mKeys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::Vector3KeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
mNode->setPosition(last->mValue + ((iter->mValue - last->mValue)*a));
break;
}
}
}
mNode->setPosition(interpKey(mTranslations.mKeys, time));
if(mScales.mKeys.size() > 0)
{
if(time <= mScales.mKeys.front().mTime)
mNode->setScale(Ogre::Vector3(mScales.mKeys.front().mValue));
else if(time >= mScales.mKeys.back().mTime)
mNode->setScale(Ogre::Vector3(mScales.mKeys.back().mValue));
else
{
Nif::FloatKeyList::VecType::const_iterator iter(mScales.mKeys.begin()+1);
for(;iter != mScales.mKeys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::FloatKeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
mNode->setScale(Ogre::Vector3(last->mValue + ((iter->mValue - last->mValue)*a)));
break;
}
}
}
mNode->setScale(Ogre::Vector3(interpKey(mScales.mKeys, time)));
}
};
@ -289,7 +306,7 @@ public:
}
public:
Value(const Ogre::MaterialPtr &material, Nif::NiUVData *data)
Value(const Ogre::MaterialPtr &material, const Nif::NiUVData *data)
: mMaterial(material)
, mUTrans(data->mKeyList[0])
, mVTrans(data->mKeyList[1])
@ -329,11 +346,70 @@ public:
typedef DefaultFunction Function;
};
class ParticleSystemController
{
public:
class Value : public Ogre::ControllerValue<Ogre::Real>
{
private:
Ogre::ParticleSystem *mParticleSys;
float mEmitStart;
float mEmitStop;
public:
Value(Ogre::ParticleSystem *psys, const Nif::NiParticleSystemController *pctrl)
: mParticleSys(psys)
, mEmitStart(pctrl->startTime)
, mEmitStop(pctrl->stopTime)
{
}
Ogre::Real getValue() const
{ return 0.0f; }
void setValue(Ogre::Real value)
{
mParticleSys->setEmitting(value >= mEmitStart && value < mEmitStop);
}
};
typedef DefaultFunction Function;
};
class GeomMorpherController
{
public:
class Value : public Ogre::ControllerValue<Ogre::Real>
{
private:
Ogre::SubEntity *mSubEntity;
std::vector<Nif::NiMorphData::MorphData> mMorphs;
public:
Value(Ogre::SubEntity *subent, const Nif::NiMorphData *data)
: mSubEntity(subent)
, mMorphs(data->mMorphs)
{ }
virtual Ogre::Real getValue() const
{
// Should not be called
return 0.0f;
}
virtual void setValue(Ogre::Real value)
{
// TODO: Implement
}
};
typedef DefaultFunction Function;
};
/** Manual resource loader for NIF objects (meshes, particle systems, etc).
* This is the main class responsible for translating the internal NIF
* structures into something Ogre can use.
/** Object creator for NIFs. This is the main class responsible for creating
* "live" Ogre objects (entities, particle systems, controllers, etc) from
* their NIF equivalents.
*/
class NIFObjectLoader
{
@ -349,14 +425,79 @@ class NIFObjectLoader
}
static void createEntity(const std::string &name, const std::string &group,
Ogre::SceneManager *sceneMgr, ObjectList &objectlist,
const Nif::Node *node, int flags, int animflags)
{
const Nif::NiTriShape *shape = static_cast<const Nif::NiTriShape*>(node);
std::string fullname = name+"@index="+Ogre::StringConverter::toString(shape->recIndex);
if(shape->name.length() > 0)
fullname += "@shape="+shape->name;
Misc::StringUtils::toLower(fullname);
Ogre::MeshManager &meshMgr = Ogre::MeshManager::getSingleton();
if(meshMgr.getByName(fullname).isNull())
NIFMeshLoader::createMesh(name, fullname, group, shape->recIndex);
Ogre::Entity *entity = sceneMgr->createEntity(fullname);
entity->setVisible(!(flags&Nif::NiNode::Flag_Hidden));
objectlist.mEntities.push_back(entity);
if(objectlist.mSkelBase)
{
if(entity->hasSkeleton())
entity->shareSkeletonInstanceWith(objectlist.mSkelBase);
else
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, shape->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), entity);
}
}
Nif::ControllerPtr ctrl = node->controller;
while(!ctrl.empty())
{
if(ctrl->recType == Nif::RC_NiUVController)
{
const Nif::NiUVController *uv = static_cast<const Nif::NiUVController*>(ctrl.getPtr());
const Ogre::MaterialPtr &material = entity->getSubEntity(0)->getMaterial();
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(material, uv->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW UVController::Function(uv, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
else if(ctrl->recType == Nif::RC_NiGeomMorpherController)
{
const Nif::NiGeomMorpherController *geom = static_cast<const Nif::NiGeomMorpherController*>(ctrl.getPtr());
Ogre::SubEntity *subent = entity->getSubEntity(0);
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW GeomMorpherController::Value(subent, geom->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW GeomMorpherController::Function(geom, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrl = ctrl->next;
}
}
static void createParticleEmitterAffectors(Ogre::ParticleSystem *partsys, const Nif::NiParticleSystemController *partctrl)
{
Ogre::ParticleEmitter *emitter = partsys->addEmitter("Nif");
emitter->setParticleVelocity(partctrl->velocity-partctrl->velocityRandom,
partctrl->velocity+partctrl->velocityRandom);
emitter->setParticleVelocity(partctrl->velocity - partctrl->velocityRandom*0.5f,
partctrl->velocity + partctrl->velocityRandom*0.5f);
emitter->setEmissionRate(partctrl->emitRate);
emitter->setTimeToLive(partctrl->lifetime-partctrl->lifetimeRandom,
partctrl->lifetime+partctrl->lifetimeRandom);
emitter->setTimeToLive(partctrl->lifetime - partctrl->lifetimeRandom*0.5f,
partctrl->lifetime + partctrl->lifetimeRandom*0.5f);
emitter->setParameter("width", Ogre::StringConverter::toString(partctrl->offsetRandom.x));
emitter->setParameter("height", Ogre::StringConverter::toString(partctrl->offsetRandom.y));
emitter->setParameter("depth", Ogre::StringConverter::toString(partctrl->offsetRandom.z));
@ -416,9 +557,9 @@ class NIFObjectLoader
}
}
static Ogre::ParticleSystem *createParticleSystem(const std::string &name, const std::string &group,
Ogre::SceneManager *sceneMgr, Ogre::Entity *entitybase,
const Nif::Node *partnode)
static void createParticleSystem(const std::string &name, const std::string &group,
Ogre::SceneManager *sceneMgr, ObjectList &objectlist,
const Nif::Node *partnode, int flags, int partflags)
{
const Nif::NiAutoNormalParticlesData *particledata = NULL;
if(partnode->recType == Nif::RC_NiAutoNormalParticles)
@ -426,13 +567,13 @@ class NIFObjectLoader
else if(partnode->recType == Nif::RC_NiRotatingParticles)
particledata = static_cast<const Nif::NiRotatingParticles*>(partnode)->data.getPtr();
Ogre::ParticleSystem *partsys = sceneMgr->createParticleSystem();
try {
std::string fullname = name+"@index="+Ogre::StringConverter::toString(partnode->recIndex);
if(partnode->name.length() > 0)
fullname += "@type="+partnode->name;
Misc::StringUtils::toLower(fullname);
Ogre::ParticleSystem *partsys = sceneMgr->createParticleSystem();
const Nif::NiTexturingProperty *texprop = NULL;
const Nif::NiMaterialProperty *matprop = NULL;
const Nif::NiAlphaProperty *alphaprop = NULL;
@ -467,9 +608,17 @@ class NIFObjectLoader
if(!partctrl->emitter.empty() && !partsys->isAttached())
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partctrl->emitter->recIndex);
Ogre::Bone *trgtbone = entitybase->getSkeleton()->getBone(trgtid);
entitybase->attachObjectToBone(trgtbone->getName(), partsys);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), partsys);
}
Ogre::ControllerValueRealPtr srcval((partflags&Nif::NiNode::ParticleFlag_AutoPlay) ?
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW ParticleSystemController::Value(partsys, partctrl));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW ParticleSystemController::Function(partctrl, (partflags&Nif::NiNode::ParticleFlag_AutoPlay)));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrl = ctrl->next;
}
@ -477,22 +626,80 @@ class NIFObjectLoader
if(!partsys->isAttached())
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partnode->recIndex);
Ogre::Bone *trgtbone = entitybase->getSkeleton()->getBone(trgtid);
entitybase->attachObjectToBone(trgtbone->getName(), partsys);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), partsys);
}
partsys->setVisible(!(flags&Nif::NiNode::Flag_Hidden));
objectlist.mParticles.push_back(partsys);
}
static void createNodeControllers(const std::string &name, Nif::ControllerPtr ctrl, ObjectList &objectlist, int animflags)
{
do {
if(ctrl->recType == Nif::RC_NiVisController)
{
const Nif::NiVisController *vis = static_cast<const Nif::NiVisController*>(ctrl.getPtr());
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW VisController::Value(trgtbone, vis->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW VisController::Function(vis, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
else if(ctrl->recType == Nif::RC_NiKeyframeController)
{
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
if(!key->data.empty())
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
}
ctrl = ctrl->next;
} while(!ctrl.empty());
}
static void extractTextKeys(const Nif::NiTextKeyExtraData *tk, TextKeyMap &textkeys)
{
for(size_t i = 0;i < tk->list.size();i++)
{
const std::string &str = tk->list[i].text;
std::string::size_type pos = 0;
while(pos < str.length())
{
if(::isspace(str[pos]))
{
pos++;
continue;
}
std::string::size_type nextpos = std::min(str.find('\r', pos), str.find('\n', pos));
std::string result = str.substr(pos, nextpos-pos);
textkeys.insert(std::make_pair(tk->list[i].time, Misc::StringUtils::toLower(result)));
pos = nextpos;
}
}
catch(std::exception &e) {
std::cerr<< "Particles exception: "<<e.what() <<std::endl;
sceneMgr->destroyParticleSystem(partsys);
partsys = NULL;
};
return partsys;
}
static void createObjects(const std::string &name, const std::string &group,
Ogre::SceneManager *sceneMgr, const Nif::Node *node,
ObjectList &objectlist, int flags)
ObjectList &objectlist, int flags, int animflags, int partflags)
{
// Do not create objects for the collision shape (includes all children)
if(node->recType == Nif::RC_RootCollisionNode)
@ -503,12 +710,24 @@ class NIFObjectLoader
if (node->name.find("marker") != std::string::npos)
return;
if(node->recType == Nif::RC_NiBSAnimationNode)
animflags |= node->flags;
else if(node->recType == Nif::RC_NiBSParticleNode)
partflags |= node->flags;
else
flags |= node->flags;
Nif::ExtraPtr e = node->extra;
while(!e.empty())
{
if(e->recType == Nif::RC_NiStringExtraData)
if(e->recType == Nif::RC_NiTextKeyExtraData)
{
const Nif::NiTextKeyExtraData *tk = static_cast<const Nif::NiTextKeyExtraData*>(e.getPtr());
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, node->recIndex);
extractTextKeys(tk, objectlist.mTextKeys[trgtid]);
}
else if(e->recType == Nif::RC_NiStringExtraData)
{
const Nif::NiStringExtraData *sd = static_cast<const Nif::NiStringExtraData*>(e.getPtr());
// String markers may contain important information
@ -520,9 +739,13 @@ class NIFObjectLoader
flags |= 0x80000000;
}
}
e = e->extra;
}
if(!node->controller.empty())
createNodeControllers(name, node->controller, objectlist, animflags);
if(node->recType == Nif::RC_NiCamera)
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, node->recIndex);
@ -530,94 +753,15 @@ class NIFObjectLoader
objectlist.mCameras.push_back(trgtbone);
}
Nif::ControllerPtr ctrl = node->controller;
while(!ctrl.empty())
{
if(ctrl->recType == Nif::RC_NiVisController)
{
const Nif::NiVisController *vis = static_cast<const Nif::NiVisController*>(ctrl.getPtr());
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
Ogre::ControllerValueRealPtr srcval; /* Filled in later */
Ogre::ControllerValueRealPtr dstval(OGRE_NEW VisController::Value(trgtbone, vis->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW VisController::Function(vis, false));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
else if(ctrl->recType == Nif::RC_NiKeyframeController)
{
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
if(!key->data.empty())
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
Ogre::ControllerValueRealPtr srcval; /* Filled in later */
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW KeyframeController::Function(key, false));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
}
ctrl = ctrl->next;
}
if(node->recType == Nif::RC_NiTriShape && !(flags&0x80000000))
{
const Nif::NiTriShape *shape = static_cast<const Nif::NiTriShape*>(node);
std::string fullname = name+"@index="+Ogre::StringConverter::toString(shape->recIndex);
if(shape->name.length() > 0)
fullname += "@shape="+shape->name;
Misc::StringUtils::toLower(fullname);
Ogre::MeshManager &meshMgr = Ogre::MeshManager::getSingleton();
if(meshMgr.getByName(fullname).isNull())
NIFMeshLoader::createMesh(name, fullname, group, shape->recIndex);
Ogre::Entity *entity = sceneMgr->createEntity(fullname);
entity->setVisible(!(flags&0x01));
objectlist.mEntities.push_back(entity);
if(objectlist.mSkelBase)
{
if(entity->hasSkeleton())
entity->shareSkeletonInstanceWith(objectlist.mSkelBase);
else
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, shape->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), entity);
}
}
Nif::ControllerPtr ctrl = node->controller;
while(!ctrl.empty())
{
if(ctrl->recType == Nif::RC_NiUVController)
{
const Nif::NiUVController *uv = static_cast<const Nif::NiUVController*>(ctrl.getPtr());
const Ogre::MaterialPtr &material = entity->getSubEntity(0)->getMaterial();
Ogre::ControllerValueRealPtr srcval(Ogre::ControllerManager::getSingleton().getFrameTimeSource());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(material, uv->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW UVController::Function(uv, true));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrl = ctrl->next;
}
createEntity(name, group, sceneMgr, objectlist, node, flags, animflags);
}
if((node->recType == Nif::RC_NiAutoNormalParticles ||
node->recType == Nif::RC_NiRotatingParticles) && !(flags&0x40000000))
{
Ogre::ParticleSystem *partsys = createParticleSystem(name, group, sceneMgr, objectlist.mSkelBase, node);
if(partsys != NULL)
{
partsys->setVisible(!(flags&0x01));
objectlist.mParticles.push_back(partsys);
}
createParticleSystem(name, group, sceneMgr, objectlist, node, flags, partflags);
}
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node);
@ -627,7 +771,7 @@ class NIFObjectLoader
for(size_t i = 0;i < children.length();i++)
{
if(!children[i].empty())
createObjects(name, group, sceneMgr, children[i].getPtr(), objectlist, flags);
createObjects(name, group, sceneMgr, children[i].getPtr(), objectlist, flags, animflags, partflags);
}
}
}
@ -674,7 +818,7 @@ public:
// Create a base skeleton entity if this NIF needs one
createSkelBase(name, group, sceneMgr, node, objectlist);
}
createObjects(name, group, sceneMgr, node, objectlist, flags);
createObjects(name, group, sceneMgr, node, objectlist, flags, 0, 0);
}
};
@ -757,12 +901,15 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena
}
ObjectList Loader::createObjectBase(Ogre::SceneManager *sceneMgr, std::string name, const std::string &group)
ObjectList Loader::createObjectBase(Ogre::SceneNode *parentNode, std::string name, const std::string &group)
{
ObjectList objectlist;
Misc::StringUtils::toLower(name);
NIFObjectLoader::load(sceneMgr, objectlist, name, group, 0xC0000000);
NIFObjectLoader::load(parentNode->getCreator(), objectlist, name, group, 0xC0000000);
if(objectlist.mSkelBase)
parentNode->attachObject(objectlist.mSkelBase);
return objectlist;
}

View file

@ -50,6 +50,8 @@ struct ObjectList {
// bones in the mSkelBase which are NiCamera nodes.
std::vector<Ogre::Bone*> mCameras;
std::map<int,TextKeyMap> mTextKeys;
std::vector<Ogre::Controller<Ogre::Real> > mControllers;
ObjectList() : mSkelBase(0)
@ -69,7 +71,7 @@ public:
std::string name,
const std::string &group="General");
static ObjectList createObjectBase(Ogre::SceneManager *sceneMgr,
static ObjectList createObjectBase(Ogre::SceneNode *parentNode,
std::string name,
const std::string &group="General");
};
@ -85,6 +87,10 @@ public:
NodeTargetValue(Ogre::Node *target) : mNode(target)
{ }
virtual Ogre::Quaternion getRotation(T value) const = 0;
virtual Ogre::Vector3 getTranslation(T value) const = 0;
virtual Ogre::Vector3 getScale(T value) const = 0;
void setNode(Ogre::Node *target)
{ mNode = target; }
Ogre::Node *getNode() const
@ -94,14 +100,4 @@ typedef Ogre::SharedPtr<NodeTargetValue<Ogre::Real> > NodeTargetValueRealPtr;
}
namespace std
{
// These operators allow extra data types to be stored in an Ogre::Any
// object, which can then be stored in user object bindings on the nodes
ostream& operator<<(ostream &o, const NifOgre::TextKeyMap&);
}
#endif

View file

@ -11,142 +11,7 @@
namespace NifOgre
{
void NIFSkeletonLoader::buildAnimation(Ogre::Skeleton *skel, const std::string &name, const std::vector<const Nif::NiKeyframeController*> &ctrls, const std::vector<std::string> &targets, float startTime, float stopTime)
{
Ogre::Animation *anim = skel->createAnimation(name, stopTime);
for(size_t i = 0;i < ctrls.size();i++)
{
const Nif::NiKeyframeController *kfc = ctrls[i];
if(kfc->data.empty())
continue;
const Nif::NiKeyframeData *kf = kfc->data.getPtr();
/* Get the keyframes and make sure they're sorted first to last */
const Nif::QuaternionKeyList &quatkeys = kf->mRotations;
const Nif::Vector3KeyList &trankeys = kf->mTranslations;
const Nif::FloatKeyList &scalekeys = kf->mScales;
Nif::QuaternionKeyList::VecType::const_iterator quatiter = quatkeys.mKeys.begin();
Nif::Vector3KeyList::VecType::const_iterator traniter = trankeys.mKeys.begin();
Nif::FloatKeyList::VecType::const_iterator scaleiter = scalekeys.mKeys.begin();
Ogre::Bone *bone = skel->getBone(targets[i]);
// NOTE: For some reason, Ogre doesn't like the node track ID being different from
// the bone ID
Ogre::NodeAnimationTrack *nodetrack = anim->hasNodeTrack(bone->getHandle()) ?
anim->getNodeTrack(bone->getHandle()) :
anim->createNodeTrack(bone->getHandle(), bone);
Ogre::Quaternion lastquat, curquat;
Ogre::Vector3 lasttrans(0.0f), curtrans(0.0f);
Ogre::Vector3 lastscale(1.0f), curscale(1.0f);
if(quatiter != quatkeys.mKeys.end())
lastquat = curquat = quatiter->mValue;
if(traniter != trankeys.mKeys.end())
lasttrans = curtrans = traniter->mValue;
if(scaleiter != scalekeys.mKeys.end())
lastscale = curscale = Ogre::Vector3(scaleiter->mValue);
bool didlast = false;
while(!didlast)
{
float curtime = std::numeric_limits<float>::max();
//Get latest time
if(quatiter != quatkeys.mKeys.end())
curtime = std::min(curtime, quatiter->mTime);
if(traniter != trankeys.mKeys.end())
curtime = std::min(curtime, traniter->mTime);
if(scaleiter != scalekeys.mKeys.end())
curtime = std::min(curtime, scaleiter->mTime);
curtime = std::max(curtime, startTime);
if(curtime >= stopTime)
{
didlast = true;
curtime = stopTime;
}
// Get the latest quaternions, translations, and scales for the
// current time
while(quatiter != quatkeys.mKeys.end() && curtime >= quatiter->mTime)
{
lastquat = curquat;
if(++quatiter != quatkeys.mKeys.end())
curquat = quatiter->mValue;
}
while(traniter != trankeys.mKeys.end() && curtime >= traniter->mTime)
{
lasttrans = curtrans;
if(++traniter != trankeys.mKeys.end())
curtrans = traniter->mValue;
}
while(scaleiter != scalekeys.mKeys.end() && curtime >= scaleiter->mTime)
{
lastscale = curscale;
if(++scaleiter != scalekeys.mKeys.end())
curscale = Ogre::Vector3(scaleiter->mValue);
}
Ogre::TransformKeyFrame *kframe;
kframe = nodetrack->createNodeKeyFrame(curtime);
if(quatiter == quatkeys.mKeys.end() || quatiter == quatkeys.mKeys.begin())
kframe->setRotation(curquat);
else
{
Nif::QuaternionKeyList::VecType::const_iterator last = quatiter-1;
float diff = (curtime-last->mTime) / (quatiter->mTime-last->mTime);
kframe->setRotation(Ogre::Quaternion::nlerp(diff, lastquat, curquat));
}
if(traniter == trankeys.mKeys.end() || traniter == trankeys.mKeys.begin())
kframe->setTranslate(curtrans);
else
{
Nif::Vector3KeyList::VecType::const_iterator last = traniter-1;
float diff = (curtime-last->mTime) / (traniter->mTime-last->mTime);
kframe->setTranslate(lasttrans + ((curtrans-lasttrans)*diff));
}
if(scaleiter == scalekeys.mKeys.end() || scaleiter == scalekeys.mKeys.begin())
kframe->setScale(curscale);
else
{
Nif::FloatKeyList::VecType::const_iterator last = scaleiter-1;
float diff = (curtime-last->mTime) / (scaleiter->mTime-last->mTime);
kframe->setScale(lastscale + ((curscale-lastscale)*diff));
}
}
}
anim->optimise();
}
TextKeyMap NIFSkeletonLoader::extractTextKeys(const Nif::NiTextKeyExtraData *tk)
{
TextKeyMap textkeys;
for(size_t i = 0;i < tk->list.size();i++)
{
const std::string &str = tk->list[i].text;
std::string::size_type pos = 0;
while(pos < str.length())
{
if(::isspace(str[pos]))
{
pos++;
continue;
}
std::string::size_type nextpos = std::min(str.find('\r', pos), str.find('\n', pos));
std::string result = str.substr(pos, nextpos-pos);
textkeys.insert(std::make_pair(tk->list[i].time, Misc::StringUtils::toLower(result)));
pos = nextpos;
}
}
return textkeys;
}
void NIFSkeletonLoader::buildBones(Ogre::Skeleton *skel, const Nif::Node *node, Ogre::Bone *&animroot, TextKeyMap &textkeys, std::vector<Nif::NiKeyframeController const*> &ctrls, Ogre::Bone *parent)
void NIFSkeletonLoader::buildBones(Ogre::Skeleton *skel, const Nif::Node *node, Ogre::Bone *parent)
{
Ogre::Bone *bone;
if(!skel->hasBone(node->name))
@ -164,6 +29,8 @@ void NIFSkeletonLoader::buildBones(Ogre::Skeleton *skel, const Nif::Node *node,
if(!(node->recType == Nif::RC_NiNode || /* Nothing special; children traversed below */
node->recType == Nif::RC_RootCollisionNode || /* handled in nifbullet (hopefully) */
node->recType == Nif::RC_NiTriShape || /* Handled in the mesh loader */
node->recType == Nif::RC_NiBSAnimationNode || /* Handled in the object loader */
node->recType == Nif::RC_NiBSParticleNode ||
node->recType == Nif::RC_NiCamera ||
node->recType == Nif::RC_NiAutoNormalParticles ||
node->recType == Nif::RC_NiRotatingParticles
@ -173,28 +40,16 @@ void NIFSkeletonLoader::buildBones(Ogre::Skeleton *skel, const Nif::Node *node,
Nif::ControllerPtr ctrl = node->controller;
while(!ctrl.empty())
{
if(ctrl->recType == Nif::RC_NiKeyframeController)
ctrls.push_back(static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr()));
else if(!(ctrl->recType == Nif::RC_NiParticleSystemController ||
if(!(ctrl->recType == Nif::RC_NiParticleSystemController ||
ctrl->recType == Nif::RC_NiVisController ||
ctrl->recType == Nif::RC_NiUVController
ctrl->recType == Nif::RC_NiUVController ||
ctrl->recType == Nif::RC_NiKeyframeController ||
ctrl->recType == Nif::RC_NiGeomMorpherController
))
warn("Unhandled "+ctrl->recName+" from node "+node->name+" in "+skel->getName());
ctrl = ctrl->next;
}
Nif::ExtraPtr e = node->extra;
while(!e.empty())
{
if(e->recType == Nif::RC_NiTextKeyExtraData && !animroot)
{
const Nif::NiTextKeyExtraData *tk = static_cast<const Nif::NiTextKeyExtraData*>(e.getPtr());
textkeys = extractTextKeys(tk);
animroot = bone;
}
e = e->extra;
}
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node);
if(ninode)
{
@ -202,7 +57,7 @@ void NIFSkeletonLoader::buildBones(Ogre::Skeleton *skel, const Nif::Node *node,
for(size_t i = 0;i < children.length();i++)
{
if(!children[i].empty())
buildBones(skel, children[i].getPtr(), animroot, textkeys, ctrls, bone);
buildBones(skel, children[i].getPtr(), bone);
}
}
}
@ -215,84 +70,14 @@ void NIFSkeletonLoader::loadResource(Ogre::Resource *resource)
Nif::NIFFile::ptr nif(Nif::NIFFile::create(skel->getName()));
const Nif::Node *node = static_cast<const Nif::Node*>(nif->getRoot(0));
std::vector<const Nif::NiKeyframeController*> ctrls;
Ogre::Bone *animroot = NULL;
TextKeyMap textkeys;
try {
buildBones(skel, node, animroot, textkeys, ctrls);
buildBones(skel, node);
}
catch(std::exception &e) {
std::cerr<< "Exception while loading "<<skel->getName() <<std::endl;
std::cerr<< e.what() <<std::endl;
return;
}
/* Animations without textkeys don't get Ogre::Animation objects. */
if(!animroot)
return;
std::vector<std::string> targets;
// TODO: If ctrls.size() == 0, check for a .kf file sharing the name of the .nif file
if(ctrls.size() == 0) // No animations? Then we're done.
return;
float maxtime = 0.0f;
for(size_t i = 0;i < ctrls.size();i++)
{
const Nif::NiKeyframeController *ctrl = ctrls[i];
maxtime = std::max(maxtime, ctrl->timeStop);
Nif::Named *target = dynamic_cast<Nif::Named*>(ctrl->target.getPtr());
if(target != NULL)
targets.push_back(target->name);
}
if(targets.size() != ctrls.size())
{
warn("Target size mismatch ("+Ogre::StringConverter::toString(targets.size())+" targets, "+
Ogre::StringConverter::toString(ctrls.size())+" controllers)");
return;
}
Ogre::UserObjectBindings &bindings = animroot->getUserObjectBindings();
bindings.setUserAny(sTextKeyExtraDataID, Ogre::Any(true));
std::string currentgroup;
TextKeyMap::const_iterator keyiter = textkeys.begin();
for(keyiter = textkeys.begin();keyiter != textkeys.end();keyiter++)
{
std::string::size_type sep = keyiter->second.find(':');
if((sep == currentgroup.length() && keyiter->second.compare(0, sep, currentgroup) == 0) ||
(sep == sizeof("soundgen")-1 && keyiter->second.compare(0, sep, "soundgen") == 0) ||
(sep == sizeof("sound")-1 && keyiter->second.compare(0, sep, "sound") == 0))
continue;
currentgroup = keyiter->second.substr(0, sep);
if(skel->hasAnimation(currentgroup))
continue;
TextKeyMap::const_iterator lastkeyiter = textkeys.end();
while((--lastkeyiter)->first > keyiter->first)
{
if(lastkeyiter->second.find(':') == currentgroup.length() &&
lastkeyiter->second.compare(0, currentgroup.length(), currentgroup) == 0)
break;
}
buildAnimation(skel, currentgroup, ctrls, targets, keyiter->first, lastkeyiter->first);
TextKeyMap::const_iterator insiter(keyiter);
TextKeyMap groupkeys;
do {
sep = insiter->second.find(':');
if(sep == currentgroup.length() && insiter->second.compare(0, sep, currentgroup) == 0)
groupkeys.insert(std::make_pair(insiter->first, insiter->second.substr(sep+2)));
else if((sep == sizeof("soundgen")-1 && insiter->second.compare(0, sep, "soundgen") == 0) ||
(sep == sizeof("sound")-1 && insiter->second.compare(0, sep, "sound") == 0))
groupkeys.insert(std::make_pair(insiter->first, insiter->second));
} while(insiter++ != lastkeyiter);
bindings.setUserAny(std::string(sTextKeyExtraDataID)+"@"+currentgroup, Ogre::Any(groupkeys));
}
}
@ -300,16 +85,16 @@ Ogre::SkeletonPtr NIFSkeletonLoader::createSkeleton(const std::string &name, con
{
/* We need to be a little aggressive here, since some NIFs have a crap-ton
* of nodes and Ogre only supports 256 bones. We will skip a skeleton if:
* There are no bones used for skinning, there are no controllers on non-
* NiTriShape nodes, there are no nodes named "AttachLight", and the tree
* consists of NiNode, NiTriShape, and RootCollisionNode types only.
* There are no bones used for skinning, there are no controllers, there
* are no nodes named "AttachLight", and the tree consists of NiNode,
* NiTriShape, and RootCollisionNode types only.
*/
if(!node->boneTrafo)
{
if(node->recType == Nif::RC_NiTriShape)
return Ogre::SkeletonPtr();
if(node->controller.empty() && node->name != "AttachLight")
{
if(node->recType == Nif::RC_NiTriShape)
return Ogre::SkeletonPtr();
if(node->recType == Nif::RC_NiNode || node->recType == Nif::RC_RootCollisionNode)
{
const Nif::NiNode *ninode = static_cast<const Nif::NiNode*>(node);

View file

@ -36,10 +36,7 @@ class NIFSkeletonLoader : public Ogre::ManualResourceLoader
abort();
}
static void buildAnimation(Ogre::Skeleton *skel, const std::string &name, const std::vector<const Nif::NiKeyframeController*> &ctrls, const std::vector<std::string> &targets, float startTime, float stopTime);
static TextKeyMap extractTextKeys(const Nif::NiTextKeyExtraData *tk);
void buildBones(Ogre::Skeleton *skel, const Nif::Node *node, Ogre::Bone *&animroot, TextKeyMap &textkeys, std::vector<Nif::NiKeyframeController const*> &ctrls, Ogre::Bone *parent=NULL);
void buildBones(Ogre::Skeleton *skel, const Nif::Node *node, Ogre::Bone *parent=NULL);
// Lookup to retrieve an Ogre bone handle for a given Nif record index
std::map<int,int> mNifToOgreHandleMap;

View file

@ -9,6 +9,7 @@
<Property key="OffsetHeight" value="0"/>
<Codes>
<Code range="33 126"/>
<Code range="160"/> <!-- Non-breaking space -->
<Code range="192 382"/> <!-- Central and Eastern European languages glyphs -->
<Code range="1025 1105"/>
<Code range="2026"/> <!-- Ellipsis -->

View file

@ -511,8 +511,8 @@ namespace Physic
void PhysicEngine::stepSimulation(double deltaT)
{
// This isn't needed as there are no dynamic objects at this point
//dynamicsWorld->stepSimulation(deltaT,10, 1/60.0);
// This seems to be needed for character controller objects
dynamicsWorld->stepSimulation(deltaT,10, 1/60.0);
if(isDebugCreated)
{
mDebugDrawer->step();

View file

@ -559,6 +559,8 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool
assert(mgr);
mSceneMgr = mgr;
mShaderRenderManager = NULL;
mRenderManager = NULL;
using namespace MyGUI;
@ -574,7 +576,10 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool
// Set up OGRE platform (bypassing OgrePlatform). We might make this more generic later.
mLogManager = new LogManager();
mRenderManager = new MyGUI::ShaderBasedRenderManager();
if (!Ogre::Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION))
mShaderRenderManager = new MyGUI::ShaderBasedRenderManager();
else
mRenderManager = new MyGUI::OgreRenderManager();
mDataManager = new MyGUI::FixedOgreDataManager();
LogManager::getInstance().setSTDOutputEnabled(logging);
@ -582,6 +587,9 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool
if (!theLogFile.empty())
LogManager::getInstance().createDefaultSource(theLogFile);
if (mShaderRenderManager)
mShaderRenderManager->initialise(wnd, mgr);
else
mRenderManager->initialise(wnd, mgr);
mDataManager->initialise("General");
@ -592,8 +600,16 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool
void MyGUIManager::updateWindow (Ogre::RenderWindow *wnd)
{
if (mShaderRenderManager)
{
mShaderRenderManager->setRenderWindow (wnd);
mShaderRenderManager->setActiveViewport(0);
}
else
{
mRenderManager->setRenderWindow (wnd);
mRenderManager->setActiveViewport(0);
}
}
void MyGUIManager::shutdown()
@ -606,6 +622,12 @@ void MyGUIManager::shutdown()
delete mRenderManager;
mRenderManager = NULL;
}
if(mShaderRenderManager)
{
mShaderRenderManager->shutdown();
delete mShaderRenderManager;
mShaderRenderManager = NULL;
}
if(mDataManager)
{
mDataManager->shutdown();

View file

@ -8,6 +8,7 @@ namespace MyGUI
class Gui;
class LogManager;
class OgreDataManager;
class OgreRenderManager;
class ShaderBasedRenderManager;
}
@ -25,12 +26,12 @@ namespace GUI
MyGUI::Gui *mGui;
MyGUI::LogManager* mLogManager;
MyGUI::OgreDataManager* mDataManager;
MyGUI::ShaderBasedRenderManager* mRenderManager;
MyGUI::OgreRenderManager* mRenderManager;
MyGUI::ShaderBasedRenderManager* mShaderRenderManager;
Ogre::SceneManager* mSceneMgr;
public:
MyGUIManager() : mLogManager(NULL), mDataManager(NULL), mRenderManager(NULL), mGui(NULL) {}
MyGUIManager(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false, const std::string& logDir = std::string(""))
{
setup(wnd,mgr,logging, logDir);

View file

@ -19,6 +19,7 @@ Fader::Fader(Ogre::SceneManager* sceneMgr)
, mTargetAlpha(0.f)
, mCurrentAlpha(0.f)
, mStartAlpha(0.f)
, mFactor(1.f)
{
// Create the fading material
MaterialPtr material = MaterialManager::getSingleton().create("FadeInOutMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
@ -63,18 +64,19 @@ void Fader::update(float dt)
if (mCurrentAlpha > mTargetAlpha) mCurrentAlpha = mTargetAlpha;
}
applyAlpha();
mRemainingTime -= dt;
}
if (mCurrentAlpha == 0.f) mRectangle->setVisible(false);
if (1.f-((1.f-mCurrentAlpha) * mFactor) == 0.f)
mRectangle->setVisible(false);
else
applyAlpha();
}
void Fader::applyAlpha()
{
mRectangle->setVisible(true);
mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, mCurrentAlpha);
mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 1.f-((1.f-mCurrentAlpha) * mFactor));
}
void Fader::fadeIn(float time)

View file

@ -29,6 +29,8 @@ namespace Render
void fadeOut(const float time);
void fadeTo(const int percent, const float time);
void setFactor (float factor) { mFactor = factor; }
private:
enum FadingMode
{
@ -49,6 +51,8 @@ namespace Render
float mCurrentAlpha;
float mStartAlpha;
float mFactor;
Ogre::SceneManager* mSceneMgr;
};
}}

View file

@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind
OpenMW is an attempt at recreating the engine for the popular role-playing game
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
Version: 0.22.0
Version: 0.23.0
License: GPL (see GPL3.txt for more information)
Website: http://www.openmw.org
@ -94,6 +94,68 @@ Allowed options:
CHANGELOG
0.23.0
Bug #522: Player collides with placeable items
Bug #553: Open/Close sounds played when accessing main menu w/ Journal Open
Bug #561: Tooltip word wrapping delay
Bug #578: Bribing works incorrectly
Bug #601: PositionCell fails on negative coordinates
Bug #606: Some NPCs hairs not rendered with Better Heads addon
Bug #609: Bad rendering of bone boots
Bug #613: Messagebox causing assert to fail
Bug #631: Segfault on shutdown
Bug #634: Exception when talking to Calvus Horatius in Mournhold, royal palace courtyard
Bug #635: Scale NPCs depending on race
Bug #643: Dialogue Race select function is inverted
Bug #646: Twohanded weapons don't work properly
Bug #654: Crash when dropping objects without a collision shape
Bug #655/656: Objects that were disabled or deleted (but not both) were added to the scene when re-entering a cell
Bug #660: "g" in "change" cut off in Race Menu
Bug #661: Arrille sells me the key to his upstairs room
Bug #662: Day counter starts at 2 instead of 1
Bug #663: Cannot select "come unprepared" topic in dialog with Dagoth Ur
Bug #665: Pickpocket -> "Grab all" grabs all NPC inventory, even not listed in container window.
Bug #666: Looking up/down problem
Bug #667: Active effects border visible during loading
Bug #669: incorrect player position at new game start
Bug #670: race selection menu: sex, face and hair left button not totally clickable
Bug #671: new game: player is naked
Bug #674: buying or selling items doesn't change amount of gold
Bug #675: fatigue is not set to its maximum when starting a new game
Bug #678: Wrong rotation order causes RefData's rotation to be stored incorrectly
Bug #680: different gold coins in Tel Mara
Bug #682: Race menu ignores playable flag for some hairs and faces
Bug #685: Script compiler does not accept ":" after a function name
Bug #688: dispose corpse makes cross-hair to disappear
Bug #691: Auto equipping ignores equipment conditions
Bug #692: OpenMW doesnt load "loose file" texture packs that places resources directly in data folder
Bug #696: Draugr incorrect head offset
Bug #697: Sail transparency issue
Bug #700: "On the rocks" mod does not load its UV coordinates correctly.
Bug #702: Some race mods don't work
Bug #711: Crash during character creation
Bug #715: Growing Tauryon
Bug #725: Auto calculate stats
Bug #728: Failure to open container and talk dialogue
Bug #731: Crash with Mush-Mere's "background" topic
Feature #55/657: Item Repairing
Feature #62/87: Enchanting
Feature #99: Pathfinding
Feature #104: AI Package: Travel
Feature #129: Levelled items
Feature #204: Texture animations
Feature #239: Fallback-Settings
Feature #535: Console object selection improvements
Feature #629: Add levelup description in levelup layout dialog
Feature #630: Optional format subrecord in (tes3) header
Feature #641: Armor rating
Feature #645: OnDeath script function
Feature #683: Companion item UI
Feature #698: Basic Particles
Task #648: Split up components/esm/loadlocks
Task #695: mwgui cleanup
0.22.0
Bug #311: Potential infinite recursion in script compiler