Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of https://github.com/clintbellanger/flare-engine

Conflicts:
	.mailmap
  • Loading branch information...
commit 19f18d545a38647e9cf7437cf15d4807cd7af460 2 parents 3964157 + aec597e
@clintbellanger authored
Showing with 1,349 additions and 1,374 deletions.
  1. +3 −0  .mailmap
  2. +1 −0  CMakeLists.txt
  3. +4 −0 astyle_flare.sh
  4. +11 −0 mods/default/cutscenes/intro.txt
  5. +3 −0  mods/default/engine/font_settings.txt
  6. +3 −5 src/Animation.cpp
  7. +1 −3 src/AnimationSet.cpp
  8. +5 −4 src/Avatar.cpp
  9. +1 −1  src/BehaviorStandard.cpp
  10. +1 −1  src/CombatText.cpp
  11. +1 −1  src/Enemy.cpp
  12. +1 −1  src/EnemyGroupManager.cpp
  13. +24 −24 src/EnemyManager.cpp
  14. +0 −34 src/Entity.cpp
  15. +0 −1  src/Entity.h
  16. +12 −3 src/FileParser.cpp
  17. +12 −1 src/FileParser.h
  18. +2 −2 src/FontEngine.cpp
  19. +18 −52 src/GameStateConfig.cpp
  20. +1 −2  src/GameStateConfig.h
  21. +232 −0 src/GameStateCutscene.cpp
  22. +87 −0 src/GameStateCutscene.h
  23. +16 −57 src/GameStateLoad.cpp
  24. +3 −18 src/GameStateNew.cpp
  25. +39 −12 src/GameStatePlay.cpp
  26. +3 −0  src/GameStatePlay.h
  27. +1 −14 src/GameStateTitle.cpp
  28. +1 −2  src/GameStateTitle.h
  29. +13 −3 src/GameSwitcher.cpp
  30. +6 −4 src/GetText.cpp
  31. +7 −24 src/ImageManager.cpp
  32. +5 −8 src/InputState.cpp
  33. +8 −23 src/ItemManager.cpp
  34. +0 −2  src/ItemManager.h
  35. +2 −2 src/LootManager.cpp
  36. +459 −458 src/MapRenderer.cpp
  37. +35 −23 src/MapRenderer.h
  38. +5 −35 src/MenuActionBar.cpp
  39. +3 −11 src/MenuActiveEffects.cpp
  40. +2 −16 src/MenuCharacter.cpp
  41. +1 −13 src/MenuConfirm.cpp
  42. +0 −1  src/MenuConfirm.h
  43. +5 −24 src/MenuEnemy.cpp
  44. +1 −13 src/MenuExit.cpp
  45. +2 −15 src/MenuInventory.cpp
  46. +3 −12 src/MenuItemStorage.cpp
  47. +2 −17 src/MenuLog.cpp
  48. +9 −17 src/MenuManager.cpp
  49. +1 −1  src/MenuMiniMap.cpp
  50. +3 −5 src/MenuNPCActions.cpp
  51. +7 −45 src/MenuPowers.cpp
  52. +2 −14 src/MenuStash.cpp
  53. +0 −3  src/MenuStash.h
  54. +5 −24 src/MenuStatBar.cpp
  55. +3 −28 src/MenuTalker.cpp
  56. +0 −2  src/MenuTalker.h
  57. +2 −14 src/MenuVendor.cpp
  58. +0 −2  src/MenuVendor.h
  59. +3 −15 src/NPC.cpp
  60. +1 −1  src/NPCManager.cpp
  61. +2 −0  src/NPCManager.h
  62. +2 −64 src/PowerManager.cpp
  63. +0 −2  src/PowerManager.h
  64. +1 −3 src/QuestLog.cpp
  65. +16 −16 src/Settings.cpp
  66. +2 −5 src/SoundManager.cpp
  67. +4 −9 src/StatBlock.cpp
  68. +7 −26 src/TileSet.cpp
  69. +168 −0 src/Utils.cpp
  70. +38 −2 src/Utils.h
  71. +4 −16 src/WidgetButton.cpp
  72. +8 −20 src/WidgetCheckBox.cpp
  73. +1 −2  src/WidgetCheckBox.h
  74. +2 −18 src/WidgetInput.cpp
  75. +3 −25 src/WidgetListBox.cpp
  76. +0 −1  src/WidgetListBox.h
  77. +1 −13 src/WidgetScrollBar.cpp
  78. +4 −12 src/WidgetSlider.cpp
  79. +0 −1  src/WidgetSlider.h
  80. +3 −14 src/WidgetTabControl.cpp
  81. +1 −3 src/WidgetTooltip.cpp
  82. +1 −9 src/main.cpp
View
3  .mailmap
@@ -1,5 +1,7 @@
# Proper Name <proper@email.xx> Commit Name <commit@email.xx>
Clint Bellanger <clintbellanger@gmail.com> clintbellanger <clintbellanger@gmail.com>
+Clint Bellanger <clintbellanger@gmail.com> unknown <cpb0001@LIB-AU16638.auburn.edu>
+Clint Bellanger <clintbellanger@gmail.com> unknown <clintbellanger@gmail.com>
Thane Brimhall <thane.brimhall@gmail.com> Thane Brimhall <thane@lenny.(none)>
Thane Brimhall <thane.brimhall@gmail.com> Thane Brimhall <tbrimhall@turtle.(none)>
Thane Brimhall <thane.brimhall@gmail.com> Thane Brimhall <thane@thane-laptop.(none)>
@@ -13,3 +15,4 @@ Manuel A. Fernandez Montecelo <manuel.montezelo@gmail.com> Manuel A. Fernandez M
Andrzej Adamczyk <akasei@inoto.net> Akasei <akasei@inoto.net>
Adrián Chaves Fernández (Gallaecio) <adriyetichaves@gmail.com> Adrian Chaves Fernandez <adriyetichaves@gmail.com>
Christian Kirchberger <hplgonzo@gmx.net> Gonzo <hplgonzo@gmx.net>
+Henrik Andersson <hean01@users.sourceforge.net> Henrik Andersson <henrik.4e@gmail.com>
View
1  CMakeLists.txt
@@ -97,6 +97,7 @@ Set (FLARE_SOURCES
./src/FontEngine.cpp
./src/GameState.cpp
./src/GameStateConfig.cpp
+ ./src/GameStateCutscene.cpp
./src/GameStateTitle.cpp
./src/GameStateLoad.cpp
./src/GameStatePlay.cpp
View
4 astyle_flare.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+astyle -S -T4 --style=kr -y src/*.cpp
+
View
11 mods/default/cutscenes/intro.txt
@@ -0,0 +1,11 @@
+#this scales art to width of flare window
+#scale_gfx=true
+
+[scene]
+image=menus/logo.png
+caption=Flare, the...
+soundfx=soundfx/level_up.ogg
+pause=60
+caption=Free Libre Action Roleplaying Engine
+pause=120
+
View
3  mods/default/engine/font_settings.txt
@@ -3,3 +3,6 @@
[font_regular]
default=LiberationSans-Regular.ttf,12,1
+
+[font_captions]
+default=LiberationSans-Regular.ttf,24,1
View
8 src/Animation.cpp
@@ -203,9 +203,6 @@ Renderable Animation::getCurrentFrame(int kind) {
r.offset.y = render_offset[index].y;
r.sprite = sprite;
}
- else {
- memset(&r, 0, sizeof(Renderable));
- }
return r;
}
@@ -226,9 +223,10 @@ void Animation::syncTo(const Animation *other) {
}
void Animation::setActiveFrames(const std::vector<short> &_active_frames) {
- if (_active_frames.size() == 1 && _active_frames[0] == -1)
- for (short i=0; i < number_frames; ++i)
+ if (_active_frames.size() == 1 && _active_frames[0] == -1) {
+ for (short i = 0; i < number_frames; ++i)
active_frames.push_back(i);
+ }
else
active_frames = std::vector<short>(_active_frames);
}
View
4 src/AnimationSet.cpp
@@ -66,10 +66,8 @@ void AnimationSet::load() {
FileParser parser;
const string filename = mods->locate(name);
- if (!parser.open(filename.c_str())) {
- cout << "Error loading animation definition file: " << name << endl;
+ if (!parser.open(filename, "Error loading animation definition: " + name))
return;
- }
string _name = "";
int position = 0;
View
9 src/Avatar.cpp
@@ -35,6 +35,7 @@ FLARE. If not, see http://www.gnu.org/licenses/
#include "MapRenderer.h"
#include "PowerManager.h"
#include "SharedResources.h"
+#include "Utils.h"
#include "UtilsParsing.h"
#include "UtilsMath.h"
@@ -170,7 +171,7 @@ void Avatar::loadLayerDefinitions() {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/hero_options.txt!\n");
+ }
// There are the positions of the items relative to layer_reference_order
// so if layer_reference_order=main,body,head,off
@@ -276,7 +277,7 @@ void Avatar::set_direction() {
target = path.back();
}
}
- stats.direction = face(target.x, target.y);
+ stats.direction = calcDirection(stats.pos, target);
} else {
if (inpt->pressing[UP] && inpt->pressing[LEFT]) stats.direction = 1;
else if (inpt->pressing[UP] && inpt->pressing[RIGHT]) stats.direction = 3;
@@ -327,7 +328,7 @@ void Avatar::handlePower(int actionbar_power) {
// is this a power that requires changing direction?
if (power.face) {
- stats.direction = face(target.x, target.y);
+ stats.direction = calcDirection(stats.pos, target);
}
switch (power.new_state) {
@@ -776,7 +777,7 @@ bool Avatar::takeHit(const Hazard &h) {
if (!stats.effects.immunity) {
if (stats.effects.forced_move) {
- float theta = powers->calcTheta(h.src_stats->pos.x, h.src_stats->pos.y, stats.pos.x, stats.pos.y);
+ float theta = calcTheta(h.src_stats->pos.x, h.src_stats->pos.y, stats.pos.x, stats.pos.y);
stats.forced_speed.x = static_cast<int>(ceil(stats.effects.forced_speed * cos(theta)));
stats.forced_speed.y = static_cast<int>(ceil(stats.effects.forced_speed * sin(theta)));
}
View
2  src/BehaviorStandard.cpp
@@ -315,7 +315,7 @@ void BehaviorStandard::checkMove() {
}
}
- e->stats.direction = e->face(pursue_pos.x, pursue_pos.y);
+ e->stats.direction = calcDirection(e->stats.pos, pursue_pos);
e->stats.turn_ticks = 0;
}
}
View
2  src/CombatText.cpp
@@ -54,7 +54,7 @@ CombatText::CombatText() {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/combat_text.txt!\n");
+ }
}
void CombatText::setCam(Point location) {
View
2  src/Enemy.cpp
@@ -240,7 +240,7 @@ bool Enemy::takeHit(const Hazard &h) {
powers->effect(&stats, h.power_index);
if (stats.effects.forced_move) {
- float theta = powers->calcTheta(stats.hero_pos.x, stats.hero_pos.y, stats.pos.x, stats.pos.y);
+ float theta = calcTheta(stats.hero_pos.x, stats.hero_pos.y, stats.pos.x, stats.pos.y);
stats.forced_speed.x = static_cast<int>(ceil(stats.effects.forced_speed * cos(theta)));
stats.forced_speed.y = static_cast<int>(ceil(stats.effects.forced_speed * sin(theta)));
}
View
2  src/EnemyGroupManager.cpp
@@ -77,7 +77,7 @@ void EnemyGroupManager::parseEnemyFileAndStore(const string& filename) {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open enemies/%s!\n", filename.c_str());
+ }
}
Enemy_Level EnemyGroupManager::getRandomEnemy(const std::string& category, int minlevel, int maxlevel) const {
View
48 src/EnemyManager.cpp
@@ -201,45 +201,45 @@ void EnemyManager::logic() {
handleSpawn();
- for (unsigned int i=0; i < enemies.size(); i++) {
-
+ vector<Enemy*>::iterator it;
+ for (it = enemies.begin(); it != enemies.end(); ++it) {
// hazards are processed after Avatar and Enemy[]
// so process and clear sound effects from previous frames
// check sound effects
if (AUDIO) {
- vector<string>::iterator found = find (sfx_prefixes.begin(), sfx_prefixes.end(), enemies[i]->stats.sfx_prefix);
+ vector<string>::iterator found = find (sfx_prefixes.begin(), sfx_prefixes.end(), (*it)->stats.sfx_prefix);
unsigned pref_id = distance(sfx_prefixes.begin(), found);
if (pref_id >= sfx_prefixes.size()) {
cerr << "ERROR: enemy sfx_prefix doesn't match registered prefixes (enemy: '"
- << enemies[i]->stats.name << "', sfx_prefix: '"
- << enemies[i]->stats.sfx_prefix << "')" << endl;
+ << (*it)->stats.name << "', sfx_prefix: '"
+ << (*it)->stats.sfx_prefix << "')" << endl;
} else {
- if (enemies[i]->sfx_phys)
- snd->play(sound_phys[pref_id], GLOBAL_VIRTUAL_CHANNEL, enemies[i]->stats.pos, false);
- if (enemies[i]->sfx_ment)
- snd->play(sound_ment[pref_id], GLOBAL_VIRTUAL_CHANNEL, enemies[i]->stats.pos, false);
- if (enemies[i]->sfx_hit)
- snd->play(sound_hit[pref_id], GLOBAL_VIRTUAL_CHANNEL, enemies[i]->stats.pos, false);
- if (enemies[i]->sfx_die)
- snd->play(sound_die[pref_id], GLOBAL_VIRTUAL_CHANNEL, enemies[i]->stats.pos, false);
- if (enemies[i]->sfx_critdie)
- snd->play(sound_critdie[pref_id], GLOBAL_VIRTUAL_CHANNEL, enemies[i]->stats.pos, false);
+ if ((*it)->sfx_phys)
+ snd->play(sound_phys[pref_id], GLOBAL_VIRTUAL_CHANNEL, (*it)->stats.pos, false);
+ if ((*it)->sfx_ment)
+ snd->play(sound_ment[pref_id], GLOBAL_VIRTUAL_CHANNEL, (*it)->stats.pos, false);
+ if ((*it)->sfx_hit)
+ snd->play(sound_hit[pref_id], GLOBAL_VIRTUAL_CHANNEL, (*it)->stats.pos, false);
+ if ((*it)->sfx_die)
+ snd->play(sound_die[pref_id], GLOBAL_VIRTUAL_CHANNEL, (*it)->stats.pos, false);
+ if ((*it)->sfx_critdie)
+ snd->play(sound_critdie[pref_id], GLOBAL_VIRTUAL_CHANNEL, (*it)->stats.pos, false);
}
// clear sound flags
- enemies[i]->sfx_hit = false;
- enemies[i]->sfx_phys = false;
- enemies[i]->sfx_ment = false;
- enemies[i]->sfx_die = false;
- enemies[i]->sfx_critdie = false;
+ (*it)->sfx_hit = false;
+ (*it)->sfx_phys = false;
+ (*it)->sfx_ment = false;
+ (*it)->sfx_die = false;
+ (*it)->sfx_critdie = false;
}
// new actions this round
- enemies[i]->stats.hero_pos = hero_pos;
- enemies[i]->stats.hero_alive = hero_alive;
- enemies[i]->stats.hero_stealth = hero_stealth;
- enemies[i]->logic();
+ (*it)->stats.hero_pos = hero_pos;
+ (*it)->stats.hero_alive = hero_alive;
+ (*it)->stats.hero_stealth = hero_stealth;
+ (*it)->logic();
}
}
View
34 src/Entity.cpp
@@ -104,40 +104,6 @@ bool Entity::move() {
}
/**
- * Change direction to face the target map location
- */
-int Entity::face(int mapx, int mapy) {
- // inverting Y to convert map coordinates to standard cartesian coordinates
- int dx = mapx - stats.pos.x;
- int dy = stats.pos.y - mapy;
-
- // avoid div by zero
- if (dx == 0) {
- if (dy > 0) return 3;
- else return 7;
- }
-
- float slope = ((float)dy)/((float)dx);
- if (0.5 <= slope && slope <= 2.0) {
- if (dy > 0) return 4;
- else return 0;
- }
- if (-0.5 <= slope && slope <= 0.5) {
- if (dx > 0) return 5;
- else return 1;
- }
- if (-2.0 <= slope && slope <= -0.5) {
- if (dx > 0) return 6;
- else return 2;
- }
- if (2.0 <= slope || -2.0 >= slope) {
- if (dy > 0) return 3;
- else return 7;
- }
- return stats.direction;
-}
-
-/**
* Set the entity's current animation by name
*/
bool Entity::setAnimation(const string& animationName) {
View
1  src/Entity.h
@@ -44,7 +44,6 @@ class Entity {
virtual ~Entity();
bool move();
- int face(int, int);
// Each child of Entity defines its own rendering method
virtual Renderable getRender() = 0;
View
15 src/FileParser.cpp
@@ -33,9 +33,13 @@ FileParser::FileParser()
, val("")
{}
-bool FileParser::open(const string& filename) {
+bool FileParser::open(const string& filename, const string &errormessage) {
+ this->filename = filename;
infile.open(filename.c_str(), ios::in);
- return infile.is_open();
+ bool ret = infile.is_open();
+ if (!ret && !errormessage.empty())
+ fprintf(stderr, "%s: %s\n", errormessage.c_str(), filename.c_str());
+ return ret;
}
void FileParser::close() {
@@ -105,7 +109,7 @@ string FileParser::nextValue() {
size_t seppos = val.find_first_of(',');
size_t alt_seppos = val.find_first_of(';');
if (alt_seppos != string::npos && alt_seppos < seppos)
- seppos = alt_seppos; // return the first ',' or ';'
+ seppos = alt_seppos; // return the first ',' or ';'
if (seppos == string::npos) {
s = val;
@@ -118,6 +122,11 @@ string FileParser::nextValue() {
return s;
}
+std::string FileParser::getFileName()
+{
+ return filename;
+}
+
FileParser::~FileParser() {
close();
}
View
13 src/FileParser.h
@@ -31,6 +31,7 @@ FLARE. If not, see http://www.gnu.org/licenses/
class FileParser {
private:
+ std::string filename;
std::ifstream infile;
std::string line;
@@ -38,11 +39,21 @@ class FileParser {
FileParser();
~FileParser();
- bool open(const std::string& filename);
+ /**
+ * @brief open
+ * @param filename The file to be opened
+ * @param errormessage
+ * Optional parameter, will be printed to stderr together with the filename
+ * if an error occurs. If errormessage is empty, there will be no output to
+ * stderr in any case.
+ * @return true if file could be opened successfully for reading.
+ */
+ bool open(const std::string& filename, const std::string &errormessage = "Could not open text file");
void close();
bool next();
std::string nextValue(); // next value inside one line.
std::string getRawLine();
+ std::string getFileName();
bool new_section;
std::string section;
View
4 src/FontEngine.cpp
@@ -77,7 +77,7 @@ FontEngine::FontEngine()
}
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/font_settings.txt!\n");
+ }
// set the font colors
// RGB values, the last value is 'unused'. For info,
@@ -92,7 +92,7 @@ FontEngine::FontEngine()
color_map[infile.key] = color;
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/font_colors.txt!\n");
+ }
// Attempt to set the default active font
setFont("font_regular");
View
70 src/GameStateConfig.cpp
@@ -50,19 +50,11 @@ GameStateConfig::GameStateConfig ()
, ok_button(NULL)
, defaults_button(NULL)
, cancel_button(NULL)
- , imgFileName(mods->locate("images/menus/config.png"))
, tip_buf()
, input_key(0)
, check_resolution(true)
{
- // Load background image
- SDL_Surface * tmp = IMG_Load(imgFileName.c_str());
- if (!tmp) {
- fprintf(stderr, "Could not load image \"%s\"\n", imgFileName.c_str());
- } else {
- background = SDL_DisplayFormatAlpha(tmp);
- SDL_FreeSurface(tmp);
- }
+ background = loadGraphicSurface("images/menus/config.png");
init();
update();
@@ -215,11 +207,7 @@ void GameStateConfig::init() {
void GameStateConfig::readConfig () {
//Load the menu configuration from file
- int x1 = 0;
- int y1 = 0;
- int x2 = 0;
- int y2 = 0;
- int setting_num = 0;
+
int offset_x = 0;
int offset_y = 0;
@@ -228,12 +216,12 @@ void GameStateConfig::readConfig () {
while (infile.next()) {
infile.val = infile.val + ',';
- x1 = eatFirstInt(infile.val, ',');
- y1 = eatFirstInt(infile.val, ',');
- x2 = eatFirstInt(infile.val, ',');
- y2 = eatFirstInt(infile.val, ',');
+ int x1 = eatFirstInt(infile.val, ',');
+ int y1 = eatFirstInt(infile.val, ',');
+ int x2 = eatFirstInt(infile.val, ',');
+ int y2 = eatFirstInt(infile.val, ',');
- setting_num = -1;
+ int setting_num = -1;
if (infile.key == "listbox_scrollbar_offset") {
activemods_lstb->scrollbar_offset = x1;
@@ -607,7 +595,7 @@ void GameStateConfig::readConfig () {
}
infile.close();
- } else fprintf(stderr, "Unable to open menus/config.txt!\n");
+ }
// Load the MenuConfirm positions and alignments from menus/menus.txt
if (infile.open(mods->locate("menus/menus.txt"))) {
@@ -634,7 +622,7 @@ void GameStateConfig::readConfig () {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open menus/menus.txt!\n");
+ }
defaults_confirm->window_area = menuConfirm_area;
defaults_confirm->alignment = menuConfirm_align;
@@ -789,7 +777,7 @@ void GameStateConfig::logic ()
delete requestedGameState;
requestedGameState = new GameStateTitle();
} else if (resolution_confirm->cancelClicked || resolution_confirm_ticks == 0) {
- applyVideoSettings(screen, old_view_w, old_view_h);
+ applyVideoSettings(old_view_w, old_view_h);
saveSettings();
delete requestedGameState;
requestedGameState = new GameStateConfig();
@@ -815,7 +803,7 @@ void GameStateConfig::logic ()
SDL_JoystickClose(joy);
joy = SDL_JoystickOpen(JOYSTICK_DEVICE);
}
- applyVideoSettings(screen, width, height);
+ applyVideoSettings(width, height);
if (width != old_view_w || height != old_view_h) {
resolution_confirm->window_area = menuConfirm_area;
resolution_confirm->align();
@@ -1175,7 +1163,7 @@ bool GameStateConfig::getLanguagesList()
i += 1;
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/languages.txt!\n");
+ }
return true;
}
@@ -1189,7 +1177,7 @@ int GameStateConfig::getLanguagesNumber()
languages_num += 1;
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/languages.txt!\n");
+ }
return languages_num;
}
@@ -1202,44 +1190,22 @@ void GameStateConfig::refreshFont() {
/**
* Tries to apply the selected video settings, reverting back to the old settings upon failure
*/
-bool GameStateConfig::applyVideoSettings(SDL_Surface *src, int width, int height) {
+bool GameStateConfig::applyVideoSettings(int width, int height) {
if (MIN_VIEW_W > width && MIN_VIEW_H > height) {
fprintf (stderr, "A mod is requiring a minimum resolution of %dx%d\n", MIN_VIEW_W, MIN_VIEW_H);
if (width < MIN_VIEW_W) width = MIN_VIEW_W;
if (height < MIN_VIEW_H) height = MIN_VIEW_H;
}
- // Temporarily save previous settings
- int tmp_fs = FULLSCREEN;
- int tmp_w = VIEW_W;
- int tmp_h = VIEW_H;
-
// Attempt to apply the new settings
- Uint32 flags = 0;
- if (FULLSCREEN) flags = flags | SDL_FULLSCREEN;
- if (DOUBLEBUF) flags = flags | SDL_DOUBLEBUF;
- if (HWSURFACE)
- flags = flags | SDL_HWSURFACE | SDL_HWACCEL;
- else
- flags = flags | SDL_SWSURFACE;
-
- src = SDL_SetVideoMode (width, height, 0, flags);
+ setupSDLVideoMode(width, height);
// If the new settings fail, revert to the old ones
- if (src == NULL) {
+ if (!screen) {
fprintf (stderr, "Error during SDL_SetVideoMode: %s\n", SDL_GetError());
-
- flags = 0;
- if (tmp_fs) flags = flags | SDL_FULLSCREEN;
- if (DOUBLEBUF) flags = flags | SDL_DOUBLEBUF;
- if (HWSURFACE)
- flags = flags | SDL_HWSURFACE | SDL_HWACCEL;
- else
- flags = flags | SDL_SWSURFACE;
-
- SDL_SetVideoMode (tmp_w, tmp_h, 0, flags);
-
+ setupSDLVideoMode(VIEW_W, VIEW_H);
return false;
+
} else {
// If the new settings succeed, adjust the view area
View
3  src/GameStateConfig.h
@@ -72,7 +72,7 @@ class GameStateConfig : public GameState {
void update();
void setDefaultResolution();
void refreshFont();
- bool applyVideoSettings(SDL_Surface *src, int width, int height);
+ bool applyVideoSettings(int width, int height);
void enableMods();
void disableMods();
bool setMods();
@@ -84,7 +84,6 @@ class GameStateConfig : public GameState {
WidgetButton * defaults_button;
WidgetButton * cancel_button;
SDL_Surface * background;
- std::string imgFileName;
WidgetCheckBox * fullscreen_cb;
WidgetLabel * fullscreen_lb;
View
232 src/GameStateCutscene.cpp
@@ -0,0 +1,232 @@
+/*
+Copyright © 2012-2013 Henrik Andersson
+
+This file is part of FLARE.
+
+FLARE 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.
+
+FLARE 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
+FLARE. If not, see http://www.gnu.org/licenses/
+*/
+
+#include "GameStateCutscene.h"
+#include "GameStatePlay.h"
+#include "FileParser.h"
+
+#include <iostream>
+using namespace std;
+
+Scene::Scene() : frame_counter(0)
+ , pause_frames(0)
+ , caption("")
+ , caption_size(0,0)
+ , art(NULL)
+ , sid(-1)
+{
+}
+
+Scene::~Scene() {
+
+ while(!components.empty())
+ components.pop();
+
+}
+
+bool Scene::logic() {
+
+ /* TODO: handle cancel input to skip scene */
+ bool skip = false;
+ if (inpt->pressing[MAIN1] && !inpt->lock[MAIN1]) {
+ inpt->lock[MAIN1] = true;
+ skip = true;
+ }
+
+ /* Pause until specified frame */
+ if (!skip && pause_frames != 0 && frame_counter < pause_frames) {
+ ++frame_counter;
+ return true;
+ }
+
+ /* parse scene components until next pause */
+ while (!components.empty() && components.front().type != "pause") {
+
+ if (components.front().type == "caption") {
+
+ font->setFont("font_captions");
+ caption = components.front().s;
+ caption_size = font->calc_size(caption, VIEW_W * 0.8f);
+
+ } else if (components.front().type == "image") {
+
+ if (art)
+ SDL_FreeSurface(art);
+
+ art = components.front().i;
+
+ art_dest.x = (VIEW_W/2) - (art->w/2);
+ art_dest.y = (VIEW_H/2) - (art->h/2);
+ art_dest.w = art->w;
+ art_dest.h = art->h;
+
+ } else if (components.front().type == "soundfx") {
+ if (sid != 0)
+ snd->unload(sid);
+
+ sid = snd->load(components.front().s, "Cutscenes");
+ snd->play(sid);
+ }
+
+ components.pop();
+ }
+
+ /* check if current scene has reached the end */
+ if (components.empty())
+ return false;
+
+ /* setup frame pausing */
+ frame_counter = 0;
+ pause_frames = components.front().x;
+ components.pop();
+
+ return true;
+}
+
+void Scene::render() {
+ SDL_Rect r = art_dest;
+ if (art != NULL)
+ SDL_BlitSurface(art, NULL, screen, &r);
+
+ if (caption != "") {
+ font->setFont("font_captions");
+ font->renderShadowed(caption, screen->w / 2, screen->h - (caption_size.y*2),
+ JUSTIFY_CENTER,
+ screen, FONT_WHITE);
+ }
+}
+
+GameStateCutscene::GameStateCutscene(GameState *game_state) : previous_gamestate(game_state)
+ , game_slot(-1)
+{
+ scale_graphics = false;
+}
+
+GameStateCutscene::~GameStateCutscene() {
+}
+
+void GameStateCutscene::logic() {
+
+ if (scenes.empty())
+ {
+ if (game_slot != -1) {
+ GameStatePlay *gsp = new GameStatePlay();
+ gsp->resetGame();
+ gsp->game_slot = game_slot;
+ gsp->loadGame();
+
+ previous_gamestate = gsp;
+ }
+
+ /* return to previous gamestate */
+ delete requestedGameState;
+ requestedGameState = previous_gamestate;
+ return;
+ }
+
+ while (!scenes.empty() && !scenes.front().logic())
+ scenes.pop();
+}
+
+void GameStateCutscene::render() {
+ if (!scenes.empty())
+ scenes.front().render();
+}
+
+bool GameStateCutscene::load(std::string filename) {
+ FileParser infile;
+
+ if (!infile.open(mods->locate("cutscenes/" + filename))) {
+ cerr << "Unable to open cutscenes/" << filename << endl;
+ return false;
+ }
+
+ // parse the cutscene file
+ while (infile.next()) {
+
+ if (infile.new_section) {
+ if (infile.section == "scene")
+ scenes.push(Scene());
+ }
+
+ if (infile.section == "scene") {
+ SceneComponent sc;
+ sc.type = "";
+
+ if (infile.key == "caption") {
+ sc.type = infile.key;
+ sc.s = msg->get(infile.val);
+ }
+ else if (infile.key == "image") {
+ sc.type = infile.key;
+ sc.i = loadImage(infile.val);
+ if (sc.i == NULL)
+ sc.type = "";
+ }
+ else if (infile.key == "pause") {
+ sc.type = infile.key;
+ sc.x = toInt(infile.val);
+ }
+ else if (infile.key == "soundfx") {
+ sc.type = infile.key;
+ sc.s = infile.val;
+ }
+
+ if (sc.type != "")
+ scenes.back().components.push(sc);
+
+ } else {
+
+ if (infile.key == "scale_gfx") {
+ scale_graphics = toBool(infile.val);
+ }
+
+ }
+ }
+
+ if (scenes.empty())
+ {
+ cerr << "No scenes defined in cutscene file " << filename << endl;
+ return false;
+ }
+
+ return true;
+}
+
+SDL_Surface *GameStateCutscene::loadImage(std::string filename) {
+
+ std::string image_file = (mods->locate("images/"+ filename));
+ SDL_Surface *image = IMG_Load(image_file.c_str());
+ if (!image) {
+ std::cerr << "Missing cutscene art reference: " << image_file << std::endl;
+ return NULL;
+ }
+
+ /* scale image to fit height */
+ if (scale_graphics) {
+ float ratio = image->h/(float)image->w;
+ SDL_Surface *art = scaleSurface(image, VIEW_W, VIEW_W*ratio);
+ if (art == NULL)
+ return image;
+
+ SDL_FreeSurface(image);
+ image = art;
+ }
+
+ return image;
+}
+
View
87 src/GameStateCutscene.h
@@ -0,0 +1,87 @@
+/*
+Copyright © 2012-2013 Henrik Andersson
+
+This file is part of FLARE.
+
+FLARE 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.
+
+FLARE 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
+FLARE. If not, see http://www.gnu.org/licenses/
+*/
+
+#include <queue>
+#include <list>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+#include "Settings.h"
+#include "SharedResources.h"
+#include "Utils.h"
+#include "UtilsParsing.h"
+#include "WidgetLabel.h"
+
+#ifndef GAMESTATECUTSCENE_H
+#define GAMESTATECUTSCENE_H
+
+#include "GameState.h"
+
+class SceneComponent {
+public:
+ std::string type;
+ SDL_Surface *i;
+ std::string s;
+ int x,y,z;
+};
+
+class Scene {
+private:
+ int frame_counter;
+ int pause_frames;
+ std::string caption;
+ Point caption_size;
+ SDL_Surface *art;
+ SDL_Rect art_dest;
+ SoundManager::SoundID sid;
+
+public:
+ Scene();
+ ~Scene();
+ bool logic();
+ void render();
+
+ std::queue<SceneComponent> components;
+
+};
+
+class GameStateCutscene : public GameState {
+private:
+ GameState *previous_gamestate;
+ std::string dest_map;
+ Point dest_pos;
+ bool scale_graphics;
+
+ std::queue<Scene> scenes;
+
+ SDL_Surface *loadImage(std::string filename);
+
+public:
+ GameStateCutscene(GameState *game_state);
+ ~GameStateCutscene();
+
+ bool load(std::string filename);
+ void logic();
+ void render();
+
+ int game_slot;
+};
+
+#endif
+
View
73 src/GameStateLoad.cpp
@@ -113,7 +113,7 @@ GameStateLoad::GameStateLoad() : GameState() {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open menus/gameload.txt!\n");
+ }
// Load the MenuConfirm positions and alignments from menus/menus.txt
if (infile.open(mods->locate("menus/menus.txt"))) {
@@ -140,7 +140,7 @@ GameStateLoad::GameStateLoad() : GameState() {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open menus/menus.txt!\n");
+ }
confirm->align();
confirm->update();
@@ -164,7 +164,7 @@ GameStateLoad::GameStateLoad() : GameState() {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/hero_options.txt!\n");
+ }
if (!found_layer) fprintf(stderr, "Warning: Could not find layers for direction 6\n");
button_action->pos.x += (VIEW_W - FRAME_W)/2;
@@ -201,35 +201,9 @@ GameStateLoad::GameStateLoad() : GameState() {
}
void GameStateLoad::loadGraphics() {
- background = IMG_Load(mods->locate("images/menus/game_slots.png").c_str());
- selection = IMG_Load(mods->locate("images/menus/game_slot_select.png").c_str());
- portrait_border = IMG_Load(mods->locate("images/menus/portrait_border.png").c_str());
- if (!background || !selection || !portrait_border) {
- fprintf(stderr, "Couldn't load image: %s\n", IMG_GetError());
- }
-
- // optimize
- SDL_Surface *cleanup;
-
- if (background) {
- cleanup = background;
- background = SDL_DisplayFormatAlpha(background);
- SDL_FreeSurface(cleanup);
- }
-
- if (selection) {
- SDL_SetColorKey( selection, SDL_SRCCOLORKEY, SDL_MapRGB(selection->format, 255, 0, 255));
- cleanup = selection;
- selection = SDL_DisplayFormatAlpha(selection);
- SDL_FreeSurface(cleanup);
- }
-
- if (portrait_border) {
- SDL_SetColorKey( portrait_border, SDL_SRCCOLORKEY, SDL_MapRGB(portrait_border->format, 255, 0, 255));
- cleanup = portrait_border;
- portrait_border = SDL_DisplayFormatAlpha(portrait_border);
- SDL_FreeSurface(cleanup);
- }
+ background = loadGraphicSurface("images/menus/game_slots.png");
+ selection = loadGraphicSurface("images/menus/game_slot_select.png", "Couldn't load image", false, true);
+ portrait_border = loadGraphicSurface("images/menus/portrait_border.png", "Couldn't load image", false, true);
}
void GameStateLoad::loadPortrait(int slot) {
@@ -240,13 +214,7 @@ void GameStateLoad::loadPortrait(int slot) {
if (stats[slot].name == "") return;
- portrait = IMG_Load(mods->locate("images/portraits/" + stats[slot].portrait + ".png").c_str());
- if (!portrait) return;
-
- // optimize
- SDL_Surface *cleanup = portrait;
- portrait = SDL_DisplayFormatAlpha(portrait);
- SDL_FreeSurface(cleanup);
+ portrait = loadGraphicSurface("images/portraits/" + stats[slot].portrait + ".png");
}
void GameStateLoad::readGameSlots() {
@@ -257,7 +225,7 @@ void GameStateLoad::readGameSlots() {
string GameStateLoad::getMapName(const string& map_filename) {
FileParser infile;
- if (!infile.open(mods->locate("maps/" + map_filename))) return "";
+ if (!infile.open(mods->locate("maps/" + map_filename), "")) return "";
string map_name = "";
while (map_name == "" && infile.next()) {
@@ -283,7 +251,7 @@ void GameStateLoad::readGameSlot(int slot) {
filename << GAME_PREFIX << "_";
filename << "save" << (slot+1) << ".txt";
- if (!infile.open(filename.str())) return;
+ if (!infile.open(filename.str(), "")) return;
while (infile.next()) {
@@ -358,26 +326,17 @@ void GameStateLoad::loadPreview(int slot) {
// composite the hero graphic
for (unsigned int i=0; i<img_gfx.size(); i++) {
- if (img_gfx[i] == "") continue;
+ if (img_gfx[i] == "")
+ continue;
+
sprites[slot].push_back(NULL);
- if (TEXTURE_QUALITY == false) {
- sprites[slot].back() = IMG_Load(mods->locate("images/avatar/" + stats[slot].base + "/preview/noalpha/" + img_gfx[i] + ".png").c_str());
+ if (!TEXTURE_QUALITY) {
+ string fname = "images/avatar/" + stats[slot].base + "/preview/noalpha/" + img_gfx[i] + ".png";
+ sprites[slot].back() = loadGraphicSurface(fname, "Falling back to alpha version", false, true);
}
if (!sprites[slot].back()) {
- sprites[slot].back() = IMG_Load(mods->locate("images/avatar/" + stats[slot].base + "/preview/" + img_gfx[i] + ".png").c_str());
- } else {
- SDL_SetColorKey(sprites[slot].back(), SDL_SRCCOLORKEY, SDL_MapRGB(sprites[slot].back()->format, 255, 0, 255));
- }
- if (!sprites[slot].back()) {
- fprintf(stderr, "Couldn't load image: %s\n", IMG_GetError());
- }
-
- // optimize
- if (sprites[slot].back()) {
- SDL_Surface *cleanup = sprites[slot].back();
- sprites[slot].back() = SDL_DisplayFormatAlpha(sprites[slot].back());
- SDL_FreeSurface(cleanup);
+ sprites[slot].back() = loadGraphicSurface("images/avatar/" + stats[slot].base + "/preview/" + img_gfx[i] + ".png");
}
}
View
21 src/GameStateNew.cpp
@@ -121,7 +121,7 @@ GameStateNew::GameStateNew() : GameState() {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open menus/gamenew.txt!\n");
+ }
button_prev->pos.x += (VIEW_W - FRAME_W)/2;
button_prev->pos.y += (VIEW_H - FRAME_H)/2;
@@ -175,27 +175,12 @@ GameStateNew::GameStateNew() : GameState() {
}
void GameStateNew::loadGraphics() {
- portrait_border = IMG_Load(mods->locate("images/menus/portrait_border.png").c_str());
- if(!portrait_border) {
- fprintf(stderr, "Couldn't load image: %s\n", IMG_GetError());
- } else {
- // optimize
- SDL_SetColorKey( portrait_border, SDL_SRCCOLORKEY, SDL_MapRGB(portrait_border->format, 255, 0, 255) );
- SDL_Surface *cleanup = portrait_border;
- portrait_border = SDL_DisplayFormatAlpha(portrait_border);
- SDL_FreeSurface(cleanup);
- }
+ portrait_border = loadGraphicSurface("images/menus/portrait_border.png", "Couldn't load portrait border image", false, true);
}
void GameStateNew::loadPortrait(const string& portrait_filename) {
SDL_FreeSurface(portrait_image);
- portrait_image = IMG_Load(mods->locate("images/portraits/" + portrait_filename + ".png").c_str());
- if (!portrait_image) return;
-
- // optimize
- SDL_Surface *cleanup = portrait_image;
- portrait_image = SDL_DisplayFormatAlpha(portrait_image);
- SDL_FreeSurface(cleanup);
+ portrait_image = loadGraphicSurface("images/portraits/" + portrait_filename + ".png");
}
/**
View
51 src/GameStatePlay.cpp
@@ -31,6 +31,7 @@ FLARE. If not, see http://www.gnu.org/licenses/
#include "GameStatePlay.h"
#include "GameState.h"
#include "GameStateTitle.h"
+#include "GameStateCutscene.h"
#include "Hazard.h"
#include "HazardManager.h"
#include "LootManager.h"
@@ -79,7 +80,8 @@ GameStatePlay::GameStatePlay()
, npcs(new NPCManager(map, loot, items, &pc->stats))
, quests(new QuestLog(camp, menu->log))
, loading(new WidgetLabel())
- , loading_bg(IMG_Load(mods->locate("images/menus/confirm_bg.png").c_str()))
+ // Load the loading screen image (we currently use the confirm dialog background):
+ , loading_bg(loadGraphicSurface("images/menus/confirm_bg.png"))
, npc_id(-1)
, eventDialogOngoing(false)
, eventPendingDialog(false)
@@ -98,16 +100,6 @@ GameStatePlay::GameStatePlay()
loading->set(VIEW_W_HALF, VIEW_H_HALF, JUSTIFY_CENTER, VALIGN_CENTER, msg->get("Loading..."), color_normal);
- // Load the loading screen image (we currently use the confirm dialog background)
-
- if(!loading_bg) {
- fprintf(stderr, "Couldn't load image: %s\n", IMG_GetError());
- } else {
- SDL_Surface *cleanup = loading_bg;
- loading_bg = SDL_DisplayFormatAlpha(loading_bg);
- SDL_FreeSurface(cleanup);
- }
-
// load the config file for character titles
loadTitles();
}
@@ -387,10 +379,10 @@ void GameStatePlay::loadTitles() {
else if (infile.key == "requires_status") titles.back().requires_status = infile.val;
else if (infile.key == "requires_not") titles.back().requires_not = infile.val;
else if (infile.key == "primary_stat") titles.back().primary_stat = infile.val;
+ else fprintf(stderr, "Unknown key value in title definitons: %s in file %s in section %s\n", infile.key.c_str(), infile.getFileName().c_str(), infile.section.c_str());
}
infile.close();
}
- else fprintf(stderr, "Unable to open engine/titles.txt!\n");
}
void GameStatePlay::checkTitle() {
@@ -704,12 +696,47 @@ void GameStatePlay::checkStash() {
}
}
+void GameStatePlay::checkCutscene() {
+ if (!map->cutscene)
+ return;
+
+ GameStateCutscene *cutscene = new GameStateCutscene(NULL);
+
+ if (!cutscene->load(map->cutscene_file)) {
+ delete cutscene;
+ map->cutscene = false;
+ return;
+ }
+
+ // handle respawn point and set game play game_slot
+ cutscene->game_slot = game_slot;
+
+ if (map->teleportation) {
+
+ if (map->teleport_mapname != "")
+ map->respawn_map = map->teleport_mapname;
+
+ map->respawn_point = map->teleport_destination;
+
+ } else {
+ map->respawn_point = pc->stats.pos;
+ }
+
+ saveGame();
+
+ delete requestedGameState;
+ requestedGameState = cutscene;
+}
+
+
/**
* Process all actions for a single frame
* This includes some message passing between child object
*/
void GameStatePlay::logic() {
+ checkCutscene();
+
// check menus first (top layer gets mouse click priority)
menu->logic();
View
3  src/GameStatePlay.h
@@ -101,6 +101,7 @@ class GameStatePlay : public GameState {
void checkNotifications();
void checkNPCInteraction();
void checkStash();
+ void checkCutscene();
void showLoading();
void loadTitles();
@@ -116,6 +117,8 @@ class GameStatePlay : public GameState {
GameStatePlay();
~GameStatePlay();
+ void initialize();
+
void logic();
void render();
void showFPS(int fps);
View
15 src/GameStateTitle.cpp
@@ -30,7 +30,7 @@ GameStateTitle::GameStateTitle() : GameState() {
exit_game = false;
load_game = false;
- loadGraphics();
+ logo = loadGraphicSurface("images/menus/logo.png");
// set up buttons
button_play = new WidgetButton(mods->locate("images/menus/buttons/button_default.png"));
@@ -63,19 +63,6 @@ GameStateTitle::GameStateTitle() : GameState() {
inpt->enableMouseEmulation();
}
-void GameStateTitle::loadGraphics() {
-
- SDL_Surface *cleanup = IMG_Load(mods->locate("images/menus/logo.png").c_str());
-
- if(!cleanup) {
- fprintf(stderr, "Couldn't load image: %s\n", IMG_GetError());
- } else {
- // optimize
- logo = SDL_DisplayFormatAlpha(cleanup);
- SDL_FreeSurface(cleanup);
- }
-}
-
void GameStateTitle::logic() {
button_play->enabled = ENABLE_PLAYGAME;
View
3  src/GameStateTitle.h
@@ -30,13 +30,12 @@ class GameStateTitle : public GameState {
SDL_Surface *logo;
WidgetButton *button_play;
WidgetButton *button_exit;
- WidgetButton *button_cfg;
+ WidgetButton *button_cfg;
WidgetLabel *label_version;
public:
GameStateTitle();
~GameStateTitle();
- void loadGraphics();
void logic();
void render();
View
16 src/GameSwitcher.cpp
@@ -2,6 +2,7 @@
Copyright © 2011-2012 Clint Bellanger
Copyright © 2012 Igor Paliychuk
Copyright © 2012 Stefan Beller
+Copyright © 2013 Henrik Andersson
This file is part of FLARE.
@@ -32,6 +33,7 @@ FLARE. If not, see http://www.gnu.org/licenses/
#include "GameSwitcher.h"
#include "GameStateTitle.h"
+#include "GameStateCutscene.h"
#include "SharedResources.h"
#include "Settings.h"
#include "FileParser.h"
@@ -41,8 +43,16 @@ using namespace std;
GameSwitcher::GameSwitcher() {
- // The initial state is the title screen
- currentState = new GameStateTitle();
+ // The initial state is the intro cutscene and then title screen
+ GameStateTitle *title=new GameStateTitle();
+ GameStateCutscene *intro = new GameStateCutscene(title);
+
+ currentState = intro;
+
+ if (!intro->load("intro.txt")) {
+ delete intro;
+ currentState = title;
+ }
label_fps = new WidgetLabel();
done = false;
@@ -118,7 +128,7 @@ void GameSwitcher::loadFPS() {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open menus/fps.txt!\n");
+ }
// this is a dummy string used to approximate the fps position when aligned to the right
font->setFont("font_regular");
View
10 src/GetText.cpp
@@ -23,10 +23,12 @@ FLARE. If not, see http://www.gnu.org/licenses/
using namespace std;
-GetText::GetText() {
- line = "";
- key = "";
- val = "";
+GetText::GetText()
+ : line("")
+ , key("")
+ , val("")
+ , fuzzy(false)
+{
}
bool GetText::open(const string& filename) {
View
31 src/ImageManager.cpp
@@ -52,31 +52,14 @@ SDL_Surface *ImageManager::getSurface(const std::string &name) {
vector<string>::iterator found = find(names.begin(), names.end(), name);
if (found != names.end()) {
int index = distance(names.begin(), found);
- if (sprites[index] == 0) {
- SDL_Surface *cleanup = NULL;
-
- if (TEXTURE_QUALITY == false) {
- string path = mods->locate(name);
- const char * pch = strrchr(path.c_str(), '/' );
- path.insert(pch-path.c_str(), "/noalpha");
- cleanup = IMG_Load(path.c_str());
- if (!cleanup)
- printf("failed to load %s\n", path.c_str());
- else
- SDL_SetColorKey(cleanup, SDL_SRCCOLORKEY, SDL_MapRGB(cleanup->format, 255, 0, 255));
- }
-
- if (!cleanup) {
- cleanup = IMG_Load(mods->locate(name).c_str());
- }
-
- if (!cleanup) {
- fprintf(stderr, "Couldn't load image: %s\n", IMG_GetError());
- } else {
- SDL_Surface *sprite = SDL_DisplayFormatAlpha(cleanup);
- SDL_FreeSurface(cleanup);
- sprites[index] = sprite;
+ if (!sprites[index]) {
+ if (!TEXTURE_QUALITY) {
+ string newname = string(name);
+ newname.replace(name.rfind("/"), 0, "/noalpha");
+ sprites[index] = loadGraphicSurface(newname, "Falling back to alpha version", false, true);
}
+ if (!sprites[index])
+ sprites[index] = loadGraphicSurface(name);
}
return sprites[index];
}
View
13 src/InputState.cpp
@@ -125,12 +125,9 @@ void InputState::defaultJoystickBindings ()
void InputState::loadKeyBindings() {
FileParser infile;
- int key1;
- int key2;
- int cursor;
- if (!infile.open(PATH_CONF + FILE_KEYBINDINGS)) {
- if (!infile.open(mods->locate("engine/default_keybindings.txt").c_str())) {
+ if (!infile.open(PATH_CONF + FILE_KEYBINDINGS, "")) {
+ if (!infile.open(mods->locate("engine/default_keybindings.txt"), "")) {
saveKeyBindings();
return;
} else saveKeyBindings();
@@ -138,10 +135,10 @@ void InputState::loadKeyBindings() {
while (infile.next()) {
- key1 = eatFirstInt(infile.val, ',');
- key2 = toInt(infile.val);
+ int key1 = eatFirstInt(infile.val, ',');
+ int key2 = toInt(infile.val);
- cursor = -1;
+ int cursor = -1;
if (infile.key == "cancel") cursor = CANCEL;
else if (infile.key == "accept") cursor = ACCEPT;
View
31 src/ItemManager.cpp
@@ -126,10 +126,7 @@ void ItemManager::loadAll() {
shrinkVecToFit(item_sets);
if (items.empty()) fprintf(stderr, "No items were found.\n");
-
- // TODO: disabled for 0.18, enable again
- // we had no item sets in that release.
- //if (item_sets.empty()) printf("No item sets were found.\n");
+ if (item_sets.empty()) printf("No item sets were found.\n");
}
/**
@@ -139,10 +136,8 @@ void ItemManager::loadAll() {
*/
void ItemManager::load(const string& filename) {
FileParser infile;
- if (!infile.open(filename)) {
- fprintf(stderr, "Unable to open %s!\n", filename.c_str());
+ if (!infile.open(filename))
return;
- }
int id = 0;
bool id_line = false;
@@ -296,7 +291,7 @@ void ItemManager::loadTypes(const string& filename) {
}
}
infile.close();
- } else fprintf(stderr, "Unable to open %s!\n", filename.c_str());
+ }
}
string ItemManager::getItemType(std::string _type) {
@@ -310,10 +305,8 @@ string ItemManager::getItemType(std::string _type) {
void ItemManager::loadSets(const string& filename) {
FileParser infile;
- if (!infile.open(filename)) {
- fprintf(stderr, "Unable to open %s!\n", filename.c_str());
+ if (!infile.open(filename))
return;
- }
int id = 0;
bool id_line;
@@ -369,18 +362,9 @@ void ItemManager::loadSets(const string& filename) {
/**
* Icon sets
*/
-void ItemManager::loadIcons() {
-
- icons = IMG_Load(mods->locate("images/icons/icons.png").c_str());
-
- if (!icons) {
- fprintf(stderr, "Couldn't load icons: %s\n", IMG_GetError());
- } else {
- // optimize
- SDL_Surface *cleanup = icons;
- icons = SDL_DisplayFormatAlpha(icons);
- SDL_FreeSurface(cleanup);
- }
+void ItemManager::loadIcons()
+{
+ icons = loadGraphicSurface("images/icons/icons.png", "Couldn't load icons");
}
/**
@@ -390,6 +374,7 @@ void ItemManager::loadIcons() {
void ItemManager::renderIcon(ItemStack stack, int x, int y, int size) {
if (!icons) return;
+ SDL_Rect src, dest;
dest.x = x;
dest.y = y;
src.w = src.h = dest.w = dest.h = size;
View
2  src/ItemManager.h
@@ -175,8 +175,6 @@ class ItemStack {
class ItemManager {
private:
SDL_Surface *icons;
- SDL_Rect src;
- SDL_Rect dest;
void load(const std::string& filename);
void loadTypes(const std::string& filename);
View
4 src/LootManager.cpp
@@ -57,7 +57,7 @@ LootManager::LootManager(ItemManager *_items, MapRenderer *_map, StatBlock *_her
FileParser infile;
// load loot animation settings from engine config file
- if (infile.open(mods->locate("engine/loot.txt").c_str())) {
+ if (infile.open(mods->locate("engine/loot.txt"))) {
while (infile.next()) {
infile.val = infile.val + ',';
@@ -96,7 +96,7 @@ LootManager::LootManager(ItemManager *_items, MapRenderer *_map, StatBlock *_her
}
}
infile.close();
- } else fprintf(stderr, "Unable to open engine/loot.txt!\n");
+ }
// reset current map loot
loot.clear();
View
917 src/MapRenderer.cpp
@@ -48,7 +48,6 @@ MapRenderer::MapRenderer(CampaignManager *_camp)
, foreground(NULL)
, collision(NULL)
, shakycam(Point())
- , new_music(false)
, backgroundsurface(NULL)
, backgroundsurfaceoffset()
, repaint_background(false)
@@ -64,6 +63,8 @@ MapRenderer::MapRenderer(CampaignManager *_camp)
, teleportation(false)
, teleport_destination()
, respawn_point()
+ , cutscene(false)
+ , cutscene_file("")
, log_msg("")
, shaky_cam_ticks(0)
, stash(false)
@@ -119,19 +120,14 @@ void MapRenderer::push_enemy_group(Map_Group g) {
int MapRenderer::load(string filename) {
FileParser infile;
- string val;
- maprow *cur_layer;
- Map_Enemy new_enemy;
- Map_Group new_group;
- bool enemy_awaiting_queue = false;
- bool group_awaiting_queue = false;
- bool npc_awaiting_queue = false;
- Map_NPC new_npc;
+ maprow *cur_layer = NULL;
clearEvents();
clearLayers();
clearQueues();
+ std::queue<Map_Group> enemy_groups;
+
/* unload sounds */
snd->reset();
while (!sids.empty()) {
@@ -139,459 +135,451 @@ int MapRenderer::load(string filename) {
sids.pop_back();
}
- cur_layer = NULL;
show_tooltip = false;
- if (!infile.open(mods->locate("maps/" + filename))) {
- cerr << "Unable to open maps/" << filename << endl;
+ if (!infile.open(mods->locate("maps/" + filename)))
return 0;
- }
while (infile.next()) {
if (infile.new_section) {
- if (enemy_awaiting_queue) {
- enemies.push(new_enemy);
- enemy_awaiting_queue = false;
- }
- if (npc_awaiting_queue) {
- npcs.push(new_npc);
- npc_awaiting_queue = false;
- }
- if (group_awaiting_queue) {
- push_enemy_group(new_group);
- group_awaiting_queue = false;
- }
-
// for sections that are stored in collections, add a new object here
- if (infile.section == "enemy") {
- new_enemy = Map_Enemy();
- enemy_awaiting_queue = true;
- }
- else if (infile.section == "enemygroup") {
- new_group.clear();
- group_awaiting_queue = true;
- }
- else if (infile.section == "npc") {
- new_npc.clear();
- npc_awaiting_queue = true;
- }
- else if (infile.section == "event") {
+ if (infile.section == "enemy")
+ enemies.push(Map_Enemy());
+ else if (infile.section == "enemygroup")
+ enemy_groups.push(Map_Group());
+ else if (infile.section == "npc")
+ npcs.push(Map_NPC());
+ else if (infile.section == "event")
events.push_back(Map_Event());
- }
}
- if (infile.section == "header") {
- if (infile.key == "title") {
- this->title = msg->get(infile.val);
- }
- else if (infile.key == "width") {
- this->w = toInt(infile.val);
- }
- else if (infile.key == "height") {
- this->h = toInt(infile.val);
- }
- else if (infile.key == "tileset") {
- this->tileset = infile.val;
- }
- else if (infile.key == "music") {
- if (this->music_filename == infile.val) {
- this->new_music = false;
- }
- else {
- this->music_filename = infile.val;
- this->new_music = true;
- }
- }
- else if (infile.key == "location") {
- spawn.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- spawn.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- spawn_dir = toInt(infile.nextValue());
- }
- }
- else if (infile.section == "layer") {
- if (infile.key == "type") {
- cur_layer = new maprow[w];
- if (infile.val == "background") background = cur_layer;
- else if (infile.val == "fringe") fringe = cur_layer;
- else if (infile.val == "object") object = cur_layer;
- else if (infile.val == "foreground") foreground = cur_layer;
- else if (infile.val == "collision") collision = cur_layer;
- }
- else if (infile.key == "format") {
- if (infile.val != "dec") {
- fprintf(stderr, "ERROR: maploading: The format of a layer must be \"dec\"!\n");
- SDL_Quit();
- exit(1);
- }
- }
- else if (infile.key == "data") {
- // layer map data handled as a special case
- // The next h lines must contain layer data. TODO: err
- for (int j=0; j<h; j++) {
- val = infile.getRawLine() + ',';
- for (int i=0; i<w; i++)
- cur_layer[i][j] = eatFirstInt(val, ',');
- }
- if (cur_layer == collision)
- collider.setmap(collision, w, h);
- }
- }
- else if (infile.section == "enemy") {
- if (infile.key == "type") {
- new_enemy.type = infile.val;
- }
- else if (infile.key == "location") {
- new_enemy.pos.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- new_enemy.pos.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- }
- else if (infile.key == "direction") {
- new_enemy.direction = toInt(infile.val);
- }
- else if (infile.key == "waypoints") {
- string none = "";
- string a = infile.nextValue();
- string b = infile.nextValue();
-
- while (a != none) {
- Point p;
- p.x = toInt(a) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
- p.y = toInt(b) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
- new_enemy.waypoints.push(p);
- a = infile.nextValue();
- b = infile.nextValue();
- }
- } else if (infile.key == "wander_area") {
- new_enemy.wander = true;
- new_enemy.wander_area.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
- new_enemy.wander_area.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
- new_enemy.wander_area.w = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
- new_enemy.wander_area.h = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
- }
- }
- else if (infile.section == "enemygroup") {
- if (infile.key == "type") {
- new_group.category = infile.val;
- }
- else if (infile.key == "level") {
- new_group.levelmin = toInt(infile.nextValue());
- new_group.levelmax = toInt(infile.nextValue());
- }
- else if (infile.key == "location") {
- new_group.pos.x = toInt(infile.nextValue());
- new_group.pos.y = toInt(infile.nextValue());
- new_group.area.x = toInt(infile.nextValue());
- new_group.area.y = toInt(infile.nextValue());
- }
- else if (infile.key == "number") {
- new_group.numbermin = toInt(infile.nextValue());
- new_group.numbermax = toInt(infile.nextValue());
- }
- else if (infile.key == "chance") {
- new_group.chance = toInt(infile.nextValue()) / 100.0f;
- if (new_group.chance > 1.0f) {
- new_group.chance = 1.0f;
- }
- if (new_group.chance < 0.0f) {
- new_group.chance = 0.0f;
- }
- }
- }
- else if (infile.section == "npc") {
- if (infile.key == "type") {
- new_npc.id = infile.val;
- }
- else if (infile.key == "location") {
- new_npc.pos.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- new_npc.pos.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- }
- }
- else if (infile.section == "event") {
- if (infile.key == "type") {
- events.back().type = infile.val;
- }
- else if (infile.key == "location") {
- events.back().location.x = toInt(infile.nextValue());
- events.back().location.y = toInt(infile.nextValue());
- events.back().location.w = toInt(infile.nextValue());
- events.back().location.h = toInt(infile.nextValue());
- }
- else if (infile.key == "hotspot") {
- if (infile.val == "location") {
- events.back().hotspot.x = events.back().location.x;
- events.back().hotspot.y = events.back().location.y;
- events.back().hotspot.w = events.back().location.w;
- events.back().hotspot.h = events.back().location.h;
- }
- else {
- events.back().hotspot.x = toInt(infile.nextValue());
- events.back().hotspot.y = toInt(infile.nextValue());
- events.back().hotspot.w = toInt(infile.nextValue());
- events.back().hotspot.h = toInt(infile.nextValue());
- }
- }
- else if (infile.key == "tooltip") {
- events.back().tooltip = msg->get(infile.val);
- }
- else if (infile.key == "power_path") {
- events.back().power_src.x = toInt(infile.nextValue());
- events.back().power_src.y = toInt(infile.nextValue());
- string dest = infile.nextValue();
- if (dest == "hero") {
- events.back().targetHero = true;
- }
- else {
- events.back().power_dest.x = toInt(dest);
- events.back().power_dest.y = toInt(infile.nextValue());
- }
- }
- else if (infile.key == "power_damage") {
- events.back().damagemin = toInt(infile.nextValue());
- events.back().damagemax = toInt(infile.nextValue());
- }
- else if (infile.key == "cooldown") {
- events.back().cooldown = parse_duration(infile.val);
- }
- else {
- // new event component
- events.back().components.push_back(Event_Component());
- Event_Component *e = &events.back().components.back();
- e->type = infile.key;
-
- if (infile.key == "intermap") {
- e->s = infile.nextValue();
- e->x = toInt(infile.nextValue());
- e->y = toInt(infile.nextValue());
- }
- else if (infile.key == "intramap") {
- e->x = toInt(infile.nextValue());
- e->y = toInt(infile.nextValue());
- }
- else if (infile.key == "mapmod") {
- e->s = infile.nextValue();
- e->x = toInt(infile.nextValue());
- e->y = toInt(infile.nextValue());
- e->z = toInt(infile.nextValue());
-
- // add repeating mapmods
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->s = repeat_val;
- e->x = toInt(infile.nextValue());
- e->y = toInt(infile.nextValue());
- e->z = toInt(infile.nextValue());
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "soundfx") {
- e->s = infile.nextValue();
- e->x = e->y = -1;
+ if (infile.section == "header")
+ loadHeader(infile);
+ else if (infile.section == "layer")
+ loadLayer(infile, &cur_layer);
+ else if (infile.section == "enemy")
+ loadEnemy(infile);
+ else if (infile.section == "enemygroup")
+ loadEnemyGroup(infile, &enemy_groups.back());
+ else if (infile.section == "npc")
+ loadNPC(infile);
+ else if (infile.section == "event")
+ loadEvent(infile);
+ }
- std::string s = infile.nextValue();
- if (s != "") e->x = toInt(s);
+ infile.close();
- s = infile.nextValue();
- if (s != "") e->y = toInt(s);
+ while (!enemy_groups.empty()) {
+ push_enemy_group(enemy_groups.front());
+ enemy_groups.pop();
+ }
- }
- else if (infile.key == "loot") {
- e->s = infile.nextValue();
- e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
-
- // drop chance
- string chance = infile.nextValue();
- if (chance == "fixed") e->z = 0;
- else e->z = toInt(chance);
-
- // quantity min/max
- e->a = toInt(infile.nextValue());
- if (e->a < 1) e->a = 1;
- e->b = toInt(infile.nextValue());
- if (e->b < e->a) e->b = e->a;
-
- // add repeating loot
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->s = repeat_val;
- e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
-
- string chance = infile.nextValue();
- if (chance == "fixed") e->z = 0;
- else e->z = toInt(chance);
-
- e->a = toInt(infile.nextValue());
- if (e->a < 1) e->a = 1;
- e->b = toInt(infile.nextValue());
- if (e->b < e->a) e->b = e->a;
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "msg") {
- e->s = msg->get(infile.val);
- }
- else if (infile.key == "shakycam") {
- e->x = toInt(infile.val);
- }
- else if (infile.key == "requires_status") {
- e->s = infile.nextValue();
-
- // add repeating requires_status
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->s = repeat_val;
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "requires_not") {
- e->s = infile.nextValue();
-
- // add repeating requires_not
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->s = repeat_val;
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "requires_level") {
- e->x = toInt(infile.nextValue());
- }
- else if (infile.key == "requires_not_level") {
- e->x = toInt(infile.nextValue());
- }
- else if (infile.key == "requires_item") {
- e->x = toInt(infile.nextValue());
-
- // add repeating requires_item
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->x = toInt(repeat_val);
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "set_status") {
- e->s = infile.nextValue();
-
- // add repeating set_status
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->s = repeat_val;
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "unset_status") {
- e->s = infile.nextValue();
-
- // add repeating unset_status
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->s = repeat_val;
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "remove_item") {
- e->x = toInt(infile.nextValue());
-
- // add repeating remove_item
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
- e->x = toInt(repeat_val);
-
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "reward_xp") {
- e->x = toInt(infile.val);
- }
- else if (infile.key == "power") {
- e->x = toInt(infile.val);
- }
- else if (infile.key == "spawn") {
+ tset.load(this->tileset);
- e->s = infile.nextValue();
- e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+ // some events automatically trigger when the map loads
+ // e.g. change map state based on campaign status
+ executeOnLoadEvents();
- // add repeating spawn
- string repeat_val = infile.nextValue();
- while (repeat_val != "") {
- events.back().components.push_back(Event_Component());
- e = &events.back().components.back();
- e->type = infile.key;
+ return 0;
+}
- e->s = repeat_val;
- e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
- e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+void MapRenderer::loadHeader(FileParser &infile)
+{
+ if (infile.key == "title") {
+ this->title = msg->get(infile.val);
+ }
+ else if (infile.key == "width") {
+ this->w = toInt(infile.val);
+ }
+ else if (infile.key == "height") {
+ this->h = toInt(infile.val);
+ }
+ else if (infile.key == "tileset") {
+ this->tileset = infile.val;
+ }
+ else if (infile.key == "music") {
+ loadMusic(infile.val);
+ }
+ else if (infile.key == "location") {
+ spawn.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+ spawn.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+ spawn_dir = toInt(infile.nextValue());
+ }
+}
- repeat_val = infile.nextValue();
- }
- }
- else if (infile.key == "npc") {
- new_npc.id = infile.val;
- e->s = infile.val;
- }
- else if (infile.key == "music") {
- e->s = infile.val;
- }
- }
+void MapRenderer::loadLayer(FileParser &infile, maprow **current_layer)
+{
+ if (infile.key == "type") {
+ *current_layer = new maprow[w];
+ if (infile.val == "background") background = *current_layer;
+ else if (infile.val == "fringe") fringe = *current_layer;
+ else if (infile.val == "object") object = *current_layer;
+ else if (infile.val == "foreground") foreground = *current_layer;
+ else if (infile.val == "collision") collision = *current_layer;
+ }
+ else if (infile.key == "format") {
+ if (infile.val != "dec") {
+ fprintf(stderr, "ERROR: maploading: The format of a layer must be \"dec\"!\n");
+ SDL_Quit();
+ exit(1);
}
}
+ else if (infile.key == "data") {
+ // layer map data handled as a special case
+ // The next h lines must contain layer data. TODO: err
+ for (int j=0; j<h; j++) {
+ string val = infile.getRawLine() + ',';
+ for (int i=0; i<w; i++)
+ (*current_layer)[i][j] = eatFirstInt(val, ',');
+ }
+ if ((*current_layer) == collision)
+ collider.setmap(collision, w, h);
+ }
+}
- infile.close();
+void MapRenderer::loadEnemy(FileParser &infile)
+{
+ if (infile.key == "type") {
+ enemies.back().type = infile.val;
+ }
+ else if (infile.key == "location") {
+ enemies.back().pos.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+ enemies.back().pos.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+ }
+ else if (infile.key == "direction") {
+ enemies.back().direction = toInt(infile.val);
+ }
+ else if (infile.key == "waypoints") {
+ string none = "";
+ string a = infile.nextValue();
+ string b = infile.nextValue();
+
+ while (a != none) {
+ Point p;
+ p.x = toInt(a) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
+ p.y = toInt(b) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
+ enemies.back().waypoints.push(p);
+ a = infile.nextValue();
+ b = infile.nextValue();
+ }
+ } else if (infile.key == "wander_area") {
+ enemies.back().wander = true;
+ enemies.back().wander_area.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
+ enemies.back().wander_area.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
+ enemies.back().wander_area.w = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
+ enemies.back().wander_area.h = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
+ }
+}
- // reached end of file. Handle any final sections.
- if (enemy_awaiting_queue)
- enemies.push(new_enemy);
+void MapRenderer::loadEnemyGroup(FileParser &infile, Map_Group *group)
+{
+ if (infile.key == "type") {
+ group->category = infile.val;
+ }
+ else if (infile.key == "level") {
+ group->levelmin = toInt(infile.nextValue());
+ group->levelmax = toInt(infile.nextValue());
+ }
+ else if (infile.key == "location") {
+ group->pos.x = toInt(infile.nextValue());
+ group->pos.y = toInt(infile.nextValue());
+ group->area.x = toInt(infile.nextValue());
+ group->area.y = toInt(infile.nextValue());
+ }
+ else if (infile.key == "number") {
+ group->numbermin = toInt(infile.nextValue());
+ group->numbermax = toInt(infile.nextValue());
+ }
+ else if (infile.key == "chance") {
+ float n = toInt(infile.nextValue()) / 100.0f;
+ group->chance = min(1.0f, max(0.0f, n));
+ }
+}
- if (npc_awaiting_queue)
- npcs.push(new_npc);
+void MapRenderer::loadNPC(FileParser &infile)
+{
+ if (infile.key == "type") {
+ npcs.back().id = infile.val;
+ }
+ else if (infile.key == "location") {
+ npcs.back().pos.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+ npcs.back().pos.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
+ }
+}
- if (group_awaiting_queue)
- push_enemy_group(new_group);
+void MapRenderer::loadEvent(FileParser &infile)
+{
+ if (infile.key == "type") {
+ events.back().type = infile.val;
+ }
+ else if (infile.key == "location") {
+ events.back().location.x = toInt(infile.nextValue());
+ events.back().location.y = toInt(infile.nextValue());
+ events.back().location.w = toInt(infile.nextValue());
+ events.back().location.h = toInt(infile.nextValue());
+ }
+ else if (infile.key == "hotspot") {
+ if (infile.val == "location") {
+ events.back().hotspot.x = events.back().location.x;
+ events.back().hotspot.y = events.back().location.y;
+ events.back().hotspot.w = events.back().location.w;
+ events.back().hotspot.h = events.back().location.h;
+ }
+ else {
+ events.back().hotspot.x = toInt(infile.nextValue());
+ events.back().hotspot.y = toInt(infile.nextValue());
+ events.back().hotspot.w = toInt(infile.nextValue());
+ events.back().hotspot.h = toInt(infile.nextValue());
+ }
+ }
+ else if (infile.key == "tooltip") {
+ events.back().tooltip = msg->get(infile.val);
+ }
+ else if (infile.key == "power_path") {
+ events.back().power_src.x = toInt(infile.nextValue());
+ events.back().power_src.y = toInt(infile.nextValue());
+ string dest = infile.nextValue();
+ if (dest == "hero") {
+ events.back().targetHero = true;
+ }
+ else {
+ events.back().power_dest.x = toInt(dest);
+ events.back().power_dest.y = toInt(infile.nextValue());
+ }
+ }
+ else if (infile.key == "power_damage") {
+ events.back().damagemin = toInt(infile.nextValue());
+ events.back().damagemax = toInt(infile.nextValue());
+ }
+ else if (infile.key == "cooldown") {
+ events.back().cooldown = parse_duration(infile.val);
+ }
+ else {
+ loadEventComponent(infile);
+ }
+}
- if (this->new_music) {
- loadMusic();
- this->new_music = false;
+void MapRenderer::loadEventComponent(FileParser &infile)
+{
+ // new event component
+ events.back().components.push_back(Event_Component());
+ Event_Component *e = &events.back().components.back();
+ e->type = infile.key;
+
+ if (infile.key == "intermap") {
+ e->s = infile.nextValue();
+ e->x = toInt(infile.nextValue());