mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-22 00:23:51 +00:00
d9dd7073cf
Previously, client mods adding packet-sending scripts to the spawn area made clients send the associated packets as soon as they inputted their character name when joining a server using those mods. This made the clients either get disconnected for not replying to a handshake first, or it made them get kicked for sending object packets that are disallowed for players who are not logged in. To fix this, LocalPlayer's hasFinishedCharGen() has been replaced with isLoggedIn(), because the former was already returning true when players inputted their names.
729 lines
24 KiB
C++
729 lines
24 KiB
C++
#include "quickkeysmenu.hpp"
|
|
|
|
#include <MyGUI_EditBox.h>
|
|
#include <MyGUI_Button.h>
|
|
#include <MyGUI_Gui.h>
|
|
#include <MyGUI_ImageBox.h>
|
|
|
|
#include <components/esm/esmwriter.hpp>
|
|
#include <components/esm/quickkeys.hpp>
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Include additional headers for multiplayer purposes
|
|
*/
|
|
#include <components/openmw-mp/Log.hpp>
|
|
#include "../mwmp/Main.hpp"
|
|
#include "../mwmp/LocalPlayer.hpp"
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
#include "../mwworld/inventorystore.hpp"
|
|
#include "../mwworld/class.hpp"
|
|
#include "../mwworld/player.hpp"
|
|
#include "../mwworld/esmstore.hpp"
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
|
#include "../mwbase/world.hpp"
|
|
#include "../mwbase/windowmanager.hpp"
|
|
|
|
#include "../mwmechanics/spellcasting.hpp"
|
|
#include "../mwmechanics/creaturestats.hpp"
|
|
#include "../mwmechanics/actorutil.hpp"
|
|
|
|
#include "itemselection.hpp"
|
|
#include "spellview.hpp"
|
|
#include "itemwidget.hpp"
|
|
#include "sortfilteritemmodel.hpp"
|
|
|
|
|
|
namespace MWGui
|
|
{
|
|
|
|
QuickKeysMenu::QuickKeysMenu()
|
|
: WindowBase("openmw_quickkeys_menu.layout")
|
|
, mKey(std::vector<keyData>(10))
|
|
, mSelected(nullptr)
|
|
, mActivated(nullptr)
|
|
, mAssignDialog(0)
|
|
, mItemSelectionDialog(0)
|
|
, mMagicSelectionDialog(0)
|
|
|
|
{
|
|
getWidget(mOkButton, "OKButton");
|
|
getWidget(mInstructionLabel, "InstructionLabel");
|
|
|
|
mMainWidget->setSize(mMainWidget->getWidth(),
|
|
mMainWidget->getHeight() +
|
|
(mInstructionLabel->getTextSize().height - mInstructionLabel->getHeight()));
|
|
|
|
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onOkButtonClicked);
|
|
center();
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
mKey[i].index = i+1;
|
|
getWidget(mKey[i].button, "QuickKey" + MyGUI::utility::toString(i+1));
|
|
mKey[i].button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
|
|
|
|
unassign(&mKey[i]);
|
|
}
|
|
}
|
|
|
|
void QuickKeysMenu::clear()
|
|
{
|
|
mActivated = nullptr;
|
|
|
|
for (int i=0; i<10; ++i)
|
|
{
|
|
unassign(&mKey[i]);
|
|
}
|
|
}
|
|
|
|
QuickKeysMenu::~QuickKeysMenu()
|
|
{
|
|
delete mAssignDialog;
|
|
delete mItemSelectionDialog;
|
|
delete mMagicSelectionDialog;
|
|
}
|
|
|
|
void QuickKeysMenu::onOpen()
|
|
{
|
|
WindowBase::onOpen();
|
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
|
|
|
// Check if quick keys are still valid
|
|
for (int i=0; i<10; ++i)
|
|
{
|
|
switch (mKey[i].type)
|
|
{
|
|
case Type_Unassigned:
|
|
case Type_HandToHand:
|
|
case Type_Magic:
|
|
break;
|
|
case Type_Item:
|
|
case Type_MagicItem:
|
|
{
|
|
MWWorld::Ptr item = *mKey[i].button->getUserData<MWWorld::Ptr>();
|
|
// Make sure the item is available and is not broken
|
|
if (!item || item.getRefData().getCount() < 1 ||
|
|
(item.getClass().hasItemHealth(item) &&
|
|
item.getClass().getItemHealth(item) <= 0))
|
|
{
|
|
// Try searching for a compatible replacement
|
|
item = store.findReplacement(mKey[i].id);
|
|
|
|
if (item)
|
|
mKey[i].button->setUserData(MWWorld::Ptr(item));
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void QuickKeysMenu::unassign(keyData* key)
|
|
{
|
|
key->button->clearUserStrings();
|
|
key->button->setItem(MWWorld::Ptr());
|
|
|
|
while (key->button->getChildCount()) // Destroy number label
|
|
MyGUI::Gui::getInstance().destroyWidget(key->button->getChildAt(0));
|
|
|
|
if (key->index == 10)
|
|
{
|
|
key->type = Type_HandToHand;
|
|
|
|
MyGUI::ImageBox* image = key->button->createWidget<MyGUI::ImageBox>("ImageBox",
|
|
MyGUI::IntCoord(14, 13, 32, 32), MyGUI::Align::Default);
|
|
|
|
image->setImageTexture("icons\\k\\stealth_handtohand.dds");
|
|
image->setNeedMouseFocus(false);
|
|
}
|
|
else
|
|
{
|
|
key->type = Type_Unassigned;
|
|
key->id = "";
|
|
key->name = "";
|
|
|
|
MyGUI::TextBox* textBox = key->button->createWidgetReal<MyGUI::TextBox>("SandText",
|
|
MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default);
|
|
|
|
textBox->setTextAlign(MyGUI::Align::Center);
|
|
textBox->setCaption(MyGUI::utility::toString(key->index));
|
|
textBox->setNeedMouseFocus(false);
|
|
}
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Send a PLAYER_QUICKKEYS packet whenever a key is unassigned, but only if the player
|
|
is logged in on the server, so as to avoid doing anything doing at startup when all
|
|
quick keys get unassigned by default
|
|
*/
|
|
if (mwmp::Main::get().getLocalPlayer()->isLoggedIn() && !mwmp::Main::get().getLocalPlayer()->isReceivingQuickKeys)
|
|
{
|
|
mwmp::Main::get().getLocalPlayer()->sendQuickKey(key->index, Type_Unassigned);
|
|
}
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
}
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Allow unassigning an index directly from elsewhere in the code
|
|
*/
|
|
void QuickKeysMenu::unassignIndex(int index)
|
|
{
|
|
unassign(&mKey[index]);
|
|
}
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
void QuickKeysMenu::onQuickKeyButtonClicked(MyGUI::Widget* sender)
|
|
{
|
|
int index = -1;
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
if (sender == mKey[i].button || sender->getParent() == mKey[i].button)
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
assert(index != -1);
|
|
if (index < 0)
|
|
{
|
|
mSelected = nullptr;
|
|
return;
|
|
}
|
|
|
|
mSelected = &mKey[index];
|
|
|
|
// prevent reallocation of zero key from Type_HandToHand
|
|
if(mSelected->index == 10)
|
|
return;
|
|
|
|
// open assign dialog
|
|
if (!mAssignDialog)
|
|
mAssignDialog = new QuickKeysMenuAssign(this);
|
|
|
|
mAssignDialog->setVisible(true);
|
|
}
|
|
|
|
void QuickKeysMenu::onOkButtonClicked (MyGUI::Widget *sender)
|
|
{
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_QuickKeysMenu);
|
|
}
|
|
|
|
void QuickKeysMenu::onItemButtonClicked(MyGUI::Widget* sender)
|
|
{
|
|
if (!mItemSelectionDialog)
|
|
{
|
|
mItemSelectionDialog = new ItemSelectionDialog("#{sQuickMenu6}");
|
|
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItem);
|
|
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItemCancel);
|
|
}
|
|
mItemSelectionDialog->setVisible(true);
|
|
mItemSelectionDialog->openContainer(MWMechanics::getPlayer());
|
|
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyUsableItems);
|
|
|
|
mAssignDialog->setVisible(false);
|
|
}
|
|
|
|
void QuickKeysMenu::onMagicButtonClicked(MyGUI::Widget* sender)
|
|
{
|
|
if (!mMagicSelectionDialog)
|
|
{
|
|
mMagicSelectionDialog = new MagicSelectionDialog(this);
|
|
}
|
|
mMagicSelectionDialog->setVisible(true);
|
|
|
|
mAssignDialog->setVisible(false);
|
|
}
|
|
|
|
void QuickKeysMenu::onUnassignButtonClicked(MyGUI::Widget* sender)
|
|
{
|
|
unassign(mSelected);
|
|
mAssignDialog->setVisible(false);
|
|
}
|
|
|
|
void QuickKeysMenu::onCancelButtonClicked(MyGUI::Widget* sender)
|
|
{
|
|
mAssignDialog->setVisible(false);
|
|
}
|
|
|
|
void QuickKeysMenu::onAssignItem(MWWorld::Ptr item)
|
|
{
|
|
assert(mSelected);
|
|
|
|
while (mSelected->button->getChildCount()) // Destroy number label
|
|
MyGUI::Gui::getInstance().destroyWidget(mSelected->button->getChildAt(0));
|
|
|
|
mSelected->type = Type_Item;
|
|
mSelected->id = item.getCellRef().getRefId();
|
|
mSelected->name = item.getClass().getName(item);
|
|
|
|
mSelected->button->setItem(item, ItemWidget::Barter);
|
|
mSelected->button->setUserString("ToolTipType", "ItemPtr");
|
|
mSelected->button->setUserData(item);
|
|
|
|
if (mItemSelectionDialog)
|
|
mItemSelectionDialog->setVisible(false);
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Send a PlayerQuickKeys packet whenever a key is assigned to an item
|
|
by a player, not by a packet received from the server
|
|
*/
|
|
if (!mwmp::Main::get().getLocalPlayer()->isReceivingQuickKeys)
|
|
mwmp::Main::get().getLocalPlayer()->sendQuickKey(mSelected->index, Type_Item, item.getCellRef().getRefId());
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
}
|
|
|
|
void QuickKeysMenu::onAssignItemCancel()
|
|
{
|
|
mItemSelectionDialog->setVisible(false);
|
|
}
|
|
|
|
void QuickKeysMenu::onAssignMagicItem(MWWorld::Ptr item)
|
|
{
|
|
assert(mSelected);
|
|
|
|
while (mSelected->button->getChildCount()) // Destroy number label
|
|
MyGUI::Gui::getInstance().destroyWidget(mSelected->button->getChildAt(0));
|
|
|
|
mSelected->type = Type_MagicItem;
|
|
|
|
mSelected->button->setFrame("textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
|
|
mSelected->button->setIcon(item);
|
|
|
|
mSelected->button->setUserString("ToolTipType", "ItemPtr");
|
|
mSelected->button->setUserData(MWWorld::Ptr(item));
|
|
|
|
if (mMagicSelectionDialog)
|
|
mMagicSelectionDialog->setVisible(false);
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Send a PLAYER_QUICKKEYS packet whenever a key is assigned to an item's magic
|
|
*/
|
|
if (!mwmp::Main::get().getLocalPlayer()->isReceivingQuickKeys)
|
|
mwmp::Main::get().getLocalPlayer()->sendQuickKey(mSelected->index, Type_MagicItem, item.getCellRef().getRefId());
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
}
|
|
|
|
void QuickKeysMenu::onAssignMagic(const std::string& spellId)
|
|
{
|
|
assert(mSelected);
|
|
while (mSelected->button->getChildCount()) // Destroy number label
|
|
MyGUI::Gui::getInstance().destroyWidget(mSelected->button->getChildAt(0));
|
|
|
|
mSelected->type = Type_Magic;
|
|
mSelected->id = spellId;
|
|
|
|
mSelected->button->setItem(MWWorld::Ptr());
|
|
mSelected->button->setUserString("ToolTipType", "Spell");
|
|
mSelected->button->setUserString("Spell", spellId);
|
|
|
|
const MWWorld::ESMStore &esmStore = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
// use the icon of the first effect
|
|
const ESM::Spell* spell = esmStore.get<ESM::Spell>().find(spellId);
|
|
|
|
const ESM::MagicEffect* effect =
|
|
esmStore.get<ESM::MagicEffect>().find(spell->mEffects.mList.front().mEffectID);
|
|
|
|
std::string path = effect->mIcon;
|
|
int slashPos = path.rfind('\\');
|
|
path.insert(slashPos+1, "b_");
|
|
path = MWBase::Environment::get().getWindowManager()->correctIconPath(path);
|
|
|
|
mSelected->button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
|
|
mSelected->button->setIcon(path);
|
|
|
|
if (mMagicSelectionDialog)
|
|
mMagicSelectionDialog->setVisible(false);
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Send a PLAYER_QUICKKEYS packet whenever a key is assigned to a spell
|
|
*/
|
|
if (!mwmp::Main::get().getLocalPlayer()->isReceivingQuickKeys)
|
|
mwmp::Main::get().getLocalPlayer()->sendQuickKey(mSelected->index, Type_Magic, spellId);
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
}
|
|
|
|
void QuickKeysMenu::onAssignMagicCancel()
|
|
{
|
|
mMagicSelectionDialog->setVisible(false);
|
|
}
|
|
|
|
void QuickKeysMenu::updateActivatedQuickKey()
|
|
{
|
|
// there is no delayed action, nothing to do.
|
|
if (!mActivated)
|
|
return;
|
|
|
|
activateQuickKey(mActivated->index);
|
|
}
|
|
|
|
void QuickKeysMenu::activateQuickKey(int index)
|
|
{
|
|
assert(index >= 1 && index <= 10);
|
|
|
|
keyData *key = &mKey[index-1];
|
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
|
const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player);
|
|
|
|
// Delay action executing,
|
|
// if player is busy for now (casting a spell, attacking someone, etc.)
|
|
bool isDelayNeeded = MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player)
|
|
|| playerStats.getKnockedDown()
|
|
|| playerStats.getHitRecovery();
|
|
|
|
bool isReturnNeeded = playerStats.isParalyzed() || playerStats.isDead();
|
|
|
|
if (isReturnNeeded && key->type != Type_Item)
|
|
{
|
|
return;
|
|
}
|
|
else if (isDelayNeeded && key->type != Type_Item)
|
|
{
|
|
mActivated = key;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
mActivated = nullptr;
|
|
}
|
|
|
|
if (key->type == Type_Item || key->type == Type_MagicItem)
|
|
{
|
|
MWWorld::Ptr item = *key->button->getUserData<MWWorld::Ptr>();
|
|
|
|
MWWorld::ContainerStoreIterator it = store.begin();
|
|
for (; it != store.end(); ++it)
|
|
{
|
|
if (*it == item)
|
|
break;
|
|
}
|
|
if (it == store.end())
|
|
item = nullptr;
|
|
|
|
// check the item is available and not broken
|
|
if (!item || item.getRefData().getCount() < 1 ||
|
|
(item.getClass().hasItemHealth(item) && item.getClass().getItemHealth(item) <= 0))
|
|
{
|
|
item = store.findReplacement(key->id);
|
|
|
|
if (!item || item.getRefData().getCount() < 1)
|
|
{
|
|
MWBase::Environment::get().getWindowManager()->messageBox(
|
|
"#{sQuickMenu5} " + key->name);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (key->type == Type_Item)
|
|
{
|
|
bool isWeapon = item.getTypeName() == typeid(ESM::Weapon).name();
|
|
bool isTool = item.getTypeName() == typeid(ESM::Probe).name() ||
|
|
item.getTypeName() == typeid(ESM::Lockpick).name();
|
|
|
|
// delay weapon switching if player is busy
|
|
if (isDelayNeeded && (isWeapon || isTool))
|
|
{
|
|
mActivated = key;
|
|
return;
|
|
}
|
|
else if (isReturnNeeded && (isWeapon || isTool))
|
|
{
|
|
return;
|
|
}
|
|
|
|
MWBase::Environment::get().getWindowManager()->useItem(item);
|
|
MWWorld::ConstContainerStoreIterator rightHand = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
|
// change draw state only if the item is in player's right hand
|
|
if (rightHand != store.end() && item == *rightHand)
|
|
{
|
|
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Weapon);
|
|
}
|
|
}
|
|
else if (key->type == Type_MagicItem)
|
|
{
|
|
// equip, if it can be equipped
|
|
if (!item.getClass().getEquipmentSlots(item).first.empty())
|
|
{
|
|
MWBase::Environment::get().getWindowManager()->useItem(item);
|
|
|
|
// make sure that item was successfully equipped
|
|
if (!store.isEquipped(item))
|
|
return;
|
|
}
|
|
|
|
store.setSelectedEnchantItem(it);
|
|
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
|
}
|
|
}
|
|
else if (key->type == Type_Magic)
|
|
{
|
|
std::string spellId = key->id;
|
|
|
|
// Make sure the player still has this spell
|
|
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
|
MWMechanics::Spells& spells = stats.getSpells();
|
|
|
|
if (!spells.hasSpell(spellId))
|
|
{
|
|
const ESM::Spell* spell =
|
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sQuickMenu5} " + spell->mName);
|
|
return;
|
|
}
|
|
|
|
store.setSelectedEnchantItem(store.end());
|
|
MWBase::Environment::get().getWindowManager()
|
|
->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
|
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Send a PlayerMiscellaneous packet with the player's new selected spell
|
|
*/
|
|
mwmp::Main::get().getLocalPlayer()->sendSelectedSpell(spellId);
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
}
|
|
else if (key->type == Type_HandToHand)
|
|
{
|
|
store.unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight, player);
|
|
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Weapon);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Make it possible to add quickKeys from elsewhere in the code
|
|
*/
|
|
void QuickKeysMenu::setSelectedIndex(int index)
|
|
{
|
|
mSelected = &mKey[index];
|
|
}
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------------------------------------------
|
|
|
|
QuickKeysMenuAssign::QuickKeysMenuAssign (QuickKeysMenu* parent)
|
|
: WindowModal("openmw_quickkeys_menu_assign.layout")
|
|
, mParent(parent)
|
|
{
|
|
getWidget(mLabel, "Label");
|
|
getWidget(mItemButton, "ItemButton");
|
|
getWidget(mMagicButton, "MagicButton");
|
|
getWidget(mUnassignButton, "UnassignButton");
|
|
getWidget(mCancelButton, "CancelButton");
|
|
|
|
mItemButton->eventMouseButtonClick += MyGUI::newDelegate(mParent, &QuickKeysMenu::onItemButtonClicked);
|
|
mMagicButton->eventMouseButtonClick += MyGUI::newDelegate(mParent, &QuickKeysMenu::onMagicButtonClicked);
|
|
mUnassignButton->eventMouseButtonClick += MyGUI::newDelegate(mParent, &QuickKeysMenu::onUnassignButtonClicked);
|
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(mParent, &QuickKeysMenu::onCancelButtonClicked);
|
|
|
|
|
|
int maxWidth = mLabel->getTextSize ().width + 24;
|
|
maxWidth = std::max(maxWidth, mItemButton->getTextSize ().width + 24);
|
|
maxWidth = std::max(maxWidth, mMagicButton->getTextSize ().width + 24);
|
|
maxWidth = std::max(maxWidth, mUnassignButton->getTextSize ().width + 24);
|
|
maxWidth = std::max(maxWidth, mCancelButton->getTextSize ().width + 24);
|
|
|
|
mMainWidget->setSize(maxWidth + 24, mMainWidget->getHeight());
|
|
mLabel->setSize(maxWidth, mLabel->getHeight());
|
|
|
|
mItemButton->setCoord((maxWidth - mItemButton->getTextSize().width-24)/2 + 8,
|
|
mItemButton->getTop(),
|
|
mItemButton->getTextSize().width + 24,
|
|
mItemButton->getHeight());
|
|
mMagicButton->setCoord((maxWidth - mMagicButton->getTextSize().width-24)/2 + 8,
|
|
mMagicButton->getTop(),
|
|
mMagicButton->getTextSize().width + 24,
|
|
mMagicButton->getHeight());
|
|
mUnassignButton->setCoord((maxWidth - mUnassignButton->getTextSize().width-24)/2 + 8,
|
|
mUnassignButton->getTop(),
|
|
mUnassignButton->getTextSize().width + 24,
|
|
mUnassignButton->getHeight());
|
|
mCancelButton->setCoord((maxWidth - mCancelButton->getTextSize().width-24)/2 + 8,
|
|
mCancelButton->getTop(),
|
|
mCancelButton->getTextSize().width + 24,
|
|
mCancelButton->getHeight());
|
|
|
|
center();
|
|
}
|
|
|
|
void QuickKeysMenu::write(ESM::ESMWriter &writer)
|
|
{
|
|
writer.startRecord(ESM::REC_KEYS);
|
|
|
|
ESM::QuickKeys keys;
|
|
|
|
for (int i=0; i<10; ++i)
|
|
{
|
|
ItemWidget* button = mKey[i].button;
|
|
|
|
int type = mKey[i].type;
|
|
|
|
ESM::QuickKeys::QuickKey key;
|
|
key.mType = type;
|
|
|
|
switch (type)
|
|
{
|
|
case Type_Unassigned:
|
|
case Type_HandToHand:
|
|
break;
|
|
case Type_Item:
|
|
case Type_MagicItem:
|
|
{
|
|
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
|
|
key.mId = item.getCellRef().getRefId();
|
|
break;
|
|
}
|
|
case Type_Magic:
|
|
std::string spellId = button->getUserString("Spell");
|
|
key.mId = spellId;
|
|
break;
|
|
}
|
|
|
|
keys.mKeys.push_back(key);
|
|
}
|
|
|
|
keys.save(writer);
|
|
|
|
writer.endRecord(ESM::REC_KEYS);
|
|
}
|
|
|
|
void QuickKeysMenu::readRecord(ESM::ESMReader &reader, uint32_t type)
|
|
{
|
|
if (type != ESM::REC_KEYS)
|
|
return;
|
|
|
|
ESM::QuickKeys keys;
|
|
keys.load(reader);
|
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
|
|
|
int i=0;
|
|
for (std::vector<ESM::QuickKeys::QuickKey>::const_iterator it = keys.mKeys.begin(); it != keys.mKeys.end(); ++it)
|
|
{
|
|
if (i >= 10)
|
|
return;
|
|
|
|
mSelected = &mKey[i];
|
|
mSelected->type = (QuickKeysMenu::QuickKeyType) it->mType;
|
|
mSelected->id = it->mId;
|
|
|
|
switch (mSelected->type)
|
|
{
|
|
case Type_Magic:
|
|
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(mSelected->id))
|
|
onAssignMagic(mSelected->id);
|
|
break;
|
|
case Type_Item:
|
|
case Type_MagicItem:
|
|
{
|
|
// Find the item by id
|
|
MWWorld::Ptr item = store.findReplacement(mSelected->id);
|
|
|
|
if (item.isEmpty())
|
|
unassign(&mKey[i]);
|
|
else
|
|
{
|
|
if (mSelected->type == Type_Item)
|
|
onAssignItem(item);
|
|
else if (mSelected->type == Type_MagicItem)
|
|
onAssignMagicItem(item);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case Type_Unassigned:
|
|
case Type_HandToHand:
|
|
unassign(&mKey[i]);
|
|
break;
|
|
}
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------------------------------
|
|
|
|
MagicSelectionDialog::MagicSelectionDialog(QuickKeysMenu* parent)
|
|
: WindowModal("openmw_magicselection_dialog.layout")
|
|
, mParent(parent)
|
|
{
|
|
getWidget(mCancelButton, "CancelButton");
|
|
getWidget(mMagicList, "MagicList");
|
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MagicSelectionDialog::onCancelButtonClicked);
|
|
|
|
mMagicList->setShowCostColumn(false);
|
|
mMagicList->setHighlightSelected(false);
|
|
mMagicList->eventSpellClicked += MyGUI::newDelegate(this, &MagicSelectionDialog::onModelIndexSelected);
|
|
|
|
center();
|
|
}
|
|
|
|
void MagicSelectionDialog::onCancelButtonClicked (MyGUI::Widget *sender)
|
|
{
|
|
exit();
|
|
}
|
|
|
|
bool MagicSelectionDialog::exit()
|
|
{
|
|
mParent->onAssignMagicCancel();
|
|
return true;
|
|
}
|
|
|
|
void MagicSelectionDialog::onOpen ()
|
|
{
|
|
WindowModal::onOpen();
|
|
|
|
mMagicList->setModel(new SpellModel(MWMechanics::getPlayer()));
|
|
mMagicList->resetScrollbars();
|
|
}
|
|
|
|
void MagicSelectionDialog::onModelIndexSelected(SpellModel::ModelIndex index)
|
|
{
|
|
const Spell& spell = mMagicList->getModel()->getItem(index);
|
|
if (spell.mType == Spell::Type_EnchantedItem)
|
|
mParent->onAssignMagicItem(spell.mItem);
|
|
else
|
|
mParent->onAssignMagic(spell.mId);
|
|
}
|
|
|
|
}
|