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 // Level Properties
10 // 2017-04-26
11 // Caskey, Damon V.
12 //
13 // Access to level and level set properties.
14 
15 #include "scriptcommon.h"
16 
17 #define invalid_pointer_input arg_value->vt != VT_PTR && arg_value->vt != VT_EMPTY
18 
19 // Set Handle
20 // Caskey, Damon V.
21 // 2017-04-26
22 //
23 // Get the handle (pointer) of a level set.
24 //
25 // get_set_handle(int index)
openbor_get_set_handle(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)26 HRESULT openbor_get_set_handle(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
27 {
28     #define SELF_NAME       "get_set_handle(int index)"
29     #define ARG_MINIMUM     1   // Minimum required arguments.
30     #define ARG_INDEX       0   // Array index.
31 
32     int                 result;
33     LONG                index;
34     extern s_set_entry *levelsets;
35     extern int          num_difficulties;
36 
37     if(paramCount != ARG_MINIMUM)
38     {
39         goto error_local;
40     }
41 
42     if(FAILED(ScriptVariant_IntegerValue(varlist[ARG_INDEX], &index)))
43     {
44         goto error_local;
45     }
46 
47     ScriptVariant_Clear(*pretvar);
48 
49     // Verify the index is within bounds, and
50     // if so, dereference the array element pointer.
51     if(index < num_difficulties && index >= 0)
52     {
53         ScriptVariant_ChangeType(*pretvar, VT_PTR);
54         (*pretvar)->ptrVal = &levelsets[index];
55     }
56 
57     result = S_OK;
58 
59     return result;
60 
61     // Error trapping.
62     error_local:
63 
64     printf("You must provide a valid index: " SELF_NAME "\n");
65 
66     *pretvar    = NULL;
67     result      = E_FAIL;
68     return result;
69 
70     #undef SELF_NAME
71     #undef ARG_MINIMUM
72     #undef ARG_INDEX
73 }
74 
75 // Set specific properties.
76 // Caskey, Damon V.
77 // 2017-04-25
78 //
79 // Access set property by handle.
80 //
81 // get_set_property(void handle, int frame, int property)
openbor_get_set_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)82 HRESULT openbor_get_set_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
83 {
84     #define SELF_NAME       "get_set_property(void handle, int property)"
85     #define ARG_MINIMUM     2   // Minimum required arguments.
86     #define ARG_HANDLE      0   // Handle (pointer to property structure).
87     #define ARG_PROPERTY    1   // Property to access.
88 
89 
90     int                     result      = S_OK; // Success or error?
91     s_set_entry             *handle     = NULL; // Property handle.
92     e_set_properties        property    = 0;    // Property argument.
93 
94     // Clear pass by reference argument used to send
95     // property data back to calling script.     .
96     ScriptVariant_Clear(*pretvar);
97 
98     // Verify incoming arguments. There should at least
99     // be a pointer for the property handle and an integer
100     // to determine which property is accessed.
101     if(paramCount < ARG_MINIMUM
102        || varlist[ARG_HANDLE]->vt != VT_PTR
103        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
104     {
105         *pretvar = NULL;
106         goto error_local;
107     }
108     else
109     {
110         handle      = (s_set_entry *)varlist[ARG_HANDLE]->ptrVal;
111         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
112     }
113 
114     // Which property to get?
115     switch(property)
116     {
117         case SET_PROP_COMPLETE_FLAG:
118 
119             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
120             (*pretvar)->lVal = (LONG)handle->ifcomplete;
121             break;
122 
123         case SET_PROP_COMPLETE_SKIP:
124 
125             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
126             (*pretvar)->lVal = (LONG)handle->noshowcomplete;
127 
128         case SET_PROP_CONTINUE_SCORE_TYPE:
129 
130             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
131             (*pretvar)->lVal = (LONG)handle->continuescore;
132 
133         case SET_PROP_CREDITS:
134 
135             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
136             (*pretvar)->lVal = (LONG)handle->credits;
137             break;
138 
139         case SET_PROP_GAME_OVER_SKIP:
140 
141             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
142             (*pretvar)->lVal = (LONG)handle->noshowgameover;
143             break;
144 
145         case SET_PROP_HOF_DISABLE:
146 
147             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
148             (*pretvar)->lVal = (LONG)handle->noshowhof;
149             break;
150 
151         case SET_PROP_LEVELSET_COLLECTION:
152 
153             // Verify the handle is populated.
154             if(handle->levelorder)
155             {
156                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
157                 (*pretvar)->ptrVal = (VOID *)handle->levelorder;
158             }
159 
160             break;
161 
162         case SET_PROP_LEVELSET_COUNT:
163 
164             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
165             (*pretvar)->lVal = (LONG)handle->numlevels;
166             break;
167 
168         case SET_PROP_LIVES:
169 
170             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
171             (*pretvar)->lVal = (LONG)handle->lives;
172             break;
173 
174         case SET_PROP_MP_RECOVER_TYPE:
175 
176             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
177             (*pretvar)->lVal = (LONG)handle->typemp;
178             break;
179 
180         case SET_PROP_MUSIC_FADE_TIME:
181 
182             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
183             (*pretvar)->lVal = (LONG)handle->custfade;
184             break;
185 
186         case SET_PROP_MUSIC_OVERLAP:
187 
188             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
189             (*pretvar)->lVal = (LONG)handle->musicoverlap;
190             break;
191 
192         case SET_PROP_NAME:
193 
194             ScriptVariant_ChangeType(*pretvar, VT_STR);
195             (*pretvar)->strVal = StrCache_CreateNewFrom(handle->name);
196             break;
197 
198         case SET_PROP_PLAYER_MAX:
199 
200             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
201             (*pretvar)->lVal = (LONG)handle->maxplayers;
202             break;
203 
204         case SET_PROP_SAVE_TYPE:
205 
206             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
207             (*pretvar)->lVal = (LONG)handle->saveflag;
208             break;
209 
210         case SET_PROP_SELECT_DISABLE:
211 
212             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
213             (*pretvar)->lVal = (LONG)handle->noselect;
214             break;
215 
216         case SET_PROP_SELECT_NO_SAME:
217 
218             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
219             (*pretvar)->lVal = (LONG)handle->nosame;
220             break;
221 
222         default:
223 
224             printf("Unsupported property.\n");
225             goto error_local;
226             break;
227     }
228 
229     return result;
230 
231     // Error trapping.
232     error_local:
233 
234     printf("You must provide a valid handle and property: " SELF_NAME "\n");
235 
236     result = E_FAIL;
237     return result;
238 
239     #undef SELF_NAME
240     #undef ARG_MINIMUM
241     #undef ARG_HANDLE
242     #undef ARG_PROPERTY
243 }
244 
245 // Set specific properties.
246 // Caskey, Damon V.
247 // 2016-10-20
248 //
249 // Access set property by handle (pointer).
250 //
251 // set_set_property(void handle, int property, value)
openbor_set_set_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)252 HRESULT openbor_set_set_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
253 {
254     #define SELF_NAME           "set_set_property(void handle, int property, value)"
255     #define ARG_MINIMUM         3   // Minimum required arguments.
256     #define ARG_HANDLE          0   // Handle (pointer to property structure).
257     #define ARG_PROPERTY        1   // Property to access.
258     #define ARG_VALUE           2   // New value to apply.
259 
260     int                     result      = S_OK; // Success or error?
261     s_set_entry             *handle     = NULL; // Property handle.
262     e_set_properties        property    = 0;    // Property to access.
263 
264     // Value carriers to apply on properties after
265     // taken from argument.
266     //LONG     temp_int;
267     //DOUBLE  temp_float;
268 
269     // Verify incoming arguments. There must be a
270     // pointer for the animation handle, an integer
271     // property, and a new value to apply.
272     if(paramCount < ARG_MINIMUM
273        || varlist[ARG_HANDLE]->vt != VT_PTR
274        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
275     {
276         *pretvar = NULL;
277         goto error_local;
278     }
279     else
280     {
281         handle      = (s_set_entry *)varlist[ARG_HANDLE]->ptrVal;
282         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
283     }
284 
285     // Which property to modify?
286     switch(property)
287     {
288         case SET_PROP_LEVELSET_COLLECTION:
289 
290             handle->levelorder = (s_level_entry *)varlist[ARG_VALUE]->ptrVal;
291 
292             break;
293 
294         default:
295 
296             printf("Unsupported or read only property.\n");
297             goto error_local;
298 
299             break;
300     }
301 
302     return result;
303 
304     // Error trapping.
305     error_local:
306 
307     printf("You must provide a valid handle, property and value: " SELF_NAME "\n");
308 
309     result = E_FAIL;
310     return result;
311 
312     #undef SELF_NAME
313     #undef ARG_MINIMUM
314     #undef ARG_HANDLE
315     #undef ARG_PROPERTY
316     #undef ARG_VALUE
317 }
318 
319 // Level specific properties.
320 // Caskey, Damon V.
321 // 2017-04-25
322 //
323 // Access level property by handle.
324 //
325 // get_level_property(void handle, int property)
openbor_get_level_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)326 HRESULT openbor_get_level_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
327 {
328     #define SELF_NAME       "get_level_property(void handle, int property)"
329     #define ARG_MINIMUM     2   // Minimum required arguments.
330     #define ARG_HANDLE      0   // Handle (pointer to property structure).
331     #define ARG_PROPERTY    1   // Property to access.
332 
333 
334     int                     result      = S_OK; // Success or error?
335     s_level                 *handle     = NULL; // Property handle.
336     e_level_properties      property    = 0;    // Property argument.
337 
338     // Clear pass by reference argument used to send
339     // property data back to calling script.     .
340     ScriptVariant_Clear(*pretvar);
341 
342     // Verify incoming arguments. There should at least
343     // be a pointer for the property handle and an integer
344     // to determine which property is accessed.
345     if(paramCount < ARG_MINIMUM
346        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
347     {
348         *pretvar = NULL;
349         goto error_local;
350     }
351 
352     // If the handle argument is null, and it almost
353     // certainly will be, use current level.
354     // At the time this function was written (2017-04-27),
355     // there was no such thing as a level collection.
356     // OpenBOR loads one level at a time and unloads when
357     // completed to conserve memory. The handle argument
358     // is in place for future compatibility in case this
359     // ever changes.
360     if(varlist[ARG_HANDLE]->vt != VT_PTR)
361     {
362         handle = level;
363     }
364     else
365     {
366         handle = (s_level *)varlist[ARG_HANDLE]->ptrVal;
367     }
368 
369     // Get the property argument.
370     property    = (LONG)varlist[ARG_PROPERTY]->lVal;
371 
372     // Which property to get?
373     switch(property)
374     {
375 
376         case LEVEL_PROP_AUTO_SCROLL_DIRECTION:
377 
378             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
379             (*pretvar)->lVal = (LONG)handle->bgdir;
380             break;
381 
382         case LEVEL_PROP_AUTO_SCROLL_X:
383 
384             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
385             (*pretvar)->dblVal = (DOUBLE)handle->bgspeed;
386             break;
387 
388         case LEVEL_PROP_AUTO_SCROLL_Y:
389 
390             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
391             (*pretvar)->dblVal = (DOUBLE)handle->vbgspeed;
392             break;
393 
394         case LEVEL_PROP_BASEMAP_COLLECTION:
395 
396             // Verify the handle is populated.
397             if(handle->basemaps)
398             {
399                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
400                 (*pretvar)->ptrVal = (VOID *)handle->basemaps;
401             }
402 
403             break;
404 
405         case LEVEL_PROP_BASEMAP_COUNT:
406 
407             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
408             (*pretvar)->lVal = (LONG)handle->numbasemaps;
409             break;
410 
411         case LEVEL_PROP_BOSS_COUNT:
412 
413             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
414             (*pretvar)->lVal = (LONG)handle->bossescount;
415             break;
416 
417         case LEVEL_PROP_BOSS_MUSIC_NAME:
418 
419             ScriptVariant_ChangeType(*pretvar, VT_STR);
420             (*pretvar)->strVal = StrCache_CreateNewFrom(handle->bossmusic);
421             break;
422 
423         case LEVEL_PROP_BOSS_MUSIC_OFFSET:
424 
425             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
426             (*pretvar)->lVal = (LONG)handle->bossmusic_offset;
427             break;
428 
429         case LEVEL_PROP_BOSS_SLOW:
430 
431             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
432             (*pretvar)->lVal = (LONG)handle->boss_slow;
433             break;
434 
435         case LEVEL_PROP_CAMERA_OFFSET_X:
436 
437             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
438             (*pretvar)->lVal = (LONG)handle->cameraxoffset;
439             break;
440 
441         case LEVEL_PROP_CAMERA_OFFSET_Z:
442 
443             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
444             (*pretvar)->lVal = (LONG)handle->camerazoffset;
445             break;
446 
447         case LEVEL_PROP_COMPLETE_FORCE:
448 
449             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
450             (*pretvar)->lVal = (LONG)handle->force_finishlevel;
451             break;
452 
453         case LEVEL_PROP_GAMEOVER:
454 
455             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
456             (*pretvar)->lVal = (LONG)handle->force_gameover;
457             break;
458 
459         case LEVEL_PROP_DAMAGE_FROM_ENEMY:
460 
461             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
462             (*pretvar)->lVal = (LONG)handle->nohurt;
463             break;
464 
465         case LEVEL_PROP_DAMAGE_FROM_PLAYER:
466 
467             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
468             (*pretvar)->lVal = (LONG)handle->nohit;
469             break;
470 
471         case LEVEL_PROP_FACING:
472 
473             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
474             (*pretvar)->lVal = (LONG)handle->facing;
475             break;
476 
477         case LEVEL_PROP_GRAVITY:
478 
479            ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
480             (*pretvar)->dblVal = (DOUBLE)handle->gravity;
481             break;
482 
483 
484         case LEVEL_PROP_HOLE_COLLECTION:
485 
486             // Verify the handle is populated.
487             if(handle->holes)
488             {
489                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
490                 (*pretvar)->ptrVal = (VOID *)handle->holes;
491             }
492 
493             break;
494 
495         case LEVEL_PROP_HOLE_COUNT:
496 
497             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
498             (*pretvar)->lVal = (LONG)handle->numholes;
499             break;
500 
501         case LEVEL_PROP_LAYER_BACKGROUND_DEFAULT_HANDLE:
502 
503             // Verify the handle is populated.
504             if(handle->background)
505             {
506                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
507                 (*pretvar)->ptrVal = (VOID *)handle->background;
508             }
509 
510             break;
511 
512         case LEVEL_PROP_LAYER_BACKGROUND_COLLECTION:
513 
514             // Verify the handle is populated.
515             if(handle->bglayers)
516             {
517                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
518                 (*pretvar)->ptrVal = (VOID *)handle->bglayers;
519             }
520 
521             break;
522 
523         case LEVEL_PROP_LAYER_BACKGROUND_COUNT:
524 
525             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
526             (*pretvar)->lVal = (LONG)handle->numbglayers;
527             break;
528 
529         case LEVEL_PROP_LAYER_COLLECTION:
530 
531             // Verify animation has item.
532             if(handle->layers)
533             {
534                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
535                 (*pretvar)->ptrVal = (VOID *)handle->layers;
536             }
537 
538             break;
539 
540         case LEVEL_PROP_LAYER_COUNT:
541 
542             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
543             (*pretvar)->lVal = (LONG)handle->numlayers;
544             break;
545 
546         case LEVEL_PROP_LAYER_FOREGROUND_COLLECTION:
547 
548             // Verify the handle is populated.
549             if(handle->fglayers)
550             {
551                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
552                 (*pretvar)->ptrVal = (VOID *)handle->fglayers;
553             }
554 
555             break;
556 
557         case LEVEL_PROP_LAYER_FOREGROUND_COUNT:
558 
559             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
560             (*pretvar)->lVal = (LONG)handle->numfglayers;
561             break;
562 
563         case LEVEL_PROP_LAYER_FRONTPANEL_COLLECTION:
564 
565             // Verify the handle is populated.
566             if(handle->frontpanels)
567             {
568                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
569                 (*pretvar)->ptrVal = (VOID *)handle->frontpanels;
570             }
571 
572             break;
573 
574         case LEVEL_PROP_LAYER_FRONTPANEL_COUNT:
575 
576             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
577             (*pretvar)->lVal = (LONG)handle->numfrontpanels;
578             break;
579 
580         case LEVEL_PROP_LAYER_GENERIC_COLLECTION:
581 
582             // Verify the handle is populated.
583             if(handle->genericlayers)
584             {
585                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
586                 (*pretvar)->ptrVal = (VOID *)handle->genericlayers;
587             }
588 
589             break;
590 
591         case LEVEL_PROP_LAYER_GENERIC_COUNT:
592 
593             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
594             (*pretvar)->lVal = (LONG)handle->numgenericlayers;
595             break;
596 
597         case LEVEL_PROP_LAYER_PANEL_COLLECTION:          // s_layer *(*panels)[3]; //normal neon screen
598 
599             // Verify the handle is populated.
600             if(handle->panels)
601             {
602                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
603                 (*pretvar)->ptrVal = (VOID *)handle->panels;
604             }
605 
606             break;
607 
608         case LEVEL_PROP_LAYER_PANEL_COUNT:
609 
610             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
611             (*pretvar)->lVal = (LONG)handle->numpanels;
612             break;
613 
614         case LEVEL_PROP_LAYER_REF_COLLECTION:
615 
616             // Verify the handle is populated.
617             if(handle->layersref)
618             {
619                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
620                 (*pretvar)->ptrVal = (VOID *)handle->layersref;
621             }
622 
623             break;
624 
625         case LEVEL_PROP_LAYER_REF_COUNT:
626 
627             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
628             (*pretvar)->lVal = (LONG)handle->numlayersref;
629             break;
630 
631         case LEVEL_PROP_LAYER_WATER_COLLECTION:
632 
633             // Verify the handle is populated.
634             if(handle->waters)
635             {
636                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
637                 (*pretvar)->ptrVal = (VOID *)handle->waters;
638             }
639 
640             break;
641 
642         case LEVEL_PROP_LAYER_WATER_COUNT:
643 
644             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
645             (*pretvar)->lVal = (LONG)handle->numwaters;
646             break;
647 
648         case LEVEL_PROP_MAX_FALL_VELOCITY:
649 
650             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
651             (*pretvar)->dblVal = (DOUBLE)handle->maxfallspeed;
652             break;
653 
654         case LEVEL_PROP_MAX_TOSS_VELOCITY:
655 
656             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
657             (*pretvar)->dblVal = (DOUBLE)handle->maxtossspeed;
658             break;
659 
660         case LEVEL_PROP_MIRROR:
661 
662             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
663             (*pretvar)->lVal = (LONG)handle->mirror;
664             break;
665 
666         case LEVEL_PROP_NAME:
667 
668             ScriptVariant_ChangeType(*pretvar, VT_STR);
669             (*pretvar)->strVal = StrCache_CreateNewFrom(handle->name);
670             break;
671 
672         case LEVEL_PROP_NUM_BOSSES:
673 
674             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
675             (*pretvar)->lVal = (LONG)handle->numbosses;
676             break;
677 
678         case LEVEL_PROP_PALETTE_BLENDING_COLLECTION:
679 
680             printf("LEVEL_PROP_PALETTE_BLENDING_COLLECTION no longer supported");
681             ScriptVariant_Clear(*pretvar);
682 
683             break;
684 
685         case LEVEL_PROP_PALETTE_COLLECTION:
686 
687             if(handle->palettes)
688             {
689                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
690                 (*pretvar)->ptrVal = (VOID *)handle->palettes;
691             }
692 
693             break;
694 
695         case LEVEL_PROP_PALETTE_COUNT:
696 
697             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
698             (*pretvar)->lVal = (LONG)handle->numpalettes;
699             break;
700 
701         case LEVEL_PROP_POSITION_X:
702 
703             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
704             (*pretvar)->lVal = (LONG)handle->pos;
705             break;
706 
707         case LEVEL_PROP_QUAKE:
708 
709             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
710             (*pretvar)->lVal = (LONG)handle->quake;
711             break;
712 
713         case LEVEL_PROP_QUAKE_TIME:
714 
715             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
716             (*pretvar)->lVal = (LONG)handle->quaketime;
717             break;
718 
719         case LEVEL_PROP_ROCKING:
720 
721             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
722             (*pretvar)->lVal = (LONG)handle->rocking;
723             break;
724 
725         case LEVEL_PROP_SCRIPT_LEVEL_END:
726 
727             //if(&handle->endlevel_script)
728             //{
729                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
730                 (*pretvar)->ptrVal = &handle->endlevel_script;
731             //}
732 
733         case LEVEL_PROP_SCRIPT_LEVEL_START:              // Script level_script;
734 
735             //if(&handle->level_script)
736             //{
737                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
738                 (*pretvar)->ptrVal = &handle->level_script;
739             //}
740 
741         case LEVEL_PROP_SCRIPT_KEY:
742 
743             //if(&handle->key_script)
744             //{
745                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
746                 (*pretvar)->ptrVal = &handle->key_script;
747             //}
748 
749         case LEVEL_PROP_SCRIPT_UPDATE:
750 
751             //if(&handle->update_script)
752             //{
753                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
754                 (*pretvar)->ptrVal = &handle->update_script;
755             //}
756 
757         case LEVEL_PROP_SCRIPT_UPDATED:
758 
759             //if(&handle->updated_script)
760             //{
761                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
762                 (*pretvar)->ptrVal = &handle->updated_script;
763             //}
764 
765         case LEVEL_PROP_SCROLL_DIRECTION:
766 
767             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
768             (*pretvar)->lVal = (LONG)handle->scrolldir;
769             break;
770 
771         case LEVEL_PROP_SCROLL_VELOCITY:
772 
773             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
774             (*pretvar)->lVal = (DOUBLE)handle->scrollspeed;
775             break;
776 
777         case LEVEL_PROP_SIZE_X:
778 
779             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
780             (*pretvar)->lVal = (LONG)handle->width;
781             break;
782 
783         case LEVEL_PROP_SPAWN_COLLECTION:
784 
785             if(handle->spawnpoints)
786             {
787                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
788                 (*pretvar)->ptrVal = (VOID *)handle->spawnpoints;
789             }
790 
791         case LEVEL_PROP_SPAWN_COUNT:
792 
793             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
794             (*pretvar)->lVal = (LONG)handle->numspawns;
795             break;
796 
797         case LEVEL_PROP_SPAWN_PLAYER_COLLECTION:
798 
799             //if(&handle->spawn)
800             //{
801                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
802                 (*pretvar)->ptrVal = (VOID *)handle->spawn;
803             //}
804 
805         case LEVEL_PROP_SPECIAL_DISABLE:
806 
807             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
808             (*pretvar)->lVal = (LONG)handle->nospecial;
809             break;
810 
811         case LEVEL_PROP_TEXT_OBJECT_COLLECTION:          // s_textobj *textobjs;
812 
813             if(handle->textobjs)
814             {
815                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
816                 (*pretvar)->ptrVal = (VOID *)handle->textobjs;
817             }
818 
819         case LEVEL_PROP_TEXT_OBJECT_COUNT:
820 
821             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
822             (*pretvar)->lVal = (LONG)handle->numtextobjs;
823             break;
824 
825         case LEVEL_PROP_TIME_ADVANCE:
826 
827             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
828             (*pretvar)->lVal = (LONG)handle->advancetime;
829             break;
830 
831         case LEVEL_PROP_TIME_DISPLAY:
832 
833             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
834             (*pretvar)->lVal = (LONG)handle->notime;
835             break;
836 
837         case LEVEL_PROP_TIME_RESET:
838 
839             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
840             (*pretvar)->lVal = (LONG)handle->noreset;
841             break;
842 
843         case LEVEL_PROP_TIME_SET:
844 
845             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
846             (*pretvar)->lVal = (LONG)handle->settime;
847             break;
848 
849         case LEVEL_PROP_TYPE:
850 
851             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
852             (*pretvar)->lVal = (LONG)handle->type;
853             break;
854 
855 
856         case LEVEL_PROP_WAITING:
857 
858             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
859             (*pretvar)->lVal = (LONG)handle->waiting;
860             break;
861 
862         case LEVEL_PROP_WALL_COLLECTION:
863 
864             // Verify animation has item.
865             if(handle->walls)
866             {
867                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
868                 (*pretvar)->ptrVal = (VOID *)handle->walls;
869             }
870 
871             break;
872 
873         case LEVEL_PROP_WALL_COUNT:
874 
875             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
876             (*pretvar)->lVal = (LONG)handle->numwalls;
877             break;
878 
879         case LEVEL_PROP_WEAPON:
880 
881             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
882             (*pretvar)->lVal = (LONG)handle->setweap;
883             break;
884 
885         default:
886 
887             printf("Unsupported property.\n");
888             goto error_local;
889             break;
890     }
891 
892     return result;
893 
894     // Error trapping.
895     error_local:
896 
897     printf("You must provide a valid handle and property: " SELF_NAME "\n");
898 
899     result = E_FAIL;
900     return result;
901 
902     #undef SELF_NAME
903     #undef ARG_MINIMUM
904     #undef ARG_HANDLE
905     #undef ARG_PROPERTY
906 }
907 
908 // Level specific properties.
909 // Caskey, Damon V.
910 // 2017-04-25
911 //
912 // Access level property by handle (pointer).
913 //
914 // set_level_property(void handle, int property, value)
openbor_set_level_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)915 HRESULT openbor_set_level_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
916 {
917     #define SELF_NAME           "set_level_property(void handle, int property, value)"
918     #define ARG_MINIMUM         3   // Minimum required arguments.
919     #define ARG_HANDLE          0   // Handle (pointer to property structure).
920     #define ARG_PROPERTY        1   // Property to access.
921     #define ARG_VALUE           2   // New value to apply.
922 
923     int                     result;     // Success or error?
924     s_level                 *handle;    // Property handle.
925     e_level_properties      property;   // Property to access.
926 
927     // Value carriers to apply on properties after
928     // taken from value argument.
929     LONG             temp_int;   // Integer type argument.
930     DOUBLE          temp_float; // Float type argument.
931     ScriptVariant   *arg_value; // Argument input carrier.
932 
933     // Verify incoming arguments. There should at least
934     // be a pointer for the property handle, an integer
935     // to determine which property is accessed and a
936     // new value to apply.
937     if(paramCount < ARG_MINIMUM
938        || varlist[ARG_HANDLE]->vt != VT_PTR
939        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
940     {
941         *pretvar = NULL;
942         goto error_local;
943     }
944     else
945     {
946         handle      = (s_level *)varlist[ARG_HANDLE]->ptrVal;
947         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
948         arg_value   = varlist[ARG_VALUE];
949     }
950 
951     // Which property to modify?
952     switch(property)
953     {
954         case LEVEL_PROP_AUTO_SCROLL_DIRECTION:
955 
956             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
957             {
958                 goto error_local;
959             }
960 
961             handle->bgdir = temp_int;
962             break;
963 
964         case LEVEL_PROP_AUTO_SCROLL_X:
965 
966             if(FAILED(ScriptVariant_DecimalValue(arg_value, &temp_float)))
967             {
968                 goto error_local;
969             }
970 
971             handle->bgspeed = temp_float;
972             break;
973 
974         case LEVEL_PROP_AUTO_SCROLL_Y:
975 
976             if(FAILED(ScriptVariant_DecimalValue(arg_value, &temp_float)))
977             {
978                 goto error_local;
979             }
980 
981             handle->vbgspeed = temp_float;
982             break;
983 
984         case LEVEL_PROP_BASEMAP_COLLECTION:
985 
986             if(invalid_pointer_input)
987             {
988                 goto error_local;
989             }
990 
991             handle->basemaps = (s_basemap *)arg_value->ptrVal;
992             break;
993 
994         case LEVEL_PROP_BASEMAP_COUNT:
995 
996             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
997             {
998                 goto error_local;
999             }
1000 
1001             handle->numbasemaps = temp_int;
1002             break;
1003 
1004         case LEVEL_PROP_BOSS_COUNT:
1005 
1006             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1007             {
1008                 goto error_local;
1009             }
1010 
1011             handle->bossescount = temp_int;
1012             break;
1013 
1014         case LEVEL_PROP_BOSS_MUSIC_NAME:
1015 
1016             if(arg_value->vt != VT_STR)
1017             {
1018                 goto error_local;
1019             }
1020             strcpy(handle->bossmusic, (char *)StrCache_Get(arg_value->strVal));
1021             break;
1022 
1023         case LEVEL_PROP_BOSS_MUSIC_OFFSET:
1024 
1025             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1026             {
1027                 goto error_local;
1028             }
1029 
1030             handle->bossmusic_offset = temp_int;
1031             break;
1032 
1033         case LEVEL_PROP_BOSS_SLOW:
1034 
1035             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1036             {
1037                 goto error_local;
1038             }
1039 
1040             handle->boss_slow = temp_int;
1041             break;
1042 
1043         case LEVEL_PROP_CAMERA_OFFSET_X:
1044 
1045             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1046             {
1047                 goto error_local;
1048             }
1049 
1050             handle->cameraxoffset = temp_int;
1051             break;
1052 
1053         case LEVEL_PROP_CAMERA_OFFSET_Z:
1054 
1055             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1056             {
1057                 goto error_local;
1058             }
1059 
1060             handle->camerazoffset = temp_int;
1061             break;
1062 
1063         case LEVEL_PROP_COMPLETE_FORCE:
1064 
1065             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1066             {
1067                 goto error_local;
1068             }
1069 
1070             handle->force_finishlevel = temp_int;
1071             break;
1072 
1073         case LEVEL_PROP_GAMEOVER:
1074 
1075             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1076             {
1077                 goto error_local;
1078             }
1079 
1080             handle->force_gameover = temp_int;
1081             break;
1082 
1083         case LEVEL_PROP_DAMAGE_FROM_ENEMY:
1084 
1085             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1086             {
1087                 goto error_local;
1088             }
1089 
1090             handle->nohurt = temp_int;
1091             break;
1092 
1093         case LEVEL_PROP_DAMAGE_FROM_PLAYER:
1094 
1095             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1096             {
1097                 goto error_local;
1098             }
1099 
1100             handle->nohit = temp_int;
1101             break;
1102 
1103         case LEVEL_PROP_FACING:
1104 
1105             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1106             {
1107                 goto error_local;
1108             }
1109 
1110             handle->facing = temp_int;
1111             break;
1112 
1113         case LEVEL_PROP_GRAVITY:
1114 
1115             if(FAILED(ScriptVariant_DecimalValue(arg_value, &temp_float)))
1116             {
1117                 goto error_local;
1118             }
1119 
1120             handle->gravity = temp_float;
1121             break;
1122 
1123         case LEVEL_PROP_HOLE_COLLECTION:
1124 
1125             if(invalid_pointer_input)
1126             {
1127                 goto error_local;
1128             }
1129 
1130             handle->holes = (s_terrain *)arg_value->ptrVal;
1131             break;
1132 
1133         case LEVEL_PROP_HOLE_COUNT:
1134 
1135             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1136             {
1137                 goto error_local;
1138             }
1139 
1140             handle->numholes = temp_int;
1141             break;
1142 
1143         case LEVEL_PROP_LAYER_BACKGROUND_DEFAULT_HANDLE:
1144 
1145             if(invalid_pointer_input)
1146             {
1147                 goto error_local;
1148             }
1149 
1150             handle->background = (s_layer *)arg_value->ptrVal;
1151             break;
1152 
1153         case LEVEL_PROP_LAYER_BACKGROUND_COLLECTION:
1154 
1155             if(invalid_pointer_input)
1156             {
1157                 goto error_local;
1158             }
1159 
1160             handle->bglayers = (s_layer **)varlist[ARG_VALUE]->ptrVal;
1161 
1162             break;
1163 
1164         case LEVEL_PROP_LAYER_BACKGROUND_COUNT:
1165 
1166             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1167             {
1168                 goto error_local;
1169             }
1170 
1171             handle->numbglayers = temp_int;
1172             break;
1173 
1174         case LEVEL_PROP_LAYER_COLLECTION:
1175 
1176             if(invalid_pointer_input)
1177             {
1178                 goto error_local;
1179             }
1180 
1181             handle->layers = (s_layer *)arg_value->ptrVal;
1182             break;
1183 
1184         case LEVEL_PROP_LAYER_COUNT:
1185 
1186             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1187             {
1188                 goto error_local;
1189             }
1190 
1191             handle->numlayers = temp_int;
1192             break;
1193 
1194         case LEVEL_PROP_LAYER_FOREGROUND_COLLECTION:
1195 
1196             if(invalid_pointer_input)
1197             {
1198                 goto error_local;
1199             }
1200 
1201             handle->fglayers = (s_layer **)arg_value->ptrVal;
1202             break;
1203 
1204         case LEVEL_PROP_LAYER_FOREGROUND_COUNT:
1205 
1206             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1207             {
1208                 goto error_local;
1209             }
1210 
1211             handle->numfglayers = temp_int;
1212             break;
1213 
1214         case LEVEL_PROP_LAYER_FRONTPANEL_COLLECTION:
1215 
1216            if(invalid_pointer_input)
1217             {
1218                 goto error_local;
1219             }
1220 
1221             handle->frontpanels = (s_layer **)arg_value->ptrVal;
1222             break;
1223 
1224         case LEVEL_PROP_LAYER_FRONTPANEL_COUNT:
1225 
1226             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1227             {
1228                 goto error_local;
1229             }
1230 
1231             handle->numfrontpanels = temp_int;
1232             break;
1233 
1234         case LEVEL_PROP_LAYER_GENERIC_COLLECTION:
1235 
1236             if(invalid_pointer_input)
1237             {
1238                 goto error_local;
1239             }
1240 
1241             handle->genericlayers = (s_layer **)arg_value->ptrVal;
1242             break;
1243 
1244         case LEVEL_PROP_LAYER_GENERIC_COUNT:
1245 
1246             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1247             {
1248                 goto error_local;
1249             }
1250 
1251             handle->numgenericlayers = temp_int;
1252             break;
1253 
1254         case LEVEL_PROP_LAYER_PANEL_COLLECTION:
1255 
1256             if(invalid_pointer_input)
1257             {
1258                 goto error_local;
1259             }
1260 
1261             handle->panels = (VOID *)arg_value->ptrVal;
1262             break;
1263 
1264         case LEVEL_PROP_LAYER_PANEL_COUNT:
1265 
1266             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1267             {
1268                 goto error_local;
1269             }
1270 
1271             handle->numpanels = temp_int;
1272             break;
1273 
1274         case LEVEL_PROP_LAYER_REF_COLLECTION:
1275 
1276             if(invalid_pointer_input)
1277             {
1278                 goto error_local;
1279             }
1280 
1281             handle->layersref = (s_layer *)arg_value->ptrVal;
1282             break;
1283 
1284         case LEVEL_PROP_LAYER_REF_COUNT:
1285 
1286             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1287             {
1288                 goto error_local;
1289             }
1290 
1291             handle->numlayersref = temp_int;
1292             break;
1293 
1294         case LEVEL_PROP_LAYER_WATER_COLLECTION:
1295 
1296             if(invalid_pointer_input)
1297             {
1298                 goto error_local;
1299             }
1300 
1301             handle->waters = (s_layer **)arg_value->ptrVal;
1302             break;
1303 
1304         case LEVEL_PROP_LAYER_WATER_COUNT:
1305 
1306             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1307             {
1308                 goto error_local;
1309             }
1310 
1311             handle->numwaters = temp_int;
1312             break;
1313 
1314         case LEVEL_PROP_MAX_FALL_VELOCITY:
1315 
1316             if(FAILED(ScriptVariant_DecimalValue(arg_value, &temp_float)))
1317             {
1318                 goto error_local;
1319             }
1320 
1321             handle->maxfallspeed = temp_float;
1322             break;
1323 
1324         case LEVEL_PROP_MAX_TOSS_VELOCITY:
1325 
1326             if(FAILED(ScriptVariant_DecimalValue(arg_value, &temp_float)))
1327             {
1328                 goto error_local;
1329             }
1330 
1331             handle->maxtossspeed = temp_float;
1332             break;
1333 
1334         case LEVEL_PROP_MIRROR:
1335 
1336             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1337             {
1338                 goto error_local;
1339             }
1340 
1341             handle->mirror = temp_int;
1342             break;
1343 
1344         case LEVEL_PROP_NAME:
1345 
1346             if(arg_value->vt != VT_STR)
1347             {
1348                 goto error_local;
1349             }
1350             strcpy(handle->name, (char *)StrCache_Get(arg_value->strVal));
1351             break;
1352 
1353         case LEVEL_PROP_NUM_BOSSES:
1354 
1355             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1356             {
1357                 goto error_local;
1358             }
1359 
1360             handle->numbosses = temp_int;
1361             break;
1362 
1363         case LEVEL_PROP_PALETTE_BLENDING_COLLECTION:
1364 
1365             // This property is read only.
1366             goto error_local;
1367             break;
1368 
1369         case LEVEL_PROP_PALETTE_COLLECTION:
1370 
1371             if(invalid_pointer_input)
1372             {
1373                 goto error_local;
1374             }
1375 
1376             handle->palettes = (VOID *)arg_value->ptrVal;
1377             break;
1378 
1379         case LEVEL_PROP_PALETTE_COUNT:
1380 
1381             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1382             {
1383                 goto error_local;
1384             }
1385 
1386             handle->numpalettes = temp_int;
1387             break;
1388 
1389         case LEVEL_PROP_POSITION_X:
1390 
1391             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1392             {
1393                 goto error_local;
1394             }
1395 
1396             handle->pos = temp_int;
1397             break;
1398 
1399         case LEVEL_PROP_QUAKE:
1400 
1401             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1402             {
1403                 goto error_local;
1404             }
1405 
1406             handle->quake = temp_int;
1407             break;
1408 
1409         case LEVEL_PROP_QUAKE_TIME:
1410 
1411             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1412             {
1413                 goto error_local;
1414             }
1415 
1416             handle->quaketime = temp_int;
1417             break;
1418 
1419         case LEVEL_PROP_ROCKING:
1420 
1421             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1422             {
1423                 goto error_local;
1424             }
1425 
1426             handle->rocking = temp_int;
1427             break;
1428 
1429         case LEVEL_PROP_SCRIPT_LEVEL_END:
1430 
1431             if(invalid_pointer_input)
1432             {
1433                 goto error_local;
1434             }
1435 
1436             handle->endlevel_script = *(Script *)arg_value->ptrVal;
1437             break;
1438 
1439         case LEVEL_PROP_SCRIPT_LEVEL_START:              // Script level_script;
1440 
1441             if(invalid_pointer_input)
1442             {
1443                 goto error_local;
1444             }
1445             handle->level_script = *(Script *)arg_value->ptrVal;
1446             break;
1447 
1448         case LEVEL_PROP_SCRIPT_KEY:
1449 
1450             if(invalid_pointer_input)
1451             {
1452                 goto error_local;
1453             }
1454 
1455             handle->key_script = *(Script *)arg_value->ptrVal;
1456             break;
1457 
1458         case LEVEL_PROP_SCRIPT_UPDATE:
1459 
1460             if(invalid_pointer_input)
1461             {
1462                 goto error_local;
1463             }
1464 
1465             handle->update_script = *(Script *)arg_value->ptrVal;
1466             break;
1467 
1468         case LEVEL_PROP_SCRIPT_UPDATED:
1469 
1470             if(invalid_pointer_input)
1471             {
1472                 goto error_local;
1473             }
1474 
1475             handle->updated_script = *(Script *)arg_value->ptrVal;
1476             break;
1477 
1478         case LEVEL_PROP_SCROLL_DIRECTION:
1479 
1480             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1481             {
1482                 goto error_local;
1483             }
1484 
1485             handle->scrolldir = temp_int;
1486             break;
1487 
1488         case LEVEL_PROP_SCROLL_VELOCITY:
1489 
1490             if(FAILED(ScriptVariant_DecimalValue(arg_value, &temp_float)))
1491             {
1492                 goto error_local;
1493             }
1494 
1495             handle->scrollspeed = temp_float;
1496             break;
1497 
1498         case LEVEL_PROP_SIZE_X:
1499 
1500             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1501             {
1502                 goto error_local;
1503             }
1504 
1505             handle->width = temp_int;
1506             break;
1507 
1508         case LEVEL_PROP_SPAWN_COLLECTION:
1509 
1510             if(invalid_pointer_input)
1511             {
1512                 goto error_local;
1513             }
1514 
1515             handle->spawnpoints = (s_spawn_entry *)arg_value->ptrVal;
1516             break;
1517 
1518         case LEVEL_PROP_SPAWN_COUNT:
1519 
1520             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1521             {
1522                 goto error_local;
1523             }
1524 
1525             handle->numspawns = temp_int;
1526             break;
1527 
1528         case LEVEL_PROP_SPAWN_PLAYER_COLLECTION:
1529 
1530             if(invalid_pointer_input)
1531             {
1532                 goto error_local;
1533             }
1534 
1535             handle->spawn = (s_axis_principal_float *)arg_value->ptrVal;
1536             break;
1537 
1538         case LEVEL_PROP_SPECIAL_DISABLE:
1539 
1540             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1541             {
1542                 goto error_local;
1543             }
1544 
1545             handle->nospecial = temp_int;
1546             break;
1547 
1548         case LEVEL_PROP_TEXT_OBJECT_COLLECTION:
1549 
1550             if(invalid_pointer_input)
1551             {
1552                 goto error_local;
1553             }
1554 
1555             handle->textobjs = (s_textobj *)arg_value->ptrVal;
1556             break;
1557 
1558         case LEVEL_PROP_TEXT_OBJECT_COUNT:
1559 
1560             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1561             {
1562                 goto error_local;
1563             }
1564 
1565             handle->numtextobjs = temp_int;
1566             break;
1567 
1568         case LEVEL_PROP_TIME_ADVANCE:
1569 
1570             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1571             {
1572                 goto error_local;
1573             }
1574 
1575             handle->advancetime = temp_int;
1576             break;
1577 
1578         case LEVEL_PROP_TIME_DISPLAY:
1579 
1580             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1581             {
1582                 goto error_local;
1583             }
1584 
1585             handle->notime = temp_int;
1586             break;
1587 
1588         case LEVEL_PROP_TIME_RESET:
1589 
1590             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1591             {
1592                 goto error_local;
1593             }
1594 
1595             handle->noreset = temp_int;
1596             break;
1597 
1598         case LEVEL_PROP_TIME_SET:
1599 
1600             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1601             {
1602                 goto error_local;
1603             }
1604 
1605             handle->settime = temp_int;
1606             break;
1607 
1608         case LEVEL_PROP_TYPE:
1609 
1610             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1611             {
1612                 goto error_local;
1613             }
1614 
1615             handle->type = temp_int;
1616             break;
1617 
1618 
1619         case LEVEL_PROP_WAITING:
1620 
1621             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1622             {
1623                 goto error_local;
1624             }
1625 
1626             handle->waiting = temp_int;
1627             break;
1628 
1629         case LEVEL_PROP_WALL_COLLECTION:
1630 
1631             // Verify animation has item.
1632             if(handle->walls)
1633             {
1634                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
1635                 (*pretvar)->ptrVal = (VOID *)handle->walls;
1636             }
1637 
1638             break;
1639 
1640         case LEVEL_PROP_WALL_COUNT:
1641 
1642             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1643             {
1644                 goto error_local;
1645             }
1646 
1647             handle->numwalls = temp_int;
1648             break;
1649 
1650         case LEVEL_PROP_WEAPON:
1651 
1652             if(FAILED(ScriptVariant_IntegerValue(arg_value, &temp_int)))
1653             {
1654                 goto error_local;
1655             }
1656 
1657             handle->setweap = temp_int;
1658             break;
1659 
1660 
1661     }
1662 
1663 
1664     result = S_OK;
1665 
1666     return result;
1667 
1668     // Error trapping.
1669     error_local:
1670 
1671     printf("You must provide a valid handle and property: " SELF_NAME "\n");
1672 
1673     result = E_FAIL;
1674     return result;
1675 
1676     #undef SELF_NAME
1677     #undef ARG_MINIMUM
1678     #undef ARG_HANDLE
1679     #undef ARG_PROPERTY
1680     #undef ARG_VALUE
1681 }
1682 
1683 // ===== Depreciated =====
1684 //
1685 // The following items are depreciated as
1686 // of 2017-04-26 and are included only for
1687 // backward compatibility. Do not add to or
1688 // update.
1689 //
1690 // DC
1691 
1692 // ===== level properties ======
1693 enum levelproperty_enum
1694 {
1695     _lp_basemap,
1696     _lp_bgspeed,
1697     _lp_cameraxoffset,
1698     _lp_camerazoffset,
1699     _lp_gravity,
1700     _lp_hole,
1701     _lp_maxfallspeed,
1702     _lp_maxtossspeed,
1703     _lp_quake,
1704     _lp_rocking,
1705     _lp_scrollspeed,
1706     _lp_type,
1707     _lp_vbgspeed,
1708     _lp_wall,
1709     _lp_the_end,
1710 };
1711 
1712 enum basemap_enum
1713 {
1714     _lp_bm_map,
1715     _lp_bm_x,
1716     _lp_bm_xsize,
1717     _lp_bm_z,
1718     _lp_bm_zsize,
1719     _lp_bm_the_end,
1720 };
1721 
1722 enum terrain_enum
1723 {
1724     _lp_terrain_depth,
1725     _lp_terrain_height,
1726     _lp_terrain_lowerleft,
1727     _lp_terrain_lowerright,
1728     _lp_terrain_type,
1729     _lp_terrain_upperleft,
1730     _lp_terrain_upperright,
1731     _lp_terrain_x,
1732     _lp_terrain_z,
1733     _lp_terrain_the_end,
1734 };
1735 
mapstrings_levelproperty(ScriptVariant ** varlist,int paramCount)1736 int mapstrings_levelproperty(ScriptVariant **varlist, int paramCount)
1737 {
1738     char *propname = NULL;
1739     int prop;
1740 
1741     static const char *proplist[] =
1742     {
1743         "basemap",
1744         "bgspeed",
1745         "cameraxoffset",
1746         "camerazoffset",
1747         "gravity",
1748         "hole",
1749         "maxfallspeed",
1750         "maxtossspeed",
1751         "quake",
1752         "rocking",
1753         "scrollspeed",
1754         "type",
1755         "vbgspeed",
1756         "wall",
1757     };
1758 
1759     static const char *basemaplist[] =
1760     {
1761         "map",
1762         "x",
1763         "xsize",
1764         "z",
1765         "zsize",
1766     };
1767 
1768     static const char *terrainlist[] =
1769     {
1770         /*
1771         Walls and holes.
1772         */
1773 
1774         "depth",
1775         "height",
1776         "lowerleft",
1777         "lowerright",
1778         "type",
1779         "upperleft",
1780         "upperright",
1781         "x",
1782         "z",
1783     };
1784 
1785     if(paramCount < 1)
1786     {
1787         return 1;
1788     }
1789     MAPSTRINGS(varlist[0], proplist, _lp_the_end,
1790                "Level property '%s' is not supported.\n");
1791 
1792     if(paramCount >= 3 && varlist[0]->vt == VT_INTEGER && varlist[0]->lVal == _lp_basemap)
1793     {
1794         MAPSTRINGS(varlist[2], basemaplist, _lp_bm_the_end,
1795                    _is_not_supported_by_, "basemap");
1796     }
1797 
1798     if(paramCount >= 3 && varlist[0]->vt == VT_INTEGER && (varlist[0]->lVal == _lp_hole || varlist[0]->lVal == _lp_wall))
1799     {
1800         MAPSTRINGS(varlist[2], terrainlist, _lp_terrain_the_end,
1801                    _is_not_supported_by_, "wall/hole");
1802     }
1803 
1804     return 1;
1805 }
1806 
openbor_getlevelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1807 HRESULT openbor_getlevelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1808 {
1809     LONG ltemp;
1810     DOUBLE dbltemp2, dbltemp3;
1811     mapstrings_levelproperty(varlist, paramCount);
1812 
1813     switch(varlist[0]->lVal)
1814     {
1815     case _lp_bgspeed:
1816     {
1817         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1818         (*pretvar)->dblVal = (DOUBLE)level->bgspeed;
1819         break;
1820     }
1821     case _lp_vbgspeed:
1822     {
1823         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1824         (*pretvar)->dblVal = (DOUBLE)level->vbgspeed;
1825         break;
1826     }
1827     case _lp_cameraxoffset:
1828     {
1829         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1830         (*pretvar)->lVal = (LONG)level->cameraxoffset;
1831         break;
1832     }
1833     case _lp_camerazoffset:
1834     {
1835         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1836         (*pretvar)->lVal = (LONG)level->camerazoffset;
1837         break;
1838     }
1839     case _lp_gravity:
1840     {
1841         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1842         (*pretvar)->dblVal = (DOUBLE)level->gravity;
1843         break;
1844     }
1845     case _lp_maxfallspeed:
1846     {
1847         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1848         (*pretvar)->dblVal = (DOUBLE)level->maxfallspeed;
1849         break;
1850     }
1851     case _lp_maxtossspeed:
1852     {
1853         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1854         (*pretvar)->dblVal = (DOUBLE)level->maxtossspeed;
1855         break;
1856     }
1857     case _lp_quake:
1858     {
1859         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1860         (*pretvar)->lVal = (LONG)level->quake;
1861         break;
1862     }
1863     case _lp_scrollspeed:
1864     {
1865         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1866         (*pretvar)->dblVal = (DOUBLE)level->scrollspeed;
1867         break;
1868     }
1869     case _lp_type:
1870     {
1871         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1872         (*pretvar)->lVal = (LONG)level->type;
1873         break;
1874     }
1875     case _lp_hole:
1876     {
1877 
1878         if(paramCount > 2 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp))
1879                 && ltemp >= 0 && ltemp < level->numholes)
1880         {
1881 
1882             if(varlist[2]->vt != VT_INTEGER)
1883             {
1884                 printf("You must provide a string value for hole subproperty.\n");
1885                 goto getlevelproperty_error;
1886             }
1887 
1888             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1889 
1890             switch(varlist[2]->lVal)
1891             {
1892                 case _lp_terrain_height:
1893                 {
1894                     (*pretvar)->dblVal = level->holes[ltemp].height;
1895                     break;
1896                 }
1897                 case _lp_terrain_depth:
1898                 {
1899                     (*pretvar)->dblVal = level->holes[ltemp].depth;
1900                     break;
1901                 }
1902                 case _lp_terrain_lowerleft:
1903                 {
1904                     (*pretvar)->dblVal = level->holes[ltemp].lowerleft;
1905                     break;
1906                 }
1907                 case _lp_terrain_lowerright:
1908                 {
1909                     (*pretvar)->dblVal = level->holes[ltemp].lowerright;
1910                     break;
1911                 }
1912                 case _lp_terrain_upperleft:
1913                 {
1914                     (*pretvar)->dblVal = level->holes[ltemp].upperleft;
1915                     break;
1916                 }
1917                 case _lp_terrain_upperright:
1918                 {
1919                     (*pretvar)->dblVal = level->holes[ltemp].upperright;
1920                     break;
1921                 }
1922                 case _lp_terrain_x:
1923                 {
1924                     (*pretvar)->dblVal = level->holes[ltemp].x;
1925                     break;
1926                 }
1927                 case _lp_terrain_z:
1928                 {
1929                     (*pretvar)->dblVal = level->holes[ltemp].z;
1930                     break;
1931                 }
1932                 case _lp_terrain_type:
1933                 {
1934                     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1935                     (*pretvar)->lVal = level->holes[ltemp].type;
1936                     break;
1937                 }
1938                 default:
1939                 {
1940                     printf("Invalid subproperty for hole.\n");
1941                     goto getlevelproperty_error;
1942                 }
1943             }
1944         }
1945         else
1946         {
1947             printf("Error in wall property.\n");
1948             goto getlevelproperty_error;
1949         }
1950         break;
1951 
1952     }
1953     case _lp_wall:
1954     {
1955         if(paramCount > 2 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp))
1956                 && ltemp >= 0 && ltemp < level->numwalls)
1957         {
1958 
1959             if(varlist[2]->vt != VT_INTEGER)
1960             {
1961                 printf("You must provide a string value for wall subproperty.\n");
1962                 goto getlevelproperty_error;
1963             }
1964 
1965             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
1966 
1967             switch(varlist[2]->lVal)
1968             {
1969                 case _lp_terrain_depth:
1970                 {
1971                     (*pretvar)->dblVal = level->walls[ltemp].depth;
1972                     break;
1973                 }
1974                 case _lp_terrain_height:
1975                 {
1976                     (*pretvar)->dblVal = level->walls[ltemp].height;
1977                     break;
1978                 }
1979                 case _lp_terrain_lowerleft:
1980                 {
1981                     (*pretvar)->dblVal = level->walls[ltemp].lowerleft;
1982                     break;
1983                 }
1984                 case _lp_terrain_lowerright:
1985                 {
1986                     (*pretvar)->dblVal = level->walls[ltemp].lowerright;
1987                     break;
1988                 }
1989                 case _lp_terrain_upperleft:
1990                 {
1991                     (*pretvar)->dblVal = level->walls[ltemp].upperleft;
1992                     break;
1993                 }
1994                 case _lp_terrain_upperright:
1995                 {
1996                     (*pretvar)->dblVal = level->walls[ltemp].upperright;
1997                     break;
1998                 }
1999                 case _lp_terrain_x:
2000                 {
2001                     (*pretvar)->dblVal = level->walls[ltemp].x;
2002                     break;
2003                 }
2004                 case _lp_terrain_z:
2005                 {
2006                     (*pretvar)->dblVal = level->walls[ltemp].z;
2007                     break;
2008                 }
2009                 case _lp_terrain_type:
2010                 {
2011                     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2012                     (*pretvar)->lVal = level->walls[ltemp].type;
2013                     break;
2014                 }
2015                 default:
2016                 {
2017                     printf("Invalid subproperty for wall.\n");
2018                     goto getlevelproperty_error;
2019                 }
2020             }
2021         }
2022         else
2023         {
2024             printf("Error in wall property.\n");
2025             goto getlevelproperty_error;
2026         }
2027         break;
2028     }
2029     case _lp_basemap:
2030         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0 && ltemp < level->numbasemaps)
2031         {
2032             if(paramCount >= 3)
2033             {
2034 
2035                 if(varlist[2]->vt != VT_INTEGER)
2036                 {
2037                     printf("You must provide a string value for basemap subproperty.\n");
2038                     goto getlevelproperty_error;
2039                 }
2040 
2041                 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2042 
2043                 switch(varlist[2]->lVal)
2044                 {
2045                 case _lp_bm_x:
2046                     (*pretvar)->dblVal = level->basemaps[ltemp].position.x;
2047                     break;
2048                 case _lp_bm_xsize:
2049                     (*pretvar)->dblVal = level->basemaps[ltemp].size.x;
2050                     break;
2051                 case _lp_bm_z:
2052                     (*pretvar)->dblVal = level->basemaps[ltemp].position.z;
2053                     break;
2054                 case _lp_bm_zsize:
2055                     (*pretvar)->dblVal = level->basemaps[ltemp].size.z;
2056                     break;
2057                 case _lp_bm_map:
2058                     if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) &&
2059                             SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp3)) &&
2060                             dbltemp2 >= 0 && dbltemp2 < level->basemaps[ltemp].size.x && dbltemp3 >= 0 && dbltemp3 < level->basemaps[ltemp].size.z
2061                       )
2062                     {
2063                         if(!level->basemaps[ltemp].map)
2064                         {
2065                             (*pretvar)->dblVal = (DOUBLE)0;
2066                         }
2067                         else (*pretvar)->dblVal = (DOUBLE)level->basemaps[ltemp].map[(LONG)(dbltemp2 + dbltemp3 * level->basemaps[ltemp].size.x)];
2068                     }
2069                     else
2070                     {
2071                         goto getlevelproperty_error;
2072                     }
2073                     break;
2074                 default:
2075                     goto getlevelproperty_error;
2076                 }
2077             }
2078             else
2079             {
2080                 goto getlevelproperty_error;
2081             }
2082         }
2083         else
2084         {
2085             goto getlevelproperty_error;
2086         }
2087         break;
2088     default:
2089         printf("Property is not supported by function getlevelproperty yet. %d\n", varlist[0]->lVal);
2090         goto getlevelproperty_error;
2091         break;
2092     }
2093 
2094     return S_OK;
2095 
2096 getlevelproperty_error:
2097     *pretvar = NULL;
2098     return E_FAIL;
2099 }
2100 
2101 //changelevelproperty(name, value)
openbor_changelevelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2102 HRESULT openbor_changelevelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2103 {
2104     LONG ltemp, ltemp1;
2105     DOUBLE dbltemp, dbltemp2, dbltemp3;
2106     static char buf[64];
2107     int i;
2108     ScriptVariant *arg = NULL;
2109 
2110     *pretvar = NULL;
2111 
2112     if(paramCount < 2)
2113     {
2114         printf("Function changelevelproperty(prop, value) need at least 2 parameters.\n");
2115         return E_FAIL;
2116     }
2117 
2118     mapstrings_levelproperty(varlist, paramCount);
2119 
2120     arg = varlist[1];
2121 
2122     switch(varlist[0]->lVal)
2123     {
2124     case _lp_rocking:
2125         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
2126         {
2127             level->rocking = (int)ltemp;
2128         }
2129         else
2130         {
2131             goto clperror;
2132         }
2133         break;
2134     case _lp_bgspeed:
2135         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
2136         {
2137             level->bgspeed = (float)dbltemp;
2138         }
2139         else
2140         {
2141             goto clperror;
2142         }
2143         break;
2144     case _lp_vbgspeed:
2145         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
2146         {
2147             level->vbgspeed = (float)dbltemp;
2148         }
2149         else
2150         {
2151             goto clperror;
2152         }
2153         break;
2154     case _lp_scrollspeed:
2155         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
2156         {
2157             level->scrollspeed = (float)dbltemp;
2158         }
2159         else
2160         {
2161             goto clperror;
2162         }
2163         break;
2164     case _lp_type:
2165         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
2166         {
2167             level->type = (int)ltemp;
2168         }
2169         else
2170         {
2171             goto clperror;
2172         }
2173         break;
2174     case _lp_cameraxoffset:
2175         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
2176         {
2177             level->cameraxoffset = (int)ltemp;
2178         }
2179         else
2180         {
2181             goto clperror;
2182         }
2183         break;
2184     case _lp_camerazoffset:
2185         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
2186         {
2187             level->camerazoffset = (int)ltemp;
2188         }
2189         else
2190         {
2191             goto clperror;
2192         }
2193         break;
2194     case _lp_gravity:
2195         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
2196         {
2197             level->gravity = (float)dbltemp;
2198         }
2199         else
2200         {
2201             goto clperror;
2202         }
2203         break;
2204     case _lp_maxfallspeed:
2205         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
2206         {
2207             level->maxfallspeed = (float)dbltemp;
2208         }
2209         else
2210         {
2211             goto clperror;
2212         }
2213         break;
2214     case _lp_maxtossspeed:
2215         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
2216         {
2217             level->maxtossspeed = (float)dbltemp;
2218         }
2219         else
2220         {
2221             goto clperror;
2222         }
2223         break;
2224     case _lp_quake:
2225         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
2226         {
2227             level->quake = (int)ltemp;
2228         }
2229         else
2230         {
2231             goto clperror;
2232         }
2233         break;
2234     case _lp_basemap:
2235         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0)
2236         {
2237             if(ltemp >= level->numbasemaps)
2238             {
2239                 __reallocto(level->basemaps, level->numbasemaps, ltemp + 1);
2240                 level->numbasemaps = ltemp + 1;
2241             }
2242             if(paramCount >= 4)
2243             {
2244                 switch(varlist[2]->lVal)
2245                 {
2246                 case _lp_bm_x:
2247                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
2248                     {
2249                         level->basemaps[ltemp].position.x = dbltemp2;
2250                     }
2251                     else
2252                     {
2253                         goto clperror;
2254                     }
2255                     break;
2256                 case _lp_bm_xsize:
2257                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
2258                     {
2259                         level->basemaps[ltemp].size.x = dbltemp2;
2260                     }
2261                     else
2262                     {
2263                         goto clperror;
2264                     }
2265                     break;
2266                 case _lp_bm_z:
2267                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
2268                     {
2269                         level->basemaps[ltemp].position.z = dbltemp2;
2270                     }
2271                     else
2272                     {
2273                         goto clperror;
2274                     }
2275                     break;
2276                 case _lp_bm_zsize:
2277                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
2278                     {
2279                         level->basemaps[ltemp].size.z = dbltemp2;
2280                     }
2281                     else
2282                     {
2283                         goto clperror;
2284                     }
2285                     break;
2286                 case _lp_bm_map:
2287                     if(paramCount >= 6 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) &&
2288                             SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp3)) &&
2289                             SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)) &&
2290                             dbltemp2 >= 0 && dbltemp2 < level->basemaps[ltemp].size.x && dbltemp3 >= 0 && dbltemp3 < level->basemaps[ltemp].size.z
2291                       )
2292                     {
2293                         if(!level->basemaps[ltemp].map)
2294                         {
2295                             level->basemaps[ltemp].map = calloc( 1, (LONG)(sizeof(*(level->basemaps[ltemp].map)) * (level->basemaps[ltemp].size.x+1)*(level->basemaps[ltemp].size.z+1)) );
2296                         }
2297                         level->basemaps[ltemp].map[(LONG)(dbltemp2 + dbltemp3 * level->basemaps[ltemp].size.x)] = (float)dbltemp;
2298                     }
2299                     else
2300                     {
2301                         goto clperror;
2302                     }
2303                     break;
2304                 default:
2305                     goto clperror;
2306                 }
2307             }
2308             else
2309             {
2310                 goto clperror;
2311             }
2312         }
2313         else
2314         {
2315             goto clperror;
2316         }
2317         break;
2318     case _lp_hole:
2319     {
2320         if( SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0
2321            && ( SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)) || SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp1)) ) )
2322         {
2323             if(varlist[2]->vt != VT_INTEGER)
2324             {
2325                 printf("You must provide a string value for hole subproperty.\n");
2326                 goto clperror;
2327             }
2328 
2329             if(ltemp >= level->numholes)
2330             {
2331                 __reallocto(level->holes, level->numholes, ltemp + 1);
2332                 level->numholes = ltemp + 1;
2333             }
2334 
2335             switch(varlist[2]->lVal)
2336             {
2337                 case _lp_terrain_height:
2338                 {
2339                     level->holes[ltemp].height = dbltemp;
2340                     break;
2341                 }
2342                 case _lp_terrain_depth:
2343                 {
2344                     level->holes[ltemp].depth = dbltemp;
2345                     break;
2346                 }
2347                 case _lp_terrain_lowerleft:
2348                 {
2349                     level->holes[ltemp].lowerleft = dbltemp;
2350                     break;
2351                 }
2352                 case _lp_terrain_lowerright:
2353                 {
2354                     level->holes[ltemp].lowerright = dbltemp;
2355                     break;
2356                 }
2357                 case _lp_terrain_upperleft:
2358                 {
2359                     level->holes[ltemp].upperleft = dbltemp;
2360                     break;
2361                 }
2362                 case _lp_terrain_upperright:
2363                 {
2364                     level->holes[ltemp].upperright = dbltemp;
2365                     break;
2366                 }
2367                 case _lp_terrain_x:
2368                 {
2369                     level->holes[ltemp].x = dbltemp;
2370                     break;
2371                 }
2372                 case _lp_terrain_z:
2373                 {
2374                     level->holes[ltemp].z = dbltemp;
2375                     break;
2376                 }
2377                 case _lp_terrain_type:
2378                 {
2379                     level->holes[ltemp].type = ltemp1;
2380                     break;
2381                 }
2382                 default:
2383                 {
2384                     printf("Invalid subproperty for hole.\n");
2385                     goto clperror;
2386                 }
2387             }
2388         }
2389         else
2390         {
2391             goto clperror;
2392         }
2393         break;
2394 
2395     }
2396     case _lp_wall:
2397     {
2398         if( SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0
2399            && ( SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)) || SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp1)) ) )
2400         {
2401             if(varlist[2]->vt != VT_INTEGER)
2402             {
2403                 printf("You must provide a string value for wall subproperty.\n");
2404                 goto clperror;
2405             }
2406 
2407             if(ltemp >= level->numwalls)
2408             {
2409                 __reallocto(level->walls, level->numwalls, ltemp + 1);
2410                 level->numwalls = ltemp + 1;
2411             }
2412 
2413             switch(varlist[2]->lVal)
2414             {
2415                 case _lp_terrain_depth:
2416                 {
2417                     level->walls[ltemp].depth = dbltemp;
2418                     break;
2419                 }
2420                 case _lp_terrain_height:
2421                 {
2422                     level->walls[ltemp].height = dbltemp;
2423                     break;
2424                 }
2425                 case _lp_terrain_lowerleft:
2426                 {
2427                     level->walls[ltemp].lowerleft = dbltemp;
2428                     break;
2429                 }
2430                 case _lp_terrain_lowerright:
2431                 {
2432                     level->walls[ltemp].lowerright = dbltemp;
2433                     break;
2434                 }
2435                 case _lp_terrain_upperleft:
2436                 {
2437                     level->walls[ltemp].upperleft = dbltemp;
2438                     break;
2439                 }
2440                 case _lp_terrain_upperright:
2441                 {
2442                     level->walls[ltemp].upperright = dbltemp;
2443                     break;
2444                 }
2445                 case _lp_terrain_x:
2446                 {
2447                     level->walls[ltemp].x = dbltemp;
2448                     break;
2449                 }
2450                 case _lp_terrain_z:
2451                 {
2452                     level->walls[ltemp].z = dbltemp;
2453                     break;
2454                 }
2455                 case _lp_terrain_type:
2456                 {
2457                     level->walls[ltemp].type = ltemp1;
2458                     break;
2459                 }
2460                 default:
2461                 {
2462                     printf("Invalid subproperty for wall.\n");
2463                     goto clperror;
2464                 }
2465             }
2466         }
2467         else
2468         {
2469             goto clperror;
2470         }
2471         break;
2472     }
2473     default:
2474         printf("Invalid or read-only level property.\n");
2475         return E_FAIL;
2476         break;
2477     }
2478 
2479     return S_OK;
2480 clperror:
2481     printf("Function changelevelproperty(prop, value) received invalid value(s). \n");
2482     printf("Dumping values: ");
2483     for(i = 1; i < paramCount; i++)
2484     {
2485         ScriptVariant_ToString(varlist[i], buf);
2486         printf("%s, ", buf);
2487     }
2488     printf("\n");
2489     return E_FAIL;
2490 }
2491 
2492 
2493