mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-10 20:01:25 +00:00
1545 lines
39 KiB
C++
1545 lines
39 KiB
C++
/* ResidualVM - A 3D game interpreter
|
|
*
|
|
* ResidualVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#include "common/foreach.h"
|
|
|
|
#include "engines/grim/grim.h"
|
|
#include "engines/grim/lua_v1.h"
|
|
#include "engines/grim/actor.h"
|
|
#include "engines/grim/costume.h"
|
|
#include "engines/grim/set.h"
|
|
#include "engines/grim/model.h"
|
|
#include "engines/grim/gfx_base.h"
|
|
|
|
#include "engines/grim/lua/lauxlib.h"
|
|
|
|
namespace Grim {
|
|
|
|
void Lua_V1::LoadActor() {
|
|
lua_Object nameObj = lua_getparam(1);
|
|
const char *name;
|
|
|
|
if (lua_isnil(nameObj) || !lua_isstring(nameObj))
|
|
name = "<unnamed>";
|
|
else
|
|
name = lua_getstring(nameObj);
|
|
Actor *a = new Actor();
|
|
a->setName(name);
|
|
lua_pushusertag(a->getId(), MKTAG('A','C','T','R'));
|
|
}
|
|
|
|
void Lua_V1::GetActorTimeScale() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
lua_pushnumber(actor->getTimeScale());
|
|
}
|
|
|
|
void Lua_V1::SetSelectedActor() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
// TODO there is missing some check here: else lua_pushnil()
|
|
g_grim->setSelectedActor(getactor(actorObj));
|
|
}
|
|
|
|
/* Get the currently selected actor, this is used in
|
|
* "Camera-Relative" mode to handle the appropriate
|
|
* actor for movement
|
|
*/
|
|
void Lua_V1::GetCameraActor() {
|
|
// TODO verify what is going on with selected actor
|
|
Actor *actor = g_grim->getSelectedActor();
|
|
lua_pushusertag(actor->getId(), MKTAG('A','C','T','R'));
|
|
}
|
|
|
|
void Lua_V1::SetActorTalkColor() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object colorObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
if (!lua_isuserdata(colorObj) && lua_tag(colorObj) != MKTAG('C','O','L','R'))
|
|
return;
|
|
Actor *actor = getactor(actorObj);
|
|
actor->setTalkColor(getcolor(colorObj));
|
|
}
|
|
|
|
void Lua_V1::GetActorTalkColor() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
int32 cTag = actor->getTalkColor().toEncodedValue();
|
|
if (g_grim->getGameType() == GType_MONKEY4)
|
|
cTag |= (0xFF << 24);
|
|
lua_pushusertag(cTag, MKTAG('C','O','L','R'));
|
|
}
|
|
|
|
void Lua_V1::SetActorRestChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(3);
|
|
Costume *costume;
|
|
int chore;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
|
|
(!lua_isnumber(choreObj) && !lua_isnil(choreObj))) {
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
if (lua_isnil(choreObj)) {
|
|
chore = -1;
|
|
} else {
|
|
chore = (int)lua_getnumber(choreObj);
|
|
}
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
actor->setRestChore(chore, costume);
|
|
}
|
|
|
|
void Lua_V1::SetActorWalkChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(3);
|
|
Costume *costume;
|
|
int chore;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
|
|
(!lua_isnumber(choreObj) && !lua_isnil(choreObj))) {
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
if (lua_isnil(choreObj)) {
|
|
chore = -1;
|
|
} else {
|
|
chore = (int)lua_getnumber(choreObj);
|
|
}
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
actor->setWalkChore(chore, costume);
|
|
}
|
|
|
|
void Lua_V1::SetActorTurnChores() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object leftChoreObj = lua_getparam(2);
|
|
lua_Object rightChoreObj = lua_getparam(3);
|
|
lua_Object costumeObj = lua_getparam(4);
|
|
Costume *costume;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
|
|
(!lua_isnumber(leftChoreObj) && !lua_isnumber(rightChoreObj))) {
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
int leftChore = (int)lua_getnumber(leftChoreObj);
|
|
int rightChore = (int)lua_getnumber(rightChoreObj);
|
|
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
actor->setTurnChores(leftChore, rightChore, costume);
|
|
}
|
|
|
|
void Lua_V1::SetActorTalkChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object indexObj = lua_getparam(2);
|
|
lua_Object choreObj = lua_getparam(3);
|
|
lua_Object costumeObj = lua_getparam(4);
|
|
Costume *costume;
|
|
int chore;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
|
|
!lua_isnumber(indexObj) || (!lua_isnumber(choreObj) && !lua_isnil(choreObj))) {
|
|
return;
|
|
}
|
|
|
|
int index = (int)lua_getnumber(indexObj);
|
|
if (index < 1 || index > 16)
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
if (lua_isnil(choreObj)) {
|
|
chore = -1;
|
|
} else {
|
|
chore = (int)lua_getnumber(choreObj);
|
|
}
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
actor->setTalkChore(index, chore, costume);
|
|
}
|
|
|
|
void Lua_V1::SetActorMumblechore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(3);
|
|
Costume *costume;
|
|
int chore;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
|
|
(!lua_isnumber(choreObj) && !lua_isnil(choreObj))) {
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
if (lua_isnil(choreObj)) {
|
|
chore = -1;
|
|
} else {
|
|
chore = (int)lua_getnumber(choreObj);
|
|
}
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
actor->setMumbleChore(chore, costume);
|
|
}
|
|
|
|
void Lua_V1::SetActorVisibility() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
bool val = getbool(2);
|
|
actor->setVisibility(val);
|
|
}
|
|
|
|
void Lua_V1::SetActorScale() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object scaleObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float scale = 1.f;
|
|
|
|
if (lua_isnumber(scaleObj))
|
|
scale = lua_getnumber(scaleObj);
|
|
|
|
actor->setScale(scale);
|
|
}
|
|
|
|
void Lua_V1::SetActorTimeScale() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object scaleObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float scale = 1.f;
|
|
|
|
if (lua_isnumber(scaleObj))
|
|
scale = lua_getnumber(scaleObj);
|
|
|
|
actor->setTimeScale(scale);
|
|
}
|
|
|
|
void Lua_V1::SetActorCollisionMode() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object modeObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
Actor::CollisionMode mode = (Actor::CollisionMode)(int)(lua_getnumber(modeObj));
|
|
|
|
actor->setCollisionMode(mode);
|
|
}
|
|
|
|
void Lua_V1::SetActorCollisionScale() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object scaleObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float scale = lua_getnumber(scaleObj);
|
|
|
|
actor->setCollisionScale(scale);
|
|
}
|
|
|
|
void Lua_V1::PutActorAt() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object xObj = lua_getparam(2);
|
|
lua_Object yObj = lua_getparam(3);
|
|
lua_Object zObj = lua_getparam(4);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
if (!lua_isnumber(xObj) || !lua_isnumber(yObj) || !lua_isnumber(zObj)) {
|
|
warning("PutActorAt called without valid target position");
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float x = lua_getnumber(xObj);
|
|
float y = lua_getnumber(yObj);
|
|
float z = lua_getnumber(zObj);
|
|
actor->setPos(Math::Vector3d(x, y, z));
|
|
}
|
|
|
|
void Lua_V1::GetActorPos() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
Math::Vector3d pos = actor->getPos();
|
|
lua_pushnumber(pos.x());
|
|
lua_pushnumber(pos.y());
|
|
lua_pushnumber(pos.z());
|
|
}
|
|
|
|
void Lua_V1::SetActorRot() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
lua_Object p = lua_getparam(2);
|
|
lua_Object y = lua_getparam(3);
|
|
lua_Object r = lua_getparam(4);
|
|
if (!lua_isnumber(p) || !lua_isnumber(y) || !lua_isnumber(r))
|
|
return;
|
|
float pitch = lua_getnumber(p);
|
|
float yaw = lua_getnumber(y);
|
|
float roll = lua_getnumber(r);
|
|
if (getbool(5)) {
|
|
actor->turnTo(pitch, yaw, roll, true);
|
|
} else {
|
|
actor->setRot(pitch, yaw, roll);
|
|
}
|
|
}
|
|
|
|
void Lua_V1::GetActorRot() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
lua_pushnumber(actor->getPitch().getDegrees());
|
|
lua_pushnumber(actor->getYaw().getDegrees());
|
|
lua_pushnumber(actor->getRoll().getDegrees());
|
|
}
|
|
|
|
void Lua_V1::IsActorTurning() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
pushbool(actor->isTurning());
|
|
}
|
|
|
|
void Lua_V1::GetAngleBetweenActors() {
|
|
lua_Object actor1Obj = lua_getparam(1);
|
|
lua_Object actor2Obj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actor1Obj) || lua_tag(actor1Obj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
if (!lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor1 = getactor(actor1Obj);
|
|
Actor *actor2 = getactor(actor2Obj);
|
|
|
|
if (!actor1 || !actor2) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
lua_pushnumber(actor1->getYawTo(actor2).getDegrees());
|
|
}
|
|
|
|
void Lua_V1::GetActorYawToPoint() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object pointObj = lua_getparam(2);
|
|
lua_Object xObj, yObj, zObj;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (lua_istable(pointObj)) {
|
|
lua_pushobject(pointObj);
|
|
lua_pushstring("x");
|
|
xObj = lua_gettable();
|
|
lua_pushobject(pointObj);
|
|
lua_pushstring("y");
|
|
yObj = lua_gettable();
|
|
lua_pushobject(pointObj);
|
|
lua_pushstring("z");
|
|
zObj = lua_gettable();
|
|
} else {
|
|
xObj = pointObj;
|
|
yObj = lua_getparam(3);
|
|
zObj = lua_getparam(4);
|
|
}
|
|
float x = lua_getnumber(xObj);
|
|
float y = lua_getnumber(yObj);
|
|
float z = lua_getnumber(zObj);
|
|
|
|
Math::Vector3d yawVector(x, y, z);
|
|
|
|
lua_pushnumber(actor->getYawTo(yawVector).getDegrees());
|
|
}
|
|
|
|
/* Changes the set that an actor is associated with,
|
|
* by changing the set to "nil" an actor is disabled
|
|
* but should still not be destroyed.
|
|
*/
|
|
void Lua_V1::PutActorInSet() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object setObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
if (!lua_isstring(setObj) && !lua_isnil(setObj))
|
|
return;
|
|
|
|
const char *set = lua_getstring(setObj);
|
|
|
|
// FIXME verify adding actor to set
|
|
if (!set)
|
|
set = "";
|
|
if (!actor->isInSet(set))
|
|
actor->putInSet(set);
|
|
}
|
|
|
|
void Lua_V1::SetActorWalkRate() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object rateObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
if (!lua_isnumber(rateObj))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float rate = lua_getnumber(rateObj);
|
|
actor->setWalkRate(rate);
|
|
}
|
|
|
|
void Lua_V1::GetActorWalkRate() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
lua_pushnumber(actor->getWalkRate());
|
|
}
|
|
|
|
void Lua_V1::SetActorTurnRate() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object rateObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
if (!lua_isnumber(rateObj))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float rate = lua_getnumber(rateObj); // FIXME verify negate values of rate
|
|
actor->setTurnRate(rate);
|
|
}
|
|
|
|
void Lua_V1::WalkActorForward() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
Actor *actor = getactor(actorObj);
|
|
actor->walkForward();
|
|
}
|
|
|
|
void Lua_V1::SetActorReflection() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object angleObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float angle = lua_getnumber(angleObj);
|
|
actor->setReflection(angle);
|
|
}
|
|
|
|
void Lua_V1::GetActorPuckVector() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object addObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (!actor) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Math::Vector3d result = actor->getPuckVector();
|
|
if (!lua_isnil(addObj))
|
|
result += actor->getPos();
|
|
|
|
lua_pushnumber(result.x());
|
|
lua_pushnumber(result.y());
|
|
lua_pushnumber(result.z());
|
|
}
|
|
|
|
void Lua_V1::ActorPuckOrient() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
actor->setPuckOrient(getbool(2));
|
|
}
|
|
|
|
void Lua_V1::WalkActorTo() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object xObj = lua_getparam(2);
|
|
lua_Object yObj = lua_getparam(3);
|
|
lua_Object zObj = lua_getparam(4);
|
|
|
|
lua_Object txObj = lua_getparam(5);
|
|
lua_Object tyObj = lua_getparam(6);
|
|
lua_Object tzObj = lua_getparam(7);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Math::Vector3d destVec;
|
|
Actor *actor = getactor(actorObj);
|
|
if (!lua_isnumber(xObj)) {
|
|
if (!lua_isuserdata(xObj) || lua_tag(xObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
Actor *destActor = getactor(xObj);
|
|
destVec = destActor->getPos();
|
|
} else {
|
|
float x = lua_getnumber(xObj);
|
|
float y = lua_getnumber(yObj);
|
|
float z = lua_getnumber(zObj);
|
|
destVec.set(x, y, z);
|
|
}
|
|
|
|
// TODO figure out purpose this
|
|
float tx = lua_getnumber(txObj);
|
|
float ty = lua_getnumber(tyObj);
|
|
float tz = lua_getnumber(tzObj);
|
|
Math::Vector3d tVec(tx, ty, tz);
|
|
|
|
actor->walkTo(destVec);
|
|
}
|
|
|
|
/* This draw an actor to an offscreen buffer.
|
|
* The actors' buffers blit to the global buffer which then gets blitted to screen.
|
|
* This double layer system is necessary for set at, where Glottis and the Albinizod
|
|
* are drawn to the clean buffer but at different times.
|
|
*
|
|
* If you change the clean system check with the sets dd, at and with the trail of flowers
|
|
* in sh or zw.
|
|
*/
|
|
void Lua_V1::ActorToClean() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
actor->drawToCleanBuffer();
|
|
}
|
|
|
|
void Lua_V1::IsActorMoving() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
pushbool(actor->isWalking());
|
|
}
|
|
|
|
void Lua_V1::IsActorResting() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
// FIXME verify if exist one flag for resting mode
|
|
pushbool(!(actor->isWalking() || actor->isTurning()));
|
|
}
|
|
|
|
/* Get the location of one of the actor's nodes, this is
|
|
* used by Glottis to watch where Manny is located in
|
|
* order to hand him the work order. This function is
|
|
* also important for when Velasco hands Manny the logbook
|
|
* in Rubacava. It is also used for calculating many positions
|
|
* passed to ActorLookAt.
|
|
*/
|
|
void Lua_V1::GetActorNodeLocation() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object nodeObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
if (!lua_isnumber(nodeObj))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (!actor->getCurrentCostume() || !actor->getCurrentCostume()->getModelNodes())
|
|
return;
|
|
|
|
int nodeId = (int)lua_getnumber(nodeObj);
|
|
|
|
ModelNode *allNodes = actor->getCurrentCostume()->getModelNodes();
|
|
ModelNode *node = allNodes + nodeId;
|
|
|
|
node->_needsUpdate = true;
|
|
ModelNode *root = node;
|
|
while (root->_parent) {
|
|
root = root->_parent;
|
|
root->_needsUpdate = true;
|
|
}
|
|
|
|
Math::Matrix4 matrix;
|
|
matrix.setPosition(actor->getPos());
|
|
matrix.buildFromEuler(actor->getYaw(), actor->getPitch(), actor->getRoll(), Math::EO_ZXY);
|
|
root->setMatrix(matrix);
|
|
root->update();
|
|
|
|
Math::Vector3d pos(node->_pivotMatrix.getPosition());
|
|
lua_pushnumber(pos.x());
|
|
lua_pushnumber(pos.y());
|
|
lua_pushnumber(pos.z());
|
|
}
|
|
|
|
void Lua_V1::SetActorWalkDominate() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object modeObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
bool mode = lua_isnil(modeObj) != 0;
|
|
Actor *actor = getactor(actorObj);
|
|
actor->setRunning(mode);
|
|
}
|
|
|
|
void Lua_V1::SetActorColormap() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object nameObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (lua_isstring(nameObj)) {
|
|
const char *name = lua_getstring(nameObj);
|
|
actor->setColormap(name);
|
|
} else if (lua_isnil(nameObj)) {
|
|
error("SetActorColormap: implement remove cmap");
|
|
// remove ?
|
|
}
|
|
}
|
|
|
|
void Lua_V1::TurnActor() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object dirObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
if (!lua_isnumber(dirObj))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
int dir = (int)lua_getnumber(dirObj);
|
|
// TODO verify. need clear mode walking
|
|
actor->turn(dir);
|
|
}
|
|
|
|
void Lua_V1::PushActorCostume() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object nameObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
if (!lua_isstring(nameObj))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
const char *costumeName = lua_getstring(nameObj);
|
|
actor->pushCostume(costumeName);
|
|
}
|
|
|
|
void Lua_V1::SetActorCostume() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object costumeObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (lua_isnil(costumeObj)) {
|
|
actor->clearCostumes();
|
|
pushbool(true);
|
|
return;
|
|
}
|
|
if (!lua_isstring(costumeObj)) {
|
|
pushbool(false);
|
|
return;
|
|
}
|
|
|
|
const char *costumeName = lua_getstring(costumeObj);
|
|
actor->setCostume(costumeName);
|
|
pushbool(true);
|
|
}
|
|
|
|
void Lua_V1::GetActorCostume() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object costumeObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
Costume *costume = actor->getCurrentCostume();
|
|
if (lua_isnil(costumeObj)) {
|
|
// dummy
|
|
} else if (lua_isnumber(costumeObj)) {
|
|
/* int num = (int)lua_getnumber(costumeObj);*/
|
|
error("GetActorCostume: implement number Id");
|
|
} else
|
|
return;
|
|
|
|
if (costume)
|
|
lua_pushstring(costume->getFilename().c_str());
|
|
else
|
|
lua_pushnil();
|
|
}
|
|
|
|
void Lua_V1::PopActorCostume() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (actor->getCurrentCostume()) {
|
|
lua_pushstring(actor->getCurrentCostume()->getFilename().c_str());
|
|
actor->popCostume();
|
|
} else
|
|
lua_pushnil();
|
|
}
|
|
|
|
void Lua_V1::GetActorCostumeDepth() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
lua_pushnumber(actor->getCostumeStackDepth());
|
|
}
|
|
|
|
void Lua_V1::PrintActorCostumes() {
|
|
// dummy
|
|
}
|
|
|
|
void Lua_V1::LoadCostume() {
|
|
lua_Object nameObj = lua_getparam(1);
|
|
if (lua_isstring(nameObj)) {
|
|
// FIXME disable loading costume due creating issue with colormap, this opcode is unknown purpose
|
|
//const char *name = lua_getstring(nameObj);
|
|
//g_resourceloader->loadCostume(name, NULL);
|
|
} else
|
|
lua_pushnil();
|
|
}
|
|
|
|
void Lua_V1::PlayActorChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(3);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!lua_isnumber(choreObj)) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
costume->playChore(chore);
|
|
pushbool(true);
|
|
}
|
|
|
|
void Lua_V1::CompleteActorChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(3);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!lua_isnumber(choreObj)) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
costume->setChoreLastFrame(chore);
|
|
pushbool(true);
|
|
}
|
|
|
|
void Lua_V1::PlayActorChoreLooping() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(3);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!lua_isnumber(choreObj)) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
costume->playChoreLooping(chore);
|
|
pushbool(true);
|
|
}
|
|
|
|
void Lua_V1::SetActorChoreLooping() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(4);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume)
|
|
return;
|
|
|
|
if (lua_isnumber(choreObj)) {
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
costume->setChoreLooping(chore, getbool(3));
|
|
} else if (lua_isnil(choreObj)) {
|
|
error("SetActorChoreLooping: implement nil case");
|
|
}
|
|
}
|
|
|
|
void Lua_V1::StopActorChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(3);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume)
|
|
return;
|
|
|
|
if (lua_isnumber(choreObj)) {
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
costume->stopChore(chore);
|
|
} else if (lua_isnil(choreObj)) {
|
|
costume->stopChores();
|
|
}
|
|
}
|
|
|
|
void Lua_V1::FadeOutChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object costumeObj = lua_getparam(2);
|
|
lua_Object choreObj = lua_getparam(3);
|
|
lua_Object timeObj = lua_getparam(4);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume)
|
|
return;
|
|
|
|
if (lua_isnumber(choreObj)) {
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
int time = (int)lua_getnumber(timeObj);
|
|
|
|
costume->fadeChoreOut(chore, time);
|
|
}
|
|
}
|
|
|
|
void Lua_V1::FadeInChore() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object costumeObj = lua_getparam(2);
|
|
lua_Object choreObj = lua_getparam(3);
|
|
lua_Object timeObj = lua_getparam(4);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume)
|
|
return;
|
|
|
|
if (lua_isnumber(choreObj)) {
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
int time = (int)lua_getnumber(timeObj);
|
|
|
|
costume->fadeChoreIn(chore, time);
|
|
}
|
|
}
|
|
|
|
void Lua_V1::IsActorChoring() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object choreObj = lua_getparam(2);
|
|
lua_Object costumeObj = lua_getparam(4);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
Costume *costume;
|
|
if (!findCostume(costumeObj, actor, &costume))
|
|
return;
|
|
|
|
if (!costume) {
|
|
costume = actor->getCurrentCostume();
|
|
}
|
|
if (!costume) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
|
|
bool excludeLoop = getbool(3);
|
|
if (lua_isnumber(choreObj)) {
|
|
int chore = (int)lua_getnumber(choreObj);
|
|
if (costume->isChoring(chore, excludeLoop) != -1) {
|
|
lua_pushobject(choreObj);
|
|
pushbool(true);
|
|
} else
|
|
lua_pushnil();
|
|
return;
|
|
} else if (lua_isnil(choreObj)) {
|
|
for (int i = 0; i < costume->getNumChores(); i++) {
|
|
int chore = costume->isChoring(i, excludeLoop);
|
|
if (chore != -1) {
|
|
// Ignore talk chores.
|
|
bool isTalk = false;
|
|
for (int j = 0; j < 10; j++) {
|
|
if (costume == actor->getTalkCostume(j) && actor->getTalkChore(j) == chore) {
|
|
isTalk = true;
|
|
break;
|
|
}
|
|
}
|
|
if (isTalk)
|
|
continue;
|
|
|
|
lua_pushnumber(chore);
|
|
pushbool(true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
lua_pushnil();
|
|
}
|
|
|
|
void Lua_V1::ActorLookAt() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object xObj = lua_getparam(2);
|
|
lua_Object yObj = lua_getparam(3);
|
|
lua_Object zObj = lua_getparam(4);
|
|
lua_Object rateObj = lua_getparam(5);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
Actor *actor = getactor(actorObj);
|
|
if (!actor->getCurrentCostume())
|
|
return;
|
|
|
|
if (lua_isnumber(rateObj))
|
|
actor->setLookAtRate(lua_getnumber(rateObj));
|
|
|
|
// Look at nothing
|
|
if (lua_isnil(xObj)) {
|
|
if (actor->isLookAtVectorZero())
|
|
return;
|
|
|
|
actor->setLookAtVectorZero();
|
|
actor->setLooking(false);
|
|
// FIXME: When grabbing Chepito lua_getnumber(yObj) returns -3.50214
|
|
// which doesn't make any sense. I suspect that is a bug in Lua, since
|
|
// i couldn't find any call to manny:head_look_at(nil, -3.50214) while
|
|
// there are some calls to glottis:setpos(-0.120987, -3.50214, 0).
|
|
// The same number, strange indeed eh?
|
|
if (lua_isnumber(yObj) && lua_getnumber(yObj) > 0)
|
|
actor->setLookAtRate(lua_getnumber(yObj));
|
|
return;
|
|
} else if (lua_isnumber(xObj)) { // look at xyz
|
|
float fY;
|
|
float fZ;
|
|
|
|
float fX = lua_getnumber(xObj);
|
|
|
|
if (lua_isnumber(yObj))
|
|
fY = lua_getnumber(yObj);
|
|
else
|
|
fY = 0.0f;
|
|
|
|
if (lua_isnumber(zObj))
|
|
fZ = lua_getnumber(zObj);
|
|
else
|
|
fZ = 0.0f;
|
|
|
|
Math::Vector3d vector;
|
|
vector.set(fX, fY, fZ);
|
|
actor->setLookAtVector(vector);
|
|
|
|
if (lua_isnumber(rateObj))
|
|
actor->setLookAtRate(lua_getnumber(rateObj));
|
|
} else if (lua_isuserdata(xObj) && lua_tag(xObj) == MKTAG('A','C','T','R')) { // look at another actor
|
|
Actor *lookedAct = getactor(xObj);
|
|
actor->setLookAtVector(lookedAct->getHeadPos());
|
|
|
|
if (lua_isnumber(yObj))
|
|
actor->setLookAtRate(lua_getnumber(yObj));
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
actor->setLooking(true);
|
|
}
|
|
|
|
/* Turn the actor to a point specified in the 3D space,
|
|
* this should not have the actor look toward the point
|
|
* but should rotate the entire actor toward it.
|
|
* It does not however make the actor slowly turn the next
|
|
* times update() is called on it. It does make it turn
|
|
* slightly, by the amount given by its turn rate, and its
|
|
* effect is immediate.
|
|
*/
|
|
void Lua_V1::TurnActorTo() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object xObj = lua_getparam(2);
|
|
lua_Object yObj = lua_getparam(3);
|
|
lua_Object zObj = lua_getparam(4);
|
|
float x, y, z;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
if (lua_isuserdata(xObj) && lua_tag(xObj) == MKTAG('A','C','T','R')) {
|
|
Actor *destActor = getactor(xObj);
|
|
const Math::Vector3d &pos = destActor->getWorldPos();
|
|
x = pos.x();
|
|
y = pos.y();
|
|
z = pos.z();
|
|
} else {
|
|
x = lua_getnumber(xObj);
|
|
y = lua_getnumber(yObj);
|
|
z = lua_getnumber(zObj);
|
|
}
|
|
|
|
Math::Vector3d turnToVector(x, y, z);
|
|
// Return true if the actor is still turning
|
|
// This allows manny to have the right yaw when he exits the elevator in the garage
|
|
pushbool(!actor->singleTurnTo(turnToVector));
|
|
}
|
|
|
|
void Lua_V1::PointActorAt() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object xObj = lua_getparam(2);
|
|
lua_Object yObj = lua_getparam(3);
|
|
lua_Object zObj = lua_getparam(4);
|
|
float x, y, z;
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
|
|
if (lua_isuserdata(xObj) && lua_tag(xObj) == MKTAG('A','C','T','R')) {
|
|
Actor *destActor = getactor(xObj);
|
|
const Math::Vector3d &pos = destActor->getPos();
|
|
x = pos.x();
|
|
y = pos.y();
|
|
z = pos.z();
|
|
} else {
|
|
x = lua_getnumber(xObj);
|
|
y = lua_getnumber(yObj);
|
|
z = lua_getnumber(zObj);
|
|
}
|
|
|
|
// Find the vector pointing from the actor to the desired location
|
|
Math::Vector3d turnToVector(x, y, z);
|
|
actor->setRot(turnToVector);
|
|
}
|
|
|
|
void Lua_V1::WalkActorVector() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object actor2Obj = lua_getparam(2);
|
|
// lua_Object xObj = lua_getparam(3);
|
|
// lua_Object yObj = lua_getparam(4);
|
|
// lua_Object zObj = lua_getparam(5);
|
|
// lua_Object param6Obj = lua_getparam(6);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
|
|
!lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
// Actor *actor = static_cast<Actor *>(lua_getuserdata(actorObj));
|
|
Actor *actor2 = getactor(actor2Obj);
|
|
|
|
// TODO whole below part need rewrote to much original
|
|
float moveHoriz, moveVert;
|
|
|
|
// Third option is the "left/right" movement
|
|
moveHoriz = luaL_check_number(3);
|
|
// Fourth Option is the "up/down" movement
|
|
moveVert = luaL_check_number(4);
|
|
|
|
// Get the direction the camera is pointing
|
|
Math::Vector3d cameraVector = g_grim->getCurrSet()->getCurrSetup()->_interest - g_grim->getCurrSet()->getCurrSetup()->_pos;
|
|
// find the angle the camera direction is around the unit circle
|
|
Math::Angle cameraYaw = cameraVector.unitCircleAngle();
|
|
|
|
// Handle the turning
|
|
Math::Vector3d adjustVector(moveHoriz, moveVert, 0);
|
|
// find the angle the adjust vector is around the unit circle
|
|
Math::Angle adjustYaw = adjustVector.unitCircleAngle();
|
|
|
|
Math::Angle yaw = cameraYaw + adjustYaw;
|
|
// yaw is offset from forward by 180 degrees
|
|
yaw -= 180.0f;
|
|
|
|
// set the new direction or walk forward
|
|
if (actor2->getYaw() != yaw)
|
|
actor2->turnTo(0, yaw, 0);
|
|
else
|
|
actor2->walkForward();
|
|
}
|
|
|
|
/* Set the pitch of the actor to the requested value,
|
|
* this will rotate an actor toward/away from the ground.
|
|
* This is used when Glottis runs over the signpost in
|
|
* the Petrified Forest
|
|
*/
|
|
void Lua_V1::SetActorPitch() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object pitchObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
float pitch = lua_getnumber(pitchObj);
|
|
actor->setRot(pitch, actor->getYaw(), actor->getRoll());
|
|
}
|
|
|
|
void Lua_V1::SetActorLookRate() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object rateObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
if (!lua_isnumber(rateObj))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (!actor->getCurrentCostume())
|
|
return;
|
|
|
|
float rate = lua_getnumber(rateObj);
|
|
actor->setLookAtRate(rate);
|
|
}
|
|
|
|
void Lua_V1::GetActorLookRate() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
if (!actor->getCurrentCostume())
|
|
lua_pushnil();
|
|
else
|
|
lua_pushnumber(actor->getLookAtRate());
|
|
}
|
|
|
|
void Lua_V1::SetActorHead() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object joint1Obj = lua_getparam(2);
|
|
lua_Object joint2Obj = lua_getparam(3);
|
|
lua_Object joint3Obj = lua_getparam(4);
|
|
lua_Object maxRollObj = lua_getparam(5);
|
|
lua_Object maxPitchObj = lua_getparam(6);
|
|
lua_Object maxYawObj = lua_getparam(7);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
if (!lua_isnumber(joint1Obj) || !lua_isnumber(joint2Obj) || !lua_isnumber(joint3Obj) ||
|
|
!lua_isnumber(maxRollObj) || !lua_isnumber(maxPitchObj) || !lua_isnumber(maxYawObj))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
int joint1 = (int)lua_getnumber(joint1Obj);
|
|
int joint2 = (int)lua_getnumber(joint2Obj);
|
|
int joint3 = (int)lua_getnumber(joint3Obj);
|
|
float maxRoll = lua_getnumber(maxRollObj);
|
|
float maxPitch = lua_getnumber(maxPitchObj);
|
|
float maxYaw = lua_getnumber(maxYawObj);
|
|
|
|
actor->setHead(joint1, joint2, joint3, maxRoll, maxPitch, maxYaw);
|
|
}
|
|
|
|
void Lua_V1::PutActorAtInterest() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
Set *scene = g_grim->getCurrSet();
|
|
if (!scene)
|
|
return;
|
|
|
|
Math::Vector3d p = scene->getCurrSetup()->_interest;
|
|
Math::Vector3d resultPt = p;
|
|
float minDist = -1.f;
|
|
|
|
for (int i = 0; i < scene->getSectorCount(); ++i) {
|
|
Sector *sector = scene->getSectorBase(i);
|
|
if (sector->getType() != Sector::WalkType || !sector->isVisible())
|
|
continue;
|
|
|
|
Math::Vector3d closestPt = sector->getClosestPoint(p);
|
|
if (scene->findPointSector(closestPt, Sector::HotType))
|
|
continue;
|
|
float thisDist = (closestPt - p).getMagnitude();
|
|
if (minDist < 0 || thisDist < minDist) {
|
|
resultPt = closestPt;
|
|
minDist = thisDist;
|
|
}
|
|
}
|
|
|
|
actor->setPos(resultPt);
|
|
}
|
|
|
|
void Lua_V1::SetActorFollowBoxes() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
Actor *actor = getactor(actorObj);
|
|
actor->setFollowBoxes(getbool(2));
|
|
}
|
|
|
|
void Lua_V1::SetActorConstrain() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
// lua_Object constrainObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
|
return;
|
|
|
|
// Actor *actor = static_cast<Actor *>(lua_getuserdata(actorObj));
|
|
// bool constrain = !lua_isnil(constrainObj);
|
|
|
|
// FIXME that below should be enabled, but for now it's disabled realated to
|
|
// above func SetActorFollowBoxes.
|
|
// actor->setConstrain(constrain);
|
|
}
|
|
|
|
void Lua_V1::GetVisibleThings() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
Actor *actor = nullptr;
|
|
if (lua_isnil(actorObj)) {
|
|
actor = g_grim->getSelectedActor();
|
|
if (!actor)
|
|
return;
|
|
} else if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKTAG('A','C','T','R')) {
|
|
actor = getactor(actorObj);
|
|
}
|
|
assert(actor);
|
|
|
|
lua_Object result = lua_createtable();
|
|
|
|
// TODO verify code below
|
|
if (actor->isInSet(g_grim->getCurrSet()->getName())) {
|
|
foreach (Actor *a, g_grim->getActiveActors()) {
|
|
// Consider the active actor visible
|
|
if (actor == a || actor->getYawTo(a) < 90) {
|
|
lua_pushobject(result);
|
|
lua_pushusertag(a->getId(), MKTAG('A','C','T','R'));
|
|
lua_pushnumber(1);
|
|
lua_settable();
|
|
}
|
|
}
|
|
}
|
|
lua_pushobject(result);
|
|
}
|
|
|
|
void Lua_V1::SetShadowColor() {
|
|
int r = (int)lua_getnumber(lua_getparam(1));
|
|
int g = (int)lua_getnumber(lua_getparam(2));
|
|
int b = (int)lua_getnumber(lua_getparam(3));
|
|
|
|
g_driver->setShadowColor(r, g, b);
|
|
}
|
|
|
|
void Lua_V1::KillActorShadows() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
|
|
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
actor->clearShadowPlanes();
|
|
}
|
|
|
|
void Lua_V1::SetActiveShadow() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object shadowIdObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || actorObj == LUA_NOOBJECT) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
int shadowId = (int)lua_getnumber(shadowIdObj);
|
|
actor->setActiveShadow(shadowId);
|
|
}
|
|
|
|
void Lua_V1::SetActorShadowPoint() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object xObj = lua_getparam(2);
|
|
lua_Object yObj = lua_getparam(3);
|
|
lua_Object zObj = lua_getparam(4);
|
|
|
|
if (!lua_isuserdata(actorObj) || actorObj == LUA_NOOBJECT) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
float x = lua_getnumber(xObj);
|
|
float y = lua_getnumber(yObj);
|
|
float z = lua_getnumber(zObj);
|
|
|
|
actor->setShadowPoint(Math::Vector3d(x, y, z));
|
|
}
|
|
|
|
void Lua_V1::SetActorShadowPlane() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object nameObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || actorObj == LUA_NOOBJECT) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
const char *name = lua_getstring(nameObj);
|
|
|
|
actor->setShadowPlane(name);
|
|
}
|
|
|
|
void Lua_V1::AddShadowPlane() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object nameObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || actorObj == LUA_NOOBJECT) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
const char *name = lua_getstring(nameObj);
|
|
|
|
actor->addShadowPlane(name);
|
|
}
|
|
|
|
void Lua_V1::ActivateActorShadow() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object shadowIdObj = lua_getparam(2);
|
|
lua_Object stateObj = lua_getparam(3);
|
|
|
|
if (!lua_isuserdata(actorObj) || actorObj == LUA_NOOBJECT) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
int shadowId = (int)lua_getnumber(shadowIdObj);
|
|
bool state = !lua_isnil(stateObj);
|
|
|
|
actor->setActivateShadow(shadowId, state);
|
|
g_grim->flagRefreshShadowMask(true);
|
|
}
|
|
|
|
void Lua_V1::SetActorShadowValid() {
|
|
lua_Object actorObj = lua_getparam(1);
|
|
lua_Object numObj = lua_getparam(2);
|
|
|
|
if (!lua_isuserdata(actorObj) || actorObj == LUA_NOOBJECT) {
|
|
lua_pushnil();
|
|
return;
|
|
}
|
|
Actor *actor = getactor(actorObj);
|
|
int valid = (int)lua_getnumber(numObj);
|
|
|
|
warning("SetActorShadowValid(%d) unknown purpose", valid);
|
|
|
|
actor->setShadowValid(valid);
|
|
}
|
|
|
|
void Lua_V1::GetActorRect() {
|
|
// This function is only used in one place and it is only checked if the return value is nil or not.
|
|
// Looking at how it is used I don't see any reason to ever return nil.
|
|
// If it does not return nil, the light that comes out of Chepito's lantern move properly.
|
|
lua_pushnumber(1);
|
|
}
|
|
|
|
} // end of namespace Grim
|