mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 22:15:32 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
fa63ebce78
14 changed files with 155 additions and 21 deletions
|
@ -342,6 +342,8 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
||||||
///< get all containers in active cells owned by this Npc
|
///< get all containers in active cells owned by this Npc
|
||||||
|
virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
||||||
|
///< get all items in active cells owned by this Npc
|
||||||
|
|
||||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,39 @@
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
bool stacks (const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
||||||
|
{
|
||||||
|
if (left == right)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||||
|
if (left.getContainerStore() && right.getContainerStore())
|
||||||
|
return left.getContainerStore()->stacks(left, right)
|
||||||
|
&& right.getContainerStore()->stacks(left, right);
|
||||||
|
|
||||||
|
if (left.getContainerStore())
|
||||||
|
return left.getContainerStore()->stacks(left, right);
|
||||||
|
if (right.getContainerStore())
|
||||||
|
return right.getContainerStore()->stacks(left, right);
|
||||||
|
|
||||||
|
MWWorld::ContainerStore store;
|
||||||
|
return store.stacks(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources)
|
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources, const std::vector<MWWorld::Ptr>& worldItems)
|
||||||
: mItemSources(itemSources)
|
: mItemSources(itemSources)
|
||||||
|
, mWorldItems(worldItems)
|
||||||
{
|
{
|
||||||
assert (mItemSources.size());
|
assert (mItemSources.size());
|
||||||
}
|
}
|
||||||
|
@ -65,8 +93,7 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
{
|
{
|
||||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
if (stacks(*it, item.mBase))
|
||||||
if (*it == item.mBase || (store.stacks(*it, item.mBase) && item.mBase.getContainerStore()->stacks(*it, item.mBase)))
|
|
||||||
{
|
{
|
||||||
int refCount = it->getRefData().getCount();
|
int refCount = it->getRefData().getCount();
|
||||||
it->getRefData().setCount(std::max(0, refCount - toRemove));
|
it->getRefData().setCount(std::max(0, refCount - toRemove));
|
||||||
|
@ -76,6 +103,21 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
||||||
|
{
|
||||||
|
if (stacks(*source, item.mBase))
|
||||||
|
{
|
||||||
|
int refCount = source->getRefData().getCount();
|
||||||
|
if (refCount - toRemove <= 0)
|
||||||
|
MWBase::Environment::get().getWorld()->deleteObject(*source);
|
||||||
|
else
|
||||||
|
source->getRefData().setCount(std::max(0, refCount - toRemove));
|
||||||
|
toRemove -= refCount;
|
||||||
|
if (toRemove <= 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Not enough items to remove could be found");
|
throw std::runtime_error("Not enough items to remove could be found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +133,7 @@ void ContainerItemModel::update()
|
||||||
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
||||||
for (; itemStack != mItems.end(); ++itemStack)
|
for (; itemStack != mItems.end(); ++itemStack)
|
||||||
{
|
{
|
||||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
if (stacks(*it, itemStack->mBase))
|
||||||
if (store.stacks(itemStack->mBase, *it) && it->getContainerStore()->stacks(itemStack->mBase, *it))
|
|
||||||
{
|
{
|
||||||
// we already have an item stack of this kind, add to it
|
// we already have an item stack of this kind, add to it
|
||||||
itemStack->mCount += it->getRefData().getCount();
|
itemStack->mCount += it->getRefData().getCount();
|
||||||
|
@ -108,6 +149,26 @@ void ContainerItemModel::update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
||||||
|
{
|
||||||
|
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
||||||
|
for (; itemStack != mItems.end(); ++itemStack)
|
||||||
|
{
|
||||||
|
if (stacks(*source, itemStack->mBase))
|
||||||
|
{
|
||||||
|
// we already have an item stack of this kind, add to it
|
||||||
|
itemStack->mCount += source->getRefData().getCount();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemStack == mItems.end())
|
||||||
|
{
|
||||||
|
// no stack yet, create one
|
||||||
|
ItemStack newItem (*source, this, source->getRefData().getCount());
|
||||||
|
mItems.push_back(newItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace MWGui
|
||||||
class ContainerItemModel : public ItemModel
|
class ContainerItemModel : public ItemModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContainerItemModel (const std::vector<MWWorld::Ptr>& itemSources);
|
ContainerItemModel (const std::vector<MWWorld::Ptr>& itemSources, const std::vector<MWWorld::Ptr>& worldItems);
|
||||||
///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal,
|
///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal,
|
||||||
/// while the last element will be used to add new items to.
|
/// while the last element will be used to add new items to.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ namespace MWGui
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<MWWorld::Ptr> mItemSources;
|
std::vector<MWWorld::Ptr> mItemSources;
|
||||||
|
std::vector<MWWorld::Ptr> mWorldItems;
|
||||||
|
|
||||||
std::vector<ItemStack> mItems;
|
std::vector<ItemStack> mItems;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,8 +13,6 @@ namespace MWGui
|
||||||
, mType(Type_Normal)
|
, mType(Type_Normal)
|
||||||
, mBase(base)
|
, mBase(base)
|
||||||
{
|
{
|
||||||
assert(base.getContainerStore());
|
|
||||||
|
|
||||||
if (MWWorld::Class::get(base).getEnchantment(base) != "")
|
if (MWWorld::Class::get(base).getEnchantment(base) != "")
|
||||||
mFlags |= Flag_Enchanted;
|
mFlags |= Flag_Enchanted;
|
||||||
}
|
}
|
||||||
|
@ -31,18 +29,42 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
if(mBase == other.mBase)
|
if(mBase == other.mBase)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||||
|
if (mBase.getContainerStore() && other.mBase.getContainerStore())
|
||||||
return mBase.getContainerStore()->stacks(mBase, other.mBase)
|
return mBase.getContainerStore()->stacks(mBase, other.mBase)
|
||||||
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||||
|
|
||||||
|
if (mBase.getContainerStore())
|
||||||
|
return mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||||
|
if (other.mBase.getContainerStore())
|
||||||
|
return other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||||
|
|
||||||
|
MWWorld::ContainerStore store;
|
||||||
|
return store.stacks(mBase, other.mBase);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == (const ItemStack& left, const ItemStack& right)
|
bool operator == (const ItemStack& left, const ItemStack& right)
|
||||||
{
|
{
|
||||||
if (left.mType != right.mType)
|
if (left.mType != right.mType)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(left.mBase == right.mBase)
|
if(left.mBase == right.mBase)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||||
|
if (left.mBase.getContainerStore() && right.mBase.getContainerStore())
|
||||||
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase)
|
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase)
|
||||||
&& right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
&& right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||||
|
|
||||||
|
if (left.mBase.getContainerStore())
|
||||||
|
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||||
|
if (right.mBase.getContainerStore())
|
||||||
|
return right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||||
|
|
||||||
|
MWWorld::ContainerStore store;
|
||||||
|
return store.stacks(left.mBase, right.mBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemModel::ItemModel()
|
ItemModel::ItemModel()
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace MWGui
|
||||||
if (item.mType == ItemStack::Type_Equipped && !mShowEquipped)
|
if (item.mType == ItemStack::Type_Equipped && !mShowEquipped)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int category;
|
int category = 0;
|
||||||
if (base.getTypeName() == typeid(ESM::Armor).name()
|
if (base.getTypeName() == typeid(ESM::Armor).name()
|
||||||
|| base.getTypeName() == typeid(ESM::Clothing).name())
|
|| base.getTypeName() == typeid(ESM::Clothing).name())
|
||||||
category = Category_Apparel;
|
category = Category_Apparel;
|
||||||
|
|
|
@ -88,8 +88,10 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources);
|
MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources);
|
||||||
// Important: actor goes last, so that items purchased by the merchant go into his inventory
|
// Important: actor goes last, so that items purchased by the merchant go into his inventory
|
||||||
itemSources.push_back(actor);
|
itemSources.push_back(actor);
|
||||||
|
std::vector<MWWorld::Ptr> worldItems;
|
||||||
|
MWBase::Environment::get().getWorld()->getItemsOwnedBy(actor, worldItems);
|
||||||
|
|
||||||
mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources), mPtr);
|
mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources, worldItems), mPtr);
|
||||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||||
mItemView->setModel (mSortModel);
|
mItemView->setModel (mSortModel);
|
||||||
|
|
||||||
|
|
|
@ -64,13 +64,16 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
|
||||||
{
|
{
|
||||||
// select best shader mode
|
// select best shader mode
|
||||||
bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos);
|
bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos);
|
||||||
|
bool glES = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL ES") != std::string::npos);
|
||||||
|
|
||||||
// glsl is only supported in opengl mode and hlsl only in direct3d mode.
|
// glsl is only supported in opengl mode and hlsl only in direct3d mode.
|
||||||
if (Settings::Manager::getString("shader mode", "General") == ""
|
std::string currentMode = Settings::Manager::getString("shader mode", "General");
|
||||||
|| (openGL && Settings::Manager::getString("shader mode", "General") == "hlsl")
|
if (currentMode == ""
|
||||||
|| (!openGL && Settings::Manager::getString("shader mode", "General") == "glsl"))
|
|| (openGL && currentMode == "hlsl")
|
||||||
|
|| (!openGL && currentMode == "glsl")
|
||||||
|
|| (glES && currentMode != "glsles"))
|
||||||
{
|
{
|
||||||
Settings::Manager::setString("shader mode", "General", openGL ? "glsl" : "hlsl");
|
Settings::Manager::setString("shader mode", "General", openGL ? (glES ? "glsles" : "glsl") : "hlsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
|
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
|
||||||
|
@ -93,6 +96,8 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
|
||||||
std::string l = Settings::Manager::getString("shader mode", "General");
|
std::string l = Settings::Manager::getString("shader mode", "General");
|
||||||
if (l == "glsl")
|
if (l == "glsl")
|
||||||
lang = sh::Language_GLSL;
|
lang = sh::Language_GLSL;
|
||||||
|
else if (l == "glsles")
|
||||||
|
lang = sh::Language_GLSLES;
|
||||||
else if (l == "hlsl")
|
else if (l == "hlsl")
|
||||||
lang = sh::Language_HLSL;
|
lang = sh::Language_HLSL;
|
||||||
else
|
else
|
||||||
|
|
|
@ -1724,4 +1724,31 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ListHandlesFunctor
|
||||||
|
{
|
||||||
|
std::vector<std::string> mHandles;
|
||||||
|
|
||||||
|
bool operator() (ESM::CellRef& ref, RefData& data)
|
||||||
|
{
|
||||||
|
Ogre::SceneNode* handle = data.getBaseNode();
|
||||||
|
if (handle)
|
||||||
|
mHandles.push_back(handle->getName());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void World::getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out)
|
||||||
|
{
|
||||||
|
const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells();
|
||||||
|
for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt)
|
||||||
|
{
|
||||||
|
ListHandlesFunctor functor;
|
||||||
|
(*cellIt)->forEach<ListHandlesFunctor>(functor);
|
||||||
|
|
||||||
|
for (std::vector<std::string>::iterator it = functor.mHandles.begin(); it != functor.mHandles.end(); ++it)
|
||||||
|
if (Misc::StringUtils::ciEqual(searchPtrViaHandle(*it).mCellRef->mOwner, npc.getCellRef().mRefID))
|
||||||
|
out.push_back(searchPtrViaHandle(*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,6 +391,8 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out);
|
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out);
|
||||||
///< get all containers in active cells owned by this Npc
|
///< get all containers in active cells owned by this Npc
|
||||||
|
virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out);
|
||||||
|
///< get all items in active cells owned by this Npc
|
||||||
|
|
||||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
||||||
|
|
||||||
|
|
2
extern/shiny/Docs/Materials.dox
vendored
2
extern/shiny/Docs/Materials.dox
vendored
|
@ -87,6 +87,8 @@
|
||||||
Now, let's get into writing our shader! As you can guess from above, the filename should be 'example.shader'.
|
Now, let's get into writing our shader! As you can guess from above, the filename should be 'example.shader'.
|
||||||
Make sure to also copy the 'core.h' file to the same location. It is included in shiny's source tree under 'Extra/'.
|
Make sure to also copy the 'core.h' file to the same location. It is included in shiny's source tree under 'Extra/'.
|
||||||
|
|
||||||
|
Important: a newline at the end of the file is <b>required</b>. Many editors do this automatically or can be configured to do so. If there is no newline at the end of the file, and the last line is '#endif', you will get the rather cryptic error message " ill formed preprocessor directive: #endif" from boost::wave.
|
||||||
|
|
||||||
\code
|
\code
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
|
|
2
extern/shiny/Editor/Actions.hpp
vendored
2
extern/shiny/Editor/Actions.hpp
vendored
|
@ -10,7 +10,7 @@ namespace sh
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void execute() = 0;
|
virtual void execute() = 0;
|
||||||
virtual ~Action();
|
virtual ~Action() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ActionDeleteMaterial : public Action
|
class ActionDeleteMaterial : public Action
|
||||||
|
|
2
extern/shiny/Editor/Query.hpp
vendored
2
extern/shiny/Editor/Query.hpp
vendored
|
@ -15,7 +15,7 @@ class Query
|
||||||
public:
|
public:
|
||||||
Query()
|
Query()
|
||||||
: mDone(false) {}
|
: mDone(false) {}
|
||||||
virtual ~Query();
|
virtual ~Query() {}
|
||||||
|
|
||||||
void execute();
|
void execute();
|
||||||
|
|
||||||
|
|
|
@ -58,11 +58,20 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SH_GLSL == 1
|
#if SH_GLSL == 1 || SH_GLSLES == 1
|
||||||
|
|
||||||
#define shFract(val) fract(val)
|
#define shFract(val) fract(val)
|
||||||
|
|
||||||
|
#if SH_GLSLES == 1
|
||||||
|
@version 100
|
||||||
|
#else
|
||||||
@version 120
|
@version 120
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SH_GLSLES == 1 && SH_FRAGMENT_SHADER
|
||||||
|
precision mediump int;
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define float2 vec2
|
#define float2 vec2
|
||||||
#define float3 vec3
|
#define float3 vec3
|
||||||
|
|
|
@ -206,6 +206,7 @@ void OgreRenderer::configure(const std::string &logPath,
|
||||||
pluginDir = absPluginPath.string();
|
pluginDir = absPluginPath.string();
|
||||||
|
|
||||||
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mRoot);
|
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mRoot);
|
||||||
|
Files::loadOgrePlugin(pluginDir, "RenderSystem_GLES2", *mRoot);
|
||||||
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mRoot);
|
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mRoot);
|
||||||
Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mRoot);
|
Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mRoot);
|
||||||
Files::loadOgrePlugin(pluginDir, "Plugin_CgProgramManager", *mRoot);
|
Files::loadOgrePlugin(pluginDir, "Plugin_CgProgramManager", *mRoot);
|
||||||
|
|
Loading…
Reference in a new issue