1 /*
2 * OpenBOR - http://www.chronocrash.com
3 * -----------------------------------------------------------------------
4 * All rights reserved. See LICENSE in OpenBOR root for license details.
5 *
6 * Copyright (c) 2004 - 2017 OpenBOR Team
7 */
8
9 // Binding Properties
10 // 2018-03-31
11 // Caskey, Damon V.
12
13 #include "scriptcommon.h"
14
15 // Use string property argument to find an
16 // integer property constant and populate
17 // varlist->lval.
mapstrings_bind_property(ScriptVariant ** varlist,int paramCount)18 int mapstrings_bind_property(ScriptVariant **varlist, int paramCount)
19 {
20 #define ARG_MINIMUM 2 // Minimum number of arguments allowed in varlist.
21 #define ARG_PROPERTY 1 // Varlist element carrying which property is requested.
22
23 char *propname = NULL; // Placeholder for string property name from varlist.
24 int prop; // Placeholder for integer constant located by string.
25
26 static const char *proplist[] =
27 {
28 "animation_frame",
29 "animation_id",
30 "animation_match",
31 "direction",
32 "mode_x",
33 "mode_y",
34 "mode_z",
35 "offset_x",
36 "offset_y",
37 "offset_z",
38 "override",
39 "sort_id",
40 "tag",
41 "target"
42 };
43
44 // If the minimum argument count
45 // was not passed, then there is
46 // nothing to map. Return true - we'll
47 // catch the mistake in property access
48 // functions.
49 if(paramCount < ARG_MINIMUM)
50 {
51 return 1;
52 }
53
54 // See macro - will return 0 on fail.
55 MAPSTRINGS(varlist[ARG_PROPERTY], proplist, _BIND_END,
56 "Property name '%s' is not supported by binding.\n");
57
58
59 // If we made it this far everything should be OK.
60 return 1;
61
62 #undef ARG_MINIMUM
63 #undef ARG_PROPERTY
64 }
65
66 // Caskey, Damon V.
67 // 2018-03-31
68 //
69 // Return a binding property. Requires
70 // the handle from binding entity
71 // property and property name to
72 // access.
openbor_get_bind_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)73 HRESULT openbor_get_bind_property(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
74 {
75 #define SELF_NAME "openbor_get_bind_property(void bind, char property)"
76 #define ARG_MINIMUM 2 // Minimum required arguments.
77 #define ARG_HANDLE 0 // Handle (pointer to property structure).
78 #define ARG_PROPERTY 1 // Property to access.
79
80 s_bind *handle = NULL; // Property handle.
81 e_bind_properties property = 0; // Property argument.
82
83 // Clear pass by reference argument used to send
84 // property data back to calling script. .
85 ScriptVariant_Clear(*pretvar);
86
87 // Map string property name to a
88 // matching integer constant.
89 mapstrings_bind_property(varlist, paramCount);
90
91 // Verify arguments. There should at least
92 // be a pointer for the property handle and an integer
93 // to determine which property constant is accessed.
94 if(paramCount < ARG_MINIMUM
95 || varlist[ARG_HANDLE]->vt != VT_PTR
96 || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
97 {
98 *pretvar = NULL;
99 goto error_local;
100 }
101 else
102 {
103 // Populate local vars for readability.
104 handle = (s_bind *)varlist[ARG_HANDLE]->ptrVal;
105 property = (LONG)varlist[ARG_PROPERTY]->lVal;
106 }
107
108 switch(property)
109 {
110 case _BIND_ANIMATION_FRAME:
111
112 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
113 (*pretvar)->lVal = (LONG)handle->frame;
114
115 break;
116
117 case _BIND_ANIMATION_ID:
118
119 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
120 (*pretvar)->lVal = (LONG)handle->animation;
121
122 break;
123
124 case _BIND_ANIMATION_MATCH:
125
126 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
127 (*pretvar)->lVal = (LONG)handle->match;
128
129 break;
130
131 case _BIND_DIRECTION:
132
133 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
134 (*pretvar)->lVal = (LONG)handle->direction;
135
136 break;
137
138 case _BIND_MODE_X:
139
140 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
141 (*pretvar)->lVal = (LONG)handle->positioning.x;
142
143 break;
144
145 case _BIND_MODE_Y:
146
147 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
148 (*pretvar)->lVal = (LONG)handle->positioning.y;
149
150 break;
151
152 case _BIND_MODE_Z:
153
154 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
155 (*pretvar)->lVal = (LONG)handle->positioning.z;
156
157 break;
158
159 case _BIND_OFFSET_X:
160
161 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
162 (*pretvar)->lVal = (LONG)handle->offset.x;
163
164 break;
165
166 case _BIND_OFFSET_Y:
167
168 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
169 (*pretvar)->lVal = (LONG)handle->offset.y;
170
171 break;
172
173 case _BIND_OFFSET_Z:
174
175 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
176 (*pretvar)->lVal = (LONG)handle->offset.z;
177
178 break;
179
180 case _BIND_OVERRIDE:
181
182 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
183 (*pretvar)->lVal = (LONG)handle->overriding;
184
185 break;
186
187 case _BIND_SORT_ID:
188
189 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
190 (*pretvar)->lVal = (LONG)handle->sortid;
191
192 break;
193
194 case _BIND_TAG:
195
196 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
197 (*pretvar)->lVal = (LONG)handle->tag;
198
199 break;
200
201 case _BIND_TARGET:
202
203 // If there is no entity bound, we just
204 // leave the return var empty.
205 if(handle->ent)
206 {
207 ScriptVariant_ChangeType(*pretvar, VT_PTR);
208 (*pretvar)->ptrVal = (entity *)handle->ent;
209 }
210
211 break;
212
213 default:
214
215 printf("Unsupported property.\n");
216 goto error_local;
217
218 break;
219 }
220
221 return S_OK;
222
223 error_local:
224
225 printf("\nYou must provide a valid pointer and property name: " SELF_NAME "\n");
226 *pretvar = NULL;
227
228 return E_FAIL;
229
230 #undef SELF_NAME
231 #undef ARG_MINIMUM
232 #undef ARG_HANDLE
233 #undef ARG_INDEX
234 }
235
236 // Caskey, Damon V.
237 // 2018-04-01
238 //
239 // Mutate a binding property. Requires
240 // the handle from binding entity
241 // property, property name to modify,
242 // and the new value.
openbor_set_bind_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)243 HRESULT openbor_set_bind_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
244 {
245 #define SELF_NAME "set_bind_property(void bind, char property, mixed value)"
246 #define ARG_MINIMUM 3 // Minimum required arguments.
247 #define ARG_HANDLE 0 // Handle (pointer to property structure).
248 #define ARG_PROPERTY 1 // Property to access.
249 #define ARG_VALUE 2 // New value to apply.
250
251 int result = S_OK; // Success or error?
252 s_bind *handle = NULL; // Property handle.
253 e_bind_properties property = 0; // Property to access.
254
255 // Value carriers to apply on properties after
256 // taken from argument.
257 LONG temp_int;
258
259 // Map string property name to a
260 // matching integer constant.
261 mapstrings_bind_property(varlist, paramCount);
262
263 // Verify incoming arguments. There should at least
264 // be a pointer for the property handle and an integer
265 // to determine which property is accessed.
266 if (paramCount < ARG_MINIMUM
267 || varlist[ARG_HANDLE]->vt != VT_PTR
268 || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
269 {
270 *pretvar = NULL;
271 goto error_local;
272 }
273
274 // Populate local handle and property vars.
275 handle = (s_bind *)varlist[ARG_HANDLE]->ptrVal;
276 property = (LONG)varlist[ARG_PROPERTY]->lVal;
277
278 // Which property to modify?
279 switch (property)
280 {
281
282 case _BIND_ANIMATION_FRAME:
283
284 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
285 {
286 handle->frame = temp_int;
287 }
288
289 break;
290
291 case _BIND_ANIMATION_ID:
292
293 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
294 {
295 handle->animation = temp_int;
296 }
297
298 break;
299
300 case _BIND_ANIMATION_MATCH:
301
302 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
303 {
304 handle->match = temp_int;
305 }
306
307 break;
308
309 case _BIND_DIRECTION:
310
311 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
312 {
313 handle->direction = temp_int;
314 }
315
316 break;
317
318 case _BIND_MODE_X:
319
320 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
321 {
322 handle->positioning.x = temp_int;
323 }
324
325 break;
326
327 case _BIND_MODE_Y:
328
329 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
330 {
331 handle->positioning.y = temp_int;
332 }
333
334 break;
335
336 case _BIND_MODE_Z:
337
338 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
339 {
340 handle->positioning.z = temp_int;
341 }
342
343 break;
344
345 case _BIND_OFFSET_X:
346
347 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
348 {
349 handle->offset.x = temp_int;
350 }
351
352 break;
353
354 case _BIND_OFFSET_Y:
355
356 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
357 {
358 handle->offset.y = temp_int;
359 }
360
361 break;
362
363 case _BIND_OFFSET_Z:
364
365 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
366 {
367 handle->offset.z = temp_int;
368 }
369
370 break;
371
372 case _BIND_OVERRIDE:
373
374 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
375 {
376 handle->overriding = temp_int;
377 }
378
379 break;
380
381 case _BIND_SORT_ID:
382
383 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
384 {
385 handle->sortid = temp_int;
386 }
387
388 break;
389
390 case _BIND_TAG:
391
392 if (SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
393 {
394 handle->tag = temp_int;
395 }
396
397 break;
398
399 case _BIND_TARGET:
400
401 handle->ent = (entity *)varlist[ARG_VALUE]->ptrVal;
402
403 break;
404
405 default:
406
407 printf("Unsupported property.\n");
408 goto error_local;
409
410 break;
411 }
412
413 return result;
414
415 // Error trapping.
416 error_local:
417
418 printf("\nYou must provide a valid pointer, property name, and new value: " SELF_NAME "\n");
419
420 result = E_FAIL;
421 return result;
422
423 #undef SELF_NAME
424 #undef ARG_MINIMUM
425 #undef ARG_HANDLE
426 #undef ARG_PROPERTY
427 #undef ARG_VALUE
428 }
429
430 // Caskey, Damon V.
431 // 2018-10-11
432 //
433 // Run engine's internal bind update function.
openbor_update_bind(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)434 HRESULT openbor_update_bind(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
435 {
436 #define SELF_NAME "update_bind(void entity)"
437 #define ARG_MINIMUM 1 // Minimum required arguments.
438 #define ARG_ENTITY 0 // Target entity.
439
440 int result = S_OK; // Success or error?
441 entity *ent = NULL; // Target entity.
442
443 // Verify incoming arguments.
444 if (paramCount < ARG_MINIMUM
445 || varlist[ARG_ENTITY]->vt != VT_PTR)
446 {
447 *pretvar = NULL;
448 goto error_local;
449 }
450
451 // Populate local handle and property vars.
452 ent = (entity *)varlist[ARG_ENTITY]->ptrVal;
453
454 adjust_bind(ent);
455
456 return result;
457
458 // Error trapping.
459 error_local:
460
461 printf("You must provide a valid entity: " SELF_NAME "\n");
462
463 result = E_FAIL;
464 return result;
465
466 #undef SELF_NAME
467 #undef ARG_MINIMUM
468 #undef ARG_ENTITY
469 }