1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 12:49:40 +00:00

Merge remote-tracking branch 'scrawl/master'

This commit is contained in:
Marc Zinnschlag 2014-06-06 19:09:24 +02:00
commit 0668019c86
45 changed files with 580 additions and 468 deletions

View file

@ -33,7 +33,7 @@ add_openmw_dir (mwgui
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
recharge mode videowidget backgroundimage recharge mode videowidget backgroundimage itemwidget
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue

View file

@ -680,7 +680,7 @@ namespace MWClass
else else
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur? getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
if(ishealth) if(ishealth && !attacker.isEmpty()) // Don't use armor mitigation for fall damage
{ {
// Hit percentages: // Hit percentages:
// cuirass = 30% // cuirass = 30%

View file

@ -13,20 +13,7 @@
#include "inventoryitemmodel.hpp" #include "inventoryitemmodel.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"
#include "itemview.hpp" #include "itemview.hpp"
#include "itemwidget.hpp"
namespace
{
std::string getIconPath(MWWorld::Ptr ptr)
{
std::string path = std::string("icons\\");
path += ptr.getClass().getInventoryIcon(ptr);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
return path;
}
}
namespace MWGui namespace MWGui
{ {
@ -149,7 +136,7 @@ namespace MWGui
{ {
mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr"); mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr");
mApparatus.at (index)->setUserData (*iter); mApparatus.at (index)->setUserData (*iter);
mApparatus.at (index)->setImageTexture (getIconPath (*iter)); mApparatus.at (index)->setItem(*iter);
} }
} }
@ -189,7 +176,7 @@ namespace MWGui
MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients (); MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients ();
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
{ {
MyGUI::ImageBox* ingredient = mIngredients[i]; ItemWidget* ingredient = mIngredients[i];
MWWorld::Ptr item; MWWorld::Ptr item;
if (it != mAlchemy.endIngredients ()) if (it != mAlchemy.endIngredients ())
@ -204,15 +191,15 @@ namespace MWGui
if (ingredient->getChildCount()) if (ingredient->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0));
ingredient->setImageTexture("");
ingredient->clearUserStrings (); ingredient->clearUserStrings ();
ingredient->setItem(item);
if (item.isEmpty ()) if (item.isEmpty ())
continue; continue;
ingredient->setUserString("ToolTipType", "ItemPtr"); ingredient->setUserString("ToolTipType", "ItemPtr");
ingredient->setUserData(item); ingredient->setUserData(item);
ingredient->setImageTexture(getIconPath(item));
MyGUI::TextBox* text = ingredient->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); MyGUI::TextBox* text = ingredient->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right); text->setTextAlign(MyGUI::Align::Right);

View file

@ -11,6 +11,7 @@
namespace MWGui namespace MWGui
{ {
class ItemView; class ItemView;
class ItemWidget;
class SortFilterItemModel; class SortFilterItemModel;
class AlchemyWindow : public WindowBase class AlchemyWindow : public WindowBase
@ -44,8 +45,8 @@ namespace MWGui
MWMechanics::Alchemy mAlchemy; MWMechanics::Alchemy mAlchemy;
std::vector<MyGUI::ImageBox *> mApparatus; std::vector<ItemWidget*> mApparatus;
std::vector<MyGUI::ImageBox *> mIngredients; std::vector<ItemWidget*> mIngredients;
}; };
} }

View file

@ -20,6 +20,7 @@
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "itemview.hpp" #include "itemview.hpp"
#include "itemwidget.hpp"
#include "inventoryitemmodel.hpp" #include "inventoryitemmodel.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"
#include "pickpocketitemmodel.hpp" #include "pickpocketitemmodel.hpp"
@ -46,22 +47,15 @@ namespace MWGui
mSourceSortModel->addDragItem(mItem.mBase, count); mSourceSortModel->addDragItem(mItem.mBase, count);
} }
std::string path = std::string("icons\\"); ItemWidget* baseWidget = mDragAndDropWidget->createWidget<ItemWidget>
path += mItem.mBase.getClass().getInventoryIcon(mItem.mBase); ("MW_ItemIcon", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
MyGUI::ImageBox* baseWidget = mDragAndDropWidget->createWidget<MyGUI::ImageBox>
("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
mDraggedWidget = baseWidget; mDraggedWidget = baseWidget;
MyGUI::ImageBox* image = baseWidget->createWidget<MyGUI::ImageBox>("ImageBox", baseWidget->setItem(mItem.mBase);
MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); baseWidget->setNeedMouseFocus(false);
size_t pos = path.rfind(".");
if (pos != std::string::npos)
path.erase(pos);
path.append(".dds");
image->setImageTexture(path);
image->setNeedMouseFocus(false);
// text widget that shows item count // text widget that shows item count
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", // TODO: move to ItemWidget
MyGUI::TextBox* text = baseWidget->createWidget<MyGUI::TextBox>("SandBrightText",
MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right); text->setTextAlign(MyGUI::Align::Right);
text->setNeedMouseFocus(false); text->setNeedMouseFocus(false);

View file

@ -14,6 +14,7 @@
#include "itemselection.hpp" #include "itemselection.hpp"
#include "container.hpp" #include "container.hpp"
#include "itemwidget.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"
@ -57,8 +58,45 @@ namespace MWGui
void EnchantingDialog::open() void EnchantingDialog::open()
{ {
center(); center();
onRemoveItem(NULL);
onRemoveSoul(NULL); setSoulGem(MWWorld::Ptr());
setItem(MWWorld::Ptr());
}
void EnchantingDialog::setSoulGem(const MWWorld::Ptr &gem)
{
if (gem.isEmpty())
{
mSoulBox->setItem(MWWorld::Ptr());
mSoulBox->clearUserStrings();
mEnchanting.setSoulGem(MWWorld::Ptr());
}
else
{
mSoulBox->setItem(gem);
mSoulBox->setUserString ("ToolTipType", "ItemPtr");
mSoulBox->setUserData(gem);
mEnchanting.setSoulGem(gem);
}
updateLabels();
}
void EnchantingDialog::setItem(const MWWorld::Ptr &item)
{
if (item.isEmpty())
{
mItemBox->setItem(MWWorld::Ptr());
mItemBox->clearUserStrings();
mEnchanting.setOldItem(MWWorld::Ptr());
}
else
{
mItemBox->setItem(item);
mItemBox->setUserString ("ToolTipType", "ItemPtr");
mItemBox->setUserData(item);
mEnchanting.setOldItem(item);
}
updateLabels();
} }
void EnchantingDialog::exit() void EnchantingDialog::exit()
@ -122,16 +160,7 @@ namespace MWGui
startEditing(); startEditing();
mEnchanting.setSoulGem(soulgem); mEnchanting.setSoulGem(soulgem);
MyGUI::ImageBox* image = mSoulBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default); setSoulGem(soulgem);
std::string path = std::string("icons\\");
path += soulgem.getClass().getInventoryIcon(soulgem);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(soulgem);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul);
mPrice->setVisible(false); mPrice->setVisible(false);
mPriceText->setVisible(false); mPriceText->setVisible(false);
@ -151,46 +180,31 @@ namespace MWGui
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender) void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
{ {
delete mItemSelectionDialog; if (mEnchanting.getOldItem().isEmpty())
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}"); {
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected); delete mItemSelectionDialog;
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel); mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}");
mItemSelectionDialog->setVisible(true); mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr()); mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable); mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable);
}
else
{
setItem(MWWorld::Ptr());
}
} }
void EnchantingDialog::onItemSelected(MWWorld::Ptr item) void EnchantingDialog::onItemSelected(MWWorld::Ptr item)
{ {
mItemSelectionDialog->setVisible(false); mItemSelectionDialog->setVisible(false);
while (mItemBox->getChildCount ()) setItem(item);
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
MyGUI::ImageBox* image = mItemBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
mEnchanting.setOldItem(item);
mEnchanting.nextCastStyle(); mEnchanting.nextCastStyle();
updateLabels(); updateLabels();
} }
void EnchantingDialog::onRemoveItem(MyGUI::Widget *sender)
{
while (mItemBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
mEnchanting.setOldItem(MWWorld::Ptr());
updateLabels();
}
void EnchantingDialog::onItemCancel() void EnchantingDialog::onItemCancel()
{ {
mItemSelectionDialog->setVisible(false); mItemSelectionDialog->setVisible(false);
@ -207,28 +221,7 @@ namespace MWGui
return; return;
} }
while (mSoulBox->getChildCount ()) setSoulGem(item);
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
MyGUI::ImageBox* image = mSoulBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul);
updateLabels();
}
void EnchantingDialog::onRemoveSoul(MyGUI::Widget *sender)
{
while (mSoulBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
mEnchanting.setSoulGem(MWWorld::Ptr());
updateLabels();
} }
void EnchantingDialog::onSoulCancel() void EnchantingDialog::onSoulCancel()
@ -238,15 +231,22 @@ namespace MWGui
void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender) void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender)
{ {
delete mItemSelectionDialog; if (mEnchanting.getGem().isEmpty())
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}"); {
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected); delete mItemSelectionDialog;
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel); mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}");
mItemSelectionDialog->setVisible(true); mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr()); mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones); mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayerPtr());
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones);
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}"); //MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
}
else
{
setSoulGem(MWWorld::Ptr());
}
} }
void EnchantingDialog::notifyEffectsChanged () void EnchantingDialog::notifyEffectsChanged ()

View file

@ -11,6 +11,7 @@ namespace MWGui
{ {
class ItemSelectionDialog; class ItemSelectionDialog;
class ItemWidget;
class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{ {
@ -22,6 +23,9 @@ namespace MWGui
virtual void exit(); virtual void exit();
void setSoulGem (const MWWorld::Ptr& gem);
void setItem (const MWWorld::Ptr& item);
void startEnchanting(MWWorld::Ptr actor); void startEnchanting(MWWorld::Ptr actor);
void startSelfEnchanting(MWWorld::Ptr soulgem); void startSelfEnchanting(MWWorld::Ptr soulgem);
@ -32,8 +36,6 @@ namespace MWGui
void onCancelButtonClicked(MyGUI::Widget* sender); void onCancelButtonClicked(MyGUI::Widget* sender);
void onSelectItem (MyGUI::Widget* sender); void onSelectItem (MyGUI::Widget* sender);
void onSelectSoul (MyGUI::Widget* sender); void onSelectSoul (MyGUI::Widget* sender);
void onRemoveItem (MyGUI::Widget* sender);
void onRemoveSoul (MyGUI::Widget* sender);
void onItemSelected(MWWorld::Ptr item); void onItemSelected(MWWorld::Ptr item);
void onItemCancel(); void onItemCancel();
@ -46,8 +48,8 @@ namespace MWGui
ItemSelectionDialog* mItemSelectionDialog; ItemSelectionDialog* mItemSelectionDialog;
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;
MyGUI::ImageBox* mItemBox; ItemWidget* mItemBox;
MyGUI::ImageBox* mSoulBox; ItemWidget* mSoulBox;
MyGUI::Button* mTypeButton; MyGUI::Button* mTypeButton;
MyGUI::Button* mBuyButton; MyGUI::Button* mBuyButton;

View file

@ -64,10 +64,15 @@ namespace
return unicode; return unicode;
} }
// getUtf8, aka the worst function ever written.
// This includes various hacks for dealing with Morrowind's .fnt files that are *mostly*
// in the expected win12XX encoding, but also have randomly swapped characters sometimes.
// Looks like the Morrowind developers found standard encodings too boring and threw in some twists for fun.
std::string getUtf8 (unsigned char c, ToUTF8::Utf8Encoder& encoder, ToUTF8::FromType encoding) std::string getUtf8 (unsigned char c, ToUTF8::Utf8Encoder& encoder, ToUTF8::FromType encoding)
{ {
if (encoding == ToUTF8::WINDOWS_1250) if (encoding == ToUTF8::WINDOWS_1250)
{ {
// Hacks for polish font
unsigned char win1250; unsigned char win1250;
std::map<unsigned char, unsigned char> conv; std::map<unsigned char, unsigned char> conv;
conv[0x80] = 0xc6; conv[0x80] = 0xc6;
@ -101,7 +106,8 @@ namespace
conv[0xa3] = 0xbf; conv[0xa3] = 0xbf;
conv[0xa4] = 0x0; // not contained in win1250 conv[0xa4] = 0x0; // not contained in win1250
conv[0xe1] = 0x8c; conv[0xe1] = 0x8c;
conv[0xe1] = 0x8c; // Can't remember if this was supposed to read 0xe2, or is it just an extraneous copypaste?
//conv[0xe1] = 0x8c;
conv[0xe3] = 0x0; // not contained in win1250 conv[0xe3] = 0x0; // not contained in win1250
conv[0xf5] = 0x0; // not contained in win1250 conv[0xf5] = 0x0; // not contained in win1250
@ -252,6 +258,21 @@ namespace MWGui
code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " " code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent))); + MyGUI::utility::toString((fontSize-data[i].ascent)));
// More hacks! The french game uses U+2019, which is nowhere to be found in
// the CP437 encoding of the font. Fall back to 39 (regular apostrophe)
if (i == 39 && mEncoding == ToUTF8::CP437)
{
MyGUI::xml::ElementPtr code = codes->createChild("Code");
code->addAttribute("index", 0x2019);
code->addAttribute("coord", MyGUI::utility::toString(x1) + " "
+ MyGUI::utility::toString(y1) + " "
+ MyGUI::utility::toString(w) + " "
+ MyGUI::utility::toString(h));
code->addAttribute("advance", data[i].width);
code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
}
// ASCII vertical bar, use this as text input cursor // ASCII vertical bar, use this as text input cursor
if (i == 124) if (i == 124)
{ {
@ -265,18 +286,30 @@ namespace MWGui
cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " " cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent))); + MyGUI::utility::toString((fontSize-data[i].ascent)));
} }
// Question mark, use for NotDefined marker (used for glyphs not existing in the font)
if (i == 63)
{
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
cursorCode->addAttribute("index", MyGUI::FontCodeType::NotDefined);
cursorCode->addAttribute("coord", MyGUI::utility::toString(x1) + " "
+ MyGUI::utility::toString(y1) + " "
+ MyGUI::utility::toString(w) + " "
+ MyGUI::utility::toString(h));
cursorCode->addAttribute("advance", data[i].width);
cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
}
} }
// These are required as well, but the fonts don't provide them // These are required as well, but the fonts don't provide them
for (int i=0; i<3; ++i) for (int i=0; i<2; ++i)
{ {
MyGUI::FontCodeType::Enum type; MyGUI::FontCodeType::Enum type;
if(i == 0) if(i == 0)
type = MyGUI::FontCodeType::Selected; type = MyGUI::FontCodeType::Selected;
else if (i == 1) else if (i == 1)
type = MyGUI::FontCodeType::SelectedBack; type = MyGUI::FontCodeType::SelectedBack;
else if (i == 2)
type = MyGUI::FontCodeType::NotDefined;
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code"); MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
cursorCode->addAttribute("index", type); cursorCode->addAttribute("index", type);

View file

@ -18,6 +18,7 @@
#include "container.hpp" #include "container.hpp"
#include "itemmodel.hpp" #include "itemmodel.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -423,9 +424,6 @@ namespace MWGui
mSpellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(successChancePercent); mSpellStatus->setProgressPosition(successChancePercent);
if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
mSpellBox->setUserString("ToolTipType", "Spell"); mSpellBox->setUserString("ToolTipType", "Spell");
mSpellBox->setUserString("Spell", spellId); mSpellBox->setUserString("Spell", spellId);
@ -438,7 +436,9 @@ namespace MWGui
icon.insert(slashPos+1, "b_"); icon.insert(slashPos+1, "b_");
icon = std::string("icons\\") + icon; icon = std::string("icons\\") + icon;
Widgets::fixTexturePath(icon); Widgets::fixTexturePath(icon);
mSpellImage->setImageTexture(icon);
mSpellImage->setItem(MWWorld::Ptr());
mSpellImage->setIcon(icon);
} }
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
@ -455,21 +455,10 @@ namespace MWGui
mSpellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(chargePercent); mSpellStatus->setProgressPosition(chargePercent);
if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
mSpellBox->setUserString("ToolTipType", "ItemPtr"); mSpellBox->setUserString("ToolTipType", "ItemPtr");
mSpellBox->setUserData(item); mSpellBox->setUserData(item);
mSpellImage->setImageTexture("textures\\menu_icon_magic_mini.dds"); mSpellImage->setItem(item);
MyGUI::ImageBox* itemBox = mSpellImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
, MyGUI::Align::Stretch);
std::string path = std::string("icons\\");
path+=item.getClass().getInventoryIcon(item);
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)
@ -489,23 +478,7 @@ namespace MWGui
mWeapStatus->setProgressRange(100); mWeapStatus->setProgressRange(100);
mWeapStatus->setProgressPosition(durabilityPercent); mWeapStatus->setProgressPosition(durabilityPercent);
if (mWeapImage->getChildCount()) mWeapImage->setItem(item);
MyGUI::Gui::getInstance().destroyWidget(mWeapImage->getChildAt(0));
std::string path = std::string("icons\\");
path+=item.getClass().getInventoryIcon(item);
Widgets::fixTexturePath(path);
if (item.getClass().getEnchantment(item) != "")
{
mWeapImage->setImageTexture("textures\\menu_icon_magic_mini.dds");
MyGUI::ImageBox* itemBox = mWeapImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1)
, MyGUI::Align::Stretch);
itemBox->setImageTexture(path);
itemBox->setNeedMouseFocus(false);
}
else
mWeapImage->setImageTexture(path);
} }
void HUD::unsetSelectedSpell() void HUD::unsetSelectedSpell()
@ -519,11 +492,9 @@ namespace MWGui
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
if (mSpellImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mSpellImage->getChildAt(0));
mSpellStatus->setProgressRange(100); mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(0); mSpellStatus->setProgressPosition(0);
mSpellImage->setImageTexture(""); mSpellImage->setItem(MWWorld::Ptr());
mSpellBox->clearUserStrings(); mSpellBox->clearUserStrings();
} }
@ -538,17 +509,17 @@ namespace MWGui
mWeaponSpellBox->setVisible(true); mWeaponSpellBox->setVisible(true);
} }
if (mWeapImage->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mWeapImage->getChildAt(0));
mWeapStatus->setProgressRange(100); mWeapStatus->setProgressRange(100);
mWeapStatus->setProgressPosition(0); mWeapStatus->setProgressPosition(0);
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayerPtr(); MWWorld::Ptr player = world->getPlayerPtr();
mWeapImage->setItem(MWWorld::Ptr());
if (player.getClass().getNpcStats(player).isWerewolf()) if (player.getClass().getNpcStats(player).isWerewolf())
mWeapImage->setImageTexture("icons\\k\\tx_werewolf_hand.dds"); mWeapImage->setIcon("icons\\k\\tx_werewolf_hand.dds");
else else
mWeapImage->setImageTexture("icons\\k\\stealth_handtohand.dds"); mWeapImage->setIcon("icons\\k\\stealth_handtohand.dds");
mWeapBox->clearUserStrings(); mWeapBox->clearUserStrings();
} }

View file

@ -10,6 +10,7 @@ namespace MWGui
{ {
class DragAndDrop; class DragAndDrop;
class SpellIcons; class SpellIcons;
class ItemWidget;
class HUD : public OEngine::GUI::Layout, public LocalMapBase class HUD : public OEngine::GUI::Layout, public LocalMapBase
{ {
@ -63,7 +64,7 @@ namespace MWGui
MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning; MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning;
MyGUI::Widget* mHealthFrame; MyGUI::Widget* mHealthFrame;
MyGUI::Widget *mWeapBox, *mSpellBox, *mSneakBox; MyGUI::Widget *mWeapBox, *mSpellBox, *mSneakBox;
MyGUI::ImageBox *mWeapImage, *mSpellImage; ItemWidget *mWeapImage, *mSpellImage;
MyGUI::ProgressBar *mWeapStatus, *mSpellStatus; MyGUI::ProgressBar *mWeapStatus, *mSpellStatus;
MyGUI::Widget *mEffectBox, *mMinimapBox; MyGUI::Widget *mEffectBox, *mMinimapBox;
MyGUI::Button* mMinimapButton; MyGUI::Button* mMinimapButton;

View file

@ -12,6 +12,7 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "itemmodel.hpp" #include "itemmodel.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -80,53 +81,24 @@ void ItemView::update()
const ItemStack& item = mModel->getItem(i); const ItemStack& item = mModel->getItem(i);
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
std::string path = std::string("icons\\"); ItemWidget* itemWidget = dragArea->createWidget<ItemWidget>("MW_ItemIcon",
path += item.mBase.getClass().getInventoryIcon(item.mBase);
// background widget (for the "equipped" frame and magic item background image)
bool isMagic = (item.mFlags & ItemStack::Flag_Enchanted);
MyGUI::ImageBox* backgroundWidget = dragArea->createWidget<MyGUI::ImageBox>("ImageBox",
MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default); MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
backgroundWidget->setUserString("ToolTipType", "ItemModelIndex"); itemWidget->setUserString("ToolTipType", "ItemModelIndex");
backgroundWidget->setUserData(std::make_pair(i, mModel)); itemWidget->setUserData(std::make_pair(i, mModel));
ItemWidget::ItemState state = ItemWidget::None;
if (item.mType == ItemStack::Type_Barter)
state = ItemWidget::Barter;
if (item.mType == ItemStack::Type_Equipped)
state = ItemWidget::Equip;
itemWidget->setItem(item.mBase, state);
std::string backgroundTex = "textures\\menu_icon"; itemWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem);
if (isMagic) itemWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheel);
backgroundTex += "_magic";
if (item.mType == ItemStack::Type_Normal)
{
if (!isMagic)
backgroundTex = "";
}
else if (item.mType == ItemStack::Type_Equipped)
backgroundTex += "_equip";
else if (item.mType == ItemStack::Type_Barter)
backgroundTex += "_barter";
if (backgroundTex != "")
backgroundTex += ".dds";
backgroundWidget->setImageTexture(backgroundTex);
if ((item.mType == ItemStack::Type_Barter) && !isMagic)
backgroundWidget->setProperty("ImageCoord", "2 2 42 42");
else
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem);
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheel);
// image
MyGUI::ImageBox* image = backgroundWidget->createWidget<MyGUI::ImageBox>("ImageBox",
MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
std::string::size_type pos = path.rfind(".");
if(pos != std::string::npos)
path.erase(pos);
path.append(".dds");
image->setImageTexture(path);
image->setNeedMouseFocus(false);
// text widget that shows item count // text widget that shows item count
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", // TODO: move to ItemWidget
MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); MyGUI::TextBox* text = itemWidget->createWidget<MyGUI::TextBox>("SandBrightText",
MyGUI::IntCoord(5, 19, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right); text->setTextAlign(MyGUI::Align::Right);
text->setNeedMouseFocus(false); text->setNeedMouseFocus(false);
text->setTextShadow(true); text->setTextShadow(true);

View file

@ -0,0 +1,105 @@
#include "itemwidget.hpp"
#include <MyGUI_FactoryManager.h>
#include <MyGUI_ImageBox.h>
#include "../mwworld/class.hpp"
namespace MWGui
{
ItemWidget::ItemWidget()
: mItem(NULL)
{
}
void ItemWidget::registerComponents()
{
MyGUI::FactoryManager::getInstance().registerFactory<ItemWidget>("Widget");
}
void ItemWidget::initialiseOverride()
{
assignWidget(mItem, "Item");
if (mItem)
mItem->setNeedMouseFocus(false);
assignWidget(mFrame, "Frame");
if (mFrame)
mFrame->setNeedMouseFocus(false);
Base::initialiseOverride();
}
void ItemWidget::setIcon(const std::string &icon)
{
if (mItem)
mItem->setImageTexture(icon);
}
void ItemWidget::setFrame(const std::string &frame, const MyGUI::IntCoord &coord)
{
if (mFrame)
{
mFrame->setImageTexture(frame);
mFrame->setImageTile(MyGUI::IntSize(coord.width, coord.height)); // Why is this needed? MyGUI bug?
mFrame->setImageCoord(coord);
}
}
void ItemWidget::setIcon(const MWWorld::Ptr &ptr)
{
// image
std::string path = std::string("icons\\");
path += ptr.getClass().getInventoryIcon(ptr);
std::string::size_type pos = path.rfind(".");
if(pos != std::string::npos)
path.erase(pos);
path.append(".dds");
setIcon(path);
}
void ItemWidget::setItem(const MWWorld::Ptr &ptr, ItemState state)
{
if (!mItem)
return;
if (ptr.isEmpty())
{
if (mFrame)
mFrame->setImageTexture("");
mItem->setImageTexture("");
return;
}
bool isMagic = !ptr.getClass().getEnchantment(ptr).empty();
std::string backgroundTex = "textures\\menu_icon";
if (isMagic)
backgroundTex += "_magic";
if (state == None)
{
if (!isMagic)
backgroundTex = "";
}
else if (state == Equip)
{
backgroundTex += "_equip";
}
else if (state == Barter)
backgroundTex += "_barter";
if (backgroundTex != "")
backgroundTex += ".dds";
if (state == Barter && !isMagic)
setFrame(backgroundTex, MyGUI::IntCoord(2,2,42,42));
else
setFrame(backgroundTex, MyGUI::IntCoord(0,0,42,42));
setIcon(ptr);
}
}

View file

@ -0,0 +1,49 @@
#ifndef OPENMW_MWGUI_ITEMWIDGET_H
#define OPENMW_MWGUI_ITEMWIDGET_H
#include <MyGUI_Widget.h>
namespace MWWorld
{
class Ptr;
}
namespace MWGui
{
/// @brief A widget that shows an icon for an MWWorld::Ptr
class ItemWidget : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(ItemWidget)
public:
ItemWidget();
/// Register needed components with MyGUI's factory manager
static void registerComponents ();
enum ItemState
{
None,
Equip,
Barter,
Magic
};
/// \a ptr may be empty
void setItem (const MWWorld::Ptr& ptr, ItemState state = None);
// Set icon and frame manually
void setIcon (const std::string& icon);
void setIcon (const MWWorld::Ptr& ptr);
void setFrame (const std::string& frame, const MyGUI::IntCoord& coord);
private:
virtual void initialiseOverride();
MyGUI::ImageBox* mItem;
MyGUI::ImageBox* mFrame;
};
}
#endif

View file

@ -179,7 +179,6 @@ namespace MWGui
{ {
WindowModal::open(); WindowModal::open();
int fixedWidth = 500;
int textPadding = 10; // padding between text-widget and main-widget int textPadding = 10; // padding between text-widget and main-widget
int textButtonPadding = 20; // padding between the text-widget und the button-widget int textButtonPadding = 20; // padding between the text-widget und the button-widget
int buttonLeftPadding = 10; // padding between the buttons if horizontal int buttonLeftPadding = 10; // padding between the buttons if horizontal
@ -232,102 +231,52 @@ namespace MWGui
buttonsWidth += buttonLeftPadding; buttonsWidth += buttonLeftPadding;
MyGUI::IntSize mainWidgetSize; MyGUI::IntSize mainWidgetSize;
if(buttonsWidth < fixedWidth) // among each other
{ if(biggestButtonWidth > textSize.width) {
// on one line mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
if(textSize.width + 2*textPadding < buttonsWidth)
{
mainWidgetSize.width = buttonsWidth;
}
else
{
mainWidgetSize.width = textSize.width + 3*textPadding;
}
mainWidgetSize.height = textSize.height + textButtonPadding + buttonHeight + buttonMainPadding;
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
mMainWidget->setPosition(absPos);
mMainWidget->setSize(mainWidgetSize);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
mMessageWidget->setCoord(messageWidgetCoord);
mMessageWidget->setSize(textSize);
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonCord.left = left;
buttonCord.top = textSize.height + textButtonPadding;
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
left += buttonSize.width + buttonLeftPadding;
}
} }
else else {
{ mainWidgetSize.width = textSize.width + 3*textPadding;
// among each other
if(biggestButtonWidth > textSize.width) {
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
}
else {
mainWidgetSize.width = textSize.width + 3*textPadding;
}
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int top = textButtonPadding + buttonTopPadding + textSize.height;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
top += buttonSize.height + 2*buttonTopPadding;
}
mainWidgetSize.height = top + buttonMainPadding;
mMainWidget->setSize(mainWidgetSize);
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
mMainWidget->setPosition(absPos);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
messageWidgetCoord.width = textSize.width;
messageWidgetCoord.height = textSize.height;
mMessageWidget->setCoord(messageWidgetCoord);
} }
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int top = textButtonPadding + buttonTopPadding + textSize.height;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
top += buttonSize.height + 2*buttonTopPadding;
}
mainWidgetSize.height = top + buttonMainPadding;
mMainWidget->setSize(mainWidgetSize);
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
mMainWidget->setPosition(absPos);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
messageWidgetCoord.width = textSize.width;
messageWidgetCoord.height = textSize.height;
mMessageWidget->setCoord(messageWidgetCoord);
// Set key focus to "Ok" button // Set key focus to "Ok" button
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}")); std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button) for(button = mButtons.begin(); button != mButtons.end(); ++button)
{ {
if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok)) if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok))

View file

@ -23,6 +23,8 @@
#include "spellwindow.hpp" #include "spellwindow.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -46,14 +48,16 @@ namespace MWGui
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
MyGUI::Button* button; ItemWidget* button;
getWidget(button, "QuickKey" + boost::lexical_cast<std::string>(i+1)); getWidget(button, "QuickKey" + boost::lexical_cast<std::string>(i+1));
button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked); button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
unassign(button, i);
mQuickKeyButtons.push_back(button); mQuickKeyButtons.push_back(button);
mAssigned.push_back(Type_Unassigned);
unassign(button, i);
} }
} }
@ -77,12 +81,14 @@ namespace MWGui
delete mMagicSelectionDialog; delete mMagicSelectionDialog;
} }
void QuickKeysMenu::unassign(MyGUI::Widget* key, int index) void QuickKeysMenu::unassign(ItemWidget* key, int index)
{ {
while (key->getChildCount ()) key->clearUserStrings();
MyGUI::Gui::getInstance ().destroyWidget (key->getChildAt(0)); key->setItem(MWWorld::Ptr());
while (key->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(key->getChildAt(0));
key->setUserData(Type_Unassigned); mAssigned[index] = Type_Unassigned;
MyGUI::TextBox* textBox = key->createWidgetReal<MyGUI::TextBox>("SandText", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default); MyGUI::TextBox* textBox = key->createWidgetReal<MyGUI::TextBox>("SandText", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default);
textBox->setTextAlign (MyGUI::Align::Center); textBox->setTextAlign (MyGUI::Align::Center);
@ -156,27 +162,16 @@ namespace MWGui
void QuickKeysMenu::onAssignItem(MWWorld::Ptr item) void QuickKeysMenu::onAssignItem(MWWorld::Ptr item)
{ {
MyGUI::Button* button = mQuickKeyButtons[mSelectedIndex]; assert (mSelectedIndex > 0);
while (button->getChildCount ()) ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
MyGUI::Gui::getInstance ().destroyWidget (button->getChildAt(0)); while (button->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
button->setUserData(Type_Item); mAssigned[mSelectedIndex] = Type_Item;
MyGUI::ImageBox* frame = button->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(9, 8, 42, 42), MyGUI::Align::Default); button->setItem(item, ItemWidget::Barter);
std::string backgroundTex = "textures\\menu_icon_barter.dds"; button->setUserString ("ToolTipType", "ItemPtr");
frame->setImageTexture (backgroundTex); button->setUserData(item);
frame->setImageCoord (MyGUI::IntCoord(4, 4, 40, 40));
frame->setUserString ("ToolTipType", "ItemPtr");
frame->setUserData(item);
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setNeedMouseFocus (false);
if (mItemSelectionDialog) if (mItemSelectionDialog)
mItemSelectionDialog->setVisible(false); mItemSelectionDialog->setVisible(false);
@ -189,28 +184,18 @@ namespace MWGui
void QuickKeysMenu::onAssignMagicItem (MWWorld::Ptr item) void QuickKeysMenu::onAssignMagicItem (MWWorld::Ptr item)
{ {
MyGUI::Button* button = mQuickKeyButtons[mSelectedIndex]; assert (mSelectedIndex > 0);
while (button->getChildCount ()) ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
MyGUI::Gui::getInstance ().destroyWidget (button->getChildAt(0)); while (button->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
button->setUserData(Type_MagicItem); mAssigned[mSelectedIndex] = Type_MagicItem;
MyGUI::ImageBox* frame = button->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(9, 8, 42, 42), MyGUI::Align::Default); button->setFrame("textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
std::string backgroundTex = "textures\\menu_icon_select_magic_magic.dds"; button->setIcon(item);
frame->setImageTexture (backgroundTex);
frame->setImageCoord (MyGUI::IntCoord(2, 2, 40, 40));
frame->setUserString ("ToolTipType", "ItemPtr");
frame->setUserData(item);
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); button->setUserString ("ToolTipType", "ItemPtr");
std::string path = std::string("icons\\"); button->setUserData(item);
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setNeedMouseFocus (false);
if (mMagicSelectionDialog) if (mMagicSelectionDialog)
mMagicSelectionDialog->setVisible(false); mMagicSelectionDialog->setVisible(false);
@ -218,21 +203,16 @@ namespace MWGui
void QuickKeysMenu::onAssignMagic (const std::string& spellId) void QuickKeysMenu::onAssignMagic (const std::string& spellId)
{ {
MyGUI::Button* button = mQuickKeyButtons[mSelectedIndex]; assert (mSelectedIndex > 0);
while (button->getChildCount ()) ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
MyGUI::Gui::getInstance ().destroyWidget (button->getChildAt(0)); while (button->getChildCount()) // Destroy number label
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
button->setUserData(Type_Magic); mAssigned[mSelectedIndex] = Type_Magic;
MyGUI::ImageBox* frame = button->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(9, 8, 42, 42), MyGUI::Align::Default); button->setItem(MWWorld::Ptr());
std::string backgroundTex = "textures\\menu_icon_select_magic.dds"; button->setUserString ("ToolTipType", "Spell");
frame->setImageTexture (backgroundTex); button->setUserString ("Spell", spellId);
frame->setImageCoord (MyGUI::IntCoord(2, 2, 40, 40));
frame->setUserString ("ToolTipType", "Spell");
frame->setUserString ("Spell", spellId);
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
const MWWorld::ESMStore &esmStore = const MWWorld::ESMStore &esmStore =
MWBase::Environment::get().getWorld()->getStore(); MWBase::Environment::get().getWorld()->getStore();
@ -251,8 +231,8 @@ namespace MWGui
path.erase(pos); path.erase(pos);
path.append(".dds"); path.append(".dds");
image->setImageTexture (path); button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
image->setNeedMouseFocus (false); button->setIcon(path);
if (mMagicSelectionDialog) if (mMagicSelectionDialog)
mMagicSelectionDialog->setVisible(false); mMagicSelectionDialog->setVisible(false);
@ -265,16 +245,17 @@ namespace MWGui
void QuickKeysMenu::activateQuickKey(int index) void QuickKeysMenu::activateQuickKey(int index)
{ {
MyGUI::Button* button = mQuickKeyButtons[index-1]; assert (index-1 > 0);
ItemWidget* button = mQuickKeyButtons[index-1];
QuickKeyType type = *button->getUserData<QuickKeyType>(); QuickKeyType type = mAssigned[index-1];
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player); MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
if (type == Type_Item || type == Type_MagicItem) if (type == Type_Item || type == Type_MagicItem)
{ {
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
// make sure the item is available // make sure the item is available
if (item.getRefData ().getCount() < 1) if (item.getRefData ().getCount() < 1)
{ {
@ -286,7 +267,7 @@ namespace MWGui
if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id)) if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
{ {
item = *it; item = *it;
button->getChildAt(0)->setUserData(item); button->setUserData(item);
break; break;
} }
} }
@ -303,7 +284,7 @@ namespace MWGui
if (type == Type_Magic) if (type == Type_Magic)
{ {
std::string spellId = button->getChildAt(0)->getUserString("Spell"); std::string spellId = button->getUserString("Spell");
// Make sure the player still has this spell // Make sure the player still has this spell
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
@ -315,13 +296,13 @@ namespace MWGui
} }
else if (type == Type_Item) else if (type == Type_Item)
{ {
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(item); MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(item);
} }
else if (type == Type_MagicItem) else if (type == Type_MagicItem)
{ {
MWWorld::Ptr item = *button->getChildAt (0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
// retrieve ContainerStoreIterator to the item // retrieve ContainerStoreIterator to the item
MWWorld::ContainerStoreIterator it = store.begin(); MWWorld::ContainerStoreIterator it = store.begin();
@ -403,9 +384,9 @@ namespace MWGui
for (int i=0; i<10; ++i) for (int i=0; i<10; ++i)
{ {
MyGUI::Button* button = mQuickKeyButtons[i]; ItemWidget* button = mQuickKeyButtons[i];
int type = *button->getUserData<QuickKeyType>(); int type = mAssigned[i];
ESM::QuickKeys::QuickKey key; ESM::QuickKeys::QuickKey key;
key.mType = type; key.mType = type;
@ -417,12 +398,12 @@ namespace MWGui
case Type_Item: case Type_Item:
case Type_MagicItem: case Type_MagicItem:
{ {
MWWorld::Ptr item = *button->getChildAt(0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
key.mId = item.getCellRef().getRefId(); key.mId = item.getCellRef().getRefId();
break; break;
} }
case Type_Magic: case Type_Magic:
std::string spellId = button->getChildAt(0)->getUserString("Spell"); std::string spellId = button->getUserString("Spell");
key.mId = spellId; key.mId = spellId;
break; break;
} }
@ -452,7 +433,7 @@ namespace MWGui
mSelectedIndex = i; mSelectedIndex = i;
int keyType = it->mType; int keyType = it->mType;
std::string id = it->mId; std::string id = it->mId;
MyGUI::Button* button = mQuickKeyButtons[i]; ItemWidget* button = mQuickKeyButtons[i];
switch (keyType) switch (keyType)
{ {

View file

@ -11,6 +11,7 @@ namespace MWGui
class QuickKeysMenuAssign; class QuickKeysMenuAssign;
class ItemSelectionDialog; class ItemSelectionDialog;
class MagicSelectionDialog; class MagicSelectionDialog;
class ItemWidget;
class QuickKeysMenu : public WindowBase class QuickKeysMenu : public WindowBase
{ {
@ -51,7 +52,8 @@ namespace MWGui
MyGUI::EditBox* mInstructionLabel; MyGUI::EditBox* mInstructionLabel;
MyGUI::Button* mOkButton; MyGUI::Button* mOkButton;
std::vector<MyGUI::Button*> mQuickKeyButtons; std::vector<ItemWidget*> mQuickKeyButtons;
std::vector<QuickKeyType> mAssigned;
QuickKeysMenuAssign* mAssignDialog; QuickKeysMenuAssign* mAssignDialog;
ItemSelectionDialog* mItemSelectionDialog; ItemSelectionDialog* mItemSelectionDialog;
@ -63,7 +65,7 @@ namespace MWGui
void onQuickKeyButtonClicked(MyGUI::Widget* sender); void onQuickKeyButtonClicked(MyGUI::Widget* sender);
void onOkButtonClicked(MyGUI::Widget* sender); void onOkButtonClicked(MyGUI::Widget* sender);
void unassign(MyGUI::Widget* key, int index); void unassign(ItemWidget* key, int index);
}; };
class QuickKeysMenuAssign : public WindowModal class QuickKeysMenuAssign : public WindowModal

View file

@ -14,6 +14,7 @@
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -45,12 +46,7 @@ void Recharge::exit()
void Recharge::start (const MWWorld::Ptr &item) void Recharge::start (const MWWorld::Ptr &item)
{ {
std::string path = std::string("icons\\"); mGemIcon->setItem(item);
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
mGemIcon->setImageTexture (path);
mGemIcon->setUserString("ToolTipType", "ItemPtr"); mGemIcon->setUserString("ToolTipType", "ItemPtr");
mGemIcon->setUserData(item); mGemIcon->setUserData(item);
@ -108,14 +104,9 @@ void Recharge::updateView()
text->setNeedMouseFocus(false); text->setNeedMouseFocus(false);
currentY += 19; currentY += 19;
MyGUI::ImageBox* icon = mView->createWidget<MyGUI::ImageBox> ( ItemWidget* icon = mView->createWidget<ItemWidget> (
"ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default); "MW_ItemIconSmall", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\"); icon->setItem(*iter);
path += iter->getClass().getInventoryIcon(*iter);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
icon->setImageTexture (path);
icon->setUserString("ToolTipType", "ItemPtr"); icon->setUserString("ToolTipType", "ItemPtr");
icon->setUserData(*iter); icon->setUserData(*iter);
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onItemClicked); icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onItemClicked);

View file

@ -8,6 +8,8 @@
namespace MWGui namespace MWGui
{ {
class ItemWidget;
class Recharge : public WindowBase class Recharge : public WindowBase
{ {
public: public:
@ -25,7 +27,7 @@ protected:
MyGUI::Widget* mGemBox; MyGUI::Widget* mGemBox;
MyGUI::ImageBox* mGemIcon; ItemWidget* mGemIcon;
MyGUI::TextBox* mChargeLabel; MyGUI::TextBox* mChargeLabel;

View file

@ -13,6 +13,8 @@
#include "widgets.hpp" #include "widgets.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -44,12 +46,7 @@ void Repair::startRepairItem(const MWWorld::Ptr &item)
{ {
mRepair.setTool(item); mRepair.setTool(item);
std::string path = std::string("icons\\"); mToolIcon->setItem(item);
path += item.getClass().getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
mToolIcon->setImageTexture (path);
mToolIcon->setUserString("ToolTipType", "ItemPtr"); mToolIcon->setUserString("ToolTipType", "ItemPtr");
mToolIcon->setUserData(item); mToolIcon->setUserData(item);
@ -113,14 +110,9 @@ void Repair::updateRepairView()
text->setNeedMouseFocus(false); text->setNeedMouseFocus(false);
currentY += 19; currentY += 19;
MyGUI::ImageBox* icon = mRepairView->createWidget<MyGUI::ImageBox> ( ItemWidget* icon = mRepairView->createWidget<ItemWidget> (
"ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default); "MW_ItemIconSmall", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\"); icon->setItem(*iter);
path += iter->getClass().getInventoryIcon(*iter);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
icon->setImageTexture (path);
icon->setUserString("ToolTipType", "ItemPtr"); icon->setUserString("ToolTipType", "ItemPtr");
icon->setUserData(*iter); icon->setUserData(*iter);
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onRepairItem); icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onRepairItem);

View file

@ -8,6 +8,8 @@
namespace MWGui namespace MWGui
{ {
class ItemWidget;
class Repair : public WindowBase class Repair : public WindowBase
{ {
public: public:
@ -25,7 +27,7 @@ protected:
MyGUI::Widget* mToolBox; MyGUI::Widget* mToolBox;
MyGUI::ImageBox* mToolIcon; ItemWidget* mToolIcon;
MyGUI::TextBox* mUsesLabel; MyGUI::TextBox* mUsesLabel;
MyGUI::TextBox* mQualityLabel; MyGUI::TextBox* mQualityLabel;

View file

@ -400,7 +400,7 @@ namespace MWGui
if (!info.effects.empty()) if (!info.effects.empty())
{ {
MyGUI::Widget* effectArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("", MyGUI::Widget* effectArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
MyGUI::IntCoord(0, totalSize.height, 300, 300-totalSize.height), MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height),
MyGUI::Align::Stretch, "ToolTipEffectArea"); MyGUI::Align::Stretch, "ToolTipEffectArea");
MyGUI::IntCoord coord(0, 6, totalSize.width, 24); MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
@ -419,7 +419,7 @@ namespace MWGui
{ {
assert(enchant); assert(enchant);
MyGUI::Widget* enchantArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("", MyGUI::Widget* enchantArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
MyGUI::IntCoord(0, totalSize.height, 300, 300-totalSize.height), MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height),
MyGUI::Align::Stretch, "ToolTipEnchantArea"); MyGUI::Align::Stretch, "ToolTipEnchantArea");
MyGUI::IntCoord coord(0, 6, totalSize.width, 24); MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
@ -512,7 +512,11 @@ namespace MWGui
std::string ToolTips::toString(const float value) std::string ToolTips::toString(const float value)
{ {
std::ostringstream stream; std::ostringstream stream;
stream << std::setprecision(3) << value;
if (value != int(value))
stream << std::setprecision(3);
stream << value;
return stream.str(); return stream.str();
} }

View file

@ -345,7 +345,7 @@ namespace MWGui
x += abs(int(npcTerm - pcTerm)); x += abs(int(npcTerm - pcTerm));
int roll = std::rand()%100 + 1; int roll = std::rand()%100 + 1;
if(roll > x) //trade refused if(roll > x || (mCurrentMerchantOffer < 0) != (mCurrentBalance < 0)) //trade refused
{ {
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}"); messageBox("#{sNotifyMessage9}");

View file

@ -42,4 +42,9 @@ bool VideoWidget::update()
return mPlayer.isPlaying(); return mPlayer.isPlaying();
} }
void VideoWidget::cleanup()
{
mPlayer.close();
}
} }

View file

@ -26,6 +26,9 @@ namespace MWGui
/// @return Is the video still playing? /// @return Is the video still playing?
bool update(); bool update();
/// Free video player resources (done automatically on destruction)
void cleanup();
private: private:
bool mAllowSkipping; bool mAllowSkipping;

View file

@ -64,6 +64,7 @@
#include "fontloader.hpp" #include "fontloader.hpp"
#include "videowidget.hpp" #include "videowidget.hpp"
#include "backgroundimage.hpp" #include "backgroundimage.hpp"
#include "itemwidget.hpp"
namespace MWGui namespace MWGui
{ {
@ -166,6 +167,7 @@ namespace MWGui
MyGUI::FactoryManager::getInstance().registerFactory<BackgroundImage>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<BackgroundImage>("Widget");
BookPage::registerMyGUIComponents (); BookPage::registerMyGUIComponents ();
ItemView::registerComponents(); ItemView::registerComponents();
ItemWidget::registerComponents();
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatClick>("Controller"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatClick>("Controller");
@ -1579,12 +1581,13 @@ namespace MWGui
bool cursorWasVisible = mCursorVisible; bool cursorWasVisible = mCursorVisible;
setCursorVisible(false); setCursorVisible(false);
while (mVideoWidget->update()) while (mVideoWidget->update() && !MWBase::Environment::get().getStateManager()->hasQuitRequest())
{ {
MWBase::Environment::get().getInputManager()->update(0, true, false); MWBase::Environment::get().getInputManager()->update(0, true, false);
mRendering->getWindow()->update(); mRendering->getWindow()->update();
} }
mVideoWidget->cleanup();
setCursorVisible(cursorWasVisible); setCursorVisible(cursorWasVisible);

View file

@ -932,7 +932,7 @@ namespace MWMechanics
for (std::list<MWWorld::Ptr>::iterator it = listGuards.begin(); it != listGuards.end(); ++it) for (std::list<MWWorld::Ptr>::iterator it = listGuards.begin(); it != listGuards.end(); ++it)
{ {
engageCombat(iter->first, *it, false); engageCombat(iter->first, *it, *it == player);
} }
} }

View file

@ -395,7 +395,8 @@ int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient)
return -1; return -1;
for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter)
if (!iter->isEmpty() && ingredient.get<ESM::Ingredient>()==iter->get<ESM::Ingredient>()) if (!iter->isEmpty() && Misc::StringUtils::ciEqual(ingredient.getClass().getId(ingredient),
iter->getClass().getId(*iter)))
return -1; return -1;
mIngredients[slot] = ingredient; mIngredients[slot] = ingredient;

View file

@ -409,6 +409,13 @@ MWWorld::ContainerStoreIterator getActiveWeapon(CreatureStats &stats, MWWorld::I
void CharacterController::playDeath(float startpoint, CharacterState death) void CharacterController::playDeath(float startpoint, CharacterState death)
{ {
if (mPtr == MWBase::Environment::get().getWorld()->getPlayerPtr())
{
// The first-person animations do not include death, so we need to
// force-switch to third person before playing the death animation.
MWBase::Environment::get().getWorld()->useDeathCamera();
}
switch (death) switch (death)
{ {
case CharState_SwimDeath: case CharState_SwimDeath:

View file

@ -73,9 +73,16 @@ namespace MWMechanics
return false; return false;
MWMechanics::CreatureStats& blockerStats = blocker.getClass().getCreatureStats(blocker); MWMechanics::CreatureStats& blockerStats = blocker.getClass().getCreatureStats(blocker);
// Don't block when in spellcasting state (shield is equipped, but not visible)
if (blockerStats.getDrawState() == DrawState_Spell) if (blockerStats.getDrawState() == DrawState_Spell)
return false; return false;
// Don't block when in hand-to-hand combat (shield is equipped, but not visible)
if (blockerStats.getDrawState() == DrawState_Weapon &&
inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight) == inv.end())
return false;
MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker); MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);
float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2 * blockerStats.getAttribute(ESM::Attribute::Agility).getModified() float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2 * blockerStats.getAttribute(ESM::Attribute::Agility).getModified()

View file

@ -140,11 +140,11 @@ namespace MWRender
} }
} }
void Camera::toggleViewMode() void Camera::toggleViewMode(bool force)
{ {
// Changing the view will stop all playing animations, so if we are playing // Changing the view will stop all playing animations, so if we are playing
// anything important, queue the view change for later // anything important, queue the view change for later
if (!mAnimation->allowSwitchViewMode()) if (!mAnimation->allowSwitchViewMode() && !force)
{ {
mViewModeToggleQueued = true; mViewModeToggleQueued = true;
return; return;

View file

@ -75,7 +75,8 @@ namespace MWRender
/// Attach camera to object /// Attach camera to object
void attachTo(const MWWorld::Ptr &); void attachTo(const MWWorld::Ptr &);
void toggleViewMode(); /// @param Force view mode switch, even if currently not allowed by the animation.
void toggleViewMode(bool force=false);
bool toggleVanityMode(bool enable); bool toggleVanityMode(bool enable);
void allowVanityMode(bool allow); void allowVanityMode(bool allow);

View file

@ -308,7 +308,7 @@ void NpcAnimation::updateParts()
ESM::PartReferenceType parts[] = { ESM::PartReferenceType parts[] = {
ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg, ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg,
ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee, ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee,
ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron ESM::PRT_RForearm, ESM::PRT_LForearm
}; };
size_t parts_size = sizeof(parts)/sizeof(parts[0]); size_t parts_size = sizeof(parts)/sizeof(parts[0]);
for(size_t p = 0;p < parts_size;++p) for(size_t p = 0;p < parts_size;++p)
@ -351,8 +351,6 @@ void NpcAnimation::updateParts()
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination // 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; static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping;
static std::map <std::pair<std::string,int>, std::vector<const ESM::BodyPart*> > sVampireMapping;
static const int Flag_Female = 1<<0; static const int Flag_Female = 1<<0;
static const int Flag_FirstPerson = 1<<1; static const int Flag_FirstPerson = 1<<1;
@ -408,8 +406,6 @@ void NpcAnimation::updateParts()
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin) if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
continue; continue;
if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
continue;
if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace)) if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace))
continue; continue;
@ -435,6 +431,20 @@ void NpcAnimation::updateParts()
} }
continue; continue;
} }
if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
{
// Allow opposite gender's parts as fallback if parts for our gender are missing
BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart));
while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart)
{
if(!parts[bIt->second])
parts[bIt->second] = &*it;
++bIt;
}
continue;
}
BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart)); BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart));
while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart) while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart)
{ {

View file

@ -144,7 +144,6 @@ void MWState::StateManager::newGame (bool bypass)
void MWState::StateManager::endGame() void MWState::StateManager::endGame()
{ {
mState = State_Ended; mState = State_Ended;
MWBase::Environment::get().getWorld()->useDeathCamera();
} }
void MWState::StateManager::saveGame (const std::string& description, const Slot *slot) void MWState::StateManager::saveGame (const std::string& description, const Slot *slot)

View file

@ -41,6 +41,8 @@ namespace MWWorld
// slots that this item can be equipped in // slots that this item can be equipped in
std::pair<std::vector<int>, bool> slots_ = getTarget().getClass().getEquipmentSlots(getTarget()); std::pair<std::vector<int>, bool> slots_ = getTarget().getClass().getEquipmentSlots(getTarget());
if (slots_.first.empty())
return;
// retrieve ContainerStoreIterator to the item // retrieve ContainerStoreIterator to the item
MWWorld::ContainerStoreIterator it = invStore.begin(); MWWorld::ContainerStoreIterator it = invStore.begin();
@ -55,20 +57,13 @@ namespace MWWorld
assert(it != invStore.end()); assert(it != invStore.end());
// equip the item in the first free slot // equip the item in the first free slot
for (std::vector<int>::const_iterator slot=slots_.first.begin(); std::vector<int>::const_iterator slot=slots_.first.begin();
slot!=slots_.first.end(); ++slot) for (;slot!=slots_.first.end(); ++slot)
{ {
// if the item is equipped already, nothing to do // if the item is equipped already, nothing to do
if (invStore.getSlot(*slot) == it) if (invStore.getSlot(*slot) == it)
return; return;
// if all slots are occupied, replace the last slot
if (slot == --slots_.first.end())
{
invStore.equip(*slot, it, actor);
break;
}
if (invStore.getSlot(*slot) == invStore.end()) if (invStore.getSlot(*slot) == invStore.end())
{ {
// slot is not occupied // slot is not occupied
@ -76,5 +71,19 @@ namespace MWWorld
break; break;
} }
} }
// all slots are occupied -> cycle
// move all slots one towards begin(), then equip the item in the slot that is now free
if (slot == slots_.first.end())
{
for (slot=slots_.first.begin();slot!=slots_.first.end(); ++slot)
{
invStore.unequipSlot(*slot, actor);
if (slot+1 != slots_.first.end())
invStore.equip(*slot, invStore.getSlot(*(slot+1)), actor);
else
invStore.equip(*slot, it, actor);
}
}
} }
} }

View file

@ -492,7 +492,7 @@ namespace MWWorld
return std::make_pair(true, ray.getPoint(len * test.second)); return std::make_pair(true, ray.getPoint(len * test.second));
} }
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal) std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal, std::string* hit)
{ {
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay( Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
mouseX, mouseX,
@ -510,6 +510,8 @@ namespace MWWorld
return std::make_pair(false, Ogre::Vector3()); return std::make_pair(false, Ogre::Vector3());
else else
{ {
if (hit != NULL)
*hit = result.first;
return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable
} }
} }

View file

@ -70,9 +70,10 @@ namespace MWWorld
std::pair<bool, Ogre::Vector3> std::pair<bool, Ogre::Vector3>
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len); castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL); std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL, std::string* hit = NULL);
///< cast ray from the mouse, return true if it hit something and the first result ///< cast ray from the mouse, return true if it hit something and the first result
/// @param normal if non-NULL, the hit normal will be written there (if there is a hit) /// @param normal if non-NULL, the hit normal will be written there (if there is a hit)
/// @param hit if non-NULL, the string handle of the hit object will be written there (if there is a hit)
OEngine::Physic::PhysicEngine* getEngine(); OEngine::Physic::PhysicEngine* getEngine();

View file

@ -432,7 +432,7 @@ namespace MWWorld
mRendering->getCamera()->toggleVanityMode(false); mRendering->getCamera()->toggleVanityMode(false);
} }
if(mRendering->getCamera()->isFirstPerson()) if(mRendering->getCamera()->isFirstPerson())
togglePOV(); mRendering->getCamera()->toggleViewMode(true);
} }
MWWorld::Player& World::getPlayer() MWWorld::Player& World::getPlayer()
@ -1624,12 +1624,20 @@ namespace MWWorld
bool World::canPlaceObject(float cursorX, float cursorY) bool World::canPlaceObject(float cursorX, float cursorY)
{ {
Ogre::Vector3 normal(0,0,0); Ogre::Vector3 normal(0,0,0);
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal); std::string handle;
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal, &handle);
if (result.first) if (result.first)
{ {
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall // check if the wanted position is on a flat surface, and not e.g. against a vertical wall
return (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() < 30); if (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() >= 30)
return false;
MWWorld::Ptr hitObject = searchPtrViaHandle(handle);
if (!hitObject.isEmpty() && hitObject.getClass().isActor())
return false;
return true;
} }
else else
return false; return false;
@ -1851,7 +1859,12 @@ namespace MWWorld
if (!mPlayer) if (!mPlayer)
mPlayer = new MWWorld::Player(player, *this); mPlayer = new MWWorld::Player(player, *this);
else else
{
// Remove the old CharacterController
MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr());
mPlayer->set(player); mPlayer->set(player);
}
Ptr ptr = mPlayer->getPlayer(); Ptr ptr = mPlayer->getPlayer();
mRendering->setupPlayer(ptr); mRendering->setupPlayer(ptr);

View file

@ -23,21 +23,13 @@
<Widget type="Widget" skin="" position="10 66 260 50"> <Widget type="Widget" skin="" position="10 66 260 50">
<Widget type="Widget" skin="MW_Box" position="0 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="0 0 50 50" name="Apparatus1"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Apparatus1"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="60 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="60 0 50 50" name="Apparatus2"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Apparatus2"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="120 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="120 0 50 50" name="Apparatus3"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Apparatus3"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="180 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="180 0 50 50" name="Apparatus4"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Apparatus4"/>
</Widget>
</Widget> </Widget>
@ -51,21 +43,13 @@
<Widget type="Widget" skin="" position="10 146 260 50"> <Widget type="Widget" skin="" position="10 146 260 50">
<Widget type="Widget" skin="MW_Box" position="0 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="0 0 50 50" name="Ingredient1"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Ingredient1"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="60 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="60 0 50 50" name="Ingredient2"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Ingredient2"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="120 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="120 0 50 50" name="Ingredient3"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Ingredient3"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="180 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="180 0 50 50" name="Ingredient4"/>
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="Ingredient4"/>
</Widget>
</Widget> </Widget>
@ -106,4 +90,4 @@
</Widget> </Widget>
</Widget> </Widget>
</MyGUI> </MyGUI>

View file

@ -73,4 +73,9 @@ as around the sections of the stats window, or around popup info windows -->
<Child type="Widget" skin="IB_BL" offset="0 514 2 2" align="Bottom Left"/> <Child type="Widget" skin="IB_BL" offset="0 514 2 2" align="Bottom Left"/>
<Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="Bottom Right"/> <Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="Bottom Right"/>
</Skin> </Skin>
<Skin name="MW_Box_Overlay" size="516 516">
<Property key="NeedMouse" value="false"/>
<Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="Stretch"/>
</Skin>
</MyGUI> </MyGUI>

View file

@ -26,8 +26,7 @@
<Widget type="AutoSizedTextBox" skin="NormalText"> <Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sItem}"/> <Property key="Caption" value="#{sItem}"/>
</Widget> </Widget>
<Widget type="Widget" skin="MW_Box" position="0 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="0 0 50 50" name="ItemBox">
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="ItemBox"/>
</Widget> </Widget>
<Widget type="Widget" position="0 0 8 0"/> <Widget type="Widget" position="0 0 8 0"/>
@ -35,8 +34,7 @@
<Widget type="AutoSizedTextBox" skin="NormalText"> <Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sSoulGem}"/> <Property key="Caption" value="#{sSoulGem}"/>
</Widget> </Widget>
<Widget type="Button" skin="MW_Box" position="0 0 50 50"> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="0 0 50 50" name="SoulBox">
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="SoulBox"/>
</Widget> </Widget>
</Widget> </Widget>

View file

@ -59,7 +59,7 @@
<Widget type="Button" skin="" position="82 146 36 41" align="Left Bottom" name="WeapBox"> <Widget type="Button" skin="" position="82 146 36 41" align="Left Bottom" name="WeapBox">
<Widget type="Widget" skin="HUD_Box" position="0 0 36 36"> <Widget type="Widget" skin="HUD_Box" position="0 0 36 36">
<Property key="NeedMouse" value="false"/> <Property key="NeedMouse" value="false"/>
<Widget type="ImageBox" skin="ImageBox" position="2 2 32 32" align="Left Top" name="WeapImage"> <Widget type="ItemWidget" skin="MW_ItemIcon" position="-3 -3 42 42" align="Left Top" name="WeapImage">
<Property key="NeedMouse" value="false"/> <Property key="NeedMouse" value="false"/>
</Widget> </Widget>
</Widget> </Widget>
@ -71,7 +71,7 @@
<!-- Selected spell box --> <!-- Selected spell box -->
<Widget type="Button" position="122 146 36 41" align="Left Bottom" name="SpellBox"> <Widget type="Button" position="122 146 36 41" align="Left Bottom" name="SpellBox">
<Widget type="Widget" skin="HUD_Box" position="0 0 36 36"> <Widget type="Widget" skin="HUD_Box" position="0 0 36 36">
<Widget type="ImageBox" skin="ImageBox" position="2 2 32 32" align="Left Top" name="SpellImage"/> <Widget type="ItemWidget" skin="MW_ItemIcon" position="-3 -3 42 42" align="Left Top" name="SpellImage"/>
<Property key="NeedMouse" value="false"/> <Property key="NeedMouse" value="false"/>
</Widget> </Widget>
<Widget type="ProgressBar" skin="MW_EnergyBar_Red" position="0 36 36 6" align="Left Bottom" name="SpellStatus"> <Widget type="ProgressBar" skin="MW_EnergyBar_Red" position="0 36 36 6" align="Left Bottom" name="SpellStatus">

View file

@ -17,16 +17,16 @@
<Widget type="Widget" skin="" position="15 55 332 128" align="Left Bottom HCenter"> <Widget type="Widget" skin="" position="15 55 332 128" align="Left Bottom HCenter">
<Widget type="Button" skin="MW_Box" position="0 0 60 59" name="QuickKey1"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="0 0 60 59" name="QuickKey1"/>
<Widget type="Button" skin="MW_Box" position="68 0 60 59" name="QuickKey2"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="68 0 60 59" name="QuickKey2"/>
<Widget type="Button" skin="MW_Box" position="136 0 60 59" name="QuickKey3"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="136 0 60 59" name="QuickKey3"/>
<Widget type="Button" skin="MW_Box" position="204 0 60 59" name="QuickKey4"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="204 0 60 59" name="QuickKey4"/>
<Widget type="Button" skin="MW_Box" position="272 0 60 59" name="QuickKey5"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="272 0 60 59" name="QuickKey5"/>
<Widget type="Button" skin="MW_Box" position="0 67 60 59" name="QuickKey6"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="0 67 60 59" name="QuickKey6"/>
<Widget type="Button" skin="MW_Box" position="68 67 60 59" name="QuickKey7"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="68 67 60 59" name="QuickKey7"/>
<Widget type="Button" skin="MW_Box" position="136 67 60 59" name="QuickKey8"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="136 67 60 59" name="QuickKey8"/>
<Widget type="Button" skin="MW_Box" position="204 67 60 59" name="QuickKey9"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="204 67 60 59" name="QuickKey9"/>
<Widget type="Button" skin="MW_Box" position="272 67 60 59" name="QuickKey10"/> <Widget type="ItemWidget" skin="MW_ItemIconBox" position="272 67 60 59" name="QuickKey10"/>
</Widget> </Widget>

View file

@ -4,7 +4,7 @@
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 329 253" name="_Main"> <Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 329 253" name="_Main">
<Widget type="Widget" skin="" position="4 4 321 42" name="GemBox"> <Widget type="Widget" skin="" position="4 4 321 42" name="GemBox">
<Widget type="ImageBox" skin="ImageBox" position="5 6 32 32" name="GemIcon"/> <Widget type="ItemWidget" skin="MW_ItemIconSmall" position="5 6 32 32" name="GemIcon"/>
<Widget type="TextBox" skin="SandText" position="55 13 250 18" name="ChargeLabel"> <Widget type="TextBox" skin="SandText" position="55 13 250 18" name="ChargeLabel">
<Property key="Caption" value="#{sQuality}"/> <Property key="Caption" value="#{sQuality}"/>

View file

@ -4,7 +4,7 @@
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 329 253" name="_Main"> <Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 329 253" name="_Main">
<Widget type="Widget" skin="" position="4 4 321 42" name="ToolBox"> <Widget type="Widget" skin="" position="4 4 321 42" name="ToolBox">
<Widget type="ImageBox" skin="ImageBox" position="5 6 32 32" name="ToolIcon"/> <Widget type="ItemWidget" skin="MW_ItemIconSmall" position="5 6 32 32" name="ToolIcon"/>
<Widget type="AutoSizedTextBox" skin="SandText" position="55 13 300 18" name="UsesLabel"> <Widget type="AutoSizedTextBox" skin="SandText" position="55 13 300 18" name="UsesLabel">
<Property key="Caption" value="#{sUses}"/> <Property key="Caption" value="#{sUses}"/>

View file

@ -319,4 +319,30 @@
</Widget> </Widget>
</Resource> </Resource>
<Resource type="ResourceLayout" name="MW_ItemIcon" version="3.2.0">
<Widget type="Widget" skin="" position="0 0 42 42" name="Root">
<Widget type="ImageBox" skin="ImageBox" position="0 0 42 42" align="Stretch" name="Frame">
<Widget type="ImageBox" skin="ImageBox" position="5 5 32 32" align="Stretch" name="Item"/>
</Widget>
</Widget>
</Resource>
<Resource type="ResourceLayout" name="MW_ItemIconSmall" version="3.2.0">
<Widget type="Widget" skin="" position="0 0 32 32" name="Root">
<Widget type="ImageBox" skin="ImageBox" position="0 0 32 32" align="Stretch" name="Frame">
<Widget type="ImageBox" skin="ImageBox" position="0 0 32 32" align="Stretch" name="Item"/>
</Widget>
</Widget>
</Resource>
<Resource type="ResourceLayout" name="MW_ItemIconBox" version="3.2.0">
<Widget type="Widget" skin="" position="0 0 50 50" name="Root">
<Widget type="ImageBox" skin="ImageBox" position="4 4 42 42" align="Center" name="Frame">
<Widget type="ImageBox" skin="ImageBox" position="5 5 32 32" align="Center" name="Item"/>
</Widget>
<Widget type="Widget" skin="MW_Box_Overlay" position="0 0 50 50" align="Stretch"/>
</Widget>
</Resource>
</MyGUI> </MyGUI>