1 /*
2  * See Licensing and Copyright notice in naev.h
3  */
4 
5 /**
6  * @file claim.c
7  *
8  * @brief Handles claiming of systems.
9  */
10 
11 #include "claim.h"
12 
13 #include "naev.h"
14 
15 #include "log.h"
16 #include "space.h"
17 #include "array.h"
18 #include "event.h"
19 #include "mission.h"
20 
21 
22 /**
23  * @brief The claim structure.
24  */
25 struct Claim_s {
26    int *ids; /**< System ids. */
27    char **strs; /**< Strings. */
28 };
29 
30 static char **claimed_strs = NULL; /**< Global claimed strings. */
31 
32 
33 /**
34  * @brief Creates a system claim.
35  *
36  *    @return Newly created system claim or NULL on error.
37  */
claim_create(void)38 Claim_t *claim_create (void)
39 {
40    Claim_t *claim;
41 
42    claim       = malloc( sizeof(Claim_t) );
43    claim->ids  = NULL;
44    claim->strs = NULL;
45 
46    return claim;
47 }
48 
49 
50 /**
51  * @brief Adds a string claim to a claim.
52  *
53  *    @param claim Claim to add system to.
54  *    @param str String to claim.
55  */
claim_addStr(Claim_t * claim,const char * str)56 int claim_addStr( Claim_t *claim, const char *str )
57 {
58    char **s;
59 
60    /* Allocate if necessary. */
61    if (claim->strs == NULL)
62       claim->strs = array_create( char* );
63 
64    /* New ID. */
65    s = &array_grow( &claim->strs );
66    *s = strdup( str );
67    return 0;
68 }
69 
70 
71 /**
72  * @brief Adds a claim to a system claim.
73  *
74  *    @param claim Claim to add system to.
75  *    @param ss_id Id of the system to add to the claim.
76  */
claim_addSys(Claim_t * claim,int ss_id)77 int claim_addSys( Claim_t *claim, int ss_id )
78 {
79    int *id;
80 
81    /* Allocate if necessary. */
82    if (claim->ids == NULL)
83       claim->ids = array_create( int );
84 
85    /* New ID. */
86    id  = &array_grow( &claim->ids );
87    *id = ss_id;
88    return 0;
89 }
90 
91 
92 /**
93  * @brief Tests to see if a system claim would have collisions.
94  *
95  *    @param claim System to test.
96  *    @return 0 if no collision found, 1 if a collision was found.
97  */
claim_test(Claim_t * claim)98 int claim_test( Claim_t *claim )
99 {
100    int claimed, i, j;
101 
102    /* Must actually have a claim. */
103    if (claim == NULL)
104       return 0;
105 
106    /* See if the system is claimed. */
107    if (claim->ids != NULL) {
108       for (i=0; i<array_size(claim->ids); i++) {
109          claimed = sys_isFlag( system_getIndex(claim->ids[i]), SYSTEM_CLAIMED );
110          if (claimed)
111             return 1;
112       }
113    }
114 
115    /* Check strings. */
116    if ((claim->strs != NULL) && (claimed_strs != NULL)) {
117       for (i=0; i<array_size(claim->strs); i++) {
118          for (j=0; j<array_size(claimed_strs); j++) {
119             if (strcmp( claim->strs[i], claimed_strs[j] )==0)
120                return 1;
121          }
122       }
123    }
124 
125    return 0;
126 }
127 
128 
129 /**
130  * @brief Tests to see if a system is claimed by a system claim.
131  *
132  *    @param claim Claim to test.
133  *    @param str Stringto see if is claimed by the claim.
134  *    @return 0 if no collision is found, 1 otherwise.
135  */
claim_testStr(Claim_t * claim,const char * str)136 int claim_testStr( Claim_t *claim, const char *str )
137 {
138    int i;
139 
140    /* Must actually have a claim. */
141    if (claim == NULL)
142       return 0;
143 
144    /* Make sure something to activate. */
145    if (claim->strs == NULL)
146       return 0;
147 
148    /* Check strings. */
149    for (i=0; i<array_size(claim->strs); i++) {
150       if (strcmp( claim->strs[i], str )==0)
151          return 1;
152    }
153 
154    return 0;
155 }
156 
157 
158 /**
159  * @brief Tests to see if a system is claimed by a system claim.
160  *
161  *    @param claim System claim to test.
162  *    @param sys System to see if is claimed by the system claim.
163  *    @return 0 if no collision is found, 1 otherwise.
164  */
claim_testSys(Claim_t * claim,int sys)165 int claim_testSys( Claim_t *claim, int sys )
166 {
167    int i;
168 
169    /* Must actually have a claim. */
170    if (claim == NULL)
171       return 0;
172 
173    /* Make sure something to activate. */
174    if (claim->ids == NULL)
175       return 0;
176 
177    /* See if the system is claimed. */
178    for (i=0; i<array_size(claim->ids); i++)
179       if (claim->ids[i] == sys)
180          return 1;
181 
182    return 0;
183 }
184 
185 
186 /**
187  * @brief Destroys a system claim.
188  *
189  *    @param claim System claim to destroy.
190  */
claim_destroy(Claim_t * claim)191 void claim_destroy( Claim_t *claim )
192 {
193    int i;
194    if (claim->ids != NULL)
195       array_free( claim->ids );
196    if (claim->strs != NULL) {
197       for (i=0; i<array_size(claim->strs); i++)
198          free( claim->strs[i] );
199       array_free( claim->strs );
200    }
201    free(claim);
202 }
203 
204 
205 /**
206  * @brief Clears the claims on all systems.
207  */
claim_clear(void)208 void claim_clear (void)
209 {
210    StarSystem *sys;
211    int nsys;
212    int i;
213 
214    /* Clears all the flags. */
215    sys = system_getAll( &nsys );
216    for (i=0; i<nsys; i++)
217       sys_rmFlag( &sys[i], SYSTEM_CLAIMED );
218 
219    if (claimed_strs != NULL) {
220       for (i=0; i<array_size(claimed_strs); i++)
221          free(claimed_strs[i]);
222       array_free(claimed_strs);
223       claimed_strs = NULL;
224    }
225 }
226 
227 
228 /**
229  * @brief Activates all the claims.
230  */
claim_activateAll(void)231 void claim_activateAll (void)
232 {
233    claim_clear();
234    event_activateClaims();
235    missions_activateClaims();
236 }
237 
238 
239 /**
240  * @brief Activates a claim on a system.
241  *
242  *    @param claim Claim to activate.
243  */
claim_activate(Claim_t * claim)244 void claim_activate( Claim_t *claim )
245 {
246    int i;
247    char **s;
248 
249    /* Add flags. */
250    if (claim->ids != NULL) {
251       for (i=0; i<array_size(claim->ids); i++)
252          sys_setFlag( system_getIndex(claim->ids[i]), SYSTEM_CLAIMED );
253    }
254 
255    /* Add strings. */
256    if (claim->strs != NULL) {
257       if (claimed_strs == NULL)
258          claimed_strs = array_create( char* );
259       for (i=0; i<array_size(claim->strs); i++) {
260          s = &array_grow( &claimed_strs );
261          *s = strdup( claim->strs[i] );
262       }
263    }
264 }
265 
266 
267 /**
268  * @brief Saves all the systems in a claim in XML.
269  *
270  * Use between xmlw_startElem and xmlw_endElem.
271  *
272  *    @param writer XML Writer to use.
273  *    @param claim Claim to save.
274  */
claim_xmlSave(xmlTextWriterPtr writer,Claim_t * claim)275 int claim_xmlSave( xmlTextWriterPtr writer, Claim_t *claim )
276 {
277    int i;
278    StarSystem *sys;
279 
280    if (claim == NULL)
281       return 0;
282 
283    if (claim->ids != NULL) {
284       for (i=0; i<array_size(claim->ids); i++) {
285          sys = system_getIndex( claim->ids[i] );
286          if (sys != NULL) {
287             xmlw_elem( writer, "sys", "%s", sys->name );
288          }
289          else
290             WARN("System Claim has inexistent system.");
291       }
292    }
293 
294    if (claim->strs != NULL) {
295       for (i=0; i<array_size(claim->strs); i++)
296          xmlw_elem( writer, "str", "%s", claim->strs[i] );
297    }
298 
299    return 0;
300 }
301 
302 
303 /**
304  * @brief Loads a claim.
305  *
306  *    @param parent Parent node containing the claim data.
307  *    @return The system claim.
308  */
claim_xmlLoad(xmlNodePtr parent)309 Claim_t *claim_xmlLoad( xmlNodePtr parent )
310 {
311    Claim_t *claim;
312    xmlNodePtr node;
313    StarSystem *sys;
314    char *str;
315 
316    /* Create the claim. */
317    claim = claim_create();
318 
319    /* Load the nodes. */
320    node = parent->xmlChildrenNode;
321    do {
322       if (xml_isNode(node,"sys")) {
323          sys = system_get( xml_get(node) );
324          if (sys != NULL)
325             claim_addSys( claim, system_index(sys) );
326          else
327             WARN("System Claim trying to load system '%s' which doesn't exist.", xml_get(node));
328       }
329       else if (xml_isNode(node,"str")) {
330          str = xml_get(node);
331          claim_addStr( claim, str );
332       }
333    } while (xml_nextNode(node));
334 
335    /* Activate the claim. */
336    claim_activate( claim );
337 
338    return claim;
339 }
340 
341 
342 
343