Simutrans-Squirrel-API  r11919
api_obj_desc.cc
Go to the documentation of this file.
1 /*
2  * This file is part of the Simutrans project under the Artistic License.
3  * (see LICENSE.txt)
4  */
5 
6 #include "api.h"
7 
10 #include "api_obj_desc_base.h"
11 #include "api_simple.h"
12 #include "export_desc.h"
13 #include "get_next.h"
14 #include "../api_class.h"
15 #include "../api_function.h"
16 #include "../../descriptor/bridge_desc.h"
17 #include "../../descriptor/building_desc.h"
18 #include "../../descriptor/vehicle_desc.h"
19 #include "../../descriptor/goods_desc.h"
20 #include "../../descriptor/roadsign_desc.h"
21 #include "../../descriptor/way_obj_desc.h"
22 #include "../../descriptor/factory_desc.h"
23 #include "../../builder/brueckenbauer.h"
24 #include "../../builder/hausbauer.h"
25 #include "../../builder/fabrikbauer.h"
26 #include "../../builder/tunnelbauer.h"
27 #include "../../builder/vehikelbauer.h"
28 #include "../../builder/goods_manager.h"
29 #include "../../builder/wegbauer.h"
30 #include "../../obj/roadsign.h"
31 #include "../../obj/wayobj.h"
32 #include "../../simhalt.h"
33 #include "../../simware.h"
34 #include "../../tool/simtool.h"
35 #include "../../world/simworld.h"
36 
37 #define begin_enum(name)
38 #define end_enum()
39 #define enum_slot create_slot
40 
41 
42 using namespace script_api;
43 
44 
45 SQInteger get_next_ware_desc(HSQUIRRELVM vm)
46 {
47  return generic_get_next(vm, goods_manager_t::get_count());
48 }
49 
50 
51 SQInteger get_goods_desc_index(HSQUIRRELVM vm)
52 {
53  uint32 index = param<uint32>::get(vm, -1);
54 
55  const char* name = "None"; // fall-back
56  if (index < goods_manager_t::get_count()) {
57  name = goods_manager_t::get_info(index)->get_name();
58  }
59  return push_instance(vm, "good_desc_x", name);
60 }
61 
62 
63 bool are_equal(const obj_named_desc_t* a, const obj_named_desc_t* b)
64 {
65  return (a==b);
66 }
67 
68 
69 sint64 get_scaled_maintenance(const obj_desc_transport_related_t* desc)
70 {
71  return desc ? welt->scale_with_month_length(desc->get_maintenance()) : 0;
72 }
73 
74 sint64 get_scaled_maintenance_vehicle(const vehicle_desc_t* desc)
75 {
76  return desc ? welt->scale_with_month_length(desc->vehicle_desc_t::get_maintenance()) : 0;
77 }
78 
79 sint64 get_scaled_maintenance_building(const building_desc_t* desc)
80 {
81  return desc ? welt->scale_with_month_length(desc->get_maintenance(welt)) : 0;
82 }
83 
84 
85 bool building_enables(const building_desc_t* desc, uint8 which)
86 {
87  return desc ? desc->get_enabled() & which : 0;
88 }
89 
90 SQInteger building_get_size(HSQUIRRELVM vm)
91 {
92  const building_desc_t* desc = param<const building_desc_t*>::get(vm, 1);
93  uint8 rotation = param<uint8>::get(vm, 2);
94  if (desc) {
95  koord size = desc->get_size(rotation);
96  // no automatic coordinate transform please
97  return push_instance(vm, "coord", size.x, size.y);
98  }
99  return -1;
100 }
101 
102 mytime_t get_intro_retire(const obj_desc_timelined_t* desc, bool intro)
103 {
104  return (uint32)(desc ? ( intro ? desc->get_intro_year_month() : desc->get_retire_year_month() ) : 1);
105 }
106 
107 
108 bool is_obsolete_future(const obj_desc_timelined_t* desc, mytime_t time, uint8 what)
109 {
110  if (desc) {
111  switch(what) {
112  case 0: return desc->is_future(time.raw);
113  case 1: return desc->is_retired(time.raw);
114  case 2: return desc->is_available(time.raw);
115  default: ;
116  }
117  }
118  return false;
119 }
120 
121 
122 const vector_tpl<const building_desc_t*>& get_building_list(building_desc_t::btype type)
123 {
124  const vector_tpl<const building_desc_t*>* p = hausbauer_t::get_list(type);
125 
126  static const vector_tpl<const building_desc_t*> dummy;
127 
128  return p ? *p : dummy;
129 }
130 
131 
132 const vector_tpl<const building_desc_t*>& get_available_stations(building_desc_t::btype type, waytype_t wt, const goods_desc_t *freight)
133 {
134  static vector_tpl<const building_desc_t*> dummy;
135  dummy.clear();
136 
137  switch(type) {
138  case building_desc_t::depot:
139  case building_desc_t::generic_stop:
140  case building_desc_t::generic_extension:
141  case building_desc_t::dock:
142  case building_desc_t::flat_dock:
143  break;
144  default:
145  return dummy;
146  }
147 
148  const vector_tpl<const building_desc_t*>* p = hausbauer_t::get_list(type);
149 
150  // translate freight to enables-flags
151  uint8 enables = 0;
152  if (freight && type != building_desc_t::depot) {
153  switch(freight->get_catg_index()) {
154  case goods_manager_t::INDEX_PAS: enables = haltestelle_t::PAX; break;
155  case goods_manager_t::INDEX_MAIL: enables = haltestelle_t::POST; break;
156  default: enables = haltestelle_t::WARE;
157  }
158  }
159 
160  // use wt_all (which is equal to invalid_wt, see api_const.cc) to get buildings for all waytypes
161  bool accept_all_wt = wt == invalid_wt || wt == ignore_wt;
162 
163  uint16 time = welt->get_timeline_year_month();
164  for(building_desc_t const* const desc : *p) {
165  if( desc->get_type()==type
166  && (accept_all_wt || desc->get_extra()==(uint32)wt)
167  && (enables==0 || (desc->get_enabled()&enables)!=0)
168  && desc->get_builder()
169  && desc->is_available(time))
170  {
171 
172  dummy.append(desc);
173  }
174  }
175  return dummy;
176 }
177 
178 sint64 building_get_cost(const building_desc_t* desc)
179 {
180  return desc->get_price(welt) * desc->get_x() * desc->get_y();
181 }
182 
183 bool building_is_terminus(const building_desc_t *desc)
184 {
185  return desc && desc->get_type() == building_desc_t::generic_stop && desc->get_all_layouts() == 4;
186 }
187 
188 bool can_be_first(const vehicle_desc_t *desc)
189 {
190  return desc->can_follow(NULL);
191 }
192 
193 bool can_be_last(const vehicle_desc_t *desc)
194 {
195  return desc->can_lead(NULL);
196 }
197 
198 bool is_coupling_allowed(const vehicle_desc_t *desc1, const vehicle_desc_t *desc2)
199 {
200  return desc1 && desc2 && desc1->can_lead(desc2) && desc2->can_follow(desc1);
201 }
202 
203 const vector_tpl<const vehicle_desc_t*>& get_predecessors(const vehicle_desc_t *desc)
204 {
205  static vector_tpl<const vehicle_desc_t*> dummy;
206  dummy.clear();
207  for(int i=0; i<desc->get_leader_count(); i++) {
208  if (desc->get_leader(i)) {
209  dummy.append(desc->get_leader(i));
210  }
211  }
212  return dummy;
213 }
215 const vector_tpl<const vehicle_desc_t*>& get_successors(const vehicle_desc_t *desc)
216 {
217  static vector_tpl<const vehicle_desc_t*> dummy;
218  dummy.clear();
219  for(int i=0; i<desc->get_trailer_count(); i++) {
220  if (desc->get_trailer(i)) {
221  dummy.append(desc->get_trailer(i));
222  }
223  }
224  return dummy;
225 }
227 const vector_tpl<const vehicle_desc_t*>& get_available_vehicles(waytype_t wt)
228 {
229  static vector_tpl<const vehicle_desc_t*> dummy;
231  bool use_obsolete = welt->get_settings().get_allow_buying_obsolete_vehicles();
232  uint16 time = welt->get_timeline_year_month();
233 
234  dummy.clear();
235  slist_tpl<vehicle_desc_t const*> const& list = vehicle_builder_t::get_info(wt);
237  for(vehicle_desc_t const* const i : list) {
238  if (!i->is_retired(time) || use_obsolete) {
239  if (!i->is_future(time)) {
240  dummy.append(i);
241  }
242  }
243  }
244  return dummy;
245 }
246 
247 uint32 get_power(const vehicle_desc_t *desc)
248 {
249  return desc->get_power() * desc->get_gear();
250 }
251 
252 bool vehicle_needs_electrification(const vehicle_desc_t *desc)
253 {
254  return desc->get_power() && (desc->get_engine_type()==vehicle_desc_t::electric);
255 }
256 
257 // export of building_desc_t::btype only here
258 namespace script_api {
259  declare_enum_param(building_desc_t::btype, uint16, "building_desc_x::building_type");
260 };
261 
262 bool is_traffic_light(const roadsign_desc_t *d)
263 {
264  return !d->is_signal_type() && d->is_traffic_light();
265 }
266 
267 
268 sint64 tree_get_price()
269 {
270  return -welt->get_settings().cst_remove_tree;
271 }
272 
274 const vector_tpl<const way_obj_desc_t*>& get_available_wayobjs(waytype_t wt)
275 {
276  static vector_tpl<const way_obj_desc_t*> dummy;
277 
278  uint16 time = welt->get_timeline_year_month();
279 
280  dummy.clear();
281  for(auto i : wayobj_t::get_list()) {
282  const way_obj_desc_t* desc = i.value;
283  if (desc->get_waytype()==wt && desc->is_available(time) && desc->get_builder()) {
284  dummy.append(desc);
285  }
286  }
287  return dummy;
288 }
289 
290 
291 #ifdef DOXYGEN
292 
295 struct factory_slot_information_x { // begin_class("factory_slot_information_x")
296  good_desc_x good;
297  integer capacity;
298  integer factor;
299 }; // end_class
300 #endif
301 
302 SQInteger get_factory_outputs(HSQUIRRELVM vm)
303 {
304  const factory_desc_t *desc = param<const factory_desc_t *>::get(vm, -1);
305  sq_newarray(vm, 0);
306  if (desc) {
307  for(uint16 i=0; i<desc->get_product_count(); i++) {
308  const factory_product_desc_t *fp = desc->get_product(i);
309  sq_newtable(vm);
310  create_slot(vm, "good", fp->get_output_type());
311  create_slot(vm, "capacity", fp->get_capacity());
312  create_slot(vm, "factor", fp->get_factor());
313  sq_arrayappend(vm, -2);
314  }
315  }
316  return 1;
317 }
318 
319 SQInteger get_factory_inputs(HSQUIRRELVM vm)
320 {
321  const factory_desc_t *desc = param<const factory_desc_t *>::get(vm, -1);
322  sq_newarray(vm, 0);
323  if (desc) {
324  for(uint16 i=0; i<desc->get_supplier_count(); i++) {
325  const factory_supplier_desc_t *fp = desc->get_supplier(i);
326  sq_newtable(vm);
327  create_slot(vm, "good", fp->get_input_type());
328  create_slot(vm, "capacity", fp->get_capacity());
329  create_slot(vm, "factor", fp->get_consumption());
330  sq_arrayappend(vm, -2);
331  }
332  }
333  return 1;
334 }
335 
336 
337 void export_goods_desc(HSQUIRRELVM vm)
338 {
342  create_class<const obj_named_desc_t*>(vm, "obj_desc_x", "extend_get");
343 
348  register_method(vm, &obj_named_desc_t::get_name, "get_name");
354  register_method(vm, &are_equal, "is_equal", true);
358  export_is_valid<const obj_named_desc_t*>(vm); //register_function("is_valid")
359  end_class(vm);
360 
364  create_class<const obj_desc_timelined_t*>(vm, "obj_desc_time_x", "obj_desc_x");
365 
369  register_method_fv(vm, &get_intro_retire, "get_intro_date", freevariable<bool>(true), true);
373  register_method_fv(vm, &get_intro_retire, "get_retire_date", freevariable<bool>(false), true);
378  register_method_fv(vm, &is_obsolete_future, "is_future", freevariable<uint8>(0), true);
383  register_method_fv(vm, &is_obsolete_future, "is_retired", freevariable<uint8>(1), true);
388  register_method_fv(vm, &is_obsolete_future, "is_available", freevariable<uint8>(2), true);
389  end_class(vm);
390 
394  create_class<const obj_desc_transport_related_t*>(vm, "obj_desc_transport_x", "obj_desc_time_x");
398  register_local_method(vm, &get_scaled_maintenance, "get_maintenance");
402  register_method(vm, &obj_desc_transport_related_t::get_price, "get_cost");
406  register_method(vm, &obj_desc_transport_related_t::get_waytype, "get_waytype");
410  register_method(vm, &obj_desc_transport_related_t::get_topspeed, "get_topspeed");
411 
412  end_class(vm);
413 
417  begin_desc_class(vm, "vehicle_desc_x", "obj_desc_transport_x", (GETDESCFUNC)param<const vehicle_desc_t*>::getfunc());
421  register_method(vm, &can_be_first, "can_be_first", true);
425  register_method(vm, &can_be_last, "can_be_last", true);
429  register_method(vm, &get_successors, "get_successors", true);
433  register_method(vm, &get_predecessors, "get_predecessors", true);
437  STATIC register_method(vm, &get_available_vehicles, "get_available_vehicles", false, true);
443  register_method(vm, &get_power, "get_power", true);
447  register_method(vm, &vehicle_needs_electrification, "needs_electrification", true);
451  register_method(vm, &vehicle_desc_t::get_freight_type, "get_freight");
455  register_method(vm, &vehicle_desc_t::get_capacity, "get_capacity");
459  register_method(vm, &vehicle_desc_t::get_running_cost, "get_running_cost");
463  register_method(vm, &get_scaled_maintenance_vehicle, "get_maintenance", true);
467  register_method(vm, &vehicle_desc_t::get_weight, "get_weight"); // in kg
471  register_method(vm, &vehicle_desc_t::get_length, "get_length"); // in CAR_UNITS_PER_TILE
478  STATIC register_method(vm, is_coupling_allowed, "is_coupling_allowed", false, true);
479  end_class(vm);
480 
484  begin_desc_class(vm, "tree_desc_x", "obj_desc_x", (GETDESCFUNC)param<const tree_desc_t*>::getfunc());
485 
490  STATIC register_method(vm, tree_get_price, "get_price", false, true);
491  end_class(vm);
492 
496  begin_desc_class(vm, "building_desc_x", "obj_desc_time_x", (GETDESCFUNC)param<const building_desc_t*>::getfunc());
497 
501  register_method(vm, &building_desc_t::is_attraction, "is_attraction");
507  register_function(vm, building_get_size, "get_size", 2, "x i");
511  register_method(vm, &get_scaled_maintenance_building, "get_maintenance", true);
516  register_method(vm, &building_get_cost, "get_cost", true);
520  register_method(vm, &building_desc_t::get_capacity, "get_capacity");
524  register_method(vm, &building_desc_t::can_be_built_underground, "can_be_built_underground");
528  register_method(vm, &building_desc_t::can_be_built_aboveground, "can_be_built_aboveground");
532  register_method_fv(vm, &building_enables, "enables_pax", freevariable<uint8>(1), true);
536  register_method_fv(vm, &building_enables, "enables_mail", freevariable<uint8>(2), true);
540  register_method_fv(vm, &building_enables, "enables_freight", freevariable<uint8>(4), true);
542  begin_enum("building_type")
544  enum_slot(vm, "attraction_city", (uint8)building_desc_t::attraction_city, true);
546  enum_slot(vm, "attraction_land", (uint8)building_desc_t::attraction_land, true);
548  enum_slot(vm, "monument", (uint8)building_desc_t::monument, true);
550  enum_slot(vm, "factory", (uint8)building_desc_t::factory, true);
552  enum_slot(vm, "townhall", (uint8)building_desc_t::townhall, true);
554  enum_slot(vm, "headquarter", (uint8)building_desc_t::headquarters, true);
556  enum_slot(vm, "harbour", (uint8)building_desc_t::dock, true);
558  enum_slot(vm, "flat_harbour", (uint8)building_desc_t::flat_dock, true);
560  enum_slot(vm, "depot", (uint8)building_desc_t::depot, true);
562  enum_slot(vm, "station", (uint8)building_desc_t::generic_stop, true);
564  enum_slot(vm, "station_extension", (uint8)building_desc_t::generic_extension, true);
566  enum_slot(vm, "city_res", (uint8)building_desc_t::city_res, true);
568  enum_slot(vm, "city_com", (uint8)building_desc_t::city_com, true);
570  enum_slot(vm, "city_ind", (uint8)building_desc_t::city_ind, true);
571  end_enum();
575  register_method(vm, &building_desc_t::get_type, "get_type");
576 
580  register_method(vm, &building_desc_t::get_finance_waytype, "get_waytype");
581 
585  register_method(vm, &building_desc_t::get_headquarters_level, "get_headquarter_level");
586 
592  STATIC register_method(vm, &get_building_list, "get_building_list", false, true);
601  STATIC register_method(vm, &get_available_stations, "get_available_stations", false, true);
602 
606  register_method(vm, &building_is_terminus, "is_terminus", true);
607 
608  end_class(vm);
609 
613  begin_desc_class(vm, "factory_desc_x", "obj_desc_x", (GETDESCFUNC)param<const factory_desc_t*>::getfunc());
617  register_method(vm, &factory_desc_t::get_name, "get_name");
621  register_method(vm, &factory_desc_t::get_building, "get_building_desc");
625  register_method(vm, &factory_desc_t::is_electricity_producer, "is_electricity_producer");
630  register_method(vm, &factory_desc_t::get_productivity, "get_productivity_base");
634  register_method(vm, &factory_desc_t::get_range, "get_productivity_range");
639  register_function(vm, get_factory_inputs, "get_inputs", 1, "t|x|y");
644  register_function(vm, get_factory_outputs, "get_outputs", 1, "t|x|y");
649  register_method(vm, &factory_builder_t::get_factory_table, "get_list", 1);
650 
651  end_class(vm);
652 
656  begin_desc_class(vm, "way_desc_x", "obj_desc_transport_x", (GETDESCFUNC)param<const way_desc_t*>::getfunc());
660  register_method(vm, &way_desc_t::has_double_slopes, "has_double_slopes");
664  register_method(vm, &way_desc_t::get_styp, "get_system_type");
665 
672  STATIC register_method(vm, way_builder_t::get_way_list, "get_available_ways", false, true);
673 
680  STATIC register_method(vm, &tool_build_way_t::get_default_desc, "get_default_way_desc", false, true);
681 
682  end_class(vm);
683 
687  begin_desc_class(vm, "tunnel_desc_x", "obj_desc_transport_x", (GETDESCFUNC)param<const tunnel_desc_t*>::getfunc());
691  STATIC register_method(vm, tunnel_builder_t::get_available_tunnels, "get_available_tunnels", false, true);
692  end_class(vm);
693 
697  begin_desc_class(vm, "bridge_desc_x", "obj_desc_transport_x", (GETDESCFUNC)param<const bridge_desc_t*>::getfunc());
701  register_method(vm, &bridge_desc_t::has_double_ramp, "has_double_ramp");
705  register_method(vm, &bridge_desc_t::has_double_start, "has_double_start");
709  register_method(vm, &bridge_desc_t::get_max_length, "get_max_length");
713  register_method(vm, &bridge_desc_t::get_max_height, "get_max_height");
717  STATIC register_method(vm, bridge_builder_t::get_desc, "get_desc", false, true);
721  STATIC register_method(vm, bridge_builder_t::get_available_bridges, "get_available_bridges", false, true);
722 
723  end_class(vm);
724 
736  create_class(vm, "good_desc_list_x", 0);
740  register_function(vm, get_next_ware_desc, "_nexti", 2, "x o|i");
744  register_function(vm, get_goods_desc_index, "_get", 2, "xi");
745 
746  end_class(vm);
747 
751  begin_desc_class(vm, "good_desc_x", "obj_desc_x", (GETDESCFUNC)param<const goods_desc_t*>::getfunc());
752 
753  // dummy entry to create documentation of constructor
759  // register_function( .., "constructor", .. )
760 
761  create_slot(vm, "passenger", goods_manager_t::passengers, true);
762  create_slot(vm, "mail", goods_manager_t::mail, true);
763 #ifdef DOXYGEN
764  static good_desc_x passenger;
765  static good_desc_x mail;
766 #endif
767 
770  register_method(vm, &goods_desc_t::get_catg_index, "get_catg_index");
771 
776  register_method(vm, &goods_desc_t::is_interchangeable, "is_interchangeable");
780  register_method(vm, &goods_desc_t::get_weight_per_unit, "get_weight_per_unit"); // in kg
781 
785  register_method(vm, &goods_desc_t::get_mass, "get_metric");
786 
796  register_method(vm, &ware_t::calc_revenue, "calc_revenue", true);
797  end_class(vm);
798 
802  begin_desc_class(vm, "sign_desc_x", "obj_desc_transport_x", (GETDESCFUNC)param<const roadsign_desc_t*>::getfunc());
803 
807  register_method(vm, &roadsign_desc_t::is_single_way, "is_one_way");
811  register_method(vm, &roadsign_desc_t::is_private_way, "is_private_way");
815  register_method(vm, &is_traffic_light, "is_traffic_light", true);
819  register_method(vm, &roadsign_desc_t::is_choose_sign, "is_choose_sign");
823  register_method(vm, &roadsign_desc_t::is_simple_signal, "is_signal");
827  register_method(vm, &roadsign_desc_t::is_pre_signal, "is_pre_signal");
831  register_method(vm, &roadsign_desc_t::is_priority_signal, "is_priority_signal");
835  register_method(vm, &roadsign_desc_t::is_longblock_signal, "is_longblock_signal");
839  register_method(vm, &roadsign_desc_t::is_end_choose_signal, "is_end_choose_signal");
844  STATIC register_method(vm, roadsign_t::get_available_signs, "get_available_signs", false, true);
845 
846  end_class(vm);
850  begin_desc_class(vm, "wayobj_desc_x", "obj_desc_transport_x", (GETDESCFUNC)param<const way_obj_desc_t*>::getfunc());
854  register_method(vm, &way_obj_desc_t::is_overhead_line, "is_overhead_line");
859  STATIC register_method(vm, get_available_wayobjs, "get_available_wayobjs", false, true);
860  end_class(vm);
861 }