1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-03 17:15:35 +00:00

Merge remote-tracking branch 'scrawl/master'

This commit is contained in:
Marc Zinnschlag 2013-11-21 19:18:04 +01:00
commit 3ef5fcb04d
31 changed files with 261 additions and 109 deletions

View file

@ -241,7 +241,7 @@ namespace MWBase
virtual void localRotateObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; virtual void localRotateObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
virtual void safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) = 0; virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) = 0;
///< place an object in a "safe" location (ie not in the void, etc). ///< place an object in a "safe" location (ie not in the void, etc).
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)

View file

@ -169,7 +169,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return ref->mBase->mData.mValue; if (ptr.getCellRef().mCharge == -1)
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr));
} }
void Armor::registerSelf() void Armor::registerSelf()
@ -281,6 +284,7 @@ namespace MWClass
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; ref->mBase = record;
ref->mRef.mRefID = record->mId;
} }
std::pair<int, std::string> Armor::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const std::pair<int, std::string> Armor::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const

View file

@ -171,6 +171,7 @@ namespace MWClass
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; ref->mBase = record;
ref->mRef.mRefID = record->mId;
} }
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const

View file

@ -227,6 +227,7 @@ namespace MWClass
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; ref->mBase = record;
ref->mRef.mRefID = record->mId;
} }
std::pair<int, std::string> Clothing::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const std::pair<int, std::string> Clothing::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const

View file

@ -98,6 +98,8 @@ namespace MWClass
data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr), data->mContainerStore.fill(ref->mBase->mInventory, getId(ptr),
MWBase::Environment::get().getWorld()->getStore()); MWBase::Environment::get().getWorld()->getStore());
data->mContainerStore.add("gold_001", ref->mBase->mData.mGold, ptr);
// store // store
ptr.getRefData().setCustomData (data.release()); ptr.getRefData().setCustomData (data.release());
} }

View file

@ -156,6 +156,9 @@ namespace MWClass
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
static const float fWortChanceValue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->getFloat();
MWGui::Widgets::SpellEffectList list; MWGui::Widgets::SpellEffectList list;
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
{ {
@ -166,10 +169,10 @@ namespace MWClass
params.mAttribute = ref->mBase->mData.mAttributes[i]; params.mAttribute = ref->mBase->mData.mAttributes[i];
params.mSkill = ref->mBase->mData.mSkills[i]; params.mSkill = ref->mBase->mData.mSkills[i];
params.mKnown = ( (i == 0 && alchemySkill >= 15) params.mKnown = ( (i == 0 && alchemySkill >= fWortChanceValue)
|| (i == 1 && alchemySkill >= 30) || (i == 1 && alchemySkill >= fWortChanceValue*2)
|| (i == 2 && alchemySkill >= 45) || (i == 2 && alchemySkill >= fWortChanceValue*3)
|| (i == 3 && alchemySkill >= 60)); || (i == 3 && alchemySkill >= fWortChanceValue*4));
list.push_back(params); list.push_back(params);
} }

View file

@ -86,7 +86,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Lockpick> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Lockpick>(); ptr.get<ESM::Lockpick>();
return ref->mBase->mData.mValue; if (ptr.getCellRef().mCharge == -1)
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr));
} }
void Lockpick::registerSelf() void Lockpick::registerSelf()

View file

@ -184,8 +184,11 @@ namespace MWClass
} }
// creature stats // creature stats
int gold=0;
if(ref->mBase->mNpdt52.mGold != -10) if(ref->mBase->mNpdt52.mGold != -10)
{ {
gold = ref->mBase->mNpdt52.mGold;
for (int i=0; i<27; ++i) for (int i=0; i<27; ++i)
data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]); data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]);
@ -207,6 +210,8 @@ namespace MWClass
} }
else else
{ {
gold = ref->mBase->mNpdt12.mGold;
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
data->mNpcStats.setDynamic (i, 10); data->mNpcStats.setDynamic (i, 10);
@ -236,6 +241,8 @@ namespace MWClass
// store // store
ptr.getRefData().setCustomData (data.release()); ptr.getRefData().setCustomData (data.release());
getContainerStore(ptr).add("gold_001", gold, ptr);
getInventoryStore(ptr).autoEquip(ptr); getInventoryStore(ptr).autoEquip(ptr);
} }
} }

View file

@ -137,13 +137,14 @@ namespace MWClass
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player);
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
int i=0; int i=0;
static const float fWortChanceValue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->getFloat();
for (MWGui::Widgets::SpellEffectList::iterator it = info.effects.begin(); it != info.effects.end(); ++it) for (MWGui::Widgets::SpellEffectList::iterator it = info.effects.begin(); it != info.effects.end(); ++it)
{ {
/// \todo this code is duplicated from mwclass/ingredient, put it in a helper function it->mKnown = ( (i == 0 && alchemySkill >= fWortChanceValue)
it->mKnown = ( (i == 0 && alchemySkill >= 15) || (i == 1 && alchemySkill >= fWortChanceValue*2)
|| (i == 1 && alchemySkill >= 30) || (i == 2 && alchemySkill >= fWortChanceValue*3)
|| (i == 2 && alchemySkill >= 45) || (i == 3 && alchemySkill >= fWortChanceValue*4));
|| (i == 3 && alchemySkill >= 60));
++i; ++i;
} }

View file

@ -85,7 +85,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
return ref->mBase->mData.mValue; if (ptr.getCellRef().mCharge == -1)
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr));
} }
void Probe::registerSelf() void Probe::registerSelf()

View file

@ -76,7 +76,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
return ref->mBase->mData.mValue; if (ptr.getCellRef().mCharge == -1)
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr));
} }
void Repair::registerSelf() void Repair::registerSelf()

View file

@ -154,7 +154,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return ref->mBase->mData.mValue; if (ptr.getCellRef().mCharge == -1)
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (ptr.getCellRef().mCharge / getItemMaxHealth(ptr));
} }
void Weapon::registerSelf() void Weapon::registerSelf()
@ -370,16 +373,17 @@ namespace MWClass
void Weapon::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const void Weapon::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{ {
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
ESM::Weapon newItem = *ref->mBase; ESM::Weapon newItem = *ref->mBase;
newItem.mId=""; newItem.mId="";
newItem.mName=newName; newItem.mName=newName;
newItem.mData.mEnchant=enchCharge; newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId; newItem.mEnchant=enchId;
const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem); const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
ref->mBase = record; ref->mBase = record;
ref->mRef.mRefID = record->mId;
} }
std::pair<int, std::string> Weapon::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const std::pair<int, std::string> Weapon::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const

View file

@ -12,6 +12,8 @@
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwdialogue/dialoguemanagerimp.hpp" #include "../mwdialogue/dialoguemanagerimp.hpp"
@ -67,23 +69,24 @@ namespace MWGui
void PersuasionDialog::onPersuade(MyGUI::Widget *sender) void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWBase::MechanicsManager::PersuasionType type; MWBase::MechanicsManager::PersuasionType type;
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire; if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate; else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt; else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
else if (sender == mBribe10Button) else if (sender == mBribe10Button)
{ {
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-10); player.getClass().getContainerStore(player).remove("gold_001", 10, player);
type = MWBase::MechanicsManager::PT_Bribe10; type = MWBase::MechanicsManager::PT_Bribe10;
} }
else if (sender == mBribe100Button) else if (sender == mBribe100Button)
{ {
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-100); player.getClass().getContainerStore(player).remove("gold_001", 100, player);
type = MWBase::MechanicsManager::PT_Bribe100; type = MWBase::MechanicsManager::PT_Bribe100;
} }
else /*if (sender == mBribe1000Button)*/ else /*if (sender == mBribe1000Button)*/
{ {
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-1000); player.getClass().getContainerStore(player).remove("gold_001", 1000, player);
type = MWBase::MechanicsManager::PT_Bribe1000; type = MWBase::MechanicsManager::PT_Bribe1000;
} }

View file

@ -13,7 +13,6 @@
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace MWGui namespace MWGui
{ {
@ -119,7 +118,9 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1); MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
int price = boost::lexical_cast<int>(sender->getUserString("Price")); int price = boost::lexical_cast<int>(sender->getUserString("Price"));
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-price);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
player.getClass().getContainerStore(player).remove("gold_001", price, player);
startRepair(mActor); startRepair(mActor);
} }

View file

@ -10,11 +10,11 @@
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace MWGui namespace MWGui
{ {
@ -123,7 +123,7 @@ namespace MWGui
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
MWMechanics::Spells& spells = stats.getSpells(); MWMechanics::Spells& spells = stats.getSpells();
spells.add (mSpellsWidgetMap.find(_sender)->second); spells.add (mSpellsWidgetMap.find(_sender)->second);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-price); player.getClass().getContainerStore(player).remove("gold_001", price, player);
startSpellBuying(mPtr); startSpellBuying(mPtr);
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);

View file

@ -8,13 +8,13 @@
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwmechanics/spellcasting.hpp" #include "../mwmechanics/spellcasting.hpp"
#include "tooltips.hpp" #include "tooltips.hpp"
#include "class.hpp" #include "class.hpp"
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace namespace
{ {
@ -342,13 +342,14 @@ namespace MWGui
mSpell.mName = mNameEdit->getCaption(); mSpell.mName = mNameEdit->getCaption();
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-boost::lexical_cast<int>(mPriceLabel->getCaption())); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
player.getClass().getContainerStore(player).remove("gold_001", boost::lexical_cast<int>(mPriceLabel->getCaption()), player);
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->createRecord(mSpell); const ESM::Spell* spell = MWBase::Environment::get().getWorld()->createRecord(mSpell);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
MWMechanics::Spells& spells = stats.getSpells(); MWMechanics::Spells& spells = stats.getSpells();
spells.add (spell->mId); spells.add (spell->mId);

View file

@ -203,19 +203,17 @@ namespace MWGui
sellToNpc(item.mBase, count, true); sellToNpc(item.mBase, count, true);
} }
void TradeWindow::addOrRemoveGold(int amount) void TradeWindow::addOrRemoveGold(int amount, const MWWorld::Ptr& actor)
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::ContainerStore& store = MWWorld::Class::get(actor).getContainerStore(actor);
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
if (amount > 0) if (amount > 0)
{ {
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001", amount); store.add("gold_001", amount, actor);
playerStore.add(ref.getPtr(), player);
} }
else else
{ {
playerStore.remove("gold_001", - amount, player); store.remove("gold_001", - amount, actor);
} }
} }
@ -270,6 +268,8 @@ namespace MWGui
return; return;
} }
MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
if(mCurrentBalance > mCurrentMerchantOffer) if(mCurrentBalance > mCurrentMerchantOffer)
{ {
//if npc is a creature: reject (no haggle) //if npc is a creature: reject (no haggle)
@ -292,7 +292,6 @@ namespace MWGui
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100)); + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(mPtr).getNpcStats(mPtr); const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
float a1 = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100.f); float a1 = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100.f);
@ -332,9 +331,12 @@ namespace MWGui
mTradeModel->transferItems(); mTradeModel->transferItems();
playerItemModel->transferItems(); playerItemModel->transferItems();
// add or remove gold from the player. // transfer the gold
if (mCurrentBalance != 0) if (mCurrentBalance != 0)
addOrRemoveGold(mCurrentBalance); {
addOrRemoveGold(mCurrentBalance, playerPtr);
addOrRemoveGold(-mCurrentBalance, mPtr);
}
std::string sound = "Item Gold Up"; std::string sound = "Item Gold Up";
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
@ -435,22 +437,13 @@ namespace MWGui
int TradeWindow::getMerchantGold() int TradeWindow::getMerchantGold()
{ {
int merchantGold; int merchantGold = 0;
MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
if (mPtr.getTypeName() == typeid(ESM::NPC).name()) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>(); if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
if (ref->mBase->mNpdt52.mGold == -10) merchantGold += it->getRefData().getCount();
merchantGold = ref->mBase->mNpdt12.mGold;
else
merchantGold = ref->mBase->mNpdt52.mGold;
} }
else // ESM::Creature
{
MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>();
merchantGold = ref->mBase->mData.mGold;
}
return merchantGold; return merchantGold;
} }
} }

View file

@ -28,7 +28,7 @@ namespace MWGui
void startTrade(const MWWorld::Ptr& actor); void startTrade(const MWWorld::Ptr& actor);
void addOrRemoveGold(int gold); void addOrRemoveGold(int gold, const MWWorld::Ptr& actor);
void onFrame(float frameDuration); void onFrame(float frameDuration);

View file

@ -11,11 +11,11 @@
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "tradewindow.hpp"
#include "tooltips.hpp" #include "tooltips.hpp"
namespace MWGui namespace MWGui
@ -142,7 +142,7 @@ namespace MWGui
pcStats.increaseSkill (skillId, *class_, true); pcStats.increaseSkill (skillId, *class_, true);
// remove gold // remove gold
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-price); player.getClass().getContainerStore(player).remove("gold_001", price, player);
// go back to game mode // go back to game mode
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training); MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training);

View file

@ -11,9 +11,9 @@
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace MWGui namespace MWGui
{ {
@ -121,13 +121,15 @@ namespace MWGui
int price; int price;
iss >> price; iss >> price;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()<price) if (MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold()<price)
return; return;
MWBase::Environment::get().getWindowManager()->getTradeWindow ()->addOrRemoveGold (-price);
player.getClass().getContainerStore(player).remove("gold_001", price, player);
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
ESM::Position pos = *_sender->getUserData<ESM::Position>(); ESM::Position pos = *_sender->getUserData<ESM::Position>();
std::string cellname = _sender->getUserString("Destination"); std::string cellname = _sender->getUserString("Destination");
int x,y; int x,y;

View file

@ -12,6 +12,8 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -27,6 +29,25 @@
#include "aicombat.hpp" #include "aicombat.hpp"
namespace
{
void adjustBoundItem (const std::string& item, bool bound, const MWWorld::Ptr& actor)
{
if (bound)
{
MWWorld::Ptr newPtr = *actor.getClass().getContainerStore(actor).add(item, 1, actor);
MWWorld::ActionEquip action(newPtr);
action.execute(actor);
}
else
{
actor.getClass().getContainerStore(actor).remove(item, 1, actor);
}
}
}
namespace MWMechanics namespace MWMechanics
{ {
void Actors::updateActor (const MWWorld::Ptr& ptr, float duration) void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
@ -247,6 +268,118 @@ namespace MWMechanics
} }
creatureStats.setHealth(health); creatureStats.setHealth(health);
// TODO: dirty flag for magic effects to avoid some unnecessary work below?
// Update bound effects
static std::map<int, std::string> boundItemsMap;
if (boundItemsMap.empty())
{
boundItemsMap[ESM::MagicEffect::BoundBattleAxe] = "battle_axe";
boundItemsMap[ESM::MagicEffect::BoundBoots] = "boots";
boundItemsMap[ESM::MagicEffect::BoundCuirass] = "cuirass";
boundItemsMap[ESM::MagicEffect::BoundDagger] = "dagger";
boundItemsMap[ESM::MagicEffect::BoundGloves] = "gauntlet"; // Note: needs both _left and _right variants, see below
boundItemsMap[ESM::MagicEffect::BoundHelm] = "helm";
boundItemsMap[ESM::MagicEffect::BoundLongbow] = "longbow";
boundItemsMap[ESM::MagicEffect::BoundLongsword] = "longsword";
boundItemsMap[ESM::MagicEffect::BoundMace] = "mace";
boundItemsMap[ESM::MagicEffect::BoundShield] = "shield";
boundItemsMap[ESM::MagicEffect::BoundSpear] = "spear";
}
for (std::map<int, std::string>::iterator it = boundItemsMap.begin(); it != boundItemsMap.end(); ++it)
{
bool found = creatureStats.mBoundItems.find(it->first) != creatureStats.mBoundItems.end();
int magnitude = creatureStats.getMagicEffects().get(EffectKey(it->first)).mMagnitude;
if (found != (magnitude > 0))
{
std::string item = "bound_" + it->second;
if (it->first == ESM::MagicEffect::BoundGloves)
{
adjustBoundItem(item + "_left", magnitude > 0, ptr);
adjustBoundItem(item + "_right", magnitude > 0, ptr);
}
else
adjustBoundItem(item, magnitude > 0, ptr);
if (magnitude > 0)
creatureStats.mBoundItems.insert(it->first);
else
creatureStats.mBoundItems.erase(it->first);
}
}
// Update summon effects
static std::map<int, std::string> summonMap;
if (summonMap.empty())
{
summonMap[ESM::MagicEffect::SummonAncestralGhost] = "ancestor_ghost_summon";
summonMap[ESM::MagicEffect::SummonBear] = "BM_bear_black_summon";
summonMap[ESM::MagicEffect::SummonBonelord] = "bonelord_summon";
summonMap[ESM::MagicEffect::SummonBonewalker] = "bonewalker_summon";
summonMap[ESM::MagicEffect::SummonBonewolf] = "BM_wolf_bone_summon";
summonMap[ESM::MagicEffect::SummonCenturionSphere] = "centurion_sphere_summon";
summonMap[ESM::MagicEffect::SummonClannfear] = "clannfear_summon";
summonMap[ESM::MagicEffect::SummonDaedroth] = "daedroth_summon";
summonMap[ESM::MagicEffect::SummonDremora] = "dremora_summon";
summonMap[ESM::MagicEffect::SummonFabricant] = "fabricant_summon";
summonMap[ESM::MagicEffect::SummonFlameAtronach] = "atronach_flame_summon";
summonMap[ESM::MagicEffect::SummonFrostAtronach] = "atronach_frost_summon";
summonMap[ESM::MagicEffect::SummonGoldenSaint] = "golden saint_summon";
summonMap[ESM::MagicEffect::SummonGreaterBonewalker] = "bonewalker_greater_summ";
summonMap[ESM::MagicEffect::SummonHunger] = "hunger_summon";
summonMap[ESM::MagicEffect::SummonScamp] = "scamp_summon";
summonMap[ESM::MagicEffect::SummonSkeletalMinion] = "skeleton_summon";
summonMap[ESM::MagicEffect::SummonStormAtronach] = "atronach_storm_summon";
summonMap[ESM::MagicEffect::SummonWingedTwilight] = "winged twilight_summon";
summonMap[ESM::MagicEffect::SummonWolf] = "BM_wolf_grey_summon";
}
for (std::map<int, std::string>::iterator it = summonMap.begin(); it != summonMap.end(); ++it)
{
bool found = creatureStats.mSummonedCreatures.find(it->first) != creatureStats.mSummonedCreatures.end();
int magnitude = creatureStats.getMagicEffects().get(EffectKey(it->first)).mMagnitude;
if (found != (magnitude > 0))
{
if (magnitude > 0)
{
ESM::Position ipos = ptr.getRefData().getPosition();
Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]);
Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z);
const float distance = 50;
pos = pos + distance*rot.yAxis();
ipos.pos[0] = pos.x;
ipos.pos[1] = pos.y;
ipos.pos[2] = pos.z;
ipos.rot[0] = 0;
ipos.rot[1] = 0;
ipos.rot[2] = 0;
MWWorld::CellStore* store = ptr.getCell();
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->second, 1);
ref.getPtr().getCellRef().mPos = ipos;
// TODO: Add AI to follow player and fight for him
creatureStats.mSummonedCreatures.insert(std::make_pair(it->first,
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),*store,ipos).getRefData().getHandle()));
}
else
{
std::string handle = creatureStats.mSummonedCreatures[it->first];
// TODO: Show death animation before deleting? We shouldn't allow looting the corpse while the animation
// plays though, which is a rather lame exploit in vanilla.
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle);
if (!ptr.isEmpty())
{
MWBase::Environment::get().getWorld()->deleteObject(ptr);
creatureStats.mSummonedCreatures.erase(it->first);
}
}
}
}
} }
void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr) void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr)

View file

@ -287,8 +287,7 @@ void MWMechanics::Alchemy::addPotion (const std::string& name)
record = MWBase::Environment::get().getWorld()->createRecord (newRecord); record = MWBase::Environment::get().getWorld()->createRecord (newRecord);
} }
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId); mAlchemist.getClass().getContainerStore (mAlchemist).add (record->mId, 1, mAlchemist);
MWWorld::Class::get (mAlchemist).getContainerStore (mAlchemist).add (ref.getPtr(), mAlchemist);
} }
void MWMechanics::Alchemy::increaseSkill() void MWMechanics::Alchemy::increaseSkill()

View file

@ -171,6 +171,11 @@ namespace MWMechanics
void setLastHitObject(const std::string &objectid); void setLastHitObject(const std::string &objectid);
const std::string &getLastHitObject() const; const std::string &getLastHitObject() const;
// Note, this is just a cache to avoid checking the whole container store every frame TODO: Put it somewhere else?
std::set<int> mBoundItems;
// Same as above
std::map<int, std::string> mSummonedCreatures;
}; };
} }

View file

@ -62,10 +62,7 @@ namespace MWMechanics
//Exception for Azura Star, new one will be added after enchanting //Exception for Azura Star, new one will be added after enchanting
if(boost::iequals(mSoulGemPtr.get<ESM::Miscellaneous>()->mBase->mId, "Misc_SoulGem_Azura")) if(boost::iequals(mSoulGemPtr.get<ESM::Miscellaneous>()->mBase->mId, "Misc_SoulGem_Azura"))
{ store.add("Misc_SoulGem_Azura", 1, player);
MWWorld::ManualRef azura (MWBase::Environment::get().getWorld()->getStore(), "Misc_SoulGem_Azura");
store.add(azura.getPtr(), player);
}
if(mSelfEnchanting) if(mSelfEnchanting)
{ {
@ -92,8 +89,8 @@ namespace MWMechanics
MWWorld::Class::get(newItemPtr).applyEnchantment(newItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName); MWWorld::Class::get(newItemPtr).applyEnchantment(newItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName);
// Add the new item to player inventory and remove the old one // Add the new item to player inventory and remove the old one
store.add(newItemPtr, player);
store.remove(mOldItemPtr, 1, player); store.remove(mOldItemPtr, 1, player);
store.add(newItemPtr, player);
if(!mSelfEnchanting) if(!mSelfEnchanting)
payForEnchantment(); payForEnchantment();

View file

@ -419,7 +419,7 @@ namespace MWMechanics
MWWorld::LiveCellRef<ESM::NPC>* player = playerPtr.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC>* player = playerPtr.get<ESM::NPC>();
const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
if (Misc::StringUtils::lowerCase(npc->mBase->mRace) == Misc::StringUtils::lowerCase(player->mBase->mRace)) if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace))
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispRaceMod")->getFloat(); x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispRaceMod")->getFloat();
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispPersonalityMult")->getFloat() x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispPersonalityMult")->getFloat()
@ -435,7 +435,9 @@ namespace MWMechanics
for(std::vector<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin(); for(std::vector<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin();
it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.end(); ++it) it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.end(); ++it)
{ {
if(Misc::StringUtils::lowerCase(it->mFaction) == Misc::StringUtils::lowerCase(npcFaction)) reaction = it->mReaction; if(Misc::StringUtils::lowerCase(it->mFaction) == Misc::StringUtils::lowerCase(npcFaction)
&& playerStats.getExpelled().find(Misc::StringUtils::lowerCase(it->mFaction)) == playerStats.getExpelled().end())
reaction = it->mReaction;
} }
rank = playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(npcFaction))->second; rank = playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(npcFaction))->second;
} }
@ -446,7 +448,8 @@ namespace MWMechanics
{ {
if(playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(it->mFaction)) != playerStats.getFactionRanks().end() ) if(playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(it->mFaction)) != playerStats.getFactionRanks().end() )
{ {
if(it->mReaction<reaction) reaction = it->mReaction; if(it->mReaction < reaction)
reaction = it->mReaction;
} }
} }
rank = 0; rank = 0;

View file

@ -17,7 +17,6 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/actionequip.hpp" #include "../mwworld/actionequip.hpp"
@ -53,24 +52,14 @@ namespace MWScript
if (count == 0) if (count == 0)
return; return;
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, count); MWWorld::Ptr itemPtr = *ptr.getClass().getContainerStore (ptr).add (item, count, ptr);
// Configure item's script variables
std::string script = MWWorld::Class::get(ref.getPtr()).getScript(ref.getPtr());
if (script != "")
{
const ESM::Script *esmscript = MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (script);
ref.getPtr().getRefData().setLocals(*esmscript);
}
MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr(), ptr);
// Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone)
if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer() ) if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer() )
{ {
// The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory // The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory
std::string msgBox; std::string msgBox;
std::string itemName = MWWorld::Class::get(ref.getPtr()).getName(ref.getPtr()); std::string itemName = itemPtr.getClass().getName(itemPtr);
if (count == 1) if (count == 1)
{ {
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage60}"); msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage60}");

View file

@ -19,7 +19,6 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
@ -348,12 +347,8 @@ namespace MWScript
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), gem, 1); MWWorld::Ptr item = *ptr.getClass().getContainerStore(ptr).add(gem, 1, ptr);
item.getCellRef().mSoul = creature;
ref.getPtr().getCellRef().mSoul = creature;
MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr(), ptr);
} }
}; };

View file

@ -118,6 +118,12 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
|| cls2.getItemMaxHealth(ptr2) == ptr2.getCellRef().mCharge); || cls2.getItemMaxHealth(ptr2) == ptr2.getCellRef().mCharge);
} }
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const std::string &id, int count, const Ptr &actorPtr)
{
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), id, count);
return add(ref.getPtr(), actorPtr);
}
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, const Ptr& actorPtr) MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, const Ptr& actorPtr)
{ {
MWWorld::ContainerStoreIterator it = addImp(itemPtr); MWWorld::ContainerStoreIterator it = addImp(itemPtr);

View file

@ -74,6 +74,9 @@ namespace MWWorld
/// ///
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item. /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item.
ContainerStoreIterator add(const std::string& id, int count, const Ptr& actorPtr);
///< Utility to construct a ManualRef and call add(ptr, actorPtr)
int remove(const std::string& itemId, int count, const Ptr& actor); int remove(const std::string& itemId, int count, const Ptr& actor);
///< Remove \a count item(s) designated by \a itemId from this container. ///< Remove \a count item(s) designated by \a itemId from this container.
/// ///

View file

@ -1084,9 +1084,9 @@ namespace MWWorld
adjust); adjust);
} }
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) MWWorld::Ptr World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
{ {
copyObjectToCell(ptr,Cell,pos); return copyObjectToCell(ptr,Cell,pos);
} }
void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const
@ -1967,23 +1967,13 @@ namespace MWWorld
if(werewolf) if(werewolf)
{ {
ManualRef ref(getStore(), "WerewolfRobe"); InventoryStore &inv = actor.getClass().getInventoryStore(actor);
// Configure item's script variables inv.equip(InventoryStore::Slot_Robe, inv.ContainerStore::add("WerewolfRobe", 1, actor), actor);
std::string script = Class::get(ref.getPtr()).getScript(ref.getPtr());
if(script != "")
{
const ESM::Script *esmscript = getStore().get<ESM::Script>().find(script);
ref.getPtr().getRefData().setLocals(*esmscript);
}
// Not sure this is right
InventoryStore &inv = Class::get(actor).getInventoryStore(actor);
inv.equip(InventoryStore::Slot_Robe, inv.add(ref.getPtr(), actor), actor);
} }
else else
{ {
Class::get(actor).getContainerStore(actor).remove("WerewolfRobe", 1, actor); actor.getClass().getContainerStore(actor).remove("WerewolfRobe", 1, actor);
} }
if(actor.getRefData().getHandle() == "player") if(actor.getRefData().getHandle() == "player")

View file

@ -302,7 +302,7 @@ namespace MWWorld
virtual void localRotateObject (const Ptr& ptr, float x, float y, float z); virtual void localRotateObject (const Ptr& ptr, float x, float y, float z);
virtual void safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos); virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos);
///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr. ///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr.
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)