1 /***************************************
2 ** Tsunagari Tile Engine **
4 ** Copyright 2011-2013 PariahSoft LLC **
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
27 #include <stdlib.h> // for exit(1) on fatal
30 #include "formatter.h"
33 #include "python-bindings-template.cpp"
38 static int ivec2_to_dir(ivec2 v
)
42 return v
.y
== 0 ? EXIT_LEFT
: -1;
56 return v
.y
== 0 ? EXIT_RIGHT
: -1;
62 static Exit
pythonNewExit(std::string area
, int x
, int y
, double z
)
64 return Exit(area
, x
, y
, z
);
71 FlagManip::FlagManip(unsigned* flags
)
76 bool FlagManip::isNowalk() const
78 return (*flags
& TILE_NOWALK
) != 0;
81 bool FlagManip::isNowalkPlayer() const
83 return (*flags
& TILE_NOWALK_PLAYER
) != 0;
86 bool FlagManip::isNowalkNPC() const
88 return (*flags
& TILE_NOWALK_NPC
) != 0;
91 bool FlagManip::isNowalkExit() const
93 return (*flags
& TILE_NOWALK_EXIT
) != 0;
96 bool FlagManip::isNowalkAreaBound() const
98 return (*flags
& TILE_NOWALK_AREA_BOUND
) != 0;
101 void FlagManip::setNowalk(bool nowalk
)
103 *flags
&= ~TILE_NOWALK
;
104 *flags
|= TILE_NOWALK
* nowalk
;
107 void FlagManip::setNowalkPlayer(bool nowalk
)
109 *flags
&= ~TILE_NOWALK_PLAYER
;
110 *flags
|= TILE_NOWALK_PLAYER
* nowalk
;
113 void FlagManip::setNowalkNPC(bool nowalk
)
115 *flags
&= ~TILE_NOWALK_NPC
;
116 *flags
|= TILE_NOWALK_NPC
* nowalk
;
119 void FlagManip::setNowalkExit(bool nowalk
)
121 *flags
&= ~TILE_NOWALK_EXIT
;
122 *flags
|= TILE_NOWALK_EXIT
* nowalk
;
125 void FlagManip::setNowalkAreaBound(bool nowalk
)
127 *flags
&= ~TILE_NOWALK_AREA_BOUND
;
128 *flags
|= TILE_NOWALK_AREA_BOUND
* nowalk
;
136 Exit::Exit(const std::string area
, int x
, int y
, double z
)
137 : area(area
), coords(x
, y
, z
)
146 : parent(NULL
), flags(0x0)
150 FlagManip
TileBase::flagManip()
152 return FlagManip(&flags
);
155 bool TileBase::hasFlag(unsigned flag
) const
157 return flags
& flag
|| (parent
&& parent
->hasFlag(flag
));
160 TileType
* TileBase::getType() const
162 return (TileType
*)parent
;
165 void TileBase::setType(TileType
* type
)
170 void TileBase::runEnterScript(Entity
* triggeredBy
)
173 runScript(triggeredBy
, enterScript
);
175 parent
->runEnterScript(triggeredBy
);
178 void TileBase::runLeaveScript(Entity
* triggeredBy
)
181 runScript(triggeredBy
, leaveScript
);
183 parent
->runLeaveScript(triggeredBy
);
186 void TileBase::runUseScript(Entity
* triggeredBy
)
189 runScript(triggeredBy
, useScript
);
191 parent
->runUseScript(triggeredBy
);
194 void TileBase::runScript(Entity
* triggeredBy
, ScriptRef
& script
)
196 pythonSetGlobal("Entity", triggeredBy
);
197 pythonSetGlobal("Tile", this);
210 Tile::Tile(Area
* area
, int x
, int y
, int z
)
211 : TileBase(), area(area
), x(x
), y(y
), z(z
), entCnt(0)
213 memset(exits
, 0, sizeof(exits
));
214 memset(layermods
, 0, sizeof(layermods
));
217 icoord
Tile::moveDest(icoord here
, ivec2 facing
) const
219 icoord dest
= here
+ icoord(facing
.x
, facing
.y
, 0);
221 double* layermod
= layermodAt(facing
);
223 dest
= area
->virt2phys(vicoord(dest
.x
, dest
.y
, *layermod
));
227 Tile
* Tile::offset(int x
, int y
) const
229 return area
->getTile(this->x
+ x
, this->y
+ y
, z
);
232 double Tile::getZ() const
234 vicoord vi
= area
->phys2virt_vi(icoord(x
, y
, z
));
238 Exit
* Tile::getNormalExit() const
240 return exits
[EXIT_NORMAL
];
243 void Tile::setNormalExit(Exit exit
)
245 Exit
** norm
= &exits
[EXIT_NORMAL
];
248 *norm
= new Exit(exit
);
251 Exit
* Tile::exitAt(ivec2 dir
) const
253 int idx
= ivec2_to_dir(dir
);
254 return idx
== -1 ? NULL
: exits
[idx
];
257 double* Tile::layermodAt(ivec2 dir
) const
259 int idx
= ivec2_to_dir(dir
);
260 return idx
== -1 ? NULL
: layermods
[idx
];
272 TileType::TileType(ImageRef
& img
)
275 anim
= Animation(img
);
278 bool TileType::needsRedraw() const
280 time_t now
= World::instance()->time();
281 return anim
.needsRedraw(now
);
291 TileSet::TileSet(int width
, int height
)
292 : width(width
), height(height
)
296 void TileSet::add(TileType
* type
)
298 types
.push_back(type
);
301 void TileSet::set(int idx
, TileType
* type
)
306 TileType
* TileSet::get(int x
, int y
)
308 size_t i
= idx(x
, y
);
309 if (i
> types
.size()) {
311 Formatter("get(%, %): out of bounds") % x
% y
);
317 int TileSet::getWidth() const
322 int TileSet::getHeight() const
327 size_t TileSet::idx(int x
, int y
) const
329 return y
* width
+ x
;
338 using namespace boost::python
;
340 class_
<FlagManip
> ("FlagManipulator", no_init
)
341 .add_property("nowalk",
342 &FlagManip::isNowalk
, &FlagManip::setNowalk
)
343 .add_property("nowalk_player",
344 &FlagManip::isNowalkPlayer
, &FlagManip::setNowalkPlayer
)
345 .add_property("nowalk_npc",
346 &FlagManip::isNowalkNPC
, &FlagManip::setNowalkNPC
)
347 .add_property("nowalk_exit",
348 &FlagManip::isNowalkExit
, &FlagManip::setNowalkExit
)
349 .add_property("nowalk_area_bound",
350 &FlagManip::isNowalkAreaBound
,
351 &FlagManip::setNowalkAreaBound
)
353 class_
<TileBase
> ("TileBase", no_init
)
354 .add_property("flag", &TileBase::flagManip
)
355 .add_property("type",
357 static_cast<TileType
* (TileBase::*) () const>
358 (&TileBase::getType
),
359 return_value_policy
<reference_existing_object
>()),
361 // .def_readwrite("on_enter", &TileBase::enterScript)
362 // .def_readwrite("on_leave", &TileBase::leaveScript)
363 // .def_readwrite("on_use", &TileBase::useScript)
364 .def("run_enter_script", &TileBase::runEnterScript
)
365 .def("run_leave_script", &TileBase::runLeaveScript
)
366 .def("run_use_script", &TileBase::runUseScript
)
368 class_
<Tile
, bases
<TileBase
> > ("Tile", no_init
)
369 .def_readonly("area", &Tile::area
)
370 .def_readonly("x", &Tile::x
)
371 .def_readonly("y", &Tile::y
)
372 .add_property("z", &Tile::getZ
)
373 .add_property("exit",
375 static_cast<Exit
* (Tile::*) () const>
376 (&Tile::getNormalExit
),
377 return_value_policy
<reference_existing_object
>()),
378 &Tile::setNormalExit
)
379 .def_readonly("nentities", &Tile::entCnt
)
380 .def("offset", &Tile::offset
,
381 return_value_policy
<reference_existing_object
>())
383 class_
<TileType
, bases
<TileBase
> > ("TileType", no_init
)
385 class_
<TileSet
> ("TileSet", no_init
)
386 .add_property("width", &TileSet::getWidth
)
387 .add_property("height", &TileSet::getHeight
)
388 .def("at", &TileSet::get
,
389 return_value_policy
<reference_existing_object
>())
391 class_
<Exit
> ("Exit", no_init
)
392 .def_readwrite("area", &Exit::area
)
393 .def_readwrite("coords", &Exit::coords
)
395 pythonAddFunction("new_exit", pythonNewExit
);