• R/O
  • SSH
  • HTTPS

marathon: コミット


コミットメタ情報

リビジョン513 (tree)
日時2012-01-12 21:02:04
作者logue

ログメッセージ

・公式版r4683とマージ。(ただし、r4680のFontHandler.cppは除外)
・Luaのtypoを修正。(r4678
・ファイルの確認ダイアログを日本語化。

変更サマリ

差分

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