forked from teamnwah/openmw-tes3coop
Added GetStandingPC, GetStandingActor; Fixed GetStartingPos
This commit is contained in:
parent
1420a2cb33
commit
627c3fdb6b
9 changed files with 96 additions and 17 deletions
|
@ -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…
Reference in a new issue