1 /*
2 LUA_PLAYER.CPP
3
4 Copyright (C) 2008 by Gregory Smith
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 This license is contained in the file "COPYING",
17 which is included with this source code; it is available online at
18 http://www.gnu.org/licenses/gpl.html
19
20 Implements the Lua Player class
21 */
22
23 #include "ActionQueues.h"
24 #include "alephversion.h"
25 #include "computer_interface.h"
26 #include "Crosshairs.h"
27 #include "fades.h"
28 #include "game_window.h"
29 #include "interface.h"
30 #include "lua_map.h"
31 #include "lua_monsters.h"
32 #include "lua_objects.h"
33 #include "lua_hud_objects.h"
34 #include "lua_player.h"
35 #include "lua_script.h"
36 #include "lua_serialize.h"
37 #include "lua_templates.h"
38 #include "map.h"
39 #include "monsters.h"
40 #include "Music.h"
41 #include "network.h"
42 #include "player.h"
43 #include "projectiles.h"
44 #include "network_games.h"
45 #include "Random.h"
46 #include "screen.h"
47 #include "shell.h"
48 #include "SoundManager.h"
49 #include "ViewControl.h"
50
51 #include <boost/iostreams/device/array.hpp>
52 #include <boost/iostreams/stream_buffer.hpp>
53 namespace io = boost::iostreams;
54
55 #define DONT_REPEAT_DEFINITIONS
56 #include "item_definitions.h"
57 #include "projectile_definitions.h"
58
59 #ifdef HAVE_LUA
60
61 const float AngleConvert = 360/float(FULL_CIRCLE);
62
63 char Lua_Action_Flags_Name[] = "action_flags";
64 typedef L_Class<Lua_Action_Flags_Name> Lua_Action_Flags;
65
66 extern ModifiableActionQueues *GetGameQueue();
67
68 template<uint32 flag>
Lua_Action_Flags_Get_t(lua_State * L)69 static int Lua_Action_Flags_Get_t(lua_State *L)
70 {
71 int player_index = Lua_Action_Flags::Index(L, 1);
72
73 if (GetGameQueue()->countActionFlags(player_index))
74 {
75 uint32 flags = GetGameQueue()->peekActionFlags(player_index, 0);
76 lua_pushboolean(L, flags & flag);
77 }
78 else
79 {
80 return luaL_error(L, "action flags are only accessible in idle()");
81 }
82
83 return 1;
84 }
85
86 template<uint32 flag>
Lua_Action_Flags_Set_t(lua_State * L)87 static int Lua_Action_Flags_Set_t(lua_State *L)
88 {
89 if (!lua_isboolean(L, 2))
90 return luaL_error(L, "action flags: incorrect argument type");
91
92 int player_index = Lua_Action_Flags::Index(L, 1);
93 if (GetGameQueue()->countActionFlags(player_index))
94 {
95 if (lua_toboolean(L, 2))
96 {
97 GetGameQueue()->modifyActionFlags(player_index, flag, flag);
98 }
99 else
100 {
101 GetGameQueue()->modifyActionFlags(player_index, 0, flag);
102 }
103 }
104 else
105 {
106 return luaL_error(L, "action flags are only accessible in idle()");
107 }
108
109 return 0;
110 }
111
Lua_Action_Flags_Set_Microphone(lua_State * L)112 static int Lua_Action_Flags_Set_Microphone(lua_State *L)
113 {
114 if (!lua_isboolean(L, 2))
115 return luaL_error(L, "action flags: incorrect argument type");
116
117 if (lua_toboolean(L, 2))
118 return luaL_error(L, "you can only disable the microphone button flag");
119
120 int player_index = Lua_Action_Flags::Index(L, 1);
121 if (GetGameQueue()->countActionFlags(player_index))
122 {
123 GetGameQueue()->modifyActionFlags(player_index, 0, _microphone_button);
124 }
125 else
126 {
127 return luaL_error(L, "action flags are only accessible in idle()");
128 }
129
130 return 0;
131 }
132
133 const luaL_Reg Lua_Action_Flags_Get[] = {
134 {"action_trigger", Lua_Action_Flags_Get_t<_action_trigger_state>},
135 {"cycle_weapons_backward", Lua_Action_Flags_Get_t<_cycle_weapons_backward>},
136 {"cycle_weapons_forward", Lua_Action_Flags_Get_t<_cycle_weapons_forward>},
137 {"left_trigger", Lua_Action_Flags_Get_t<_left_trigger_state>},
138 {"microphone_button", Lua_Action_Flags_Get_t<_microphone_button>},
139 {"right_trigger", Lua_Action_Flags_Get_t<_right_trigger_state>},
140 {"toggle_map", Lua_Action_Flags_Get_t<_toggle_map>},
141 {0, 0}
142 };
143
144 const luaL_Reg Lua_Action_Flags_Set[] = {
145 {"action_trigger", Lua_Action_Flags_Set_t<_action_trigger_state>},
146 {"cycle_weapons_backward", Lua_Action_Flags_Set_t<_cycle_weapons_backward>},
147 {"cycle_weapons_forward", Lua_Action_Flags_Set_t<_cycle_weapons_forward>},
148 {"left_trigger", Lua_Action_Flags_Set_t<_left_trigger_state>},
149 {"microphone_button", Lua_Action_Flags_Set_Microphone},
150 {"right_trigger", Lua_Action_Flags_Set_t<_right_trigger_state>},
151 {"toggle_map", Lua_Action_Flags_Set_t<_toggle_map>},
152 {0, 0}
153 };
154
155 extern vector<lua_camera> lua_cameras;
156
157 char Lua_Camera_Path_Points_Name[] = "camera_path_points";
158 typedef L_Class<Lua_Camera_Path_Points_Name> Lua_Camera_Path_Points;
159
Lua_Camera_Path_Points_New(lua_State * L)160 int Lua_Camera_Path_Points_New(lua_State *L)
161 {
162 if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4) || !lua_isnumber(L, 6))
163 return luaL_error(L, "new: incorrect argument type");
164
165 int camera_index = Lua_Camera_Path_Points::Index(L, 1);
166
167 int polygon = 0;
168 if (lua_isnumber(L, 5))
169 {
170 polygon = static_cast<int>(lua_tonumber(L, 5));
171 if (!Lua_Polygon::Valid(polygon))
172 return luaL_error(L, "new: invalid polygon index");
173 }
174 else if (Lua_Polygon::Is(L, 5))
175 {
176 polygon = Lua_Polygon::Index(L, 5);
177 }
178 else
179 return luaL_error(L, "new: incorrect argument type");
180
181 world_point3d point = {
182 static_cast<world_distance>(lua_tonumber(L, 2) * WORLD_ONE),
183 static_cast<world_distance>(lua_tonumber(L, 3) * WORLD_ONE),
184 static_cast<world_distance>(lua_tonumber(L, 4) * WORLD_ONE)
185 };
186
187 int32 time = static_cast<int32>(lua_tonumber(L, 6));
188 int point_index = lua_cameras[camera_index].path.path_points.size();
189 lua_cameras[camera_index].path.path_points.resize(point_index+1);
190 lua_cameras[camera_index].path.path_points[point_index].polygon = polygon;
191 lua_cameras[camera_index].path.path_points[point_index].point = point;
192 lua_cameras[camera_index].path.path_points[point_index].delta_time = time;
193 return 0;
194 }
195
196 const luaL_Reg Lua_Camera_Path_Points_Get[] = {
197 {"new", L_TableFunction<Lua_Camera_Path_Points_New>},
198 {0, 0}
199 };
200
201 char Lua_Camera_Path_Angles_Name[] = "camera_path_angles";
202 typedef L_Class<Lua_Camera_Path_Angles_Name> Lua_Camera_Path_Angles;
203
Lua_Camera_Path_Angles_New(lua_State * L)204 int Lua_Camera_Path_Angles_New(lua_State *L)
205 {
206 if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4))
207 return luaL_error(L, "new: incorrect argument type");
208
209 int camera_index = Lua_Camera_Path_Angles::Index(L, 1);
210 short yaw = static_cast<short>(lua_tonumber(L,2));
211 short pitch = static_cast<short>(lua_tonumber(L,3));
212 int32 time = static_cast<int32>(lua_tonumber(L,4));
213 int angle_index = lua_cameras[camera_index].path.path_angles.size();
214
215 lua_cameras[camera_index].path.path_angles.resize(angle_index+1);
216 lua_cameras[camera_index].path.path_angles[angle_index].yaw = static_cast<short>(yaw/AngleConvert);
217 lua_cameras[camera_index].path.path_angles[angle_index].pitch = static_cast<short>(pitch/AngleConvert);
218 lua_cameras[camera_index].path.path_angles[angle_index].delta_time = time;
219 return 0;
220 }
221
222 const luaL_Reg Lua_Camera_Path_Angles_Get[] = {
223 {"new", L_TableFunction<Lua_Camera_Path_Angles_New>},
224 {0, 0}
225 };
226
227 char Lua_Camera_Name[] = "camera";
228 typedef L_Class<Lua_Camera_Name> Lua_Camera;
229
230
Lua_Camera_Activate(lua_State * L)231 int Lua_Camera_Activate(lua_State *L)
232 {
233 int player_index = -1;
234 if (lua_isnumber(L, 2))
235 {
236 player_index = static_cast<int>(lua_tonumber(L, 2));
237 }
238 else if (Lua_Player::Is(L, 2))
239 {
240 player_index = Lua_Player::Index(L, 2);
241 }
242 else
243 return luaL_error(L, "activate: incorrect argument type");
244
245 if (player_index == local_player_index)
246 {
247 int camera_index = Lua_Camera::Index(L, 1);
248 lua_cameras[camera_index].time_elapsed = 0;
249 lua_cameras[camera_index].player_active = player_index;
250 lua_cameras[camera_index].path.current_point_index = 0;
251 lua_cameras[camera_index].path.current_angle_index = 0;
252 lua_cameras[camera_index].path.last_point_time = 0;
253 lua_cameras[camera_index].path.last_angle_time = 0;
254 }
255
256 return 0;
257 }
258
Lua_Camera_Clear(lua_State * L)259 int Lua_Camera_Clear(lua_State *L)
260 {
261 int camera_index = Lua_Camera::Index(L, 1);
262 lua_cameras[camera_index].path.path_points.resize(0);
263 lua_cameras[camera_index].path.path_angles.resize(0);
264 return 0;
265 }
266
Lua_Camera_Deactivate(lua_State * L)267 int Lua_Camera_Deactivate(lua_State *L)
268 {
269 int camera_index = Lua_Camera::Index(L, 1);
270 lua_cameras[camera_index].time_elapsed = 0;
271 lua_cameras[camera_index].player_active = -1;
272 lua_cameras[camera_index].path.last_point_time = 0;
273 lua_cameras[camera_index].path.last_angle_time = 0;
274 return 0;
275 }
276
Lua_Get_Path_Angles(lua_State * L)277 static int Lua_Get_Path_Angles(lua_State *L)
278 {
279 Lua_Camera_Path_Angles::Push(L, Lua_Camera::Index(L, 1));
280 return 1;
281 }
282
Lua_Get_Path_Points(lua_State * L)283 static int Lua_Get_Path_Points(lua_State *L)
284 {
285 Lua_Camera_Path_Points::Push(L, Lua_Camera::Index(L, 1));
286 return 1;
287 }
288
289 const luaL_Reg Lua_Camera_Get[] = {
290 {"activate", L_TableFunction<Lua_Camera_Activate>},
291 {"clear", L_TableFunction<Lua_Camera_Clear>},
292 {"deactivate", L_TableFunction<Lua_Camera_Deactivate>},
293 {"path_angles", Lua_Get_Path_Angles},
294 {"path_points", Lua_Get_Path_Points},
295 {0, 0}
296 };
297
Lua_Camera_Valid(int16 index)298 static int Lua_Camera_Valid(int16 index)
299 {
300 return index >= 0 && index < lua_cameras.size();
301 }
302
303 char Lua_Cameras_Name[] = "Cameras";
304 typedef L_Container<Lua_Cameras_Name, Lua_Camera> Lua_Cameras;
305
Lua_Cameras_New(lua_State * L)306 int Lua_Cameras_New(lua_State *L)
307 {
308 if (lua_cameras.size() == INT16_MAX)
309 {
310 return 0;
311 }
312
313 lua_camera camera;
314 camera.index = lua_cameras.size();
315 camera.path.index = lua_cameras.size();
316 camera.path.current_point_index = 0;
317 camera.path.current_angle_index = 0;
318 camera.path.last_point_time = 0;
319 camera.path.last_angle_time = 0;
320 camera.time_elapsed = 0;
321 camera.player_active = -1;
322 lua_cameras.push_back(camera);
323
324 Lua_Camera::Push(L, camera.index);
325
326 return 1;
327 }
328
329 const luaL_Reg Lua_Cameras_Methods[] = {
330 {"new", L_TableFunction<Lua_Cameras_New>},
331 {0, 0}
332 };
333
Lua_Cameras_Length()334 static int16 Lua_Cameras_Length() {
335 return lua_cameras.size();
336 }
337
338 char Lua_Crosshairs_Name[] = "crosshairs";
339 typedef L_Class<Lua_Crosshairs_Name> Lua_Crosshairs;
340
Lua_Crosshairs_Get_Active(lua_State * L)341 static int Lua_Crosshairs_Get_Active(lua_State *L)
342 {
343 int player_index = Lua_Crosshairs::Index(L, 1);
344 if (player_index == local_player_index)
345 {
346 lua_pushboolean(L, Crosshairs_IsActive());
347 return 1;
348 }
349 else
350 {
351 return 0;
352 }
353 }
354
355 const luaL_Reg Lua_Crosshairs_Get[] = {
356 {"active", Lua_Crosshairs_Get_Active},
357 {0, 0}
358 };
359
Lua_Crosshairs_Set_Active(lua_State * L)360 static int Lua_Crosshairs_Set_Active(lua_State *L)
361 {
362 int player_index = Lua_Crosshairs::Index(L, 1);
363 if (player_index == local_player_index)
364 {
365 if (!lua_isboolean(L, 2))
366 return luaL_error(L, "active: incorrect argument type");
367
368 Crosshairs_SetActive(lua_toboolean(L, 2));
369 }
370
371 return 0;
372 }
373
374 const luaL_Reg Lua_Crosshairs_Set[] = {
375 {"active", Lua_Crosshairs_Set_Active},
376 {0, 0}
377 };
378
379 char Lua_OverlayColor_Name[] = "overlay_color";
380 typedef L_Enum<Lua_OverlayColor_Name> Lua_OverlayColor;
381
382 template<char *name>
383 class PlayerSubtable : public L_Class<name>
384 {
385 public:
386 int16 m_player_index;
387
388 template<typename instance_t = PlayerSubtable /*or a derived class*/>
389 static instance_t *Push(lua_State *L, int16 player_index, int16 index);
390
391 static int16 PlayerIndex(lua_State *L, int index);
392 };
393
394 template<char *name>
395 template<typename instance_t>
Push(lua_State * L,int16 player_index,int16 index)396 instance_t *PlayerSubtable<name>::Push(lua_State *L, int16 player_index, int16 index)
397 {
398 instance_t *t = 0;
399
400 if (!L_Class<name, int16>::Valid(index) || !Lua_Player::Valid(player_index))
401 {
402 lua_pushnil(L);
403 return 0;
404 }
405
406 t = L_Class<name>::template NewInstance<instance_t>(L, index);
407 t->m_player_index = player_index;
408
409 return t;
410 }
411
412 template<char *name>
PlayerIndex(lua_State * L,int index)413 int16 PlayerSubtable<name>::PlayerIndex(lua_State *L, int index)
414 {
415 PlayerSubtable<name> *t = static_cast<PlayerSubtable<name> *>(L_Class<name>::Instance(L, index));
416 if (!t) luaL_typerror(L, index, name);
417 return t->m_player_index;
418 }
419
420 char Lua_Overlay_Name[] = "overlay";
421 typedef PlayerSubtable<Lua_Overlay_Name> Lua_Overlay;
422
Lua_Overlay_Clear(lua_State * L)423 int Lua_Overlay_Clear(lua_State *L)
424 {
425 int player = Lua_Overlay::PlayerIndex(L, 1);
426 int index = Lua_Overlay::Index(L, 1);
427 SetScriptHUDIcon(player, index, 0, 0);
428 SetScriptHUDText(player, index, 0);
429
430 return 0;
431 }
432
Lua_Overlay_Fill_Icon(lua_State * L)433 int Lua_Overlay_Fill_Icon(lua_State *L)
434 {
435 int player = Lua_Overlay::PlayerIndex(L, 1);
436 int color = Lua_OverlayColor::ToIndex(L, 2);
437 SetScriptHUDSquare(player, Lua_Overlay::Index(L, 1), color);
438
439 return 0;
440 }
441
442 const luaL_Reg Lua_Overlay_Get[] = {
443 {"clear", L_TableFunction<Lua_Overlay_Clear>},
444 {"fill_icon", L_TableFunction<Lua_Overlay_Fill_Icon>},
445 {0, 0}
446 };
447
Lua_Overlay_Set_Icon(lua_State * L)448 static int Lua_Overlay_Set_Icon(lua_State *L)
449 {
450 int player = Lua_Overlay::PlayerIndex(L, 1);
451 if (lua_isstring(L, 2))
452 {
453 SetScriptHUDIcon(player, Lua_Overlay::Index(L, 1), lua_tostring(L, 2), lua_rawlen(L, 2));
454 }
455 else
456 {
457 SetScriptHUDIcon(player, Lua_Overlay::Index(L, 1), 0, 0);
458 }
459
460 return 0;
461 }
462
Lua_Overlay_Set_Text(lua_State * L)463 static int Lua_Overlay_Set_Text(lua_State *L)
464 {
465 int player = Lua_Overlay::PlayerIndex(L, 1);
466 const char *text = 0;
467 if (lua_isstring(L, 2))
468 text = lua_tostring(L, 2);
469
470 SetScriptHUDText(player, Lua_Overlay::Index(L, 1), text);
471
472 return 0;
473 }
474
Lua_Overlay_Set_Text_Color(lua_State * L)475 static int Lua_Overlay_Set_Text_Color(lua_State *L)
476 {
477 int player = Lua_Overlay::PlayerIndex(L, 1);
478 int color = Lua_OverlayColor::ToIndex(L, 2);
479 SetScriptHUDColor(player, Lua_Overlay::Index(L, 1), color);
480
481 return 0;
482 }
483
484 const luaL_Reg Lua_Overlay_Set[] = {
485 {"color", Lua_Overlay_Set_Text_Color},
486 {"icon", Lua_Overlay_Set_Icon},
487 {"text", Lua_Overlay_Set_Text},
488 {0, 0}
489 };
490
491 char Lua_Overlays_Name[] = "overlays";
492 typedef L_Class<Lua_Overlays_Name> Lua_Overlays;
493
Lua_Overlays_Get(lua_State * L)494 static int Lua_Overlays_Get(lua_State *L)
495 {
496 if (lua_isnumber(L, 2))
497 {
498 int player_index = Lua_Overlays::Index(L, 1);
499 int index = static_cast<int>(lua_tonumber(L, 2));
500 if (Lua_Overlays::Valid(player_index) && index >= 0 && index < MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS)
501 {
502 Lua_Overlay::Push(L, player_index, index);
503 }
504 else
505 {
506 lua_pushnil(L);
507 }
508 }
509 else
510 {
511 lua_pushnil(L);
512 }
513
514 return 1;
515 }
516
Lua_Overlays_Length(lua_State * L)517 static int Lua_Overlays_Length(lua_State *L)
518 {
519 int player_index = Lua_Overlays::Index(L, 1);
520 if (Lua_Overlays::Valid(player_index))
521 lua_pushnumber(L, MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS);
522 else
523 lua_pushnumber(L, 0);
524 return 1;
525 }
526
527 const luaL_Reg Lua_Overlays_Metatable[] = {
528 {"__index", Lua_Overlays_Get},
529 {"__len", Lua_Overlays_Length},
530 {0, 0}
531 };
532
533 extern bool use_lua_compass[MAXIMUM_NUMBER_OF_NETWORK_PLAYERS];
534 extern world_point2d lua_compass_beacons[MAXIMUM_NUMBER_OF_NETWORK_PLAYERS];
535 extern short lua_compass_states[MAXIMUM_NUMBER_OF_NETWORK_PLAYERS];
536
537 char Lua_Player_Compass_Name[] = "player_compass";
538 typedef L_Class<Lua_Player_Compass_Name> Lua_Player_Compass;
539
540 template<short state>
Lua_Player_Compass_All(lua_State * L)541 int Lua_Player_Compass_All(lua_State *L)
542 {
543 int player_index = Lua_Player_Compass::Index(L, 1);
544 lua_compass_states[player_index] = state;
545 return 0;
546 }
547
Lua_Player_Compass_Get_Lua(lua_State * L)548 static int Lua_Player_Compass_Get_Lua(lua_State *L)
549 {
550 int player_index = Lua_Player_Compass::Index(L, 1);
551 lua_pushboolean(L, use_lua_compass[player_index]);
552 return 1;
553 }
554
555 template<short state>
Lua_Player_Compass_Get_State(lua_State * L)556 static int Lua_Player_Compass_Get_State(lua_State *L)
557 {
558 int player_index = Lua_Player_Compass::Index(L, 1);
559 lua_pushboolean(L, lua_compass_states[player_index] & state);
560 return 1;
561 }
562
Lua_Player_Compass_Get_X(lua_State * L)563 static int Lua_Player_Compass_Get_X(lua_State *L)
564 {
565 int player_index = Lua_Player_Compass::Index(L, 1);
566 lua_pushnumber(L, static_cast<double>(lua_compass_beacons[player_index].x / WORLD_ONE));
567 return 1;
568 }
569
Lua_Player_Compass_Get_Y(lua_State * L)570 static int Lua_Player_Compass_Get_Y(lua_State *L)
571 {
572 int player_index = Lua_Player_Compass::Index(L, 1);
573 lua_pushnumber(L, static_cast<double>(lua_compass_beacons[player_index].y / WORLD_ONE));
574 return 1;
575 }
576
577 const luaL_Reg Lua_Player_Compass_Get[] = {
578 {"all_off", L_TableFunction<Lua_Player_Compass_All<_network_compass_all_off> >},
579 {"all_on", L_TableFunction<Lua_Player_Compass_All<_network_compass_all_on> >},
580 {"beacon", Lua_Player_Compass_Get_State<_network_compass_use_beacon>},
581 {"lua", Lua_Player_Compass_Get_Lua},
582 {"ne", Lua_Player_Compass_Get_State<_network_compass_ne>},
583 {"northeast", Lua_Player_Compass_Get_State<_network_compass_ne>},
584 {"northwest", Lua_Player_Compass_Get_State<_network_compass_nw>},
585 {"nw", Lua_Player_Compass_Get_State<_network_compass_nw>},
586 {"se", Lua_Player_Compass_Get_State<_network_compass_se>},
587 {"southeast", Lua_Player_Compass_Get_State<_network_compass_se>},
588 {"southwest", Lua_Player_Compass_Get_State<_network_compass_sw>},
589 {"sw", Lua_Player_Compass_Get_State<_network_compass_sw>},
590 {"x", Lua_Player_Compass_Get_X},
591 {"y", Lua_Player_Compass_Get_Y},
592 {0, 0}
593 };
594
Lua_Player_Compass_Set_Lua(lua_State * L)595 static int Lua_Player_Compass_Set_Lua(lua_State *L)
596 {
597 if (!lua_isboolean(L, 2))
598 return luaL_error(L, "lua: incorrect argument type");
599
600 int player_index = Lua_Player_Compass::Index(L, 1);
601 use_lua_compass[player_index] = lua_toboolean(L, 2);
602 return 0;
603 }
604
605 template<short state>
Lua_Player_Compass_Set_State(lua_State * L)606 static int Lua_Player_Compass_Set_State(lua_State *L)
607 {
608 if (!lua_isboolean(L, 2))
609 return luaL_error(L, "compass: incorrect argument type");
610
611 int player_index = Lua_Player_Compass::Index(L, 1);
612 if (lua_toboolean(L, 2))
613 {
614 lua_compass_states[player_index] |= state;
615 }
616 else
617 {
618 lua_compass_states[player_index] &= ~state;
619 }
620
621 return 0;
622 }
623
Lua_Player_Compass_Set_X(lua_State * L)624 static int Lua_Player_Compass_Set_X(lua_State *L)
625 {
626 if (!lua_isnumber(L, 2))
627 return luaL_error(L, "x: incorrect argument type");
628
629 int player_index = Lua_Player_Compass::Index(L, 1);
630 lua_compass_beacons[player_index].x = static_cast<world_distance>(lua_tonumber(L, 2) * WORLD_ONE);
631 return 0;
632 }
633
Lua_Player_Compass_Set_Y(lua_State * L)634 static int Lua_Player_Compass_Set_Y(lua_State *L)
635 {
636 if (!lua_isnumber(L, 2))
637 return luaL_error(L, "y: incorrect argument type");
638
639 int player_index = Lua_Player_Compass::Index(L, 1);
640 lua_compass_beacons[player_index].y = static_cast<world_distance>(lua_tonumber(L, 2) * WORLD_ONE);
641 return 0;
642 }
643
644 const luaL_Reg Lua_Player_Compass_Set[] = {
645 {"beacon", Lua_Player_Compass_Set_State<_network_compass_use_beacon>},
646 {"lua", Lua_Player_Compass_Set_Lua},
647 {"ne", Lua_Player_Compass_Set_State<_network_compass_ne>},
648 {"northeast", Lua_Player_Compass_Set_State<_network_compass_ne>},
649 {"northwest", Lua_Player_Compass_Set_State<_network_compass_nw>},
650 {"nw", Lua_Player_Compass_Set_State<_network_compass_nw>},
651 {"se", Lua_Player_Compass_Set_State<_network_compass_se>},
652 {"southeast", Lua_Player_Compass_Set_State<_network_compass_se>},
653 {"southwest", Lua_Player_Compass_Set_State<_network_compass_sw>},
654 {"sw", Lua_Player_Compass_Set_State<_network_compass_sw>},
655 {"x", Lua_Player_Compass_Set_X},
656 {"y", Lua_Player_Compass_Set_Y},
657 {0, 0}
658 };
659
660 char Lua_Player_Items_Name[] = "player_items";
661 typedef L_Class<Lua_Player_Items_Name> Lua_Player_Items;
662
Lua_Player_Items_Get(lua_State * L)663 static int Lua_Player_Items_Get(lua_State *L)
664 {
665 int player_index = Lua_Player_Items::Index(L, 1);
666 int item_type = Lua_ItemType::ToIndex(L, 2);
667
668 player_data *player = get_player_data(player_index);
669 int item_count = player->items[item_type];
670 if (item_count == NONE) item_count = 0;
671 lua_pushnumber(L, item_count);
672 return 1;
673 }
674
Lua_Player_Items_Length(lua_State * L)675 static int Lua_Player_Items_Length(lua_State *L)
676 {
677 lua_pushnumber(L, NUMBER_OF_DEFINED_ITEMS);
678 return 1;
679 }
680
681 extern void destroy_players_ball(short player_index);
682 extern void select_next_best_weapon(short player_index);
683
Lua_Player_Items_Set(lua_State * L)684 static int Lua_Player_Items_Set(lua_State *L)
685 {
686 if (!lua_isnumber(L, 3))
687 return luaL_error(L, "items: incorrect argument type");
688
689 int player_index = Lua_Player_Items::Index(L, 1);
690 player_data *player = get_player_data(player_index);
691 int item_type = Lua_ItemType::ToIndex(L, 2);
692 int item_count = player->items[item_type];
693 item_definition *definition = get_item_definition_external(item_type);
694 int new_item_count = static_cast<int>(lua_tonumber(L, 3));
695
696 bool accounting = L_Get_Proper_Item_Accounting(L);
697
698 if (new_item_count < 0)
699 luaL_error(L, "items: invalid item count");
700
701 if (item_count == NONE) item_count = 0;
702 int real_difference = item_count - new_item_count;
703 if (new_item_count == 0) new_item_count = NONE;
704
705 if (new_item_count < item_count)
706 {
707 if (definition->item_kind == _ball)
708 {
709 if (find_player_ball_color(player_index) != NONE)
710 destroy_players_ball(player_index);
711 }
712 else
713 {
714 player->items[item_type] = new_item_count;
715 mark_player_inventory_as_dirty(player_index, item_type);
716 if (definition->item_kind == _weapon && player->items[item_type] == NONE)
717 {
718 select_next_best_weapon(player_index);
719 }
720
721 if (accounting)
722 {
723 for (int i = 0; i < real_difference; ++i)
724 object_was_just_destroyed(_object_is_item, item_type);
725 }
726 }
727 }
728 else if (new_item_count > item_count)
729 {
730 while (new_item_count-- > item_count)
731 {
732 if (try_and_add_player_item(player_index, item_type))
733 {
734 if (accounting)
735 object_was_just_added(_object_is_item, item_type);
736 }
737 }
738 }
739
740 return 0;
741 }
742
743 const luaL_Reg Lua_Player_Items_Metatable[] = {
744 {"__index", Lua_Player_Items_Get},
745 {"__newindex", Lua_Player_Items_Set},
746 {"__len", Lua_Player_Items_Length},
747 {0, 0}
748 };
749
750 char Lua_InternalVelocity_Name[] = "internal_velocity";
751 typedef L_Class<Lua_InternalVelocity_Name> Lua_InternalVelocity;
752
Lua_InternalVelocity_Get_Forward(lua_State * L)753 static int Lua_InternalVelocity_Get_Forward(lua_State *L)
754 {
755 int player_index = Lua_InternalVelocity::Index(L, 1);
756 player_data *player = get_player_data(player_index);
757 lua_pushnumber(L, (double) player->variables.velocity / FIXED_ONE);
758 return 1;
759 }
760
Lua_InternalVelocity_Get_Perpendicular(lua_State * L)761 static int Lua_InternalVelocity_Get_Perpendicular(lua_State *L)
762 {
763 int player_index = Lua_InternalVelocity::Index(L, 1);
764 player_data *player = get_player_data(player_index);
765 lua_pushnumber(L, (double) player->variables.perpendicular_velocity / FIXED_ONE);
766 return 1;
767 }
768
769 const luaL_Reg Lua_InternalVelocity_Get[] = {
770 {"forward", Lua_InternalVelocity_Get_Forward},
771 {"perpendicular", Lua_InternalVelocity_Get_Perpendicular},
772 {0, 0}
773 };
774
775 char Lua_ExternalVelocity_Name[] = "external_velocity";
776 typedef L_Class<Lua_ExternalVelocity_Name> Lua_ExternalVelocity;
777
Lua_ExternalVelocity_Get_I(lua_State * L)778 static int Lua_ExternalVelocity_Get_I(lua_State *L)
779 {
780 lua_pushnumber(L, (double) get_player_data(Lua_ExternalVelocity::Index(L, 1))->variables.external_velocity.i / WORLD_ONE);
781 return 1;
782 }
783
Lua_ExternalVelocity_Get_J(lua_State * L)784 static int Lua_ExternalVelocity_Get_J(lua_State *L)
785 {
786 lua_pushnumber(L, (double) get_player_data(Lua_ExternalVelocity::Index(L, 1))->variables.external_velocity.j / WORLD_ONE);
787 return 1;
788 }
789
Lua_ExternalVelocity_Get_K(lua_State * L)790 static int Lua_ExternalVelocity_Get_K(lua_State *L)
791 {
792 lua_pushnumber(L, (double) get_player_data(Lua_ExternalVelocity::Index(L, 1))->variables.external_velocity.k / WORLD_ONE);
793 return 1;
794 }
795
796 const luaL_Reg Lua_ExternalVelocity_Get[] = {
797 {"i", Lua_ExternalVelocity_Get_I},
798 {"j", Lua_ExternalVelocity_Get_J},
799 {"k", Lua_ExternalVelocity_Get_K},
800 {"x", Lua_ExternalVelocity_Get_I},
801 {"y", Lua_ExternalVelocity_Get_J},
802 {"z", Lua_ExternalVelocity_Get_K},
803 {0, 0}
804 };
805
Lua_ExternalVelocity_Set_I(lua_State * L)806 static int Lua_ExternalVelocity_Set_I(lua_State *L)
807 {
808 if (!lua_isnumber(L, 2))
809 return luaL_error(L, "i: incorrect argument type");
810
811 int raw_velocity = static_cast<int>(lua_tonumber(L, 2) * WORLD_ONE);
812 get_player_data(Lua_ExternalVelocity::Index(L, 1))->variables.external_velocity.i = raw_velocity;
813 return 0;
814 }
815
Lua_ExternalVelocity_Set_J(lua_State * L)816 static int Lua_ExternalVelocity_Set_J(lua_State *L)
817 {
818 if (!lua_isnumber(L, 2))
819 return luaL_error(L, "j: incorrect argument type");
820
821 int raw_velocity = static_cast<int>(lua_tonumber(L, 2) * WORLD_ONE);
822 get_player_data(Lua_ExternalVelocity::Index(L, 1))->variables.external_velocity.j = raw_velocity;
823 return 0;
824 }
825
Lua_ExternalVelocity_Set_K(lua_State * L)826 static int Lua_ExternalVelocity_Set_K(lua_State *L)
827 {
828 if (!lua_isnumber(L, 2))
829 return luaL_error(L, "k: incorrect argument type");
830
831 int raw_velocity = static_cast<int>(lua_tonumber(L, 2) * WORLD_ONE);
832 get_player_data(Lua_ExternalVelocity::Index(L, 1))->variables.external_velocity.k = raw_velocity;
833 return 0;
834 }
835
836 const luaL_Reg Lua_ExternalVelocity_Set[] = {
837 {"i", Lua_ExternalVelocity_Set_I},
838 {"j", Lua_ExternalVelocity_Set_J},
839 {"k", Lua_ExternalVelocity_Set_K},
840 {"x", Lua_ExternalVelocity_Set_I},
841 {"y", Lua_ExternalVelocity_Set_J},
842 {"z", Lua_ExternalVelocity_Set_K},
843 {0, 0}
844 };
845
846 char Lua_FadeType_Name[] = "fade_type";
847 typedef L_Enum<Lua_FadeType_Name> Lua_FadeType;
848
849 char Lua_FadeTypes_Name[] = "FadeTypes";
850 typedef L_EnumContainer<Lua_FadeTypes_Name, Lua_FadeType> Lua_FadeTypes;
851
852 const int MAX_TEXTURE_PALETTE_SIZE = 256;
853 struct lua_texture {
854 shape_descriptor shape;
855 short type;
856 };
857 typedef struct lua_texture lua_texture;
858 static std::vector<lua_texture> lua_texture_palette;
859 static int lua_texture_palette_selected = -1;
860
LuaTexturePaletteClear()861 void LuaTexturePaletteClear() {
862 lua_texture_palette.clear();
863 }
864
LuaTexturePaletteSize()865 int LuaTexturePaletteSize() {
866 return lua_texture_palette.size();
867 }
868
LuaTexturePaletteTexture(size_t index)869 shape_descriptor LuaTexturePaletteTexture(size_t index)
870 {
871 if (index < lua_texture_palette.size())
872 return lua_texture_palette[index].shape;
873 else
874 return UNONE;
875 }
876
LuaTexturePaletteTextureType(size_t index)877 short LuaTexturePaletteTextureType(size_t index)
878 {
879 if (index < lua_texture_palette.size())
880 return lua_texture_palette[index].type;
881 else
882 return 0;
883 }
884
LuaTexturePaletteSelected()885 int LuaTexturePaletteSelected()
886 {
887 return lua_texture_palette_selected;
888 }
889
890 char Lua_Texture_Palette_Slot_Name[] = "texture_palette_slot";
891 typedef PlayerSubtable<Lua_Texture_Palette_Slot_Name> Lua_Texture_Palette_Slot;
892
Lua_Texture_Palette_Slot_Clear(lua_State * L)893 int Lua_Texture_Palette_Slot_Clear(lua_State *L)
894 {
895 int player_index = Lua_Texture_Palette_Slot::PlayerIndex(L, 1);
896 if (player_index != local_player_index)
897 return 0;
898
899 lua_texture blank = { UNONE, 0 };
900 lua_texture_palette[Lua_Texture_Palette_Slot::Index(L, 1)] = blank;
901 return 0;
902 }
903
Lua_Texture_Palette_Slot_Get_Collection(lua_State * L)904 static int Lua_Texture_Palette_Slot_Get_Collection(lua_State *L)
905 {
906 int player_index = Lua_Texture_Palette_Slot::PlayerIndex(L, 1);
907 if (player_index != local_player_index)
908 return 0;
909
910 int index = Lua_Texture_Palette_Slot::Index(L, 1);
911 if (lua_texture_palette[index].shape == UNONE)
912 return 0;
913
914 lua_pushnumber(L, GET_COLLECTION(GET_DESCRIPTOR_COLLECTION(lua_texture_palette[index].shape)));
915 return 1;
916 }
917
Lua_Texture_Palette_Slot_Get_Texture(lua_State * L)918 static int Lua_Texture_Palette_Slot_Get_Texture(lua_State *L)
919 {
920 int player_index = Lua_Texture_Palette_Slot::PlayerIndex(L, 1);
921 if (player_index != local_player_index)
922 return 0;
923
924 int index = Lua_Texture_Palette_Slot::Index(L, 1);
925 if (lua_texture_palette[index].shape == UNONE)
926 return 0;
927
928 lua_pushnumber(L, GET_DESCRIPTOR_SHAPE(lua_texture_palette[index].shape));
929 return 1;
930 }
931
Lua_Texture_Palette_Slot_Get_Type(lua_State * L)932 static int Lua_Texture_Palette_Slot_Get_Type(lua_State *L)
933 {
934 int player_index = Lua_Texture_Palette_Slot::PlayerIndex(L, 1);
935 if (player_index != local_player_index)
936 return 0;
937
938 int index = Lua_Texture_Palette_Slot::Index(L, 1);
939 if (lua_texture_palette[index].shape == UNONE)
940 return 0;
941
942 lua_pushnumber(L, lua_texture_palette[index].type);
943 return 1;
944 }
945
946 const luaL_Reg Lua_Texture_Palette_Slot_Get[] = {
947 {"clear", L_TableFunction<Lua_Texture_Palette_Slot_Clear>},
948 {"collection", Lua_Texture_Palette_Slot_Get_Collection},
949 {"texture_index", Lua_Texture_Palette_Slot_Get_Texture},
950 {"type", Lua_Texture_Palette_Slot_Get_Type},
951 {0, 0}
952 };
953
Lua_Texture_Palette_Slot_Set_Collection(lua_State * L)954 static int Lua_Texture_Palette_Slot_Set_Collection(lua_State *L)
955 {
956 int player_index = Lua_Texture_Palette_Slot::PlayerIndex(L, 1);
957 if (player_index != local_player_index)
958 return 0;
959
960 int16 index = Lua_Texture_Palette_Slot::Index(L, 1);
961 short collection_index = Lua_Collection::ToIndex(L, 2);
962
963 lua_texture_palette[index].shape = BUILD_DESCRIPTOR(collection_index, GET_DESCRIPTOR_SHAPE(lua_texture_palette[index].shape));
964 return 0;
965 }
966
Lua_Texture_Palette_Slot_Set_Texture(lua_State * L)967 static int Lua_Texture_Palette_Slot_Set_Texture(lua_State *L)
968 {
969 int player_index = Lua_Texture_Palette_Slot::PlayerIndex(L, 1);
970 if (player_index != local_player_index)
971 return 0;
972
973 if (!lua_isnumber(L, 2))
974 return luaL_error(L, "texture_index: incorrect argument type");
975
976 int16 index = Lua_Texture_Palette_Slot::Index(L, 1);
977 short shape_index = static_cast<short>(lua_tonumber(L, 2));
978 if (shape_index < 0 || shape_index >= MAXIMUM_SHAPES_PER_COLLECTION)
979 return luaL_error(L, "texture_index: invalid texture index");
980
981 lua_texture_palette[index].shape = BUILD_DESCRIPTOR(GET_DESCRIPTOR_COLLECTION(lua_texture_palette[index].shape), shape_index);
982 return 0;
983 }
984
Lua_Texture_Palette_Slot_Set_Type(lua_State * L)985 static int Lua_Texture_Palette_Slot_Set_Type(lua_State *L)
986 {
987 int player_index = Lua_Texture_Palette_Slot::PlayerIndex(L, 1);
988 if (player_index != local_player_index)
989 return 0;
990
991 int16 index = Lua_Texture_Palette_Slot::Index(L, 1);
992 short texture_type = Lua_TextureType::ToIndex(L, 2);
993
994 lua_texture_palette[index].type = texture_type;
995 return 0;
996 }
997
998
999 const luaL_Reg Lua_Texture_Palette_Slot_Set[] = {
1000 {"collection", Lua_Texture_Palette_Slot_Set_Collection},
1001 {"texture_index", Lua_Texture_Palette_Slot_Set_Texture},
1002 {"type", Lua_Texture_Palette_Slot_Set_Type},
1003 {0, 0}
1004 };
1005
1006 char Lua_Texture_Palette_Slots_Name[] = "texture_palette_slots";
1007 typedef L_Class<Lua_Texture_Palette_Slots_Name> Lua_Texture_Palette_Slots;
1008
Lua_Texture_Palette_Slots_Get(lua_State * L)1009 static int Lua_Texture_Palette_Slots_Get(lua_State *L)
1010 {
1011 if (lua_isnumber(L, 2))
1012 {
1013 int player_index = Lua_Texture_Palette_Slots::Index(L, 1);
1014 int index = static_cast<int>(lua_tonumber(L, 2));
1015 if (Lua_Texture_Palette_Slots::Valid(player_index) && index >= 0 && index < lua_texture_palette.size())
1016 {
1017 Lua_Texture_Palette_Slot::Push(L, player_index, index);
1018 }
1019 else
1020 {
1021 lua_pushnil(L);
1022 }
1023 }
1024 else
1025 {
1026 lua_pushnil(L);
1027 }
1028
1029 return 1;
1030 }
1031
Lua_Texture_Palette_Slots_Length(lua_State * L)1032 static int Lua_Texture_Palette_Slots_Length(lua_State *L)
1033 {
1034 int player_index = Lua_Texture_Palette_Slots::Index(L, 1);
1035 if (player_index != local_player_index)
1036 return 0;
1037
1038 lua_pushnumber(L, lua_texture_palette.size());
1039 return 1;
1040 }
1041
1042 const luaL_Reg Lua_Texture_Palette_Slots_Metatable[] = {
1043 {"__index", Lua_Texture_Palette_Slots_Get},
1044 {"__len", Lua_Texture_Palette_Slots_Length},
1045 {0, 0}
1046 };
1047
1048 char Lua_Texture_Palette_Name[] = "texture_palette";
1049 typedef L_Class<Lua_Texture_Palette_Name> Lua_Texture_Palette;
1050
Lua_Texture_Palette_Get_Selected(lua_State * L)1051 static int Lua_Texture_Palette_Get_Selected(lua_State *L)
1052 {
1053 int player_index = Lua_Texture_Palette::Index(L, 1);
1054 if (player_index != local_player_index)
1055 return 0;
1056
1057 if (lua_texture_palette_selected == -1)
1058 return 0;
1059
1060 lua_pushnumber(L, lua_texture_palette_selected);
1061 return 1;
1062 }
1063
Lua_Texture_Palette_Get_Size(lua_State * L)1064 static int Lua_Texture_Palette_Get_Size(lua_State *L)
1065 {
1066 int player_index = Lua_Texture_Palette::Index(L, 1);
1067 if (player_index != local_player_index)
1068 return 0;
1069
1070 lua_pushnumber(L, lua_texture_palette.size());
1071 return 1;
1072 }
1073
Lua_Texture_Palette_Get_Slots(lua_State * L)1074 static int Lua_Texture_Palette_Get_Slots(lua_State *L)
1075 {
1076 Lua_Texture_Palette_Slots::Push(L, Lua_Texture_Palette::Index(L, 1));
1077 return 1;
1078 }
1079
1080 const luaL_Reg Lua_Texture_Palette_Get[] = {
1081 {"highlight", Lua_Texture_Palette_Get_Selected},
1082 {"size", Lua_Texture_Palette_Get_Size},
1083 {"slots", Lua_Texture_Palette_Get_Slots},
1084 {0, 0}
1085 };
1086
1087 extern void draw_panels();
1088
Lua_Texture_Palette_Set_Selected(lua_State * L)1089 static int Lua_Texture_Palette_Set_Selected(lua_State *L)
1090 {
1091 int player_index = Lua_Texture_Palette::Index(L, 1);
1092 if (player_index != local_player_index)
1093 return 0;
1094
1095 if (lua_isnil(L, 2))
1096 lua_texture_palette_selected = -1;
1097 else if (lua_isnumber(L, 2))
1098 {
1099 int selected = static_cast<int>(lua_tonumber(L, 2));
1100 if (selected < -1 || selected > lua_texture_palette.size())
1101 return luaL_error(L, "highlight: invalid slot");
1102
1103 lua_texture_palette_selected = selected;
1104 draw_panels();
1105 }
1106 else
1107 return luaL_error(L, "highlight: incorrect argument type");
1108
1109 return 0;
1110 }
1111
1112
Lua_Texture_Palette_Set_Size(lua_State * L)1113 static int Lua_Texture_Palette_Set_Size(lua_State *L)
1114 {
1115 int player_index = Lua_Texture_Palette::Index(L, 1);
1116 if (player_index != local_player_index)
1117 return 0;
1118
1119 if (!lua_isnumber(L, 2))
1120 return luaL_error(L, "size: incorrect argument type");
1121
1122 size_t size = static_cast<size_t>(lua_tonumber(L, 2));
1123 if (size > MAX_TEXTURE_PALETTE_SIZE)
1124 return luaL_error(L, "size: Its really big");
1125
1126 lua_texture blank = { UNONE, 0 };
1127 lua_texture_palette.resize(size, blank);
1128 if (lua_texture_palette_selected >= lua_texture_palette.size())
1129 lua_texture_palette_selected = -1;
1130
1131 draw_panels();
1132 return 0;
1133 }
1134
1135 const luaL_Reg Lua_Texture_Palette_Set[] = {
1136 {"highlight", Lua_Texture_Palette_Set_Selected},
1137 {"size", Lua_Texture_Palette_Set_Size},
1138 {0, 0}
1139 };
1140
1141 char Lua_WeaponType_Name[] = "weapon_type";
1142 typedef L_Enum<Lua_WeaponType_Name> Lua_WeaponType;
1143
1144 char Lua_WeaponTypes_Name[] = "WeaponTypes";
1145 typedef L_EnumContainer<Lua_WeaponTypes_Name, Lua_WeaponType> Lua_WeaponTypes;
1146
1147 char Lua_Player_Weapon_Trigger_Name[] = "player_weapon_trigger";
1148 class Lua_Player_Weapon_Trigger : public PlayerSubtable<Lua_Player_Weapon_Trigger_Name>
1149 {
1150 public:
1151 int16 m_weapon_index;
1152
1153 static Lua_Player_Weapon_Trigger *Push(lua_State *L, int16 player_index, int16 weapon_index, int16 index);
1154 static int16 WeaponIndex(lua_State *L, int index);
1155 };
1156
Push(lua_State * L,int16 player_index,int16 weapon_index,int16 index)1157 Lua_Player_Weapon_Trigger *Lua_Player_Weapon_Trigger::Push(lua_State *L, int16 player_index, int16 weapon_index, int16 index)
1158 {
1159 Lua_Player_Weapon_Trigger *t = PlayerSubtable::Push<Lua_Player_Weapon_Trigger>(L, player_index, index);
1160 if (t)
1161 {
1162 t->m_weapon_index = weapon_index;
1163 }
1164
1165 return t;
1166 }
1167
WeaponIndex(lua_State * L,int index)1168 int16 Lua_Player_Weapon_Trigger::WeaponIndex(lua_State *L, int index)
1169 {
1170 Lua_Player_Weapon_Trigger *t = static_cast<Lua_Player_Weapon_Trigger*>(Instance(L, index));
1171 if (!t) luaL_typerror(L, index, Lua_Player_Weapon_Trigger_Name);
1172 return t->m_weapon_index;
1173 }
1174
Lua_Player_Weapon_Trigger_Get_Rounds(lua_State * L)1175 static int Lua_Player_Weapon_Trigger_Get_Rounds(lua_State *L)
1176 {
1177 short rounds = get_player_weapon_ammo_count(
1178 Lua_Player_Weapon_Trigger::PlayerIndex(L, 1),
1179 Lua_Player_Weapon_Trigger::WeaponIndex(L, 1),
1180 Lua_Player_Weapon_Trigger::Index(L, 1));
1181 lua_pushnumber(L, rounds);
1182 return 1;
1183 }
1184
1185 const luaL_Reg Lua_Player_Weapon_Trigger_Get[] = {
1186 {"rounds", Lua_Player_Weapon_Trigger_Get_Rounds},
1187 {0, 0}
1188 };
1189
1190 char Lua_Player_Weapon_Name[] = "player_weapon";
1191 typedef PlayerSubtable<Lua_Player_Weapon_Name> Lua_Player_Weapon;
1192
1193 template<int trigger>
get_weapon_trigger(lua_State * L)1194 static int get_weapon_trigger(lua_State *L)
1195 {
1196 Lua_Player_Weapon_Trigger::Push(L, Lua_Player_Weapon::PlayerIndex(L, 1), Lua_Player_Weapon::Index(L, 1), trigger);
1197 return 1;
1198 }
1199
Lua_Player_Weapon_Get_Type(lua_State * L)1200 static int Lua_Player_Weapon_Get_Type(lua_State *L)
1201 {
1202 Lua_WeaponType::Push(L, Lua_Player_Weapon::Index(L, 1));
1203 return 1;
1204 }
1205
1206 extern bool ready_weapon(short player_index, short weapon_index);
1207
Lua_Player_Weapon_Select(lua_State * L)1208 int Lua_Player_Weapon_Select(lua_State *L)
1209 {
1210 ready_weapon(Lua_Player_Weapon::PlayerIndex(L, 1), Lua_Player_Weapon::Index(L, 1));
1211 return 0;
1212 }
1213
1214 const luaL_Reg Lua_Player_Weapon_Get[] = {
1215 {"primary", get_weapon_trigger<_primary_weapon>},
1216 {"secondary", get_weapon_trigger<_secondary_weapon>},
1217 {"select", L_TableFunction<Lua_Player_Weapon_Select>},
1218 {"type", Lua_Player_Weapon_Get_Type},
1219 {0, 0}
1220 };
1221
1222 extern player_weapon_data *get_player_weapon_data(const short player_index);
1223 extern bool player_has_valid_weapon(short player_index);
1224
1225 char Lua_Player_Weapons_Name[] = "player_weapons";
1226 typedef L_Class<Lua_Player_Weapons_Name> Lua_Player_Weapons;
1227
1228 extern bool can_wield_weapons[MAXIMUM_NUMBER_OF_NETWORK_PLAYERS];
1229
Lua_Player_Weapons_Get(lua_State * L)1230 static int Lua_Player_Weapons_Get(lua_State *L)
1231 {
1232 int player_index = Lua_Player_Weapons::Index(L, 1);
1233 bool string_arg = lua_isstring(L, 2) && !lua_isnumber(L, 2);
1234 if (string_arg && (strcmp(lua_tostring(L, 2), "current") == 0))
1235 {
1236 if (player_has_valid_weapon(player_index))
1237 {
1238 player_weapon_data *weapon_data = get_player_weapon_data(player_index);
1239 Lua_Player_Weapon::Push(L, player_index, weapon_data->current_weapon);
1240 }
1241 else
1242 {
1243 lua_pushnil(L);
1244 }
1245 }
1246 else if (string_arg && (strcmp(lua_tostring(L, 2), "desired") == 0))
1247 {
1248 player_weapon_data *weapon_data = get_player_weapon_data(player_index);
1249 if (weapon_data->desired_weapon != NONE)
1250 {
1251 Lua_Player_Weapon::Push(L, player_index, weapon_data->desired_weapon);
1252 }
1253 else
1254 {
1255 lua_pushnil(L);
1256 }
1257 }
1258 else if (string_arg && (strcmp(lua_tostring(L, 2), "active") == 0))
1259 {
1260 lua_pushboolean(L, can_wield_weapons[player_index]);
1261 }
1262 else
1263 {
1264 int index = Lua_WeaponType::ToIndex(L, 2);
1265 Lua_Player_Weapon::Push(L, player_index, index);
1266 }
1267
1268 return 1;
1269 }
1270
Lua_Player_Weapons_Length(lua_State * L)1271 static int Lua_Player_Weapons_Length(lua_State *L)
1272 {
1273 lua_pushnumber(L, MAXIMUM_NUMBER_OF_WEAPONS);
1274 return 1;
1275 }
1276
Lua_Player_Weapons_Set(lua_State * L)1277 static int Lua_Player_Weapons_Set(lua_State *L)
1278 {
1279 if (lua_isstring(L, 2) && strcmp(lua_tostring(L, 2), "active") == 0)
1280 {
1281 if (!lua_isboolean(L, 3))
1282 return luaL_error(L, "can_wield: incorrect argument type");
1283 can_wield_weapons[Lua_Player_Weapons::Index(L, 1)] = lua_toboolean(L, 3);
1284 return 0;
1285 }
1286 else
1287 return luaL_error(L, "no such index");
1288 }
1289
1290 const luaL_Reg Lua_Player_Weapons_Metatable[] = {
1291 {"__index", Lua_Player_Weapons_Get},
1292 {"__newindex", Lua_Player_Weapons_Set},
1293 {"__len", Lua_Player_Weapons_Length},
1294 {0, 0}
1295 };
1296
1297 char Lua_Player_Kills_Name[] = "player_kills";
1298 typedef L_Class<Lua_Player_Kills_Name> Lua_Player_Kills;
1299
Lua_Player_Kills_Get(lua_State * L)1300 static int Lua_Player_Kills_Get(lua_State *L)
1301 {
1302 int player_index = Lua_Player_Kills::Index(L, 1);
1303 int slain_player_index = Lua_Player::Index(L, 2);
1304
1305 player_data *slain_player = get_player_data(slain_player_index);
1306
1307 lua_pushnumber(L, slain_player->damage_taken[player_index].kills);
1308 return 1;
1309 }
1310
Lua_Player_Kills_Length(lua_State * L)1311 static int Lua_Player_Kills_Length(lua_State *L)
1312 {
1313 lua_pushnumber(L, dynamic_world->player_count);
1314 return 1;
1315 }
1316
Lua_Player_Kills_Set(lua_State * L)1317 static int Lua_Player_Kills_Set(lua_State *L)
1318 {
1319 if (!lua_isnumber(L, 3))
1320 return luaL_error(L, "kills: incorrect argument type");
1321
1322 int player_index = Lua_Player_Kills::Index(L, 1);
1323 int slain_player_index = Lua_Player::Index(L, 2);
1324 int kills = static_cast<int>(lua_tonumber(L, 3));
1325
1326 player_data *player = get_player_data(player_index);
1327 player_data *slain_player = get_player_data(slain_player_index);
1328
1329 int kills_award = kills - slain_player->damage_taken[player_index].kills;
1330 if (kills_award)
1331 {
1332 slain_player->damage_taken[player_index].kills += kills_award;
1333 team_damage_taken[slain_player->team].kills += kills_award;
1334
1335 if (player_index != slain_player_index)
1336 {
1337 player->total_damage_given.kills += kills_award;
1338 team_damage_given[player->team].kills += kills_award;
1339 }
1340 if (slain_player->team == player->team)
1341 {
1342 team_friendly_fire[slain_player->team].kills += kills_award;
1343 }
1344 mark_player_network_stats_as_dirty(current_player_index);
1345 }
1346 return 0;
1347 }
1348
1349 const luaL_Reg Lua_Player_Kills_Metatable[] = {
1350 {"__index", Lua_Player_Kills_Get},
1351 {"__newindex", Lua_Player_Kills_Set},
1352 {"__len", Lua_Player_Kills_Length},
1353 {0, 0}
1354 };
1355
1356 char Lua_PlayerColor_Name[] = "player_color";
1357
1358 char Lua_PlayerColors_Name[] = "PlayerColors";
1359
1360 char Lua_Player_Name[] = "player";
1361
1362 // methods
1363
1364 // accelerate(direction, velocity, vertical_velocity)
Lua_Player_Accelerate(lua_State * L)1365 int Lua_Player_Accelerate(lua_State *L)
1366 {
1367 if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4))
1368 return luaL_error(L, "accelerate: incorrect argument type");
1369
1370 player_data *player = get_player_data(Lua_Player::Index(L, 1));
1371 double direction = static_cast<double>(lua_tonumber(L, 2));
1372 double velocity = static_cast<double>(lua_tonumber(L, 3));
1373 double vertical_velocity = static_cast<double>(lua_tonumber(L, 4));
1374
1375 accelerate_player(player->monster_index, static_cast<int>(vertical_velocity * WORLD_ONE), static_cast<int>(direction/AngleConvert), static_cast<int>(velocity * WORLD_ONE));
1376 return 0;
1377 }
1378
Lua_Player_Activate_Terminal(lua_State * L)1379 int Lua_Player_Activate_Terminal(lua_State *L)
1380 {
1381 int16 text_index = NONE;
1382 if (lua_isnumber(L, 2))
1383 text_index = static_cast<int16>(lua_tonumber(L, 2));
1384 else if (Lua_Terminal::Is(L, 2))
1385 text_index = Lua_Terminal::Index(L, 2);
1386 else
1387 return luaL_error(L, "activate_terminal: invalid terminal index");
1388
1389 enter_computer_interface(Lua_Player::Index(L, 1), text_index, calculate_level_completion_state());
1390 return 0;
1391 }
1392
Lua_Player_Find_Action_Key_Target(lua_State * L)1393 int Lua_Player_Find_Action_Key_Target(lua_State *L)
1394 {
1395 short target_type;
1396 short object_index = find_action_key_target(Lua_Player::Index(L, 1), MAXIMUM_ACTIVATION_RANGE, &target_type, film_profile.find_action_key_target_has_side_effects);
1397
1398 if (object_index != NONE)
1399 {
1400 switch (target_type)
1401 {
1402 case _target_is_platform:
1403 Lua_Platform::Push(L, object_index);
1404 break;
1405
1406 case _target_is_control_panel:
1407 Lua_Side::Push(L, object_index);
1408 break;
1409
1410 default:
1411 lua_pushnil(L);
1412 break;
1413 }
1414 }
1415 else
1416 {
1417 lua_pushnil(L);
1418 }
1419
1420 return 1;
1421 }
1422
1423 extern projectile_definition *get_projectile_definition(short type);
1424
Lua_Player_Find_Target(lua_State * L)1425 int Lua_Player_Find_Target(lua_State *L)
1426 {
1427 // find the origin of projectiles (don't move left/right)
1428 player_data *player = get_player_data(Lua_Player::Index(L, 1));
1429 world_point3d origin = player->camera_location;
1430 world_point3d destination = origin;
1431
1432 translate_point3d(&destination, WORLD_ONE, player->facing, player->elevation);
1433 short old_polygon = get_object_data(player->object_index)->polygon;
1434 short new_polygon;
1435 short obstruction_index;
1436 short line_index;
1437
1438 projectile_definition *definition = get_projectile_definition(0);
1439 bool was_pass_transparent = definition->flags & _usually_pass_transparent_side;
1440 if (!was_pass_transparent)
1441 definition->flags |= _usually_pass_transparent_side;
1442
1443 // preflight a projectile, 1 WU at a time (because of projectile speed bug)
1444 uint16 flags = translate_projectile(0, &origin, old_polygon, &destination, &new_polygon, player->monster_index, &obstruction_index, &line_index, true, NONE);
1445
1446 while (!(flags & _projectile_hit))
1447 {
1448 origin = destination;
1449 old_polygon = new_polygon;
1450
1451 translate_point3d(&destination, WORLD_ONE, player->facing, player->elevation);
1452 flags = translate_projectile(0, &origin, old_polygon, &destination, &new_polygon, player->monster_index, &obstruction_index, &line_index, true, NONE);
1453 }
1454
1455 if (!was_pass_transparent)
1456 definition->flags &= ~_usually_pass_transparent_side;
1457
1458 if (flags & _projectile_hit_monster)
1459 {
1460 object_data *object = get_object_data(obstruction_index);
1461 Lua_Monster::Push(L, object->permutation);
1462 }
1463 else if (flags & _projectile_hit_floor)
1464 {
1465 Lua_Polygon_Floor::Push(L, new_polygon);
1466 }
1467 else if (flags & _projectile_hit_media)
1468 {
1469 Lua_Polygon::Push(L, new_polygon);
1470 }
1471 else if (flags & _projectile_hit_scenery)
1472 {
1473 Lua_Scenery::Push(L, obstruction_index);
1474 }
1475 else if (obstruction_index != NONE)
1476 {
1477 Lua_Polygon_Ceiling::Push(L, new_polygon);
1478 }
1479 else
1480 {
1481 short side_index = find_adjacent_side(new_polygon, line_index);
1482 Lua_Side::Push(L, side_index);
1483 }
1484
1485 lua_pushnumber(L, (double) destination.x / WORLD_ONE);
1486 lua_pushnumber(L, (double) destination.y / WORLD_ONE);
1487 lua_pushnumber(L, (double) destination.z / WORLD_ONE);
1488 Lua_Polygon::Push(L, new_polygon);
1489
1490 return 5;
1491 }
1492
1493
Lua_Player_Damage(lua_State * L)1494 int Lua_Player_Damage(lua_State *L)
1495 {
1496 int args = lua_gettop(L);
1497 if (!lua_isnumber(L, 2))
1498 return luaL_error(L, "damage: incorrect argument type");
1499
1500 player_data *player = get_player_data(Lua_Player::Index(L, 1));
1501 if (PLAYER_IS_DEAD(player) || PLAYER_IS_TOTALLY_DEAD(player))
1502 return 0;
1503
1504 damage_definition damage;
1505 damage.type = _damage_crushing;
1506 damage.base = static_cast<int>(lua_tonumber(L, 2));
1507 damage.random = 0;
1508 damage.scale = FIXED_ONE;
1509
1510 if (args > 2)
1511 {
1512 damage.type = Lua_DamageType::ToIndex(L, 3);
1513 }
1514
1515 damage_player(player->monster_index, NONE, NONE, &damage, NONE);
1516 return 0;
1517 }
1518
Lua_Player_Fade_Screen(lua_State * L)1519 int Lua_Player_Fade_Screen(lua_State *L)
1520 {
1521 short player_index = Lua_Player::Index(L, 1);
1522 if (player_index == local_player_index)
1523 {
1524 int fade_index = Lua_FadeType::ToIndex(L, 2);
1525 start_fade(fade_index);
1526 }
1527 return 0;
1528 }
1529
Lua_Player_Play_Sound(lua_State * L)1530 int Lua_Player_Play_Sound(lua_State *L)
1531 {
1532 int args = lua_gettop(L);
1533
1534 int player_index = Lua_Player::Index(L, 1);
1535 int sound_index = Lua_Sound::ToIndex(L, 2);
1536 float pitch = 1.0;
1537 if (args > 2)
1538 {
1539 if (lua_isnumber(L, 3))
1540 pitch = static_cast<float>(lua_tonumber(L, 3));
1541 else
1542 return luaL_error(L, "play_sound: incorrect argument type");
1543 }
1544
1545 if (local_player_index != player_index)
1546 return 0;
1547
1548 SoundManager::instance()->PlaySound(sound_index, NULL, NONE, _fixed(FIXED_ONE * pitch));
1549 return 0;
1550 }
1551
1552 extern bool mute_lua;
1553
Lua_Player_Print(lua_State * L)1554 int Lua_Player_Print(lua_State *L)
1555 {
1556 if (mute_lua) return 0;
1557
1558 if (lua_gettop(L) != 2)
1559 return luaL_error(L, "print: incorrect argument type");
1560
1561 int player_index = Lua_Player::Index(L, 1);
1562 if (player_index == (IsScriptHUDNonlocal() ? current_player_index : local_player_index))
1563 {
1564 lua_getglobal(L, "tostring");
1565 lua_insert(L, -2);
1566 lua_pcall(L, 1, 1, 0);
1567 if (lua_tostring(L, -1))
1568 {
1569 screen_printf("%s", lua_tostring(L, -1));
1570 }
1571 lua_pop(L, 1);
1572 }
1573
1574 return 0;
1575 }
1576
1577 extern struct physics_constants *get_physics_constants_for_model(short physics_model, uint32 action_flags);
1578 extern void instantiate_physics_variables(struct physics_constants *constants, struct physics_variables *variables, short player_index, bool first_time, bool take_action);
1579
Lua_Player_Position(lua_State * L)1580 int Lua_Player_Position(lua_State *L)
1581 {
1582 if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4))
1583 return luaL_error(L, ("position: incorrect argument type"));
1584
1585 int polygon_index = 0;
1586 if (lua_isnumber(L, 5))
1587 {
1588 polygon_index = static_cast<int>(lua_tonumber(L, 5));
1589 if (!Lua_Polygon::Valid(polygon_index))
1590 return luaL_error(L, ("position: invalid polygon index"));
1591 }
1592 else if (Lua_Polygon::Is(L, 5))
1593 {
1594 polygon_index = Lua_Polygon::Index(L, 5);
1595 }
1596 else
1597 return luaL_error(L, ("position: incorrect argument type"));
1598
1599 int player_index = Lua_Player::Index(L, 1);
1600 player_data *player = get_player_data(player_index);
1601 object_data *object = get_object_data(player->object_index);
1602
1603 world_point3d location;
1604 location.x = static_cast<int>(lua_tonumber(L, 2) * WORLD_ONE);
1605 location.y = static_cast<int>(lua_tonumber(L, 3) * WORLD_ONE);
1606 location.z = static_cast<int>(lua_tonumber(L, 4) * WORLD_ONE);
1607
1608 translate_map_object(player->object_index, &location, polygon_index);
1609 player->variables.position.x = WORLD_TO_FIXED(object->location.x);
1610 player->variables.position.y = WORLD_TO_FIXED(object->location.y);
1611 player->variables.position.z = WORLD_TO_FIXED(object->location.z);
1612
1613 instantiate_physics_variables(get_physics_constants_for_model(static_world->physics_model, 0), &player->variables, player_index, false, false);
1614 return 0;
1615 }
1616
Lua_Player_Teleport(lua_State * L)1617 int Lua_Player_Teleport(lua_State *L)
1618 {
1619 if (!lua_isnumber(L, 2) && !Lua_Polygon::Is(L, 2))
1620 return luaL_error(L, "teleport(): incorrect argument type");
1621
1622 int destination = -1;
1623 if (lua_isnumber(L, 2))
1624 destination = static_cast<int>(lua_tonumber(L, 2));
1625 else
1626 destination = Lua_Polygon::Index(L, 2);
1627
1628 int player_index = Lua_Player::Index(L, 1);
1629
1630 player_data *player = get_player_data(player_index);
1631 monster_data *monster = get_monster_data(player->monster_index);
1632
1633 SET_PLAYER_TELEPORTING_STATUS(player, true);
1634 monster->action = _monster_is_teleporting;
1635 player->teleporting_phase = 0;
1636 player->delay_before_teleport = 0;
1637
1638 player->teleporting_destination = destination;
1639 if (local_player_index == player_index)
1640 start_teleporting_effect(true);
1641 play_object_sound(player->object_index, Sound_TeleportOut());
1642 return 0;
1643 }
1644
Lua_Player_Teleport_To_Level(lua_State * L)1645 int Lua_Player_Teleport_To_Level(lua_State *L)
1646 {
1647 if (!lua_isnumber(L, 2))
1648 return luaL_error(L, "teleport_to_level(): incorrect argument type");
1649
1650 int level = static_cast<int>(lua_tonumber(L, 2));
1651 int player_index = Lua_Player::Index(L, 1);
1652
1653 player_data *player = get_player_data(player_index);
1654 monster_data *monster = get_monster_data(player->monster_index);
1655
1656 SET_PLAYER_TELEPORTING_STATUS(player, true);
1657 monster->action = _monster_is_teleporting;
1658 player->teleporting_phase = 0;
1659 player->delay_before_teleport = 0;
1660
1661 player->teleporting_destination = -level - 1;
1662 if (View_DoInterlevelTeleportOutEffects()) {
1663 start_teleporting_effect(true);
1664 play_object_sound(player->object_index, Sound_TeleportOut());
1665 }
1666 return 0;
1667 }
1668
1669 extern short current_player_index;
1670
Lua_Player_Get_Viewed_Player(lua_State * L)1671 int Lua_Player_Get_Viewed_Player(lua_State *L)
1672 {
1673 int player_index = Lua_Player::Index(L, 1);
1674 if (player_index != local_player_index)
1675 return 0;
1676 Lua_Player::Push(L, current_player_index);
1677 return 1;
1678 }
1679
Lua_Player_View_Player(lua_State * L)1680 int Lua_Player_View_Player(lua_State *L)
1681 {
1682 int player_index = Lua_Player::Index(L, 1);
1683 if (player_index != local_player_index)
1684 return 0;
1685
1686 int view_player_index;
1687 if (lua_isnumber(L, 2))
1688 {
1689 view_player_index = static_cast<int>(lua_tonumber(L, 2));
1690 if (view_player_index < 0 || view_player_index >= dynamic_world->player_count)
1691 return luaL_error(L, "view_player(): invalid player index");
1692 }
1693 else if (Lua_Player::Is(L, 2))
1694 view_player_index = Lua_Player::Index(L, 2);
1695 else
1696 return luaL_error(L, "view_player(): incorrect argument type");
1697
1698 if (view_player_index != current_player_index)
1699 {
1700 set_current_player_index(view_player_index);
1701 update_interface(NONE);
1702 dirty_terminal_view(player_index);
1703 }
1704
1705 return 0;
1706
1707 }
1708
1709 // get accessors
1710
Lua_Player_Get_Action_Flags(lua_State * L)1711 static int Lua_Player_Get_Action_Flags(lua_State *L)
1712 {
1713 Lua_Action_Flags::Push(L, Lua_Player::Index(L, 1));
1714 return 1;
1715 }
1716
Lua_Player_Get_Color(lua_State * L)1717 static int Lua_Player_Get_Color(lua_State *L)
1718 {
1719 Lua_PlayerColor::Push(L, get_player_data(Lua_Player::Index(L, 1))->color);
1720 return 1;
1721 }
1722
Lua_Player_Get_Compass(lua_State * L)1723 static int Lua_Player_Get_Compass(lua_State *L)
1724 {
1725 Lua_Player_Compass::Push(L, Lua_Player::Index(L, 1));
1726 return 1;
1727 }
1728
Lua_Player_Get_Crosshairs(lua_State * L)1729 static int Lua_Player_Get_Crosshairs(lua_State *L)
1730 {
1731 Lua_Crosshairs::Push(L, Lua_Player::Index(L, 1));
1732 return 1;
1733 }
1734
Lua_Player_Get_Dead(lua_State * L)1735 static int Lua_Player_Get_Dead(lua_State *L)
1736 {
1737 player_data *player = get_player_data(Lua_Player::Index(L, 1));
1738 lua_pushboolean(L, (PLAYER_IS_DEAD(player) || PLAYER_IS_TOTALLY_DEAD(player)));
1739 return 1;
1740 }
1741
Lua_Player_Get_Deaths(lua_State * L)1742 static int Lua_Player_Get_Deaths(lua_State *L)
1743 {
1744 player_data *player = get_player_data(Lua_Player::Index(L, 1));
1745 lua_pushnumber(L, player->monster_damage_taken.kills);
1746 return 1;
1747 }
1748
Lua_Player_Get_Energy(lua_State * L)1749 static int Lua_Player_Get_Energy(lua_State *L)
1750 {
1751 lua_pushnumber(L, get_player_data(Lua_Player::Index(L, 1))->suit_energy);
1752 return 1;
1753 }
1754
Lua_Player_Get_Elevation(lua_State * L)1755 static int Lua_Player_Get_Elevation(lua_State *L)
1756 {
1757 double angle = FIXED_INTEGERAL_PART(get_player_data(Lua_Player::Index(L, 1))->variables.elevation) * AngleConvert;
1758 lua_pushnumber(L, angle);
1759 return 1;
1760 }
1761
Lua_Player_Get_Direction(lua_State * L)1762 static int Lua_Player_Get_Direction(lua_State *L)
1763 {
1764 double angle = FIXED_INTEGERAL_PART(get_player_data(Lua_Player::Index(L, 1))->variables.direction) * AngleConvert;
1765 lua_pushnumber(L, angle);
1766 return 1;
1767 }
1768
Lua_Player_Get_Head_Direction(lua_State * L)1769 static int Lua_Player_Get_Head_Direction(lua_State *L)
1770 {
1771 player_data *pdata = get_player_data(Lua_Player::Index(L, 1));
1772 double angle = FIXED_INTEGERAL_PART(pdata->variables.direction + pdata->variables.head_direction) * AngleConvert;
1773 if (angle >= 360.0) { angle -= 360.0; }
1774 if (angle < 0.0) { angle += 360.0; }
1775 lua_pushnumber(L, angle);
1776 return 1;
1777 }
1778
Lua_Player_Get_External_Velocity(lua_State * L)1779 static int Lua_Player_Get_External_Velocity(lua_State *L)
1780 {
1781 Lua_ExternalVelocity::Push(L, Lua_Player::Index(L, 1));
1782 return 1;
1783 }
1784
Lua_Player_Get_Extravision_Duration(lua_State * L)1785 static int Lua_Player_Get_Extravision_Duration(lua_State *L)
1786 {
1787 lua_pushnumber(L, get_player_data(Lua_Player::Index(L, 1))->extravision_duration);
1788 return 1;
1789 }
1790
1791 template<uint16 flag>
Lua_Player_Get_Flag(lua_State * L)1792 static int Lua_Player_Get_Flag(lua_State *L)
1793 {
1794 player_data *player = get_player_data(Lua_Player::Index(L, 1));
1795 lua_pushboolean(L, player->variables.flags & flag);
1796 return 1;
1797 }
1798
Lua_Player_Get_Infravision_Duration(lua_State * L)1799 static int Lua_Player_Get_Infravision_Duration(lua_State *L)
1800 {
1801 lua_pushnumber(L, get_player_data(Lua_Player::Index(L, 1))->infravision_duration);
1802 return 1;
1803 }
1804
Lua_Player_Get_Internal_Velocity(lua_State * L)1805 static int Lua_Player_Get_Internal_Velocity(lua_State *L)
1806 {
1807 Lua_InternalVelocity::Push(L, Lua_Player::Index(L, 1));
1808 return 1;
1809 }
1810
Lua_Player_Get_Invincibility_Duration(lua_State * L)1811 static int Lua_Player_Get_Invincibility_Duration(lua_State *L)
1812 {
1813 lua_pushnumber(L, get_player_data(Lua_Player::Index(L, 1))->invincibility_duration);
1814 return 1;
1815 }
1816
Lua_Player_Get_Invisibility_Duration(lua_State * L)1817 static int Lua_Player_Get_Invisibility_Duration(lua_State *L)
1818 {
1819 lua_pushnumber(L, get_player_data(Lua_Player::Index(L, 1))->invisibility_duration);
1820 return 1;
1821 }
1822
Lua_Player_Get_Items(lua_State * L)1823 static int Lua_Player_Get_Items(lua_State *L)
1824 {
1825 Lua_Player_Items::Push(L, Lua_Player::Index(L, 1));
1826 return 1;
1827 }
1828
Lua_Player_Get_Kills(lua_State * L)1829 static int Lua_Player_Get_Kills(lua_State *L)
1830 {
1831 Lua_Player_Kills::Push(L, Lua_Player::Index(L, 1));
1832 return 1;
1833 }
1834
Lua_Player_Get_Local(lua_State * L)1835 static int Lua_Player_Get_Local(lua_State *L)
1836 {
1837 lua_pushboolean(L, Lua_Player::Index(L, 1) == local_player_index);
1838 return 1;
1839 }
1840
1841 extern bool MotionSensorActive;
1842
Lua_Player_Get_Motion_Sensor(lua_State * L)1843 static int Lua_Player_Get_Motion_Sensor(lua_State *L)
1844 {
1845 short player_index = Lua_Player::Index(L, 1);
1846 if (player_index == local_player_index)
1847 {
1848 lua_pushboolean(L, MotionSensorActive);
1849 return 1;
1850 }
1851 else
1852 {
1853 return 0;
1854 }
1855 }
1856
Lua_Player_Get_Monster(lua_State * L)1857 static int Lua_Player_Get_Monster(lua_State *L)
1858 {
1859 Lua_Monster::Push(L, get_player_data(Lua_Player::Index(L, 1))->monster_index);
1860 return 1;
1861 }
1862
Lua_Player_Get_Name(lua_State * L)1863 static int Lua_Player_Get_Name(lua_State *L)
1864 {
1865 lua_pushstring(L, get_player_data(Lua_Player::Index(L, 1))->name);
1866 return 1;
1867 }
1868
Lua_Player_Get_Netdead(lua_State * L)1869 static int Lua_Player_Get_Netdead(lua_State *L)
1870 {
1871 lua_pushboolean(L, get_player_data(Lua_Player::Index(L, 1))->netdead);
1872 return 1;
1873 }
1874
Lua_Player_Get_Overlays(lua_State * L)1875 static int Lua_Player_Get_Overlays(lua_State *L)
1876 {
1877 Lua_Overlays::Push(L, Lua_Player::Index(L, 1));
1878 return 1;
1879 }
1880
Lua_Player_Get_Oxygen(lua_State * L)1881 static int Lua_Player_Get_Oxygen(lua_State *L)
1882 {
1883 lua_pushnumber(L, get_player_data(Lua_Player::Index(L, 1))->suit_oxygen);
1884 return 1;
1885 }
1886
Lua_Player_Get_Points(lua_State * L)1887 static int Lua_Player_Get_Points(lua_State *L)
1888 {
1889 lua_pushnumber(L, get_player_data(Lua_Player::Index(L, 1))->netgame_parameters[0]);
1890 return 1;
1891 }
1892
Lua_Player_Get_Polygon(lua_State * L)1893 static int Lua_Player_Get_Polygon(lua_State *L)
1894 {
1895 Lua_Polygon::Push(L, get_player_data(Lua_Player::Index(L, 1))->supporting_polygon_index);
1896 return 1;
1897 }
1898
Lua_Player_Get_Team(lua_State * L)1899 static int Lua_Player_Get_Team(lua_State *L)
1900 {
1901 Lua_PlayerColor::Push(L, get_player_data(Lua_Player::Index(L, 1))->team);
1902 return 1;
1903 }
1904
Lua_Player_Get_Texture_Palette(lua_State * L)1905 static int Lua_Player_Get_Texture_Palette(lua_State *L)
1906 {
1907 Lua_Texture_Palette::Push(L, Lua_Player::Index(L, 1));
1908 return 1;
1909 }
1910
Lua_Player_Get_Weapons(lua_State * L)1911 static int Lua_Player_Get_Weapons(lua_State *L)
1912 {
1913 Lua_Player_Weapons::Push(L, Lua_Player::Index(L, 1));
1914 return 1;
1915 }
1916
Lua_Player_Get_X(lua_State * L)1917 static int Lua_Player_Get_X(lua_State *L)
1918 {
1919 lua_pushnumber(L, (double) get_player_data(Lua_Player::Index(L, 1))->location.x / WORLD_ONE);
1920 return 1;
1921 }
1922
Lua_Player_Get_Y(lua_State * L)1923 static int Lua_Player_Get_Y(lua_State *L)
1924 {
1925 lua_pushnumber(L, (double) get_player_data(Lua_Player::Index(L, 1))->location.y / WORLD_ONE);
1926 return 1;
1927 }
1928
Lua_Player_Get_Z(lua_State * L)1929 static int Lua_Player_Get_Z(lua_State *L)
1930 {
1931 lua_pushnumber(L, (double) get_player_data(Lua_Player::Index(L, 1))->location.z / WORLD_ONE);
1932 return 1;
1933 }
1934
Lua_Player_Get_Zoom(lua_State * L)1935 static int Lua_Player_Get_Zoom(lua_State *L)
1936 {
1937 short player_index = Lua_Player::Index(L, 1);
1938 if (player_index == local_player_index)
1939 {
1940 lua_pushboolean(L, GetTunnelVision());
1941 return 1;
1942 }
1943 else
1944 {
1945 return 0;
1946 }
1947 }
1948
1949 const luaL_Reg Lua_Player_Get[] = {
1950 {"accelerate", L_TableFunction<Lua_Player_Accelerate>},
1951 {"action_flags", Lua_Player_Get_Action_Flags},
1952 {"activate_terminal", L_TableFunction<Lua_Player_Activate_Terminal>},
1953 {"color", Lua_Player_Get_Color},
1954 {"compass", Lua_Player_Get_Compass},
1955 {"crosshairs", Lua_Player_Get_Crosshairs},
1956 {"damage", L_TableFunction<Lua_Player_Damage>},
1957 {"dead", Lua_Player_Get_Dead},
1958 {"deaths", Lua_Player_Get_Deaths},
1959 {"direction", Lua_Player_Get_Direction},
1960 {"head_direction", Lua_Player_Get_Head_Direction},
1961 {"disconnected", Lua_Player_Get_Netdead},
1962 {"energy", Lua_Player_Get_Energy},
1963 {"elevation", Lua_Player_Get_Elevation},
1964 {"external_velocity", Lua_Player_Get_External_Velocity},
1965 {"extravision_duration", Lua_Player_Get_Extravision_Duration},
1966 {"feet_below_media", Lua_Player_Get_Flag<_FEET_BELOW_MEDIA_BIT>},
1967 {"fade_screen", L_TableFunction<Lua_Player_Fade_Screen>},
1968 {"find_action_key_target", L_TableFunction<Lua_Player_Find_Action_Key_Target>},
1969 {"find_target", L_TableFunction<Lua_Player_Find_Target>},
1970 {"head_below_media", Lua_Player_Get_Flag<_HEAD_BELOW_MEDIA_BIT>},
1971 {"infravision_duration", Lua_Player_Get_Infravision_Duration},
1972 {"internal_velocity", Lua_Player_Get_Internal_Velocity},
1973 {"invincibility_duration", Lua_Player_Get_Invincibility_Duration},
1974 {"invisibility_duration", Lua_Player_Get_Invisibility_Duration},
1975 {"items", Lua_Player_Get_Items},
1976 {"local_", Lua_Player_Get_Local},
1977 {"juice", Lua_Player_Get_Energy},
1978 {"kills", Lua_Player_Get_Kills},
1979 {"life", Lua_Player_Get_Energy},
1980 {"monster", Lua_Player_Get_Monster},
1981 {"motion_sensor_active", Lua_Player_Get_Motion_Sensor},
1982 {"name", Lua_Player_Get_Name},
1983 {"overlays", Lua_Player_Get_Overlays},
1984 {"oxygen", Lua_Player_Get_Oxygen},
1985 {"pitch", Lua_Player_Get_Elevation},
1986 {"print", L_TableFunction<Lua_Player_Print>},
1987 {"play_sound", L_TableFunction<Lua_Player_Play_Sound>},
1988 {"points", Lua_Player_Get_Points},
1989 {"polygon", Lua_Player_Get_Polygon},
1990 {"position", L_TableFunction<Lua_Player_Position>},
1991 {"team", Lua_Player_Get_Team},
1992 {"teleport", L_TableFunction<Lua_Player_Teleport>},
1993 {"teleport_to_level", L_TableFunction<Lua_Player_Teleport_To_Level>},
1994 {"texture_palette", Lua_Player_Get_Texture_Palette},
1995 {"view_player", L_TableFunction<Lua_Player_View_Player>},
1996 {"viewed_player", Lua_Player_Get_Viewed_Player},
1997 {"weapons", Lua_Player_Get_Weapons},
1998 {"x", Lua_Player_Get_X},
1999 {"y", Lua_Player_Get_Y},
2000 {"yaw", Lua_Player_Get_Direction},
2001 {"z", Lua_Player_Get_Z},
2002 {"zoom_active", Lua_Player_Get_Zoom},
2003 {0, 0}
2004 };
2005
2006 extern void mark_shield_display_as_dirty();
2007
Lua_Player_Set_Color(lua_State * L)2008 static int Lua_Player_Set_Color(lua_State *L)
2009 {
2010 int color = Lua_PlayerColor::ToIndex(L, 2);
2011 get_player_data(Lua_Player::Index(L, 1))->color = color;
2012
2013 return 0;
2014 }
2015
Lua_Player_Set_Deaths(lua_State * L)2016 static int Lua_Player_Set_Deaths(lua_State *L)
2017 {
2018 if (!lua_isnumber(L, 2))
2019 return luaL_error(L, "deaths: incorrect argument type");
2020
2021 player_data *player = get_player_data(Lua_Player::Index(L, 1));
2022 int kills = static_cast<int>(lua_tonumber(L, 2));
2023 if (player->monster_damage_taken.kills != kills)
2024 {
2025 team_monster_damage_taken[player->team].kills += (kills - player->monster_damage_taken.kills);
2026 player->monster_damage_taken.kills = kills;
2027 mark_player_network_stats_as_dirty(current_player_index);
2028 }
2029
2030 return 0;
2031 }
2032
Lua_Player_Set_Direction(lua_State * L)2033 static int Lua_Player_Set_Direction(lua_State *L)
2034 {
2035 if (!lua_isnumber(L, 2))
2036 return luaL_error(L, "direction: incorrect argument type");
2037
2038 double facing = static_cast<double>(lua_tonumber(L, 2));
2039 int player_index = Lua_Player::Index(L, 1);
2040 player_data *player = get_player_data(player_index);
2041 player->variables.direction = INTEGER_TO_FIXED((int)(facing/AngleConvert));
2042 instantiate_physics_variables(get_physics_constants_for_model(static_world->physics_model, 0), &player->variables, player_index, false, false);
2043
2044 // Lua control locks virtual aim to physical aim
2045 if (player_index == local_player_index)
2046 resync_virtual_aim();
2047
2048 return 0;
2049 }
2050
Lua_Player_Set_Head_Direction(lua_State * L)2051 static int Lua_Player_Set_Head_Direction(lua_State *L)
2052 {
2053 if (!lua_isnumber(L, 2))
2054 return luaL_error(L, "head_direction: incorrect argument type");
2055
2056 double facing = static_cast<double>(lua_tonumber(L, 2));
2057 int player_index = Lua_Player::Index(L, 1);
2058 player_data *player = get_player_data(player_index);
2059 player->variables.head_direction = INTEGER_TO_FIXED((int)(facing/AngleConvert)) - player->variables.direction;
2060 while (player->variables.head_direction >= INTEGER_TO_FIXED(HALF_CIRCLE)) {
2061 player->variables.head_direction -= INTEGER_TO_FIXED(FULL_CIRCLE);
2062 }
2063 while (player->variables.head_direction < -1*INTEGER_TO_FIXED(HALF_CIRCLE)) {
2064 player->variables.head_direction += INTEGER_TO_FIXED(FULL_CIRCLE);
2065 }
2066 instantiate_physics_variables(get_physics_constants_for_model(static_world->physics_model, 0), &player->variables, player_index, false, false);
2067
2068 return 0;
2069 }
2070
Lua_Player_Set_Elevation(lua_State * L)2071 static int Lua_Player_Set_Elevation(lua_State *L)
2072 {
2073 if (!lua_isnumber(L, 2))
2074 return luaL_error(L, "elevation: incorrect argument type");
2075
2076 double elevation = static_cast<double>(lua_tonumber(L, 2));
2077 if (elevation > 180) elevation -= 360.0;
2078 int player_index = Lua_Player::Index(L, 1);
2079 player_data *player = get_player_data(player_index);
2080 player->variables.elevation = INTEGER_TO_FIXED((int)(elevation/AngleConvert));
2081 instantiate_physics_variables(get_physics_constants_for_model(static_world->physics_model, 0), &player->variables, player_index, false, false);
2082
2083 // Lua control locks virtual aim to physical aim
2084 if (player_index == local_player_index)
2085 resync_virtual_aim();
2086
2087 return 0;
2088 }
2089
Lua_Player_Set_Infravision_Duration(lua_State * L)2090 static int Lua_Player_Set_Infravision_Duration(lua_State *L)
2091 {
2092 if (!lua_isnumber(L, 2))
2093 return luaL_error(L, "extravision: incorrect argument type");
2094
2095 player_data *player = get_player_data(Lua_Player::Index(L, 1));
2096 player->infravision_duration = static_cast<int>(lua_tonumber(L, 2));
2097 return 0;
2098 }
2099
Lua_Player_Set_Invincibility_Duration(lua_State * L)2100 static int Lua_Player_Set_Invincibility_Duration(lua_State *L)
2101 {
2102 if (!lua_isnumber(L, 2))
2103 return luaL_error(L, "extravision: incorrect argument type");
2104
2105 player_data *player = get_player_data(Lua_Player::Index(L, 1));
2106 player->invincibility_duration = static_cast<int>(lua_tonumber(L, 2));
2107 return 0;
2108 }
2109
Lua_Player_Set_Invisibility_Duration(lua_State * L)2110 static int Lua_Player_Set_Invisibility_Duration(lua_State *L)
2111 {
2112 if (!lua_isnumber(L, 2))
2113 return luaL_error(L, "extravision: incorrect argument type");
2114
2115 player_data *player = get_player_data(Lua_Player::Index(L, 1));
2116 player->invisibility_duration = static_cast<int>(lua_tonumber(L, 2));
2117 return 0;
2118 }
2119
Lua_Player_Set_Energy(lua_State * L)2120 static int Lua_Player_Set_Energy(lua_State *L)
2121 {
2122 if (!lua_isnumber(L, 2))
2123 return luaL_error(L, "energy: incorrect argument type");
2124
2125 int energy = static_cast<int>(lua_tonumber(L, 2));
2126 if (energy > 3 * PLAYER_MAXIMUM_SUIT_ENERGY)
2127 energy = 3 * PLAYER_MAXIMUM_SUIT_ENERGY;
2128
2129 get_player_data(Lua_Player::Index(L, 1))->suit_energy = energy;
2130 mark_shield_display_as_dirty();
2131
2132 return 0;
2133 }
2134
Lua_Player_Set_Extravision_Duration(lua_State * L)2135 static int Lua_Player_Set_Extravision_Duration(lua_State *L)
2136 {
2137 if (!lua_isnumber(L, 2))
2138 return luaL_error(L, "extravision: incorrect argument type");
2139
2140 int player_index = Lua_Player::Index(L, 1);
2141 player_data *player = get_player_data(player_index);
2142 short extravision_duration = static_cast<short>(lua_tonumber(L, 2));
2143 if ((player_index == local_player_index) && (extravision_duration == 0) != (player->extravision_duration == 0))
2144 {
2145 start_extravision_effect(extravision_duration);
2146 }
2147 player->extravision_duration = static_cast<int>(lua_tonumber(L, 2));
2148 return 0;
2149 }
2150
Lua_Player_Set_Motion_Sensor(lua_State * L)2151 static int Lua_Player_Set_Motion_Sensor(lua_State *L)
2152 {
2153 short player_index = Lua_Player::Index(L, 1);
2154 if (player_index == local_player_index)
2155 {
2156 if (!lua_isboolean(L, 2))
2157 return luaL_error(L, "motion_sensor: incorrect argument type");
2158 bool state = lua_toboolean(L, 2);
2159 if (MotionSensorActive != state)
2160 {
2161 MotionSensorActive = lua_toboolean(L, 2);
2162 draw_panels();
2163 }
2164 }
2165
2166 return 0;
2167 }
2168
Lua_Player_Set_Oxygen(lua_State * L)2169 static int Lua_Player_Set_Oxygen(lua_State *L)
2170 {
2171 if (!lua_isnumber(L, 2))
2172 return luaL_error(L, "oxygen: incorrect argument type");
2173
2174 int oxygen = static_cast<int>(lua_tonumber(L, 2));
2175 if (oxygen > PLAYER_MAXIMUM_SUIT_OXYGEN)
2176 oxygen = PLAYER_MAXIMUM_SUIT_OXYGEN;
2177
2178 get_player_data(Lua_Player::Index(L, 1))->suit_oxygen = oxygen;
2179 mark_shield_display_as_dirty();
2180
2181 return 0;
2182 }
2183
Lua_Player_Set_Points(lua_State * L)2184 static int Lua_Player_Set_Points(lua_State *L)
2185 {
2186 if (!lua_isnumber(L, 2))
2187 return luaL_error(L, "points: incorrect argument type");
2188
2189 int points = static_cast<int>(lua_tonumber(L, 2));
2190
2191 player_data *player = get_player_data(Lua_Player::Index(L, 1));
2192 if (player->netgame_parameters[0] != points)
2193 {
2194 #if !defined(DISABLE_NETWORKING)
2195 team_netgame_parameters[player->team][0] += points - player->netgame_parameters[0];
2196 #endif
2197 player->netgame_parameters[0] = points;
2198 mark_player_network_stats_as_dirty(current_player_index);
2199 }
2200
2201 return 0;
2202 }
2203
Lua_Player_Set_Team(lua_State * L)2204 static int Lua_Player_Set_Team(lua_State *L)
2205 {
2206 int team = Lua_PlayerColor::ToIndex(L, 2);
2207 get_player_data(Lua_Player::Index(L, 1))->team = team;
2208
2209 return 0;
2210 }
2211
Lua_Player_Set_Zoom(lua_State * L)2212 static int Lua_Player_Set_Zoom(lua_State *L)
2213 {
2214 short player_index = Lua_Player::Index(L, 1);
2215 if (player_index == local_player_index)
2216 {
2217 if (!lua_isboolean(L, 2))
2218 return luaL_error(L, "zoom_active: incorrect argument type");
2219
2220 SetTunnelVision(lua_toboolean(L, 2));
2221 }
2222
2223 return 0;
2224 }
2225
2226 const luaL_Reg Lua_Player_Set[] = {
2227 {"color", Lua_Player_Set_Color},
2228 {"deaths", Lua_Player_Set_Deaths},
2229 {"direction", Lua_Player_Set_Direction},
2230 {"head_direction", Lua_Player_Set_Head_Direction},
2231 {"elevation", Lua_Player_Set_Elevation},
2232 {"energy", Lua_Player_Set_Energy},
2233 {"extravision_duration", Lua_Player_Set_Extravision_Duration},
2234 {"infravision_duration", Lua_Player_Set_Infravision_Duration},
2235 {"invincibility_duration", Lua_Player_Set_Invincibility_Duration},
2236 {"invisibility_duration", Lua_Player_Set_Invisibility_Duration},
2237 {"juice", Lua_Player_Set_Energy},
2238 {"life", Lua_Player_Set_Energy},
2239 {"motion_sensor_active", Lua_Player_Set_Motion_Sensor},
2240 {"oxygen", Lua_Player_Set_Oxygen},
2241 {"pitch", Lua_Player_Set_Elevation},
2242 {"points", Lua_Player_Set_Points},
2243 {"team", Lua_Player_Set_Team},
2244 {"yaw", Lua_Player_Set_Direction},
2245 {"zoom_active", Lua_Player_Set_Zoom},
2246 {0, 0}
2247 };
2248
Lua_Player_Valid(int16 index)2249 bool Lua_Player_Valid(int16 index)
2250 {
2251 return index >= 0 && index < dynamic_world->player_count;
2252 }
2253
2254 char Lua_Players_Name[] = "Players";
2255
Lua_Players_Print(lua_State * L)2256 int Lua_Players_Print(lua_State *L)
2257 {
2258 if (mute_lua) return 0;
2259
2260 if (lua_gettop(L) != 1)
2261 return luaL_error(L, "print: incorrect argument type");
2262
2263 lua_getglobal(L, "tostring");
2264 lua_insert(L, -2);
2265 lua_pcall(L, 1, 1, 0);
2266 if (lua_tostring(L, -1))
2267 {
2268 screen_printf("%s", lua_tostring(L, -1));
2269 }
2270 lua_pop(L, 1);
2271
2272 return 0;
2273 }
2274
Lua_Players_Get_Local_Player(lua_State * L)2275 int Lua_Players_Get_Local_Player(lua_State *L)
2276 {
2277 Lua_Player::Push(L, local_player_index);
2278 return 1;
2279 }
2280
2281 const luaL_Reg Lua_Players_Get[] = {
2282 {"local_player", Lua_Players_Get_Local_Player},
2283 {"print", L_TableFunction<Lua_Players_Print>},
2284 {0, 0}
2285 };
2286
Lua_Players_Length()2287 int16 Lua_Players_Length() {
2288 return dynamic_world->player_count;
2289 }
2290
2291 char Lua_DifficultyType_Name[] = "difficulty_type";
2292 typedef L_Enum<Lua_DifficultyType_Name> Lua_DifficultyType;
2293
2294 char Lua_DifficultyTypes_Name[] = "DifficultyTypes";
2295 typedef L_EnumContainer<Lua_DifficultyTypes_Name, Lua_DifficultyType> Lua_DifficultyTypes;
2296
2297 char Lua_GameType_Name[] = "game_type";
2298 typedef L_Enum<Lua_GameType_Name> Lua_GameType;
2299
2300 char Lua_GameTypes_Name[] = "GameTypes";
2301 typedef L_EnumContainer<Lua_GameTypes_Name, Lua_GameType> Lua_GameTypes;
2302
2303 char Lua_Game_Name[] = "Game";
2304 typedef L_Class<Lua_Game_Name> Lua_Game;
2305
2306 char Lua_ScoringMode_Name[] = "scoring_mode";
2307 typedef L_Enum<Lua_ScoringMode_Name> Lua_ScoringMode;
2308
2309 char Lua_ScoringModes_Name[] = "ScoringModes";
2310 typedef L_Container<Lua_ScoringModes_Name, Lua_ScoringMode> Lua_ScoringModes;
2311
Lua_Game_Get_Dead_Players_Drop_Items(lua_State * L)2312 static int Lua_Game_Get_Dead_Players_Drop_Items(lua_State *L)
2313 {
2314 lua_pushboolean(L, !(GET_GAME_OPTIONS() & _burn_items_on_death));
2315 return 1;
2316 }
2317
Lua_Game_Get_Difficulty(lua_State * L)2318 static int Lua_Game_Get_Difficulty(lua_State *L)
2319 {
2320 Lua_DifficultyType::Push(L, dynamic_world->game_information.difficulty_level);
2321 return 1;
2322 }
2323
Lua_Game_Get_Kill_Limit(lua_State * L)2324 static int Lua_Game_Get_Kill_Limit(lua_State *L)
2325 {
2326 lua_pushnumber(L, dynamic_world->game_information.kill_limit);
2327 return 1;
2328 }
2329
Lua_Game_Get_Monsters_Replenish(lua_State * L)2330 static int Lua_Game_Get_Monsters_Replenish(lua_State* L)
2331 {
2332 lua_pushboolean(L, dynamic_world->game_information.game_options & _monsters_replenish);
2333 return 1;
2334 }
2335
Lua_Game_Get_Proper_Item_Accounting(lua_State * L)2336 static int Lua_Game_Get_Proper_Item_Accounting(lua_State* L)
2337 {
2338 lua_pushboolean(L, L_Get_Proper_Item_Accounting(L));
2339 return 1;
2340 }
2341
Lua_Game_Get_Nonlocal_Overlays(lua_State * L)2342 static int Lua_Game_Get_Nonlocal_Overlays(lua_State* L)
2343 {
2344 lua_pushboolean(L, L_Get_Nonlocal_Overlays(L));
2345 return 1;
2346 }
2347
Lua_Game_Get_Time_Remaining(lua_State * L)2348 static int Lua_Game_Get_Time_Remaining(lua_State* L)
2349 {
2350 if(dynamic_world->game_information.game_time_remaining > 999 * 30)
2351 lua_pushnil(L);
2352 else
2353 lua_pushnumber(L, dynamic_world->game_information.game_time_remaining);
2354 return 1;
2355 }
2356
Lua_Game_Get_Ticks(lua_State * L)2357 static int Lua_Game_Get_Ticks(lua_State *L)
2358 {
2359 lua_pushnumber(L, dynamic_world->tick_count);
2360 return 1;
2361 }
2362
Lua_Game_Get_Type(lua_State * L)2363 static int Lua_Game_Get_Type(lua_State *L)
2364 {
2365 Lua_GameType::Push(L, GET_GAME_TYPE());
2366 return 1;
2367 }
2368
2369 extern int game_end_condition;
2370 extern int game_scoring_mode;
2371
Lua_Game_Get_Scoring_Mode(lua_State * L)2372 static int Lua_Game_Get_Scoring_Mode(lua_State *L)
2373 {
2374 Lua_ScoringMode::Push(L, game_scoring_mode);
2375 return 1;
2376 }
2377
Lua_Game_Get_Version(lua_State * L)2378 static int Lua_Game_Get_Version(lua_State *L)
2379 {
2380 lua_pushstring(L, A1_DATE_VERSION);
2381 return 1;
2382 }
2383
Lua_Game_Set_View_Player(lua_State * L)2384 static int Lua_Game_Set_View_Player(lua_State *L)
2385 {
2386
2387 int view_player_index;
2388 if (lua_isnumber(L, 2))
2389 {
2390 view_player_index = static_cast<int>(lua_tonumber(L, 2));
2391 if (view_player_index < 0 || view_player_index >= dynamic_world->player_count)
2392 return luaL_error(L, "view_player: invalid player index");
2393 }
2394 else if (Lua_Player::Is(L, 2))
2395 view_player_index = Lua_Player::Index(L, 2);
2396 else
2397 return luaL_error(L, "view_player: incorrect argument type");
2398
2399 if (view_player_index != current_player_index)
2400 {
2401 set_current_player_index(view_player_index);
2402 update_interface(NONE);
2403 dirty_terminal_view(local_player_index);
2404 }
2405
2406 return 0;
2407
2408 }
2409
Lua_Game_Set_Proper_Item_Accounting(lua_State * L)2410 static int Lua_Game_Set_Proper_Item_Accounting(lua_State* L)
2411 {
2412 if (!lua_isboolean(L, 2))
2413 luaL_error(L, "proper_item_accounting: incorrect argument type");
2414 L_Set_Proper_Item_Accounting(L, lua_toboolean(L, 2));
2415 return 0;
2416 }
2417
Lua_Game_Set_Nonlocal_Overlays(lua_State * L)2418 static int Lua_Game_Set_Nonlocal_Overlays(lua_State* L)
2419 {
2420 if (!lua_isboolean(L, 2))
2421 luaL_error(L, "nonlocal_overlays: incorrect argument type");
2422 L_Set_Nonlocal_Overlays(L, lua_toboolean(L, 2));
2423 return 0;
2424 }
2425
Lua_Game_Set_Scoring_Mode(lua_State * L)2426 static int Lua_Game_Set_Scoring_Mode(lua_State *L)
2427 {
2428 int mode = Lua_ScoringMode::ToIndex(L, 2);
2429 game_scoring_mode = mode;
2430 // TODO: set network stats to dirty
2431 return 0;
2432 }
2433
Lua_Game_Set_Dead_Players_Drop_Items(lua_State * L)2434 static int Lua_Game_Set_Dead_Players_Drop_Items(lua_State* L)
2435 {
2436 if (!lua_isboolean(L, 2))
2437 luaL_error(L, "dead_players_drop_items: incorrect argument type");
2438
2439 bool dpdi = lua_toboolean(L, 2);
2440 if (dpdi)
2441 {
2442 GET_GAME_OPTIONS() &= ~_burn_items_on_death;
2443 }
2444 else
2445 {
2446 GET_GAME_OPTIONS() |= _burn_items_on_death;
2447 }
2448
2449 return 0;
2450 }
2451
Lua_Game_Set_Monsters_Replenish(lua_State * L)2452 static int Lua_Game_Set_Monsters_Replenish(lua_State* L)
2453 {
2454 if (!lua_isboolean(L, 2))
2455 luaL_error(L, "monsters_replenish: incorrect argument type");
2456
2457 bool replenish = lua_toboolean(L, 2);
2458 if (replenish)
2459 {
2460 dynamic_world->game_information.game_options |= _monsters_replenish;
2461 }
2462 else
2463 {
2464 dynamic_world->game_information.game_options &= ~_monsters_replenish;
2465 }
2466 return 0;
2467 }
2468
Lua_Game_Set_Over(lua_State * L)2469 static int Lua_Game_Set_Over(lua_State *L)
2470 {
2471 if(lua_isnil(L, 2)) game_end_condition = _game_normal_end_condition;
2472 else game_end_condition = lua_toboolean(L, 2) ? _game_end_now_condition : _game_no_end_condition;
2473 return 0;
2474 }
2475
2476 extern GM_Random lua_random_generator;
2477
Lua_Game_Better_Random(lua_State * L)2478 int Lua_Game_Better_Random(lua_State *L)
2479 {
2480 if (lua_isnumber(L, 1))
2481 {
2482 lua_pushnumber(L, lua_random_generator.KISS() % static_cast<uint32>(lua_tonumber(L, 1)));
2483 }
2484 else
2485 {
2486 lua_pushnumber(L, lua_random_generator.KISS());
2487 }
2488 return 1;
2489 }
2490
Lua_Game_Deserialize(lua_State * L)2491 int Lua_Game_Deserialize(lua_State* L)
2492 {
2493 if (!lua_isstring(L, 1))
2494 {
2495 lua_pushstring(L, "Game.deserialize: incorrect argument type");
2496 lua_error(L);
2497 }
2498
2499 size_t len;
2500 auto s = lua_tolstring(L, 1, &len);
2501
2502 io::stream_buffer<io::array_source> sb(s, len);
2503
2504 if (lua_restore(L, &sb))
2505 {
2506 return 1;
2507 }
2508 else
2509 {
2510 return 0;
2511 }
2512 }
2513
Lua_Game_Global_Random(lua_State * L)2514 int Lua_Game_Global_Random(lua_State *L)
2515 {
2516 if (lua_isnumber(L, 1))
2517 {
2518 lua_pushnumber(L, ::global_random() % static_cast<uint16>(lua_tonumber(L, 1)));
2519 }
2520 else
2521 {
2522 lua_pushnumber(L, ::global_random());
2523 }
2524 return 1;
2525 }
2526
Lua_Game_Local_Random(lua_State * L)2527 int Lua_Game_Local_Random(lua_State *L)
2528 {
2529 if (lua_isnumber(L, 1))
2530 {
2531 lua_pushnumber(L, ::local_random() % static_cast<uint16>(lua_tonumber(L, 1)));
2532 }
2533 else
2534 {
2535 lua_pushnumber(L, ::local_random());
2536 }
2537 return 1;
2538 }
2539
Lua_Game_Save(lua_State * L)2540 int Lua_Game_Save(lua_State *L)
2541 {
2542 if (!game_is_networked)
2543 save_game();
2544
2545 return 0;
2546 }
2547
Lua_Game_Serialize(lua_State * L)2548 int Lua_Game_Serialize(lua_State* L)
2549 {
2550 std::stringbuf sb;
2551 if (lua_save(L, &sb))
2552 {
2553 lua_pushlstring(L, sb.str().data(), sb.str().size());
2554 return 1;
2555 }
2556 else
2557 {
2558 return 0;
2559 }
2560 }
2561
2562 extern int L_Restore_Passed(lua_State *);
2563 extern int L_Restore_Saved(lua_State *);
2564
2565 const luaL_Reg Lua_Game_Get[] = {
2566 {"dead_players_drop_items", Lua_Game_Get_Dead_Players_Drop_Items},
2567 {"deserialize", L_TableFunction<Lua_Game_Deserialize>},
2568 {"difficulty", Lua_Game_Get_Difficulty},
2569 {"global_random", L_TableFunction<Lua_Game_Global_Random>},
2570 {"kill_limit", Lua_Game_Get_Kill_Limit},
2571 {"time_remaining", Lua_Game_Get_Time_Remaining},
2572 {"local_random", L_TableFunction<Lua_Game_Local_Random>},
2573 {"monsters_replenish", Lua_Game_Get_Monsters_Replenish},
2574 {"proper_item_accounting", Lua_Game_Get_Proper_Item_Accounting},
2575 {"nonlocal_overlays", Lua_Game_Get_Nonlocal_Overlays},
2576 {"random", L_TableFunction<Lua_Game_Better_Random>},
2577 {"restore_passed", L_TableFunction<L_Restore_Passed>},
2578 {"restore_saved", L_TableFunction<L_Restore_Saved>},
2579 {"ticks", Lua_Game_Get_Ticks},
2580 {"type", Lua_Game_Get_Type},
2581 {"save", L_TableFunction<Lua_Game_Save>},
2582 {"serialize", L_TableFunction<Lua_Game_Serialize>},
2583 {"scoring_mode", Lua_Game_Get_Scoring_Mode},
2584 {"version", Lua_Game_Get_Version},
2585 {0, 0}
2586 };
2587
2588 const luaL_Reg Lua_Game_Set[] = {
2589 {"dead_players_drop_items", Lua_Game_Set_Dead_Players_Drop_Items},
2590 {"monsters_replenish", Lua_Game_Set_Monsters_Replenish},
2591 {"proper_item_accounting", Lua_Game_Set_Proper_Item_Accounting},
2592 {"nonlocal_overlays", Lua_Game_Set_Nonlocal_Overlays},
2593 {"scoring_mode", Lua_Game_Set_Scoring_Mode},
2594 {"over", Lua_Game_Set_Over},
2595 {0, 0}
2596 };
2597
2598 char Lua_Music_Name[] = "Music";
2599 typedef L_Class<Lua_Music_Name> Lua_Music;
2600
Lua_Music_Clear(lua_State * L)2601 int Lua_Music_Clear(lua_State *L)
2602 {
2603 Music::instance()->ClearLevelMusic();
2604 return 0;
2605 }
2606
Lua_Music_Fade(lua_State * L)2607 int Lua_Music_Fade(lua_State *L)
2608 {
2609 int duration;
2610 if (!lua_isnumber(L, 1))
2611 duration = 1000;
2612 else
2613 duration = static_cast<int>(lua_tonumber(L, 1) * 1000);
2614 Music::instance()->FadeOut(duration);
2615 Music::instance()->ClearLevelMusic();
2616 return 0;
2617 }
2618
Lua_Music_Play(lua_State * L)2619 int Lua_Music_Play(lua_State *L)
2620 {
2621 bool restart_music;
2622 restart_music = !Music::instance()->IsLevelMusicActive() && !Music::instance()->Playing();
2623 for (int n = 1; n <= lua_gettop(L); n++)
2624 {
2625 if (!lua_isstring(L, n))
2626 return luaL_error(L, "play: invalid file specifier");
2627
2628 std::string search_path = L_Get_Search_Path(L);
2629
2630 FileSpecifier file;
2631 if (search_path.size())
2632 {
2633 if (!file.SetNameWithPath(lua_tostring(L, n), search_path))
2634 Music::instance()->PushBackLevelMusic(file);
2635 }
2636 else
2637 {
2638 if (file.SetNameWithPath(lua_tostring(L, n)))
2639 Music::instance()->PushBackLevelMusic(file);
2640 }
2641 }
2642
2643 if (restart_music)
2644 Music::instance()->PreloadLevelMusic();
2645 return 0;
2646 }
2647
Lua_Music_Stop(lua_State * L)2648 int Lua_Music_Stop(lua_State *L)
2649 {
2650 Music::instance()->ClearLevelMusic();
2651 Music::instance()->StopLevelMusic();
2652
2653 return 0;
2654 }
2655
Lua_Music_Valid(lua_State * L)2656 int Lua_Music_Valid(lua_State* L) {
2657 int top = lua_gettop(L);
2658 for(int n = 1; n <= top; n++) {
2659 if(!lua_isstring(L, n))
2660 return luaL_error(L, "valid: invalid file specifier");
2661 FileSpecifier path;
2662 if(path.SetNameWithPath(lua_tostring(L, n))) {
2663 StreamDecoder* stream = StreamDecoder::Get(path);
2664 if(stream) {
2665 lua_pushboolean(L, true);
2666 delete stream;
2667 } else lua_pushboolean(L, false);
2668 } else lua_pushboolean(L, false);
2669 }
2670 return top;
2671 }
2672
2673 const luaL_Reg Lua_Music_Get[] = {
2674 {"clear", L_TableFunction<Lua_Music_Clear>},
2675 {"fade", L_TableFunction<Lua_Music_Fade>},
2676 {"play", L_TableFunction<Lua_Music_Play>},
2677 {"stop", L_TableFunction<Lua_Music_Stop>},
2678 {"valid", L_TableFunction<Lua_Music_Valid>},
2679 {0, 0}
2680 };
2681
2682 static void Lua_Player_load_compatibility(lua_State *L);
2683
Lua_Player_register(lua_State * L)2684 int Lua_Player_register (lua_State *L)
2685 {
2686 Lua_Action_Flags::Register(L, Lua_Action_Flags_Get, Lua_Action_Flags_Set);
2687
2688 Lua_Camera_Path_Angles::Register(L, Lua_Camera_Path_Angles_Get);
2689 Lua_Camera_Path_Points::Register(L, Lua_Camera_Path_Points_Get);
2690 Lua_Camera::Register(L, Lua_Camera_Get);
2691 Lua_Camera::Valid = Lua_Camera_Valid;
2692
2693 Lua_Cameras::Register(L, Lua_Cameras_Methods);
2694 Lua_Cameras::Length = Lua_Cameras_Length;
2695
2696 Lua_Crosshairs::Register(L, Lua_Crosshairs_Get, Lua_Crosshairs_Set);
2697 Lua_Player_Compass::Register(L, Lua_Player_Compass_Get, Lua_Player_Compass_Set);
2698 Lua_Player_Items::Register(L, 0, 0, Lua_Player_Items_Metatable);
2699 Lua_Player_Kills::Register(L, 0, 0, Lua_Player_Kills_Metatable);
2700
2701 Lua_InternalVelocity::Register(L, Lua_InternalVelocity_Get);
2702 Lua_ExternalVelocity::Register(L, Lua_ExternalVelocity_Get, Lua_ExternalVelocity_Set);
2703 Lua_FadeType::Register(L, 0, 0, 0, Lua_FadeType_Mnemonics);
2704 Lua_FadeType::Valid = Lua_FadeType::ValidRange(NUMBER_OF_FADE_TYPES);
2705
2706 Lua_FadeTypes::Register(L);
2707 Lua_FadeTypes::Length = Lua_FadeTypes::ConstantLength((int16) NUMBER_OF_FADE_TYPES);
2708
2709 Lua_Texture_Palette_Slot::Register(L, Lua_Texture_Palette_Slot_Get, Lua_Texture_Palette_Slot_Set);
2710 Lua_Texture_Palette_Slots::Register(L, 0, 0, Lua_Texture_Palette_Slots_Metatable);
2711 Lua_Texture_Palette::Register(L, Lua_Texture_Palette_Get, Lua_Texture_Palette_Set);
2712
2713 Lua_WeaponType::Register(L, 0, 0, 0, Lua_WeaponType_Mnemonics);
2714 Lua_WeaponType::Valid = Lua_WeaponType::ValidRange(MAXIMUM_NUMBER_OF_WEAPONS);
2715
2716 Lua_WeaponTypes::Register(L);
2717 Lua_WeaponTypes::Length = Lua_WeaponTypes::ConstantLength((int16) MAXIMUM_NUMBER_OF_WEAPONS);
2718
2719 Lua_Player_Weapon::Register(L, Lua_Player_Weapon_Get);
2720 Lua_Player_Weapon::Valid = Lua_Player_Weapon::ValidRange(MAXIMUM_NUMBER_OF_WEAPONS);
2721
2722 Lua_Player_Weapons::Register(L, 0, 0, Lua_Player_Weapons_Metatable);
2723 Lua_Player_Weapons::Valid = Lua_Player_Valid;
2724
2725 Lua_Player_Weapon_Trigger::Register(L, Lua_Player_Weapon_Trigger_Get);
2726 Lua_Player_Weapon_Trigger::Valid = Lua_Player_Weapon_Trigger::ValidRange((int) _secondary_weapon + 1);
2727
2728 Lua_OverlayColor::Register(L, 0, 0, 0, Lua_OverlayColor_Mnemonics);
2729 Lua_OverlayColor::Valid = Lua_OverlayColor::ValidRange(8);
2730
2731 Lua_Overlays::Register(L, 0, 0, Lua_Overlays_Metatable);
2732 Lua_Overlays::Valid = Lua_Player_Valid;
2733
2734 Lua_Overlay::Register(L, Lua_Overlay_Get, Lua_Overlay_Set);
2735 Lua_Overlay::Valid = Lua_Overlay::ValidRange(MAXIMUM_NUMBER_OF_SCRIPT_HUD_ELEMENTS);
2736
2737 Lua_PlayerColor::Register(L, 0, 0, 0, Lua_PlayerColor_Mnemonics);
2738 Lua_PlayerColor::Valid = Lua_PlayerColor::ValidRange(NUMBER_OF_TEAM_COLORS);
2739
2740 Lua_PlayerColors::Register(L);
2741 Lua_PlayerColors::Length = Lua_PlayerColors::ConstantLength((int16) NUMBER_OF_TEAM_COLORS);
2742
2743 Lua_Player::Register(L, Lua_Player_Get, Lua_Player_Set);
2744 Lua_Player::Valid = Lua_Player_Valid;
2745
2746 Lua_Players::Register(L, Lua_Players_Get);
2747 Lua_Players::Length = Lua_Players_Length;
2748
2749 Lua_Game::Register(L, Lua_Game_Get, Lua_Game_Set);
2750
2751 Lua_GameType::Register(L, 0, 0, 0, Lua_GameType_Mnemonics);
2752 Lua_GameType::Valid = Lua_GameType::ValidRange(NUMBER_OF_GAME_TYPES);
2753
2754 Lua_GameTypes::Register(L);
2755 Lua_GameTypes::Length = Lua_GameTypes::ConstantLength(NUMBER_OF_GAME_TYPES);
2756
2757 Lua_ScoringMode::Register(L, 0, 0, 0, Lua_ScoringMode_Mnemonics);
2758 Lua_ScoringMode::Valid = Lua_ScoringMode::ValidRange(NUMBER_OF_GAME_SCORING_MODES);
2759
2760 Lua_ScoringModes::Register(L);
2761 Lua_ScoringModes::Length = Lua_ScoringModes::ConstantLength(NUMBER_OF_GAME_SCORING_MODES);
2762
2763 Lua_DifficultyType::Register(L, 0, 0, 0, Lua_DifficultyType_Mnemonics);
2764 Lua_DifficultyType::Valid = Lua_DifficultyType::ValidRange(NUMBER_OF_GAME_DIFFICULTY_LEVELS);
2765
2766 Lua_DifficultyTypes::Register(L);
2767 Lua_DifficultyTypes::Length = Lua_DifficultyTypes::ConstantLength(NUMBER_OF_GAME_DIFFICULTY_LEVELS);
2768
2769 Lua_TextureType::Register(L, 0, 0, 0, Lua_TextureType_Mnemonics);
2770 Lua_TextureType::Valid = Lua_TextureType::ValidRange(NUMBER_OF_LUA_TEXTURE_TYPES);
2771
2772 Lua_TextureTypes::Register(L);
2773 Lua_TextureTypes::Length = Lua_TextureTypes::ConstantLength(NUMBER_OF_LUA_TEXTURE_TYPES);
2774
2775 Lua_Music::Register(L, Lua_Music_Get);
2776
2777 // register one Game userdatum globally
2778 Lua_Game::Push(L, 0);
2779 lua_setglobal(L, Lua_Game_Name);
2780
2781 // register one Music userdatum
2782 Lua_Music::Push(L, 0);
2783 lua_setglobal(L, Lua_Music_Name);
2784
2785 Lua_Player_load_compatibility(L);
2786
2787 return 0;
2788 }
2789
2790 static const char *compatibility_script = ""
2791 "function accelerate_player(player, vertical_velocity, direction, velocity) Players[player]:accelerate(direction, velocity, vertical_velocity) end\n"
2792 "function activate_camera(player, camera) Cameras[camera]:activate(player) end\n"
2793 "function activate_terminal(player, text) Players[player]:activate_terminal(text) end\n"
2794 "function add_item(player, item_type) Players[player].items[item_type] = Players[player].items[item_type] + 1 end\n"
2795 "function add_path_angle(camera, yaw, pitch, time) Cameras[camera].path_angles:new(yaw, pitch, time) end\n"
2796 "function add_path_point(camera, polygon, x, y, z, time) Cameras[camera].path_points:new(x, y, z, polygon, time) end\n"
2797 "function award_kills(player, slain_player, amount) if player == -1 then Players[slain_player].deaths = Players[slain_player].deaths + amount else Players[player].kills[slain_player] = Players[player].kills[slain_player] + amount end end\n"
2798 "function add_to_player_external_velocity(player, x, y, z) Players[player].external_velocity.i = Players[player].external_velocity.i + x Players[player].external_velocity.j = Players[player].external_velocity.j + y Players[player].external_velocity.k = Players[player].external_velocity.k + z end\n"
2799 "function award_points(player, amount) Players[player].points = Players[player].points + amount end\n"
2800 "function better_random() return Game.random() end\n"
2801 "function clear_camera(camera) Cameras[camera]:clear() end\n"
2802 "function clear_music() Music.clear() end\n"
2803 "function count_item(player, item_type) return Players[player].items[item_type] end\n"
2804 "function create_camera() return Cameras.new().index end\n"
2805 "function crosshairs_active(player) return Players[player].crosshairs.active end\n"
2806 "function deactivate_camera(camera) Cameras[camera]:deactivate() end\n"
2807 "function destroy_ball(player) for i in ItemTypes() do if i.ball then Players[player].items[i] = 0 end end end\n"
2808 "function fade_music(duration) if duration then Music.fade(duration * 60 / 1000) else Music.fade(60 / 1000) end end\n"
2809 "function get_game_difficulty() return Game.difficulty.index end\n"
2810 "function get_game_type() return Game.type.index end\n"
2811 "function get_kills(player, slain_player) if player == -1 then return Players[slain_player].deaths else return Players[player].kills[slain_player] end end\n"
2812 "function get_kill_limit() return Game.kill_limit end\n"
2813 "function get_life(player) return Players[player].energy end\n"
2814 "function get_motion_sensor_state(player) return Players[player].motion_sensor_active end\n"
2815 "function get_oxygen(player) return Players[player].oxygen end\n"
2816 "function get_player_angle(player) return Players[player].yaw, Players[player].pitch end\n"
2817 "function get_player_color(player) return Players[player].color.index end\n"
2818 "function get_player_external_velocity(player) return Players[player].external_velocity.i * 1024, Players[player].external_velocity.j * 1024, Players[player].external_velocity.k * 1024 end\n"
2819 "function get_player_internal_velocity(player) return Players[player].internal_velocity.forward * 65536, Players[player].internal_velocity.perpendicular * 65536 end\n"
2820 "function get_player_name(player) return Players[player].name end\n"
2821 "function get_player_polygon(player) return Players[player].polygon.index end\n"
2822 "function get_player_position(player) return Players[player].x, Players[player].y, Players[player].z end\n"
2823 "function get_player_powerup_duration(player, powerup) if powerup == _powerup_invisibility then return Players[player].invisibility_duration elseif powerup == _powerup_invincibility then return Players[player].invincibility_duration elseif powerup == _powerup_infravision then return Players[player].infravision_duration elseif powerup == _powerup_extravision then return Players[player].extravision_duration end end\n"
2824 "function get_player_team(player) return Players[player].team.index end\n"
2825 "function get_player_weapon(player) if Players[player].weapons.current then return Players[player].weapons.current.index else return nil end end\n"
2826 "function get_points(player) return Players[player].points end\n"
2827 "function global_random() return Game.global_random() end\n"
2828 "function inflict_damage(player, amount, type) if (type) then Players[player]:damage(amount, type) else Players[player]:damage(amount) end end\n"
2829 "function local_player_index() for p in Players() do if p.local_ then return p.index end end end\n"
2830 "function local_random() return Game.local_random() end\n"
2831 "function number_of_players() return # Players end\n"
2832 "function play_music(...) Music.play(...) end\n"
2833 "function player_is_dead(player) return Players[player].dead end\n"
2834 "function player_media(player) if Players[player].head_below_media then return Players[player].polygon.media.index else return nil end end\n"
2835 "function player_to_monster_index(player) return Players[player].monster.index end\n"
2836 "function play_sound(player, sound, pitch) Players[player]:play_sound(sound, pitch) end\n"
2837 "function remove_item(player, item_type) if Players[player].items[item_type] > 0 then Players[player].items[item_type] = Players[player].items[item_type] - 1 end end\n"
2838 "function screen_fade(player, fade) if fade then Players[player]:fade_screen(fade) else for p in Players() do p:fade_screen(player) end end end\n"
2839 "function screen_print(player, message) if message then if Players[player] then Players[player]:print(message) end else Players.print(player) end end\n"
2840 "function select_weapon(player, weapon) Players[player].weapons[weapon]:select() end\n"
2841 "function set_crosshairs_state(player, state) Players[player].crosshairs.active = state end\n"
2842 "function set_kills(player, slain_player, amount) if player == -1 then Players[slain_player].deaths = amount else Players[player].kills[slain_player] = amount end end\n"
2843 "function set_life(player, shield) Players[player].energy = shield end\n"
2844 "function set_lua_compass_beacon(player, x, y) Players[player].compass.x = x Players[player].compass.y = y end\n"
2845 "function set_lua_compass_state(player, state) if state > 15 then Players[player].compass.beacon = true state = state % 16 else Players[player].compass.beacon = false end if state > 7 then Players[player].compass.se = true state = state - 8 else Players[player].compass.se = false end if state > 3 then Players[player].compass.sw = true state = state - 4 else Players[player].compass.sw = false end if state > 1 then Players[player].compass.ne = true state = state - 2 else Players[player].compass.ne = false end if state == 1 then Players[player].compass.nw = true else Players[player].compass.nw = false end end\n"
2846 "function set_motion_sensor_state(player, state) Players[player].motion_sensor_active = state end\n"
2847 "function set_overlay_color(overlay, color) for p in Players() do if p.local_ then p.overlays[overlay].color = color end end end\n"
2848 "function set_overlay_icon(overlay, icon) for p in Players() do if p.local_ then p.overlays[overlay].icon = icon end end end\n"
2849 "function set_overlay_icon_by_color(overlay, color) for p in Players() do if p.local_ then p.overlays[overlay]:fill_icon(color) end end end\n"
2850 "function set_overlay_text(overlay, text) for p in Players() do if p.local_ then p.overlays[overlay].text = text end end end\n"
2851 "function set_oxygen(player, oxygen) Players[player].oxygen = oxygen end\n"
2852 "function set_player_angle(player, yaw, pitch) Players[player].yaw = yaw Players[player].pitch = pitch + 360.0 end\n"
2853 "function set_player_color(player, color) Players[player].color = color end\n"
2854 "function set_player_external_velocity(player, x, y, z) Players[player].external_velocity.i = x / 1024 Players[player].external_velocity.j = y / 1024 Players[player].external_velocity.k = z / 1024 end\n"
2855 "function set_player_position(player, x, y, z, polygon) Players[player]:position(x, y, z, polygon) end\n"
2856 "function set_player_powerup_duration(player, powerup, duration) if powerup == _powerup_invisibility then Players[player].invisibility_duration = duration elseif powerup == _powerup_invincibility then Players[player].invincibility_duration = duration elseif powerup == _powerup_infravision then Players[player].infravision_duration = duration elseif powerup == _powerup_extravision then Players[player].extravision_duration = duration end end\n"
2857 "function set_player_team(player, team) Players[player].team = team end\n"
2858 "function set_points(player, amount) Players[player].points = amount end\n"
2859 "function stop_music() Music.stop() end\n"
2860 "function set_zoom_state(player, state) Players[player].zoom_active = state end\n"
2861 "function teleport_player(player, polygon) Players[player]:teleport(polygon) end\n"
2862 "function teleport_player_to_level(player, level) Players[player]:teleport_to_level(level) end\n"
2863 "function use_lua_compass(player, state) if state ~= nil then Players[player].compass.lua = state else for p in Players() do p.compass.lua = player end end end\n"
2864 "function zoom_active(player) return Players[player].zoom_active end\n"
2865 ;
2866
Lua_Player_load_compatibility(lua_State * L)2867 static void Lua_Player_load_compatibility(lua_State *L)
2868 {
2869 luaL_loadbuffer(L, compatibility_script, strlen(compatibility_script), "player_compatibility");
2870 lua_pcall(L, 0, 0, 0);
2871 }
2872
2873 #endif
2874