Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
37 KB
Referenced Files
None
Subscribers
None
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

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)

Event Timeline