|
|
|
@ -5,10 +5,33 @@
|
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
|
#include "../mwbase/world.hpp"
|
|
|
|
|
#include "../mwworld/player.hpp"
|
|
|
|
|
#include "../mwworld/inventorystore.hpp"
|
|
|
|
|
#include "../mwmechanics/spells.hpp"
|
|
|
|
|
#include "../mwmechanics/creaturestats.hpp"
|
|
|
|
|
|
|
|
|
|
#include "windowmanagerimp.hpp"
|
|
|
|
|
#include "itemselection.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
|
|
|
|
{
|
|
|
|
|
int cmp = MWWorld::Class::get(left).getName(left).compare(
|
|
|
|
|
MWWorld::Class::get(right).getName(right));
|
|
|
|
|
return cmp < 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool sortSpells(const std::string& left, const std::string& right)
|
|
|
|
|
{
|
|
|
|
|
const ESM::Spell* a = MWBase::Environment::get().getWorld()->getStore().spells.find(left);
|
|
|
|
|
const ESM::Spell* b = MWBase::Environment::get().getWorld()->getStore().spells.find(right);
|
|
|
|
|
|
|
|
|
|
int cmp = a->name.compare(b->name);
|
|
|
|
|
return cmp < 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace MWGui
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
@ -157,12 +180,35 @@ namespace MWGui
|
|
|
|
|
|
|
|
|
|
void QuickKeysMenu::onAssignMagicItem (MWWorld::Ptr item)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
onAssignItem(item);
|
|
|
|
|
mMagicSelectionDialog->setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QuickKeysMenu::onAssignMagic (const std::string& spellId)
|
|
|
|
|
{
|
|
|
|
|
MyGUI::Button* button = mQuickKeyButtons[mSelectedIndex];
|
|
|
|
|
while (button->getChildCount ())
|
|
|
|
|
MyGUI::Gui::getInstance ().destroyWidget (button->getChildAt(0));
|
|
|
|
|
|
|
|
|
|
MyGUI::ImageBox* image = button->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(9, 8, 42, 42), MyGUI::Align::Default);
|
|
|
|
|
image->setUserString ("ToolTipType", "Spell");
|
|
|
|
|
image->setUserString ("Spell", spellId);
|
|
|
|
|
|
|
|
|
|
// use the icon of the first effect
|
|
|
|
|
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
|
|
|
|
|
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(spell->effects.list.front().effectID);
|
|
|
|
|
std::string path = effect->icon;
|
|
|
|
|
int slashPos = path.find("\\");
|
|
|
|
|
path.insert(slashPos+1, "b_");
|
|
|
|
|
path = std::string("icons\\") + path;
|
|
|
|
|
int pos = path.rfind(".");
|
|
|
|
|
path.erase(pos);
|
|
|
|
|
path.append(".dds");
|
|
|
|
|
|
|
|
|
|
image->setImageTexture (path);
|
|
|
|
|
image->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
|
|
|
|
|
|
|
|
|
|
mMagicSelectionDialog->setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QuickKeysMenu::onAssignMagicCancel ()
|
|
|
|
@ -222,8 +268,11 @@ namespace MWGui
|
|
|
|
|
MagicSelectionDialog::MagicSelectionDialog(MWBase::WindowManager &parWindowManager, QuickKeysMenu* parent)
|
|
|
|
|
: WindowModal("openmw_magicselection_dialog.layout", parWindowManager)
|
|
|
|
|
, mParent(parent)
|
|
|
|
|
, mWidth(0)
|
|
|
|
|
, mHeight(0)
|
|
|
|
|
{
|
|
|
|
|
getWidget(mCancelButton, "CancelButton");
|
|
|
|
|
getWidget(mMagicList, "MagicList");
|
|
|
|
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MagicSelectionDialog::onCancelButtonClicked);
|
|
|
|
|
|
|
|
|
|
center();
|
|
|
|
@ -234,4 +283,210 @@ namespace MWGui
|
|
|
|
|
mParent->onAssignMagicCancel ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MagicSelectionDialog::open ()
|
|
|
|
|
{
|
|
|
|
|
WindowModal::open();
|
|
|
|
|
|
|
|
|
|
while (mMagicList->getChildCount ())
|
|
|
|
|
MyGUI::Gui::getInstance ().destroyWidget (mMagicList->getChildAt (0));
|
|
|
|
|
|
|
|
|
|
mHeight = 0;
|
|
|
|
|
|
|
|
|
|
const int spellHeight = 18;
|
|
|
|
|
|
|
|
|
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
|
|
|
|
MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player);
|
|
|
|
|
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
|
|
|
|
MWMechanics::Spells& spells = stats.getSpells();
|
|
|
|
|
|
|
|
|
|
/// \todo lots of copy&pasted code from SpellWindow
|
|
|
|
|
|
|
|
|
|
// retrieve powers & spells, sort by name
|
|
|
|
|
std::vector<std::string> spellList;
|
|
|
|
|
|
|
|
|
|
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
spellList.push_back(*it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> powers;
|
|
|
|
|
std::vector<std::string>::iterator it = spellList.begin();
|
|
|
|
|
while (it != spellList.end())
|
|
|
|
|
{
|
|
|
|
|
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it);
|
|
|
|
|
if (spell->data.type == ESM::Spell::ST_Power)
|
|
|
|
|
{
|
|
|
|
|
powers.push_back(*it);
|
|
|
|
|
it = spellList.erase(it);
|
|
|
|
|
}
|
|
|
|
|
else if (spell->data.type == ESM::Spell::ST_Ability
|
|
|
|
|
|| spell->data.type == ESM::Spell::ST_Blight
|
|
|
|
|
|| spell->data.type == ESM::Spell::ST_Curse
|
|
|
|
|
|| spell->data.type == ESM::Spell::ST_Disease)
|
|
|
|
|
{
|
|
|
|
|
it = spellList.erase(it);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
std::sort(powers.begin(), powers.end(), sortSpells);
|
|
|
|
|
std::sort(spellList.begin(), spellList.end(), sortSpells);
|
|
|
|
|
|
|
|
|
|
// retrieve usable magic items & sort
|
|
|
|
|
std::vector<MWWorld::Ptr> items;
|
|
|
|
|
for (MWWorld::ContainerStoreIterator it(store.begin()); it != store.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
std::string enchantId = MWWorld::Class::get(*it).getEnchantment(*it);
|
|
|
|
|
if (enchantId != "")
|
|
|
|
|
{
|
|
|
|
|
// only add items with "Cast once" or "Cast on use"
|
|
|
|
|
const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().enchants.find(enchantId);
|
|
|
|
|
int type = enchant->data.type;
|
|
|
|
|
if (type != ESM::Enchantment::CastOnce
|
|
|
|
|
&& type != ESM::Enchantment::WhenUsed)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
items.push_back(*it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
std::sort(items.begin(), items.end(), sortItems);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int height = estimateHeight(items.size() + powers.size() + spellList.size());
|
|
|
|
|
bool scrollVisible = height > mMagicList->getHeight();
|
|
|
|
|
mWidth = mMagicList->getWidth() - scrollVisible * 18;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// powers
|
|
|
|
|
addGroup("#{sPowers}", "");
|
|
|
|
|
|
|
|
|
|
for (std::vector<std::string>::const_iterator it = powers.begin(); it != powers.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it);
|
|
|
|
|
MyGUI::Button* t = mMagicList->createWidget<MyGUI::Button>("SpellText",
|
|
|
|
|
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
|
|
|
|
t->setCaption(spell->name);
|
|
|
|
|
t->setTextAlign(MyGUI::Align::Left);
|
|
|
|
|
t->setUserString("ToolTipType", "Spell");
|
|
|
|
|
t->setUserString("Spell", *it);
|
|
|
|
|
t->eventMouseWheel += MyGUI::newDelegate(this, &MagicSelectionDialog::onMouseWheel);
|
|
|
|
|
t->eventMouseButtonClick += MyGUI::newDelegate(this, &MagicSelectionDialog::onSpellSelected);
|
|
|
|
|
|
|
|
|
|
mHeight += spellHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// other spells
|
|
|
|
|
addGroup("#{sSpells}", "");
|
|
|
|
|
for (std::vector<std::string>::const_iterator it = spellList.begin(); it != spellList.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it);
|
|
|
|
|
MyGUI::Button* t = mMagicList->createWidget<MyGUI::Button>("SpellText",
|
|
|
|
|
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
|
|
|
|
t->setCaption(spell->name);
|
|
|
|
|
t->setTextAlign(MyGUI::Align::Left);
|
|
|
|
|
t->setUserString("ToolTipType", "Spell");
|
|
|
|
|
t->setUserString("Spell", *it);
|
|
|
|
|
t->eventMouseWheel += MyGUI::newDelegate(this, &MagicSelectionDialog::onMouseWheel);
|
|
|
|
|
t->eventMouseButtonClick += MyGUI::newDelegate(this, &MagicSelectionDialog::onSpellSelected);
|
|
|
|
|
|
|
|
|
|
mHeight += spellHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// enchanted items
|
|
|
|
|
addGroup("#{sMagicItem}", "");
|
|
|
|
|
|
|
|
|
|
for (std::vector<MWWorld::Ptr>::const_iterator it = items.begin(); it != items.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
MWWorld::Ptr item = *it;
|
|
|
|
|
|
|
|
|
|
// check if the item is currently equipped (will display in a different color)
|
|
|
|
|
bool equipped = false;
|
|
|
|
|
for (int i=0; i < MWWorld::InventoryStore::Slots; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (store.getSlot(i) != store.end() && *store.getSlot(i) == item)
|
|
|
|
|
{
|
|
|
|
|
equipped = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MyGUI::Button* t = mMagicList->createWidget<MyGUI::Button>(equipped ? "SpellText" : "SpellTextUnequipped",
|
|
|
|
|
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
|
|
|
|
t->setCaption(MWWorld::Class::get(item).getName(item));
|
|
|
|
|
t->setTextAlign(MyGUI::Align::Left);
|
|
|
|
|
t->setUserData(item);
|
|
|
|
|
t->setUserString("ToolTipType", "ItemPtr");
|
|
|
|
|
t->eventMouseButtonClick += MyGUI::newDelegate(this, &MagicSelectionDialog::onEnchantedItemSelected);
|
|
|
|
|
t->eventMouseWheel += MyGUI::newDelegate(this, &MagicSelectionDialog::onMouseWheel);
|
|
|
|
|
|
|
|
|
|
mHeight += spellHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mMagicList->setCanvasSize (mWidth, std::max(mMagicList->getHeight(), mHeight));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MagicSelectionDialog::addGroup(const std::string &label, const std::string& label2)
|
|
|
|
|
{
|
|
|
|
|
if (mMagicList->getChildCount() > 0)
|
|
|
|
|
{
|
|
|
|
|
MyGUI::ImageBox* separator = mMagicList->createWidget<MyGUI::ImageBox>("MW_HLine",
|
|
|
|
|
MyGUI::IntCoord(4, mHeight, mWidth-8, 18),
|
|
|
|
|
MyGUI::Align::Left | MyGUI::Align::Top);
|
|
|
|
|
separator->setNeedMouseFocus(false);
|
|
|
|
|
mHeight += 18;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MyGUI::TextBox* groupWidget = mMagicList->createWidget<MyGUI::TextBox>("SandBrightText",
|
|
|
|
|
MyGUI::IntCoord(0, mHeight, mWidth, 24),
|
|
|
|
|
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
|
|
|
|
groupWidget->setCaptionWithReplacing(label);
|
|
|
|
|
groupWidget->setTextAlign(MyGUI::Align::Left);
|
|
|
|
|
groupWidget->setNeedMouseFocus(false);
|
|
|
|
|
|
|
|
|
|
if (label2 != "")
|
|
|
|
|
{
|
|
|
|
|
MyGUI::TextBox* groupWidget2 = mMagicList->createWidget<MyGUI::TextBox>("SandBrightText",
|
|
|
|
|
MyGUI::IntCoord(0, mHeight, mWidth-4, 24),
|
|
|
|
|
MyGUI::Align::Left | MyGUI::Align::Top);
|
|
|
|
|
groupWidget2->setCaptionWithReplacing(label2);
|
|
|
|
|
groupWidget2->setTextAlign(MyGUI::Align::Right);
|
|
|
|
|
groupWidget2->setNeedMouseFocus(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mHeight += 24;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MagicSelectionDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
|
|
|
|
{
|
|
|
|
|
if (mMagicList->getViewOffset().top + _rel*0.3 > 0)
|
|
|
|
|
mMagicList->setViewOffset(MyGUI::IntPoint(0, 0));
|
|
|
|
|
else
|
|
|
|
|
mMagicList->setViewOffset(MyGUI::IntPoint(0, mMagicList->getViewOffset().top + _rel*0.3));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MagicSelectionDialog::onEnchantedItemSelected(MyGUI::Widget* _sender)
|
|
|
|
|
{
|
|
|
|
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
|
|
|
|
MWWorld::Ptr item = *_sender->getUserData<MWWorld::Ptr>();
|
|
|
|
|
|
|
|
|
|
mParent->onAssignMagicItem (item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MagicSelectionDialog::onSpellSelected(MyGUI::Widget* _sender)
|
|
|
|
|
{
|
|
|
|
|
mParent->onAssignMagic (_sender->getUserString("Spell"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int MagicSelectionDialog::estimateHeight(int numSpells) const
|
|
|
|
|
{
|
|
|
|
|
int height = 0;
|
|
|
|
|
height += 24 * 3 + 18 * 2; // group headings
|
|
|
|
|
height += numSpells * 18;
|
|
|
|
|
return height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|