Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

game-script.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  */
00009 #include "game-script.h"
00010 
00011 #include "Log.h"
00012 #include "KeyControl.h"
00013 #include "Path.h"
00014 #include "V2.h"
00015 #include "Anim.h"
00016 #include "Shape.h"
00017 #include "Cube.h"
00018 #include "Rules.h"
00019 #include "LevelScript.h"
00020 #include "ModelFactory.h"
00021 #include "Room.h"
00022 #include "RopeDecor.h"
00023 
00024 #include "EffectNone.h"
00025 #include "EffectMirror.h"
00026 #include "EffectInvisible.h"
00027 #include "EffectReverse.h"
00028 #include "EffectZx.h"
00029 
00030 #include "def-script.h"
00031 
00032 //-----------------------------------------------------------------
00033     inline LevelScript *
00034 getLevelScript(lua_State *L)
00035 {
00036     return dynamic_cast<LevelScript*>(script_getLeader(L));
00037 }
00038 //-----------------------------------------------------------------
00039     inline Cube *
00040 getModel(lua_State *L, int model_index)
00041 {
00042     return getLevelScript(L)->getModel(model_index);
00043 }
00044 
00045 //-----------------------------------------------------------------
00046 /**
00047  * void game_setRoomWaves(amplitude, periode, speed)
00048  */
00049     int
00050 script_game_setRoomWaves(lua_State *L) throw()
00051 {
00052     BEGIN_NOEXCEPTION;
00053     float amp = luaL_checknumber(L, 1);
00054     float periode = luaL_checknumber(L, 2);
00055     float speed = luaL_checknumber(L, 3);
00056 
00057     getLevelScript(L)->room()->setWaves(amp, periode, speed);
00058     END_NOEXCEPTION;
00059     return 0;
00060 }
00061 //-----------------------------------------------------------------
00062 /**
00063  * int game_addModel(kind, x, y, shape)
00064  * Return model index.
00065  *
00066  *  table = addModel("light", 10, 30, "table.bmp",
00067  *  [[
00068  *  XXXXX
00069  *  ..X
00070  *  ..X
00071  *  ]])
00072  */
00073     int
00074 script_game_addModel(lua_State *L) throw()
00075 {
00076     BEGIN_NOEXCEPTION;
00077     const char *kind = luaL_checkstring(L, 1);
00078     int x = luaL_checkint(L, 2);
00079     int y = luaL_checkint(L, 3);
00080     const char *shape = luaL_checkstring(L, 4);
00081 
00082     Cube *model = ModelFactory::createModel(kind, V2(x, y), shape);
00083     Unit *unit = ModelFactory::createUnit(kind);
00084     int model_index = getLevelScript(L)->addModel(model, unit);
00085     lua_pushnumber(L, model_index);
00086     END_NOEXCEPTION;
00087     //NOTE: return model_index
00088     return 1;
00089 }
00090 //-----------------------------------------------------------------
00091 /**
00092  * int game_getCycles()
00093  */
00094     int
00095 script_game_getCycles(lua_State *L) throw()
00096 {
00097     BEGIN_NOEXCEPTION;
00098     int cycles = getLevelScript(L)->room()->getCycles();
00099     lua_pushnumber(L, cycles);
00100     END_NOEXCEPTION;
00101     //NOTE: return cycles
00102     return 1;
00103 }
00104 //-----------------------------------------------------------------
00105 /**
00106  * void game_addDecor(decor_name, params...)
00107  *
00108  * decor_name:
00109  * "rope" ... draw rope between models
00110  *          params = (model_index1, model_index2,
00111  *              shift_x1, shift_y1, shift_x2, shift_y2)
00112  */
00113     int
00114 script_game_addDecor(lua_State *L) throw()
00115 {
00116     BEGIN_NOEXCEPTION;
00117     std::string decor_name = luaL_checkstring(L, 1);
00118     if ("rope" == decor_name) {
00119         int model_index1 = luaL_checkint(L, 2);
00120         int model_index2 = luaL_checkint(L, 3);
00121         int shift_x1 = luaL_checkint(L, 4);
00122         int shift_y1 = luaL_checkint(L, 5);
00123         int shift_x2 = luaL_checkint(L, 6);
00124         int shift_y2 = luaL_checkint(L, 7);
00125 
00126         Cube *model1 = getModel(L, model_index1);
00127         Cube *model2 = getModel(L, model_index2);
00128         getLevelScript(L)->room()->addDecor(new RopeDecor(model1, model2,
00129                     V2(shift_x1, shift_y1), V2(shift_x2, shift_y2)));
00130     }
00131     else {
00132         LOG_WARNING(ExInfo("unknown decor")
00133                 .addInfo("decor_name", decor_name));
00134     }
00135 
00136     END_NOEXCEPTION;
00137     return 0;
00138 }
00139 //-----------------------------------------------------------------
00140 /**
00141  * void game_setScreenShift(x, y)
00142  */
00143     int
00144 script_game_setScreenShift(lua_State *L) throw()
00145 {
00146     BEGIN_NOEXCEPTION;
00147     int x = luaL_checkint(L, 1);
00148     int y = luaL_checkint(L, 2);
00149     getLevelScript(L)->room()->setScreenShift(V2(x, y));
00150     END_NOEXCEPTION;
00151     return 0;
00152 }
00153 //-----------------------------------------------------------------
00154 /**
00155  * void game_changeBg(picture)
00156  */
00157     int
00158 script_game_changeBg(lua_State *L) throw()
00159 {
00160     BEGIN_NOEXCEPTION;
00161     const char *picture = luaL_checkstring(L, 1);
00162     getLevelScript(L)->room()->changeBg(Path::dataReadPath(picture));
00163     END_NOEXCEPTION;
00164     return 0;
00165 }
00166 //-----------------------------------------------------------------
00167 /**
00168  * void game_checkActive()
00169  * Check active fish, switch to non busy alive fish.
00170  */
00171     int
00172 script_game_checkActive(lua_State *L) throw()
00173 {
00174     BEGIN_NOEXCEPTION;
00175     getLevelScript(L)->room()->checkActive();
00176     END_NOEXCEPTION;
00177     return 0;
00178 }
00179 //-----------------------------------------------------------------
00180 /**
00181  * void game_setFastFalling(value)
00182  * Value==true sets fast falling for all objets.
00183  */
00184     int
00185 script_game_setFastFalling(lua_State *L) throw()
00186 {
00187     BEGIN_NOEXCEPTION;
00188     bool value = lua_toboolean(L, 1);
00189     getLevelScript(L)->room()->setFastFalling(value);
00190     END_NOEXCEPTION;
00191     return 0;
00192 }
00193 
00194 //-----------------------------------------------------------------
00195 /**
00196  * void model_addAnim(model_index, anim_name, picture, lookDir)
00197  * Sides:
00198  * LOOK_LEFT = 0
00199  * LOOK_RIGHT = 1
00200  */
00201     int
00202 script_model_addAnim(lua_State *L) throw()
00203 {
00204     BEGIN_NOEXCEPTION;
00205     int model_index = luaL_checkint(L, 1);
00206     const char *anim_name = luaL_checkstring(L, 2);
00207     const char *picture = luaL_checkstring(L, 3);
00208     Anim::eSide lookDir = static_cast<Anim::eSide>(
00209             luaL_optint(L, 4, Anim::SIDE_LEFT));
00210 
00211     Cube *model = getModel(L, model_index);
00212     model->anim()->addAnim(anim_name, Path::dataReadPath(picture), lookDir);
00213     END_NOEXCEPTION;
00214     return 0;
00215 }
00216 //-----------------------------------------------------------------
00217 /**
00218  * void model_runAnim(model_index, anim_name, phase=0)
00219  */
00220     int
00221 script_model_runAnim(lua_State *L) throw()
00222 {
00223     BEGIN_NOEXCEPTION;
00224     int model_index = luaL_checkint(L, 1);
00225     const char *anim_name = luaL_checkstring(L, 2);
00226     int phase = luaL_optint(L, 3, 0);
00227 
00228     Cube *model = getModel(L, model_index);
00229     model->anim()->runAnim(anim_name, phase);
00230     END_NOEXCEPTION;
00231     return 0;
00232 }
00233 //-----------------------------------------------------------------
00234 /**
00235  * void model_setAnim(model_index, anim_name, phase)
00236  */
00237     int
00238 script_model_setAnim(lua_State *L) throw()
00239 {
00240     BEGIN_NOEXCEPTION;
00241     int model_index = luaL_checkint(L, 1);
00242     const char *anim_name = luaL_checkstring(L, 2);
00243     int phase = luaL_checkint(L, 3);
00244 
00245     Cube *model = getModel(L, model_index);
00246     model->anim()->setAnim(anim_name, phase);
00247     END_NOEXCEPTION;
00248     return 0;
00249 }
00250 //-----------------------------------------------------------------
00251 /**
00252  * void model_useSpecialAnim(model_index, anim_name, phase)
00253  *
00254  * Set special anim for one phase.
00255  */
00256     int
00257 script_model_useSpecialAnim(lua_State *L) throw()
00258 {
00259     BEGIN_NOEXCEPTION;
00260     int model_index = luaL_checkint(L, 1);
00261     const char *anim_name = luaL_checkstring(L, 2);
00262     int phase = luaL_checkint(L, 3);
00263 
00264     Cube *model = getModel(L, model_index);
00265     model->anim()->useSpecialAnim(anim_name, phase);
00266     END_NOEXCEPTION;
00267     return 0;
00268 }
00269 //-----------------------------------------------------------------
00270 /**
00271  * int model_countAnims(model_index, anim_name)
00272  */
00273     int
00274 script_model_countAnims(lua_State *L) throw()
00275 {
00276     BEGIN_NOEXCEPTION;
00277     int model_index = luaL_checkint(L, 1);
00278     const char *anim_name = luaL_checkstring(L, 2);
00279 
00280     Cube *model = getModel(L, model_index);
00281     int anims = model->anim()->countAnimPhases(anim_name);
00282     lua_pushnumber(L, anims);
00283     END_NOEXCEPTION;
00284     //NOTE: return anims
00285     return 1;
00286 }
00287 //-----------------------------------------------------------------
00288 /**
00289  * void model_setEffect(model_index, effect_name)
00290  *
00291  * Set special view effect.
00292  * available effects: "none", "mirror", "invisible", "reverse", "zx"
00293  */
00294     int
00295 script_model_setEffect(lua_State *L) throw()
00296 {
00297     BEGIN_NOEXCEPTION;
00298     int model_index = luaL_checkint(L, 1);
00299     std::string effect_name = luaL_checkstring(L, 2);
00300 
00301     Cube *model = getModel(L, model_index);
00302     if ("none" == effect_name) {
00303         model->anim()->changeEffect(new EffectNone());
00304     }
00305     else if ("mirror" == effect_name) {
00306         model->anim()->changeEffect(new EffectMirror());
00307     }
00308     else if ("invisible" == effect_name) {
00309         model->anim()->changeEffect(new EffectInvisible());
00310     }
00311     else if ("reverse" == effect_name) {
00312         model->anim()->changeEffect(new EffectReverse());
00313     }
00314     else if ("zx" == effect_name) {
00315         model->anim()->changeEffect(new EffectZx());
00316     }
00317     else {
00318         ExInfo error = ExInfo("unknown view effect")
00319             .addInfo("effect", effect_name);
00320         LOG_WARNING(error);
00321         luaL_error(L, error.what());
00322     }
00323     END_NOEXCEPTION;
00324     return 0;
00325 }
00326 //-----------------------------------------------------------------
00327 /**
00328  * (x, y) model_getLoc(model_index)
00329  */
00330     int
00331 script_model_getLoc(lua_State *L) throw()
00332 {
00333     BEGIN_NOEXCEPTION;
00334     int model_index = luaL_checkint(L, 1);
00335 
00336     Cube *model = getModel(L, model_index);
00337     V2 loc = model->getLocation();
00338 
00339     lua_pushnumber(L, loc.getX());
00340     lua_pushnumber(L, loc.getY());
00341     END_NOEXCEPTION;
00342     //NOTE: return (x, y)
00343     return 2;
00344 }
00345 
00346 //-----------------------------------------------------------------
00347 /**
00348  * string model_getAction(model_index)
00349  */
00350     int
00351 script_model_getAction(lua_State *L) throw()
00352 {
00353     BEGIN_NOEXCEPTION;
00354     int model_index = luaL_checkint(L, 1);
00355     Cube *model = getModel(L, model_index);
00356     std::string action = model->rules()->getAction();
00357 
00358     lua_pushlstring(L, action.c_str(), action.size());
00359     END_NOEXCEPTION;
00360     //NOTE: return action
00361     return 1;
00362 }
00363 //-----------------------------------------------------------------
00364 /**
00365  * string model_getState(model_index)
00366  */
00367     int
00368 script_model_getState(lua_State *L) throw()
00369 {
00370     BEGIN_NOEXCEPTION;
00371     int model_index = luaL_checkint(L, 1);
00372     Cube *model = getModel(L, model_index);
00373     std::string state = model->rules()->getState();
00374 
00375     lua_pushlstring(L, state.c_str(), state.size());
00376     END_NOEXCEPTION;
00377     //NOTE: return state
00378     return 1;
00379 }
00380 //-----------------------------------------------------------------
00381 /**
00382  * Dir::eDir model_getDir(model_index)
00383  */
00384     int
00385 script_model_getDir(lua_State *L) throw()
00386 {
00387     BEGIN_NOEXCEPTION;
00388     int model_index = luaL_checkint(L, 1);
00389     Cube *model = getModel(L, model_index);
00390     Dir::eDir dir = model->getLastMoveDir();
00391 
00392     lua_pushnumber(L, dir);
00393     END_NOEXCEPTION;
00394     //NOTE: return dir
00395     return 1;
00396 }
00397 //-----------------------------------------------------------------
00398 /**
00399  * Dir::eDir model_getTouchDir(model_index)
00400  */
00401     int
00402 script_model_getTouchDir(lua_State *L) throw()
00403 {
00404     BEGIN_NOEXCEPTION;
00405     int model_index = luaL_checkint(L, 1);
00406     Cube *model = getModel(L, model_index);
00407     Dir::eDir dir = model->rules()->getTouchDir();
00408 
00409     lua_pushnumber(L, dir);
00410     END_NOEXCEPTION;
00411     //NOTE: return dir
00412     return 1;
00413 }
00414 //-----------------------------------------------------------------
00415 /**
00416  * bool model_isAlive(model_index)
00417  */
00418     int
00419 script_model_isAlive(lua_State *L) throw()
00420 {
00421     BEGIN_NOEXCEPTION;
00422     int model_index = luaL_checkint(L, 1);
00423     Cube *model = getModel(L, model_index);
00424     bool alive = model->isAlive();
00425 
00426     lua_pushboolean(L, alive);
00427     END_NOEXCEPTION;
00428     //NOTE: return alive
00429     return 1;
00430 }
00431 //-----------------------------------------------------------------
00432 /**
00433  * bool model_isOut(model_index)
00434  *
00435  * Returns true when model is out of room.
00436  */
00437     int
00438 script_model_isOut(lua_State *L) throw()
00439 {
00440     BEGIN_NOEXCEPTION;
00441     int model_index = luaL_checkint(L, 1);
00442     Cube *model = getModel(L, model_index);
00443     bool out = model->isOut();
00444 
00445     lua_pushboolean(L, out);
00446     END_NOEXCEPTION;
00447     //NOTE: return out
00448     return 1;
00449 }
00450 //-----------------------------------------------------------------
00451 /**
00452  * bool model_isLeft(model_index)
00453  *
00454  * Returns true when model is looking to the left.
00455  */
00456     int
00457 script_model_isLeft(lua_State *L) throw()
00458 {
00459     BEGIN_NOEXCEPTION;
00460     int model_index = luaL_checkint(L, 1);
00461     Cube *model = getModel(L, model_index);
00462     bool left = model->isLeft();
00463 
00464     lua_pushboolean(L, left);
00465     END_NOEXCEPTION;
00466     //NOTE: return left
00467     return 1;
00468 }
00469 //-----------------------------------------------------------------
00470 /**
00471  * bool model_isAtBorder(model_index)
00472  *
00473  * Returns true when model is at room border.
00474  */
00475     int
00476 script_model_isAtBorder(lua_State *L) throw()
00477 {
00478     BEGIN_NOEXCEPTION;
00479     int model_index = luaL_checkint(L, 1);
00480     Cube *model = getModel(L, model_index);
00481     bool atBorder = model->rules()->isAtBorder();
00482 
00483     lua_pushboolean(L, atBorder);
00484     END_NOEXCEPTION;
00485     //NOTE: return atBorder
00486     return 1;
00487 }
00488 //-----------------------------------------------------------------
00489 /**
00490  * int model_getW(model_index)
00491  *
00492  * Returns model width.
00493  */
00494     int
00495 script_model_getW(lua_State *L) throw()
00496 {
00497     BEGIN_NOEXCEPTION;
00498     int model_index = luaL_checkint(L, 1);
00499     Cube *model = getModel(L, model_index);
00500     int width = model->shape()->getW();
00501 
00502     lua_pushnumber(L, width);
00503     END_NOEXCEPTION;
00504     //NOTE: return width
00505     return 1;
00506 }
00507 //-----------------------------------------------------------------
00508 /**
00509  * int model_getH(model_index)
00510  *
00511  * Returns model height.
00512  */
00513     int
00514 script_model_getH(lua_State *L) throw()
00515 {
00516     BEGIN_NOEXCEPTION;
00517     int model_index = luaL_checkint(L, 1);
00518     Cube *model = getModel(L, model_index);
00519     int height = model->shape()->getH();
00520 
00521     lua_pushnumber(L, height);
00522     END_NOEXCEPTION;
00523     //NOTE: return height
00524     return 1;
00525 }
00526 //-----------------------------------------------------------------
00527 /**
00528  * void model_setGoal(model_index, goalname)
00529  * Choose:
00530  * - "goal_no" .. no goal
00531  * - "goal_out" ... go out
00532  * - "goal_escape" ... go alive out
00533  */
00534     int
00535 script_model_setGoal(lua_State *L) throw()
00536 {
00537     //NOTE: (const char*)== does not compare string equality
00538     BEGIN_NOEXCEPTION;
00539     int model_index = luaL_checkint(L, 1);
00540     std::string goalname = luaL_checkstring(L, 2);
00541 
00542     Cube *model = getModel(L, model_index);
00543     Goal goal = Goal::noGoal();
00544     if ("goal_no" == goalname) {
00545         goal = Goal::noGoal();
00546     }
00547     else if ("goal_out" == goalname) {
00548         goal = Goal::outGoal();
00549     }
00550     else if ("goal_escape" == goalname) {
00551         goal = Goal::escapeGoal();
00552     }
00553     else if ("goal_alive" == goalname) {
00554         goal = Goal::aliveGoal();
00555     }
00556     else {
00557         ExInfo error = ExInfo("unknown goal")
00558             .addInfo("goal", goalname);
00559         LOG_WARNING(error);
00560         luaL_error(L, error.what());
00561     }
00562 
00563     model->setGoal(goal);
00564 
00565     END_NOEXCEPTION;
00566     return 0;
00567 }
00568 //-----------------------------------------------------------------
00569 /**
00570  * void model_change_turnSide(model_index)
00571  *
00572  * Change look side.
00573  */
00574     int
00575 script_model_change_turnSide(lua_State *L) throw()
00576 {
00577     BEGIN_NOEXCEPTION;
00578     int model_index = luaL_checkint(L, 1);
00579     Cube *model = getModel(L, model_index);
00580     model->change_turnSide();
00581 
00582     END_NOEXCEPTION;
00583     return 0;
00584 }
00585 //-----------------------------------------------------------------
00586 /**
00587  * void model_setViewShift(model_index, shift_x, shift_y)
00588  * Shift view (used for obsolete animation effects).
00589  */
00590     int
00591 script_model_setViewShift(lua_State *L) throw()
00592 {
00593     BEGIN_NOEXCEPTION;
00594     int model_index = luaL_checkint(L, 1);
00595     int shift_x = luaL_checkint(L, 2);
00596     int shift_y = luaL_checkint(L, 3);
00597     Cube *model = getModel(L, model_index);
00598     model->anim()->setViewShift(V2(shift_x, shift_y));
00599 
00600     END_NOEXCEPTION;
00601     return 0;
00602 }
00603 //-----------------------------------------------------------------
00604 /**
00605  * shift_x, shift_y model_getViewShift(model_index)
00606  */
00607     int
00608 script_model_getViewShift(lua_State *L) throw()
00609 {
00610     BEGIN_NOEXCEPTION;
00611     int model_index = luaL_checkint(L, 1);
00612     Cube *model = getModel(L, model_index);
00613     V2 shift = model->anim()->getViewShift();
00614 
00615     lua_pushnumber(L, shift.getX());
00616     lua_pushnumber(L, shift.getY());
00617     END_NOEXCEPTION;
00618     //NOTE: return shift_x, shift_y
00619     return 2;
00620 }
00621 //-----------------------------------------------------------------
00622 /**
00623  * void model_setBusy(model_index, value)
00624  */
00625     int
00626 script_model_setBusy(lua_State *L) throw()
00627 {
00628     BEGIN_NOEXCEPTION;
00629     int model_index = luaL_checkint(L, 1);
00630     bool busy = lua_toboolean(L, 2);
00631     Cube *model = getModel(L, model_index);
00632     model->setBusy(busy);
00633 
00634     END_NOEXCEPTION;
00635     return 0;
00636 }
00637 
00638 //-----------------------------------------------------------------
00639 /**
00640  * void model_equals(model_index, x, y)
00641  *
00642  * Returns whether object at location(x, y) is equal.
00643  * NOTE: model_index can be -1 for empty water.
00644  * NOTE: boder is as wall (even thought border.index == -1)
00645  */
00646     int
00647 script_model_equals(lua_State *L) throw()
00648 {
00649     BEGIN_NOEXCEPTION;
00650     int model_index = luaL_checkint(L, 1);
00651     int x = luaL_checkint(L, 2);
00652     int y = luaL_checkint(L, 3);
00653     Cube *other = getLevelScript(L)->askField(V2(x, y));
00654 
00655     bool equals = false;
00656     if (other) {
00657         if (model_index == -1) {
00658             equals = false;
00659         }
00660         else {
00661             equals = (model_index == other->getIndex());
00662         }
00663     }
00664     else {
00665         if (model_index == -1) {
00666             equals = true;
00667         }
00668     }
00669 
00670     lua_pushboolean(L, equals);
00671     END_NOEXCEPTION;
00672     //NOTE: return equals
00673     return 1;
00674 }
00675 
00676 
00677 //-----------------------------------------------------------------
00678 /**
00679  * void sound_addSound(name, file)
00680  * 
00681  * Store this sound resource under this name.
00682  */
00683     int
00684 script_sound_addSound(lua_State *L) throw()
00685 {
00686     BEGIN_NOEXCEPTION;
00687     const char *name = luaL_checkstring(L, 1);
00688     const char *file = luaL_checkstring(L, 2);
00689 
00690     getLevelScript(L)->addSound(name, Path::dataReadPath(file));
00691     END_NOEXCEPTION;
00692     return 0;
00693 }
00694 //-----------------------------------------------------------------
00695 /**
00696  * void sound_playSound(name, volume)
00697  */
00698     int
00699 script_sound_playSound(lua_State *L) throw()
00700 {
00701     BEGIN_NOEXCEPTION;
00702     const char *name = luaL_checkstring(L, 1);
00703     int volume = luaL_optint(L, 2, 100);
00704 
00705     getLevelScript(L)->playSound(name, volume);
00706     END_NOEXCEPTION;
00707     return 0;
00708 }
00709 

Generated on Wed Jun 1 09:54:31 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2