1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-05 15:55:45 +00:00

Attempt to restack item after repair or recharge (Fixes #1656)

This commit is contained in:
scrawl 2014-07-16 15:30:06 +02:00
parent 20a0040bdb
commit 08ce6ed7fb
6 changed files with 65 additions and 24 deletions

View File

@ -117,15 +117,18 @@ void MerchantRepair::exit()
void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
// repair
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
item.getCellRef().setCharge(item.getClass().getItemMaxHealth(item));
player.getClass().getContainerStore(player).restack(item);
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
int price = boost::lexical_cast<int>(sender->getUserString("Price"));
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
startRepair(mActor);

View File

@ -165,6 +165,8 @@ void Recharge::onItemClicked(MyGUI::Widget *sender)
item.getCellRef().setEnchantmentCharge(
std::min(item.getCellRef().getEnchantmentCharge() + restored, static_cast<float>(enchantment->mData.mCharge)));
player.getClass().getContainerStore(player).restack(item);
player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0);
}

View File

@ -57,10 +57,13 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
charge = std::min(charge + y, itemToRepair.getClass().getItemMaxHealth(itemToRepair));
itemToRepair.getCellRef().setCharge(charge);
// attempt to re-stack item, in case it was fully repaired
MWWorld::ContainerStoreIterator stacked = player.getClass().getContainerStore(player).restack(itemToRepair);
// set the OnPCRepair variable on the item's script
std::string script = itemToRepair.getClass().getScript(itemToRepair);
std::string script = stacked->getClass().getScript(itemToRepair);
if(script != "")
itemToRepair.getRefData().getLocals().setVarByInt(script, "onpcrepair", 1);
stacked->getRefData().getLocals().setVarByInt(script, "onpcrepair", 1);
// increase skill
player.getClass().skillUsageSucceeded(player, ESM::Skill::Armorer, 0);

View File

@ -141,6 +141,34 @@ void MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container)
remove(ptr, ptr.getRefData().getCount()-1, container);
}
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::restack(const MWWorld::Ptr& item)
{
MWWorld::ContainerStoreIterator retval = end();
for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter)
{
if (item == *iter)
{
retval = iter;
break;
}
}
if (retval == end())
throw std::runtime_error("item is not from this container");
for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter)
{
if (stacks(*iter, item))
{
iter->getRefData().setCount(iter->getRefData().getCount() + item.getRefData().getCount());
item.getRefData().setCount(0);
retval = iter;
break;
}
}
return retval;
}
bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
{
const MWWorld::Class& cls1 = ptr1.getClass();

View File

@ -134,6 +134,11 @@ namespace MWWorld
void unstack (const Ptr& ptr, const Ptr& container);
///< Unstack an item in this container. The item's count will be set to 1, then a new stack will be added with (origCount-1).
MWWorld::ContainerStoreIterator restack (const MWWorld::Ptr& item);
///< Attempt to re-stack an item in this container.
/// If a compatible stack is found, the item's count is added to that stack, then the original is deleted.
/// @return If the item was stacked, return the stack, otherwise return the old (untouched) item.
/// @return How many items with refID \a id are in this container?
int count (const std::string& id);

View File

@ -512,28 +512,21 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, c
// empty this slot
mSlots[slot] = end();
// restack the previously equipped item with other (non-equipped) items
for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter)
if (it->getRefData().getCount())
{
if (stacks(*iter, *it))
{
iter->getRefData().setCount(iter->getRefData().getCount() + it->getRefData().getCount());
it->getRefData().setCount(0);
retval = iter;
break;
}
}
retval = restack(*it);
if (actor.getRefData().getHandle() == "player")
{
// Unset OnPCEquip Variable on item's script, if it has a script with that variable declared
const std::string& script = it->getClass().getScript(*it);
if (script != "")
(*it).getRefData().getLocals().setVarByInt(script, "onpcequip", 0);
if ((mSelectedEnchantItem != end()) && (mSelectedEnchantItem == it))
if (actor.getRefData().getHandle() == "player")
{
mSelectedEnchantItem = end();
// Unset OnPCEquip Variable on item's script, if it has a script with that variable declared
const std::string& script = it->getClass().getScript(*it);
if (script != "")
(*it).getRefData().getLocals().setVarByInt(script, "onpcequip", 0);
if ((mSelectedEnchantItem != end()) && (mSelectedEnchantItem == it))
{
mSelectedEnchantItem = end();
}
}
}
@ -633,8 +626,15 @@ void MWWorld::InventoryStore::rechargeItems(float duration)
static float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
"fMagicItemRechargePerSecond")->getFloat();
it->first->getCellRef().setEnchantmentCharge(std::min (it->first->getCellRef().getEnchantmentCharge() + fMagicItemRechargePerSecond * duration,
it->second));
if (it->first->getCellRef().getEnchantmentCharge() <= it->second)
{
it->first->getCellRef().setEnchantmentCharge(std::min (it->first->getCellRef().getEnchantmentCharge() + fMagicItemRechargePerSecond * duration,
it->second));
// attempt to restack when fully recharged
if (it->first->getCellRef().getEnchantmentCharge() == it->second)
it->first = restack(*it->first);
}
}
}