1 /*
2 * See Licensing and Copyright notice in naev.h
3 */
4
5 /**
6 * @file nlua_faction.c
7 *
8 * @brief Handles the Lua faction bindings.
9 *
10 * These bindings control the factions.
11 */
12
13 #include "nlua_faction.h"
14
15 #include "naev.h"
16
17 #include <lauxlib.h>
18
19 #include "log.h"
20 #include "nluadef.h"
21 #include "nlua_tex.h"
22 #include "nlua_col.h"
23 #include "faction.h"
24
25
26 /* Faction metatable methods */
27 static int factionL_get( lua_State *L );
28 static int factionL_eq( lua_State *L );
29 static int factionL_name( lua_State *L );
30 static int factionL_longname( lua_State *L );
31 static int factionL_areenemies( lua_State *L );
32 static int factionL_areallies( lua_State *L );
33 static int factionL_modplayer( lua_State *L );
34 static int factionL_modplayersingle( lua_State *L );
35 static int factionL_modplayerraw( lua_State *L );
36 static int factionL_setplayerstanding( lua_State *L );
37 static int factionL_playerstanding( lua_State *L );
38 static int factionL_enemies( lua_State *L );
39 static int factionL_allies( lua_State *L );
40 static int factionL_logoSmall( lua_State *L );
41 static int factionL_logoTiny( lua_State *L );
42 static int factionL_colour( lua_State *L );
43 static int factionL_isknown( lua_State *L );
44 static int factionL_setknown( lua_State *L );
45 static const luaL_reg faction_methods[] = {
46 { "get", factionL_get },
47 { "__eq", factionL_eq },
48 { "__tostring", factionL_name },
49 { "name", factionL_name },
50 { "longname", factionL_longname },
51 { "areEnemies", factionL_areenemies },
52 { "areAllies", factionL_areallies },
53 { "modPlayer", factionL_modplayer },
54 { "modPlayerSingle", factionL_modplayersingle },
55 { "modPlayerRaw", factionL_modplayerraw },
56 { "setPlayerStanding", factionL_setplayerstanding },
57 { "playerStanding", factionL_playerstanding },
58 { "enemies", factionL_enemies },
59 { "allies", factionL_allies },
60 { "logoSmall", factionL_logoSmall },
61 { "logoTiny", factionL_logoTiny },
62 { "colour", factionL_colour },
63 { "known", factionL_isknown },
64 { "setKnown", factionL_setknown },
65 {0,0}
66 }; /**< Faction metatable methods. */
67
68
69 /**
70 * @brief Loads the faction library.
71 *
72 * @param env Environment to load faction library into.
73 * @return 0 on success.
74 */
nlua_loadFaction(nlua_env env)75 int nlua_loadFaction( nlua_env env )
76 {
77 nlua_register(env, FACTION_METATABLE, faction_methods, 1);
78 return 0; /* No error */
79 }
80
81
82 /**
83 * @brief Lua bindings to deal with factions.
84 *
85 * Use like:
86 * @code
87 * f = faction.get( "Empire" )
88 * if f:playerStanding() < 0 then
89 * -- player is hostile to "Empire"
90 * end
91 * @endcode
92 *
93 * @luamod faction
94 */
95 /**
96 * @brief Gets the faction based on its name.
97 *
98 * @usage f = faction.get( "Empire" )
99 *
100 * @luatparam string name Name of the faction to get.
101 * @luatreturn Faction The faction matching name.
102 * @luafunc get( name )
103 */
factionL_get(lua_State * L)104 static int factionL_get( lua_State *L )
105 {
106 LuaFaction f;
107 const char *name;
108
109 name = luaL_checkstring(L,1);
110 f = faction_get(name);
111 if (f < 0) {
112 NLUA_ERROR(L,"Faction '%s' not found in stack.", name );
113 return 0;
114 }
115 lua_pushfaction(L,f);
116 return 1;
117 }
118
119
120 /**
121 * @brief Gets faction at index.
122 *
123 * @param L Lua state to get faction from.
124 * @param ind Index position to find the faction.
125 * @return Faction found at the index in the state.
126 */
lua_tofaction(lua_State * L,int ind)127 LuaFaction lua_tofaction( lua_State *L, int ind )
128 {
129 return *((LuaFaction*) lua_touserdata(L,ind));
130 }
131
132
133 /**
134 * @brief Gets faction (or faction name) at index, raising an error if type isn't a valid faction.
135 *
136 * @param L Lua state to get faction from.
137 * @param ind Index position to find the faction.
138 * @return Faction found at the index in the state.
139 */
luaL_validfaction(lua_State * L,int ind)140 LuaFaction luaL_validfaction( lua_State *L, int ind )
141 {
142 int id;
143
144 if (lua_isfaction(L,ind))
145 id = lua_tofaction(L,ind);
146 else if (lua_isstring(L,ind))
147 id = faction_get( lua_tostring(L, ind) );
148 else {
149 luaL_typerror(L, ind, FACTION_METATABLE);
150 return 0;
151 }
152
153 if (id == -1)
154 NLUA_ERROR(L,"Faction '%s' not found in stack.", lua_tostring(L,ind) );
155
156 return id;
157 }
158
159
160 /**
161 * @brief Pushes a faction on the stack.
162 *
163 * @param L Lua state to push faction into.
164 * @param faction Faction to push.
165 * @return Newly pushed faction.
166 */
lua_pushfaction(lua_State * L,LuaFaction faction)167 LuaFaction* lua_pushfaction( lua_State *L, LuaFaction faction )
168 {
169 LuaFaction *f;
170 f = (LuaFaction*) lua_newuserdata(L, sizeof(LuaFaction));
171 *f = faction;
172 luaL_getmetatable(L, FACTION_METATABLE);
173 lua_setmetatable(L, -2);
174 return f;
175 }
176 /**
177 * @brief Checks to see if ind is a faction.
178 *
179 * @param L Lua state to check.
180 * @param ind Index position to check.
181 * @return 1 if ind is a faction.
182 */
lua_isfaction(lua_State * L,int ind)183 int lua_isfaction( lua_State *L, int ind )
184 {
185 int ret;
186
187 if (lua_getmetatable(L,ind)==0)
188 return 0;
189 lua_getfield(L, LUA_REGISTRYINDEX, FACTION_METATABLE);
190
191 ret = 0;
192 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
193 ret = 1;
194
195 lua_pop(L, 2); /* remove both metatables */
196 return ret;
197 }
198
199 /**
200 * @brief __eq (equality) metamethod for factions.
201 *
202 * You can use the '==' operator within Lua to compare factions with this.
203 *
204 * @usage if f == faction.get( "Dvaered" ) then
205 *
206 * @luatparam Faction f Faction comparing.
207 * @luatparam Faction comp faction to compare against.
208 * @luatreturn boolean true if both factions are the same.
209 * @luafunc __eq( f, comp )
210 */
factionL_eq(lua_State * L)211 static int factionL_eq( lua_State *L )
212 {
213 int a, b;
214 a = luaL_validfaction(L,1);
215 b = luaL_validfaction(L,2);
216 lua_pushboolean(L, a == b);
217 return 1;
218 }
219
220 /**
221 * @brief Gets the faction's name.
222 *
223 * @usage name = f:name()
224 *
225 * @luatparam Faction f The faction to get the name of.
226 * @luatreturn string The name of the faction.
227 * @luafunc name( f )
228 */
factionL_name(lua_State * L)229 static int factionL_name( lua_State *L )
230 {
231 int f;
232 f = luaL_validfaction(L,1);
233 lua_pushstring(L, faction_name(f));
234 return 1;
235 }
236
237 /**
238 * @brief Gets the faction's long name.
239 *
240 * @usage longname = f:longname()
241 * @luatparam Faction f Faction to get long name of.
242 * @luatreturn string The long name of the faction.
243 * @luafunc longname( f )
244 */
factionL_longname(lua_State * L)245 static int factionL_longname( lua_State *L )
246 {
247 int f;
248 f = luaL_validfaction(L,1);
249 lua_pushstring(L, faction_longname(f));
250 return 1;
251 }
252
253 /**
254 * @brief Checks to see if f is an enemy of e.
255 *
256 * @usage if f:areEnemies( faction.get( "Dvaered" ) ) then
257 *
258 * @luatparam Faction f Faction to check against.
259 * @luatparam Faction e Faction to check if is an enemy.
260 * @luatreturn string true if they are enemies, false if they aren't.
261 * @luafunc areEnemies( f, e )
262 */
factionL_areenemies(lua_State * L)263 static int factionL_areenemies( lua_State *L )
264 {
265 int f, ff;
266 f = luaL_validfaction(L,1);
267 ff = luaL_validfaction(L,2);
268
269 lua_pushboolean(L, areEnemies( f, ff ));
270 return 1;
271 }
272
273 /**
274 * @brief Checks to see if f is an ally of a.
275 *
276 * @usage if f:areAllies( faction.get( "Pirate" ) ) then
277 *
278 * @luatparam Faction f Faction to check against.
279 * @luatparam faction a Faction to check if is an enemy.
280 * @luatreturn boolean true if they are enemies, false if they aren't.
281 * @luafunc areAllies( f, a )
282 */
factionL_areallies(lua_State * L)283 static int factionL_areallies( lua_State *L )
284 {
285 int f, ff;
286 f = luaL_validfaction(L,1);
287 ff = luaL_validfaction(L,2);
288
289 lua_pushboolean(L, areAllies( f, ff ));
290 return 1;
291 }
292
293 /**
294 * @brief Modifies the player's standing with the faction.
295 *
296 * Also modifies standing with allies and enemies of the faction.
297 *
298 * @usage f:modPlayer( -5 ) -- Lowers faction by 5
299 *
300 * @luatparam Faction f Faction to modify player's standing with.
301 * @luatparam number mod The modifier to modify faction by.
302 * @luafunc modPlayer( f, mod )
303 */
factionL_modplayer(lua_State * L)304 static int factionL_modplayer( lua_State *L )
305 {
306 int f;
307 double n;
308
309 NLUA_CHECKRW(L);
310
311 f = luaL_validfaction(L,1);
312 n = luaL_checknumber(L,2);
313 faction_modPlayer( f, n, "script" );
314
315 return 0;
316 }
317
318 /**
319 * @brief Modifies the player's standing with the faction.
320 *
321 * Does not affect other faction standings.
322 *
323 * @usage f:modPlayerSingle( 10 )
324 *
325 * @luatparam Faction f Faction to modify player's standing with.
326 * @luatparam number mod The modifier to modify faction by.
327 * @luafunc modPlayerSingle( f, mod )
328 */
factionL_modplayersingle(lua_State * L)329 static int factionL_modplayersingle( lua_State *L )
330 {
331 int f;
332 double n;
333
334 NLUA_CHECKRW(L);
335
336 f = luaL_validfaction(L,1);
337 n = luaL_checknumber(L,2);
338 faction_modPlayerSingle( f, n, "script" );
339
340 return 0;
341 }
342
343 /**
344 * @brief Modifies the player's standing with the faction.
345 *
346 * Does not affect other faction standings and is not processed by the faction
347 * Lua script, so it indicates exactly the amount to be changed.
348 *
349 * @usage f:modPlayerRaw( 10 )
350 *
351 * @luatparam Faction f Faction to modify player's standing with.
352 * @luatparam number mod The modifier to modify faction by.
353 * @luafunc modPlayerRaw( f, mod )
354 */
factionL_modplayerraw(lua_State * L)355 static int factionL_modplayerraw( lua_State *L )
356 {
357 int f;
358 double n;
359
360 NLUA_CHECKRW(L);
361
362 f = luaL_validfaction(L,1);
363 n = luaL_checknumber(L,2);
364 faction_modPlayerRaw( f, n );
365
366 return 0;
367 }
368
369 /**
370 * @brief Sets the player's standing with the faction.
371 *
372 * @usage f:setPlayerStanding(70) -- Make player an ally
373 *
374 * @luatparam Faction f Faction to set the player's standing for.
375 * @luatparam number value Value to set the player's standing to (from -100 to 100).
376 * @luafunc setPlayerStanding( f, value )
377 */
factionL_setplayerstanding(lua_State * L)378 static int factionL_setplayerstanding( lua_State *L )
379 {
380 int f;
381 double n;
382
383 NLUA_CHECKRW(L);
384
385 f = luaL_validfaction( L, 1 );
386 n = luaL_checknumber( L, 2 );
387 faction_setPlayer( f, n );
388
389 return 0;
390 }
391
392 /**
393 * @brief Gets the player's standing with the faction.
394 *
395 * @usage if f:playerStanding() > 70 then -- Player is an ally
396 *
397 * @luatparam Faction f Faction to get player's standing with.
398 * @luatreturn number The value of the standing and the human readable string.
399 * @luafunc playerStanding( f )
400 */
factionL_playerstanding(lua_State * L)401 static int factionL_playerstanding( lua_State *L )
402 {
403 int f;
404 double n;
405
406 f = luaL_validfaction( L, 1 );
407 n = faction_getPlayer( f );
408
409 lua_pushnumber( L, n );
410 lua_pushstring( L, faction_getStandingText( f ) );
411
412 return 2;
413 }
414
415 /**
416 * @brief Gets the enemies of the faction.
417 *
418 * @usage for k,v in pairs(f:enemies()) do -- Iterates over enemies
419 *
420 * @luatparam Faction f Faction to get enemies of.
421 * @luatreturn {Faction,...} A table containing the enemies of the faction.
422 * @luafunc enemies( f )
423 */
factionL_enemies(lua_State * L)424 static int factionL_enemies( lua_State *L )
425 {
426 int i, n, f;
427 int *factions;
428
429 f = luaL_validfaction(L,1);
430
431 /* Push the enemies in a table. */
432 lua_newtable(L);
433 factions = faction_getEnemies( f, &n );
434 for (i=0; i<n; i++) {
435 lua_pushnumber(L, i+1); /* key */
436 lua_pushfaction(L, factions[i]); /* value */
437 lua_rawset(L, -3);
438 }
439
440 return 1;
441 }
442
443 /**
444 * @brief Gets the allies of the faction.
445 *
446 * @usage for k,v in pairs(f:allies()) do -- Iterate over faction allies
447 *
448 * @luatparam Faction f Faction to get allies of.
449 * @luatreturn {Faction,...} A table containing the allies of the faction.
450 * @luafunc allies( f )
451 */
factionL_allies(lua_State * L)452 static int factionL_allies( lua_State *L )
453 {
454 int i, n, f;
455 int *factions;
456
457 f = luaL_validfaction(L,1);
458
459 /* Push the enemies in a table. */
460 lua_newtable(L);
461 factions = faction_getAllies( f, &n );
462 for (i=0; i<n; i++) {
463 lua_pushnumber(L, i+1); /* key */
464 lua_pushfaction(L, factions[i]); /* value */
465 lua_rawset(L, -3);
466 }
467
468 return 1;
469 }
470
471
472 /**
473 * @brief Gets the small faction logo which is 64x64 or smaller.
474 *
475 * @luatparam Faction f Faction to get logo from.
476 * @luatreturn Tex The small faction logo or nil if not applicable.
477 * @luafunc logoSmall( f )
478 */
factionL_logoSmall(lua_State * L)479 static int factionL_logoSmall( lua_State *L )
480 {
481 int lf;
482 glTexture *tex;
483 lf = luaL_validfaction(L,1);
484 tex = faction_logoSmall( lf );
485 if (tex == NULL)
486 return 0;
487 lua_pushtex( L, gl_dupTexture( tex ) );
488 return 1;
489 }
490
491
492 /**
493 * @brief Gets the tiny faction logo which is 24x24 or smaller.
494 *
495 * @luatparam Faction f Faction to get logo from.
496 * @luatreturn Tex The tiny faction logo or nil if not applicable.
497 * @luafunc logoTiny( f )
498 */
factionL_logoTiny(lua_State * L)499 static int factionL_logoTiny( lua_State *L )
500 {
501 int lf;
502 glTexture *tex;
503 lf = luaL_validfaction(L,1);
504 tex = faction_logoTiny( lf );
505 if (tex == NULL)
506 return 0;
507 lua_pushtex( L, gl_dupTexture( tex ) );
508 return 1;
509 }
510
511
512 /**
513 * @brief Gets the faction colour.
514 *
515 * @luatparam Faction f Faction to get colour from.
516 * @luatreturn Colour|nil The faction colour or nil if not applicable.
517 * @luafunc colour( f )
518 */
factionL_colour(lua_State * L)519 static int factionL_colour( lua_State *L )
520 {
521 int lf;
522 const glColour *col;
523 lf = luaL_validfaction(L,1);
524 col = faction_getColour(lf);
525 if (col == NULL)
526 return 0;
527 lua_pushcolour( L, *col );
528 return 1;
529 }
530
531
532 /**
533 * @brief Checks to see if a faction is known by the player.
534 *
535 * @usage b = f:known()
536 *
537 * @luatparam Faction f Faction to check if the player knows.
538 * @luatreturn boolean true if the player knows the faction.
539 * @luafunc known( f )
540 */
factionL_isknown(lua_State * L)541 static int factionL_isknown( lua_State *L )
542 {
543 int fac = luaL_validfaction(L, 1);
544 lua_pushboolean(L, faction_isKnown(fac));
545 return 1;
546 }
547
548
549 /**
550 * @brief Sets a faction's known state.
551 *
552 * @usage f:setKnown( false ) -- Makes faction unknown.
553 * @luatparam Faction f Faction to set known.
554 * @luatparam[opt=false] boolean b Whether or not to set as known.
555 * @luafunc setKnown( f, b )
556 */
factionL_setknown(lua_State * L)557 static int factionL_setknown( lua_State *L )
558 {
559 int b, fac;
560
561 NLUA_CHECKRW(L);
562
563 fac = luaL_validfaction(L, 1);
564 b = lua_toboolean(L, 2);
565
566 faction_setKnown( fac, b );
567
568 return 0;
569 }
570
571