added some comments

This commit is contained in:
Dave White 2003-11-12 18:37:30 +00:00
parent ad64775682
commit d64e04a5ca
27 changed files with 520 additions and 147 deletions

View file

@ -10,6 +10,7 @@
See the COPYING file for more details.
*/
#ifndef ACTIONS_H_INCLUDED
#define ACTIONS_H_INCLUDED
@ -24,11 +25,26 @@
#include <map>
#include <string>
std::string recruit_unit(const gamemap& map, int team,
std::map<gamemap::location,unit>& units,
unit& unit, gamemap::location preferred_location,
//this file defines various functions which implement different in-game
//events and commands.
//recruit_unit: function which recruits a unit into the game. A
//copy of u will be created and inserted as the new recruited unit.
//If need_castle is true, then the new unit must be on the same castle
//as the leader of the team is on the keep of.
//
//If preferred_location is in a valid location, it will be used, otherwise
//a valid location will be arbitrarily chosen. If disp is not NULL, the
//new unit will be faded in.
//
//If the unit cannot be recruited, then a human-readable message
//describing why not will be returned. On success, the return string is empty
std::string recruit_unit(const gamemap& map, int team, unit_map& units,
unit& u, gamemap::location preferred_location,
display *disp=NULL, bool need_castle=true);
//a structure which defines all the statistics for a potential
//battle that could take place.
struct battle_stats
{
std::string attack_name, defend_name;
@ -43,6 +59,19 @@ struct battle_stats
bool attacker_plague, defender_plague;
};
//evaluate_battle_stats: a function which, if given an attacker
//and defender, and the number of a weapon to use, will report
//the statistics if that battle were to take place.
//
//attacker_terrain_override allows a different terrain to the
//one currently stood on by the attacker to be used in calculating
//the statistics. This is useful if one wants to look at the
//statistics if an attacker were to attack from one of several
//different locations.
//
//if include_strings is false, then none of the strings in
//battle_stats will be populated, and the function will run
//substantially faster.
battle_stats evaluate_battle_stats(
const gamemap& map,
const gamemap::location& attacker,
@ -54,6 +83,7 @@ battle_stats evaluate_battle_stats(
gamemap::TERRAIN attacker_terrain_override=0,
bool include_strings=true);
//attack: executes an attack.
void attack(display& gui, const gamemap& map,
const gamemap::location& attacker,
const gamemap::location& defender,
@ -62,42 +92,62 @@ void attack(display& gui, const gamemap& map,
const gamestatus& state,
const game_data& info, bool player_is_attacker);
//given the location of a village, will return the 0-based index of the team
//that currently owns it, and -1 if it is unowned.
int tower_owner(const gamemap::location& loc, std::vector<team>& teams);
//makes it so the tower at the given location is owned by the given
//0-based team number
void get_tower(const gamemap::location& loc, std::vector<team>& teams,
int team_num);
//given the 1-based side, will find the leader of that side,
//and return an iterator to the leader
std::map<gamemap::location,unit>::iterator
find_leader(std::map<gamemap::location,unit>& units, int side);
//calculates healing for all units for the given side. Should be called
//at the beginning of a side's turn.
void calculate_healing(display& disp, const gamemap& map,
std::map<gamemap::location,unit>& units, int side);
//function which, given the location of a unit that is advancing, and the
//name of the unit it is advancing to, will return the advanced version of
//this unit. (with traits and items retained).
unit get_advanced_unit(const game_data& info,
std::map<gamemap::location,unit>& units,
const gamemap::location& loc, const std::string& advance_to);
//function which will advance the unit at loc to 'advance_to'.
void advance_unit(const game_data& info,
std::map<gamemap::location,unit>& units,
const gamemap::location& loc, const std::string& advance_to);
//function which returns true iff the unit at loc is currently affected
//by leadership. (i.e. has a higher-level 'leadership' unit next to it)
bool under_leadership(const std::map<gamemap::location,unit>& units,
const gamemap::location& loc);
//checks to see if a side has won, and will throw an end_level_exception
//if one has.
void check_victory(std::map<gamemap::location,unit>& units,
const std::vector<team>& teams);
//gets the time of day at a certain tile. Certain tiles may have a time of
//day that differs from 'the' time of day, if a unit that brings light is there
//day that differs from 'the' time of day, if a unit that illuminates is
//in that tile or adjacent.
const time_of_day& timeofday_at(const gamestatus& status,
const std::map<gamemap::location,unit>& units,
const gamemap::location& loc);
//returns the amount that a unit's damage should be multiplied by due to
//the current time of day.
double combat_modifier(const gamestatus& status,
const std::map<gamemap::location,unit>& units,
const gamemap::location& loc,
unit_type::ALIGNMENT alignment);
//structure which records information to be able to undo a movement
struct undo_action {
undo_action(const std::vector<gamemap::location>& rt,int sm,int orig=-1)
: route(rt), starting_moves(sm), original_village_owner(orig) {}
@ -108,14 +158,22 @@ struct undo_action {
typedef std::deque<undo_action> undo_list;
//function which moves a unit along the sequence of locations given by
//steps. If the unit cannot make it completely along the path this turn,
//a goto order will be set. If move_recorder is not NULL, the move will
//be recorded in it. If undos is not NULL, undo information will be added.
size_t move_unit(display* disp, const gamemap& map,
unit_map& units, std::vector<team>& teams,
const std::vector<gamemap::location>& steps,
replay* move_recorder, undo_list* undos);
//function which will clear shroud away for the given 0-based team based on
//current unit positions. Returns true if some shroud is actually cleared away.
bool clear_shroud(display& disp, const gamemap& map, const game_data& gamedata,
const unit_map& units, std::vector<team>& teams, int team);
//will return true iff the unit at 'loc' has any possible moves it can do
//(including attacking etc).
bool unit_can_move(const gamemap::location& loc, const unit_map& units,
const gamemap& map, const std::vector<team>& teams);

View file

@ -2306,7 +2306,7 @@ bool display::update_locked() const
bool display::turbo() const
{
bool res = turbo_;
if(keys_[KEY_LSHIFT] || keys_[KEY_RSHIFT])
if(keys_[SDLK_LSHIFT] || keys_[SDLK_RSHIFT])
res = !res;
return res;

View file

@ -28,6 +28,19 @@
#include <set>
#include <string>
//display: class which takes care of displaying the map and
//game-data on the screen.
//
//the display is divided into two main sections: the game area,
//which displays the tiles of the game board, and units on them,
//and the side bar, which appears on the right hand side. The side bar
//display is divided into three sections:
// - the minimap, which is displayed at the top right
// - the game status, which includes the day/night image, the turn number,
// information about the current side, and information about the hex
// currently moused over (highlighted)
// - the unit status, which displays an image for, and stats for, the
// current unit.
class display
{
public:
@ -39,88 +52,190 @@ public:
const std::vector<team>& t);
~display();
//new_turn should be called on every new turn, to update
//lighting settings.
void new_turn();
//function to make it so a unit is 'hidden' - not displayed
//when the tile it is on is drawn. Only one unit may be hidden
//at a time. The previously hidden unit will be returned.
gamemap::location hide_unit(const gamemap::location& loc);
//function which given rgb values, will return the equivalent pixel
//for the frame buffer surface.
Pixel rgb(int r, int g, int b) const;
//function which scrolls the display by xmov,ymov. Invalidation and
//redrawing will be scheduled.
void scroll(double xmov, double ymov);
//function which zooms the display by the specified amount. Negative
//valeus zoom out.
void zoom(double amount);
//function to take the zoom amount to the default.
void default_zoom();
enum SCROLL_TYPE { SCROLL, WARP };
//function which will scroll such that location x,y is on-screen.
void scroll_to_tile(int x, int y, SCROLL_TYPE scroll_type=SCROLL);
//function which will scroll such that location x1,y1 is on-screen.
//it will also try to make it such that x2,y2 is on-screen but this
//is not guaranteed.
void scroll_to_tiles(int x1, int y1, int x2, int y2,
SCROLL_TYPE scroll_type=SCROLL);
//invalidates entire screen, including all tiles and sidebar.
void redraw_everything();
//draws invalidated items. If update is true, will also copy the
//display to the frame buffer. If force is true, will not skip frames,
//even if running behind.
void draw(bool update=true,bool force=false);
//the dimensions of the display. x and y are width/height. mapx is the
//width of the portion of the display which shows the game area. Between
//mapx and x is the sidebar region.
int x() const;
int mapx() const;
int y() const;
SDL_Rect screen_area() const;
//function to display a location as selected. If a unit is in the location,
//and there is no unit in the currently highlighted hex, the unit will be
//displayed in the sidebar.
void select_hex(gamemap::location hex);
//function to highlight a location. If a unit is in the location, it will
//be displayed in the sidebar. Selection is used when a unit has been
//clicked on, while highlighting is used when a location has been moused
//over
void highlight_hex(gamemap::location hex);
//given x,y co-ordinates of the mouse, will return the location of the
//hex that the mouse is currently over. Returns an invalid location is
//the mouse isn't over any valid location.
gamemap::location hex_clicked_on(int x, int y);
//given x,y co-ordinates of the mouse, will return the location of the
//hex in the minimap that the mouse is currently over, or an invalid
//location if the mouse isn't over the minimap.
gamemap::location minimap_location_on(int x, int y);
//sets the paths that are currently displayed as available for the unit
//to move along. All other paths will be greyed out. If NULL, no paths
//will be displayed as selected.
//paths_list must remain valid until it is set again
void set_paths(const paths* paths_list);
//sets the route along which footsteps are drawn to show movement of a
//unit. If NULL, no route is displayed.
//route does not have to remain valid after being set
void set_route(const paths::route* route);
//functions to get the on-screen positions of hexes.
double get_location_x(const gamemap::location& loc) const;
double get_location_y(const gamemap::location& loc) const;
//function to display movement of a unit along the given sequence of tiles
void move_unit(const std::vector<gamemap::location>& path, unit& u);
//function to show one unit taking one attack attempt at another. damage
//is the amount of damage inflicted, and 0 if the attack misses.
bool unit_attack(const gamemap::location& a, const gamemap::location& b,
int damage, const attack_type& attack);
//function to draw the tile at location (x,y). If unit_image is not NULL,
//then it will be used, otherwise the unit's default image will be used.
//alpha controls how faded the unit is. If blend_to is not 0, then the
//unit will be alpha-blended to blend_to instead of the background colour
void draw_tile(int x, int y, SDL_Surface* unit_image=NULL,
double alpha=1.0, short blend_to=0);
//function to draw a footstep for the given location, on screen at
//pixel co-ordinates (xloc,yloc). A footstep will only be drawn if
//loc is on the current route set by set_route. Otherwise it will
//return with no effect.
void draw_footstep(const gamemap::location& loc, int xloc, int yloc);
//gets the underlying screen object.
CVideo& video() { return screen_; }
//blits a surface with black as alpha
void blit_surface(int x, int y, SDL_Surface* surface);
//function to invalidate all tiles.
void invalidate_all();
//function to invalidate the game status displayed on the sidebar.
void invalidate_game_status();
//function to invalidate that unit status displayed on the sidebar.
void invalidate_unit();
//function to schedule the minimap for recalculation. Useful if any
//terrain in the map has changed.
void recalculate_minimap();
//functions to add and remove overlays from locations. An overlay is an
//image that is displayed on top of the tile. One tile may have multiple
//overlays. remove_overlay will remove all overlays on a tile.
void add_overlay(const gamemap::location& loc, const std::string& image);
void remove_overlay(const gamemap::location& loc);
//function which draws the details of the unit at the given location, at
//(x,y) on-screen. xprofile and yprofile are the size of the unit's image.
//this function is suitable for drawing a unit's details on the sidebar,
//but can also be used to draw the unit details on a dialog elsewhere on
//the screen.
void draw_unit_details(int x, int y, const gamemap::location& loc,
const unit& u, SDL_Rect& description_rect,
int xprofile,int yprofile,SDL_Rect* clip_rect=NULL);
//function which copies the backbuffer to the framebuffer.
void update_display();
//functions used in the editor.
void draw_terrain_palette(int x, int y, gamemap::TERRAIN selected);
gamemap::TERRAIN get_terrain_on(int palx, int paly, int x, int y);
//set_team sets the team controlled by the player using the computer,
//and it is this team whose data is displayed in the game status.
//set_playing_team sets the team whose turn it currently is
void set_team(size_t team);
void set_playing_team(size_t team);
//makes it so that the unit at the given location will be displayed
//in an advancing-highlight with intensity between 0.0 and 1.0 given
//by amount.
void set_advancing_unit(const gamemap::location& loc, double amount);
//function to stop the screen being redrawn. Anything that happens while
//the update is locked will be hidden from the user's view.
//note that this function is re-entrant, meaning that if lock_updates(true)
//is called twice, lock_updates(false) must be called twice to unlock
//updates.
void lock_updates(bool value);
bool update_locked() const;
//functions to set/get whether 'turbo' mode is on. When turbo mode is on,
//everything moves much faster.
bool turbo() const;
void set_turbo(bool turbo);
//function which determines whether a grid should be overlayed on the
//game board to more clearly show where hexes are.
void set_grid(bool grid);
//a debug highlight draws a cross on a tile to emphasize something there.
//it is used in debug mode, typically to show AI plans.
static void debug_highlight(const gamemap::location& loc, double amount);
static void clear_debug_highlights();
//function which returns true if location (x,y) is covered in shroud.
bool shrouded(int x, int y) const;
private:
@ -226,6 +341,7 @@ private:
static std::map<gamemap::location,double> debugHighlights_;
};
//an object which will lock the display for the duration of its lifetime.
struct update_locker
{
update_locker(display& d, bool lock=true) : disp(d), unlock(lock) {

View file

@ -82,7 +82,7 @@ int main(int argc, char** argv)
std::cerr << "starting for(;;)\n";
for(;;) {
if(key[KEY_ESCAPE])
if(key[SDLK_ESCAPE])
break;
int mousex, mousey;
@ -90,25 +90,25 @@ int main(int argc, char** argv)
const bool new_left_button = mouse_flags & SDL_BUTTON_LMASK;
const bool new_right_button = mouse_flags & SDL_BUTTON_RMASK;
if(key[KEY_UP] || mousey == 0)
if(key[SDLK_UP] || mousey == 0)
gui.scroll(0.0,-scroll_speed);
if(key[KEY_DOWN] || mousey == gui.y()-1)
if(key[SDLK_DOWN] || mousey == gui.y()-1)
gui.scroll(0.0,scroll_speed);
if(key[KEY_LEFT] || mousex == 0)
if(key[SDLK_LEFT] || mousex == 0)
gui.scroll(-scroll_speed,0.0);
if(key[KEY_RIGHT] || mousex == gui.x()-1)
if(key[SDLK_RIGHT] || mousex == gui.x()-1)
gui.scroll(scroll_speed,0.0);
if(key[KEY_Z])
if(key[SDLK_Z])
gui.zoom(zoom_amount);
if(key[KEY_X])
if(key[SDLK_X])
gui.zoom(-zoom_amount);
if(key[KEY_D])
if(key[SDLK_D])
gui.default_zoom();
gui.highlight_hex(gui.hex_clicked_on(mousex,mousey));

View file

@ -5,6 +5,9 @@
namespace events
{
//an object which prevents resizing of the screen occuring during
//its lifetime.
struct resize_lock {
resize_lock();
~resize_lock();
@ -13,7 +16,8 @@ struct resize_lock {
//any classes that derive from this class will automatically
//receive sdl events through the handle function for their lifetime
//note that handlers should *always* be allocated as automatic variables
//(never on the free store or in static memory)
//(never on the free store or in static memory), as the event mechanism
//relies on handlers being created and destroyed in LIFO ordering.
class handler
{
public:
@ -26,6 +30,7 @@ private:
const int unicode_;
};
//causes events to be dispatched to all handler objects.
void pump();
}

View file

@ -18,15 +18,23 @@
enum FILE_NAME_MODE { ENTIRE_FILE_PATH, FILE_NAME_ONLY };
//function which populates files with all the files and dirs
//with all the directories in dir. If files or dirs are NULL
//they will not be used.
//
//mode determines whether the entire path or just the filename
//is retrieved.
void get_files_in_dir(const std::string& dir,
std::vector<std::string>* files,
std::vector<std::string>* dirs=NULL,
FILE_NAME_MODE mode=FILE_NAME_ONLY);
//the location of various important files
std::string get_prefs_file();
std::string get_saves_dir();
std::string get_user_data_dir();
//function which returns true iff the given file is a directory
bool is_directory(const std::string& fname);
#endif

View file

@ -22,18 +22,37 @@
namespace font {
//object which initializes and destroys structures needed for fonts
struct manager {
manager();
~manager();
};
//function which, given a 1-based side, will return the colour of
//that side.
const SDL_Color& get_side_colour(int side);
//various standard colours
extern const SDL_Color NORMAL_COLOUR, GOOD_COLOUR, BAD_COLOUR, BLACK_COLOUR,
BUTTON_COLOUR;
enum MARKUP { USE_MARKUP, NO_MARKUP };
//function to draw text on the screen. The text will be clipped to area.
//If the text runs outside of area horizontally, an ellipsis will be displayed
//at the end of it. If use_tooltips is true, then text with an ellipsis will
//have a tooltip set for it equivalent to the entire contents of the text.
//
//if use_markup is equal to USE_MARKUP, then some very basic 'markup' will
//be done on the text:
// - any line beginning in # will be displayed in BAD_COLOUR
// - any line beginning in @ will be displayed in GOOD_COLOUR
// - any line beginning in + will be displayed with size increased by 2
// - any line beginning in - will be displayed with size decreased by 2
// - any line beginning with 0x0n will be displayed in the colour of side n
//
//a bounding rectangle of the text is returned. If gui is NULL, then the
//text will not be drawn, and a bounding rectangle only will be returned.
SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
const SDL_Color& colour, const std::string& text,
int x, int y, SDL_Surface* bg=NULL,

View file

@ -15,6 +15,7 @@
#include <string>
//basic game configuration information is here.
namespace game_config
{
extern const int unit_cost;

View file

@ -23,24 +23,34 @@
#include <map>
//this file defines the game's events mechanism. Events might be units
//moving or fighting, or when victory or defeat occurs. A scenario's
//configuration file will define actions to take when certain events
//occur. This module is responsible for making sure that when the events
//occur, the actions take place.
//
//note that game events have nothing to do with SDL events, like mouse
//movement, keyboard events, etc. See events.hpp for how they are handled.
namespace game_events
{
bool conditional_passed(game_state& state_of_game,
const std::map<gamemap::location,unit>* units,
config& cond);
//the game event manager loads the scenario configuration object, and
//ensures that events are handled according to the scenario configuration
//for its lifetime.
//
//thus, a manager object should be created when a scenario is played, and
//destroyed at the end of the scenario.
struct manager {
manager(config& cfg, display& disp, gamemap& map,
//note that references will be maintained, and must remain valid
//for the life of the object.
manager(config& scenario_cfg, display& disp, gamemap& map,
std::map<gamemap::location,unit>& units, std::vector<team>& teams,
game_state& state_of_game, game_data& data);
~manager();
};
void raise(const std::string& event,
const gamemap::location& loc1=gamemap::location::null_location,
const gamemap::location& loc2=gamemap::location::null_location);
//function to fire an event. Events may have up to two arguments, both of
//which must be locations.
bool fire(const std::string& event,
const gamemap::location& loc1=gamemap::location::null_location,
const gamemap::location& loc2=gamemap::location::null_location);

View file

@ -19,16 +19,26 @@
#include <string>
#include <vector>
//an object which defines the current time of day
struct time_of_day
{
explicit time_of_day(config& cfg);
//the % bonus lawful units receive. chaotic units will
//receive -lawful_bonus.
int lawful_bonus;
//the image to be displayed in the game status.
std::string image;
std::string name;
//the colour modifications that should
//be made to the game board to reflect the time of day.
int red, green, blue;
};
//class which contains the global status of the game -- namely
//the current turn, the number of turns, and the time of day.
class gamestatus
{
public:
@ -38,8 +48,11 @@ public:
size_t turn() const;
size_t number_of_turns() const;
//function to move to the next turn. Returns true iff time
//has expired.
bool next_turn();
//an exception object used when loading a game fails.
struct load_game_failed {
load_game_failed() {}
load_game_failed(const std::string& msg) : message(msg) {}
@ -47,6 +60,8 @@ public:
std::string message;
};
//an exception object used for any general game error.
//e.g. data files are corrupt.
struct game_error {
game_error(const std::string& msg) : message(msg) {}
std::string message;
@ -59,24 +74,35 @@ private:
size_t numTurns_;
};
//object which holds all the data needed to start a scenario.
//i.e. this is the object serialized to disk when saving/loading a game.
//is also the object which needs to be created to start a nwe game
struct game_state
{
game_state() : gold(-1), difficulty("NORMAL") {}
std::string label;
std::string version;
std::string campaign_type;
std::string scenario;
int gold;
std::vector<unit> available_units;
std::map<std::string,std::string> variables;
std::string difficulty;
std::string label; //name of the game (e.g. name of save file)
std::string version; //version game was created with.
std::string campaign_type; //type of the game - campaign, multiplayer etc
std::string scenario; //the scenario being played
int gold; //amount of gold the player has saved
std::vector<unit> available_units; //units the player has to recall
std::map<std::string,std::string> variables; //variables that have been set
std::string difficulty; //the difficulty level the game is being played on.
//if the game is saved mid-level, we have a series of replay steps to
//take the game up to the position it was saved at.
config replay_data;
//information about the starting conditions of the scenario. Used in
//multiplayer games, when the starting position isn't just literally
//read from a file, since there is game setup information.
config starting_pos;
};
//function to get a list of available saves.
std::vector<std::string> get_saves_list();
//functions to load/save games.
void load_game(game_data& data, const std::string& name, game_state& state);
void save_game(const game_state& state);

View file

@ -18,7 +18,26 @@
#include "events.hpp"
#include "key.hpp"
//the hotkey system allows hotkey definitions to be loaded from
//configuration objects, and then detect if a keyboard event
//refers to a hotkey command being executed.
namespace hotkey {
//function to load a hotkey configuration object. hotkey configuration objects
//are a list of nodes that look like:
//[hotkey]
//command='cmd'
//key='k'
//ctrl=(yes|no)
//alt=(yes|no)
//shift=(yes|no)
//[/hotkey]
//where 'cmd' is a command name, and 'k' is a key. see hotkeys.cpp for the
//valid command names.
void add_hotkeys(config& cfg);
//abstract base class for objects that implement the ability
//to execute hotkey commands.
class command_executor
{
public:
@ -38,6 +57,13 @@ public:
virtual void recruit() = 0;
};
//function to be called every time a key event is intercepted. Will
//call the relevant function in executor if the keyboard event is
//not NULL. Also handles some events in the function itself, and so
//is still meaningful to call with executor=NULL
void key_event(display& disp, const SDL_KeyboardEvent& event,
command_executor* executor);
//object which will ensure that basic keyboard events like escape
//are handled properly for the duration of its lifetime
struct basic_handler : public events::handler {
@ -49,11 +75,6 @@ private:
display& disp_;
};
void add_hotkeys(config& cfg);
void key_event(display& disp, const SDL_KeyboardEvent& event,
command_executor* executor);
}
#endif

View file

@ -7,20 +7,49 @@
#include <string>
//this module manages the cache of images. With an image name, you can get
//the surface corresponding to that image, and don't need to free the image.
//Note that surfaces returned from here are invalidated whenever events::pump()
//is called, and so shouldn't be kept, but should be regotten from here as
//needed.
//
//images come in a number of varieties:
// - unscaled: no modifications have been done on the image.
// - scaled: images are scaled to the size of a tile
// - greyed: images are scaled and in greyscale
// - brightened: images are scaled and brighter than normal.
namespace image {
//the image manager is responsible for setting up images, and destroying
//all images when the program exits. It should probably
//be created once for the life of the program
struct manager
{
manager();
~manager();
};
//will make all scaled images have these rgb values added to all
//their pixels. i.e. add a certain colour hint to images. useful
//for representing day/night. Invalidates all scaled images.
void set_colour_adjustment(int r, int g, int b);
//sets the pixel format used by the images. Is called every time the
//video mode changes. Invalidates all images.
void set_pixel_format(SDL_PixelFormat* format);
//sets the amount scaled images should be scaled. Invalidates all
//scaled images.
void set_zoom(double zoom);
enum TYPE { UNSCALED, SCALED, GREYED, BRIGHTENED };
//function to get the surface corresponding to an image.
SDL_Surface* get_image(const std::string& filename,TYPE type=SCALED);
//function to get a scaled image, but scale it to specific dimensions.
//if you later try to get the same image using get_image() the image will
//have the dimensions specified here.
SDL_Surface* get_image_dim(const std::string& filename, size_t x, size_t y);
}

View file

@ -114,11 +114,11 @@ void show_intro(display& screen, config& data)
events::pump();
if(key[KEY_ESCAPE] ||
if(key[SDLK_ESCAPE] ||
skip_button.process(mousex,mousey,left_button))
return;
if(key[KEY_SPACE] || key[KEY_ENTER] ||
if(key[SDLK_SPACE] || key[SDLK_RETURN] ||
next_button.process(mousex,mousey,left_button)) {
if(!last)
break;
@ -217,7 +217,7 @@ void show_map_scene(display& screen, config& data)
update_rect(dstrect);
for(int i = 0; i != 50; ++i) {
if(key[KEY_ESCAPE]) {
if(key[SDLK_ESCAPE]) {
break;
}
@ -227,19 +227,19 @@ void show_map_scene(display& screen, config& data)
int a, b;
const int mouse_flags = SDL_GetMouseState(&a,&b);
if(key[KEY_ENTER] || key[KEY_SPACE] || mouse_flags) {
if(key[SDLK_RETURN] || key[SDLK_SPACE] || mouse_flags) {
break;
}
}
if(key[KEY_ESCAPE]) {
if(key[SDLK_ESCAPE]) {
break;
}
screen.video().flip();
}
if(!key[KEY_ESCAPE]) {
if(!key[SDLK_ESCAPE]) {
SDL_Delay(500);
}
@ -258,8 +258,8 @@ void show_map_scene(display& screen, config& data)
int a, b;
const int mouse_flags = SDL_GetMouseState(&a,&b);
const bool new_state = mouse_flags || key[KEY_ESCAPE] ||
key[KEY_ENTER] || key[KEY_SPACE];
const bool new_state = mouse_flags || key[SDLK_ESCAPE] ||
key[SDLK_RETURN] || key[SDLK_SPACE];
if(new_state && !last_state)
break;

View file

@ -19,8 +19,35 @@
#include <string>
//function to show an introduction sequence specified by data.
//the format of data is like,
//[part]
//id='id'
//story='story'
//image='img'
//[/part]
//where 'id' is a unique identifier, 'story' is text describing
//storyline, and 'img' is an image.
//
//each part of the sequence will be displayed in turn, with the
//user able to go to the next part, or skip it entirely.
void show_intro(display& screen, config& data);
//function to show the map before each scenario.
//data is in a format that looks like,
//[bigmap]
//image='map-image'
// [dot]
// x='x'
// y='y'
// type=cross (optional)
// [/dot]
// ... more 'dot' nodes'
//[/bigmap]
//
//where 'map-image' is the image of the map. dots are displayed
//at 'x','y' on the image in sequence. type=cross should be used
//for the last dot, to show where the battle takes place.
void show_map_scene(display& screen, config& data);
#endif

View file

@ -27,7 +27,7 @@ int main( void )
for(;;) {
if( key[KEY_RETURN] != 0 )
printf( "key(ENTER) pressed\n" );
if( key[KEY_ESCAPE] != 0 )
if( key[SDLK_ESCAPE] != 0 )
return 1;
}
}
@ -42,7 +42,7 @@ CKey::CKey() : is_enabled(true)
int CKey::operator[]( int code )
{
return (code == KEY_ESCAPE || is_enabled) && int(key_list[code]);
return (code == SDLK_ESCAPE || is_enabled) && int(key_list[code]);
}
void CKey::SetEnabled( bool enable )

View file

@ -10,87 +10,26 @@
See the COPYING file for more details.
*/
#ifndef KEY_HPP_INCLUDED
#define KEY_HPP_INCLUDED
#include "SDL.h"
//object which keeps track of all the keys on the keyboard, and
//whether any key is pressed or not can be found by using its
//operator[]. Note though that it is generally better to use
//key events to see when keys are pressed rather than poll using
//this object.
class CKey {
public:
public:
CKey();
int operator[](int);
void SetEnabled(bool enable);
private:
private:
Uint8 *key_list;
bool is_enabled;
};
#define KEY_PAGEUP SDLK_PAGEUP
#define KEY_PAGEDOWN SDLK_PAGEDOWN
#define KEY_BACKSPACE SDLK_BACKSPACE
#define KEY_DELETE SDLK_DELETE
#define KEY_TAB SDLK_TAB
#define KEY_CLEAR SDLK_CLEAR
#define KEY_RETURN SDLK_RETURN
#define KEY_ENTER KEY_RETURN
#define KEY_ESCAPE SDLK_ESCAPE
#define KEY_SPACE SDLK_SPACE
#define KEY_0 SDLK_0
#define KEY_1 SDLK_1
#define KEY_2 SDLK_2
#define KEY_3 SDLK_3
#define KEY_4 SDLK_4
#define KEY_5 SDLK_5
#define KEY_6 SDLK_6
#define KEY_7 SDLK_7
#define KEY_8 SDLK_8
#define KEY_9 SDLK_9
#define KEY_KP0 SDLK_KP0
#define KEY_KP1 SDLK_KP1
#define KEY_KP2 SDLK_KP2
#define KEY_KP3 SDLK_KP3
#define KEY_KP4 SDLK_KP4
#define KEY_KP5 SDLK_KP5
#define KEY_KP6 SDLK_KP6
#define KEY_KP7 SDLK_KP7
#define KEY_KP8 SDLK_KP8
#define KEY_KP9 SDLK_KP9
#define KEY_A SDLK_a
#define KEY_B SDLK_b
#define KEY_C SDLK_c
#define KEY_D SDLK_d
#define KEY_E SDLK_e
#define KEY_F SDLK_f
#define KEY_G SDLK_g
#define KEY_H SDLK_h
#define KEY_I SDLK_i
#define KEY_J SDLK_j
#define KEY_K SDLK_k
#define KEY_L SDLK_l
#define KEY_M SDLK_m
#define KEY_N SDLK_n
#define KEY_O SDLK_o
#define KEY_P SDLK_p
#define KEY_Q SDLK_q
#define KEY_R SDLK_r
#define KEY_S SDLK_s
#define KEY_T SDLK_t
#define KEY_U SDLK_u
#define KEY_V SDLK_v
#define KEY_W SDLK_w
#define KEY_X SDLK_x
#define KEY_Y SDLK_y
#define KEY_Z SDLK_z
#define KEY_RSHIFT SDLK_RSHIFT
#define KEY_LSHIFT SDLK_LSHIFT
#define KEY_RCONTROL SDLK_RCTRL
#define KEY_LCONTROL SDLK_LCTRL
#define KEY_RALT SDLK_RALT
#define KEY_LALT SDLK_LALT
#define KEY_UP SDLK_UP
#define KEY_DOWN SDLK_DOWN
#define KEY_LEFT SDLK_LEFT
#define KEY_RIGHT SDLK_RIGHT
#endif

View file

@ -19,13 +19,29 @@
#include <string>
#include <vector>
//this module controls internationalization.
//table of strings which are displayed to the user. Maps ids -> text.
//this table should be consulted whenever something is to be
//displayed on screen.
extern std::map<std::string,std::string> string_table;
//function which, given the main configuration object, will return
//a list of the translations of the game available.
std::vector<std::string> get_languages(config& cfg);
//function which, given the main configuration object, and a locale,
//will set string_table to be populated with data from that locale.
//locale may be either the full name of the language, like 'English',
//or the 2-letter version, like 'en'.
bool set_language(const std::string& locale, config& cfg);
//function which attempts to query and return the locale on the system
std::string get_locale();
//two character sets are supported: LATIN1 and UTF-8. This is
//set in the translation by using encoding=(LATIN1|UTF-8)
//the character set used affects the font rendering function called
enum CHARSET { CHARSET_LATIN1, CHARSET_UTF8 };
CHARSET charset();

View file

@ -10,6 +10,7 @@
See the COPYING file for more details.
*/
#ifndef MAP_H_INCLUDED
#define MAP_H_INCLUDED
@ -20,12 +21,18 @@
#include <string>
#include <vector>
//class which encapsulates the map of the game. Although the game is hexagonal,
//the map is stored as a grid. Each type of terrain is represented by a letter.
class gamemap
{
public:
typedef char TERRAIN;
//some types of terrain which must be known, and can't just be loaded
//in dynamically because they're special. It's asserted that there will
//be corresponding entries for these types of terrain in the terrain
//configuration file.
enum { VOID_TERRAIN = ' ', CASTLE = 'C', TOWER = 't', FOREST = 'f' };
//the name of the terrain is the terrain itself, the underlying terrain
@ -36,12 +43,15 @@ public:
const std::string& underlying_terrain_name(TERRAIN terrain) const;
TERRAIN underlying_terrain(TERRAIN terrain) const;
//exception thrown if the map file is not in the correct format.
struct incorrect_format_exception {
incorrect_format_exception(const char* msg) : msg_(msg) {}
const char* const msg_;
};
//structure which represents a location on the map.
struct location {
//any valid direction which can be moved in in our hexagonal world.
enum DIRECTION { NORTH, NORTH_EAST, SOUTH_EAST, SOUTH,
SOUTH_WEST, NORTH_WEST };
@ -62,36 +72,52 @@ public:
static location null_location;
};
gamemap(config& cfg,
//loads a map, with the given terrain configuration.
//data should be a series of lines, with each character representing
//one hex on the map. Starting locations are represented by numbers,
//and will be of type keep.
gamemap(config& terrain_cfg,
const std::string& data); //throw(incorrect_format_exception)
std::string write() const;
//dimensions of the map.
int x() const;
int y() const;
//allows lookup of terrain at a particular location.
const std::vector<TERRAIN>& operator[](int index) const;
const location& starting_position(int n) const;
//functions to manipulate starting positions of the different sides.
const location& starting_position(int side) const;
int num_starting_positions() const;
bool is_starting_position(const location& loc) const;
//function which, given a location, will tell if that location is
//on the map. Should be called before indexing using []
bool on_board(const location& loc) const
{
return loc.valid() && loc.x < x() && loc.y < y();
}
//function to tell if the map is of 0 size.
bool empty() const
{
return x() == 0 || y() == 0;
}
//function to return a list of the locations of villages on the map
const std::vector<location>& towers() const { return towers_; }
//function to get the corresponding terrain_type information object
//for a given type of terrain
const terrain_type& get_terrain_info(TERRAIN terrain) const;
//gets the list of which terrain types should display on top of
//other terrain types. Has no effect on gameplay, only display.
const std::vector<TERRAIN>& get_terrain_precedence() const;
//clobbers over the terrain at location 'loc', with the given terrain
void set_terrain(const location& loc, TERRAIN ter);
private:
std::vector<TERRAIN> terrainPrecedence_;

View file

@ -83,7 +83,7 @@ int main(int argc, char** argv)
std::cerr << "starting for(;;)\n";
for(;;) {
if(key[KEY_ESCAPE])
if(key[SDLK_ESCAPE])
break;
int mousex, mousey;
@ -91,25 +91,25 @@ int main(int argc, char** argv)
const bool new_left_button = mouse_flags & SDL_BUTTON_LMASK;
const bool new_right_button = mouse_flags & SDL_BUTTON_RMASK;
if(key[KEY_UP] || mousey == 0)
if(key[SDLK_UP] || mousey == 0)
gui.scroll(0.0,-scroll_speed);
if(key[KEY_DOWN] || mousey == gui.y()-1)
if(key[SDLK_DOWN] || mousey == gui.y()-1)
gui.scroll(0.0,scroll_speed);
if(key[KEY_LEFT] || mousex == 0)
if(key[SDLK_LEFT] || mousex == 0)
gui.scroll(-scroll_speed,0.0);
if(key[KEY_RIGHT] || mousex == gui.x()-1)
if(key[SDLK_RIGHT] || mousex == gui.x()-1)
gui.scroll(scroll_speed,0.0);
if(key[KEY_Z])
if(key[SDLK_Z])
gui.zoom(zoom_amount);
if(key[KEY_X])
if(key[SDLK_X])
gui.zoom(-zoom_amount);
if(key[KEY_D])
if(key[SDLK_D])
gui.default_zoom();
gui.highlight_hex(gui.hex_clicked_on(mousex,mousey));

View file

@ -19,13 +19,17 @@
#include "unit_types.hpp"
#include "video.hpp"
//an object which guarantees that when it is destroyed, a 'leave game'
//message will be sent to any hosts still connected.
struct network_game_manager {
network_game_manager() {}
~network_game_manager();
};
void play_multiplayer_client(display& disp, game_data& units_data,
config& cfg, game_state& state);
//function to host a multiplayer game. If server is true, then the
//game will accept connections from foreign hosts. Otherwise it'll
//just use existing network connections for players, or the game
//is an entirely local game
void play_multiplayer(display& disp, game_data& units_data,
config cfg, game_state& state, bool server=true);

View file

@ -7,6 +7,8 @@
#include "network.hpp"
#include "unit_types.hpp"
//function to play a game as a client, joining either another player who is
//hosting a game, or connecting to a server.
void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
game_state& state);

View file

@ -145,8 +145,8 @@ RESULT enter(display& disp, config& game_data)
break;
}
const bool enter = key[KEY_ENTER] && !old_enter;
old_enter = key[KEY_ENTER];
const bool enter = key[SDLK_RETURN] && !old_enter;
old_enter = key[SDLK_RETURN];
if((enter) &&
message_entry.text().empty() == false) {
config msg;
@ -156,7 +156,7 @@ RESULT enter(display& disp, config& game_data)
message_entry.clear();
}
if(key[KEY_ESCAPE] || quit_game.process(mousex,mousey,left_button)){
if(key[SDLK_ESCAPE] || quit_game.process(mousex,mousey,left_button)){
return QUIT;
}

View file

@ -4,10 +4,14 @@
#include "config.hpp"
#include "display.hpp"
//this module controls the multiplayer lobby. A section on the server which
//allows players to chat, create games, and join games.
namespace lobby {
enum RESULT { QUIT, CREATE, JOIN };
//function which controls the lobby, and will result in the player creating
//a game, joining a game, or quitting the lobby.
RESULT enter(display& disp, config& data);
}

View file

@ -7,8 +7,12 @@
#include <string>
//this module wraps the network interface.
namespace network {
//a network manager must be created before networking can be used.
//it must be destroyed only after all networking activity stops.
struct manager {
manager();
~manager();
@ -17,7 +21,11 @@ private:
bool free_;
};
//a server manager causes listening on a given port to occur
//for the duration of its lifetime.
struct server_manager {
//if create_server is false, then the object has no effect.
//throws error.
server_manager(int port=15000, bool create_server=true);
~server_manager();
@ -27,16 +35,43 @@ private:
typedef TCPsocket connection;
//the number of peers we are connected to
size_t nconnections();
//if we are currently accepting connections
bool is_server();
//function to attempt to connect to a remote host. Returns
//the new connection on success, or 0 on failure.
//throws error.
connection connect(const std::string& host, int port=15000);
//function to accept a connection from a remote host. If no
//host is attempting to connect, it will return 0 immediately.
//otherwise returns the new connection.
//throws error.
connection accept_connection();
//function to disconnect from a certain host, or close all
//connections if connection_num is 0
void disconnect(connection connection_num=0);
//function to queue a disconnection. Next time receive_data is
//called, it will generate an error on the given connection.
//(and presumably then the handling of the error will include
// closing the connection)
void queue_disconnect(connection connection_num);
connection receive_data(config& cfg, connection connection_num=0, int tout=0);
//function to receive data from either a certain connection, or
//all connections if connection_num is 0. Will store the data
//received in cfg. Times out after timeout milliseconds. Returns
//the connection that data was received from, or 0 if timeout
//occurred. Throws error if an error occurred.
connection receive_data(config& cfg, connection connection_num=0,
int timeout=0);
//function to send data down a given connection, or broadcast
//to all peers if connection_num is 0. throws error.
void send_data(const config& cfg, connection connection_num=0);
struct error

View file

@ -25,38 +25,65 @@
#include <list>
#include <vector>
//this module contains various pathfinding functions and utilities.
//function which, given a location, will place all adjacent locations in
//res. res must point to an array of 6 location objects.
void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res);
//function which tells if two locations are adjacent.
bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b);
//function which gives the number of hexes between two tiles (i.e. the minimum
//number of hexes that have to be traversed to get from one hex to the other)
size_t distance_between(const gamemap::location& a, const gamemap::location& b);
//function which will find a location on the board that is as near to loc as
//possible, but which is unoccupied by any units. If terrain is not 0, then
//the location found must be of the given terrain type, and must have a path
//of that terrain type to loc.
//
//if no valid location can be found, it will return a null location.
gamemap::location find_vacant_tile(const gamemap& map,
const std::map<gamemap::location,unit>& un,
const gamemap::location& loc,
gamemap::TERRAIN terrain=0);
//function which determines if a given location is an enemy zone of control
bool enemy_zoc(const gamemap& map,const std::map<gamemap::location,unit>& units,
const gamemap::location& loc,const team& current_team,int side);
//object which contains all the possible locations a unit can move to, with
//associated best routes to those locations.
struct paths
{
paths() {}
//construct a list of paths for the unit at loc.
//ignore_zocs: determines whether unit has to stop upon entering an ezoc
//allow_teleport: indicates whether unit teleports between villages
//additional_turns: if 0, paths for how far the unit can move this turn
//will be calculated. If 1, paths for how far the unit can move by the
//end of next turn will be calculated, and so forth.
paths(const gamemap& map, const game_data& gamedata,
const std::map<gamemap::location,unit>& units,
const gamemap::location& loc, std::vector<team>& teams,
bool ignore_zocs, bool allow_teleport, int additional_turns=0);
//structure which holds a single route between one location and another.
struct route
{
route() : move_left(0) {}
std::vector<gamemap::location> steps;
int move_left;
int move_left; //movement unit will have left at end of the route.
};
typedef std::map<gamemap::location,route> routes_map;
routes_map routes;
};
//function which, given a unit and a route the unit can move on, will
//return the number of turns it will take the unit to traverse the route.
int route_turns_to_complete(const unit& u, const gamemap& map,
const paths::route& rt);

View file

@ -147,16 +147,16 @@ void turn_info::turn_slice()
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
tooltips::process(mousex,mousey,mouse_flags & SDL_BUTTON_LMASK);
if(key_[KEY_UP] || mousey == 0)
if(key_[SDLK_UP] || mousey == 0)
gui_.scroll(0.0,-preferences::scroll_speed());
if(key_[KEY_DOWN] || mousey == gui_.y()-1)
if(key_[SDLK_DOWN] || mousey == gui_.y()-1)
gui_.scroll(0.0,preferences::scroll_speed());
if(key_[KEY_LEFT] || mousex == 0)
if(key_[SDLK_LEFT] || mousex == 0)
gui_.scroll(-preferences::scroll_speed(),0.0);
if(key_[KEY_RIGHT] || mousex == gui_.x()-1)
if(key_[SDLK_RIGHT] || mousex == gui_.x()-1)
gui_.scroll(preferences::scroll_speed(),0.0);
}

View file

@ -468,11 +468,11 @@ int show_dialog(display& disp, SDL_Surface* image,
const bool new_right_button = mouse_flags&SDL_BUTTON_RMASK;
const bool new_left_button = mouse_flags&SDL_BUTTON_LMASK;
const bool new_key_down = key[KEY_SPACE] || key[KEY_ENTER] ||
key[KEY_ESCAPE];
const bool new_key_down = key[SDLK_SPACE] || key[SDLK_RETURN] ||
key[SDLK_ESCAPE];
const bool new_up_arrow = key[KEY_UP];
const bool new_down_arrow = key[KEY_DOWN];
const bool new_up_arrow = key[SDLK_UP];
const bool new_down_arrow = key[SDLK_DOWN];
const bool new_page_up = key[SDLK_PAGEUP];
const bool new_page_down = key[SDLK_PAGEDOWN];
@ -484,7 +484,7 @@ int show_dialog(display& disp, SDL_Surface* image,
}
if(!key_down && key[KEY_ENTER] &&
if(!key_down && key[SDLK_RETURN] &&
(type == YES_NO || type == OK_CANCEL)) {
if(text_widget_text != NULL && use_textbox)
@ -497,11 +497,11 @@ int show_dialog(display& disp, SDL_Surface* image,
}
}
if(!key_down && key[KEY_ESCAPE] && type == MESSAGE) {
if(!key_down && key[SDLK_ESCAPE] && type == MESSAGE) {
return -1;
}
if(!key_down && key[KEY_ESCAPE] &&
if(!key_down && key[SDLK_ESCAPE] &&
(type == YES_NO || type == OK_CANCEL)) {
if(menu_.height() == 0) {
@ -663,7 +663,7 @@ TITLE_RESULT show_title(display& screen)
CKey key;
bool last_escape = key[KEY_ESCAPE];
bool last_escape = key[SDLK_ESCAPE];
update_whole_screen();
@ -693,10 +693,10 @@ TITLE_RESULT show_title(display& screen)
if(quit_button.process(mousex,mousey,left_button))
return QUIT_GAME;
if(!last_escape && key[KEY_ESCAPE])
if(!last_escape && key[SDLK_ESCAPE])
return QUIT_GAME;
last_escape = key[KEY_ESCAPE];
last_escape = key[SDLK_ESCAPE];
screen.video().flip();