naev 0.10.4
damagetype.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <inttypes.h>
11#include "SDL.h"
12
13#include "naev.h"
16#include "damagetype.h"
17
18#include "array.h"
19#include "log.h"
20#include "ndata.h"
21#include "nxml.h"
22#include "pause.h"
23#include "pilot.h"
24#include "rng.h"
25#include "shipstats.h"
26
27#define DTYPE_XML_ID "dtype"
34typedef struct DTYPE_ {
35 char* name;
36 double sdam;
37 double adam;
38 double knock;
39 size_t soffset;
40 size_t aoffset;
41} DTYPE;
42
43static DTYPE* dtype_types = NULL;
45/*
46 * prototypes
47 */
48static int DTYPE_parse( DTYPE *temp, const char *file);
49static void DTYPE_free( DTYPE *damtype );
50static DTYPE* dtype_validType( int type );
51
59static int DTYPE_parse( DTYPE *temp, const char *file )
60{
61 xmlNodePtr node, parent;
62 xmlDocPtr doc;
63 char *stat;
64
65 /* Load and read the data. */
66 doc = xml_parsePhysFS( file );
67 if (doc == NULL)
68 return -1;
69
70 /* Check to see if document exists. */
71 parent = doc->xmlChildrenNode;
72 if (!xml_isNode(parent,DTYPE_XML_ID)) {
73 WARN(_("Malformed '%s' file: missing root element '%s'"), file, DTYPE_XML_ID);
74 return -1;
75 }
76
77 /* Clear data. */
78 memset( temp, 0, sizeof(DTYPE) );
79
80 xmlr_attr_strd( parent, "name", temp->name );
81
82 /* Extract the data. */
83 node = parent->xmlChildrenNode;
84 do {
85 xml_onlyNodes(node);
86
87 if (xml_isNode(node, "shield")) {
88 temp->sdam = xml_getFloat(node);
89
90 xmlr_attr_strd( node, "stat", stat );
91 if (stat != NULL) {
93 free(stat);
94 }
95
96 continue;
97 }
98 else if (xml_isNode(node, "armour")) {
99 temp->adam = xml_getFloat(node);
100
101 xmlr_attr_strd( node, "stat", stat );
102 if (stat != NULL) {
104 free(stat);
105 }
106
107 continue;
108 }
109 xmlr_float(node, "knockback", temp->knock);
110
111 WARN(_("Unknown node of type '%s' in damage node '%s'."), node->name, temp->name);
112 } while (xml_nextNode(node));
113
114#define MELEMENT(o,s) \
115 if (o) WARN(_("DTYPE '%s' invalid '"s"' element"), temp->name)
116 MELEMENT(temp->sdam<0.,"shield");
117 MELEMENT(temp->adam<0.,"armour");
118 MELEMENT(temp->knock<0.,"knockback");
119#undef MELEMENT
120
121 /* Clean up. */
122 xmlFreeDoc(doc);
123
124 return 0;
125}
126
132static void DTYPE_free( DTYPE *damtype )
133{
134 free(damtype->name);
135 damtype->name = NULL;
136}
137
144int dtype_get( const char* name )
145{
146 for (int i=0; i<array_size(dtype_types); i++)
147 if (strcmp(dtype_types[i].name, name)==0)
148 return i;
149 WARN(_("Damage type '%s' not found in stack."), name);
150 return -1;
151}
152
156static DTYPE* dtype_validType( int type )
157{
158 if ((type < 0) || (type >= array_size(dtype_types))) {
159 WARN(_("Damage type '%d' is invalid."), type);
160 return NULL;
161 }
162 return &dtype_types[ type ];
163}
164
168const char* dtype_damageTypeToStr( int type )
169{
170 DTYPE *dmg = dtype_validType( type );
171 if (dmg == NULL)
172 return NULL;
173 return dmg->name;
174}
175
181int dtype_load (void)
182{
183 const DTYPE normal = {
184 .name = strdup(N_("normal")),
185 .sdam = 1.,
186 .adam = 1.,
187 .knock = 0.,
188 .soffset = 0,
189 .aoffset = 0,
190 };
191 char **dtype_files = ndata_listRecursive( DTYPE_DATA_PATH );
192
193 /* Load up the individual damage types. */
195 array_push_back( &dtype_types, normal );
196
197 for (int i=0; i<array_size(dtype_files); i++) {
198 DTYPE dtype;
199 int ret = DTYPE_parse( &dtype, dtype_files[i] );
200 if (ret == 0)
201 array_push_back( &dtype_types, dtype );
202 free( dtype_files[i] );
203 }
204 array_free( dtype_files );
205
206 /* Shrink back to minimum - shouldn't change ever. */
208
209 return 0;
210}
211
215void dtype_free (void)
216{
217 /* clear the damtypes */
218 for (int i=0; i<array_size(dtype_types); i++)
219 DTYPE_free( &dtype_types[i] );
221 dtype_types = NULL;
222}
223
233int dtype_raw( int type, double *shield, double *armour, double *knockback )
234{
235 DTYPE *dtype = dtype_validType( type );
236 if (dtype == NULL)
237 return -1;
238 if (shield != NULL)
239 *shield = dtype->sdam;
240 if (armour != NULL)
241 *armour = dtype->adam;
242 if (knockback != NULL)
243 *knockback = dtype->knock;
244 return 0;
245}
246
257void dtype_calcDamage( double *dshield, double *darmour, double absorb, double *knockback, const Damage *dmg, const ShipStats *s )
258{
259 DTYPE *dtype;
260 char *ptr;
261 double multiplier;
262
263 /* Must be valid. */
264 dtype = dtype_validType( dmg->type );
265 if (dtype == NULL)
266 return;
267
268 /* Set if non-nil. */
269 if (dshield != NULL) {
270 if ((dtype->soffset <= 0) || (s == NULL))
271 *dshield = dtype->sdam * dmg->damage * absorb;
272 else {
273 /*
274 * If an offset has been specified, look for a double at that offset
275 * in the ShipStats struct, and used it as a multiplier.
276 *
277 * The 1. - n logic serves to convert the value from absorption to
278 * damage multiplier.
279 */
280 ptr = (char*) s;
281 memcpy(&multiplier, &ptr[ dtype->soffset ], sizeof(double));
282 multiplier = MAX( 0., 1. - multiplier );
283 *dshield = dtype->sdam * dmg->damage * absorb * multiplier;
284 }
285 }
286 if (darmour != NULL) {
287 if ((dtype->aoffset) <= 0 || (s == NULL))
288 *darmour = dtype->adam * dmg->damage * absorb;
289 else {
290 ptr = (char*) s;
291 memcpy(&multiplier, &ptr[ dtype->aoffset ], sizeof(double));
292 multiplier = MAX( 0., 1. - multiplier );
293 *darmour = dtype->adam * dmg->damage * absorb * multiplier;
294 }
295 }
296
297 if (knockback != NULL)
298 *knockback = dtype->knock;
299}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition: array.h:158
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
#define array_shrink(ptr_array)
Shrinks memory to fit only ‘size’ elements.
Definition: array.h:149
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition: array.h:129
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition: array.h:93
int dtype_load(void)
Loads the dtype stack.
Definition: damagetype.c:181
static void DTYPE_free(DTYPE *damtype)
Frees a DTYPE.
Definition: damagetype.c:132
int dtype_raw(int type, double *shield, double *armour, double *knockback)
Gets the raw modulation stats of a damage type.
Definition: damagetype.c:233
void dtype_calcDamage(double *dshield, double *darmour, double absorb, double *knockback, const Damage *dmg, const ShipStats *s)
Gives the real shield damage, armour damage and knockback modifier.
Definition: damagetype.c:257
static DTYPE * dtype_types
Definition: damagetype.c:43
int dtype_get(const char *name)
Gets the id of a dtype based on name.
Definition: damagetype.c:144
void dtype_free(void)
Frees the dtype stack.
Definition: damagetype.c:215
#define DTYPE_XML_ID
Definition: damagetype.c:27
static int DTYPE_parse(DTYPE *temp, const char *file)
Parses an XML file containing a DTYPE.
Definition: damagetype.c:59
static DTYPE * dtype_validType(int type)
Gets the damage type.
Definition: damagetype.c:156
const char * dtype_damageTypeToStr(int type)
Gets the human readable string from damage type.
Definition: damagetype.c:168
Header file with generic functions and naev-specifics.
#define MAX(x, y)
Definition: naev.h:39
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
Definition: ndata.c:232
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
Definition: nxml.c:75
size_t ss_offsetFromType(ShipStatsType type)
Gets the offset from type.
Definition: shipstats.c:585
ShipStatsType ss_typeFromName(const char *name)
Gets the type from the name.
Definition: shipstats.c:596
A damage type.
Definition: damagetype.c:34
size_t soffset
Definition: damagetype.c:39
double knock
Definition: damagetype.c:38
double adam
Definition: damagetype.c:37
char * name
Definition: damagetype.c:35
size_t aoffset
Definition: damagetype.c:40
double sdam
Definition: damagetype.c:36
Core damage that an outfit does.
Definition: outfit.h:111
int type
Definition: outfit.h:112
double damage
Definition: outfit.h:114
Represents ship statistics, properties ship can use.
Definition: shipstats.h:198