Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F118918
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
58 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/ScriptAPI.cpp b/src/ScriptAPI.cpp
index 4aa67bf..de8c95b 100644
--- a/src/ScriptAPI.cpp
+++ b/src/ScriptAPI.cpp
@@ -1,913 +1,969 @@
-/*
- * Copyright (C) 2012-2013 Me and My Shadow
- *
- * This file is part of Me and My Shadow.
- *
- * Me and My Shadow 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 3 of the License, or
- * (at your option) any later version.
- *
- * Me and My Shadow 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 Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ScriptAPI.h"
-#include "ScriptExecutor.h"
-#include "Functions.h"
-#include "Game.h"
-#include <iostream>
-using namespace std;
-
-///////////////////////////BLOCK SPECIFIC///////////////////////////
-int getBlockById(lua_State* state){
- //Get the number of args, this MUST be one.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for getBlockById, expected 1.");
- lua_error(state);
- }
- //Make sure the given argument is an id (string).
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getBlockById, should be string.");
- lua_error(state);
- }
-
- //Check if the currentState is the game state.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return 0;
-
- //Get the actual game object.
- string id=lua_tostring(state,1);
- std::vector<Block*>& levelObjects=game->levelObjects;
- Block* object=NULL;
- for(unsigned int i=0;i<levelObjects.size();i++){
- if(levelObjects[i]->getEditorProperty("id")==id){
- object=levelObjects[i];
- break;
- }
- }
- if(object==NULL){
- //Unable to find the requested object.
- //Return nothing, will result in a nil in the script.
- return 0;
- }
-
- //Create the userdatum.
- object->createUserData(state,"block");
-
- //We return one object, the userdatum.
- return 1;
-}
-
-int getBlocksById(lua_State* state){
- //Get the number of args, this MUST be one.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for getBlocksById, expected 1.");
- lua_error(state);
- }
- //Make sure the given argument is an id (string).
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getBlocksById, should be string.");
- lua_error(state);
- }
-
- //Check if the currentState is the game state.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return 0;
-
- //Get the actual game object.
- string id=lua_tostring(state,1);
- std::vector<Block*>& levelObjects=game->levelObjects;
- std::vector<Block*> result;
- for(unsigned int i=0;i<levelObjects.size();i++){
- if(levelObjects[i]->getEditorProperty("id")==id){
- result.push_back(levelObjects[i]);
- }
- }
-
- //Create the table that will hold the result.
- lua_createtable(state,result.size(),0);
-
- //Loop through the results.
- for(unsigned int i=0;i<result.size();i++){
- //Create the userdatum.
- result[i]->createUserData(state,"block");
- //And set the table.
- lua_rawseti(state,-2,i+1);
- }
-
- //We return one object, the userdatum.
- return 1;
-}
-
-int getBlockLocation(lua_State* state){
- //Make sure there's only one argument and that argument is an userdatum.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for getBlockLocation, expected 1.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getBlockLocation.");
- lua_error(state);
- }
- Block* object = Block::getObjectFromUserData(state,1);
- if(object==NULL) return 0;
-
- //Get the object.
- lua_pushnumber(state,object->getBox().x);
- lua_pushnumber(state,object->getBox().y);
- return 2;
-}
-
-int setBlockLocation(lua_State* state){
- //Check the number of arguments.
- int args=lua_gettop(state);
-
- //Make sure the number of arguments is correct.
- if(args!=3){
- lua_pushstring(state,"Incorrect number of arguments for setBlockLocation, expected 3.");
- lua_error(state);
- }
- //Check if the arguments are of the right type.
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setBlockLocation.");
- lua_error(state);
- }
- if(!lua_isnumber(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of setBlockLocation, should be integer.");
- lua_error(state);
- }
- if(!lua_isnumber(state,3)){
- lua_pushstring(state,"Invalid type for argument 3 of setBlockLocation, should be integer.");
- lua_error(state);
- }
-
- //Now get the pointer to the object.
- Block* object = Block::getObjectFromUserData(state,1);
- if(object==NULL) return 0;
-
- int x=lua_tonumber(state,2);
- int y=lua_tonumber(state,3);
- object->setLocation(x,y);
-
- return 0;
-}
-
-int getBlockType(lua_State* state){
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for getBlockType, expected 1.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getBlockType.");
- lua_error(state);
- }
- Block* object = Block::getObjectFromUserData(state,1);
- if(object==NULL || object->type<0 || object->type>=TYPE_MAX) return 0;
-
- lua_pushstring(state,Game::blockName[object->type]);
- return 1;
-}
-
-int changeBlockThemeState(lua_State* state){
- int args=lua_gettop(state);
- if(args!=2){
- lua_pushstring(state,"Incorrect number of arguments for changeBlockThemeState, expected 2.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of changeBlockThemeState.");
- lua_error(state);
- }
- if(!lua_isstring(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of changeBlockThemeState, should be string.");
- lua_error(state);
- }
- Block* object = Block::getObjectFromUserData(state,1);
- object->appearance.changeState(lua_tostring(state,2));
-
- return 0;
-}
-
-int setBlockEnabled(lua_State* state){
- int args=lua_gettop(state);
- if(args!=2){
- lua_pushstring(state,"Incorrect number of arguments for setBlockEnabled, expected 2.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setBlockEnabled.");
- lua_error(state);
- }
- if(!lua_isboolean(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of setBlockEnabled, should be boolean.");
- lua_error(state);
- }
-
- Block* object = Block::getObjectFromUserData(state,1);
- if(object==NULL)
- return 0;
-
- bool enabled=lua_toboolean(state,2);
- object->enabled=enabled;
-
- return 0;
-}
-
-int isBlockEnabled(lua_State* state){
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for isBlockEnabled, expected 1.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of isBlockEnabled.");
- lua_error(state);
- }
-
- Block* object = Block::getObjectFromUserData(state,1);
- if(object==NULL)
- return 0;
-
- lua_pushboolean(state,object->enabled);
- return 1;
-}
-
-int getBlockEventHandler(lua_State* state){
- int args=lua_gettop(state);
- if(args!=2){
- lua_pushstring(state,"Incorrect number of arguments for getBlockEventHandler, expected 2.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getBlockEventHandler.");
- lua_error(state);
- }
- if(!lua_isstring(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of getBlockEventHandler, should be string.");
- lua_error(state);
- }
-
- Block* object = Block::getObjectFromUserData(state,1);
- if(object==NULL) return 0;
-
- //Check event type
- string eventType=lua_tostring(state,2);
+/*
+ * Copyright (C) 2012-2013 Me and My Shadow
+ *
+ * This file is part of Me and My Shadow.
+ *
+ * Me and My Shadow 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Me and My Shadow 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 Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptAPI.h"
+#include "ScriptExecutor.h"
+#include "Functions.h"
+#include "Game.h"
+#include <iostream>
+using namespace std;
+
+///////////////////////////BLOCK SPECIFIC///////////////////////////
+int getBlockById(lua_State* state){
+ //Get the number of args, this MUST be one.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for getBlockById, expected 1.");
+ lua_error(state);
+ }
+ //Make sure the given argument is an id (string).
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getBlockById, should be string.");
+ lua_error(state);
+ }
+
+ //Check if the currentState is the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ //Get the actual game object.
+ string id=lua_tostring(state,1);
+ std::vector<Block*>& levelObjects=game->levelObjects;
+ Block* object=NULL;
+ for(unsigned int i=0;i<levelObjects.size();i++){
+ if(levelObjects[i]->getEditorProperty("id")==id){
+ object=levelObjects[i];
+ break;
+ }
+ }
+ if(object==NULL){
+ //Unable to find the requested object.
+ //Return nothing, will result in a nil in the script.
+ return 0;
+ }
+
+ //Create the userdatum.
+ object->createUserData(state,"block");
+
+ //We return one object, the userdatum.
+ return 1;
+}
+
+int getBlocksById(lua_State* state){
+ //Get the number of args, this MUST be one.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for getBlocksById, expected 1.");
+ lua_error(state);
+ }
+ //Make sure the given argument is an id (string).
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getBlocksById, should be string.");
+ lua_error(state);
+ }
+
+ //Check if the currentState is the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ //Get the actual game object.
+ string id=lua_tostring(state,1);
+ std::vector<Block*>& levelObjects=game->levelObjects;
+ std::vector<Block*> result;
+ for(unsigned int i=0;i<levelObjects.size();i++){
+ if(levelObjects[i]->getEditorProperty("id")==id){
+ result.push_back(levelObjects[i]);
+ }
+ }
+
+ //Create the table that will hold the result.
+ lua_createtable(state,result.size(),0);
+
+ //Loop through the results.
+ for(unsigned int i=0;i<result.size();i++){
+ //Create the userdatum.
+ result[i]->createUserData(state,"block");
+ //And set the table.
+ lua_rawseti(state,-2,i+1);
+ }
+
+ //We return one object, the userdatum.
+ return 1;
+}
+
+int getBlockLocation(lua_State* state){
+ //Make sure there's only one argument and that argument is an userdatum.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for getBlockLocation, expected 1.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getBlockLocation.");
+ lua_error(state);
+ }
+ Block* object = Block::getObjectFromUserData(state,1);
+ if(object==NULL) return 0;
+
+ //Get the object.
+ lua_pushnumber(state,object->getBox().x);
+ lua_pushnumber(state,object->getBox().y);
+ return 2;
+}
+
+int setBlockLocation(lua_State* state){
+ //Check the number of arguments.
+ int args=lua_gettop(state);
+
+ //Make sure the number of arguments is correct.
+ if(args!=3){
+ lua_pushstring(state,"Incorrect number of arguments for setBlockLocation, expected 3.");
+ lua_error(state);
+ }
+ //Check if the arguments are of the right type.
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setBlockLocation.");
+ lua_error(state);
+ }
+ if(!lua_isnumber(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of setBlockLocation, should be integer.");
+ lua_error(state);
+ }
+ if(!lua_isnumber(state,3)){
+ lua_pushstring(state,"Invalid type for argument 3 of setBlockLocation, should be integer.");
+ lua_error(state);
+ }
+
+ //Now get the pointer to the object.
+ Block* object = Block::getObjectFromUserData(state,1);
+ if(object==NULL) return 0;
+
+ int x=lua_tonumber(state,2);
+ int y=lua_tonumber(state,3);
+ object->setLocation(x,y);
+
+ return 0;
+}
+
+int getBlockType(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for getBlockType, expected 1.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getBlockType.");
+ lua_error(state);
+ }
+ Block* object = Block::getObjectFromUserData(state,1);
+ if(object==NULL || object->type<0 || object->type>=TYPE_MAX) return 0;
+
+ lua_pushstring(state,Game::blockName[object->type]);
+ return 1;
+}
+
+int changeBlockThemeState(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=2){
+ lua_pushstring(state,"Incorrect number of arguments for changeBlockThemeState, expected 2.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of changeBlockThemeState.");
+ lua_error(state);
+ }
+ if(!lua_isstring(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of changeBlockThemeState, should be string.");
+ lua_error(state);
+ }
+ Block* object = Block::getObjectFromUserData(state,1);
+ object->appearance.changeState(lua_tostring(state,2));
+
+ return 0;
+}
+
+int setBlockEnabled(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=2){
+ lua_pushstring(state,"Incorrect number of arguments for setBlockEnabled, expected 2.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setBlockEnabled.");
+ lua_error(state);
+ }
+ if(!lua_isboolean(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of setBlockEnabled, should be boolean.");
+ lua_error(state);
+ }
+
+ Block* object = Block::getObjectFromUserData(state,1);
+ if(object==NULL)
+ return 0;
+
+ bool enabled=lua_toboolean(state,2);
+ object->enabled=enabled;
+
+ return 0;
+}
+
+int isBlockEnabled(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for isBlockEnabled, expected 1.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of isBlockEnabled.");
+ lua_error(state);
+ }
+
+ Block* object = Block::getObjectFromUserData(state,1);
+ if(object==NULL)
+ return 0;
+
+ lua_pushboolean(state,object->enabled);
+ return 1;
+}
+
+int getBlockEventHandler(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=2){
+ lua_pushstring(state,"Incorrect number of arguments for getBlockEventHandler, expected 2.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getBlockEventHandler.");
+ lua_error(state);
+ }
+ if(!lua_isstring(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of getBlockEventHandler, should be string.");
+ lua_error(state);
+ }
+
+ Block* object = Block::getObjectFromUserData(state,1);
+ if(object==NULL) return 0;
+
+ //Check event type
+ string eventType=lua_tostring(state,2);
map<string,int>::iterator it=Game::gameObjectEventNameMap.find(eventType);
if(it==Game::gameObjectEventNameMap.end()) return 0;
//Check compiled script
map<int,int>::iterator script=object->compiledScripts.find(it->second);
if(script==object->compiledScripts.end()) return 0;
//Get event handler
lua_rawgeti(state,LUA_REGISTRYINDEX,script->second);
return 1;
-}
-
-//It will return old event handler.
-int setBlockEventHandler(lua_State* state){
- int args=lua_gettop(state);
- if(args!=3){
- lua_pushstring(state,"Incorrect number of arguments for setBlockEventHandler, expected 3.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setBlockEventHandler.");
- lua_error(state);
- }
- if(!lua_isstring(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of setBlockEventHandler, should be string.");
- lua_error(state);
- }
- if(!lua_isfunction(state,3) && !lua_isnil(state,3)){
- lua_pushstring(state,"Invalid type for argument 3 of setBlockEventHandler, should be function.");
- lua_error(state);
- }
-
- Block* object = Block::getObjectFromUserData(state,1);
- if(object==NULL) return 0;
-
- //Check event type
- string eventType=lua_tostring(state,2);
+}
+
+//It will return old event handler.
+int setBlockEventHandler(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=3){
+ lua_pushstring(state,"Incorrect number of arguments for setBlockEventHandler, expected 3.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setBlockEventHandler.");
+ lua_error(state);
+ }
+ if(!lua_isstring(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of setBlockEventHandler, should be string.");
+ lua_error(state);
+ }
+ if(!lua_isfunction(state,3) && !lua_isnil(state,3)){
+ lua_pushstring(state,"Invalid type for argument 3 of setBlockEventHandler, should be function.");
+ lua_error(state);
+ }
+
+ Block* object = Block::getObjectFromUserData(state,1);
+ if(object==NULL) return 0;
+
+ //Check event type
+ string eventType=lua_tostring(state,2);
map<string,int>::const_iterator it=Game::gameObjectEventNameMap.find(eventType);
if(it==Game::gameObjectEventNameMap.end()){
- lua_pushfstring(state,"Unknown block event type: '%s'.",eventType.c_str());
- lua_error(state);
+ lua_pushfstring(state,"Unknown block event type: '%s'.",eventType.c_str());
+ lua_error(state);
}
//Check compiled script
int scriptIndex=LUA_REFNIL;
{
map<int,int>::iterator script=object->compiledScripts.find(it->second);
if(script!=object->compiledScripts.end()) scriptIndex=script->second;
}
//Set new event handler
object->compiledScripts[it->second]=luaL_ref(state,LUA_REGISTRYINDEX);
//Get old event handler and unreference it
lua_rawgeti(state,LUA_REGISTRYINDEX,scriptIndex);
luaL_unref(state,LUA_REGISTRYINDEX,scriptIndex);
return 1;
-}
-
-//Array with the methods for the block library.
-static const struct luaL_Reg blocklib_m[]={
- {"getBlockById",getBlockById},
- {"getBlocksById",getBlocksById},
- {"getLocation",getBlockLocation},
- {"setLocation",setBlockLocation},
- {"getType",getBlockType},
- {"changeThemeState",changeBlockThemeState},
- {"setEnabled",setBlockEnabled},
- {"isEnabled",isBlockEnabled},
- {"getEventHandler",getBlockEventHandler},
- {"setEventHandler",setBlockEventHandler},
- {NULL,NULL}
-};
-
-int luaopen_block(lua_State* state){
- luaL_newlib(state,blocklib_m);
-
- //Create the metatable for the block userdata.
- luaL_newmetatable(state,"block");
-
- lua_pushstring(state,"__index");
- lua_pushvalue(state,-2);
- lua_settable(state,-3);
-
- Block::registerMetatableFunctions(state,-3);
-
- //Register the functions and methods.
- luaL_setfuncs(state,blocklib_m,0);
- return 1;
-}
-
-//////////////////////////PLAYER SPECIFIC///////////////////////////
-
-struct PlayerUserDatum{
- char sig1,sig2,sig3,sig4;
-};
-
-Player* getPlayerFromUserData(lua_State* state,int idx){
- PlayerUserDatum* ud=(PlayerUserDatum*)lua_touserdata(state,1);
- //Make sure the user datum isn't null.
- if(!ud) return NULL;
-
- //Get the game state.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return NULL;
-
- Player* player=NULL;
-
- //Check the signature to see if it's the player or the shadow.
- if(ud->sig1=='P' && ud->sig2=='L' && ud->sig3=='Y' && ud->sig4=='R')
- player=&game->player;
- else if(ud->sig1=='S' && ud->sig2=='H' && ud->sig3=='D' && ud->sig4=='W')
- player=&game->shadow;
-
- return player;
-}
-
-
-int getPlayerLocation(lua_State* state){
- //Make sure there's only one argument and that argument is an userdatum.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for getPlayerLocation, expected 1.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getPlayerLocation.");
- lua_error(state);
- }
-
- Player* player=getPlayerFromUserData(state,1);
- if(player==NULL) return 0;
-
- //Get the object.
- lua_pushnumber(state,player->getBox().x);
- lua_pushnumber(state,player->getBox().y);
- return 2;
-}
-
-int setPlayerLocation(lua_State* state){
- //Make sure there are three arguments, userdatum and two integers.
- int args=lua_gettop(state);
- if(args!=3){
- lua_pushstring(state,"Incorrect number of arguments for setPlayerLocation, expected 3.");
- lua_error(state);
- }
- //Check if the arguments are of the right type.
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setPlayerLocation.");
- lua_error(state);
- }
- if(!lua_isnumber(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of setPlayerLocation, should be integer.");
- lua_error(state);
- }
- if(!lua_isnumber(state,3)){
- lua_pushstring(state,"Invalid type for argument 3 of setPlayerLocation, should be integer.");
- lua_error(state);
- }
-
- //Get the player.
- Player* player=getPlayerFromUserData(state,1);
- if(player==NULL) return 0;
-
- //Get the new location.
- int x=lua_tonumber(state,2);
- int y=lua_tonumber(state,3);
- player->setLocation(x,y);
-
- return 0;
-}
-
-int setPlayerJump(lua_State* state){
- //Make sure there are three arguments, userdatum and one integers.
- int args=lua_gettop(state);
- if(args!=1 && args!=2){
- lua_pushstring(state,"Incorrect number of arguments for setPlayerJump, expected 1 or 2.");
- lua_error(state);
- }
- //Check if the arguments are of the right type.
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setPlayerJump.");
- lua_error(state);
- }
- if(args==2 && !lua_isnumber(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of setPlayerJump, should be integer.");
- lua_error(state);
- }
-
- //Get the player.
- Player* player=getPlayerFromUserData(state,1);
- if(player==NULL) return 0;
-
- //Get the new location.
- if(args==2){
- int yVel=lua_tonumber(state,2);
- player->jump(yVel);
- }else{
- //Use default jump strength.
- player->jump();
- }
-
- return 0;
-}
-
-int isPlayerShadow(lua_State* state){
- //Make sure there's only one argument and that argument is an userdatum.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for isPlayerShadow, expected 1.");
- lua_error(state);
- }
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of isPlayerShadow.");
- lua_error(state);
- }
-
- Player* player=getPlayerFromUserData(state,1);
- if(player==NULL) return 0;
-
- lua_pushboolean(state,player->isShadow());
- return 1;
-}
-
-int getPlayerCurrentStand(lua_State* state){
- //Get the number of args, this MUST be one.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for getPlayerCurrentStand, expected 1.");
- lua_error(state);
- }
- //Make sure the given argument is a player userdatum.
- if(!lua_isuserdata(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getPlayerCurrentStand.");
- lua_error(state);
- }
-
- Player* player=getPlayerFromUserData(state,1);
- if(player==NULL) return 0;
-
- //Get the actual game object.
- Block* object=player->getObjCurrentStand();
- if(object==NULL){
- return 0;
- }
-
- //Create the userdatum.
- object->createUserData(state,"block");
-
- //We return one object, the userdatum.
- return 1;
-}
-
-//Array with the methods for the player and shadow library.
-static const struct luaL_Reg playerlib_m[]={
- {"getLocation",getPlayerLocation},
- {"setLocation",setPlayerLocation},
- {"jump",setPlayerJump},
- {"isShadow",isPlayerShadow},
- {"getCurrentStand",getPlayerCurrentStand},
- {NULL,NULL}
-};
-
-int luaopen_player(lua_State* state){
- luaL_newlib(state,playerlib_m);
-
- //Create the metatable for the player userdata.
- luaL_newmetatable(state,"player");
-
- lua_pushstring(state,"__index");
- lua_pushvalue(state,-2);
- lua_settable(state,-3);
-
- //Now create two default player user data, one for the player and one for the shadow.
- PlayerUserDatum* ud=(PlayerUserDatum*)lua_newuserdata(state,sizeof(PlayerUserDatum));
- ud->sig1='P';ud->sig2='L';ud->sig3='Y';ud->sig4='R';
- luaL_getmetatable(state,"player");
- lua_setmetatable(state,-2);
- lua_setglobal(state,"player");
-
- ud=(PlayerUserDatum*)lua_newuserdata(state,sizeof(PlayerUserDatum));
- ud->sig1='S';ud->sig2='H';ud->sig3='D';ud->sig4='W';
- luaL_getmetatable(state,"player");
- lua_setmetatable(state,-2);
- lua_setglobal(state,"shadow");
-
- //Register the functions and methods.
- luaL_setfuncs(state,playerlib_m,0);
- return 1;
-}
-
-//////////////////////////LEVEL SPECIFIC///////////////////////////
-
-int getLevelSize(lua_State* state){
- //NOTE: this function accepts 0 arguments, but we ignore the argument count.
-
- //Returns level size.
- lua_pushinteger(state,LEVEL_WIDTH);
- lua_pushinteger(state,LEVEL_HEIGHT);
- return 2;
-}
-
-int getLevelWidth(lua_State* state){
- //NOTE: this function accepts 0 arguments, but we ignore the argument count.
-
- //Returns level size.
- lua_pushinteger(state,LEVEL_WIDTH);
- return 1;
-}
-
-int getLevelHeight(lua_State* state){
- //NOTE: this function accepts 0 arguments, but we ignore the argument count.
-
- //Returns level size.
- lua_pushinteger(state,LEVEL_HEIGHT);
- return 1;
-}
-
-int getLevelName(lua_State* state){
- //NOTE: this function accepts 0 arguments, but we ignore the argument count.
-
- //Check if the currentState is the game state.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return 0;
-
- //Returns level name.
- lua_pushstring(state,game->getLevelName().c_str());
- return 1;
-}
-
-int getLevelEventHandler(lua_State* state){
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for getLevelEventHandler, expected 1.");
- lua_error(state);
- }
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of getLevelEventHandler, should be string.");
- lua_error(state);
- }
-
- //Check if the currentState is the game state.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return 0;
-
- //Check event type
- string eventType=lua_tostring(state,1);
+}
+
+//Array with the methods for the block library.
+static const struct luaL_Reg blocklib_m[]={
+ {"getBlockById",getBlockById},
+ {"getBlocksById",getBlocksById},
+ {"getLocation",getBlockLocation},
+ {"setLocation",setBlockLocation},
+ {"getType",getBlockType},
+ {"changeThemeState",changeBlockThemeState},
+ {"setEnabled",setBlockEnabled},
+ {"isEnabled",isBlockEnabled},
+ {"getEventHandler",getBlockEventHandler},
+ {"setEventHandler",setBlockEventHandler},
+ {NULL,NULL}
+};
+
+int luaopen_block(lua_State* state){
+ luaL_newlib(state,blocklib_m);
+
+ //Create the metatable for the block userdata.
+ luaL_newmetatable(state,"block");
+
+ lua_pushstring(state,"__index");
+ lua_pushvalue(state,-2);
+ lua_settable(state,-3);
+
+ Block::registerMetatableFunctions(state,-3);
+
+ //Register the functions and methods.
+ luaL_setfuncs(state,blocklib_m,0);
+ return 1;
+}
+
+//////////////////////////PLAYER SPECIFIC///////////////////////////
+
+struct PlayerUserDatum{
+ char sig1,sig2,sig3,sig4;
+};
+
+Player* getPlayerFromUserData(lua_State* state,int idx){
+ PlayerUserDatum* ud=(PlayerUserDatum*)lua_touserdata(state,1);
+ //Make sure the user datum isn't null.
+ if(!ud) return NULL;
+
+ //Get the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return NULL;
+
+ Player* player=NULL;
+
+ //Check the signature to see if it's the player or the shadow.
+ if(ud->sig1=='P' && ud->sig2=='L' && ud->sig3=='Y' && ud->sig4=='R')
+ player=&game->player;
+ else if(ud->sig1=='S' && ud->sig2=='H' && ud->sig3=='D' && ud->sig4=='W')
+ player=&game->shadow;
+
+ return player;
+}
+
+
+int getPlayerLocation(lua_State* state){
+ //Make sure there's only one argument and that argument is an userdatum.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for getPlayerLocation, expected 1.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getPlayerLocation.");
+ lua_error(state);
+ }
+
+ Player* player=getPlayerFromUserData(state,1);
+ if(player==NULL) return 0;
+
+ //Get the object.
+ lua_pushnumber(state,player->getBox().x);
+ lua_pushnumber(state,player->getBox().y);
+ return 2;
+}
+
+int setPlayerLocation(lua_State* state){
+ //Make sure there are three arguments, userdatum and two integers.
+ int args=lua_gettop(state);
+ if(args!=3){
+ lua_pushstring(state,"Incorrect number of arguments for setPlayerLocation, expected 3.");
+ lua_error(state);
+ }
+ //Check if the arguments are of the right type.
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setPlayerLocation.");
+ lua_error(state);
+ }
+ if(!lua_isnumber(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of setPlayerLocation, should be integer.");
+ lua_error(state);
+ }
+ if(!lua_isnumber(state,3)){
+ lua_pushstring(state,"Invalid type for argument 3 of setPlayerLocation, should be integer.");
+ lua_error(state);
+ }
+
+ //Get the player.
+ Player* player=getPlayerFromUserData(state,1);
+ if(player==NULL) return 0;
+
+ //Get the new location.
+ int x=lua_tonumber(state,2);
+ int y=lua_tonumber(state,3);
+ player->setLocation(x,y);
+
+ return 0;
+}
+
+int setPlayerJump(lua_State* state){
+ //Make sure there are three arguments, userdatum and one integers.
+ int args=lua_gettop(state);
+ if(args!=1 && args!=2){
+ lua_pushstring(state,"Incorrect number of arguments for setPlayerJump, expected 1 or 2.");
+ lua_error(state);
+ }
+ //Check if the arguments are of the right type.
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setPlayerJump.");
+ lua_error(state);
+ }
+ if(args==2 && !lua_isnumber(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of setPlayerJump, should be integer.");
+ lua_error(state);
+ }
+
+ //Get the player.
+ Player* player=getPlayerFromUserData(state,1);
+ if(player==NULL) return 0;
+
+ //Get the new location.
+ if(args==2){
+ int yVel=lua_tonumber(state,2);
+ player->jump(yVel);
+ }else{
+ //Use default jump strength.
+ player->jump();
+ }
+
+ return 0;
+}
+
+int isPlayerShadow(lua_State* state){
+ //Make sure there's only one argument and that argument is an userdatum.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for isPlayerShadow, expected 1.");
+ lua_error(state);
+ }
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of isPlayerShadow.");
+ lua_error(state);
+ }
+
+ Player* player=getPlayerFromUserData(state,1);
+ if(player==NULL) return 0;
+
+ lua_pushboolean(state,player->isShadow());
+ return 1;
+}
+
+int getPlayerCurrentStand(lua_State* state){
+ //Get the number of args, this MUST be one.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for getPlayerCurrentStand, expected 1.");
+ lua_error(state);
+ }
+ //Make sure the given argument is a player userdatum.
+ if(!lua_isuserdata(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getPlayerCurrentStand.");
+ lua_error(state);
+ }
+
+ Player* player=getPlayerFromUserData(state,1);
+ if(player==NULL) return 0;
+
+ //Get the actual game object.
+ Block* object=player->getObjCurrentStand();
+ if(object==NULL){
+ return 0;
+ }
+
+ //Create the userdatum.
+ object->createUserData(state,"block");
+
+ //We return one object, the userdatum.
+ return 1;
+}
+
+//Array with the methods for the player and shadow library.
+static const struct luaL_Reg playerlib_m[]={
+ {"getLocation",getPlayerLocation},
+ {"setLocation",setPlayerLocation},
+ {"jump",setPlayerJump},
+ {"isShadow",isPlayerShadow},
+ {"getCurrentStand",getPlayerCurrentStand},
+ {NULL,NULL}
+};
+
+int luaopen_player(lua_State* state){
+ luaL_newlib(state,playerlib_m);
+
+ //Create the metatable for the player userdata.
+ luaL_newmetatable(state,"player");
+
+ lua_pushstring(state,"__index");
+ lua_pushvalue(state,-2);
+ lua_settable(state,-3);
+
+ //Now create two default player user data, one for the player and one for the shadow.
+ PlayerUserDatum* ud=(PlayerUserDatum*)lua_newuserdata(state,sizeof(PlayerUserDatum));
+ ud->sig1='P';ud->sig2='L';ud->sig3='Y';ud->sig4='R';
+ luaL_getmetatable(state,"player");
+ lua_setmetatable(state,-2);
+ lua_setglobal(state,"player");
+
+ ud=(PlayerUserDatum*)lua_newuserdata(state,sizeof(PlayerUserDatum));
+ ud->sig1='S';ud->sig2='H';ud->sig3='D';ud->sig4='W';
+ luaL_getmetatable(state,"player");
+ lua_setmetatable(state,-2);
+ lua_setglobal(state,"shadow");
+
+ //Register the functions and methods.
+ luaL_setfuncs(state,playerlib_m,0);
+ return 1;
+}
+
+//////////////////////////LEVEL SPECIFIC///////////////////////////
+
+int getLevelSize(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Returns level size.
+ lua_pushinteger(state,LEVEL_WIDTH);
+ lua_pushinteger(state,LEVEL_HEIGHT);
+ return 2;
+}
+
+int getLevelWidth(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Returns level size.
+ lua_pushinteger(state,LEVEL_WIDTH);
+ return 1;
+}
+
+int getLevelHeight(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Returns level size.
+ lua_pushinteger(state,LEVEL_HEIGHT);
+ return 1;
+}
+
+int getLevelName(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Check if the currentState is the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ //Returns level name.
+ lua_pushstring(state,game->getLevelName().c_str());
+ return 1;
+}
+
+int getLevelEventHandler(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for getLevelEventHandler, expected 1.");
+ lua_error(state);
+ }
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of getLevelEventHandler, should be string.");
+ lua_error(state);
+ }
+
+ //Check if the currentState is the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ //Check event type
+ string eventType=lua_tostring(state,1);
map<string,int>::iterator it=Game::levelEventNameMap.find(eventType);
if(it==Game::levelEventNameMap.end()) return 0;
//Check compiled script
map<int,int>::iterator script=game->compiledScripts.find(it->second);
if(script==game->compiledScripts.end()) return 0;
//Get event handler
lua_rawgeti(state,LUA_REGISTRYINDEX,script->second);
return 1;
-}
-
-//It will return old event handler.
-int setLevelEventHandler(lua_State* state){
- int args=lua_gettop(state);
- if(args!=2){
- lua_pushstring(state,"Incorrect number of arguments for setLevelEventHandler, expected 2.");
- lua_error(state);
- }
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setLevelEventHandler, should be string.");
- lua_error(state);
- }
- if(!lua_isfunction(state,2) && !lua_isnil(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of setLevelEventHandler, should be function.");
- lua_error(state);
- }
-
- //Check if the currentState is the game state.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return 0;
-
- //Check event type
- string eventType=lua_tostring(state,1);
+}
+
+//It will return old event handler.
+int setLevelEventHandler(lua_State* state){
+ int args=lua_gettop(state);
+ if(args!=2){
+ lua_pushstring(state,"Incorrect number of arguments for setLevelEventHandler, expected 2.");
+ lua_error(state);
+ }
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setLevelEventHandler, should be string.");
+ lua_error(state);
+ }
+ if(!lua_isfunction(state,2) && !lua_isnil(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of setLevelEventHandler, should be function.");
+ lua_error(state);
+ }
+
+ //Check if the currentState is the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ //Check event type
+ string eventType=lua_tostring(state,1);
map<string,int>::const_iterator it=Game::levelEventNameMap.find(eventType);
if(it==Game::levelEventNameMap.end()){
- lua_pushfstring(state,"Unknown level event type: '%s'.",eventType.c_str());
- lua_error(state);
+ lua_pushfstring(state,"Unknown level event type: '%s'.",eventType.c_str());
+ lua_error(state);
}
//Check compiled script
int scriptIndex=LUA_REFNIL;
{
map<int,int>::iterator script=game->compiledScripts.find(it->second);
if(script!=game->compiledScripts.end()) scriptIndex=script->second;
}
//Set new event handler
game->compiledScripts[it->second]=luaL_ref(state,LUA_REGISTRYINDEX);
//Get old event handler and unreference it
lua_rawgeti(state,LUA_REGISTRYINDEX,scriptIndex);
luaL_unref(state,LUA_REGISTRYINDEX,scriptIndex);
return 1;
-}
-
-//Array with the methods for the level library.
-static const struct luaL_Reg levellib_m[]={
- {"getSize",getLevelSize},
- {"getWidth",getLevelWidth},
- {"getHeight",getLevelHeight},
- {"getName",getLevelName},
- {"getEventHandler",getLevelEventHandler},
- {"setEventHandler",setLevelEventHandler},
- {NULL,NULL}
-};
-
-int luaopen_level(lua_State* state){
- luaL_newlib(state,levellib_m);
-
- //Register the functions and methods.
- luaL_setfuncs(state,levellib_m,0);
- return 1;
-}
-
-/////////////////////////CAMERA SPECIFIC///////////////////////////
-
-int setCameraMode(lua_State* state){
- //Get the number of args, this MUST be one.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for setCameraMode, expected 1.");
- lua_error(state);
- }
- //Make sure the given argument is a string.
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setCameraMode, should be string.");
- lua_error(state);
- }
-
- string mode=lua_tostring(state,1);
-
- //Get the game for setting the camera.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return 0;
- //Check which mode.
- if(mode=="player"){
- game->cameraMode=Game::CAMERA_PLAYER;
- }else if(mode=="shadow"){
- game->cameraMode=Game::CAMERA_SHADOW;
- }else{
- //Unkown OR invalid camera mode.
- lua_pushfstring(state,"Unkown or invalid camera mode for setCameraMode: '%s'.",mode.c_str());
- lua_error(state);
- }
-
- //Returns nothing.
- return 0;
-}
-
-int cameraLookAt(lua_State* state){
- //Get the number of args, this MUST be two (x and y).
- int args=lua_gettop(state);
- if(args!=2){
- lua_pushstring(state,"Incorrect number of arguments for cameraLookAt, expected 2.");
- lua_error(state);
- }
- //Make sure the given arguments are integers.
- if(!lua_isnumber(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of cameraLookAt, should be integer.");
- lua_error(state);
- }
- if(!lua_isnumber(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of cameraLookAt, should be integer.");
- lua_error(state);
- }
-
- //Get the point.
- int x=lua_tonumber(state,1);
- int y=lua_tonumber(state,2);
-
- //Get the game for setting the camera.
- Game* game=dynamic_cast<Game*>(currentState);
- if(game==NULL) return 0;
- game->cameraMode=Game::CAMERA_CUSTOM;
- game->cameraTarget.x=x;
- game->cameraTarget.y=y;
-
- return 0;
-}
-
-//Array with the methods for the camera library.
-static const struct luaL_Reg cameralib_m[]={
- {"setMode",setCameraMode},
- {"lookAt",cameraLookAt},
- {NULL,NULL}
-};
-
-int luaopen_camera(lua_State* state){
- luaL_newlib(state,cameralib_m);
-
- //Register the functions and methods.
- luaL_setfuncs(state,cameralib_m,0);
- return 1;
-}
-
-/////////////////////////AUDIO SPECIFIC///////////////////////////
-
-int playSound(lua_State* state){
- //Get the number of args, this can be anything from one to three.
- int args=lua_gettop(state);
- if(args<1 || args>3){
- lua_pushstring(state,"Incorrect number of arguments for playSound, expected 1-3.");
- lua_error(state);
- }
- //Make sure the first argument is a string.
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of playSound, should be string.");
- lua_error(state);
- }
-
- //Default values for concurrent and force.
- //See SoundManager.h
- int concurrent=1;
- bool force=false;
-
- //If there's a second one it should be an integer.
- if(args>1){
- if(!lua_isnumber(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of playSound, should be integer.");
- lua_error(state);
- }else{
- concurrent=lua_tonumber(state,2);
- }
- }
- //If there's a third one it should be a boolean.
- if(args>2){
- if(!lua_isboolean(state,3)){
- lua_pushstring(state,"Invalid type for argument 3 of playSound, should be boolean.");
- lua_error(state);
- }else{
- force=lua_toboolean(state,3);
- }
- }
-
- //Get the name of the sound.
- string sound=lua_tostring(state,1);
- //Try to play the sound.
- getSoundManager()->playSound(sound,concurrent,force);
-
- //Returns nothing.
- return 0;
-}
-
-int playMusic(lua_State* state){
- //Get the number of args, this can be either one or two.
- int args=lua_gettop(state);
- if(args<1 || args>2){
- lua_pushstring(state,"Incorrect number of arguments for playMusic, expected 1 or 2.");
- lua_error(state);
- }
- //Make sure the first argument is a string.
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of playMusic, should be string.");
- lua_error(state);
- }
-
- //Default value of fade for playMusic.
- //See MusicManager.h.
- bool fade=true;
-
- //If there's a second one it should be a boolean.
- if(args>1){
- if(!lua_isboolean(state,2)){
- lua_pushstring(state,"Invalid type for argument 2 of playMusic, should be boolean.");
- lua_error(state);
- }else{
- fade=lua_toboolean(state,2);
- }
- }
-
- //Get the name of the music.
- string music=lua_tostring(state,1);
- //Try to switch to the new music.
- getMusicManager()->playMusic(music,fade);
-
- //Returns nothing.
- return 0;
-}
-
-int pickMusic(lua_State* state){
- //NOTE: this function accepts 0 arguments, but we ignore the argument count.
-
- //Let the music manager pick a song from the current music list.
- getMusicManager()->pickMusic();
- return 0;
-}
-
-int setMusicList(lua_State* state){
- //Get the number of args, this MUST be one.
- int args=lua_gettop(state);
- if(args!=1){
- lua_pushstring(state,"Incorrect number of arguments for setMusicList, expected 1.");
- lua_error(state);
- }
- //Make sure the given argument is a string.
- if(!lua_isstring(state,1)){
- lua_pushstring(state,"Invalid type for argument 1 of setMusicList, should be string.");
- lua_error(state);
- }
-
- //And set the music list in the music manager.
- string list=lua_tostring(state,1);
- getMusicManager()->setMusicList(list);
- return 0;
-}
-
-int getMusicList(lua_State* state){
- //NOTE: this function accepts 0 arguments, but we ignore the argument count.
-
- //Return the name of the song (contains list prefix).
- lua_pushstring(state,getMusicManager()->getCurrentMusicList().c_str());
- return 1;
-}
-
-
-int currentMusicPlaying(lua_State* state){
- //NOTE: this function accepts 0 arguments, but we ignore the argument count.
-
- //Return the name of the song (contains list prefix).
- lua_pushstring(state,getMusicManager()->getCurrentMusic().c_str());
- return 1;
-}
-
-//Array with the methods for the audio library.
-static const struct luaL_Reg audiolib_m[]={
- {"playSound",playSound},
- {"playMusic",playMusic},
- {"pickMusic",pickMusic},
- {"setMusicList",setMusicList},
- {"getMusicList",getMusicList},
- {"currentMusic",currentMusicPlaying},
- {NULL,NULL}
-};
-
-int luaopen_audio(lua_State* state){
- luaL_newlib(state,audiolib_m);
-
- //Register the functions and methods.
- luaL_setfuncs(state,audiolib_m,0);
- return 1;
-}
+}
+
+//Array with the methods for the level library.
+static const struct luaL_Reg levellib_m[]={
+ {"getSize",getLevelSize},
+ {"getWidth",getLevelWidth},
+ {"getHeight",getLevelHeight},
+ {"getName",getLevelName},
+ {"getEventHandler",getLevelEventHandler},
+ {"setEventHandler",setLevelEventHandler},
+ {NULL,NULL}
+};
+
+int luaopen_level(lua_State* state){
+ luaL_newlib(state,levellib_m);
+
+ //Register the functions and methods.
+ luaL_setfuncs(state,levellib_m,0);
+ return 1;
+}
+
+//////////////////////////GAME SPECIFIC///////////////////////////
+
+int winGame(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Check if the currentState is the game state.
+ if(stateID==STATE_LEVEL_EDITOR)
+ return 0;
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ game->won=true;
+ return 0;
+}
+
+int getGameTime(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Check if the currentState is the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ //Returns level size.
+ lua_pushinteger(state,game->time);
+ return 1;
+}
+
+int getGameRecordings(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Check if the currentState is the game state.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+
+ //Returns level size.
+ lua_pushinteger(state,game->recordings);
+ return 1;
+}
+
+
+//Array with the methods for the game library.
+static const struct luaL_Reg gamelib_m[]={
+ {"win",winGame},
+ {"getTime",getGameTime},
+ {"getRecordings",getGameRecordings},
+ {NULL,NULL}
+};
+
+int luaopen_game(lua_State* state){
+ luaL_newlib(state,gamelib_m);
+
+ //Register the functions and methods.
+ luaL_setfuncs(state,gamelib_m,0);
+ return 1;
+}
+
+/////////////////////////CAMERA SPECIFIC///////////////////////////
+
+int setCameraMode(lua_State* state){
+ //Get the number of args, this MUST be one.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for setCameraMode, expected 1.");
+ lua_error(state);
+ }
+ //Make sure the given argument is a string.
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setCameraMode, should be string.");
+ lua_error(state);
+ }
+
+ string mode=lua_tostring(state,1);
+
+ //Get the game for setting the camera.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+ //Check which mode.
+ if(mode=="player"){
+ game->cameraMode=Game::CAMERA_PLAYER;
+ }else if(mode=="shadow"){
+ game->cameraMode=Game::CAMERA_SHADOW;
+ }else{
+ //Unkown OR invalid camera mode.
+ lua_pushfstring(state,"Unkown or invalid camera mode for setCameraMode: '%s'.",mode.c_str());
+ lua_error(state);
+ }
+
+ //Returns nothing.
+ return 0;
+}
+
+int cameraLookAt(lua_State* state){
+ //Get the number of args, this MUST be two (x and y).
+ int args=lua_gettop(state);
+ if(args!=2){
+ lua_pushstring(state,"Incorrect number of arguments for cameraLookAt, expected 2.");
+ lua_error(state);
+ }
+ //Make sure the given arguments are integers.
+ if(!lua_isnumber(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of cameraLookAt, should be integer.");
+ lua_error(state);
+ }
+ if(!lua_isnumber(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of cameraLookAt, should be integer.");
+ lua_error(state);
+ }
+
+ //Get the point.
+ int x=lua_tonumber(state,1);
+ int y=lua_tonumber(state,2);
+
+ //Get the game for setting the camera.
+ Game* game=dynamic_cast<Game*>(currentState);
+ if(game==NULL) return 0;
+ game->cameraMode=Game::CAMERA_CUSTOM;
+ game->cameraTarget.x=x;
+ game->cameraTarget.y=y;
+
+ return 0;
+}
+
+//Array with the methods for the camera library.
+static const struct luaL_Reg cameralib_m[]={
+ {"setMode",setCameraMode},
+ {"lookAt",cameraLookAt},
+ {NULL,NULL}
+};
+
+int luaopen_camera(lua_State* state){
+ luaL_newlib(state,cameralib_m);
+
+ //Register the functions and methods.
+ luaL_setfuncs(state,cameralib_m,0);
+ return 1;
+}
+
+/////////////////////////AUDIO SPECIFIC///////////////////////////
+
+int playSound(lua_State* state){
+ //Get the number of args, this can be anything from one to three.
+ int args=lua_gettop(state);
+ if(args<1 || args>3){
+ lua_pushstring(state,"Incorrect number of arguments for playSound, expected 1-3.");
+ lua_error(state);
+ }
+ //Make sure the first argument is a string.
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of playSound, should be string.");
+ lua_error(state);
+ }
+
+ //Default values for concurrent and force.
+ //See SoundManager.h
+ int concurrent=1;
+ bool force=false;
+
+ //If there's a second one it should be an integer.
+ if(args>1){
+ if(!lua_isnumber(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of playSound, should be integer.");
+ lua_error(state);
+ }else{
+ concurrent=lua_tonumber(state,2);
+ }
+ }
+ //If there's a third one it should be a boolean.
+ if(args>2){
+ if(!lua_isboolean(state,3)){
+ lua_pushstring(state,"Invalid type for argument 3 of playSound, should be boolean.");
+ lua_error(state);
+ }else{
+ force=lua_toboolean(state,3);
+ }
+ }
+
+ //Get the name of the sound.
+ string sound=lua_tostring(state,1);
+ //Try to play the sound.
+ getSoundManager()->playSound(sound,concurrent,force);
+
+ //Returns nothing.
+ return 0;
+}
+
+int playMusic(lua_State* state){
+ //Get the number of args, this can be either one or two.
+ int args=lua_gettop(state);
+ if(args<1 || args>2){
+ lua_pushstring(state,"Incorrect number of arguments for playMusic, expected 1 or 2.");
+ lua_error(state);
+ }
+ //Make sure the first argument is a string.
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of playMusic, should be string.");
+ lua_error(state);
+ }
+
+ //Default value of fade for playMusic.
+ //See MusicManager.h.
+ bool fade=true;
+
+ //If there's a second one it should be a boolean.
+ if(args>1){
+ if(!lua_isboolean(state,2)){
+ lua_pushstring(state,"Invalid type for argument 2 of playMusic, should be boolean.");
+ lua_error(state);
+ }else{
+ fade=lua_toboolean(state,2);
+ }
+ }
+
+ //Get the name of the music.
+ string music=lua_tostring(state,1);
+ //Try to switch to the new music.
+ getMusicManager()->playMusic(music,fade);
+
+ //Returns nothing.
+ return 0;
+}
+
+int pickMusic(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Let the music manager pick a song from the current music list.
+ getMusicManager()->pickMusic();
+ return 0;
+}
+
+int setMusicList(lua_State* state){
+ //Get the number of args, this MUST be one.
+ int args=lua_gettop(state);
+ if(args!=1){
+ lua_pushstring(state,"Incorrect number of arguments for setMusicList, expected 1.");
+ lua_error(state);
+ }
+ //Make sure the given argument is a string.
+ if(!lua_isstring(state,1)){
+ lua_pushstring(state,"Invalid type for argument 1 of setMusicList, should be string.");
+ lua_error(state);
+ }
+
+ //And set the music list in the music manager.
+ string list=lua_tostring(state,1);
+ getMusicManager()->setMusicList(list);
+ return 0;
+}
+
+int getMusicList(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Return the name of the song (contains list prefix).
+ lua_pushstring(state,getMusicManager()->getCurrentMusicList().c_str());
+ return 1;
+}
+
+
+int currentMusicPlaying(lua_State* state){
+ //NOTE: this function accepts 0 arguments, but we ignore the argument count.
+
+ //Return the name of the song (contains list prefix).
+ lua_pushstring(state,getMusicManager()->getCurrentMusic().c_str());
+ return 1;
+}
+
+//Array with the methods for the audio library.
+static const struct luaL_Reg audiolib_m[]={
+ {"playSound",playSound},
+ {"playMusic",playMusic},
+ {"pickMusic",pickMusic},
+ {"setMusicList",setMusicList},
+ {"getMusicList",getMusicList},
+ {"currentMusic",currentMusicPlaying},
+ {NULL,NULL}
+};
+
+int luaopen_audio(lua_State* state){
+ luaL_newlib(state,audiolib_m);
+
+ //Register the functions and methods.
+ luaL_setfuncs(state,audiolib_m,0);
+ return 1;
+}
diff --git a/src/ScriptAPI.h b/src/ScriptAPI.h
index 5847948..2aa2d1d 100644
--- a/src/ScriptAPI.h
+++ b/src/ScriptAPI.h
@@ -1,42 +1,44 @@
/*
* Copyright (C) 2012-2013 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow 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 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow 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 Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SCRIPTAPI_H
#define SCRIPTAPI_H
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
class ScriptExecutor;
//Method for loading the block library.
int luaopen_block(lua_State* state);
//Method for loading the player and shadow library.
int luaopen_player(lua_State* state);
//Method for loading the level library.
int luaopen_level(lua_State* state);
+//Method for loading the game library.
+int luaopen_game(lua_State* state);
//Method for loading the camera library.
int luaopen_camera(lua_State* state);
//Method for loading the audio library.
int luaopen_audio(lua_State* state);
#endif
\ No newline at end of file
diff --git a/src/ScriptExecutor.cpp b/src/ScriptExecutor.cpp
index 301dbac..4cb58c2 100644
--- a/src/ScriptExecutor.cpp
+++ b/src/ScriptExecutor.cpp
@@ -1,134 +1,135 @@
/*
* Copyright (C) 2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow 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 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow 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 Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptExecutor.h"
#include "ScriptAPI.h"
#include <iostream>
using namespace std;
ScriptExecutor::ScriptExecutor():state(NULL){
//NOTE: If a state is going to use the scriptExecutor it is his task to reset it.
}
ScriptExecutor::~ScriptExecutor(){
//Make sure there is a state to close.
if(state)
lua_close(state);
}
void ScriptExecutor::reset(){
//Close the lua_state, if any.
if(state)
lua_close(state);
//Create a new state.
state=luaL_newstate();
//Now load the lua libraries.
//FIXME: Only allow safe libraries/functions.
luaopen_base(state);
luaL_requiref(state,"table",luaopen_table,1);
luaL_requiref(state,"bit32",luaopen_bit32,1);
luaL_requiref(state,"string",luaopen_string,1);
luaL_requiref(state,"math",luaopen_math,1);
//Load our own libraries.
luaL_requiref(state,"block",luaopen_block,1);
luaL_requiref(state,"playershadow",luaopen_player,1);
luaL_requiref(state,"level",luaopen_level,1);
+ luaL_requiref(state,"game",luaopen_game,1);
luaL_requiref(state,"camera",luaopen_camera,1);
luaL_requiref(state,"audio",luaopen_audio,1);
}
void ScriptExecutor::registerFunction(std::string name,lua_CFunction function){
lua_register(state,name.c_str(),function);
}
int ScriptExecutor::compileScript(std::string script){
//First make sure the stack is empty.
lua_settop(state,0);
//Compile the script.
if(luaL_loadstring(state,script.c_str())!=LUA_OK){
cerr<<"LUA ERROR: "<<lua_tostring(state,-1)<<endl;
return LUA_REFNIL;
}
//Save it to LUA_REGISTRYINDEX and return values.
return luaL_ref(state,LUA_REGISTRYINDEX);
}
int ScriptExecutor::executeScript(std::string script,Block* origin){
//First make sure the stack is empty.
lua_settop(state,0);
//Compile the script.
if(luaL_loadstring(state,script.c_str())!=LUA_OK){
cerr<<"LUA ERROR: "<<lua_tostring(state,-1)<<endl;
return 0;
}
//Now execute the script.
return executeScriptInternal(origin);
}
int ScriptExecutor::executeScript(int scriptIndex,Block* origin){
//Check if reference is empty.
if(scriptIndex==LUA_REFNIL) return 0;
//Make sure the stack is empty.
lua_settop(state,0);
//Get the function
lua_rawgeti(state,LUA_REGISTRYINDEX,scriptIndex);
//Check if it's function and run.
if(lua_isfunction(state,-1)){
return executeScriptInternal(origin);
}else{
cerr<<"LUA ERROR: Not a function"<<endl;
return 0;
}
}
int ScriptExecutor::executeScriptInternal(Block* origin){
//If the origin isn't null set it in the global scope.
if(origin){
origin->createUserData(state,"block");
lua_setglobal(state,"this");
}
//Now execute the script on the top of Lua stack.
int ret=lua_pcall(state,0,1,0);
//If we set an origin set it back to nothing.
if(origin){
lua_pushnil(state);
lua_setglobal(state,"this");
}
//Check if there's an error.
if(ret!=LUA_OK){
cerr<<"LUA ERROR: "<<lua_tostring(state,-1)<<endl;
return 0;
}
//Get the return value.
return lua_tonumber(state,-1);
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 16, 8:22 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63543
Default Alt Text
(58 KB)
Attached To
Mode
R79 meandmyshadow
Attached
Detach File
Event Timeline