Adonthell 0.4
mapcharacter.h
Go to the documentation of this file.
00001 /*
00002    $Id: mapcharacter.h,v 1.59 2003/02/23 23:14:34 ksterker Exp $
00003 
00004    Copyright (C) 1999/2000/2001   Alexandre Courbot
00005    Part of the Adonthell Project http://adonthell.linuxgames.com
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 
00016 
00017 /** 
00018  * @file mapcharacter.h
00019  *
00020  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
00021  * @brief Declares the mapcharacter class.
00022  */
00023 
00024 
00025 
00026 #ifndef MAPCHARACTER_H_
00027 #define MAPCHARACTER_H_
00028 
00029 /**
00030  * Where mapcharacter files resides.
00031  * 
00032  */ 
00033 #define MAPCHAR_DIR "gfx/mapcharacters/"
00034 
00035 #include "animation.h"
00036 #include "character_base.h"
00037 #include "path.h"
00038 #include "text_bubble.h"
00039 #include "event_list.h"
00040 
00041 class landmap; 
00042 class path; 
00043 
00044 /**
00045  * @name mapcharacter moves.
00046  * 
00047  */ 
00048 //@{
00049  
00050 /**
00051  * Standing North.
00052  * 
00053  */ 
00054 #define STAND_NORTH 0
00055 
00056 /**
00057  * Standing South.
00058  * 
00059  */ 
00060 #define STAND_SOUTH 1
00061 
00062 /**
00063  * Standing West.
00064  * 
00065  */ 
00066 #define STAND_WEST 2
00067 
00068 /**
00069  * Standing East.
00070  * 
00071  */ 
00072 #define STAND_EAST 3
00073 
00074 /**
00075  * Walking North.
00076  * 
00077  */ 
00078 #define WALK_NORTH 4
00079 
00080 /**
00081  * Walking South.
00082  * 
00083  */ 
00084 #define WALK_SOUTH 5
00085 
00086 /**
00087  * Walking West.
00088  * 
00089  */ 
00090 #define WALK_WEST 6
00091 
00092 /**
00093  * Walking East.
00094  * 
00095  */ 
00096 #define WALK_EAST 7
00097 
00098 /**
00099  * Total number of moves.
00100  * 
00101  */
00102 #define NBR_MOVES 8
00103 
00104 /**
00105  * No move.
00106  * 
00107  */
00108 #define NO_MOVE 65535
00109 
00110 //@}
00111 
00112 class mapview;
00113 
00114 
00115 
00116 /**
00117  * Representation of characters on a landmap.
00118  *
00119  * Like mapobjects, mapcharacters are a set of animations (one for every movment)
00120  * and a grid of mapsquare_walkables. This grid represents the map area the mapcharacter
00121  * physically occupies, which means that a mapcharacter can occupies several tiles.
00122  *
00123  * During the execution of Python scripts, some mapcharacter-local variables are
00124  * available:
00125  * @li myself is a pointer to the character holding this mapcharacter (can of course
00126  * serve as a mapcharacter pointer, as character inheritates from mapcharacter).
00127  * @li mymap, if defined, points to the landmap the mapcharacter is on.
00128  *
00129  * These Python variables are available both for schedules and actions.  
00130  *
00131  * In supplement, actions have an extra variable available:
00132  * @li requester, which points to the mapcharacter that requested the action.
00133  * 
00134  */ 
00135 class mapcharacter : public mapsquare_walkable_area, public character_base, public event_list
00136 {
00137 public:
00138     
00139     /** 
00140      * Default constructor.
00141      * 
00142      */ 
00143      mapcharacter ();
00144 
00145     /**
00146      * Destructor.
00147      * 
00148      */ 
00149     ~mapcharacter ();
00150 
00151     /**
00152      * Puts the mapcharacter back to it's post-constructor state.
00153      * 
00154      */ 
00155     void clear ();
00156     
00157     /** 
00158      * Returns the current file name of the mapcharacter.
00159      * 
00160      * 
00161      * @return filename of the mapcharacter.
00162      */
00163     string filename () const
00164     {
00165         return filename_;
00166     }
00167 
00168     /**
00169      * @name State updating
00170      * 
00171      */ 
00172     //@{ 
00173          
00174     /** 
00175      * Updates the mapcharacter's state and launchs his schedule.
00176      * 
00177      */
00178     bool update ();
00179 
00180     //@}
00181 
00182 
00183     /**
00184      * @name Drawing methods
00185      * 
00186      */ 
00187     //@{ 
00188 
00189     void draw (s_int16 x, s_int16 y, const drawing_area * da_opt = NULL, surface * target = NULL) const;
00190     void draw_bubble (s_int16 x, s_int16 y, const drawing_area * da_opt = NULL, surface * target = NULL) const;
00191     
00192     //@}
00193     
00194     
00195     /**
00196      * @name Loading/Saving methods
00197      *
00198      * @note You can't save mapcharacters with this class.
00199      */
00200     //@{
00201         
00202     /**
00203      * Loads a mapcharacter from an opened file.
00204      * @param file the opened file from which to load.
00205      * @return 0 in case of success, error code otherwise.
00206      *
00207      */ 
00208     s_int8 get (igzstream& file);
00209 
00210     /**
00211      * Loads a mapcharacter from it's filename.
00212      * 
00213      * @param fname the name of the file to load.
00214      * 
00215      * @return 0 in case of success, error code otherwise.
00216      */
00217     s_int8 load (string fname);
00218 
00219     /** Saves an mapcharacter into an opened file, in %game format, with
00220      *  alpha and mask values. 
00221      *  @warning as the mapcharacter which is saved comes from a %screen's depth
00222      *           surface, it will be slightly altered during the save.
00223      *           If you want a class capable of saving mapcharacters with full
00224      *           truecolor quality, use mapcharacter_edit instead.
00225      *  @param file opened file where to save into.
00226      *  @return
00227      *      @li 0 in case of success.
00228      *      @li -1 in case of error.
00229      *  @sa save ()
00230      */
00231     s_int8 put (ogzstream& file) const;
00232 
00233     /** Saves an mapcharacter into an file, in %game format, with
00234      *  alpha and mask values.
00235      *  @warning as the mapcharacter which is saved comes from a %screen's depth
00236      *           surface, it will be slightly altered during the save.
00237      *           If you want a class capable of saving mapcharacters with full
00238      *           truecolor quality, use mapcharacter_edit instead.
00239      *  @param fname file name where to save into.
00240      *  @return
00241      *      @li 0 in case of success.
00242      *      @li -1 in case of error.
00243      *  @sa put ()
00244      */
00245     s_int8 save (string fname) const;
00246     //@}
00247     
00248 
00249     /**
00250      * @name State loading/saving methods
00251      *
00252      */
00253     //@{
00254 
00255     /** 
00256      * Restore the mapcharacter's state from an opened file.
00257      * 
00258      * @param file the opened file from which to load the state.
00259      * 
00260      * @return 0 in case of success, error code otherwise.
00261      */
00262     s_int8 get_state (igzstream& file);
00263 
00264     /** 
00265      * Saves the mapcharacter's state into an opened file.
00266      * 
00267      * @param file the opened file where to the state.
00268      * 
00269      * @return 0 in case of success, error code otherwise.
00270      */
00271     s_int8 put_state (ogzstream& file) const;
00272 
00273     //@}
00274 
00275 
00276 
00277     /**
00278      * @name Landmap assignment
00279      * 
00280      */ 
00281     //@{
00282     
00283     /** 
00284      * Puts the mapcharacter on a landmap.
00285      * This methods can only be applied if the mapcharacter isn't on any landmap
00286      * when it is called, otherwise nothing will occur.
00287      *
00288      * @warning Be aware that once this methods is called, the mapcharacter has NO
00289      * position on the landmap. You MUST call jump_to () after this method to actually
00290      * have placed the character on the map.
00291      * 
00292      * @param m pointer to the landmap the mapcharacter should be on.
00293      */
00294     void set_map (landmap * m); 
00295     
00296     /** 
00297      * Removes the mapcharacter from the landmap he was on (if any).
00298      * 
00299      */
00300     void remove_from_map ();
00301     
00302     /** 
00303      * Returns a pointer to the landmap the mapcharacter is on.
00304      * 
00305      * 
00306      * @return pointer to the landmap the mapcharacter is on (NULL if none).
00307      */
00308     landmap * mymap () const
00309     {
00310         return refmap; 
00311     }
00312     
00313     //@}
00314     
00315     /**
00316      * @name High-level control
00317      *
00318      * These methods provide a simple way to control the mapcharacter on the map he's on.
00319      * They cover "normal" moves like walking or looking into a direction, plus tests to
00320      * know whether a move is possible or not.
00321      *
00322      */
00323     //@{
00324 
00325     /** 
00326      * Look to North.
00327      * 
00328      */
00329     void stand_north ();
00330 
00331     /** 
00332      * Look to South.
00333      * 
00334      */
00335     void stand_south ();
00336 
00337     /** 
00338      * Look to East.
00339      * 
00340      */
00341     void stand_east ();
00342 
00343     /** 
00344      * Look to West.
00345      * 
00346      */
00347     void stand_west ();
00348 
00349     /** 
00350      * Stand to the current direction.
00351      *
00352      * @note This method only serves to abord an expected waking movment.
00353      * 
00354      */
00355     void stand ();
00356     
00357     /** 
00358      * Walk to North (if possible).
00359      *
00360      * This method asks the mapcharacter to walk one square to North. If the
00361      * movment isn't possible (non-walkable mapsquare or map limit), the
00362      * character will stand_north () instead.
00363      *
00364      * @note Each time update () is called, the mapcharacter will continue advancing,
00365      * until he reaches the next mapsquare.
00366      *
00367      */
00368     bool go_north ();
00369 
00370     /** 
00371      * Walk to South (if possible).
00372      *
00373      * This method asks the mapcharacter to walk one square to South. If the
00374      * movment isn't possible (non-walkable mapsquare or map limit), the
00375      * character will stand_south () instead.
00376      *
00377      * @note Each time update () is called, the mapcharacter will continue advancing,
00378      * until he reaches the next mapsquare.
00379      *
00380      */
00381     bool go_south ();
00382 
00383     /** 
00384      * Walk to East (if possible).
00385      *
00386      * This method asks the mapcharacter to walk one square to East. If the
00387      * movment isn't possible (non-walkable mapsquare or map limit), the
00388      * character will stand_east () instead.
00389      *
00390      * @note Each time update () is called, the mapcharacter will continue advancing,
00391      * until he reaches the next mapsquare.
00392      *
00393      */
00394     bool go_east ();
00395     
00396     /** 
00397      * Walk to West (if possible).
00398      *
00399      * This method asks the mapcharacter to walk one square to West. If the
00400      * movment isn't possible (non-walkable mapsquare or map limit), the
00401      * character will stand_west () instead.
00402      *
00403      * @note Each time update () is called, the mapcharacter will continue advancing,
00404      * until he reaches the next mapsquare.
00405      *
00406      */
00407     bool go_west ();
00408 
00409     /** 
00410      * Returns whether it is possible or not to go to North from
00411      * the current mapcharacter's position.
00412      * 
00413      * 
00414      * @return \c true if it is possible to go to North, \c false otherwise.
00415      */
00416     bool can_go_north () const;
00417     
00418     /** 
00419      * Returns whether it is possible or not to go to South from
00420      * the current mapcharacter's position.
00421      * 
00422      * 
00423      * @return \c true if it is possible to go to South, \c false otherwise.
00424      */
00425     bool can_go_south () const;
00426 
00427     /** 
00428      * Returns whether it is possible or not to go to East from
00429      * the current mapcharacter's position.
00430      * 
00431      * 
00432      * @return \c true if it is possible to go to East, \c false otherwise.
00433      */
00434     bool can_go_east ()const;
00435     
00436     /** 
00437      * Returns whether it is possible or not to go to West from
00438      * the current mapcharacter's position.
00439      * 
00440      * 
00441      * @return \c true if it is possible to go to West, \c false otherwise.
00442      */
00443     bool can_go_west () const; 
00444 
00445     /** 
00446      * Look at the opposite position of p.
00447      * 
00448      * This method is usefull for dialogues, when we want two
00449      * characters to face each other.
00450      *
00451      * 
00452      * @param p opposite position of the position to look at. Can be
00453      * \c STAND_NORTH, \c STAND_SOUTH, \c STAND_EAST or \c STAND_WEST.
00454      */
00455     void look_invert (u_int16 p);
00456 
00457     /** 
00458      * Return a pointer to the mapcharacter that is right next to this
00459      * mapcharacter, i.e the mapcharacter that is on the square this
00460      * mapcharacter is looking at.
00461      *
00462      * If no mapcharacter is next to this one, NULL will be returned.
00463      *
00464      * 
00465      * @return pointer to the mapcharacter next to this mapcharacter.
00466      */
00467     mapcharacter *whosnext () const;
00468 
00469     void speak (const string & text);
00470 
00471     bool is_speaking ()
00472     {
00473         return (saying != NULL); 
00474     }
00475 
00476     text_bubble * get_bubble () 
00477     {
00478         return saying; 
00479     }
00480     //@}
00481       
00482 
00483     /**
00484      * @name Low-level controls
00485      *
00486      * If you need to do non-conventionnal or special things (like
00487      * teleport a character from a position to another), or need
00488      * to override the walkable mechanism, use these methods.
00489      *
00490      * You are also provided with various informative methods.
00491      *
00492      */ 
00493     //@{
00494 
00495     /** 
00496      * Sets the offset of the mapcharacter on it's current mapsquare.
00497      * 
00498      * @param x X offset.
00499      * @param y Y offset.
00500      */
00501     void set_offset (s_int8 x, s_int8 y)
00502     {
00503         offx_ = x;
00504         offy_ = y;
00505     }
00506 
00507     /** 
00508      * Removes the mapcharacter from the place he was on the map.
00509      * 
00510      */
00511     void remove_from_pos ();
00512     
00513     /** 
00514      * Remove the mapcharacter from it's current place and put him to a new one.
00515      * 
00516      * @param smap index of the submap to jump to.
00517      * @param x X offset to to.
00518      * @param y Y offset to to.
00519      * @param pos Position to adopt once placed.
00520      */
00521     void jump_to (u_int16 smap, u_int16 x, u_int16 y, u_int16 pos = NO_MOVE);
00522 
00523     /** 
00524      * Returns the index of the submap where the mapcharacter is.
00525      * 
00526      * 
00527      * @return the index of the submap where the mapcharacter is.
00528      */
00529     u_int16 submap () const
00530     {
00531         return submap_;
00532     }
00533     
00534     /** 
00535      * Returns the X position of the mapcharacter.
00536      * 
00537      * 
00538      * @return the X position of the mapcharacter on his map.
00539      */
00540     u_int16 posx () const
00541     {
00542         return posx_;
00543     }
00544     
00545     /** 
00546      * Returns the Y position of the mapcharacter.
00547      * 
00548      * 
00549      * @return the Y position of the mapcharacter on his map.
00550      */
00551     u_int16 posy () const
00552     {
00553         return posy_;
00554     }
00555     
00556     /** 
00557      * Returns the X offset of the mapcharacter.
00558      * 
00559      * 
00560      * @return the X offset of the mapcharacter on his map.
00561      */
00562     s_int8 offx () const
00563     {
00564         return offx_;
00565     }
00566     
00567     /** 
00568      * Returns the Y offset of the mapcharacter.
00569      * 
00570      * 
00571      * @return the Y offset of the mapcharacter on his map.
00572      */
00573     s_int8 offy () const
00574     {
00575         return offy_;
00576     }
00577 
00578     /** 
00579      * Returns the current move of the mapcharacter.
00580      * 
00581      * 
00582      * @return current mapcharacter's move (STAND_NORTH, WALK_SOUTH, etc...).
00583      */
00584     u_int16 currentmove () const
00585     {
00586         return current_move;
00587     }
00588  
00589     bool set_goal (u_int16 x, u_int16 y, u_int16 dir = NO_MOVE);
00590     void set_callback (PyObject *callback, PyObject *args = NULL);
00591     bool follow_path (); 
00592     bool goal_reached ();
00593     void stop_moving ();
00594     
00595     void time_callback (string delay, PyObject *cb, PyObject *args = NULL);
00596     void time_callback_string (string delay, string cb, PyObject *args = NULL);
00597     //@}
00598     
00599 
00600     /**
00601      * Schedule control.
00602      * 
00603      */
00604 
00605     //@{
00606 
00607     /** 
00608      * Assign a schedule to the mapcharacter.
00609      * 
00610      * The schedule's filename will be \e "scripts/schedules/mapcharacters/<file>.py".
00611      * 
00612      * @param file name of the schedule to use.
00613      * @param args Python tuple containing extra arguments passed to the class constructor.
00614      *
00615      * @warning the args tuple argument MUST ONLY contain strings or integers, as it will
00616      * be saved with the mapcharacter state by python::put_tuple ().
00617      *
00618      */
00619     void set_schedule (string file, PyObject * args = NULL);
00620 
00621     /** 
00622      * Returns the name of the mapcharacter's current schedule.
00623      * 
00624      * 
00625      * @return name of the mapcharacter's current schedule.
00626      */
00627     string schedule_file () const
00628     {
00629         return schedule_file_;
00630     }
00631     
00632     /** 
00633      * Returns whether the schedule is activated or not.
00634      * 
00635      * 
00636      * @return \c true if the schedule is activated, \c false otherwise.
00637      */
00638     bool is_schedule_activated () const
00639     {
00640         return schedule_activated; 
00641     }
00642     
00643     /** 
00644      * Sets whether the schedule is active or not.
00645      * 
00646      * @param a \c true if the schedule should be activated, \c false otherwise.
00647      */
00648     void set_schedule_active (bool a)
00649     {
00650         if (a && !schedule.has_attribute ("run")) return;
00651         schedule_activated = a; 
00652     }
00653 
00654     /**
00655      * Tell the character to do something. Will execute the given method
00656      * of the current schedule with the given arguments.
00657      *
00658      * @param method The method of the schedule to call.
00659      * @param args The arguments to pass to the method.
00660      *
00661      * @return \c true if the method has been called, \c false otherwise.
00662      */
00663     bool do_stuff (string method, PyObject *args = NULL); 
00664     //@}
00665 
00666 
00667     /**
00668      * Action control.
00669      * 
00670      */
00671 
00672     //@{
00673 
00674     /** 
00675      * Assign a action to the mapcharacter.
00676      * 
00677      * The action's filename will be \e "scripts/actions/<file>.py".
00678      * 
00679      * @param file name of the action to use.
00680      * @param args Python tuple containing extra arguments passed to the class constructor.
00681      *
00682      * @warning the args tuple argument MUST ONLY contain strings or integers, as it will
00683      * be saved with the mapcharacter state by python::put_tuple ().
00684      *
00685      */
00686     void set_action (string file, PyObject * args = NULL);
00687 
00688     /** 
00689      * Returns the name of the mapcharacter's current action.
00690      * 
00691      * 
00692      * @return name of the mapcharacter's current action.
00693      */
00694     string action_file () const
00695     {
00696         return action_file_;
00697     }
00698     
00699     /** 
00700      * Returns whether the action is activated or not.
00701      * 
00702      * 
00703      * @return \c true if the action is activated, \c false otherwise.
00704      */
00705     bool is_action_activated () const
00706     {
00707         return action_activated; 
00708     }
00709     
00710     /** 
00711      * Sets whether the action is active or not.
00712      * 
00713      * @param a \c true if the action should be activated, \c false otherwise.
00714      */
00715     void set_action_active (bool a)
00716     {
00717         action_activated = a; 
00718     }
00719 
00720     /** 
00721      * Run the mapcharacter's action, passing requester as the "requester" parameter
00722      * for the action's Python script.
00723      * 
00724      * @param requester pointer to the mapcharacter that requested the action, which
00725      * is passed to the Python run () method. 
00726      */
00727     void launch_action (mapcharacter * requester);
00728 
00729     //@}
00730 
00731 
00732     /** 
00733      * Returns a pointer to an animation corresponding
00734      * to a movment.
00735      * 
00736      * @param nbr index of the animation to get.
00737      * 
00738      * @return pointer to the \e nbr animation.
00739      */
00740     animation * get_animation (u_int16 nbr) 
00741     {
00742         return anim[nbr]; 
00743     }
00744     
00745 #ifndef SWIG
00746     /**
00747      * Mapcharacter copy (similar to copy ()).
00748      *
00749      * @attention Not available from Python. Use copy () from Python instead.
00750      * @sa copy ()
00751      */ 
00752     mapcharacter & operator = (const mapcharacter & m);
00753 #endif                          // SWIG
00754 
00755     /**
00756      * Synonym of operator = to guarantee its access from Python.
00757      *
00758      * @sa operator = 
00759      */
00760     void copy (const mapcharacter& src) 
00761     {
00762         *this = src; 
00763     }
00764       
00765 private:
00766     /**
00767      * Forbid value passing.
00768      * 
00769      */ 
00770     mapcharacter (const mapcharacter & src); 
00771     
00772     /** 
00773      * Makes the mapcharacter physically occupy an area.
00774      *
00775      * The given parameters are considered to be where
00776      * the mapcharacter's base square will be.
00777      * 
00778      * @param smap submap where to occupy.
00779      * @param px X position where to occupy.
00780      * @param py Y position where to occupy.
00781      */
00782     void occupy (u_int16 smap, u_int16 px, u_int16 py);
00783 
00784     /** 
00785      * Makes the mapcharacter physically leave an area previously occupied
00786      * with occupy ().
00787      *
00788      * The given parameters are considered to be where
00789      * the mapcharacter's base square were be.
00790      * 
00791      * @param smap submap where to leave.
00792      * @param px X position where to leave.
00793      * @param py Y position where to leave.
00794      */ 
00795     void leave (u_int16 smap, u_int16 px, u_int16 py); 
00796 
00797     void leave_position (); 
00798     
00799     /** 
00800      * Sets the position of the mapcharacter on the map.
00801      *
00802      * This sets the mapcharacter's position to the parameters,
00803      * and occupy () the corresponding region.
00804      *
00805      * @warning Don't forget to leave () the region when moving!
00806      * 
00807      * @param smap index of the submap where the mapcharacter should be.
00808      * @param x X position on the submap.
00809      * @param y Y position on the submap.
00810      */
00811     void set_pos (u_int16 smap, u_int16 x, u_int16 y);
00812 
00813     /** 
00814      * Updates the movment of the mapcharacter.
00815      * 
00816      */
00817     void update_move ();
00818     
00819 
00820     /**
00821      * Path used for the mapcharacter to have realistic movments.
00822      * 
00823      */ 
00824     path mypath; 
00825 
00826     /**
00827      * Used to count the position on the path
00828      * 
00829      */ 
00830     u_int16 pathindex; 
00831 
00832     u_int16 current_move;
00833     u_int16 previous_move;
00834     u_int16 submap_;
00835     u_int16 posx_, posy_;
00836     s_int8 offx_, offy_;
00837     vector <animation *> anim;
00838     landmap *refmap;
00839 
00840     py_object schedule; 
00841     py_object action; 
00842     
00843     string filename_; 
00844 
00845     text_bubble * saying; 
00846 
00847     bool schedule_activated;
00848     bool action_activated;
00849     bool goal_reached_;
00850 
00851     PyObject * schedule_args;
00852     PyObject * action_args; 
00853 
00854     string schedule_file_;
00855     string action_file_; 
00856     
00857     py_callback *callback;
00858     
00859 #ifndef SWIG
00860     friend class landmap; 
00861 #endif
00862 };
00863 
00864 #endif