naev 0.12.6
comm.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
9#include "comm.h"
10
11#include "ai.h"
12#include "array.h"
13#include "escort.h"
14#include "hook.h"
15#include "log.h"
16#include "ndata.h"
17#include "nlua.h"
18#include "pilot.h"
19#include "player.h"
20
21#define BUTTON_WIDTH 80
22#define BUTTON_HEIGHT 30
23
24#define GRAPHIC_WIDTH 256
25#define GRAPHIC_HEIGHT 256
26
27static Spob *comm_spob = NULL;
28static int comm_commClose = 0;
29static nlua_env comm_env = LUA_NOREF;
30static int comm_open = 0;
31
32/*
33 * Prototypes.
34 */
35/* Static. */
36static const char *comm_getString( const Pilot *p, const char *str );
37
41int comm_isOpen( void )
42{
43 return comm_open;
44}
45
49void comm_queueClose( void )
50{
52}
53
60int comm_openPilot( unsigned int pilot )
61{
62 const char *msg;
63 char c;
64 Pilot *p;
65 Pilot *const *pltstk;
66 AIMemory oldmem;
67
68 /* Get the pilot. */
69 p = pilot_get( pilot );
70
71 /* Make sure pilot exists. */
72 if ( p == NULL )
73 return -1;
74
75 /* Make sure pilot in range. */
76 if ( !pilot_isFlag( p, PILOT_HAILING ) &&
77 pilot_inRangePilot( player.p, p, NULL ) <= 0 ) {
78 player_message( _( "#rTarget is out of communications range" ) );
79 return -1;
80 }
82
83 /* Must not be jumping. */
84 if ( pilot_isFlag( p, PILOT_HYPERSPACE ) ) {
85 player_message( _( "#%c%s#r is jumping and can't respond" ), c, p->name );
86 return 0;
87 }
88
89 /* Must not be disabled, unless hailing. */
90 if ( !pilot_isFlag( p, PILOT_HAILING ) &&
91 pilot_isFlag( p, PILOT_DISABLED ) ) {
92 player_message( _( "#%c%s#r does not respond" ), c, p->name );
93 return 0;
94 }
95
96 /* Set up for the comm_get* functions. */
97 oldmem = ai_setPilot( p );
98
99 /* Have pilot stop hailing. */
100 pilot_rmFlag( p, PILOT_HAILING );
101
102 /* Don't close automatically. */
103 comm_commClose = 0;
104
105 /* Run specific hail hooks on hailing pilot. */
106 if ( pilot_canTarget( p ) ) {
107 HookParam hparam[] = { { .type = HOOK_PARAM_PILOT, .u = { .lp = p->id } },
108 { .type = HOOK_PARAM_SENTINEL } };
109 hooks_runParam( "hail", hparam );
110 pilot_runHook( p, PILOT_HOOK_HAIL );
111 }
112
113 /* Check for player faction (escorts). Should be moved to the comm script
114 * most likely. For now, we just run it after hooks if it hasn't been closed
115 * already. */
116 if ( !comm_commClose && p->faction == FACTION_PLAYER ) {
118 ai_unsetPilot( oldmem );
119 return 0;
120 }
121
122 /* Check to see if pilot wants to communicate. */
123 msg = comm_getString( p, "comm_no" );
124 if ( msg != NULL ) {
125 if ( comm_commClose == 0 ) {
126 char col = pilot_getFactionColourChar( p );
127 player_message( _( "#%c%s>#0 %s" ), col, p->name, msg );
128 }
129 ai_unsetPilot( oldmem );
130 return 0;
131 }
132
133 /* Run generic hail hooks on all pilots. */
134 pltstk = pilot_getAll();
135 for ( int i = 0; i < array_size( pltstk ); i++ )
136 ai_hail( pltstk[i] );
137
138 /* Close window if necessary. */
139 if ( comm_commClose ) {
140 comm_spob = NULL;
141 comm_commClose = 0;
142 ai_unsetPilot( oldmem );
143 return 0;
144 }
145
146 /* Set up environment first time. */
147 if ( comm_env == LUA_NOREF ) {
148 comm_env = nlua_newEnv( "comm" );
150
151 size_t bufsize;
152 char *buf = ndata_read( COMM_PATH, &bufsize );
153 if ( nlua_dobufenv( comm_env, buf, bufsize, COMM_PATH ) != 0 ) {
154 WARN( _( "Error loading file: %s\n"
155 "%s\n"
156 "Most likely Lua file has improper syntax, please check" ),
157 COMM_PATH, lua_tostring( naevL, -1 ) );
158 free( buf );
159 ai_unsetPilot( oldmem );
160 return -1;
161 }
162 free( buf );
163 }
164
165 comm_open = 1;
166
167 /* Run Lua. */
168 nlua_getenv( naevL, comm_env, "comm" );
169 lua_pushpilot( naevL, p->id );
170 if ( nlua_pcall( comm_env, 1, 0 ) ) { /* error has occurred */
171 WARN( _( "Comm: '%s'" ), lua_tostring( naevL, -1 ) );
172 lua_pop( naevL, 1 );
173 }
174
175 ai_unsetPilot( oldmem );
176 comm_open = 0;
177
178 return 0;
179}
180
187int comm_openSpob( Spob *spob )
188{
189 /* Don't close automatically. */
190 comm_commClose = 0;
191
192 /* Run hail_spob hook. */
193 HookParam hparam[] = {
194 { .type = HOOK_PARAM_SPOB, .u = { .la = spob_index( spob ) } },
195 { .type = HOOK_PARAM_SENTINEL } };
196 hooks_runParam( "hail_spob", hparam );
197
198 /* Close window if necessary. */
199 if ( comm_commClose ) {
200 comm_spob = NULL;
201 comm_commClose = 0;
202 return 0;
203 }
204
205 /* Lua stuff. */
206 if ( spob->lua_comm != LUA_NOREF ) {
207 comm_open = 1;
208 spob_luaInitMem( spob );
209 lua_rawgeti( naevL, LUA_REGISTRYINDEX, spob->lua_comm ); /* f */
210 if ( nlua_pcall( spob->lua_env, 0, 1 ) ) {
211 WARN( _( "Spob '%s' failed to run '%s':\n%s" ), spob->name, "comm",
212 lua_tostring( naevL, -1 ) );
213 lua_pop( naevL, 1 );
214 } else {
215 int commed = lua_toboolean( naevL, -1 );
216 lua_pop( naevL, 1 );
217 if ( commed ) {
218 comm_open = 0;
219 return 0;
220 }
221 }
222 comm_open = 0;
223 }
224
225 player_message( _( "%s does not respond." ), spob_name( spob ) );
226 return 0;
227}
228
242static const char *comm_getString( const Pilot *p, const char *str )
243{
244 const char *ret;
245
246 if ( p->ai == NULL )
247 return NULL;
248
249 /* Get memory table. */
250 nlua_getenv( naevL, p->ai->env, "mem" );
251
252 /* Get str message. */
253 lua_getfield( naevL, -1, str );
254 if ( !lua_isstring( naevL, -1 ) )
255 ret = NULL;
256 else
257 ret = lua_tostring( naevL, -1 );
258 lua_pop( naevL, 2 );
259
260 return ret;
261}
void ai_unsetPilot(AIMemory oldmem)
Finishes setting up a pilot.
Definition ai.c:428
AIMemory ai_setPilot(Pilot *p)
Sets the pilot for further AI calls.
Definition ai.c:416
void ai_hail(Pilot *recipient)
Triggers the hail() function in the pilot's AI.
Definition ai.c:1025
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:179
int comm_openPilot(unsigned int pilot)
Opens the communication dialogue with a pilot.
Definition comm.c:60
static const char * comm_getString(const Pilot *p, const char *str)
Gets a string from the pilot's memory.
Definition comm.c:242
int comm_openSpob(Spob *spob)
Opens a communication dialogue with a spob.
Definition comm.c:187
static Spob * comm_spob
Definition comm.c:27
int comm_isOpen(void)
Check to see if the comm window is open.
Definition comm.c:41
void comm_queueClose(void)
Queues a close command when possible.
Definition comm.c:49
static int comm_commClose
Definition comm.c:28
static nlua_env comm_env
Definition comm.c:29
int escort_playerCommand(const Pilot *e)
Open a dialog for the player to issue a command to an escort.
Definition escort.c:384
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
Definition gui.c:353
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
Definition hook.c:1029
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
Definition ndata.c:207
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
Definition nlua.c:914
lua_State * naevL
Definition nlua.c:54
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
Definition nlua_pilot.c:576
char pilot_getFactionColourChar(const Pilot *p)
Gets the faction colour char, works like faction_reputationColourChar but for a pilot.
Definition pilot.c:1121
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:640
Pilot *const * pilot_getAll(void)
Gets the pilot stack.
Definition pilot.c:93
int pilot_canTarget(const Pilot *p)
Same as pilot_validTarget but without the range check.
Definition pilot.c:270
int pilot_inRangePilot(const Pilot *p, const Pilot *target, double *dist2)
Check to see if a pilot is in sensor range of another.
Definition pilot_ew.c:256
int pilot_runHook(Pilot *p, int hook_type)
Tries to run a pilot hook if he has it.
Definition pilot_hook.c:104
Player_t player
Definition player.c:77
static const double c[]
Definition rng.c:256
int spob_index(const Spob *p)
Gets the ID of a spob.
Definition space.c:1158
const char * spob_name(const Spob *p)
Gets the translated name of a spob.
Definition space.c:1834
void spob_luaInitMem(const Spob *spob)
Initializes the memory fo a spob.
Definition space.c:2109
Represents a temporary pilot memory. For use with ai_setPilot and ai_unsetPilot.
Definition ai.h:59
The actual hook parameter.
Definition hook.h:40
The representation of an in-game pilot.
Definition pilot.h:263
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition space.h:102
int lua_comm
Definition space.h:173
nlua_env lua_env
Definition space.h:164
char * name
Definition space.h:105