1 /*********************************
2 ** Tsunagari Tile Engine **
4 ** Copyright 2011-2012 OmegaSDG **
5 *********************************/
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
33 #include <boost/unordered_map.hpp>
34 #include <boost/unordered_set.hpp>
35 #include <boost/scoped_ptr.hpp>
36 #include <boost/shared_ptr.hpp>
37 #include <boost/python/tuple.hpp>
38 #include <Gosu/Color.hpp>
40 #include "scriptinst.h"
43 #define ISOMETRIC_ZOFF_PER_TILE 0.001
56 //! An Area represents one map, or screen, in a World.
58 The Area class manages a three-dimensional structure of Tiles and a set
61 The game's Viewport must be "focused" on an Area. Only one Area can be
64 The viewport will not scroll past the edge of an Area. (At least as of
70 Area(Viewport
* view
, Player
* player
, const std::string
& filename
);
73 //! Parse the file specified in the constructor, generating a full Area
74 //! object. Must be called before use.
77 //! Prepare game state for this Area to be in focus.
80 //! Processes keyboard input, calling the Player object when necessary.
81 void buttonDown(const Gosu::Button btn
);
82 void buttonUp(const Gosu::Button btn
);
84 //! Renders all visible Tiles and Entities within this Area.
87 //! If false, drawing might be skipped. Saves CPU cycles when idle.
88 bool needsRedraw() const;
90 //! Inform the Area that a redraw is needed.
94 * Update the game state within this Area as if dt milliseconds had
95 * passed since the last call. Updates Entities, runs scripts, and
96 * checks for Tile animation updates.
98 void tick(unsigned long dt
);
101 * Updates Entities, runs scripts, and checks for Tile animation
106 void setColorOverlay(int r
, int g
, int b
, int a
);
108 const Tile
* getTile(int x
, int y
, int z
) const; /* phys */
109 const Tile
* getTile(int x
, int y
, double z
) const; /* virt */
110 const Tile
* getTile(icoord phys
) const;
111 const Tile
* getTile(vicoord virt
) const;
112 const Tile
* getTile(rcoord virt
) const;
113 Tile
* getTile(int x
, int y
, int z
); /* phys */
114 Tile
* getTile(int x
, int y
, double z
); /* virt */
115 Tile
* getTile(icoord phys
);
116 Tile
* getTile(vicoord virt
);
117 Tile
* getTile(rcoord virt
);
119 TileSet
* getTileSet(const std::string
& imagePath
);
121 //! Return the dimensions of the Tile matrix.
122 ivec3
getDimensions() const;
123 //! Return the pixel dimensions of a Tile graphic.
124 ivec2
getTileDimensions() const;
125 //! Return the isometric z-offset for an X-Y position in the Area.
126 double isometricZOff(rvec2 pos
) const;
127 //! Returns a physical cubic range of Tiles that could be visible
129 icube
visibleTileBounds() const;
130 //! Returns a physical cubic range of Tiles that are visible on-screen.
131 //! Takes actual map size into account.
132 icube
visibleTiles() const;
134 //! Returns true if a Tile exists at the specified coordinate.
135 bool inBounds(int x
, int y
, int z
) const; /* phys */
136 bool inBounds(int x
, int y
, double z
) const; /* virt */
137 bool inBounds(icoord phys
) const;
138 bool inBounds(vicoord virt
) const;
139 bool inBounds(rcoord virt
) const;
140 bool inBounds(Entity
* ent
) const;
142 bool loopsInX() const;
143 bool loopsInY() const;
145 const std::string
getDescriptor() const;
147 Entity
* spawnNPC(const std::string
& descriptor
,
148 int x
, int y
, double z
, const std::string
& phase
);
149 Entity
* spawnOverlay(const std::string
& descriptor
,
150 int x
, int y
, double z
, const std::string
& phase
);
151 void insert(Character
* c
);
152 void insert(Overlay
* o
);
153 void erase(Character
* c
);
154 void erase(Overlay
* o
);
156 // Convert between virtual and physical map coordinates. Physical
157 // coordinates are the physical indexes into the Tile matrix. Layer
158 // depth is represented by an arbirarily chosen integer in the physical
159 // system. Virtual coordinates include the correct floating-point
161 vicoord
phys2virt_vi(icoord phys
) const;
162 rcoord
phys2virt_r(icoord phys
) const;
163 icoord
virt2phys(vicoord virt
) const;
164 icoord
virt2phys(rcoord virt
) const;
165 rcoord
virt2virt(vicoord virt
) const;
166 vicoord
virt2virt(rcoord virt
) const;
168 // For Python interface.
169 boost::python::tuple
pyGetDimensions();
173 // Variables public for Python scripts
177 ScriptInst loadScript
, focusScript
, tickScript
, turnScript
;
181 // Convert between virtual and physical map depths.
182 int depthIndex(double depth
) const;
183 double indexDepth(int idx
) const;
185 //! Run scripts that needs to be run before this Area is usable.
186 void runLoadScripts();
188 //! Calculate frame to show for each type of tile
190 void drawTile(Tile
& tile
, int x
, int y
, double depth
);
192 void drawColorOverlay();
197 boost::unordered_set
<Character
*> characters
;
198 boost::unordered_set
<Overlay
*> overlays
;
199 Gosu::Color colorOverlay
;
201 typedef std::vector
<Tile
> row_t
;
202 typedef std::vector
<row_t
> grid_t
;
203 typedef std::vector
<grid_t
> tilematrix_t
;
205 //! 3-dimensional array of the tiles that make up the map.
208 //! 3-dimensional length of map.
211 //! Pixel size for each tile in area. All tiles in an Area must be the
215 typedef std::map
<std::string
, TileSet
> tilesets_t
;
218 //! Maps virtual float-point depths to an index in our map array.
219 boost::unordered_map
<double, int> depth2idx
;
221 //! Maps an index in our map array to a virtual float-point depth.
222 std::vector
<double> idx2depth
;
225 std::string name
, author
;
230 // The following contain filenames such that they may be loaded lazily.
231 const std::string descriptor
;
232 std::string musicIntro
, musicLoop
;
235 //! Register Areas with Python.