1 #include "api_param.h"
2 #include "api_class.h"
3 
4 #include "../simcity.h"
5 #include "../simfab.h"
6 #include "../bauer/goods_manager.h"
7 #include "../dataobj/schedule.h"
8 #include "../dataobj/loadsave.h"
9 #include "../dataobj/scenario.h"
10 #include "../player/simplay.h"
11 #include "../utils/plainstring.h"
12 #include "api/api_command.h" // script_api::my_tool_t
13 #include "api/api_simple.h"  // my_ribi_t
14 
15 
clamp(T v,T l,T u)16 template<typename T> T clamp(T v, T l, T u) { return v < l ? l : (v > u ? u :v); }
17 
18 namespace script_api {
19 
20 	karte_ptr_t welt;
21 
22 // rotation handling
rotate90()23 	void rotate90() { coordinate_transform_t::rotate90(); }
new_world()24 	void new_world() { coordinate_transform_t::new_world(); }
25 
26 	uint8 coordinate_transform_t::rotation = 4;
27 
initialize()28 	void coordinate_transform_t::initialize()
29 	{
30 		if (rotation == 4) {
31 			rotation = welt->get_settings().get_rotation();
32 		}
33 	}
34 
rdwr(loadsave_t * file)35 	void coordinate_transform_t::rdwr(loadsave_t *file)
36 	{
37 		file->rdwr_byte(rotation);
38 	}
39 
koord_w2sq(koord & k)40 	void coordinate_transform_t::koord_w2sq(koord &k)
41 	{
42 		// do not transform koord::invalid
43 		if (k.x == -1  &&  k.y == -1) {
44 			return;
45 		}
46 		switch( rotation ) {
47 			// 0: do nothing
48 			case 1: k = koord(k.y, welt->get_size().x-1 - k.x); break;
49 			case 2: k = koord(welt->get_size().x-1 - k.x, welt->get_size().y-1 - k.y); break;
50 			case 3: k = koord(welt->get_size().y-1 - k.y, k.x); break;
51 			default: break;
52 		}
53 	}
54 
koord_sq2w(koord & k)55 	void coordinate_transform_t::koord_sq2w(koord &k)
56 	{
57 		// do not transform koord::invalid
58 		if (k.x == -1  &&  k.y == -1) {
59 			return;
60 		}
61 		switch( rotation ) {
62 			// 0: do nothing
63 			case 1: k = koord(welt->get_size().x-1 - k.y, k.x); break;
64 			case 2: k = koord(welt->get_size().x-1 - k.x, welt->get_size().y-1 - k.y); break;
65 			case 3: k = koord(k.y, welt->get_size().y-1 - k.x); break;
66 			default: break;
67 		}
68 	}
69 
ribi_w2sq(ribi_t::ribi & r)70 	void coordinate_transform_t::ribi_w2sq(ribi_t::ribi &r)
71 	{
72 		if (rotation) {
73 			r = ( ( (r << 4) | r) >> rotation) & 15;
74 		}
75 	}
76 
ribi_sq2w(ribi_t::ribi & r)77 	void coordinate_transform_t::ribi_sq2w(ribi_t::ribi &r)
78 	{
79 		if (rotation) {
80 			r = ( ( (r << 4) | r) << rotation) >> 4 & 15;
81 		}
82 	}
83 
slope_w2sq(slope_t::type & s)84 	void coordinate_transform_t::slope_w2sq(slope_t::type &s)
85 	{
86 		if (s < slope_t::raised) {
87 			for(uint8 i=1; i <= 4-rotation; i++) {
88 				s = slope_t::rotate90(s);
89 			}
90 		}
91 	}
92 
slope_sq2w(slope_t::type & s)93 	void coordinate_transform_t::slope_sq2w(slope_t::type &s)
94 	{
95 		if (s < slope_t::raised) {
96 			for(uint8 i=1; i <= rotation; i++) {
97 				s = slope_t::rotate90(s);
98 			}
99 		}
100 	}
101 
102 // void parameter
push(HSQUIRRELVM,void_t const &)103 	SQInteger param<void_t>::push(HSQUIRRELVM, void_t const&)
104 	{
105 		return 0;
106 	}
107 
get(HSQUIRRELVM,SQInteger)108 	void_t param<void_t>::get(HSQUIRRELVM, SQInteger)
109 	{
110 		return void_t();
111 	}
112 
113 // integer arguments
get(HSQUIRRELVM vm,SQInteger index)114 	uint8 param<uint8>::get(HSQUIRRELVM vm, SQInteger index)
115 	{
116 		SQInteger i = 0;
117 		sq_getinteger(vm, index, &i);
118 		return clamp<uint8>(i, 0, 255);
119 	}
push(HSQUIRRELVM vm,uint8 const & v)120 	SQInteger param<uint8>::push(HSQUIRRELVM vm, uint8 const& v)
121 	{
122 		sq_pushinteger(vm, v);
123 		return 1;
124 	}
125 
get(HSQUIRRELVM vm,SQInteger index)126 	sint8 param<sint8>::get(HSQUIRRELVM vm, SQInteger index)
127 	{
128 		SQInteger i = 0;
129 		sq_getinteger(vm, index, &i);
130 		return clamp<sint8>(i, -128, 127);
131 	}
push(HSQUIRRELVM vm,sint8 const & v)132 	SQInteger param<sint8>::push(HSQUIRRELVM vm, sint8 const& v)
133 	{
134 		sq_pushinteger(vm, v);
135 		return 1;
136 	}
137 
get(HSQUIRRELVM vm,SQInteger index)138 	uint16 param<uint16>::get(HSQUIRRELVM vm, SQInteger index)
139 	{
140 		SQInteger i = 0;
141 		sq_getinteger(vm, index, &i);
142 		return clamp<uint16>(i, 0, 0xffff);
143 	}
push(HSQUIRRELVM vm,uint16 const & v)144 	SQInteger param<uint16>::push(HSQUIRRELVM vm, uint16 const& v)
145 	{
146 		sq_pushinteger(vm, v);
147 		return 1;
148 	}
149 
get(HSQUIRRELVM vm,SQInteger index)150 	sint16 param<sint16>::get(HSQUIRRELVM vm, SQInteger index)
151 	{
152 		SQInteger i = 0;
153 		sq_getinteger(vm, index, &i);
154 		return clamp<sint16>(i, -32768, 0x7fff);
155 	}
push(HSQUIRRELVM vm,sint16 const & v)156 	SQInteger param<sint16>::push(HSQUIRRELVM vm, sint16 const& v)
157 	{
158 		sq_pushinteger(vm, v);
159 		return 1;
160 	}
161 
get(HSQUIRRELVM vm,SQInteger index)162 	uint32 param<uint32>::get(HSQUIRRELVM vm, SQInteger index)
163 	{
164 		SQInteger i = 0;
165 		sq_getinteger(vm, index, &i);
166 		return i>=0 ? i : 0;
167 	}
push(HSQUIRRELVM vm,uint32 const & v)168 	SQInteger param<uint32>::push(HSQUIRRELVM vm, uint32 const& v)
169 	{
170 		sq_pushinteger(vm, v);
171 		return 1;
172 	}
173 
get(HSQUIRRELVM vm,SQInteger index)174 	sint32 param<sint32>::get(HSQUIRRELVM vm, SQInteger index)
175 	{
176 		SQInteger i = 0;
177 		sq_getinteger(vm, index, &i);
178 		return i;
179 	}
push(HSQUIRRELVM vm,sint32 const & v)180 	SQInteger param<sint32>::push(HSQUIRRELVM vm, sint32 const& v)
181 	{
182 		sq_pushinteger(vm, v);
183 		return 1;
184 	}
185 
get(HSQUIRRELVM vm,SQInteger index)186 	uint64 param<uint64>::get(HSQUIRRELVM vm, SQInteger index)
187 	{
188 		SQInteger i = 0;
189 		sq_getinteger(vm, index, &i);
190 		return i>=0 ? i : 0;
191 	}
push(HSQUIRRELVM vm,uint64 const & v)192 	SQInteger param<uint64>::push(HSQUIRRELVM vm, uint64 const& v)
193 	{
194 		sq_pushinteger(vm, (SQInteger)v);
195 		return 1;
196 	}
197 
get(HSQUIRRELVM vm,SQInteger index)198 	sint64 param<sint64>::get(HSQUIRRELVM vm, SQInteger index)
199 	{
200 		SQInteger i = 0;
201 		sq_getinteger(vm, index, &i);
202 		return i;
203 	}
push(HSQUIRRELVM vm,sint64 const & v)204 	SQInteger param<sint64>::push(HSQUIRRELVM vm, sint64 const& v)
205 	{
206 		sq_pushinteger(vm, (SQInteger)v);
207 		return 1;
208 	}
209 
210 // floats
get(HSQUIRRELVM vm,SQInteger index)211 	double param<double>::get(HSQUIRRELVM vm, SQInteger index)
212 	{
213 		SQFloat d = 0.0;
214 		sq_getfloat(vm, index, &d);
215 		return d;
216 	}
push(HSQUIRRELVM vm,double const & v)217 	SQInteger param<double>::push(HSQUIRRELVM vm, double  const& v)
218 	{
219 		sq_pushfloat(vm, (SQFloat)v);
220 		return 1;
221 	}
222 
223 // strings
get(HSQUIRRELVM vm,SQInteger index)224 	const char* param<const char*>::get(HSQUIRRELVM vm, SQInteger index)
225 	{
226 		const char* str = NULL;
227 		if (!SQ_SUCCEEDED(sq_getstring(vm, index, &str))) {
228 			sq_raise_error(vm, "Supplied string parameter is null");
229 			return NULL;
230 		}
231 		return str;
232 	}
push(HSQUIRRELVM vm,const char * const & v)233 	SQInteger param<const char*>::push(HSQUIRRELVM vm, const char* const& v)
234 	{
235 		if (v) {
236 			sq_pushstring(vm, v, -1);
237 		}
238 		else {
239 			sq_pushnull(vm);
240 		}
241 		return 1;
242 	}
243 
get(HSQUIRRELVM vm,SQInteger index)244 	plainstring param<plainstring>::get(HSQUIRRELVM vm, SQInteger index)
245 	{
246 		if (sq_gettype(vm, index) == OT_NULL) {
247 			return NULL;
248 		}
249 		plainstring ret;
250 		const char* str = NULL;
251 		if (!SQ_SUCCEEDED(sq_getstring(vm, index, &str))) {
252 			// try tostring
253 			if (SQ_SUCCEEDED(sq_tostring(vm, index))) {
254 				sq_getstring(vm, -1, &str);
255 				ret = str;
256 				sq_pop(vm, 1);
257 			}
258 		}
259 		else {
260 			ret = str;
261 		}
262 		return ret;
263 	}
264 
push(HSQUIRRELVM vm,plainstring const & v)265 	SQInteger param<plainstring>::push(HSQUIRRELVM vm, plainstring const& v)
266 	{
267 		return param<const char*>::push(vm, v.c_str());
268 	}
269 
270 // bool
get(HSQUIRRELVM vm,SQInteger index)271 	bool param<bool>::get(HSQUIRRELVM vm, SQInteger index)
272 	{
273 		SQBool b = false;
274 		sq_tobool(vm, index, &b);
275 		return b;
276 	}
push(HSQUIRRELVM vm,bool const & v)277 	SQInteger param<bool>::push(HSQUIRRELVM vm, bool const& v)
278 	{
279 		sq_pushbool(vm, v);
280 		return 1;
281 	}
282 
283 // coordinates
get(HSQUIRRELVM vm,SQInteger index)284 	koord param<koord>::get(HSQUIRRELVM vm, SQInteger index)
285 	{
286 		sint16 x=-1, y=-1;
287 		get_slot(vm, "x", x, index);
288 		get_slot(vm, "y", y, index);
289 		koord k(x,y);
290 		if (k.x != -1  &&  k.y != -1) {
291 			// transform coordinates
292 			coordinate_transform_t::koord_sq2w(k);
293 		}
294 		else {
295 			k = koord::invalid;
296 		}
297 		return k;
298 	}
299 
push(HSQUIRRELVM vm,koord const & v)300 	SQInteger param<koord>::push(HSQUIRRELVM vm, koord const& v)
301 	{
302 		koord k(v);
303 		if (k.x != -1  &&  k.y != -1) {
304 			// transform coordinates
305 			coordinate_transform_t::koord_w2sq(k);
306 		}
307 		else {
308 			k = koord::invalid;
309 		}
310 		return push_instance(vm, "coord", k.x, k.y);
311 	}
312 
get(HSQUIRRELVM vm,SQInteger index)313 	koord3d param<koord3d>::get(HSQUIRRELVM vm, SQInteger index)
314 	{
315 		sint8 z = -1;
316 		if (!SQ_SUCCEEDED(get_slot(vm, "z", z, index))) {
317 			return koord3d::invalid;
318 		}
319 		koord k = param<koord>::get(vm, index);
320 		return koord3d(k, z);
321 	}
322 
323 
push(HSQUIRRELVM vm,koord3d const & v)324 	SQInteger param<koord3d>::push(HSQUIRRELVM vm, koord3d const& v)
325 	{
326 		koord k(v.get_2d());
327 		if (k.x != -1  &&  k.y != -1) {
328 			// transform coordinates
329 			coordinate_transform_t::koord_w2sq(k);
330 		}
331 		else {
332 			k = koord::invalid;
333 		}
334 		return push_instance(vm, "coord3d", k.x, k.y, v.z);
335 	}
336 // directions / ribis
push(HSQUIRRELVM vm,my_ribi_t const & v)337 	SQInteger param<my_ribi_t>::push(HSQUIRRELVM vm, my_ribi_t const& v)
338 	{
339 		ribi_t::ribi ribi = v;
340 		coordinate_transform_t::ribi_w2sq(ribi);
341 		return param<uint8>::push(vm, ribi);
342 	}
343 
get(HSQUIRRELVM vm,SQInteger index)344 	my_ribi_t param<my_ribi_t>::get(HSQUIRRELVM vm, SQInteger index)
345 	{
346 		ribi_t::ribi ribi = param<uint8>::get(vm, index) & ribi_t::all;
347 		coordinate_transform_t::ribi_sq2w(ribi);
348 		return ribi;
349 	}
350 // slopes
push(HSQUIRRELVM vm,my_slope_t const & v)351 	SQInteger param<my_slope_t>::push(HSQUIRRELVM vm, my_slope_t const& v)
352 	{
353 		slope_t::type slope = v;
354 		coordinate_transform_t::slope_w2sq(slope);
355 		return param<uint8>::push(vm, slope);
356 	}
357 
get(HSQUIRRELVM vm,SQInteger index)358 	my_slope_t param<my_slope_t>::get(HSQUIRRELVM vm, SQInteger index)
359 	{
360 		slope_t::type slope = param<uint8>::get(vm, index);
361 		coordinate_transform_t::slope_sq2w(slope);
362 		return slope;
363 	}
364 
365 // pointers to classes
366 
get(HSQUIRRELVM vm,SQInteger index)367 	convoi_t* param<convoi_t*>::get(HSQUIRRELVM vm, SQInteger index)
368 	{
369 		convoihandle_t cnv = param<convoihandle_t>::get(vm, index);
370 		if (!cnv.is_bound()) {
371 			sq_raise_error(vm, "Invalid convoi id %d", cnv.get_id());
372 		}
373 		return cnv.get_rep();
374 	}
375 
get(HSQUIRRELVM vm,SQInteger index)376 	fabrik_t* param<fabrik_t*>::get(HSQUIRRELVM vm, SQInteger index)
377 	{
378 		koord pos = param<koord>::get(vm, index);
379 		fabrik_t* fab = fabrik_t::get_fab(pos);
380 		if (fab==NULL) {
381 			sq_raise_error(vm, "no factory at position (%s)", pos.get_str());
382 		}
383 		return fab;
384 	}
385 
push(HSQUIRRELVM vm,fabrik_t * const & fab)386 	SQInteger param<fabrik_t*>::push(HSQUIRRELVM vm, fabrik_t* const& fab)
387 	{
388 		if (fab == NULL) {
389 			sq_pushnull(vm); return 1;
390 		}
391 		koord pos(fab->get_pos().get_2d());
392 		coordinate_transform_t::koord_w2sq(pos);
393 		return push_instance(vm, "factory_x", pos.x, pos.y);
394 	}
395 
get(HSQUIRRELVM vm,SQInteger index)396 	const ware_production_t* param<const ware_production_t*>::get(HSQUIRRELVM vm, SQInteger index)
397 	{
398 		fabrik_t* fab = param<fabrik_t*>::get(vm, index);
399 		if (fab == NULL) {
400 			return NULL;
401 		}
402 		// obtain index into wareproduction_t arrays
403 		SQInteger i = -1;
404 		if (SQ_SUCCEEDED(get_slot(vm, "index", i, index))) {
405 			if (i>=0) {
406 				if ( (uint32)i<fab->get_input().get_count()) {
407 					return &fab->get_input()[i];
408 				}
409 				else {
410 					i -= fab->get_input().get_count();
411 					if ( (uint32)i<fab->get_output().get_count()) {
412 						return &fab->get_output()[i];
413 					}
414 				}
415 			}
416 		}
417 		sq_raise_error(vm, "No production slot [%d] in factory at (%s)", i, fab->get_pos().get_str());
418 		return NULL;
419 	}
420 
get(HSQUIRRELVM vm,SQInteger index)421 	const factory_supplier_desc_t* param<const factory_supplier_desc_t*>::get(HSQUIRRELVM vm, SQInteger index)
422 	{
423 		fabrik_t* fab = param<fabrik_t*>::get(vm, index);
424 		if (fab == NULL) {
425 			return NULL;
426 		}
427 		// obtain index into wareproduction_t arrays
428 		SQInteger i = -1;
429 		if (SQ_SUCCEEDED(get_slot(vm, "index", i, index))) {
430 			if (i>=0  &&  (uint32)i<fab->get_input().get_count()) {
431 				const ware_production_t& in = fab->get_input()[i];
432 				const factory_supplier_desc_t* desc = fab->get_desc()->get_supplier(i);
433 				// sanity check
434 				if (desc  &&  desc->get_input_type() == in.get_typ()) {
435 					return desc;
436 				}
437 			}
438 		}
439 		sq_raise_error(vm, "No input slot [%d] in factory at (%s)", i, fab->get_pos().get_str());
440 		return NULL;
441 	}
442 
get(HSQUIRRELVM vm,SQInteger index)443 	const factory_product_desc_t* param<const factory_product_desc_t*>::get(HSQUIRRELVM vm, SQInteger index)
444 	{
445 		fabrik_t* fab = param<fabrik_t*>::get(vm, index);
446 		if (fab == NULL) {
447 			return NULL;
448 		}
449 		// obtain index into wareproduction_t arrays
450 		SQInteger i = -1;
451 		if (SQ_SUCCEEDED(get_slot(vm, "index", i, index))) {
452 			i -= fab->get_input().get_count();
453 			if (i>=0  &&  (uint32)i<fab->get_output().get_count()) {
454 				const ware_production_t& out = fab->get_output()[i];
455 				const factory_product_desc_t* desc = fab->get_desc()->get_product(i);
456 				// sanity check
457 				if (desc  &&  desc->get_output_type() == out.get_typ()) {
458 					return desc;
459 				}
460 			}
461 		}
462 		sq_raise_error(vm, "No output slot [%d] in factory at (%s)", i, fab->get_pos().get_str());
463 		return NULL;
464 	}
465 
get(HSQUIRRELVM vm,SQInteger index)466 	player_t* param<player_t*>::get(HSQUIRRELVM vm, SQInteger index)
467 	{
468 		uint8 plnr = 0;
469 		get_slot(vm, "nr", plnr, index);
470 		if(plnr < 15) {
471 			return welt->get_player(plnr);
472 		}
473 		else {
474 			sq_raise_error(vm, "Invalid player index %d", plnr);
475 			return NULL;
476 		}
477 	}
478 
479 
push(HSQUIRRELVM vm,player_t * const & player)480 	SQInteger param<player_t*>::push(HSQUIRRELVM vm, player_t* const& player)
481 	{
482 		return push_instance(vm, "player_x", player ? player->get_player_nr() : 16);
483 	}
484 
485 
get_my_player(HSQUIRRELVM vm)486 	player_t* get_my_player(HSQUIRRELVM vm)
487 	{
488 		sq_pushregistrytable(vm);
489 		uint8 player_nr = PLAYER_UNOWNED;
490 		player_t *pl = NULL;
491 		if (SQ_SUCCEEDED(get_slot<uint8>(vm, "my_player_nr", player_nr))  &&  player_nr < 15) {
492 			pl =  welt->get_player(player_nr);
493 		}
494 		sq_poptop(vm);
495 		return pl;
496 	}
497 
498 
get(HSQUIRRELVM vm,SQInteger index)499 	const haltestelle_t* param<const haltestelle_t*>::get(HSQUIRRELVM vm, SQInteger index)
500 	{
501 		halthandle_t halt = param<halthandle_t>::get(vm, index);
502 		if (!halt.is_bound()) {
503 			sq_raise_error(vm, "Invalid halt id %d", halt.get_id());
504 		}
505 		return halt.get_rep();
506 	}
507 
508 
get(HSQUIRRELVM vm,SQInteger index)509 	planquadrat_t* param<planquadrat_t*>::get(HSQUIRRELVM vm, SQInteger index)
510 	{
511 		koord pos = param<koord>::get(vm, index);
512 		planquadrat_t *plan = welt->access(pos);
513 		if (plan==NULL) {
514 			sq_raise_error(vm, "Coordinate out of range (%s)", pos.get_str());
515 		}
516 		return plan;
517 	}
518 
519 
get(HSQUIRRELVM vm,SQInteger index)520 	grund_t* param<grund_t*>::get(HSQUIRRELVM vm, SQInteger index)
521 	{
522 		koord3d pos = param<koord3d>::get(vm, index);
523 		grund_t *gr = welt->lookup(pos);
524 		if (gr==NULL) {
525 			gr = welt->lookup_kartenboden(pos.get_2d());
526 		}
527 		if (gr==NULL) {
528 			sq_raise_error(vm, "Coordinate out of range (%s)", pos.get_str());
529 		}
530 		return gr;
531 	}
532 
533 
push(HSQUIRRELVM vm,grund_t * const & v)534 	SQInteger param<grund_t*>::push(HSQUIRRELVM vm, grund_t* const& v)
535 	{
536 		if (v) {
537 			koord k = v->get_pos().get_2d();
538 			// transform coordinates
539 			coordinate_transform_t::koord_w2sq(k);
540 			return push_instance(vm, "tile_x", k.x, k.y, v->get_pos().z);
541 		}
542 		else {
543 			sq_pushnull(vm); return 1;
544 		}
545 	}
546 
547 
get(HSQUIRRELVM,SQInteger)548 	scenario_t* param<scenario_t*>::get(HSQUIRRELVM, SQInteger)
549 	{
550 		return welt->get_scenario();
551 	}
552 
553 
push(HSQUIRRELVM vm,schedule_entry_t const & v)554 	SQInteger param<schedule_entry_t>::push(HSQUIRRELVM vm, schedule_entry_t const& v)
555 	{
556 		return push_instance(vm, "schedule_entry_x", v.pos, v.minimum_loading, v.waiting_time_shift);
557 	}
558 
559 
push(HSQUIRRELVM vm,schedule_t * const & v)560 	SQInteger param<schedule_t*>::push(HSQUIRRELVM vm, schedule_t* const& v)
561 	{
562 		return param<const schedule_t*>::push(vm, v);
563 	}
564 
565 
push(HSQUIRRELVM vm,const schedule_t * const & v)566 	SQInteger param<const schedule_t*>::push(HSQUIRRELVM vm, const schedule_t* const& v)
567 	{
568 		if (v) {
569 			return push_instance(vm, "schedule_x", v->get_waytype(), v->entries);
570 		}
571 		else {
572 			sq_pushnull(vm); return 1;
573 		}
574 	}
575 
576 
get(HSQUIRRELVM,SQInteger)577 	settings_t* param<settings_t*>::get(HSQUIRRELVM, SQInteger)
578 	{
579 		return &welt->get_settings();
580 	}
581 
582 
get(HSQUIRRELVM vm,SQInteger index)583 	simline_t* param<simline_t*>::get(HSQUIRRELVM vm, SQInteger index)
584 	{
585 		linehandle_t line = param<linehandle_t>::get(vm, index);
586 		if (!line.is_bound()) {
587 			sq_raise_error(vm, "Invalid line id %d", line.get_id());
588 		}
589 		return line.get_rep();
590 	}
591 
592 
get(HSQUIRRELVM vm,SQInteger index)593 	stadt_t* param<stadt_t*>::get(HSQUIRRELVM vm, SQInteger index)
594 	{
595 		koord pos = param<koord>::get(vm, index);
596 		return welt->find_nearest_city(pos);
597 	}
598 
push(HSQUIRRELVM vm,stadt_t * const & v)599 	SQInteger param<stadt_t*>::push(HSQUIRRELVM vm, stadt_t* const& v)
600 	{
601 		if (v) {
602 			koord k = v->get_pos();
603 			// transform coordinates
604 			coordinate_transform_t::koord_w2sq(k);
605 			return push_instance(vm, "city_x", k.x, k.y);
606 		}
607 		else {
608 			sq_pushnull(vm); return 1;
609 		}
610 	}
611 
get(HSQUIRRELVM,SQInteger)612 	karte_t* param<karte_t*>::get(HSQUIRRELVM, SQInteger)
613 	{
614 		return welt;
615 	}
616 
push(HSQUIRRELVM vm,karte_t * const &)617 	SQInteger param<karte_t*>::push(HSQUIRRELVM vm, karte_t* const&)
618 	{
619 		sq_pushnull(vm); return 1;
620 	}
621 
get(HSQUIRRELVM vm,SQInteger index)622 	tool_t* param<tool_t*>::get(HSQUIRRELVM vm, SQInteger index)
623 	{
624 		my_tool_t *mtool = get_attached_instance<my_tool_t>(vm, index, param<tool_t*>::tag());
625 		if (mtool) {
626 			return mtool->tool;
627 		}
628 		return NULL;
629 	}
630 };
631