Allow choosing different apparatus in alchemy window

macos_ci_fix
Kindi 1 year ago committed by kuyondo
parent edd69885ce
commit 6d0dceae34

@ -7,6 +7,7 @@
#include <MyGUI_EditBox.h>
#include <MyGUI_Gui.h>
#include <components/esm3/loadappa.hpp>
#include <components/esm3/loadingr.hpp>
#include <components/esm3/loadmgef.hpp>
@ -77,6 +78,11 @@ namespace MWGui
mIngredients[2]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredients[3]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mApparatus[0]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected);
mApparatus[1]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected);
mApparatus[2]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected);
mApparatus[3]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected);
mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
@ -293,6 +299,80 @@ namespace MWGui
update();
}
void AlchemyWindow::onItemSelected(MWWorld::Ptr item)
{
mItemSelectionDialog->setVisible(false);
int32_t index = item.get<ESM::Apparatus>()->mBase->mData.mType;
const auto& widget = mApparatus[index];
widget->setItem(item);
if (item.isEmpty())
{
widget->clearUserStrings();
return;
}
mAlchemy->addApparatus(item);
widget->setUserString("ToolTipType", "ItemPtr");
widget->setUserData(MWWorld::Ptr(item));
MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item));
update();
}
void AlchemyWindow::onItemCancel()
{
mItemSelectionDialog->setVisible(false);
}
void AlchemyWindow::onApparatusSelected(MyGUI::Widget* _sender)
{
if (_sender->getUserData<MWWorld::Ptr>()->isEmpty()) // if this apparatus slot is empty
{
std::string title;
size_t i = 0;
for (; i < mApparatus.size(); ++i)
{
if (mApparatus[i] == _sender)
break;
}
switch (i)
{
case ESM::Apparatus::AppaType::MortarPestle:
title = "#{sMortar}";
break;
case ESM::Apparatus::AppaType::Alembic:
title = "#{sAlembic}";
break;
case ESM::Apparatus::AppaType::Calcinator:
title = "#{sCalcinator}";
break;
case ESM::Apparatus::AppaType::Retort:
title = "#{sRetort}";
break;
default:
title = "#{sApparatus}";
}
mItemSelectionDialog = std::make_unique<ItemSelectionDialog>(title);
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &AlchemyWindow::onItemSelected);
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &AlchemyWindow::onItemCancel);
mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWMechanics::getPlayer());
mItemSelectionDialog->getSortModel()->setApparatusTypeFilter(i);
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyAlchemyTools);
}
else
removeApparatus(_sender);
update();
}
void AlchemyWindow::onSelectedItem(int index)
{
MWWorld::Ptr item = mSortModel->getItem(index).mBase;
@ -395,6 +475,27 @@ namespace MWGui
update();
}
void AlchemyWindow::removeApparatus(MyGUI::Widget* apparatus)
{
for (size_t i = 0; i < mApparatus.size(); ++i)
{
const auto& widget = mApparatus[i];
if (widget == apparatus)
{
mAlchemy->removeApparatus(i);
if (widget->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(widget->getChildAt(0));
widget->clearUserStrings();
widget->setItem(MWWorld::Ptr());
widget->setUserData(MWWorld::Ptr());
}
}
}
void AlchemyWindow::addRepeatController(MyGUI::Widget* widget)
{
MyGUI::ControllerItem* item

@ -10,6 +10,7 @@
#include <components/widgets/box.hpp>
#include <components/widgets/numericeditbox.hpp>
#include "itemselection.hpp"
#include "windowbase.hpp"
#include "../mwmechanics/alchemy.hpp"
@ -44,6 +45,8 @@ namespace MWGui
};
FilterType mCurrentFilter;
std::unique_ptr<ItemSelectionDialog> mItemSelectionDialog;
ItemView* mItemView;
InventoryItemModel* mModel;
SortFilterItemModel* mSortModel;
@ -63,6 +66,7 @@ namespace MWGui
void onCancelButtonClicked(MyGUI::Widget* _sender);
void onCreateButtonClicked(MyGUI::Widget* _sender);
void onIngredientSelected(MyGUI::Widget* _sender);
void onApparatusSelected(MyGUI::Widget* _sender);
void onAccept(MyGUI::EditBox*);
void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
@ -85,6 +89,10 @@ namespace MWGui
void onSelectedItem(int index);
void removeIngredient(MyGUI::Widget* ingredient);
void removeApparatus(MyGUI::Widget* ingredient);
void onItemSelected(MWWorld::Ptr item);
void onItemCancel();
void createPotions(int count);

@ -32,6 +32,8 @@ namespace MWGui
void setCategory(int category);
void setFilter(int filter);
SortFilterItemModel* getSortModel() { return mSortModel; }
private:
ItemView* mItemView;
SortFilterItemModel* mSortModel;

@ -174,6 +174,7 @@ namespace MWGui
: mCategory(Category_All)
, mFilter(0)
, mSortByType(true)
, mApparatusTypeFilter(-1)
{
mSourceModel = std::move(sourceModel);
}
@ -311,6 +312,16 @@ namespace MWGui
return false;
}
if ((mFilter & Filter_OnlyAlchemyTools))
{
if (base.getType() != ESM::Apparatus::sRecordId)
return false;
int32_t apparatusType = base.get<ESM::Apparatus>()->mBase->mData.mType;
if (mApparatusTypeFilter >= 0 && apparatusType != mApparatusTypeFilter)
return false;
}
std::string compare = Utf8Stream::lowerCaseUtf8(item.mBase.getClass().getName(item.mBase));
if (compare.find(mNameFilter) == std::string::npos)
return false;
@ -352,6 +363,11 @@ namespace MWGui
mEffectFilter = Utf8Stream::lowerCaseUtf8(filter);
}
void SortFilterItemModel::setApparatusTypeFilter(const int32_t type)
{
mApparatusTypeFilter = type;
}
void SortFilterItemModel::update()
{
mSourceModel->update();

@ -27,6 +27,7 @@ namespace MWGui
void setFilter(int filter);
void setNameFilter(const std::string& filter);
void setEffectFilter(const std::string& filter);
void setApparatusTypeFilter(const int32_t type);
/// Use ItemStack::Type for sorting?
void setSortByType(bool sort) { mSortByType = sort; }
@ -49,6 +50,7 @@ namespace MWGui
static constexpr int Filter_OnlyRepairable = (1 << 5);
static constexpr int Filter_OnlyRechargable = (1 << 6);
static constexpr int Filter_OnlyRepairTools = (1 << 7);
static constexpr int Filter_OnlyAlchemyTools = (1 << 8);
private:
std::vector<ItemStack> mItems;
@ -59,6 +61,7 @@ namespace MWGui
int mFilter;
bool mSortByType;
int32_t mApparatusTypeFilter; // filter by apparatus type
std::string mNameFilter; // filter by item name
std::string mEffectFilter; // filter by magic effect
};

@ -461,6 +461,24 @@ void MWMechanics::Alchemy::removeIngredient(int index)
}
}
void MWMechanics::Alchemy::addApparatus(const MWWorld::Ptr& apparatus)
{
int32_t slot = apparatus.get<ESM::Apparatus>()->mBase->mData.mType;
mTools[slot] = apparatus;
updateEffects();
}
void MWMechanics::Alchemy::removeApparatus(int index)
{
if (index >= 0 && index < static_cast<int>(mTools.size()))
{
mTools[index] = MWWorld::Ptr();
updateEffects();
}
}
MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::beginEffects() const
{
return mEffects.begin();

@ -119,9 +119,15 @@ namespace MWMechanics
/// \return Slot index or -1, if adding failed because of no free slot or the ingredient type being
/// listed already.
void addApparatus(const MWWorld::Ptr& apparatus);
///< Add apparatus into the appropriate slot.
void removeIngredient(int index);
///< Remove ingredient from slot (calling this function on an empty slot is a no-op).
void removeApparatus(int index);
///< Remove apparatus from slot.
std::string suggestPotionName();
///< Suggest a name for the potion, based on the current effects

Loading…
Cancel
Save