#include <fstream>
#include <stdexcept>
-#include "globals.h"
+#include "app/globals.h"
#include "sector.h"
-#include "lispreader.h"
+#include "utils/lispreader.h"
#include "badguy.h"
#include "special.h"
#include "gameobjs.h"
#include "particlesystem.h"
#include "tile.h"
#include "tilemap.h"
-#include "sound_manager.h"
+#include "audio/sound_manager.h"
#include "gameloop.h"
#include "resources.h"
#include "interactive_object.h"
#include "door.h"
+#include "statistics.h"
Sector* Sector::_current = 0;
Sector::Sector()
: gravity(10), player(0), solids(0), background(0), camera(0),
- currentmusic(LEVEL_MUSIC)
+ currentmusic(LEVEL_MUSIC), end_sequence_animation_type(NONE_ENDSEQ_ANIM)
{
song_title = "Mortimers_chipdisko.mod";
player = new Player();
} else if(token == "music") {
song_title = lisp_string(data);
load_music();
+ } else if(token == "end-sequence-animation") {
+ std::string end_seq_anim = lisp_string(data);
+ if(end_seq_anim == "fireworks")
+ end_sequence_animation_type = FIREWORKS_ENDSEQ_ANIM;
} else if(token == "camera") {
if(camera) {
std::cerr << "Warning: More than 1 camera defined in sector.\n";
} else if(token == "background") {
background = new Background(reader);
add_object(background);
- } else if(token == "playerspawn") {
+ } else if(token == "spawn-points") {
SpawnPoint* sp = new SpawnPoint;
reader.read_string("name", sp->name);
reader.read_float("x", sp->pos.x);
reader.read_string("background", backgroundimage);
float bgspeed = .5;
reader.read_float("bkgd_speed", bgspeed);
+ bgspeed /= 100;
Color bkgd_top, bkgd_bottom;
int r = 0, g = 0, b = 128;
add_object(background);
}
+ std::string end_seq_anim;
+ reader.read_string("end-sequence-animation", end_seq_anim);
+ if(end_seq_anim == "fireworks")
+ end_sequence_animation_type = FIREWORKS_ENDSEQ_ANIM;
+// else
+// end_sequence_animation = NONE_ENDSEQ_ANIM;
+
std::string particlesystem;
reader.read_string("particle_system", particlesystem);
if(particlesystem == "clouds")
add_object(tilemap);
}
- // TODO read resetpoints
+ // read reset-points (now spawn-points)
+ {
+ lisp_object_t* cur = 0;
+ if(reader.read_lisp("reset-points", cur)) {
+ while(!lisp_nil_p(cur)) {
+ lisp_object_t* data = lisp_car(cur);
+ LispReader reader(lisp_cdr(data));
+
+ Vector sp_pos;
+ if(reader.read_float("x", sp_pos.x) && reader.read_float("y", sp_pos.y))
+ {
+ SpawnPoint* sp = new SpawnPoint;
+ sp->name = "main";
+ sp->pos = sp_pos;
+ spawnpoints.push_back(sp);
+ }
+
+ cur = lisp_cdr(cur);
+ }
+ }
+ }
// read objects
{
for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
++i) {
SpawnPoint* spawn = *i;
- writer.start_list("playerspawn");
+ writer.start_list("spawn-points");
writer.write_string("name", spawn->name);
writer.write_float("x", spawn->pos.x);
writer.write_float("y", spawn->pos.y);
- writer.end_list("playerspawn");
+ writer.end_list("spawn-points");
}
// write objects
}
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)
{
gameobjects_new.push_back(object);
camera->reset(Vector(player->base.x, player->base.y));
}
+Vector
+Sector::get_best_spawn_point(Vector pos)
+{
+Vector best_reset_point = Vector(-1,-1);
+
+for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
+ ++i) {
+ if((*i)->name != "main")
+ continue;
+ if((*i)->pos.x > best_reset_point.x && (*i)->pos.x < pos.x)
+ best_reset_point = (*i)->pos;
+ }
+
+return best_reset_point;
+}
+
void
Sector::action(float elapsed_time)
{
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());
+ }
+ Particles* particle = dynamic_cast<Particles*> (*i);
+ if(particle) {
+ particles.erase(
+ std::remove(particles.begin(), particles.end(), particle),
+ particles.end());
+ }
+
delete *i;
i = gameobjects.erase(i);
} else {
= 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);
+ Particles* particle = dynamic_cast<Particles*> (*i);
+ if(particle)
+ particles.push_back(particle);
gameobjects.push_back(*i);
}
void
Sector::add_score(const Vector& pos, int s)
{
- player_status.score += s;
+ global_stats.add_points(SCORE_STAT, s);
add_object(new FloatingScore(pos, s));
}
else
throw std::runtime_error("wrong bullet type.");
add_object(new_bullet);
-
- sound_manager->play_sound(sounds[SND_SHOOT]);
+
+ SoundManager::get()->play_sound(IDToSound(SND_SHOOT));
return true;
}
+bool
+Sector::add_smoke_cloud(const Vector& pos)
+{
+ add_object(new SmokeCloud(pos));
+ return true;
+}
+
+bool
+Sector::add_particles(const Vector& epicenter, const Vector& velocity, const Vector& acceleration, int number, Color color, int size, int life_time)
+{
+ add_object(new Particles(epicenter, velocity, acceleration, number, color, size, life_time));
+ return true;
+}
+
/* Break a brick: */
bool
Sector::trybreakbrick(const Vector& pos, bool small)
counting_distros = false;
solids->change_at(pos, tile->next_tile);
}
-
- sound_manager->play_sound(sounds[SND_DISTRO]);
- player_status.score = player_status.score + SCORE_DISTRO;
+
+ SoundManager::get()->play_sound(IDToSound(SND_DISTRO));
+ global_stats.add_points(SCORE_STAT, SCORE_DISTRO);
+ global_stats.add_points(COINS_COLLECTED_STAT, 1);
player_status.distros++;
return true;
}
(int)(pos.y / 32) * 32), tile);
/* Get some score: */
- sound_manager->play_sound(sounds[SND_BRICK]);
- player_status.score = player_status.score + SCORE_BRICK;
+ SoundManager::get()->play_sound(IDToSound(SND_BRICK));
+ global_stats.add_points(SCORE_STAT, SCORE_BRICK);
return true;
}
{
case 1: // Box with a distro!
add_bouncy_distro(Vector(posx, posy));
- sound_manager->play_sound(sounds[SND_DISTRO]);
- player_status.score = player_status.score + SCORE_DISTRO;
+ SoundManager::get()->play_sound(IDToSound(SND_DISTRO));
+ global_stats.add_points(SCORE_STAT, SCORE_DISTRO);
+ global_stats.add_points(COINS_COLLECTED_STAT, 1);
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);
- sound_manager->play_sound(sounds[SND_UPGRADE]);
+ 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);
- sound_manager->play_sound(sounds[SND_UPGRADE]);
+ SoundManager::get()->play_sound(IDToSound(SND_UPGRADE));
break;
case 3: // Add a golden herring
- add_upgrade(Vector(posx, posy), col_side, UPGRADE_HERRING);
+ add_upgrade(Vector(posx, posy), col_side, UPGRADE_STAR);
break;
case 4: // Add a 1up extra
return;
solids->change_at(pos, tile->next_tile);
- sound_manager->play_sound(sounds[SND_DISTRO]);
-
+ SoundManager::get()->play_sound(IDToSound(SND_DISTRO));
+
if (bounciness == BOUNCE)
{
add_bouncy_distro(Vector(((int)(pos.x + 1) / 32) * 32,
(int)(pos.y / 32) * 32));
}
- player_status.score = player_status.score + SCORE_DISTRO;
+ global_stats.add_points(SCORE_STAT, SCORE_DISTRO);
+ global_stats.add_points(COINS_COLLECTED_STAT, 1);
player_status.distros++;
}
char* song_path;
char* song_subtitle;
- level_song = sound_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(!sound_manager->exists_music(song_path)) {
+ if(!SoundManager::get()->exists_music(song_path)) {
level_song_fast = level_song;
} else {
- level_song_fast = sound_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:
- sound_manager->play_music(level_song_fast);
+ SoundManager::get()->play_music(level_song_fast);
break;
case LEVEL_MUSIC:
- sound_manager->play_music(level_song);
+ SoundManager::get()->play_music(level_song);
break;
case HERRING_MUSIC:
- sound_manager->play_music(herring_song);
+ SoundManager::get()->play_music(herring_song);
break;
default:
- sound_manager->halt_music();
+ SoundManager::get()->halt_music();
break;
}
}
{
return currentmusic;
}
+
+int
+Sector::get_total_badguys()
+{
+ int total_badguys = 0;
+ for(GameObjects::iterator i = gameobjects_new.begin(); i != gameobjects_new.end(); ++i)
+ {
+ BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
+ if(badguy)
+ total_badguys++;
+ }
+ return total_badguys;
+}