12 #include "../api_class.h" 13 #include "../api_function.h" 15 #include "../../obj/simobj.h" 16 #include "../../obj/depot.h" 17 #include "../../world/simworld.h" 18 #include "../../ground/grund.h" 19 #include "../../dataobj/scenario.h" 20 #include "../../descriptor/ground_desc.h" 21 #include "../../obj/baum.h" 22 #include "../../obj/bruecke.h" 23 #include "../../obj/gebaeude.h" 24 #include "../../obj/field.h" 25 #include "../../obj/label.h" 26 #include "../../obj/leitung2.h" 27 #include "../../obj/roadsign.h" 28 #include "../../obj/signal.h" 29 #include "../../obj/tunnel.h" 30 #include "../../obj/wayobj.h" 31 #include "../../player/simplay.h" 34 #include "../../simconvoi.h" 35 #include "../../tool/simmenu.h" 36 #include "../../descriptor/building_desc.h" 37 #include "../../descriptor/vehicle_desc.h" 40 using namespace script_api;
43 static uint8 obj_t_tag[256];
48 template<
class D>
struct bind_code;
53 template<
class D>
struct access_objs {
58 static D* get_by_pos(HSQUIRRELVM vm, SQInteger index)
60 SQUserPointer tag = obj_t_tag + bind_code<D>::objtype;
61 SQUserPointer p = NULL;
62 if (SQ_SUCCEEDED(sq_getinstanceup(vm, index, &p, tag)) && p) {
63 D *obj =
static_cast<D*
>(p);
64 koord3d pos = param<koord3d>::get(vm, index);
65 grund_t *gr = welt->lookup(pos);
66 if (gr && gr->obj_ist_da(obj)) {
71 sq_setinstanceup(vm, index, NULL);
73 sq_raise_error(vm,
"Object of type %s vanished from (%s).", param<D*>::squirrel_type(), pos.get_str());
76 sq_raise_error(vm,
"Object is not of type %s.", param<D*>::squirrel_type);
84 static SQInteger push_with_pos(HSQUIRRELVM vm, D*
const& obj)
90 koord pos = obj->get_pos().get_2d();
91 coordinate_transform_t::koord_w2sq(pos);
94 sint8 z = obj->get_pos().z;
95 if (bind_code<D>::objtype == obj_t::obj) {
97 if (!SQ_SUCCEEDED(push_instance(vm, script_api::param<D*>::squirrel_type(), x, y, z, obj->get_typ()))) {
101 else if (bind_code<D>::objtype != obj->get_typ()) {
103 return script_api::param<obj_t*>::push(vm, obj);
107 if (!SQ_SUCCEEDED(push_instance(vm, script_api::param<D*>::squirrel_type(), x, y, z))) {
111 sq_setinstanceup(vm, -1, obj);
118 SQInteger exp_obj_pos_constructor(HSQUIRRELVM vm)
121 sint16 x = param<sint16>::get(vm, 2);
122 sint16 y = param<sint16>::get(vm, 3);
123 sint8 z = param<sint16>::get(vm, 4);
125 set_slot(vm,
"x", x, 1);
126 set_slot(vm,
"y", y, 1);
128 coordinate_transform_t::koord_sq2w(pos);
130 grund_t *gr = welt->lookup(koord3d(pos, z));
131 for(uint8 i=1, end = ground_desc_t::double_grounds ? 2 : 1; gr == NULL && i<=end; i++) {
132 gr = welt->lookup(koord3d(pos, z-i));
137 set_slot(vm,
"z", gr->get_pos().z, 1);
139 obj_t::typ type = (obj_t::typ)param<uint8>::get(vm, 5);
141 if (type == obj_t::roadsign || type == obj_t::signal) {
143 obj = gr->suche_obj(obj_t::roadsign);
145 obj = gr->suche_obj(obj_t::signal);
148 else if (type == obj_t::pumpe || type == obj_t::senke) {
149 obj = gr->suche_obj(obj_t::pumpe);
151 obj = gr->suche_obj(obj_t::senke);
154 else if (type != obj_t::old_airdepot) {
155 obj = gr->suche_obj(type);
158 obj = gr->get_depot();
161 sq_setinstanceup(vm, 1, obj);
165 return sq_raise_error(vm,
"No object of requested type on tile (or no tile at this position)");
168 template<>
struct bind_code<obj_t> {
static const uint8 objtype = obj_t::obj; };
171 #define getpush_obj_pos(D, type) \ 172 D* script_api::param<D*>::get(HSQUIRRELVM vm, SQInteger index) \ 174 return access_objs<D>::get_by_pos(vm, index); \ 176 SQInteger script_api::param<D*>::push(HSQUIRRELVM vm, D* const& obj) \ 178 return access_objs<D>::push_with_pos(vm, obj); \ 180 template<> struct bind_code<D> { static const uint8 objtype = type; }; 183 getpush_obj_pos(baum_t, obj_t::baum);
184 getpush_obj_pos(gebaeude_t, obj_t::gebaeude);
185 getpush_obj_pos(label_t, obj_t::label);
186 getpush_obj_pos(weg_t, obj_t::way);
187 getpush_obj_pos(leitung_t, obj_t::leitung);
188 getpush_obj_pos(field_t, obj_t::field);
189 getpush_obj_pos(wayobj_t, obj_t::wayobj);
190 getpush_obj_pos(bruecke_t, obj_t::bruecke);
191 getpush_obj_pos(tunnel_t, obj_t::tunnel);
193 namespace script_api {
195 declare_specialized_param(depot_t*,
"t|x|y",
"depot_x");
196 declare_specialized_param(airdepot_t*,
"t|x|y",
"depot_x");
197 declare_specialized_param(narrowgaugedepot_t*,
"t|x|y",
"depot_x");
198 declare_specialized_param(bahndepot_t*,
"t|x|y",
"depot_x");
199 declare_specialized_param(strassendepot_t*,
"t|x|y",
"depot_x");
200 declare_specialized_param(schiffdepot_t*,
"t|x|y",
"depot_x");
201 declare_specialized_param(monoraildepot_t*,
"t|x|y",
"depot_x");
202 declare_specialized_param(tramdepot_t*,
"t|x|y",
"depot_x");
203 declare_specialized_param(maglevdepot_t*,
"t|x|y",
"depot_x");
206 declare_specialized_param(roadsign_t*,
"t|x|y",
"sign_x");
207 declare_specialized_param(signal_t*,
"t|x|y",
"sign_x");
210 declare_specialized_param(pumpe_t*,
"t|x|y",
"transformer_x");
211 declare_specialized_param(senke_t*,
"t|x|y",
"transformer_x");
215 getpush_obj_pos(depot_t, obj_t::old_airdepot);
217 getpush_obj_pos(airdepot_t, obj_t::airdepot);
218 getpush_obj_pos(narrowgaugedepot_t, obj_t::narrowgaugedepot);
219 getpush_obj_pos(bahndepot_t, obj_t::bahndepot);
220 getpush_obj_pos(strassendepot_t, obj_t::strassendepot);
221 getpush_obj_pos(schiffdepot_t, obj_t::schiffdepot);
222 getpush_obj_pos(monoraildepot_t, obj_t::monoraildepot);
223 getpush_obj_pos(tramdepot_t, obj_t::tramdepot);
224 getpush_obj_pos(maglevdepot_t, obj_t::maglevdepot);
226 getpush_obj_pos(roadsign_t, obj_t::roadsign);
227 getpush_obj_pos(signal_t, obj_t::signal);
229 getpush_obj_pos(pumpe_t, obj_t::pumpe);
230 getpush_obj_pos(senke_t, obj_t::senke);
233 #define case_resolve_obj(D) \ 234 case bind_code<D>::objtype: \ 235 return script_api::param<D*>::push(vm, (D*)obj); 238 SQInteger script_api::param<obj_t*>::push(HSQUIRRELVM vm, obj_t*
const& obj)
244 obj_t::typ type = obj->get_typ();
246 case_resolve_obj(baum_t);
247 case_resolve_obj(gebaeude_t);
248 case_resolve_obj(label_t);
249 case_resolve_obj(weg_t);
250 case_resolve_obj(roadsign_t);
251 case_resolve_obj(signal_t);
252 case_resolve_obj(field_t);
254 case_resolve_obj(airdepot_t);
255 case_resolve_obj(narrowgaugedepot_t);
256 case_resolve_obj(bahndepot_t);
257 case_resolve_obj(strassendepot_t);
258 case_resolve_obj(schiffdepot_t);
259 case_resolve_obj(monoraildepot_t);
260 case_resolve_obj(tramdepot_t);
261 case_resolve_obj(maglevdepot_t);
263 case_resolve_obj(leitung_t);
264 case_resolve_obj(pumpe_t);
265 case_resolve_obj(senke_t);
267 case_resolve_obj(wayobj_t);
268 case_resolve_obj(bruecke_t);
269 case_resolve_obj(tunnel_t);
271 return access_objs<obj_t>::push_with_pos(vm, obj);
275 obj_t* script_api::param<obj_t*>::get(HSQUIRRELVM vm, SQInteger index)
277 return access_objs<obj_t>::get_by_pos(vm, index);
281 static SQInteger get_way_ribi(HSQUIRRELVM vm)
283 weg_t *w = param<weg_t*>::get(vm, 1);
284 bool masked = param<bool>::get(vm, 2);
286 ribi_t::ribi ribi = w ? (masked ? w->get_ribi() : w->get_ribi_unmasked() ) : 0;
288 return param<my_ribi_t>::push(vm, ribi);
293 static SQInteger map_obj_to_string(HSQUIRRELVM vm)
295 static cbuffer_t buf;
297 koord3d pos = script_api::param<koord3d>::get(vm, 1);
298 D* obj = script_api::param<D*>::get(vm, 1);
299 buf.printf(
"%s@%s", script_api::param<D*>::squirrel_type(), pos.get_str());
301 buf.append(
" [invalid]");
303 sq_pushstring(vm, (
const char*)buf, -1);
310 static void begin_obj_class(HSQUIRRELVM vm,
const char* name,
const char* base = NULL)
312 SQInteger res = create_class(vm, name, base);
313 if( !SQ_SUCCEEDED(res) ) {
315 dbg->error(
"begin_obj_class()",
"Create class failed for %s. Base class %s missing. Please update simutrans (or just script/script_base.nut)!", name, base );
316 sq_raise_error(vm,
"Create class failed for %s. Base class %s missing. Please update simutrans (or just script/script_base.nut)!", name, base);
318 uint8 objtype = bind_code<D>::objtype;
320 sq_settypetag(vm, -1, obj_t_tag + objtype);
322 register_function_fv(vm, exp_obj_pos_constructor,
"constructor", 4,
"xiiii", freevariable<uint8>(objtype));
324 register_function(vm, map_obj_to_string<D>,
"_tostring", 1,
"x");
329 static void mark_object(obj_t* obj)
331 obj->set_flag(obj_t::highlight);
332 obj->set_flag(obj_t::dirty);
334 static void unmark_object(obj_t* obj)
336 obj->clear_flag(obj_t::highlight);
337 obj->set_flag(obj_t::dirty);
339 static bool object_is_marked(obj_t* obj)
341 return obj->get_flag(obj_t::highlight);
345 static call_tool_work create_marker(koord pos, player_t* player,
const char* text)
348 return "Cannot create label with text == null";
350 return call_tool_work(TOOL_MARKER | GENERAL_TOOL, text, 0, player, koord3d(pos, 0));
353 static call_tool_init label_set_text(label_t *l,
const char* text)
355 return command_rename(l->get_owner(),
'm', l->get_pos(), text);
358 static const char* label_get_text(label_t* l)
361 if (grund_t *gr = welt->lookup(l->get_pos())) {
362 return gr->get_text();
369 static bool roadsign_can_pass(
const roadsign_t* rs, player_t* player)
371 return player && rs->get_desc()->is_private_way() ? (rs->get_player_mask() & (1<<player->get_player_nr()))!=0 :
true;
375 static call_tool_init depot_append_vehicle(depot_t *depot, player_t *player, convoihandle_t cnv,
const vehicle_desc_t *desc)
378 return "Invalid vehicle_desc_x provided";
383 buf.printf(
"%c,%s,%hu,%s",
'a', depot->get_pos().get_str(), cnv.get_id(), desc->get_name());
385 return call_tool_init(TOOL_CHANGE_DEPOT | SIMPLE_TOOL, buf, 0, player);
388 static call_tool_init depot_start_convoy(depot_t *depot, player_t *player, convoihandle_t cnv)
393 if (cnv.is_bound()) {
394 buf.printf(
"%c,%s,%hu",
'b', depot->get_pos().get_str(), cnv->self.get_id());
397 buf.printf(
"%c,%s,%hu",
'B', depot->get_pos().get_str(), 0);
400 return call_tool_init(TOOL_CHANGE_DEPOT | SIMPLE_TOOL, buf, 0, player);
403 static vector_tpl<convoihandle_t>
const& depot_get_convoy_list(depot_t *depot)
405 static vector_tpl<convoihandle_t> list;
411 slist_tpl<convoihandle_t>
const& slist = depot->get_convoy_list();
413 for(slist_tpl<convoihandle_t>::const_iterator i = slist.begin(), end = slist.end(); i!=end; ++i) {
419 static vector_tpl<depot_t*>
const& get_depot_list(player_t *player, waytype_t wt)
421 static vector_tpl<depot_t*> list;
424 simline_t::linetype line_type = simline_t::waytype_to_linetype(wt);
425 if (player == NULL || line_type == simline_t::MAX_LINE_TYPE) {
429 const slist_tpl<depot_t*> &depot_list = depot_t::get_depot_list();
431 for(depot_t* d : depot_list) {
432 if(d->get_line_type()==line_type && d->get_owner()==player) {
440 static const fabrik_t* transformer_get_factory(leitung_t *lt)
442 if (pumpe_t *p = dynamic_cast<pumpe_t*>(lt)) {
443 return p->get_factory();
445 if (senke_t *s = dynamic_cast<senke_t*>(lt)) {
446 return s->get_factory();
451 static bool leitung_is_connected(leitung_t* lt1, leitung_t* lt2)
453 return lt2 != NULL && lt1->get_net() == lt2->get_net();
456 static bool field_is_deletable(field_t* f)
458 return f->get_removal_error( welt->get_public_player() ) == NULL;
462 static vector_tpl<sint64>
const& get_way_stat(weg_t* weg, sint32 INDEX)
464 static vector_tpl<sint64> v;
466 if (weg && 0<=INDEX && INDEX<WAY_STAT_MAX) {
467 for(uint16 i = 0; i < MAX_WAY_STAT_MONTHS; i++) {
468 v.append( weg->get_stat(i, INDEX) );
474 static vector_tpl<grund_t*>
const& get_tile_list( gebaeude_t *gb )
476 static vector_tpl<grund_t*> list;
477 gb->get_tile_list( list );
482 void export_map_objects(HSQUIRRELVM vm)
488 begin_class(vm,
"map_object_x",
"coord3d,extend_get,ingame_object");
489 uint8 objtype = bind_code<obj_t>::objtype;
490 sq_settypetag(vm, -1, obj_t_tag + objtype);
501 register_function(vm, exp_obj_pos_constructor,
"constructor", 5,
"xiiii");
505 export_is_valid<obj_t*>(vm);
509 register_method(vm, &obj_t::get_owner,
"get_owner");
513 register_method(vm, &obj_t::get_name,
"get_name");
517 register_method(vm, &obj_t::get_waytype,
"get_waytype");
521 register_method(vm, &obj_t::get_pos,
"get_pos");
526 register_method(vm, &obj_t::get_removal_error,
"is_removable");
530 register_method(vm, &obj_t::get_typ,
"get_type");
534 register_method(vm, &mark_object,
"mark",
true);
538 register_method(vm, &unmark_object,
"unmark",
true);
542 register_method(vm, &object_is_marked,
"is_marked",
true);
549 begin_obj_class<baum_t>(vm,
"tree_x",
"map_object_x");
553 register_method(vm, &baum_t::get_age,
"get_age");
557 register_method(vm, &baum_t::get_desc,
"get_desc");
564 begin_obj_class<gebaeude_t>(vm,
"building_x",
"map_object_x");
568 register_method(vm, &gebaeude_t::get_fabrik,
"get_factory");
572 register_method(vm, &gebaeude_t::get_stadt,
"get_city");
576 register_method(vm, &gebaeude_t::is_townhall,
"is_townhall");
580 register_method(vm, &gebaeude_t::is_headquarter,
"is_headquarter");
584 register_method(vm, &gebaeude_t::is_monument,
"is_monument");
589 register_method(vm, &gebaeude_t::get_passagier_level,
"get_passenger_level");
594 register_method(vm, &gebaeude_t::get_mail_level,
"get_mail_level");
598 register_method(vm, &gebaeude_t::get_tile,
"get_desc");
602 register_method( vm, &get_tile_list,
"get_tile_list",
true );
606 register_method(vm, &gebaeude_t::is_same_building,
"is_same_building");
614 begin_obj_class<depot_t>(vm,
"depot_x",
"building_x");
622 register_method(vm, depot_append_vehicle,
"append_vehicle",
true);
627 register_method(vm, depot_start_convoy,
"start_convoy",
true);
632 register_method_fv(vm, depot_start_convoy,
"start_all_convoys", freevariable<convoihandle_t>(convoihandle_t()),
true);
636 register_method(vm, &depot_get_convoy_list,
"get_convoy_list",
true);
643 STATIC register_method(vm, &get_depot_list,
"get_depot_list",
false,
true);
649 begin_obj_class<weg_t>(vm,
"way_x",
"map_object_x");
653 register_method(vm, &weg_t::hat_gehweg,
"has_sidewalk");
657 register_method(vm, &weg_t::is_electrified,
"is_electrified");
661 register_method(vm, &weg_t::has_sign,
"has_sign");
665 register_method(vm, &weg_t::has_signal,
"has_signal");
669 register_method(vm, &weg_t::has_wayobj,
"has_wayobj");
673 register_method(vm, &weg_t::is_crossing,
"is_crossing");
679 register_function_fv(vm, &get_way_ribi,
"get_dirs", 1,
"x", freevariable<bool>(
false) );
685 register_function_fv(vm, &get_way_ribi,
"get_dirs_masked", 1,
"x", freevariable<bool>(
true) );
689 register_method(vm, &weg_t::get_desc,
"get_desc");
695 register_method(vm, &weg_t::get_max_speed,
"get_max_speed");
700 register_method_fv(vm, &get_way_stat,
"get_transported_goods", freevariable<sint32>(WAY_STAT_GOODS),
true);
705 register_method_fv(vm, &get_way_stat,
"get_convoys_passed", freevariable<sint32>(WAY_STAT_CONVOIS),
true);
712 begin_obj_class<label_t>(vm,
"label_x",
"map_object_x");
720 STATIC register_method(vm, &create_marker,
"create",
false,
true);
726 register_method(vm, &label_set_text,
"set_text",
true);
731 register_method(vm, &label_get_text,
"get_text",
true);
738 begin_obj_class<roadsign_t>(vm,
"sign_x",
"map_object_x");
742 register_method(vm, &roadsign_t::get_desc,
"get_desc");
749 register_method(vm, &roadsign_can_pass,
"can_pass",
true);
756 begin_obj_class<leitung_t>(vm,
"powerline_x",
"map_object_x");
762 register_method(vm, &leitung_is_connected,
"is_connected",
true);
769 begin_obj_class<pumpe_t>(vm,
"transformer_x",
"powerline_x");
774 register_method(vm, &transformer_get_factory,
"get_factory",
true);
780 begin_obj_class<field_t>(vm,
"field_x",
"map_object_x");
786 register_method(vm, &field_is_deletable,
"is_deletable",
true);
791 register_method(vm, &field_t::get_factory,
"get_factory");
797 begin_obj_class<wayobj_t>(vm,
"wayobj_x",
"map_object_x");
801 register_method(vm, &wayobj_t::get_desc,
"get_desc");
807 begin_obj_class<bruecke_t>(vm,
"bridge_x",
"map_object_x");
811 register_method(vm, &bruecke_t::get_desc,
"get_desc");
817 begin_obj_class<tunnel_t>(vm,
"tunnel_x",
"map_object_x");
821 register_method(vm, &tunnel_t::get_desc,
"get_desc");