Merge remote-tracking branch 'wheybags/master' into next

This commit is contained in:
Marc Zinnschlag 2013-02-05 11:55:47 +01:00
commit 86fb3574a0
9 changed files with 113 additions and 24 deletions

View file

@ -41,7 +41,7 @@ add_openmw_dir (mwscript
locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions
guiextensions soundextensions skyextensions statsextensions containerextensions guiextensions soundextensions skyextensions statsextensions containerextensions
aiextensions controlextensions extensions globalscripts ref dialogueextensions aiextensions controlextensions extensions globalscripts ref dialogueextensions
animationextensions transformationextensions consoleextensions userextensions animationextensions transformationextensions consoleextensions userextensions locals
) )
add_openmw_dir (mwsound add_openmw_dir (mwsound

View file

@ -7,6 +7,8 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <components/compiler/locals.hpp>
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
@ -240,6 +242,12 @@ namespace MWGui
if (it != invStore.end() && *it == item) if (it != invStore.end() && *it == item)
{ {
invStore.equip(slot, invStore.end()); invStore.equip(slot, invStore.end());
std::string script = MWWorld::Class::get(*it).getScript(*it);
// Unset OnPCEquip Variable on item's script, if it has a script with that variable declared
if(script != "")
(*it).mRefData->getLocals().setVarByInt(script, "onpcequip", 0);
return; return;
} }
} }

View file

@ -50,6 +50,14 @@ namespace MWScript
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item); MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item);
ref.getPtr().getRefData().setCount (count); ref.getPtr().getRefData().setCount (count);
// 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()); MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());
} }

View file

@ -0,0 +1,41 @@
#include "locals.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/scriptmanager.hpp"
#include <components/compiler/locals.hpp>
namespace MWScript
{
void Locals::configure (const ESM::Script& script)
{
mShorts.clear();
mShorts.resize (script.mData.mNumShorts, 0);
mLongs.clear();
mLongs.resize (script.mData.mNumLongs, 0);
mFloats.clear();
mFloats.resize (script.mData.mNumFloats, 0);
}
bool Locals::setVarByInt(const std::string& script, const std::string& var, int val)
{
Compiler::Locals locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
int index = locals.getIndex(var);
char type = locals.getType(var);
if(index != -1)
{
switch(type)
{
case 's':
mShorts.at (index) = val; break;
case 'l':
mLongs.at (index) = val; break;
case 'f':
mFloats.at (index) = val; break;
}
return true;
}
return false;
}
}

View file

@ -8,21 +8,16 @@
namespace MWScript namespace MWScript
{ {
struct Locals class Locals
{ {
std::vector<Interpreter::Type_Short> mShorts; public:
std::vector<Interpreter::Type_Integer> mLongs; std::vector<Interpreter::Type_Short> mShorts;
std::vector<Interpreter::Type_Float> mFloats; std::vector<Interpreter::Type_Integer> mLongs;
std::vector<Interpreter::Type_Float> mFloats;
void configure (const ESM::Script& script);
bool setVarByInt(const std::string& script, const std::string& var, int val);
void configure (const ESM::Script& script)
{
mShorts.clear();
mShorts.resize (script.mData.mNumShorts, 0);
mLongs.clear();
mLongs.resize (script.mData.mNumLongs, 0);
mFloats.clear();
mFloats.resize (script.mData.mNumFloats, 0);
}
}; };
} }

View file

@ -4,6 +4,8 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include <components/compiler/locals.hpp>
#include "inventorystore.hpp" #include "inventorystore.hpp"
#include "player.hpp" #include "player.hpp"
#include "class.hpp" #include "class.hpp"
@ -35,6 +37,8 @@ namespace MWWorld
std::string npcRace = actor.get<ESM::NPC>()->mBase->mRace; std::string npcRace = actor.get<ESM::NPC>()->mBase->mRace;
bool equipped = false;
// equip the item in the first free slot // equip the item in the first free slot
for (std::vector<int>::const_iterator slot=slots.first.begin(); for (std::vector<int>::const_iterator slot=slots.first.begin();
slot!=slots.first.end(); ++slot) slot!=slots.first.end(); ++slot)
@ -91,6 +95,7 @@ namespace MWWorld
if (slot == --slots.first.end()) if (slot == --slots.first.end())
{ {
invStore.equip(*slot, it); invStore.equip(*slot, it);
equipped = true;
break; break;
} }
@ -98,8 +103,15 @@ namespace MWWorld
{ {
// slot is not occupied // slot is not occupied
invStore.equip(*slot, it); invStore.equip(*slot, it);
equipped = true;
break; break;
} }
} }
std::string script = MWWorld::Class::get(*it).getScript(*it);
/* Set OnPCEquip Variable on item's script, if the player is equipping it, and it has a script with that variable declared */
if(equipped && actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() && script != "")
(*it).mRefData->getLocals().setVarByInt(script, "onpcequip", 1);
} }
} }

View file

@ -8,9 +8,11 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <components/esm/loadcont.hpp> #include <components/esm/loadcont.hpp>
#include <components/compiler/locals.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/scriptmanager.hpp"
#include "manualref.hpp" #include "manualref.hpp"
#include "refdata.hpp" #include "refdata.hpp"
@ -83,9 +85,14 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
CellStore *cell; CellStore *cell;
Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
// Items in players inventory have cell set to 0, so their scripts will never be removed
if(&(MWWorld::Class::get (player).getContainerStore (player)) == this) if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
cell = 0; {
cell = 0; // Items in player's inventory have cell set to 0, so their scripts will never be removed
// Set OnPCAdd special variable, if it is declared
item.mRefData->getLocals().setVarByInt(script, "onpcadd", 1);
}
else else
cell = player.getCell(); cell = player.getCell();

View file

@ -2,11 +2,13 @@
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/files/collections.hpp> #include <components/files/collections.hpp>
#include <components/compiler/locals.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/scriptmanager.hpp"
#include "../mwrender/sky.hpp" #include "../mwrender/sky.hpp"
#include "../mwrender/player.hpp" #include "../mwrender/player.hpp"
@ -694,10 +696,11 @@ namespace MWWorld
bool isPlayer = ptr == mPlayer->getPlayer(); bool isPlayer = ptr == mPlayer->getPlayer();
bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer; bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
removeContainerScripts(ptr);
if (*currCell != newCell) if (*currCell != newCell)
{ {
removeContainerScripts(ptr);
if (isPlayer) if (isPlayer)
if (!newCell.isExterior()) if (!newCell.isExterior())
changeToInteriorCell(Misc::StringUtils::lowerCase(newCell.mCell->mName), pos); changeToInteriorCell(Misc::StringUtils::lowerCase(newCell.mCell->mName), pos);
@ -1270,6 +1273,15 @@ namespace MWWorld
mRendering->toggleWater(); mRendering->toggleWater();
} }
void World::PCDropped (const Ptr& item)
{
std::string script = MWWorld::Class::get(item).getScript(item);
// Set OnPCDrop Variable on item's script, if it has a script with that variable declared
if(script != "")
item.mRefData->getLocals().setVarByInt(script, "onpcdrop", 1);
}
bool World::placeObject (const Ptr& object, float cursorX, float cursorY) bool World::placeObject (const Ptr& object, float cursorX, float cursorY)
{ {
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY); std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
@ -1292,9 +1304,10 @@ namespace MWWorld
pos.pos[1] = -result.second[2]; pos.pos[1] = -result.second[2];
pos.pos[2] = result.second[1]; pos.pos[2] = result.second[1];
copyObjectToCell(object, *cell, pos); Ptr dropped = copyObjectToCell(object, *cell, pos);
PCDropped(dropped);
object.getRefData().setCount(0); object.getRefData().setCount(0);
return true; return true;
} }
@ -1309,8 +1322,8 @@ namespace MWWorld
return true; return true;
} }
void
World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos) Ptr World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos)
{ {
/// \todo add searching correct cell for position specified /// \todo add searching correct cell for position specified
MWWorld::Ptr dropped = MWWorld::Ptr dropped =
@ -1334,6 +1347,8 @@ namespace MWWorld
} }
addContainerScripts(dropped, &cell); addContainerScripts(dropped, &cell);
} }
return dropped;
} }
void World::dropObjectOnGround (const Ptr& actor, const Ptr& object) void World::dropObjectOnGround (const Ptr& actor, const Ptr& object)
@ -1354,7 +1369,9 @@ namespace MWWorld
mPhysics->castRay(orig, dir, len); mPhysics->castRay(orig, dir, len);
pos.pos[2] = hit.second.z; pos.pos[2] = hit.second.z;
copyObjectToCell(object, *cell, pos); Ptr dropped = copyObjectToCell(object, *cell, pos);
if(actor == mPlayer->getPlayer()) // Only call if dropped by player
PCDropped(dropped);
object.getRefData().setCount(0); object.getRefData().setCount(0);
} }

View file

@ -91,8 +91,8 @@ namespace MWWorld
bool moveObjectImp (const Ptr& ptr, float x, float y, float z); bool moveObjectImp (const Ptr& ptr, float x, float y, float z);
///< @return true if the active cell (cell player is in) changed ///< @return true if the active cell (cell player is in) changed
virtual void
copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); Ptr copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos);
void updateWindowManager (); void updateWindowManager ();
void performUpdateSceneQueries (); void performUpdateSceneQueries ();
@ -107,6 +107,7 @@ namespace MWWorld
void removeContainerScripts(const Ptr& reference); void removeContainerScripts(const Ptr& reference);
void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell); void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell);
void PCDropped (const Ptr& item);
public: public: