Merge remote branch 'scrawl/inventoryGUI'

Conflicts:
	apps/openmw/CMakeLists.txt
actorid
Marc Zinnschlag 13 years ago
commit 3e85151c9d

@ -23,10 +23,10 @@ add_openmw_dir (mwinput
)
add_openmw_dir (mwgui
layouts text_input widgets race class birth review window_manager console dialogue
text_input widgets race class birth review window_manager console dialogue
dialogue_history window_base stats_window messagebox journalwindow charactercreation
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
formatting
formatting itemwidget inventorywindow container hud countdialog tradewindow
)
add_openmw_dir (mwdialogue
@ -47,8 +47,8 @@ add_openmw_dir (mwsound
add_openmw_dir (mwworld
refdata world physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors
cells localscripts customdata weather inventorystore ptr actionread
timestamp
cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp
)
add_openmw_dir (mwclass

@ -79,7 +79,7 @@ namespace MWClass
ptr.get<ESM::Activator>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp())

@ -100,6 +100,14 @@ namespace MWClass
return std::string("Item Apparatus Down");
}
std::string Apparatus::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->icon;
}
bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
@ -114,7 +122,7 @@ namespace MWClass
ptr.get<ESM::Apparatus>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();

@ -41,6 +41,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -9,6 +9,7 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/world.hpp"
@ -198,6 +199,14 @@ namespace MWClass
return std::string("Item Armor Heavy Down");
}
std::string Armor::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
ptr.get<ESM::Armor>();
return ref->base->icon;
}
bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
@ -212,7 +221,7 @@ namespace MWClass
ptr.get<ESM::Armor>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
std::string text;
@ -256,4 +265,11 @@ namespace MWClass
return ref->base->enchant;
}
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
{
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
}
}

@ -56,8 +56,16 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const;
///< Generate action for using via inventory menu
};
}

@ -97,6 +97,14 @@ namespace MWClass
return std::string("Item Book Down");
}
std::string Book::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
ptr.get<ESM::Book>();
return ref->base->icon;
}
bool Book::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
@ -111,7 +119,7 @@ namespace MWClass
ptr.get<ESM::Book>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
@ -132,4 +140,18 @@ namespace MWClass
return info;
}
std::string Book::getEnchantment (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
ptr.get<ESM::Book>();
return ref->base->enchant;
}
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
{
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
}
}

@ -41,6 +41,15 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
///< Generate action for using via inventory menu
};
}

@ -9,6 +9,7 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/world.hpp"
@ -166,6 +167,14 @@ namespace MWClass
return std::string("Item Clothes Down");
}
std::string Clothing::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
ptr.get<ESM::Clothing>();
return ref->base->icon;
}
bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
@ -180,7 +189,7 @@ namespace MWClass
ptr.get<ESM::Clothing>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
@ -209,4 +218,11 @@ namespace MWClass
return ref->base->enchant;
}
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
{
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
}
}

@ -50,8 +50,15 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const;
///< Generate action for using via inventory menu
};
}

@ -17,6 +17,7 @@
#include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp"
#include "../mwworld/actionopen.hpp"
#include "../mwsound/soundmanager.hpp"
@ -86,6 +87,7 @@ namespace MWClass
const std::string lockedSound = "LockedChest";
const std::string trapActivationSound = "Disarm Trap Fail";
if (ptr.getCellRef().lockLevel>0)
{
// TODO check for key
@ -99,7 +101,8 @@ namespace MWClass
if(ptr.getCellRef().trap.empty())
{
// Not trapped, Inventory GUI goes here
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
//return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionOpen(ptr));
}
else
{
@ -177,7 +180,7 @@ namespace MWClass
return info;
}
float Container::getCapactiy (const MWWorld::Ptr& ptr) const
float Container::getCapacity (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
ptr.get<ESM::Container>();

@ -36,7 +36,7 @@ namespace MWClass
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual float getCapactiy (const MWWorld::Ptr& ptr) const;
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
///< Return total weight that fits into the object. Throws an exception, if the object can't
/// hold other objects.

@ -166,7 +166,7 @@ namespace MWClass
return info;
}
float Creature::getCapactiy (const MWWorld::Ptr& ptr) const
float Creature::getCapacity (const MWWorld::Ptr& ptr) const
{
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
return stats.mAttributes[0].getModified()*5;

@ -52,7 +52,7 @@ namespace MWClass
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
virtual float getCapactiy (const MWWorld::Ptr& ptr) const;
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
///< Return total weight that fits into the object. Throws an exception, if the object can't
/// hold other objects.

@ -98,6 +98,14 @@ namespace MWClass
return std::string("Item Ingredient Down");
}
std::string Ingredient::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->icon;
}
bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
@ -112,7 +120,7 @@ namespace MWClass
ptr.get<ESM::Ingredient>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();

@ -41,6 +41,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -140,6 +140,15 @@ namespace MWClass
return std::string("Item Misc Down");
}
std::string Light::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
return ref->base->icon;
}
bool Light::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
@ -154,7 +163,7 @@ namespace MWClass
ptr.get<ESM::Light>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();

@ -50,6 +50,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -110,6 +110,14 @@ namespace MWClass
return std::string("Item Lockpick Down");
}
std::string Lockpick::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
ptr.get<ESM::Tool>();
return ref->base->icon;
}
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
@ -124,7 +132,7 @@ namespace MWClass
ptr.get<ESM::Tool>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();

@ -45,6 +45,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -1,6 +1,8 @@
#include "misc.hpp"
#include <boost/lexical_cast.hpp>
#include <components/esm/loadmisc.hpp>
#include <components/esm_store/cell_store.hpp>
@ -116,6 +118,14 @@ namespace MWClass
return std::string("Item Misc Down");
}
std::string Miscellaneous::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->icon;
}
bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
@ -130,11 +140,24 @@ namespace MWClass
ptr.get<ESM::Miscellaneous>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
int count = ptr.getRefData().getCount();
bool isGold = (ref->base->name == store.gameSettings.search("sGold")->str);
if (isGold && count == 1)
count = ref->base->data.value;
std::string countString;
if (!isGold)
countString = MWGui::ToolTips::getCountString(count);
else // gold displays its count also if it's 1.
countString = " (" + boost::lexical_cast<std::string>(count) + ")";
info.caption = ref->base->name + countString;
info.icon = ref->base->icon;
if (ref->ref.soul != "")
{
const ESM::Creature *creature = store.creatures.search(ref->ref.soul);
@ -143,9 +166,7 @@ namespace MWClass
std::string text;
if (ref->base->name == store.gameSettings.search("sGold")->str)
info.caption += " (" + boost::lexical_cast<std::string>(ref->base->data.value) + ")";
else
if (!isGold)
{
text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight);
text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str);

@ -41,6 +41,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -3,6 +3,8 @@
#include <memory>
#include <boost/algorithm/string.hpp>
#include <OgreSceneNode.h>
#include <components/esm/loadnpc.hpp>
@ -56,13 +58,15 @@ namespace MWClass
// NPC stats
if (!ref->base->faction.empty())
{
std::string faction = ref->base->faction;
boost::algorithm::to_lower(faction);
if(ref->base->npdt52.gold != -10)
{
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank;
data->mNpcStats.mFactionRank[faction] = (int)ref->base->npdt52.rank;
}
else
{
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank;
data->mNpcStats.mFactionRank[faction] = (int)ref->base->npdt12.rank;
}
}
@ -324,7 +328,7 @@ namespace MWClass
return info;
}
float Npc::getCapactiy (const MWWorld::Ptr& ptr) const
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
{
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
return stats.mAttributes[0].getModified()*5;

@ -74,7 +74,7 @@ namespace MWClass
///< Return desired movement vector (determined based on movement settings,
/// stance and stats).
virtual float getCapactiy (const MWWorld::Ptr& ptr) const;
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
///< Return total weight that fits into the object. Throws an exception, if the object can't
/// hold other objects.

@ -100,6 +100,14 @@ namespace MWClass
return std::string("Item Potion Down");
}
std::string Potion::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
ptr.get<ESM::Potion>();
return ref->base->icon;
}
bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
@ -114,7 +122,7 @@ namespace MWClass
ptr.get<ESM::Potion>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();

@ -41,6 +41,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -109,6 +109,14 @@ namespace MWClass
return std::string("Item Probe Down");
}
std::string Probe::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
ptr.get<ESM::Probe>();
return ref->base->icon;
}
bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
@ -123,7 +131,7 @@ namespace MWClass
ptr.get<ESM::Probe>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();

@ -45,6 +45,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -99,6 +99,14 @@ namespace MWClass
return std::string("Item Repair Down");
}
std::string Repair::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
ptr.get<ESM::Repair>();
return ref->base->icon;
}
bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
@ -113,7 +121,7 @@ namespace MWClass
ptr.get<ESM::Repair>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
std::string text;

@ -41,6 +41,9 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
};
}

@ -9,6 +9,7 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/world.hpp"
@ -250,6 +251,14 @@ namespace MWClass
return std::string("Item Misc Down");
}
std::string Weapon::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
ptr.get<ESM::Weapon>();
return ref->base->icon;
}
bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
@ -264,7 +273,7 @@ namespace MWClass
ptr.get<ESM::Weapon>();
MWGui::ToolTipInfo info;
info.caption = ref->base->name;
info.caption = ref->base->name + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->icon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
@ -347,4 +356,11 @@ namespace MWClass
return ref->base->enchant;
}
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
{
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
}
}

@ -56,8 +56,16 @@ namespace MWClass
virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const;
///< Return the put down sound Id
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const;
///< Generate action for using via inventory menu
};
}

@ -206,7 +206,7 @@ namespace MWDialogue
if(!NPCstats.mFactionRank.empty())
{
std::string NPCFaction = NPCstats.mFactionRank.begin()->first;
if(PCstats.mFactionRank.find(NPCFaction) != PCstats.mFactionRank.end()) sameFaction = 1;
if(PCstats.mFactionRank.find(toLower(NPCFaction)) != PCstats.mFactionRank.end()) sameFaction = 1;
}
if(!selectCompare<int,int>(comp,sameFaction,select.i)) return false;
}
@ -525,7 +525,7 @@ namespace MWDialogue
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
std::map<std::string,int>::iterator it = stats.mFactionRank.find(toLower(info.npcFaction));
if(it!=stats.mFactionRank.end())
{
//check rank
@ -542,7 +542,7 @@ namespace MWDialogue
if(!info.pcFaction.empty())
{
MWMechanics::NpcStats stats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.pcFaction);
std::map<std::string,int>::iterator it = stats.mFactionRank.find(toLower(info.pcFaction));
if(it!=stats.mFactionRank.end())
{
//check rank
@ -637,7 +637,7 @@ namespace MWDialogue
//initialise the GUI
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Dialogue);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->startDialogue(MWWorld::Class::get (actor).getName (actor));
win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor));
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
updateTopics();
@ -767,6 +767,36 @@ namespace MWDialogue
}
}
// check the available services of this actor
int services = 0;
if (mActor.getTypeName() == typeid(ESM::NPC).name())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mActor.get<ESM::NPC>();
if (ref->base->hasAI)
services = ref->base->AI.services;
}
else if (mActor.getTypeName() == typeid(ESM::Creature).name())
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mActor.get<ESM::Creature>();
if (ref->base->hasAI)
services = ref->base->AI.services;
}
if (services & ESM::NPC::Weapon
|| services & ESM::NPC::Armor
|| services & ESM::NPC::Clothing
|| services & ESM::NPC::Books
|| services & ESM::NPC::Ingredients
|| services & ESM::NPC::Picks
|| services & ESM::NPC::Probes
|| services & ESM::NPC::Lights
|| services & ESM::NPC::Apparatus
|| services & ESM::NPC::RepairItem
|| services & ESM::NPC::Misc)
win->setShowTrade(true);
else
win->setShowTrade(false);
// sort again, because the previous sort was case-sensitive
keywordList.sort(stringCompareNoCase);
win->setKeywords(keywordList);

@ -27,7 +27,6 @@ BirthDialog::BirthDialog(WindowManager& parWindowManager)
MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton");
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
MyGUI::ButtonPtr okButton;

@ -52,7 +52,7 @@ void BookWindow::open (MWWorld::Ptr book)
clearPages();
mCurrentPage = 0;
MWBase::Environment::get().getSoundManager()->playSound3D (book, "book open", 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
mBook.get<ESM::Book>();
@ -77,18 +77,26 @@ void BookWindow::open (MWWorld::Ptr book)
}
updatePages();
setTakeButtonShow(true);
}
void BookWindow::setTakeButtonShow(bool show)
{
mTakeButton->setVisible(show);
}
void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "book close", 1.0, 1.0);
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game);
}
void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWWorld::ActionTake take(mBook);
take.execute();

@ -11,7 +11,9 @@ namespace MWGui
{
public:
BookWindow(WindowManager& parWindowManager);
void open(MWWorld::Ptr book);
void setTakeButtonShow(bool show);
protected:
void onNextPageButtonClicked (MyGUI::Widget* _sender);

@ -173,7 +173,6 @@ void CharacterCreation::spawnDialog(const char id)
mWM->removeDialog(mBirthSignDialog);
mBirthSignDialog = new BirthDialog(*mWM);
mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen);
mBirthSignDialog->setBirthId(mPlayerBirthSignId);
mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone);
mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack);
mBirthSignDialog->open();
@ -414,7 +413,6 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
if (mBirthSignDialog)
{
mPlayerBirthSignId = mBirthSignDialog->getBirthId();
mWM->setBirthSign(mPlayerBirthSignId);
if (!mPlayerBirthSignId.empty())
MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mPlayerBirthSignId);
mWM->removeDialog(mBirthSignDialog);

@ -28,7 +28,6 @@ GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowMan
MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton");
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked);
MyGUI::ButtonPtr okButton;
@ -111,7 +110,6 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager)
MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked);
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton");
@ -432,7 +430,6 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager)
MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked);
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton");

@ -34,7 +34,7 @@ namespace MWGui
typedef delegates::CMultiDelegate1<int> EventHandle_Int;
/** Event : Button was clicked.\n
signature : void method(MyGUI::WidgetPtr widget, int index)\n
signature : void method(int index)\n
*/
EventHandle_Int eventButtonSelected;

@ -0,0 +1,672 @@
#include "container.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <assert.h>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwclass/container.hpp"
#include "../mwinput/inputmanager.hpp"
#include "../mwsound/soundmanager.hpp"
#include "window_manager.hpp"
#include "widgets.hpp"
#include "countdialog.hpp"
#include "tradewindow.hpp"
#include "inventorywindow.hpp"
using namespace MWGui;
using namespace Widgets;
namespace
{
bool compareType(std::string type1, std::string type2)
{
// this defines the sorting order of types. types that are first in the vector, appear before other types.
std::vector<std::string> mapping;
mapping.push_back( typeid(ESM::Weapon).name() );
mapping.push_back( typeid(ESM::Armor).name() );
mapping.push_back( typeid(ESM::Clothing).name() );
mapping.push_back( typeid(ESM::Potion).name() );
mapping.push_back( typeid(ESM::Ingredient).name() );
mapping.push_back( typeid(ESM::Apparatus).name() );
mapping.push_back( typeid(ESM::Book).name() );
mapping.push_back( typeid(ESM::Light).name() );
mapping.push_back( typeid(ESM::Miscellaneous).name() );
mapping.push_back( typeid(ESM::Tool).name() );
mapping.push_back( typeid(ESM::Repair).name() );
mapping.push_back( typeid(ESM::Probe).name() );
assert( std::find(mapping.begin(), mapping.end(), type1) != mapping.end() );
assert( std::find(mapping.begin(), mapping.end(), type2) != mapping.end() );
return std::find(mapping.begin(), mapping.end(), type1) < std::find(mapping.begin(), mapping.end(), type2);
}
bool sortItems(MWWorld::Ptr left, MWWorld::Ptr right)
{
if (left.getTypeName() == right.getTypeName())
{
int cmp = MWWorld::Class::get(left).getName(left).compare(
MWWorld::Class::get(right).getName(right));
return cmp < 0;
}
else
{
return compareType(left.getTypeName(), right.getTypeName());
}
}
}
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop) :
mDragAndDrop(dragAndDrop),
mFilter(ContainerBase::Filter_All)
{
}
void ContainerBase::setWidgets(Widget* containerWidget, ScrollView* itemView)
{
mContainerWidget = containerWidget;
mItemView = itemView;
mContainerWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onContainerClicked);
mContainerWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerWindow::onMouseWheel);
}
ContainerBase::~ContainerBase()
{
}
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
{
mSelectedItem = _sender;
if (mDragAndDrop && !isTrading())
{
if(!mDragAndDrop->mIsOnDragAndDrop)
{
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
int count = object.getRefData().getCount();
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
{
startDragItem(_sender, count);
}
else if (MyGUI::InputManager::getInstance().isControlPressed())
{
startDragItem(_sender, 1);
}
else
{
std::string message = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTake")->str;
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::startDragItem);
}
}
else
onContainerClicked(mContainerWidget);
}
else
{
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
int count = object.getRefData().getCount();
if (isInventory())
{
// the player is trying to sell an item, check if the merchant accepts it
// also, don't allow selling gold (let's be better than Morrowind at this, can we?)
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object)
|| MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
{
// user notification "i don't buy this item"
MWBase::Environment::get().getWindowManager()->
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog4")->str, std::vector<std::string>());
return;
}
}
bool buying = isTradeWindow(); // buying or selling?
std::string message = buying ? MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage02")->str
: MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage01")->str;
if (std::find(mBoughtItems.begin(), mBoughtItems.end(), object) != mBoughtItems.end())
{
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
{
sellAlreadyBoughtItem(NULL, count);
}
else if (MyGUI::InputManager::getInstance().isControlPressed())
{
sellAlreadyBoughtItem(NULL, 1);
}
else
{
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellAlreadyBoughtItem);
}
}
else
{
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
{
sellItem(NULL, count);
}
else if (MyGUI::InputManager::getInstance().isControlPressed())
{
sellItem(NULL, 1);
}
else
{
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellItem);
}
}
}
}
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
{
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
if (isInventory())
{
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addItem(object, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
}
else
{
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addItem(object, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
}
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
drawItems();
}
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
{
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
if (isInventory())
{
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addBarteredItem(object, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
}
else
{
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addBarteredItem(object, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
}
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
drawItems();
}
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
{
mDragAndDrop->mIsOnDragAndDrop = true;
mSelectedItem->detachFromWidget();
mSelectedItem->attachToWidget(mDragAndDrop->mDragAndDropWidget);
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
_unequipItem(object);
mDragAndDrop->mDraggedCount = count;
mDragAndDrop->mDraggedFrom = this;
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
mDragAndDrop->mDraggedWidget = mSelectedItem;
static_cast<MyGUI::ImageBox*>(mSelectedItem)->setImageTexture(""); // remove the background texture (not visible during drag)
static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption(
getCountString(mDragAndDrop->mDraggedCount));
drawItems();
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
}
void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
{
if (mDragAndDrop == NULL) return;
if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
{
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
if (mDragAndDrop->mDraggedFrom != this)
{
assert(object.getContainerStore() && "Item is not in a container!");
// check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
if (mContainer.getTypeName() == typeid(ESM::Container).name())
{
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mContainer.get<ESM::Container>();
if (ref->base->flags & ESM::Container::Organic)
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage2")->str, std::vector<std::string>());
return;
}
}
int origCount = object.getRefData().getCount();
// check that we don't exceed the allowed weight (only for containers, not for inventory)
if (!isInventory())
{
float capacity = MWWorld::Class::get(mContainer).getCapacity(mContainer);
// try adding the item, and if weight is exceeded, just remove it again.
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
MWWorld::ContainerStoreIterator it = containerStore.add(object);
float curWeight = MWWorld::Class::get(mContainer).getEncumbrance(mContainer);
if (curWeight > capacity)
{
it->getRefData().setCount(0);
object.getRefData().setCount(origCount);
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage3")->str, std::vector<std::string>());
return;
}
else
{
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
}
std::cout << "container weight " << curWeight << "/" << capacity << std::endl;
}
else
{
object.getRefData().setCount (mDragAndDrop->mDraggedCount);
containerStore.add(object);
object.getRefData().setCount (origCount - mDragAndDrop->mDraggedCount);
}
}
mDragAndDrop->mIsOnDragAndDrop = false;
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
drawItems();
mDragAndDrop->mDraggedFrom->drawItems();
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
}
}
void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mItemView->getViewOffset().left + _rel*0.3 > 0)
mItemView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
}
void ContainerBase::setFilter(ContainerBase::Filter filter)
{
mFilter = filter;
drawItems();
}
void ContainerBase::openContainer(MWWorld::Ptr container)
{
mContainer = container;
drawItems();
}
void ContainerBase::drawItems()
{
while (mContainerWidget->getChildCount())
{
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
}
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
int x = 0;
int y = 0;
int maxHeight = mItemView->getSize().height - 58;
int index = 0;
bool onlyMagic = false;
int categories;
if (mFilter == Filter_All)
categories = MWWorld::ContainerStore::Type_All;
else if (mFilter == Filter_Weapon)
categories = MWWorld::ContainerStore::Type_Weapon;
else if (mFilter == Filter_Apparel)
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor;
else if (mFilter == Filter_Magic)
{
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor
+ MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book
+ MWWorld::ContainerStore::Type_Potion;
onlyMagic = true;
}
else if (mFilter == Filter_Misc)
{
categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book
+ MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair
+ MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light
+ MWWorld::ContainerStore::Type_Apparatus;
}
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
std::vector< std::pair<MWWorld::Ptr, ItemState> > items;
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
// add bought items (always at the beginning)
std::vector<MWWorld::Ptr> boughtItems;
for (MWWorld::ContainerStoreIterator it (mBoughtItems.begin()); it!=mBoughtItems.end(); ++it)
{
boughtItems.push_back(*it);
}
std::sort(boughtItems.begin(), boughtItems.end(), sortItems);
for (std::vector<MWWorld::Ptr>::iterator it=boughtItems.begin();
it != boughtItems.end(); ++it)
{
items.push_back( std::make_pair(*it, ItemState_Barter) );
}
// filter out the equipped items of categories we don't want
std::vector<MWWorld::Ptr> unwantedItems = equippedItems;
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
{
std::vector<MWWorld::Ptr>::iterator found = std::find(unwantedItems.begin(), unwantedItems.end(), *iter);
if (found != unwantedItems.end())
{
unwantedItems.erase(found);
}
}
// now erase everything that's still in unwantedItems.
for (std::vector<MWWorld::Ptr>::iterator it=unwantedItems.begin();
it != unwantedItems.end(); ++it)
{
std::vector<MWWorld::Ptr>::iterator found = std::find(equippedItems.begin(), equippedItems.end(), *it);
assert(found != equippedItems.end());
equippedItems.erase(found);
}
// and add the items that are left (= have the correct category)
if (!ignoreEquippedItems())
{
for (std::vector<MWWorld::Ptr>::const_iterator it=equippedItems.begin();
it != equippedItems.end(); ++it)
{
items.push_back( std::make_pair(*it, ItemState_Equipped) );
}
}
std::vector<MWWorld::Ptr> ignoreItems = itemsToIgnore();
// now add the regular items
std::vector<MWWorld::Ptr> regularItems;
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
{
if (std::find(equippedItems.begin(), equippedItems.end(), *iter) == equippedItems.end()
&& std::find(ignoreItems.begin(), ignoreItems.end(), *iter) == ignoreItems.end()
&& std::find(mBoughtItems.begin(), mBoughtItems.end(), *iter) == mBoughtItems.end())
regularItems.push_back(*iter);
}
// sort them and add
std::sort(regularItems.begin(), regularItems.end(), sortItems);
for (std::vector<MWWorld::Ptr>::const_iterator it=regularItems.begin(); it!=regularItems.end(); ++it)
{
items.push_back( std::make_pair(*it, ItemState_Normal) );
}
for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin();
it != items.end(); ++it)
{
index++;
const MWWorld::Ptr* iter = &((*it).first);
int displayCount = iter->getRefData().getCount();
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
{
displayCount -= mDragAndDrop->mDraggedCount;
}
if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
{
std::string path = std::string("icons\\");
path+=MWWorld::Class::get(*iter).getInventoryIcon(*iter);
// background widget (for the "equipped" frame and magic item background image)
bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != "");
MyGUI::ImageBox* backgroundWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
backgroundWidget->setUserString("ToolTipType", "ItemPtr");
backgroundWidget->setUserData(*iter);
std::string backgroundTex = "textures\\menu_icon";
if (isMagic)
backgroundTex += "_magic";
if (it->second == ItemState_Normal)
{
if (!isMagic)
backgroundTex = "";
}
else if (it->second == ItemState_Equipped)
{
backgroundTex += "_equip";
}
else if (it->second == ItemState_Barter)
{
backgroundTex += "_barter";
}
if (backgroundTex != "")
backgroundTex += ".dds";
backgroundWidget->setImageTexture(backgroundTex);
if (it->second == ItemState_Barter && !isMagic)
backgroundWidget->setProperty("ImageCoord", "2 2 42 42");
else
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onSelectedItem);
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerBase::onMouseWheel);
// image
ImageBox* image = backgroundWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture(path);
image->setNeedMouseFocus(false);
// text widget that shows item count
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right);
text->setNeedMouseFocus(false);
text->setTextShadow(true);
text->setTextShadowColour(MyGUI::Colour(0,0,0));
y += 42;
if (y > maxHeight)
{
x += 42;
y = 0;
}
text->setCaption(getCountString(displayCount));
}
}
MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height);
mItemView->setCanvasSize(size);
mContainerWidget->setSize(size);
}
std::string ContainerBase::getCountString(const int count)
{
if (count == 1)
return "";
if (count > 9999)
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
else
return boost::lexical_cast<std::string>(count);
}
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
{
int origCount = item.getRefData().getCount();
item.getRefData().setCount(count);
MWWorld::ContainerStoreIterator it = mBoughtItems.add(item);
item.getRefData().setCount(origCount - count);
}
void ContainerBase::addItem(MWWorld::Ptr item, int count)
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
int origCount = item.getRefData().getCount();
item.getRefData().setCount(count);
MWWorld::ContainerStoreIterator it = containerStore.add(item);
item.getRefData().setCount(origCount - count);
}
void ContainerBase::transferBoughtItems()
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
{
containerStore.add(*it);
}
}
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
{
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
{
store.add(*it);
}
}
MWWorld::ContainerStore& ContainerBase::getContainerStore()
{
MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
return store;
}
// ------------------------------------------------------------------------------------------------
ContainerWindow::ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
: ContainerBase(dragAndDrop)
, WindowBase("openmw_container_window_layout.xml", parWindowManager)
{
getWidget(mTakeButton, "TakeButton");
getWidget(mCloseButton, "CloseButton");
MyGUI::ScrollView* itemView;
MyGUI::Widget* containerWidget;
getWidget(containerWidget, "Items");
getWidget(itemView, "ItemView");
setWidgets(containerWidget, itemView);
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
// adjust buttons size to fit text
int closeButtonWidth = mCloseButton->getTextSize().width+24;
int takeButtonWidth = mTakeButton->getTextSize().width+24;
mCloseButton->setCoord(600-20-closeButtonWidth, mCloseButton->getCoord().top, closeButtonWidth, mCloseButton->getCoord().height);
mTakeButton->setCoord(600-20-closeButtonWidth-takeButtonWidth-8, mTakeButton->getCoord().top, takeButtonWidth, mTakeButton->getCoord().height);
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
//int h = MyGUI::RenderManager::getInstance().getViewSize().height;
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ContainerWindow::onWindowResize);
setCoord(w-600,0,600,300);
}
ContainerWindow::~ContainerWindow()
{
}
void ContainerWindow::onWindowResize(MyGUI::Window* window)
{
drawItems();
}
void ContainerWindow::open(MWWorld::Ptr container)
{
openContainer(container);
setTitle(MWWorld::Class::get(container).getName(container));
}
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game);
}
}
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
// transfer everything into the player's inventory
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
int i=0;
for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter)
{
playerStore.add(*iter);
if (i==0)
{
// play the sound of the first object
std::string sound = MWWorld::Class::get(*iter).getUpSoundId(*iter);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
}
++i;
}
containerStore.clear();
MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game);
}
}

@ -0,0 +1,141 @@
#ifndef MGUI_CONTAINER_H
#define MGUI_CONTAINER_H
#include <components/esm_store/store.hpp>
#include "../mwclass/container.hpp"
#include <sstream>
#include <set>
#include <string>
#include <utility>
#include "window_base.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/containerstore.hpp"
#include <vector>
namespace MWWorld
{
class Environment;
}
namespace MyGUI
{
class Gui;
class Widget;
}
namespace MWGui
{
class WindowManager;
class ContainerWindow;
class ContainerBase;
}
namespace MWGui
{
class DragAndDrop
{
public:
bool mIsOnDragAndDrop;
MyGUI::Widget* mDraggedWidget;
MyGUI::Widget* mDragAndDropWidget;
ContainerBase* mDraggedFrom;
int mDraggedCount;
};
class ContainerBase
{
public:
ContainerBase(DragAndDrop* dragAndDrop);
virtual ~ContainerBase();
enum Filter
{
Filter_All = 0x01,
Filter_Weapon = 0x02,
Filter_Apparel = 0x03,
Filter_Magic = 0x04,
Filter_Misc = 0x05
};
enum ItemState
{
ItemState_Normal = 0x01,
ItemState_Equipped = 0x02,
ItemState_Barter = 0x03
};
void setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView); ///< only call once
void addBarteredItem(MWWorld::Ptr item, int count);
void addItem(MWWorld::Ptr item, int count);
void transferBoughtItems(); ///< transfer bought items into the inventory
void returnBoughtItems(MWWorld::ContainerStore& store); ///< return bought items into the specified ContainerStore
MWWorld::ContainerStore& getContainerStore();
MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; }
void openContainer(MWWorld::Ptr container);
void setFilter(Filter filter); ///< set category filter
void drawItems();
protected:
MyGUI::ScrollView* mItemView;
MyGUI::Widget* mContainerWidget;
MyGUI::Widget* mSelectedItem;
DragAndDrop* mDragAndDrop;
MWWorld::Ptr mContainer;
Filter mFilter;
// bought items are put in a separate ContainerStore so that they don't stack with other (not bought) items.
MWWorld::ContainerStore mBoughtItems;
void onSelectedItem(MyGUI::Widget* _sender);
void onContainerClicked(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
/// start dragging an item (drag & drop)
void startDragItem(MyGUI::Widget* _sender, int count);
/// sell an item from this container
void sellItem(MyGUI::Widget* _sender, int count);
/// sell an item from this container, that was previously just bought
void sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count);
std::string getCountString(const int count);
virtual bool isTradeWindow() { return false; }
virtual bool isInventory() { return false; }
virtual std::vector<MWWorld::Ptr> getEquippedItems() { return std::vector<MWWorld::Ptr>(); }
virtual void _unequipItem(MWWorld::Ptr item) { ; }
virtual bool isTrading() { return false; }
virtual bool ignoreEquippedItems() { return false; }
virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); }
};
class ContainerWindow : public ContainerBase, public WindowBase
{
public:
ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
virtual ~ContainerWindow();
void open(MWWorld::Ptr container);
protected:
MyGUI::Button* mTakeButton;
MyGUI::Button* mCloseButton;
void onWindowResize(MyGUI::Window* window);
void onCloseButtonClicked(MyGUI::Widget* _sender);
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
};
}
#endif // CONTAINER_H

@ -0,0 +1,111 @@
#include "countdialog.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
namespace MWGui
{
CountDialog::CountDialog(WindowManager& parWindowManager) :
WindowBase("openmw_count_window_layout.xml", parWindowManager)
{
getWidget(mSlider, "CountSlider");
getWidget(mItemEdit, "ItemEdit");
getWidget(mItemText, "ItemText");
getWidget(mLabelText, "LabelText");
getWidget(mOkButton, "OkButton");
getWidget(mCancelButton, "CancelButton");
mOkButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sOk")->str);
mCancelButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sCancel")->str);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked);
mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange);
mSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &CountDialog::onSliderMoved);
}
void CountDialog::open(const std::string& item, const std::string& message, const int maxCount)
{
setVisible(true);
mLabelText->setCaption(message);
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
mSlider->setScrollRange(maxCount);
mItemText->setCaption(item);
int width = std::max(mItemText->getTextSize().width + 128, 320);
setCoord(viewSize.width/2 - width/2,
viewSize.height/2 - mMainWidget->getHeight()/2,
width,
mMainWidget->getHeight());
// make other gui elements inaccessible while this dialog is open
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit);
mSlider->setScrollPosition(maxCount-1);
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
int okButtonWidth = mOkButton->getTextSize().width + 24;
mOkButton->setCoord(width - 30 - okButtonWidth,
mOkButton->getTop(),
okButtonWidth,
mOkButton->getHeight());
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
mCancelButton->setCoord(width - 30 - okButtonWidth - cancelButtonWidth - 8,
mCancelButton->getTop(),
cancelButtonWidth,
mCancelButton->getHeight());
}
void CountDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
{
close();
}
void CountDialog::onOkButtonClicked(MyGUI::Widget* _sender)
{
eventOkClicked(NULL, mSlider->getScrollPosition()+1);
close();
}
void CountDialog::onEditTextChange(MyGUI::EditBox* _sender)
{
if (_sender->getCaption() == "")
return;
unsigned int count;
try
{
count = boost::lexical_cast<unsigned int>(_sender->getCaption());
}
catch (std::bad_cast&)
{
count = 1;
}
if (count > mSlider->getScrollRange())
{
count = mSlider->getScrollRange();
}
mSlider->setScrollPosition(count-1);
onSliderMoved(mSlider, count-1);
}
void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position)
{
mItemEdit->setCaption(boost::lexical_cast<std::string>(_position+1));
}
void CountDialog::close()
{
setVisible(false);
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
}
}

@ -0,0 +1,39 @@
#ifndef MWGUI_COUNTDIALOG_H
#define MWGUI_COUNTDIALOG_H
#include "window_base.hpp"
namespace MWGui
{
class CountDialog : public WindowBase
{
public:
CountDialog(WindowManager& parWindowManager);
void open(const std::string& item, const std::string& message, const int maxCount);
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, int> EventHandle_WidgetInt;
/** Event : Ok button was clicked.\n
signature : void method(MyGUI::Widget* _sender, int _count)\n
*/
EventHandle_WidgetInt eventOkClicked;
private:
MyGUI::ScrollBar* mSlider;
MyGUI::EditBox* mItemEdit;
MyGUI::TextBox* mItemText;
MyGUI::TextBox* mLabelText;
MyGUI::Button* mOkButton;
MyGUI::Button* mCancelButton;
void onCancelButtonClicked(MyGUI::Widget* _sender);
void onOkButtonClicked(MyGUI::Widget* _sender);
void onEditTextChange(MyGUI::EditBox* _sender);
void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position);
void close();
};
}
#endif

@ -1,11 +1,4 @@
#include "dialogue.hpp"
#include "dialogue_history.hpp"
#include "window_manager.hpp"
#include "widgets.hpp"
#include "list.hpp"
#include "components/esm_store/store.hpp"
#include "../mwbase/environment.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
#include <assert.h>
#include <iostream>
@ -14,6 +7,18 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
#include "dialogue_history.hpp"
#include "window_manager.hpp"
#include "widgets.hpp"
#include "list.hpp"
#include "tradewindow.hpp"
#include "inventorywindow.hpp"
using namespace MWGui;
using namespace Widgets;
@ -40,6 +45,7 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager)
, mEnabled(true)
, mShowTrade(false)
{
// Centre dialog
center();
@ -58,14 +64,11 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
//Topics list
getWidget(topicsList, "TopicsList");
//topicsList->eventListSelectAccept += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
topicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
//topicsList->eventListChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
MyGUI::ButtonPtr byeButton;
getWidget(byeButton, "ByeButton");
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
byeButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->str);
getWidget(pDispositionBar, "Disposition");
getWidget(pDispositionText,"DispositionText");
@ -127,24 +130,42 @@ void DialogueWindow::onSelectTopic(std::string topic)
{
if (!mEnabled) return;
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str)
{
/// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
mWindowManager.setGuiMode(GM_Barter);
mWindowManager.getTradeWindow()->startTrade(mActor);
}
else
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
}
void DialogueWindow::startDialogue(std::string npcName)
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
{
mEnabled = true;
mActor = actor;
topicsList->setEnabled(true);
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(npcName);
adjustWindowCaption();
setTitle(npcName);
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
topicsList->clear();
bool anyService = mShowTrade;
if (mShowTrade)
topicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str);
if (anyService)
topicsList->addSeparator();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++)
{
topicsList->addItem(*it);
}
topicsList->adjustSize();
}
void DialogueWindow::removeKeyword(std::string keyWord)
@ -154,6 +175,7 @@ void DialogueWindow::removeKeyword(std::string keyWord)
topicsList->removeItem(keyWord);
pTopicsText.erase(keyWord);
}
topicsList->adjustSize();
}
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
@ -192,7 +214,8 @@ std::string DialogueWindow::parseText(std::string text)
for(unsigned int i = 0;i<topicsList->getItemCount();i++)
{
std::string keyWord = topicsList->getItemNameAt(i);
addColorInString(text,keyWord,"#686EBA","#B29154");
if (keyWord != "")
addColorInString(text,keyWord,"#686EBA","#B29154");
}
return text;
}

@ -4,6 +4,8 @@
#include "window_base.hpp"
#include <boost/array.hpp>
#include "../mwworld/ptr.hpp"
namespace MWGui
{
class WindowManager;
@ -38,7 +40,7 @@ namespace MWGui
*/
EventHandle_Void eventBye;
void startDialogue(std::string npcName);
void startDialogue(MWWorld::Ptr actor, std::string npcName);
void stopDialogue();
void setKeywords(std::list<std::string> keyWord);
void removeKeyword(std::string keyWord);
@ -47,6 +49,10 @@ namespace MWGui
void askQuestion(std::string question);
void goodbye();
// various service button visibilities, depending if the npc/creature talked to has these services
// make sure to call these before setKeywords()
void setShowTrade(bool show) { mShowTrade = show; }
protected:
void onSelectTopic(std::string topic);
void onByeClicked(MyGUI::Widget* _sender);
@ -61,8 +67,13 @@ namespace MWGui
*/
std::string parseText(std::string text);
// various service button visibilities, depending if the npc/creature talked to has these services
bool mShowTrade;
bool mEnabled;
MWWorld::Ptr mActor; // actor being talked to
DialogueHistory* history;
Widgets::MWList* topicsList;
MyGUI::ProgressPtr pDispositionBar;

@ -1,19 +1,23 @@
#include "layouts.hpp"
#include "../mwmechanics/mechanicsmanager.hpp"
#include "window_manager.hpp"
#include "hud.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#undef min
#undef max
#include <MyGUI.h>
using namespace MWGui;
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwsound/soundmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/player.hpp"
#include "window_manager.hpp"
#include "container.hpp"
HUD::HUD(int width, int height, int fpsLevel)
using namespace MWGui;
HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
: Layout("openmw_hud_layout.xml")
, health(NULL)
, magicka(NULL)
@ -36,6 +40,7 @@ HUD::HUD(int width, int height, int fpsLevel)
, spellBoxBaseLeft(0)
, effectBoxBaseRight(0)
, minimapBoxBaseRight(0)
, mDragAndDrop(dragAndDrop)
{
setCoord(0,0, width, height);
@ -72,9 +77,6 @@ HUD::HUD(int width, int height, int fpsLevel)
getWidget(trianglecounter, "TriangleCounter");
getWidget(batchcounter, "BatchCounter");
compass->setImageTexture("textures\\compass.dds");
crosshair->setImageTexture("textures\\target.dds");
// These are just demo values, you should replace these with
// real calls from outside the class later.
setWeapIcon("icons\\w\\tx_knife_iron.dds");
@ -84,6 +86,10 @@ HUD::HUD(int width, int height, int fpsLevel)
setEffect("icons\\s\\tx_s_chameleon.dds");
LocalMapBase::init(minimap, this);
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
}
void HUD::setFpsLevel(int level)
@ -123,16 +129,6 @@ void HUD::setBatchCount(size_t count)
batchcounter->setCaption(boost::lexical_cast<std::string>(count));
}
void HUD::setStats(int h, int hmax, int m, int mmax, int s, int smax)
{
health->setProgressRange(hmax);
health->setProgressPosition(h);
magicka->setProgressRange(mmax);
magicka->setProgressPosition(m);
stamina->setProgressRange(smax);
stamina->setProgressPosition(s);
}
void HUD::setWeapIcon(const char *str)
{
weapImage->setImageTexture(str);
@ -170,19 +166,27 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& v
for (int i=0; ids[i]; ++i)
if (ids[i]==id)
{
MyGUI::Widget* w;
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
switch (i)
{
case 0:
health->setProgressRange (value.getModified());
health->setProgressPosition (value.getCurrent());
getWidget(w, "HealthFrame");
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
break;
case 1:
magicka->setProgressRange (value.getModified());
magicka->setProgressPosition (value.getCurrent());
getWidget(w, "MagickaFrame");
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
break;
case 2:
stamina->setProgressRange (value.getModified());
stamina->setProgressPosition (value.getCurrent());
getWidget(w, "FatigueFrame");
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
break;
}
}
@ -247,86 +251,72 @@ void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible
effectBox->setVisible(effectBoxVisible);
}
LocalMapBase::LocalMapBase()
: mCurX(0)
, mCurY(0)
, mInterior(false)
, mFogOfWar(true)
, mLocalMap(NULL)
, mPrefix()
, mChanged(true)
, mLayout(NULL)
, mLastPositionX(0.0f)
, mLastPositionY(0.0f)
, mLastDirectionX(0.0f)
, mLastDirectionY(0.0f)
void HUD::onWorldClicked(MyGUI::Widget* _sender)
{
}
if (mDragAndDrop->mIsOnDragAndDrop)
{
// drop item into the gameworld
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout)
{
mLocalMap = widget;
mLayout = layout;
}
MWWorld::World* world = MWBase::Environment::get().getWorld();
void LocalMapBase::setCellPrefix(const std::string& prefix)
{
mPrefix = prefix;
mChanged = true;
}
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
float mouseX = cursorPosition.left / float(viewSize.width);
float mouseY = cursorPosition.top / float(viewSize.height);
void LocalMapBase::toggleFogOfWar()
{
mFogOfWar = !mFogOfWar;
applyFogOfWar();
}
int origCount = object.getRefData().getCount();
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
void LocalMapBase::applyFogOfWar()
{
for (int mx=0; mx<3; ++mx)
{
for (int my=0; my<3; ++my)
{
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
+ boost::lexical_cast<std::string>(my);
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
MyGUI::ImageBox* fog;
mLayout->getWidget(fog, name+"_fog");
fog->setImageTexture(mFogOfWar ?
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
: "black.png" )
: "");
}
if (world->canPlaceObject(mouseX, mouseY))
world->placeObject(object, mouseX, mouseY);
else
world->dropObjectOnGround(object);
MyGUI::PointerManager::getInstance().setPointer("arrow");
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
// remove object from the container it was coming from
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
mDragAndDrop->mIsOnDragAndDrop = false;
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
mDragAndDrop->mDraggedWidget = 0;
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
}
}
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
{
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
for (int mx=0; mx<3; ++mx)
if (mDragAndDrop->mIsOnDragAndDrop)
{
for (int my=0; my<3; ++my)
{
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
+ boost::lexical_cast<std::string>(my);
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
float mouseX = cursorPosition.left / float(viewSize.width);
float mouseY = cursorPosition.top / float(viewSize.height);
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
MWWorld::World* world = MWBase::Environment::get().getWorld();
MyGUI::ImageBox* box;
mLayout->getWidget(box, name);
// if we can't drop the object at the wanted position, show the "drop on ground" cursor.
bool canDrop = world->canPlaceObject(mouseX, mouseY);
if (!canDrop)
MyGUI::PointerManager::getInstance().setPointer("drop_ground");
else
MyGUI::PointerManager::getInstance().setPointer("arrow");
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
box->setImageTexture(image);
else
box->setImageTexture("black.png");
}
}
mInterior = interior;
mCurX = x;
mCurY = y;
mChanged = false;
applyFogOfWar();
else
{
MyGUI::PointerManager::getInstance().setPointer("arrow");
/// \todo make it possible to pick up objects with the mouse, if inventory or container window is open
}
}
void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new)
{
MyGUI::PointerManager::getInstance().setPointer("arrow");
}

@ -0,0 +1,57 @@
#include "map_window.hpp"
#include <openengine/gui/layout.hpp>
#include "../mwmechanics/stat.hpp"
namespace MWGui
{
class DragAndDrop;
class HUD : public OEngine::GUI::Layout, public LocalMapBase
{
public:
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
void setWeapIcon(const char *str);
void setSpellIcon(const char *str);
void setWeapStatus(int s, int smax);
void setSpellStatus(int s, int smax);
void setEffect(const char *img);
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
void setFPS(float fps);
void setTriangleCount(size_t count);
void setBatchCount(size_t count);
void setPlayerDir(const float x, const float y);
void setPlayerPos(const float x, const float y);
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
void setFpsLevel(const int level);
MyGUI::ProgressPtr health, magicka, stamina;
MyGUI::Widget *weapBox, *spellBox;
MyGUI::ImageBox *weapImage, *spellImage;
MyGUI::ProgressPtr weapStatus, spellStatus;
MyGUI::Widget *effectBox, *minimapBox;
MyGUI::ImageBox* effect1;
MyGUI::ScrollView* minimap;
MyGUI::ImageBox* compass;
MyGUI::ImageBox* crosshair;
MyGUI::WidgetPtr fpsbox;
MyGUI::TextBox* fpscounter;
MyGUI::TextBox* trianglecounter;
MyGUI::TextBox* batchcounter;
private:
// bottom left elements
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
// bottom right elements
int minimapBoxBaseRight, effectBoxBaseRight;
DragAndDrop* mDragAndDrop;
void onWorldClicked(MyGUI::Widget* _sender);
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);
};
}

@ -0,0 +1,262 @@
#include "inventorywindow.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <assert.h>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include "../mwclass/container.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/player.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/manualref.hpp"
#include "window_manager.hpp"
#include "widgets.hpp"
#include "bookwindow.hpp"
#include "scrollwindow.hpp"
namespace
{
std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
}
namespace MWGui
{
InventoryWindow::InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
: ContainerBase(dragAndDrop)
, WindowPinnableBase("openmw_inventory_window_layout.xml", parWindowManager)
, mTrading(false)
{
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
getWidget(mAvatar, "Avatar");
getWidget(mEncumbranceBar, "EncumbranceBar");
getWidget(mEncumbranceText, "EncumbranceBarT");
getWidget(mFilterAll, "AllButton");
getWidget(mFilterWeapon, "WeaponButton");
getWidget(mFilterApparel, "ApparelButton");
getWidget(mFilterMagic, "MagicButton");
getWidget(mFilterMisc, "MiscButton");
getWidget(mLeftPane, "LeftPane");
getWidget(mRightPane, "RightPane");
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
MyGUI::ScrollView* itemView;
MyGUI::Widget* containerWidget;
getWidget(containerWidget, "Items");
getWidget(itemView, "ItemView");
setWidgets(containerWidget, itemView);
// adjust size of buttons to fit text
int curX = 0;
mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height );
curX += mFilterAll->getTextSize().width + 24 + 4;
mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top);
mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height );
curX += mFilterWeapon->getTextSize().width + 24 + 4;
mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top);
mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height );
curX += mFilterApparel->getTextSize().width + 24 + 4;
mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top);
mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height );
curX += mFilterMagic->getTextSize().width + 24 + 4;
mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top);
mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height );
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
mFilterAll->setStateSelected(true);
setCoord(0, 342, 600, 258);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
openContainer(player);
}
void InventoryWindow::openInventory()
{
updateEncumbranceBar();
mTrading = false;
mBoughtItems.clear();
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
}
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
{
const float aspect = 0.5; // fixed aspect ratio for the left pane
mLeftPane->setSize( (_sender->getSize().height-44) * aspect, _sender->getSize().height-44 );
mRightPane->setCoord( mLeftPane->getPosition().left + (_sender->getSize().height-44) * aspect + 4,
mRightPane->getPosition().top,
_sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15,
_sender->getSize().height-44 );
drawItems();
}
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
{
if (_sender == mFilterAll)
setFilter(ContainerBase::Filter_All);
else if (_sender == mFilterWeapon)
setFilter(ContainerBase::Filter_Weapon);
else if (_sender == mFilterApparel)
setFilter(ContainerBase::Filter_Apparel);
else if (_sender == mFilterMagic)
setFilter(ContainerBase::Filter_Magic);
else if (_sender == mFilterMisc)
setFilter(ContainerBase::Filter_Misc);
mFilterAll->setStateSelected(false);
mFilterWeapon->setStateSelected(false);
mFilterApparel->setStateSelected(false);
mFilterMagic->setStateSelected(false);
mFilterMisc->setStateSelected(false);
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
}
void InventoryWindow::onPinToggled()
{
mWindowManager.setWeaponVisibility(!mPinned);
}
void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender)
{
if (mDragAndDrop->mIsOnDragAndDrop)
{
MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
if (mDragAndDrop->mDraggedFrom != this)
{
// add item to the player's inventory
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStoreIterator it = invStore.begin();
int origCount = ptr.getRefData().getCount();
ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
it = invStore.add(ptr);
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
ptr = *it;
}
/// \todo scripts
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
action->execute();
// this is necessary for books/scrolls: if they are already in the player's inventory,
// the "Take" button should not be visible.
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
// without screwing up future book windows
if (mDragAndDrop->mDraggedFrom == this)
{
mWindowManager.getBookWindow()->setTakeButtonShow(false);
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
}
mDragAndDrop->mIsOnDragAndDrop = false;
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
mWindowManager.setDragDrop(false);
drawItems();
}
}
std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems()
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
std::vector<MWWorld::Ptr> items;
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
if (it != invStore.end())
{
items.push_back(*it);
}
}
return items;
}
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
if (it != invStore.end() && *it == item)
{
invStore.equip(slot, invStore.end());
return;
}
}
}
void InventoryWindow::updateEncumbranceBar()
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float capacity = MWWorld::Class::get(player).getCapacity(player);
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
mEncumbranceBar->setProgressRange(capacity);
mEncumbranceBar->setProgressPosition(encumbrance);
mEncumbranceText->setCaption( boost::lexical_cast<std::string>(int(encumbrance)) + "/" + boost::lexical_cast<std::string>(int(capacity)) );
}
void InventoryWindow::onFrame()
{
if (!mMainWidget->getVisible())
return;
updateEncumbranceBar();
}
int InventoryWindow::getPlayerGold()
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
for (MWWorld::ContainerStoreIterator it = invStore.begin();
it != invStore.end(); ++it)
{
if (toLower(it->getCellRef().refID) == "gold_001")
return it->getRefData().getCount();
}
return 0;
}
void InventoryWindow::startTrade()
{
mTrading = true;
}
}

@ -0,0 +1,54 @@
#ifndef MGUI_Inventory_H
#define MGUI_Inventory_H
#include "container.hpp"
#include "window_pinnable_base.hpp"
namespace MWGui
{
class InventoryWindow : public ContainerBase, public WindowPinnableBase
{
public:
InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
void openInventory();
/// start trading, disables item drag&drop
void startTrade();
void onFrame();
int getPlayerGold();
protected:
MyGUI::Widget* mAvatar;
MyGUI::TextBox* mArmorRating;
MyGUI::ProgressBar* mEncumbranceBar;
MyGUI::TextBox* mEncumbranceText;
MyGUI::Widget* mLeftPane;
MyGUI::Widget* mRightPane;
MyGUI::Button* mFilterAll;
MyGUI::Button* mFilterWeapon;
MyGUI::Button* mFilterApparel;
MyGUI::Button* mFilterMagic;
MyGUI::Button* mFilterMisc;
bool mTrading;
void onWindowResize(MyGUI::Window* _sender);
void onFilterChanged(MyGUI::Widget* _sender);
void onAvatarClicked(MyGUI::Widget* _sender);
void onPinToggled();
void updateEncumbranceBar();
virtual bool isTrading() { return mTrading; }
virtual bool isInventory() { return true; }
virtual std::vector<MWWorld::Ptr> getEquippedItems();
virtual void _unequipItem(MWWorld::Ptr item);
};
}
#endif // Inventory_H

@ -1,236 +0,0 @@
#ifndef MWGUI_LAYOUTS_H
#define MWGUI_LAYOUTS_H
#include <components/esm_store/store.hpp>
#include <boost/array.hpp>
#include <boost/lexical_cast.hpp>
#include <sstream>
#include <set>
#include <string>
#include <utility>
#include "../mwmechanics/stat.hpp"
#include "window_base.hpp"
#include <cmath>
/*
This file contains classes corresponding to window layouts
defined in resources/mygui/ *.xml.
Each class inherites GUI::Layout and loads the XML file, and
provides some helper functions to manipulate the elements of the
window.
The windows are never created or destroyed (except at startup and
shutdown), they are only hid. You can control visibility with
setVisible().
*/
namespace MWGui
{
class LocalMapBase
{
public:
LocalMapBase();
void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout);
void setCellPrefix(const std::string& prefix);
void setActiveCell(const int x, const int y, bool interior=false);
void toggleFogOfWar();
protected:
int mCurX, mCurY;
bool mInterior;
MyGUI::ScrollView* mLocalMap;
std::string mPrefix;
bool mChanged;
bool mFogOfWar;
void applyFogOfWar();
OEngine::GUI::Layout* mLayout;
float mLastPositionX;
float mLastPositionY;
float mLastDirectionX;
float mLastDirectionY;
};
class HUD : public OEngine::GUI::Layout, public LocalMapBase
{
public:
HUD(int width, int height, int fpsLevel);
void setStats(int h, int hmax, int m, int mmax, int s, int smax);
void setWeapIcon(const char *str);
void setSpellIcon(const char *str);
void setWeapStatus(int s, int smax);
void setSpellStatus(int s, int smax);
void setEffect(const char *img);
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
void setFPS(float fps);
void setTriangleCount(size_t count);
void setBatchCount(size_t count);
void setPlayerDir(const float x, const float y);
void setPlayerPos(const float x, const float y);
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
void setFpsLevel(const int level);
MyGUI::ProgressPtr health, magicka, stamina;
MyGUI::Widget *weapBox, *spellBox;
MyGUI::ImageBox *weapImage, *spellImage;
MyGUI::ProgressPtr weapStatus, spellStatus;
MyGUI::Widget *effectBox, *minimapBox;
MyGUI::ImageBox* effect1;
MyGUI::ScrollView* minimap;
MyGUI::ImageBox* compass;
MyGUI::ImageBox* crosshair;
MyGUI::WidgetPtr fpsbox;
MyGUI::TextBox* fpscounter;
MyGUI::TextBox* trianglecounter;
MyGUI::TextBox* batchcounter;
private:
// bottom left elements
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
// bottom right elements
int minimapBoxBaseRight, effectBoxBaseRight;
};
class MainMenu : public OEngine::GUI::Layout
{
public:
MainMenu(int w, int h)
: Layout("openmw_mainmenu_layout.xml")
{
setCoord(0,0,w,h);
}
};
#if 0
class InventoryWindow : public OEngine::GUI::Layout
{
public:
enum CategoryMode
{
CM_All = 0, // All items
CM_Weapon = 1, // Only weapons
CM_Apparel = 2, // Apparel
CM_Magic = 3, // Magic
CM_Misc = 4 // Misc
};
InventoryWindow ()
: Layout("openmw_inventory_window_layout.xml")
, categoryMode(CM_All)
// color should be fetched from skin
, activeColor(0, 0, 1)
, inactiveColor(0.7, 0.7, 0.7)
{
setCoord(0, 200, 600, 400);
// These are just demo values, you should replace these with
// real calls from outside the class later.
mMainWidget->setCaption("Glass Frostsword");
setText("EncumbranceBarT", "176/210");
MyGUI::ProgressPtr pt;
getWidget(pt, "EncumbranceBar");
pt->setProgressRange(210);
pt->setProgressPosition(176);
MyGUI::WidgetPtr avatar;
getWidget(avatar, "Avatar");
// Adjust armor rating text to bottom of avatar widget
MyGUI::TextBox* armor_rating;
getWidget(armor_rating, "ArmorRating");
armor_rating->setCaption("Armor: 11");
MyGUI::IntCoord coord = armor_rating->getCoord();
coord.top = avatar->getCoord().height - 4 - coord.height;
armor_rating->setCoord(coord);
names[0] = "All";
names[1] = "Weapon";
names[2] = "Apparel";
names[3] = "Magic";
names[4] = "Misc";
boost::array<CategoryMode, 5> categories = { {
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
} };
// Initialize buttons with text and adjust sizes, also mark All as active button
int margin = 2;
int last_x = 0;
for (int i = 0; i < categories.size(); ++i)
{
CategoryMode mode = categories[i];
std::string name = names[mode];
name += "Button";
setText(name, names[mode]);
getWidget(buttons[mode], name);
MyGUI::ButtonPtr &button_pt = buttons[mode];
if (mode == CM_All)
button_pt->setTextColour(activeColor);
else
button_pt->setTextColour(inactiveColor);
MyGUI::IntCoord coord = button_pt->getCoord();
coord.left = last_x;
last_x += coord.width + margin;
button_pt->setCoord(coord);
button_pt->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onCategorySelected);
}
}
void setCategory(CategoryMode mode)
{
MyGUI::ButtonPtr pt = getCategoryButton(categoryMode);
pt->setTextColour(inactiveColor);
pt = getCategoryButton(mode);
pt->setTextColour(activeColor);
categoryMode = mode;
}
MyGUI::ButtonPtr getCategoryButton(CategoryMode mode)
{
return buttons[mode];
}
void onCategorySelected(MyGUI::Widget *widget)
{
boost::array<CategoryMode, 5> categories = { {
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
} };
for (int i = 0; i < categories.size(); ++i)
{
CategoryMode mode = categories[i];
if (widget == buttons[mode])
{
setCategory(mode);
return;
}
}
}
CategoryMode categoryMode; // Current category filter
MyGUI::ButtonPtr buttons[5]; // Button pointers
std::string names[5]; // Names of category buttons
MyGUI::Colour activeColor;
MyGUI::Colour inactiveColor;
};
#endif
}
#endif

@ -28,8 +28,11 @@ void MWList::initialiseOverride()
void MWList::addItem(const std::string& name)
{
mItems.push_back(name);
}
redraw();
void MWList::addSeparator()
{
mItems.push_back("");
}
void MWList::adjustSize()
@ -52,22 +55,33 @@ void MWList::redraw(bool scrollbarShown)
for (std::vector<std::string>::const_iterator it=mItems.begin();
it!=mItems.end(); ++it)
{
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
"MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it));
button->setCaption((*it));
button->getSubWidgetText()->setWordWrap(true);
button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left);
button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheel);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected);
int height = button->getTextSize().height;
button->setSize(MyGUI::IntSize(button->getSize().width, height));
mItemHeight += height + spacing;
if (*it != "")
{
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
"MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it));
button->setCaption((*it));
button->getSubWidgetText()->setWordWrap(true);
button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left);
button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheel);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected);
int height = button->getTextSize().height;
button->setSize(MyGUI::IntSize(button->getSize().width, height));
mItemHeight += height + spacing;
}
else
{
MyGUI::ImageBox* separator = mScrollView->createWidget<MyGUI::ImageBox>("MW_HLine",
MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth()-4, 18),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
separator->setNeedMouseFocus(false);
mItemHeight += 18 + spacing;
}
}
mScrollView->setCanvasSize(mClient->getSize().width + (_scrollBarWidth-scrollBarWidth), std::max(mItemHeight, mClient->getSize().height));
mScrollView->setViewOffset(MyGUI::IntPoint(0,0));
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
redraw(true);
@ -93,15 +107,11 @@ void MWList::removeItem(const std::string& name)
{
assert( std::find(mItems.begin(), mItems.end(), name) != mItems.end() );
mItems.erase( std::find(mItems.begin(), mItems.end(), name) );
redraw();
}
void MWList::clear()
{
mItems.clear();
redraw();
}
void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel)

@ -26,15 +26,16 @@ namespace MWGui
EventHandle_String eventItemSelected;
/**
* Call after the size of the list changed
* Call after the size of the list changed, or items were inserted/removed
*/
void adjustSize();
void addItem(const std::string& name);
void addSeparator(); ///< add a seperator between the current and the next item.
void removeItem(const std::string& name);
bool hasItem(const std::string& name);
unsigned int getItemCount();
std::string getItemNameAt(unsigned int at);
std::string getItemNameAt(unsigned int at); ///< \attention if there are separators, this method will return "" at the place where the separator is
void clear();
protected:

@ -0,0 +1,16 @@
#include <openengine/gui/layout.hpp>
namespace MWGui
{
class MainMenu : public OEngine::GUI::Layout
{
public:
MainMenu(int w, int h)
: Layout("openmw_mainmenu_layout.xml")
{
setCoord(0,0,w,h);
}
};
}

@ -1,27 +1,100 @@
#include "map_window.hpp"
#include "window_manager.hpp"
/*
#include "../mwmechanics/mechanicsmanager.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <boost/lexical_cast.hpp>
#undef min
#undef max
*/
using namespace MWGui;
LocalMapBase::LocalMapBase()
: mCurX(0)
, mCurY(0)
, mInterior(false)
, mFogOfWar(true)
, mLocalMap(NULL)
, mPrefix()
, mChanged(true)
, mLayout(NULL)
, mLastPositionX(0.0f)
, mLastPositionY(0.0f)
, mLastDirectionX(0.0f)
, mLastDirectionY(0.0f)
{
}
void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout)
{
mLocalMap = widget;
mLayout = layout;
}
void LocalMapBase::setCellPrefix(const std::string& prefix)
{
mPrefix = prefix;
mChanged = true;
}
void LocalMapBase::toggleFogOfWar()
{
mFogOfWar = !mFogOfWar;
applyFogOfWar();
}
void LocalMapBase::applyFogOfWar()
{
for (int mx=0; mx<3; ++mx)
{
for (int my=0; my<3; ++my)
{
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
+ boost::lexical_cast<std::string>(my);
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
MyGUI::ImageBox* fog;
mLayout->getWidget(fog, name+"_fog");
fog->setImageTexture(mFogOfWar ?
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
: "black.png" )
: "");
}
}
}
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
{
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
for (int mx=0; mx<3; ++mx)
{
for (int my=0; my<3; ++my)
{
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
+ boost::lexical_cast<std::string>(my);
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
MyGUI::ImageBox* box;
mLayout->getWidget(box, name);
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
box->setImageTexture(image);
else
box->setImageTexture("black.png");
}
}
mInterior = interior;
mCurX = x;
mCurY = y;
mChanged = false;
applyFogOfWar();
}
// ------------------------------------------------------------------------------------------
MapWindow::MapWindow(WindowManager& parWindowManager) :
MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager),
mGlobal(false)
{
setCoord(500,0,320,300);
setText("WorldButton", "World");
setImage("Compass", "textures\\compass.dds");
// Obviously you should override this later on
setCellName("No Cell Loaded");
getWidget(mLocalMap, "LocalMap");
getWidget(mGlobalMap, "GlobalMap");
@ -43,8 +116,7 @@ MapWindow::MapWindow(WindowManager& parWindowManager) :
void MapWindow::setCellName(const std::string& cellName)
{
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
adjustWindowCaption();
setTitle(cellName);
}
void MapWindow::setPlayerPos(const float x, const float y)

@ -1,11 +1,39 @@
#ifndef MWGUI_MAPWINDOW_H
#define MWGUI_MAPWINDOW_H
#include "layouts.hpp"
#include "window_pinnable_base.hpp"
namespace MWGui
{
class LocalMapBase
{
public:
LocalMapBase();
void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout);
void setCellPrefix(const std::string& prefix);
void setActiveCell(const int x, const int y, bool interior=false);
void toggleFogOfWar();
protected:
int mCurX, mCurY;
bool mInterior;
MyGUI::ScrollView* mLocalMap;
std::string mPrefix;
bool mChanged;
bool mFogOfWar;
void applyFogOfWar();
OEngine::GUI::Layout* mLayout;
float mLastPositionX;
float mLastPositionY;
float mLastDirectionX;
float mLastDirectionY;
};
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase
{
public:

@ -15,6 +15,13 @@ void MessageBoxManager::onFrame (float frameDuration)
std::vector<MessageBoxManagerTimer>::iterator it;
for(it = mTimers.begin(); it != mTimers.end();)
{
// if this messagebox is already deleted, remove the timer and move on
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
{
it = mTimers.erase(it);
continue;
}
it->current += frameDuration;
if(it->current >= it->max)
{

@ -7,6 +7,7 @@ namespace MWGui
{
GM_Game, // Game mode, only HUD
GM_Inventory, // Inventory mode
GM_Container,
GM_MainMenu, // Main menu mode
GM_Console, // Console mode

@ -71,7 +71,6 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager)
MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton");
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked);
MyGUI::ButtonPtr okButton;

@ -27,25 +27,21 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
ButtonPtr button;
getWidget(nameWidget, "NameText");
getWidget(button, "NameButton");
button->setCaption(mWindowManager.getGameSettingString("sName", ""));
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
getWidget(raceWidget, "RaceText");
getWidget(button, "RaceButton");
button->setCaption(mWindowManager.getGameSettingString("sRace", ""));
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
getWidget(classWidget, "ClassText");
getWidget(button, "ClassButton");
button->setCaption(mWindowManager.getGameSettingString("sClass", ""));
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
getWidget(birthSignWidget, "SignText");
getWidget(button, "SignButton");
button->setCaption(mWindowManager.getGameSettingString("sBirthSign", ""));
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
@ -92,7 +88,6 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager)
MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton");
backButton->setCaption(mWindowManager.getGameSettingString("sBack", ""));
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
MyGUI::ButtonPtr okButton;

@ -25,7 +25,8 @@ ScrollWindow::ScrollWindow (WindowManager& parWindowManager) :
void ScrollWindow::open (MWWorld::Ptr scroll)
{
MWBase::Environment::get().getSoundManager()->playSound3D (scroll, "scroll", 1.0, 1.0);
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
mScroll = scroll;
@ -41,18 +42,25 @@ void ScrollWindow::open (MWWorld::Ptr scroll)
mTextView->setCanvasSize(410, mTextView->getSize().height);
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
setTakeButtonShow(true);
}
void ScrollWindow::setTakeButtonShow(bool show)
{
mTakeButton->setVisible(show);
}
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "scroll", 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
}
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWWorld::ActionTake take(mScroll);
take.execute();

@ -11,7 +11,9 @@ namespace MWGui
{
public:
ScrollWindow (WindowManager& parWindowManager);
void open (MWWorld::Ptr scroll);
void setTakeButtonShow(bool show);
protected:
void onCloseButtonClicked (MyGUI::Widget* _sender);

@ -1,13 +1,19 @@
#include "stats_window.hpp"
#include "../mwmechanics/mechanicsmanager.hpp"
#include "window_manager.hpp"
#include <cmath>
#include <algorithm>
#include <iterator>
#include <boost/lexical_cast.hpp>
#include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/player.hpp"
#include "../mwbase/environment.hpp"
#include "window_manager.hpp"
using namespace MWGui;
const int StatsWindow::lineHeight = 18;
@ -24,11 +30,12 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
, skillValues()
, skillWidgetMap()
, factionWidgetMap()
, factions()
, mFactions()
, birthSignId()
, reputation(0)
, bounty(0)
, skillWidgets()
, mChanged(true)
{
setCoord(0,0,498, 342);
@ -42,12 +49,6 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager)
{ "Attrib6", "sAttributeEndurance" },
{ "Attrib7", "sAttributePersonality" },
{ "Attrib8", "sAttributeLuck" },
{ "Health_str", "sHealth" },
{ "Magicka_str", "sMagic" },
{ "Fatigue_str", "sFatigue" },
{ "Level_str", "sLevel" },
{ "Race_str", "sRace" },
{ "Class_str", "sClass" },
{ 0, 0 }
};
@ -171,11 +172,32 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicSta
};
for (int i=0; ids[i]; ++i)
{
if (ids[i]==id)
{
std::string id (ids[i]);
setBar (id, id + "T", value.getCurrent(), value.getModified());
// health, magicka, fatigue tooltip
MyGUI::Widget* w;
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
if (i==0)
{
getWidget(w, "Health");
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
}
else if (i==1)
{
getWidget(w, "Magicka");
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
}
else if (i==2)
{
getWidget(w, "Fatigue");
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
}
}
}
}
void StatsWindow::setValue (const std::string& id, const std::string& value)
@ -236,14 +258,38 @@ void StatsWindow::configureSkills (const std::vector<int>& major, const std::vec
}
}
void StatsWindow::setFactions (const std::vector<Faction>& factions)
void StatsWindow::onFrame ()
{
this->factions = factions;
if (mMainWidget->getVisible())
return;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::NpcStats PCstats = MWWorld::Class::get(player).getNpcStats(player);
setFactions(PCstats.mFactionRank);
setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());
if (mChanged)
updateSkillArea();
}
void StatsWindow::setFactions (const FactionList& factions)
{
if (mFactions != factions)
{
mFactions = factions;
mChanged = true;
}
}
void StatsWindow::setBirthSign (const std::string& signId)
{
birthSignId = signId;
if (signId != birthSignId)
{
birthSignId = signId;
mChanged = true;
}
}
void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
@ -271,19 +317,15 @@ void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, My
coord2.top += lineHeight;
}
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string& tooltip, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox *skillNameWidget, *skillValueWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
skillNameWidget->setCaption(text);
skillNameWidget->setUserString("ToolTipType", "Text");
skillNameWidget->setUserString("ToolTipText", tooltip);
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top);
skillValueWidget->setUserString("ToolTipType", "Text");
skillValueWidget->setUserString("ToolTipText", tooltip);
skillValueWidget->setCaption(value);
skillValueWidget->_setWidgetState(state);
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel);
@ -297,7 +339,7 @@ MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::st
return skillValueWidget;
}
void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
MyGUI::Widget* StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::TextBox* skillNameWidget;
@ -309,6 +351,8 @@ void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI
coord1.top += lineHeight;
coord2.top += lineHeight;
return skillNameWidget;
}
void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
@ -333,25 +377,52 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId,
float base = stat.getBase();
float modified = stat.getModified();
const ESM::Skill* skill = mWindowManager.getStore().skills.search(skillId);
assert(skill);
std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
const ESM::Attribute* attr = mWindowManager.getStore().attributes.search(skill->data.attribute);
assert(attr);
std::string state = "normal";
if (modified > base)
state = "increased";
else if (modified < base)
state = "decreased";
MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), "",
MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId),
boost::lexical_cast<std::string>(static_cast<int>(modified)), state, coord1, coord2);
for (int i=0; i<2; ++i)
{
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "SkillToolTip");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillName", "#{"+skillNameId+"}");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->description);
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon);
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", "0/100");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100");
}
skillWidgetMap[skillId] = widget;
}
}
void StatsWindow::updateSkillArea()
{
mChanged = false;
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
skillWidgets.clear();
skillScrollerWidget->setScrollPosition(0);
onScrollChangePosition(skillScrollerWidget, 0);
clientHeight = 0;
const int valueSize = 40;
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18);
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
@ -367,19 +438,90 @@ void StatsWindow::updateSkillArea()
const ESMS::ESMStore &store = mWindowManager.getStore();
if (!factions.empty())
// race tooltip
const ESM::Race* playerRace = store.races.find (MWBase::Environment::get().getWorld()->getPlayer().getRace());
MyGUI::Widget* raceWidget;
getWidget(raceWidget, "RaceText");
raceWidget->setUserString("Caption_CenteredCaption", playerRace->name);
raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description);
getWidget(raceWidget, "Race_str");
raceWidget->setUserString("Caption_CenteredCaption", playerRace->name);
raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description);
// class tooltip
MyGUI::Widget* classWidget;
const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass();
int spec = playerClass.data.specialization;
std::string specStr;
if (spec == 0)
specStr = "#{sSpecializationCombat}";
else if (spec == 1)
specStr = "#{sSpecializationMagic}";
else if (spec == 2)
specStr = "#{sSpecializationStealth}";
getWidget(classWidget, "ClassText");
classWidget->setUserString("Caption_ClassName", playerClass.name);
classWidget->setUserString("Caption_ClassDescription", playerClass.description);
classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr);
getWidget(classWidget, "Class_str");
classWidget->setUserString("Caption_ClassName", playerClass.name);
classWidget->setUserString("Caption_ClassDescription", playerClass.description);
classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr);
if (!mFactions.empty())
{
// Add a line separator if there are items above
if (!skillWidgets.empty())
addSeparator(coord1, coord2);
addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2);
FactionList::const_iterator end = factions.end();
for (FactionList::const_iterator it = factions.begin(); it != end; ++it)
FactionList::const_iterator end = mFactions.end();
for (FactionList::const_iterator it = mFactions.begin(); it != end; ++it)
{
const ESM::Faction *faction = store.factions.find(it->first);
addItem(faction->name, coord1, coord2);
// TODO: Faction rank should be placed in tooltip
MyGUI::Widget* w = addItem(faction->name, coord1, coord2);
std::string text;
text += std::string("#DDC79E") + faction->name;
text += std::string("\n#BF9959") + faction->ranks[it->second];
if (it->second < 9)
{
// player doesn't have max rank yet
text += std::string("\n\n#DDC79E#{sNextRank} ") + faction->ranks[it->second+1];
ESM::RankData rankData = faction->data.rankData[it->second+1];
const ESM::Attribute* attr1 = mWindowManager.getStore().attributes.search(faction->data.attribute1);
const ESM::Attribute* attr2 = mWindowManager.getStore().attributes.search(faction->data.attribute2);
assert(attr1 && attr2);
text += "\n#BF9959#{" + attr1->name + "}: " + boost::lexical_cast<std::string>(rankData.attribute1)
+ ", #{" + attr2->name + "}: " + boost::lexical_cast<std::string>(rankData.attribute2);
text += "\n\n#DDC79E#{sFavoriteSkills}";
text += "\n#BF9959";
for (int i=0; i<6; ++i)
{
const ESM::Skill* skill = mWindowManager.getStore().skills.search(faction->data.skillID[i]);
assert(skill);
text += "#{"+ESM::Skill::sSkillNameIds[faction->data.skillID[i]]+"}";
if (i<5)
text += ", ";
}
text += "\n";
if (rankData.skill1 > 0)
text += "\n#{sNeedOneSkill} " + boost::lexical_cast<std::string>(rankData.skill1);
if (rankData.skill2 > 0)
text += "\n#{sNeedTwoSkills} " + boost::lexical_cast<std::string>(rankData.skill2);
}
w->setUserString("ToolTipType", "Layout");
w->setUserString("ToolTipLayout", "TextToolTip");
w->setUserString("Caption_Text", text);
}
}
@ -391,7 +533,62 @@ void StatsWindow::updateSkillArea()
addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2);
const ESM::BirthSign *sign = store.birthSigns.find(birthSignId);
addItem(sign->name, coord1, coord2);
MyGUI::Widget* w = addItem(sign->name, coord1, coord2);
w->setUserString("ToolTipType", "Layout");
w->setUserString("ToolTipLayout", "BirthSignToolTip");
std::string image = sign->texture;
image.replace(image.size()-3, 3, "dds");
w->setUserString("ImageTexture_BirthSignImage", "textures\\" + image);
std::string text;
text += sign->name;
text += "\n#BF9959" + sign->description;
std::vector<std::string> abilities, powers, spells;
std::vector<std::string>::const_iterator it = sign->powers.list.begin();
std::vector<std::string>::const_iterator end = sign->powers.list.end();
for (; it != end; ++it)
{
const std::string &spellId = *it;
const ESM::Spell *spell = store.spells.search(spellId);
if (!spell)
continue; // Skip spells which cannot be found
ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->data.type);
if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Ability && type != ESM::Spell::ST_Power)
continue; // We only want spell, ability and powers.
if (type == ESM::Spell::ST_Ability)
abilities.push_back(spellId);
else if (type == ESM::Spell::ST_Power)
powers.push_back(spellId);
else if (type == ESM::Spell::ST_Spell)
spells.push_back(spellId);
}
struct{ const std::vector<std::string> &spells; std::string label; } categories[3] = {
{abilities, "sBirthsignmenu1"},
{powers, "sPowers"},
{spells, "sBirthsignmenu2"}
};
for (int category = 0; category < 3; ++category)
{
for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != categories[category].spells.end(); ++it)
{
if (it == categories[category].spells.begin())
{
text += std::string("\n#DDC79E") + std::string("#{") + categories[category].label + "}";
}
const std::string &spellId = *it;
const ESM::Spell *spell = store.spells.search(spellId);
text += "\n#BF9959" + spell->name;
}
}
w->setUserString("Caption_BirthSignText", text);
}
// Add a line separator if there are items above
@ -399,12 +596,25 @@ void StatsWindow::updateSkillArea()
addSeparator(coord1, coord2);
addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"),
mWindowManager.getGameSettingString("sSkillsMenuReputationHelp", ""),
boost::lexical_cast<std::string>(static_cast<int>(reputation)), "normal", coord1, coord2);
for (int i=0; i<2; ++i)
{
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sSkillsMenuReputationHelp}");
}
addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"),
mWindowManager.getGameSettingString("sCrimeHelp", ""),
boost::lexical_cast<std::string>(static_cast<int>(bounty)), "normal", coord1, coord2);
for (int i=0; i<2; ++i)
{
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout");
skillWidgets[skillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip");
skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sCrimeHelp}");
}
clientHeight = coord1.top;
updateScroller();
}
@ -428,91 +638,109 @@ void StatsWindow::setupToolTips()
const ESMS::ESMStore &store = mWindowManager.getStore();
MyGUI::Widget* widget;
/// \todo move this into the .layout file!
getWidget(widget, "Attrib1");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeStrength")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sStrDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_strength.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeStrength")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sStrDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_strength.dds");
getWidget(widget, "AttribVal1");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeStrength")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sStrDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_strength.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeStrength")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sStrDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_strength.dds");
getWidget(widget, "Attrib2");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeIntelligence")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sIntDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_int.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeIntelligence")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sIntDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_int.dds");
getWidget(widget, "AttribVal2");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeIntelligence")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sIntDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_int.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeIntelligence")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sIntDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_int.dds");
getWidget(widget, "Attrib3");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeWillpower")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sWilDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_wilpower.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeWillpower")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sWilDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_wilpower.dds");
getWidget(widget, "AttribVal3");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeWillpower")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sWilDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_wilpower.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeWillpower")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sWilDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_wilpower.dds");
getWidget(widget, "Attrib4");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeAgility")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sAgiDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_agility.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeAgility")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sAgiDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_agility.dds");
getWidget(widget, "AttribVal4");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeAgility")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sAgiDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_agility.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeAgility")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sAgiDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_agility.dds");
getWidget(widget, "Attrib5");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeSpeed")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sSpdDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_speed.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeSpeed")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sSpdDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_speed.dds");
getWidget(widget, "AttribVal5");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeSpeed")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sSpdDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_speed.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeSpeed")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sSpdDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_speed.dds");
getWidget(widget, "Attrib6");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeEndurance")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sEndDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_endurance.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeEndurance")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sEndDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_endurance.dds");
getWidget(widget, "AttribVal6");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeEndurance")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sEndDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_endurance.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeEndurance")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sEndDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_endurance.dds");
getWidget(widget, "Attrib7");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributePersonality")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sPerDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_personality.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributePersonality")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sPerDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_personality.dds");
getWidget(widget, "AttribVal7");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributePersonality")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sPerDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_personality.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributePersonality")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sPerDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_personality.dds");
getWidget(widget, "Attrib8");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeLuck")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sLucDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_luck.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeLuck")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sLucDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_luck.dds");
getWidget(widget, "AttribVal8");
widget->setUserString("ToolTipType", "ImageCaptionText");
widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeLuck")->str);
widget->setUserString("ToolTipText", store.gameSettings.find ("sLucDesc")->str);
widget->setUserString("ToolTipImage", "k\\attribute_luck.dds");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "AttributeToolTip");
widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeLuck")->str);
widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sLucDesc")->str);
widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_luck.dds");
}

@ -18,13 +18,15 @@ namespace MWGui
class StatsWindow : public WindowPinnableBase
{
public:
typedef std::pair<std::string, int> Faction;
typedef std::vector<Faction> FactionList;
typedef std::map<std::string, int> FactionList;
typedef std::vector<int> SkillList;
StatsWindow(WindowManager& parWindowManager);
/// automatically updates all the data in the stats window, but only if it has changed.
void onFrame();
void setBar(const std::string& name, const std::string& tname, int val, int max);
void setPlayerName(const std::string& playerName);
@ -36,8 +38,6 @@ namespace MWGui
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
void configureSkills (const SkillList& major, const SkillList& minor);
void setFactions (const std::vector<Faction>& factions);
void setBirthSign (const std::string &signId);
void setReputation (int reputation) { this->reputation = reputation; }
void setBounty (int bounty) { this->bounty = bounty; }
void updateSkillArea();
@ -46,12 +46,15 @@ namespace MWGui
void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
MyGUI::TextBox* addValueItem(const std::string& text, const std::string& tooltip, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
MyGUI::Widget* addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void updateScroller();
void setupToolTips();
void setFactions (const FactionList& factions);
void setBirthSign (const std::string &signId);
void onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos);
void onWindowResize(MyGUI::Window* window);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
@ -69,11 +72,13 @@ namespace MWGui
std::map<int, MWMechanics::Stat<float> > skillValues;
std::map<int, MyGUI::TextBox*> skillWidgetMap;
std::map<std::string, MyGUI::WidgetPtr> factionWidgetMap;
FactionList factions; ///< Stores a list of factions and the current rank
FactionList mFactions; ///< Stores a list of factions and the current rank
std::string birthSignId;
int reputation, bounty;
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
bool mChanged;
protected:
virtual void onPinToggled();
};

@ -16,6 +16,9 @@ ToolTips::ToolTips(WindowManager* windowManager) :
, mGameMode(true)
, mWindowManager(windowManager)
, mFullHelp(false)
, mEnabled(true)
, mFocusToolTipX(0.0)
, mFocusToolTipY(0.0)
{
getWidget(mDynamicToolTipBox, "DynamicToolTipBox");
@ -27,23 +30,36 @@ ToolTips::ToolTips(WindowManager* windowManager) :
mMainWidget->setNeedMouseFocus(false);
}
void ToolTips::onFrame(float frameDuration)
void ToolTips::setEnabled(bool enabled)
{
/// \todo Store a MWWorld::Ptr in the widget user data, retrieve it here and construct a tooltip dynamically
mEnabled = enabled;
}
void ToolTips::onFrame(float frameDuration)
{
MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox);
mDynamicToolTipBox = mMainWidget->createWidget<Widget>("HUD_Box",
IntCoord(0, 0, mMainWidget->getCoord().width, mMainWidget->getCoord().height),
Align::Stretch, "DynamicToolTipBox");
// start by hiding everything
for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i)
{
mMainWidget->getChildAt(i)->setVisible(false);
}
const IntSize &viewSize = RenderManager::getInstance().getViewSize();
if (!mEnabled)
{
return;
}
if (!mGameMode)
{
Widget* focus = InputManager::getInstance().getMouseFocusWidget();
if (focus == 0)
{
mDynamicToolTipBox->setVisible(false);
return;
}
@ -55,30 +71,77 @@ void ToolTips::onFrame(float frameDuration)
ToolTipInfo info;
if (type == "")
{
mDynamicToolTipBox->setVisible(false);
return;
}
else if (type == "Text")
{
info.text = text;
}
else if (type == "CaptionText")
else if (type == "ItemPtr")
{
std::string caption = focus->getUserString("ToolTipCaption");
info.caption = caption;
info.text = text;
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
tooltipSize = getToolTipViaPtr(false);
}
else if (type == "ImageCaptionText")
else if (type == "Layout")
{
std::string caption = focus->getUserString("ToolTipCaption");
std::string image = focus->getUserString("ToolTipImage");
std::string sizeString = focus->getUserString("ToolTipImageSize");
// tooltip defined in the layout
MyGUI::Widget* tooltip;
getWidget(tooltip, focus->getUserString("ToolTipLayout"));
tooltip->setVisible(true);
if (!tooltip->isUserString("DontResize"))
{
tooltip->setCoord(0, 0, 450, 300); // this is the maximum width of the tooltip before it starts word-wrapping
tooltipSize = MyGUI::IntSize(0, tooltip->getSize().height);
}
else
tooltipSize = tooltip->getSize();
std::map<std::string, std::string> userStrings = focus->getUserStrings();
for (std::map<std::string, std::string>::iterator it = userStrings.begin();
it != userStrings.end(); ++it)
{
if (it->first == "ToolTipType"
|| it->first == "ToolTipLayout")
continue;
size_t underscorePos = it->first.find("_");
std::string propertyKey = it->first.substr(0, underscorePos);
std::string widgetName = it->first.substr(underscorePos+1, it->first.size()-(underscorePos+1));
info.text = text;
info.caption = caption;
info.icon = image;
MyGUI::Widget* w;
getWidget(w, widgetName);
w->setProperty(propertyKey, it->second);
}
for (unsigned int i=0; i<tooltip->getChildCount(); ++i)
{
MyGUI::Widget* w = tooltip->getChildAt(i);
if (w->isUserString("AutoResizeHorizontal"))
{
MyGUI::TextBox* text = w->castType<MyGUI::TextBox>();
tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + text->getTextSize().width + 8);
}
else if (!tooltip->isUserString("DontResize"))
tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + w->getWidth() + 8);
if (w->isUserString("AutoResizeVertical"))
{
MyGUI::TextBox* text = w->castType<MyGUI::TextBox>();
int height = text->getTextSize().height;
if (height > w->getHeight())
{
tooltipSize += MyGUI::IntSize(0, height - w->getHeight());
}
if (height < w->getHeight())
{
tooltipSize -= MyGUI::IntSize(0, w->getHeight() - height);
}
}
}
tooltip->setCoord(0, 0, tooltipSize.width, tooltipSize.height);
}
tooltipSize = createToolTip(info);
else
throw std::runtime_error ("unknown tooltip type");
IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24);
@ -93,7 +156,6 @@ void ToolTips::onFrame(float frameDuration)
}
setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height);
mDynamicToolTipBox->setVisible(true);
}
else
{
@ -101,15 +163,13 @@ void ToolTips::onFrame(float frameDuration)
{
IntSize tooltipSize = getToolTipViaPtr();
// adjust tooltip size to fit its content, position it above the crosshair
/// \todo Slide the tooltip along the bounding box of the focused object (like in Morrowind)
setCoord(std::max(0, viewSize.width/2 - (tooltipSize.width)/2),
std::max(0, viewSize.height/2 - (tooltipSize.height) - 32),
setCoord(viewSize.width/2 - tooltipSize.width/2,
std::max(0, int(mFocusToolTipY*viewSize.height - tooltipSize.height)),
tooltipSize.width,
tooltipSize.height);
mDynamicToolTipBox->setVisible(true);
}
else
mDynamicToolTipBox->setVisible(false);
}
}
@ -128,7 +188,7 @@ void ToolTips::setFocusObject(const MWWorld::Ptr& focus)
mFocusObject = focus;
}
IntSize ToolTips::getToolTipViaPtr ()
IntSize ToolTips::getToolTipViaPtr (bool image)
{
// this the maximum width of the tooltip before it starts word-wrapping
setCoord(0, 0, 300, 300);
@ -145,6 +205,8 @@ IntSize ToolTips::getToolTipViaPtr ()
mDynamicToolTipBox->setVisible(true);
ToolTipInfo info = object.getToolTipInfo(mFocusObject);
if (!image)
info.icon = "";
tooltipSize = createToolTip(info);
}
@ -165,8 +227,10 @@ void ToolTips::findImageExtension(std::string& image)
}
}
IntSize ToolTips::createToolTip(const ToolTipInfo& info)
IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
{
mDynamicToolTipBox->setVisible(true);
std::string caption = info.caption;
std::string image = info.icon;
int imageSize = (image != "") ? 32 : 0;
@ -279,6 +343,9 @@ IntSize ToolTips::createToolTip(const ToolTipInfo& info)
const int chargeTextWidth = chargeText->getTextSize().width + 5;
const int chargeAndTextWidth = chargeWidth + chargeTextWidth;
totalSize.width = std::max(totalSize.width, chargeAndTextWidth);
chargeText->setCoord((totalSize.width - chargeAndTextWidth)/2, coord.top+6, chargeTextWidth, 18);
IntCoord chargeCoord;
@ -350,6 +417,14 @@ std::string ToolTips::getMiscString(const std::string& text, const std::string&
return "\n" + prefix + ": " + text;
}
std::string ToolTips::getCountString(const int value)
{
if (value == 1)
return "";
else
return " (" + boost::lexical_cast<std::string>(value) + ")";
}
void ToolTips::toggleFullHelp()
{
mFullHelp = !mFullHelp;
@ -359,3 +434,9 @@ bool ToolTips::getFullHelp() const
{
return mFullHelp;
}
void ToolTips::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
{
mFocusToolTipX = (min_x + max_x) / 2;
mFocusToolTipY = min_y;
}

@ -39,10 +39,14 @@ namespace MWGui
void enterGameMode();
void enterGuiMode();
void setEnabled(bool enabled);
void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
bool getFullHelp() const;
void setFocusObject(const MWWorld::Ptr& focus);
void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y);
///< set the screen-space position of the tooltip for focused object
static std::string getValueString(const int value, const std::string& prefix);
///< @return "prefix: value" or "" if value is 0
@ -53,6 +57,9 @@ namespace MWGui
static std::string toString(const float value);
static std::string toString(const int value);
static std::string getCountString(const int value);
///< @return blank string if count is 1, or else " (value)"
private:
MyGUI::Widget* mDynamicToolTipBox;
@ -62,14 +69,19 @@ namespace MWGui
void findImageExtension(std::string& image);
MyGUI::IntSize getToolTipViaPtr ();
MyGUI::IntSize getToolTipViaPtr (bool image=true);
///< @return requested tooltip size
MyGUI::IntSize createToolTip(const ToolTipInfo& info);
///< @return requested tooltip size
float mFocusToolTipX;
float mFocusToolTipY;
bool mGameMode;
bool mEnabled;
bool mFullHelp;
};
}

@ -0,0 +1,359 @@
#include "tradewindow.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwsound/soundmanager.hpp"
#include "window_manager.hpp"
#include "inventorywindow.hpp"
namespace MWGui
{
TradeWindow::TradeWindow(WindowManager& parWindowManager) :
WindowBase("openmw_trade_window_layout.xml", parWindowManager)
, ContainerBase(NULL) // no drag&drop
, mCurrentBalance(0)
{
MyGUI::ScrollView* itemView;
MyGUI::Widget* containerWidget;
getWidget(containerWidget, "Items");
getWidget(itemView, "ItemView");
setWidgets(containerWidget, itemView);
getWidget(mFilterAll, "AllButton");
getWidget(mFilterWeapon, "WeaponButton");
getWidget(mFilterApparel, "ApparelButton");
getWidget(mFilterMagic, "MagicButton");
getWidget(mFilterMisc, "MiscButton");
getWidget(mMaxSaleButton, "MaxSaleButton");
getWidget(mCancelButton, "CancelButton");
getWidget(mOfferButton, "OfferButton");
getWidget(mPlayerGold, "PlayerGold");
getWidget(mMerchantGold, "MerchantGold");
getWidget(mIncreaseButton, "IncreaseButton");
getWidget(mDecreaseButton, "DecreaseButton");
getWidget(mTotalBalance, "TotalBalance");
getWidget(mTotalBalanceLabel, "TotalBalanceLabel");
getWidget(mBottomPane, "BottomPane");
// adjust size of buttons to fit text
int curX = 0;
mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height );
curX += mFilterAll->getTextSize().width + 24 + 4;
mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top);
mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height );
curX += mFilterWeapon->getTextSize().width + 24 + 4;
mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top);
mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height );
curX += mFilterApparel->getTextSize().width + 24 + 4;
mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top);
mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height );
curX += mFilterMagic->getTextSize().width + 24 + 4;
mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top);
mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height );
mFilterAll->setStateSelected(true);
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked);
mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked);
mMaxSaleButton->setSize(MyGUI::IntSize(mMaxSaleButton->getTextSize().width + 24, mMaxSaleButton->getHeight()));
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
mCancelButton->setCoord(mBottomPane->getWidth()-cancelButtonWidth,
mCancelButton->getTop(),
cancelButtonWidth,
mCancelButton->getHeight());
int offerButtonWidth = mOfferButton->getTextSize().width + 24;
mOfferButton->setCoord(mBottomPane->getWidth()-cancelButtonWidth-offerButtonWidth-8,
mOfferButton->getTop(),
offerButtonWidth,
mOfferButton->getHeight());
setCoord(400, 0, 400, 300);
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &TradeWindow::onWindowResize);
}
void TradeWindow::startTrade(MWWorld::Ptr actor)
{
setTitle(MWWorld::Class::get(actor).getName(actor));
mCurrentBalance = 0;
mWindowManager.getInventoryWindow()->startTrade();
mBoughtItems.clear();
ContainerBase::openContainer(actor);
updateLabels();
}
void TradeWindow::onFilterChanged(MyGUI::Widget* _sender)
{
if (_sender == mFilterAll)
setFilter(ContainerBase::Filter_All);
else if (_sender == mFilterWeapon)
setFilter(ContainerBase::Filter_Weapon);
else if (_sender == mFilterApparel)
setFilter(ContainerBase::Filter_Apparel);
else if (_sender == mFilterMagic)
setFilter(ContainerBase::Filter_Magic);
else if (_sender == mFilterMisc)
setFilter(ContainerBase::Filter_Misc);
mFilterAll->setStateSelected(false);
mFilterWeapon->setStateSelected(false);
mFilterApparel->setStateSelected(false);
mFilterMagic->setStateSelected(false);
mFilterMisc->setStateSelected(false);
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
}
void TradeWindow::onWindowResize(MyGUI::Window* _sender)
{
drawItems();
}
void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender)
{
// were there any items traded at all?
MWWorld::ContainerStore& playerBought = mWindowManager.getInventoryWindow()->getBoughtItems();
MWWorld::ContainerStore& merchantBought = getBoughtItems();
if (playerBought.begin() == playerBought.end() && merchantBought.begin() == merchantBought.end())
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog11")->str, std::vector<std::string>());
return;
}
// check if the player can afford this
if (mCurrentBalance < 0 && mWindowManager.getInventoryWindow()->getPlayerGold() < std::abs(mCurrentBalance))
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog1")->str, std::vector<std::string>());
return;
}
// check if the merchant can afford this
int merchantgold;
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
if (ref->base->npdt52.gold == -10)
merchantgold = ref->base->npdt12.gold;
else
merchantgold = ref->base->npdt52.gold;
}
else // ESM::Creature
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
merchantgold = ref->base->data.gold;
}
if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog2")->str, std::vector<std::string>());
return;
}
// success! make the item transfer.
transferBoughtItems();
mWindowManager.getInventoryWindow()->transferBoughtItems();
// add or remove gold from the player.
bool goldFound = false;
MWWorld::Ptr gold;
MWWorld::ContainerStore& playerStore = mWindowManager.getInventoryWindow()->getContainerStore();
for (MWWorld::ContainerStoreIterator it = playerStore.begin();
it != playerStore.end(); ++it)
{
if (MWWorld::Class::get(*it).getName(*it) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
{
goldFound = true;
gold = *it;
}
}
if (goldFound)
{
gold.getRefData().setCount(gold.getRefData().getCount() + mCurrentBalance);
}
else
{
assert(mCurrentBalance > 0);
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001");
ref.getPtr().getRefData().setCount(mCurrentBalance);
playerStore.add(ref.getPtr());
}
std::string sound = "Item Gold Up";
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
mWindowManager.setGuiMode(GM_Game);
}
void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
{
// i give you back your stuff!
returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore());
// now gimme back my stuff!
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
mWindowManager.setGuiMode(GM_Game);
}
void TradeWindow::updateLabels()
{
mPlayerGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sYourGold")->str
+ " " + boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
if (mCurrentBalance > 0)
{
mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalSold")->str);
mTotalBalance->setCaption(boost::lexical_cast<std::string>(mCurrentBalance));
}
else
{
mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalCost")->str);
mTotalBalance->setCaption(boost::lexical_cast<std::string>(-mCurrentBalance));
}
int merchantgold;
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
if (ref->base->npdt52.gold == -10)
merchantgold = ref->base->npdt12.gold;
else
merchantgold = ref->base->npdt52.gold;
}
else // ESM::Creature
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
merchantgold = ref->base->data.gold;
}
mMerchantGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSellerGold")->str
+ " " + boost::lexical_cast<std::string>(merchantgold));
}
std::vector<MWWorld::Ptr> TradeWindow::getEquippedItems()
{
std::vector<MWWorld::Ptr> items;
if (mContainer.getTypeName() == typeid(ESM::Creature).name())
{
// creatures don't have equipment slots.
return items;
}
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
if (it != invStore.end())
{
items.push_back(*it);
}
}
return items;
}
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
{
int services = 0;
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
if (ref->base->hasAI)
services = ref->base->AI.services;
}
else if (mContainer.getTypeName() == typeid(ESM::Creature).name())
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
if (ref->base->hasAI)
services = ref->base->AI.services;
}
if (item.getTypeName() == typeid(ESM::Weapon).name())
return services & ESM::NPC::Weapon;
else if (item.getTypeName() == typeid(ESM::Armor).name())
return services & ESM::NPC::Armor;
else if (item.getTypeName() == typeid(ESM::Clothing).name())
return services & ESM::NPC::Clothing;
else if (item.getTypeName() == typeid(ESM::Book).name())
return services & ESM::NPC::Books;
else if (item.getTypeName() == typeid(ESM::Ingredient).name())
return services & ESM::NPC::Ingredients;
else if (item.getTypeName() == typeid(ESM::Tool).name())
return services & ESM::NPC::Picks;
else if (item.getTypeName() == typeid(ESM::Probe).name())
return services & ESM::NPC::Probes;
else if (item.getTypeName() == typeid(ESM::Light).name())
return services & ESM::NPC::Lights;
else if (item.getTypeName() == typeid(ESM::Apparatus).name())
return services & ESM::NPC::Apparatus;
else if (item.getTypeName() == typeid(ESM::Repair).name())
return services & ESM::NPC::RepairItem;
else if (item.getTypeName() == typeid(ESM::Miscellaneous).name())
return services & ESM::NPC::Misc;
return false;
}
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()
{
std::vector<MWWorld::Ptr> items;
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
for (MWWorld::ContainerStoreIterator it = invStore.begin();
it != invStore.end(); ++it)
{
if (!npcAcceptsItem(*it))
items.push_back(*it);
}
return items;
}
void TradeWindow::sellToNpc(MWWorld::Ptr item, int count)
{
/// \todo price adjustment depending on merchantile skill
mCurrentBalance -= MWWorld::Class::get(item).getValue(item) * count;
updateLabels();
}
void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count)
{
/// \todo price adjustment depending on merchantile skill
mCurrentBalance += MWWorld::Class::get(item).getValue(item) * count;
updateLabels();
}
}

@ -0,0 +1,75 @@
#ifndef MWGUI_TRADEWINDOW_H
#define MWGUI_TRADEWINDOW_H
#include "container.hpp"
#include "window_base.hpp"
#include "../mwworld/ptr.hpp"
namespace MyGUI
{
class Gui;
class Widget;
}
namespace MWGui
{
class WindowManager;
}
namespace MWGui
{
class TradeWindow : public ContainerBase, public WindowBase
{
public:
TradeWindow(WindowManager& parWindowManager);
void startTrade(MWWorld::Ptr actor);
void sellToNpc(MWWorld::Ptr item, int count); ///< only used for adjusting the gold balance
void buyFromNpc(MWWorld::Ptr item, int count); ///< only used for adjusting the gold balance
bool npcAcceptsItem(MWWorld::Ptr item);
protected:
MyGUI::Button* mFilterAll;
MyGUI::Button* mFilterWeapon;
MyGUI::Button* mFilterApparel;
MyGUI::Button* mFilterMagic;
MyGUI::Button* mFilterMisc;
MyGUI::Button* mIncreaseButton;
MyGUI::Button* mDecreaseButton;
MyGUI::TextBox* mTotalBalanceLabel;
MyGUI::TextBox* mTotalBalance;
MyGUI::Widget* mBottomPane;
MyGUI::Button* mMaxSaleButton;
MyGUI::Button* mCancelButton;
MyGUI::Button* mOfferButton;
MyGUI::TextBox* mPlayerGold;
MyGUI::TextBox* mMerchantGold;
int mCurrentBalance;
void onWindowResize(MyGUI::Window* _sender);
void onFilterChanged(MyGUI::Widget* _sender);
void onOfferButtonClicked(MyGUI::Widget* _sender);
void onCancelButtonClicked(MyGUI::Widget* _sender);
// don't show items that the NPC has equipped in his trade-window.
virtual bool ignoreEquippedItems() { return true; }
virtual std::vector<MWWorld::Ptr> getEquippedItems();
virtual bool isTrading() { return true; }
virtual bool isTradeWindow() { return true; }
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
void updateLabels();
};
}
#endif

@ -1,5 +1,4 @@
#include "window_manager.hpp"
#include "layouts.hpp"
#include "text_input.hpp"
#include "review.hpp"
#include "dialogue.hpp"
@ -7,10 +6,16 @@
#include "map_window.hpp"
#include "stats_window.hpp"
#include "messagebox.hpp"
#include "container.hpp"
#include "inventorywindow.hpp"
#include "tooltips.hpp"
#include "scrollwindow.hpp"
#include "bookwindow.hpp"
#include "list.hpp"
#include "hud.hpp"
#include "mainmenu.hpp"
#include "countdialog.hpp"
#include "tradewindow.hpp"
#include "../mwmechanics/mechanicsmanager.hpp"
#include "../mwinput/inputmanager.hpp"
@ -35,19 +40,20 @@ WindowManager::WindowManager(
, hud(NULL)
, map(NULL)
, menu(NULL)
, stats(NULL)
, mStatsWindow(NULL)
, mToolTips(NULL)
, mMessageBoxManager(NULL)
, console(NULL)
, mJournal(NULL)
, mDialogueWindow(nullptr)
, mBookWindow(NULL)
, mScrollWindow(NULL)
, dialogueWindow(nullptr)
, mCountDialog(NULL)
, mTradeWindow(NULL)
, mCharGen(NULL)
, playerClass()
, playerName()
, playerRaceId()
, playerBirthSignId()
, playerAttributes()
, playerMajorSkills()
, playerMinorSkills()
@ -71,7 +77,7 @@ WindowManager::WindowManager(
// Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath);
gui = mGuiManager->getGui();
//Register own widgets with MyGUI
MyGUI::FactoryManager::getInstance().registerFactory<DialogueHistory>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSkill>("Widget");
@ -82,22 +88,36 @@ WindowManager::WindowManager(
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWDynamicStat>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWList>("Widget");
MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
// Get size info from the Gui object
assert(gui);
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
int h = MyGUI::RenderManager::getInstance().getViewSize().height;
hud = new HUD(w,h, showFPSLevel);
MyGUI::Widget* dragAndDropWidget = gui->createWidgetT("Widget","",0,0,w,h,MyGUI::Align::Default,"DragAndDrop","DragAndDropWidget");
dragAndDropWidget->setVisible(false);
mDragAndDrop = new DragAndDrop();
mDragAndDrop->mIsOnDragAndDrop = false;
mDragAndDrop->mDraggedWidget = 0;
mDragAndDrop->mDragAndDropWidget = dragAndDropWidget;
menu = new MainMenu(w,h);
map = new MapWindow(*this);
stats = new StatsWindow(*this);
mStatsWindow = new StatsWindow(*this);
console = new Console(w,h, extensions);
mJournal = new JournalWindow(*this);
mMessageBoxManager = new MessageBoxManager(this);
dialogueWindow = new DialogueWindow(*this);
mInventoryWindow = new InventoryWindow(*this,mDragAndDrop);
mTradeWindow = new TradeWindow(*this);
mDialogueWindow = new DialogueWindow(*this);
mContainerWindow = new ContainerWindow(*this,mDragAndDrop);
hud = new HUD(w,h, showFPSLevel, mDragAndDrop);
mToolTips = new ToolTips(this);
mScrollWindow = new ScrollWindow(*this);
mBookWindow = new BookWindow(*this);
mCountDialog = new CountDialog(*this);
// The HUD is always on
hud->setVisible(true);
@ -127,12 +147,17 @@ WindowManager::~WindowManager()
delete hud;
delete map;
delete menu;
delete stats;
delete mStatsWindow;
delete mJournal;
delete dialogueWindow;
delete mDialogueWindow;
delete mContainerWindow;
delete mInventoryWindow;
delete mToolTips;
delete mCharGen;
delete mDragAndDrop;
delete mBookWindow;
delete mScrollWindow;
delete mTradeWindow;
cleanupGarbage();
}
@ -183,12 +208,15 @@ void WindowManager::updateVisible()
// Start out by hiding everything except the HUD
map->setVisible(false);
menu->setVisible(false);
stats->setVisible(false);
mStatsWindow->setVisible(false);
console->disable();
mJournal->setVisible(false);
mDialogueWindow->setVisible(false);
mContainerWindow->setVisible(false);
mInventoryWindow->setVisible(false);
mScrollWindow->setVisible(false);
mBookWindow->setVisible(false);
dialogueWindow->setVisible(false);
mTradeWindow->setVisible(false);
// Mouse is visible whenever we're not in game mode
MyGUI::PointerManager::getInstance().setVisible(isGuiMode());
@ -234,11 +262,23 @@ void WindowManager::updateVisible()
// Show the windows we want
map -> setVisible( (eff & GW_Map) != 0 );
stats -> setVisible( (eff & GW_Stats) != 0 );
mStatsWindow -> setVisible( (eff & GW_Stats) != 0 );
mInventoryWindow->setVisible(true);
mInventoryWindow->openInventory();
break;
}
case GM_Container:
mContainerWindow->setVisible(true);
mInventoryWindow->setVisible(true);
mInventoryWindow->openInventory();
break;
case GM_Dialogue:
dialogueWindow->open();
mDialogueWindow->open();
break;
case GM_Barter:
mInventoryWindow->setVisible(true);
mInventoryWindow->openInventory();
mTradeWindow->setVisible(true);
break;
case GM_InterMessageBox:
if(!mMessageBoxManager->isInteractiveMessageBox()) {
@ -260,7 +300,7 @@ void WindowManager::updateVisible()
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
stats->setValue (id, value);
mStatsWindow->setValue (id, value);
static const char *ids[] =
{
@ -290,13 +330,13 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int
void WindowManager::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
{
stats->setValue(parSkill, value);
mStatsWindow->setValue(parSkill, value);
playerSkillValues[parSkill] = value;
}
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
{
stats->setValue (id, value);
mStatsWindow->setValue (id, value);
hud->setValue (id, value);
if (id == "HBar")
{
@ -329,7 +369,7 @@ MWMechanics::DynamicStat<int> WindowManager::getValue(const std::string& id)
void WindowManager::setValue (const std::string& id, const std::string& value)
{
stats->setValue (id, value);
mStatsWindow->setValue (id, value);
if (id=="name")
playerName = value;
else if (id=="race")
@ -338,46 +378,35 @@ void WindowManager::setValue (const std::string& id, const std::string& value)
void WindowManager::setValue (const std::string& id, int value)
{
stats->setValue (id, value);
mStatsWindow->setValue (id, value);
}
void WindowManager::setPlayerClass (const ESM::Class &class_)
{
playerClass = class_;
stats->setValue("class", playerClass.name);
mStatsWindow->setValue("class", playerClass.name);
}
void WindowManager::configureSkills (const SkillList& major, const SkillList& minor)
{
stats->configureSkills (major, minor);
mStatsWindow->configureSkills (major, minor);
playerMajorSkills = major;
playerMinorSkills = minor;
}
void WindowManager::setFactions (const FactionList& factions)
{
stats->setFactions (factions);
}
void WindowManager::setBirthSign (const std::string &signId)
{
stats->setBirthSign (signId);
playerBirthSignId = signId;
}
void WindowManager::setReputation (int reputation)
{
stats->setReputation (reputation);
mStatsWindow->setReputation (reputation);
}
void WindowManager::setBounty (int bounty)
{
stats->setBounty (bounty);
mStatsWindow->setBounty (bounty);
}
void WindowManager::updateSkillArea()
{
stats->updateSkillArea();
mStatsWindow->updateSkillArea();
}
void WindowManager::removeDialog(OEngine::GUI::Layout*dialog)
@ -417,11 +446,11 @@ const std::string &WindowManager::getGameSettingString(const std::string &id, co
void WindowManager::onDialogueWindowBye()
{
if (dialogueWindow)
if (mDialogueWindow)
{
//FIXME set some state and stuff?
//removeDialog(dialogueWindow);
dialogueWindow->setVisible(false);
mDialogueWindow->setVisible(false);
}
setGuiMode(GM_Game);
}
@ -430,6 +459,16 @@ void WindowManager::onFrame (float frameDuration)
{
mMessageBoxManager->onFrame(frameDuration);
mToolTips->onFrame(frameDuration);
if (mDragAndDrop->mIsOnDragAndDrop)
{
assert(mDragAndDrop->mDraggedWidget);
mDragAndDrop->mDraggedWidget->setPosition(MyGUI::InputManager::getInstance().getMousePosition());
}
mInventoryWindow->onFrame();
mStatsWindow->onFrame();
}
const ESMS::ESMStore& WindowManager::getStore() const
@ -516,6 +555,11 @@ void WindowManager::setFocusObject(const MWWorld::Ptr& focus)
mToolTips->setFocusObject(focus);
}
void WindowManager::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y)
{
mToolTips->setFocusObjectScreenCoords(min_x, min_y, max_x, max_y);
}
void WindowManager::toggleFullHelp()
{
mToolTips->toggleFullHelp();
@ -525,3 +569,31 @@ bool WindowManager::getFullHelp() const
{
return mToolTips->getFullHelp();
}
void WindowManager::setWeaponVisibility(bool visible)
{
hud->weapBox->setVisible(visible);
}
void WindowManager::setSpellVisibility(bool visible)
{
hud->spellBox->setVisible(visible);
}
void WindowManager::setMouseVisible(bool visible)
{
MyGUI::PointerManager::getInstance().setVisible(visible);
}
void WindowManager::setDragDrop(bool dragDrop)
{
mToolTips->setEnabled(!dragDrop);
MWBase::Environment::get().getInputManager()->setDragDrop(dragDrop);
}
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
{
const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(_tag);
if (setting && setting->type == ESM::VT_String)
_result = setting->str;
}

@ -14,11 +14,15 @@
#include <vector>
#include <set>
#include "MyGUI_UString.h"
#include <components/esm_store/store.hpp>
#include <openengine/ogre/renderer.hpp>
#include <openengine/gui/manager.hpp>
#include "../mwmechanics/stat.hpp"
#include "../mwworld/ptr.hpp"
#include "mode.hpp"
namespace MyGUI
@ -61,14 +65,18 @@ namespace MWGui
class Console;
class JournalWindow;
class CharacterCreation;
class ContainerWindow;
class DragAndDrop;
class InventoryWindow;
class ToolTips;
class ScrollWindow;
class BookWindow;
class TextInputDialog;
class InfoBoxDialog;
class DialogueWindow;
class MessageBoxManager;
class CountDialog;
class TradeWindow;
struct ClassPoint
{
@ -125,10 +133,13 @@ namespace MWGui
updateVisible();
}
MWGui::DialogueWindow* getDialogueWindow() {return dialogueWindow;}
MWGui::DialogueWindow* getDialogueWindow() {return mDialogueWindow;}
MWGui::ContainerWindow* getContainerWindow() {return mContainerWindow;}
MWGui::InventoryWindow* getInventoryWindow() {return mInventoryWindow;}
MWGui::BookWindow* getBookWindow() {return mBookWindow;}
MWGui::ScrollWindow* getScrollWindow() {return mScrollWindow;}
MWGui::CountDialog* getCountDialog() {return mCountDialog;}
MWGui::TradeWindow* getTradeWindow() {return mTradeWindow;}
MyGUI::Gui* getGui() const { return gui; }
@ -150,8 +161,6 @@ namespace MWGui
void setPlayerClass (const ESM::Class &class_); ///< set current class of player
void configureSkills (const SkillList& major, const SkillList& minor); ///< configure skill groups, each set contains the skill ID for that group.
void setFactions (const FactionList& factions); ///< set faction and rank to display on stat window, use an empty vector to disable
void setBirthSign (const std::string &signId); ///< set birth sign to display on stat window, use an empty string to disable.
void setReputation (int reputation); ///< set the current reputation value
void setBounty (int bounty); ///< set the current bounty value
void updateSkillArea(); ///< update display of skills, factions, birth sign, reputation and bounty
@ -161,6 +170,10 @@ namespace MWGui
void setPlayerDir(const float x, const float y); ///< set player view direction in map space
void setFocusObject(const MWWorld::Ptr& focus);
void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y);
void setMouseVisible(bool visible);
void setDragDrop(bool dragDrop);
void toggleFogOfWar();
void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
@ -176,6 +189,8 @@ namespace MWGui
void setHMSVisibility(bool visible);
// sets the visibility of the hud minimap
void setMinimapVisibility(bool visible);
void setWeaponVisibility(bool visible);
void setSpellVisibility(bool visible);
template<typename T>
void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
@ -203,13 +218,18 @@ namespace MWGui
MapWindow *map;
MainMenu *menu;
ToolTips *mToolTips;
StatsWindow *stats;
StatsWindow *mStatsWindow;
MessageBoxManager *mMessageBoxManager;
Console *console;
JournalWindow* mJournal;
DialogueWindow *dialogueWindow;
DialogueWindow *mDialogueWindow;
ContainerWindow *mContainerWindow;
DragAndDrop* mDragAndDrop;
InventoryWindow *mInventoryWindow;
ScrollWindow* mScrollWindow;
BookWindow* mBookWindow;
CountDialog* mCountDialog;
TradeWindow* mTradeWindow;
CharacterCreation* mCharGen;
@ -217,7 +237,6 @@ namespace MWGui
ESM::Class playerClass;
std::string playerName;
std::string playerRaceId;
std::string playerBirthSignId;
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > playerAttributes;
SkillList playerMajorSkills, playerMinorSkills;
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > playerSkillValues;
@ -252,6 +271,12 @@ namespace MWGui
size_t mBatchCount;
void onDialogueWindowBye();
/**
* Called when MyGUI tries to retrieve a tag. This usually corresponds to a GMST string,
* so this method will retrieve the GMST with the name \a _tag and place the result in \a _result
*/
void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result);
};
template<typename T>

@ -60,7 +60,7 @@ namespace MWInput
A_CycleWeaponRight,
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
A_ToggleWalk, //Toggle Walking/Running
A_Crouch,
A_Crouch,
A_QuickSave,
A_QuickLoad,
@ -88,6 +88,8 @@ namespace MWInput
MWGui::WindowManager &windows;
OMW::Engine& mEngine;
bool mDragDrop;
/* InputImpl Methods */
@ -143,6 +145,9 @@ namespace MWInput
{
using namespace MWGui;
if (mDragDrop)
return;
GuiMode mode = windows.getMode();
// Toggle between game mode and inventory mode
@ -159,6 +164,9 @@ namespace MWInput
{
using namespace MWGui;
if (mDragDrop)
return;
GuiMode mode = windows.getMode();
// Switch to console mode no matter what mode we are currently
@ -219,7 +227,8 @@ namespace MWInput
poller(input),
player(_player),
windows(_windows),
mEngine (engine)
mEngine (engine),
mDragDrop(false)
{
using namespace OEngine::Input;
using namespace OEngine::Render;
@ -314,9 +323,14 @@ namespace MWInput
poller.bind(A_MoveRight, KC_D);
poller.bind(A_MoveForward, KC_W);
poller.bind(A_MoveBackward, KC_S);
poller.bind(A_Jump, KC_E);
poller.bind(A_Crouch, KC_LCONTROL);
poller.bind(A_Jump, KC_E);
poller.bind(A_Crouch, KC_LCONTROL);
}
void setDragDrop(bool dragDrop)
{
mDragDrop = dragDrop;
}
//NOTE: Used to check for movement keys
@ -364,7 +378,7 @@ namespace MWInput
else
player.setForwardBackward (0);
if (poller.isDown(A_Jump))
if (poller.isDown(A_Jump))
player.setUpDown (1);
else if (poller.isDown(A_Crouch))
player.setUpDown (-1);
@ -426,4 +440,9 @@ namespace MWInput
{
impl->update();
}
void MWInputManager::setDragDrop(bool dragDrop)
{
impl->setDragDrop(dragDrop);
}
}

@ -50,6 +50,8 @@ namespace MWInput
void update();
void setDragDrop(bool dragDrop);
void setGuiMode(MWGui::GuiMode mode);
};
}

@ -20,6 +20,7 @@ namespace MWMechanics
{
// NPCs other than the player can only have one faction. But for the sake of consistency
// we use the same data structure for the PC and the NPCs.
/// \note the faction key must be in lowercase
std::map<std::string, int> mFactionRank;
Stat<float> mSkill[27];

@ -219,7 +219,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
info.type = LT_Normal;
// random starting phase for the animation
info.time = Ogre::Math::RangeRandom(0, 2 * M_PI);
info.time = Ogre::Math::RangeRandom(0, 2 * Ogre::Math::PI);
// adjust the lights depending if we're in an interior or exterior cell
// quadratic means the light intensity falls off quite fast, resulting in a
@ -367,7 +367,7 @@ void Objects::update(const float dt)
// Light animation (pulse & flicker)
it->time += dt;
const float phase = std::fmod(static_cast<double> (it->time), (32 * 2 * M_PI)) * 20;
const float phase = std::fmod(static_cast<double> (it->time), static_cast<double>(32 * 2 * Ogre::Math::PI)) * 20;
float pulseConstant;
// These formulas are just guesswork, but they work pretty well

@ -521,4 +521,43 @@ void RenderingManager::switchToExterior()
mRendering.getScene()->setCameraRelativeRendering(true);
}
Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
{
Ogre::Matrix4 mat = mRendering.getCamera()->getViewMatrix();
const Ogre::Vector3* corners = bounds.getAllCorners();
float min_x = 1.0f, max_x = 0.0f, min_y = 1.0f, max_y = 0.0f;
// expand the screen-space bounding-box so that it completely encloses
// the object's AABB
for (int i=0; i<8; i++)
{
Ogre::Vector3 corner = corners[i];
// multiply the AABB corner vertex by the view matrix to
// get a camera-space vertex
corner = mat * corner;
// make 2D relative/normalized coords from the view-space vertex
// by dividing out the Z (depth) factor -- this is an approximation
float x = corner.x / corner.z + 0.5;
float y = corner.y / corner.z + 0.5;
if (x < min_x)
min_x = x;
if (x > max_x)
max_x = x;
if (y < min_y)
min_y = y;
if (y > max_y)
max_y = y;
}
return Vector4(min_x, min_y, max_x, max_y);
}
} // namespace

@ -151,6 +151,10 @@ class RenderingManager: private RenderingInterface {
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
/// references that are currently not in the rendered scene should be ignored.
Ogre::Vector4 boundingBoxToScreen(Ogre::AxisAlignedBox bounds);
///< transform the specified bounding box (in world coordinates) into screen coordinates.
/// @return packed vector4 (min_x, min_y, max_x, max_y)
private:
void setAmbientMode();

@ -155,10 +155,10 @@ void Water::changeCell(const ESM::Cell* cell)
{
mTop = cell->water;
setHeight(mTop);
if(!(cell->data.flags & cell->Interior))
mWaterNode->setPosition(getSceneNodeCoordinates(cell->data.gridX, cell->data.gridY));
else
setHeight(mTop);
}
void Water::setHeight(const float height)

@ -1,6 +1,8 @@
#include "statsextensions.hpp"
#include <boost/algorithm/string.hpp>
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
@ -362,6 +364,7 @@ namespace MWScript
factionID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
}
boost::algorithm::to_lower(factionID);
if(factionID != "")
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
@ -390,6 +393,7 @@ namespace MWScript
factionID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
}
boost::algorithm::to_lower(factionID);
if(factionID != "")
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
@ -422,6 +426,7 @@ namespace MWScript
factionID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
}
boost::algorithm::to_lower(factionID);
if(factionID != "")
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
@ -459,6 +464,7 @@ namespace MWScript
factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).mFactionRank.begin()->first;
}
}
boost::algorithm::to_lower(factionID);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
if(factionID!="")
{

@ -0,0 +1,54 @@
#include "actionequip.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/player.hpp"
namespace MWWorld
{
ActionEquip::ActionEquip (const MWWorld::Ptr& object) : mObject (object)
{
}
void ActionEquip::execute ()
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(player).getContainerStore(player));
// slots that this item can be equipped in
std::pair<std::vector<int>, bool> slots = MWWorld::Class::get(mObject).getEquipmentSlots(mObject);
// retrieve ContainerStoreIterator to the item
MWWorld::ContainerStoreIterator it = invStore.begin();
for (; it != invStore.end(); ++it)
{
if (*it == mObject)
{
break;
}
}
assert(it != invStore.end());
// equip the item in the first free slot
for (std::vector<int>::const_iterator slot=slots.first.begin();
slot!=slots.first.end(); ++slot)
{
// if all slots are occupied, replace the last slot
if (slot == --slots.first.end())
{
invStore.equip(*slot, it);
break;
}
if (invStore.getSlot(*slot) == invStore.end())
{
// slot is not occupied
invStore.equip(*slot, it);
break;
}
}
}
}

@ -0,0 +1,21 @@
#ifndef GAME_MWWORLD_ACTIONEQUIP_H
#define GAME_MWWORLD_ACTIONEQUIP_H
#include "action.hpp"
#include "ptr.hpp"
namespace MWWorld
{
class ActionEquip : public Action
{
Ptr mObject;
public:
/// @param item to equip
ActionEquip (const Ptr& object);
virtual void execute ();
};
}
#endif

@ -0,0 +1,22 @@
#include "actionopen.hpp"
#include "../mwbase/environment.hpp"
#include "class.hpp"
#include "world.hpp"
#include "containerstore.hpp"
#include "../mwclass/container.hpp"
#include "../mwgui/window_manager.hpp"
#include "../mwgui/container.hpp"
namespace MWWorld
{
ActionOpen::ActionOpen (const MWWorld::Ptr& container) : mContainer (container) {
mContainer = container;
}
void ActionOpen::execute ()
{
MWBase::Environment::get().getWindowManager()->setGuiMode(MWGui::GM_Container);
MWBase::Environment::get().getWindowManager()->getContainerWindow()->open(mContainer);
}
}

@ -0,0 +1,22 @@
#ifndef GAME_MWWORLD_ACTIONOPEN_H
#define GAME_MWWORLD_ACTIONOPEN_H
#include "action.hpp"
#include "ptr.hpp"
namespace MWWorld
{
class ActionOpen : public Action
{
Ptr mContainer;
public:
ActionOpen (const Ptr& container);
///< \param The Container the Player has activated.
virtual void execute ();
};
}
#endif // ACTIONOPEN_H

@ -18,7 +18,8 @@ namespace MWWorld
MWWorld::Class::get (player).getContainerStore (player).add (mObject);
// remove from world
MWBase::Environment::get().getWorld()->deleteObject (mObject);
// remove from world, if the item is currently in the world (it could also be in a container)
if (mObject.isInCell())
MWBase::Environment::get().getWorld()->deleteObject (mObject);
}
}

@ -142,7 +142,7 @@ namespace MWWorld
throw std::logic_error ("value not supported by this class");
}
float Class::getCapactiy (const MWWorld::Ptr& ptr) const
float Class::getCapacity (const MWWorld::Ptr& ptr) const
{
throw std::runtime_error ("capacity not supported by this class");
}
@ -182,6 +182,12 @@ namespace MWWorld
throw std::runtime_error ("class does not have an down sound");
}
std::string Class::getInventoryIcon (const MWWorld::Ptr& ptr) const
{
throw std::runtime_error ("class does not have any inventory icon");
}
MWGui::ToolTipInfo Class::getToolTipInfo (const Ptr& ptr) const
{
throw std::runtime_error ("class does not have a tool tip");

@ -164,7 +164,7 @@ namespace MWWorld
///< Return trade value of the object. Throws an exception, if the object can't be traded.
/// (default implementation: throws an exception)
virtual float getCapactiy (const MWWorld::Ptr& ptr) const;
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
///< Return total weight that fits into the object. Throws an exception, if the object can't
/// hold other objects.
/// (default implementation: throws an exception)
@ -190,6 +190,9 @@ namespace MWWorld
///< Return the down sound ID of \a ptr or throw an exception, if class does not support ID retrieval
/// (default implementation: throw an exception)
virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const;
///< Return name of inventory icon.
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
/// (default implementation: return empty string)

@ -5,8 +5,13 @@
#include <typeinfo>
#include <stdexcept>
#include <boost/algorithm/string.hpp>
#include <components/esm/loadcont.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "manualref.hpp"
#include "refdata.hpp"
#include "class.hpp"
@ -29,6 +34,12 @@ namespace
return sum;
}
bool compare_string_ci(std::string str1, std::string str2)
{
boost::algorithm::to_lower(str1);
return str1 == str2;
}
}
MWWorld::ContainerStore::ContainerStore() : mStateId (0), mCachedWeight (0), mWeightUpToDate (false) {}
@ -58,10 +69,41 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
return false;
}
void MWWorld::ContainerStore::add (const Ptr& ptr)
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
{
int type = getType(ptr);
// gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001
// this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold)
if (MWWorld::Class::get(ptr).getName(ptr) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *gold =
ptr.get<ESM::Miscellaneous>();
if (compare_string_ci(gold->ref.refID, "gold_001")
|| compare_string_ci(gold->ref.refID, "gold_005")
|| compare_string_ci(gold->ref.refID, "gold_010")
|| compare_string_ci(gold->ref.refID, "gold_025")
|| compare_string_ci(gold->ref.refID, "gold_100"))
{
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001");
int count = (ptr.getRefData().getCount() == 1) ? gold->base->data.value : ptr.getRefData().getCount();
ref.getPtr().getRefData().setCount(count);
for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
{
if (compare_string_ci((*iter).get<ESM::Miscellaneous>()->ref.refID, "gold_001"))
{
(*iter).getRefData().setCount( (*iter).getRefData().getCount() + count);
flagAsModified();
return iter;
}
}
return addImpl(ref.getPtr());
}
}
// determine whether to stack or not
for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
{
@ -71,33 +113,36 @@ void MWWorld::ContainerStore::add (const Ptr& ptr)
iter->getRefData().setCount( iter->getRefData().getCount() + ptr.getRefData().getCount() );
flagAsModified();
return;
return iter;
}
}
// if we got here, this means no stacking
addImpl(ptr);
return addImpl(ptr);
}
void MWWorld::ContainerStore::addImpl (const Ptr& ptr)
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImpl (const Ptr& ptr)
{
ContainerStoreIterator it = begin();
switch (getType(ptr))
{
case Type_Potion: potions.list.push_back (*ptr.get<ESM::Potion>()); break;
case Type_Apparatus: appas.list.push_back (*ptr.get<ESM::Apparatus>()); break;
case Type_Armor: armors.list.push_back (*ptr.get<ESM::Armor>()); break;
case Type_Book: books.list.push_back (*ptr.get<ESM::Book>()); break;
case Type_Clothing: clothes.list.push_back (*ptr.get<ESM::Clothing>()); break;
case Type_Ingredient: ingreds.list.push_back (*ptr.get<ESM::Ingredient>()); break;
case Type_Light: lights.list.push_back (*ptr.get<ESM::Light>()); break;
case Type_Lockpick: lockpicks.list.push_back (*ptr.get<ESM::Tool>()); break;
case Type_Miscellaneous: miscItems.list.push_back (*ptr.get<ESM::Miscellaneous>()); break;
case Type_Probe: probes.list.push_back (*ptr.get<ESM::Probe>()); break;
case Type_Repair: repairs.list.push_back (*ptr.get<ESM::Repair>()); break;
case Type_Weapon: weapons.list.push_back (*ptr.get<ESM::Weapon>()); break;
case Type_Potion: potions.list.push_back (*ptr.get<ESM::Potion>()); it = ContainerStoreIterator(this, --potions.list.end()); break;
case Type_Apparatus: appas.list.push_back (*ptr.get<ESM::Apparatus>()); it = ContainerStoreIterator(this, --appas.list.end()); break;
case Type_Armor: armors.list.push_back (*ptr.get<ESM::Armor>()); it = ContainerStoreIterator(this, --armors.list.end()); break;
case Type_Book: books.list.push_back (*ptr.get<ESM::Book>()); it = ContainerStoreIterator(this, --books.list.end()); break;
case Type_Clothing: clothes.list.push_back (*ptr.get<ESM::Clothing>()); it = ContainerStoreIterator(this, --clothes.list.end()); break;
case Type_Ingredient: ingreds.list.push_back (*ptr.get<ESM::Ingredient>()); it = ContainerStoreIterator(this, --ingreds.list.end()); break;
case Type_Light: lights.list.push_back (*ptr.get<ESM::Light>()); it = ContainerStoreIterator(this, --lights.list.end()); break;
case Type_Lockpick: lockpicks.list.push_back (*ptr.get<ESM::Tool>()); it = ContainerStoreIterator(this, --lockpicks.list.end()); break;
case Type_Miscellaneous: miscItems.list.push_back (*ptr.get<ESM::Miscellaneous>()); it = ContainerStoreIterator(this, --miscItems.list.end()); break;
case Type_Probe: probes.list.push_back (*ptr.get<ESM::Probe>()); it = ContainerStoreIterator(this, --probes.list.end()); break;
case Type_Repair: repairs.list.push_back (*ptr.get<ESM::Repair>()); it = ContainerStoreIterator(this, --repairs.list.end()); break;
case Type_Weapon: weapons.list.push_back (*ptr.get<ESM::Weapon>()); it = ContainerStoreIterator(this, --weapons.list.end()); break;
}
flagAsModified();
return it;
}
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const ESMS::ESMStore& store)
@ -113,7 +158,7 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const ESMS:
continue;
}
ref.getPtr().getRefData().setCount (iter->count);
ref.getPtr().getRefData().setCount (std::abs(iter->count)); /// \todo implement item restocking (indicated by negative count)
add (ref.getPtr());
}
@ -228,8 +273,38 @@ MWWorld::ContainerStoreIterator::ContainerStoreIterator (int mask, ContainerStor
: mType (0), mMask (mask), mContainer (container)
{
nextType();
if (mType==-1 || (**this).getRefData().getCount())
return;
++*this;
}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Potion, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Potion), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mPotion(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Apparatus, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Apparatus), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mApparatus(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Armor, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Armor), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mArmor(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Book, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Book), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mBook(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Clothing, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Clothing), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mClothing(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Ingredient, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Ingredient), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mIngredient(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Light, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Light), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLight(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Tool, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Lockpick), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLockpick(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Miscellaneous, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Miscellaneous), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mMiscellaneous(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Probe, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Probe), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mProbe(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Repair, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Repair), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mRepair(iterator){}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Weapon, RefData>::List::iterator iterator)
: mType(MWWorld::ContainerStore::Type_Weapon), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mWeapon(iterator){}
void MWWorld::ContainerStoreIterator::incType()
{
if (mType==0)
@ -249,7 +324,7 @@ void MWWorld::ContainerStoreIterator::nextType()
{
incType();
if (mType & mMask)
if ((mType & mMask) && mType>0)
if (resetIterator())
break;
}

@ -66,16 +66,18 @@ namespace MWWorld
ContainerStoreIterator end();
void add (const Ptr& ptr);
ContainerStoreIterator add (const Ptr& ptr);
///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed)
///
/// \note The item pointed to is not required to exist beyond this function call.
///
/// \attention Do not add items to an existing stack by increasing the count instead of
/// calling this function!
///
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item.
protected:
void addImpl (const Ptr& ptr);
ContainerStoreIterator addImpl (const Ptr& ptr);
///< Add the item to this container (no stacking)
virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);
@ -141,6 +143,20 @@ namespace MWWorld
ContainerStoreIterator (int mask, ContainerStore *container);
///< Begin-iterator
// construct iterator using a CellRefList iterator
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Potion, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Apparatus, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Armor, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Book, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Clothing, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Ingredient, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Light, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Tool, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Miscellaneous, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Probe, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Repair, RefData>::List::iterator);
ContainerStoreIterator (ContainerStore *container, ESMS::CellRefList<ESM::Weapon, RefData>::List::iterator);
void incType();
void nextType();

@ -80,7 +80,7 @@ namespace MWWorld
Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
mRender.getViewport()->getWidth()/2,
mRender.getViewport()->getHeight()/2);
btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y);
btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); /// \todo make this distance (ray length) configurable
return result;
}
@ -95,6 +95,29 @@ namespace MWWorld
return !(result.first == "");
}
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY)
{
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
mouseX,
mouseY);
Ogre::Vector3 from = ray.getOrigin();
Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable
btVector3 _from, _to;
// OGRE to MW coordinates
_from = btVector3(from.x, -from.z, from.y);
_to = btVector3(to.x, -to.z, to.y);
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
if (result.first == "")
return std::make_pair(false, Ogre::Vector3());
else
{
return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable
}
}
void PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
{
//set the DebugRenderingMode. To disable it,set it to 0

@ -53,6 +53,9 @@ namespace MWWorld
// cast ray, return true if it hit something
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY);
///< cast ray from the mouse, return true if it hit something and the first result (in OGRE coordinates)
void insertObjectPhysics(const MWWorld::Ptr& ptr, std::string model);
void insertActorPhysics(const MWWorld::Ptr&, std::string model);

@ -77,6 +77,11 @@ namespace MWWorld
return mCell;
}
bool isInCell() const
{
return (mCell != 0);
}
void setContainerStore (ContainerStore *store);
///< Must not be called on references that are in a cell.

@ -9,45 +9,49 @@
#include "../mwgui/window_manager.hpp"
#include "../mwworld/world.hpp" /// FIXME
#include "../mwworld/manualref.hpp" /// FIXME
#include "ptr.hpp"
#include "player.hpp"
#include "class.hpp"
#include "cellfunctors.hpp"
namespace {
template<typename T>
void insertCellRefList(MWRender::RenderingManager& rendering,
T& cellRefList, ESMS::CellStore<MWWorld::RefData> &cell, MWWorld::PhysicsSystem& physics)
namespace
{
if (!cellRefList.list.empty())
{
const MWWorld::Class& class_ =
MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.list.begin(), &cell));
for (typename T::List::iterator it = cellRefList.list.begin();
it != cellRefList.list.end(); it++)
template<typename T>
void insertCellRefList(MWRender::RenderingManager& rendering,
T& cellRefList, ESMS::CellStore<MWWorld::RefData> &cell, MWWorld::PhysicsSystem& physics)
{
if (!cellRefList.list.empty())
{
if (it->mData.getCount() || it->mData.isEnabled())
{
MWWorld::Ptr ptr (&*it, &cell);
const MWWorld::Class& class_ =
MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.list.begin(), &cell));
try
{
rendering.addObject(ptr);
class_.insertObject(ptr, physics);
class_.enable (ptr);
}
catch (const std::exception& e)
for (typename T::List::iterator it = cellRefList.list.begin();
it != cellRefList.list.end(); it++)
{
if (it->mData.getCount() || it->mData.isEnabled())
{
std::string error ("error during rendering: ");
std::cerr << error + e.what() << std::endl;
MWWorld::Ptr ptr (&*it, &cell);
try
{
rendering.addObject(ptr);
class_.insertObject(ptr, physics);
class_.enable (ptr);
}
catch (const std::exception& e)
{
std::string error ("error during rendering: ");
std::cerr << error + e.what() << std::endl;
}
}
}
}
}
}
}
@ -306,30 +310,157 @@ namespace MWWorld
mCellChanged = false;
}
void Scene::insertCell(ESMS::CellStore<MWWorld::RefData> &cell)
{
// Loop through all references in the cell
insertCellRefList(mRendering, cell.activators, cell, *mPhysics);
insertCellRefList(mRendering, cell.potions, cell, *mPhysics);
insertCellRefList(mRendering, cell.appas, cell, *mPhysics);
insertCellRefList(mRendering, cell.armors, cell, *mPhysics);
insertCellRefList(mRendering, cell.books, cell, *mPhysics);
insertCellRefList(mRendering, cell.clothes, cell, *mPhysics);
insertCellRefList(mRendering, cell.containers, cell, *mPhysics);
insertCellRefList(mRendering, cell.creatures, cell, *mPhysics);
insertCellRefList(mRendering, cell.doors, cell, *mPhysics);
insertCellRefList(mRendering, cell.ingreds, cell, *mPhysics);
insertCellRefList(mRendering, cell.creatureLists, cell, *mPhysics);
insertCellRefList(mRendering, cell.itemLists, cell, *mPhysics);
insertCellRefList(mRendering, cell.lights, cell, *mPhysics);
insertCellRefList(mRendering, cell.lockpicks, cell, *mPhysics);
insertCellRefList(mRendering, cell.miscItems, cell, *mPhysics);
insertCellRefList(mRendering, cell.npcs, cell, *mPhysics);
insertCellRefList(mRendering, cell.probes, cell, *mPhysics);
insertCellRefList(mRendering, cell.repairs, cell, *mPhysics);
insertCellRefList(mRendering, cell.statics, cell, *mPhysics);
insertCellRefList(mRendering, cell.weapons, cell, *mPhysics);
}
void Scene::insertCell(ESMS::CellStore<MWWorld::RefData> &cell)
{
// Loop through all references in the cell
insertCellRefList(mRendering, cell.activators, cell, *mPhysics);
insertCellRefList(mRendering, cell.potions, cell, *mPhysics);
insertCellRefList(mRendering, cell.appas, cell, *mPhysics);
insertCellRefList(mRendering, cell.armors, cell, *mPhysics);
insertCellRefList(mRendering, cell.books, cell, *mPhysics);
insertCellRefList(mRendering, cell.clothes, cell, *mPhysics);
insertCellRefList(mRendering, cell.containers, cell, *mPhysics);
insertCellRefList(mRendering, cell.creatures, cell, *mPhysics);
insertCellRefList(mRendering, cell.doors, cell, *mPhysics);
insertCellRefList(mRendering, cell.ingreds, cell, *mPhysics);
insertCellRefList(mRendering, cell.creatureLists, cell, *mPhysics);
insertCellRefList(mRendering, cell.itemLists, cell, *mPhysics);
insertCellRefList(mRendering, cell.lights, cell, *mPhysics);
insertCellRefList(mRendering, cell.lockpicks, cell, *mPhysics);
insertCellRefList(mRendering, cell.miscItems, cell, *mPhysics);
insertCellRefList(mRendering, cell.npcs, cell, *mPhysics);
insertCellRefList(mRendering, cell.probes, cell, *mPhysics);
insertCellRefList(mRendering, cell.repairs, cell, *mPhysics);
insertCellRefList(mRendering, cell.statics, cell, *mPhysics);
insertCellRefList(mRendering, cell.weapons, cell, *mPhysics);
}
/// \todo this whole code needs major clean up, and doesn't belong in this class.
void Scene::insertObject(MWWorld::Ptr ptr, Ptr::CellStore* cell)
{
std::string type = ptr.getTypeName();
MWWorld::Ptr newPtr;
// insert into the correct CellRefList
if (type == typeid(ESM::Potion).name())
{
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData>* ref = ptr.get<ESM::Potion>();
cell->potions.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->potions.list.back(), cell);
}
else if (type == typeid(ESM::Apparatus).name())
{
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData>* ref = ptr.get<ESM::Apparatus>();
cell->appas.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->appas.list.back(), cell);
}
else if (type == typeid(ESM::Armor).name())
{
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData>* ref = ptr.get<ESM::Armor>();
cell->armors.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->armors.list.back(), cell);
}
else if (type == typeid(ESM::Book).name())
{
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData>* ref = ptr.get<ESM::Book>();
cell->books.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->books.list.back(), cell);
}
else if (type == typeid(ESM::Clothing).name())
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData>* ref = ptr.get<ESM::Clothing>();
cell->clothes.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->clothes.list.back(), cell);
}
else if (type == typeid(ESM::Ingredient).name())
{
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData>* ref = ptr.get<ESM::Ingredient>();
cell->ingreds.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->ingreds.list.back(), cell);
}
else if (type == typeid(ESM::Light).name())
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData>* ref = ptr.get<ESM::Light>();
cell->lights.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->lights.list.back(), cell);
}
else if (type == typeid(ESM::Tool).name())
{
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData>* ref = ptr.get<ESM::Tool>();
cell->lockpicks.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->lockpicks.list.back(), cell);
}
else if (type == typeid(ESM::Repair).name())
{
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData>* ref = ptr.get<ESM::Repair>();
cell->repairs.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->repairs.list.back(), cell);
}
else if (type == typeid(ESM::Probe).name())
{
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData>* ref = ptr.get<ESM::Probe>();
cell->probes.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->probes.list.back(), cell);
}
else if (type == typeid(ESM::Weapon).name())
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData>* ref = ptr.get<ESM::Weapon>();
cell->weapons.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->weapons.list.back(), cell);
}
else if (type == typeid(ESM::Miscellaneous).name())
{
// if this is gold, we need to fetch the correct mesh depending on the amount of gold.
if (MWWorld::Class::get(ptr).getName(ptr) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
{
int goldAmount = ptr.getRefData().getCount();
std::string base = "Gold_001";
if (goldAmount >= 100)
base = "Gold_100";
else if (goldAmount >= 25)
base = "Gold_025";
else if (goldAmount >= 10)
base = "Gold_010";
else if (goldAmount >= 5)
base = "Gold_005";
MWWorld::ManualRef newRef (MWBase::Environment::get().getWorld()->getStore(), base);
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData>* ref = newRef.getPtr().get<ESM::Miscellaneous>();
cell->miscItems.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->miscItems.list.back(), cell);
ESM::Position& p = newPtr.getRefData().getPosition();
p.pos[0] = ptr.getRefData().getPosition().pos[0];
p.pos[1] = ptr.getRefData().getPosition().pos[1];
p.pos[2] = ptr.getRefData().getPosition().pos[2];
}
else
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData>* ref = ptr.get<ESM::Miscellaneous>();
cell->miscItems.list.push_back( *ref );
newPtr = MWWorld::Ptr(&cell->miscItems.list.back(), cell);
}
}
else
throw std::runtime_error("Trying to insert object of unhandled type");
newPtr.getRefData().setCount(ptr.getRefData().getCount());
ptr.getRefData().setCount(0);
newPtr.getRefData().enable();
mRendering.addObject(newPtr);
MWWorld::Class::get(newPtr).insertObject(newPtr, *mPhysics);
MWWorld::Class::get(newPtr).enable(newPtr);
}
}

@ -100,6 +100,10 @@ namespace MWWorld
void insertCell(ESMS::CellStore<MWWorld::RefData> &cell);
/// this method is only meant for dropping objects into the gameworld from a container
/// and thus only handles object types that can be placed in a container
void insertObject(MWWorld::Ptr object, Ptr::CellStore* cell);
void update (float duration);
};
}

@ -21,7 +21,7 @@
#include "class.hpp"
#include "player.hpp"
#include "weather.hpp"
#include "manualref.hpp"
#include "refdata.hpp"
#include "globals.hpp"
#include "cellfunctors.hpp"
@ -774,7 +774,24 @@ namespace MWWorld
// inform the GUI about focused object
try
{
MWBase::Environment::get().getWindowManager()->setFocusObject(getPtrViaHandle(mFacedHandle));
MWWorld::Ptr object = getPtrViaHandle(mFacedHandle);
MWBase::Environment::get().getWindowManager()->setFocusObject(object);
// retrieve object dimensions so we know where to place the floating label
Ogre::SceneNode* node = object.getRefData().getBaseNode();
Ogre::AxisAlignedBox bounds;
int i;
for (i=0; i<node->numAttachedObjects(); ++i)
{
Ogre::MovableObject* ob = node->getAttachedObject(i);
bounds.merge(ob->getWorldBoundingBox());
}
if (bounds.isFinite())
{
Vector4 screenCoords = mRendering->boundingBoxToScreen(bounds);
MWBase::Environment::get().getWindowManager()->setFocusObjectScreenCoords(
screenCoords[0], screenCoords[1], screenCoords[2], screenCoords[3]);
}
}
catch (std::runtime_error&)
{
@ -954,4 +971,57 @@ namespace MWWorld
mRendering->toggleWater();
}
bool World::placeObject(MWWorld::Ptr object, float cursorX, float cursorY)
{
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
if (!result.first)
return false;
MWWorld::Ptr::CellStore* cell;
if (isCellExterior())
{
int cellX, cellY;
positionToIndex(result.second[0], -result.second[2], cellX, cellY);
cell = mCells.getExterior(cellX, cellY);
}
else
cell = getPlayer().getPlayer().getCell();
ESM::Position& pos = object.getRefData().getPosition();
pos.pos[0] = result.second[0];
pos.pos[1] = -result.second[2];
pos.pos[2] = result.second[1];
mWorldScene->insertObject(object, cell);
/// \todo retrieve the bounds of the object and translate it accordingly
return true;
}
bool World::canPlaceObject(float cursorX, float cursorY)
{
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
/// \todo also check if the wanted position is on a flat surface, and not e.g. against a vertical wall!
if (!result.first)
return false;
return true;
}
void World::dropObjectOnGround(MWWorld::Ptr object)
{
MWWorld::Ptr::CellStore* cell = getPlayer().getPlayer().getCell();
float* playerPos = getPlayer().getPlayer().getRefData().getPosition().pos;
ESM::Position& pos = object.getRefData().getPosition();
pos.pos[0] = playerPos[0];
pos.pos[1] = playerPos[1];
pos.pos[2] = playerPos[2];
mWorldScene->insertObject(object, cell);
}
}

@ -267,6 +267,17 @@ namespace MWWorld
void update (float duration);
bool placeObject(MWWorld::Ptr object, float cursorX, float cursorY);
///< place an object into the gameworld at the specified cursor position
/// @param object
/// @param cursor X (relative 0-1)
/// @param cursor Y (relative 0-1)
/// @return true if the object was placed, or false if it was rejected because the position is too far away
void dropObjectOnGround(MWWorld::Ptr object);
bool canPlaceObject(float cursorX, float cursorY);
///< @return true if it is possible to place on object at specified cursor location
};
}

@ -19,9 +19,15 @@ void Creature::load(ESMReader &esm, const std::string& id)
inventory.load(esm);
// More subrecords:
if (esm.isNextSub("AIDT"))
{
esm.getHExact(&AI, sizeof(AI));
hasAI = true;
}
else
hasAI = false;
// AIDT - data (12 bytes, unknown)
// More subrecords:
// AI_W - wander (14 bytes, i don't understand it)
// short distance
// byte duration
@ -33,8 +39,8 @@ void Creature::load(ESMReader &esm, const std::string& id)
// AI_F - follow?
// AI_E - escort?
// AI_A - activate?
esm.skipRecord();
}
}

@ -51,6 +51,15 @@ struct Creature
int gold;
}; // 96 bytes
struct AIDTstruct
{
// These are probabilities
char hello, u1, fight, flee, alarm, u2, u3, u4;
// The last u's might be the skills that this NPC can train you
// in?
int services; // See the NPC::Services enum
}; // 12 bytes
NPDTstruct data;
int flags;
@ -61,6 +70,9 @@ struct Creature
// Defined in loadcont.hpp
InventoryList inventory;
bool hasAI;
AIDTstruct AI;
std::string mId;
void load(ESMReader &esm, const std::string& id);

@ -31,6 +31,35 @@ namespace ESM
"sSkillSpeechcraft",
"sSkillHandtohand",
};
const std::string Skill::sIconNames[Length] = {
"combat_block.dds",
"combat_armor.dds",
"combat_mediumarmor.dds",
"combat_heavyarmor.dds",
"combat_blunt.dds",
"combat_longblade.dds",
"combat_axe.dds",
"combat_spear.dds",
"combat_athletics.dds",
"magic_enchant.dds",
"magic_destruction.dds",
"magic_alteration.dds",
"magic_illusion.dds",
"magic_conjuration.dds",
"magic_mysticism.dds",
"magic_restoration.dds",
"magic_alchemy.dds",
"magic_unarmored.dds",
"stealth_security.dds",
"stealth_sneak.dds",
"stealth_acrobatics.dds",
"stealth_lightarmor.dds",
"stealth_shortblade.dds",
"stealth_marksman.dds",
"stealth_mercantile.dds",
"stealth_speechcraft.dds",
"stealth_handtohand.dds",
};
const boost::array<Skill::SkillEnum, Skill::Length> Skill::skillIds = {{
Block,
Armorer,

@ -64,6 +64,7 @@ struct Skill
Length
};
static const std::string sSkillNameIds[Length];
static const std::string sIconNames[Length];
static const boost::array<SkillEnum, Length> skillIds;
void load(ESMReader &esm);

@ -36,6 +36,7 @@ configure_file("${SDIR}/openmw_chargen_review_layout.xml" "${DDIR}/openmw_charge
configure_file("${SDIR}/openmw_dialogue_window_layout.xml" "${DDIR}/openmw_dialogue_window_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_dialogue_window_skin.xml" "${DDIR}/openmw_dialogue_window_skin.xml" COPYONLY)
configure_file("${SDIR}/openmw_inventory_window_layout.xml" "${DDIR}/openmw_inventory_window_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_container_window_layout.xml" "${DDIR}/openmw_container_window_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY)
configure_file("${SDIR}/openmw_mainmenu_layout.xml" "${DDIR}/openmw_mainmenu_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_mainmenu_skin.xml" "${DDIR}/openmw_mainmenu_skin.xml" COPYONLY)
@ -54,6 +55,8 @@ configure_file("${SDIR}/openmw_tooltips.xml" "${DDIR}/openmw_tooltips.xml" COPYO
configure_file("${SDIR}/openmw_scroll_layout.xml" "${DDIR}/openmw_scroll_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_scroll_skin.xml" "${DDIR}/openmw_scroll_skin.xml" COPYONLY)
configure_file("${SDIR}/openmw_book_layout.xml" "${DDIR}/openmw_book_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_count_window_layout.xml" "${DDIR}/openmw_count_window_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_trade_window_layout.xml" "${DDIR}/openmw_trade_window_layout.xml" COPYONLY)
configure_file("${SDIR}/atlas1.cfg" "${DDIR}/atlas1.cfg" COPYONLY)
configure_file("${SDIR}/smallbars.png" "${DDIR}/smallbars.png" COPYONLY)
configure_file("${SDIR}/transparent.png" "${DDIR}/transparent.png" COPYONLY)

@ -13,6 +13,7 @@
<Code range="1025 1105"/>
<Code range="8470"/>
<Code range="8216 8217"/> <!-- Single quotes -->
<Code range="8220 8221"/> <!-- Right and Left Double Quotation mark -->
<Code hide="128"/>
<Code hide="1026 1039"/>
<Code hide="1104"/>

@ -26,4 +26,9 @@
<Property key="Size" value="32 32"/>
<Property key="Resource" value="DResize2PointerImage"/>
</Resource>
<Resource type="ResourceImageSetPointer" name="drop_ground">
<Property key="Point" value="0 24"/>
<Property key="Size" value="32 32"/>
<Property key="Resource" value="DropGroundPointerImage"/>
</Resource>
</MyGUI>

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

Loading…
Cancel
Save