Added GetStandingPC, GetStandingActor; Fixed GetStartingPos

actorid
scrawl 12 years ago
parent 1420a2cb33
commit 627c3fdb6b

@ -331,6 +331,9 @@ namespace MWBase
virtual void activateDoor(const MWWorld::Ptr& door) = 0;
///< activate (open or close) an non-teleport door
virtual bool getPlayerStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if the player is standing on \a object
virtual bool getActorStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if any actor is standing on \a object
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
virtual int canRest() = 0;

@ -331,5 +331,9 @@ op 0x2000208: MoveWorld
op 0x2000209: MoveWorld, explicit
op 0x200020a: Fall
op 0x200020b: Fall, explicit
op 0x200020c: GetStandingPC
op 0x200020d: GetStandingPC, explicit
op 0x200020e: GetStandingActor
op 0x200020f: GetStandingActor, explicit
opcodes 0x200020c-0x3ffffff unused
opcodes 0x2000210-0x3ffffff unused

@ -565,6 +565,30 @@ namespace MWScript
}
};
template <class R>
class OpGetStandingPc : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push (MWBase::Environment::get().getWorld()->getPlayerStandingOn(ptr));
}
};
template <class R>
class OpGetStandingActor : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push (MWBase::Environment::get().getWorld()->getActorStandingOn(ptr));
}
};
const int opcodeXBox = 0x200000c;
const int opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075;
@ -608,6 +632,10 @@ namespace MWScript
const int opcodeGetSquareRoot = 0x20001e7;
const int opcodeFall = 0x200020a;
const int opcodeFallExplicit = 0x200020b;
const int opcodeGetStandingPc = 0x200020c;
const int opcodeGetStandingPcExplicit = 0x200020d;
const int opcodeGetStandingActor = 0x200020e;
const int opcodeGetStandingActorExplicit = 0x200020f;
const int opcodePlayBink = 0x20001f7;
@ -650,6 +678,8 @@ namespace MWScript
extensions.registerInstruction ("setdelete", "l", opcodeSetDelete, opcodeSetDeleteExplicit);
extensions.registerFunction ("getsquareroot", 'f', "f", opcodeGetSquareRoot);
extensions.registerInstruction ("fall", "", opcodeFall, opcodeFallExplicit);
extensions.registerFunction ("getstandingpc", 'l', "", opcodeGetStandingPc, opcodeGetStandingPcExplicit);
extensions.registerFunction ("getstandingactor", 'l', "", opcodeGetStandingActor, opcodeGetStandingActorExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
@ -698,7 +728,10 @@ namespace MWScript
interpreter.installSegment5 (opcodeGetSquareRoot, new OpGetSquareRoot);
interpreter.installSegment5 (opcodeFall, new OpFall<ImplicitRef>);
interpreter.installSegment5 (opcodeFallExplicit, new OpFall<ExplicitRef>);
interpreter.installSegment5 (opcodeGetStandingPc, new OpGetStandingPc<ImplicitRef>);
interpreter.installSegment5 (opcodeGetStandingPcExplicit, new OpGetStandingPc<ExplicitRef>);
interpreter.installSegment5 (opcodeGetStandingActor, new OpGetStandingActor<ImplicitRef>);
interpreter.installSegment5 (opcodeGetStandingActorExplicit, new OpGetStandingActor<ExplicitRef>);
}
}
}

@ -247,15 +247,15 @@ namespace MWScript
if(axis == "x")
{
runtime.push(ptr.getRefData().getPosition().pos[0]);
runtime.push(ptr.getCellRef().mPos.pos[0]);
}
else if(axis == "y")
{
runtime.push(ptr.getRefData().getPosition().pos[1]);
runtime.push(ptr.getCellRef().mPos.pos[1]);
}
else if(axis == "z")
{
runtime.push(ptr.getRefData().getPosition().pos[2]);
runtime.push(ptr.getCellRef().mPos.pos[2]);
}
else
throw std::runtime_error ("invalid axis: " + axis);

@ -501,7 +501,7 @@ namespace MWWorld
bool PhysicsSystem::toggleCollisionMode()
{
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->mActorMap.begin(); it != mEngine->mActorMap.end();it++)
{
if (it->first=="player")
{

@ -1583,4 +1583,20 @@ namespace MWWorld
return !mDoorStates[door]; // if currently opening or closing, then do the opposite
return door.getRefData().getLocalRotation().rot[2] == 0;
}
bool World::getPlayerStandingOn (const MWWorld::Ptr& object)
{
MWWorld::Ptr player = mPlayer->getPlayer();
if (!mPhysEngine->getCharacter("player")->getOnGround())
return false;
btVector3 from (player.getRefData().getPosition().pos[0], player.getRefData().getPosition().pos[1], player.getRefData().getPosition().pos[2]);
btVector3 to = from - btVector3(0,0,5);
std::pair<std::string, float> result = mPhysEngine->rayTest(from, to);
return result.first == object.getRefData().getBaseNode()->getName();
}
bool World::getActorStandingOn (const MWWorld::Ptr& object)
{
return mPhysEngine->isAnyActorStandingOn(object.getRefData().getBaseNode()->getName());
}
}

@ -381,6 +381,9 @@ namespace MWWorld
virtual void activateDoor(const MWWorld::Ptr& door);
///< activate (open or close) an non-teleport door
virtual bool getPlayerStandingOn (const MWWorld::Ptr& object); ///< @return true if the player is standing on \a object
virtual bool getActorStandingOn (const MWWorld::Ptr& object); ///< @return true if any actor is standing on \a object
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
virtual int canRest();

@ -267,8 +267,8 @@ namespace Physic
}
}
PhysicActorContainer::iterator pa_it = PhysicActorMap.begin();
for (; pa_it != PhysicActorMap.end(); ++pa_it)
PhysicActorContainer::iterator pa_it = mActorMap.begin();
for (; pa_it != mActorMap.end(); ++pa_it)
{
if (pa_it->second != NULL)
{
@ -567,13 +567,13 @@ namespace Physic
//dynamicsWorld->addAction( newActor->mCharacter );
PhysicActorMap[name] = newActor;
mActorMap[name] = newActor;
}
void PhysicEngine::removeCharacter(const std::string &name)
{
PhysicActorContainer::iterator it = PhysicActorMap.find(name);
if (it != PhysicActorMap.end() )
PhysicActorContainer::iterator it = mActorMap.find(name);
if (it != mActorMap.end() )
{
PhysicActor* act = it->second;
if(act != NULL)
@ -581,16 +581,16 @@ namespace Physic
delete act;
}
PhysicActorMap.erase(it);
mActorMap.erase(it);
}
}
PhysicActor* PhysicEngine::getCharacter(const std::string &name)
{
PhysicActorContainer::iterator it = PhysicActorMap.find(name);
if (it != PhysicActorMap.end() )
PhysicActorContainer::iterator it = mActorMap.find(name);
if (it != mActorMap.end() )
{
PhysicActor* act = PhysicActorMap[name];
PhysicActor* act = mActorMap[name];
return act;
}
else
@ -700,4 +700,22 @@ namespace Physic
max = btVector3(0,0,0);
}
}
}}
bool PhysicEngine::isAnyActorStandingOn (const std::string& objectName)
{
for (PhysicActorContainer::iterator it = mActorMap.begin(); it != mActorMap.end(); ++it)
{
if (!it->second->getOnGround())
continue;
Ogre::Vector3 pos = it->second->getPosition();
btVector3 from (pos.x, pos.y, pos.z);
btVector3 to = from - btVector3(0,0,5);
std::pair<std::string, float> result = rayTest(from, to);
if (result.first == objectName)
return true;
}
return false;
}
}
}

@ -288,6 +288,8 @@ namespace Physic
void setSceneManager(Ogre::SceneManager* sceneMgr);
bool isAnyActorStandingOn (const std::string& objectName);
/**
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
*/
@ -329,7 +331,7 @@ namespace Physic
RigidBodyContainer mRaycastingObjectMap;
typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
PhysicActorContainer PhysicActorMap;
PhysicActorContainer mActorMap;
Ogre::SceneManager* mSceneMgr;

Loading…
Cancel
Save