forked from mirror/openmw-tes3mp
magic selection window
This commit is contained in:
parent
fab4cfecb1
commit
c0f27bd5ef
3 changed files with 270 additions and 2 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,12 +71,25 @@ namespace MWGui
|
|||
public:
|
||||
MagicSelectionDialog(MWBase::WindowManager& parWindowManager, QuickKeysMenu* parent);
|
||||
|
||||
virtual void open();
|
||||
|
||||
private:
|
||||
MyGUI::Button* mCancelButton;
|
||||
MyGUI::ScrollView* mMagicList;
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
|
||||
QuickKeysMenu* mParent;
|
||||
|
||||
void onCancelButtonClicked (MyGUI::Widget* sender);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onEnchantedItemSelected(MyGUI::Widget* _sender);
|
||||
void onSpellSelected(MyGUI::Widget* _sender);
|
||||
int estimateHeight(int numSpells) const;
|
||||
|
||||
|
||||
void addGroup(const std::string& label, const std::string& label2);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</Widget>
|
||||
|
||||
<Widget type="Widget" skin="MW_Box" position="8 38 314 285" name="box" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 306 277" name="MagicList" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollView" position="4 4 306 277" name="MagicList" align="Left Top Stretch">
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
|
|
Loading…
Reference in a new issue