rename Exit::coord to Exit::coords
[Tsunagari.git] / src / tile.cpp
blob526248d1cd462d8875a7e8ce03780f5775ba06ba
1 /*********************************
2 ** Tsunagari Tile Engine **
3 ** tile.cpp **
4 ** Copyright 2011-2012 OmegaSDG **
5 *********************************/
7 #include <boost/foreach.hpp>
9 #include "area.h"
10 #include "python.h"
11 #include "python_optional.h"
12 #include "tile.h"
13 #include "window.h"
15 static int ivec2_to_dir(ivec2 v)
17 switch (v.x) {
18 case -1:
19 return v.y == 0 ? EXIT_LEFT : -1;
20 case 0:
21 switch (v.y) {
22 case -1:
23 return EXIT_UP;
24 case 0:
25 return EXIT_NORMAL;
26 case 1:
27 return EXIT_DOWN;
28 default:
29 return -1;
31 break;
32 case 1:
33 return v.y == 0 ? EXIT_RIGHT : -1;
34 default:
35 return -1;
39 FlagManip::FlagManip(unsigned* flags)
40 : flags(flags)
44 bool FlagManip::isNowalk() const
46 return (*flags & TILE_NOWALK) != 0;
49 bool FlagManip::isNowalkPlayer() const
51 return (*flags & TILE_NOWALK_PLAYER) != 0;
54 bool FlagManip::isNowalkNPC() const
56 return (*flags & TILE_NOWALK_NPC) != 0;
59 void FlagManip::setNowalk(bool nowalk)
61 *flags = (*flags & ~TILE_NOWALK) | TILE_NOWALK * nowalk;
64 void FlagManip::setNowalkPlayer(bool nowalk)
66 *flags = (*flags & ~TILE_NOWALK_PLAYER) | TILE_NOWALK_PLAYER * nowalk;
69 void FlagManip::setNowalkNPC(bool nowalk)
71 *flags = (*flags & ~TILE_NOWALK_NPC) | TILE_NOWALK_NPC * nowalk;
75 Exit::Exit()
79 Exit::Exit(const std::string area, int x, int y, double z)
80 : area(area), coords(x, y, z)
85 TileBase::TileBase()
86 : parent(NULL), flags(0x0)
90 bool TileBase::hasFlag(unsigned flag) const
92 return flags & flag || (parent && parent->hasFlag(flag));
95 FlagManip TileBase::flagManip()
97 return FlagManip(&flags);
100 TileType* TileBase::getType()
102 return (TileType*)parent;
105 void TileBase::setType(TileType* type)
107 parent = type;
110 void TileBase::onEnterScripts(Entity* triggeredBy)
112 runScripts(triggeredBy, onEnter);
113 if (parent)
114 parent->onEnterScripts(triggeredBy);
117 void TileBase::onLeaveScripts(Entity* triggeredBy)
119 runScripts(triggeredBy, onLeave);
120 if (parent)
121 parent->onLeaveScripts(triggeredBy);
124 void TileBase::onUseScripts(Entity* triggeredBy)
126 runScripts(triggeredBy, onUse);
127 if (parent)
128 parent->onUseScripts(triggeredBy);
131 void TileBase::runScripts(Entity* triggeredBy,
132 const std::vector<std::string>& events)
134 BOOST_FOREACH(const std::string& script, events) {
135 Resourcer* rc = Resourcer::instance();
136 pythonSetGlobal("Entity", triggeredBy);
137 pythonSetGlobal("Tile", this);
138 rc->runPythonScript(script);
142 Tile::Tile()
146 Tile::Tile(Area* area, int x, int y, int z)
147 : TileBase(), area(area), x(x), y(y), z(z)
149 memset(exits, 0, sizeof(exits));
150 memset(layermods, 0, sizeof(layermods));
153 Tile& Tile::offset(int x, int y)
155 return area->getTile(this->x + x, this->y + y, z);
158 Exit* Tile::getNormalExit()
160 return exits[EXIT_NORMAL];
163 void Tile::setNormalExit(Exit exit)
165 Exit** norm = &exits[EXIT_NORMAL];
166 if (*norm)
167 delete *norm;
168 *norm = new Exit(exit);
171 Exit* Tile::exitAt(ivec2 dir)
173 int idx = ivec2_to_dir(dir);
174 return idx == -1 ? NULL : exits[idx];
177 boost::optional<double> Tile::layermodAt(ivec2 dir)
179 int idx = ivec2_to_dir(dir);
180 return idx == -1 ? boost::optional<double>() : layermods[idx];
183 TileType::TileType()
184 : TileBase()
188 TileType::TileType(TiledImage& img)
189 : TileBase()
191 anim.addFrame(img.front());
192 img.pop_front();
195 bool TileType::needsRedraw(const Area& area) const
197 const int millis = GameWindow::getWindow().time();
198 return anim.needsRedraw(millis) &&
199 visibleIn(area, area.visibleTiles());
202 bool TileType::visibleIn(const Area& area, const icube_t& tiles) const
204 for (int z = tiles.z1; z != tiles.z2; z++) {
205 for (int y = tiles.y1; y != tiles.y2; y++) {
206 for (int x = tiles.x1; x != tiles.x2; x++) {
207 icoord pos(x, y, z);
208 // Do this check before passing _tiles_ to fn.
209 if (area.inBounds(pos)) {
210 const Tile& tile = area.getTile(pos);
211 if (tile.parent == this)
212 return true;
217 return false;
222 Exit pythonNewExit(std::string area, int x, int y, double z)
224 return Exit(area, x, y, z);
228 void exportTile()
230 using namespace boost::python;
232 class_<FlagManip> ("FlagManipulator", no_init)
233 .add_property("nowalk",
234 &FlagManip::isNowalk, &FlagManip::setNowalk)
235 .add_property("nowalk_player",
236 &FlagManip::isNowalkPlayer, &FlagManip::setNowalkPlayer)
237 .add_property("nowalk_npc",
238 &FlagManip::isNowalkNPC, &FlagManip::setNowalkNPC)
240 class_<TileBase> ("TileBase", no_init)
241 .add_property("flags", &TileBase::flagManip)
242 .add_property("type",
243 make_function(
244 static_cast<TileType* (TileBase::*) ()>
245 (&TileBase::getType),
246 return_value_policy<reference_existing_object>()),
247 &TileBase::setType)
248 .def("onEnterScripts", &TileBase::onEnterScripts)
249 .def("onLeaveScripts", &TileBase::onLeaveScripts)
250 .def("onUseScripts", &TileBase::onUseScripts)
252 class_<Tile, bases<TileBase> > ("Tile", no_init)
253 .def_readonly("area", &Tile::area)
254 .def_readonly("x", &Tile::x)
255 .def_readonly("y", &Tile::y)
256 .def_readonly("z", &Tile::z)
257 .add_property("exit",
258 make_function(
259 static_cast<Exit* (Tile::*) ()> (&Tile::getNormalExit),
260 return_value_policy<reference_existing_object>()),
261 &Tile::setNormalExit)
262 .def("offset", &Tile::offset,
263 return_value_policy<reference_existing_object>())
265 class_<TileType, bases<TileBase> > ("TileType", no_init)
267 class_<Exit> ("Exit", no_init)
268 .def_readwrite("area", &Exit::area)
269 .def_readwrite("coords", &Exit::coords)
271 pythonAddFunction("newExit", pythonNewExit);