Merge remote-tracking branch 'scrawl/master'

actorid
Marc Zinnschlag 12 years ago
commit 85e5bd212b

@ -159,4 +159,9 @@ namespace MWClass
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
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;
}
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 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;
}
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 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;
}
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 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);
}
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.
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);
}
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
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);
}
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
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));
}
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)
const;
///< 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);
}
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.
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);
}
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
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));
}
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;
///< Return item max health or throw an exception, if class does not have item health
/// (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;
}
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 bool canSell (const MWWorld::Ptr& item, int npcServices) const;
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
};
}

@ -150,6 +150,7 @@ namespace MWGui
it = invStore.add(ptr);
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
ptr = *it;
mDragAndDrop->mDraggedFrom->notifyItemDragged(ptr, -mDragAndDrop->mDraggedCount);
}
/// \todo scripts

@ -257,6 +257,12 @@ namespace MWGui
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);
// 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();
mWindowManager.getInventoryWindow()->transferBoughtItems();
@ -356,32 +362,7 @@ namespace MWGui
services = ref->mBase->mAiData.mServices;
}
/// \todo what about potions, there doesn't seem to be a flag for them??
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;
return MWWorld::Class::get(item).canSell(item, services);
}
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()

@ -156,6 +156,7 @@ namespace MWGui
MWBase::Environment::get().getWorld()->advanceTime(time);
}
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_Dialogue);
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0);

@ -45,7 +45,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
Ptr container (&*iter, &cellStore);
Class::get (container).getContainerStore (container).fill (
iter->mBase->mInventory, mStore);
iter->mBase->mInventory, container.getCellRef().mOwner, mStore);
}
for (CellRefList<ESM::Creature>::List::iterator iter (
@ -55,7 +55,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
Ptr container (&*iter, &cellStore);
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 (
@ -65,7 +65,7 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore)
Ptr container (&*iter, &cellStore);
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");
}
bool Class::canSell (const MWWorld::Ptr& item, int npcServices) const
{
return false;
}
MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const
{
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 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 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/scriptmanager.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "manualref.hpp"
#include "refdata.hpp"
#include "class.hpp"
@ -175,24 +177,76 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImpl (const Ptr& ptr
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();
++iter)
{
ManualRef ref (store, iter->mItem.toString());
std::string id = iter->mItem.toString();
addInitialItem(id, owner, iter->mCount);
}
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 (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each)
{
/// \todo implement leveled item lists
continue;
for (int i=0; i<count; ++i)
addInitialItem(id, owner, 1, failChance, false);
return;
}
ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
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());
}
flagAsModified();
}
void MWWorld::ContainerStore::clear()

@ -53,6 +53,7 @@ namespace MWWorld
mutable float mCachedWeight;
mutable bool mWeightUpToDate;
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:
@ -84,7 +85,7 @@ namespace MWWorld
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.
void clear();

@ -22,17 +22,20 @@ struct LeveledListBase
{
enum Flags
{
AllLevels = 0x01, // Calculate from all levels <= player
// level, not just the closest below
// player.
Each = 0x02 // Select a new item each time this
Each = 0x01, // Select a new item each time this
// list is instantiated, instead of
// giving several identical items
}; // (used when a container has more
// (used when a container has more
// than one instance of one leveled
// list.)
AllLevels = 0x02 // Calculate from all levels <= player
// level, not just the closest below
// player.
};
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;
// Record name used to read references. Must be set before load() is

@ -35,11 +35,11 @@ struct NPC
Apparatus = 0x00100,
RepairItem = 0x00200,
Misc = 0x00400,
Potions = 0x02000,
// Other services
Spells = 0x00800,
MagicItems = 0x01000,
Potions = 0x02000,
Training = 0x04000, // What skills?
Spellmaking = 0x08000,
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("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]));
if (!texName[Nif::NiTexturingProperty::GlowTexture].empty())
{
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)));
}
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++)
{
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");
}
@ -992,17 +1005,19 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
size_t numUVs = data->uvlist.size();
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++)
{
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];
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);
bind->setBinding(nextBuf++, vbuf);
}
bind->setBinding(nextBuf++, vbuf);
}
// Triangle faces

@ -9,9 +9,10 @@ material openmw_objects_base
normalMap
emissiveMap
use_emissive_map false
use_detail_map false
emissiveMapUVSet 0
detailMapUVSet 0
is_transparent false // real transparency, alpha rejection doesn't count here
scene_blend default
depth_write default
depth_check default
@ -26,10 +27,11 @@ material openmw_objects_base
shader_properties
{
vertexcolor_mode $vertmode
is_transparent $is_transparent
normalMap $normalMap
emissiveMapUVSet $emissiveMapUVSet
detailMapUVSet $detailMapUVSet
emissiveMap $emissiveMap
detailMap $detailMap
}
diffuse $diffuse
@ -51,7 +53,7 @@ material openmw_objects_base
texture_unit normalMap
{
direct_texture $normalMap
texture $normalMap
}
texture_unit emissiveMap
@ -61,6 +63,14 @@ material openmw_objects_base
direct_texture $emissiveMap
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
{

@ -16,9 +16,10 @@
#define NORMAL_MAP @shPropertyHasValue(normalMap)
#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
#define SECOND_UV_SET @shPropertyString(emissiveMapUVSet)
#define SECOND_UV_SET (@shPropertyString(emissiveMapUVSet) || @shPropertyString(detailMapUVSet))
// if normal mapping is enabled, we force pixel lighting
#define VERTEX_LIGHTING (!@shPropertyHasValue(normalMap))
@ -236,6 +237,10 @@
shSampler2D(emissiveMap)
#endif
#if DETAIL_MAP
shSampler2D(detailMap)
#endif
shInput(float4, UV)
#if NORMAL_MAP
@ -313,6 +318,14 @@
{
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
float3 normal = normalPassthrough;
float3 binormal = cross(tangentPassthrough.xyz, normal.xyz);
@ -419,7 +432,7 @@
#endif
#if EMISSIVE_MAP
#if SECOND_UV_SET
#if @shPropertyString(emissiveMapUVSet)
shOutputColour(0).xyz += shSample(emissiveMap, UV.zw).xyz;
#else
shOutputColour(0).xyz += shSample(emissiveMap, UV.xy).xyz;

Loading…
Cancel
Save