Simutrans-Squirrel-API  r11919
api_schedule.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_class.h"
11 #include "../api_function.h"
12 #include "../../dataobj/schedule.h"
13 #include "../../simhalt.h"
14 #include "../../simintr.h"
15 #include "../../world/simworld.h"
16 
17 using namespace script_api;
18 
19 SQInteger schedule_entry_constructor(HSQUIRRELVM vm) // instance, coord3d, load, wait
20 {
21  koord3d pos = param<koord3d>::get(vm, 2); // world coordinates
22  uint8 load = param<uint8>::get(vm, 3);
23  uint16 wait = param<uint16>::get(vm, 4);
24 
25  // transform coordinates to squirrel coordinates
26  koord k(pos.get_2d());
27  coordinate_transform_t::koord_w2sq(k);
28 
29  // propagate error
30  SQInteger res = pos != koord3d::invalid ? SQ_OK : SQ_ERROR;
31 
32  if (SQ_SUCCEEDED(res)) {
33  res = set_slot(vm, "x", k.x, 1);
34  }
35  if (SQ_SUCCEEDED(res)) {
36  res = set_slot(vm, "y", k.y, 1);
37  }
38  if (SQ_SUCCEEDED(res)) {
39  res = set_slot(vm, "z", pos.z, 1);
40  }
41  if (SQ_SUCCEEDED(res)) {
42  res = set_slot(vm, "wait", wait, 1);
43  }
44  if (SQ_SUCCEEDED(res)) {
45  res = set_slot(vm, "load", load, 1);
46  }
47  return res;
48 }
49 
50 halthandle_t get_halt_from_koord3d(koord3d pos, const player_t *player )
51 {
52  if( player == NULL ) {
53  return halthandle_t();
54  }
55  return haltestelle_t::get_halt(pos, player);
56 }
57 
58 SQInteger waiting_time_to_string(HSQUIRRELVM vm)
59 {
60  schedule_entry_t entry(koord3d::invalid, 0, 0);
61  get_slot(vm, "wait", entry.waiting_time, -1);
62  plainstring str = difftick_to_string(entry.get_waiting_ticks(), false);
63  return param<plainstring>::push(vm, str);
64 }
65 
66 SQInteger schedule_constructor(HSQUIRRELVM vm) // instance, wt, entries = [], current = 0
67 {
68  waytype_t wt = param<waytype_t>::get(vm, 2);
69  SQInteger res = set_slot(vm, "waytype", wt, 1);
70 
71  if (SQ_SUCCEEDED(res)) {
72  sq_pushstring(vm, "entries", -1);
73  // entries parameter
74  if (sq_gettop(vm) >= 3) {
75  sq_push(vm, 3);
76  }
77  else {
78  // not provided, push empty array
79  sq_newarray(vm, 4);
80  }
81  res = sq_set(vm, 1);
82  }
83  if (SQ_SUCCEEDED(res)) {
84  uint8 current = 0;
85  if (sq_gettop(vm) >= 4) {
86  current = param<uint8>::get(vm, 4);
87  }
88  res = set_slot(vm, "current", current, 1);
89  }
90  if (SQ_SUCCEEDED(res)) {
91  // attach a schedule instance
92  // the c++ schedule_t instance will be refilled everytime when transfered to the c++ side of things.
93  schedule_t* sched = NULL;
94  switch(wt) {
95  case road_wt: sched = new truck_schedule_t(); break;
96  case track_wt: sched = new train_schedule_t(); break;
97  case water_wt: sched = new ship_schedule_t(); break;
98  case air_wt: sched = new airplane_schedule_t(); break;
99  case monorail_wt: sched = new monorail_schedule_t(); break;
100  case tram_wt: sched = new tram_schedule_t(); break;
101  case maglev_wt: sched = new maglev_schedule_t(); break;
102  case narrowgauge_wt: sched = new narrowgauge_schedule_t(); break;
103  default:
104  sq_raise_error(vm, "Invalid waytype %d", wt);
105  return SQ_ERROR;
106  }
107  attach_instance(vm, 1, sched);
108  }
109  return res;
110 }
111 
112 // read entry at index, append to schedule
113 void append_entry(HSQUIRRELVM vm, SQInteger index, schedule_t* sched)
114 {
115  koord3d pos = param<koord3d>::get(vm, index);
116 
117  uint8 minimum_loading = 0;
118  get_slot(vm, "load", minimum_loading, index);
119 
120  uint16 waiting_time_shift = 0;
121  get_slot(vm, "wait", waiting_time_shift, index);
122 
123  grund_t *gr = welt->lookup(pos);
124  if (gr) {
125  sched->append(gr, minimum_loading, waiting_time_shift);
126  }
127 }
128 
129 schedule_t* script_api::param<schedule_t*>::get(HSQUIRRELVM vm, SQInteger index)
130 {
131  // get waytype
132  waytype_t wt = invalid_wt;
133  get_slot(vm, "waytype", wt, index);
134 
135  // get instance pointer
136  schedule_t* sched = get_attached_instance<schedule_t>(vm, index, param<schedule_t*>::tag());
137  if (sched) {
138  // check waytype
139  if (wt != sched->get_waytype()) {
140  sq_raise_error(vm, "Waytype mismatch in schedule");
141  return NULL;
142  }
143  sched->entries.clear();
144  // now read the entries
145  sq_pushstring(vm, "entries", -1);
146  SQInteger new_index = index > 0 ? index : index-1;
147  if (SQ_SUCCEEDED(sq_get(vm, new_index))) {
148  // now entries array at the top of the stack
149  // foreach loop
150  sq_pushnull(vm);
151  while(SQ_SUCCEEDED(sq_next(vm, -2))) {
152  append_entry(vm, -1, sched);
153  sq_pop(vm, 2);
154  }
155  sq_pop(vm, 1);
156  }
157  // current stop
158  uint8 current = 0;
159  get_slot(vm, "current", current, index);
160  sched->set_current_stop(current);
161  }
162  return sched;
163 }
164 
165 void* script_api::param<schedule_t*>::tag()
166 {
167  return (void*)&script_api::param<schedule_t*>::get;
168 }
169 
170 void export_schedule(HSQUIRRELVM vm)
171 {
175  begin_class(vm, "schedule_entry_x", "coord3d");
176 
177 #ifdef SQAPI_DOC // document members
178 
181  integer load;
185  integer wait;
186 #endif
187 
194  register_function<void(*)(koord3d,uint8,uint16)>(vm, schedule_entry_constructor, "constructor");
201  register_method(vm, &get_halt_from_koord3d, "get_halt", true);
206  register_function(vm, waiting_time_to_string, "waiting_time_to_string", 1, "x" );
207 
208  end_class(vm);
209 
213  create_class(vm, "schedule_x");
214 
224  register_function(vm, schedule_constructor, "constructor", 3, "xi.");
225  sq_settypetag(vm, -1, param<schedule_t*>::tag());
226 
227 #ifdef SQAPI_DOC // document members
228 
231  array< schedule_entry_x > entries;
232 
236  way_types waytype;
237 
246  integer current;
247 #else
248  create_slot(vm, "entries", 0);
249  create_slot(vm, "waytype", 0);
250  create_slot(vm, "current", 0);
251 #endif
252 
253  end_class(vm);
254 }
way_types
Definition: api_const.cc:120
string difftick_to_string(integer difftick_to_string_intern)