Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F118968
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
37 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/MusicManager.cpp b/src/MusicManager.cpp
index 1d768f2..599d1d4 100644
--- a/src/MusicManager.cpp
+++ b/src/MusicManager.cpp
@@ -1,384 +1,392 @@
/*
* 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 "MusicManager.h"
#include "TreeStorageNode.h"
#include "POASerializer.h"
#include "FileManager.h"
#include "Functions.h"
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;
MusicManager::MusicManager(){
Mix_HookMusicFinished(musicStoppedHook);
Mix_VolumeMusic(MIX_MAX_VOLUME);
enabled=false;
currentList="default";
lastTime=0;
playing=NULL;
}
MusicManager::~MusicManager(){
//We call destroy().
destroy();
}
void MusicManager::destroy(){
//Loop through the imageCollection and free them.
std::map<std::string,Music*>::iterator i;
for(i=musicCollection.begin();i!=musicCollection.end();++i){
if(i->second!=NULL){
Mix_FreeMusic(i->second->music);
if(i->second->loop)
Mix_FreeMusic(i->second->loop);
delete i->second;
}
}
playing=NULL;
//And clear the collection and the lists.
musicCollection.clear();
musicLists.clear();
}
void MusicManager::setEnabled(bool enable){
//Set the new status.
if(enabled!=enable)
enabled=enable;
else
return;
if(enable){
//It got turned on, so start the menu music.
playMusic("menu",false);
}else{
//Stop the current music.
Mix_HaltMusic();
Mix_VolumeMusic(atoi(getSettings()->getValue("music").c_str()));
}
}
void MusicManager::setVolume(int volume){
Mix_VolumeMusic(volume);
}
string MusicManager::loadMusic(const std::string &file,const std::string &list){
//Open the .music file.
ifstream musicFile;
musicFile.open(file.c_str());
string returnString="";
string listPrefix=list;
//Add the trailing slash to the list.
//NOTE: It's added here to prevent a slash in the global list.
if(!listPrefix.empty())
listPrefix+="/";
//The path from where the actual audio files should be read.
string musicPath=pathFromFileName(file);
//Check if the file exists.
if(musicFile){
//Now parse the file.
TreeStorageNode obj;
{
POASerializer objSerializer;
if(!objSerializer.readNode(musicFile,&obj,true)){
cerr<<"ERROR: Invalid file format of music description file."<<endl;
}
}
//Loop through the entries.
for(unsigned int i=0;i<obj.subNodes.size();i++){
TreeStorageNode* obj1=obj.subNodes[i];
if(obj1==NULL)
continue;
if(!obj1->value.empty() && obj1->name=="music"){
//Make sure that this music isn't already loaded.
map<string,Music*>::iterator it=musicCollection.find(listPrefix+obj1->value[0]);
if(it==musicCollection.end()){
//We've found an entry for a music file.
Music* music=new Music;
music->music=NULL;
music->loop=NULL;
//Load some data.
for(map<string,vector<string> >::iterator i=obj1->attributes.begin();i!=obj1->attributes.end();++i){
if(i->first=="file"){
//Load the music file.
music->music=Mix_LoadMUS((musicPath+i->second[0]).c_str());
}
if(i->first=="loopfile"){
//Load the loop file.
music->loop=Mix_LoadMUS((musicPath+i->second[0]).c_str());
}
if(i->first=="trackname"){
music->trackName=i->second[0];
}
if(i->first=="author"){
music->author=i->second[0];
}
if(i->first=="license"){
music->license=i->second[0];
}
if(i->first=="start"){
music->start=(atoi(i->second[0].c_str()));
}
if(i->first=="volume"){
music->volume=(atoi(i->second[0].c_str()));
}
if(i->first=="loopstart"){
music->loopStart=(atoi(i->second[0].c_str()));
}
if(i->first=="loopend"){
music->loopEnd=(atoi(i->second[0].c_str()));
}
}
//Set the default value for lastTime.
music->lastTime=-1;
- music->name=obj1->value[0];
+ music->name=listPrefix+obj1->value[0];
//Now add it to the collection.
musicCollection[listPrefix+obj1->value[0]]=music;
}
//Add the name of the music to the return string even if it's already loaded.
//This is to allow music to be in multiple music lists.
if(!returnString.empty())
returnString+=',';
returnString+=obj1->value[0];
}
}
}
//Return the return string.
return returnString;
}
bool MusicManager::loadMusicList(const std::string &file){
//Open the .list file.
ifstream musicFile;
musicFile.open(file.c_str());
//Check if the file exists.
if(musicFile){
//Now parse the file.
TreeStorageNode obj;
{
POASerializer objSerializer;
if(!objSerializer.readNode(musicFile,&obj,true)){
cerr<<"ERROR: Invalid file format of music list file."<<endl;
return false;
}
}
//Get the name of the list.
std::string name;
{
map<string,vector<string> >::iterator it=obj.attributes.find("name");
if(it!=obj.attributes.end()){
name=obj.attributes["name"][0];
}else{
cerr<<"ERROR: No name for music list "<<file<<endl;
return false;
}
}
//Check if the list isn't already loaded.
std::map<std::string,std::vector<std::string> >::iterator it=musicLists.find(name);
if(it!=musicLists.end())
return true;
//The path where the .music files should be.
string musicPath=pathFromFileName(file);
//Loop through the entries.
for(unsigned int i=0;i<obj.subNodes.size();i++){
TreeStorageNode* obj1=obj.subNodes[i];
if(obj1==NULL)
continue;
if(!obj1->value.empty() && obj1->name=="musicfile"){
//Load the music file.
string result=loadMusic(musicPath+obj1->value[0],name);
if(!result.empty()){
if(result.find(',')!=string::npos){
size_t pos=result.find(',');
while(pos!=string::npos){
musicLists[name].push_back(result.substr(pos,result.find(',',pos+1)));
}
}else{
musicLists[name].push_back(result);
}
}
}
}
}else{
cerr<<"ERROR: Unable to open music list file "<<file<<endl;
return false;
}
//Nothing went wrong so return true.
return true;
}
void MusicManager::playMusic(const std::string &name,bool fade){
//Make sure music is enabled.
if(!enabled)
return;
//Check if the music is in the collection.
Music* music=musicCollection[name];
if(music==NULL){
cerr<<"ERROR: Unable to play music "<<name<<endl;
return;
}
//Now check if we should fade the previous one out.
if(fade){
Mix_FadeOutMusic(375);
//Set the next music.
nextMusic=name;
}else{
if(music->loopStart<=0 && music->loop==NULL){
Mix_FadeInMusicPos(music->music,-1,0,music->start);
}else{
Mix_FadeInMusicPos(music->music,0,0,music->start);
}
Mix_VolumeMusic(music->volume*float(atoi(getSettings()->getValue("music").c_str())/float(MIX_MAX_VOLUME)));
//Set the playing pointer.
playing=music;
}
}
+string MusicManager::getCurrentMusic(){
+ return playing->name;
+}
+
void MusicManager::pickMusic(){
//Make sure the currentList exists.
vector<std::string> list=musicLists[currentList];
if(list.empty()){
cerr<<"ERROR: Unknown music list "<<currentList<<endl;
return;
}
//Shuffle the list.
random_shuffle(list.begin(),list.end());
//Now loop through the music and search the oldest.
Music* oldest=NULL;
for(unsigned int i=0;i<list.size();i++){
//As key we use "list/name" to prevent collision.
string listEntry=currentList+"/"+list[i];
//Check if oldest is set.
if(oldest==NULL){
//It isn't so pick the first music.
oldest=musicCollection[listEntry];
continue;
}
//Check if this song is null.
if(musicCollection[listEntry]==NULL)
continue;
//Check if this music is never played.
if(musicCollection[listEntry]->lastTime==-1){
oldest=musicCollection[listEntry];
//And break out.
break;
}
//Check if this music is older.
if(musicCollection[listEntry]->lastTime<oldest->lastTime){
oldest=musicCollection[listEntry];
}
}
//Check if oldest ins't null.
if(oldest!=NULL){
- playMusic(currentList+"/"+oldest->name);
+ playMusic(oldest->name);
//Set the lastTime and increase it.
oldest->lastTime=lastTime;
lastTime++;
}
}
void MusicManager::musicStopped(){
//Check if there's a music to play.
if(!nextMusic.empty()){
//Check if the music is in the collection.
Music* music=musicCollection[nextMusic];
if(music==NULL){
cerr<<"ERROR: Unable to play music "<<nextMusic<<endl;
return;
}
if(music->loopStart<=0){
Mix_FadeInMusicPos(music->music,-1,375,music->start);
}else{
Mix_FadeInMusicPos(music->music,0,375,music->start);
}
Mix_VolumeMusic(music->volume*float(atoi(getSettings()->getValue("music").c_str())/float(MIX_MAX_VOLUME)));
//Set playing.
playing=music;
//Now reset nextMusic.
nextMusic.clear();
}else{
//Check what kind of loop.
if(playing->loop!=NULL){
Mix_FadeInMusicPos(playing->loop,-1,0,playing->loopStart);
}else{
//This is for looping the end of music.
Mix_FadeInMusicPos(playing->music,0,0,playing->loopStart);
}
}
}
void MusicManager::setMusicList(const string &listName){
//Check if the list exists.
vector<std::string> list=musicLists[listName];
if(list.empty()){
cerr<<"ERROR: Unknown music list "<<listName<<endl;
return;
}
//The list exist and contains music so set it as current.
currentList=listName;
}
+std::string MusicManager::getCurrentMusicList(){
+ return currentList;
+}
+
vector<string> MusicManager::createCredits(){
//Vector that will be returned.
vector<string> result;
//Loop through the music tracks.
std::map<std::string,Music*>::iterator it;
for(it=musicCollection.begin();it!=musicCollection.end();++it){
result.push_back(" - "+it->second->trackName);
result.push_back(" License: "+it->second->license);
result.push_back(" Attribution: "+it->second->author);
}
//And return the result.
return result;
}
diff --git a/src/MusicManager.h b/src/MusicManager.h
index 38466aa..652b97b 100644
--- a/src/MusicManager.h
+++ b/src/MusicManager.h
@@ -1,146 +1,155 @@
/*
* 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/>.
*/
#ifndef MUSICMANAGER_H
#define MUSICMANAGER_H
#include <SDL/SDL.h>
#ifdef __APPLE__
#include <SDL_mixer/SDL_mixer.h>
#else
#include <SDL/SDL_mixer.h>
#endif
#include <string>
#include <map>
#include <vector>
//Class for loading and playing the music.
class MusicManager{
private:
//This structure is used to hold music information.
struct Music{
//Pointer to the actual music.
Mix_Music* music;
//Pointer to the loop music, if any.
Mix_Music* loop;
//String containing the name of the music.
//This is the same name as in the musicCollection.
std::string name;
//String containing the track name of the music.
//This is the name given by the author.
std::string trackName;
//String containing the name of the author.
std::string author;
//String containing the license the music is released under.
std::string license;
//Integer containing the time where to start playing.
int start;
//The volume to play the music with.
//Scale 0-128.
int volume;
//Integer containing the loopstart.
int loopStart;
//Integer containing the loopend.
//NOTE: loopend doesn't work and is thus ignored.
int loopEnd;
//Integer used to keep track when which music was played.
int lastTime;
};
public:
//Constructor.
MusicManager();
//Destructor.
~MusicManager();
//Destroys the music.
void destroy();
//Method that will either disable or enable music.
//enable: Boolean if the musicManager should be enabled or not.
void setEnabled(bool enable=true);
//Method that will set the volume of the music.
//NOTE: The set volume isn't presistent, only use this to update the volume after a change to the music setting.
//volume: The new volume.
void setVolume(int volume);
//This method will load one music file and add it to the collection.
//file: The filename of the music file.
//list: The music list the music belongs to.
//Returns: String containing the loaded music comma sperated, it's empty if it fails.
std::string loadMusic(const std::string &file,const std::string &list="");
//This method will load from a music list.
//file: The filename of the music list file.
//Returns: True if no error occurs.
bool loadMusicList(const std::string &file);
//This method will start playing a music file.
//name: The name of the song.
//fade: Boolean if it should fade the current one out or not.
void playMusic(const std::string &name,bool fade=true);
+
+ //Method for retrieving the current playing track.
+ //Returns: the name of the music that is playing.
+ std::string getCurrentMusic();
//This method will pick music from the current music list.
void pickMusic();
//Method that will be called when a music stopped.
void musicStopped();
//Set the music list.
//list: The name of the list.
void setMusicList(const std::string &list);
+ //Method for retrieving the current music list.
+ //NOTE This returns the set music list, this doesn't mean the playing music IS from this list.
+ //Returns: the name of the current music list.
+ std::string getCurrentMusicList();
+
//Method that will create credits text for the (loaded) music tracks.
//NOTE: This is only used by the Credits screen.
//Returns: A vector containing the lines of credits.
std::vector<std::string> createCredits();
private:
//Boolean if the MusicManager is enabled or not.
//The default value is false meaning that the MusicManager has to be enabled before the music starts.
bool enabled;
//Integer that is used to keep track of the last played song.
int lastTime;
//Pointer to the music struct that is currently playing.
Music* playing;
//String containing the name of the music to play when the previous one stopped.
//This means that it will be checked in the musicStopped method.
std::string nextMusic;
//String containing the name of the current music list.
std::string currentList;
//Map containing the music.
//The key is the name of the music and the value is a pointer to the Mix_Music.
std::map<std::string,Music*> musicCollection;
//Map containing the music lists.
//The key is the name of the list and the value is an array of music names.
std::map<std::string,std::vector<std::string> > musicLists;
};
#endif
diff --git a/src/ScriptAPI.cpp b/src/ScriptAPI.cpp
index 5ae5d86..0dd0599 100644
--- a/src/ScriptAPI.cpp
+++ b/src/ScriptAPI.cpp
@@ -1,683 +1,768 @@
/*
* 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 "Objects.h"
#include "Game.h"
#include <iostream>
using namespace std;
int test(lua_State* state){
cout<<"Hello world"<<endl;
return 0;
}
//Register the libraries.
void registerFunctions(ScriptExecutor* executor){
//
}
///////////////////////////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.");
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.");
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.");
lua_error(state);
}
if(!lua_isnumber(state,3)){
lua_pushstring(state,"Invalid type for argument 3 of setBlockLocation.");
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.");
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.");
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 setBlockEnabled.");
lua_error(state);
}
Block* object = Block::getObjectFromUserData(state,1);
if(object==NULL)
return 0;
lua_pushboolean(state,object->enabled);
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},
{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.");
lua_error(state);
}
if(!lua_isnumber(state,3)){
lua_pushstring(state,"Invalid type for argument 3 of setPlayerLocation.");
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.");
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;
}
//Array with the methods for the level library.
static const struct luaL_Reg levellib_m[]={
{"getSize",getLevelSize},
{"getWidth",getLevelWidth},
{"getHeight",getLevelHeight},
{"getName",getLevelName},
{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.");
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_pushstring(state,"Unkown or invalid camera mode for setCameraMode.");
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.");
lua_error(state);
}
if(!lua_isnumber(state,2)){
lua_pushstring(state,"Invalid type for argument 2 of cameraLookAt.");
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.");
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.");
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.");
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.");
+ 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.");
+ 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.");
+ 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;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 16, 8:26 PM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63826
Default Alt Text
(37 KB)
Attached To
Mode
R79 meandmyshadow
Attached
Detach File
Event Timeline