// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "sector.h"
#include <memory>
+#include <algorithm>
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <stdexcept>
-#include "lispreader.h"
+#include "app/globals.h"
+#include "sector.h"
+#include "utils/lispreader.h"
#include "badguy.h"
#include "special.h"
#include "gameobjs.h"
#include "particlesystem.h"
#include "tile.h"
#include "tilemap.h"
-#include "music_manager.h"
+#include "audio/sound_manager.h"
#include "gameloop.h"
#include "resources.h"
#include "interactive_object.h"
for(lisp_object_t* cur = lispreader.get_lisp(); !lisp_nil_p(cur);
cur = lisp_cdr(cur)) {
std::string token = lisp_symbol(lisp_car(lisp_car(cur)));
+ // FIXME: doesn't handle empty data
lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur)));
LispReader reader(lisp_cdr(lisp_car(cur)));
if(token == "name") {
name = lisp_string(data);
} else if(token == "gravity") {
- gravity = lisp_integer(data);
+ gravity = lisp_real(data);
} else if(token == "music") {
song_title = lisp_string(data);
load_music();
{
writer.write_string("name", name);
writer.write_float("gravity", gravity);
+ writer.write_string("music", song_title);
+
+ // write spawnpoints
+ for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
+ ++i) {
+ SpawnPoint* spawn = *i;
+ writer.start_list("playerspawn");
+ writer.write_string("name", spawn->name);
+ writer.write_float("x", spawn->pos.x);
+ writer.write_float("y", spawn->pos.y);
+ writer.end_list("playerspawn");
+ }
+ // write objects
for(GameObjects::iterator i = gameobjects.begin();
i != gameobjects.end(); ++i) {
Serializable* serializable = dynamic_cast<Serializable*> (*i);
}
void
+Sector::do_vertical_flip()
+{
+ for(GameObjects::iterator i = gameobjects_new.begin(); i != gameobjects_new.end(); ++i)
+ {
+ TileMap* tilemap = dynamic_cast<TileMap*> (*i);
+ if(tilemap)
+ {
+ tilemap->do_vertical_flip();
+ }
+
+ BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
+ if(badguy)
+ badguy->start_position.y = solids->get_height()*32 - badguy->start_position.y - 32;
+ Trampoline* trampoline = dynamic_cast<Trampoline*> (*i);
+ if(trampoline)
+ trampoline->base.y = solids->get_height()*32 - trampoline->base.y - 32;
+ FlyingPlatform* flying_platform = dynamic_cast<FlyingPlatform*> (*i);
+ if(flying_platform)
+ flying_platform->base.y = solids->get_height()*32 - flying_platform->base.y - 32;
+ Door* door = dynamic_cast<Door*> (*i);
+ if(door)
+ door->set_area(door->get_area().x, solids->get_height()*32 - door->get_area().y - 32);
+ }
+
+ for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
+ ++i) {
+ SpawnPoint* spawn = *i;
+ spawn->pos.y = solids->get_height()*32 - spawn->pos.y - 32;
+ }
+}
+
+void
Sector::add_object(GameObject* object)
{
- // XXX a bit hackish, at least try to keep the number of these things down...
- BadGuy* badguy = dynamic_cast<BadGuy*> (object);
- if(badguy)
- badguys.push_back(badguy);
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet)
- bullets.push_back(bullet);
- Upgrade* upgrade = dynamic_cast<Upgrade*> (object);
- if(upgrade)
- upgrades.push_back(upgrade);
- Trampoline* trampoline = dynamic_cast<Trampoline*> (object);
- if(trampoline)
- trampolines.push_back(trampoline);
- FlyingPlatform* flying_platform = dynamic_cast<FlyingPlatform*> (object);
- if(flying_platform)
- flying_platforms.push_back(flying_platform);
- InteractiveObject* interactive_object
- = dynamic_cast<InteractiveObject*> (object);
- if(interactive_object)
- interactive_objects.push_back(interactive_object);
-
- gameobjects.push_back(object);
+ gameobjects_new.push_back(object);
}
void
/* Handle all possible collisions. */
collision_handler();
+ update_game_objects();
+}
+
+void
+Sector::update_game_objects()
+{
/** cleanup marked objects */
for(std::vector<GameObject*>::iterator i = gameobjects.begin();
i != gameobjects.end(); /* nothing */) {
std::remove(flying_platforms.begin(), flying_platforms.end(), flying_platform),
flying_platforms.end());
}
+ SmokeCloud* smoke_cloud = dynamic_cast<SmokeCloud*> (*i);
+ if(smoke_cloud) {
+ smoke_clouds.erase(
+ std::remove(smoke_clouds.begin(), smoke_clouds.end(), smoke_cloud),
+ smoke_clouds.end());
+ }
delete *i;
i = gameobjects.erase(i);
++i;
}
}
+
+ /* add newly created objects */
+ for(std::vector<GameObject*>::iterator i = gameobjects_new.begin();
+ i != gameobjects_new.end(); ++i)
+ {
+ BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
+ if(badguy)
+ badguys.push_back(badguy);
+ Bullet* bullet = dynamic_cast<Bullet*> (*i);
+ if(bullet)
+ bullets.push_back(bullet);
+ Upgrade* upgrade = dynamic_cast<Upgrade*> (*i);
+ if(upgrade)
+ upgrades.push_back(upgrade);
+ Trampoline* trampoline = dynamic_cast<Trampoline*> (*i);
+ if(trampoline)
+ trampolines.push_back(trampoline);
+ FlyingPlatform* flying_platform = dynamic_cast<FlyingPlatform*> (*i);
+ if(flying_platform)
+ flying_platforms.push_back(flying_platform);
+ InteractiveObject* interactive_object
+ = dynamic_cast<InteractiveObject*> (*i);
+ if(interactive_object)
+ interactive_objects.push_back(interactive_object);
+ SmokeCloud* smoke_cloud = dynamic_cast<SmokeCloud*> (*i);
+ if(smoke_cloud)
+ smoke_clouds.push_back(smoke_cloud);
+
+
+ gameobjects.push_back(*i);
+ }
+ gameobjects_new.clear();
}
void
throw std::runtime_error("wrong bullet type.");
add_object(new_bullet);
- play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
+ SoundManager::get()->play_sound(IDToSound(SND_SHOOT));
return true;
}
+bool
+Sector::add_smoke_cloud(const Vector& pos)
+{
+ add_object(new SmokeCloud(pos));
+ return true;
+}
+
/* Break a brick: */
bool
Sector::trybreakbrick(const Vector& pos, bool small)
{
Tile* tile = solids->get_tile_at(pos);
+ if (!tile)
+ {
+ char errmsg[64];
+ sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32));
+ throw SuperTuxException(errmsg, __FILE__, __LINE__);
+ }
+
if (tile->attributes & Tile::BRICK)
{
if (tile->data > 0)
solids->change_at(pos, tile->next_tile);
}
- play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+ SoundManager::get()->play_sound(IDToSound(SND_DISTRO));
player_status.score = player_status.score + SCORE_DISTRO;
player_status.distros++;
return true;
(int)(pos.y / 32) * 32), tile);
/* Get some score: */
- play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
+ SoundManager::get()->play_sound(IDToSound(SND_BRICK));
player_status.score = player_status.score + SCORE_BRICK;
return true;
Sector::tryemptybox(const Vector& pos, Direction col_side)
{
Tile* tile = solids->get_tile_at(pos);
+ if (!tile)
+ {
+ char errmsg[64];
+ sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32));
+ throw SuperTuxException(errmsg, __FILE__, __LINE__);
+ }
+
+
if (!(tile->attributes & Tile::FULLBOX))
return;
{
case 1: // Box with a distro!
add_bouncy_distro(Vector(posx, posy));
- play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+ SoundManager::get()->play_sound(IDToSound(SND_DISTRO));
player_status.score = player_status.score + SCORE_DISTRO;
player_status.distros++;
break;
add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP);
else /* Tux is big, add a fireflower: */
add_upgrade(Vector(posx, posy), col_side, UPGRADE_FIREFLOWER);
- play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
+ SoundManager::get()->play_sound(IDToSound(SND_UPGRADE));
break;
case 5: // Add an ice flower upgrade!
add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP);
else /* Tux is big, add an iceflower: */
add_upgrade(Vector(posx, posy), col_side, UPGRADE_ICEFLOWER);
- play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
+ SoundManager::get()->play_sound(IDToSound(SND_UPGRADE));
break;
case 3: // Add a golden herring
Sector::trygrabdistro(const Vector& pos, int bounciness)
{
Tile* tile = solids->get_tile_at(pos);
+ if (!tile)
+ {
+ /*char errmsg[64];
+ sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32));
+ throw SuperTuxException(errmsg, __FILE__, __LINE__); */
+
+ //Bad tiles (i.e. tiles that are not defined in supertux.stgt but appear in the map) are changed to ID 0 (blank tile)
+ std::cout << "Warning: Undefined tile at " <<(int)pos.x/32 << "/" << (int)pos.y/32 << " (ID: " << (int)solids->get_tile_id_at(pos).id << ")" << std::endl;
+ solids->change_at(pos,0);
+ tile = solids->get_tile_at(pos);
+ }
+
+
if (!(tile->attributes & Tile::COIN))
return;
solids->change_at(pos, tile->next_tile);
- play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+ SoundManager::get()->play_sound(IDToSound(SND_DISTRO));
if (bounciness == BOUNCE)
{
player_status.score = player_status.score + SCORE_DISTRO;
player_status.distros++;
+
}
/* Try to bump a bad guy from below: */
char* song_path;
char* song_subtitle;
- level_song = music_manager->load_music(datadir + "/music/" + song_title);
+ level_song = SoundManager::get()->load_music(datadir + "/music/" + song_title);
song_path = (char *) malloc(sizeof(char) * datadir.length() +
strlen(song_title.c_str()) + 8 + 5);
strcpy(strstr(song_subtitle, "."), "\0");
sprintf(song_path, "%s/music/%s-fast%s", datadir.c_str(),
song_subtitle, strstr(song_title.c_str(), "."));
- if(!music_manager->exists_music(song_path)) {
+ if(!SoundManager::get()->exists_music(song_path)) {
level_song_fast = level_song;
} else {
- level_song_fast = music_manager->load_music(song_path);
+ level_song_fast = SoundManager::get()->load_music(song_path);
}
free(song_subtitle);
free(song_path);
currentmusic = type;
switch(currentmusic) {
case HURRYUP_MUSIC:
- music_manager->play_music(level_song_fast);
+ SoundManager::get()->play_music(level_song_fast);
break;
case LEVEL_MUSIC:
- music_manager->play_music(level_song);
+ SoundManager::get()->play_music(level_song);
break;
case HERRING_MUSIC:
- music_manager->play_music(herring_song);
+ SoundManager::get()->play_music(herring_song);
break;
default:
- music_manager->halt_music();
+ SoundManager::get()->halt_music();
break;
}
}