1 /*
2 LUA_SAVED_OBJECTS.CPP
3 
4 	Copyright (C) 2010 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 saved map objects classes
21 */
22 
23 #include "lua_monsters.h"
24 #include "lua_objects.h"
25 #include "lua_player.h"
26 #include "lua_saved_objects.h"
27 #include "lua_templates.h"
28 
29 #include "lua_map.h"
30 
31 #include "SoundManagerEnums.h"
32 
33 const float AngleConvert = 360/float(FULL_CIRCLE);
34 
get_map_object(short index)35 map_object* get_map_object(short index) {
36 	return saved_objects + index;
37 }
38 
39 template<class T>
get_saved_object_facing(lua_State * L)40 static int get_saved_object_facing(lua_State* L)
41 {
42 	map_object* object = get_map_object(T::Index(L, 1));
43 	lua_pushnumber(L, (double) object->facing * AngleConvert);
44 	return 1;
45 }
46 
47 template<class T, int16 flag>
get_saved_object_flag(lua_State * L)48 static int get_saved_object_flag(lua_State* L)
49 {
50 	map_object* object = get_map_object(T::Index(L, 1));
51 	lua_pushboolean(L, object->flags & flag);
52 	return 1;
53 }
54 
55 template<class T>
get_saved_object_polygon(lua_State * L)56 static int get_saved_object_polygon(lua_State* L)
57 {
58 	map_object* object = get_map_object(T::Index(L, 1));
59 	Lua_Polygon::Push(L, object->polygon_index);
60 	return 1;
61 }
62 
63 template<class T>
get_saved_object_x(lua_State * L)64 static int get_saved_object_x(lua_State* L)
65 {
66 	map_object* object = get_map_object(T::Index(L, 1));
67 	lua_pushnumber(L, (double) object->location.x / WORLD_ONE);
68 	return 1;
69 }
70 
71 template<class T>
get_saved_object_y(lua_State * L)72 static int get_saved_object_y(lua_State* L)
73 {
74 	map_object* object = get_map_object(T::Index(L, 1));
75 	lua_pushnumber(L, (double) object->location.y / WORLD_ONE);
76 	return 1;
77 }
78 
79 template<class T>
get_saved_object_z(lua_State * L)80 static int get_saved_object_z(lua_State* L)
81 {
82 	map_object* object = get_map_object(T::Index(L, 1));
83 	lua_pushnumber(L, (double) object->location.z / WORLD_ONE);
84 	return 1;
85 }
86 
saved_objects_length()87 int saved_objects_length() {
88 	return dynamic_world->initial_objects_count;
89 }
90 
91 template<short T>
saved_object_valid(short index)92 bool saved_object_valid(short index)
93 {
94 	if (index < 0 || index >= dynamic_world->initial_objects_count)
95 		return false;
96 
97 	map_object* object = get_map_object(index);
98 	return object->type == T;
99 }
100 
101 char Lua_Goal_Name[] = "goal";
102 
Lua_Goal_Get_ID(lua_State * L)103 static int Lua_Goal_Get_ID(lua_State* L)
104 {
105 	map_object* object = get_map_object(Lua_Goal::Index(L, 1));
106 	lua_pushnumber(L, object->index);
107 	return 1;
108 }
109 
110 const luaL_Reg Lua_Goal_Get[] = {
111 	{"facing", get_saved_object_facing<Lua_Goal>},
112 	{"id", Lua_Goal_Get_ID},
113 	{"polygon", get_saved_object_polygon<Lua_Goal>},
114 	{"x", get_saved_object_x<Lua_Goal>},
115 	{"y", get_saved_object_y<Lua_Goal>},
116 	{"z", get_saved_object_z<Lua_Goal>},
117 	{0, 0}
118 };
119 
120 char Lua_Goals_Name[] = "Goals";
121 
122 char Lua_ItemStart_Name[] = "item_start";
123 
Lua_ItemStart_Get_Type(lua_State * L)124 static int Lua_ItemStart_Get_Type(lua_State* L)
125 {
126 	map_object* object = get_map_object(Lua_ItemStart::Index(L, 1));
127 	Lua_ItemType::Push(L, object->index);
128 	return 1;
129 }
130 
131 const luaL_Reg Lua_ItemStart_Get[] = {
132 	{"facing", get_saved_object_facing<Lua_ItemStart>},
133 	{"from_ceiling", get_saved_object_flag<Lua_ItemStart, _map_object_hanging_from_ceiling>},
134 	{"invisible", get_saved_object_flag<Lua_ItemStart, _map_object_is_invisible>},
135 	{"polygon", get_saved_object_polygon<Lua_ItemStart>},
136 	{"type", Lua_ItemStart_Get_Type},
137 	{"x", get_saved_object_x<Lua_ItemStart>},
138 	{"y", get_saved_object_y<Lua_ItemStart>},
139 	{"z", get_saved_object_z<Lua_ItemStart>},
140 	{0, 0}
141 };
142 
143 char Lua_ItemStarts_Name[] = "ItemStarts";
144 
145 char Lua_MonsterStart_Name[] = "monster_start";
146 
Lua_MonsterStart_Get_Type(lua_State * L)147 static int Lua_MonsterStart_Get_Type(lua_State* L)
148 {
149 	map_object* object = get_map_object(Lua_MonsterStart::Index(L, 1));
150 	Lua_MonsterType::Push(L, object->index);
151 	return 1;
152 }
153 
154 const luaL_Reg Lua_MonsterStart_Get[] = {
155 	{"blind", get_saved_object_flag<Lua_MonsterStart, _map_object_is_blind>},
156 	{"deaf", get_saved_object_flag<Lua_MonsterStart, _map_object_is_deaf>},
157 	{"facing", get_saved_object_facing<Lua_MonsterStart>},
158 	{"from_ceiling", get_saved_object_flag<Lua_MonsterStart, _map_object_hanging_from_ceiling>},
159 	{"invisible", get_saved_object_flag<Lua_MonsterStart, _map_object_is_invisible>},
160 	{"polygon", get_saved_object_polygon<Lua_MonsterStart>},
161 	{"type", Lua_MonsterStart_Get_Type},
162 	{"x", get_saved_object_x<Lua_MonsterStart>},
163 	{"y", get_saved_object_y<Lua_MonsterStart>},
164 	{"z", get_saved_object_z<Lua_MonsterStart>},
165 	{0, 0}
166 };
167 
168 char Lua_MonsterStarts_Name[] = "MonsterStarts";
169 
170 char Lua_PlayerStart_Name[] = "player_start";
171 
Lua_PlayerStart_Get_Team(lua_State * L)172 static int Lua_PlayerStart_Get_Team(lua_State* L)
173 {
174 	map_object* object = get_map_object(Lua_PlayerStart::Index(L, 1));
175 	Lua_PlayerColor::Push(L, object->index);
176 	return 1;
177 }
178 
179 const luaL_Reg Lua_PlayerStart_Get[] = {
180 	{"facing", get_saved_object_facing<Lua_PlayerStart>},
181 	{"from_ceiling", get_saved_object_flag<Lua_PlayerStart, _map_object_hanging_from_ceiling>},
182 	{"polygon", get_saved_object_polygon<Lua_PlayerStart>},
183 	{"team", Lua_PlayerStart_Get_Team},
184 	{"x", get_saved_object_x<Lua_PlayerStart>},
185 	{"y", get_saved_object_y<Lua_PlayerStart>},
186 	{"z", get_saved_object_z<Lua_PlayerStart>},
187 	{0, 0}
188 };
189 
190 char Lua_PlayerStarts_Name[] = "PlayerStarts";
191 
192 char Lua_SoundObject_Name[] = "sound_object";
193 
Lua_SoundObject_Get_Light(lua_State * L)194 static int Lua_SoundObject_Get_Light(lua_State* L)
195 {
196 	map_object* object = get_map_object(Lua_SoundObject::Index(L, 1));
197 	if (object->facing < 0)
198 	{
199 		Lua_Light::Push(L, -object->facing);
200 	}
201 	else
202 	{
203 		lua_pushnil(L);
204 	}
205 
206 	return 1;
207 }
208 
Lua_SoundObject_Get_Type(lua_State * L)209 static int Lua_SoundObject_Get_Type(lua_State* L)
210 {
211 	map_object* object = get_map_object(Lua_SoundObject::Index(L, 1));
212 	Lua_AmbientSound::Push(L, object->index);
213 	return 1;
214 }
215 
Lua_SoundObject_Get_Volume(lua_State * L)216 static int Lua_SoundObject_Get_Volume(lua_State* L)
217 {
218 	map_object* object = get_map_object(Lua_SoundObject::Index(L, 1));
219 	if (object->facing >= 0)
220 	{
221 		lua_pushnumber(L, (double) object->facing / MAXIMUM_SOUND_VOLUME);
222 	}
223 	else
224 	{
225 		lua_pushnil(L);
226 	}
227 
228 	return 1;
229 }
230 
231 const luaL_Reg Lua_SoundObject_Get[] = {
232 	{"from_ceiling", get_saved_object_flag<Lua_SoundObject, _map_object_hanging_from_ceiling>},
233 	{"light", Lua_SoundObject_Get_Light},
234 	{"on_platform", get_saved_object_flag<Lua_SoundObject, _map_object_is_platform_sound>},
235 	{"polygon", get_saved_object_polygon<Lua_SoundObject>},
236 	{"type", Lua_SoundObject_Get_Type},
237 	{"volume", Lua_SoundObject_Get_Volume},
238 	{"x", get_saved_object_x<Lua_SoundObject>},
239 	{"y", get_saved_object_y<Lua_SoundObject>},
240 	{"z", get_saved_object_z<Lua_SoundObject>},
241 	{0, 0}
242 };
243 
244 char Lua_SoundObjects_Name[] = "SoundObjects";
245 
Lua_Saved_Objects_register(lua_State * L)246 int Lua_Saved_Objects_register(lua_State* L)
247 {
248 	Lua_Goal::Register(L, Lua_Goal_Get);
249 	Lua_Goal::Valid = saved_object_valid<_saved_goal>;
250 
251 	Lua_Goals::Register(L);
252 	Lua_Goals::Length = saved_objects_length;
253 
254 	Lua_ItemStart::Register(L, Lua_ItemStart_Get);
255 	Lua_ItemStart::Valid = saved_object_valid<_saved_item>;
256 
257 	Lua_ItemStarts::Register(L);
258 	Lua_ItemStarts::Length = saved_objects_length;
259 
260 	Lua_MonsterStart::Register(L, Lua_MonsterStart_Get);
261 	Lua_MonsterStart::Valid = saved_object_valid<_saved_monster>;
262 
263 	Lua_MonsterStarts::Register(L);
264 	Lua_MonsterStarts::Length = saved_objects_length;
265 
266 	Lua_PlayerStart::Register(L, Lua_PlayerStart_Get);
267 	Lua_PlayerStart::Valid = saved_object_valid<_saved_player>;
268 
269 	Lua_PlayerStarts::Register(L);
270 	Lua_PlayerStarts::Length = saved_objects_length;
271 
272 	Lua_SoundObject::Register(L, Lua_SoundObject_Get);
273 	Lua_SoundObject::Valid = saved_object_valid<_saved_sound_source>;
274 
275 	Lua_SoundObjects::Register(L);
276 	Lua_SoundObjects::Length = saved_objects_length;
277 
278 	return 0;
279 }
280