mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-01 04:45:34 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
85e5bd212b
37 changed files with 234 additions and 60 deletions
|
@ -159,4 +159,9 @@ namespace MWClass
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Apparatus::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Apparatus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@ namespace MWClass
|
||||||
///< Generate action for using via inventory menu
|
///< Generate action for using via inventory menu
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,4 +315,9 @@ namespace MWClass
|
||||||
|
|
||||||
return ref->mBase->mData.mEnchant;
|
return ref->mBase->mData.mEnchant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Armor::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Armor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,8 @@ namespace MWClass
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,4 +183,9 @@ namespace MWClass
|
||||||
|
|
||||||
return ref->mBase->mData.mEnchant;
|
return ref->mBase->mData.mEnchant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Book::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Books;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ namespace MWClass
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,4 +262,9 @@ namespace MWClass
|
||||||
|
|
||||||
return ref->mBase->mData.mEnchant;
|
return ref->mBase->mData.mEnchant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Clothing::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Clothing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,8 @@ namespace MWClass
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,4 +197,9 @@ namespace MWClass
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ingredient::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Ingredients;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ namespace MWClass
|
||||||
///< Return name of inventory icon.
|
///< Return name of inventory icon.
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,4 +203,9 @@ namespace MWClass
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Lights;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
||||||
///< Generate action for using via inventory menu
|
///< Generate action for using via inventory menu
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,4 +176,9 @@ namespace MWClass
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lockpick::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Picks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
||||||
///< Generate action for using via inventory menu
|
///< Generate action for using via inventory menu
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,4 +246,12 @@ namespace MWClass
|
||||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr));
|
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Miscellaneous::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||||
|
item.get<ESM::Miscellaneous>();
|
||||||
|
|
||||||
|
return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ namespace MWClass
|
||||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||||
const;
|
const;
|
||||||
///< Generate action for using via inventory menu
|
///< Generate action for using via inventory menu
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,4 +194,9 @@ namespace MWClass
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Potion::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Potions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,8 @@ namespace MWClass
|
||||||
///< Return name of inventory icon.
|
///< Return name of inventory icon.
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,4 +175,9 @@ namespace MWClass
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Probe::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Probes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
||||||
///< Generate action for using via inventory menu
|
///< Generate action for using via inventory menu
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,4 +175,9 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRepair(ptr));
|
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRepair(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Repair::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::RepairItem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,8 @@ namespace MWClass
|
||||||
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return item max health or throw an exception, if class does not have item health
|
///< Return item max health or throw an exception, if class does not have item health
|
||||||
/// (default implementation: throw an exceoption)
|
/// (default implementation: throw an exceoption)
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -409,4 +409,9 @@ namespace MWClass
|
||||||
|
|
||||||
return ref->mBase->mData.mEnchant;
|
return ref->mBase->mData.mEnchant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Weapon::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return npcServices & ESM::NPC::Weapon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,8 @@ namespace MWClass
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
|
|
||||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,7 @@ namespace MWGui
|
||||||
it = invStore.add(ptr);
|
it = invStore.add(ptr);
|
||||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||||
ptr = *it;
|
ptr = *it;
|
||||||
|
mDragAndDrop->mDraggedFrom->notifyItemDragged(ptr, -mDragAndDrop->mDraggedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \todo scripts
|
/// \todo scripts
|
||||||
|
|
|
@ -257,6 +257,12 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);
|
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);
|
||||||
|
|
||||||
// success! make the item transfer.
|
// success! make the item transfer.
|
||||||
|
MWWorld::ContainerStore& playerBoughtItems = mWindowManager.getInventoryWindow()->getBoughtItems();
|
||||||
|
for (MWWorld::ContainerStoreIterator it = playerBoughtItems.begin(); it != playerBoughtItems.end(); ++it)
|
||||||
|
{
|
||||||
|
if (Misc::StringUtils::ciEqual(it->getCellRef().mOwner, MWWorld::Class::get(mPtr).getId(mPtr)))
|
||||||
|
it->getCellRef().mOwner = "";
|
||||||
|
}
|
||||||
transferBoughtItems();
|
transferBoughtItems();
|
||||||
mWindowManager.getInventoryWindow()->transferBoughtItems();
|
mWindowManager.getInventoryWindow()->transferBoughtItems();
|
||||||
|
|
||||||
|
@ -356,32 +362,7 @@ namespace MWGui
|
||||||
services = ref->mBase->mAiData.mServices;
|
services = ref->mBase->mAiData.mServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \todo what about potions, there doesn't seem to be a flag for them??
|
return MWWorld::Class::get(item).canSell(item, 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::Lockpick).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> TradeWindow::itemsToIgnore()
|
||||||
|
|
|
@ -156,6 +156,7 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWorld()->advanceTime(time);
|
MWBase::Environment::get().getWorld()->advanceTime(time);
|
||||||
}
|
}
|
||||||
MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]);
|
MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]);
|
||||||
|
MWWorld::Class::get(player).adjustPosition(player);
|
||||||
mWindowManager.removeGuiMode(GM_Travel);
|
mWindowManager.removeGuiMode(GM_Travel);
|
||||||
mWindowManager.removeGuiMode(GM_Dialogue);
|
mWindowManager.removeGuiMode(GM_Dialogue);
|
||||||
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0);
|
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0);
|
||||||
|
|
|
@ -45,7 +45,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
|
||||||
Ptr container (&*iter, &cellStore);
|
Ptr container (&*iter, &cellStore);
|
||||||
|
|
||||||
Class::get (container).getContainerStore (container).fill (
|
Class::get (container).getContainerStore (container).fill (
|
||||||
iter->mBase->mInventory, mStore);
|
iter->mBase->mInventory, container.getCellRef().mOwner, mStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CellRefList<ESM::Creature>::List::iterator iter (
|
for (CellRefList<ESM::Creature>::List::iterator iter (
|
||||||
|
@ -55,7 +55,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
|
||||||
Ptr container (&*iter, &cellStore);
|
Ptr container (&*iter, &cellStore);
|
||||||
|
|
||||||
Class::get (container).getContainerStore (container).fill (
|
Class::get (container).getContainerStore (container).fill (
|
||||||
iter->mBase->mInventory, mStore);
|
iter->mBase->mInventory, Class::get(container).getId(container), mStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CellRefList<ESM::NPC>::List::iterator iter (
|
for (CellRefList<ESM::NPC>::List::iterator iter (
|
||||||
|
@ -65,7 +65,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
|
||||||
Ptr container (&*iter, &cellStore);
|
Ptr container (&*iter, &cellStore);
|
||||||
|
|
||||||
Class::get (container).getContainerStore (container).fill (
|
Class::get (container).getContainerStore (container).fill (
|
||||||
iter->mBase->mInventory, mStore);
|
iter->mBase->mInventory, Class::get(container).getId(container), mStore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,11 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("class does not represent an actor");
|
throw std::runtime_error ("class does not represent an actor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Class::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const
|
MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const
|
||||||
{
|
{
|
||||||
throw std::runtime_error ("class does not have creature stats");
|
throw std::runtime_error ("class does not have creature stats");
|
||||||
|
|
|
@ -238,6 +238,9 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
|
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
|
||||||
|
|
||||||
|
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||||
|
///< Determine whether or not \a item can be sold to an npc with the given \a npcServices
|
||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/scriptmanager.hpp"
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
|
||||||
#include "manualref.hpp"
|
#include "manualref.hpp"
|
||||||
#include "refdata.hpp"
|
#include "refdata.hpp"
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
|
@ -175,26 +177,78 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImpl (const Ptr& ptr
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const MWWorld::ESMStore& store)
|
void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, const MWWorld::ESMStore& store)
|
||||||
{
|
{
|
||||||
for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
|
for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
ManualRef ref (store, iter->mItem.toString());
|
std::string id = iter->mItem.toString();
|
||||||
|
addInitialItem(id, owner, iter->mCount);
|
||||||
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
|
|
||||||
{
|
|
||||||
/// \todo implement leveled item lists
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
|
|
||||||
addImp (ref.getPtr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, int count, unsigned char failChance, bool topLevel)
|
||||||
|
{
|
||||||
|
count = std::abs(count); /// \todo implement item restocking (indicated by negative count)
|
||||||
|
|
||||||
|
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id);
|
||||||
|
|
||||||
|
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
|
||||||
|
{
|
||||||
|
const ESM::ItemLevList* levItem = ref.getPtr().get<ESM::ItemLevList>()->mBase;
|
||||||
|
const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
|
||||||
|
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||||
|
int playerLevel = MWWorld::Class::get(player).getCreatureStats(player).getLevel();
|
||||||
|
|
||||||
|
failChance += levItem->mChanceNone;
|
||||||
|
|
||||||
|
if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each)
|
||||||
|
{
|
||||||
|
for (int i=0; i<count; ++i)
|
||||||
|
addInitialItem(id, owner, 1, failChance, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
||||||
|
if (random >= failChance/100.f)
|
||||||
|
{
|
||||||
|
std::vector<std::string> candidates;
|
||||||
|
int highestLevel = 0;
|
||||||
|
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->mLevel > highestLevel)
|
||||||
|
highestLevel = it->mLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<int, std::string> highest = std::make_pair(-1, "");
|
||||||
|
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||||
|
{
|
||||||
|
if (playerLevel >= it->mLevel
|
||||||
|
&& (levItem->mFlags & ESM::ItemLevList::AllLevels || it->mLevel == highestLevel))
|
||||||
|
{
|
||||||
|
candidates.push_back(it->mId);
|
||||||
|
if (it->mLevel >= highest.first)
|
||||||
|
highest = std::make_pair(it->mLevel, it->mId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!candidates.size())
|
||||||
|
return;
|
||||||
|
std::string item = candidates[std::rand()%candidates.size()];
|
||||||
|
addInitialItem(item, owner, count, failChance, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ref.getPtr().getRefData().setCount (count);
|
||||||
|
ref.getPtr().getCellRef().mOwner = owner;
|
||||||
|
addImp (ref.getPtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::clear()
|
void MWWorld::ContainerStore::clear()
|
||||||
{
|
{
|
||||||
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace MWWorld
|
||||||
mutable float mCachedWeight;
|
mutable float mCachedWeight;
|
||||||
mutable bool mWeightUpToDate;
|
mutable bool mWeightUpToDate;
|
||||||
ContainerStoreIterator addImp (const Ptr& ptr);
|
ContainerStoreIterator addImp (const Ptr& ptr);
|
||||||
|
void addInitialItem (const std::string& id, const std::string& owner, int count, unsigned char failChance=0, bool topLevel=true);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ namespace MWWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void fill (const ESM::InventoryList& items, const MWWorld::ESMStore& store);
|
void fill (const ESM::InventoryList& items, const std::string& owner, const MWWorld::ESMStore& store);
|
||||||
///< Insert items into *this.
|
///< Insert items into *this.
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -22,17 +22,20 @@ struct LeveledListBase
|
||||||
{
|
{
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
AllLevels = 0x01, // Calculate from all levels <= player
|
|
||||||
// level, not just the closest below
|
Each = 0x01, // Select a new item each time this
|
||||||
// player.
|
|
||||||
Each = 0x02 // Select a new item each time this
|
|
||||||
// list is instantiated, instead of
|
// list is instantiated, instead of
|
||||||
// giving several identical items
|
// giving several identical items
|
||||||
}; // (used when a container has more
|
// (used when a container has more
|
||||||
// than one instance of one leveled
|
// than one instance of one leveled
|
||||||
// list.)
|
// list.)
|
||||||
|
AllLevels = 0x02 // Calculate from all levels <= player
|
||||||
|
// level, not just the closest below
|
||||||
|
// player.
|
||||||
|
};
|
||||||
|
|
||||||
int mFlags;
|
int mFlags;
|
||||||
unsigned char mChanceNone; // Chance that none are selected (0-255?)
|
unsigned char mChanceNone; // Chance that none are selected (0-100)
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
// Record name used to read references. Must be set before load() is
|
// Record name used to read references. Must be set before load() is
|
||||||
|
|
|
@ -35,11 +35,11 @@ struct NPC
|
||||||
Apparatus = 0x00100,
|
Apparatus = 0x00100,
|
||||||
RepairItem = 0x00200,
|
RepairItem = 0x00200,
|
||||||
Misc = 0x00400,
|
Misc = 0x00400,
|
||||||
|
Potions = 0x02000,
|
||||||
|
|
||||||
// Other services
|
// Other services
|
||||||
Spells = 0x00800,
|
Spells = 0x00800,
|
||||||
MagicItems = 0x01000,
|
MagicItems = 0x01000,
|
||||||
Potions = 0x02000,
|
|
||||||
Training = 0x04000, // What skills?
|
Training = 0x04000, // What skills?
|
||||||
Spellmaking = 0x08000,
|
Spellmaking = 0x08000,
|
||||||
Enchanting = 0x10000,
|
Enchanting = 0x10000,
|
||||||
|
|
|
@ -749,16 +749,29 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
|
||||||
|
|
||||||
instance->setProperty("diffuseMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BaseTexture]));
|
instance->setProperty("diffuseMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BaseTexture]));
|
||||||
instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture]));
|
instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture]));
|
||||||
|
instance->setProperty("detailMap", sh::makeProperty(texName[Nif::NiTexturingProperty::DetailTexture]));
|
||||||
instance->setProperty("emissiveMap", sh::makeProperty(texName[Nif::NiTexturingProperty::GlowTexture]));
|
instance->setProperty("emissiveMap", sh::makeProperty(texName[Nif::NiTexturingProperty::GlowTexture]));
|
||||||
if (!texName[Nif::NiTexturingProperty::GlowTexture].empty())
|
if (!texName[Nif::NiTexturingProperty::GlowTexture].empty())
|
||||||
{
|
{
|
||||||
instance->setProperty("use_emissive_map", sh::makeProperty(new sh::BooleanValue(true)));
|
instance->setProperty("use_emissive_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||||
instance->setProperty("emissiveMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::GlowTexture].uvSet)));
|
instance->setProperty("emissiveMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::GlowTexture].uvSet)));
|
||||||
}
|
}
|
||||||
|
if (!texName[Nif::NiTexturingProperty::DetailTexture].empty())
|
||||||
|
{
|
||||||
|
instance->setProperty("use_detail_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||||
|
instance->setProperty("detailMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::DetailTexture].uvSet)));
|
||||||
|
}
|
||||||
|
if (!texName[Nif::NiTexturingProperty::BumpTexture].empty())
|
||||||
|
{
|
||||||
|
// force automips on normal maps for now
|
||||||
|
instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture] + " 4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for(int i = 1;i < 7;i++)
|
for(int i = 1;i < 7;i++)
|
||||||
{
|
{
|
||||||
if(!texName[i].empty())
|
if(!texName[i].empty() && (i == Nif::NiTexturingProperty::DarkTexture || i == Nif::NiTexturingProperty::DecalTexture
|
||||||
|
|| i == Nif::NiTexturingProperty::GlossTexture))
|
||||||
warn("Ignored texture "+texName[i]+" on layer "+Ogre::StringConverter::toString(i)+"\n");
|
warn("Ignored texture "+texName[i]+" on layer "+Ogre::StringConverter::toString(i)+"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,18 +1005,20 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
|
||||||
size_t numUVs = data->uvlist.size();
|
size_t numUVs = data->uvlist.size();
|
||||||
if(numUVs)
|
if(numUVs)
|
||||||
{
|
{
|
||||||
size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
|
|
||||||
vbuf = hwBufMgr->createVertexBuffer(elemSize, srcVerts.size()*numUVs,
|
|
||||||
Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
|
|
||||||
for(size_t i = 0;i < numUVs;i++)
|
for(size_t i = 0;i < numUVs;i++)
|
||||||
{
|
{
|
||||||
|
size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
|
||||||
|
vbuf = hwBufMgr->createVertexBuffer(elemSize, srcVerts.size(),
|
||||||
|
Ogre::HardwareBuffer::HBU_STATIC);
|
||||||
|
|
||||||
const std::vector<Ogre::Vector2> &uvlist = data->uvlist[i];
|
const std::vector<Ogre::Vector2> &uvlist = data->uvlist[i];
|
||||||
vbuf->writeData(i*srcVerts.size()*elemSize, elemSize*srcVerts.size(), &uvlist[0], true);
|
|
||||||
decl->addElement(nextBuf, i*srcVerts.size()*elemSize, Ogre::VET_FLOAT2,
|
vbuf->writeData(0, elemSize*srcVerts.size(), &uvlist[0], true);
|
||||||
|
decl->addElement(nextBuf, 0, Ogre::VET_FLOAT2,
|
||||||
Ogre::VES_TEXTURE_COORDINATES, i);
|
Ogre::VES_TEXTURE_COORDINATES, i);
|
||||||
}
|
|
||||||
bind->setBinding(nextBuf++, vbuf);
|
bind->setBinding(nextBuf++, vbuf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Triangle faces
|
// Triangle faces
|
||||||
const std::vector<short> &srcIdx = data->triangles;
|
const std::vector<short> &srcIdx = data->triangles;
|
||||||
|
|
|
@ -9,9 +9,10 @@ material openmw_objects_base
|
||||||
normalMap
|
normalMap
|
||||||
emissiveMap
|
emissiveMap
|
||||||
use_emissive_map false
|
use_emissive_map false
|
||||||
|
use_detail_map false
|
||||||
emissiveMapUVSet 0
|
emissiveMapUVSet 0
|
||||||
|
detailMapUVSet 0
|
||||||
|
|
||||||
is_transparent false // real transparency, alpha rejection doesn't count here
|
|
||||||
scene_blend default
|
scene_blend default
|
||||||
depth_write default
|
depth_write default
|
||||||
depth_check default
|
depth_check default
|
||||||
|
@ -26,10 +27,11 @@ material openmw_objects_base
|
||||||
shader_properties
|
shader_properties
|
||||||
{
|
{
|
||||||
vertexcolor_mode $vertmode
|
vertexcolor_mode $vertmode
|
||||||
is_transparent $is_transparent
|
|
||||||
normalMap $normalMap
|
normalMap $normalMap
|
||||||
emissiveMapUVSet $emissiveMapUVSet
|
emissiveMapUVSet $emissiveMapUVSet
|
||||||
|
detailMapUVSet $detailMapUVSet
|
||||||
emissiveMap $emissiveMap
|
emissiveMap $emissiveMap
|
||||||
|
detailMap $detailMap
|
||||||
}
|
}
|
||||||
|
|
||||||
diffuse $diffuse
|
diffuse $diffuse
|
||||||
|
@ -51,7 +53,7 @@ material openmw_objects_base
|
||||||
|
|
||||||
texture_unit normalMap
|
texture_unit normalMap
|
||||||
{
|
{
|
||||||
direct_texture $normalMap
|
texture $normalMap
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_unit emissiveMap
|
texture_unit emissiveMap
|
||||||
|
@ -62,6 +64,14 @@ material openmw_objects_base
|
||||||
tex_coord_set $emissiveMapUVSet
|
tex_coord_set $emissiveMapUVSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
texture_unit detailMap
|
||||||
|
{
|
||||||
|
create_in_ffp $use_detail_map
|
||||||
|
colour_op_ex modulate_x2 src_current src_texture
|
||||||
|
direct_texture $detailMap
|
||||||
|
tex_coord_set $detailMapUVSet
|
||||||
|
}
|
||||||
|
|
||||||
texture_unit shadowMap0
|
texture_unit shadowMap0
|
||||||
{
|
{
|
||||||
content_type shadow
|
content_type shadow
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
|
|
||||||
#define NORMAL_MAP @shPropertyHasValue(normalMap)
|
#define NORMAL_MAP @shPropertyHasValue(normalMap)
|
||||||
#define EMISSIVE_MAP @shPropertyHasValue(emissiveMap)
|
#define EMISSIVE_MAP @shPropertyHasValue(emissiveMap)
|
||||||
|
#define DETAIL_MAP @shPropertyHasValue(detailMap)
|
||||||
|
|
||||||
// right now we support 2 UV sets max. implementing them is tedious, and we're probably not going to need more
|
// right now we support 2 UV sets max. implementing them is tedious, and we're probably not going to need more
|
||||||
#define SECOND_UV_SET @shPropertyString(emissiveMapUVSet)
|
#define SECOND_UV_SET (@shPropertyString(emissiveMapUVSet) || @shPropertyString(detailMapUVSet))
|
||||||
|
|
||||||
// if normal mapping is enabled, we force pixel lighting
|
// if normal mapping is enabled, we force pixel lighting
|
||||||
#define VERTEX_LIGHTING (!@shPropertyHasValue(normalMap))
|
#define VERTEX_LIGHTING (!@shPropertyHasValue(normalMap))
|
||||||
|
@ -236,6 +237,10 @@
|
||||||
shSampler2D(emissiveMap)
|
shSampler2D(emissiveMap)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if DETAIL_MAP
|
||||||
|
shSampler2D(detailMap)
|
||||||
|
#endif
|
||||||
|
|
||||||
shInput(float4, UV)
|
shInput(float4, UV)
|
||||||
|
|
||||||
#if NORMAL_MAP
|
#if NORMAL_MAP
|
||||||
|
@ -313,6 +318,14 @@
|
||||||
{
|
{
|
||||||
shOutputColour(0) = shSample(diffuseMap, UV.xy);
|
shOutputColour(0) = shSample(diffuseMap, UV.xy);
|
||||||
|
|
||||||
|
#if DETAIL_MAP
|
||||||
|
#if @shPropertyString(detailMapUVSet)
|
||||||
|
shOutputColour(0) *= shSample(detailMap, UV.zw)*2;
|
||||||
|
#else
|
||||||
|
shOutputColour(0) *= shSample(detailMap, UV.xy)*2;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if NORMAL_MAP
|
#if NORMAL_MAP
|
||||||
float3 normal = normalPassthrough;
|
float3 normal = normalPassthrough;
|
||||||
float3 binormal = cross(tangentPassthrough.xyz, normal.xyz);
|
float3 binormal = cross(tangentPassthrough.xyz, normal.xyz);
|
||||||
|
@ -419,7 +432,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EMISSIVE_MAP
|
#if EMISSIVE_MAP
|
||||||
#if SECOND_UV_SET
|
#if @shPropertyString(emissiveMapUVSet)
|
||||||
shOutputColour(0).xyz += shSample(emissiveMap, UV.zw).xyz;
|
shOutputColour(0).xyz += shSample(emissiveMap, UV.zw).xyz;
|
||||||
#else
|
#else
|
||||||
shOutputColour(0).xyz += shSample(emissiveMap, UV.xy).xyz;
|
shOutputColour(0).xyz += shSample(emissiveMap, UV.xy).xyz;
|
||||||
|
|
Loading…
Reference in a new issue