ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

lua_v2_actor.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/debug-channels.h"
00024 
00025 #include "engines/grim/emi/lua_v2.h"
00026 #include "engines/grim/lua/lua.h"
00027 
00028 #include "engines/grim/actor.h"
00029 #include "engines/grim/debug.h"
00030 #include "engines/grim/grim.h"
00031 #include "engines/grim/costume.h"
00032 #include "engines/grim/set.h"
00033 
00034 #include "engines/grim/emi/emi.h"
00035 #include "engines/grim/emi/costumeemi.h"
00036 #include "engines/grim/emi/skeleton.h"
00037 #include "engines/grim/emi/costume/emichore.h"
00038 #include "engines/grim/emi/costume/emiskel_component.h"
00039 
00040 #include "engines/grim/lua/lauxlib.h"
00041 
00042 namespace Grim {
00043 
00044 void Lua_V2::SetActorLocalAlpha() {
00045     lua_Object actorObj = lua_getparam(1);
00046     lua_Object vertexObj= lua_getparam(2);
00047     lua_Object alphaObj = lua_getparam(3);
00048     // lua_Object unknownObj = lua_getparam(4);
00049 
00050     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00051         return;
00052 
00053     Actor *actor = getactor(actorObj);
00054     if (!actor)
00055         return;
00056 
00057     if (!lua_isnumber(vertexObj))
00058         return;
00059 
00060     if (!lua_isnumber(alphaObj))
00061         return;
00062 
00063     int vertex = lua_getnumber(vertexObj);
00064     float alpha = lua_getnumber(alphaObj);
00065 
00066     Actor::AlphaMode mode = (Actor::AlphaMode)(int)alpha;
00067 
00068     if (mode == Actor::AlphaOff || mode == Actor::AlphaReplace || mode == Actor::AlphaModulate) {
00069         actor->setLocalAlphaMode(vertex, mode);
00070     } else {
00071         actor->setLocalAlpha(vertex, alpha);
00072     }
00073 }
00074 
00075 
00076 void Lua_V2::SetActorGlobalAlpha() {
00077     lua_Object actorObj = lua_getparam(1);
00078     lua_Object alphaObj = lua_getparam(2);
00079     lua_Object meshObj = lua_getparam(3);
00080 
00081     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00082         return;
00083 
00084     Actor *actor = getactor(actorObj);
00085     if (!actor)
00086         return;
00087 
00088     if (!lua_isnumber(alphaObj))
00089         return;
00090 
00091     const char *mesh = nullptr;
00092     if (lua_isstring(meshObj)) {
00093         mesh = lua_getstring(meshObj);
00094     }
00095     float alpha = lua_getnumber(alphaObj);
00096     if (alpha == Actor::AlphaOff ||
00097         alpha == Actor::AlphaReplace ||
00098         alpha == Actor::AlphaModulate) {
00099             actor->setAlphaMode((Actor::AlphaMode) (int) alpha, mesh);
00100     } else {
00101         actor->setGlobalAlpha(alpha, mesh);
00102     }
00103 }
00104 
00105 void Lua_V2::PutActorInOverworld() {
00106     lua_Object actorObj = lua_getparam(1);
00107 
00108     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00109         return;
00110 
00111     Actor *actor = getactor(actorObj);
00112 
00113     actor->setInOverworld(true);
00114 }
00115 
00116 void Lua_V2::RemoveActorFromOverworld() {
00117     lua_Object actorObj = lua_getparam(1);
00118 
00119     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00120         return;
00121 
00122     Actor *actor = getactor(actorObj);
00123     if (!actor)
00124         return;
00125 
00126     actor->setInOverworld(false);
00127 }
00128 
00129 void Lua_V2::UnloadActor() {
00130     lua_Object actorObj = lua_getparam(1);
00131 
00132     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00133         return;
00134 
00135     Actor *actor = getactor(actorObj);
00136     if (!actor)
00137         return;
00138 
00139     g_grim->invalidateActiveActorsList();
00140     g_grim->immediatelyRemoveActor(actor);
00141     delete actor;
00142 }
00143 
00144 void Lua_V2::SetActorWalkRate() {
00145     lua_Object actorObj = lua_getparam(1);
00146     lua_Object rateObj = lua_getparam(2);
00147 
00148     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00149         return;
00150     if (!lua_isnumber(rateObj))
00151         return;
00152 
00153     Actor *actor = getactor(actorObj);
00154     float rate = lua_getnumber(rateObj);
00155     // const below only differ from grim
00156     actor->setWalkRate(rate * 3.279999971389771);
00157 }
00158 
00159 void Lua_V2::GetActorWalkRate() {
00160     lua_Object actorObj = lua_getparam(1);
00161     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00162         return;
00163 
00164     Actor *actor = getactor(actorObj);
00165     // const below only differ from grim
00166     lua_pushnumber(actor->getWalkRate() * 0.3048780560493469);
00167 }
00168 
00169 void Lua_V2::SetActorTurnRate() {
00170     lua_Object actorObj = lua_getparam(1);
00171     lua_Object rateObj = lua_getparam(2);
00172 
00173     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00174         return;
00175     if (!lua_isnumber(rateObj))
00176         return;
00177 
00178     Actor *actor = getactor(actorObj);
00179     float rate = lua_getnumber(rateObj); // FIXME verify negate values of rate
00180 
00181     // special handling of value 1 only used for voodoo chair
00182     actor->setTurnRate((rate == 1) ? 100 : rate);
00183 }
00184 
00185 void Lua_V2::LockChoreSet() {
00186     lua_Object choreObj = lua_getparam(1);
00187 
00188     const char *choreName = lua_getstring(choreObj);
00189     warning("Lua_V2::LockChoreSet: chore: %s", choreName);
00190 }
00191 
00192 void Lua_V2::UnlockChoreSet() {
00193     lua_Object choreObj = lua_getparam(1);
00194 
00195     const char *choreName = lua_getstring(choreObj);
00196     warning("Lua_V2::UnlockChoreSet: chore: %s", choreName);
00197 }
00198 
00199 void Lua_V2::LockChore() {
00200     lua_Object nameObj = lua_getparam(1);
00201     lua_Object filenameObj = lua_getparam(2);
00202 
00203     if (!lua_isstring(nameObj) || !lua_isstring(filenameObj)) {
00204         lua_pushnil();
00205         return;
00206     }
00207 
00208     const char *name = lua_getstring(nameObj);
00209     const char *filename = lua_getstring(filenameObj);
00210     warning("Lua_V2::LockChore, name: %s, filename: %s", name, filename);
00211     // FIXME: implement missing rest part of code
00212 }
00213 
00214 void Lua_V2::UnlockChore() {
00215     lua_Object nameObj = lua_getparam(1);
00216     lua_Object filenameObj = lua_getparam(2);
00217 
00218     if (!lua_isstring(nameObj) || !lua_isstring(filenameObj)) {
00219         lua_pushnil();
00220         return;
00221     }
00222 
00223     const char *name = lua_getstring(nameObj);
00224     const char *filename = lua_getstring(filenameObj);
00225     warning("Lua_V2::UnlockChore, name: %s, filename: %s", name, filename);
00226     // FIXME: implement missing rest part of code
00227 }
00228 
00229 void Lua_V2::IsActorChoring() {
00230     lua_Object actorObj = lua_getparam(1);
00231     bool excludeLoop = getbool(2);
00232 
00233     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00234         return;
00235 
00236     Actor *actor = getactor(actorObj);
00237     const Common::List<Costume *> &costumes = actor->getCostumes();
00238 
00239     for (Common::List<Costume *>::const_iterator it = costumes.begin(); it != costumes.end(); ++it) {
00240         Costume *costume = *it;
00241         for (int i = 0; i < costume->getNumChores(); i++) {
00242             int chore = costume->isChoring(i, excludeLoop);
00243             if (chore != -1) {
00244                 // Ignore talk chores.
00245                 bool isTalk = false;
00246                 for (int j = 0; j < 10; j++) {
00247                     if (costume == actor->getTalkCostume(j) && actor->getTalkChore(j) == chore) {
00248                         isTalk = true;
00249                         break;
00250                     }
00251                 }
00252                 if (isTalk)
00253                     continue;
00254 
00255                 lua_pushnumber(chore);
00256 
00257                 pushbool(true);
00258                 return;
00259             }
00260         }
00261     }
00262 
00263     lua_pushnil();
00264 }
00265 
00266 void Lua_V2::IsChoreValid() {
00267     lua_Object choreObj = lua_getparam(1);
00268 
00269     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R'))
00270         return;
00271 
00272     int chore = lua_getuserdata(choreObj);
00273     Chore *c = EMIChore::getPool().getObject(chore);
00274 
00275     if (c) {
00276         pushbool(c != nullptr);
00277     } else {
00278         lua_pushnil();
00279     }
00280 }
00281 
00282 void Lua_V2::IsChorePlaying() {
00283     lua_Object choreObj = lua_getparam(1);
00284 
00285     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R'))
00286         return;
00287 
00288     int chore = lua_getuserdata(choreObj);
00289     Chore *c = EMIChore::getPool().getObject(chore);
00290 
00291     if (c) {
00292         pushbool(c->isPlaying() && !c->isPaused());
00293     } else {
00294         lua_pushnil();
00295     }
00296 }
00297 
00298 void Lua_V2::IsChoreLooping() {
00299     lua_Object choreObj = lua_getparam(1);
00300 
00301     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R'))
00302         return;
00303 
00304     int chore = lua_getuserdata(choreObj);
00305     Chore *c = EMIChore::getPool().getObject(chore);
00306 
00307     if (c) {
00308         pushbool(c->isLooping());
00309     } else {
00310         lua_pushnil();
00311     }
00312 }
00313 
00314 void Lua_V2::SetChoreLooping() {
00315     lua_Object choreObj = lua_getparam(1);
00316     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R'))
00317         return;
00318 
00319     int chore = lua_getuserdata(choreObj);
00320     Chore *c = EMIChore::getPool().getObject(chore);
00321 
00322     if (c) {
00323         c->setLooping(false);
00324     }
00325     lua_pushnil();
00326 }
00327 
00328 void Lua_V2::PlayChore() {
00329     lua_Object choreObj = lua_getparam(1);
00330 
00331     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R'))
00332         return;
00333     int chore = lua_getuserdata(choreObj);
00334 
00335     Chore *c = EMIChore::getPool().getObject(chore);
00336     if (c) {
00337         c->setPaused(false);
00338     }
00339 }
00340 
00341 void Lua_V2::PauseChore() {
00342     lua_Object choreObj = lua_getparam(1);
00343 
00344     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R'))
00345         return;
00346     int chore = lua_getuserdata(choreObj);
00347 
00348     Chore *c = EMIChore::getPool().getObject(chore);
00349     if (c) {
00350         c->setPaused(true);
00351     }
00352 }
00353 
00354 void Lua_V2::StopChore() {
00355     lua_Object choreObj = lua_getparam(1);
00356     lua_Object fadeTimeObj = lua_getparam(2);
00357 
00358     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R'))
00359         return;
00360 
00361     int chore = lua_getuserdata(choreObj);
00362     float fadeTime = 0.0f;
00363 
00364     if (!lua_isnil(fadeTimeObj)) {
00365         if (lua_isnumber(fadeTimeObj))
00366             fadeTime = lua_getnumber(fadeTimeObj);
00367     }
00368 
00369     // There are a few cases in the scripts where StopChore is called with an excessively
00370     // large fadeTime value. The original engine ignores fade times greater or equal
00371     // to 0.6 seconds, so we replicate that behavior here.
00372     if (fadeTime >= 0.6f) {
00373         fadeTime = 0.0f;
00374     }
00375 
00376     Chore *c = EMIChore::getPool().getObject(chore);
00377     if (c) {
00378         c->stop((int)(fadeTime * 1000));
00379     }
00380 }
00381 
00382 void Lua_V2::AdvanceChore() {
00383     lua_Object choreObj = lua_getparam(1);
00384     lua_Object timeObj = lua_getparam(2);
00385 
00386     if (!lua_isuserdata(choreObj) || lua_tag(choreObj) != MKTAG('C','H','O','R') || !lua_isnumber(timeObj))
00387         return;
00388 
00389     int chore = lua_getuserdata(choreObj);
00390     float time = lua_getnumber(timeObj);
00391     Chore *c = EMIChore::getPool().getObject(chore);
00392     if (c) {
00393         if (!c->isPlaying()) {
00394             warning("AdvanceChore() called on stopped chore %s (%s)",
00395                     c->getName(), c->getOwner()->getFilename().c_str());
00396             if (c->isLooping()) {
00397                 c->getOwner()->playChoreLooping(c->getName());
00398             } else {
00399                 c->getOwner()->playChore(c->getName());
00400             }
00401         }
00402         c->advance(time * 1000);
00403     }
00404 }
00405 
00406 // TODO: Implement, verify, and rename parameters
00407 void Lua_V2::CompleteChore() {
00408     lua_Object param1 = lua_getparam(1);
00409     lua_Object param2 = lua_getparam(2);
00410 
00411     if (!lua_isuserdata(param1) || !lua_isnumber(param2))
00412         error("Lua_V2::CompleteChore - Unknown params");
00413 
00414     // Guesswork based on StopChore:
00415     int chore = lua_getuserdata(param1);
00416     float time = lua_getnumber(param2);
00417 
00418     error("Lua_V2::CompleteChore(%d, %f) - TODO: Implement opcode", chore, time);
00419 }
00420 
00421 void Lua_V2::SetActorSortOrder() {
00422     lua_Object actorObj = lua_getparam(1);
00423     lua_Object orderObj = lua_getparam(2);
00424 
00425     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00426         return;
00427 
00428     if (!lua_isnumber(orderObj))
00429         return;
00430 
00431     Actor *actor = getactor(actorObj);
00432     int order = (int)lua_getnumber(orderObj);
00433     actor->setSortOrder(order);
00434 
00435     g_emi->invalidateSortOrder();
00436 }
00437 
00438 void Lua_V2::GetActorSortOrder() {
00439     lua_Object actorObj = lua_getparam(1);
00440 
00441     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00442         return;
00443 
00444     Actor *actor = getactor(actorObj);
00445     lua_pushnumber(actor->getEffectiveSortOrder());
00446 }
00447 
00448 void Lua_V2::ActorActivateShadow() {
00449     lua_Object actorObj = lua_getparam(1);
00450     lua_Object activeObj = lua_getparam(2);
00451     lua_Object planeObj = lua_getparam(3);
00452 
00453     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00454         return;
00455 
00456     Actor *actor = getactor(actorObj);
00457     if (!actor)
00458         return;
00459     bool active = (int)lua_getnumber(activeObj) == 1;
00460     const char *plane = nullptr;
00461     if (lua_isstring(planeObj))
00462         plane = lua_getstring(planeObj);
00463     actor->activateShadow(active, plane);
00464 }
00465 
00466 void Lua_V2::ActorStopMoving() {
00467     lua_Object actorObj = lua_getparam(1);
00468 
00469     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00470         return;
00471 
00472     Actor *actor = getactor(actorObj);
00473 
00474     actor->stopWalking();
00475     actor->stopTurning();
00476 
00477     warning("Lua_V2::ActorStopMoving, actor: %s", actor->getName().c_str());
00478     // FIXME: Inspect the rest of the code to see if there's anything else missing
00479 }
00480 
00481 void Lua_V2::ActorLookAt() {
00482     lua_Object actorObj = lua_getparam(1);
00483     lua_Object xObj = lua_getparam(2);
00484     lua_Object yObj = lua_getparam(3);
00485     lua_Object zObj = lua_getparam(4);
00486     lua_Object rateObj = lua_getparam(5);
00487 
00488     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A', 'C', 'T', 'R'))
00489         return;
00490     Actor *actor = getactor(actorObj);
00491     if (!actor->getCurrentCostume())
00492         return;
00493 
00494     if (lua_isnumber(rateObj))
00495         actor->setLookAtRate(lua_getnumber(rateObj));
00496 
00497     // Look at nothing
00498     if (lua_isnil(xObj)) {
00499         if (actor->isLookAtVectorZero())
00500             return;
00501 
00502         actor->setLookAtVectorZero();
00503         actor->setLooking(false);
00504         if (lua_isnumber(yObj) && lua_getnumber(yObj) > 0)
00505             actor->setLookAtRate(lua_getnumber(yObj));
00506         return;
00507     } else if (lua_isnumber(xObj)) { // look at xyz
00508         float fY;
00509         float fZ;
00510 
00511         float fX = lua_getnumber(xObj);
00512 
00513         if (lua_isnumber(yObj))
00514             fY = lua_getnumber(yObj);
00515         else
00516             fY = 0.0f;
00517 
00518         if (lua_isnumber(zObj))
00519             fZ = lua_getnumber(zObj);
00520         else
00521             fZ = 0.0f;
00522 
00523         Math::Vector3d vector;
00524         vector.set(fX, fY, fZ);
00525         actor->setLookAtVector(vector);
00526 
00527         if (lua_isnumber(rateObj))
00528             actor->setLookAtRate(lua_getnumber(rateObj));
00529     } else if (lua_isuserdata(xObj) && lua_tag(xObj) == MKTAG('A', 'C', 'T', 'R')) { // look at another actor
00530         Actor *lookedAct = getactor(xObj);
00531         actor->setLookAtActor(lookedAct);
00532 
00533         if (lua_isnumber(yObj))
00534             actor->setLookAtRate(lua_getnumber(yObj));
00535     } else {
00536         return;
00537     }
00538 
00539     actor->setLooking(true);
00540 }
00541 
00542 void Lua_V2::GetActorWorldPos() {
00543     lua_Object actorObj = lua_getparam(1);
00544 
00545     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00546         return;
00547 
00548     Actor *actor = getactor(actorObj);
00549     if (!actor)
00550         return;
00551 
00552     Math::Vector3d pos = actor->getWorldPos();
00553     lua_pushnumber(pos.x());
00554     lua_pushnumber(pos.y());
00555     lua_pushnumber(pos.z());
00556 }
00557 
00558 void Lua_V2::PutActorInSet() {
00559     lua_Object actorObj = lua_getparam(1);
00560     lua_Object setObj = lua_getparam(2);
00561 
00562     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00563         return;
00564 
00565     Actor *actor = getactor(actorObj);
00566 
00567     if (!lua_isstring(setObj) && !lua_isnil(setObj)) {
00568         lua_pushnil();
00569         return;
00570     }
00571 
00572     const char *set = lua_getstring(setObj);
00573 
00574     // FIXME verify adding actor to set
00575     if (!set) {
00576         actor->putInSet("");
00577         lua_pushnil();
00578     } else {
00579         if (!actor->isInSet(set)) {
00580             actor->putInSet(set);
00581         }
00582         lua_pushnumber(1.0);
00583     }
00584 }
00585 
00586 void Lua_V2::SetActorRestChore() {
00587     lua_Object actorObj = lua_getparam(1);
00588     lua_Object choreObj = lua_getparam(2);
00589     lua_Object costumeObj = lua_getparam(3);
00590     Costume *costume = nullptr;
00591     int chore = -1;
00592 
00593     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
00594             (!lua_isstring(choreObj) && !lua_isnil(choreObj))) {
00595         return;
00596     }
00597 
00598     Actor *actor = getactor(actorObj);
00599 
00600     setChoreAndCostume(choreObj, costumeObj, actor, costume, chore);
00601 
00602     actor->setRestChore(chore, costume);
00603 }
00604 
00605 void Lua_V2::SetActorWalkChore() {
00606     lua_Object actorObj = lua_getparam(1);
00607     lua_Object choreObj = lua_getparam(2);
00608     lua_Object costumeObj = lua_getparam(3);
00609     Costume *costume = nullptr;
00610     int chore = -1;
00611 
00612     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
00613             (!lua_isstring(choreObj) && !lua_isnil(choreObj))) {
00614         return;
00615     }
00616 
00617     Actor *actor = getactor(actorObj);
00618 
00619     setChoreAndCostume(choreObj, costumeObj, actor, costume, chore);
00620 
00621     actor->setWalkChore(chore, costume);
00622 }
00623 
00624 void Lua_V2::SetActorTurnChores() {
00625     lua_Object actorObj = lua_getparam(1);
00626     lua_Object leftChoreObj = lua_getparam(2);
00627     lua_Object rightChoreObj = lua_getparam(3);
00628     lua_Object costumeObj = lua_getparam(4);
00629     Costume *costume;
00630 
00631     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
00632         return;
00633     } else if (!lua_isnil(leftChoreObj) && !lua_isstring(leftChoreObj)) {
00634         return;
00635     } else if (!lua_isnil(rightChoreObj) && !lua_isstring(rightChoreObj)) {
00636         return;
00637     }
00638 
00639     Actor *actor = getactor(actorObj);
00640 
00641     if (!findCostume(costumeObj, actor, &costume))
00642         return;
00643 
00644     int leftChore = costume->getChoreId(lua_getstring(leftChoreObj));
00645     int rightChore = costume->getChoreId(lua_getstring(rightChoreObj));
00646 
00647     actor->setTurnChores(leftChore, rightChore, costume);
00648 }
00649 
00650 
00651 
00652 void Lua_V2::SetActorTalkChore() {
00653     lua_Object actorObj = lua_getparam(1);
00654     lua_Object indexObj = lua_getparam(2);
00655     lua_Object choreObj = lua_getparam(3);
00656     lua_Object costumeObj = lua_getparam(4);
00657     Costume *costume = nullptr;
00658     int chore = -1;
00659 
00660     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
00661             !lua_isnumber(indexObj) ||
00662             (!lua_isstring(choreObj) && !lua_isnil(choreObj))) {
00663         return;
00664     }
00665 
00666     int index = (int)lua_getnumber(indexObj);
00667     if (index < 0 || index >= 16)
00668         return;
00669 
00670     Actor *actor = getactor(actorObj);
00671 
00672     setChoreAndCostume(choreObj, costumeObj, actor, costume, chore);
00673 
00674     actor->setTalkChore(index + 1, chore, costume);
00675 }
00676 
00677 void Lua_V2::SetActorMumblechore() {
00678     lua_Object actorObj = lua_getparam(1);
00679     lua_Object choreObj = lua_getparam(2);
00680     lua_Object costumeObj = lua_getparam(3);
00681     Costume *costume = nullptr;
00682     int chore = -1;
00683 
00684     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') ||
00685             (!lua_isstring(choreObj) && !lua_isnil(choreObj))) {
00686         return;
00687     }
00688 
00689     Actor *actor = getactor(actorObj);
00690 
00691     setChoreAndCostume(choreObj, costumeObj, actor, costume, chore);
00692 
00693     actor->setMumbleChore(chore, costume);
00694 }
00695 
00696 void Lua_V2::GetActorChores() {
00697     lua_Object actorObj = lua_getparam(1);
00698     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00699         return;
00700     Actor *actor = getactor(actorObj);
00701     const Common::List<Costume *> &costumes = actor->getCostumes();
00702 
00703     lua_Object result = lua_createtable();
00704     int count = 0;
00705     for (Common::List<Costume *>::const_iterator it = costumes.begin(); it != costumes.end(); ++it) {
00706         const Common::List<Chore *> &playingChores = (*it)->getPlayingChores();
00707         for (Common::List<Chore *>::const_iterator cit = playingChores.begin(); cit != playingChores.end(); ++cit) {
00708             lua_pushobject(result);
00709             lua_pushnumber(count++);
00710             lua_pushusertag(((EMIChore *)*cit)->getId(), MKTAG('C', 'H', 'O', 'R'));
00711             lua_settable();
00712         }
00713     }
00714     lua_pushobject(result);
00715     lua_pushstring("count");
00716     lua_pushnumber(count);
00717     lua_settable();
00718 
00719     lua_pushobject(result);
00720 }
00721 
00722 // Helper function, not called from LUA directly
00723 bool Lua_V2::findCostume(lua_Object costumeObj, Actor *actor, Costume **costume) {
00724     *costume = nullptr;
00725     if (lua_isnil(costumeObj)) {
00726         *costume = actor->getCurrentCostume();
00727     } else {
00728         if (lua_isstring(costumeObj)) {
00729             const char *costumeName = lua_getstring(costumeObj);
00730             *costume = actor->findCostume(costumeName);
00731             if (*costume == nullptr) {
00732                 actor->pushCostume(costumeName);
00733                 *costume = actor->findCostume(costumeName);
00734             }
00735         }
00736     }
00737     return (*costume != nullptr);
00738 }
00739 
00740 void Lua_V2::PlayActorChore() {
00741     lua_Object actorObj = lua_getparam(1);
00742     lua_Object choreObj = lua_getparam(2);
00743     lua_Object costumeObj = lua_getparam(3);
00744     lua_Object modeObj = lua_getparam(4);
00745     lua_Object fadeTimeObj = lua_getparam(5);
00746 
00747     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00748         return;
00749 
00750     Actor *actor = getactor(actorObj);
00751 
00752     if (!lua_isstring(choreObj) || !lua_isstring(costumeObj))
00753         lua_pushnil();
00754 
00755     bool mode = false;
00756     float fadeTime = 0.0f;
00757 
00758     if (!lua_isnil(modeObj)) {
00759         if (lua_getnumber(modeObj) != 0.0)
00760             mode = true;
00761     }
00762 
00763     if (!lua_isnil(fadeTimeObj)) {
00764         if (lua_isnumber(fadeTimeObj))
00765             fadeTime = lua_getnumber(fadeTimeObj);
00766     }
00767 
00768     const char *choreName = lua_getstring(choreObj);
00769 
00770     Costume *costume;
00771     if (!findCostume(costumeObj, actor, &costume))
00772         return;
00773 
00774     EMIChore *chore = (EMIChore *)costume->getChore(choreName);
00775     if (mode) {
00776         costume->playChoreLooping(choreName, (int)(fadeTime * 1000));
00777     } else {
00778         costume->playChore(choreName, (int)(fadeTime * 1000));
00779     }
00780     if (chore) {
00781         lua_pushusertag(chore->getId(), MKTAG('C','H','O','R'));
00782     } else {
00783         lua_pushnil();
00784     }
00785 
00786 }
00787 
00788 void Lua_V2::StopActorChores() {
00789     lua_Object actorObj = lua_getparam(1);
00790     // Guesswork for boolean parameter
00791     bool ignoreLoopingChores = getbool(2);
00792 
00793     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00794         return;
00795 
00796     Actor *actor = getactor(actorObj);
00797     if (!actor)
00798         return;
00799 
00800     actor->stopAllChores(ignoreLoopingChores);
00801 }
00802 
00803 void Lua_V2::SetActorLighting() {
00804     lua_Object actorObj = lua_getparam(1);
00805     lua_Object lightModeObj = lua_getparam(2);
00806 
00807     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00808         return;
00809 
00810     Actor *actor = getactor(actorObj);
00811     if (!actor)
00812         return;
00813 
00814     if (lua_isnil(lightModeObj) || !lua_isnumber(lightModeObj))
00815         return;
00816 
00817     int lightMode = (int)lua_getnumber(lightModeObj);
00818     actor->setLightMode((Actor::LightMode)lightMode);
00819 }
00820 
00821 void Lua_V2::SetActorCollisionMode() {
00822     lua_Object actorObj = lua_getparam(1);
00823     lua_Object modeObj = lua_getparam(2);
00824 
00825     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00826         return;
00827 
00828     Actor *actor = getactor(actorObj);
00829     assert(actor);
00830     int mode = (int)lua_getnumber(modeObj);
00831 
00832     Actor::CollisionMode m;
00833     switch (mode) {
00834         case Actor::CollisionOff:
00835             m = Actor::CollisionOff;
00836             break;
00837         case Actor::CollisionBox:
00838             m = Actor::CollisionBox;
00839             break;
00840         case Actor::CollisionSphere:
00841             m = Actor::CollisionSphere;
00842             break;
00843         default:
00844             warning("Lua_V2::SetActorCollisionMode(): wrong collisionmode: %d, using default 0", mode);
00845             m = Actor::CollisionOff;
00846     }
00847     actor->setCollisionMode(m);
00848 }
00849 
00850 void Lua_V2::SetActorCollisionScale() {
00851     lua_Object actorObj = lua_getparam(1);
00852     lua_Object scaleObj = lua_getparam(2);
00853 
00854     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00855         return;
00856 
00857     Actor *actor = getactor(actorObj);
00858     assert(actor);
00859 
00860     float scale = lua_getnumber(scaleObj);
00861     actor->setCollisionScale(scale);
00862 }
00863 
00864 void Lua_V2::GetActorPuckVector() {
00865     lua_Object actorObj = lua_getparam(1);
00866     lua_Object addObj = lua_getparam(2);
00867 
00868     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
00869         lua_pushnil();
00870         return;
00871     }
00872 
00873     Actor *actor = getactor(actorObj);
00874     // Note: The wear chore of dumbshadow.cos is only started from Lua if
00875     // GetActorPuckVector returns a non-nil value. The original engine seems
00876     // to return nil for all actors that have never followed walkboxes.
00877     if (!actor || !actor->hasFollowedBoxes()) {
00878         lua_pushnil();
00879         return;
00880     }
00881 
00882     Math::Vector3d result = actor->getPuckVector();
00883     if (!lua_isnil(addObj))
00884         result += actor->getPos();
00885 
00886     lua_pushnumber(result.x());
00887     lua_pushnumber(result.y());
00888     lua_pushnumber(result.z());
00889 }
00890 
00891 void Lua_V2::SetActorHeadLimits() {
00892     lua_Object actorObj = lua_getparam(1);
00893     lua_Object yawObj = lua_getparam(2);
00894     lua_Object maxPitchObj = lua_getparam(3);
00895     lua_Object minPitchObj = lua_getparam(4);
00896 
00897     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00898         return;
00899 
00900     Actor *actor = getactor(actorObj);
00901     if (!actor)
00902         return;
00903 
00904     if (lua_isnumber(yawObj) && lua_isnumber(minPitchObj) && lua_isnumber(maxPitchObj)) {
00905         float yaw = lua_getnumber(yawObj);
00906         float maxPitch = lua_getnumber(maxPitchObj);
00907         float minPitch = lua_getnumber(minPitchObj);
00908         actor->setHeadLimits(yaw / 2, maxPitch, -minPitch);
00909     }
00910 }
00911 
00912 void Lua_V2::SetActorHead() {
00913     lua_Object actorObj = lua_getparam(1);
00914     lua_Object jointObj = lua_getparam(2);
00915     lua_Object xObj = lua_getparam(3);
00916     lua_Object yObj = lua_getparam(4);
00917     lua_Object zObj = lua_getparam(5);
00918 
00919     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A', 'C', 'T', 'R'))
00920         return;
00921 
00922     Actor *actor = getactor(actorObj);
00923     if (!actor)
00924         return;
00925 
00926     if (lua_isstring(jointObj)) {
00927         const char *joint = lua_getstring(jointObj);
00928         Math::Vector3d offset;
00929         offset.x() = lua_getnumber(xObj);
00930         offset.y() = lua_getnumber(yObj);
00931         offset.z() = lua_getnumber(zObj);
00932         actor->setHead(joint, offset);
00933     }
00934 }
00935 
00936 void Lua_V2::SetActorFOV() {
00937     lua_Object actorObj = lua_getparam(1);
00938     lua_Object fovObj = lua_getparam(2);
00939 
00940     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
00941         return;
00942 
00943     Actor *actor = getactor(actorObj);
00944     if (!actor)
00945         return;
00946 
00947     if (lua_isnumber(fovObj)) {
00948         float fov = lua_getnumber(fovObj);
00949         // FIXME: implement missing code
00950         //actor->func(fov); // cos(fov * some tuntime val * 0.5)
00951         warning("Lua_V2::SetActorFOV: implement opcode. actor: %s, param: %f", actor->getName().c_str(), fov);
00952     }
00953 }
00954 
00955 void Lua_V2::AttachActor() {
00956     // Missing lua parts
00957     lua_Object attachedObj = lua_getparam(1);
00958     lua_Object actorObj = lua_getparam(2);
00959     lua_Object jointObj = lua_getparam(3);
00960 
00961     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A', 'C', 'T', 'R'))
00962         return;
00963 
00964     Actor *actor = getactor(actorObj);
00965     if (!actor)
00966         return;
00967 
00968     if (!lua_isuserdata(attachedObj) || lua_tag(attachedObj) != MKTAG('A', 'C', 'T', 'R'))
00969         return;
00970 
00971     Actor *attached = getactor(attachedObj);
00972     if (!attached)
00973         return;
00974 
00975     const char *joint = nullptr;
00976     if (!lua_isnil(jointObj)) {
00977         joint = lua_getstring(jointObj);
00978     }
00979 
00980     attached->attachToActor(actor, joint);
00981     Debug::debug(Debug::Actors | Debug::Scripts, "Lua_V2::AttachActor: attaching %s to %s (on %s)", attached->getName().c_str(), actor->getName().c_str(), joint ? joint : "(none)");
00982 
00983     g_emi->invalidateSortOrder();
00984 }
00985 
00986 void Lua_V2::DetachActor() {
00987     // Missing lua parts
00988     lua_Object attachedObj = lua_getparam(1);
00989 
00990     if (!lua_isuserdata(attachedObj) || lua_tag(attachedObj) != MKTAG('A','C','T','R'))
00991         return;
00992 
00993     Actor *attached = getactor(attachedObj);
00994     if (!attached)
00995         return;
00996 
00997     Debug::debug(Debug::Actors | Debug::Scripts, "Lua_V2::DetachActor: detaching %s from parent actor", attached->getName().c_str());
00998     attached->detach();
00999 
01000     g_emi->invalidateSortOrder();
01001 }
01002 
01003 void Lua_V2::WalkActorToAvoiding() {
01004     lua_Object actorObj = lua_getparam(1);
01005     lua_Object actor2Obj = lua_getparam(2);
01006     lua_Object xObj = lua_getparam(3);
01007     lua_Object yObj = lua_getparam(4);
01008     lua_Object zObj = lua_getparam(5);
01009 
01010     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
01011         return;
01012 
01013     if (!lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKTAG('A','C','T','R'))
01014         return;
01015 
01016     Math::Vector3d destVec;
01017     Actor *actor = getactor(actorObj);
01018     if (!lua_isnumber(xObj)) {
01019         if (!lua_isuserdata(xObj) || lua_tag(xObj) != MKTAG('A','C','T','R'))
01020             return;
01021         Actor *destActor = getactor(xObj);
01022         destVec = destActor->getPos();
01023     } else {
01024         float x = lua_getnumber(xObj);
01025         float y = lua_getnumber(yObj);
01026         float z = lua_getnumber(zObj);
01027         destVec.set(x, y, z);
01028     }
01029 
01030     // TODO: Make this actually avoid the second actor
01031 
01032     actor->walkTo(destVec);
01033 }
01034 
01035 void Lua_V2::WalkActorVector() {
01036     lua_Object actorObj = lua_getparam(1);
01037     //  lua_Object xObj = lua_getparam(3);
01038     //  lua_Object yObj = lua_getparam(4);
01039     //  lua_Object zObj = lua_getparam(5);
01040     //  lua_Object param6Obj = lua_getparam(6);
01041 
01042     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A', 'C', 'T', 'R'))
01043         return;
01044 
01045     //  Actor *actor = static_cast<Actor *>(lua_getuserdata(actorObj));
01046     Actor *actor2 = getactor(actorObj);
01047 
01048     // TODO whole below part need rewrote to much original
01049     float moveHoriz, moveVert;
01050 
01051     // Third option is the "left/right" movement
01052     moveHoriz = luaL_check_number(2);
01053     // Fourth Option is the "up/down" movement
01054     moveVert = luaL_check_number(4);
01055 
01056     // Get the direction the camera is pointing
01057     Set::Setup *setup = g_grim->getCurrSet()->getCurrSetup();
01058     Math::Vector3d cameraVector(0, 0, 1);
01059 
01060     setup->_rot.transform(&cameraVector, false);
01061 
01062     // find the angle the camera direction is around the unit circle
01063     Math::Angle cameraYaw = Math::Angle::arcTangent2(cameraVector.x(), cameraVector.z());
01064 
01065     // Handle the turning
01066     Math::Vector3d adjustVector(moveHoriz, 0, moveVert);
01067     // find the angle the adjust vector is around the unit circle
01068     Math::Angle adjustYaw = Math::Angle::arcTangent2(adjustVector.x(), adjustVector.z());
01069 
01070     Math::Angle yaw = cameraYaw + adjustYaw;
01071 
01072     // set the new direction or walk forward
01073     if (actor2->getYaw() != yaw)
01074         actor2->turnTo(0, yaw, 0, true);
01075     actor2->walkForward();
01076 }
01077 
01078 void Lua_V2::EnableActorPuck() {
01079     lua_Object actorObj = lua_getparam(1);
01080 
01081     if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
01082         return;
01083 
01084     Actor *actor = getactor(actorObj);
01085     if (!actor)
01086         return;
01087 
01088     bool enable = getbool(2);
01089 
01090     // FIXME: Implement.
01091     warning("Lua_V2::EnableActorPuck: stub, actor: %s enable: %s", actor->getName().c_str(), enable ? "TRUE" : "FALSE");
01092 }
01093 
01094 // Helper function, not called from LUA directly
01095 void Lua_V2::setChoreAndCostume(lua_Object choreObj, lua_Object costumeObj, Actor *actor, Costume *&costume, int &chore) {
01096     if (lua_isnil(choreObj)) {
01097         return;
01098     }
01099 
01100     if (!findCostume(costumeObj, actor, &costume))
01101         return;
01102 
01103     const char *choreStr = lua_getstring(choreObj);
01104     chore = costume->getChoreId(choreStr);
01105 }
01106 
01107 } // end of namespace Grim


Generated on Sat Oct 12 2019 05:00:48 for ResidualVM by doxygen 1.7.1
curved edge   curved edge