1 /*********************************
2 ** Tsunagari Tile Engine **
4 ** Copyright 2011-2012 OmegaSDG **
5 *********************************/
7 #include <boost/foreach.hpp>
11 #include "python_optional.h"
15 static int ivec2_to_dir(ivec2 v
)
19 return v
.y
== 0 ? EXIT_LEFT
: -1;
33 return v
.y
== 0 ? EXIT_RIGHT
: -1;
39 FlagManip::FlagManip(unsigned* 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
;
79 Exit::Exit(const std::string area
, int x
, int y
, double z
)
80 : area(area
), coords(x
, y
, z
)
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
)
110 void TileBase::onEnterScripts(Entity
* triggeredBy
)
112 runScripts(triggeredBy
, onEnter
);
114 parent
->onEnterScripts(triggeredBy
);
117 void TileBase::onLeaveScripts(Entity
* triggeredBy
)
119 runScripts(triggeredBy
, onLeave
);
121 parent
->onLeaveScripts(triggeredBy
);
124 void TileBase::onUseScripts(Entity
* triggeredBy
)
126 runScripts(triggeredBy
, onUse
);
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
);
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
];
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
];
188 TileType::TileType(TiledImage
& img
)
191 anim
.addFrame(img
.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
++) {
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)
222 Exit
pythonNewExit(std::string area
, int x
, int y
, double z
)
224 return Exit(area
, x
, y
, z
);
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",
244 static_cast<TileType
* (TileBase::*) ()>
245 (&TileBase::getType
),
246 return_value_policy
<reference_existing_object
>()),
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",
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
);