1 /*
2  * OpenBOR - http://www.chronocrash.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2014 OpenBOR Team
7  */
8 
9 /* This file include all script methods used by openbor engine
10 
11  Notice: Make sure to null *pretvar when you about to return E_FAIL,
12 		 Or the engine might crash.
13 
14  Notice: Every new ScriptVariant must be initialized when you first alloc it by
15 		 ScriptVariant_Init immediately, memset it all to zero should also work by now,
16 		 unless VT_EMPTY is changed.
17 
18 		 If you want to reset a ScriptVariant to empty, you must use ScriptVariant_Clear instead.
19 		 ScriptVariant_Init or memset must be called only ONCE, later you should use ScriptVariant_Clear.
20 
21 		 Besure to call ScriptVariant_Clear if you want to use free to delete those variants.
22 
23 		 If you want to copy a ScriptVariant from another, use ScriptVariant_Copy instead of assignment,
24 		 not because it is faster, but this method is neccessary for string types.
25 
26 		 If you want to change types of an ScriptVariant, use ScriptVariant_ChangeType, don't change vt directly.
27 
28 */
29 
30 #include "openborscript.h"
31 #include "openbor.h"
32 #include "soundmix.h"
33 #include "globals.h"
34 #include "ImportCache.h"
35 #include "models.h"
36 
37 #define _is_not_a_known_subproperty_of_  "'%s' is not a known subproperty of '%s'.\n"
38 #define _is_not_supported_by_ "'%s' is not supported by '%s'.\n"
39 
40 // Define macro for string mapping
41 #define MAPSTRINGS(VAR, LIST, MAXINDEX, FAILMSG, args...) \
42 if(VAR->vt == VT_STR) { \
43 	propname = (char*)StrCache_Get(VAR->strVal); \
44 	prop = searchList(LIST, propname, MAXINDEX); \
45 	if(prop >= 0) { \
46 		ScriptVariant_ChangeType(VAR, VT_INTEGER); \
47 		VAR->lVal = prop; \
48 	} else { printf(FAILMSG, propname, ##args); return 0;} \
49 }
50 
51 extern int			  PLAYER_MIN_Z;
52 extern int			  PLAYER_MAX_Z;
53 extern int			  BGHEIGHT;
54 extern int            MAX_WALL_HEIGHT;
55 extern int			  SAMPLE_GO;
56 extern int			  SAMPLE_BEAT;
57 extern int			  SAMPLE_BLOCK;
58 extern int			  SAMPLE_INDIRECT;
59 extern int			  SAMPLE_GET;
60 extern int			  SAMPLE_GET2;
61 extern int			  SAMPLE_FALL;
62 extern int			  SAMPLE_JUMP;
63 extern int			  SAMPLE_PUNCH;
64 extern int			  SAMPLE_1UP;
65 extern int			  SAMPLE_TIMEOVER;
66 extern int			  SAMPLE_BEEP;
67 extern int			  SAMPLE_BEEP2;
68 extern int			  SAMPLE_BIKE;
69 extern int            current_palette;
70 extern s_player       player[4];
71 extern s_level        *level;
72 extern s_filestream  *filestreams;
73 extern int			  numfilestreams;
74 extern entity         *self;
75 extern int            *animspecials;
76 extern int            *animattacks;
77 extern int            *animfollows;
78 extern int            *animpains;
79 extern int            *animfalls;
80 extern int            *animrises;
81 extern int            *animriseattacks;
82 extern int            *animdies;
83 extern int            *animidles;
84 extern int            *animwalks;
85 extern int            *animbackwalks;
86 extern int            *animups;
87 extern int            *animdowns;
88 extern int            *animbackpains;
89 extern int            *animbackfalls;
90 extern int            *animbackdies;
91 
92 extern int            noshare;
93 extern int            credits;
94 extern char           musicname[128];
95 extern float          musicfade[2];
96 extern int            musicloop;
97 extern u32            musicoffset;
98 extern int            models_cached;
99 extern int endgame;
100 extern int useSave;
101 extern int useSet;
102 
103 
104 extern s_sprite_list *sprite_list;
105 extern s_sprite_map *sprite_map;
106 
107 extern unsigned char *blendings[MAX_BLENDINGS];
108 extern int            current_palette;
109 extern s_collision_attack emptyattack;
110 Varlist global_var_list;
111 Script *pcurrentscript = NULL;//used by local script functions
112 List theFunctionList;
113 static List   scriptheap;
114 static s_spawn_entry spawnentry;
115 static s_drawmethod drawmethod;
116 static s_collision_attack attack ;
117 
118 int            max_indexed_vars = 0;
119 int            max_entity_vars = 0;
120 int            max_script_vars = 0;
121 int			   no_nested_script = 0;
122 
clear_named_var_list(List * list,int level)123 static void clear_named_var_list(List *list, int level)
124 {
125     ScriptVariant *var;
126     int i, size;
127     size = List_GetSize(list);
128     for(i = 0, List_Reset(list); i < size; i++)
129     {
130         var = (ScriptVariant *)List_Retrieve(list);
131         ScriptVariant_Clear(var);
132         free(var);
133         List_Remove(list);
134     }
135     if(level)
136     {
137         List_Clear(list);
138     }
139 }
140 
Varlist_Init(Varlist * varlist,int size)141 void Varlist_Init(Varlist *varlist, int size)
142 {
143     int i;
144     varlist->magic = varlist_magic;
145     varlist->list = calloc(1, sizeof(*varlist->list));
146     List_Init(varlist->list);
147     varlist->vars = calloc(size + 1, sizeof(*varlist->vars));
148     for(i = 0; i <= size; i++)
149     {
150         ScriptVariant_Init(varlist->vars + i);
151         ScriptVariant_ChangeType(varlist->vars, VT_INTEGER);
152         varlist->vars->lVal = (LONG)size;
153     }
154 }
155 
Varlist_Clear(Varlist * varlist)156 void Varlist_Clear(Varlist *varlist)
157 {
158     int i;
159     clear_named_var_list(varlist->list, 1);
160     free(varlist->list);
161     varlist->list = NULL;
162     // the first one must be an integer variable, so it's safe to leave it alone
163     for(i = 1; i <= varlist->vars->lVal; i++)
164     {
165         ScriptVariant_Clear(varlist->vars + i);
166     }
167     free(varlist->vars);
168     varlist->vars = NULL;
169     varlist->magic = 0;
170 }
171 
Varlist_Cleanup(Varlist * varlist)172 void Varlist_Cleanup(Varlist *varlist)
173 {
174     int i;
175     clear_named_var_list(varlist->list, 0);
176     for(i = 1; i <= varlist->vars->lVal; i++)
177     {
178         ScriptVariant_Clear(varlist->vars + i);
179     }
180 }
181 
Varlist_GetByName(Varlist * varlist,char * theName)182 ScriptVariant *Varlist_GetByName(Varlist *varlist, char *theName)
183 {
184     if(!theName || !theName[0])
185     {
186         return NULL;
187     }
188 
189     if(List_FindByName(varlist->list, theName))
190     {
191         return (ScriptVariant *)List_Retrieve(varlist->list);
192     }
193 
194     return NULL;
195 }
196 
Varlist_SetByName(Varlist * varlist,char * theName,ScriptVariant * var)197 int Varlist_SetByName(Varlist *varlist, char *theName, ScriptVariant *var)
198 {
199     ScriptVariant *v;
200     if(!theName || !theName[0])
201     {
202         return 0;
203     }
204     if(List_FindByName(varlist->list, theName))
205     {
206         ScriptVariant_Copy((ScriptVariant *)List_Retrieve(varlist->list), var);
207     }
208     else
209     {
210         v = calloc(1, sizeof(*v));
211         ScriptVariant_Copy(v, var);
212         List_InsertAfter(varlist->list, v, theName);
213     }
214     return 1;
215 }
216 
Varlist_GetByIndex(Varlist * varlist,int index)217 ScriptVariant *Varlist_GetByIndex(Varlist *varlist, int index)
218 {
219     if(index < 0 || index >= varlist->vars->lVal)
220     {
221         return NULL;
222     }
223     return varlist->vars + index + 1;
224 }
225 
Varlist_SetByIndex(Varlist * varlist,int index,ScriptVariant * var)226 int Varlist_SetByIndex(Varlist *varlist, int index, ScriptVariant *var)
227 {
228     if(index < 0)
229     {
230         return 0;
231     }
232     else if(index >= varlist->vars->lVal)
233     {
234         __reallocto(varlist->vars, varlist->vars->lVal + 1, index + 2);
235         varlist->vars->lVal = index + 1;
236     }
237     ScriptVariant_Copy(varlist->vars + index + 1, var);
238     return 1;
239 }
240 
241 // By White Dragon
Varlist_AddByIndex(Varlist * array,int index,ScriptVariant * var)242 int Varlist_AddByIndex(Varlist *array, int index, ScriptVariant *var)
243 {
244     if(index < 0 || index >= array->vars->lVal+1)
245     {
246         return 0;
247     }
248     else
249     {
250         int i = 0;
251         int size = array->vars->lVal;
252 
253         __reallocto(array->vars, size+1, size+2);
254         size = ++array->vars->lVal;
255 
256         for ( i = size-1; i > index; i-- )
257         {
258             ScriptVariant_Copy(array->vars+1+i, array->vars+1+i-1); // first value of array is his size!
259         }
260         ScriptVariant_Copy(array->vars+1+index, var);
261 
262         //printf("aaa: %s\n", (char*)StrCache_Get(elem->strVal) );
263     }
264 
265     return 1;
266 }
267 
268 // By White Dragon
Varlist_DeleteByIndex(Varlist * array,int index)269 int Varlist_DeleteByIndex(Varlist *array, int index)
270 {
271     if(index < 0 || index >= array->vars->lVal)
272     {
273         return 0;
274     }
275     else
276     {
277         int i = 0;
278         int size = array->vars->lVal;
279         ScriptVariant *elem;
280 
281         for ( i = index; i < size-1; i++ )
282         {
283             ScriptVariant_Copy(array->vars+1+i, array->vars+1+i+1); // first value of array is his size!
284         }
285         --array->vars->lVal;
286 
287         // set last element to NULL
288         elem = array->vars+1+size-1;
289         ScriptVariant_ChangeType(elem, VT_EMPTY);
290         elem->ptrVal = NULL;
291 
292         //realloc mem
293         array->vars = realloc((array->vars), sizeof(*(array->vars))*(array->vars->lVal+1));
294 
295         //printf("aaa: %s\n", (char*)StrCache_Get(elem->strVal) );
296     }
297 
298     return 1;
299 }
300 
301 // By White Dragon
Varlist_DeleteByName(Varlist * array,char * theName)302 int Varlist_DeleteByName(Varlist *array, char *theName)
303 {
304     if(!theName || !theName[0])
305     {
306         return 0;
307     }
308     if(List_FindByName(array->list, theName))
309     {
310         Node* node;
311         Node* prev_node;
312         Node* next_node;
313 
314         node = array->list->current;
315         prev_node = node->prev;
316         next_node = node->next;
317 
318         if ( prev_node ) prev_node->next = next_node;
319         if ( next_node ) next_node->prev = prev_node;
320 
321         if ( array->list->last == node ) array->list->last = prev_node;
322         if ( array->list->first == node ) array->list->first = next_node;
323         if ( array->list->first == array->list->last && array->list->first == node ) {
324             array->list->last = NULL;
325             array->list->first = NULL;
326         }
327 
328         --array->list->size;
329 
330         free(node);
331     } else return 0;
332 
333     return 1;
334 }
335 
336 //this function should be called before all script methods, for once
Script_Global_Init()337 void Script_Global_Init()
338 {
339     memset(&spawnentry, 0, sizeof(spawnentry));//clear up the spawn entry
340     drawmethod = plainmethod;
341 
342     Varlist_Init(&global_var_list, max_indexed_vars);
343 
344     List_Init(&theFunctionList);
345     Script_LoadSystemFunctions();
346     List_Init(&scriptheap);
347     ImportCache_Init(&theFunctionList);
348 }
349 
_freeheapnode(void * ptr)350 void _freeheapnode(void *ptr)
351 {
352     if(((Script *)ptr)->magic == script_magic)
353     {
354         Script_Clear((Script *)ptr, 2);
355     }
356     else if(((anigif_info *)ptr)->magic == anigif_magic)
357     {
358         anigif_close((anigif_info *)ptr);
359     }
360     else if(((Varlist *)ptr)->magic == varlist_magic)
361     {
362         Varlist_Clear((Varlist *)ptr);
363     }
364     else if(((s_sprite *)ptr)->magic == sprite_magic)
365     {
366         if(((s_sprite *)ptr)->mask)
367         {
368             free(((s_sprite *)ptr)->mask);
369         }
370     }
371     free(ptr);
372 }
373 
374 //this function should only be called when the engine is shutting down
Script_Global_Clear()375 void Script_Global_Clear()
376 {
377     int i, size;
378     List_Clear(&theFunctionList);
379     // dump all un-freed variants
380     size = List_GetSize(&scriptheap);
381     if(size > 0)
382     {
383         printf("\nWarning: %d script variants are not freed, dumping...\n", size);
384     }
385     for(i = 0, List_Reset(&scriptheap); i < size; List_GotoNext(&scriptheap), i++)
386     {
387         printf("%s\n", List_GetName(&scriptheap));
388         _freeheapnode(List_Retrieve(&scriptheap));
389     }
390     List_Clear(&scriptheap);
391     // clear the global list
392     Varlist_Clear(&global_var_list);
393 
394     memset(&spawnentry, 0, sizeof(spawnentry));//clear up the spawn entry
395     for(i = 0; i < numfilestreams; i++)
396     {
397         if(filestreams[i].buf)
398         {
399             free(filestreams[i].buf);
400             filestreams[i].buf = NULL;
401         }
402     }
403     if(filestreams)
404     {
405         free(filestreams);
406     }
407     filestreams = NULL;
408     numfilestreams = 0;
409     ImportCache_Clear();
410     StrCache_Clear();
411 }
412 
Script_Save_Local_Variant(Script * cs,char * namelist[])413 int Script_Save_Local_Variant(Script *cs, char *namelist[])
414 {
415     return 0;
416 }
417 
Script_Load_Local_Variant(Script * cs,int handle)418 void Script_Load_Local_Variant(Script *cs, int handle)
419 {
420 
421 }
422 
alloc_script()423 Script *alloc_script()
424 {
425     Script *pscript = calloc(1, sizeof(*pscript));
426     pscript->magic = script_magic;
427     pscript->varlist = calloc(1, sizeof(*pscript->varlist));
428     Varlist_Init(pscript->varlist, max_script_vars);
429     return pscript;
430 }
431 
Script_Init(Script * pscript,char * theName,char * comment,int first)432 void Script_Init(Script *pscript, char *theName, char *comment, int first)
433 {
434     if(first)
435     {
436         memset(pscript, 0, sizeof(*pscript));
437         pscript->magic = script_magic;
438         pscript->varlist = calloc(1, sizeof(*pscript->varlist));
439         Varlist_Init(pscript->varlist, max_script_vars);
440     }
441     if(!theName || !theName[0])
442     {
443         return;    // if no name specified, only alloc the variants
444     }
445 
446     pscript->pinterpreter = malloc(sizeof(*pscript->pinterpreter));
447     Interpreter_Init(pscript->pinterpreter, theName, &theFunctionList);
448     pscript->interpreterowner = 1; // this is the owner, important
449     pscript->initialized = 1;
450     if(comment)
451     {
452         pscript->comment = malloc(sizeof(*pscript->comment) * (strlen(comment) + 1));
453         strcpy(pscript->comment, comment);
454     }
455 }
456 
execute_init_method(Script * pdest,int iscopy,int localclear)457 static void execute_init_method(Script *pdest, int iscopy, int localclear)
458 {
459     Script *temp;
460     ScriptVariant tempvar;
461     //Execute init method
462     if(pdest->initialized && pdest->pinterpreter->pInitEntry)
463     {
464         temp = pcurrentscript;
465         pcurrentscript = pdest;
466 
467         ScriptVariant_Init(&tempvar);
468         ScriptVariant_ChangeType(&tempvar, VT_INTEGER);
469         tempvar.lVal = (LONG)iscopy;
470         Script_Set_Local_Variant(pdest, "iscopy", &tempvar);
471         tempvar.lVal = (LONG)localclear;
472         Script_Set_Local_Variant(pdest, "localclear", &tempvar);
473         Interpreter_Reset(pdest->pinterpreter);
474         pdest->pinterpreter->pCurrentInstruction = pdest->pinterpreter->pInitEntry;
475         if(FAILED( Interpreter_EvaluateCall(pdest->pinterpreter)))
476         {
477             shutdown(1, "Fatal: failed to execute 'init' in script %s %s", pdest->pinterpreter->theSymbolTable.name, pdest->comment ? pdest->comment : "");
478         }
479         pdest->pinterpreter->bReset = FALSE; // not needed, perhaps
480         ScriptVariant_Clear(&tempvar);
481         Script_Set_Local_Variant(pdest, "iscopy", &tempvar);
482         Script_Set_Local_Variant(pdest, "localclear", &tempvar);
483         pcurrentscript = temp;
484     }
485 }
486 
487 //safe copy method
Script_Copy(Script * pdest,Script * psrc,int localclear)488 void Script_Copy(Script *pdest, Script *psrc, int localclear)
489 {
490     if(!psrc->initialized)
491     {
492         return;
493     }
494     if(pdest->initialized)
495     {
496         Script_Clear(pdest, localclear);
497     }
498     pdest->pinterpreter = psrc->pinterpreter;
499     pdest->comment = psrc->comment;
500     pdest->interpreterowner = 0; // dont own it
501     pdest->initialized = psrc->initialized; //just copy, it should be 1
502     execute_init_method(pdest, 1, localclear);
503 }
504 
Script_Clear(Script * pscript,int localclear)505 void Script_Clear(Script *pscript, int localclear)
506 {
507     Script *temp;
508     Varlist *pvars;
509 
510     ScriptVariant tempvar;
511     //Execute clear method
512     if(pscript->initialized && pscript->pinterpreter->pClearEntry)
513     {
514         temp = pcurrentscript;
515         pcurrentscript = pscript;
516 
517         ScriptVariant_Init(&tempvar);
518         ScriptVariant_ChangeType(&tempvar, VT_INTEGER);
519         tempvar.lVal = (LONG)localclear;
520         Script_Set_Local_Variant(pscript, "localclear", &tempvar);
521         Interpreter_Reset(pscript->pinterpreter);
522         pscript->pinterpreter->pCurrentInstruction = pscript->pinterpreter->pClearEntry;
523         if(FAILED( Interpreter_EvaluateCall(pscript->pinterpreter)))
524         {
525             shutdown(1, "Fatal: failed to execute 'clear' in script %s %s", pscript->pinterpreter->theSymbolTable.name, pscript->comment ? pscript->comment : "");
526         }
527         pscript->pinterpreter->bReset = FALSE; // not needed, perhaps
528         ScriptVariant_Clear(&tempvar);
529         Script_Set_Local_Variant(pscript, "localclear", &tempvar);
530         pcurrentscript = temp;
531     }
532 
533     if(localclear && pscript->varlist)
534     {
535         if(localclear == 2)
536         {
537             Varlist_Clear(pscript->varlist);
538             free(pscript->varlist);
539             pscript->varlist = NULL;
540         }
541         else
542         {
543             Varlist_Cleanup(pscript->varlist);
544         }
545     }
546     if(!pscript->initialized)
547     {
548         return;
549     }
550 
551     //if it is the owner, free the interpreter
552     if(pscript->pinterpreter && pscript->interpreterowner)
553     {
554         Interpreter_Clear(pscript->pinterpreter);
555         free(pscript->pinterpreter);
556         pscript->pinterpreter = NULL;
557         if(pscript->comment)
558         {
559             free(pscript->comment);
560         }
561         pscript->comment = NULL;
562     }
563     pvars = pscript->varlist; // in game clear(localclear!=2) just keep this value
564     memset(pscript, 0, sizeof(*pscript));
565     pscript->varlist = pvars; // copy it back
566 }
567 
568 //append part of the script
569 //Because the script might not be initialized in 1 time.
Script_AppendText(Script * pscript,char * text,char * path)570 int Script_AppendText(Script *pscript, char *text, char *path)
571 {
572     int success;
573 
574     //printf(text);
575     Interpreter_Reset(pscript->pinterpreter);
576 
577     success = SUCCEEDED(Interpreter_ParseText(pscript->pinterpreter, text, 1, path));
578 
579     return success;
580 }
581 
582 //return name of function from pointer to function
Script_GetFunctionName(void * functionRef)583 const char *Script_GetFunctionName(void *functionRef)
584 {
585     if (functionRef == ((void *)system_isempty))
586     {
587         return "isempty";
588     }
589     else if (functionRef == ((void *)system_exit))
590     {
591         return "exit";
592     }
593     else if (functionRef == ((void *)system_NULL))
594     {
595         return "NULL";
596     }
597     else if (functionRef == ((void *)system_rand))
598     {
599         return "rand";
600     }
601     else if (functionRef == ((void *)system_srand))
602     {
603         return "srand";
604     }
605     else if (functionRef == ((void *)system_getglobalvar))
606     {
607         return "getglobalvar";
608     }
609     else if (functionRef == ((void *)system_setglobalvar))
610     {
611         return "setglobalvar";
612     }
613     else if (functionRef == ((void *)system_getlocalvar))
614     {
615         return "getlocalvar";
616     }
617     else if (functionRef == ((void *)system_setlocalvar))
618     {
619         return "setlocalvar";
620     }
621     else if (functionRef == ((void *)system_clearglobalvar))
622     {
623         return "clearglobalvar";
624     }
625     else if (functionRef == ((void *)system_clearlocalvar))
626     {
627         return "clearlocalvar";
628     }
629     else if (functionRef == ((void *)system_free))
630     {
631         return "free";
632     }
633     else if (functionRef == ((void *)system_typeof))
634     {
635         return "typeof";
636     }
637     else if (functionRef == ((void *)math_sin))
638     {
639         return "sin";
640     }
641     else if (functionRef == ((void *)math_ssin))
642     {
643         return "ssin";
644     }
645     else if (functionRef == ((void *)math_cos))
646     {
647         return "cos";
648     }
649     else if (functionRef == ((void *)math_scos))
650     {
651         return "scos";
652     }
653     else if (functionRef == ((void *)math_sqrt))
654     {
655         return "sqrt";
656     }
657     else if (functionRef == ((void *)math_pow))
658     {
659         return "pow";
660     }
661     else if (functionRef == ((void *)math_asin))
662     {
663         return "asin";
664     }
665     else if (functionRef == ((void *)math_acos))
666     {
667         return "acos";
668     }
669     else if (functionRef == ((void *)math_atan))
670     {
671         return "atan";
672     }
673     else if (functionRef == ((void *)math_trunc))
674     {
675         return "trunc";
676     }
677     else if (functionRef == ((void *)math_round))
678     {
679         return "round";
680     }
681     else if (functionRef == ((void *)openbor_systemvariant))
682     {
683         return "openborvariant";
684     }
685     else if (functionRef == ((void *)openbor_changesystemvariant))
686     {
687         return "changeopenborvariant";
688     }
689     else if (functionRef == ((void *)openbor_drawstring))
690     {
691         return "drawstring";
692     }
693     else if (functionRef == ((void *)openbor_drawstringtoscreen))
694     {
695         return "drawstringtoscreen";
696     }
697     else if (functionRef == ((void *)openbor_log))
698     {
699         return "log";
700     }
701     else if (functionRef == ((void *)openbor_drawbox))
702     {
703         return "drawbox";
704     }
705     else if (functionRef == ((void *)openbor_drawboxtoscreen))
706     {
707         return "drawboxtoscreen";
708     }
709     else if (functionRef == ((void *)openbor_drawline))
710     {
711         return "drawline";
712     }
713     else if (functionRef == ((void *)openbor_drawlinetoscreen))
714     {
715         return "drawlinetoscreen";
716     }
717     else if (functionRef == ((void *)openbor_drawsprite))
718     {
719         return "drawsprite";
720     }
721     else if (functionRef == ((void *)openbor_drawspritetoscreen))
722     {
723         return "drawspritetoscreen";
724     }
725     else if (functionRef == ((void *)openbor_drawdot))
726     {
727         return "drawdot";
728     }
729     else if (functionRef == ((void *)openbor_drawdottoscreen))
730     {
731         return "drawdottoscreen";
732     }
733     else if (functionRef == ((void *)openbor_drawscreen))
734     {
735         return "drawscreen";
736     }
737     else if (functionRef == ((void *)openbor_changeplayerproperty))
738     {
739         return "changeplayerproperty";
740     }
741     else if (functionRef == ((void *)openbor_getplayerproperty))
742     {
743         return "getplayerproperty";
744     }
745     else if (functionRef == ((void *)openbor_changeentityproperty))
746     {
747         return "changeentityproperty";
748     }
749     else if (functionRef == ((void *)openbor_getentityproperty))
750     {
751         return "getentityproperty";
752     }
753     else if (functionRef == ((void *)openbor_get_animation_property))
754     {
755         return "get_animation_property";
756     }
757     else if (functionRef == ((void *)openbor_set_animation_property))
758     {
759         return "set_animation_property";
760     }
761     else if (functionRef == ((void *)openbor_get_attack_collection))
762     {
763         return "get_attack_collection";
764     }
765     else if (functionRef == ((void *)openbor_get_attack_instance))
766     {
767         return "get_attack_instance";
768     }
769     else if (functionRef == ((void *)openbor_get_attack_property))
770     {
771         return "get_attack_property";
772     }
773     else if (functionRef == ((void *)openbor_set_attack_property))
774     {
775         return "set_attack_property";
776     }
777 
778     // Body collision (bbox)
779     else if (functionRef == ((void *)openbor_get_body_collision_collection))
780     {
781         return "get_body_collision_collection";
782     }
783     else if (functionRef == ((void *)openbor_get_body_collision_instance))
784     {
785         return "get_body_collision_instance";
786     }
787     else if (functionRef == ((void *)openbor_get_body_collision_property))
788     {
789         return "get_body_collision_property";
790     }
791     else if (functionRef == ((void *)openbor_set_body_collision_property))
792     {
793         return "set_body_collision_property";
794     }
795 
796     else if (functionRef == ((void *)openbor_tossentity))
797     {
798         return "tossentity";
799     }
800     else if (functionRef == ((void *)openbor_clearspawnentry))
801     {
802         return "clearspawnentry";
803     }
804     else if (functionRef == ((void *)openbor_setspawnentry))
805     {
806         return "setspawnentry";
807     }
808     else if (functionRef == ((void *)openbor_spawn))
809     {
810         return "spawn";
811     }
812     else if (functionRef == ((void *)openbor_projectile))
813     {
814         return "projectile";
815     }
816     else if (functionRef == ((void *)openbor_transconst))
817     {
818         return "openborconstant";
819     }
820     else if (functionRef == ((void *)openbor_playmusic))
821     {
822         return "playmusic";
823     }
824     else if (functionRef == ((void *)openbor_fademusic))
825     {
826         return "fademusic";
827     }
828     else if (functionRef == ((void *)openbor_setmusicvolume))
829     {
830         return "setmusicvolume";
831     }
832     else if (functionRef == ((void *)openbor_setmusictempo))
833     {
834         return "setmusictempo";
835     }
836     else if (functionRef == ((void *)openbor_pausemusic))
837     {
838         return "pausemusic";
839     }
840     else if (functionRef == ((void *)openbor_pausesamples))
841     {
842         return "pausesamples";
843     }
844     else if (functionRef == ((void *)openbor_pausesample))
845     {
846         return "pausesample";
847     }
848     else if (functionRef == ((void *)openbor_querychannel))
849     {
850         return "querychannel";
851     }
852     else if (functionRef == ((void *)openbor_stopchannel))
853     {
854         return "stopchannel";
855     }
856     else if (functionRef == ((void *)openbor_isactivesample))
857     {
858         return "isactivesample";
859     }
860     else if (functionRef == ((void *)openbor_sampleid))
861     {
862         return "sampleid";
863     }
864     else if (functionRef == ((void *)openbor_playsample))
865     {
866         return "playsample";
867     }
868     else if (functionRef == ((void *)openbor_loadsample))
869     {
870         return "loadsample";
871     }
872     else if (functionRef == ((void *)openbor_unloadsample))
873     {
874         return "unloadsample";
875     }
876     else if (functionRef == ((void *)openbor_fadeout))
877     {
878         return "fadeout";
879     }
880     else if (functionRef == ((void *)openbor_playerkeys))
881     {
882         return "playerkeys";
883     }
884     else if (functionRef == ((void *)openbor_changepalette))
885     {
886         return "changepalette";
887     }
888     else if (functionRef == ((void *)openbor_damageentity))
889     {
890         return "damageentity";
891     }
892     else if (functionRef == ((void *)openbor_killentity))
893     {
894         return "killentity";
895     }
896     else if (functionRef == ((void *)openbor_dograb))
897     {
898         return "dograb";
899     }
900     else if (functionRef == ((void *)openbor_findtarget))
901     {
902         return "findtarget";
903     }
904     else if (functionRef == ((void *)openbor_checkrange))
905     {
906         return "checkrange";
907     }
908     else if (functionRef == ((void *)openbor_gettextobjproperty))
909     {
910         return "gettextobjproperty";
911     }
912     else if (functionRef == ((void *)openbor_changetextobjproperty))
913     {
914         return "changetextobjproperty";
915     }
916     else if (functionRef == ((void *)openbor_settextobj))
917     {
918         return "settextobj";
919     }
920     else if (functionRef == ((void *)openbor_cleartextobj))
921     {
922         return "cleartextobj";
923     }
924     else if (functionRef == ((void *)openbor_getlayerproperty))
925     {
926         return "getlayerproperty";
927     }
928     else if (functionRef == ((void *)openbor_changelayerproperty))
929     {
930         return "changelayerproperty";
931     }
932     else if (functionRef == ((void *)openbor_getlevelproperty))
933     {
934         return "getlevelproperty";
935     }
936     else if (functionRef == ((void *)openbor_changelevelproperty))
937     {
938         return "changelevelproperty";
939     }
940     else if (functionRef == ((void *)openbor_checkhole))
941     {
942         return "checkhole";
943     }
944     else if (functionRef == ((void *)openbor_checkholeindex))
945     {
946         return "checkholeindex";
947     }
948     else if (functionRef == ((void *)openbor_checkwall))
949     {
950         return "checkwall";
951     }
952     else if (functionRef == ((void *)openbor_checkwallindex))
953     {
954         return "checkwallindex";
955     }
956     else if (functionRef == ((void *)openbor_checkplatformbelow))
957     {
958         return "checkplatformbelow";
959     }
960     else if (functionRef == ((void *)openbor_checkplatformabove))
961     {
962         return "checkplatformabove";
963     }
964     else if (functionRef == ((void *)openbor_checkplatformbetween))
965     {
966         return "checkplatformbetween";
967     }
968     else if (functionRef == ((void *)openbor_checkbasemap))
969     {
970         return "checkbasemap";
971     }
972     else if (functionRef == ((void *)openbor_checkbasemapindex))
973     {
974         return "checkbasemapindex";
975     }
976     else if (functionRef == ((void *)openbor_generatebasemap))
977     {
978         return "generatebasemap";
979     }
980     else if (functionRef == ((void *)openbor_openfilestream))
981     {
982         return "openfilestream";
983     }
984     else if (functionRef == ((void *)openbor_getfilestreamline))
985     {
986         return "getfilestreamline";
987     }
988     else if (functionRef == ((void *)openbor_getfilestreamargument))
989     {
990         return "getfilestreamargument";
991     }
992     else if (functionRef == ((void *)openbor_filestreamnextline))
993     {
994         return "filestreamnextline";
995     }
996     else if (functionRef == ((void *)openbor_getfilestreamposition))
997     {
998         return "getfilestreamposition";
999     }
1000     else if (functionRef == ((void *)openbor_setfilestreamposition))
1001     {
1002         return "setfilestreamposition";
1003     }
1004     else if (functionRef == ((void *)openbor_filestreamappend))
1005     {
1006         return "filestreamappend";
1007     }
1008     else if (functionRef == ((void *)openbor_createfilestream))
1009     {
1010         return "createfilestream";
1011     }
1012     else if (functionRef == ((void *)openbor_closefilestream))
1013     {
1014         return "closefilestream";
1015     }
1016     else if (functionRef == ((void *)openbor_savefilestream))
1017     {
1018         return "savefilestream";
1019     }
1020     else if (functionRef == ((void *)openbor_getindexedvar))
1021     {
1022         return "getindexedvar";
1023     }
1024     else if (functionRef == ((void *)openbor_setindexedvar))
1025     {
1026         return "setindexedvar";
1027     }
1028     else if (functionRef == ((void *)openbor_getscriptvar))
1029     {
1030         return "getscriptvar";
1031     }
1032     else if (functionRef == ((void *)openbor_setscriptvar))
1033     {
1034         return "setscriptvar";
1035     }
1036     else if (functionRef == ((void *)openbor_getentityvar))
1037     {
1038         return "getentityvar";
1039     }
1040     else if (functionRef == ((void *)openbor_setentityvar))
1041     {
1042         return "setentityvar";
1043     }
1044     else if (functionRef == ((void *)openbor_shutdown))
1045     {
1046         return "shutdown";
1047     }
1048     else if (functionRef == ((void *)openbor_jumptobranch))
1049     {
1050         return "jumptobranch";
1051     }
1052     else if (functionRef == ((void *)openbor_changelight))
1053     {
1054         return "changelight";
1055     }
1056     else if (functionRef == ((void *)openbor_changeshadowcolor))
1057     {
1058         return "changeshadowcolor";
1059     }
1060     else if (functionRef == ((void *)openbor_bindentity))
1061     {
1062         return "bindentity";
1063     }
1064     else if (functionRef == ((void *)openbor_array))
1065     {
1066         return "array";
1067     }
1068     else if (functionRef == ((void *)openbor_size))
1069     {
1070         return "size";
1071     }
1072     else if (functionRef == ((void *)openbor_get))
1073     {
1074         return "get";
1075     }
1076     else if (functionRef == ((void *)openbor_set))
1077     {
1078         return "set";
1079     }
1080     else if (functionRef == ((void *)openbor_delete))
1081     {
1082         return "delete";
1083     }
1084     else if (functionRef == ((void *)openbor_add))
1085     {
1086         return "add";
1087     }
1088     else if (functionRef == ((void *)openbor_reset))
1089     {
1090         return "reset";
1091     }
1092     else if (functionRef == ((void *)openbor_next))
1093     {
1094         return "next";
1095     }
1096     else if (functionRef == ((void *)openbor_previous))
1097     {
1098         return "previous";
1099     }
1100     else if (functionRef == ((void *)openbor_key))
1101     {
1102         return "key";
1103     }
1104     else if (functionRef == ((void *)openbor_value))
1105     {
1106         return "value";
1107     }
1108     else if (functionRef == ((void *)openbor_islast))
1109     {
1110         return "islast";
1111     }
1112     else if (functionRef == ((void *)openbor_isfirst))
1113     {
1114         return "isfirst";
1115     }
1116     else if (functionRef == ((void *)openbor_allocscreen))
1117     {
1118         return "allocscreen";
1119     }
1120     else if (functionRef == ((void *)openbor_clearscreen))
1121     {
1122         return "clearscreen";
1123     }
1124     else if (functionRef == ((void *)openbor_setdrawmethod))
1125     {
1126         return "setdrawmethod";
1127     }
1128     else if (functionRef == ((void *)openbor_changedrawmethod))
1129     {
1130         return "changedrawmethod";
1131     }
1132     else if (functionRef == ((void *)openbor_updateframe))
1133     {
1134         return "updateframe";
1135     }
1136     else if (functionRef == ((void *)openbor_performattack))
1137     {
1138         return "performattack";
1139     }
1140     else if (functionRef == ((void *)openbor_executeanimation))
1141     {
1142         return "executeanimation";
1143     }
1144     else if (functionRef == ((void *)openbor_setidle))
1145     {
1146         return "setidle";
1147     }
1148     else if (functionRef == ((void *)openbor_getentity))
1149     {
1150         return "getentity";
1151     }
1152     else if (functionRef == ((void *)openbor_hallfame))
1153     {
1154         return "hallfame";
1155     }
1156     else if (functionRef == ((void *)openbor_loadmodel))
1157     {
1158         return "loadmodel";
1159     }
1160     else if (functionRef == ((void *)openbor_loadsprite))
1161     {
1162         return "loadsprite";
1163     }
1164     else if (functionRef == ((void *)openbor_menu_options))
1165     {
1166         return "options";
1167     }
1168     else if (functionRef == ((void *)openbor_playwebm))
1169     {
1170         return "playwebm";
1171     }
1172     else if (functionRef == ((void *)openbor_playgif))
1173     {
1174         return "playgif";
1175     }
1176     else if (functionRef == ((void *)openbor_openanigif))
1177     {
1178         return "openanigif";
1179     }
1180     else if (functionRef == ((void *)openbor_decodeanigif))
1181     {
1182         return "decodeanigif";
1183     }
1184     else if (functionRef == ((void *)openbor_getanigifinfo))
1185     {
1186         return "getanigifinfo";
1187     }
1188     else if (functionRef == ((void *)openbor_strinfirst))
1189     {
1190         return "strinfirst";
1191     }
1192     else if (functionRef == ((void *)openbor_strinlast))
1193     {
1194         return "strinlast";
1195     }
1196     else if (functionRef == ((void *)openbor_strleft))
1197     {
1198         return "strleft";
1199     }
1200     else if (functionRef == ((void *)openbor_strlength))
1201     {
1202         return "strlength";
1203     }
1204     else if (functionRef == ((void *)openbor_strwidth))
1205     {
1206         return "strwidth";
1207     }
1208     else if (functionRef == ((void *)openbor_strright))
1209     {
1210         return "strright";
1211     }
1212     else if (functionRef == ((void *)openbor_getmodelproperty))
1213     {
1214         return "getmodelproperty";
1215     }
1216     else if (functionRef == ((void *)openbor_changemodelproperty))
1217     {
1218         return "changemodelproperty";
1219     }
1220     else if (functionRef == ((void *)openbor_rgbcolor))
1221     {
1222         return "rgbcolor";
1223     }
1224     else if (functionRef == ((void *)openbor_adjustwalkanimation))
1225     {
1226         return "adjustwalkanimation";
1227     }
1228     else if (functionRef == ((void *)openbor_finditem))
1229     {
1230         return "finditem";
1231     }
1232     else if (functionRef == ((void *)openbor_pickup))
1233     {
1234         return "pickup";
1235     }
1236     else if (functionRef == ((void *)openbor_waypoints))
1237     {
1238         return "waypoints";
1239     }
1240     else if (functionRef == ((void *)openbor_drawspriteq))
1241     {
1242         return "drawspriteq";
1243     }
1244     else if (functionRef == ((void *)openbor_clearspriteq))
1245     {
1246         return "clearspriteq";
1247     }
1248     else if (functionRef == ((void *)openbor_getgfxproperty))
1249     {
1250         return "getgfxproperty";
1251     }
1252     else if (functionRef == ((void *)openbor_allocscript))
1253     {
1254         return "allocscript";
1255     }
1256     else if (functionRef == ((void *)openbor_loadscript))
1257     {
1258         return "loadscript";
1259     }
1260     else if (functionRef == ((void *)openbor_compilescript))
1261     {
1262         return "compilescript";
1263     }
1264     else if (functionRef == ((void *)openbor_executescript))
1265     {
1266         return "executescript";
1267     }
1268     else if (functionRef == ((void *)openbor_loadgamefile))
1269     {
1270         return "loadgamefile";
1271     }
1272     else if (functionRef == ((void *)openbor_finishlevel))
1273     {
1274         return "finishlevel";
1275     }
1276     else if (functionRef == ((void *)openbor_gotomainmenu))
1277     {
1278         return "gotomainmenu";
1279     }
1280     else if (functionRef == ((void *)openbor_playgame))
1281     {
1282         return "playgame";
1283     }
1284     else if (functionRef == ((void *)openbor_getrecordingstatus))
1285     {
1286         return "getrecordingstatus";
1287     }
1288     else if (functionRef == ((void *)openbor_recordinputs))
1289     {
1290         return "recordinputs";
1291     }
1292     else if (functionRef == ((void *)openbor_getsaveinfo))
1293     {
1294         return "getsaveinfo";
1295     }
1296     else
1297     {
1298         return "<unknown function>";
1299     }
1300 }
1301 
1302 //return string mapping function corresponding to a given function
Script_GetStringMapFunction(void * functionRef)1303 void *Script_GetStringMapFunction(void *functionRef)
1304 {
1305     if (functionRef == ((void *)openbor_systemvariant))
1306     {
1307         return (void *)mapstrings_systemvariant;
1308     }
1309     else if (functionRef == ((void *)openbor_changesystemvariant))
1310     {
1311         return (void *)mapstrings_systemvariant;
1312     }
1313     else if (functionRef == ((void *)openbor_getentityproperty))
1314     {
1315         return (void *)mapstrings_entityproperty;
1316     }
1317     else if (functionRef == ((void *)openbor_changeentityproperty))
1318     {
1319         return (void *)mapstrings_entityproperty;
1320     }
1321     else if (functionRef == ((void *)openbor_getplayerproperty))
1322     {
1323         return (void *)mapstrings_playerproperty;
1324     }
1325     else if (functionRef == ((void *)openbor_changeplayerproperty))
1326     {
1327         return (void *)mapstrings_playerproperty;
1328     }
1329     else if (functionRef == ((void *)openbor_setspawnentry))
1330     {
1331         return (void *)mapstrings_setspawnentry;
1332     }
1333     else if (functionRef == ((void *)openbor_transconst))
1334     {
1335         return (void *)mapstrings_transconst;
1336     }
1337     else if (functionRef == ((void *)openbor_playerkeys))
1338     {
1339         return (void *)mapstrings_playerkeys;
1340     }
1341     else if (functionRef == ((void *)openbor_gettextobjproperty))
1342     {
1343         return (void *)mapstrings_textobjproperty;
1344     }
1345     else if (functionRef == ((void *)openbor_changetextobjproperty))
1346     {
1347         return (void *)mapstrings_textobjproperty;
1348     }
1349     else if (functionRef == ((void *)openbor_getlayerproperty))
1350     {
1351         return (void *)mapstrings_layerproperty;
1352     }
1353     else if (functionRef == ((void *)openbor_changelayerproperty))
1354     {
1355         return (void *)mapstrings_layerproperty;
1356     }
1357     else if (functionRef == ((void *)openbor_changedrawmethod))
1358     {
1359         return (void *)mapstrings_drawmethodproperty;
1360     }
1361     else if (functionRef == ((void *)openbor_getgfxproperty))
1362     {
1363         return (void *)mapstrings_gfxproperty;
1364     }
1365     else if (functionRef == ((void *)openbor_getlevelproperty))
1366     {
1367         return (void *)mapstrings_levelproperty;
1368     }
1369     else if (functionRef == ((void *)openbor_changelevelproperty))
1370     {
1371         return (void *)mapstrings_levelproperty;
1372     }
1373     else
1374     {
1375         return NULL;
1376     }
1377 }
1378 
1379 /* Replace string constants with enum constants at compile time to speed up
1380    script execution. */
Script_MapStringConstants(Instruction * pInstruction)1381 int Script_MapStringConstants(Instruction *pInstruction)
1382 {
1383     ScriptVariant **params;
1384     int paramCount;
1385     int (*pMapstrings)(ScriptVariant **, int);
1386 
1387     if(pInstruction->functionRef)
1388     {
1389         params = (ScriptVariant **)pInstruction->theRefList->solidlist;
1390         paramCount = (int)pInstruction->theRef->lVal;
1391         assert(paramCount <= 32);
1392         // Get the pointer to the correct mapstrings function, if one exists.
1393         pMapstrings = Script_GetStringMapFunction(pInstruction->functionRef);
1394         if(pMapstrings)
1395         {
1396             // Call the mapstrings function.
1397             if(!pMapstrings(params, paramCount))
1398             {
1399                 return 0;
1400             }
1401         }
1402     }
1403 
1404     return 1;
1405 }
1406 
1407 //should be called only once after parsing text
Script_Compile(Script * pscript)1408 int Script_Compile(Script *pscript)
1409 {
1410     int result;
1411     if(!pscript || !pscript->pinterpreter)
1412     {
1413         return 1;
1414     }
1415     //Interpreter_OutputPCode(pscript->pinterpreter, "code");
1416     result = SUCCEEDED(Interpreter_CompileInstructions(pscript->pinterpreter));
1417     if(!result)
1418     {
1419         shutdown(1, "Can't compile script '%s' %s\n", pscript->pinterpreter->theSymbolTable.name, pscript->comment ? pscript->comment : "");
1420     }
1421 
1422     pscript->pinterpreter->bReset = FALSE;
1423     execute_init_method(pscript, 0, 1);
1424     return result;
1425 }
1426 
Script_IsInitialized(Script * pscript)1427 int Script_IsInitialized(Script *pscript)
1428 {
1429     //if(pscript && pscript->initialized) pcurrentscript = pscript; //used by local script functions
1430     return pscript->initialized;
1431 }
1432 
1433 //execute the script
Script_Execute(Script * pscript)1434 int Script_Execute(Script *pscript)
1435 {
1436     int result, nested;
1437     extern int no_cmd_compatible;
1438     Script *temp = pcurrentscript;
1439     Interpreter tinter, *pinter;
1440     pcurrentscript = pscript; //used by local script functions
1441     nested = pscript->pinterpreter->bReset;
1442     if(no_nested_script && nested)
1443     {
1444         result = 1;
1445     }
1446     else
1447     {
1448         pinter = pscript->pinterpreter;
1449         if(nested && no_cmd_compatible)
1450         {
1451             tinter = *pinter;
1452         }
1453         Interpreter_Reset(pinter);
1454         result = (int)SUCCEEDED(Interpreter_EvaluateImmediate(pinter));
1455         if(nested && no_cmd_compatible)
1456         {
1457             *pinter = tinter;
1458         }
1459         else if(nested)
1460         {
1461             pinter->bReset = FALSE;
1462         }
1463     }
1464     pcurrentscript = temp;
1465     if(!result)
1466     {
1467         shutdown(1, "There's an exception while executing script '%s' %s", pscript->pinterpreter->theSymbolTable.name, pscript->comment ? pscript->comment : "");
1468     }
1469     return result;
1470 }
1471 
1472 #ifndef COMPILED_SCRIPT
1473 //this method is for debug purpose
Script_Call(Script * pscript,char * method,ScriptVariant * pretvar)1474 int Script_Call(Script *pscript, char *method, ScriptVariant *pretvar)
1475 {
1476     int result;
1477     Script *temp = pcurrentscript;
1478     pcurrentscript = pscript; //used by local script functions
1479     Interpreter_Reset(pscript->pinterpreter);
1480     result = (int)SUCCEEDED(Interpreter_Call(pscript->pinterpreter, method, pretvar));
1481     pcurrentscript = temp;
1482     return result;
1483 }
1484 #endif
1485 
1486 //used by Script_Global_Init
Script_LoadSystemFunctions()1487 void Script_LoadSystemFunctions()
1488 {
1489     //printf("Loading system script functions....");
1490     //load system functions if we need
1491     List_Reset(&theFunctionList);
1492 
1493     List_InsertAfter(&theFunctionList,
1494                      (void *)system_isempty, "isempty");
1495     List_InsertAfter(&theFunctionList,
1496                      (void *)system_exit, "exit");
1497     List_InsertAfter(&theFunctionList,
1498                      (void *)system_NULL, "NULL");
1499     List_InsertAfter(&theFunctionList,
1500                      (void *)system_rand, "rand");
1501     List_InsertAfter(&theFunctionList,
1502                      (void *)system_srand, "srand");
1503     List_InsertAfter(&theFunctionList,
1504                      (void *)system_getglobalvar, "getglobalvar");
1505     List_InsertAfter(&theFunctionList,
1506                      (void *)system_setglobalvar, "setglobalvar");
1507     List_InsertAfter(&theFunctionList,
1508                      (void *)system_getlocalvar, "getlocalvar");
1509     List_InsertAfter(&theFunctionList,
1510                      (void *)system_setlocalvar, "setlocalvar");
1511     List_InsertAfter(&theFunctionList,
1512                      (void *)system_clearglobalvar, "clearglobalvar");
1513     List_InsertAfter(&theFunctionList,
1514                      (void *)system_clearlocalvar, "clearlocalvar");
1515     List_InsertAfter(&theFunctionList,
1516                      (void *)system_free, "free");
1517     List_InsertAfter(&theFunctionList,
1518                      (void *)system_typeof, "typeof");
1519     List_InsertAfter(&theFunctionList,
1520                      (void *)math_sin, "sin");
1521     List_InsertAfter(&theFunctionList,
1522                      (void *)math_ssin, "ssin");
1523     List_InsertAfter(&theFunctionList,
1524                      (void *)math_cos, "cos");
1525     List_InsertAfter(&theFunctionList,
1526                      (void *)math_scos, "scos");
1527     List_InsertAfter(&theFunctionList,
1528                      (void *)math_sqrt, "sqrt");
1529     List_InsertAfter(&theFunctionList,
1530                      (void *)math_pow, "pow");
1531     List_InsertAfter(&theFunctionList,
1532                      (void *)math_asin, "asin");
1533     List_InsertAfter(&theFunctionList,
1534                      (void *)math_acos, "acos");
1535     List_InsertAfter(&theFunctionList,
1536                      (void *)math_atan, "atan");
1537     List_InsertAfter(&theFunctionList,
1538                      (void *)math_trunc, "trunc");
1539     List_InsertAfter(&theFunctionList,
1540                      (void *)math_round, "round");
1541     List_InsertAfter(&theFunctionList,
1542                      (void *)openbor_systemvariant, "openborvariant");
1543     List_InsertAfter(&theFunctionList,
1544                      (void *)openbor_changesystemvariant, "changeopenborvariant");
1545     List_InsertAfter(&theFunctionList,
1546                      (void *)openbor_drawstring, "drawstring");
1547     List_InsertAfter(&theFunctionList,
1548                      (void *)openbor_drawstringtoscreen, "drawstringtoscreen");
1549     List_InsertAfter(&theFunctionList,
1550                      (void *)openbor_log, "log");
1551     List_InsertAfter(&theFunctionList,
1552                      (void *)openbor_drawbox, "drawbox");
1553     List_InsertAfter(&theFunctionList,
1554                      (void *)openbor_drawboxtoscreen, "drawboxtoscreen");
1555     List_InsertAfter(&theFunctionList,
1556                      (void *)openbor_drawline, "drawline");
1557     List_InsertAfter(&theFunctionList,
1558                      (void *)openbor_drawlinetoscreen, "drawlinetoscreen");
1559     List_InsertAfter(&theFunctionList,
1560                      (void *)openbor_drawsprite, "drawsprite");
1561     List_InsertAfter(&theFunctionList,
1562                      (void *)openbor_drawspritetoscreen, "drawspritetoscreen");
1563     List_InsertAfter(&theFunctionList,
1564                      (void *)openbor_drawdot, "drawdot");
1565     List_InsertAfter(&theFunctionList,
1566                      (void *)openbor_drawdottoscreen, "drawdottoscreen");
1567     List_InsertAfter(&theFunctionList,
1568                      (void *)openbor_drawscreen, "drawscreen");
1569     List_InsertAfter(&theFunctionList,
1570                      (void *)openbor_changeplayerproperty, "changeplayerproperty");
1571     List_InsertAfter(&theFunctionList,
1572                      (void *)openbor_changeentityproperty, "changeentityproperty");
1573     List_InsertAfter(&theFunctionList,
1574                      (void *)openbor_getplayerproperty, "getplayerproperty");
1575     List_InsertAfter(&theFunctionList,
1576                      (void *)openbor_get_animation_property, "get_animation_property");
1577     List_InsertAfter(&theFunctionList,
1578                      (void *)openbor_set_animation_property, "set_animation_property");
1579 
1580     // Attack properties
1581     List_InsertAfter(&theFunctionList,
1582                      (void *)openbor_get_attack_collection, "get_attack_collection");
1583     List_InsertAfter(&theFunctionList,
1584                      (void *)openbor_get_attack_instance, "get_attack_instance");
1585     List_InsertAfter(&theFunctionList,
1586                      (void *)openbor_get_attack_property, "get_attack_property");
1587     List_InsertAfter(&theFunctionList,
1588                      (void *)openbor_set_attack_property, "set_attack_property");
1589 
1590     // Body collision (bbox) properties.
1591     List_InsertAfter(&theFunctionList,
1592                      (void *)openbor_get_body_collision_collection, "get_body_collision_collection");
1593     List_InsertAfter(&theFunctionList,
1594                      (void *)openbor_get_body_collision_instance, "get_body_collision_instance");
1595     List_InsertAfter(&theFunctionList,
1596                      (void *)openbor_get_body_collision_property, "get_body_collision_property");
1597     List_InsertAfter(&theFunctionList,
1598                      (void *)openbor_set_body_collision_property, "set_body_collision_property");
1599 
1600     List_InsertAfter(&theFunctionList,
1601                      (void *)openbor_getentityproperty, "getentityproperty");
1602     List_InsertAfter(&theFunctionList,
1603                      (void *)openbor_tossentity, "tossentity");
1604     List_InsertAfter(&theFunctionList,
1605                      (void *)openbor_clearspawnentry, "clearspawnentry");
1606     List_InsertAfter(&theFunctionList,
1607                      (void *)openbor_setspawnentry, "setspawnentry");
1608     List_InsertAfter(&theFunctionList,
1609                      (void *)openbor_spawn, "spawn");
1610     List_InsertAfter(&theFunctionList,
1611                      (void *)openbor_projectile, "projectile");
1612     List_InsertAfter(&theFunctionList,
1613                      (void *)openbor_transconst, "openborconstant");
1614     List_InsertAfter(&theFunctionList,
1615                      (void *)openbor_playmusic, "playmusic");
1616     List_InsertAfter(&theFunctionList,
1617                      (void *)openbor_fademusic, "fademusic");
1618     List_InsertAfter(&theFunctionList,
1619                      (void *)openbor_setmusicvolume, "setmusicvolume");
1620     List_InsertAfter(&theFunctionList,
1621                      (void *)openbor_setmusictempo, "setmusictempo");
1622     List_InsertAfter(&theFunctionList,
1623                      (void *)openbor_pausemusic, "pausemusic");
1624     List_InsertAfter(&theFunctionList,
1625                      (void *)openbor_pausesamples, "pausesamples");
1626     List_InsertAfter(&theFunctionList,
1627                      (void *)openbor_pausesample, "pausesample");
1628     List_InsertAfter(&theFunctionList,
1629                      (void *)openbor_querychannel, "querychannel");
1630     List_InsertAfter(&theFunctionList,
1631                      (void *)openbor_stopchannel, "stopchannel");
1632     List_InsertAfter(&theFunctionList,
1633                      (void *)openbor_isactivesample, "isactivesample");
1634     List_InsertAfter(&theFunctionList,
1635                      (void *)openbor_sampleid, "sampleid");
1636     List_InsertAfter(&theFunctionList,
1637                      (void *)openbor_playsample, "playsample");
1638     List_InsertAfter(&theFunctionList,
1639                      (void *)openbor_loadsample, "loadsample");
1640     List_InsertAfter(&theFunctionList,
1641                      (void *)openbor_unloadsample, "unloadsample");
1642     List_InsertAfter(&theFunctionList,
1643                      (void *)openbor_fadeout, "fadeout");
1644     List_InsertAfter(&theFunctionList,
1645                      (void *)openbor_playerkeys, "playerkeys");
1646     List_InsertAfter(&theFunctionList,
1647                      (void *)openbor_changepalette, "changepalette");
1648     List_InsertAfter(&theFunctionList,
1649                      (void *)openbor_damageentity, "damageentity");
1650     List_InsertAfter(&theFunctionList,
1651                      (void *)openbor_killentity, "killentity");
1652     List_InsertAfter(&theFunctionList,
1653                      (void *)openbor_dograb, "dograb");
1654     List_InsertAfter(&theFunctionList,
1655                      (void *)openbor_findtarget, "findtarget");
1656     List_InsertAfter(&theFunctionList,
1657                      (void *)openbor_checkrange, "checkrange");
1658     List_InsertAfter(&theFunctionList,
1659                      (void *)openbor_gettextobjproperty, "gettextobjproperty");
1660     List_InsertAfter(&theFunctionList,
1661                      (void *)openbor_changetextobjproperty, "changetextobjproperty");
1662     List_InsertAfter(&theFunctionList,
1663                      (void *)openbor_settextobj, "settextobj");
1664     List_InsertAfter(&theFunctionList,
1665                      (void *)openbor_cleartextobj, "cleartextobj");
1666     List_InsertAfter(&theFunctionList,
1667                      (void *)openbor_getlayerproperty, "getlayerproperty");
1668     List_InsertAfter(&theFunctionList,
1669                      (void *)openbor_changelayerproperty, "changelayerproperty");
1670     List_InsertAfter(&theFunctionList,
1671                      (void *)openbor_getlevelproperty, "getlevelproperty");
1672     List_InsertAfter(&theFunctionList,
1673                      (void *)openbor_changelevelproperty, "changelevelproperty");
1674     List_InsertAfter(&theFunctionList,
1675                      (void *)openbor_checkhole, "checkhole");
1676     List_InsertAfter(&theFunctionList,
1677                      (void *)openbor_checkholeindex, "checkholeindex");
1678     List_InsertAfter(&theFunctionList,
1679                      (void *)openbor_checkwall, "checkwall");
1680     List_InsertAfter(&theFunctionList,
1681                      (void *)openbor_checkholeindex, "checkwallindex");
1682     List_InsertAfter(&theFunctionList,
1683                      (void *)openbor_checkplatformbelow, "checkplatformbelow");
1684     List_InsertAfter(&theFunctionList,
1685                      (void *)openbor_checkplatformabove, "checkplatformabove");
1686     List_InsertAfter(&theFunctionList,
1687                      (void *)openbor_checkplatformbetween, "checkplatformbetween");
1688     List_InsertAfter(&theFunctionList,
1689                      (void *)openbor_checkbasemap, "checkbasemap");
1690     List_InsertAfter(&theFunctionList,
1691                      (void *)openbor_checkbasemap, "checkbasemapindex");
1692     List_InsertAfter(&theFunctionList,
1693                      (void *)openbor_generatebasemap, "generatebasemap");
1694     List_InsertAfter(&theFunctionList,
1695                      (void *)openbor_openfilestream, "openfilestream");
1696     List_InsertAfter(&theFunctionList,
1697                      (void *)openbor_getfilestreamline, "getfilestreamline");
1698     List_InsertAfter(&theFunctionList,
1699                      (void *)openbor_getfilestreamargument, "getfilestreamargument");
1700     List_InsertAfter(&theFunctionList,
1701                      (void *)openbor_filestreamnextline, "filestreamnextline");
1702     List_InsertAfter(&theFunctionList,
1703                      (void *)openbor_getfilestreamposition, "getfilestreamposition");
1704     List_InsertAfter(&theFunctionList,
1705                      (void *)openbor_setfilestreamposition, "setfilestreamposition");
1706     List_InsertAfter(&theFunctionList,
1707                      (void *)openbor_filestreamappend, "filestreamappend");
1708     List_InsertAfter(&theFunctionList,
1709                      (void *)openbor_createfilestream, "createfilestream");
1710     List_InsertAfter(&theFunctionList,
1711                      (void *)openbor_closefilestream, "closefilestream");
1712     List_InsertAfter(&theFunctionList,
1713                      (void *)openbor_savefilestream, "savefilestream");
1714     List_InsertAfter(&theFunctionList,
1715                      (void *)openbor_getindexedvar, "getindexedvar");
1716     List_InsertAfter(&theFunctionList,
1717                      (void *)openbor_setindexedvar, "setindexedvar");
1718     List_InsertAfter(&theFunctionList,
1719                      (void *)openbor_getscriptvar, "getscriptvar");
1720     List_InsertAfter(&theFunctionList,
1721                      (void *)openbor_setscriptvar, "setscriptvar");
1722     List_InsertAfter(&theFunctionList,
1723                      (void *)openbor_getentityvar, "getentityvar");
1724     List_InsertAfter(&theFunctionList,
1725                      (void *)openbor_setentityvar, "setentityvar");
1726     List_InsertAfter(&theFunctionList,
1727                      (void *)openbor_shutdown, "shutdown");
1728     List_InsertAfter(&theFunctionList,
1729                      (void *)openbor_jumptobranch, "jumptobranch");
1730     List_InsertAfter(&theFunctionList,
1731                      (void *)openbor_changelight, "changelight");
1732     List_InsertAfter(&theFunctionList,
1733                      (void *)openbor_changeshadowcolor, "changeshadowcolor");
1734     List_InsertAfter(&theFunctionList,
1735                      (void *)openbor_bindentity, "bindentity");
1736     List_InsertAfter(&theFunctionList,
1737                      (void *)openbor_array, "array");
1738     List_InsertAfter(&theFunctionList,
1739                      (void *)openbor_size, "size");
1740     List_InsertAfter(&theFunctionList,
1741                      (void *)openbor_get, "get");
1742     List_InsertAfter(&theFunctionList,
1743                      (void *)openbor_set, "set");
1744     List_InsertAfter(&theFunctionList,
1745                      (void *)openbor_delete, "delete");
1746     List_InsertAfter(&theFunctionList,
1747                      (void *)openbor_add, "add");
1748     List_InsertAfter(&theFunctionList,
1749                      (void *)openbor_reset, "reset");
1750     List_InsertAfter(&theFunctionList,
1751                      (void *)openbor_next, "next");
1752     List_InsertAfter(&theFunctionList,
1753                      (void *)openbor_previous, "previous");
1754     List_InsertAfter(&theFunctionList,
1755                      (void *)openbor_key, "key");
1756     List_InsertAfter(&theFunctionList,
1757                      (void *)openbor_value, "value");
1758     List_InsertAfter(&theFunctionList,
1759                      (void *)openbor_islast, "islast");
1760     List_InsertAfter(&theFunctionList,
1761                      (void *)openbor_isfirst, "isfirst");
1762     List_InsertAfter(&theFunctionList,
1763                      (void *)openbor_allocscreen, "allocscreen");
1764     List_InsertAfter(&theFunctionList,
1765                      (void *)openbor_clearscreen, "clearscreen");
1766     List_InsertAfter(&theFunctionList,
1767                      (void *)openbor_setdrawmethod, "setdrawmethod");
1768     List_InsertAfter(&theFunctionList,
1769                      (void *)openbor_changedrawmethod, "changedrawmethod");
1770     List_InsertAfter(&theFunctionList,
1771                      (void *)openbor_updateframe, "updateframe");
1772     List_InsertAfter(&theFunctionList,
1773                      (void *)openbor_performattack, "performattack");
1774     List_InsertAfter(&theFunctionList,
1775                      (void *)openbor_executeanimation, "executeanimation");
1776     List_InsertAfter(&theFunctionList,
1777                      (void *)openbor_setidle, "setidle");
1778     List_InsertAfter(&theFunctionList,
1779                      (void *)openbor_getentity, "getentity");
1780     List_InsertAfter(&theFunctionList,
1781                      (void *)openbor_loadmodel, "loadmodel");
1782     List_InsertAfter(&theFunctionList,
1783                      (void *)openbor_loadsprite, "loadsprite");
1784     List_InsertAfter(&theFunctionList,
1785                      (void *)openbor_hallfame, "hallfame");
1786     List_InsertAfter(&theFunctionList,
1787                      (void *)openbor_menu_options, "options");
1788     List_InsertAfter(&theFunctionList,
1789                      (void *)openbor_playwebm, "playwebm");
1790     List_InsertAfter(&theFunctionList,
1791                      (void *)openbor_playgif, "playgif");
1792     List_InsertAfter(&theFunctionList,
1793                      (void *)openbor_openanigif, "openanigif");
1794     List_InsertAfter(&theFunctionList,
1795                      (void *)openbor_decodeanigif, "decodeanigif");
1796     List_InsertAfter(&theFunctionList,
1797                      (void *)openbor_getanigifinfo, "getanigifinfo");
1798     List_InsertAfter(&theFunctionList,
1799                      (void *)openbor_strinfirst, "strinfirst");
1800     List_InsertAfter(&theFunctionList,
1801                      (void *)openbor_strinlast, "strinlast");
1802     List_InsertAfter(&theFunctionList,
1803                      (void *)openbor_strleft, "strleft");
1804     List_InsertAfter(&theFunctionList,
1805                      (void *)openbor_strlength, "strlength");
1806     List_InsertAfter(&theFunctionList,
1807                      (void *)openbor_strwidth, "strwidth");
1808     List_InsertAfter(&theFunctionList,
1809                      (void *)openbor_strright, "strright");
1810     List_InsertAfter(&theFunctionList,
1811                      (void *)openbor_getmodelproperty, "getmodelproperty");
1812     List_InsertAfter(&theFunctionList,
1813                      (void *)openbor_changemodelproperty, "changemodelproperty");
1814     List_InsertAfter(&theFunctionList,
1815                      (void *)openbor_rgbcolor, "rgbcolor");
1816 
1817     List_InsertAfter(&theFunctionList,
1818                      (void *)openbor_adjustwalkanimation, "adjustwalkanimation");
1819     List_InsertAfter(&theFunctionList,
1820                      (void *)openbor_finditem, "finditem");
1821     List_InsertAfter(&theFunctionList,
1822                      (void *)openbor_pickup, "pickup");
1823     List_InsertAfter(&theFunctionList,
1824                      (void *)openbor_waypoints, "waypoints");
1825     List_InsertAfter(&theFunctionList,
1826                      (void *)openbor_drawspriteq, "drawspriteq");
1827     List_InsertAfter(&theFunctionList,
1828                      (void *)openbor_clearspriteq, "clearspriteq");
1829     List_InsertAfter(&theFunctionList,
1830                      (void *)openbor_getgfxproperty, "getgfxproperty");
1831     List_InsertAfter(&theFunctionList,
1832                      (void *)openbor_allocscript, "allocscript");
1833     List_InsertAfter(&theFunctionList,
1834                      (void *)openbor_loadscript, "loadscript");
1835     List_InsertAfter(&theFunctionList,
1836                      (void *)openbor_compilescript, "compilescript");
1837     List_InsertAfter(&theFunctionList,
1838                      (void *)openbor_executescript, "executescript");
1839     List_InsertAfter(&theFunctionList,
1840                      (void *)openbor_loadgamefile, "loadgamefile");
1841     List_InsertAfter(&theFunctionList,
1842                      (void *)openbor_finishlevel, "finishlevel");
1843     List_InsertAfter(&theFunctionList,
1844                      (void *)openbor_gotomainmenu, "gotomainmenu");
1845     List_InsertAfter(&theFunctionList,
1846                      (void *)openbor_playgame, "playgame");
1847     List_InsertAfter(&theFunctionList,
1848                      (void *)openbor_getrecordingstatus, "getrecordingstatus");
1849     List_InsertAfter(&theFunctionList,
1850                      (void *)openbor_recordinputs, "recordinputs");
1851     List_InsertAfter(&theFunctionList,
1852                      (void *)openbor_getsaveinfo, "getsaveinfo");
1853 
1854     //printf("Done!\n");
1855 
1856 }
1857 
1858 //////////////////////////////////////////////////////////
1859 ////////////   system functions
1860 //////////////////////////////////////////////////////////
1861 //isempty(var);
system_isempty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1862 HRESULT system_isempty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1863 {
1864     *pretvar = NULL;
1865     if(paramCount != 1)
1866     {
1867         return E_FAIL;
1868     }
1869 
1870     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1871     (*pretvar)->lVal = (LONG)((varlist[0])->vt == VT_EMPTY );
1872 
1873     return S_OK;
1874 }
1875 //NULL();
system_NULL(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1876 HRESULT system_NULL(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1877 {
1878     ScriptVariant_Clear(*pretvar);
1879 
1880     return S_OK;
1881 }
system_exit(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1882 HRESULT system_exit(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1883 {
1884     *pretvar = NULL;
1885     pcurrentscript->pinterpreter->bReset = FALSE;
1886     return S_OK;
1887 }
system_rand(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1888 HRESULT system_rand(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1889 {
1890     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1891     (*pretvar)->lVal = (LONG)rand32();
1892     return S_OK;
1893 }
system_srand(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1894 HRESULT system_srand(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1895 {
1896     LONG ltemp;
1897 
1898     *pretvar = NULL;
1899     if(paramCount != 1)
1900     {
1901         return E_FAIL;
1902     }
1903     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
1904     {
1905         return E_FAIL;
1906     }
1907 
1908     srand32(ltemp);
1909     return S_OK;
1910 }
1911 //getglobalvar(varname);
system_getglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1912 HRESULT system_getglobalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1913 {
1914     LONG ltemp;
1915     ScriptVariant *ptmpvar;
1916 
1917     if(paramCount != 1)
1918     {
1919         goto ggv_error;
1920     }
1921 
1922     if(varlist[0]->vt == VT_STR)
1923     {
1924         ptmpvar = Varlist_GetByName(&global_var_list, StrCache_Get(varlist[0]->strVal));
1925     }
1926     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
1927     {
1928         ptmpvar = Varlist_GetByIndex(&global_var_list, (int)ltemp);
1929     }
1930     else
1931     {
1932         goto ggv_error;
1933     }
1934 
1935     if(ptmpvar)
1936     {
1937         ScriptVariant_Copy(*pretvar,  ptmpvar);
1938     }
1939     else
1940     {
1941         ScriptVariant_Clear(*pretvar);
1942     }
1943     return S_OK;
1944 
1945 ggv_error:
1946     *pretvar = NULL;
1947     return E_FAIL;
1948 }
1949 //setglobalvar(varname, value);
system_setglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1950 HRESULT system_setglobalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1951 {
1952     LONG ltemp;
1953     if(paramCount < 2)
1954     {
1955         goto sgv_error;
1956     }
1957 
1958     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1959 
1960     if(varlist[0]->vt == VT_STR)
1961     {
1962         (*pretvar)->lVal = (LONG)Varlist_SetByName(&global_var_list, StrCache_Get(varlist[0]->strVal), varlist[1]);
1963     }
1964     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
1965     {
1966         (*pretvar)->lVal = (LONG)Varlist_SetByIndex(&global_var_list, (int)ltemp, varlist[1]);
1967     }
1968     else
1969     {
1970         goto sgv_error;
1971     }
1972 
1973     return S_OK;
1974 sgv_error:
1975     *pretvar = NULL;
1976     return E_FAIL;
1977 }
1978 //getlocalvar(varname);
system_getlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1979 HRESULT system_getlocalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1980 {
1981     LONG ltemp;
1982     ScriptVariant *ptmpvar;
1983 
1984     if(paramCount != 1)
1985     {
1986         goto glv_error;
1987     }
1988 
1989     if(varlist[0]->vt == VT_STR)
1990     {
1991         ptmpvar = Varlist_GetByName(pcurrentscript->varlist, StrCache_Get(varlist[0]->strVal));
1992     }
1993     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
1994     {
1995         ptmpvar = Varlist_GetByIndex(pcurrentscript->varlist, (int)ltemp);
1996     }
1997     else
1998     {
1999         goto glv_error;
2000     }
2001 
2002     if(ptmpvar)
2003     {
2004         ScriptVariant_Copy(*pretvar,  ptmpvar);
2005     }
2006     else
2007     {
2008         ScriptVariant_Clear(*pretvar);
2009     }
2010     return S_OK;
2011 
2012 glv_error:
2013     *pretvar = NULL;
2014     return E_FAIL;
2015 }
2016 //setlocalvar(varname, value);
system_setlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2017 HRESULT system_setlocalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2018 {
2019     LONG ltemp;
2020     if(paramCount < 2)
2021     {
2022         goto slv_error;
2023     }
2024 
2025     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2026 
2027     if(varlist[0]->vt == VT_STR)
2028     {
2029         (*pretvar)->lVal = (LONG)Varlist_SetByName(pcurrentscript->varlist, StrCache_Get(varlist[0]->strVal), varlist[1]);
2030     }
2031     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
2032     {
2033         (*pretvar)->lVal = (LONG)Varlist_SetByIndex(pcurrentscript->varlist, (int)ltemp, varlist[1]);
2034     }
2035     else
2036     {
2037         goto slv_error;
2038     }
2039 
2040     return S_OK;
2041 slv_error:
2042     *pretvar = NULL;
2043     return E_FAIL;
2044 }
2045 //clearlocalvar();
system_clearlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2046 HRESULT system_clearlocalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2047 {
2048     *pretvar = NULL;
2049     Varlist_Cleanup(pcurrentscript->varlist);
2050     return S_OK;
2051 }
2052 //clearglobalvar();
system_clearglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2053 HRESULT system_clearglobalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2054 {
2055     *pretvar = NULL;
2056     Varlist_Cleanup(&global_var_list);
2057     return S_OK;
2058 }
2059 
2060 //free();
system_free(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2061 HRESULT system_free(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2062 {
2063     *pretvar = NULL;
2064     if(paramCount < 1)
2065     {
2066         return E_FAIL;
2067     }
2068     if(List_Includes(&scriptheap, varlist[0]->ptrVal))
2069     {
2070         _freeheapnode(List_Retrieve(&scriptheap));
2071         // a script's ondestroy() may free something else and change the list
2072         // position, so set the position to this variant again
2073         List_Includes(&scriptheap, varlist[0]->ptrVal);
2074         List_Remove(&scriptheap);
2075         return S_OK;
2076     }
2077     return E_FAIL;
2078 }
2079 
2080 //typeof(v);
system_typeof(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2081 HRESULT system_typeof(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2082 {
2083     if(paramCount < 1)
2084     {
2085         *pretvar = NULL;
2086         return E_FAIL;
2087     }
2088     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2089     (*pretvar)->lVal = (LONG)varlist[0]->vt;
2090     return S_OK;
2091 }
2092 
math_sin(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2093 HRESULT math_sin(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2094 {
2095     LONG ltemp;
2096     if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
2097     {
2098         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2099         (*pretvar)->dblVal = sin_table[(ltemp % 360 + 360) % 360];
2100         return S_OK;
2101     }
2102     *pretvar = NULL;
2103     return E_FAIL;
2104 }
2105 
math_cos(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2106 HRESULT math_cos(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2107 {
2108     LONG ltemp;
2109     if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
2110     {
2111         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2112         (*pretvar)->dblVal = cos_table[(ltemp % 360 + 360) % 360];
2113         return S_OK;
2114     }
2115     *pretvar = NULL;
2116     return E_FAIL;
2117 }
2118 
math_ssin(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2119 HRESULT math_ssin(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2120 {
2121     DOUBLE dbltemp;
2122 
2123     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2124     {
2125         double PI = 3.14159265;
2126 
2127         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2128         (*pretvar)->dblVal = (DOUBLE)sin(dbltemp*PI/180.0);
2129         return S_OK;
2130     }
2131     *pretvar = NULL;
2132     return E_FAIL;
2133 }
2134 
math_scos(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2135 HRESULT math_scos(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2136 {
2137     DOUBLE dbltemp;
2138 
2139     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2140     {
2141         double PI = 3.14159265;
2142 
2143         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2144         (*pretvar)->dblVal = (DOUBLE)cos(dbltemp*PI/180.0);
2145         return S_OK;
2146     }
2147     *pretvar = NULL;
2148     return E_FAIL;
2149 }
2150 
math_sqrt(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2151 HRESULT math_sqrt(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2152 {
2153     DOUBLE dbltemp;
2154     float inv;
2155 
2156     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2157     {
2158         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2159         inv = invsqrt((float)dbltemp);
2160         assert(inv != 0.0f);
2161         (*pretvar)->dblVal = (DOUBLE)1.0 / inv;
2162         return S_OK;
2163     }
2164     *pretvar = NULL;
2165 
2166     return E_FAIL;
2167 }
2168 
math_pow(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2169 HRESULT math_pow(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2170 {
2171     DOUBLE dbltempA, dbltempB;
2172 
2173     if( SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltempA)) && SUCCEEDED(ScriptVariant_DecimalValue(varlist[1], &dbltempB)) )
2174     {
2175         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2176         (*pretvar)->dblVal = pow((double)dbltempA,(double)dbltempB);
2177         return S_OK;
2178     }
2179     *pretvar = NULL;
2180     return E_FAIL;
2181 }
2182 
math_asin(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2183 HRESULT math_asin(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2184 {
2185     DOUBLE dbltemp;
2186 
2187     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2188     {
2189         double PI = 3.14159265;
2190 
2191         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2192         (*pretvar)->dblVal = (DOUBLE)(asin((double)dbltemp) * 180.0 / PI);
2193         return S_OK;
2194     }
2195     *pretvar = NULL;
2196     return E_FAIL;
2197 }
2198 
math_acos(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2199 HRESULT math_acos(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2200 {
2201     DOUBLE dbltemp;
2202 
2203     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2204     {
2205         double PI = 3.14159265;
2206 
2207         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2208         (*pretvar)->dblVal = (DOUBLE)(aacos((double)dbltemp) * 180.0 / PI);
2209         return S_OK;
2210     }
2211     *pretvar = NULL;
2212     return E_FAIL;
2213 }
2214 
math_atan(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2215 HRESULT math_atan(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2216 {
2217     DOUBLE dbltemp;
2218 
2219     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2220     {
2221         double PI = 3.14159265;
2222 
2223         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2224         (*pretvar)->dblVal = (DOUBLE)(aatan((double)dbltemp) * 180.0 / PI);
2225         return S_OK;
2226     }
2227     *pretvar = NULL;
2228     return E_FAIL;
2229 }
2230 
math_trunc(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2231 HRESULT math_trunc(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2232 {
2233     DOUBLE dbltemp;
2234 
2235     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2236     {
2237         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2238         (*pretvar)->lVal = (LONG)(trunc(dbltemp));
2239         return S_OK;
2240     }
2241     *pretvar = NULL;
2242     return E_FAIL;
2243 }
2244 
math_round(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2245 HRESULT math_round(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2246 {
2247     DOUBLE dbltemp;
2248 
2249     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[0], &dbltemp)))
2250     {
2251         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
2252         (*pretvar)->dblVal = (DOUBLE)(round(dbltemp));
2253         return S_OK;
2254     }
2255     *pretvar = NULL;
2256     return E_FAIL;
2257 }
2258 
2259 
2260 //////////////////////////////////////////////////////////
2261 ////////////   openbor functions
2262 //////////////////////////////////////////////////////////
2263 
2264 //check openborscript.h for systemvariant_enum
2265 
2266 // arranged list, for searching
2267 static const char *svlist[] =
2268 {
2269     "background",
2270     "blockade",
2271     "branchname",
2272     "cheats",
2273     "count_enemies",
2274     "count_entities",
2275     "count_npcs",
2276     "count_players",
2277     "current_branch",
2278     "current_level",
2279     "current_palette",
2280     "current_scene",
2281     "current_set",
2282     "current_stage",
2283     "effectvol",
2284     "elapsed_time",
2285     "ent_max",
2286     "fps",
2287     "freeram",
2288     "game_paused",
2289     "game_speed",
2290     "gfx_x_offset",
2291     "gfx_y_offset",
2292     "gfx_y_offset_adj",
2293     "hresolution",
2294     "in_cheat_options",
2295     "in_control_options",
2296     "in_enginecreditsscreen",
2297     "in_gameoverscreen",
2298     "in_halloffamescreen",
2299     "in_level",
2300     "in_load_game",
2301     "in_menuscreen",
2302     "in_new_game",
2303     "in_options",
2304     "in_selectscreen",
2305     "in_showcomplete",
2306     "in_sound_options",
2307     "in_start_game",
2308     "in_system_options",
2309     "in_titlescreen",
2310     "in_video_options",
2311     "lasthita",
2312     "lasthitc",
2313     "lasthitt",
2314     "lasthitx",
2315     "lasthity",
2316     "lasthitz",
2317     "levelheight",
2318     "levelpos",
2319     "levelwidth",
2320     "lightx",
2321     "lightz",
2322     "maxanimations",
2323     "maxattacktypes",
2324     "maxentityvars",
2325     "maxglobalvars",
2326     "maxindexedvars",
2327     "maxplayers",
2328     "maxscriptvars",
2329     "maxsoundchannels",
2330     "models_cached",
2331     "models_loaded",
2332     "musicvol",
2333     "nofadeout",
2334     "nogameover",
2335     "nohof",
2336     "nojoin",
2337     "nopause",
2338     "nosave",
2339     "noscreenshot",
2340     "noshowcomplete",
2341     "numbasemaps",
2342     "numholes",
2343     "numlayers",
2344     "numpalettes",
2345     "numwalls",
2346     "pakname",
2347     "pause",
2348     "pixelformat",
2349     "player",
2350     "player1",
2351     "player2",
2352     "player3",
2353     "player4",
2354     "player_max_z",
2355     "player_min_z",
2356     "porting",
2357     "sample_play_id",
2358     "scrollmaxx",
2359     "scrollmaxz",
2360     "scrollminx",
2361     "scrollminz",
2362     "self",
2363     "shadowalpha",
2364     "shadowcolor",
2365     "shadowopacity",
2366     "skiptoset",
2367     "slowmotion",
2368     "slowmotion_duration",
2369     "smartbomber",
2370     "soundvol",
2371     "textbox",
2372     "ticks",
2373     "totalram",
2374     "usedram",
2375     "viewporth",
2376     "viewportw",
2377     "viewportx",
2378     "viewporty",
2379     "vresolution",
2380     "vscreen",
2381     "waiting",
2382     "xpos",
2383     "ypos",
2384 };
2385 
2386 
2387 // ===== openborvariant =====
mapstrings_systemvariant(ScriptVariant ** varlist,int paramCount)2388 int mapstrings_systemvariant(ScriptVariant **varlist, int paramCount)
2389 {
2390     char *propname;
2391     int prop;
2392 
2393 
2394     MAPSTRINGS(varlist[0], svlist, _sv_the_end,
2395                "openborvariant: System variable name not found: '%s'\n");
2396 
2397     return 1;
2398 }
2399 
2400 //sample function, used for getting a system variant
2401 //openborvariant(varname);
openbor_systemvariant(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2402 HRESULT openbor_systemvariant(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2403 {
2404     //used for getting the index from the enum of properties
2405     int variantindex = -1;
2406     //the paramCount used for checking.
2407     //check it first so the engine wont crash if the list is empty
2408     if(paramCount != 1)
2409     {
2410         goto systemvariant_error;
2411     }
2412     //call this function's mapstrings function to map string constants to enum values
2413     mapstrings_systemvariant(varlist, paramCount);
2414     //the variant name should be here
2415     //you can check the argument type if you like
2416     if(varlist[0]->vt == VT_INTEGER)
2417     {
2418         variantindex = varlist[0]->lVal;
2419     }
2420     else
2421     {
2422         goto systemvariant_error;
2423     }
2424     ///////these should be your get method, ///////
2425     ScriptVariant_Clear(*pretvar);
2426     if(getsyspropertybyindex(*pretvar, variantindex))
2427     {
2428         return S_OK;
2429     }
2430     //else if
2431     //////////////////////////////////////////////
2432 systemvariant_error:
2433     *pretvar = NULL;
2434     // we have finshed, so return
2435     return E_FAIL;
2436 }
2437 
2438 
2439 //used for changing a system variant
2440 //changeopenborvariant(varname, value);
openbor_changesystemvariant(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2441 HRESULT openbor_changesystemvariant(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2442 {
2443     //used for getting the enum constant corresponding to the desired variable
2444     int variantindex = 0;
2445     //reference to the arguments
2446     ScriptVariant *arg = NULL;
2447     //the paramCount used for checking.
2448     //check it first so the engine wont crash if the list is empty
2449     if(paramCount != 2)
2450     {
2451         goto changesystemvariant_error;
2452     }
2453     // map string constants to enum constants for speed
2454     mapstrings_systemvariant(varlist, paramCount);
2455     //get the 1st argument
2456     arg = varlist[0];
2457     //the variant name should be here
2458     //you can check the argument type if you like
2459     if(arg->vt == VT_INTEGER)
2460     {
2461         variantindex = arg->lVal;
2462     }
2463     else
2464     {
2465         goto changesystemvariant_error;
2466     }
2467 
2468     if(changesyspropertybyindex(variantindex, varlist[1]))
2469     {
2470         return S_OK;
2471     }
2472 changesystemvariant_error:
2473     *pretvar = NULL;
2474     // we have finshed, so return
2475     return E_FAIL;
2476 
2477 }
2478 
2479 // use font_printf to draw string
2480 //drawstring(x, y, font, string, z);
openbor_drawstring(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2481 HRESULT openbor_drawstring(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2482 {
2483     int i;
2484     char buf[256];
2485     LONG value[4];
2486     *pretvar = NULL;
2487 
2488     if(paramCount < 4)
2489     {
2490         goto drawstring_error;
2491     }
2492 
2493     for(i = 0; i < 3; i++)
2494     {
2495         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
2496         {
2497             goto drawstring_error;
2498         }
2499     }
2500     if(paramCount > 4)
2501     {
2502         if(FAILED(ScriptVariant_IntegerValue(varlist[4], value + 3)))
2503         {
2504             goto drawstring_error;
2505         }
2506     }
2507     else
2508     {
2509         value[3] = 0;
2510     }
2511     ScriptVariant_ToString(varlist[3], buf);
2512     font_printf((int)value[0], (int)value[1], (int)value[2], (int)value[3], "%s", buf);
2513     return S_OK;
2514 
2515 drawstring_error:
2516     printf("First 3 values must be integer values and 4th value a string: drawstring(int x, int y, int font, value)\n");
2517     return E_FAIL;
2518 }
2519 
2520 //use screen_printf
2521 //drawstringtoscreen(screen, x, y, font, string);
openbor_drawstringtoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2522 HRESULT openbor_drawstringtoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2523 {
2524     int i;
2525     s_screen *scr;
2526     char buf[256];
2527     LONG value[3];
2528     *pretvar = NULL;
2529 
2530     if(paramCount != 5)
2531     {
2532         goto drawstring_error;
2533     }
2534 
2535     if(varlist[0]->vt != VT_PTR)
2536     {
2537         goto drawstring_error;
2538     }
2539     scr = (s_screen *)varlist[0]->ptrVal;
2540     if(!scr)
2541     {
2542         goto drawstring_error;
2543     }
2544 
2545     for(i = 0; i < 3; i++)
2546     {
2547         if(FAILED(ScriptVariant_IntegerValue(varlist[i + 1], value + i)))
2548         {
2549             goto drawstring_error;
2550         }
2551     }
2552 
2553     ScriptVariant_ToString(varlist[4], buf);
2554     screen_printf(scr, (int)value[0], (int)value[1], (int)value[2], "%s", buf);
2555     return S_OK;
2556 
2557 drawstring_error:
2558     printf("Function needs a valid screen handle, 3 integers and a string value: drawstringtoscreen(screen, int font, value)\n");
2559     return E_FAIL;
2560 }
2561 
2562 // debug purpose
2563 //log(string);
openbor_log(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2564 HRESULT openbor_log(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2565 {
2566     char buf[256];
2567     *pretvar = NULL;
2568 
2569     if(paramCount != 1)
2570     {
2571         goto drawstring_error;
2572     }
2573 
2574     ScriptVariant_ToString(varlist[0], buf);
2575     printf("%s", buf);
2576     return S_OK;
2577 
2578 drawstring_error:
2579     printf("Function needs 1 parameter: log(value)\n");
2580     return E_FAIL;
2581 }
2582 
2583 //drawbox(x, y, width, height, z, color, lut);
openbor_drawbox(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2584 HRESULT openbor_drawbox(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2585 {
2586     int i;
2587     LONG value[6], l;
2588     *pretvar = NULL;
2589     s_drawmethod dm;
2590 
2591     if(paramCount < 6)
2592     {
2593         goto drawbox_error;
2594     }
2595 
2596     for(i = 0; i < 6; i++)
2597     {
2598         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
2599         {
2600             goto drawbox_error;
2601         }
2602     }
2603 
2604     if(paramCount > 6)
2605     {
2606         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
2607         {
2608             goto drawbox_error;
2609         }
2610     }
2611     else
2612     {
2613         l = -1;
2614     }
2615 
2616     if(l >= 0)
2617     {
2618         l %= MAX_BLENDINGS + 1;
2619     }
2620     if(drawmethod.flag)
2621     {
2622         dm = drawmethod;
2623     }
2624     else
2625     {
2626         dm = plainmethod;
2627     }
2628     dm.alpha = l;
2629     spriteq_add_box((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], (int)value[5], &dm);
2630 
2631     return S_OK;
2632 
2633 drawbox_error:
2634     printf("Function requires 6 integer values: drawbox(int x, int y, int width, int height, int z, int color, int lut)\n");
2635     return E_FAIL;
2636 }
2637 
2638 //drawboxtoscreen(screen, x, y, width, height, color, lut);
openbor_drawboxtoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2639 HRESULT openbor_drawboxtoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2640 {
2641     int i;
2642     s_screen *s;
2643     LONG value[5], l;
2644     *pretvar = NULL;
2645     s_drawmethod dm;
2646 
2647     if(paramCount < 6)
2648     {
2649         goto drawbox_error;
2650     }
2651 
2652     s = (s_screen *)varlist[0]->ptrVal;
2653 
2654     if(!s)
2655     {
2656         goto drawbox_error;
2657     }
2658 
2659     for(i = 1; i < 6; i++)
2660     {
2661         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
2662         {
2663             goto drawbox_error;
2664         }
2665     }
2666 
2667     if(paramCount > 6)
2668     {
2669         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
2670         {
2671             goto drawbox_error;
2672         }
2673     }
2674     else
2675     {
2676         l = -1;
2677     }
2678 
2679     if(l >= 0)
2680     {
2681         l %= MAX_BLENDINGS + 1;
2682     }
2683     if(drawmethod.flag)
2684     {
2685         dm = drawmethod;
2686     }
2687     else
2688     {
2689         dm = plainmethod;
2690     }
2691     dm.alpha = l;
2692 
2693     putbox((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, &dm);
2694 
2695     return S_OK;
2696 
2697 drawbox_error:
2698     printf("Function requires a screen handle and 5 integer values, 7th integer value is optional: drawboxtoscreen(screen, int x, int y, int width, int height, int color, int lut)\n");
2699     return E_FAIL;
2700 }
2701 
2702 //drawline(x1, y1, x2, y2, z, color, lut);
openbor_drawline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2703 HRESULT openbor_drawline(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2704 {
2705     int i;
2706     LONG value[6], l;
2707     *pretvar = NULL;
2708     s_drawmethod dm;
2709 
2710     if(paramCount < 6)
2711     {
2712         goto drawline_error;
2713     }
2714 
2715     for(i = 0; i < 6; i++)
2716     {
2717         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
2718         {
2719             goto drawline_error;
2720         }
2721     }
2722 
2723     if(paramCount > 6)
2724     {
2725         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
2726         {
2727             goto drawline_error;
2728         }
2729     }
2730     else
2731     {
2732         l = -1;
2733     }
2734 
2735     if(l >= 0 )
2736     {
2737         l %= MAX_BLENDINGS + 1;
2738     }
2739     if(drawmethod.flag)
2740     {
2741         dm = drawmethod;
2742     }
2743     else
2744     {
2745         dm = plainmethod;
2746     }
2747     dm.alpha = l;
2748     spriteq_add_line((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], (int)value[5], &dm);
2749 
2750     return S_OK;
2751 
2752 drawline_error:
2753     printf("Function requires 6 integer values, 7th integer value is optional: drawline(int x1, int y1, int x2, int y2, int z, int color, int lut)\n");
2754     return E_FAIL;
2755 }
2756 
2757 //drawlinetoscreen(screen, x1, y1, x2, y2, color, lut);
openbor_drawlinetoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2758 HRESULT openbor_drawlinetoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2759 {
2760     int i;
2761     LONG value[5], l;
2762     s_screen *s;
2763     *pretvar = NULL;
2764     s_drawmethod dm;
2765 
2766     if(paramCount < 6)
2767     {
2768         goto drawline_error;
2769     }
2770 
2771     s = (s_screen *)varlist[0]->ptrVal;
2772 
2773     if(!s)
2774     {
2775         goto drawline_error;
2776     }
2777 
2778     for(i = 1; i < 6; i++)
2779     {
2780         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
2781         {
2782             goto drawline_error;
2783         }
2784     }
2785 
2786     if(paramCount > 6)
2787     {
2788         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
2789         {
2790             goto drawline_error;
2791         }
2792     }
2793     else
2794     {
2795         l = -1;
2796     }
2797 
2798     if(l >= 0 )
2799     {
2800         l %= MAX_BLENDINGS + 1;
2801     }
2802     if(drawmethod.flag)
2803     {
2804         dm = drawmethod;
2805     }
2806     else
2807     {
2808         dm = plainmethod;
2809     }
2810     dm.alpha = l;
2811     putline((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, &dm);
2812 
2813     return S_OK;
2814 drawline_error:
2815     printf("Function requires a screen handle and 5 integer values, 7th integer value is optional: drawlinetoscreen(screen, int x1, int y1, int x2, int y2, int color, int lut)\n");
2816     return E_FAIL;
2817 }
2818 
2819 //drawsprite(sprite, x, y, z, sortid);
openbor_drawsprite(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2820 HRESULT openbor_drawsprite(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2821 {
2822     int i;
2823     LONG value[4];
2824     s_sprite *spr;
2825     *pretvar = NULL;
2826 
2827     if(paramCount < 4)
2828     {
2829         goto drawsprite_error;
2830     }
2831     if(varlist[0]->vt != VT_PTR)
2832     {
2833         goto drawsprite_error;
2834     }
2835 
2836     spr = varlist[0]->ptrVal;
2837     if(!spr)
2838     {
2839         goto drawsprite_error;
2840     }
2841 
2842     value[3] = (LONG)0;
2843     for(i = 1; i < paramCount && i < 5; i++)
2844     {
2845         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
2846         {
2847             goto drawsprite_error;
2848         }
2849     }
2850 
2851     spriteq_add_frame((int)value[0], (int)value[1], (int)value[2], spr, &drawmethod, (int)value[3]);
2852 
2853     return S_OK;
2854 
2855 drawsprite_error:
2856     printf("Function requires a valid sprite handle 3 integer values, 5th integer value is optional: drawsprite(sprite, int x, int y, int z, int sortid)\n");
2857     return E_FAIL;
2858 }
2859 
2860 //drawspritetoscreen(sprite, screen, x, y);
openbor_drawspritetoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2861 HRESULT openbor_drawspritetoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2862 {
2863     int i;
2864     LONG value[2];
2865     s_sprite *spr;
2866     s_screen *scr;
2867     *pretvar = NULL;
2868 
2869     if(paramCount < 4)
2870     {
2871         goto drawsprite_error;
2872     }
2873     if(varlist[0]->vt != VT_PTR)
2874     {
2875         goto drawsprite_error;
2876     }
2877     spr = varlist[0]->ptrVal;
2878     if(!spr)
2879     {
2880         goto drawsprite_error;
2881     }
2882 
2883     if(varlist[1]->vt != VT_PTR)
2884     {
2885         goto drawsprite_error;
2886     }
2887     scr = varlist[1]->ptrVal;
2888     if(!scr)
2889     {
2890         goto drawsprite_error;
2891     }
2892 
2893     for(i = 2; i < paramCount && i < 4; i++)
2894     {
2895         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 2)))
2896         {
2897             goto drawsprite_error;
2898         }
2899     }
2900 
2901     putsprite((int)value[0], (int)value[1], spr, scr, &drawmethod);
2902 
2903     return S_OK;
2904 
2905 drawsprite_error:
2906     printf("Function requires a valid sprite handle, a valid screen handle and 2 integer values: drawspritetoscreen(sprite, screen, int x, int y)\n");
2907     return E_FAIL;
2908 }
2909 
2910 //drawdot(x, y, z, color, lut);
openbor_drawdot(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2911 HRESULT openbor_drawdot(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2912 {
2913     int i;
2914     LONG value[4], l;
2915     *pretvar = NULL;
2916     s_drawmethod dm;
2917 
2918     if(paramCount < 4)
2919     {
2920         goto drawdot_error;
2921     }
2922 
2923     for(i = 0; i < 4; i++)
2924     {
2925         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
2926         {
2927             goto drawdot_error;
2928         }
2929     }
2930 
2931     if(paramCount > 4)
2932     {
2933         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
2934         {
2935             goto drawdot_error;
2936         }
2937     }
2938     else
2939     {
2940         l = -1;
2941     }
2942 
2943     if(l >= 0 )
2944     {
2945         l %= MAX_BLENDINGS + 1;
2946     }
2947     if(drawmethod.flag)
2948     {
2949         dm = drawmethod;
2950     }
2951     else
2952     {
2953         dm = plainmethod;
2954     }
2955     dm.alpha = l;
2956     spriteq_add_dot((int)value[0], (int)value[1], (int)value[2], (int)value[3], &dm);
2957 
2958     return S_OK;
2959 
2960 drawdot_error:
2961     printf("Function requires 4 integer values, 5th integer value is optional: drawdot(int x, int y, int z, int color, int lut)\n");
2962     return E_FAIL;
2963 }
2964 
2965 //drawdottoscreen(screen, x, y, color, lut);
openbor_drawdottoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2966 HRESULT openbor_drawdottoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
2967 {
2968     int i;
2969     LONG value[3], l;
2970     s_screen *s;
2971     *pretvar = NULL;
2972     s_drawmethod dm;
2973 
2974     if(paramCount < 4)
2975     {
2976         goto drawdot_error;
2977     }
2978 
2979     s = (s_screen *)varlist[0]->ptrVal;
2980 
2981     if(!s)
2982     {
2983         goto drawdot_error;
2984     }
2985 
2986     for(i = 1; i < 4; i++)
2987     {
2988         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
2989         {
2990             goto drawdot_error;
2991         }
2992     }
2993 
2994     if(paramCount > 4)
2995     {
2996         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
2997         {
2998             goto drawdot_error;
2999         }
3000     }
3001     else
3002     {
3003         l = -1;
3004     }
3005 
3006     if(l >= 0 )
3007     {
3008         l %= MAX_BLENDINGS + 1;
3009     }
3010     if(drawmethod.flag)
3011     {
3012         dm = drawmethod;
3013     }
3014     else
3015     {
3016         dm = plainmethod;
3017     }
3018     dm.alpha = l;
3019 
3020     putpixel((int)value[0], (int)value[1], (int)value[2], s, &dm);
3021 
3022     return S_OK;
3023 
3024 drawdot_error:
3025     printf("Function requires a screen handle and 3 integer values, 5th integer value is optional: dottoscreen(screen, int x, int y, int color, int lut)\n");
3026     return E_FAIL;
3027 }
3028 
3029 
3030 //drawscreen(screen, x, y, z, lut);
openbor_drawscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3031 HRESULT openbor_drawscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3032 {
3033     int i;
3034     LONG value[3], l;
3035     s_screen *s;
3036     s_drawmethod screenmethod;
3037     *pretvar = NULL;
3038 
3039     if(paramCount < 4)
3040     {
3041         goto drawscreen_error;
3042     }
3043 
3044     s = (s_screen *)varlist[0]->ptrVal;
3045 
3046     if(!s)
3047     {
3048         goto drawscreen_error;
3049     }
3050 
3051     for(i = 1; i < 4; i++)
3052     {
3053         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
3054         {
3055             goto drawscreen_error;
3056         }
3057     }
3058 
3059     if(paramCount > 4)
3060     {
3061         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
3062         {
3063             goto drawscreen_error;
3064         }
3065     }
3066     else
3067     {
3068         l = -1;
3069     }
3070 
3071     if(l >= 0 )
3072     {
3073         l %= MAX_BLENDINGS + 1;
3074     }
3075     if(paramCount <= 4)
3076     {
3077         screenmethod = drawmethod;
3078     }
3079     else
3080     {
3081         screenmethod = plainmethod;
3082         screenmethod.alpha = l;
3083         screenmethod.transbg = 1;
3084     }
3085 
3086     spriteq_add_screen((int)value[0], (int)value[1], (int)value[2], s, &screenmethod, 0);
3087 
3088     return S_OK;
3089 
3090 drawscreen_error:
3091     printf("Function requires a screen handle and 3 integer values, 5th integer value is optional: drawscreen(screen, int x, int y, int z, int lut)\n");
3092     return E_FAIL;
3093 }
3094 
3095 //getindexedvar(int index);
openbor_getindexedvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3096 HRESULT openbor_getindexedvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3097 {
3098     return system_getglobalvar(varlist, pretvar, paramCount);
3099 }
3100 
3101 //setindexedvar(int index, var);
openbor_setindexedvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3102 HRESULT openbor_setindexedvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3103 {
3104     return system_setglobalvar(varlist, pretvar, paramCount);
3105 }
3106 
3107 //getscriptvar(int index);
openbor_getscriptvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3108 HRESULT openbor_getscriptvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3109 {
3110     return system_getlocalvar(varlist, pretvar, paramCount);
3111 }
3112 
3113 //setscriptvar(int index, var);
openbor_setscriptvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3114 HRESULT openbor_setscriptvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3115 {
3116     return system_setlocalvar(varlist, pretvar, paramCount);
3117 }
3118 
3119 //getentityvar(entity, int index);
openbor_getentityvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3120 HRESULT openbor_getentityvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3121 {
3122     LONG ltemp;
3123     ScriptVariant *ptmpvar;
3124     entity *ent;
3125 
3126     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
3127     {
3128         goto gev_error;
3129     }
3130 
3131     ent = (entity *)varlist[0]->ptrVal;
3132 
3133     if(varlist[1]->vt == VT_STR)
3134     {
3135         ptmpvar = Varlist_GetByName(ent->varlist, StrCache_Get(varlist[1]->strVal));
3136     }
3137     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
3138     {
3139         ptmpvar = Varlist_GetByIndex(ent->varlist, (int)ltemp);
3140     }
3141     else
3142     {
3143         goto gev_error;
3144     }
3145 
3146     if(ptmpvar)
3147     {
3148         ScriptVariant_Copy(*pretvar,  ptmpvar);
3149     }
3150     else
3151     {
3152         ScriptVariant_Clear(*pretvar);
3153     }
3154     return S_OK;
3155 
3156 gev_error:
3157     *pretvar = NULL;
3158     return E_FAIL;
3159 }
3160 
3161 //setentityvar(int index, var);
openbor_setentityvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3162 HRESULT openbor_setentityvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3163 {
3164     LONG ltemp;
3165     entity *ent;
3166 
3167     if(paramCount < 3 || varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
3168     {
3169         goto sev_error;
3170     }
3171 
3172     ent = (entity *)varlist[0]->ptrVal;
3173 
3174     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3175 
3176     if(varlist[1]->vt == VT_STR)
3177     {
3178         (*pretvar)->lVal = (LONG)Varlist_SetByName(ent->varlist, StrCache_Get(varlist[1]->strVal), varlist[2]);
3179     }
3180     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
3181     {
3182         (*pretvar)->lVal = (LONG)Varlist_SetByIndex(ent->varlist, (int)ltemp, varlist[2]);
3183     }
3184     else
3185     {
3186         goto sev_error;
3187     }
3188 
3189     return S_OK;
3190 sev_error:
3191     *pretvar = NULL;
3192     return E_FAIL;
3193 }
3194 
3195 //strinfirst(char string, char search_string);
openbor_strinfirst(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3196 HRESULT openbor_strinfirst(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3197 {
3198     char *tempstr = NULL;
3199 
3200     if(paramCount < 2)
3201     {
3202         goto sif_error;
3203     }
3204 
3205     if(varlist[0]->vt != VT_STR || varlist[1]->vt != VT_STR)
3206     {
3207         printf("\n Error, strinfirst({string}, {search string}): Strinfirst must be passed valid {string} and {search string}. \n");
3208         goto sif_error;
3209     }
3210 
3211     tempstr = strstr((char *)StrCache_Get(varlist[0]->strVal), (char *)StrCache_Get(varlist[1]->strVal));
3212 
3213     if (tempstr != NULL)
3214     {
3215         ScriptVariant_ChangeType(*pretvar, VT_STR);
3216         StrCache_Copy((*pretvar)->strVal, tempstr);
3217     }
3218     else
3219     {
3220         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3221         (*pretvar)->lVal = -1;
3222     }
3223     return S_OK;
3224 
3225 sif_error:
3226     *pretvar = NULL;
3227     return E_FAIL;
3228 }
3229 
3230 //strinlast(char string, char search_string);
openbor_strinlast(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3231 HRESULT openbor_strinlast(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3232 {
3233     char *tempstr = NULL;
3234 
3235     if(paramCount < 2)
3236     {
3237         goto sil_error;
3238     }
3239 
3240     if(varlist[0]->vt != VT_STR || varlist[1]->vt != VT_STR)
3241     {
3242         printf("\n Error, strinlast({string}, {search string}): Strinlast must be passed valid {string} and {search string}. \n");
3243         goto sil_error;
3244     }
3245 
3246     tempstr = strrchr((char *)StrCache_Get(varlist[0]->strVal), varlist[1]->strVal);
3247 
3248     if (tempstr != NULL)
3249     {
3250         ScriptVariant_ChangeType(*pretvar, VT_STR);
3251         StrCache_Copy((*pretvar)->strVal, tempstr);
3252     }
3253     else
3254     {
3255         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3256         (*pretvar)->lVal = -1;
3257     }
3258     return S_OK;
3259 sil_error:
3260     *pretvar = NULL;
3261     return E_FAIL;
3262 }
3263 
3264 //strleft(char string, int i);
openbor_strleft(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3265 HRESULT openbor_strleft(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3266 {
3267     if(paramCount < 2)
3268     {
3269         goto sl_error;
3270     }
3271 
3272     if(varlist[0]->vt != VT_STR || varlist[1]->vt != VT_INTEGER)
3273     {
3274         printf("\n Error, strleft({string}, {characters}): Invalid or missing parameter. Strleft must be passed valid {string} and number of {characters}.\n");
3275         goto sl_error;
3276     }
3277     ScriptVariant_ChangeType(*pretvar, VT_STR);
3278     StrCache_NCopy((*pretvar)->strVal, (char *)StrCache_Get(varlist[0]->strVal), varlist[1]->lVal);
3279 
3280     return S_OK;
3281 sl_error:
3282     *pretvar = NULL;
3283     return E_FAIL;
3284 }
3285 
3286 //strlength(char string);
openbor_strlength(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3287 HRESULT openbor_strlength(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3288 {
3289     if(paramCount < 1 || varlist[0]->vt != VT_STR)
3290     {
3291         goto strlength_error;
3292     }
3293 
3294     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3295     (*pretvar)->lVal = strlen((char *)StrCache_Get(varlist[0]->strVal));
3296     return S_OK;
3297 
3298 strlength_error:
3299     printf("Error, strlength({string}): Invalid or missing parameter. Strlength must be passed a valid {string}.\n");
3300     *pretvar = NULL;
3301     return E_FAIL;
3302 }
3303 
3304 //strwidth(char string, int font);
openbor_strwidth(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3305 HRESULT openbor_strwidth(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3306 {
3307     LONG ltemp;
3308     if(paramCount < 2 || varlist[0]->vt != VT_STR ||
3309             FAILED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
3310     {
3311         goto strwidth_error;
3312     }
3313 
3314     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3315     (*pretvar)->lVal = font_string_width((int)ltemp, (char *)StrCache_Get(varlist[0]->strVal));
3316     return S_OK;
3317 
3318 strwidth_error:
3319     printf("Error, strwidth({string}, {font}): Invalid or missing parameter.\n");
3320     *pretvar = NULL;
3321     return E_FAIL;
3322 }
3323 
3324 //strright(char string, int i);
openbor_strright(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3325 HRESULT openbor_strright(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3326 {
3327     char *tempstr = NULL;
3328 
3329     if(paramCount < 2)
3330     {
3331         goto sr_error;
3332     }
3333 
3334     if(varlist[0]->vt != VT_STR || varlist[1]->vt != VT_INTEGER)
3335     {
3336         printf("\n Error, strright({string}, {characters}): Invalid or missing parameter. Strright must be passed valid {string} and number of {characters}.\n");
3337         goto sr_error;
3338     }
3339 
3340     tempstr = (char *)StrCache_Get(varlist[0]->strVal);
3341 
3342     if (tempstr && tempstr[0])
3343     {
3344         ScriptVariant_ChangeType(*pretvar, VT_STR);
3345         StrCache_Copy((*pretvar)->strVal, &tempstr[varlist[1]->lVal]);
3346     }
3347     else
3348     {
3349         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3350         (*pretvar)->lVal = -1;
3351     }
3352 
3353     return S_OK;
3354 sr_error:
3355     *pretvar = NULL;
3356     return E_FAIL;
3357 }
3358 
openbor_getmodelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3359 HRESULT openbor_getmodelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3360 {
3361     int iArg;
3362 
3363     if(paramCount < 2)
3364     {
3365         *pretvar = NULL;
3366         return E_FAIL;
3367     }
3368 
3369     if((varlist[0]->vt != VT_INTEGER && varlist[0]->vt != VT_STR) || varlist[1]->vt != VT_INTEGER)
3370     {
3371         printf("\n Error, getmodelproperty({model}, {property}): Invalid or missing parameter. Getmodelproperty must be passed valid {model} and {property} indexes.\n");
3372     }
3373 
3374     iArg = varlist[0]->vt == VT_INTEGER ? varlist[0]->lVal : get_cached_model_index(StrCache_Get(varlist[0]->strVal));
3375 
3376     if(iArg < 0 || iArg >= models_cached)
3377     {
3378         return E_FAIL;
3379     }
3380 
3381     switch (varlist[1]->lVal)
3382     {
3383     case 0:                                                    //Loaded?
3384     {
3385         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3386         (*pretvar)->lVal = (LONG)model_cache[iArg].loadflag;
3387         break;
3388     }
3389     case 1:
3390     {
3391         ScriptVariant_ChangeType(*pretvar, VT_PTR);
3392         (*pretvar)->ptrVal = (VOID *)model_cache[iArg].model;
3393     }
3394     case 2:
3395     {
3396         ScriptVariant_ChangeType(*pretvar, VT_STR);
3397         StrCache_Copy((*pretvar)->strVal, model_cache[iArg].name);
3398         break;
3399     }
3400     case 3:
3401     {
3402         ScriptVariant_ChangeType(*pretvar, VT_STR);
3403         StrCache_Copy((*pretvar)->strVal, model_cache[iArg].path);
3404         break;
3405     }
3406     case 4:                                                    //Loaded?
3407     {
3408         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3409         (*pretvar)->lVal = (LONG)model_cache[iArg].selectable;
3410         break;
3411     }
3412     }
3413 
3414     return S_OK;
3415 }
3416 
openbor_changemodelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3417 HRESULT openbor_changemodelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3418 {
3419     int iArg;
3420     LONG ltemp;
3421 
3422     if(paramCount < 2)
3423     {
3424         *pretvar = NULL;
3425         return E_FAIL;
3426     }
3427 
3428     if((varlist[0]->vt != VT_INTEGER && varlist[0]->vt != VT_STR) || varlist[1]->vt != VT_INTEGER)
3429     {
3430         printf("\n Error, changemodelproperty({model}, {property}, {value}): Invalid or missing parameter. Changemodelproperty must be passed valid {model}, {property} and {value}.\n");
3431     }
3432 
3433     iArg = varlist[0]->vt == VT_INTEGER ? varlist[0]->lVal : get_cached_model_index(StrCache_Get(varlist[0]->strVal));
3434 
3435     if(iArg < 0 || iArg >= models_cached)
3436     {
3437         return E_FAIL;
3438     }
3439 
3440     switch (varlist[1]->lVal)
3441     {
3442     case 0:                                                    //Loaded?
3443     {
3444         /*
3445         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
3446         	model_cache[iArg].loadflag = (int)ltemp;
3447         else (*pretvar)->lVal = (LONG)0;
3448         break;
3449         */
3450     }
3451     case 1:
3452     {
3453         /*
3454         if(varlist[2]->vt != VT_STR)
3455         {
3456         	printf("You must give a string value for {value}.\n");
3457         	goto changeentityproperty_error;
3458         }
3459         strcpy(model_cache[iArg].model, (char*)StrCache_Get(varlist[2]->strVal));
3460         (*pretvar)->lVal = (LONG)1;
3461         break;
3462         */
3463     }
3464     case 2:
3465     {
3466         /*
3467         if(varlist[2]->vt != VT_STR)
3468         {
3469         	printf("You must give a string value for {value}.\n");
3470         	goto changeentityproperty_error;
3471         }
3472         strcpy(model_cache[iArg].name, (char*)StrCache_Get(varlist[2]->strVal));
3473         (*pretvar)->lVal = (LONG)1;
3474         break;
3475         */
3476     }
3477     case 3:
3478     {
3479         /*
3480         if(varlist[2]->vt != VT_STR)
3481         {
3482         	printf("You must give a string value for {value}.\n");
3483         	goto changeentityproperty_error;
3484         }
3485         strcpy(model_cache[iArg].path, (char*)StrCache_Get(varlist[2]->strVal));
3486         (*pretvar)->lVal = (LONG)1;
3487         break;
3488         */
3489     }
3490     case 4:
3491     {
3492         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
3493         {
3494             model_cache[iArg].selectable = (int)ltemp;
3495         }
3496         else
3497         {
3498             (*pretvar)->lVal = (LONG)0;
3499         }
3500         break;
3501     }
3502     }
3503 
3504     return S_OK;
3505 }
3506 
3507 // ===== getentityproperty =====
3508 enum entityproperty_enum
3509 {
3510     _ep_a,
3511     _ep_aggression,
3512     _ep_aiattack,
3513     _ep_aiflag,
3514     _ep_aimove,
3515     _ep_alpha,
3516     _ep_animal,
3517     _ep_animating,
3518     _ep_animation,
3519     _ep_animation_handle,
3520     _ep_animationid,
3521     _ep_animheight,
3522     _ep_animhits,
3523     _ep_animnum,
3524     _ep_animpos,
3525     _ep_animvalid,
3526     _ep_antigrab,
3527     _ep_antigravity,
3528     _ep_attackid,
3529     _ep_attacking,
3530     _ep_attackthrottle,
3531     _ep_attackthrottletime,
3532     _ep_autokill,
3533     _ep_base,
3534     _ep_bbox,
3535     _ep_blink,
3536     _ep_blockback,
3537     _ep_blockodds,
3538     _ep_blockpain,
3539     _ep_boomerang,
3540     _ep_boss,
3541     _ep_bounce,
3542     _ep_bound,
3543     _ep_candamage,
3544     _ep_chargerate,
3545     _ep_colourmap,
3546     _ep_colourtable,
3547     _ep_combostep,
3548     _ep_combotime,
3549     _ep_custom_target,
3550     _ep_damage_on_landing,
3551     _ep_dead,
3552     _ep_defaultmodel,
3553     _ep_defaultname,
3554     _ep_defense,
3555     _ep_destx,
3556     _ep_destz,
3557     _ep_detect,
3558     _ep_direction,
3559     _ep_dot,
3560     _ep_dropframe,
3561     _ep_edelay,
3562     _ep_energycost,
3563     _ep_escapecount,
3564     _ep_escapehits,
3565     _ep_exists,
3566     _ep_facing,
3567     _ep_falldie,
3568     _ep_flash,
3569     _ep_freezetime,
3570     _ep_frozen,
3571     _ep_gfxshadow,
3572     _ep_grabbing,
3573     _ep_grabforce,
3574     _ep_guardpoints,
3575     _ep_hasplatforms,
3576     _ep_health,
3577     _ep_height,
3578     _ep_hitbyid,
3579     _ep_hitheadplatform,
3580     _ep_hitwall,
3581     _ep_hmapl,
3582     _ep_hmapu,
3583     _ep_hostile,
3584     _ep_icon,
3585     _ep_iconposition,
3586     _ep_invincible,
3587     _ep_invinctime,
3588     _ep_jugglepoints,
3589     _ep_jumpheight,
3590     _ep_jumpmovex,
3591     _ep_jumpmovez,
3592     _ep_jumpspeed,
3593     _ep_knockdowncount,
3594     _ep_komap,
3595     _ep_landedplatform,
3596     _ep_landframe,
3597     _ep_lifeposition,
3598     _ep_lifespancountdown,
3599     _ep_link,
3600     _ep_map,
3601     _ep_mapcount,
3602     _ep_mapdefault,
3603     _ep_maps,
3604     _ep_maptime,
3605     _ep_maxguardpoints,
3606     _ep_maxhealth,
3607     _ep_maxjugglepoints,
3608     _ep_maxmp,
3609     _ep_model,
3610     _ep_mp,
3611     _ep_mpdroprate,
3612     _ep_mprate,
3613     _ep_mpset,
3614     _ep_mpstable,
3615     _ep_mpstableval,
3616     _ep_name,
3617     _ep_nameposition,
3618     _ep_nextanim,
3619     _ep_nextmove,
3620     _ep_nextthink,
3621     _ep_no_adjust_base,
3622     _ep_noaicontrol,
3623     _ep_nodieblink,
3624     _ep_nodrop,
3625     _ep_nograb,
3626     _ep_nohithead,
3627     _ep_nolife,
3628     _ep_nopain,
3629     _ep_numweapons,
3630     _ep_offense,
3631     _ep_offscreen_noatk_factor,
3632     _ep_offscreenkill,
3633     _ep_opponent,
3634     _ep_owner,
3635     _ep_pain_time,
3636     _ep_parent,
3637     _ep_path,
3638     _ep_pathfindstep,
3639     _ep_playerindex,
3640     _ep_position,
3641     _ep_projectile,
3642     _ep_projectilehit,
3643     _ep_range,
3644     _ep_releasetime,
3645     _ep_running,
3646     _ep_rush_count,
3647     _ep_rush_tally,
3648     _ep_rush_time,
3649     _ep_score,
3650     _ep_scroll,
3651     _ep_seal,
3652     _ep_sealtime,
3653     _ep_setlayer,
3654     _ep_shadowbase,
3655     _ep_sortid,
3656     _ep_spawntype,
3657     _ep_speed,
3658     _ep_sprite,
3659     _ep_spritea,
3660     _ep_stalltime,
3661     _ep_stats,
3662     _ep_staydown,
3663     _ep_staydownatk,
3664     _ep_stealth,
3665     _ep_subentity,
3666     _ep_subject_to_basemap,
3667     _ep_subject_to_gravity,
3668     _ep_subject_to_hole,
3669     _ep_subject_to_maxz,
3670     _ep_subject_to_minz,
3671     _ep_subject_to_obstacle,
3672     _ep_subject_to_platform,
3673     _ep_subject_to_screen,
3674     _ep_subject_to_wall,
3675     _ep_subtype,
3676     _ep_takeaction,
3677     _ep_think,
3678     _ep_thold,
3679     _ep_throwdamage,
3680     _ep_throwdist,
3681     _ep_throwframewait,
3682     _ep_throwheight,
3683     _ep_tosstime,
3684     _ep_tossv,
3685     _ep_trymove,
3686     _ep_type,
3687     _ep_velocity,
3688     _ep_vulnerable,
3689     _ep_walkoffmovex,
3690     _ep_walkoffmovez,
3691     _ep_weapent,
3692     _ep_weaploss,
3693     _ep_weapnum,
3694     _ep_weapon,
3695     _ep_x,
3696     _ep_xdir,
3697     _ep_y,
3698     _ep_z,
3699     _ep_zdir,
3700     _ep_the_end,
3701 };
3702 
3703 // arranged list, for searching
3704 static const char *eplist[] =
3705 {
3706     "a",
3707     "aggression",
3708     "aiattack",
3709     "aiflag",
3710     "aimove",
3711     "alpha",
3712     "animal",
3713     "animating",
3714     "animation",
3715     "animation.handle",
3716     "animationid",
3717     "animheight",
3718     "animhits",
3719     "animnum",
3720     "animpos",
3721     "animvalid",
3722     "antigrab",
3723     "antigravity",
3724     "attackid",
3725     "attacking",
3726     "attackthrottle",
3727     "attackthrottletime",
3728     "autokill",
3729     "base",
3730     "bbox",
3731     "blink",
3732     "blockback",
3733     "blockodds",
3734     "blockpain",
3735     "boomerang",
3736     "boss",
3737     "bounce",
3738     "bound",
3739     "candamage",
3740     "chargerate",
3741     "colourmap",
3742     "colourtable",
3743     "combostep",
3744     "combotime",
3745     "custom_target",
3746     "damage_on_landing",
3747     "dead",
3748     "defaultmodel",
3749     "defaultname",
3750     "defense",
3751     "destx",
3752     "destz",
3753     "detect",
3754     "direction",
3755     "dot",
3756     "dropframe",
3757     "edelay",
3758     "energycost",
3759     "escapecount",
3760     "escapehits",
3761     "exists",
3762     "facing",
3763     "falldie",
3764     "flash",
3765     "freezetime",
3766     "frozen",
3767     "gfxshadow",
3768     "grabbing",
3769     "grabforce",
3770     "guardpoints",
3771     "hasplatforms",
3772     "health",
3773     "height",
3774     "hitbyid",
3775     "hitheadplatform",
3776     "hitwall",
3777     "hmapl",
3778     "hmapu",
3779     "hostile",
3780     "icon",
3781     "iconposition",
3782     "invincible",
3783     "invinctime",
3784     "jugglepoints",
3785     "jumpheight",
3786     "jumpmovex",
3787     "jumpmovez",
3788     "jumpspeed",
3789     "knockdowncount",
3790     "komap",
3791     "landedplatform",
3792     "landframe",
3793     "lifeposition",
3794     "lifespancountdown",
3795     "link",
3796     "map",
3797     "mapcount",
3798     "mapdefault",
3799     "maps",
3800     "maptime",
3801     "maxguardpoints",
3802     "maxhealth",
3803     "maxjugglepoints",
3804     "maxmp",
3805     "model",
3806     "mp",
3807     "mpdroprate",
3808     "mprate",
3809     "mpset",
3810     "mpstable",
3811     "mpstableval",
3812     "name",
3813     "nameposition",
3814     "nextanim",
3815     "nextmove",
3816     "nextthink",
3817     "no_adjust_base",
3818     "noaicontrol",
3819     "nodieblink",
3820     "nodrop",
3821     "nograb",
3822     "nohithead",
3823     "nolife",
3824     "nopain",
3825     "numweapons",
3826     "offense",
3827     "offscreennoatkfactor",
3828     "offscreenkill",
3829     "opponent",
3830     "owner",
3831     "pain_time",
3832     "parent",
3833     "path",
3834     "pathfindstep",
3835     "playerindex",
3836     "position",
3837     "projectile",
3838     "projectilehit",
3839     "range",
3840     "releasetime",
3841     "running",
3842     "rush_count",
3843     "rush_tally",
3844     "rush_time",
3845     "score",
3846     "scroll",
3847     "seal",
3848     "sealtime",
3849     "setlayer",
3850     "shadowbase",
3851     "sortid",
3852     "spawntype",
3853     "speed",
3854     "sprite",
3855     "spritea",
3856     "stalltime",
3857     "stats",
3858     "staydown",
3859     "staydownatk",
3860     "stealth",
3861     "subentity",
3862     "subject_to_basemap",
3863     "subject_to_gravity",
3864     "subject_to_hole",
3865     "subject_to_maxz",
3866     "subject_to_minz",
3867     "subject_to_obstacle",
3868     "subject_to_platform",
3869     "subject_to_screen",
3870     "subject_to_wall",
3871     "subtype",
3872     "takeaction",
3873     "think",
3874     "thold",
3875     "throwdamage",
3876     "throwdist",
3877     "throwframewait",
3878     "throwheight",
3879     "tosstime",
3880     "tossv",
3881     "trymove",
3882     "type",
3883     "velocity",
3884     "vulnerable",
3885     "walkoffmovex",
3886     "walkoffmovez",
3887     "weapent",
3888     "weaploss",
3889     "weapnum",
3890     "weapon",
3891     "x",
3892     "xdir",
3893     "y",
3894     "z",
3895     "zdir",
3896 };
3897 
3898 enum aiflag_enum
3899 {
3900     _ep_aiflag_animating,
3901     _ep_aiflag_attacking,
3902     _ep_aiflag_autokill,
3903     _ep_aiflag_blink,
3904     _ep_aiflag_blocking,
3905     _ep_aiflag_charging,
3906     _ep_aiflag_dead,
3907     _ep_aiflag_drop,
3908     _ep_aiflag_falling,
3909     _ep_aiflag_frozen,
3910     _ep_aiflag_getting,
3911     _ep_aiflag_idlemode,
3912     _ep_aiflag_idling,
3913     _ep_aiflag_inbackpain,
3914     _ep_aiflag_inpain,
3915     _ep_aiflag_invincible,
3916     _ep_aiflag_jumpid,
3917     _ep_aiflag_jumping,
3918     _ep_aiflag_projectile,
3919     _ep_aiflag_running,
3920     _ep_aiflag_toexplode,
3921     _ep_aiflag_turning,
3922     _ep_aiflag_walking,
3923     _ep_aiflag_walkmode,
3924     _ep_aiflag_the_end,
3925 };
3926 
3927 
3928 static const char *eplist_aiflag[] =
3929 {
3930     "animating",
3931     "attacking",
3932     "autokill",
3933     "blink",
3934     "blocking",
3935     "charging",
3936     "dead",
3937     "drop",
3938     "falling",
3939     "frozen",
3940     "getting",
3941     "idlemode",
3942     "idling",
3943     "inbackpain",
3944     "inpain",
3945     "invincible",
3946     "jumpid",
3947     "jumping",
3948     "projectile",
3949     "running",
3950     "toexplode",
3951     "turning",
3952     "walking",
3953     "walkmode",
3954 };
3955 
3956 // ===== changedrawmethod ======
3957 enum drawmethod_enum
3958 {
3959     _dm_alpha,
3960     _dm_amplitude,
3961     _dm_beginsize,
3962     _dm_centerx,
3963     _dm_centery,
3964     _dm_channelb,
3965     _dm_channelg,
3966     _dm_channelr,
3967     _dm_clip,
3968     _dm_cliph,
3969     _dm_clipw,
3970     _dm_clipx,
3971     _dm_clipy,
3972     _dm_enabled,
3973     _dm_endsize,
3974     _dm_fillcolor,
3975     _dm_flag,
3976     _dm_fliprotate,
3977     _dm_flipx,
3978     _dm_flipy,
3979     _dm_perspective,
3980     _dm_remap,
3981     _dm_reset,
3982     _dm_rotate,
3983     _dm_scalex,
3984     _dm_scaley,
3985     _dm_shiftx,
3986     _dm_table,
3987     _dm_tintcolor,
3988     _dm_tintmode,
3989     _dm_transbg,
3990     _dm_watermode,
3991     _dm_wavelength,
3992     _dm_wavespeed,
3993     _dm_wavetime,
3994     _dm_xrepeat,
3995     _dm_xspan,
3996     _dm_yrepeat,
3997     _dm_yspan,
3998     _dm_the_end,
3999 };
4000 
4001 enum _prop_dropframe_enum
4002 {
4003     _PROP_DROPFRAME_FRAME,
4004     _PROP_DROPFRAME_VELOCITY_X,
4005     _PROP_DROPFRAME_VELOCITY_Y,
4006     _PROP_DROPFRAME_VELOCITY_Z,
4007     _PROP_DROPFRAME_THE_END
4008 };
4009 
4010 enum _prop_followup_enum
4011 {
4012     _PROP_FOLLOWUP_ANIMATION,
4013     _PROP_FOLLOWUP_CONDITION,
4014     _PROP_FOLLOWUP_THE_END
4015 };
4016 
4017 enum _prop_jumpframe_enum
4018 {
4019     _PROP_JUMPFRAME_FRAME,
4020     _PROP_JUMPFRAME_VELOCITY_X,
4021     _PROP_JUMPFRAME_VELOCITY_Y,
4022     _PROP_JUMPFRAME_VELOCITY_Z,
4023     _PROP_JUMPFRAME_THE_END
4024 };
4025 
4026 enum _prop_landframe_enum
4027 {
4028     _PROP_LANDFRAME_FRAME,
4029     _PROP_LANDFRAME_VELOCITY_X,
4030     _PROP_LANDFRAME_VELOCITY_Y,
4031     _PROP_LANDFRAME_VELOCITY_Z,
4032     _PROP_LANDFRAME_THE_END
4033 };
4034 
4035 enum _prop_loop_enum
4036 {
4037     _PROP_LOOP_FRAME_MAX,
4038     _PROP_LOOP_FRAME_MIN,
4039     _PROP_LOOP_MODE,
4040     _PROP_LOOP_THE_END
4041 };
4042 
4043  enum _prop_move_enum
4044 {
4045     _PROP_MOVE_BASE,
4046     _PROP_MOVE_X,
4047     _PROP_MOVE_Y,
4048     _PROP_MOVE_Z,
4049     _PROP_MOVE_THE_END
4050 };
4051 
4052  enum _prop_offset_enum
4053 {
4054     _PROP_OFFSET_X,
4055     _PROP_OFFSET_Y,
4056     _PROP_OFFSET_THE_END
4057 };
4058 
4059  enum _prop_platform_enum
4060 {
4061     _PROP_PLATFORM_ALT,
4062     _PROP_PLATFORM_DEPTH,
4063     _PROP_PLATFORM_LOWERLEFT,
4064     _PROP_PLATFORM_LOWERRIGHT,
4065     _PROP_PLATFORM_UPPERLEFT,
4066     _PROP_PLATFORM_UPPERRIGHT,
4067     _PROP_PLATFORM_X,
4068     _PROP_PLATFORM_Z,
4069     _PROP_PLATFORM_THE_END
4070 };
4071 
4072 enum _prop_projectile_enum
4073 {
4074     _PROP_PROJECTILE_BOMB,
4075     _PROP_PROJECTILE_FLASH,
4076     _PROP_PROJECTILE_KNIFE,
4077     _PROP_PROJECTILE_SHOOTFRAME,
4078     _PROP_PROJECTILE_STAR,
4079     _PROP_PROJECTILE_THROWFRAME,
4080     _PROP_PROJECTILE_THROWPOSITION_BASE,
4081     _PROP_PROJECTILE_THROWPOSITION_X,
4082     _PROP_PROJECTILE_THROWPOSITION_Y,
4083     _PROP_PROJECTILE_THROWPOSITION_Z,
4084     _PROP_PROJECTILE_TOSSFRAME,
4085     _PROP_PROJECTILE_THE_END
4086 };
4087 
4088 enum _prop_quakeframe_enum
4089 {
4090     _PROP_QUAKEFRAME_FRAMESTART,
4091     _PROP_QUAKEFRAME_INTENSITY,
4092     _PROP_QUAKEFRAME_REPEAT,
4093     _PROP_QUAKEFRAME_THE_END
4094 };
4095 
4096 enum _prop_range_enum
4097 {
4098     _PROP_RANGEA_MAX,
4099     _PROP_RANGEA_MIN,
4100     _PROP_RANGEB_MAX,
4101     _PROP_RANGEB_MIN,
4102     _PROP_RANGEX_MAX,
4103     _PROP_RANGEX_MIN,
4104     _PROP_RANGEZ_MAX,
4105     _PROP_RANGEZ_MIN,
4106     _PROP_RANGE_THE_END
4107 };
4108 
4109 enum _prop_size_enum
4110 {
4111     _PROP_SIZE_BASE,
4112     _PROP_SIZE_X,
4113     _PROP_SIZE_Y,
4114     _PROP_SIZE_Z,
4115     _PROP_SIZE_THE_END
4116 };
4117 
4118  enum _prop_shadow_enum
4119 {
4120     _PROP_FSHADOW,
4121     _PROP_SHADOW_COORDS_X,
4122     _PROP_SHADOW_COORDS_Y,
4123     _PROP_SHADOW_THE_END
4124 };
4125 
4126 enum _prop_spawnframe_enum
4127 {
4128     _PROP_SPAWNFRAME_FRAME,
4129     _PROP_SPAWNFRAME_RELATIVE,
4130     _PROP_SPAWNFRAME_X,
4131     _PROP_SPAWNFRAME_Y,
4132     _PROP_SPAWNFRAME_Z,
4133     _PROP_SPAWNFRAME_THE_END
4134 };
4135 
4136 enum _prop_spritea_enum
4137 {
4138     _PROP_SPRITEA_CENTERX,
4139     _PROP_SPRITEA_CENTERY,
4140     _PROP_SPRITEA_FILE,
4141     _PROP_SPRITEA_OFFSETX,
4142     _PROP_SPRITEA_OFFSETY,
4143     _PROP_SPRITEA_SPRITE,
4144     _PROP_SPRITEA_THE_END
4145 };
4146 
4147 enum _prop_summonframe_enum
4148 {
4149     _PROP_SUMMONFRAME_FRAME,
4150     _PROP_SUMMONFRAME_RELATIVE,
4151     _PROP_SUMMONFRAME_X,
4152     _PROP_SUMMONFRAME_Y,
4153     _PROP_SUMMONFRAME_Z,
4154     _PROP_SUMMONFRAME_THE_END
4155 };
4156 
4157 enum _prop_weaponframe_enum
4158 {
4159     _PROP_WEAPONFRAME_FRAME,
4160     _PROP_WEAPONFRAME_WEAPON,
4161     _PROP_WEAPONFRAME_THE_END
4162 };
4163 
4164 enum _ep_defense_enum
4165 {
4166     _ep_defense_blockpower,
4167     _ep_defense_blockratio,
4168     _ep_defense_blockthreshold,
4169     _ep_defense_blocktype,
4170     _ep_defense_factor,
4171     _ep_defense_knockdown,
4172     _ep_defense_pain,
4173     _ep_defense_the_end,
4174 };
4175 
4176 enum gep_dot_enum
4177 {
4178     _ep_dot_force,
4179     _ep_dot_mode,
4180     _ep_dot_owner,
4181     _ep_dot_rate,
4182     _ep_dot_time,
4183     _ep_dot_type,
4184     _ep_dot_the_end,
4185 };
4186 
4187 enum gep_edelay_enum
4188 {
4189     _ep_edelay_cap_max,
4190     _ep_edelay_cap_min,
4191     _ep_edelay_factor,
4192     _ep_edelay_mode,
4193     _ep_edelay_range_max,
4194     _ep_edelay_range_min,
4195     _ep_edelay_the_end,
4196 };
4197 
4198 enum gep_energycost_enum
4199 {
4200     _ep_energycost_cost,
4201     _ep_energycost_disable,
4202     _ep_energycost_mponly,
4203     _ep_energycost_the_end,
4204 };
4205 
4206 enum gep_flash_enum
4207 {
4208     _ep_flash_block,
4209     _ep_flash_def,
4210     _ep_flash_noattack,
4211     _ep_flash_the_end,
4212 };
4213 
4214 enum gep_icon_enum
4215 {
4216     _ep_icon_def,
4217     _ep_icon_die,
4218     _ep_icon_get,
4219     _ep_icon_mphigh,
4220     _ep_icon_mplow,
4221     _ep_icon_mpmed,
4222     _ep_icon_pain,
4223     _ep_icon_weapon,
4224     _ep_icon_x,
4225     _ep_icon_y,
4226     _ep_icon_the_end,
4227 };
4228 
4229 enum _ep_knockdowncount_enum
4230 {
4231     _ep_knockdowncount_current,
4232     _ep_knockdowncount_max,
4233     _ep_knockdowncount_time,
4234     _ep_knockdowncount_the_end,
4235 };
4236 
4237 enum gep_landframe_enum
4238 {
4239     _ep_landframe_ent,
4240     _ep_landframe_frame,
4241     _ep_landframe_the_end,
4242 };
4243 
4244 enum gep_maps_enum
4245 {
4246     _ep_maps_count,
4247     _ep_maps_current,
4248     _ep_maps_default,
4249     _ep_maps_dying,
4250     _ep_maps_dying_critical,
4251     _ep_maps_dying_low,
4252     _ep_maps_frozen,
4253     _ep_maps_hide_end,
4254     _ep_maps_hide_start,
4255     _ep_maps_ko,
4256     _ep_maps_kotype,
4257     _ep_maps_table,
4258     _ep_maps_time,
4259     _ep_maps_the_end,
4260 };
4261 
4262 enum gep_range_enum
4263 {
4264     _ep_range_amax,
4265     _ep_range_amin,
4266     _ep_range_bmax,
4267     _ep_range_bmin,
4268     _ep_range_xmax,
4269     _ep_range_xmin,
4270     _ep_range_zmax,
4271     _ep_range_zmin,
4272     _ep_range_the_end,
4273 };
4274 
4275 enum gep_running_enum
4276 {
4277     _ep_running_jumpx,
4278     _ep_running_jumpy,
4279     _ep_running_land,
4280     _ep_running_movez,
4281     _ep_running_speed,
4282     _ep_running_the_end,
4283 };
4284 
4285 enum gep_spritea_enum
4286 {
4287     _ep_spritea_centerx,
4288     _ep_spritea_centery,
4289     _ep_spritea_file,
4290     _ep_spritea_offsetx,
4291     _ep_spritea_offsety,
4292     _ep_spritea_sprite,
4293     _ep_spritea_the_end,
4294 };
4295 
4296 enum gep_staydown_enum
4297 {
4298     _ep_staydown_rise,
4299     _ep_staydown_riseattack,
4300     _ep_staydown_riseattack_stall,
4301     _ep_staydown_the_end,
4302 };
4303 
4304 enum cep_hostile_candamage_enum
4305 {
4306     _ep_hcd_ground,
4307     _ep_hcd_type_enemy,
4308     _ep_hcd_type_npc,
4309     _ep_hcd_type_obstacle,
4310     _ep_hcd_type_player,
4311     _ep_hcd_type_shot,
4312     _ep_hcd_the_end,
4313 };
4314 
4315 enum cep_takeaction_enum
4316 {
4317     _ep_ta_bomb_explode,
4318     _ep_ta_common_animation_normal,
4319     _ep_ta_common_attack_proc,
4320     _ep_ta_common_block,
4321     _ep_ta_common_drop,
4322     _ep_ta_common_fall,
4323     _ep_ta_common_get,
4324     _ep_ta_common_grab,
4325     _ep_ta_common_grabattack,
4326     _ep_ta_common_grabbed,
4327     _ep_ta_common_jump,
4328     _ep_ta_common_land,
4329     _ep_ta_common_lie,
4330     _ep_ta_common_pain,
4331     _ep_ta_common_prejump,
4332     _ep_ta_common_rise,
4333     _ep_ta_common_spawn,
4334     _ep_ta_common_turn,
4335     _ep_ta_normal_prepare,
4336     _ep_ta_npc_warp,
4337     _ep_ta_player_blink,
4338     _ep_ta_suicide,
4339     _ep_ta_the_end,
4340 };
4341 
4342 enum cep_think_enum   // 2011_03_03, DC: Think types.
4343 {
4344     _ep_th_common_think,
4345     _ep_th_player_think,
4346     _ep_th_steam_think,
4347     _ep_th_steamer_think,
4348     _ep_th_text_think,
4349     _ep_th_trap_think,
4350     _ep_th_the_end,
4351 };
4352 
mapstrings_animationproperty(ScriptVariant ** varlist,int paramCount)4353 int mapstrings_animationproperty(ScriptVariant **varlist, int paramCount)
4354 {
4355     return 0;
4356 //    char *propname;
4357 //    const char *aps;
4358 //    int prop, ap; //int prop, i, ep, t;
4359 //    int result = 1;
4360 //
4361 //    MAPSTRINGS(varlist[1], list_animation_prop, ANI_PROP_THE_END,
4362 //               "Property name '%s' is not a supported animation property.\n");
4363 //
4364 //    if(paramCount < 3 || varlist[1]->vt != VT_INTEGER)
4365 //    {
4366 //        return result;
4367 //    }
4368 //    else
4369 //    {
4370 //        ap = varlist[1]->lVal;
4371 //        aps = (ap < ANI_PROP_THE_END && ap >= 0) ? list_animation_prop[ap] : "";
4372 //    }
4373 //
4374 //    return result;
4375 }
4376 
mapstrings_entityproperty(ScriptVariant ** varlist,int paramCount)4377 int mapstrings_entityproperty(ScriptVariant **varlist, int paramCount)
4378 {
4379     char *propname;
4380     const char *eps;
4381     int prop, i, ep, t;
4382 
4383     static const char *proplist_defense[] =
4384     {
4385         "blockpower",
4386         "blockratio",
4387         "blockthreshold",
4388         "blocktype",
4389         "factor",
4390         "knockdown",
4391         "pain",
4392     };
4393 
4394     static const char *proplist_dot[] =
4395     {
4396         "force",
4397         "mode",
4398         "owner",
4399         "rate",
4400         "time",
4401         "type",
4402     };
4403 
4404     static const char *proplist_edelay[] =
4405     {
4406         "cap_max",
4407         "cap_min",
4408         "factor",
4409         "mode",
4410         "range_max",
4411         "range_min",
4412     };
4413 
4414     static const char *proplist_energycost[] =
4415     {
4416         "cost",
4417         "disable",
4418         "mponly",
4419     };
4420 
4421     static const char *proplist_flash[] =
4422     {
4423         "block",
4424         "default",
4425         "noattack",
4426     };
4427 
4428     static const char *proplist_icon[] =
4429     {
4430         "default",
4431         "die",
4432         "get",
4433         "mphigh",
4434         "mplow",
4435         "mpmed",
4436         "pain",
4437         "weapon",
4438         "x",
4439         "y",
4440     };
4441 
4442     static const char *proplist_knockdowncount[] =
4443     {
4444         "current",
4445         "max",
4446         "time",
4447     };
4448 
4449     static const char *proplist_landframe[] =
4450     {
4451         "ent",
4452         "frame",
4453     };
4454 
4455     static const char *proplist_maps[] =
4456     {
4457         "count",
4458         "current",
4459         "default",
4460         "dying",
4461         "dying_critical",
4462         "dying_low",
4463         "frozen",
4464         "hide_end",
4465         "hide_start",
4466         "ko",
4467         "kotype",
4468         "table",
4469         "time",
4470     };
4471 
4472     static const char *proplist_range[] =
4473     {
4474         "amax",
4475         "amin",
4476         "bmax",
4477         "bmin",
4478         "xmax",
4479         "xmin",
4480         "zmax",
4481         "zmin",
4482     };
4483 
4484     static const char *proplist_running[] =
4485     {
4486         "jumpx",
4487         "jumpy",
4488         "land",
4489         "movez",
4490         "speed",
4491     };
4492 
4493     static const char *proplist_spritea[] =
4494     {
4495         "centerx",
4496         "centery",
4497         "file",
4498         "offsetx",
4499         "offsety",
4500         "sprite",
4501     };
4502 
4503     static const char *proplist_staydown[] =
4504     {
4505         "rise",
4506         "riseattack",
4507         "riseattack_stall",
4508     };
4509 
4510     static const char *proplist_hostile_candamage[] =
4511     {
4512         "ground",
4513         "type_enemy",
4514         "type_npc",
4515         "type_obstacle",
4516         "type_player",
4517         "type_shot",
4518     };
4519 
4520     static const char *proplist_takeaction[] =
4521     {
4522         "bomb_explode",
4523         "common_animation_normal",
4524         "common_attack_proc",
4525         "common_block",
4526         "common_drop",
4527         "common_fall",
4528         "common_get",
4529         "common_grab",
4530         "common_grabattack",
4531         "common_grabbed",
4532         "common_jump",
4533         "common_land",
4534         "common_lie",
4535         "common_pain",
4536         "common_prejump",
4537         "common_rise",
4538         "common_spawn",
4539         "common_turn",
4540         "normal_prepare",
4541         "npc_warp",
4542         "player_blink",
4543         "suicide",
4544     };
4545 
4546     static const char *proplist_think[] =   // 2011_03_03, DC: Think types.
4547     {
4548         "common_think",
4549         "player_think",
4550         "steam_think",
4551         "steamer_think",
4552         "text_think",
4553         "trap_think",
4554     };
4555 
4556     if(paramCount < 2)
4557     {
4558         return 1;
4559     }
4560 
4561     // map entity properties
4562     MAPSTRINGS(varlist[1], eplist, _ep_the_end,
4563                "Property name '%s' is not supported by function getentityproperty.\n");
4564 
4565     if(paramCount < 3 || varlist[1]->vt != VT_INTEGER)
4566     {
4567         return 1;
4568     }
4569 
4570     ep = varlist[1]->lVal;
4571     eps = (ep < _ep_the_end && ep >= 0) ? eplist[ep] : "";
4572 
4573     switch (ep)
4574     {
4575     // deprecation warning for "a" property
4576     case _ep_a:
4577     {
4578         printf("\nNote: Property 'a' has been deprecated. Use 'y' to access the Y (vertical) axis property.\n");
4579         break;
4580     }
4581     // map subproperties of aiflag property
4582     case _ep_aiflag:
4583     {
4584         MAPSTRINGS(varlist[2], eplist_aiflag, _ep_aiflag_the_end,
4585                    _is_not_a_known_subproperty_of_, eps);
4586         break;
4587     }
4588 
4589     // map subproperties of defense property
4590     case _ep_defense:
4591     {
4592         if(paramCount >= 4)
4593         {
4594             MAPSTRINGS(varlist[3], proplist_defense, _ep_defense_the_end,
4595                        _is_not_a_known_subproperty_of_, eps);
4596         }
4597         break;
4598     }
4599     // map subproperties of DOT
4600     case _ep_dot:
4601     {
4602         MAPSTRINGS(varlist[2], proplist_dot, _ep_dot_the_end,
4603                    _is_not_a_known_subproperty_of_, eps);
4604         break;
4605     }
4606     // map subproperties of Edelay property
4607     case _ep_edelay:
4608     {
4609         MAPSTRINGS(varlist[2], proplist_edelay, _ep_edelay_the_end,
4610                    _is_not_a_known_subproperty_of_, eps);
4611         break;
4612     }
4613     // map subproperties of Energycost
4614     case _ep_energycost:
4615     {
4616         MAPSTRINGS(varlist[2], proplist_energycost, _ep_energycost_the_end,
4617                    _is_not_a_known_subproperty_of_, eps);
4618         break;
4619     }
4620     // map subproperties of Flash
4621     case _ep_flash:
4622     {
4623         MAPSTRINGS(varlist[2], proplist_flash, _ep_flash_the_end,
4624                    _is_not_a_known_subproperty_of_, eps);
4625         break;
4626     }
4627     // map subproperties of Icon
4628     case _ep_icon:
4629     {
4630         MAPSTRINGS(varlist[2], proplist_icon, _ep_icon_the_end,
4631                    _is_not_a_known_subproperty_of_, eps);
4632         break;
4633     }
4634 
4635     // map subproperties of Knockdowncount
4636     case _ep_knockdowncount:
4637     {
4638         MAPSTRINGS(varlist[2], proplist_knockdowncount, _ep_knockdowncount_the_end,
4639                    _is_not_a_known_subproperty_of_, eps);
4640         break;
4641     }
4642     // map subproperties of Landframe
4643     case _ep_landframe:
4644     {
4645         MAPSTRINGS(varlist[2], proplist_landframe, _ep_landframe_the_end,
4646                    _is_not_a_known_subproperty_of_, eps);
4647         break;
4648     }
4649     // map subproperties of Maps
4650     case  _ep_maps:
4651     {
4652         MAPSTRINGS(varlist[2], proplist_maps, _ep_maps_the_end,
4653                    _is_not_a_known_subproperty_of_, eps);
4654         break;
4655     }
4656     // map subproperties of Range
4657     case _ep_range:
4658     {
4659         MAPSTRINGS(varlist[2], proplist_range, _ep_range_the_end,
4660                    _is_not_a_known_subproperty_of_, eps);
4661         break;
4662     }
4663     // map subproperties of Running
4664     case _ep_running:
4665     {
4666         MAPSTRINGS(varlist[2], proplist_running, _ep_running_the_end,
4667                    _is_not_a_known_subproperty_of_, eps);
4668         break;
4669     }
4670 
4671     // map subproperties of Spritea
4672     case _ep_spritea:
4673     {
4674         MAPSTRINGS(varlist[2], proplist_spritea, _ep_spritea_the_end,
4675                    _is_not_a_known_subproperty_of_, eps);
4676         break;
4677     }
4678     // map subproperties of Staydown
4679     case _ep_staydown:
4680     {
4681         MAPSTRINGS(varlist[2], proplist_staydown, _ep_running_the_end,
4682                    _is_not_a_known_subproperty_of_, eps);
4683         break;
4684     }
4685     //hostile, candamage, projectilehit
4686     case _ep_hostile:
4687     case _ep_candamage:
4688     case _ep_projectilehit:
4689     {
4690         for(i = 2; i < paramCount; i++)
4691         {
4692             t = varlist[i]->vt;
4693             MAPSTRINGS(varlist[i], proplist_hostile_candamage, _ep_hcd_the_end,
4694                        _is_not_supported_by_, eps);
4695 
4696             if(varlist[i]->vt == VT_INTEGER && t == VT_STR)
4697             {
4698                 varlist[i]->lVal |= 0x80000000;    //flag it
4699             }
4700         }
4701         break;
4702     }
4703     // action for takeaction
4704     case _ep_takeaction:
4705     {
4706         MAPSTRINGS(varlist[2], proplist_takeaction, _ep_ta_the_end,
4707                    _is_not_supported_by_, eps);
4708         break;
4709     }
4710     // 2011_03_13, DC: Think sets for think.
4711     case _ep_think:
4712     {
4713         MAPSTRINGS(varlist[2], proplist_think, _ep_th_the_end,
4714                    _is_not_supported_by_, eps);
4715         break;
4716     }
4717     }
4718 
4719     return 1;
4720 }
4721 
4722 // Animation specific properties.
4723 // Caskey, Damon V.
4724 // 2016-10-20
4725 //
4726 // Access animation property by handle (pointer).
4727 //
4728 // set_animation_property(void handle, int property, value)
openbor_set_animation_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)4729 HRESULT openbor_set_animation_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
4730 {
4731     #define SELF_NAME           "set_animation_property(void handle, int property, value)"
4732     #define ARG_MINIMUM         3   // Minimum required arguments.
4733     #define ARG_HANDLE          0   // Handle (pointer to property structure).
4734     #define ARG_PROPERTY        1   // Property to access.
4735     #define ARG_VALUE           2   // New value to apply.
4736 
4737     int                     result      = S_OK; // Success or error?
4738     s_anim                  *handle     = NULL; // Property handle.
4739     e_animation_properties  property    = 0;    // Property to access.
4740 
4741     // Value carriers to apply on properties after
4742     // taken from argument.
4743     int     temp_int;
4744     //DOUBLE  temp_float;
4745 
4746     // Verify incoming arguments. There must be a
4747     // pointer for the animation handle, an integer
4748     // property, and a new value to apply.
4749     if(paramCount < ARG_MINIMUM
4750        || varlist[ARG_HANDLE]->vt != VT_PTR
4751        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
4752     {
4753         *pretvar = NULL;
4754         goto error_local;
4755     }
4756     else
4757     {
4758         handle      = (s_anim *)varlist[ARG_HANDLE]->ptrVal;
4759         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
4760     }
4761 
4762     // Which property to modify?
4763     switch(property)
4764     {
4765         case ANI_PROP_ANIMHITS:
4766 
4767             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
4768             {
4769                 handle->animhits = (int)temp_int;
4770             }
4771 
4772             break;
4773 
4774         case ANI_PROP_ANTIGRAV:
4775 
4776             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
4777             {
4778                 handle->antigrav = (int)temp_int;
4779             }
4780 
4781             break;
4782 
4783         case ANI_PROP_NUMFRAMES:
4784 
4785             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
4786             {
4787                 handle->numframes = (int)temp_int;
4788             }
4789 
4790             break;
4791 
4792         default:
4793 
4794             printf("Unsupported property.\n");
4795             goto error_local;
4796 
4797             break;
4798     }
4799 
4800     return result;
4801 
4802     // Error trapping.
4803     error_local:
4804 
4805     printf("You must provide a valid handle and property: " SELF_NAME "\n");
4806 
4807     result = E_FAIL;
4808     return result;
4809 
4810     #undef SELF_NAME
4811     #undef ARG_MINIMUM
4812     #undef ARG_HANDLE
4813     #undef ARG_PROPERTY
4814     #undef ARG_VALUE
4815 }
4816 
4817 // Animation specific properties.
4818 // Caskey, Damon V.
4819 // 2016-10-20
4820 //
4821 // Access animation property by handle (pointer).
4822 //
4823 // get_animation_property(void handle, int frame, int property)
openbor_get_animation_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)4824 HRESULT openbor_get_animation_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
4825 {
4826     #define SELF_NAME       "get_animation_property(void handle, int property)"
4827     #define ARG_MINIMUM     2   // Minimum required arguments.
4828     #define ARG_HANDLE      0   // Handle (pointer to property structure).
4829     #define ARG_PROPERTY    1   // Property to access.
4830 
4831 
4832     int                     result      = S_OK; // Success or error?
4833     s_anim                  *handle     = NULL; // Property handle.
4834     e_animation_properties  property    = 0;    // Property argument.
4835 
4836     // Clear pass by reference argument used to send
4837     // property data back to calling script.     .
4838     ScriptVariant_Clear(*pretvar);
4839 
4840     // Verify incoming arguments. There should at least
4841     // be a pointer for the property handle and an integer
4842     // to determine which property is accessed.
4843     if(paramCount < ARG_MINIMUM
4844        || varlist[ARG_HANDLE]->vt != VT_PTR
4845        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
4846     {
4847         *pretvar = NULL;
4848         goto error_local;
4849     }
4850     else
4851     {
4852         handle      = (s_anim *)varlist[ARG_HANDLE]->ptrVal;
4853         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
4854     }
4855 
4856     // Which property to get?
4857     switch(property)
4858     {
4859         case ANI_PROP_ANIMHITS:
4860 
4861             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4862             (*pretvar)->lVal = (LONG)handle->animhits;
4863             break;
4864 
4865         case ANI_PROP_ANTIGRAV:
4866 
4867             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4868             (*pretvar)->dblVal = (DOUBLE)handle->antigrav;
4869             break;
4870 
4871         case ANI_PROP_ATTACK:
4872 
4873             // Verify animation has attacks.
4874             if(handle->collision_attack)
4875             {
4876                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
4877                 (*pretvar)->ptrVal = (VOID *)handle->collision_attack;
4878             }
4879 
4880             break;
4881 
4882         case ANI_PROP_COLLISIONONE:
4883 
4884             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4885             (*pretvar)->lVal = (LONG)handle->attackone;
4886             break;
4887 
4888         case ANI_PROP_BODY_COLLISION:
4889 
4890             // Verify animation has any bbox.
4891             if(handle->collision_body)
4892             {
4893                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
4894                 (*pretvar)->ptrVal = (VOID *)handle->collision_body;
4895             }
4896 
4897             break;
4898 
4899         case ANI_PROP_BOUNCE:
4900 
4901             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4902             (*pretvar)->dblVal = (DOUBLE)handle->bounce;
4903 
4904             break;
4905 
4906         case ANI_PROP_CANCEL:
4907 
4908             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4909             (*pretvar)->lVal = (LONG)handle->cancel;
4910             break;
4911 
4912         case ANI_PROP_CHARGETIME:
4913 
4914             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4915             (*pretvar)->dblVal = (DOUBLE)handle->chargetime;
4916             break;
4917 
4918         case ANI_PROP_COUNTERRANGE:
4919 
4920             // Verify animation has item.
4921             if(handle->counterrange)
4922             {
4923                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
4924                 (*pretvar)->ptrVal = (VOID *)handle->counterrange;
4925             }
4926 
4927             break;
4928 
4929         case ANI_PROP_NUMFRAMES:
4930 
4931             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4932             (*pretvar)->lVal = (LONG)handle->numframes;
4933             break;
4934 
4935         default:
4936 
4937             printf("Unsupported property.\n");
4938             goto error_local;
4939             break;
4940     }
4941 
4942     return result;
4943 
4944     // Error trapping.
4945     error_local:
4946 
4947     printf("You must provide a valid handle and property: " SELF_NAME "\n");
4948 
4949     result = E_FAIL;
4950     return result;
4951 
4952     #undef SELF_NAME
4953     #undef ARG_MINIMUM
4954     #undef ARG_HANDLE
4955     #undef ARG_PROPERTY
4956 }
4957 
4958 
4959 
4960 // Attack specific properties.
4961 // Caskey, Damon V.
4962 // 2016-10-20
4963 
4964 // get_attack_collection(void handle, int frame)
4965 //
4966 // Get item handle for an animation frame. When
4967 // multiple items per frame support is implemented,
4968 // this will return the collection of items. It is therefore
4969 // imperative this function NOT be used to access a single
4970 // item handle directly. You should instead use
4971 // get<item>instance(), and pass it the result from
4972 // this function.
openbor_get_attack_collection(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)4973 HRESULT openbor_get_attack_collection(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
4974 {
4975     #define SELF_NAME       "get_attack_collection(void handle, int frame)"
4976     #define ARG_MINIMUM     2   // Minimum required arguments.
4977     #define ARG_HANDLE      0   // Handle (pointer to property structure).
4978     #define ARG_FRAME       1   // Frame to access.
4979 
4980 
4981     int         result      = S_OK;     // Success or error?
4982     s_collision_attack    **handle     = NULL;    // Property handle.
4983     int         frame       = 0;        // Property argument.
4984 
4985     // Clear pass by reference argument used to send
4986     // property data back to calling script.     .
4987     ScriptVariant_Clear(*pretvar);
4988 
4989     // Verify incoming arguments. There should at least
4990     // be a pointer for the property handle and an integer
4991     // to determine which frame is accessed.
4992     if(paramCount < ARG_MINIMUM
4993        || varlist[ARG_HANDLE]->vt != VT_PTR
4994        || varlist[ARG_FRAME]->vt != VT_INTEGER)
4995     {
4996         *pretvar = NULL;
4997         goto error_local;
4998     }
4999     else
5000     {
5001         handle  = (s_collision_attack **)varlist[ARG_HANDLE]->ptrVal;
5002         frame   = (LONG)varlist[ARG_FRAME]->lVal;
5003     }
5004 
5005     // If this frame has property, send value back to user.
5006     if(handle[frame])
5007     {
5008         ScriptVariant_ChangeType(*pretvar, VT_PTR);
5009         (*pretvar)->ptrVal = handle[frame];
5010     }
5011 
5012     return result;
5013 
5014     // Error trapping.
5015     error_local:
5016 
5017     printf("You must provide a valid handle and frame: " SELF_NAME "\n");
5018 
5019     result = E_FAIL;
5020     return result;
5021 
5022     #undef SELF_NAME
5023     #undef ARG_MINIMUM
5024     #undef ARG_HANDLE
5025     #undef ARG_FRAME
5026 }
5027 
5028 // get_attack_instance(void handle, int index)
5029 //
5030 // Get single item handle from item collection.
5031 // As of 2016-10-30, this function is a placeholder and
5032 // simply returns the handle given. It is in place for future
5033 // support of multiple instances per frame.
openbor_get_attack_instance(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5034 HRESULT openbor_get_attack_instance(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
5035 {
5036     #define SELF_NAME       "get_attack_instance(void handle, int index)"
5037     #define ARG_MINIMUM     2   // Minimum required arguments.
5038     #define ARG_HANDLE      0   // Handle (pointer to property structure).
5039     #define ARG_INDEX       1   // Index to access.
5040 
5041     int         result     = S_OK; // Success or error?
5042     s_collision_attack    *handle    = NULL; // Property handle.
5043     //int         index      = 0;    // Property argument.
5044 
5045     // Clear pass by reference argument used to send
5046     // property data back to calling script.     .
5047     ScriptVariant_Clear(*pretvar);
5048 
5049     // Verify incoming arguments. There should at least
5050     // be a pointer for the property handle and an integer
5051     // to determine which index is accessed.
5052     if(paramCount < ARG_MINIMUM
5053        || varlist[ARG_HANDLE]->vt != VT_PTR
5054        || varlist[ARG_INDEX]->vt != VT_INTEGER)
5055     {
5056         *pretvar = NULL;
5057         goto error_local;
5058     }
5059     else
5060     {
5061         handle  = (s_collision_attack *)varlist[ARG_HANDLE]->ptrVal;
5062         //index   = (LONG)varlist[ARG_INDEX]->lVal;
5063     }
5064 
5065     // If this index has property, send value back to user.
5066     //if(handle[index])
5067     //{
5068         ScriptVariant_ChangeType(*pretvar, VT_PTR);
5069         //(*pretvar)->ptrVal = handle[index];
5070 
5071         (*pretvar)->ptrVal = handle;
5072     //}
5073 
5074     return result;
5075 
5076     // Error trapping.
5077     error_local:
5078 
5079     printf("You must provide a valid handle and index: " SELF_NAME "\n");
5080 
5081     result = E_FAIL;
5082     return result;
5083 
5084     #undef SELF_NAME
5085     #undef ARG_MINIMUM
5086     #undef ARG_HANDLE
5087     #undef ARG_INDEX
5088 }
5089 
5090 // get_attack_property(void handle, int property)
openbor_get_attack_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5091 HRESULT openbor_get_attack_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
5092 {
5093     #define SELF_NAME       "get_attack_property(void handle, int property)"
5094     #define ARG_MINIMUM     2   // Minimum required arguments.
5095     #define ARG_HANDLE      0   // Handle (pointer to property structure).
5096     #define ARG_PROPERTY    1   // Property to access.
5097 
5098     int                     result      = S_OK; // Success or error?
5099     s_collision_attack                *handle     = NULL; // Property handle.
5100     e_attack_properties     property    = 0;    // Property argument.
5101 
5102     // Clear pass by reference argument used to send
5103     // property data back to calling script.     .
5104     ScriptVariant_Clear(*pretvar);
5105 
5106     // Verify incoming arguments. There should at least
5107     // be a pointer for the property handle and an integer
5108     // to determine which property is accessed.
5109     if(paramCount < ARG_MINIMUM
5110        || varlist[ARG_HANDLE]->vt != VT_PTR
5111        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
5112     {
5113         *pretvar = NULL;
5114         goto error_local;
5115     }
5116     else
5117     {
5118         handle      = (s_collision_attack *)varlist[ARG_HANDLE]->ptrVal;
5119         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
5120     }
5121 
5122     // Which property to get?
5123     switch(property)
5124     {
5125         case ATTACK_PROP_BLOCK_COST:
5126 
5127             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5128             (*pretvar)->lVal = (LONG)handle->guardcost;
5129             break;
5130 
5131         case ATTACK_PROP_BLOCK_PENETRATE:
5132 
5133             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5134             (*pretvar)->lVal = (LONG)handle->no_block;
5135             break;
5136 
5137         case ATTACK_PROP_COUNTER:
5138 
5139             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5140             (*pretvar)->lVal = (LONG)handle->counterattack;
5141             break;
5142 
5143         case ATTACK_PROP_DAMAGE_FORCE:
5144 
5145             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5146             (*pretvar)->lVal = (LONG)handle->attack_force;
5147             break;
5148 
5149         case ATTACK_PROP_DAMAGE_LAND_FORCE:
5150 
5151             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5152             (*pretvar)->lVal = (LONG)handle->damage_on_landing;
5153             break;
5154 
5155         case ATTACK_PROP_DAMAGE_LAND_MODE:
5156 
5157             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5158             (*pretvar)->lVal = (LONG)handle->blast;
5159             break;
5160 
5161         case ATTACK_PROP_DAMAGE_LETHAL_DISABLE:
5162 
5163             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5164             (*pretvar)->lVal = (LONG)handle->no_kill;
5165             break;
5166 
5167         case ATTACK_PROP_DAMAGE_STEAL:
5168 
5169             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5170             (*pretvar)->lVal = (LONG)handle->steal;
5171             break;
5172 
5173         case ATTACK_PROP_DAMAGE_TYPE:
5174 
5175             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5176             (*pretvar)->lVal = (LONG)handle->attack_type;
5177             break;
5178 
5179 //        case ATTACK_PROP_DAMAGE_RECURSIVE_FORCE:
5180 //
5181 //            ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5182 //            (*pretvar)->lVal = (LONG)handle->dot_force;
5183 //            break;
5184 //
5185 //        case ATTACK_PROP_DAMAGE_RECURSIVE_INDEX:
5186 //
5187 //            ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5188 //            (*pretvar)->lVal = (LONG)handle->dot_index;
5189 //            break;
5190 //
5191 //        case ATTACK_PROP_DAMAGE_RECURSIVE_MODE:
5192 //
5193 //            ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5194 //            (*pretvar)->lVal = (LONG)handle->dot;
5195 //            break;
5196 //
5197 //        case ATTACK_PROP_DAMAGE_RECURSIVE_TIME_EXPIRE:
5198 //
5199 //            ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5200 //            (*pretvar)->lVal = (LONG)handle->dot_time;
5201 //            break;
5202 //
5203 //        case ATTACK_PROP_DAMAGE_RECURSIVE_TIME_RATE:
5204 //
5205 //            ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5206 //            (*pretvar)->lVal = (LONG)handle->dot_rate;
5207 //            break;
5208 
5209         case ATTACK_PROP_EFFECT_BLOCK_FLASH:
5210 
5211             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5212             (*pretvar)->lVal = (LONG)handle->blockflash;
5213             break;
5214 
5215         case ATTACK_PROP_EFFECT_BLOCK_SOUND:
5216 
5217             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5218             (*pretvar)->lVal = (LONG)handle->blocksound;
5219             break;
5220 
5221         case ATTACK_PROP_EFFECT_HIT_FLASH:
5222 
5223             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5224             (*pretvar)->lVal = (LONG)handle->hitflash;
5225             break;
5226 
5227         case ATTACK_PROP_EFFECT_HIT_FLASH_DISABLE:
5228 
5229             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5230             (*pretvar)->lVal = (LONG)handle->no_flash;
5231             break;
5232 
5233         case ATTACK_PROP_EFFECT_HIT_SOUND:
5234 
5235             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5236             (*pretvar)->lVal = (LONG)handle->hitsound;
5237             break;
5238 
5239         case ATTACK_PROP_GROUND:
5240 
5241             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5242             (*pretvar)->lVal = (LONG)handle->otg;
5243             break;
5244 
5245         case ATTACK_PROP_MAP_INDEX:
5246 
5247             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5248             (*pretvar)->lVal = (LONG)handle->forcemap;
5249             break;
5250 
5251         case ATTACK_PROP_MAP_TIME:
5252 
5253             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5254             (*pretvar)->lVal = (LONG)handle->maptime;
5255             break;
5256 
5257         case ATTACK_PROP_POSITION_X:
5258 
5259             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5260             //(*pretvar)->lVal = (LONG)handle->coords.x;
5261             break;
5262 
5263         case ATTACK_PROP_POSITION_Y:
5264 
5265             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5266             //(*pretvar)->lVal = (LONG)handle->coords.y;
5267             break;
5268 
5269         case ATTACK_PROP_REACTION_FALL_FORCE:
5270 
5271             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5272             (*pretvar)->lVal = (LONG)handle->attack_drop;
5273             break;
5274 
5275         case ATTACK_PROP_REACTION_FALL_VELOCITY_X:
5276 
5277             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5278             (*pretvar)->dblVal = (DOUBLE)handle->dropv.x;
5279             break;
5280 
5281         case ATTACK_PROP_REACTION_FALL_VELOCITY_Y:
5282 
5283             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5284             (*pretvar)->dblVal = (DOUBLE)handle->dropv.y;
5285             break;
5286 
5287         case ATTACK_PROP_REACTION_FALL_VELOCITY_Z:
5288 
5289             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5290             (*pretvar)->dblVal = (DOUBLE)handle->dropv.z;
5291             break;
5292 
5293         case ATTACK_PROP_REACTION_FREEZE_MODE:
5294 
5295             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5296             (*pretvar)->lVal = (LONG)handle->freeze;
5297             break;
5298 
5299         case ATTACK_PROP_REACTION_FREEZE_TIME:
5300 
5301             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5302             (*pretvar)->lVal = (LONG)handle->freezetime;
5303             break;
5304 
5305         case ATTACK_PROP_REACTION_INVINCIBLE_TIME:
5306 
5307             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5308             (*pretvar)->lVal = (LONG)handle->pain_time;
5309             break;
5310 
5311         case ATTACK_PROP_REACTION_PAIN_SKIP:
5312 
5313             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5314             (*pretvar)->lVal = (LONG)handle->no_pain;
5315             break;
5316 
5317         case ATTACK_PROP_REACTION_PAUSE_TIME:
5318 
5319             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5320             (*pretvar)->lVal = (LONG)handle->pause_add;
5321             break;
5322 
5323         case ATTACK_PROP_REACTION_REPOSITION_DIRECTION:
5324 
5325             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5326             (*pretvar)->lVal = (LONG)handle->force_direction;
5327             break;
5328 
5329         case ATTACK_PROP_REACTION_REPOSITION_DISTANCE:
5330 
5331             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5332             (*pretvar)->lVal = (LONG)handle->grab_distance;
5333             break;
5334 
5335         case ATTACK_PROP_REACTION_REPOSITION_MODE:
5336 
5337             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5338             (*pretvar)->lVal = (LONG)handle->grab;
5339             break;
5340 
5341         case ATTACK_PROP_SEAL_COST:
5342 
5343             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5344             (*pretvar)->lVal = (LONG)handle->seal;
5345             break;
5346 
5347         case ATTACK_PROP_SEAL_TIME:
5348 
5349             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5350             (*pretvar)->lVal = (LONG)handle->sealtime;
5351             break;
5352 
5353         case ATTACK_PROP_SIZE_X:
5354 
5355             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5356             //(*pretvar)->lVal = (LONG)handle->coords.width;
5357             break;
5358 
5359         case ATTACK_PROP_SIZE_Y:
5360 
5361             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5362             //(*pretvar)->lVal = (LONG)handle->coords.height;
5363             break;
5364 
5365         case ATTACK_PROP_SIZE_Z_1:
5366 
5367             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5368             //(*pretvar)->lVal = (LONG)handle->coords.z1;
5369             break;
5370 
5371         case ATTACK_PROP_SIZE_Z_2:
5372 
5373             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5374             //(*pretvar)->lVal = (LONG)handle->coords.z2;
5375             break;
5376 
5377         case ATTACK_PROP_STAYDOWN_RISE:
5378 
5379             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5380             (*pretvar)->lVal = (LONG)handle->staydown.rise;
5381             break;
5382 
5383         case ATTACK_PROP_STAYDOWN_RISEATTACK:
5384 
5385             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5386             (*pretvar)->lVal = (LONG)handle->staydown.riseattack;
5387             break;
5388 
5389         case ATTACK_PROP_TAG:
5390 
5391             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5392             (*pretvar)->lVal = (LONG)handle->tag;
5393             break;
5394 
5395         default:
5396 
5397             printf("Unsupported property.\n");
5398             goto error_local;
5399             break;
5400     }
5401 
5402     return result;
5403 
5404     // Error trapping.
5405     error_local:
5406 
5407     printf("You must provide a valid handle and property: " SELF_NAME "\n");
5408 
5409     result = E_FAIL;
5410     return result;
5411 
5412     #undef SELF_NAME
5413     #undef ARG_MINIMUM
5414     #undef ARG_HANDLE
5415     #undef ARG_PROPERTY
5416 }
5417 
5418 // set_attack_property(void handle, int property, value)
openbor_set_attack_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5419 HRESULT openbor_set_attack_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
5420 {
5421     #define SELF_NAME           "set_attack_property(void handle, int property, value)"
5422     #define ARG_MINIMUM         3   // Minimum required arguments.
5423     #define ARG_HANDLE          0   // Handle (pointer to property structure).
5424     #define ARG_PROPERTY        1   // Property to access.
5425     #define ARG_VALUE           2   // New value to apply.
5426 
5427     int                     result      = S_OK; // Success or error?
5428     s_collision_attack                *handle     = NULL; // Property handle.
5429     e_attack_properties     property    = 0;    // Property to access.
5430 
5431     // Value carriers to apply on properties after
5432     // taken from argument.
5433     int     temp_int;
5434     DOUBLE  temp_dbl;
5435 
5436     // Verify incoming arguments. There must be a
5437     // pointer for the animation handle, an integer
5438     // property, and a new value to apply.
5439     if(paramCount < ARG_MINIMUM
5440        || varlist[ARG_HANDLE]->vt != VT_PTR
5441        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
5442     {
5443         *pretvar = NULL;
5444         goto error_local;
5445     }
5446     else
5447     {
5448         handle      = (s_collision_attack *)varlist[ARG_HANDLE]->ptrVal;
5449         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
5450     }
5451 
5452     // Which property to modify?
5453     switch(property)
5454     {
5455         case ATTACK_PROP_BLOCK_COST:
5456 
5457             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5458             {
5459                 handle->guardcost = temp_int;
5460             }
5461             break;
5462 
5463         case ATTACK_PROP_BLOCK_PENETRATE:
5464 
5465             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5466             {
5467                 handle->no_block = temp_int;
5468             }
5469             break;
5470 
5471         case ATTACK_PROP_COUNTER:
5472 
5473             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5474             {
5475                 handle->counterattack = temp_int;
5476             }
5477             break;
5478 
5479         case ATTACK_PROP_DAMAGE_FORCE:
5480 
5481             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5482             {
5483                 handle->attack_force = temp_int;
5484             }
5485             break;
5486 
5487         case ATTACK_PROP_DAMAGE_LAND_FORCE:
5488 
5489             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5490             {
5491                 handle->damage_on_landing = temp_int;
5492             }
5493             break;
5494 
5495         case ATTACK_PROP_DAMAGE_LAND_MODE:
5496 
5497             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5498             {
5499                 handle->blast = temp_int;
5500             }
5501             break;
5502 
5503         case ATTACK_PROP_DAMAGE_LETHAL_DISABLE:
5504 
5505             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5506             {
5507                 handle->no_kill = temp_int;
5508             }
5509             break;
5510 
5511         case ATTACK_PROP_DAMAGE_STEAL:
5512 
5513             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5514             {
5515                 handle->steal = temp_int;
5516             }
5517             break;
5518 
5519         case ATTACK_PROP_DAMAGE_TYPE:
5520 
5521             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5522             {
5523                 handle->attack_type = temp_int;
5524             }
5525             break;
5526 
5527 //        case ATTACK_PROP_DAMAGE_RECURSIVE_FORCE:
5528 //
5529 //            if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5530 //            {
5531 //                handle->dot_force = temp_int;
5532 //            }
5533 //            break;
5534 //
5535 //        case ATTACK_PROP_DAMAGE_RECURSIVE_INDEX:
5536 //
5537 //            if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5538 //            {
5539 //                handle->dot_index = temp_int;
5540 //            }
5541 //            break;
5542 //
5543 //        case ATTACK_PROP_DAMAGE_RECURSIVE_MODE:
5544 //
5545 //            if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5546 //            {
5547 //                handle->dot = temp_int;
5548 //            }
5549 //            break;
5550 //
5551 //        case ATTACK_PROP_DAMAGE_RECURSIVE_TIME_EXPIRE:
5552 //
5553 //            if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5554 //            {
5555 //                handle->dot_time = temp_int;
5556 //            }
5557 //            break;
5558 //
5559 //        case ATTACK_PROP_DAMAGE_RECURSIVE_TIME_RATE:
5560 //
5561 //            if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5562 //            {
5563 //                handle->dot_rate = temp_int;
5564 //            }
5565 //            break;
5566 
5567         case ATTACK_PROP_EFFECT_BLOCK_FLASH:
5568 
5569             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5570             {
5571                 handle->blockflash = temp_int;
5572             }
5573             break;
5574 
5575         case ATTACK_PROP_EFFECT_BLOCK_SOUND:
5576 
5577             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5578             {
5579                 handle->blocksound = temp_int;
5580             }
5581             break;
5582 
5583         case ATTACK_PROP_EFFECT_HIT_FLASH:
5584 
5585             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5586             {
5587                 handle->hitflash = temp_int;
5588             }
5589             break;
5590 
5591         case ATTACK_PROP_EFFECT_HIT_FLASH_DISABLE:
5592 
5593             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5594             {
5595                 handle->no_flash = temp_int;
5596             }
5597             break;
5598 
5599         case ATTACK_PROP_EFFECT_HIT_SOUND:
5600 
5601             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5602             {
5603                 handle->hitsound = temp_int;
5604             }
5605             break;
5606 
5607         case ATTACK_PROP_GROUND:
5608 
5609             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5610             {
5611                 handle->otg = temp_int;
5612             }
5613             break;
5614 
5615         case ATTACK_PROP_MAP_INDEX:
5616 
5617             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5618             {
5619                 handle->forcemap = temp_int;
5620             }
5621             break;
5622 
5623         case ATTACK_PROP_MAP_TIME:
5624 
5625             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5626             {
5627                 handle->maptime = temp_int;
5628             }
5629             break;
5630 
5631         case ATTACK_PROP_POSITION_X:
5632 
5633             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5634             {
5635                 //handle->coords.x = temp_int;
5636             }
5637             break;
5638 
5639         case ATTACK_PROP_POSITION_Y:
5640 
5641             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5642             {
5643                 //handle->coords.y = temp_int;
5644             }
5645             break;
5646 
5647         case ATTACK_PROP_REACTION_FALL_FORCE:
5648 
5649             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5650             {
5651                 handle->attack_drop = temp_int;
5652             }
5653 
5654             break;
5655 
5656         case ATTACK_PROP_REACTION_FALL_VELOCITY_X:
5657 
5658             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[ARG_VALUE], &temp_dbl)))
5659             {
5660                 handle->dropv.x = temp_dbl;
5661             }
5662             break;
5663 
5664         case ATTACK_PROP_REACTION_FALL_VELOCITY_Y:
5665 
5666             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[ARG_VALUE], &temp_dbl)))
5667             {
5668                 handle->dropv.y = temp_dbl;
5669             }
5670             break;
5671 
5672         case ATTACK_PROP_REACTION_FALL_VELOCITY_Z:
5673 
5674             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[ARG_VALUE], &temp_dbl)))
5675             {
5676                 handle->dropv.y = temp_dbl;
5677             }
5678             break;
5679 
5680         case ATTACK_PROP_REACTION_FREEZE_MODE:
5681 
5682             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5683             {
5684                 handle->freeze = temp_int;
5685             }
5686             break;
5687 
5688         case ATTACK_PROP_REACTION_FREEZE_TIME:
5689 
5690             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5691             {
5692                 handle->freezetime = temp_int;
5693             }
5694             break;
5695 
5696         case ATTACK_PROP_REACTION_INVINCIBLE_TIME:
5697 
5698             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5699             {
5700                 handle->pain_time = temp_int;
5701             }
5702             break;
5703 
5704         case ATTACK_PROP_REACTION_PAIN_SKIP:
5705 
5706             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5707             {
5708                 handle->no_pain = temp_int;
5709             }
5710             break;
5711 
5712         case ATTACK_PROP_REACTION_PAUSE_TIME:
5713 
5714             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5715             {
5716                 handle->pause_add = temp_int;
5717             }
5718             break;
5719 
5720         case ATTACK_PROP_REACTION_REPOSITION_DIRECTION:
5721 
5722             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5723             {
5724                 handle->force_direction = temp_int;
5725             }
5726             break;
5727 
5728         case ATTACK_PROP_REACTION_REPOSITION_DISTANCE:
5729 
5730             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5731             {
5732                 handle->grab_distance = temp_int;
5733             }
5734             break;
5735 
5736         case ATTACK_PROP_REACTION_REPOSITION_MODE:
5737 
5738             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5739             {
5740                 handle->grab = temp_int;
5741             }
5742             break;
5743 
5744         case ATTACK_PROP_SEAL_COST:
5745 
5746             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5747             {
5748                 handle->seal = temp_int;
5749             }
5750             break;
5751 
5752         case ATTACK_PROP_SEAL_TIME:
5753 
5754             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5755             {
5756                 handle->sealtime = temp_int;
5757             }
5758             break;
5759 
5760         case ATTACK_PROP_SIZE_X:
5761 
5762             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5763             {
5764                 //handle->coords.width = temp_int;
5765             }
5766             break;
5767 
5768         case ATTACK_PROP_SIZE_Y:
5769 
5770             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5771             {
5772                 //handle->coords.height = temp_int;
5773             }
5774             break;
5775 
5776         case ATTACK_PROP_SIZE_Z_1:
5777 
5778             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5779             {
5780                 //handle->coords.z1 = temp_int;
5781             }
5782             break;
5783 
5784         case ATTACK_PROP_SIZE_Z_2:
5785 
5786             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5787             {
5788                 //handle->coords.z2 = temp_int;
5789             }
5790             break;
5791 
5792         case ATTACK_PROP_STAYDOWN_RISE:
5793 
5794             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5795             {
5796                 handle->staydown.rise = temp_int;
5797             }
5798             break;
5799 
5800         case ATTACK_PROP_STAYDOWN_RISEATTACK:
5801 
5802             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5803             {
5804                 handle->staydown.riseattack = temp_int;
5805             }
5806             break;
5807 
5808         case ATTACK_PROP_TAG:
5809 
5810             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
5811             {
5812                 handle->tag = temp_int;
5813             }
5814             break;
5815 
5816         default:
5817 
5818             printf("Unsupported property.\n");
5819             goto error_local;
5820             break;
5821     }
5822 
5823     return result;
5824 
5825     // Error trapping.
5826     error_local:
5827 
5828     printf("You must provide a valid handle, property, and new value: " SELF_NAME "\n");
5829 
5830     result = E_FAIL;
5831     return result;
5832 
5833     #undef SELF_NAME
5834     #undef ARG_MINIMUM
5835     #undef ARG_HANDLE
5836     #undef ARG_PROPERTY
5837     #undef ARG_VALUE
5838 }
5839 
5840 // Body collision properties.
5841 // Caskey, Damon V.
5842 // 2016-10-31
5843 //
5844 // All body collision functions are identical to
5845 // their attack property counterparts. See the attack
5846 // versions of each for details.
5847 
5848 // get_body_collision_collection(void handle, int frame)
openbor_get_body_collision_collection(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5849 HRESULT openbor_get_body_collision_collection(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
5850 {
5851     #define SELF_NAME       "get_body_collision_collection(void handle, int frame)"
5852     #define ARG_MINIMUM     2   // Minimum required arguments.
5853     #define ARG_HANDLE      0   // Handle (pointer to property structure).
5854     #define ARG_FRAME       1   // Frame to access.
5855 
5856 
5857     int         result      = S_OK; // Success or error?
5858     s_collision_body      **handle    = NULL; // Property handle.
5859     int         frame       = 0;    // Property argument.
5860 
5861     // Clear pass by reference argument used to send
5862     // property data back to calling script.     .
5863     ScriptVariant_Clear(*pretvar);
5864 
5865     // Verify incoming arguments. There should at least
5866     // be a pointer for the property handle and an integer
5867     // to determine which frame is accessed.
5868     if(paramCount < ARG_MINIMUM
5869        || varlist[ARG_HANDLE]->vt != VT_PTR
5870        || varlist[ARG_FRAME]->vt != VT_INTEGER)
5871     {
5872         *pretvar = NULL;
5873         goto error_local;
5874     }
5875     else
5876     {
5877         handle  = (s_collision_body **)varlist[ARG_HANDLE]->ptrVal;
5878         frame   = (LONG)varlist[ARG_FRAME]->lVal;
5879     }
5880 
5881     // If this frame has property, send value back to user.
5882     if(handle[frame])
5883     {
5884         ScriptVariant_ChangeType(*pretvar, VT_PTR);
5885         (*pretvar)->ptrVal = handle[frame];
5886     }
5887 
5888     return result;
5889 
5890     // Error trapping.
5891     error_local:
5892 
5893     printf("You must provide a valid handle and frame: " SELF_NAME "\n");
5894 
5895     result = E_FAIL;
5896     return result;
5897 
5898     #undef SELF_NAME
5899     #undef ARG_MINIMUM
5900     #undef ARG_HANDLE
5901     #undef ARG_FRAME
5902 }
5903 
5904 // get_body_collision_instance(void handle, int index)
openbor_get_body_collision_instance(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5905 HRESULT openbor_get_body_collision_instance(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
5906 {
5907     #define SELF_NAME       "get_body_collision_instance(void handle, int index)"
5908     #define ARG_MINIMUM     2   // Minimum required arguments.
5909     #define ARG_HANDLE      0   // Handle (pointer to property structure).
5910     #define ARG_INDEX       1   // Index to access.
5911 
5912     int         result     = S_OK; // Success or error?
5913     s_collision_body      *handle    = NULL; // Property handle.
5914     //int         index      = 0;    // Property argument.
5915 
5916     // Clear pass by reference argument used to send
5917     // property data back to calling script.     .
5918     ScriptVariant_Clear(*pretvar);
5919 
5920     // Verify incoming arguments. There should at least
5921     // be a pointer for the property handle and an integer
5922     // to determine which index is accessed.
5923     if(paramCount < ARG_MINIMUM
5924        || varlist[ARG_HANDLE]->vt != VT_PTR
5925        || varlist[ARG_INDEX]->vt != VT_INTEGER)
5926     {
5927         *pretvar = NULL;
5928         goto error_local;
5929     }
5930     else
5931     {
5932         handle  = (s_collision_body *)varlist[ARG_HANDLE]->ptrVal;
5933         //index   = (LONG)varlist[ARG_INDEX]->lVal;
5934     }
5935 
5936     // If this index has property, send value back to user.
5937     //if(handle[index])
5938     //{
5939         ScriptVariant_ChangeType(*pretvar, VT_PTR);
5940         //(*pretvar)->ptrVal = handle[index];
5941 
5942         (*pretvar)->ptrVal = handle;
5943     //}
5944 
5945     return result;
5946 
5947     // Error trapping.
5948     error_local:
5949 
5950     printf("You must provide a valid handle and index: " SELF_NAME "\n");
5951 
5952     result = E_FAIL;
5953     return result;
5954 
5955     #undef SELF_NAME
5956     #undef ARG_MINIMUM
5957     #undef ARG_HANDLE
5958     #undef ARG_INDEX
5959 }
5960 
5961 // get_body_collision_property(void handle, int property)
openbor_get_body_collision_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5962 HRESULT openbor_get_body_collision_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
5963 {
5964     #define SELF_NAME       "get_body_collision_property(void handle, int property)"
5965     #define ARG_MINIMUM     2   // Minimum required arguments.
5966     #define ARG_HANDLE      0   // Handle (pointer to property structure).
5967     #define ARG_PROPERTY    1   // Property to access.
5968 
5969     int                         result      = S_OK; // Success or error?
5970     s_collision_body                      *handle     = NULL; // Property handle.
5971     e_body_collision_properties property    = 0;    // Property argument.
5972 
5973     // Clear pass by reference argument used to send
5974     // property data back to calling script.     .
5975     ScriptVariant_Clear(*pretvar);
5976 
5977     // Verify incoming arguments. There should at least
5978     // be a pointer for the property handle and an integer
5979     // to determine which property is accessed.
5980     if(paramCount < ARG_MINIMUM
5981        || varlist[ARG_HANDLE]->vt != VT_PTR
5982        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
5983     {
5984         *pretvar = NULL;
5985         goto error_local;
5986     }
5987     else
5988     {
5989         handle      = (s_collision_body *)varlist[ARG_HANDLE]->ptrVal;
5990         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
5991     }
5992 
5993     // Which property to get?
5994     switch(property)
5995     {
5996         case BODY_COLLISION_PROP_DEFENSE:
5997 
5998             /*
5999             // Verify animation has any defense.
6000             if(handle->defense)
6001             {
6002                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
6003                 (*pretvar)->ptrVal = (VOID *)handle->defense;
6004             }
6005             */
6006 
6007             break;
6008 
6009         case BODY_COLLISION_PROP_POSITION_X:
6010 
6011             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6012             //(*pretvar)->lVal = (LONG)handle->coords.x;
6013             break;
6014 
6015         case BODY_COLLISION_PROP_POSISTION_Y:
6016 
6017             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6018             //(*pretvar)->lVal = (LONG)handle->coords.y;
6019             break;
6020 
6021         case BODY_COLLISION_PROP_SIZE_X:
6022 
6023             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6024             //(*pretvar)->lVal = (LONG)handle->coords.width;
6025             break;
6026 
6027         case BODY_COLLISION_PROP_SIZE_Y:
6028 
6029             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6030             //(*pretvar)->lVal = (LONG)handle->coords.height;
6031             break;
6032 
6033         case BODY_COLLISION_PROP_SIZE_Z_1:
6034 
6035             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6036             //(*pretvar)->lVal = (LONG)handle->coords.z1;
6037             break;
6038 
6039         case BODY_COLLISION_PROP_SIZE_Z_2:
6040 
6041             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6042             //(*pretvar)->lVal = (LONG)handle->coords.z2;
6043             break;
6044 
6045         case BODY_COLLISION_PROP_TAG:
6046 
6047             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6048             (*pretvar)->lVal = (LONG)handle->tag;
6049             break;
6050 
6051         default:
6052 
6053             printf("Unsupported property.\n");
6054             goto error_local;
6055             break;
6056     }
6057 
6058     return result;
6059 
6060     // Error trapping.
6061     error_local:
6062 
6063     printf("You must provide a valid handle and property: " SELF_NAME "\n");
6064 
6065     result = E_FAIL;
6066     return result;
6067 
6068     #undef SELF_NAME
6069     #undef ARG_MINIMUM
6070     #undef ARG_HANDLE
6071     #undef ARG_PROPERTY
6072 }
6073 
6074 // set_body_collision_property(void handle, int property, value)
openbor_set_body_collision_property(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)6075 HRESULT openbor_set_body_collision_property(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
6076 {
6077     #define SELF_NAME           "set_body_collision_property(void handle, int property, value)"
6078     #define ARG_MINIMUM         3   // Minimum required arguments.
6079     #define ARG_HANDLE          0   // Handle (pointer to property structure).
6080     #define ARG_PROPERTY        1   // Property to access.
6081     #define ARG_VALUE           2   // New value to apply.
6082 
6083     int                         result      = S_OK; // Success or error?
6084     s_collision_body                      *handle     = NULL; // Property handle.
6085     e_body_collision_properties property    = 0;    // Property to access.
6086 
6087 
6088     // Value carriers to apply on properties after
6089     // taken from argument.
6090     int         temp_int;
6091     //s_defense   *temp_defense;
6092 
6093     // Verify incoming arguments. There must be a
6094     // pointer for the animation handle, an integer
6095     // property, and a new value to apply.
6096     if(paramCount < ARG_MINIMUM
6097        || varlist[ARG_HANDLE]->vt != VT_PTR
6098        || varlist[ARG_PROPERTY]->vt != VT_INTEGER)
6099     {
6100         *pretvar = NULL;
6101         goto error_local;
6102     }
6103     else
6104     {
6105         handle      = (s_collision_body *)varlist[ARG_HANDLE]->ptrVal;
6106         property    = (LONG)varlist[ARG_PROPERTY]->lVal;
6107     }
6108 
6109     // Which property to modify?
6110     switch(property)
6111     {
6112         case BODY_COLLISION_PROP_DEFENSE:
6113 
6114                 //handle->defense = (temp_defense *)varlist[ARG_VALUE]->ptrVal;
6115 
6116             break;
6117 
6118         case BODY_COLLISION_PROP_POSITION_X:
6119 
6120             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
6121             {
6122                 //handle->coords.x = temp_int;
6123             }
6124             break;
6125 
6126         case BODY_COLLISION_PROP_POSISTION_Y:
6127 
6128             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
6129             {
6130                 //handle->coords.y = temp_int;
6131             }
6132             break;
6133 
6134         case BODY_COLLISION_PROP_SIZE_X:
6135 
6136             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
6137             {
6138                 //handle->coords.width = temp_int;
6139             }
6140             break;
6141 
6142         case BODY_COLLISION_PROP_SIZE_Y:
6143 
6144             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
6145             {
6146                 //handle->coords.height = temp_int;
6147             }
6148             break;
6149 
6150         case BODY_COLLISION_PROP_SIZE_Z_1:
6151 
6152             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
6153             {
6154                 //handle->coords.z1 = temp_int;
6155             }
6156             break;
6157 
6158         case BODY_COLLISION_PROP_SIZE_Z_2:
6159 
6160             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
6161             {
6162                 //handle->coords.z2 = temp_int;
6163             }
6164             break;
6165 
6166         case BODY_COLLISION_PROP_TAG:
6167 
6168             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[ARG_VALUE], &temp_int)))
6169             {
6170                 handle->tag = temp_int;
6171             }
6172             break;
6173 
6174         default:
6175 
6176             printf("Unsupported property.\n");
6177             goto error_local;
6178             break;
6179     }
6180 
6181     return result;
6182 
6183     // Error trapping.
6184     error_local:
6185 
6186     printf("You must provide a valid handle, property, and new value: " SELF_NAME "\n");
6187 
6188     result = E_FAIL;
6189     return result;
6190 
6191     #undef SELF_NAME
6192     #undef ARG_MINIMUM
6193     #undef ARG_HANDLE
6194     #undef ARG_PROPERTY
6195     #undef ARG_VALUE
6196 }
6197 
6198 
6199 
6200 //getentityproperty(pentity, propname);
openbor_getentityproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)6201 HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
6202 {
6203     entity *ent			= NULL;
6204     char *tempstr		= NULL;
6205     ScriptVariant *arg	= NULL;
6206     ScriptVariant *arg1	= NULL;
6207     s_sprite *spr;
6208     LONG ltemp, ltemp2;
6209     int i				= 0;
6210     int propind ;
6211     int tempint			= 0;
6212 
6213     if(paramCount < 2)
6214     {
6215         *pretvar = NULL;
6216         return E_FAIL;
6217     }
6218 
6219     ScriptVariant_Clear(*pretvar);
6220     mapstrings_entityproperty(varlist, paramCount);
6221 
6222     arg = varlist[0];
6223     if(arg->vt != VT_PTR && arg->vt != VT_EMPTY)
6224     {
6225         printf("Function getentityproperty must have a valid entity handle.\n");
6226         *pretvar = NULL;
6227         return E_FAIL;
6228     }
6229     ent = (entity *)arg->ptrVal; //retrieve the entity
6230     if(!ent)
6231     {
6232         return S_OK;
6233     }
6234 
6235     arg = varlist[1];
6236     if(arg->vt != VT_INTEGER)
6237     {
6238         printf("Function getentityproperty must have a string property name.\n");
6239     }
6240 
6241     propind = arg->lVal;
6242 
6243     switch(propind)
6244     {
6245     case _ep_a:
6246     case _ep_y:
6247     {
6248         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6249         (*pretvar)->dblVal = (DOUBLE)ent->position.y;
6250         break;
6251     }
6252     case _ep_aggression:
6253     {
6254         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6255         (*pretvar)->lVal = (LONG)ent->modeldata.aggression;
6256         break;
6257     }
6258     case _ep_aiattack:
6259     {
6260         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6261         (*pretvar)->lVal = (LONG)ent->modeldata.aiattack;
6262         break;
6263     }
6264     case _ep_aiflag:
6265     {
6266         if(paramCount < 3)
6267         {
6268             break;
6269         }
6270         arg = varlist[2];
6271         if(arg->vt != VT_INTEGER)
6272         {
6273             printf("You must give a string name for aiflag.\n");
6274             return E_FAIL;
6275         }
6276         ltemp = arg->lVal;
6277 
6278         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6279         switch(ltemp)
6280         {
6281         case _ep_aiflag_dead:
6282             (*pretvar)->lVal = (LONG)ent->dead;
6283             break;
6284         case _ep_aiflag_jumpid:
6285             (*pretvar)->lVal = (LONG)ent->jump.id;
6286             break;
6287         case _ep_aiflag_jumping:
6288             (*pretvar)->lVal = (LONG)ent->jumping;
6289             break;
6290         case _ep_aiflag_idling:
6291             (*pretvar)->lVal = (LONG)ent->idling;
6292             break;
6293         case _ep_aiflag_drop:
6294             (*pretvar)->lVal = (LONG)ent->drop;
6295             break;
6296         case _ep_aiflag_attacking:
6297             (*pretvar)->lVal = (LONG)ent->attacking;
6298             break;
6299         case _ep_aiflag_getting:
6300             (*pretvar)->lVal = (LONG)ent->getting;
6301             break;
6302         case _ep_aiflag_turning:
6303             (*pretvar)->lVal = (LONG)ent->turning;
6304             break;
6305         case _ep_aiflag_charging:
6306             (*pretvar)->lVal = (LONG)ent->charging;
6307             break;
6308         case _ep_aiflag_blocking:
6309             (*pretvar)->lVal = (LONG)ent->blocking;
6310             break;
6311         case _ep_aiflag_falling:
6312             (*pretvar)->lVal = (LONG)ent->falling;
6313             break;
6314         case _ep_aiflag_running:
6315             (*pretvar)->lVal = (LONG)ent->running;
6316             break;
6317         case _ep_aiflag_inpain:
6318             (*pretvar)->lVal = (LONG)ent->inpain;
6319             break;
6320         case _ep_aiflag_inbackpain:
6321             (*pretvar)->lVal = (LONG)ent->inbackpain;
6322             break;
6323         case _ep_aiflag_projectile:
6324             (*pretvar)->lVal = (LONG)ent->projectile;
6325             break;
6326         case _ep_aiflag_frozen:
6327             (*pretvar)->lVal = (LONG)ent->frozen;
6328             break;
6329         case _ep_aiflag_toexplode:
6330             (*pretvar)->lVal = (LONG)ent->toexplode;
6331             break;
6332         case _ep_aiflag_animating:
6333             (*pretvar)->lVal = (LONG)ent->animating;
6334             break;
6335         case _ep_aiflag_blink:
6336             (*pretvar)->lVal = (LONG)ent->blink;
6337             break;
6338         case _ep_aiflag_invincible:
6339             (*pretvar)->lVal = (LONG)ent->invincible;
6340             break;
6341         case _ep_aiflag_autokill:
6342             (*pretvar)->lVal = (LONG)ent->autokill;
6343             break;
6344         case _ep_aiflag_idlemode:
6345             (*pretvar)->lVal = (LONG)ent->idlemode;
6346             break;
6347         case _ep_aiflag_walkmode:
6348             (*pretvar)->lVal = (LONG)ent->walkmode;
6349             break;
6350         case _ep_aiflag_walking:
6351             (*pretvar)->lVal = (LONG)ent->walking;
6352             break;
6353         default:
6354             ScriptVariant_Clear(*pretvar);
6355             return E_FAIL;
6356         }
6357         break;
6358     }
6359     case _ep_aimove:
6360     {
6361         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6362         (*pretvar)->lVal = (LONG)ent->modeldata.aimove;
6363         break;
6364     }
6365     case _ep_alpha:
6366     {
6367         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6368         (*pretvar)->lVal = (LONG)ent->modeldata.alpha;
6369         break;
6370     }
6371     case _ep_animal:
6372     {
6373         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6374         (*pretvar)->lVal = (LONG)ent->modeldata.animal;
6375         break;
6376     }
6377     case _ep_animating:
6378     {
6379         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6380         (*pretvar)->lVal = (LONG)ent->animating;
6381         break;
6382     }
6383     case _ep_animation_handle:
6384     {
6385         #define ARG_ANIMATION_ID 2
6386 
6387         // Did the user provide an animation id?
6388         if(paramCount > 2)
6389         {
6390             arg = varlist[ARG_ANIMATION_ID];
6391 
6392             // If the argument is invalid, use current animation ID instead.
6393             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
6394             {
6395                 ltemp = (LONG)ent->animnum;
6396             }
6397         }
6398         else
6399         {
6400             ltemp = (LONG)ent->animnum;
6401         }
6402 
6403         // If the animation exists, get the handle.
6404         if(validanim(ent, ltemp))
6405         {
6406             ScriptVariant_ChangeType(*pretvar, VT_PTR);
6407             (*pretvar)->ptrVal = (VOID *)ent->modeldata.animation[ltemp];
6408         }
6409 
6410         break;
6411 
6412         #undef ARG_ANIMATION_ID
6413     }
6414     /*
6415     case _ep_animationid: See animnum.
6416     */
6417     case _ep_animheight:
6418     {
6419         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6420         (*pretvar)->lVal = (LONG)ent->animation->size.x;
6421         break;
6422     }
6423     case _ep_animhits:
6424     {
6425         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6426         (*pretvar)->lVal = (LONG)ent->animation->animhits;
6427         break;
6428     }
6429     case _ep_animnum:
6430     case _ep_animationid:
6431     {
6432         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6433         (*pretvar)->lVal = (LONG)ent->animnum;
6434         break;
6435     }
6436     case _ep_animpos:
6437     {
6438         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6439         (*pretvar)->lVal = (LONG)ent->animpos;
6440         break;
6441     }
6442     case _ep_animvalid:
6443     {
6444         ltemp = 0;
6445         if(paramCount == 3)
6446         {
6447             arg = varlist[2];
6448             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
6449             {
6450                 ltemp = (LONG)0;
6451             }
6452         }
6453         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6454         (*pretvar)->lVal = (LONG)validanim(ent, ltemp);
6455         break;
6456     }
6457     case _ep_antigrab:
6458     {
6459         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6460         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.antigrab;
6461         break;
6462     }
6463     case _ep_antigravity:
6464     {
6465         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6466         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.antigravity;
6467         break;
6468     }
6469     case _ep_attacking:
6470     {
6471         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6472         (*pretvar)->lVal = (LONG)ent->attacking;
6473         break;
6474     }
6475     case _ep_attackid:
6476     {
6477         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6478         (*pretvar)->lVal = (LONG)ent->attack_id;
6479         break;
6480     }
6481     case _ep_autokill:
6482     {
6483         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6484         (*pretvar)->lVal = (LONG)ent->autokill;
6485         break;
6486     }
6487     case _ep_base:
6488     {
6489         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6490         (*pretvar)->dblVal = (DOUBLE)ent->base;
6491         break;
6492     }
6493     case _ep_vulnerable:
6494     {
6495         if(paramCount == 2)
6496         {
6497             i		= ent->animnum;
6498             tempint	= ent->animpos;
6499         }
6500         else if(paramCount < 4
6501                 || varlist[2]->vt != VT_INTEGER
6502                 || varlist[3]->vt != VT_INTEGER)
6503         {
6504             printf("\n Error, getentityproperty({ent}, \"vulnerable\", {animation}, {frame}): parameters missing or invalid. \n");
6505             *pretvar = NULL;
6506             return E_FAIL;
6507         }
6508         else
6509         {
6510             i		= varlist[2]->lVal;												//Animation parameter.
6511             tempint	= varlist[3]->lVal;												//Frame parameter.
6512         }
6513         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6514         (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->vulnerable[tempint];
6515         break;
6516     }
6517     case _ep_blink:
6518     {
6519         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6520         (*pretvar)->lVal = (LONG)ent->blink;
6521         break;
6522     }
6523     case _ep_blockback:
6524     {
6525         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6526         (*pretvar)->lVal = (LONG)ent->modeldata.blockback;
6527         break;
6528     }
6529     case _ep_blockodds:
6530     {
6531         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6532         (*pretvar)->lVal = (LONG)ent->modeldata.blockodds;
6533         break;
6534     }
6535     case _ep_blockpain:
6536     {
6537         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6538         (*pretvar)->lVal = (LONG)ent->modeldata.blockpain;
6539         break;
6540     }
6541     case _ep_boomerang:
6542     {
6543         if (paramCount < 3)
6544         {
6545             printf("You must specify a flag value for boomerang property (0 = acceleration, 1 = distance_x).\n");
6546             *pretvar = NULL;
6547             return E_FAIL;
6548         }
6549         else
6550         {
6551             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6552             if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6553             {
6554                 printf("You must specify a flag value for boomerang property (0 = acceleration, 1 = distance_x).\n");
6555                 *pretvar = NULL;
6556                 return E_FAIL;
6557             }
6558             else
6559             {
6560                 if (ltemp == 0) (*pretvar)->dblVal = (DOUBLE)ent->modeldata.boomerang_acc;
6561                 else (*pretvar)->dblVal = (DOUBLE)ent->modeldata.boomerang_distx;
6562             }
6563         }
6564         break;
6565     }
6566     case _ep_boss:
6567     {
6568         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6569         (*pretvar)->lVal = (LONG)ent->boss;
6570         break;
6571     }
6572     case _ep_bounce:
6573     {
6574         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6575         (*pretvar)->lVal = (LONG)ent->modeldata.bounce;
6576         break;
6577     }
6578     case _ep_bound:
6579     {
6580         ScriptVariant_ChangeType(*pretvar, VT_PTR);
6581         (*pretvar)->ptrVal = (VOID *)ent->binding.ent;
6582         break;
6583     }
6584     case _ep_candamage:
6585     {
6586         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6587         (*pretvar)->lVal = (LONG)ent->modeldata.candamage;
6588         break;
6589     }
6590     case _ep_combostep:
6591     {
6592         if(paramCount >= 3)
6593         {
6594             if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
6595             {
6596                 *pretvar = NULL;
6597                 return E_FAIL;
6598             }
6599         }
6600         else
6601         {
6602             ltemp2 = 0;
6603         }
6604         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6605         (*pretvar)->lVal = (LONG)ent->combostep[(int)ltemp2];
6606         break;
6607     }
6608     case _ep_combotime:
6609     {
6610         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6611         (*pretvar)->lVal = (LONG)ent->combotime;
6612         break;
6613     }
6614     case _ep_hostile:
6615     {
6616         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6617         (*pretvar)->lVal = (LONG)ent->modeldata.hostile;
6618         break;
6619     }
6620     case _ep_projectilehit:
6621     {
6622         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6623         (*pretvar)->lVal = (LONG)ent->modeldata.projectilehit;
6624         break;
6625     }
6626     case _ep_chargerate:
6627     {
6628         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6629         (*pretvar)->lVal = (LONG)ent->modeldata.chargerate;
6630         break;
6631     }
6632     case _ep_colourmap:
6633     {
6634         ScriptVariant_ChangeType(*pretvar, VT_PTR);
6635         (*pretvar)->ptrVal = (VOID *)(ent->colourmap);
6636         break;
6637     }
6638     case _ep_colourtable:
6639     {
6640         ScriptVariant_ChangeType(*pretvar, VT_PTR);
6641         (*pretvar)->ptrVal = (VOID *)model_get_colourmap(&(ent->modeldata), varlist[2]->lVal + 1);
6642         break;
6643     }
6644     case _ep_damage_on_landing:
6645     {
6646         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6647         (*pretvar)->lVal = (LONG)ent->damage_on_landing;
6648         break;
6649     }
6650     case _ep_dead:
6651     {
6652         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6653         (*pretvar)->lVal = (LONG)ent->dead;
6654         break;
6655     }
6656     case _ep_defaultmodel:
6657     case _ep_defaultname:
6658     {
6659         ScriptVariant_ChangeType(*pretvar, VT_STR);
6660         StrCache_Copy((*pretvar)->strVal, ent->defaultmodel->name);
6661         break;
6662     }
6663     case _ep_defense:
6664     {
6665         ltemp = 0;
6666         if(paramCount >= 3)
6667         {
6668             if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6669             {
6670                 printf("You must specify an attack type for your defense property.\n");
6671                 *pretvar = NULL;
6672                 return E_FAIL;
6673             }
6674             ltemp2 = _ep_defense_factor;
6675         }
6676 
6677         if(paramCount >= 4)
6678         {
6679             if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
6680             {
6681                 *pretvar = NULL;
6682                 return E_FAIL;
6683             }
6684         }
6685         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6686 
6687         switch(ltemp2)
6688         {
6689         case _ep_defense_factor:
6690         {
6691             (*pretvar)->dblVal = (DOUBLE)ent->defense[(int)ltemp].factor;
6692             break;
6693         }
6694         case _ep_defense_blockpower:
6695         {
6696             (*pretvar)->dblVal = (DOUBLE)ent->defense[(int)ltemp].blockpower;
6697             break;
6698         }
6699         case _ep_defense_blockratio:
6700         {
6701             (*pretvar)->dblVal = (DOUBLE)ent->defense[(int)ltemp].blockratio;
6702             break;
6703         }
6704         case _ep_defense_blockthreshold:
6705         {
6706             (*pretvar)->dblVal = (DOUBLE)ent->defense[(int)ltemp].blockthreshold;
6707             break;
6708         }
6709         case _ep_defense_blocktype:
6710         {
6711             (*pretvar)->dblVal = (DOUBLE)ent->defense[(int)ltemp].blocktype;
6712             break;
6713         }
6714         case _ep_defense_knockdown:
6715         {
6716             (*pretvar)->dblVal = (DOUBLE)ent->defense[(int)ltemp].knockdown;
6717             break;
6718         }
6719         case _ep_defense_pain:
6720         {
6721             (*pretvar)->dblVal = (DOUBLE)ent->defense[(int)ltemp].pain;
6722             break;
6723         }
6724         default:
6725             *pretvar = NULL;
6726             return E_FAIL;
6727         }
6728         break;
6729     }
6730     case _ep_destx:
6731     {
6732         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6733         (*pretvar)->dblVal = (DOUBLE)ent->destx;
6734         break;
6735     }
6736     case _ep_destz:
6737     {
6738         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
6739         (*pretvar)->dblVal = (DOUBLE)ent->destz;
6740         break;
6741     }
6742     case _ep_detect:
6743     {
6744         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6745         (*pretvar)->lVal = (LONG)ent->modeldata.stealth.detect;
6746         break;
6747     }
6748     case _ep_direction:
6749     {
6750         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6751         (*pretvar)->lVal = (LONG)ent->direction;
6752         break;
6753     }
6754     case _ep_dot:
6755     {
6756         if(paramCount < 4)
6757         {
6758             break;
6759         }
6760 
6761         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6762         {
6763             i = (int)ltemp;
6764         }
6765 
6766         arg = varlist[3];
6767         if(arg->vt != VT_INTEGER)
6768         {
6769             printf("You must provide a string name for dot subproperty.\n\
6770 	~'time'\n\
6771 	~'mode'\n\
6772 	~'force'\n\
6773 	~'rate'\n\
6774 	~'type'\n\
6775 	~'owner'\n");
6776             *pretvar = NULL;
6777             return E_FAIL;
6778         }
6779         switch(arg->lVal)
6780         {
6781         case _ep_dot_time:
6782         {
6783             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6784             (*pretvar)->lVal = (LONG)ent->dot_time[i];
6785             break;
6786         }
6787         case _ep_dot_mode:
6788         {
6789             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6790             (*pretvar)->lVal = (LONG)ent->dot[i];
6791             break;
6792         }
6793         case _ep_dot_force:
6794 
6795         {
6796             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6797             (*pretvar)->lVal = (LONG)ent->dot_force[i];
6798             break;
6799         }
6800         case _ep_dot_rate:
6801         {
6802             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6803             (*pretvar)->lVal = (LONG)ent->dot_rate[i];
6804             break;
6805         }
6806         case _ep_dot_type:
6807         {
6808             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6809             (*pretvar)->lVal = (LONG)ent->dot_atk[i];
6810             break;
6811         }
6812         case _ep_dot_owner:
6813         {
6814             ScriptVariant_ChangeType(*pretvar, VT_PTR);
6815             (*pretvar)->ptrVal = (VOID *)ent->dot_owner[i];
6816             break;
6817         }
6818         break;
6819         }
6820     }
6821     case _ep_dropframe:
6822     {
6823         ltemp = 0;
6824         if(paramCount == 3)
6825         {
6826             arg = varlist[2];
6827             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
6828             {
6829                 ltemp = 0;
6830             }
6831         }
6832 
6833         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6834 
6835         if(ent->modeldata.animation[ltemp]->dropframe)
6836         {
6837             (*pretvar)->lVal = ent->modeldata.animation[ltemp]->dropframe->frame;
6838         }
6839 
6840         break;
6841     }
6842     case _ep_edelay:
6843     {
6844         arg = varlist[2];
6845         if(arg->vt != VT_INTEGER)
6846         {
6847             printf("You must provide a string name for edelay subproperty.\n\
6848 	~'cap_max'\n\
6849 	~'cap_min'\n\
6850 	~'factor'\n\
6851 	~'mode'\n\
6852 	~'range_max'\n\
6853 	~'range_min'\n");
6854             *pretvar = NULL;
6855             return E_FAIL;
6856         }
6857         ltemp = arg->lVal;
6858         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6859 
6860         switch(ltemp)
6861         {
6862         case _ep_edelay_mode:
6863         {
6864             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.mode;
6865             break;
6866         }
6867         case _ep_edelay_factor:
6868         {
6869             (*pretvar)->dblVal = (float)ent->modeldata.edelay.factor;
6870             break;
6871         }
6872         case _ep_edelay_cap_min:
6873         {
6874             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.cap.min;
6875             break;
6876         }
6877         case _ep_edelay_cap_max:
6878         {
6879             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.cap.max;
6880             break;
6881         }
6882         case _ep_edelay_range_min:
6883         {
6884             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.range.min;
6885             break;
6886         }
6887         case _ep_edelay_range_max:
6888         {
6889             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.range.max;
6890             break;
6891         }
6892         default:
6893             *pretvar = NULL;
6894             return E_FAIL;
6895         }
6896         break;
6897     }
6898     case _ep_energycost:
6899     {
6900         if(paramCount < 4)
6901         {
6902             break;
6903         }
6904 
6905         if(varlist[2]->vt != VT_INTEGER)
6906         {
6907             printf("You must provide a string name for energycost.\n\
6908 	~'cost'\n\
6909 	~'disable'\n\
6910 	~'mponly'\n");
6911             *pretvar = NULL;
6912             return E_FAIL;
6913         }
6914         ltemp	= varlist[2]->lVal;												//Subproperty.
6915         i		= varlist[3]->lVal;												//Animation.
6916 
6917         if(!validanim(ent, i))													//Verify animation.
6918         {
6919             break;
6920         }
6921 
6922         switch(ltemp)
6923         {
6924         case _ep_energycost_cost:
6925             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6926             if(ent->modeldata.animation[i]->energycost)
6927             {
6928                 (*pretvar)->lVal = ent->modeldata.animation[i]->energycost->cost;
6929             }
6930 
6931             break;
6932         case _ep_energycost_disable:
6933             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6934             if(ent->modeldata.animation[i]->energycost)
6935             {
6936                 (*pretvar)->lVal = ent->modeldata.animation[i]->energycost->disable;
6937             }
6938             break;
6939         case _ep_energycost_mponly:
6940             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6941             if(ent->modeldata.animation[i]->energycost)
6942             {
6943                 (*pretvar)->lVal = ent->modeldata.animation[i]->energycost->mponly;
6944             }
6945             break;
6946         default:
6947             *pretvar = NULL;
6948             return E_FAIL;
6949         }
6950         break;
6951     }
6952     case _ep_escapecount:
6953     {
6954         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6955         (*pretvar)->lVal = (LONG)ent->escapecount;
6956         break;
6957     }
6958     case _ep_escapehits:
6959     {
6960         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6961         (*pretvar)->lVal = (LONG)ent->modeldata.escapehits;
6962         break;
6963     }
6964     case _ep_exists:
6965     {
6966         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6967         (*pretvar)->lVal = (LONG)ent->exists;
6968         break;
6969     }
6970     case _ep_facing:
6971     {
6972         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6973         (*pretvar)->lVal = (LONG)ent->modeldata.facing;
6974         break;
6975     }
6976     case _ep_falldie:
6977     {
6978         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6979         (*pretvar)->lVal = (LONG)ent->modeldata.falldie;
6980         break;
6981     }
6982     case _ep_flash:
6983     {
6984         arg = varlist[2];
6985         if(arg->vt != VT_INTEGER)
6986         {
6987             printf("You must give a string name for flash property.\n");
6988             *pretvar = NULL;
6989             return E_FAIL;
6990         }
6991         ltemp = arg->lVal;
6992         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
6993 
6994         switch(ltemp)
6995         {
6996         case _ep_flash_block:
6997         {
6998             i = ent->modeldata.bflash;
6999             break;
7000         }
7001         case _ep_flash_def:
7002         {
7003             i = ent->modeldata.flash;
7004             break;
7005         }
7006         case _ep_flash_noattack:
7007         {
7008             i = ent->modeldata.noatflash;
7009             break;
7010         }
7011         default:
7012         {
7013             *pretvar = NULL;
7014             return E_FAIL;
7015         }
7016         }
7017         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7018         (*pretvar)->lVal = (LONG)i;
7019         break;
7020     }
7021     case _ep_pain_time:
7022     {
7023         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7024         (*pretvar)->lVal = (LONG)ent->pain_time;
7025         break;
7026     }
7027     case _ep_freezetime:
7028     {
7029         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7030         (*pretvar)->lVal = (LONG)ent->freezetime;
7031         break;
7032     }
7033     case _ep_frozen:
7034     {
7035         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7036         (*pretvar)->lVal = (LONG)ent->frozen;
7037         break;
7038     }
7039     case _ep_gfxshadow:
7040     {
7041         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7042         (*pretvar)->lVal = (LONG)ent->modeldata.gfxshadow;
7043         break;
7044     }
7045     case _ep_shadowbase:
7046     {
7047         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7048         (*pretvar)->lVal = (LONG)ent->modeldata.shadowbase;
7049         break;
7050     }
7051     case _ep_grabbing:
7052     {
7053         if(ent->grabbing) // always return an empty var if it is NULL
7054         {
7055             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7056             (*pretvar)->ptrVal = (VOID *)ent->grabbing;
7057         }
7058         break;
7059     }
7060     case _ep_grabforce:
7061     {
7062         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7063         (*pretvar)->lVal = (LONG)ent->modeldata.grabforce;
7064         break;
7065     }
7066     case _ep_guardpoints:
7067     {
7068         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7069         (*pretvar)->lVal = (LONG)ent->modeldata.guardpoints.current;
7070         break;
7071     }
7072     case _ep_hasplatforms:
7073     {
7074         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7075         (*pretvar)->lVal = (LONG)ent->modeldata.hasPlatforms;
7076         break;
7077     }
7078     case _ep_health:
7079     {
7080         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7081         (*pretvar)->lVal = (LONG)ent->health;
7082         break;
7083     }
7084     case _ep_height:
7085     {
7086         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7087         (*pretvar)->lVal = (LONG)ent->modeldata.size.y;
7088         break;
7089     }
7090     case _ep_hitbyid:
7091     {
7092         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7093         (*pretvar)->lVal = (LONG)ent->hit_by_attack_id;
7094         break;
7095     }
7096     case _ep_hitheadplatform:
7097     {
7098         ScriptVariant_ChangeType(*pretvar, VT_PTR);
7099         (*pretvar)->ptrVal = (VOID *)ent->hithead;
7100         break;
7101     }
7102     case _ep_landedplatform:
7103     {
7104         ScriptVariant_ChangeType(*pretvar, VT_PTR);
7105         (*pretvar)->ptrVal = (VOID *)ent->landed_on_platform;
7106         break;
7107     }
7108     case _ep_hitwall:
7109     {
7110         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7111         (*pretvar)->lVal = (LONG)ent->hitwall;
7112         break;
7113     }
7114     case _ep_hmapl:
7115     {
7116         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7117         (*pretvar)->lVal = (LONG)ent->modeldata.maps.hide_start;
7118         break;
7119     }
7120     case _ep_hmapu:
7121     {
7122         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7123         (*pretvar)->lVal = (LONG)ent->modeldata.maps.hide_end;
7124         break;
7125     }
7126     case _ep_icon:
7127     {
7128         arg = varlist[2];
7129         if(arg->vt != VT_INTEGER)
7130         {
7131             printf("You must provide a string name for icon subproperty:\n\
7132 	getentityproperty({ent}, 'icon', {subproperty});\n\
7133 	~'default'\n\
7134 	~'die'\n\
7135 	~'get'\n\
7136 	~'mphigh'\n\
7137 	~'mplow'\n\
7138 	~'mpmed'\n\
7139 	~'pain'\n\
7140 	~'weapon'\n\
7141 	~'x'\n\
7142 	~'y'\n");
7143             *pretvar = NULL;
7144             return E_FAIL;
7145         }
7146         ltemp = arg->lVal;
7147         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7148 
7149         switch(ltemp)
7150         {
7151         case _ep_icon_def:
7152         {
7153             i = ent->modeldata.icon.def;
7154             break;
7155         }
7156         case _ep_icon_die:
7157         {
7158             i = ent->modeldata.icon.die;
7159             break;
7160         }
7161         case _ep_icon_get:
7162         {
7163             i = ent->modeldata.icon.get;
7164             break;
7165         }
7166         case _ep_icon_mphigh:
7167         {
7168             i = ent->modeldata.icon.mphigh;
7169             break;
7170         }
7171         case _ep_icon_mplow:
7172         {
7173             i = ent->modeldata.icon.mplow;
7174             break;
7175         }
7176         case _ep_icon_mpmed:
7177         {
7178             i = ent->modeldata.icon.mpmed;
7179             break;
7180         }
7181         case _ep_icon_pain:
7182         {
7183             i = ent->modeldata.icon.pain;
7184             break;
7185         }
7186         case _ep_icon_weapon:
7187         {
7188             i = ent->modeldata.icon.weapon;
7189             break;
7190         }
7191         case _ep_icon_x:
7192         {
7193             i = ent->modeldata.icon.position.x;
7194             break;
7195         }
7196         case _ep_icon_y:
7197         {
7198             i = ent->modeldata.icon.position.y;
7199             break;
7200         }
7201         default:
7202         {
7203             *pretvar = NULL;
7204             return E_FAIL;
7205         }
7206         }
7207 
7208         if (i >= 0)
7209         {
7210             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7211             spr = sprite_map[i].node->sprite;
7212             spr->centerx = sprite_map[i].centerx;
7213             spr->centery = sprite_map[i].centery;
7214             (*pretvar)->ptrVal = (VOID *)(spr);
7215         }
7216         else
7217         {
7218             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7219             (*pretvar)->lVal = -1;
7220         }
7221         break;
7222     }
7223     case _ep_invincible:
7224     {
7225         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7226         (*pretvar)->lVal = (LONG)ent->invincible;
7227         break;
7228     }
7229     case _ep_invinctime:
7230     {
7231         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7232         (*pretvar)->lVal = (LONG)ent->invinctime;
7233         break;
7234     }
7235     case _ep_jugglepoints:
7236     {
7237         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7238         (*pretvar)->lVal = (LONG)ent->modeldata.jugglepoints.current;
7239         break;
7240     }
7241     case _ep_jumpheight:
7242     {
7243         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7244         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.jumpheight;
7245         break;
7246     }
7247     case _ep_jumpmovex:
7248     {
7249         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7250         (*pretvar)->lVal = (LONG)ent->modeldata.jumpmovex;
7251         break;
7252     }
7253     case _ep_jumpmovez:
7254     {
7255         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7256         (*pretvar)->lVal = (LONG)ent->modeldata.jumpmovez;
7257         break;
7258     }
7259     case _ep_jumpspeed:
7260     {
7261         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7262         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.jumpspeed;
7263         break;
7264     }
7265     case _ep_knockdowncount:
7266     {
7267         /*
7268         2011_04_14, DC: Backward compatability; default to current if subproperty not provided.
7269         */
7270         if(paramCount < 3)
7271         {
7272             ltemp = _ep_knockdowncount_current;
7273         }
7274         else
7275         {
7276             arg = varlist[2];
7277 
7278             if(arg->vt != VT_INTEGER)
7279             {
7280                 printf("You must provide a string name for knockdowncount subproperty:\n\
7281 		getentityproperty({ent}, 'knockdowncount', {subproperty})\n\
7282 		~'current'\n\
7283 		~'max'\n\
7284 		~'time'\n");
7285                 *pretvar = NULL;
7286                 return E_FAIL;
7287             }
7288 
7289             ltemp = arg->lVal;
7290         }
7291 
7292         switch(ltemp)
7293         {
7294         case _ep_knockdowncount_current:
7295             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7296             (*pretvar)->dblVal = (DOUBLE)ent->knockdowncount;
7297             break;
7298         case _ep_knockdowncount_max:
7299             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7300             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.knockdowncount;
7301             break;
7302         case _ep_knockdowncount_time:
7303             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7304             (*pretvar)->lVal = (LONG)ent->knockdowncount;
7305             break;
7306         default:
7307             *pretvar = NULL;
7308             return E_FAIL;
7309         }
7310         break;
7311     }
7312     case _ep_komap:
7313     {
7314         if(paramCount < 2)
7315         {
7316             break;
7317         }
7318 
7319         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7320         (*pretvar)->lVal = (LONG)ent->modeldata.maps.ko;
7321         break;
7322     }
7323     case _ep_landframe:
7324     {
7325         if(paramCount < 4)
7326         {
7327             break;
7328         }
7329 
7330         if(varlist[2]->vt != VT_INTEGER
7331                 || varlist[3]->vt != VT_INTEGER)
7332         {
7333             printf("\n Error, getentityproperty({ent}, 'landframe', {sub property}, {animation}): {Sub property} or {Animation} parameter is missing or invalid. \n");
7334             *pretvar = NULL;
7335             return E_FAIL;
7336         }
7337         ltemp	= varlist[2]->lVal;												//Subproperty.
7338         i		= varlist[3]->lVal;												//Animation.
7339 
7340         if(!validanim(ent, i))													//Verify animation.
7341         {
7342             break;
7343         }
7344 
7345         switch(ltemp)
7346         {
7347         case _ep_landframe_ent:
7348             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7349             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->landframe.ent;
7350             break;
7351         case _ep_landframe_frame:
7352             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7353             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->landframe.frame;
7354             break;
7355         default:
7356             *pretvar = NULL;
7357             return E_FAIL;
7358         }
7359         break;
7360     }
7361     case _ep_lifespancountdown:
7362     {
7363         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7364         (*pretvar)->lVal = (LONG)ent->lifespancountdown;
7365         break;
7366     }
7367     case _ep_attackthrottle:
7368     {
7369         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7370         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.attackthrottle;
7371         break;
7372     }
7373     case _ep_attackthrottletime:
7374     {
7375         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7376         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.attackthrottletime;
7377         break;
7378     }
7379     case _ep_link:
7380     {
7381         if(ent->link) // always return an empty var if it is NULL
7382         {
7383             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7384             (*pretvar)->ptrVal = (VOID *)ent->link;
7385         }
7386         break;
7387     }
7388     case _ep_map:
7389     {
7390         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7391         (*pretvar)->lVal = (LONG)0;
7392         for(i = 0; i < ent->modeldata.maps_loaded; i++)
7393         {
7394             if(ent->colourmap == ent->modeldata.colourmap[i])
7395             {
7396                 (*pretvar)->lVal = (LONG)(i + 1);
7397                 break;
7398             }
7399         }
7400         break;
7401     }
7402     case _ep_mapcount:
7403     {
7404         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7405         (*pretvar)->lVal = (LONG)(ent->modeldata.maps_loaded + 1);
7406         break;
7407     }
7408     case _ep_mapdefault:
7409     {
7410         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7411         (*pretvar)->lVal = (LONG)(ent->map);
7412         break;
7413     }
7414     case _ep_maps:
7415     {
7416         arg = varlist[2];
7417         if(arg->vt != VT_INTEGER)
7418         {
7419             printf("You must give a string name for maps property.\n");
7420             *pretvar = NULL;
7421             return E_FAIL;
7422         }
7423         ltemp = arg->lVal;
7424         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7425 
7426         switch(ltemp)
7427         {
7428         case _ep_maps_count:
7429         {
7430             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7431             (*pretvar)->lVal = (LONG)(ent->modeldata.maps_loaded + 1);
7432             break;
7433         }
7434 
7435         case _ep_maps_current:
7436         {
7437             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7438             (*pretvar)->lVal = (LONG)0;
7439             for(i = 0; i < ent->modeldata.maps_loaded; i++)
7440             {
7441                 if(ent->colourmap == ent->modeldata.colourmap[i])
7442                 {
7443                     (*pretvar)->lVal = (LONG)(i + 1);
7444                     break;
7445                 }
7446             }
7447             break;
7448         }
7449         case _ep_maps_dying:
7450         {
7451             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7452             if(paramCount >= 3)
7453             {
7454                 if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7455                 {
7456                     printf("You must specify the integer value for remap.\n");
7457                     *pretvar = NULL;
7458                     return E_FAIL;
7459                 }
7460                 else
7461                 {
7462                     if (ltemp == 0) (*pretvar)->lVal = (LONG)(ent->dying);
7463                     else (*pretvar)->lVal = (LONG)(ent->dying2);
7464                 }
7465             }
7466             else
7467             {
7468                 (*pretvar)->lVal = (LONG)(ent->dying);
7469             }
7470             break;
7471         }
7472         case _ep_maps_dying_critical:
7473         {
7474             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7475             (*pretvar)->lVal = (LONG)(ent->per2);
7476             break;
7477         }
7478         case _ep_maps_dying_low:
7479         {
7480             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7481             (*pretvar)->lVal = (LONG)(ent->per1);
7482             break;
7483         }
7484         case _ep_maps_frozen:
7485         {
7486             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7487             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.frozen);
7488             break;
7489         }
7490         case _ep_maps_hide_end:
7491         {
7492             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7493             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.hide_end);
7494             break;
7495         }
7496         case _ep_maps_hide_start:
7497         {
7498             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7499             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.hide_start);
7500             break;
7501         }
7502         case _ep_maps_ko:
7503         {
7504             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7505             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.ko);
7506             break;
7507         }
7508         case _ep_maps_kotype:
7509         {
7510             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7511             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.kotype);
7512             break;
7513         }
7514         case _ep_maps_table:
7515         {
7516             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7517             (*pretvar)->ptrVal = (VOID *)(ent->colourmap);
7518             break;
7519         }
7520         case _ep_maps_time:
7521         {
7522             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7523             (*pretvar)->lVal = (LONG)(ent->maptime);
7524             break;
7525         }
7526         default:
7527         {
7528             *pretvar = NULL;
7529             return E_FAIL;
7530         }
7531         }
7532         break;
7533     }
7534     case _ep_maxguardpoints:
7535     {
7536         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7537         (*pretvar)->lVal = (LONG)ent->modeldata.guardpoints.max;
7538         break;
7539     }
7540     case _ep_maxhealth:
7541     {
7542         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7543         (*pretvar)->lVal = (LONG)ent->modeldata.health;
7544         break;
7545     }
7546     case _ep_maxjugglepoints:
7547     {
7548         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7549         (*pretvar)->lVal = (LONG)ent->modeldata.jugglepoints.max;
7550         break;
7551     }
7552     case _ep_maxmp:
7553     {
7554         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7555         (*pretvar)->lVal = (LONG)ent->modeldata.mp;
7556         break;
7557     }
7558     case _ep_model:
7559     {
7560         ScriptVariant_ChangeType(*pretvar, VT_STR);
7561         StrCache_Copy((*pretvar)->strVal, ent->model->name);
7562         break;
7563     }
7564     case _ep_mp:
7565     {
7566         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7567         (*pretvar)->lVal = (LONG)ent->mp;
7568         break;
7569     }
7570     case _ep_mpdroprate:
7571     {
7572         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7573         (*pretvar)->lVal = (LONG)ent->modeldata.mpdroprate;
7574         break;
7575     }
7576     case _ep_mprate:
7577     {
7578         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7579         (*pretvar)->lVal = (LONG)ent->modeldata.mprate;
7580         break;
7581     }
7582     case _ep_mpstable:
7583     {
7584         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7585         (*pretvar)->lVal = (LONG)ent->modeldata.mpstable;
7586         break;
7587     }
7588     case _ep_mpstableval:
7589     {
7590         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7591         (*pretvar)->lVal = (LONG)ent->modeldata.mpstableval;
7592         break;
7593     }
7594     case _ep_name:
7595     {
7596         ScriptVariant_ChangeType(*pretvar, VT_STR);
7597         StrCache_Copy((*pretvar)->strVal, ent->name);
7598         break;
7599     }
7600     case _ep_nextanim:
7601     {
7602         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7603         (*pretvar)->lVal = (LONG)ent->nextanim;
7604         break;
7605     }
7606     case _ep_nextmove:
7607     {
7608         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7609         (*pretvar)->lVal = (LONG)ent->nextmove;
7610         break;
7611     }
7612     case _ep_nextthink:
7613     {
7614         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7615         (*pretvar)->lVal = (LONG)ent->nextthink;
7616         break;
7617     }
7618     case _ep_no_adjust_base:
7619     {
7620         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7621         (*pretvar)->lVal = (LONG)ent->modeldata.no_adjust_base;
7622         break;
7623     }
7624     case _ep_noaicontrol:
7625     {
7626         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7627         (*pretvar)->lVal = (LONG)ent->noaicontrol;
7628         break;
7629     }
7630     case _ep_nodieblink:
7631     {
7632         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7633         (*pretvar)->lVal = (LONG)ent->modeldata.nodieblink;
7634         break;
7635     }
7636     case _ep_nodrop:
7637     {
7638         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7639         (*pretvar)->lVal = (LONG)ent->modeldata.nodrop;
7640         break;
7641     }
7642     case _ep_nograb:
7643     {
7644         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7645         (*pretvar)->lVal = (LONG)ent->nograb;
7646         break;
7647     }
7648     case _ep_nohithead:
7649     {
7650         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7651         (*pretvar)->lVal = (LONG)ent->modeldata.nohithead;
7652         break;
7653     }
7654     case _ep_nolife:
7655     {
7656         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7657         (*pretvar)->lVal = (LONG)ent->modeldata.nolife;
7658         break;
7659     }
7660     case _ep_nopain:
7661     {
7662         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7663         (*pretvar)->lVal = (LONG)ent->modeldata.nopain;
7664         break;
7665     }
7666     case _ep_offense:
7667     {
7668         ltemp = 0;
7669         if(paramCount >= 3)
7670         {
7671             arg = varlist[2];
7672             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
7673             {
7674                 ltemp = (LONG)0;
7675             }
7676         }
7677         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7678         (*pretvar)->dblVal = (DOUBLE)ent->offense_factors[(int)ltemp];
7679         break;
7680     }
7681     case _ep_offscreen_noatk_factor:
7682     {
7683         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7684         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.offscreen_noatk_factor;
7685         break;
7686     }
7687     case _ep_offscreenkill:
7688     {
7689         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7690         (*pretvar)->lVal = (LONG)ent->modeldata.offscreenkill;
7691         break;
7692     }
7693     case _ep_opponent:
7694     {
7695         if(ent->opponent) // always return an empty var if it is NULL
7696         {
7697             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7698             (*pretvar)->ptrVal = (VOID *)ent->opponent;
7699         }
7700         break;
7701     }
7702     case _ep_custom_target:
7703     {
7704         if(ent->custom_target) // always return an empty var if it is NULL
7705         {
7706             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7707             (*pretvar)->ptrVal = (VOID *)ent->custom_target;
7708         }
7709         break;
7710     }
7711     case _ep_owner:
7712     {
7713         if(ent->owner) // always return an empty var if it is NULL
7714         {
7715             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7716             (*pretvar)->ptrVal = (VOID *)ent->owner;
7717         }
7718         break;
7719     }
7720     case _ep_parent:
7721     {
7722         if(ent->parent) // always return an empty var if it is NULL
7723         {
7724             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7725             (*pretvar)->ptrVal = (VOID *)ent->parent;
7726         }
7727         break;
7728     }
7729     case _ep_path:
7730     {
7731         ScriptVariant_ChangeType(*pretvar, VT_STR);
7732         tempstr = ent->modeldata.path;
7733 
7734         StrCache_Copy((*pretvar)->strVal, tempstr);
7735         break;
7736     }
7737     case _ep_pathfindstep:
7738     {
7739         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7740         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.pathfindstep;
7741         //printf("%d %s %d\n", ent->sortid, ent->name, ent->playerindex);
7742         break;
7743     }
7744     case _ep_playerindex:
7745     {
7746         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7747         (*pretvar)->lVal = (LONG)ent->playerindex;
7748         //printf("%d %s %d\n", ent->sortid, ent->name, ent->playerindex);
7749         break;
7750     }
7751     case _ep_projectile:
7752     {
7753         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7754         (*pretvar)->lVal = (LONG)ent->projectile;
7755         break;
7756     }
7757     case _ep_range:
7758     {
7759         if(paramCount < 4)
7760         {
7761             break;
7762         }
7763 
7764         if(varlist[2]->vt != VT_INTEGER
7765                 || varlist[3]->vt != VT_INTEGER)
7766         {
7767             printf("\n Error, getentityproperty({ent}, 'range', {sub property}, {animation}): {Sub property} or {Animation} parameter is missing or invalid. \n");
7768             *pretvar = NULL;
7769             return E_FAIL;
7770         }
7771         ltemp	= varlist[2]->lVal;												//Subproperty.
7772         i		= varlist[3]->lVal;												//Animation.
7773 
7774         if(!validanim(ent, i))													//Verify animation.
7775         {
7776             break;
7777         }
7778 
7779         switch(ltemp)
7780         {
7781         case _ep_range_amax:
7782             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7783             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.max.y;
7784             break;
7785         case _ep_range_amin:
7786             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7787             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.min.y;
7788             break;
7789         case _ep_range_bmax:
7790             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7791             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.max.base;
7792             break;
7793         case _ep_range_bmin:
7794             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7795             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.min.base;
7796             break;
7797         case _ep_range_xmax:
7798             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7799             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.max.x;
7800             break;
7801         case _ep_range_xmin:
7802             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7803             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.min.x;
7804             break;
7805         case _ep_range_zmax:
7806             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7807             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.max.z;
7808             break;
7809         case _ep_range_zmin:
7810             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7811             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.min.z;
7812             break;
7813         default:
7814             *pretvar = NULL;
7815             return E_FAIL;
7816         }
7817         break;
7818     }
7819     case _ep_running:
7820     {
7821         if(paramCount < 3)
7822         {
7823             break;
7824         }
7825         arg = varlist[2];
7826         if(arg->vt != VT_INTEGER)
7827         {
7828             printf("You must give a string name for running property.\n");
7829             *pretvar = NULL;
7830             return E_FAIL;
7831         }
7832         ltemp = arg->lVal;
7833         switch(ltemp)
7834         {
7835         case _ep_running_speed:
7836         {
7837             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7838             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.runspeed;
7839             break;
7840         }
7841         case _ep_running_jumpy:
7842         {
7843             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7844             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.runjumpheight;
7845             break;
7846         }
7847         case _ep_running_jumpx:
7848         {
7849             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7850             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.runjumpdist;
7851             break;
7852         }
7853         case _ep_running_land:
7854         {
7855             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7856             (*pretvar)->lVal = (LONG)ent->modeldata.runhold;
7857             break;
7858         }
7859         case _ep_running_movez:
7860         {
7861             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7862             (*pretvar)->lVal = (LONG)ent->modeldata.runupdown;
7863             break;
7864         }
7865         }
7866         break;
7867     }
7868     case _ep_rush_count:
7869     {
7870         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7871         (*pretvar)->lVal = (LONG)ent->rush.count.current;
7872         break;
7873     }
7874     case _ep_rush_tally:
7875     {
7876         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7877         (*pretvar)->lVal = (LONG)ent->rush.count.max;
7878         break;
7879     }
7880     case _ep_rush_time:
7881     {
7882         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7883         (*pretvar)->lVal = (LONG)ent->rush.time;
7884         break;
7885     }
7886     case _ep_score:
7887     {
7888         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7889         (*pretvar)->lVal = (LONG)ent->modeldata.score;
7890         break;
7891     }
7892     case _ep_scroll:
7893     {
7894         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7895         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.scroll;
7896         break;
7897     }
7898     case _ep_seal:
7899     {
7900         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7901         (*pretvar)->lVal = (LONG)ent->seal;
7902         break;
7903     }
7904     case _ep_sealtime:
7905     {
7906         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7907         (*pretvar)->lVal = (LONG)ent->sealtime;
7908         break;
7909     }
7910     case _ep_setlayer:
7911     {
7912         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7913         (*pretvar)->lVal = (LONG)ent->modeldata.setlayer;
7914         break;
7915     }
7916     case _ep_sortid:
7917     {
7918         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7919         (*pretvar)->lVal = (LONG)ent->sortid;
7920         break;
7921     }
7922     case _ep_spawntype:
7923     {
7924         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7925         (*pretvar)->lVal = (LONG)ent->spawntype;
7926         break;
7927     }
7928     case _ep_speed:
7929     {
7930         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7931         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.speed;
7932         break;
7933     }
7934     case _ep_sprite:
7935     {
7936         ScriptVariant_ChangeType(*pretvar, VT_PTR);
7937         i = ent->animation->sprite[ent->animpos];
7938         spr = sprite_map[i].node->sprite;
7939         spr->centerx = sprite_map[i].centerx;
7940         spr->centery = sprite_map[i].centery;
7941         (*pretvar)->ptrVal = (VOID *)(spr);
7942         break;
7943     }
7944     case _ep_spritea:
7945     {
7946         /*
7947         2011_04_17, DC: Modder can now specify animation and frame to return sprite from.
7948         To retain backward compatibility, sprite from current animation/frame is returned
7949         when animation and/or frame parameters are not provided.
7950         */
7951 
7952         ltemp   = varlist[2]->lVal;
7953         arg     = varlist[3];
7954         arg1    = varlist[4];
7955 
7956         /*
7957         Request from animation or frame that doesn't exist = shutdown.
7958         Let's be more user friendly then that; return empty so modder can evaluate
7959         and take action accordingly.*/
7960         if(!validanim(ent, arg->lVal) || !(ent->modeldata.animation[arg->lVal]->numframes >= arg1->lVal))
7961         {
7962             break;
7963         }
7964 
7965         i = ent->modeldata.animation[arg->lVal]->sprite[arg1->lVal];
7966 
7967         switch(ltemp)
7968         {
7969         case _ep_spritea_centerx:
7970         {
7971             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7972             (*pretvar)->lVal = (LONG)sprite_map[i].centerx;
7973             break;
7974         }
7975         case _ep_spritea_centery:
7976         {
7977             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7978             (*pretvar)->lVal = (LONG)sprite_map[i].centery;
7979             break;
7980         }
7981         case _ep_spritea_file:
7982         {
7983             ScriptVariant_ChangeType(*pretvar, VT_STR);
7984             StrCache_Copy((*pretvar)->strVal, sprite_map[i].node->filename);
7985             break;
7986         }
7987         case _ep_spritea_offsetx:
7988         {
7989             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7990             (*pretvar)->lVal = (LONG)sprite_map[i].node->sprite->offsetx;
7991             break;
7992         }
7993         case _ep_spritea_offsety:
7994         {
7995             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7996             (*pretvar)->lVal = (LONG)sprite_map[i].node->sprite->offsety;
7997             break;
7998         }
7999         case _ep_spritea_sprite:
8000         {
8001             ScriptVariant_ChangeType(*pretvar, VT_PTR);
8002             spr = sprite_map[i].node->sprite;
8003             spr->centerx = sprite_map[i].centery;
8004             spr->centery = sprite_map[i].centery;
8005             (*pretvar)->ptrVal = (VOID *)(spr);
8006             break;
8007         }
8008         default:
8009         {
8010             *pretvar = NULL;
8011             return E_FAIL;
8012         }
8013         }
8014 
8015         break;
8016 
8017     }
8018     case _ep_stalltime:
8019     {
8020         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8021         (*pretvar)->lVal = (LONG)ent->stalltime;
8022         break;
8023     }
8024     case _ep_releasetime:
8025     {
8026         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8027         (*pretvar)->lVal = (LONG)ent->releasetime;
8028         break;
8029     }
8030     case _ep_stats:
8031     {
8032         if(paramCount < 4)
8033         {
8034             break;
8035         }
8036         arg = varlist[2];
8037         arg1 = varlist[3];
8038 
8039         if(arg->vt != VT_INTEGER || arg1->vt != VT_INTEGER)
8040         {
8041             printf("Incorrect parameters: getentityproperty({ent}, 'stats', {type}, {index}) \n {type}: \n 0 = Model. \n 1 = Entity. \n");
8042             *pretvar = NULL;
8043             return E_FAIL;
8044         }
8045 
8046         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8047 
8048         switch(arg->lVal)
8049         {
8050         default:
8051             if (ent->modeldata.stats[arg1->lVal])
8052             {
8053                 (*pretvar)->dblVal = (DOUBLE)ent->modeldata.stats[arg1->lVal];
8054             }
8055             break;
8056         case 1:
8057             if (ent->stats[arg1->lVal])
8058             {
8059                 (*pretvar)->dblVal = (DOUBLE)ent->stats[arg1->lVal];
8060             }
8061             break;
8062         }
8063         break;
8064     }
8065     case _ep_staydown:
8066     {
8067         arg = varlist[2];
8068         if(arg->vt != VT_INTEGER)
8069         {
8070 
8071             printf("You must provide a string name for staydown property:\n\
8072 	getentityproperty({ent}, 'staydown', {subproperty})\n\
8073 	~'rise'\n\
8074 	~'riseattack'\n\
8075 	~'riseattack_stall' \n");
8076             *pretvar = NULL;
8077             return E_FAIL;
8078         }
8079         ltemp = arg->lVal;
8080         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8081 
8082         switch(ltemp)
8083         {
8084         case _ep_staydown_rise:
8085         {
8086             i = ent->staydown.rise;
8087             break;
8088         }
8089         case _ep_staydown_riseattack:
8090         {
8091             i = ent->staydown.riseattack;
8092             break;
8093         }
8094         case _ep_staydown_riseattack_stall:
8095         {
8096             i = ent->staydown.riseattack_stall;
8097             break;
8098         }
8099         default:
8100         {
8101             *pretvar = NULL;
8102             return E_FAIL;
8103         }
8104         }
8105         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8106         (*pretvar)->lVal = (LONG)i;
8107         break;
8108     }
8109     case _ep_stealth:
8110     {
8111         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8112         (*pretvar)->lVal = (LONG)ent->modeldata.stealth.hide;
8113         break;
8114     }
8115     case _ep_subentity:
8116     {
8117         if(ent->subentity) // always return an empty var if it is NULL
8118         {
8119             ScriptVariant_ChangeType(*pretvar, VT_PTR);
8120             (*pretvar)->ptrVal = (VOID *)ent->subentity;
8121         }
8122         break;
8123     }
8124     case _ep_subject_to_basemap:
8125     {
8126         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8127         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_basemap;
8128         break;
8129     }
8130     case _ep_subject_to_gravity:
8131     {
8132         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8133         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_gravity;
8134         break;
8135     }
8136     case _ep_subject_to_hole:
8137     {
8138         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8139         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_hole;
8140         break;
8141     }
8142     case _ep_subject_to_maxz:
8143     {
8144         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8145         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_maxz;
8146         break;
8147     }
8148     case _ep_subject_to_minz:
8149     {
8150         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8151         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_minz;
8152         break;
8153     }
8154     case _ep_subject_to_obstacle:
8155     {
8156         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8157         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_obstacle;
8158         break;
8159     }
8160     case _ep_subject_to_platform:
8161     {
8162         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8163         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_platform;
8164         break;
8165     }
8166     case _ep_subject_to_screen:
8167     {
8168         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8169         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_screen;
8170         break;
8171     }
8172     case _ep_subject_to_wall:
8173     {
8174         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8175         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_wall;
8176         break;
8177     }
8178     case _ep_subtype:
8179     {
8180         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8181         (*pretvar)->lVal = (LONG)ent->modeldata.subtype;
8182         break;
8183     }
8184     case _ep_thold:
8185     {
8186         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8187         (*pretvar)->lVal = (LONG)ent->modeldata.thold;
8188         break;
8189     }
8190     case _ep_throwdamage:
8191     {
8192         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8193         (*pretvar)->lVal = (LONG)ent->modeldata.throwdamage;
8194         break;
8195     }
8196     case _ep_throwdist:
8197     {
8198         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8199         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.throwdist;
8200         break;
8201     }
8202     case _ep_throwframewait:
8203     {
8204         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8205         (*pretvar)->lVal = (LONG)ent->modeldata.throwframewait;
8206         break;
8207     }
8208     case _ep_throwheight:
8209     {
8210         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8211         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.throwheight;
8212         break;
8213     }
8214     case _ep_tosstime:
8215     {
8216         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8217         (*pretvar)->lVal = (LONG)ent->toss_time;
8218         break;
8219     }
8220     case _ep_tossv:
8221     {
8222         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8223         (*pretvar)->dblVal = (DOUBLE)ent->velocity.y;
8224         break;
8225     }
8226     case _ep_type:
8227     {
8228         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8229         (*pretvar)->lVal = (LONG)ent->modeldata.type;
8230         break;
8231     }
8232     case _ep_walkoffmovex:
8233     {
8234         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8235         (*pretvar)->lVal = (LONG)ent->modeldata.walkoffmovex;
8236         break;
8237     }
8238     case _ep_walkoffmovez:
8239     {
8240         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8241         (*pretvar)->lVal = (LONG)ent->modeldata.walkoffmovez;
8242         break;
8243     }
8244     case _ep_weapent:
8245     {
8246         ScriptVariant_ChangeType(*pretvar, VT_PTR);
8247         (*pretvar)->ptrVal = (VOID *)ent->weapent;
8248         break;
8249     }
8250     case _ep_numweapons:
8251     {
8252         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8253         (*pretvar)->lVal = (LONG)ent->modeldata.numweapons;
8254         break;
8255     }
8256     case _ep_weapnum:
8257     {
8258         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8259         (*pretvar)->lVal = (LONG)ent->modeldata.weapnum;
8260         break;
8261     }
8262     case _ep_weaploss:
8263     {
8264         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8265         if(paramCount >= 3)
8266         {
8267             if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8268             {
8269                 printf("You must specify the flag value.\n");
8270                 *pretvar = NULL;
8271                 return E_FAIL;
8272             }
8273 
8274             if (ltemp == 0) (*pretvar)->lVal = (LONG)ent->modeldata.weaploss[0];
8275             else (*pretvar)->lVal = (LONG)ent->modeldata.weaploss[1];
8276         }
8277         else (*pretvar)->lVal = (LONG)ent->modeldata.weaploss[0];
8278 
8279         break;
8280     }
8281     case _ep_x:
8282     {
8283         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8284         (*pretvar)->dblVal = (DOUBLE)ent->position.x;
8285         break;
8286     }
8287     case _ep_xdir:
8288     {
8289         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8290         (*pretvar)->dblVal = (DOUBLE)ent->velocity.x;
8291         break;
8292     }
8293     case _ep_z:
8294     {
8295         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8296         (*pretvar)->dblVal = (DOUBLE)ent->position.z;
8297         break;
8298     }
8299     case _ep_zdir:
8300     {
8301         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8302         (*pretvar)->dblVal = (DOUBLE)ent->velocity.z;
8303         break;
8304     }
8305     default:
8306         //printf("Property name '%s' is not supported by function getentityproperty.\n", propname);
8307         *pretvar = NULL;
8308         return E_FAIL;
8309         break;
8310     }
8311 
8312     return S_OK;
8313 }
8314 
8315 
8316 //changeentityproperty(pentity, propname, value1[ ,value2, value3, ...]);
openbor_changeentityproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8317 HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
8318 {
8319     entity *ent = NULL;
8320     s_model *tempmodel ;
8321     char *tempstr = NULL;
8322     LONG ltemp, ltemp2;
8323     DOUBLE dbltemp;
8324     int propind;
8325     int i = 0;
8326 
8327     static const void *actions[] =   // for takeaction
8328     {
8329         bomb_explode,
8330         common_animation_normal,
8331         common_attack_proc,
8332         common_block,
8333         common_drop,
8334         common_fall,
8335         common_get,
8336         common_grab,
8337         common_grabattack,
8338         common_grabbed,
8339         common_jump,
8340         common_land,
8341         common_lie,
8342         common_pain,
8343         common_prejump,
8344         common_rise,
8345         common_spawn,
8346         common_turn,
8347         normal_prepare,
8348         npc_warp,
8349         player_blink,
8350         suicide,
8351     };
8352 
8353     static const int entitytypes[] =
8354     {
8355         0, // "ground"; not a real entity type
8356         TYPE_ENEMY,
8357         TYPE_NPC,
8358         TYPE_OBSTACLE,
8359         TYPE_PLAYER,
8360         TYPE_SHOT,
8361 
8362     };
8363 
8364     static const void *think[] =   // 2011_03_03, DC: Think types.
8365     {
8366         common_think,
8367         player_think,
8368         steam_think,
8369         steamer_think,
8370         text_think,
8371         trap_think,
8372     };
8373 
8374     *pretvar = NULL;
8375 
8376     if(paramCount < 3)
8377     {
8378         printf("Function changeentityproperty must have have at least 3 parameters.");
8379         goto changeentityproperty_error;
8380     }
8381 
8382     mapstrings_entityproperty(varlist, paramCount);
8383 
8384     if(varlist[0]->vt != VT_PTR && varlist[0]->vt != VT_EMPTY)
8385     {
8386         printf("Function changeentityproperty must have a valid entity handle.");
8387         goto changeentityproperty_error;
8388     }
8389     ent = (entity *)varlist[0]->ptrVal; //retrieve the entity
8390     if(!ent)
8391     {
8392         return S_OK;
8393     }
8394 
8395     if(varlist[1]->vt != VT_INTEGER)
8396     {
8397         if(varlist[1]->vt != VT_STR)
8398         {
8399             printf("Function changeentityproperty must have a string property name.\n");
8400         }
8401         goto changeentityproperty_error;
8402     }
8403 
8404     propind = varlist[1]->lVal;
8405 
8406     switch(propind)
8407     {
8408     case _ep_aggression:
8409     {
8410         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8411         {
8412             ent->modeldata.aggression = (int)ltemp;
8413         }
8414         break;
8415     }
8416     case _ep_aiattack:
8417     {
8418         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8419         {
8420             ent->modeldata.aiattack = (int)ltemp;
8421         }
8422         break;
8423     }
8424     case _ep_aiflag:
8425     {
8426         if(varlist[2]->vt != VT_INTEGER)
8427         {
8428             if(varlist[2]->vt != VT_STR)
8429             {
8430                 printf("You must give a string value for AI flag name.\n");
8431             }
8432             goto changeentityproperty_error;
8433         }
8434         if(paramCount < 4)
8435         {
8436             break;
8437         }
8438 
8439         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
8440         {
8441             switch(varlist[2]->lVal)
8442             {
8443             case _ep_aiflag_dead:
8444                 ent->dead = (int)ltemp;
8445                 break;
8446             case _ep_aiflag_jumpid:
8447                 ent->jump.id = (int)ltemp;
8448                 break;
8449             case _ep_aiflag_jumping:
8450                 ent->jumping = (int)ltemp;
8451                 break;
8452             case _ep_aiflag_idling:
8453                 ent->idling = (int)ltemp;
8454                 break;
8455             case _ep_aiflag_drop:
8456                 ent->drop = (int)ltemp;
8457                 break;
8458             case _ep_aiflag_attacking:
8459                 ent->attacking = (int)ltemp;
8460                 break;
8461             case _ep_aiflag_getting:
8462                 ent->getting = (int)ltemp;
8463                 break;
8464             case _ep_aiflag_turning:
8465                 ent->turning = (int)ltemp;
8466                 break;
8467             case _ep_aiflag_charging:
8468                 ent->charging = (int)ltemp;
8469                 break;
8470             case _ep_aiflag_blocking:
8471                 ent->blocking = (int)ltemp;
8472                 break;
8473             case _ep_aiflag_falling:
8474                 ent->falling = (int)ltemp;
8475                 break;
8476             case _ep_aiflag_running:
8477                 ent->running = (int)ltemp;
8478                 break;
8479             case _ep_aiflag_inpain:
8480                 ent->inpain = (int)ltemp;
8481                 break;
8482             case _ep_aiflag_inbackpain:
8483                 ent->inbackpain = (int)ltemp;
8484                 break;
8485             case _ep_aiflag_projectile:
8486                 ent->projectile = (int)ltemp;
8487                 break;
8488             case _ep_aiflag_frozen:
8489                 ent->frozen = (int)ltemp;
8490                 break;
8491             case _ep_aiflag_toexplode:
8492                 ent->toexplode = (int)ltemp;
8493                 break;
8494             case _ep_aiflag_animating:
8495                 ent->animating = (int)ltemp;
8496                 break;
8497             case _ep_aiflag_blink:
8498                 ent->blink = (int)ltemp;
8499                 break;
8500             case _ep_aiflag_invincible:
8501                 ent->invincible = (int)ltemp;
8502                 break;
8503             case _ep_aiflag_autokill:
8504                 ent->autokill = (int)ltemp;
8505                 break;
8506             case _ep_aiflag_idlemode:
8507                 ent->idlemode = (int)ltemp;
8508                 break;
8509             case _ep_aiflag_walkmode:
8510                 ent->walkmode = (int)ltemp;
8511                 break;
8512             case _ep_aiflag_walking:
8513                 ent->walking = (int)ltemp;
8514                 break;
8515             default:
8516                 printf("Unknown AI flag.\n");
8517                 goto changeentityproperty_error;
8518             }
8519         }
8520         break;
8521     }
8522     case _ep_aimove:
8523     {
8524         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8525         {
8526             ent->modeldata.aimove = (int)ltemp;
8527         }
8528         break;
8529     }
8530     case _ep_alpha:
8531     {
8532         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8533         {
8534             ent->modeldata.alpha = (int)ltemp;
8535         }
8536         break;
8537     }
8538     case _ep_animation:
8539     {
8540         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8541         {
8542             ltemp2 = (LONG)1;
8543             if(paramCount < 4 || SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
8544             {
8545                 ent_set_anim(ent, (int)ltemp, (int)ltemp2);
8546             }
8547         }
8548         break;
8549     }
8550     case _ep_animhits:
8551     {
8552         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8553         {
8554             ent->animation->animhits = (int)ltemp;
8555         }
8556         break;
8557     }
8558     case _ep_animpos:
8559     {
8560         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8561         {
8562             ent->animpos = (int)ltemp;
8563         }
8564         break;
8565     }
8566     case _ep_antigrab:
8567     {
8568         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8569         {
8570             ent->modeldata.antigrab = (int)ltemp;
8571         }
8572         break;
8573     }
8574     case _ep_antigravity:
8575     {
8576         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
8577         {
8578             ent->modeldata.antigravity = (float)dbltemp;
8579         }
8580         break;
8581     }
8582 
8583     case _ep_attacking:
8584     {
8585         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8586         {
8587             ent->attacking = (int)ltemp;
8588         }
8589         break;
8590     }
8591     case _ep_attackid:
8592     {
8593         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8594         {
8595             ent->attack_id = (int)ltemp;
8596         }
8597         break;
8598     }
8599     case _ep_autokill:
8600     {
8601         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8602         {
8603             ent->autokill = (int)ltemp;
8604         }
8605         break;
8606     }
8607     case _ep_base:
8608     {
8609         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
8610         {
8611             ent->base = (float)dbltemp;
8612         }
8613         break;
8614     }
8615     case _ep_blink:
8616     {
8617         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8618         {
8619             ent->blink = (int)ltemp;
8620         }
8621         break;
8622     }
8623     case _ep_blockback:
8624     {
8625         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8626         {
8627             ent->modeldata.blockback = (int)ltemp;
8628         }
8629         break;
8630     }
8631     case _ep_blockodds:
8632     {
8633         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8634         {
8635             ent->modeldata.blockodds = (int)ltemp;
8636         }
8637         break;
8638     }
8639     case _ep_blockpain:
8640     {
8641         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8642         {
8643             ent->modeldata.blockpain = (int)ltemp;
8644         }
8645         break;
8646     }
8647     case _ep_boomerang:
8648     {
8649         if (paramCount < 4)
8650         {
8651             printf("You must specify 2 float values to change boomerang property (acceleration anddistance_x).\n");
8652             *pretvar = NULL;
8653             return E_FAIL;
8654         }
8655         else
8656         {
8657             DOUBLE dbltemp2;
8658 
8659             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8660             if( FAILED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)) || FAILED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
8661             {
8662                 printf("You must specify 2 float values to change boomerang property (acceleration anddistance_x).\n");
8663                 *pretvar = NULL;
8664                 return E_FAIL;
8665             }
8666             else
8667             {
8668                 ent->modeldata.boomerang_acc     = (float)dbltemp;
8669                 ent->modeldata.boomerang_distx   = (float)dbltemp2;
8670             }
8671         }
8672         break;
8673     }
8674     case _ep_boss:
8675     {
8676         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8677         {
8678             ent->boss = (int)ltemp;
8679         }
8680         break;
8681     }
8682     case _ep_bounce:
8683     {
8684         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8685         {
8686             ent->modeldata.bounce = (int)ltemp;
8687         }
8688         break;
8689     }
8690     case _ep_candamage:
8691     {
8692         ent->modeldata.candamage = 0;
8693 
8694         for(i = 2; i < paramCount; i++)
8695         {
8696             if(varlist[i]->vt == VT_INTEGER) // known entity type
8697             {
8698                 ltemp = varlist[i]->lVal;
8699                 if(ltemp == (_ep_hcd_ground | 0x80000000)) // "ground" - not needed?
8700                 {
8701                     ent->modeldata.ground = 1;
8702                 }
8703                 else if(ltemp & 0x80000000)
8704                 {
8705                     ent->modeldata.candamage |= entitytypes[ltemp & 0x7fffffff];
8706                 }
8707                 else
8708                 {
8709                     ent->modeldata.candamage |= ltemp;
8710                 }
8711             }
8712             else
8713             {
8714                 printf("You must pass one or more string constants for candamage entity type.\n");
8715                 goto changeentityproperty_error;
8716             }
8717         }
8718         break;
8719     }
8720     case _ep_combostep:
8721     {
8722         if(paramCount >= 4 &&
8723                 SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
8724                 SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
8725         {
8726             ent->combostep[(int)ltemp] = (int)ltemp2;
8727         }
8728         break;
8729     }
8730     case _ep_combotime:
8731     {
8732         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8733         {
8734             ent->combotime = (int)ltemp;
8735         }
8736         break;
8737     }
8738     case _ep_colourmap:
8739     {
8740         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8741         {
8742             ent->colourmap = (VOID *)model_get_colourmap(&(ent->modeldata), ltemp);
8743         }
8744         break;
8745     }
8746     case _ep_damage_on_landing:
8747     {
8748         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8749         {
8750             ent->damage_on_landing = (int)ltemp;
8751         }
8752         break;
8753     }
8754     case _ep_dead:
8755     {
8756         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8757         {
8758             ent->dead = (int)ltemp;
8759         }
8760         break;
8761     }
8762     case _ep_defaultname:
8763     {
8764         if(varlist[2]->vt != VT_STR)
8765         {
8766             printf("You must give a string value for entity name.\n");
8767             goto changeentityproperty_error;
8768         }
8769         tempmodel = findmodel((char *)StrCache_Get(varlist[2]->strVal));
8770         if(!tempmodel)
8771         {
8772             printf("Use must give an existing model's name for entity's default model name.\n");
8773             goto changeentityproperty_error;
8774         }
8775         ent->defaultmodel = tempmodel;
8776         break;
8777     }
8778     case _ep_defense:
8779     {
8780         if((ltemp2 =
8781                     (paramCount >= 4 &&
8782                      SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
8783                      ltemp < (LONG)MAX_ATKS && ltemp >= (LONG)0 &&
8784                      SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
8785            ))
8786         {
8787             ent->defense[(int)ltemp].factor = (float)dbltemp;
8788         }
8789 
8790         if(paramCount >= 5 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp))))
8791         {
8792             ent->defense[(int)ltemp].pain = (float)dbltemp;
8793         }
8794         if(paramCount >= 6 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp))))
8795         {
8796             ent->defense[(int)ltemp].knockdown = (float)dbltemp;
8797         }
8798         if(paramCount >= 7 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp))))
8799         {
8800             ent->defense[(int)ltemp].blockpower = (float)dbltemp;
8801         }
8802         if(paramCount >= 8 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp))))
8803         {
8804             ent->defense[(int)ltemp].blockthreshold = (float)dbltemp;
8805         }
8806         if(paramCount >= 9 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[8], &dbltemp))))
8807         {
8808             ent->defense[(int)ltemp].blockratio = (float)dbltemp;
8809         }
8810         if(paramCount >= 10 && ltemp2 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[9], &dbltemp)))
8811         {
8812             ent->defense[(int)ltemp].blocktype = dbltemp;
8813         }
8814 
8815         break;
8816     }
8817     case _ep_destx:
8818     {
8819         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
8820         {
8821             ent->destx = (float)dbltemp;
8822         }
8823         break;
8824     }
8825     case _ep_destz:
8826     {
8827         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
8828         {
8829             ent->destz = (float)dbltemp;
8830         }
8831         break;
8832     }
8833     case _ep_detect:
8834     {
8835         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8836         {
8837             ent->modeldata.stealth.detect = (int)ltemp;
8838         }
8839         break;
8840     }
8841     case _ep_direction:
8842     {
8843         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
8844         {
8845             ent->direction = (int)dbltemp;
8846         }
8847         break;
8848     }
8849     case _ep_dot:
8850     {
8851         if((SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp))))
8852         {
8853             i = (int)ltemp;
8854             if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
8855             {
8856                 ent->dot_time[i] = (int)dbltemp;
8857             }
8858             if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
8859             {
8860                 ent->dot[i] = (int)dbltemp;
8861             }
8862             if(paramCount >= 6 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
8863             {
8864                 ent->dot_force[i] = (int)dbltemp;
8865             }
8866             if(paramCount >= 7 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
8867             {
8868                 ent->dot_rate[i] = (int)dbltemp;
8869             }
8870             if(paramCount >= 8 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp)))
8871             {
8872                 ent->dot_atk[i] = (int)dbltemp;
8873             }
8874             if(paramCount >= 9)
8875             {
8876                 ent->dot_owner[i] = (entity *)varlist[8]->ptrVal;
8877             }
8878         }
8879         break;
8880     }
8881     case _ep_edelay:
8882     {
8883         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8884         {
8885             ent->modeldata.edelay.mode = (int)ltemp;
8886         }
8887         if(paramCount >= 3 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
8888         {
8889             ent->modeldata.edelay.factor = (float)dbltemp;
8890         }
8891         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
8892         {
8893             ent->modeldata.edelay.cap.min = (int)ltemp;
8894         }
8895         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
8896         {
8897             ent->modeldata.edelay.cap.max = (int)ltemp;
8898         }
8899         if(paramCount >= 6 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[6], &ltemp)))
8900         {
8901             ent->modeldata.edelay.range.min = (int)ltemp;
8902         }
8903         if(paramCount >= 7 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[7], &ltemp)))
8904         {
8905             ent->modeldata.edelay.range.max = (int)ltemp;
8906         }
8907 
8908         break;
8909     }
8910     case _ep_energycost:
8911     {
8912         if(paramCount != 5)
8913         {
8914             printf("\n Error, changeentityproperty({ent}, 'energycost', {subproperty}, {animation}, {value}): Invalid or missing parameter. \n");
8915             goto changeentityproperty_error;
8916         }
8917 
8918         if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
8919         {
8920             printf("\n Error, changeentityproperty has invalid animation id.\n");
8921             goto changeentityproperty_error;
8922         }
8923 
8924         i = (int)ltemp;
8925 
8926         if(!validanim(ent, i))
8927         {
8928             printf("\n Error, changeentityproperty({ent}, 'energycost', {subproperty}, {animation}, {value}): {animation} parameter invalid. Make sure the animation exists. \n");
8929             goto changeentityproperty_error;
8930         }
8931 
8932         if(varlist[2]->vt != VT_INTEGER)
8933         {
8934             printf("You must give a string value for energycost flag name.\n");
8935             goto changeentityproperty_error;
8936         }
8937 
8938         switch(varlist[2]->lVal)
8939         {
8940         case _ep_energycost_cost:
8941         {
8942             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
8943             {
8944                 if(ent->modeldata.animation[i]->energycost)
8945                 {
8946                     ent->modeldata.animation[i]->energycost->cost = ltemp;
8947                 }
8948 
8949             }
8950             break;
8951         }
8952         case _ep_energycost_disable:
8953         {
8954             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
8955             {
8956                 if(ent->modeldata.animation[i]->energycost)
8957                 {
8958                     ent->modeldata.animation[i]->energycost->disable = ltemp;
8959                 }
8960             }
8961             break;
8962         }
8963         case _ep_energycost_mponly:
8964         {
8965             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
8966             {
8967                 if(ent->modeldata.animation[i]->energycost)
8968                 {
8969                     ent->modeldata.animation[i]->energycost->mponly = ltemp;
8970                 }
8971             }
8972             break;
8973         }
8974         default:
8975             printf("Unknown Energycost flag.\n");
8976             goto changeentityproperty_error;
8977         }
8978         break;
8979     }
8980     case _ep_escapecount:
8981     {
8982         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8983         {
8984             ent->escapecount = (int)ltemp;
8985         }
8986         break;
8987     }
8988     case _ep_escapehits:
8989     {
8990         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8991         {
8992             ent->modeldata.escapehits = (int)ltemp;
8993         }
8994         break;
8995     }
8996     case _ep_facing:
8997     {
8998         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8999         {
9000             ent->modeldata.facing = (int)ltemp;
9001         }
9002         break;
9003     }
9004     case _ep_falldie:
9005     {
9006         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9007         {
9008             ent->modeldata.falldie = (int)ltemp;
9009         }
9010         break;
9011     }
9012     case _ep_playerindex:
9013     {
9014         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9015         {
9016             ent->playerindex = (int)ltemp;
9017         }
9018         break;
9019     }
9020     case _ep_pain_time:
9021     {
9022         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9023         {
9024             ent->pain_time = (int)ltemp;
9025         }
9026         break;
9027     }
9028     case _ep_freezetime:
9029     {
9030         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9031         {
9032             ent->freezetime = (int)ltemp;
9033         }
9034         break;
9035     }
9036     case _ep_frozen:
9037     {
9038         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9039         {
9040             ent->frozen = (int)ltemp;
9041         }
9042         break;
9043     }
9044     case _ep_gfxshadow:
9045     {
9046         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9047         {
9048             ent->modeldata.gfxshadow = (int)ltemp;
9049         }
9050         break;
9051     }
9052     case _ep_shadowbase:
9053     {
9054         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9055         {
9056             ent->modeldata.shadowbase = (int)ltemp;
9057         }
9058         break;
9059     }
9060     case _ep_grabforce:
9061     {
9062         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9063         {
9064             ent->modeldata.grabforce = (int)ltemp;
9065         }
9066         break;
9067     }
9068     case _ep_guardpoints:
9069     {
9070         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9071         {
9072             ent->modeldata.guardpoints.current = (int)ltemp;
9073         }
9074         break;
9075     }
9076     case _ep_hasplatforms:
9077     {
9078         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9079         {
9080             ent->modeldata.hasPlatforms = (int)ltemp;
9081         }
9082         break;
9083     }
9084     case _ep_health:
9085     {
9086         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9087         {
9088             ent->health = (int)ltemp;
9089             if(ent->health > ent->modeldata.health)
9090             {
9091                 ent->health = ent->modeldata.health;
9092             }
9093             else if(ent->health < 0)
9094             {
9095                 ent->health = 0;
9096             }
9097         }
9098         break;
9099     }
9100     case _ep_hitbyid:
9101     {
9102         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9103         {
9104             ent->hit_by_attack_id = (int)ltemp;
9105         }
9106         break;
9107     }
9108     case _ep_hitheadplatform:
9109     {
9110         ent->hithead = (entity *)varlist[2]->ptrVal;
9111         break;
9112     }
9113     case _ep_landedplatform:
9114     {
9115         ent->landed_on_platform = (entity *)varlist[2]->ptrVal;
9116         break;
9117     }
9118     case _ep_hitwall:
9119     {
9120         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9121         {
9122             ent->hitwall = (int)ltemp;
9123         }
9124         break;
9125     }
9126     case _ep_hmapl:
9127     {
9128         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9129         {
9130             ent->modeldata.maps.hide_start = ltemp;
9131         }
9132         break;
9133     }
9134     case _ep_hmapu:
9135     {
9136         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9137         {
9138             ent->modeldata.maps.hide_end = ltemp;
9139         }
9140         break;
9141     }
9142     case _ep_hostile:
9143     {
9144         ent->modeldata.hostile = 0;
9145         for(i = 2; i < paramCount; i++)
9146         {
9147             if(varlist[i]->vt == VT_INTEGER) // known entity type
9148             {
9149                 ltemp = varlist[i]->lVal;
9150                 if(ltemp & 0x80000000)
9151                 {
9152                     ent->modeldata.hostile |= entitytypes[ltemp & 0x7fffffff];
9153                 }
9154                 else
9155                 {
9156                     ent->modeldata.hostile |= ltemp;
9157                 }
9158             }
9159             else
9160             {
9161                 printf("You must pass one or more string constants for hostile entity type.\n");
9162                 goto changeentityproperty_error;
9163             }
9164         }
9165 
9166         break;
9167     }
9168     case _ep_iconposition:
9169     {
9170         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9171         {
9172             ent->modeldata.icon.position.x = (int)ltemp;
9173         }
9174         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9175         {
9176             ent->modeldata.icon.position.y = (int)ltemp;
9177         }
9178         break;
9179     }
9180     case _ep_invincible:
9181     {
9182         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9183         {
9184             ent->invincible = (int)ltemp;
9185         }
9186         break;
9187     }
9188     case _ep_invinctime:
9189     {
9190         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9191         {
9192             ent->invinctime = (int)ltemp;
9193         }
9194         break;
9195     }
9196     case _ep_jugglepoints:
9197     {
9198         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9199         {
9200             ent->modeldata.jugglepoints.current = (int)ltemp;
9201         }
9202         break;
9203     }
9204     case _ep_jumpheight:
9205     {
9206         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9207         {
9208             ent->modeldata.jumpheight = (float)dbltemp;
9209         }
9210         break;
9211     }
9212     case _ep_jumpmovex:
9213     {
9214         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9215         {
9216             ent->modeldata.jumpmovex = (int)ltemp;
9217         }
9218         break;
9219     }
9220     case _ep_jumpmovez:
9221     {
9222         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9223         {
9224             ent->modeldata.jumpmovex = (int)ltemp;
9225         }
9226         break;
9227     }
9228     case _ep_jumpspeed:
9229     {
9230         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9231         {
9232             ent->modeldata.jumpspeed = (float)dbltemp;
9233         }
9234         break;
9235     }
9236     case _ep_knockdowncount:
9237     {
9238         if(varlist[2]->vt != VT_INTEGER)
9239         {
9240             if(varlist[2]->vt != VT_STR)
9241                 printf("You must provide a string value for Knockdowncount subproperty:\n\
9242                     changeentityproperty({ent}, 'knockdowncount', {subproperty}, {value})\n\
9243                     ~'current'\n\
9244                     ~'max'\n\
9245                     ~'time'\n");
9246             goto changeentityproperty_error;
9247         }
9248 
9249         switch(varlist[2]->lVal)
9250         {
9251         case _ep_knockdowncount_current:
9252         {
9253             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
9254             {
9255                 ent->knockdowncount = (float)dbltemp;
9256             }
9257             break;
9258         }
9259         case _ep_knockdowncount_max:
9260         {
9261             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
9262             {
9263                 ent->modeldata.knockdowncount = (float)dbltemp;
9264             }
9265             break;
9266             case _ep_knockdowncount_time:
9267                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9268                 {
9269                     ent->knockdowntime = (int)ltemp;
9270                 }
9271                 break;
9272             }
9273         default:
9274             printf("Unknown knockdowncount subproperty.\n");
9275             goto changeentityproperty_error;
9276         }
9277         break;
9278     }
9279     case _ep_komap:
9280     {
9281         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9282         {
9283             ent->modeldata.maps.ko = (int)ltemp;
9284         }
9285         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9286         {
9287             ent->modeldata.maps.kotype = (int)ltemp;
9288         }
9289         break;
9290     }
9291     case _ep_lifeposition:
9292     {
9293         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9294         {
9295             ent->modeldata.hpx = (int)ltemp;
9296         }
9297         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9298         {
9299             ent->modeldata.hpy = (int)ltemp;
9300         }
9301         break;
9302     }
9303     case _ep_lifespancountdown:
9304     {
9305         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9306         {
9307             ent->lifespancountdown = (int)ltemp;
9308         }
9309         break;
9310     }
9311     case _ep_attackthrottle:
9312     {
9313         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9314         {
9315             ent->modeldata.attackthrottle = (float)dbltemp;
9316         }
9317         break;
9318     }
9319     case _ep_attackthrottletime:
9320     {
9321         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9322         {
9323             ent->modeldata.attackthrottletime = (float)dbltemp;
9324         }
9325         break;
9326     }
9327     case _ep_map:
9328     {
9329         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9330         {
9331             ent_set_colourmap(ent, (int)ltemp);
9332         }
9333         break;
9334     }
9335     case _ep_maptime:
9336     {
9337         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9338         {
9339             ent->maptime = (int)ltemp;
9340         }
9341         break;
9342     }
9343     case _ep_maxguardpoints:
9344     {
9345         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9346         {
9347             ent->modeldata.guardpoints.max = (int)ltemp;
9348         }
9349         break;
9350     }
9351     case _ep_maxhealth:
9352     {
9353         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9354         {
9355             ent->modeldata.health = (int)ltemp;
9356             if(ent->modeldata.health < 0)
9357             {
9358                 ent->modeldata.health = 0;    //OK, no need to have ot below 0
9359             }
9360         }
9361         break;
9362     }
9363     case _ep_maxjugglepoints:
9364     {
9365         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9366         {
9367             ent->modeldata.jugglepoints.max = (int)ltemp;
9368         }
9369         break;
9370     }
9371     case _ep_maxmp:
9372     {
9373         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9374         {
9375             ent->modeldata.mp = (int)ltemp;
9376             if(ent->modeldata.mp < 0)
9377             {
9378                 ent->modeldata.mp = 0;    //OK, no need to have ot below 0
9379             }
9380         }
9381         break;
9382     }
9383     case _ep_model:
9384     {
9385         if(varlist[2]->vt != VT_STR)
9386         {
9387             printf("You must give a string value for model name.\n");
9388             goto changeentityproperty_error;
9389         }
9390         tempstr = (char *)StrCache_Get(varlist[2]->strVal);
9391         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9392         {
9393             set_model_ex(ent, tempstr, -1, NULL, (int)ltemp);
9394             if(!ent->weapent)
9395             {
9396                 ent->weapent = ent;
9397             }
9398         }
9399         break;
9400     }
9401     case _ep_mp:
9402     {
9403         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9404         {
9405             ent->mp = (int)ltemp;
9406             if(ent->mp > ent->modeldata.mp)
9407             {
9408                 ent->mp = ent->modeldata.mp;
9409             }
9410             else if(ent->mp < 0)
9411             {
9412                 ent->mp = 0;
9413             }
9414         }
9415         break;
9416     }
9417     case _ep_mpset:
9418     {
9419         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9420         {
9421             ent->modeldata.mp = (int)dbltemp;
9422         }
9423         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
9424         {
9425             ent->modeldata.mpstable = (int)dbltemp;
9426         }
9427         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
9428         {
9429             ent->modeldata.mpstableval = (int)dbltemp;
9430         }
9431         if(paramCount >= 6 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
9432         {
9433             ent->modeldata.mprate = (int)dbltemp;
9434         }
9435         if(paramCount >= 7 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
9436         {
9437             ent->modeldata.mpdroprate = (int)dbltemp;
9438         }
9439         if(paramCount >= 8 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp)))
9440         {
9441             ent->modeldata.chargerate = (int)dbltemp;
9442         }
9443         break;
9444     }
9445     case _ep_name:
9446     {
9447         if(varlist[2]->vt != VT_STR)
9448         {
9449             printf("You must give a string value for entity name.\n");
9450             goto changeentityproperty_error;
9451         }
9452         strcpy(ent->name, (char *)StrCache_Get(varlist[2]->strVal));
9453         break;
9454     }
9455     case _ep_nameposition:
9456     {
9457         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9458         {
9459             ent->modeldata.namex = (int)ltemp;
9460         }
9461         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9462         {
9463             ent->modeldata.namey = (int)ltemp;
9464         }
9465         break;
9466     }
9467     case _ep_nextanim:
9468     {
9469         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9470         {
9471             ent->nextanim = (int)ltemp;
9472         }
9473         break;
9474     }
9475     case _ep_nextmove:
9476     {
9477         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9478         {
9479             ent->nextmove = (int)ltemp;
9480         }
9481         break;
9482     }
9483     case _ep_nextthink:
9484     {
9485         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9486         {
9487             ent->nextthink = (int)ltemp;
9488         }
9489         break;
9490     }
9491     case _ep_no_adjust_base:
9492     {
9493         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9494         {
9495             ent->modeldata.no_adjust_base = (int)ltemp;
9496         }
9497         break;
9498     }
9499     case _ep_noaicontrol:
9500     {
9501         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9502         {
9503             ent->noaicontrol = (int)ltemp;
9504         }
9505         break;
9506     }
9507     case _ep_nodieblink:
9508     {
9509         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9510         {
9511             ent->modeldata.nodieblink = (int)ltemp;
9512         }
9513         break;
9514     }
9515     case _ep_nodrop:
9516     {
9517         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9518         {
9519             ent->modeldata.nodrop = (int)ltemp;
9520         }
9521         break;
9522     }
9523     case _ep_nograb:
9524     {
9525         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9526         {
9527             ent->nograb = (int)ltemp;
9528         }
9529         break;
9530     }
9531     case _ep_nohithead:
9532     {
9533         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9534         {
9535             ent->modeldata.nohithead = (int)ltemp;
9536         }
9537         break;
9538     }
9539     case _ep_nolife:
9540     {
9541         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9542         {
9543             ent->modeldata.nolife = (int)ltemp;
9544         }
9545         break;
9546     }
9547     case _ep_nopain:
9548     {
9549         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9550         {
9551             ent->modeldata.nopain = (int)ltemp;
9552         }
9553         break;
9554     }
9555     case _ep_offense:
9556     {
9557         if(paramCount >= 4 &&
9558                 SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
9559                 ltemp < (LONG)MAX_ATKS && ltemp >= (LONG)0 &&
9560                 SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
9561         {
9562             ent->offense_factors[(int)ltemp] = (float)dbltemp;
9563         }
9564         break;
9565     }
9566     case _ep_offscreen_noatk_factor:
9567     {
9568         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9569         {
9570             ent->modeldata.offscreen_noatk_factor = (float)dbltemp;
9571         }
9572         break;
9573     }
9574     case _ep_offscreenkill:
9575     {
9576         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9577         {
9578             ent->modeldata.offscreenkill = (int)ltemp;
9579         }
9580         break;
9581     }
9582     case _ep_opponent:
9583     {
9584         ent->opponent = (entity *)varlist[2]->ptrVal;
9585         break;
9586     }
9587     case _ep_custom_target:
9588     {
9589         ent->custom_target = (entity *)varlist[2]->ptrVal;
9590         break;
9591     }
9592     case _ep_owner:
9593     {
9594         ent->owner = (entity *)varlist[2]->ptrVal;
9595         break;
9596     }
9597     case _ep_parent:
9598     {
9599         ent->parent = (entity *)varlist[2]->ptrVal;
9600         break;
9601     }
9602     case _ep_pathfindstep:
9603     {
9604         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9605         {
9606             ent->modeldata.pathfindstep = (float)dbltemp;
9607         }
9608         break;
9609     }
9610     case _ep_position:
9611     {
9612         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9613         {
9614             ent->position.x = (float)dbltemp;
9615         }
9616         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
9617         {
9618             ent->position.z = (float)dbltemp;
9619         }
9620         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
9621         {
9622             ent->position.y = (float)dbltemp;
9623         }
9624         break;
9625     }
9626     case _ep_x:
9627     {
9628         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9629         {
9630             ent->position.x = (float)dbltemp;
9631         }
9632         break;
9633     }
9634     case _ep_z:
9635     {
9636         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9637         {
9638             ent->position.z = (float)dbltemp;
9639         }
9640         break;
9641     }
9642     case _ep_a:
9643     case _ep_y:
9644     {
9645         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9646         {
9647             ent->position.y = (float)dbltemp;
9648         }
9649         break;
9650     }
9651     case _ep_projectile:
9652     {
9653         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9654         {
9655             ent->projectile = (int)ltemp;
9656         }
9657         break;
9658     }
9659     case _ep_projectilehit:
9660     {
9661         ent->modeldata.projectilehit = 0;
9662 
9663         for(i = 2; i < paramCount; i++)
9664         {
9665             if(varlist[i]->vt == VT_INTEGER) // known entity type
9666             {
9667                 ltemp = varlist[i]->lVal;
9668                 if(ltemp & 0x80000000)
9669                 {
9670                     ent->modeldata.projectilehit |= entitytypes[ltemp & 0x7fffffff];
9671                 }
9672                 else
9673                 {
9674                     ent->modeldata.projectilehit |= ltemp;
9675                 }
9676             }
9677             else
9678             {
9679                 printf("You must pass one or more string constants for projectilehit entity type.\n");
9680                 goto changeentityproperty_error;
9681             }
9682         }
9683 
9684         break;
9685     }
9686     case _ep_running:
9687     {
9688         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9689         {
9690             ent->modeldata.runspeed = (float)dbltemp;
9691         }
9692         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
9693         {
9694             ent->modeldata.runjumpheight = (float)dbltemp;
9695         }
9696         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
9697         {
9698             ent->modeldata.runjumpdist = (float)dbltemp;
9699         }
9700         if(paramCount >= 6 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
9701         {
9702             ent->modeldata.runhold = (int)dbltemp;
9703         }
9704         if(paramCount >= 7 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
9705         {
9706             ent->modeldata.runupdown = (int)dbltemp;
9707         }
9708 
9709         break;
9710     }
9711     case _ep_rush_count:
9712     {
9713         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9714         {
9715             ent->rush.count.current = (int)ltemp;
9716         }
9717         break;
9718     }
9719     case _ep_rush_tally:
9720     {
9721         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9722         {
9723             ent->rush.count.max = (int)ltemp;
9724         }
9725         break;
9726     }
9727     case _ep_rush_time:
9728     {
9729         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9730         {
9731             ent->rush.time = (int)ltemp;
9732         }
9733         break;
9734     }
9735     case _ep_score:
9736     {
9737         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9738         {
9739             ent->modeldata.score = (int)ltemp;
9740         }
9741         break;
9742     }
9743     case _ep_scroll:
9744     {
9745         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9746         {
9747             ent->modeldata.scroll = (float)dbltemp;
9748         }
9749         break;
9750     }
9751     case _ep_seal:
9752     {
9753         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9754         {
9755             ent->seal = (int)ltemp;
9756         }
9757         break;
9758     }
9759     case _ep_sealtime:
9760     {
9761         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9762         {
9763             ent->sealtime = (int)ltemp;
9764         }
9765         break;
9766     }
9767     case _ep_setlayer:
9768     {
9769         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9770         {
9771             ent->modeldata.setlayer = (int)ltemp;
9772         }
9773         break;
9774     }
9775     case _ep_sortid:
9776     {
9777         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9778         {
9779             ent->sortid = (int)ltemp;
9780         }
9781         break;
9782     }
9783     case _ep_speed:
9784     {
9785         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
9786         {
9787             ent->modeldata.speed = (float)dbltemp;
9788         }
9789         break;
9790     }
9791     case _ep_spritea:
9792     {
9793         if(varlist[2]->vt != VT_INTEGER)
9794         {
9795             if(varlist[2]->vt != VT_STR)
9796                 printf("You must provide a string value for Sprite Array subproperty:\n\
9797                     changeentityproperty({ent}, 'spritea', {subproperty}, {animation ID}, {frame}, {value})\n\
9798                     ~'centerx'\n\
9799                     ~'centery'\n\
9800                     ~'file'\n\
9801                     ~'offsetx'\n\
9802                     ~'sprite'\n");
9803             goto changeentityproperty_error;
9804         }
9805 
9806         ltemp   = varlist[2]->lVal;
9807 
9808         /*
9809         Failsafe checks. Any attempt to access a sprite property on invalid frame would cause instant shutdown.
9810         */
9811         if(!validanim(ent, varlist[3]->lVal) || !(ent->modeldata.animation[varlist[3]->lVal]->numframes >= varlist[4]->lVal) || paramCount < 5)
9812         {
9813             break;
9814         }
9815 
9816         i = ent->modeldata.animation[varlist[3]->lVal]->sprite[varlist[4]->lVal];   //Get sprite index.
9817 
9818         switch(ltemp)
9819         {
9820         case _ep_spritea_centerx:
9821         {
9822             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
9823             {
9824                 sprite_map[i].centerx = (int)ltemp;
9825             }
9826 
9827             break;
9828         }
9829         case _ep_spritea_centery:
9830         {
9831             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
9832             {
9833                 sprite_map[i].centery = (int)ltemp;
9834             }
9835             break;
9836         }
9837         case _ep_spritea_file:
9838         {
9839             if(varlist[5]->vt != VT_STR)
9840             {
9841                 printf("You must provide a string value for file name.\n");
9842                 goto changeentityproperty_error;
9843             }
9844             strcpy(sprite_map[i].node->filename, (char *)StrCache_Get(varlist[5]->strVal));
9845             break;
9846         }
9847         /*
9848         case _ep_spritea_offsetx:
9849         {
9850             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
9851             {
9852                 sprite_map[i].ofsx = (int)ltemp;
9853                 (*pretvar)->lVal = (LONG)1;
9854             }
9855             break;
9856         }
9857         case _ep_spritea_offsety:
9858         {
9859             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9860             {
9861                 sprite_map[i].ofsy = (int)ltemp;
9862                 (*pretvar)->lVal = (LONG)1;
9863             }
9864             break;
9865         }*/
9866         case _ep_spritea_sprite:
9867         {
9868             sprite_map[i].node->sprite = (VOID *)varlist[5]->ptrVal;
9869 
9870             break;
9871         }
9872         default:
9873             printf("Unknown Sprite Array subproperty.\n");
9874             goto changeentityproperty_error;
9875         }
9876         break;
9877     }
9878     case _ep_stalltime:
9879     {
9880         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9881         {
9882             ent->stalltime = (int)ltemp;
9883         }
9884         break;
9885     }
9886     case _ep_releasetime:
9887     {
9888         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9889         {
9890             ent->releasetime = (int)ltemp;
9891         }
9892         break;
9893     }
9894     case _ep_stats:
9895     {
9896         if(paramCount < 4)
9897         {
9898             break;
9899         }
9900 
9901         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9902         {
9903             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
9904             {
9905                 switch(varlist[2]->lVal)
9906                 {
9907                 default:
9908                     ent->modeldata.stats[(int)ltemp] = (float)dbltemp;
9909                     break;
9910                 case 1:
9911                     ent->stats[(int)ltemp] = (float)dbltemp;
9912                     break;
9913                 }
9914             }
9915         }
9916         break;
9917     }
9918     case _ep_staydown:
9919     {
9920         if(varlist[2]->vt != VT_INTEGER)
9921         {
9922             if(varlist[2]->vt != VT_STR)
9923                 printf("You must provide a string value for Staydown subproperty:\n\
9924                     changeentityproperty({ent}, 'staydown', {subproperty}, {value})\n\
9925                     ~'rise'\n\
9926                     ~'riseattack'\n\
9927                     ~'riseattack_stall'\n");
9928             goto changeentityproperty_error;
9929         }
9930         if(paramCount < 4)
9931         {
9932             break;
9933         }
9934 
9935         switch(varlist[2]->lVal)
9936         {
9937         case _ep_staydown_rise:
9938         {
9939             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9940             {
9941                 ent->staydown.rise = (int)ltemp;
9942             }
9943             break;
9944         }
9945         case _ep_staydown_riseattack:
9946         {
9947             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9948             {
9949                 ent->staydown.riseattack = (int)ltemp;
9950             }
9951             break;
9952         }
9953         case _ep_staydown_riseattack_stall:
9954         {
9955             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
9956             {
9957                 ent->staydown.riseattack_stall = (int)ltemp;
9958             }
9959             break;
9960         }
9961         default:
9962             printf("Unknown Staydown subproperty.\n");
9963             goto changeentityproperty_error;
9964         }
9965         break;
9966     }
9967     case _ep_stealth:
9968     {
9969         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9970         {
9971             ent->modeldata.stealth.hide = (int)ltemp;
9972         }
9973         break;
9974     }
9975     case _ep_subentity:
9976     {
9977         if(ent->subentity)
9978         {
9979             ent->subentity->parent = NULL;
9980         }
9981         ent->subentity = (entity *)varlist[2]->ptrVal;
9982         if(ent->subentity)
9983         {
9984             ent->subentity->parent = ent;
9985         }
9986         break;
9987     }
9988     case _ep_subject_to_basemap:
9989     {
9990         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9991         {
9992             ent->modeldata.subject_to_basemap = (int)ltemp;
9993         }
9994         break;
9995     }
9996     case _ep_subject_to_gravity:
9997     {
9998         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9999         {
10000             ent->modeldata.subject_to_gravity = (int)ltemp;
10001         }
10002         break;
10003     }
10004     case _ep_subject_to_hole:
10005     {
10006         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10007         {
10008             ent->modeldata.subject_to_hole = (int)ltemp;
10009         }
10010         break;
10011     }
10012     case _ep_subject_to_maxz:
10013     {
10014         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10015         {
10016             ent->modeldata.subject_to_maxz = (int)ltemp;
10017         }
10018         break;
10019     }
10020     case _ep_subject_to_minz:
10021     {
10022         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10023         {
10024             ent->modeldata.subject_to_minz = (int)ltemp;
10025         }
10026         break;
10027     }
10028     case _ep_subject_to_obstacle:
10029     {
10030         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10031         {
10032             ent->modeldata.subject_to_obstacle = (int)ltemp;
10033         }
10034         break;
10035     }
10036     case _ep_subject_to_platform:
10037     {
10038         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10039         {
10040             ent->modeldata.subject_to_platform = (int)ltemp;
10041         }
10042         break;
10043     }
10044     case _ep_subject_to_screen:
10045     {
10046         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10047         {
10048             ent->modeldata.subject_to_screen = (int)ltemp;
10049         }
10050         break;
10051     }
10052     case _ep_subject_to_wall:
10053     {
10054         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10055         {
10056             ent->modeldata.subject_to_wall = (int)ltemp;
10057         }
10058         break;
10059     }
10060     case _ep_subtype:
10061     {
10062         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10063         {
10064             ent->modeldata.subtype = (int)ltemp;
10065         }
10066         break;
10067     }
10068     case _ep_takeaction:
10069     {
10070         //if(varlist[2]->vt == VT_STRING)
10071         if(varlist[2]->vt == VT_EMPTY)
10072         {
10073             // UT: changed this to only accept NULL(), otherwise the log file is filled with warnings
10074             ent->takeaction = NULL;
10075             break;
10076         }
10077         else if(varlist[2]->vt != VT_INTEGER)
10078         {
10079             printf("You must give a string value for action type.\n");
10080             goto changeentityproperty_error;
10081         }
10082 
10083         // otherwise, the parameter is a known action
10084         ltemp = varlist[2]->lVal;
10085         if((ltemp >= 0) && (ltemp < _ep_ta_the_end))
10086         {
10087             ent->takeaction = actions[(int)ltemp];
10088         }
10089 
10090         break;
10091     }
10092     case _ep_think:
10093     {
10094         //if(varlist[2]->vt == VT_STRING)
10095         if(varlist[2]->vt == VT_EMPTY)
10096         {
10097             // UT: changed this to only accept NULL(), otherwise the log file is filled with warnings
10098             break;
10099         }
10100         else if(varlist[2]->vt != VT_INTEGER)
10101         {
10102             printf("You must give a string value for think type.\n");
10103             goto changeentityproperty_error;
10104         }
10105 
10106         // otherwise, the parameter is a known action
10107         ltemp = varlist[2]->lVal;
10108         if((ltemp >= 0) && (ltemp < _ep_th_the_end))
10109         {
10110             ent->think = think[(int)ltemp];
10111         }
10112 
10113         break;
10114     }
10115     case _ep_thold:
10116     {
10117         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10118         {
10119             ent->modeldata.thold = (int)ltemp;
10120         }
10121         break;
10122     }
10123     case _ep_throwdamage:
10124     {
10125         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10126         {
10127             ent->modeldata.throwdamage = (int)ltemp;
10128         }
10129         break;
10130     }
10131     case _ep_throwdist:
10132     {
10133         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10134         {
10135             ent->modeldata.throwdist = (float)dbltemp;
10136         }
10137         break;
10138     }
10139     case _ep_throwframewait:
10140     {
10141         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10142         {
10143             ent->modeldata.throwframewait = (int)ltemp;
10144         }
10145         break;
10146     }
10147     case _ep_throwheight:
10148     {
10149         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10150         {
10151             ent->modeldata.throwheight = (float)dbltemp;
10152         }
10153         break;
10154     }
10155     case _ep_tosstime:
10156     {
10157         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10158         {
10159             ent->toss_time = (int)ltemp;
10160         }
10161         break;
10162     }
10163     case _ep_trymove:
10164     {
10165         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10166         {
10167             if(ltemp == 1)
10168             {
10169                 ent->trymove = common_trymove;
10170             }
10171             else if(ltemp == 2)
10172             {
10173                 ent->trymove = player_trymove;
10174             }
10175             else
10176             {
10177                 ent->trymove = NULL;
10178             }
10179         }
10180         break;
10181     }
10182     case _ep_type:
10183     {
10184         if(varlist[2]->vt != VT_INTEGER)
10185         {
10186             printf("You must provide a type constant for type.\n");
10187             goto changeentityproperty_error;
10188         }
10189 
10190         ltemp = varlist[2]->lVal;
10191         ent->modeldata.type = (int)ltemp;
10192 
10193         break;
10194     }
10195     case _ep_velocity:
10196     {
10197         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10198         {
10199             ent->velocity.x = (float)dbltemp;
10200         }
10201         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
10202         {
10203             ent->velocity.z = (float)dbltemp;
10204         }
10205         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
10206         {
10207             ent->velocity.y = (float)dbltemp;
10208         }
10209         break;
10210     }
10211     case _ep_walkoffmovex:
10212     {
10213         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10214         {
10215             ent->modeldata.walkoffmovex = (int)ltemp;
10216         }
10217         break;
10218     }
10219     case _ep_walkoffmovez:
10220     {
10221         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10222         {
10223             ent->modeldata.walkoffmovez = (int)ltemp;
10224         }
10225         break;
10226     }
10227     case _ep_weapnum:
10228     {
10229         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10230         {
10231             ent->modeldata.weapnum = (int)ltemp;
10232         }
10233         break;
10234     }
10235     case _ep_weaploss:
10236     {
10237         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10238         {
10239             ent->modeldata.weaploss[0] = (int)ltemp;
10240         }
10241 
10242         if(paramCount >= 4)
10243         {
10244             if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
10245             {
10246                 printf("You must specify the flag value.\n");
10247                 *pretvar = NULL;
10248                 return E_FAIL;
10249             }
10250             ent->modeldata.weaploss[1] = (int)ltemp2;
10251         }
10252         break;
10253     }
10254     case _ep_weapon:
10255     {
10256         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10257         {
10258             ltemp2 = (LONG)0;
10259             if(paramCount < 4 ||  SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
10260             {
10261                 set_weapon(ent, (int)ltemp, (int)ltemp2);
10262             }
10263         }
10264         break;
10265     }
10266     default:
10267         //printf("Property name '%s' is not supported by function changeentityproperty.\n", propname);
10268         goto changeentityproperty_error;
10269         break;
10270     }
10271 
10272     return S_OK;
10273 changeentityproperty_error:
10274     return E_FAIL;
10275 }
10276 
10277 //tossentity(entity, height, speedx, speedz)
openbor_tossentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10278 HRESULT openbor_tossentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10279 {
10280     entity *ent = NULL;
10281     DOUBLE height = 0, speedx = 0, speedz = 0;
10282 
10283     if(paramCount < 1)
10284     {
10285         goto toss_error;
10286     }
10287 
10288     ent = (entity *)varlist[0]->ptrVal; //retrieve the entity
10289     if(!ent)
10290     {
10291         goto toss_error;
10292     }
10293 
10294     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10295     (*pretvar)->lVal = (LONG)1;
10296 
10297     if(paramCount >= 2)
10298     {
10299         ScriptVariant_DecimalValue(varlist[1], &height);
10300     }
10301     if(paramCount >= 3)
10302     {
10303         ScriptVariant_DecimalValue(varlist[2], &speedx);
10304     }
10305     if(paramCount >= 4)
10306     {
10307         ScriptVariant_DecimalValue(varlist[3], &speedz);
10308     }
10309 
10310     ent->velocity.x = (float)speedx;
10311     ent->velocity.z = (float)speedz;
10312     toss(ent, (float)height);
10313     return S_OK;
10314 
10315 toss_error:
10316     printf("Function tossentity(entity,height, speedx, speedz) requires at least a valid entity handle.\n");
10317     *pretvar = NULL;
10318     return E_FAIL;
10319 }
10320 
10321 // ===== getplayerproperty =====
10322 enum playerproperty_enum
10323 {
10324     _pp_colourmap,
10325     _pp_combokey,
10326     _pp_combostep,
10327     _pp_credits,
10328     _pp_disablekeys,
10329     _pp_ent,
10330     _pp_entity,
10331     _pp_hasplayed,
10332     _pp_hmapl,
10333     _pp_hmapu,
10334     _pp_inputtime,
10335     _pp_joining,
10336     _pp_keys,
10337     _pp_lives,
10338     _pp_mapcount,
10339     _pp_name,
10340     _pp_newkeys,
10341     _pp_numweapons,
10342     _pp_playkeys,
10343     _pp_releasekeys,
10344     _pp_score,
10345     _pp_spawnhealth,
10346     _pp_spawnmp,
10347     _pp_weapnum,
10348     _pp_weapon,
10349     _pp_the_end
10350 };
10351 
mapstrings_playerproperty(ScriptVariant ** varlist,int paramCount)10352 int mapstrings_playerproperty(ScriptVariant **varlist, int paramCount)
10353 {
10354     char *propname;
10355     int prop;
10356 
10357     static const char *proplist[] =
10358     {
10359         "colourmap",
10360         "combokey",
10361         "combostep",
10362         "credits",
10363         "disablekeys",
10364         "ent",
10365         "entity",
10366         "hasplayed",
10367         "hmapl",
10368         "hmapu",
10369         "inputtime",
10370         "joining",
10371         "keys",
10372         "lives",
10373         "mapcount",
10374         "name",
10375         "newkeys",
10376         "numweapons",
10377         "playkeys",
10378         "releasekeys",
10379         "score",
10380         "spawnhealth",
10381         "spawnmp",
10382         "weapnum",
10383         "weapon",
10384     };
10385 
10386     if(paramCount < 2)
10387     {
10388         return 1;
10389     }
10390 
10391     // property name
10392     MAPSTRINGS(varlist[1], proplist, _pp_the_end,
10393                "Player property name '%s' is not supported yet.\n");
10394 
10395     return 1;
10396 }
10397 
10398 //getplayerproperty(index, propname);
openbor_getplayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10399 HRESULT openbor_getplayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10400 {
10401     LONG ltemp;
10402     int index;
10403     entity *ent = NULL;
10404     int prop = -1;
10405     ScriptVariant *arg = NULL;
10406 
10407     if(paramCount < 2)
10408     {
10409         *pretvar = NULL;
10410         return E_FAIL;
10411     }
10412 
10413     mapstrings_playerproperty(varlist, paramCount);
10414     ScriptVariant_Clear(*pretvar);
10415 
10416     arg = varlist[0];
10417     if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
10418     {
10419         index = 0;
10420     }
10421     else
10422     {
10423         index = (int)ltemp;
10424     }
10425 
10426 
10427     ent = player[index].ent;
10428 
10429     arg = varlist[1];
10430     if(arg->vt != VT_INTEGER)
10431     {
10432         if(arg->vt != VT_STR)
10433         {
10434             printf("Function call getplayerproperty has invalid propery name parameter, it must be a string value.\n");
10435         }
10436         *pretvar = NULL;
10437         return E_FAIL;
10438     }
10439     prop = arg->lVal;
10440 
10441     switch(prop)
10442     {
10443     case _pp_ent:
10444     case _pp_entity:
10445     {
10446         if(!ent)
10447         {
10448             ScriptVariant_Clear(*pretvar);    // player not spawned
10449         }
10450         else
10451         {
10452             ScriptVariant_ChangeType(*pretvar, VT_PTR);
10453             (*pretvar)->ptrVal = (VOID *)ent;
10454         }
10455         break;
10456     }
10457     case _pp_name:
10458     {
10459         ScriptVariant_ChangeType(*pretvar, VT_STR);
10460         StrCache_Copy((*pretvar)->strVal, (char *)player[index].name);
10461         break;
10462     }
10463     case _pp_colourmap:
10464     {
10465         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10466         (*pretvar)->lVal = (LONG)player[index].colourmap;
10467         break;
10468     }
10469     case _pp_score:
10470     {
10471         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10472         (*pretvar)->lVal = (LONG)player[index].score;
10473         break;
10474     }
10475     case _pp_hasplayed:
10476     {
10477         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10478         (*pretvar)->lVal = (LONG)player[index].hasplayed;
10479         break;
10480     }
10481     case _pp_spawnhealth:
10482     {
10483         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10484         (*pretvar)->lVal = (LONG)player[index].spawnhealth;
10485         break;
10486     }
10487     case _pp_spawnmp:
10488     {
10489         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10490         (*pretvar)->lVal = (LONG)player[index].spawnmp;
10491         break;
10492     }
10493     case _pp_lives:
10494     {
10495         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10496         (*pretvar)->lVal = (LONG)player[index].lives;
10497         break;
10498     }
10499     case _pp_disablekeys:
10500     {
10501         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10502         (*pretvar)->lVal = (LONG)player[index].disablekeys;
10503         break;
10504     }
10505     case _pp_playkeys:
10506     {
10507         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10508         (*pretvar)->lVal = (LONG)player[index].playkeys;
10509         break;
10510     }
10511     case _pp_keys:
10512     {
10513         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10514         (*pretvar)->lVal = (LONG)player[index].keys;
10515         break;
10516     }
10517     case _pp_newkeys:
10518     {
10519         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10520         (*pretvar)->lVal = (LONG)player[index].newkeys;
10521         break;
10522     }
10523     case _pp_releasekeys:
10524     {
10525         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10526         (*pretvar)->lVal = (LONG)player[index].releasekeys;
10527         break;
10528     }
10529     case _pp_credits:
10530     {
10531         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10532         if(noshare)
10533         {
10534             (*pretvar)->lVal = (LONG)player[index].credits;
10535         }
10536         else
10537         {
10538             (*pretvar)->lVal = credits;
10539         }
10540         break;
10541     }
10542     case _pp_weapnum:
10543     {
10544         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10545         (*pretvar)->lVal = (LONG)player[index].weapnum;
10546         break;
10547     }
10548     case _pp_numweapons:
10549     {
10550         int cacheindex;
10551 
10552         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10553 
10554         if ( stricmp(player[index].name,"") != 0 ) {
10555             cacheindex = get_cached_model_index(player[index].name);
10556             if ( cacheindex == -1 )
10557             {
10558                (*pretvar)->lVal = (LONG)0;
10559                break;
10560             }
10561         } else
10562         {
10563            (*pretvar)->lVal = (LONG)0;
10564            break;
10565         }
10566 
10567         (*pretvar)->lVal = (LONG)model_cache[cacheindex].model->numweapons;
10568         break;
10569     }
10570     case _pp_joining:
10571     {
10572         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10573         (*pretvar)->lVal = (LONG)player[index].joining;
10574         break;
10575     }
10576     case _pp_combokey:
10577     {
10578         ScriptVariant *frm = NULL;
10579         frm = varlist[2];
10580         if(frm->vt != VT_INTEGER)
10581         {
10582             printf("Need a combostep value number for this property.\n");
10583             *pretvar = NULL;
10584             return E_FAIL;
10585         }
10586         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10587         (*pretvar)->lVal = (LONG)player[index].combokey[frm->lVal];
10588         break;
10589     }
10590     case _pp_combostep:
10591     {
10592         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10593         (*pretvar)->lVal = (LONG)player[index].combostep;
10594         break;
10595     }
10596     case _pp_inputtime:
10597     {
10598         ScriptVariant *frm = NULL;
10599         frm = varlist[2];
10600         if(frm->vt != VT_INTEGER)
10601         {
10602             printf("Need a combostep value number for this property.\n");
10603             *pretvar = NULL;
10604             return E_FAIL;
10605         }
10606         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10607         (*pretvar)->lVal = (LONG)player[index].inputtime[frm->lVal];
10608         break;
10609     }
10610     case _pp_hmapl:
10611     {
10612         int cacheindex;
10613 
10614         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10615 
10616         if ( stricmp(player[index].name,"") != 0 ) {
10617             cacheindex = get_cached_model_index(player[index].name);
10618             if ( cacheindex == -1 )
10619             {
10620                (*pretvar)->lVal = (LONG)0;
10621                break;
10622             }
10623         } else
10624         {
10625            (*pretvar)->lVal = (LONG)0;
10626            break;
10627         }
10628 
10629         (*pretvar)->lVal = (LONG)model_cache[cacheindex].model->maps.hide_start;
10630         break;
10631     }
10632     case _pp_hmapu:
10633     {
10634         int cacheindex;
10635 
10636         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10637 
10638         if ( stricmp(player[index].name,"") != 0 ) {
10639             cacheindex = get_cached_model_index(player[index].name);
10640             if ( cacheindex == -1 )
10641             {
10642                (*pretvar)->lVal = (LONG)0;
10643                break;
10644             }
10645         } else
10646         {
10647            (*pretvar)->lVal = (LONG)0;
10648            break;
10649         }
10650 
10651         (*pretvar)->lVal = (LONG)model_cache[cacheindex].model->maps.hide_end;
10652         break;
10653     }
10654     case _pp_mapcount:
10655     {
10656         int cacheindex;
10657 
10658         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10659 
10660         if ( stricmp(player[index].name,"") != 0 ) {
10661             cacheindex = get_cached_model_index(player[index].name);
10662             if ( cacheindex == -1 )
10663             {
10664                (*pretvar)->lVal = (LONG)0;
10665                break;
10666             }
10667         } else
10668         {
10669            (*pretvar)->lVal = (LONG)0;
10670            break;
10671         }
10672 
10673         (*pretvar)->lVal = (LONG)(model_cache[cacheindex].model->maps_loaded + 1);
10674         break;
10675     }
10676     //this property is not known
10677     //default:{
10678     //  .....
10679     //}
10680     }
10681     return S_OK;
10682 }
10683 
10684 
10685 //changeplayerproperty(index, propname, value[, value2, value3,...]);
openbor_changeplayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10686 HRESULT openbor_changeplayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10687 {
10688     LONG ltemp, ltemp2;
10689     int index;
10690     entity *ent = NULL;
10691     int prop = -1;
10692     char *tempstr = NULL;
10693     static char buffer[64];
10694     ScriptVariant *arg = NULL;
10695 
10696     *pretvar = NULL;
10697     if(paramCount < 3)
10698     {
10699         printf("Function changeplayerproperty must have at least 3 arguments.\n");
10700         return E_FAIL;
10701     }
10702 
10703     mapstrings_playerproperty(varlist, paramCount);
10704     arg = varlist[0];
10705 
10706     if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
10707     {
10708         index = 0;
10709     }
10710     else
10711     {
10712         index = (int)ltemp;
10713     }
10714 
10715     ent = player[index].ent;
10716 
10717     if(varlist[1]->vt != VT_INTEGER)
10718     {
10719         if(varlist[1]->vt != VT_STR)
10720         {
10721             printf("You must give a string value for player property name.\n");
10722         }
10723         return E_FAIL;
10724     }
10725     prop = varlist[1]->lVal;
10726 
10727     arg = varlist[2];
10728 
10729     //change the model
10730     switch(prop)
10731     {
10732     case _pp_ent:
10733     case _pp_entity:
10734     {
10735         if(arg->vt == VT_PTR || arg->vt == VT_EMPTY)
10736         {
10737             player[index].ent = (entity *)arg->ptrVal;
10738         }
10739         else
10740         {
10741             goto cpperror;
10742         }
10743         break;
10744     }
10745     case _pp_weapon:
10746     {
10747         if(ent)
10748         {
10749             if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10750             {
10751                 if(paramCount > 3)
10752                 {
10753                     if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
10754                     {
10755                         goto cpperror;
10756                     }
10757                 }
10758                 else
10759                 {
10760                     ltemp2 = (LONG)0;
10761                 }
10762                 set_weapon(player[index].ent, (int)ltemp, (int)ltemp2);
10763             }
10764             else
10765             {
10766                 goto cpperror;
10767             }
10768         }
10769         break;
10770     }
10771     case _pp_weapnum:
10772     {
10773         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10774         {
10775             player[index].weapnum = (int)ltemp;
10776         }
10777         else
10778         {
10779             goto cpperror;
10780         }
10781         break;
10782     }
10783     case _pp_name:
10784     {
10785         if(arg->vt != VT_STR)
10786         {
10787             goto cpperror;
10788         }
10789         tempstr = (char *)StrCache_Get(arg->strVal);
10790         strcpy(player[index].name, tempstr);
10791         break;
10792     }
10793     case _pp_colourmap:
10794     {
10795         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10796         {
10797             player[index].colourmap = (int)ltemp;
10798         }
10799         else
10800         {
10801             goto cpperror;
10802         }
10803         break;
10804     }
10805     case _pp_score:
10806     {
10807         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10808         {
10809             if(ltemp < 0)
10810             {
10811                 ltemp = 0;
10812             }
10813             else if(ltemp > 999999999)
10814             {
10815                 ltemp = 999999999;
10816             }
10817             player[index].score = (unsigned int)ltemp;
10818         }
10819         else
10820         {
10821             goto cpperror;
10822         }
10823         break;
10824     }
10825     case _pp_hasplayed:
10826     {
10827         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10828         {
10829             player[index].hasplayed = (int)ltemp;
10830         }
10831         else
10832         {
10833             goto cpperror;
10834         }
10835         break;
10836     }
10837     case _pp_spawnhealth:
10838     {
10839         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10840         {
10841             player[index].spawnhealth = (int)ltemp;
10842         }
10843         else
10844         {
10845             goto cpperror;
10846         }
10847         break;
10848     }
10849     case _pp_spawnmp:
10850     {
10851         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10852         {
10853             player[index].spawnmp = (int)ltemp;
10854         }
10855         else
10856         {
10857             goto cpperror;
10858         }
10859         break;
10860     }
10861     case _pp_lives:
10862     {
10863         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10864         {
10865             player[index].lives = (int)ltemp;
10866         }
10867         else
10868         {
10869             goto cpperror;
10870         }
10871         break;
10872     }
10873     case _pp_disablekeys:
10874     {
10875         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10876         {
10877             player[index].disablekeys = (int)ltemp;
10878         }
10879         else
10880         {
10881             goto cpperror;
10882         }
10883         break;
10884     }
10885     case _pp_playkeys:
10886     {
10887         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10888         {
10889             player[index].playkeys = (int)ltemp;
10890         }
10891         else
10892         {
10893             goto cpperror;
10894         }
10895         break;
10896     }
10897     case _pp_keys:
10898     {
10899         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10900         {
10901             player[index].keys = (int)ltemp;
10902         }
10903         else
10904         {
10905             goto cpperror;
10906         }
10907         break;
10908     }
10909     case _pp_newkeys:
10910     {
10911         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
10912         {
10913             player[index].newkeys = (int)ltemp;
10914         }
10915         else
10916         {
10917             goto cpperror;
10918         }
10919         break;
10920     }
10921     case _pp_credits:
10922     {
10923         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10924         {
10925             if(noshare)
10926             {
10927                 player[index].credits = (int)ltemp;
10928             }
10929             else
10930             {
10931                 credits = (int)ltemp;
10932             }
10933         }
10934         else
10935         {
10936             goto cpperror;
10937         }
10938         break;
10939     }
10940     case _pp_joining:
10941     {
10942         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
10943         {
10944             player[index].joining = (int)ltemp;
10945         }
10946         else
10947         {
10948             goto cpperror;
10949         }
10950         break;
10951     }
10952     case _pp_releasekeys:
10953     {
10954         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
10955         {
10956             player[index].releasekeys = (int)ltemp;
10957         }
10958         else
10959         {
10960             goto cpperror;
10961         }
10962         break;
10963     }
10964     case _pp_combokey:
10965     {
10966         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
10967         {
10968             ScriptVariant *value = NULL;
10969             value = varlist[3];
10970             if(value->vt != VT_INTEGER)
10971             {
10972                 printf("Need a value and combostep value for this property.\n");
10973                 *pretvar = NULL;
10974                 return E_FAIL;
10975             }
10976             player[index].combokey[ltemp] = (int)value->lVal;
10977         }
10978         else
10979         {
10980             goto cpperror;
10981         }
10982         break;
10983     }
10984     case _pp_combostep:
10985     {
10986         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
10987         {
10988             player[index].combostep = (int)ltemp;
10989         }
10990         else
10991         {
10992             goto cpperror;
10993         }
10994         break;
10995     }
10996     case _pp_inputtime:
10997     {
10998         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
10999         {
11000             ScriptVariant *value = NULL;
11001             value = varlist[3];
11002             if(value->vt != VT_INTEGER)
11003             {
11004                 printf("Need a value and combostep value number for this property.\n");
11005                 *pretvar = NULL;
11006                 return E_FAIL;
11007             }
11008             player[index].inputtime[ltemp] = (int)value->lVal;
11009         }
11010         else
11011         {
11012             goto cpperror;
11013         }
11014         break;
11015     }
11016     default:
11017         printf("Invalid property name for function changeplayerproperty.\n");
11018         return E_FAIL;
11019     }
11020 
11021     return S_OK;
11022 cpperror:
11023     ScriptVariant_ToString(arg, buffer);
11024     printf("Function changeplayerproperty receives an invalid value: %s.\n", buffer);
11025     return E_FAIL;
11026 }
11027 
11028 //checkhole(x,z,a), return 1 if there's hole here
openbor_checkhole(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11029 HRESULT openbor_checkhole(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11030 {
11031     ScriptVariant *arg = NULL;
11032     DOUBLE x, z, a;
11033 
11034     if(paramCount < 2)
11035     {
11036         *pretvar = NULL;
11037         return E_FAIL;
11038     }
11039 
11040     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11041     (*pretvar)->lVal = (LONG)0;
11042 
11043     arg = varlist[0];
11044     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11045     {
11046         return S_OK;
11047     }
11048 
11049     arg = varlist[1];
11050     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11051     {
11052         return S_OK;
11053     }
11054 
11055     if ( paramCount >= 3 )
11056     {
11057         arg = varlist[2];
11058         if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
11059         {
11060             return S_OK;
11061         }
11062 
11063         (*pretvar)->lVal = (LONG)(checkhole_in((float)x, (float)z, (float)a) && checkwall((float)x, (float)z) < 0);
11064     }
11065     else (*pretvar)->lVal = (LONG)(checkhole((float)x, (float)z) && checkwall((float)x, (float)z) < 0);
11066 
11067     return S_OK;
11068 }
11069 
11070 //checkholeindex(x,z,a), return hole index if there's hole here, else it returns -1
openbor_checkholeindex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11071 HRESULT openbor_checkholeindex(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11072 {
11073     ScriptVariant *arg = NULL;
11074     DOUBLE x, z, a;
11075 
11076     if(paramCount < 2)
11077     {
11078         *pretvar = NULL;
11079         return E_FAIL;
11080     }
11081 
11082     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11083     (*pretvar)->lVal = (LONG)-1;
11084 
11085     arg = varlist[0];
11086     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11087     {
11088         return S_OK;
11089     }
11090 
11091     arg = varlist[1];
11092     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11093     {
11094         return S_OK;
11095     }
11096 
11097     if ( checkwall((float)x, (float)z) < 0 )
11098     {
11099         if ( paramCount >= 3 )
11100         {
11101             arg = varlist[2];
11102             if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
11103             {
11104                 return S_OK;
11105             }
11106 
11107             (*pretvar)->lVal = (LONG)checkholeindex_in((float)x, (float)z, (float)a);
11108         }
11109         else (*pretvar)->lVal = (LONG)checkhole_index((float)x, (float)z);
11110     }
11111 
11112     return S_OK;
11113 }
11114 
11115 //checkwall(x,z), return wall height, or 0 | accept checkwall(x,z,y) too
openbor_checkwall(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11116 HRESULT openbor_checkwall(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11117 {
11118     ScriptVariant *arg = NULL;
11119     DOUBLE x, z, y;
11120     int wall;
11121     float h = 100000;
11122 
11123     if(paramCount < 2)
11124     {
11125         *pretvar = NULL;
11126         return E_FAIL;
11127     }
11128 
11129     ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11130     (*pretvar)->dblVal = (DOUBLE)0;
11131 
11132     arg = varlist[0];
11133     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11134     {
11135         return S_OK;
11136     }
11137 
11138     arg = varlist[1];
11139     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11140     {
11141         return S_OK;
11142     }
11143 
11144     if (paramCount > 2)
11145     {
11146         arg = varlist[2];
11147         if(FAILED(ScriptVariant_DecimalValue(arg, &y)))
11148         {
11149             return S_OK;
11150         }
11151         h = (float)y;
11152     }
11153 
11154     if((wall = checkwall_below((float)x, (float)z, (float)h)) >= 0)
11155     {
11156         (*pretvar)->dblVal = (DOUBLE)level->walls[wall].height;
11157     }
11158     return S_OK;
11159 }
11160 
11161 //checkwallindex(x,z), return wall index, or -1 | accept checkwallindex(x,z,y) too
openbor_checkwallindex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11162 HRESULT openbor_checkwallindex(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11163 {
11164     ScriptVariant *arg = NULL;
11165     DOUBLE x, z, y;
11166     int wall;
11167     float h = 100000;
11168 
11169     if(paramCount < 2)
11170     {
11171         *pretvar = NULL;
11172         return E_FAIL;
11173     }
11174 
11175     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11176     (*pretvar)->lVal = (LONG)-1;
11177 
11178     arg = varlist[0];
11179     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11180     {
11181         return S_OK;
11182     }
11183 
11184     arg = varlist[1];
11185     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11186     {
11187         return S_OK;
11188     }
11189 
11190     if (paramCount > 2)
11191     {
11192         arg = varlist[2];
11193         if(FAILED(ScriptVariant_DecimalValue(arg, &y)))
11194         {
11195             return S_OK;
11196         }
11197         h = (float)arg->dblVal;
11198     }
11199 
11200     if((wall = checkwall_below((float)x, (float)z, (float)h)) >= 0)
11201     {
11202         (*pretvar)->lVal = (LONG)wall;
11203     }
11204     return S_OK;
11205 }
11206 
11207 //checkplatformbelow(x,z,a), return the highest platfrom entity below
openbor_checkplatformbelow(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11208 HRESULT openbor_checkplatformbelow(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11209 {
11210     ScriptVariant *arg = NULL;
11211     DOUBLE x, z, a;
11212 
11213     if(paramCount < 3)
11214     {
11215         *pretvar = NULL;
11216         return E_FAIL;
11217     }
11218 
11219     //ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11220     //(*pretvar)->dblVal = (DOUBLE)0;
11221     ScriptVariant_ChangeType(*pretvar, VT_PTR);
11222     (*pretvar)->ptrVal = (VOID *)NULL;
11223 
11224     arg = varlist[0];
11225     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11226     {
11227         return S_OK;
11228     }
11229 
11230     arg = varlist[1];
11231     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11232     {
11233         return S_OK;
11234     }
11235 
11236     arg = varlist[2];
11237     if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
11238     {
11239         return S_OK;
11240     }
11241 
11242     ScriptVariant_ChangeType(*pretvar, VT_PTR);
11243     (*pretvar)->ptrVal = (VOID *)check_platform_below((float)x, (float)z, (float)a, NULL);
11244     return S_OK;
11245 }
11246 
11247 //checkplatformabove(x,z,a), find a lowest platform above this altitude
openbor_checkplatformabove(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11248 HRESULT openbor_checkplatformabove(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11249 {
11250     ScriptVariant *arg = NULL;
11251     DOUBLE x, z, a;
11252 
11253     if(paramCount < 3)
11254     {
11255         *pretvar = NULL;
11256         return E_FAIL;
11257     }
11258 
11259     //ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11260     //(*pretvar)->dblVal = (DOUBLE)0;
11261     ScriptVariant_ChangeType(*pretvar, VT_PTR);
11262     (*pretvar)->ptrVal = (VOID *)NULL;
11263 
11264     arg = varlist[0];
11265     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11266     {
11267         return S_OK;
11268     }
11269 
11270     arg = varlist[1];
11271     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11272     {
11273         return S_OK;
11274     }
11275 
11276     arg = varlist[2];
11277     if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
11278     {
11279         return S_OK;
11280     }
11281 
11282     ScriptVariant_ChangeType(*pretvar, VT_PTR);
11283     (*pretvar)->ptrVal = (VOID *)check_platform_above((float)x, (float)z, (float)a, NULL);
11284     return S_OK;
11285 }
11286 
11287 //checkplatformbetween(x,z,a_min,a_max), find the first platform between these 2 altitudes
openbor_checkplatformbetween(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11288 HRESULT openbor_checkplatformbetween(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11289 {
11290     ScriptVariant *arg = NULL;
11291     DOUBLE x, z, amin, amax;
11292 
11293     if(paramCount < 3)
11294     {
11295         *pretvar = NULL;
11296         return E_FAIL;
11297     }
11298 
11299     //ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11300     //(*pretvar)->dblVal = (DOUBLE)0;
11301     ScriptVariant_ChangeType(*pretvar, VT_PTR);
11302     (*pretvar)->ptrVal = (VOID *)NULL;
11303 
11304     arg = varlist[0];
11305     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11306     {
11307         return S_OK;
11308     }
11309 
11310     arg = varlist[1];
11311     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11312     {
11313         return S_OK;
11314     }
11315 
11316     arg = varlist[2];
11317     if(FAILED(ScriptVariant_DecimalValue(arg, &amin)))
11318     {
11319         return S_OK;
11320     }
11321 
11322     arg = varlist[3];
11323     if(FAILED(ScriptVariant_DecimalValue(arg, &amax)))
11324     {
11325         return S_OK;
11326     }
11327 
11328     ScriptVariant_ChangeType(*pretvar, VT_PTR);
11329     (*pretvar)->ptrVal = (VOID *)check_platform_between((float)x, (float)z, (float)amin, (float)amax, NULL);
11330     return S_OK;
11331 }
11332 
11333 //checkbasemap(x,z), return basemap height (float)
openbor_checkbasemap(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11334 HRESULT openbor_checkbasemap(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11335 {
11336     ScriptVariant *arg = NULL;
11337     DOUBLE x, z;
11338 
11339     if(paramCount < 2)
11340     {
11341         *pretvar = NULL;
11342         return E_FAIL;
11343     }
11344 
11345     ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11346     (*pretvar)->dblVal = (DOUBLE)0;
11347 
11348     arg = varlist[0];
11349     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11350     {
11351         return S_OK;
11352     }
11353 
11354     arg = varlist[1];
11355     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11356     {
11357         return S_OK;
11358     }
11359 
11360     (*pretvar)->dblVal = (DOUBLE)check_basemap((float)x, (float)z);
11361 
11362     return S_OK;
11363 }
11364 
11365 //checkbasemapindex(x,z), return basemap index in (x,z)
openbor_checkbasemapindex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11366 HRESULT openbor_checkbasemapindex(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11367 {
11368     ScriptVariant *arg = NULL;
11369     DOUBLE x, z;
11370 
11371     if(paramCount < 2)
11372     {
11373         *pretvar = NULL;
11374         return E_FAIL;
11375     }
11376 
11377     ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11378     (*pretvar)->dblVal = (DOUBLE)0;
11379 
11380     arg = varlist[0];
11381     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
11382     {
11383         return S_OK;
11384     }
11385 
11386     arg = varlist[1];
11387     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
11388     {
11389         return S_OK;
11390     }
11391 
11392     (*pretvar)->dblVal = (DOUBLE)check_basemap_index((float)x, (float)z);
11393 
11394     return S_OK;
11395 }
11396 
11397 //generatebasemap(int map_index, float rx, float rz, float x_size, float z_size, float min_y, float max_y, int x_cont) to generate an inclined terrain
openbor_generatebasemap(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11398 HRESULT openbor_generatebasemap(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11399 {
11400     DOUBLE rx, rz, x_size, z_size, min_y, max_y;
11401     LONG index;
11402     LONG x_cont = (LONG)0;
11403 
11404     if(paramCount < 7)
11405     {
11406         *pretvar = NULL;
11407         return E_FAIL;
11408     }
11409 
11410     if ( FAILED(ScriptVariant_IntegerValue(varlist[0], &index)) )
11411     {
11412         *pretvar = NULL;
11413         return E_FAIL;
11414     }
11415     if(paramCount > 7)
11416     {
11417         if ( FAILED(ScriptVariant_IntegerValue(varlist[7], &x_cont)) )
11418         {
11419             *pretvar = NULL;
11420             return E_FAIL;
11421         }
11422     }
11423     if ( FAILED(ScriptVariant_DecimalValue(varlist[1], &rx)) || FAILED(ScriptVariant_DecimalValue(varlist[2], &rz)) ||
11424          FAILED(ScriptVariant_DecimalValue(varlist[3], &x_size)) || FAILED(ScriptVariant_DecimalValue(varlist[4], &z_size)) ||
11425          FAILED(ScriptVariant_DecimalValue(varlist[5], &min_y)) || FAILED(ScriptVariant_DecimalValue(varlist[6], &max_y))
11426     )
11427     {
11428         *pretvar = NULL;
11429         return E_FAIL;
11430     }
11431 
11432     generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont);
11433 
11434     return S_OK;
11435 }
11436 
openbor_openfilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11437 HRESULT openbor_openfilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11438 {
11439     char *filename = NULL;
11440     ScriptVariant *arg = NULL;
11441     LONG location = 0;
11442     int fsindex;
11443 
11444     FILE *handle = NULL;
11445     char path[256] = {""};
11446     char tmpname[256] = {""};
11447     long size;
11448 
11449     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11450 
11451     if(paramCount < 1)
11452     {
11453         *pretvar = NULL;
11454         return E_FAIL;
11455     }
11456 
11457     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11458 
11459     arg = varlist[0];
11460     if(arg->vt != VT_STR)
11461     {
11462         printf("Filename for openfilestream must be a string.\n");
11463         *pretvar = NULL;
11464         return E_FAIL;
11465     }
11466 
11467     filename = (char *)StrCache_Get(arg->strVal);
11468 
11469     if(paramCount > 1)
11470     {
11471         arg = varlist[1];
11472         if(FAILED(ScriptVariant_IntegerValue(arg, &location)))
11473         {
11474             *pretvar = NULL;
11475             return E_FAIL;
11476         }
11477     }
11478 
11479     for(fsindex = 0; fsindex < numfilestreams; fsindex++)
11480     {
11481         if(filestreams[fsindex].buf == NULL)
11482         {
11483             break;
11484         }
11485     }
11486 
11487     if(fsindex == numfilestreams)
11488     {
11489         __realloc(filestreams, numfilestreams); //warning, don't ++ here, its a macro
11490         numfilestreams++;
11491     }
11492 
11493     // Load file from saves directory if specified
11494     if(location)
11495     {
11496         getBasePath(path, "Saves", 0);
11497         getPakName(tmpname, -1);
11498         strcat(path, tmpname);
11499         strcat(path, "/");
11500         strcat(path, filename);
11501         //printf("open path: %s", path);
11502 #ifndef DC
11503         if(!(fileExists(path)))
11504         {
11505             /*
11506             2011_03_27, DC: Let's be a little more friendly about missing files; this will let a function evaluate if file exists and decide what to do.
11507 
11508             printf("Openfilestream - file specified does not exist.\n"); //Keep this for possible debug mode in the future.
11509             */
11510             (*pretvar)->lVal = -1;
11511 
11512             return S_OK;
11513         }
11514 #endif
11515         handle = fopen(path, "rb");
11516         if(handle == NULL)
11517         {
11518             (*pretvar)->lVal = -1;
11519             return S_OK;
11520         }
11521         //printf("\nfile opened\n");
11522         fseek(handle, 0, SEEK_END);
11523         size = ftell(handle);
11524         //printf("\n file size %d fsindex %d\n", size, fsindex);
11525         rewind(handle);
11526         filestreams[fsindex].buf = malloc(sizeof(*filestreams[fsindex].buf) * (size + 1));
11527         if(filestreams[fsindex].buf == NULL)
11528         {
11529             (*pretvar)->lVal = -1;
11530             return S_OK;
11531         }
11532         fread(filestreams[fsindex].buf, 1, size, handle);
11533         filestreams[fsindex].buf[size] = 0;
11534         filestreams[fsindex].size = size;
11535     }
11536     else if(buffer_pakfile(filename, &filestreams[fsindex].buf, &filestreams[fsindex].size) != 1)
11537     {
11538         printf("Invalid filename used in openfilestream.\n");
11539         (*pretvar)->lVal = -1;
11540         return S_OK;
11541     }
11542 
11543     (*pretvar)->lVal = (LONG)fsindex;
11544 
11545     filestreams[fsindex].pos = 0;
11546     return S_OK;
11547 }
11548 
openbor_getfilestreamline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11549 HRESULT openbor_getfilestreamline(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11550 {
11551     int length;
11552     char *buf;
11553     ScriptVariant *arg = NULL;
11554     LONG filestreamindex;
11555 
11556     if(paramCount < 1)
11557     {
11558         *pretvar = NULL;
11559         return E_FAIL;
11560     }
11561 
11562     arg = varlist[0];
11563     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11564     {
11565         return S_OK;
11566     }
11567 
11568     ScriptVariant_ChangeType(*pretvar, VT_STR);
11569 
11570     length = 0;
11571     buf = filestreams[filestreamindex].buf + filestreams[filestreamindex].pos;
11572     while(buf[length] && buf[length] != '\n' && buf[length] != '\r')
11573     {
11574         ++length;
11575     }
11576 
11577     StrCache_NCopy((*pretvar)->strVal, buf, length);
11578 
11579     return S_OK;
11580 }
11581 
openbor_getfilestreamargument(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11582 HRESULT openbor_getfilestreamargument(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11583 {
11584     ScriptVariant *arg = NULL;
11585     LONG filestreamindex, argument;
11586     char *argtype = NULL;
11587 
11588     if(paramCount < 3)
11589     {
11590         *pretvar = NULL;
11591         return E_FAIL;
11592     }
11593 
11594     arg = varlist[0];
11595     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11596     {
11597         return S_OK;
11598     }
11599 
11600     arg = varlist[1];
11601     if(FAILED(ScriptVariant_IntegerValue(arg, &argument)))
11602     {
11603         return S_OK;
11604     }
11605     ScriptVariant_Clear(*pretvar);
11606 
11607     if(varlist[2]->vt != VT_STR)
11608     {
11609         printf("You must give a string value specifying what kind of value you want the argument converted to.\n");
11610         return E_FAIL;
11611     }
11612     argtype = (char *)StrCache_Get(varlist[2]->strVal);
11613 
11614     if(stricmp(argtype, "string") == 0)
11615     {
11616         ScriptVariant_ChangeType(*pretvar, VT_STR);
11617         StrCache_Copy((*pretvar)->strVal, (char *)findarg(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos, argument));
11618     }
11619     else if(stricmp(argtype, "int") == 0)
11620     {
11621         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11622         (*pretvar)->lVal = (LONG)atoi(findarg(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos, argument));
11623     }
11624     else if(stricmp(argtype, "float") == 0)
11625     {
11626         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11627         (*pretvar)->dblVal = (DOUBLE)atof(findarg(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos, argument));
11628     }
11629     else if(stricmp(argtype, "byte") == 0) // By White Dragon
11630     {
11631         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11632         (*pretvar)->lVal = (LONG)(readByte(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos));
11633     }
11634     else
11635     {
11636         printf("Invalid type for argument converted to (getfilestreamargument).\n");
11637         return E_FAIL;
11638     }
11639 
11640     return S_OK;
11641 }
11642 
openbor_filestreamnextline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11643 HRESULT openbor_filestreamnextline(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11644 {
11645     ScriptVariant *arg = NULL;
11646     char *buf;
11647     size_t pos;
11648     LONG filestreamindex;
11649 
11650     if(paramCount < 1)
11651     {
11652         *pretvar = NULL;
11653         return E_FAIL;
11654     }
11655 
11656     arg = varlist[0];
11657     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11658     {
11659         return S_OK;
11660     }
11661     pos = filestreams[filestreamindex].pos;
11662     buf = filestreams[filestreamindex].buf;
11663     while(buf[pos] && buf[pos] != '\n' && buf[pos] != '\r')
11664     {
11665         ++pos;
11666     }
11667     while(buf[pos] == '\n' || buf[pos] == '\r')
11668     {
11669         ++pos;
11670     }
11671     filestreams[filestreamindex].pos = pos;
11672 
11673     return S_OK;
11674 }
11675 
openbor_getfilestreamposition(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11676 HRESULT openbor_getfilestreamposition(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11677 {
11678     ScriptVariant *arg = NULL;
11679     LONG filestreamindex;
11680 
11681     if(paramCount < 1)
11682     {
11683         *pretvar = NULL;
11684         return E_FAIL;
11685     }
11686 
11687     arg = varlist[0];
11688     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11689     {
11690         return S_OK;
11691     }
11692 
11693     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11694     (*pretvar)->lVal = (LONG)filestreams[filestreamindex].pos;
11695     return S_OK;
11696 }
11697 
openbor_setfilestreamposition(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11698 HRESULT openbor_setfilestreamposition(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11699 {
11700     ScriptVariant *arg = NULL;
11701     LONG filestreamindex, position;
11702 
11703 
11704     if(paramCount < 2)
11705     {
11706         *pretvar = NULL;
11707         return E_FAIL;
11708     }
11709 
11710     arg = varlist[0];
11711     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11712     {
11713         return S_OK;
11714     }
11715 
11716     arg = varlist[1];
11717     if(FAILED(ScriptVariant_IntegerValue(arg, &position)))
11718     {
11719         return S_OK;
11720     }
11721 
11722     filestreams[filestreamindex].pos = position;
11723     return S_OK;
11724 }
11725 
openbor_filestreamappend(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11726 HRESULT openbor_filestreamappend(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11727 {
11728     LONG filestreamindex;
11729     ScriptVariant *arg = NULL;
11730     LONG appendtype = -1;
11731     size_t len1, len2;
11732     char *temp;
11733     static char append[2048];
11734 
11735     *pretvar = NULL;
11736     if(paramCount < 2)
11737     {
11738         goto append_error;
11739     }
11740 
11741     arg = varlist[0];
11742     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11743     {
11744         goto append_error;
11745     }
11746 
11747     if(paramCount >= 3)
11748     {
11749         arg = varlist[2];
11750         if(FAILED(ScriptVariant_IntegerValue(arg, &appendtype)))
11751         {
11752             goto append_error;
11753         }
11754     }
11755 
11756     arg = varlist[1];
11757 
11758     /*
11759      * By White Dragon to write a byte
11760      */
11761     if ( paramCount >= 4 )
11762     {
11763         char* argtype = NULL;
11764         unsigned char byte = (unsigned char)0x00;
11765         if ( varlist[3]->vt != VT_STR ) goto append_error;
11766 
11767         argtype = (char *)StrCache_Get(varlist[3]->strVal);
11768 
11769         if( stricmp(argtype, "byte") != 0 ) goto append_error;
11770         else
11771         {
11772             int inc = -1; // if buf > 0 (prev bytes) you need to begin from size-1 (index)
11773 
11774             len1 = 1+1; // +1 is the NULL to close the buffer
11775             len2 = filestreams[filestreamindex].size;
11776 
11777             filestreams[filestreamindex].buf = realloc( filestreams[filestreamindex].buf, sizeof(*temp)*(len1+len2+0) );
11778 
11779             byte = (unsigned char)varlist[1]->lVal;
11780             //printf("a:%s->%d->%d\n",filestreams[filestreamindex].buf,byte,filestreams[filestreamindex].size);
11781 
11782             if ( len2 <= 0 ) inc = 0;
11783 
11784             filestreams[filestreamindex].buf[filestreams[filestreamindex].size+inc] = byte; // overwrite 0x00 byte
11785             if (appendtype <= 1) filestreams[filestreamindex].buf[filestreams[filestreamindex].size+1+inc] = 0x00;
11786             //printf("b:%s\n",filestreams[filestreamindex].buf);
11787 
11788             filestreams[filestreamindex].size = len1 + len2;
11789         }
11790     } else
11791     {
11792         ScriptVariant_ToString(arg, append);
11793 
11794         len1 = strlen(append);
11795         len2 = filestreams[filestreamindex].size;
11796 
11797         filestreams[filestreamindex].buf = realloc(filestreams[filestreamindex].buf, sizeof(*temp) * (len1 + len2 + 4));
11798 
11799         if(appendtype == 0)
11800         {
11801             append[len1] = ' ';
11802             append[++len1] = '\0';
11803             strcpy(filestreams[filestreamindex].buf + len2, "\r\n");
11804             len2 += 2;
11805             strcpy(filestreams[filestreamindex].buf + len2, append);
11806         }
11807         else if(appendtype == 1)
11808         {
11809             append[len1] = ' ';
11810             append[++len1] = '\0';
11811             strcpy(filestreams[filestreamindex].buf + len2, append);
11812         }
11813         else
11814         {
11815             strcpy(filestreams[filestreamindex].buf + len2, append);
11816         }
11817         filestreams[filestreamindex].size = len1 + len2;
11818     }
11819 
11820     return S_OK;
11821 
11822 append_error:
11823     return E_FAIL;
11824 
11825 }
11826 
openbor_createfilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11827 HRESULT openbor_createfilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11828 {
11829     int fsindex;
11830     ScriptVariant_Clear(*pretvar);
11831 
11832     for(fsindex = 0; fsindex < numfilestreams; fsindex++)
11833     {
11834         if(filestreams[fsindex].buf == NULL)
11835         {
11836             break;
11837         }
11838     }
11839 
11840     if(fsindex == numfilestreams)
11841     {
11842         __realloc(filestreams, numfilestreams); //warning, don't ++ here, its a macro
11843         numfilestreams++;
11844     }
11845 
11846     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11847     (*pretvar)->lVal = (LONG)fsindex;
11848 
11849     // Initialize the new filestream
11850     filestreams[fsindex].pos = 0;
11851     filestreams[fsindex].size = 0;
11852     filestreams[fsindex].buf = malloc(sizeof(*filestreams[fsindex].buf) * 128);
11853     filestreams[fsindex].buf[0] = '\0';
11854     return S_OK;
11855 }
11856 
openbor_savefilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11857 HRESULT openbor_savefilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11858 {
11859     int i;
11860     LONG filestreamindex;
11861     ScriptVariant *arg = NULL;
11862     char *bytearg = NULL, *patharg = NULL;
11863     FILE *handle = NULL;
11864     char path[256] = {""};
11865     char tmpname[256] = {""};
11866 
11867     *pretvar = NULL;
11868 
11869     if(paramCount < 1)
11870     {
11871         return E_FAIL;
11872     }
11873 
11874     arg = varlist[0];
11875     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11876     {
11877         printf("You must give a valid filestrema handle for savefilestream!\n");
11878         return E_FAIL;
11879     }
11880 
11881     arg = varlist[1];
11882     if(arg->vt != VT_STR)
11883     {
11884         printf("Filename for savefilestream must be a string.\n");
11885         return E_FAIL;
11886     }
11887 
11888     if (paramCount > 2)
11889     {
11890         patharg = (char *)StrCache_Get(varlist[2]->strVal);
11891         if( varlist[2]->vt != VT_STR )
11892         {
11893             printf("The pathname parameter must be a string.\n");
11894             return E_FAIL;
11895         }
11896     }
11897 
11898     if (paramCount > 3) // By White Dragon
11899     {
11900         bytearg = (char *)StrCache_Get(varlist[3]->strVal);
11901         if( stricmp(bytearg, "byte") != 0 )
11902         {
11903             printf("%s parameter does not exist.\n",bytearg);
11904             return E_FAIL;
11905         }
11906     }
11907 
11908     // Get the saves directory
11909     if ( paramCount <= 2 || patharg == NULL )
11910     {
11911         getBasePath(path, "Saves", 0);
11912         getPakName(tmpname, -1);
11913         strcat(path, tmpname);
11914         // Add user's filename to path and write the filestream to it
11915         strcat(path, "/");
11916     } else // By White Dragon
11917     {
11918         strcat(path, "./");
11919         strcat(path, patharg);
11920     }
11921     //printf("path:%s\n",path);
11922 
11923     strcat(path, (char *)StrCache_Get(arg->strVal));
11924 
11925     for(i = strlen(path) - 1; i >= 0; i--)
11926     {
11927 
11928         if(path[i] == '/' || path[i] == '\\')
11929         {
11930             path[i] = 0;
11931             // Make folder if it doesn't exist
11932 #ifndef DC
11933             dirExists(path, 1);
11934 #endif
11935             path[i] = '/';
11936             break;
11937         }
11938     }
11939 
11940     //printf("save path: %s", path);
11941     handle = fopen(path, "wb");
11942     if(handle == NULL)
11943     {
11944         return E_FAIL;
11945     }
11946     fwrite(filestreams[filestreamindex].buf, 1, strlen(filestreams[filestreamindex].buf), handle);
11947 
11948     // add blank line so it can be read successfully
11949     if ( paramCount <= 3 || (paramCount > 3 && stricmp(bytearg, "byte") != 0 ) ) fwrite("\r\n", 1, 2, handle);
11950     fclose(handle);
11951 
11952     return S_OK;
11953 }
11954 
openbor_closefilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11955 HRESULT openbor_closefilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11956 {
11957     LONG filestreamindex;
11958     ScriptVariant *arg = NULL;
11959 
11960     *pretvar = NULL;
11961 
11962     if(paramCount < 1)
11963     {
11964         return E_FAIL;
11965     }
11966 
11967     arg = varlist[0];
11968     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
11969     {
11970         return E_FAIL;
11971     }
11972 
11973 
11974     if(filestreams[filestreamindex].buf)
11975     {
11976         free(filestreams[filestreamindex].buf);
11977         filestreams[filestreamindex].buf = NULL;
11978     }
11979     return S_OK;
11980 }
11981 //damageentity(entity, other, force, drop, type)
openbor_damageentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11982 HRESULT openbor_damageentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11983 {
11984     entity *ent = NULL;
11985     entity *other = NULL;
11986     entity *temp = NULL;
11987     LONG force, drop, type;
11988     s_collision_attack atk;
11989 
11990     if(paramCount < 1)
11991     {
11992         printf("Function requires at least 1 parameter.\n");
11993         goto de_error;
11994     }
11995 
11996     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11997     (*pretvar)->lVal = (LONG)0;
11998 
11999     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
12000     if(!ent)
12001     {
12002         printf("Invalid entity parameter.\n");
12003         goto de_error;
12004     }
12005 
12006     other = ent;
12007 
12008     if(paramCount >= 2 && varlist[1]->ptrVal)
12009     {
12010         other = (entity *)(varlist[1])->ptrVal;
12011     }
12012 
12013     if(paramCount >= 3 )
12014     {
12015         force = (LONG)1;
12016         drop = (LONG)0;
12017         type = (LONG)ATK_NORMAL;
12018 
12019         if(FAILED(ScriptVariant_IntegerValue((varlist[2]), &force)))
12020         {
12021             printf("Wrong force value.\n");
12022             goto de_error;
12023         }
12024 
12025         if(paramCount >= 4)
12026         {
12027             if(FAILED(ScriptVariant_IntegerValue((varlist[3]), &drop)))
12028             {
12029                 printf("Wrong drop value.\n");
12030                 goto de_error;
12031             }
12032         }
12033         if(paramCount >= 5)
12034         {
12035             if(FAILED(ScriptVariant_IntegerValue((varlist[4]), &type)))
12036             {
12037                 printf("Wrong type value.\n");
12038                 goto de_error;
12039             }
12040         }
12041 
12042         atk = emptyattack;
12043         atk.attack_force = force;
12044         atk.attack_drop = drop;
12045         if(drop)
12046         {
12047             atk.dropv.y = (float)DEFAULT_ATK_DROPV_Y;
12048             atk.dropv.x = (float)DEFAULT_ATK_DROPV_X;
12049             atk.dropv.z = (float)DEFAULT_ATK_DROPV_Z;
12050         }
12051         atk.attack_type = type;
12052     }
12053     else
12054     {
12055         atk = attack;
12056     }
12057 
12058     if(!ent->takedamage)
12059     {
12060         ent->health -= atk.attack_force;
12061         if(ent->health <= 0)
12062         {
12063             kill(ent);
12064         }
12065         (*pretvar)->lVal = (LONG)1;
12066     }
12067     else
12068     {
12069         temp = self;
12070         self = ent;
12071         (*pretvar)->lVal = (LONG)self->takedamage(other, &atk);
12072         self = temp;
12073     }
12074     return S_OK;
12075 
12076 de_error:
12077     *pretvar = NULL;
12078     return E_FAIL;
12079 }
12080 
12081 //killentity(entity)
openbor_killentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12082 HRESULT openbor_killentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12083 {
12084     entity *ent = NULL;
12085 
12086     if(paramCount < 1)
12087     {
12088         *pretvar = NULL;
12089         return E_FAIL;
12090     }
12091 
12092     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12093 
12094     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
12095     if(ent == NULL)
12096     {
12097         (*pretvar)->lVal = (LONG)0;
12098         return S_OK;
12099     }
12100     kill(ent);
12101     (*pretvar)->lVal = (LONG)1;
12102     return S_OK;
12103 }
12104 
12105 // dograb
12106 // Damon V. Caskey
12107 // 2013-12-30
12108 //
12109 // Enables initiation of the engine's default grab state between attacker and
12110 // target entities.
12111 //
12112 // dograb(ptr attacker, ptr target, int adjust);
12113 //
12114 // attacker: Entity attempting grab.
12115 // target: Entity to be grabbed.
12116 // adjustcheck: Engine's dograb adjust check flag.
openbor_dograb(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12117 HRESULT openbor_dograb(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12118 {
12119     #define SELF_NAME           "dograb(void attacker, void target, int adjust)"
12120     #define ARG_MINIMUM         2
12121     #define ARG_ATTACKER        0
12122     #define ARG_TARGET          1
12123     #define ARG_ADJUST          2
12124     #define ARG_ADJUST_DEFAULT  1
12125 
12126     int adjust          = ARG_ADJUST_DEFAULT;   // dograb adjust check.
12127     int result          = S_OK;                 // Function pass/fail result.
12128     entity *attacker    = NULL;                 // Attacker entity (attempting grab)
12129     entity *target      = NULL;                 // Target entity (to be grabbed)
12130 
12131     ScriptVariant_Clear(*pretvar);
12132 
12133     // Validate there are at least two parameters (attacker and target entities).
12134     if(paramCount < ARG_MINIMUM)
12135     {
12136         goto error_local;
12137     }
12138 
12139     // Get adjust check.
12140     if(paramCount > ARG_ADJUST)
12141     {
12142         ScriptVariant_IntegerValue(varlist[ARG_ADJUST], &adjust);
12143     }
12144 
12145     // Get attacking and target entity.
12146     attacker = (entity *)(varlist[ARG_ATTACKER])->ptrVal;
12147     target = (entity *)(varlist[ARG_TARGET])->ptrVal;
12148 
12149     // Validate entities.
12150     if(!attacker && !target)
12151     {
12152         goto error_local;
12153     }
12154 
12155     // Execute engine's grab function.
12156     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12157     (*pretvar)->lVal = dograb(attacker, target, adjust);
12158 
12159     return result;
12160 
12161     // Error trap
12162     error_local:
12163 
12164     result = E_FAIL;
12165     printf("\nYou must provide valid entity handles and an optional adjustment: " SELF_NAME);
12166 
12167     // Return result.
12168     return result;
12169 
12170     #undef SELF_NAME
12171     #undef ARG_MINIMUM
12172     #undef ARG_ATTACKER
12173     #undef ARG_TARGET
12174     #undef ARG_ADJUST
12175     #undef ARG_ADJUST_DEFAULT
12176 }
12177 
12178 //findtarget(entity, int animation);
openbor_findtarget(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12179 HRESULT openbor_findtarget(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12180 {
12181     int i = 0;
12182     entity *ent = NULL;
12183     entity *tempself, *target;
12184     LONG anim = -1;
12185 
12186     if(paramCount > 2)
12187     {
12188         ScriptVariant_IntegerValue(varlist[2], &i);
12189     }
12190 
12191     if(paramCount < 1)
12192     {
12193         *pretvar = NULL;
12194         return E_FAIL;
12195     }
12196 
12197     ScriptVariant_ChangeType(*pretvar, VT_PTR);
12198 
12199     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
12200     if(!ent)
12201     {
12202         ScriptVariant_Clear(*pretvar);
12203         return S_OK;
12204     }
12205     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
12206     {
12207         return E_FAIL;
12208     }
12209     tempself = self;
12210     self = ent;
12211     target = normal_find_target((int)anim, i);
12212     if(!target)
12213     {
12214         ScriptVariant_Clear(*pretvar);
12215     }
12216     else
12217     {
12218         (*pretvar)->ptrVal = (VOID *)target;
12219     }
12220     self = tempself;
12221     return S_OK;
12222 }
12223 
12224 //checkrange(entity, target, int ani);
openbor_checkrange(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12225 HRESULT openbor_checkrange(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12226 {
12227     entity *ent = NULL, *target = NULL;
12228     LONG ani = 0;
12229     extern int max_animations;
12230 
12231     if(paramCount < 2)
12232     {
12233         goto checkrange_error;
12234     }
12235 
12236     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12237 
12238     if(varlist[0]->vt != VT_PTR || varlist[1]->vt != VT_PTR)
12239     {
12240         goto checkrange_error;
12241     }
12242 
12243     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
12244     target = (entity *)(varlist[1])->ptrVal; //retrieve the target
12245 
12246     if(!ent || !target)
12247     {
12248         goto checkrange_error;
12249     }
12250 
12251     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &ani)))
12252     {
12253         goto checkrange_error;
12254     }
12255     else if(paramCount <= 2)
12256     {
12257         ani = ent->animnum;
12258     }
12259 
12260     if(ani < 0 || ani >= max_animations)
12261     {
12262         printf("Animation id out of range: %d / %d.\n", (int)ani, max_animations);
12263         goto checkrange_error;
12264     }
12265 
12266     (*pretvar)->lVal = check_range(ent, target, ani);
12267 
12268     return S_OK;
12269 
12270 checkrange_error:
12271     printf("Function needs at least 2 valid entity handles, the third parameter is optional: checkrange(entity, target, int animnum)\n");
12272     *pretvar = NULL;
12273     return E_FAIL;
12274 }
12275 
12276 //clearspawnentry();
openbor_clearspawnentry(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12277 HRESULT openbor_clearspawnentry(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12278 {
12279     *pretvar = NULL;
12280     memset(&spawnentry, 0, sizeof(spawnentry));
12281     spawnentry.index = spawnentry.itemindex = spawnentry.weaponindex = -1;
12282     return S_OK;
12283 }
12284 
12285 // ===== setspawnentry =====
12286 enum setspawnentry_enum
12287 {
12288     _sse_2phealth,
12289     _sse_2pitem,
12290     _sse_3phealth,
12291     _sse_3pitem,
12292     _sse_4phealth,
12293     _sse_4pitem,
12294     _sse_aggression,
12295     _sse_alias,
12296     _sse_alpha,
12297     _sse_boss,
12298     _sse_coords,
12299     _sse_credit,
12300     _sse_dying,
12301     _sse_flip,
12302     _sse_health,
12303     _sse_item,
12304     _sse_itemalias,
12305     _sse_itemhealth,
12306     _sse_itemmap,
12307     _sse_map,
12308     _sse_mp,
12309     _sse_multiple,
12310     _sse_name,
12311     _sse_nolife,
12312     _sse_parent,
12313     _sse_type,
12314     _sse_weapon,
12315     _sse_the_end,
12316 };
12317 
mapstrings_setspawnentry(ScriptVariant ** varlist,int paramCount)12318 int mapstrings_setspawnentry(ScriptVariant **varlist, int paramCount)
12319 {
12320     char *propname;
12321     int prop;
12322     static const char *proplist[] =
12323     {
12324         "2phealth",
12325         "2pitem",
12326         "3phealth",
12327         "3pitem",
12328         "4phealth",
12329         "4pitem",
12330         "aggression",
12331         "alias",
12332         "alpha",
12333         "boss",
12334         "coords",
12335         "credit",
12336         "dying",
12337         "flip",
12338         "health",
12339         "item",
12340         "itemalias",
12341         "itemhealth",
12342         "itemmap",
12343         "map",
12344         "mp",
12345         "multiple",
12346         "name",
12347         "nolife",
12348         "parent",
12349         "type",
12350         "weapon",
12351     };
12352 
12353     MAPSTRINGS(varlist[0], proplist, _sse_the_end,
12354                "Property name '%s' is not supported by setspawnentry.\n");
12355 
12356     return 1;
12357 }
12358 
12359 //setspawnentry(propname, value1[, value2, value3, ...]);
openbor_setspawnentry(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12360 HRESULT openbor_setspawnentry(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
12361 {
12362     LONG ltemp;
12363     s_model *tempmodel;
12364     DOUBLE dbltemp;
12365     int temp, prop;
12366     ScriptVariant *arg = NULL;
12367 
12368     if(paramCount < 2)
12369     {
12370         *pretvar = NULL;
12371         return E_FAIL;
12372     }
12373 
12374     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12375     (*pretvar)->lVal = (LONG)1;
12376 
12377     mapstrings_setspawnentry(varlist, paramCount);
12378     if(varlist[0]->vt != VT_INTEGER)
12379     {
12380         if(varlist[0]->vt != VT_STR)
12381         {
12382             printf("You must give a string value for spawn entry property name.\n");
12383         }
12384         *pretvar = NULL;
12385         return E_FAIL;
12386     }
12387 
12388     prop = varlist[0]->lVal;
12389 
12390     arg = varlist[1];
12391 
12392     switch(prop)
12393     {
12394     case _sse_name:
12395         if(arg->vt != VT_STR)
12396         {
12397             printf("You must use a string value for spawn entry's name property: function setspawnentry.\n");
12398             goto setspawnentry_error;
12399         }
12400         spawnentry.model = findmodel((char *)StrCache_Get(arg->strVal));
12401         break;
12402     case _sse_alias:
12403         if(arg->vt != VT_STR)
12404         {
12405             goto setspawnentry_error;
12406         }
12407         strcpy(spawnentry.alias, (char *)StrCache_Get(arg->strVal));
12408         break;
12409     case _sse_item:
12410         if(arg->vt != VT_STR)
12411         {
12412             goto setspawnentry_error;
12413         }
12414         spawnentry.itemmodel = findmodel((char *)StrCache_Get(arg->strVal));
12415         spawnentry.item = spawnentry.itemmodel->name;
12416         spawnentry.itemindex = get_cached_model_index(spawnentry.item);
12417         spawnentry.itemplayer_count = 0;
12418         break;
12419     case _sse_2pitem:
12420         if(arg->vt != VT_STR)
12421         {
12422             goto setspawnentry_error;
12423         }
12424         tempmodel = findmodel((char *)StrCache_Get(arg->strVal));
12425         if(!tempmodel)
12426         {
12427             spawnentry.item = NULL;
12428         }
12429         else
12430         {
12431             spawnentry.item = tempmodel->name;
12432         }
12433         spawnentry.itemplayer_count = 1;
12434         break;
12435     case _sse_3pitem:
12436         if(arg->vt != VT_STR)
12437         {
12438             goto setspawnentry_error;
12439         }
12440         spawnentry.itemmodel = findmodel((char *)StrCache_Get(arg->strVal));
12441         spawnentry.itemplayer_count = 2;
12442         break;
12443     case _sse_4pitem:
12444         if(arg->vt != VT_STR)
12445         {
12446             goto setspawnentry_error;
12447         }
12448         spawnentry.itemmodel = findmodel((char *)StrCache_Get(arg->strVal));
12449         spawnentry.itemplayer_count = 3;
12450         break;
12451     case _sse_health:
12452         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12453         {
12454             spawnentry.health[0] = (int)ltemp;
12455         }
12456         else
12457         {
12458             (*pretvar)->lVal = (LONG)0;
12459         }
12460         break;
12461     case _sse_itemhealth:
12462         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12463         {
12464             spawnentry.itemhealth = (int)ltemp;
12465         }
12466         else
12467         {
12468             (*pretvar)->lVal = (LONG)0;
12469         }
12470         break;
12471     case _sse_itemalias:
12472         if(arg->vt != VT_STR)
12473         {
12474             return E_FAIL;
12475         }
12476         strcpy(spawnentry.itemalias, (char *)StrCache_Get(arg->strVal));
12477         break;
12478     case _sse_2phealth:
12479         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12480         {
12481             spawnentry.health[1] = (int)ltemp;
12482         }
12483         else
12484         {
12485             (*pretvar)->lVal = (LONG)0;
12486         }
12487         break;
12488     case _sse_3phealth:
12489         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12490         {
12491             spawnentry.health[2] = (int)ltemp;
12492         }
12493         else
12494         {
12495             (*pretvar)->lVal = (LONG)0;
12496         }
12497         break;
12498     case _sse_4phealth:
12499         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12500         {
12501             spawnentry.health[3] = (int)ltemp;
12502         }
12503         else
12504         {
12505             (*pretvar)->lVal = (LONG)0;
12506         }
12507         break;
12508     case _sse_coords:
12509         temp = 1;
12510         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
12511         {
12512             spawnentry.position.x = (float)dbltemp;
12513         }
12514         else
12515         {
12516             temp = 0;
12517         }
12518         if(paramCount >= 3 && temp)
12519         {
12520             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
12521             {
12522                 spawnentry.position.z = (float)dbltemp;
12523             }
12524             else
12525             {
12526                 temp = 0;
12527             }
12528         }
12529         if(paramCount >= 4 && temp)
12530         {
12531             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
12532             {
12533                 spawnentry.position.y = (float)dbltemp;
12534             }
12535             else
12536             {
12537                 temp = 0;
12538             }
12539         }
12540         (*pretvar)->lVal = (LONG)temp;
12541         break;
12542     case _sse_mp:
12543         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12544         {
12545             spawnentry.mp = (int)ltemp;
12546         }
12547         else
12548         {
12549             (*pretvar)->lVal = (LONG)0;
12550         }
12551         break;
12552     case _sse_map:
12553         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12554         {
12555             spawnentry.colourmap = (int)ltemp;
12556         }
12557         else
12558         {
12559             (*pretvar)->lVal = (LONG)0;
12560         }
12561         break;
12562     case _sse_itemmap:
12563         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12564         {
12565             spawnentry.itemmap = (int)ltemp;
12566         }
12567         else
12568         {
12569             (*pretvar)->lVal = (LONG)0;
12570         }
12571         break;
12572     case _sse_alpha:
12573         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12574         {
12575             spawnentry.alpha = (int)ltemp;
12576         }
12577         else
12578         {
12579             (*pretvar)->lVal = (LONG)0;
12580         }
12581         break;
12582     case _sse_multiple:
12583         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12584         {
12585             spawnentry.multiple = (int)ltemp;
12586         }
12587         else
12588         {
12589             (*pretvar)->lVal = (LONG)0;
12590         }
12591         break;
12592     case _sse_dying:
12593         temp = 1;
12594         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12595         {
12596             spawnentry.dying = (int)ltemp;
12597         }
12598         else
12599         {
12600             temp = 0;
12601         }
12602         if(paramCount >= 3 && temp)
12603         {
12604             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
12605             {
12606                 spawnentry.per1 = (int)ltemp;
12607             }
12608             else
12609             {
12610                 temp = 0;
12611             }
12612         }
12613         if(paramCount >= 4 && temp)
12614         {
12615             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
12616             {
12617                 spawnentry.per2 = (int)ltemp;
12618             }
12619             else
12620             {
12621                 temp = 0;
12622             }
12623         }
12624         (*pretvar)->lVal = (LONG)temp;
12625         break;
12626     case _sse_nolife:
12627         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12628         {
12629             spawnentry.nolife = (int)ltemp;
12630         }
12631         else
12632         {
12633             (*pretvar)->lVal = (LONG)0;
12634         }
12635         break;
12636     case _sse_boss:
12637         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12638         {
12639             spawnentry.boss = (int)ltemp;
12640         }
12641         else
12642         {
12643             (*pretvar)->lVal = (LONG)0;
12644         }
12645         break;
12646     case _sse_flip:
12647         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12648         {
12649             spawnentry.flip = (int)ltemp;
12650         }
12651         else
12652         {
12653             (*pretvar)->lVal = (LONG)0;
12654         }
12655         break;
12656     case _sse_credit:
12657         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12658         {
12659             spawnentry.credit = (int)ltemp;
12660         }
12661         else
12662         {
12663             (*pretvar)->lVal = (LONG)0;
12664         }
12665         break;
12666     case _sse_aggression:
12667         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12668         {
12669             spawnentry.aggression = (int)ltemp;
12670         }
12671         else
12672         {
12673             (*pretvar)->lVal = (LONG)0;
12674         }
12675         break;
12676     case _sse_parent:
12677         if( arg->vt == VT_PTR ) //&& arg->vt != VT_EMPTY
12678         {
12679             spawnentry.parent = (entity *)arg->ptrVal;
12680         }
12681         else
12682         {
12683             (*pretvar)->ptrVal = (VOID *)NULL;
12684         }
12685         break;
12686     case _sse_type:
12687         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
12688         {
12689             spawnentry.entitytype = (int)ltemp;
12690         }
12691         else
12692         {
12693             (*pretvar)->lVal = (LONG)0;
12694         }
12695         break;
12696     case _sse_weapon:
12697         if(arg->vt != VT_STR)
12698         {
12699             goto setspawnentry_error;
12700         }
12701         spawnentry.weaponmodel = findmodel((char *)StrCache_Get(arg->strVal));
12702         break;
12703     default:
12704         //printf("Property name '%s' is not supported by setspawnentry.\n", propname);
12705         goto setspawnentry_error;
12706     }
12707 
12708     return S_OK;
12709 setspawnentry_error:
12710     *pretvar = NULL;
12711     return E_FAIL;
12712 }
12713 
12714 //spawn();
openbor_spawn(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12715 HRESULT openbor_spawn(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12716 {
12717     entity *ent;
12718 
12719     if(spawnentry.boss && level)
12720     {
12721         level->bosses++;
12722     }
12723 
12724     ent = smartspawn(&spawnentry);
12725 
12726     if(ent)
12727     {
12728         ScriptVariant_ChangeType(*pretvar, VT_PTR);
12729         (*pretvar)->ptrVal = (VOID *) ent;
12730     }
12731     else
12732     {
12733         ScriptVariant_Clear(*pretvar);
12734     }
12735 
12736     return S_OK;
12737 }
12738 
12739 //entity * projectile([0/1], char *name, float x, float z, float a, int direction, int pytype, int type, int map);
openbor_projectile(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12740 HRESULT openbor_projectile(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12741 {
12742     DOUBLE temp = 0;
12743     LONG ltemp = 0;
12744     entity *ent;
12745     char *name = NULL;
12746     float x = 0, z = 0, a = 0;
12747     int direction = DIRECTION_LEFT;
12748     int type = 0;
12749     int ptype = 0;
12750     int map = 0;
12751 
12752     int relative;
12753 
12754     if(paramCount >= 1 && varlist[0]->vt == VT_INTEGER && varlist[0]->lVal)
12755     {
12756         relative = 1;
12757         paramCount--;
12758         varlist++;
12759     }
12760     else
12761     {
12762         relative = 0;
12763     }
12764 
12765     if(paramCount >= 1 && varlist[0]->vt == VT_STR)
12766     {
12767         name = StrCache_Get(varlist[0]->strVal);
12768     }
12769 
12770     if(paramCount >= 2 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[1], &temp)))
12771     {
12772         x = (float)temp;
12773     }
12774     else if(relative)
12775     {
12776         x = 0;
12777     }
12778     else
12779     {
12780         x = self->position.x;
12781     }
12782     if(paramCount >= 3 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &temp)))
12783     {
12784         z = (float)temp;
12785     }
12786     else if(relative)
12787     {
12788         z = 0;
12789     }
12790     else
12791     {
12792         z = self->position.z;
12793     }
12794     if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &temp)))
12795     {
12796         a = (float)temp;
12797     }
12798     else if(relative)
12799     {
12800         a  = self->animation->projectile.position.y;
12801     }
12802     else
12803     {
12804         a = self->position.y + self->animation->projectile.position.y;
12805     }
12806     if(paramCount >= 5 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
12807     {
12808         direction = (int)ltemp;
12809     }
12810     else if(relative)
12811     {
12812         direction  = DIRECTION_RIGHT;
12813     }
12814     else
12815     {
12816         direction = self->direction;
12817     }
12818     if(paramCount >= 6 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
12819     {
12820         ptype = (int)ltemp;
12821     }
12822     if(paramCount >= 7 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[6], &ltemp)))
12823     {
12824         type = (int)ltemp;
12825     }
12826     if(paramCount >= 8 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[7], &ltemp)))
12827     {
12828         map = (int)ltemp;
12829     }
12830 
12831     if(relative)
12832     {
12833         if(self->direction == DIRECTION_RIGHT)
12834         {
12835             x += self->position.x;
12836         }
12837         else
12838         {
12839             x = self->position.x - x;
12840             direction = !direction;
12841         }
12842         z += self->position.z;
12843         a += self->position.y;
12844     }
12845 
12846     switch(type)
12847     {
12848     default:
12849     case 0:
12850         ent = knife_spawn(name, -1, x, z, a, direction, ptype, map);
12851         break;
12852     case 1:
12853         ent = bomb_spawn(name, -1, x, z, a, direction, map);
12854         break;
12855     }
12856 
12857     ScriptVariant_ChangeType(*pretvar, VT_PTR);
12858     (*pretvar)->ptrVal = (VOID *) ent;
12859 
12860     return S_OK;
12861 }
12862 
12863 
12864 // ===== openborconstant =====
12865 #define IICMPCONST(x) \
12866 if(stricmp(#x, constname)==0) {\
12867 	v.lVal = (LONG)x;\
12868 }
12869 
12870 
12871 #define ICMPCONST(x) \
12872 else if(stricmp(#x, constname)==0) {\
12873 	v.lVal = (LONG)x;\
12874 }
12875 
12876 #define ICMPSCONSTA(x, y) \
12877 else if(strnicmp(constname, #x, sizeof(#x)-1)==0 && constname[sizeof(#x)-1] >= '1' && constname[sizeof(#x)-1]<='9') \
12878 { \
12879 	v.lVal = (LONG)(y[atoi(constname+(sizeof(#x)-1))-1]);\
12880 }
12881 
12882 #define ICMPSCONSTB(x, y) \
12883 else if(strnicmp(constname, #x, sizeof(#x)-1)==0 && constname[sizeof(#x)-1] >= '1' && constname[sizeof(#x)-1]<='9') \
12884 { \
12885 	v.lVal = (LONG)(y[atoi(constname+(sizeof(#x)-1))+STA_ATKS-1]);\
12886 }
12887 
12888 #define ICMPSCONSTC(x) \
12889 else if(strnicmp(constname, #x, sizeof(#x)-1)==0 && constname[sizeof(#x)-1] >= '1' && constname[sizeof(#x)-1]<='9') \
12890 { \
12891 	v.lVal = (LONG)(atoi(constname+(sizeof(#x)-1))+STA_ATKS-1);\
12892 }
12893 
mapstrings_transconst(ScriptVariant ** varlist,int paramCount)12894 int mapstrings_transconst(ScriptVariant **varlist, int paramCount)
12895 {
12896     char *constname = NULL;
12897     int found = TRUE;
12898     ScriptVariant v;
12899 
12900     if(paramCount < 1)
12901     {
12902         return 1;
12903     }
12904 
12905     if(varlist[0]->vt == VT_STR)
12906     {
12907         ScriptVariant_Init(&v);
12908         ScriptVariant_ChangeType(&v, VT_INTEGER);
12909         constname = (char *)StrCache_Get(varlist[0]->strVal);
12910 
12911         IICMPCONST(COMPATIBLEVERSION)
12912         ICMPCONST(DIRECTION_LEFT)
12913         ICMPCONST(DIRECTION_RIGHT)
12914         ICMPCONST(DIRECTION_ADJUST_LEFT)
12915         ICMPCONST(DIRECTION_ADJUST_NONE)
12916         ICMPCONST(DIRECTION_ADJUST_OPPOSITE)
12917         ICMPCONST(DIRECTION_ADJUST_RIGHT)
12918         ICMPCONST(DIRECTION_ADJUST_SAME)
12919         ICMPCONST(VT_EMPTY)
12920         ICMPCONST(VT_STR)
12921         ICMPCONST(VT_INTEGER)
12922         ICMPCONST(VT_DECIMAL)
12923         ICMPCONST(VT_PTR)
12924         ICMPCONST(MIN_INT)
12925         ICMPCONST(MAX_INT)
12926         ICMPCONST(PIXEL_8)
12927         ICMPCONST(PIXEL_x8)
12928         ICMPCONST(PIXEL_16)
12929         ICMPCONST(PIXEL_32)
12930         ICMPCONST(CV_SAVED_GAME)
12931         ICMPCONST(CV_HIGH_SCORE)
12932         ICMPCONST(THINK_SPEED)
12933         ICMPCONST(COUNTER_SPEED)
12934         ICMPCONST(MAX_ENTS)
12935         ICMPCONST(MAX_NAME_LEN)
12936         ICMPCONST(MAX_SPECIALS)
12937         ICMPCONST(MAX_ATCHAIN)
12938         ICMPCONST(MAX_ATTACKS)
12939         ICMPCONST(MAX_FOLLOWS)
12940         ICMPCONST(MAX_PLAYERS)
12941         ICMPCONST(MAX_ARG_LEN)
12942         ICMPCONST(FLAG_ESC)
12943         ICMPCONST(FLAG_START)
12944         ICMPCONST(FLAG_MOVELEFT)
12945         ICMPCONST(FLAG_MOVERIGHT)
12946         ICMPCONST(FLAG_MOVEUP)
12947         ICMPCONST(FLAG_MOVEDOWN)
12948         ICMPCONST(FLAG_ATTACK)
12949         ICMPCONST(FLAG_ATTACK2)
12950         ICMPCONST(FLAG_ATTACK3)
12951         ICMPCONST(FLAG_ATTACK4)
12952         ICMPCONST(FLAG_JUMP)
12953         ICMPCONST(FLAG_SPECIAL)
12954         ICMPCONST(FLAG_SCREENSHOT)
12955         ICMPCONST(FLAG_ANYBUTTON)
12956         ICMPCONST(FLAG_FORWARD)
12957         ICMPCONST(FLAG_BACKWARD)
12958         ICMPCONST(SDID_MOVEUP)
12959         ICMPCONST(SDID_MOVEDOWN)
12960         ICMPCONST(SDID_MOVELEFT)
12961         ICMPCONST(SDID_MOVERIGHT)
12962         ICMPCONST(SDID_SPECIAL)
12963         ICMPCONST(SDID_ATTACK)
12964         ICMPCONST(SDID_ATTACK2)
12965         ICMPCONST(SDID_ATTACK3)
12966         ICMPCONST(SDID_ATTACK4)
12967         ICMPCONST(SDID_JUMP)
12968         ICMPCONST(SDID_START)
12969         ICMPCONST(SDID_SCREENSHOT)
12970         ICMPCONST(TYPE_NONE)
12971         ICMPCONST(TYPE_PLAYER)
12972         ICMPCONST(TYPE_ENEMY)
12973         ICMPCONST(TYPE_ITEM)
12974         ICMPCONST(TYPE_OBSTACLE)
12975         ICMPCONST(TYPE_STEAMER)
12976         ICMPCONST(TYPE_SHOT)
12977         ICMPCONST(TYPE_TRAP)
12978         ICMPCONST(TYPE_TEXTBOX)
12979         ICMPCONST(TYPE_ENDLEVEL)
12980         ICMPCONST(TYPE_NPC)
12981         ICMPCONST(TYPE_PANEL)
12982         ICMPCONST(TYPE_MAX)
12983         ICMPCONST(TYPE_RESERVED)
12984         ICMPCONST(SUBTYPE_NONE)
12985         ICMPCONST(SUBTYPE_BIKER)
12986         ICMPCONST(SUBTYPE_NOTGRAB)
12987         ICMPCONST(SUBTYPE_ARROW)
12988         ICMPCONST(SUBTYPE_BOOMERANG)
12989         ICMPCONST(SUBTYPE_TOUCH)
12990         ICMPCONST(SUBTYPE_WEAPON)
12991         ICMPCONST(SUBTYPE_NOSKIP)
12992         ICMPCONST(SUBTYPE_FLYDIE)
12993         ICMPCONST(SUBTYPE_BOTH)
12994         ICMPCONST(SUBTYPE_PROJECTILE)
12995         ICMPCONST(SUBTYPE_FOLLOW)
12996         ICMPCONST(SUBTYPE_CHASE)
12997         ICMPCONST(AIMOVE1_NORMAL)
12998         ICMPCONST(AIMOVE1_CHASE)
12999         ICMPCONST(AIMOVE1_CHASEZ)
13000         ICMPCONST(AIMOVE1_CHASEX)
13001         ICMPCONST(AIMOVE1_AVOID)
13002         ICMPCONST(AIMOVE1_AVOIDZ)
13003         ICMPCONST(AIMOVE1_AVOIDX)
13004         ICMPCONST(AIMOVE1_WANDER)
13005         ICMPCONST(AIMOVE1_NOMOVE)
13006         ICMPCONST(AIMOVE1_BIKER)
13007         ICMPCONST(AIMOVE1_STAR)
13008         ICMPCONST(AIMOVE1_ARROW)
13009         ICMPCONST(AIMOVE1_BOMB)
13010         ICMPCONST(AIMOVE1_BOOMERANG)
13011         ICMPCONST(AIMOVE2_NORMAL)
13012         ICMPCONST(AIMOVE2_IGNOREHOLES)
13013         ICMPCONST(AIMOVE2_NOTARGETIDLE)
13014         ICMPCONST(AIATTACK1_NORMAL)
13015         ICMPCONST(AIATTACK1_LONG)
13016         ICMPCONST(AIATTACK1_MELEE)
13017         ICMPCONST(AIATTACK1_NOATTACK)
13018         ICMPCONST(AIATTACK1_ALWAYS)
13019         ICMPCONST(AIATTACK2_NORMAL)
13020         ICMPCONST(AIATTACK2_DODGE)
13021         ICMPCONST(AIATTACK2_DODGEMOVE)
13022         ICMPCONST(FRONTPANEL_Z)
13023         ICMPCONST(HOLE_Z)
13024         ICMPCONST(NEONPANEL_Z)
13025         ICMPCONST(SHADOW_Z)
13026         ICMPCONST(SCREENPANEL_Z)
13027         ICMPCONST(PANEL_Z)
13028         ICMPCONST(MIRROR_Z)
13029         ICMPCONST(PIT_DEPTH)
13030         ICMPCONST(P2_STATS_DIST)
13031         ICMPCONST(CONTACT_DIST_H)
13032         ICMPCONST(CONTACT_DIST_V)
13033         ICMPCONST(GRAB_DIST)
13034         ICMPCONST(GRAB_STALL)
13035         ICMPCONST(ATK_NORMAL)
13036         ICMPCONST(ATK_NORMAL2)
13037         ICMPCONST(ATK_NORMAL3)
13038         ICMPCONST(ATK_NORMAL4)
13039         ICMPCONST(ATK_BLAST)
13040         ICMPCONST(ATK_BURN)
13041         ICMPCONST(ATK_FREEZE)
13042         ICMPCONST(ATK_SHOCK)
13043         ICMPCONST(ATK_STEAL)
13044         ICMPCONST(ATK_NORMAL5)
13045         ICMPCONST(ATK_NORMAL6)
13046         ICMPCONST(ATK_NORMAL7)
13047         ICMPCONST(ATK_NORMAL8)
13048         ICMPCONST(ATK_NORMAL9)
13049         ICMPCONST(ATK_NORMAL10)
13050         ICMPCONST(ATK_ITEM)
13051         ICMPCONST(ATK_LAND)
13052         ICMPCONST(ATK_PIT)
13053         ICMPCONST(ATK_LIFESPAN)
13054         ICMPCONST(ATK_TIMEOVER)
13055         ICMPCONST(SCROLL_RIGHT)
13056         ICMPCONST(SCROLL_DOWN)
13057         ICMPCONST(SCROLL_LEFT)
13058         ICMPCONST(SCROLL_UP)
13059         ICMPCONST(SCROLL_BOTH)
13060         ICMPCONST(SCROLL_LEFTRIGHT)
13061         ICMPCONST(SCROLL_RIGHTLEFT)
13062         ICMPCONST(SCROLL_INWARD)
13063         ICMPCONST(SCROLL_OUTWARD)
13064         ICMPCONST(SCROLL_INOUT)
13065         ICMPCONST(SCROLL_OUTIN)
13066         ICMPCONST(SCROLL_UPWARD)
13067         ICMPCONST(SCROLL_DOWNWARD)
13068         ICMPCONST(ANI_IDLE)
13069         ICMPCONST(ANI_WALK)
13070         ICMPCONST(ANI_JUMP)
13071         ICMPCONST(ANI_LAND)
13072         ICMPCONST(ANI_PAIN)
13073         ICMPCONST(ANI_FALL)
13074         ICMPCONST(ANI_RISE)
13075         ICMPCONST(ANI_UPPER)
13076         ICMPCONST(ANI_BLOCK)
13077         ICMPCONST(ANI_JUMPATTACK)
13078         ICMPCONST(ANI_JUMPATTACK2)
13079         ICMPCONST(ANI_GET)
13080         ICMPCONST(ANI_GRAB)
13081         ICMPCONST(ANI_GRABATTACK)
13082         ICMPCONST(ANI_GRABATTACK2)
13083         ICMPCONST(ANI_THROW)
13084         ICMPCONST(ANI_SPECIAL)
13085         ICMPCONST(ANI_SPAWN)
13086         ICMPCONST(ANI_DIE)
13087         ICMPCONST(ANI_PICK)
13088         ICMPCONST(ANI_JUMPATTACK3)
13089         ICMPCONST(ANI_UP)
13090         ICMPCONST(ANI_DOWN)
13091         ICMPCONST(ANI_SHOCK)
13092         ICMPCONST(ANI_BURN)
13093         ICMPCONST(ANI_SHOCKPAIN)
13094         ICMPCONST(ANI_BURNPAIN)
13095         ICMPCONST(ANI_GRABBED)
13096         ICMPCONST(ANI_SPECIAL2)
13097         ICMPCONST(ANI_RUN)
13098         ICMPCONST(ANI_RUNATTACK)
13099         ICMPCONST(ANI_RUNJUMPATTACK)
13100         ICMPCONST(ANI_ATTACKUP)
13101         ICMPCONST(ANI_ATTACKDOWN)
13102         ICMPCONST(ANI_ATTACKFORWARD)
13103         ICMPCONST(ANI_ATTACKBACKWARD)
13104         ICMPCONST(ANI_RISEATTACK)
13105         ICMPCONST(ANI_DODGE)
13106         ICMPCONST(ANI_ATTACKBOTH)
13107         ICMPCONST(ANI_GRABFORWARD)
13108         ICMPCONST(ANI_GRABFORWARD2)
13109         ICMPCONST(ANI_JUMPFORWARD)
13110         ICMPCONST(ANI_GRABDOWN)
13111         ICMPCONST(ANI_GRABDOWN2)
13112         ICMPCONST(ANI_GRABUP)
13113         ICMPCONST(ANI_GRABUP2)
13114         ICMPCONST(ANI_SELECT)
13115         ICMPCONST(ANI_DUCK)
13116         ICMPCONST(ANI_FAINT)
13117         ICMPCONST(ANI_CANT)
13118         ICMPCONST(ANI_THROWATTACK)
13119         ICMPCONST(ANI_CHARGEATTACK)
13120         ICMPCONST(ANI_JUMPCANT)
13121         ICMPCONST(ANI_JUMPSPECIAL)
13122         ICMPCONST(ANI_BURNDIE)
13123         ICMPCONST(ANI_SHOCKDIE)
13124         ICMPCONST(ANI_PAIN2)
13125         ICMPCONST(ANI_PAIN3)
13126         ICMPCONST(ANI_PAIN4)
13127         ICMPCONST(ANI_FALL2)
13128         ICMPCONST(ANI_FALL3)
13129         ICMPCONST(ANI_FALL4)
13130         ICMPCONST(ANI_DIE2)
13131         ICMPCONST(ANI_DIE3)
13132         ICMPCONST(ANI_DIE4)
13133         ICMPCONST(ANI_CHARGE)
13134         ICMPCONST(ANI_BACKWALK)
13135         ICMPCONST(ANI_SLEEP)
13136         ICMPCONST(ANI_PAIN5)
13137         ICMPCONST(ANI_PAIN6)
13138         ICMPCONST(ANI_PAIN7)
13139         ICMPCONST(ANI_PAIN8)
13140         ICMPCONST(ANI_PAIN9)
13141         ICMPCONST(ANI_PAIN10)
13142         ICMPCONST(ANI_FALL5)
13143         ICMPCONST(ANI_FALL6)
13144         ICMPCONST(ANI_FALL7)
13145         ICMPCONST(ANI_FALL8)
13146         ICMPCONST(ANI_FALL9)
13147         ICMPCONST(ANI_FALL10)
13148         ICMPCONST(ANI_DIE5)
13149         ICMPCONST(ANI_DIE6)
13150         ICMPCONST(ANI_DIE7)
13151         ICMPCONST(ANI_DIE8)
13152         ICMPCONST(ANI_DIE9)
13153         ICMPCONST(ANI_DIE10)
13154         ICMPCONST(ANI_TURN)
13155         ICMPCONST(ANI_RESPAWN)
13156         ICMPCONST(ANI_FORWARDJUMP)
13157         ICMPCONST(ANI_RUNJUMP)
13158         ICMPCONST(ANI_JUMPLAND)
13159         ICMPCONST(ANI_JUMPDELAY)
13160         ICMPCONST(ANI_HITWALL)
13161         ICMPCONST(ANI_GRABBACKWARD)
13162         ICMPCONST(ANI_GRABBACKWARD2)
13163         ICMPCONST(ANI_GRABWALK)
13164         ICMPCONST(ANI_GRABBEDWALK)
13165         ICMPCONST(ANI_GRABWALKUP)
13166         ICMPCONST(ANI_GRABBEDWALKUP)
13167         ICMPCONST(ANI_GRABWALKDOWN)
13168         ICMPCONST(ANI_GRABBEDWALKDOWN)
13169         ICMPCONST(ANI_GRABTURN)
13170         ICMPCONST(ANI_GRABBEDTURN)
13171         ICMPCONST(ANI_GRABBACKWALK)
13172         ICMPCONST(ANI_GRABBEDBACKWALK)
13173         ICMPCONST(ANI_SLIDE)
13174         ICMPCONST(ANI_RUNSLIDE)
13175         ICMPCONST(ANI_BLOCKPAIN)
13176         ICMPCONST(ANI_DUCKATTACK)
13177         ICMPCONST(MAX_ANIS)
13178         ICMPCONST(PLAYER_MIN_Z)
13179         ICMPCONST(PLAYER_MAX_Z)
13180         ICMPCONST(BGHEIGHT)
13181         ICMPCONST(MAX_WALL_HEIGHT)
13182         ICMPCONST(SAMPLE_GO)
13183         ICMPCONST(SAMPLE_BEAT)
13184         ICMPCONST(SAMPLE_BLOCK)
13185         ICMPCONST(SAMPLE_INDIRECT)
13186         ICMPCONST(SAMPLE_GET)
13187         ICMPCONST(SAMPLE_GET2)
13188         ICMPCONST(SAMPLE_FALL)
13189         ICMPCONST(SAMPLE_JUMP)
13190         ICMPCONST(SAMPLE_PUNCH)
13191         ICMPCONST(SAMPLE_1UP)
13192         ICMPCONST(SAMPLE_TIMEOVER)
13193         ICMPCONST(SAMPLE_BEEP)
13194         ICMPCONST(SAMPLE_BEEP2)
13195         ICMPCONST(SAMPLE_BIKE)
13196         ICMPCONST(ANI_RISE2)
13197         ICMPCONST(ANI_RISE3)
13198         ICMPCONST(ANI_RISE4)
13199         ICMPCONST(ANI_RISE5)
13200         ICMPCONST(ANI_RISE6)
13201         ICMPCONST(ANI_RISE7)
13202         ICMPCONST(ANI_RISE8)
13203         ICMPCONST(ANI_RISE9)
13204         ICMPCONST(ANI_RISE10)
13205         ICMPCONST(ANI_RISEB)
13206         ICMPCONST(ANI_RISES)
13207         ICMPCONST(ANI_BLOCKPAIN2)
13208         ICMPCONST(ANI_BLOCKPAIN3)
13209         ICMPCONST(ANI_BLOCKPAIN4)
13210         ICMPCONST(ANI_BLOCKPAIN5)
13211         ICMPCONST(ANI_BLOCKPAIN6)
13212         ICMPCONST(ANI_BLOCKPAIN7)
13213         ICMPCONST(ANI_BLOCKPAIN8)
13214         ICMPCONST(ANI_BLOCKPAIN9)
13215         ICMPCONST(ANI_BLOCKPAIN10)
13216         ICMPCONST(ANI_BLOCKPAINB)
13217         ICMPCONST(ANI_BLOCKPAINS)
13218         ICMPCONST(ANI_CHIPDEATH)
13219         ICMPCONST(ANI_GUARDBREAK)
13220         ICMPCONST(ANI_RISEATTACK2)
13221         ICMPCONST(ANI_RISEATTACK3)
13222         ICMPCONST(ANI_RISEATTACK4)
13223         ICMPCONST(ANI_RISEATTACK5)
13224         ICMPCONST(ANI_RISEATTACK6)
13225         ICMPCONST(ANI_RISEATTACK7)
13226         ICMPCONST(ANI_RISEATTACK8)
13227         ICMPCONST(ANI_RISEATTACK9)
13228         ICMPCONST(ANI_RISEATTACK10)
13229         ICMPCONST(ANI_RISEATTACKB)
13230         ICMPCONST(ANI_RISEATTACKS)
13231         ICMPCONST(ANI_SLIDE)
13232         ICMPCONST(ANI_RUNSLIDE)
13233         ICMPCONST(ANI_DUCKATTACK)
13234         ICMPCONST(ANI_WALKOFF)
13235         ICMPCONST(ANI_FREESPECIAL)
13236         ICMPCONST(ANI_ATTACK)
13237         ICMPCONST(ANI_BACKPAIN)
13238         ICMPCONST(ANI_BACKPAIN2)
13239         ICMPCONST(ANI_BACKPAIN3)
13240         ICMPCONST(ANI_BACKPAIN4)
13241         ICMPCONST(ANI_BACKPAIN5)
13242         ICMPCONST(ANI_BACKPAIN6)
13243         ICMPCONST(ANI_BACKPAIN7)
13244         ICMPCONST(ANI_BACKPAIN8)
13245         ICMPCONST(ANI_BACKPAIN9)
13246         ICMPCONST(ANI_BACKPAIN10)
13247         ICMPCONST(ANI_BACKFALL)
13248         ICMPCONST(ANI_BACKFALL2)
13249         ICMPCONST(ANI_BACKFALL3)
13250         ICMPCONST(ANI_BACKFALL4)
13251         ICMPCONST(ANI_BACKFALL5)
13252         ICMPCONST(ANI_BACKFALL6)
13253         ICMPCONST(ANI_BACKFALL7)
13254         ICMPCONST(ANI_BACKFALL8)
13255         ICMPCONST(ANI_BACKFALL9)
13256         ICMPCONST(ANI_BACKFALL10)
13257         ICMPCONST(ANI_BACKDIE)
13258         ICMPCONST(ANI_BACKDIE2)
13259         ICMPCONST(ANI_BACKDIE3)
13260         ICMPCONST(ANI_BACKDIE4)
13261         ICMPCONST(ANI_BACKDIE5)
13262         ICMPCONST(ANI_BACKDIE6)
13263         ICMPCONST(ANI_BACKDIE7)
13264         ICMPCONST(ANI_BACKDIE8)
13265         ICMPCONST(ANI_BACKDIE9)
13266         ICMPCONST(ANI_BACKDIE10)
13267         ICMPCONST(ANI_BACKRUN)
13268         ICMPCONST(ANI_HITOBSTACLE)
13269         ICMPCONST(ANI_HITPLATFORM)
13270         ICMPCONST(ANI_HITWALL)
13271         ICMPCONST(ANI_GETBOOMERANG)
13272         ICMPCONST(ANI_GETBOOMERANGINAIR)
13273 
13274 
13275         // for the extra animation ids
13276         ICMPSCONSTC(ATK_NORMAL)
13277         ICMPSCONSTA(ANI_DOWN, animdowns)
13278         ICMPSCONSTA(ANI_UP, animups)
13279         ICMPSCONSTA(ANI_BACKWALK, animbackwalks)
13280         ICMPSCONSTA(ANI_WALK, animwalks)
13281         ICMPSCONSTA(ANI_IDLE, animidles)
13282         ICMPSCONSTB(ANI_FALL, animfalls)
13283         ICMPSCONSTB(ANI_RISE, animrises)
13284         ICMPSCONSTB(ANI_RISEATTACK, animriseattacks)
13285         ICMPSCONSTB(ANI_PAIN, animpains)
13286         ICMPSCONSTB(ANI_DIE, animdies)
13287         ICMPSCONSTA(ANI_ATTACK, animattacks)
13288         ICMPSCONSTA(ANI_FOLLOW, animfollows)
13289         ICMPSCONSTA(ANI_FREESPECIAL, animspecials)
13290         ICMPSCONSTA(ANI_BACKPAIN, animbackpains)
13291         ICMPSCONSTA(ANI_BACKFALL, animbackfalls)
13292         ICMPSCONSTA(ANI_BACKDIE, animbackdies)
13293 
13294         // Animation properties.
13295         ICMPCONST(ANI_PROP_ANIMHITS)
13296         ICMPCONST(ANI_PROP_ANTIGRAV)
13297         ICMPCONST(ANI_PROP_ATTACK)
13298         ICMPCONST(ANI_PROP_COLLISIONONE)
13299         ICMPCONST(ANI_PROP_BODY_COLLISION)
13300         ICMPCONST(ANI_PROP_BOUNCE)
13301         ICMPCONST(ANI_PROP_CANCEL)
13302         ICMPCONST(ANI_PROP_CHARGETIME)
13303         ICMPCONST(ANI_PROP_COUNTERRANGE)
13304         ICMPCONST(ANI_PROP_DELAY)
13305         ICMPCONST(ANI_PROP_DRAWMETHODS)
13306         ICMPCONST(ANI_PROP_DROPFRAME)
13307         ICMPCONST(ANI_PROP_DROPV)
13308         ICMPCONST(ANI_PROP_ENERGYCOST)
13309         ICMPCONST(ANI_PROP_FLIPFRAME)
13310         ICMPCONST(ANI_PROP_FOLLOWUP)
13311         ICMPCONST(ANI_PROP_IDLE)
13312         ICMPCONST(ANI_PROP_INDEX)
13313         ICMPCONST(ANI_PROP_JUMPFRAME)
13314         ICMPCONST(ANI_PROP_LANDFRAME)
13315         ICMPCONST(ANI_PROP_LOOP)
13316         ICMPCONST(ANI_PROP_MODEL_INDEX)
13317         ICMPCONST(ANI_PROP_MOVE)
13318         ICMPCONST(ANI_PROP_NUMFRAMES)
13319         ICMPCONST(ANI_PROP_OFFSET)
13320         ICMPCONST(ANI_PROP_PLATFORM)
13321         ICMPCONST(ANI_PROP_PROJECTILE)
13322         ICMPCONST(ANI_PROP_QUAKEFRAME)
13323         ICMPCONST(ANI_PROP_RANGE)
13324         ICMPCONST(ANI_PROP_SHADOW)
13325         ICMPCONST(ANI_PROP_SIZE)
13326         ICMPCONST(ANI_PROP_SOUNDTOPLAY)
13327         ICMPCONST(ANI_PROP_SPAWNFRAME)
13328         ICMPCONST(ANI_PROP_SPRITE)
13329         ICMPCONST(ANI_PROP_SPRITEA)
13330         ICMPCONST(ANI_PROP_SUBENTITY)
13331         ICMPCONST(ANI_PROP_SUMMONFRAME)
13332         ICMPCONST(ANI_PROP_SYNC)
13333         ICMPCONST(ANI_PROP_UNSUMMONFRAME)
13334         ICMPCONST(ANI_PROP_VULNERABLE)
13335         ICMPCONST(ANI_PROP_WEAPONFRAME)
13336 
13337         // Attack properties
13338         ICMPCONST(ATTACK_PROP_BLOCK_COST)
13339         ICMPCONST(ATTACK_PROP_BLOCK_PENETRATE)
13340         ICMPCONST(ATTACK_PROP_COUNTER)
13341         ICMPCONST(ATTACK_PROP_DAMAGE_FORCE)
13342         ICMPCONST(ATTACK_PROP_DAMAGE_LAND_FORCE)
13343         ICMPCONST(ATTACK_PROP_DAMAGE_LAND_MODE)
13344         ICMPCONST(ATTACK_PROP_DAMAGE_LETHAL_DISABLE)
13345         ICMPCONST(ATTACK_PROP_DAMAGE_RECURSIVE_FORCE)
13346         ICMPCONST(ATTACK_PROP_DAMAGE_RECURSIVE_INDEX)
13347         ICMPCONST(ATTACK_PROP_DAMAGE_RECURSIVE_MODE)
13348         ICMPCONST(ATTACK_PROP_DAMAGE_RECURSIVE_TIME_RATE)
13349         ICMPCONST(ATTACK_PROP_DAMAGE_RECURSIVE_TIME_EXPIRE)
13350         ICMPCONST(ATTACK_PROP_DAMAGE_STEAL)
13351         ICMPCONST(ATTACK_PROP_DAMAGE_TYPE)
13352         ICMPCONST(ATTACK_PROP_EFFECT_BLOCK_FLASH)
13353         ICMPCONST(ATTACK_PROP_EFFECT_BLOCK_SOUND)
13354         ICMPCONST(ATTACK_PROP_EFFECT_HIT_FLASH)
13355         ICMPCONST(ATTACK_PROP_EFFECT_HIT_FLASH_DISABLE)
13356         ICMPCONST(ATTACK_PROP_EFFECT_HIT_SOUND)
13357         ICMPCONST(ATTACK_PROP_GROUND)
13358         ICMPCONST(ATTACK_PROP_MAP_INDEX)
13359         ICMPCONST(ATTACK_PROP_MAP_TIME)
13360         ICMPCONST(ATTACK_PROP_POSITION_X)
13361         ICMPCONST(ATTACK_PROP_POSITION_Y)
13362         ICMPCONST(ATTACK_PROP_REACTION_FALL_FORCE)
13363         ICMPCONST(ATTACK_PROP_REACTION_FALL_VELOCITY_X)
13364         ICMPCONST(ATTACK_PROP_REACTION_FALL_VELOCITY_Y)
13365         ICMPCONST(ATTACK_PROP_REACTION_FALL_VELOCITY_Z)
13366         ICMPCONST(ATTACK_PROP_REACTION_FREEZE_MODE)
13367         ICMPCONST(ATTACK_PROP_REACTION_FREEZE_TIME)
13368         ICMPCONST(ATTACK_PROP_REACTION_INVINCIBLE_TIME)
13369         ICMPCONST(ATTACK_PROP_REACTION_REPOSITION_DIRECTION)
13370         ICMPCONST(ATTACK_PROP_REACTION_REPOSITION_DISTANCE)
13371         ICMPCONST(ATTACK_PROP_REACTION_REPOSITION_MODE)
13372         ICMPCONST(ATTACK_PROP_REACTION_PAIN_SKIP)
13373         ICMPCONST(ATTACK_PROP_REACTION_PAUSE_TIME)
13374         ICMPCONST(ATTACK_PROP_SEAL_COST)
13375         ICMPCONST(ATTACK_PROP_SEAL_TIME)
13376         ICMPCONST(ATTACK_PROP_SIZE_X)
13377         ICMPCONST(ATTACK_PROP_SIZE_Y)
13378         ICMPCONST(ATTACK_PROP_SIZE_Z_1)
13379         ICMPCONST(ATTACK_PROP_SIZE_Z_2)
13380         ICMPCONST(ATTACK_PROP_STAYDOWN_RISE)
13381         ICMPCONST(ATTACK_PROP_STAYDOWN_RISEATTACK)
13382         ICMPCONST(ATTACK_PROP_TAG)
13383 
13384         // Body Collision (bbox) properties.
13385         ICMPCONST(BODY_COLLISION_PROP_DEFENSE)
13386         ICMPCONST(BODY_COLLISION_PROP_POSITION_X)
13387         ICMPCONST(BODY_COLLISION_PROP_POSISTION_Y)
13388         ICMPCONST(BODY_COLLISION_PROP_SIZE_X)
13389         ICMPCONST(BODY_COLLISION_PROP_SIZE_Y)
13390         ICMPCONST(BODY_COLLISION_PROP_SIZE_Z_1)
13391         ICMPCONST(BODY_COLLISION_PROP_SIZE_Z_2)
13392         ICMPCONST(BODY_COLLISION_PROP_TAG)
13393 
13394         // Porting
13395         ICMPCONST(PORTING_ANDROID)
13396         ICMPCONST(PORTING_DARWIN)
13397         ICMPCONST(PORTING_DREAMCAST)
13398         ICMPCONST(PORTING_GPX2)
13399         ICMPCONST(PORTING_LINUX)
13400         ICMPCONST(PORTING_OPENDINGUX)
13401         ICMPCONST(PORTING_PSP)
13402         ICMPCONST(PORTING_UNKNOWN)
13403         ICMPCONST(PORTING_WII)
13404         ICMPCONST(PORTING_WINDOWS)
13405         ICMPCONST(PORTING_WIZ)
13406         ICMPCONST(PORTING_XBOX)
13407 
13408         else
13409         {
13410             found = FALSE;
13411         }
13412 
13413         if(found)
13414         {
13415             ScriptVariant_Copy(varlist[0], &v);
13416         }
13417         else
13418         {
13419             ScriptVariant_Clear(&v);
13420             printf("Can't find openbor constant '%s' \n", constname);
13421         }
13422 
13423         return found;
13424     }
13425 
13426     return 1;
13427 }
13428 //openborconstant(constname);
13429 //translate a constant by string, used to retrieve a constant or macro of openbor
openbor_transconst(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13430 HRESULT openbor_transconst(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13431 {
13432     static char buf[128];
13433     if(paramCount < 1)
13434     {
13435         goto transconst_error;
13436     }
13437 
13438     //if(varlist[0]->vt == VT_INTEGER) printf("debug: mapstring for openborconstant works!\n");
13439 
13440     mapstrings_transconst(varlist, paramCount);
13441 
13442     if(varlist[0]->vt == VT_INTEGER) // return value already determined by mapstrings
13443     {
13444         ScriptVariant_Copy((*pretvar), varlist[0]);
13445         return S_OK;
13446     }
13447 
13448 transconst_error:
13449     ScriptVariant_ToString(varlist[0], buf);
13450     printf("Can't translate constant %s\n", buf);
13451     *pretvar = NULL;
13452     return E_FAIL;
13453 }
13454 
13455 //int rgbcolor(int r, int g, int b);
openbor_rgbcolor(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13456 HRESULT openbor_rgbcolor(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13457 {
13458     LONG r, g, b;
13459 
13460     if(paramCount != 3)
13461     {
13462         goto rgbcolor_error;
13463     }
13464     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &r)))
13465     {
13466         goto rgbcolor_error;    // decimal/integer value for red?
13467     }
13468     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &g)))
13469     {
13470         goto rgbcolor_error;    // decimal/integer value for green?
13471     }
13472     if(FAILED(ScriptVariant_IntegerValue(varlist[2], &b)))
13473     {
13474         goto rgbcolor_error;    // decimal/integer value for blue?
13475     }
13476 
13477     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13478     (*pretvar)->lVal = _makecolour(r, g, b);
13479     return S_OK;
13480 
13481 rgbcolor_error:
13482     *pretvar = NULL;
13483     return E_FAIL;
13484 }
13485 
13486 // ===== playerkeys =====
13487 enum playerkeys_enum
13488 {
13489     _pk_anybutton,
13490     _pk_attack,
13491     _pk_attack2,
13492     _pk_attack3,
13493     _pk_attack4,
13494     _pk_esc,
13495     _pk_jump,
13496     _pk_movedown,
13497     _pk_moveleft,
13498     _pk_moveright,
13499     _pk_moveup,
13500     _pk_screenshot,
13501     _pk_special,
13502     _pk_start,
13503     _pk_the_end,
13504 };
13505 
mapstrings_playerkeys(ScriptVariant ** varlist,int paramCount)13506 int mapstrings_playerkeys(ScriptVariant **varlist, int paramCount)
13507 {
13508     char *propname = NULL;
13509     int i, prop;
13510 
13511     static const char *proplist[] = // for args 2+
13512     {
13513         "anybutton",
13514         "attack",
13515         "attack2",
13516         "attack3",
13517         "attack4",
13518         "esc",
13519         "jump",
13520         "movedown",
13521         "moveleft",
13522         "moveright",
13523         "moveup",
13524         "screenshot",
13525         "special",
13526         "start",
13527     };
13528 
13529     for(i = 2; i < paramCount; i++)
13530     {
13531         MAPSTRINGS(varlist[i], proplist, _pk_the_end,
13532                    "Button name '%s' is not supported by playerkeys.");
13533     }
13534 
13535     return 1;
13536 }
13537 
13538 //playerkeys(playerindex, newkey?, key1, key2, ...);
openbor_playerkeys(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13539 HRESULT openbor_playerkeys(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13540 {
13541     LONG ltemp;
13542     int index, newkey;
13543     int i;
13544     u32 keys;
13545     ScriptVariant *arg = NULL;
13546 
13547     if(paramCount < 3)
13548     {
13549         *pretvar = NULL;
13550         return E_FAIL;
13551     }
13552 
13553     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13554     (*pretvar)->lVal = (LONG)1;
13555 
13556     mapstrings_playerkeys(varlist, paramCount);
13557 
13558     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &ltemp)))
13559     {
13560         index = 0;
13561     }
13562     else
13563     {
13564         index = (int)ltemp;
13565     }
13566 
13567     if(SUCCEEDED(ScriptVariant_IntegerValue((varlist[1]), &ltemp)))
13568     {
13569         newkey = (int)ltemp;
13570     }
13571     else
13572     {
13573         newkey = 0;
13574     }
13575 
13576     if(newkey == 1)
13577     {
13578         keys = player[index].newkeys;
13579     }
13580     else if(newkey == 2)
13581     {
13582         keys = player[index].releasekeys;
13583     }
13584     else
13585     {
13586         keys = player[index].keys;
13587     }
13588 
13589     for(i = 2; i < paramCount; i++)
13590     {
13591         arg = varlist[i];
13592         if(arg->vt == VT_INTEGER)
13593         {
13594             switch(arg->lVal)
13595             {
13596             case _pk_jump:
13597                 (*pretvar)->lVal = (LONG)(keys & FLAG_JUMP);
13598                 break;
13599             case _pk_attack:
13600                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK);
13601                 break;
13602             case _pk_attack2:
13603                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK2);
13604                 break;
13605             case _pk_attack3:
13606                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK3);
13607                 break;
13608             case _pk_attack4:
13609                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK4);
13610                 break;
13611             case _pk_special:
13612                 (*pretvar)->lVal = (LONG)(keys & FLAG_SPECIAL);
13613                 break;
13614             case _pk_esc:
13615                 (*pretvar)->lVal = (LONG)(keys & FLAG_ESC);
13616                 break;
13617             case _pk_start:
13618                 (*pretvar)->lVal = (LONG)(keys & FLAG_START);
13619                 break;
13620             case _pk_moveleft:
13621                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVELEFT);
13622                 break;
13623             case _pk_moveright:
13624                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVERIGHT);
13625                 break;
13626             case _pk_moveup:
13627                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVEUP);
13628                 break;
13629             case _pk_movedown:
13630                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVEDOWN);
13631                 break;
13632             case _pk_screenshot:
13633                 (*pretvar)->lVal = (LONG)(keys & FLAG_SCREENSHOT);
13634                 break;
13635             case _pk_anybutton:
13636                 (*pretvar)->lVal = (LONG)(keys & FLAG_ANYBUTTON);
13637                 break;
13638             default:
13639                 (*pretvar)->lVal = (LONG)0;
13640             }
13641         }
13642         else
13643         {
13644             (*pretvar)->lVal = (LONG)0;
13645         }
13646         if(!((*pretvar)->lVal))
13647         {
13648             break;
13649         }
13650     }
13651 
13652     return S_OK;
13653 }
13654 
13655 //playmusic(name, loop)
openbor_playmusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13656 HRESULT openbor_playmusic(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13657 {
13658     int loop = 0;
13659     LONG offset = 0;
13660     char *thename = NULL;
13661 
13662     *pretvar = NULL;
13663     if(paramCount < 1)
13664     {
13665         sound_close_music();
13666         return S_OK;
13667     }
13668     if(varlist[0]->vt != VT_STR)
13669     {
13670         //printf("");
13671         return E_FAIL;
13672     }
13673     thename = StrCache_Get(varlist[0]->strVal);
13674 
13675     if(paramCount > 1)
13676     {
13677         loop = (int)ScriptVariant_IsTrue(varlist[1]);
13678     }
13679 
13680     if(paramCount > 2)
13681     {
13682         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &offset)))
13683         {
13684             return E_FAIL;
13685         }
13686     }
13687 
13688 
13689     music(thename, loop, offset);
13690     return S_OK;
13691 }
13692 
13693 //fademusic(fade, name, loop, offset)
openbor_fademusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13694 HRESULT openbor_fademusic(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13695 {
13696     DOUBLE value = 0;
13697     LONG values[2] = {0, 0};
13698     *pretvar = NULL;
13699     if(paramCount < 1)
13700     {
13701         goto fademusic_error;
13702     }
13703     if(FAILED(ScriptVariant_DecimalValue(varlist[0], &value)))
13704     {
13705         goto fademusic_error;
13706     }
13707     musicfade[0] = value;
13708     musicfade[1] = (float)savedata.musicvol;
13709 
13710     if(paramCount == 4)
13711     {
13712         strncpy(musicname, StrCache_Get(varlist[1]->strVal), 128);
13713         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &values[0])))
13714         {
13715             goto fademusic_error;
13716         }
13717         if(FAILED(ScriptVariant_IntegerValue(varlist[3], &values[1])))
13718         {
13719             goto fademusic_error;
13720         }
13721         musicloop = values[0];
13722         musicoffset = values[1];
13723     }
13724     return S_OK;
13725 
13726 fademusic_error:
13727     printf("Function requires 1 value, with an optional 3 for music triggering: fademusic_error(float fade, char name, int loop, unsigned long offset)\n");
13728     return E_FAIL;
13729 }
13730 
13731 //setmusicvolume(left, right)
openbor_setmusicvolume(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13732 HRESULT openbor_setmusicvolume(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13733 {
13734     LONG channels[2];
13735 
13736     if(paramCount < 1)
13737     {
13738         return S_OK;
13739     }
13740 
13741     if(FAILED(ScriptVariant_IntegerValue(varlist[0], channels)))
13742     {
13743         goto setmusicvolume_error;
13744     }
13745 
13746     if(paramCount > 1)
13747     {
13748         if(FAILED(ScriptVariant_IntegerValue(varlist[1], channels + 1)))
13749         {
13750             goto setmusicvolume_error;
13751         }
13752     }
13753     else
13754     {
13755         channels[1] = channels[0];
13756     }
13757 
13758     sound_volume_music((int)channels[0], (int)channels[1]);
13759     return S_OK;
13760 
13761 setmusicvolume_error:
13762     printf("values must be integers: setmusicvolume(int left, (optional)int right)\n");
13763     return E_FAIL;
13764 }
13765 
13766 //setmusicvolume(left, right)
openbor_setmusictempo(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13767 HRESULT openbor_setmusictempo(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13768 {
13769     LONG new_tempo;
13770 
13771     if(paramCount < 1)
13772     {
13773         return S_OK;
13774     }
13775 
13776     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &new_tempo)))
13777     {
13778         return E_FAIL;
13779     }
13780 
13781     sound_music_tempo(new_tempo);
13782     return S_OK;
13783 }
13784 
13785 //pausemusic(togglr)
openbor_pausemusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13786 HRESULT openbor_pausemusic(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13787 {
13788     int pause = 0;
13789     if(paramCount < 1)
13790     {
13791         return S_OK;
13792     }
13793 
13794     pause = (int)ScriptVariant_IsTrue(varlist[0]);
13795 
13796     sound_pause_music(pause);
13797     return S_OK;
13798 }
13799 
13800 //pausesamples(toggle)
openbor_pausesamples(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13801 HRESULT openbor_pausesamples(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13802 {
13803     int pause = 0;
13804     if(paramCount < 1)
13805     {
13806         return S_OK;
13807     }
13808 
13809     pause = (int)ScriptVariant_IsTrue(varlist[0]);
13810 
13811     sound_pause_sample(pause);
13812     return S_OK;
13813 }
13814 
13815 //pausesample(toggle,channel)
openbor_pausesample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13816 HRESULT openbor_pausesample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13817 {
13818     int pause = 0, channel = 0;
13819     if(paramCount < 2)
13820     {
13821         return S_OK;
13822     }
13823 
13824     pause = (int)ScriptVariant_IsTrue(varlist[0]);
13825     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &channel)))
13826     {
13827         return S_OK;
13828     }
13829 
13830     sound_pause_single_sample(pause,channel);
13831     return S_OK;
13832 }
13833 
openbor_querychannel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13834 HRESULT openbor_querychannel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13835 {
13836     LONG ltemp;
13837     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
13838     {
13839         goto query_error;
13840     }
13841     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13842     (*pretvar)->lVal = sound_query_channel((int)ltemp);
13843 
13844     query_error:
13845     *pretvar = NULL;
13846     return E_FAIL;
13847 }
13848 
openbor_stopchannel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13849 HRESULT openbor_stopchannel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13850 {
13851     LONG ltemp;
13852     *pretvar = NULL;
13853     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
13854     {
13855         goto sc_error;
13856     }
13857     sound_stop_sample((int)ltemp);
13858 
13859     sc_error:
13860     return E_FAIL;
13861 }
13862 
13863 //isactivesample(channel): returns 1 is sample is active, returns 0 otherwise
openbor_isactivesample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13864 HRESULT openbor_isactivesample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13865 {
13866     LONG ltemp;
13867     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
13868     {
13869         goto error;
13870     }
13871     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13872     (*pretvar)->lVal = sound_is_active((int)ltemp);
13873 
13874     error:
13875     *pretvar = NULL;
13876     return E_FAIL;
13877 }
13878 
13879 //sampleid(channel): returns sample id in channel if sample is active, it returns -1 otherwise
openbor_sampleid(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13880 HRESULT openbor_sampleid(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13881 {
13882     LONG ltemp;
13883     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
13884     {
13885         goto error;
13886     }
13887     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13888     (*pretvar)->lVal = sound_id((int)ltemp);
13889 
13890     error:
13891     *pretvar = NULL;
13892     return E_FAIL;
13893 }
13894 
13895 //playsample(id, priority, lvolume, rvolume, speed, loop)
openbor_playsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13896 HRESULT openbor_playsample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13897 {
13898     int i, result;
13899     LONG value[6] = { -1, 0, savedata.effectvol, savedata.effectvol, 100, 0};
13900 
13901     for(i = 0; i < 6 && i < paramCount; i++)
13902     {
13903         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
13904         {
13905             goto playsample_error;
13906         }
13907     }
13908     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13909     if((int)value[5])
13910     {
13911         result = sound_loop_sample((int)value[0], (unsigned int)value[1], (int)value[2], (int)value[3], (unsigned int)value[4]);
13912     }
13913     else
13914     {
13915         result = sound_play_sample((int)value[0], (unsigned int)value[1], (int)value[2], (int)value[3], (unsigned int)value[4]);
13916     }
13917     (*pretvar)->lVal = (LONG)result;
13918     return S_OK;
13919 
13920 playsample_error:
13921     *pretvar = NULL;
13922     printf("Function requires 6 integer values: playsample(int id, unsigned int priority, int lvolume, int rvolume, unsigned int speed, int loop)\n");
13923     return E_FAIL;
13924 }
13925 
13926 // int loadsample(filename, log)
openbor_loadsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13927 HRESULT openbor_loadsample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13928 {
13929     int arg = 0;
13930 
13931     if(paramCount < 1)
13932     {
13933         goto loadsample_error;
13934     }
13935     if(varlist[0]->vt != VT_STR)
13936     {
13937         goto loadsample_error;
13938     }
13939 
13940     if(paramCount > 1)
13941     {
13942         if(varlist[1]->vt == VT_INTEGER)
13943         {
13944             arg = varlist[1]->lVal;
13945         }
13946         else
13947         {
13948             goto loadsample_error;
13949         }
13950     }
13951 
13952     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13953     (*pretvar)->lVal = (LONG)sound_load_sample(StrCache_Get(varlist[0]->strVal), packfile, arg);
13954     return S_OK;
13955 
13956 loadsample_error:
13957     printf("Function requires 1 string value and optional log value: loadsample(string {filename} integer {log})\n");
13958     *pretvar = NULL;
13959     return E_FAIL;
13960 }
13961 
13962 // void unloadsample(id)
openbor_unloadsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13963 HRESULT openbor_unloadsample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13964 {
13965     LONG id;
13966     *pretvar = NULL;
13967     if(paramCount != 1 )
13968     {
13969         goto unloadsample_error;
13970     }
13971 
13972     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &id)))
13973     {
13974         goto unloadsample_error;
13975     }
13976 
13977     sound_unload_sample((int)id);
13978     return S_OK;
13979 
13980 unloadsample_error:
13981     printf("Function requires 1 integer value: unloadsample(int id)\n");
13982     return E_FAIL;
13983 }
13984 
13985 //fadeout(type, speed);
openbor_fadeout(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13986 HRESULT openbor_fadeout(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13987 {
13988     LONG type;
13989     LONG speed;
13990     *pretvar = NULL;
13991     if(paramCount < 1 )
13992     {
13993         goto fade_out_error;
13994     }
13995 
13996     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &type)))
13997     {
13998         goto fade_out_error;
13999     }
14000     if(FAILED(ScriptVariant_IntegerValue((varlist[1]), &speed)))
14001 
14002     {
14003         fade_out((int)type, (int)speed);
14004     }
14005     return S_OK;
14006 
14007 fade_out_error:
14008     printf("Function requires 2 integer values: fade_out(int type, int speed)\n");
14009     return E_FAIL;
14010 }
14011 
14012 //changepalette(index);
openbor_changepalette(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14013 HRESULT openbor_changepalette(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14014 {
14015     LONG index;
14016 
14017     *pretvar = NULL;
14018 
14019     if(paramCount < 1)
14020     {
14021         goto changepalette_error;
14022     }
14023 
14024     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &index)))
14025     {
14026         goto changepalette_error;
14027     }
14028 
14029     change_system_palette((int)index);
14030 
14031     return S_OK;
14032 
14033 changepalette_error:
14034     printf("Function requires 1 integer value: changepalette(int index)\n");
14035     return E_FAIL;
14036 }
14037 
14038 //changelight(x, z);
openbor_changelight(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14039 HRESULT openbor_changelight(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14040 {
14041     LONG x, z;
14042     extern s_axis_i light;
14043     ScriptVariant *arg = NULL;
14044 
14045     *pretvar = NULL;
14046     if(paramCount < 2)
14047     {
14048         goto changelight_error;
14049     }
14050 
14051     arg = varlist[0];
14052     if(arg->vt != VT_EMPTY)
14053     {
14054         if(FAILED(ScriptVariant_IntegerValue(arg, &x)))
14055         {
14056             goto changelight_error;
14057         }
14058         light.x = (int)x;
14059     }
14060 
14061     arg = varlist[1];
14062     if(arg->vt != VT_EMPTY)
14063     {
14064         if(FAILED(ScriptVariant_IntegerValue(arg, &z)))
14065         {
14066             goto changelight_error;
14067         }
14068         light.y = (int)z;
14069     }
14070 
14071     return S_OK;
14072 changelight_error:
14073     printf("Function requires 2 integer values: changepalette(int x, int z)\n");
14074     return E_FAIL;
14075 }
14076 
14077 //changeshadowcolor(color, alpha);
14078 // color = 0 means no gfxshadow, -1 means don't fill the shadow with colour
14079 // alpha default to 2, <=0 means no alpha effect
openbor_changeshadowcolor(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14080 HRESULT openbor_changeshadowcolor(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14081 {
14082     LONG c, a;
14083     extern int            shadowcolor;
14084     extern int            shadowalpha;
14085 
14086     *pretvar = NULL;
14087     if(paramCount < 1)
14088     {
14089         goto changeshadowcolor_error;
14090     }
14091 
14092     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &c)))
14093     {
14094         goto changeshadowcolor_error;
14095     }
14096 
14097     shadowcolor = (int)c;
14098 
14099     if(paramCount > 1)
14100     {
14101         if(FAILED(ScriptVariant_IntegerValue(varlist[1], &a)))
14102         {
14103             goto changeshadowcolor_error;
14104         }
14105         shadowalpha = (int)a;
14106     }
14107 
14108     return S_OK;
14109 changeshadowcolor_error:
14110     printf("Function requires at least 1 integer value, the 2nd integer parameter is optional: changepalette(int colorindex, int alpha)\n");
14111     return E_FAIL;
14112 }
14113 
14114 // ===== gettextobjproperty(name, value) =====
14115 enum gtop_enum
14116 {
14117     _top_a,
14118     _top_font,
14119     _top_text,
14120     _top_time,
14121     _top_x,
14122     _top_y,
14123     _top_z,
14124     _top_the_end,
14125 };
14126 
mapstrings_textobjproperty(ScriptVariant ** varlist,int paramCount)14127 int mapstrings_textobjproperty(ScriptVariant **varlist, int paramCount)
14128 {
14129     char *propname = NULL;
14130     int prop;
14131 
14132     static const char *proplist[] =
14133     {
14134         "a",
14135         "font",
14136         "text",
14137         "time",
14138         "x",
14139         "y",
14140         "z",
14141     };
14142 
14143     if(paramCount < 2)
14144     {
14145         return 1;
14146     }
14147 
14148     MAPSTRINGS(varlist[1], proplist, _top_the_end,
14149                "'%s' is not a valid textobj property.\n");
14150 
14151     return 1;
14152 }
14153 
openbor_gettextobjproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14154 HRESULT openbor_gettextobjproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14155 {
14156     LONG ind;
14157     int propind;
14158 
14159     if(paramCount < 2)
14160     {
14161         goto gettextobjproperty_error;
14162     }
14163 
14164 
14165     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
14166     {
14167         printf("Function's 1st argument must be a numeric value: gettextproperty(int index, \"property\")\n");
14168         goto gettextobjproperty_error;
14169     }
14170 
14171     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14172     mapstrings_textobjproperty(varlist, paramCount);
14173 
14174     if(ind < 0 || ind >= level->numtextobjs)
14175     {
14176         (*pretvar)->lVal = 0;
14177         return S_OK;
14178     }
14179 
14180     if(varlist[1]->vt != VT_INTEGER)
14181     {
14182         if(varlist[1]->vt != VT_STR)
14183         {
14184             printf("Function gettextobjproperty must have a string property name.\n");
14185         }
14186         goto gettextobjproperty_error;
14187     }
14188 
14189     propind = varlist[1]->lVal;
14190 
14191     switch(propind)
14192     {
14193     case _top_font:
14194     {
14195         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14196         (*pretvar)->lVal = (LONG)level->textobjs[ind].font;
14197         break;
14198     }
14199     case _top_text:
14200     {
14201         ScriptVariant_ChangeType(*pretvar, VT_STR);
14202         StrCache_Copy((*pretvar)->strVal, level->textobjs[ind].text);
14203         break;
14204     }
14205     case _top_time:
14206     {
14207         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14208         (*pretvar)->lVal = (LONG)level->textobjs[ind].time;
14209         break;
14210     }
14211     case _top_x:
14212     {
14213         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14214         (*pretvar)->lVal = (LONG)level->textobjs[ind].position.x;
14215         break;
14216     }
14217     case _top_y:
14218     case _top_a:
14219     {
14220         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14221         (*pretvar)->lVal = (LONG)level->textobjs[ind].position.y;
14222         break;
14223     }
14224     case _top_z:
14225     {
14226         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14227         (*pretvar)->lVal = (LONG)level->textobjs[ind].position.z;
14228         break;
14229     }
14230     default:
14231         //printf("Property name '%s' is not supported by function gettextobjproperty.\n", propname);
14232         goto gettextobjproperty_error;
14233         break;
14234     }
14235 
14236     return S_OK;
14237 
14238 gettextobjproperty_error:
14239     *pretvar = NULL;
14240     return E_FAIL;
14241 }
14242 
openbor_changetextobjproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14243 HRESULT openbor_changetextobjproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14244 {
14245     LONG ind;
14246     int propind;
14247     static char buf[MAX_STR_VAR_LEN];
14248     LONG ltemp;
14249     const char *ctotext = "changetextobjproperty(int index, \"property\", value)";
14250 
14251     *pretvar = NULL;
14252 
14253     if(paramCount < 3)
14254     {
14255         printf("Function needs at last 3 parameters: %s\n", ctotext);
14256         return E_FAIL;
14257     }
14258 
14259     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
14260     {
14261         printf("Function's 1st argument must be a numeric value: %s\n", ctotext);
14262         return E_FAIL;
14263     }
14264 
14265     mapstrings_textobjproperty(varlist, paramCount);
14266 
14267     if(ind < 0)
14268     {
14269         printf("Invalid textobj index, must be >= 0\n");
14270         return E_FAIL;
14271     }
14272     else if (ind >= level->numtextobjs)
14273     {
14274         __reallocto(level->textobjs, level->numtextobjs, ind + 1);
14275         level->numtextobjs = ind + 1;
14276     }
14277 
14278     if(varlist[1]->vt != VT_INTEGER)
14279     {
14280         printf("Invalid property type for changetextobjproperty.\n");
14281         return E_FAIL;
14282     }
14283 
14284     propind = varlist[1]->lVal;
14285 
14286     switch(propind)
14287     {
14288     case _top_font:
14289     {
14290         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
14291         {
14292             level->textobjs[ind].font = (int)ltemp;
14293         }
14294         else
14295         {
14296             goto changetextobjproperty_error;
14297         }
14298         break;
14299     }
14300     case _top_text:
14301     {
14302         ScriptVariant_ToString(varlist[2], buf);
14303         level->textobjs[ind].text = malloc(MAX_STR_VAR_LEN);
14304         strncpy(level->textobjs[ind].text, buf, MAX_STR_VAR_LEN);
14305         break;
14306     }
14307     case _top_time:
14308     {
14309         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
14310         {
14311             level->textobjs[ind].time = (int)ltemp;
14312         }
14313         else
14314         {
14315             goto changetextobjproperty_error;
14316         }
14317         break;
14318     }
14319     case _top_x:
14320     {
14321         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
14322         {
14323             level->textobjs[ind].position.x = (int)ltemp;
14324         }
14325         else
14326         {
14327             goto changetextobjproperty_error;
14328         }
14329         break;
14330     }
14331     case _top_a:
14332     case _top_y:
14333     {
14334         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
14335         {
14336             level->textobjs[ind].position.y = (int)ltemp;
14337         }
14338         else
14339         {
14340             goto changetextobjproperty_error;
14341         }
14342         break;
14343     }
14344     case _top_z:
14345     {
14346         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
14347         {
14348             level->textobjs[ind].position.z = (int)ltemp;
14349         }
14350         else
14351         {
14352             goto changetextobjproperty_error;
14353         }
14354         break;
14355     }
14356     default:
14357         //printf("Property name '%s' is not supported by function changetextobjproperty.\n", propname);
14358         return E_FAIL;
14359         break;
14360     }
14361 
14362     return S_OK;
14363 
14364 changetextobjproperty_error:
14365     ScriptVariant_ToString(varlist[2], buf);
14366     printf("Invalid textobj value: %s\n", buf);
14367     return E_FAIL;
14368 }
14369 
14370 // settextobj(int index, int x, int y, int font, int z, char text, int time {optional})
openbor_settextobj(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14371 HRESULT openbor_settextobj(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14372 {
14373     LONG ind;
14374     LONG X, Y, Z, F, T = 0;
14375     static char buf[MAX_STR_VAR_LEN];
14376     const char *stotext = "settextobj(int index, int x, int y, int font, int z, char text, int time {optional})";
14377 
14378     *pretvar = NULL;
14379 
14380 
14381     if(paramCount < 6)
14382     {
14383         printf("Function needs at least 6 parameters: %s\n", stotext);
14384         return E_FAIL;
14385     }
14386 
14387     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
14388     {
14389         printf("Function's 1st argument must be a numeric value: %s\n", stotext);
14390         return E_FAIL;
14391     }
14392 
14393     if(ind < 0)
14394     {
14395         printf("Invalid textobj index, must be >= 0\n");
14396         return E_FAIL;
14397     }
14398     else if(ind >= level->numtextobjs)
14399     {
14400         __reallocto(level->textobjs, level->numtextobjs, ind + 1);
14401         level->numtextobjs = ind + 1;
14402     }
14403 
14404     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &X)))
14405     {
14406         goto settextobj_error;
14407     }
14408     if(FAILED(ScriptVariant_IntegerValue(varlist[2], &Y)))
14409     {
14410         goto settextobj_error;
14411     }
14412     if(FAILED(ScriptVariant_IntegerValue(varlist[3], &F)))
14413     {
14414         goto settextobj_error;
14415     }
14416     if(FAILED(ScriptVariant_IntegerValue(varlist[4], &Z)))
14417     {
14418         goto settextobj_error;
14419     }
14420     ScriptVariant_ToString(varlist[5], buf);
14421     if(paramCount >= 7 && FAILED(ScriptVariant_IntegerValue(varlist[6], &T)))
14422     {
14423         goto settextobj_error;
14424     }
14425 
14426     level->textobjs[ind].time = (int)T;
14427     level->textobjs[ind].position.x = (int)X;
14428     level->textobjs[ind].position.y = (int)Y;
14429     level->textobjs[ind].position.z = (int)Z;
14430     level->textobjs[ind].font = (int)F;
14431 
14432     if(!level->textobjs[ind].text)
14433     {
14434         level->textobjs[ind].text = (char *)malloc(MAX_STR_VAR_LEN);
14435     }
14436     strncpy(level->textobjs[ind].text, buf, MAX_STR_VAR_LEN);
14437 
14438     return S_OK;
14439 
14440 settextobj_error:
14441     printf("Invalid value(s) for settextobj: %s\n", stotext);
14442     return E_FAIL;
14443 }
14444 
openbor_cleartextobj(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14445 HRESULT openbor_cleartextobj(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14446 {
14447     LONG ind;
14448     const char *cltotext = "cleartextobj(int index)";
14449 
14450     *pretvar = NULL;
14451 
14452     if(paramCount < 1)
14453     {
14454         printf("Function needs at least 1 parameter: %s\n", cltotext);
14455         return E_FAIL;
14456     }
14457 
14458     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
14459     {
14460         printf("Function's 1st argument must be a numeric value: %s\n", cltotext);
14461         return E_FAIL;
14462     }
14463 
14464     if(ind < 0 || ind >= level->numtextobjs)
14465     {
14466         return S_OK;
14467     }
14468 
14469     level->textobjs[ind].time = 0;
14470     level->textobjs[ind].position.x = 0;
14471     level->textobjs[ind].position.y = 0;
14472     level->textobjs[ind].font = 0;
14473     level->textobjs[ind].position.z = 0;
14474     if(level->textobjs[ind].text)
14475     {
14476         free(level->textobjs[ind].text);
14477     }
14478     level->textobjs[ind].text = NULL;
14479     return S_OK;
14480 }
14481 
14482 // ===== get layer type ======
14483 enum getlt_enum
14484 {
14485     _glt_background,
14486     _glt_bglayer,
14487     _glt_fglayer,
14488     _glt_frontpanel,
14489     _glt_generic,
14490     _glt_neon,
14491     _glt_panel,
14492     _glt_screen,
14493     _glt_water,
14494     _glt_the_end,
14495 };
14496 
14497 
14498 // ===== getbglayerproperty ======
14499 enum getbglp_enum
14500 {
14501     _glp_alpha,
14502     _glp_amplitude,
14503     _glp_bgspeedratio,
14504     _glp_enabled,
14505     _glp_neon,
14506     _glp_quake,
14507     _glp_transparency,
14508     _glp_watermode,
14509     _glp_wavelength,
14510     _glp_wavespeed,
14511     _glp_xoffset,
14512     _glp_xratio,
14513     _glp_xrepeat,
14514     _glp_xspacing,
14515     _glp_z,
14516     _glp_zoffset,
14517     _glp_zratio,
14518     _glp_zrepeat,
14519     _glp_zspacing,
14520     _glp_the_end,
14521 };
14522 
mapstrings_layerproperty(ScriptVariant ** varlist,int paramCount)14523 int mapstrings_layerproperty(ScriptVariant **varlist, int paramCount)
14524 {
14525     char *propname = NULL;
14526     int prop;
14527 
14528     static const char *proplist[] =
14529     {
14530         "alpha",
14531         "amplitude",
14532         "bgspeedratio",
14533         "enabled",
14534         "neon",
14535         "quake",
14536         "transparency",
14537         "watermode",
14538         "wavelength",
14539         "wavespeed",
14540         "xoffset",
14541         "xratio",
14542         "xrepeat",
14543         "xspacing",
14544         "z",
14545         "zoffset",
14546         "zratio",
14547         "zrepeat",
14548         "zspacing",
14549     };
14550 
14551     static const char *typelist[] =
14552     {
14553         "background",
14554         "bglayer",
14555         "fglayer",
14556         "frontpanel",
14557         "generic",
14558         "neon",
14559         "panel",
14560         "water",
14561     };
14562 
14563     if(paramCount < 3)
14564     {
14565         return 1;
14566     }
14567     MAPSTRINGS(varlist[0], typelist, _glt_the_end,
14568                "Type name '%s' is not supported by function getlayerproperty.\n");
14569     MAPSTRINGS(varlist[2], proplist, _glp_the_end,
14570                "Property name '%s' is not supported by function getlayerproperty.\n");
14571 
14572     return 1;
14573 }
14574 
_getlayerproperty(s_layer * layer,int propind,ScriptVariant ** pretvar)14575 HRESULT _getlayerproperty(s_layer *layer, int propind, ScriptVariant **pretvar)
14576 {
14577 
14578     switch(propind)
14579     {
14580     case _glp_alpha:
14581     {
14582         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14583         (*pretvar)->lVal = (LONG)layer->drawmethod.alpha;
14584         break;
14585     }
14586     case _glp_amplitude:
14587     {
14588         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14589         (*pretvar)->lVal = (LONG)layer->drawmethod.water.amplitude;
14590         break;
14591     }
14592     case _glp_bgspeedratio:
14593     {
14594         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
14595         (*pretvar)->dblVal = (DOUBLE)layer->bgspeedratio;
14596         break;
14597     }
14598     case _glp_enabled:
14599     {
14600         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14601         (*pretvar)->lVal = (LONG)layer->enabled;
14602         break;
14603     }
14604     case _glp_neon:
14605     {
14606         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14607         (*pretvar)->lVal = (LONG)layer->neon;
14608         break;
14609     }
14610     case _glp_quake:
14611     {
14612         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14613         (*pretvar)->lVal = (LONG)layer->quake;
14614         break;
14615     }
14616     case _glp_transparency:
14617     {
14618         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14619         (*pretvar)->lVal = (LONG)layer->drawmethod.transbg;
14620         break;
14621     }
14622     case _glp_watermode:
14623     {
14624         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14625         (*pretvar)->lVal = (LONG)layer->drawmethod.water.watermode;
14626         break;
14627     }
14628 
14629     case _glp_wavelength:
14630     {
14631         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14632         (*pretvar)->lVal = (LONG)layer->drawmethod.water.wavelength;
14633         break;
14634     }
14635     case _glp_wavespeed:
14636     {
14637         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
14638         (*pretvar)->dblVal = (DOUBLE)layer->drawmethod.water.wavespeed;
14639         break;
14640     }
14641     case _glp_xoffset:
14642     {
14643         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14644         (*pretvar)->lVal = (LONG)layer->offset.x;
14645         break;
14646     }
14647     case _glp_xratio:
14648     {
14649         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
14650         (*pretvar)->dblVal = (DOUBLE)layer->ratio.x;
14651         break;
14652     }
14653     case _glp_xrepeat:
14654     {
14655         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14656         (*pretvar)->lVal = (LONG)layer->drawmethod.xrepeat;
14657         break;
14658     }
14659     case _glp_xspacing:
14660     {
14661         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14662         (*pretvar)->lVal = (LONG)layer->spacing.x;
14663         break;
14664     }
14665     case _glp_z:
14666     {
14667         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14668         (*pretvar)->lVal = (LONG)layer->z;
14669         break;
14670     }
14671     case _glp_zoffset:
14672     {
14673         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14674         (*pretvar)->lVal = (LONG)layer->offset.z;
14675         break;
14676     }
14677     case _glp_zratio:
14678     {
14679         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
14680         (*pretvar)->dblVal = (DOUBLE)layer->ratio.z;
14681         break;
14682     }
14683     case _glp_zrepeat:
14684     {
14685         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14686         (*pretvar)->lVal = (LONG)layer->drawmethod.yrepeat;
14687         break;
14688     }
14689     case _glp_zspacing:
14690     {
14691         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14692         (*pretvar)->lVal = (LONG)layer->spacing.z;
14693         break;
14694     }
14695     default:
14696         *pretvar = NULL;
14697         return E_FAIL;
14698     }
14699     return S_OK;
14700 }
14701 
_changelayerproperty(s_layer * layer,int propind,ScriptVariant * var)14702 HRESULT _changelayerproperty(s_layer *layer, int propind, ScriptVariant *var)
14703 {
14704     LONG temp;
14705     DOUBLE temp2;
14706     switch(propind)
14707     {
14708     case _glp_alpha:
14709     {
14710         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14711         {
14712             return E_FAIL;
14713         }
14714         layer->drawmethod.alpha = temp;
14715         break;
14716     }
14717     case _glp_amplitude:
14718     {
14719         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14720         {
14721             return E_FAIL;
14722         }
14723         layer->drawmethod.water.amplitude = temp;
14724         break;
14725     }
14726     case _glp_bgspeedratio:
14727     {
14728         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
14729         {
14730             return E_FAIL;
14731         }
14732         layer->bgspeedratio = temp2;
14733         break;
14734     }
14735     case _glp_enabled:
14736     {
14737         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14738         {
14739             return E_FAIL;
14740         }
14741         layer->enabled = temp;
14742         break;
14743     }
14744     case _glp_neon:
14745     {
14746         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14747         {
14748             return E_FAIL;
14749         }
14750         layer->neon = temp;
14751         break;
14752     }
14753     case _glp_quake:
14754     {
14755         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14756         {
14757             return E_FAIL;
14758         }
14759         layer->quake = temp;
14760         break;
14761     }
14762     case _glp_transparency:
14763     {
14764         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14765         {
14766             return E_FAIL;
14767         }
14768         layer->drawmethod.transbg = temp;
14769         break;
14770     }
14771     case _glp_watermode:
14772     {
14773         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14774         {
14775             return E_FAIL;
14776         }
14777         layer->drawmethod.water.watermode = temp;
14778         break;
14779     }
14780 
14781     case _glp_wavelength:
14782     {
14783         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
14784         {
14785             return E_FAIL;
14786         }
14787         layer->drawmethod.water.wavelength = temp2;
14788         break;
14789     }
14790     case _glp_wavespeed:
14791     {
14792         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
14793         {
14794             return E_FAIL;
14795         }
14796         layer->drawmethod.water.wavespeed = temp2;
14797         break;
14798     }
14799     case _glp_xoffset:
14800     {
14801         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14802         {
14803             return E_FAIL;
14804         }
14805         layer->offset.x = temp;
14806         break;
14807     }
14808     case _glp_xratio:
14809     {
14810         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
14811         {
14812             return E_FAIL;
14813         }
14814         layer->ratio.x = temp2;
14815         break;
14816     }
14817     case _glp_xrepeat:
14818     {
14819         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14820         {
14821             return E_FAIL;
14822         }
14823         layer->drawmethod.xrepeat = temp;
14824         break;
14825     }
14826     case _glp_xspacing:
14827     {
14828         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14829         {
14830             return E_FAIL;
14831         }
14832         layer->spacing.x = temp;
14833         break;
14834     }
14835     case _glp_z:
14836     {
14837         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14838         {
14839             return E_FAIL;
14840         }
14841         layer->z = temp;
14842         break;
14843     }
14844     case _glp_zoffset:
14845     {
14846         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14847         {
14848             return E_FAIL;
14849         }
14850         layer->offset.z = temp;
14851         break;
14852     }
14853     case _glp_zratio:
14854     {
14855         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
14856         {
14857             return E_FAIL;
14858         }
14859         layer->ratio.z = temp2;
14860         break;
14861     }
14862     case _glp_zrepeat:
14863     {
14864         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14865         {
14866             return E_FAIL;
14867         }
14868         layer->drawmethod.yrepeat = temp;
14869         break;
14870     }
14871     case _glp_zspacing:
14872     {
14873         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
14874         {
14875             return E_FAIL;
14876         }
14877         layer->spacing.z = temp;
14878         break;
14879     }
14880     default:
14881         return E_FAIL;
14882     }
14883     return S_OK;
14884 }
14885 
_getlayer(int type,int ind)14886 s_layer *_getlayer(int type, int ind)
14887 {
14888     switch(type)
14889     {
14890     case _glt_background:
14891         return level->background;
14892     case _glt_bglayer:
14893         if(ind < 0 || ind >= level->numbglayers)
14894         {
14895             return NULL;
14896         }
14897         return level->bglayers[ind];
14898     case _glt_fglayer:
14899         if(ind < 0 || ind >= level->numfglayers)
14900         {
14901             return NULL;
14902         }
14903         return level->fglayers[ind];
14904     case _glt_frontpanel:
14905         if(ind < 0 || ind >= level->numfrontpanels)
14906         {
14907             return NULL;
14908         }
14909         return level->frontpanels[ind];
14910     case _glt_generic:
14911         if(ind < 0 || ind >= level->numgenericlayers)
14912         {
14913             return NULL;
14914         }
14915         return level->genericlayers[ind];
14916     case _glt_neon:
14917         if(ind < 0 || ind >= level->numpanels)
14918         {
14919             return NULL;
14920         }
14921         return level->panels[ind][1];
14922     case _glt_panel:
14923         if(ind < 0 || ind >= level->numpanels)
14924         {
14925             return NULL;
14926         }
14927         return level->panels[ind][0];
14928     case _glt_screen:
14929         if(ind < 0 || ind >= level->numpanels)
14930         {
14931             return NULL;
14932         }
14933         return level->panels[ind][2];
14934     case _glt_water:
14935         if(ind < 0 || ind >= level->numwaters)
14936         {
14937             return NULL;
14938         }
14939         return level->waters[ind];
14940     default:
14941         return NULL;
14942     }
14943 }
14944 
14945 // getlayerproperty(type, index, propertyname);
openbor_getlayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14946 HRESULT openbor_getlayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14947 {
14948     LONG ind;
14949     int propind, type;
14950     s_layer *layer = NULL;
14951 
14952     if(paramCount < 3)
14953     {
14954         goto getlayerproperty_error;
14955     }
14956 
14957     mapstrings_layerproperty(varlist, paramCount);
14958 
14959     type = varlist[0]->lVal;
14960     propind = varlist[2]->lVal;
14961 
14962     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
14963     {
14964         goto getlayerproperty_error2;
14965     }
14966 
14967     layer = _getlayer(type, (int)ind);
14968 
14969     if(layer == NULL)
14970     {
14971         goto getlayerproperty_error2;
14972     }
14973 
14974     if(FAILED(_getlayerproperty(layer, propind, pretvar)))
14975     {
14976         goto getlayerproperty_error3;
14977     }
14978 
14979     return S_OK;
14980 
14981 getlayerproperty_error:
14982     *pretvar = NULL;
14983     printf("Function getlayerproperty must have 3 parameters: layertype, index and propertyname\n");
14984     return E_FAIL;
14985 getlayerproperty_error2:
14986     *pretvar = NULL;
14987     printf("Layer not found!\n");
14988     return E_FAIL;
14989 getlayerproperty_error3:
14990     *pretvar = NULL;
14991     printf("Bad property name or value.\n");
14992     return E_FAIL;
14993 }
14994 
14995 // changelayerproperty(type, index, propertyname);
openbor_changelayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14996 HRESULT openbor_changelayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14997 {
14998     LONG ind;
14999     int propind, type;
15000     s_layer *layer = NULL;
15001     *pretvar = NULL;
15002 
15003     if(paramCount < 4)
15004     {
15005         goto chglayerproperty_error;
15006     }
15007 
15008     mapstrings_layerproperty(varlist, paramCount);
15009 
15010     type = varlist[0]->lVal;
15011     propind = varlist[2]->lVal;
15012 
15013     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
15014     {
15015         goto chglayerproperty_error2;
15016     }
15017 
15018     layer = _getlayer(type, (int)ind);
15019 
15020     if(layer == NULL)
15021     {
15022         goto chglayerproperty_error2;
15023     }
15024 
15025     if(FAILED(_changelayerproperty(layer, propind, varlist[3])))
15026     {
15027         goto chglayerproperty_error3;
15028     }
15029 
15030     return S_OK;
15031 
15032 chglayerproperty_error:
15033     printf("Function changelayerproperty must have 4 parameters: layertype, index, propertyname and value\n");
15034     return E_FAIL;
15035 chglayerproperty_error2:
15036     printf("Layer not found!\n");
15037     return E_FAIL;
15038 chglayerproperty_error3:
15039     printf("Layer property not understood or bad value.\n");
15040     return E_FAIL;
15041 }
15042 
15043 
15044 // ===== level properties ======
15045 enum levelproperty_enum
15046 {
15047     _lp_basemap,
15048     _lp_bgspeed,
15049     _lp_cameraxoffset,
15050     _lp_camerazoffset,
15051     _lp_gravity,
15052     _lp_hole,
15053     _lp_maxfallspeed,
15054     _lp_maxtossspeed,
15055     _lp_quake,
15056     _lp_rocking,
15057     _lp_scrollspeed,
15058     _lp_type,
15059     _lp_vbgspeed,
15060     _lp_wall,
15061     _lp_the_end,
15062 };
15063 
15064 enum basemap_enum
15065 {
15066     _lp_bm_map,
15067     _lp_bm_x,
15068     _lp_bm_xsize,
15069     _lp_bm_z,
15070     _lp_bm_zsize,
15071     _lp_bm_the_end,
15072 };
15073 
15074 enum terrain_enum
15075 {
15076     _lp_terrain_depth,
15077     _lp_terrain_height,
15078     _lp_terrain_lowerleft,
15079     _lp_terrain_lowerright,
15080     _lp_terrain_type,
15081     _lp_terrain_upperleft,
15082     _lp_terrain_upperright,
15083     _lp_terrain_x,
15084     _lp_terrain_z,
15085     _lp_terrain_the_end,
15086 };
15087 
mapstrings_levelproperty(ScriptVariant ** varlist,int paramCount)15088 int mapstrings_levelproperty(ScriptVariant **varlist, int paramCount)
15089 {
15090     char *propname = NULL;
15091     int prop;
15092 
15093     static const char *proplist[] =
15094     {
15095         "basemap",
15096         "bgspeed",
15097         "cameraxoffset",
15098         "camerazoffset",
15099         "gravity",
15100         "hole",
15101         "maxfallspeed",
15102         "maxtossspeed",
15103         "quake",
15104         "rocking",
15105         "scrollspeed",
15106         "type",
15107         "vbgspeed",
15108         "wall",
15109     };
15110 
15111     static const char *basemaplist[] =
15112     {
15113         "map",
15114         "x",
15115         "xsize",
15116         "z",
15117         "zsize",
15118     };
15119 
15120     static const char *terrainlist[] =
15121     {
15122         /*
15123         Walls and holes.
15124         */
15125 
15126         "depth",
15127         "height",
15128         "lowerleft",
15129         "lowerright",
15130         "type",
15131         "upperleft",
15132         "upperright",
15133         "x",
15134         "z",
15135     };
15136 
15137     if(paramCount < 1)
15138     {
15139         return 1;
15140     }
15141     MAPSTRINGS(varlist[0], proplist, _lp_the_end,
15142                "Level property '%s' is not supported.\n");
15143 
15144     if(paramCount >= 3 && varlist[0]->vt == VT_INTEGER && varlist[0]->lVal == _lp_basemap)
15145     {
15146         MAPSTRINGS(varlist[2], basemaplist, _lp_bm_the_end,
15147                    _is_not_supported_by_, "basemap");
15148     }
15149 
15150     if(paramCount >= 3 && varlist[0]->vt == VT_INTEGER && (varlist[0]->lVal == _lp_hole || varlist[0]->lVal == _lp_wall))
15151     {
15152         MAPSTRINGS(varlist[2], terrainlist, _lp_terrain_the_end,
15153                    _is_not_supported_by_, "wall/hole");
15154     }
15155 
15156     return 1;
15157 }
15158 
openbor_getlevelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15159 HRESULT openbor_getlevelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15160 {
15161     LONG ltemp;
15162     DOUBLE dbltemp2, dbltemp3;
15163     mapstrings_levelproperty(varlist, paramCount);
15164 
15165     switch(varlist[0]->lVal)
15166     {
15167     case _lp_bgspeed:
15168     {
15169         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15170         (*pretvar)->lVal = (DOUBLE)level->bgspeed;
15171         break;
15172     }
15173     case _lp_vbgspeed:
15174     {
15175         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15176         (*pretvar)->lVal = (DOUBLE)level->vbgspeed;
15177         break;
15178     }
15179     case _lp_cameraxoffset:
15180     {
15181         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15182         (*pretvar)->lVal = (LONG)level->cameraxoffset;
15183         break;
15184     }
15185     case _lp_camerazoffset:
15186     {
15187         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15188         (*pretvar)->lVal = (LONG)level->camerazoffset;
15189         break;
15190     }
15191     case _lp_gravity:
15192     {
15193         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15194         (*pretvar)->dblVal = (DOUBLE)level->gravity;
15195         break;
15196     }
15197     case _lp_maxfallspeed:
15198     {
15199         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15200         (*pretvar)->dblVal = (DOUBLE)level->maxfallspeed;
15201         break;
15202     }
15203     case _lp_maxtossspeed:
15204     {
15205         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15206         (*pretvar)->dblVal = (DOUBLE)level->maxtossspeed;
15207         break;
15208     }
15209     case _lp_quake:
15210     {
15211         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15212         (*pretvar)->lVal = (LONG)level->quake;
15213         break;
15214     }
15215     case _lp_scrollspeed:
15216     {
15217         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15218         (*pretvar)->dblVal = (DOUBLE)level->scrollspeed;
15219         break;
15220     }
15221     case _lp_type:
15222     {
15223         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15224         (*pretvar)->lVal = (LONG)level->type;
15225         break;
15226     }
15227     case _lp_hole:
15228     {
15229 
15230         if(paramCount > 2 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp))
15231                 && ltemp >= 0 && ltemp < level->numholes)
15232         {
15233 
15234             if(varlist[2]->vt != VT_STR)
15235                 printf("You must provide a string value for hole subproperty.\n");
15236                 goto getlevelproperty_error;
15237 
15238             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15239 
15240             switch(varlist[2]->lVal)
15241             {
15242                 case _lp_terrain_height:
15243                 {
15244                     (*pretvar)->dblVal = level->holes[ltemp].height;
15245                     break;
15246                 }
15247                 case _lp_terrain_depth:
15248                 {
15249                     (*pretvar)->dblVal = level->holes[ltemp].depth;
15250                     break;
15251                 }
15252                 case _lp_terrain_lowerleft:
15253                 {
15254                     (*pretvar)->dblVal = level->holes[ltemp].lowerleft;
15255                     break;
15256                 }
15257                 case _lp_terrain_lowerright:
15258                 {
15259                     (*pretvar)->dblVal = level->holes[ltemp].lowerright;
15260                     break;
15261                 }
15262                 case _lp_terrain_upperleft:
15263                 {
15264                     (*pretvar)->dblVal = level->holes[ltemp].upperleft;
15265                     break;
15266                 }
15267                 case _lp_terrain_upperright:
15268                 {
15269                     (*pretvar)->dblVal = level->holes[ltemp].upperright;
15270                     break;
15271                 }
15272                 case _lp_terrain_x:
15273                 {
15274                     (*pretvar)->dblVal = level->holes[ltemp].x;
15275                     break;
15276                 }
15277                 case _lp_terrain_z:
15278                 {
15279                     (*pretvar)->dblVal = level->holes[ltemp].z;
15280                     break;
15281                 }
15282                 case _lp_terrain_type:
15283                 {
15284                     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15285                     (*pretvar)->lVal = level->holes[ltemp].type;
15286                     break;
15287                 }
15288                 default:
15289                 {
15290                     printf("Invalid subproperty for hole.\n");
15291                     goto getlevelproperty_error;
15292                 }
15293             }
15294         }
15295         else
15296         {
15297             printf("Error in wall property.\n");
15298             goto getlevelproperty_error;
15299         }
15300         break;
15301 
15302     }
15303     case _lp_wall:
15304     {
15305         if(paramCount > 2 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp))
15306                 && ltemp >= 0 && ltemp < level->numwalls)
15307         {
15308 
15309             if(varlist[2]->vt != VT_STR)
15310                 printf("You must provide a string value for wall subproperty.\n");
15311                 goto getlevelproperty_error;
15312 
15313             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15314 
15315             switch(varlist[2]->lVal)
15316             {
15317                 case _lp_terrain_depth:
15318                 {
15319                     (*pretvar)->dblVal = level->walls[ltemp].depth;
15320                     break;
15321                 }
15322                 case _lp_terrain_height:
15323                 {
15324                     (*pretvar)->dblVal = level->walls[ltemp].height;
15325                     break;
15326                 }
15327                 case _lp_terrain_lowerleft:
15328                 {
15329                     (*pretvar)->dblVal = level->walls[ltemp].lowerleft;
15330                     break;
15331                 }
15332                 case _lp_terrain_lowerright:
15333                 {
15334                     (*pretvar)->dblVal = level->walls[ltemp].lowerright;
15335                     break;
15336                 }
15337                 case _lp_terrain_upperleft:
15338                 {
15339                     (*pretvar)->dblVal = level->walls[ltemp].upperleft;
15340                     break;
15341                 }
15342                 case _lp_terrain_upperright:
15343                 {
15344                     (*pretvar)->dblVal = level->walls[ltemp].upperright;
15345                     break;
15346                 }
15347                 case _lp_terrain_x:
15348                 {
15349                     (*pretvar)->dblVal = level->walls[ltemp].x;
15350                     break;
15351                 }
15352                 case _lp_terrain_z:
15353                 {
15354                     (*pretvar)->dblVal = level->walls[ltemp].z;
15355                     break;
15356                 }
15357                 case _lp_terrain_type:
15358                 {
15359                     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15360                     (*pretvar)->lVal = level->walls[ltemp].type;
15361                     break;
15362                 }
15363                 default:
15364                 {
15365                     printf("Invalid subproperty for wall.\n");
15366                     goto getlevelproperty_error;
15367                 }
15368             }
15369         }
15370         else
15371         {
15372             printf("Error in wall property.\n");
15373             goto getlevelproperty_error;
15374         }
15375         break;
15376     }
15377     case _lp_basemap:
15378         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0 && ltemp < level->numbasemaps)
15379         {
15380             if(paramCount >= 3)
15381             {
15382 
15383                 if(varlist[2]->vt != VT_STR)
15384                     printf("You must provide a string value for basemap subproperty.\n");
15385                     goto getlevelproperty_error;
15386 
15387                 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
15388 
15389                 switch(varlist[2]->lVal)
15390                 {
15391                 case _lp_bm_x:
15392                     (*pretvar)->dblVal = level->basemaps[ltemp].position.x;
15393                     break;
15394                 case _lp_bm_xsize:
15395                     (*pretvar)->dblVal = level->basemaps[ltemp].size.x;
15396                     break;
15397                 case _lp_bm_z:
15398                     (*pretvar)->dblVal = level->basemaps[ltemp].position.z;
15399                     break;
15400                 case _lp_bm_zsize:
15401                     (*pretvar)->dblVal = level->basemaps[ltemp].size.z;
15402                     break;
15403                 case _lp_bm_map:
15404                     if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) &&
15405                             SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp3)) &&
15406                             dbltemp2 >= 0 && dbltemp2 < level->basemaps[ltemp].size.x && dbltemp3 >= 0 && dbltemp3 < level->basemaps[ltemp].size.z
15407                       )
15408                     {
15409                         if(!level->basemaps[ltemp].map)
15410                         {
15411                             (*pretvar)->dblVal = (DOUBLE)0;
15412                         }
15413                         else (*pretvar)->dblVal = (DOUBLE)level->basemaps[ltemp].map[(LONG)(dbltemp2 + dbltemp3 * level->basemaps[ltemp].size.x)];
15414                     }
15415                     else
15416                     {
15417                         goto getlevelproperty_error;
15418                     }
15419                     break;
15420                 default:
15421                     goto getlevelproperty_error;
15422                 }
15423             }
15424             else
15425             {
15426                 goto getlevelproperty_error;
15427             }
15428         }
15429         else
15430         {
15431             goto getlevelproperty_error;
15432         }
15433         break;
15434     default:
15435         printf("Property is not supported by function getlevelproperty yet. %d\n", varlist[0]->lVal);
15436         goto getlevelproperty_error;
15437         break;
15438     }
15439 
15440     return S_OK;
15441 
15442 getlevelproperty_error:
15443     *pretvar = NULL;
15444     return E_FAIL;
15445 }
15446 
15447 //changelevelproperty(name, value)
openbor_changelevelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15448 HRESULT openbor_changelevelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15449 {
15450     LONG ltemp, ltemp1;
15451     DOUBLE dbltemp, dbltemp2, dbltemp3;
15452     static char buf[64];
15453     int i;
15454     ScriptVariant *arg = NULL;
15455 
15456     *pretvar = NULL;
15457 
15458     if(paramCount < 2)
15459     {
15460         printf("Function changelevelproperty(prop, value) need at least 2 parameters.\n");
15461         return E_FAIL;
15462     }
15463 
15464     mapstrings_levelproperty(varlist, paramCount);
15465 
15466     arg = varlist[1];
15467 
15468     switch(varlist[0]->lVal)
15469     {
15470     case _lp_rocking:
15471         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
15472         {
15473             level->rocking = (int)ltemp;
15474         }
15475         else
15476         {
15477             goto clperror;
15478         }
15479         break;
15480     case _lp_bgspeed:
15481         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
15482         {
15483             level->bgspeed = (float)dbltemp;
15484         }
15485         else
15486         {
15487             goto clperror;
15488         }
15489         break;
15490     case _lp_vbgspeed:
15491         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
15492         {
15493             level->vbgspeed = (float)dbltemp;
15494         }
15495         else
15496         {
15497             goto clperror;
15498         }
15499         break;
15500     case _lp_scrollspeed:
15501         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
15502         {
15503             level->scrollspeed = (float)dbltemp;
15504         }
15505         else
15506         {
15507             goto clperror;
15508         }
15509         break;
15510     case _lp_type:
15511         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
15512         {
15513             level->type = (int)ltemp;
15514         }
15515         else
15516         {
15517             goto clperror;
15518         }
15519         break;
15520     case _lp_cameraxoffset:
15521         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
15522         {
15523             level->cameraxoffset = (int)ltemp;
15524         }
15525         else
15526         {
15527             goto clperror;
15528         }
15529         break;
15530     case _lp_camerazoffset:
15531         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
15532         {
15533             level->camerazoffset = (int)ltemp;
15534         }
15535         else
15536         {
15537             goto clperror;
15538         }
15539         break;
15540     case _lp_gravity:
15541         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
15542         {
15543             level->gravity = (float)dbltemp;
15544         }
15545         else
15546         {
15547             goto clperror;
15548         }
15549         break;
15550     case _lp_maxfallspeed:
15551         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
15552         {
15553             level->maxfallspeed = (float)dbltemp;
15554         }
15555         else
15556         {
15557             goto clperror;
15558         }
15559         break;
15560     case _lp_maxtossspeed:
15561         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
15562         {
15563             level->maxtossspeed = (float)dbltemp;
15564         }
15565         else
15566         {
15567             goto clperror;
15568         }
15569         break;
15570     case _lp_quake:
15571         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
15572         {
15573             level->quake = (int)ltemp;
15574         }
15575         else
15576         {
15577             goto clperror;
15578         }
15579         break;
15580     case _lp_basemap:
15581         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0)
15582         {
15583             if(ltemp >= level->numbasemaps)
15584             {
15585                 __reallocto(level->basemaps, level->numbasemaps, ltemp + 1);
15586                 level->numbasemaps = ltemp + 1;
15587             }
15588             if(paramCount >= 4)
15589             {
15590                 switch(varlist[2]->lVal)
15591                 {
15592                 case _lp_bm_x:
15593                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
15594                     {
15595                         level->basemaps[ltemp].position.x = dbltemp2;
15596                     }
15597                     else
15598                     {
15599                         goto clperror;
15600                     }
15601                     break;
15602                 case _lp_bm_xsize:
15603                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
15604                     {
15605                         level->basemaps[ltemp].size.x = dbltemp2;
15606                     }
15607                     else
15608                     {
15609                         goto clperror;
15610                     }
15611                     break;
15612                 case _lp_bm_z:
15613                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
15614                     {
15615                         level->basemaps[ltemp].position.z = dbltemp2;
15616                     }
15617                     else
15618                     {
15619                         goto clperror;
15620                     }
15621                     break;
15622                 case _lp_bm_zsize:
15623                     if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) )
15624                     {
15625                         level->basemaps[ltemp].size.z = dbltemp2;
15626                     }
15627                     else
15628                     {
15629                         goto clperror;
15630                     }
15631                     break;
15632                 case _lp_bm_map:
15633                     if(paramCount >= 6 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp2)) &&
15634                             SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp3)) &&
15635                             SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)) &&
15636                             dbltemp2 >= 0 && dbltemp2 < level->basemaps[ltemp].size.x && dbltemp3 >= 0 && dbltemp3 < level->basemaps[ltemp].size.z
15637                       )
15638                     {
15639                         if(!level->basemaps[ltemp].map)
15640                         {
15641                             level->basemaps[ltemp].map = calloc( 1, (LONG)(sizeof(*(level->basemaps[ltemp].map)) * (level->basemaps[ltemp].size.x+1)*(level->basemaps[ltemp].size.z+1)) );
15642                         }
15643                         level->basemaps[ltemp].map[(LONG)(dbltemp2 + dbltemp3 * level->basemaps[ltemp].size.x)] = (float)dbltemp;
15644                     }
15645                     else
15646                     {
15647                         goto clperror;
15648                     }
15649                     break;
15650                 default:
15651                     goto clperror;
15652                 }
15653             }
15654             else
15655             {
15656                 goto clperror;
15657             }
15658         }
15659         else
15660         {
15661             goto clperror;
15662         }
15663         break;
15664     case _lp_hole:
15665     {
15666         if( SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0
15667            && ( SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)) || SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp1)) ) )
15668         {
15669             if(varlist[2]->vt != VT_STR)
15670                 printf("You must provide a string value for hole subproperty.\n");
15671                 goto clperror;
15672 
15673             if(ltemp >= level->numholes)
15674             {
15675                 __reallocto(level->holes, level->numholes, ltemp + 1);
15676                 level->numholes = ltemp + 1;
15677             }
15678 
15679             switch(varlist[2]->lVal)
15680             {
15681                 case _lp_terrain_height:
15682                 {
15683                     level->holes[ltemp].height = dbltemp;
15684                     break;
15685                 }
15686                 case _lp_terrain_depth:
15687                 {
15688                     level->holes[ltemp].depth = dbltemp;
15689                     break;
15690                 }
15691                 case _lp_terrain_lowerleft:
15692                 {
15693                     level->holes[ltemp].lowerleft = dbltemp;
15694                     break;
15695                 }
15696                 case _lp_terrain_lowerright:
15697                 {
15698                     level->holes[ltemp].lowerright = dbltemp;
15699                     break;
15700                 }
15701                 case _lp_terrain_upperleft:
15702                 {
15703                     level->holes[ltemp].upperleft = dbltemp;
15704                     break;
15705                 }
15706                 case _lp_terrain_upperright:
15707                 {
15708                     level->holes[ltemp].upperright = dbltemp;
15709                     break;
15710                 }
15711                 case _lp_terrain_x:
15712                 {
15713                     level->holes[ltemp].x = dbltemp;
15714                     break;
15715                 }
15716                 case _lp_terrain_z:
15717                 {
15718                     level->holes[ltemp].z = dbltemp;
15719                     break;
15720                 }
15721                 case _lp_terrain_type:
15722                 {
15723                     level->holes[ltemp].type = ltemp1;
15724                     break;
15725                 }
15726                 default:
15727                 {
15728                     printf("Invalid subproperty for hole.\n");
15729                     goto clperror;
15730                 }
15731             }
15732         }
15733         else
15734         {
15735             goto clperror;
15736         }
15737         break;
15738 
15739     }
15740     case _lp_wall:
15741     {
15742         if( SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)) && ltemp >= 0
15743            && ( SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)) || SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp1)) ) )
15744         {
15745             if(varlist[2]->vt != VT_STR)
15746                 printf("You must provide a string value for wall subproperty.\n");
15747                 goto clperror;
15748 
15749             if(ltemp >= level->numwalls)
15750             {
15751                 __reallocto(level->walls, level->numwalls, ltemp + 1);
15752                 level->numwalls = ltemp + 1;
15753             }
15754 
15755             switch(varlist[2]->lVal)
15756             {
15757                 case _lp_terrain_depth:
15758                 {
15759                     level->walls[ltemp].depth = dbltemp;
15760                     break;
15761                 }
15762                 case _lp_terrain_height:
15763                 {
15764                     level->walls[ltemp].height = dbltemp;
15765                     break;
15766                 }
15767                 case _lp_terrain_lowerleft:
15768                 {
15769                     level->walls[ltemp].lowerleft = dbltemp;
15770                     break;
15771                 }
15772                 case _lp_terrain_lowerright:
15773                 {
15774                     level->walls[ltemp].lowerright = dbltemp;
15775                     break;
15776                 }
15777                 case _lp_terrain_upperleft:
15778                 {
15779                     level->walls[ltemp].upperleft = dbltemp;
15780                     break;
15781                 }
15782                 case _lp_terrain_upperright:
15783                 {
15784                     level->walls[ltemp].upperright = dbltemp;
15785                     break;
15786                 }
15787                 case _lp_terrain_x:
15788                 {
15789                     level->walls[ltemp].x = dbltemp;
15790                     break;
15791                 }
15792                 case _lp_terrain_z:
15793                 {
15794                     level->walls[ltemp].z = dbltemp;
15795                     break;
15796                 }
15797                 case _lp_terrain_type:
15798                 {
15799                     level->walls[ltemp].type = ltemp1;
15800                     break;
15801                 }
15802                 default:
15803                 {
15804                     printf("Invalid subproperty for wall.\n");
15805                     goto clperror;
15806                 }
15807             }
15808         }
15809         else
15810         {
15811             goto clperror;
15812         }
15813         break;
15814     }
15815     default:
15816         printf("Invalid or read-only level property.\n");
15817         return E_FAIL;
15818         break;
15819     }
15820 
15821     return S_OK;
15822 clperror:
15823     printf("Function changelevelproperty(prop, value) received invalid value(s). \n");
15824     printf("Dumping values: ");
15825     for(i = 1; i < paramCount; i++)
15826     {
15827         ScriptVariant_ToString(varlist[i], buf);
15828         printf("%s, ", buf);
15829     }
15830     printf("\n");
15831     return E_FAIL;
15832 }
15833 
15834 
15835 //shutdown(status, message)
openbor_shutdown(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15836 HRESULT openbor_shutdown(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15837 {
15838     LONG ltemp = 0;
15839 
15840     *pretvar = NULL;
15841 
15842     if(paramCount > 0 && FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
15843     {
15844         goto shutdown_error;
15845     }
15846     if(paramCount > 1 && varlist[1]->vt != VT_STR)
15847     {
15848         goto shutdown_error;
15849     }
15850 
15851     shutdown((int)ltemp,  paramCount > 1 ? StrCache_Get(varlist[1]->strVal) : (DEFAULT_SHUTDOWN_MESSAGE));
15852 
15853     return S_OK;
15854 shutdown_error:
15855     printf("shutdown(status, message): both parameters are optional but must be valid.\n");
15856     return E_FAIL;
15857 }
15858 
15859 //jumptobranch(name, immediate)
openbor_jumptobranch(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15860 HRESULT openbor_jumptobranch(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15861 {
15862     LONG ltemp;
15863     extern char branch_name[MAX_NAME_LEN + 1];
15864     *pretvar = NULL;
15865     if(paramCount < 1)
15866     {
15867         goto jumptobranch_error;
15868     }
15869     if(varlist[0]->vt != VT_STR)
15870     {
15871         goto jumptobranch_error;
15872     }
15873 
15874     strncpy(branch_name, StrCache_Get(varlist[0]->strVal), MIN(MAX_NAME_LEN, MAX_STR_VAR_LEN)); // copy the string value to branch name
15875 
15876     if(paramCount >= 2)
15877     {
15878         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
15879         {
15880             endgame = (int)ltemp;
15881             // 1 means goto that level immediately, or, wait until the level is complete
15882         }
15883         else
15884         {
15885             goto jumptobranch_error;
15886         }
15887     }
15888 
15889     return S_OK;
15890 jumptobranch_error:
15891     printf("Function requires 1 string value, the second argument is optional(int): jumptobranch(name, immediate)\n");
15892     return E_FAIL;
15893 }
15894 
15895 //bindentity(entity, target, x, z, a, direction, binding.ani_bind);
15896 //bindentity(entity, NULL()); // unbind
openbor_bindentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15897 HRESULT openbor_bindentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15898 {
15899     entity *ent = NULL;
15900     entity *other = NULL;
15901     ScriptVariant *arg = NULL;
15902     void adjust_bind(entity * e);
15903     LONG x = 0, z = 0, a = 0, dir = 0, anim = 0, sortid = -1;
15904 
15905     *pretvar = NULL;
15906     if(paramCount < 2)
15907     {
15908         return E_FAIL;
15909     }
15910 
15911     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
15912     if(!ent)
15913     {
15914         return S_OK;
15915     }
15916 
15917     other = (entity *)(varlist[1])->ptrVal;
15918     if(!other)
15919     {
15920         ent->binding.ent = NULL;
15921         ent->binding.offset_flag.x = 0;
15922         ent->binding.offset_flag.z = 0;
15923         ent->binding.offset_flag.y = 0;
15924         return S_OK;
15925     }
15926 
15927     ent->binding.ent = other;
15928     ent->binding.sortid = sortid;
15929 
15930     if(paramCount < 3)
15931     {
15932         goto BIND;
15933     }
15934     // x
15935     arg = varlist[2];
15936     if(arg->vt != VT_EMPTY)
15937     {
15938         if(FAILED(ScriptVariant_IntegerValue(arg, &x)))
15939         {
15940             return E_FAIL;
15941         }
15942 
15943         ent->binding.offset.x = (int)x;
15944         ent->binding.offset_flag.x = 1;
15945     } else ent->binding.offset_flag.x = 0;
15946     if(paramCount < 4)
15947     {
15948         goto BIND;
15949     }
15950     // z
15951     arg = varlist[3];
15952     if(arg->vt != VT_EMPTY)
15953     {
15954         if(FAILED(ScriptVariant_IntegerValue(arg, &z)))
15955         {
15956             return E_FAIL;
15957         }
15958         ent->binding.offset.z = (int)z;
15959         ent->binding.offset_flag.z = 1;
15960     } else ent->binding.offset_flag.z = 0;
15961     if(paramCount < 5)
15962     {
15963         goto BIND;
15964     }
15965     // a
15966     arg = varlist[4];
15967     if(arg->vt != VT_EMPTY)
15968     {
15969         if(FAILED(ScriptVariant_IntegerValue(arg, &a)))
15970         {
15971             return E_FAIL;
15972         }
15973         ent->binding.offset.y = (int)a;
15974         ent->binding.offset_flag.y = 1;
15975     } else ent->binding.offset_flag.y = 0;
15976     if(paramCount < 6)
15977     {
15978         goto BIND;
15979     }
15980     // direction
15981     arg = varlist[5];
15982     if(arg->vt != VT_EMPTY)
15983     {
15984         if(FAILED(ScriptVariant_IntegerValue(arg, &dir)))
15985         {
15986             return E_FAIL;
15987         }
15988         ent->binding.direction = (int)dir;
15989     }
15990     if(paramCount < 7)
15991     {
15992         goto BIND;
15993     }
15994     // animation
15995     arg = varlist[6];
15996     if(arg->vt != VT_EMPTY)
15997     {
15998         if(FAILED(ScriptVariant_IntegerValue(arg, &anim)))
15999         {
16000             return E_FAIL;
16001         }
16002         ent->binding.ani_bind = (int)anim;
16003     }
16004     if(paramCount < 8)
16005     {
16006         goto BIND;
16007     }
16008     // sortid
16009     arg = varlist[7];
16010     if(arg->vt != VT_EMPTY)
16011     {
16012         if(FAILED(ScriptVariant_IntegerValue(arg, &sortid)))
16013         {
16014             return E_FAIL;
16015         }
16016         ent->binding.sortid = (int)sortid;
16017     }
16018 
16019 BIND:
16020     adjust_bind(ent);
16021 
16022     return S_OK;
16023 }
16024 
16025 //array(size);
openbor_array(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16026 HRESULT openbor_array(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16027 {
16028     LONG size;
16029     Varlist *array;
16030 
16031     if(paramCount < 1 || FAILED(ScriptVariant_IntegerValue(varlist[0], &size)) || size < 0)
16032     {
16033         printf("Function requires 1 positive int value: array(int size)\n");
16034         goto array_error;
16035     }
16036 
16037     ScriptVariant_ChangeType(*pretvar, VT_PTR);
16038     array = malloc(sizeof(*array));
16039     (*pretvar)->ptrVal = (VOID *)array;
16040 
16041     if((*pretvar)->ptrVal == NULL)
16042     {
16043         printf("Not enough memory: array(%d)\n", (int)size);
16044         goto array_error;
16045     }
16046 
16047     Varlist_Init(array, size);
16048 
16049     List_InsertAfter(&scriptheap, (void *)(array), "openbor_array");
16050     return S_OK;
16051 
16052 array_error:
16053     (*pretvar) = NULL;
16054     return E_FAIL;
16055 }
16056 
16057 //size(array)
openbor_size(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16058 HRESULT openbor_size(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16059 {
16060     Varlist *array;
16061     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16062     {
16063         goto size_error;
16064     }
16065 
16066     // By White Dragon
16067     if( array->list->size != 0 ) //or array->list->first
16068     {
16069         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
16070         (*pretvar)->lVal = (LONG)array->list->size;
16071     }
16072     else
16073     {
16074         ScriptVariant_Copy(*pretvar, array->vars);
16075     }
16076 
16077     return S_OK;
16078 size_error:
16079     printf("Function requires 1 array handle: %s(array)\n", "size");
16080     (*pretvar) = NULL;
16081     return E_FAIL;
16082 }
16083 
16084 //get(array, index);
openbor_get(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16085 HRESULT openbor_get(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16086 {
16087     ScriptVariant *ptmpvar;
16088     Varlist *array;
16089     LONG ltemp;
16090 
16091     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16092     {
16093         goto get_error;
16094     }
16095 
16096     if(varlist[1]->vt == VT_STR)
16097     {
16098         ptmpvar = Varlist_GetByName(array, StrCache_Get(varlist[1]->strVal));
16099     }
16100     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
16101     {
16102         ptmpvar = Varlist_GetByIndex(array, (int)ltemp);
16103     }
16104     else
16105     {
16106         goto get_error;
16107     }
16108 
16109     if(ptmpvar)
16110     {
16111         ScriptVariant_Copy(*pretvar,  ptmpvar);
16112     }
16113     else
16114     {
16115         ScriptVariant_Clear(*pretvar);
16116     }
16117     return S_OK;
16118 
16119 get_error:
16120     printf("Function requires 1 array handle and 1 int value: get(array, int index)\n");
16121     (*pretvar) = NULL;
16122     return E_FAIL;
16123 }
16124 
16125 //set(array, index, value);
openbor_set(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16126 HRESULT openbor_set(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16127 {
16128     Varlist *array;
16129     LONG ltemp;
16130 
16131     *pretvar = NULL;
16132     if(paramCount < 3 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16133     {
16134         goto set_error;
16135     }
16136 
16137     if(varlist[1]->vt == VT_STR)
16138     {
16139         Varlist_SetByName(array, StrCache_Get(varlist[1]->strVal), varlist[2]);
16140     }
16141     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
16142     {
16143         Varlist_SetByIndex(array, (int)ltemp, varlist[2]);
16144     }
16145     else
16146     {
16147         goto set_error;
16148     }
16149 
16150     return S_OK;
16151 
16152 set_error:
16153     printf("Function requires 1 array handle, 1 int value and 1 value: set(array, int index, value)\n");
16154     return E_FAIL;
16155 }
16156 
16157 //delete(array, index); // By White Dragon
openbor_delete(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16158 HRESULT openbor_delete(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16159 {
16160     Varlist *array;
16161     LONG index;
16162 
16163     *pretvar = NULL;
16164     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16165     {
16166         goto set_error;
16167     }
16168 
16169     if(varlist[1]->vt == VT_STR)
16170     {
16171         if ( !Varlist_DeleteByName(array, StrCache_Get(varlist[1]->strVal)) ) goto set_error;
16172     }
16173     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &index)))
16174     {
16175         if ( !Varlist_DeleteByIndex(array, (int)index) ) goto set_error;
16176     }
16177     else
16178     {
16179         goto set_error;
16180     }
16181 
16182     return S_OK;
16183 
16184 set_error:
16185     printf("Function requires 1 array handle and 1 int value (index): delete(array, index)\n");
16186     return E_FAIL;
16187 }
16188 
16189 //add(array, index); // By White Dragon
openbor_add(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16190 HRESULT openbor_add(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16191 {
16192     Varlist *array;
16193     LONG index;
16194 
16195     *pretvar = NULL;
16196     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16197     {
16198         goto add_error;
16199     }
16200 
16201     if(varlist[1]->vt == VT_STR)
16202     {
16203         Varlist_SetByName(array, StrCache_Get(varlist[1]->strVal), varlist[2]);
16204     }
16205     else if( SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &index)) )
16206     {
16207         if ( !Varlist_AddByIndex(array, (int)index, varlist[2]) ) goto add_error;
16208     }
16209     else
16210     {
16211         goto add_error;
16212     }
16213 
16214     return S_OK;
16215 
16216 add_error:
16217     printf("Function requires 1 array handle and 1 int value (index): add(array, index)\n");
16218     return E_FAIL;
16219 }
16220 
16221 //reset(array)
openbor_reset(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16222 HRESULT openbor_reset(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16223 {
16224     Varlist *array;
16225     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16226     {
16227         goto reset_error;
16228     }
16229     List_Reset(array->list);
16230 
16231     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
16232     (*pretvar)->lVal = (LONG)(array->list->current != NULL);
16233 
16234     return S_OK;
16235 reset_error:
16236     printf("Function requires 1 array handle: %s(array)\n", "reset");
16237     (*pretvar) = NULL;
16238     return E_FAIL;
16239 }
16240 
16241 //next(array)
openbor_next(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16242 HRESULT openbor_next(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16243 {
16244     Varlist *array;
16245     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16246     {
16247         goto next_error;
16248     }
16249 
16250     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
16251     (*pretvar)->lVal = (LONG)(List_GotoNext(array->list));
16252 
16253     return S_OK;
16254 next_error:
16255     printf("Function requires 1 array handle: %s(array)\n", "next");
16256     (*pretvar) = NULL;
16257     return E_FAIL;
16258 }
16259 
16260 //previous(array)
openbor_previous(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16261 HRESULT openbor_previous(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16262 {
16263     Varlist *array;
16264     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16265     {
16266         goto previous_error;
16267     }
16268 
16269     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
16270     (*pretvar)->lVal = (LONG)(List_GotoPrevious(array->list));
16271 
16272     return S_OK;
16273 previous_error:
16274     printf("Function requires 1 array handle: %s(array)\n", "previous");
16275     (*pretvar) = NULL;
16276     return E_FAIL;
16277 }
16278 
16279 //islast(array)
openbor_islast(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16280 HRESULT openbor_islast(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16281 {
16282     Varlist *array;
16283     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16284     {
16285         goto islast_error;
16286     }
16287 
16288     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
16289     (*pretvar)->lVal = (LONG)(  List_Retrieve(array->list) == List_GetLast(array->list) );
16290 
16291     return S_OK;
16292 islast_error:
16293     printf("Function requires 1 array handle: %s(array)\n", "islast");
16294     (*pretvar) = NULL;
16295     return E_FAIL;
16296 }
16297 
16298 //isfirst(array)
openbor_isfirst(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16299 HRESULT openbor_isfirst(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16300 {
16301     Varlist *array;
16302     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16303     {
16304         goto isfirst_error;
16305     }
16306 
16307     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
16308     (*pretvar)->lVal = (LONG)(  List_Retrieve(array->list) == List_GetFirst(array->list) );
16309 
16310     return S_OK;
16311 isfirst_error:
16312     printf("Function requires 1 array handle: %s(array)\n", "isfirst");
16313     (*pretvar) = NULL;
16314     return E_FAIL;
16315 }
16316 
16317 //key(array)
openbor_key(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16318 HRESULT openbor_key(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16319 {
16320     char *name;
16321     Varlist *array;
16322     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16323     {
16324         goto key_error;
16325     }
16326 
16327     name = List_GetName(array->list);
16328     if(name)
16329     {
16330         ScriptVariant_ChangeType(*pretvar, VT_STR);
16331         StrCache_Copy((*pretvar)->strVal, name);
16332     }
16333     else
16334     {
16335         ScriptVariant_Clear(*pretvar);
16336     }
16337 
16338     return S_OK;
16339 key_error:
16340     printf("Function requires 1 array handle: %s(array)\n", "key");
16341     (*pretvar) = NULL;
16342     return E_FAIL;
16343 }
16344 
16345 //value(array)
openbor_value(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16346 HRESULT openbor_value(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16347 {
16348     ScriptVariant *var;
16349     Varlist *array;
16350     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
16351     {
16352         goto value_error;
16353     }
16354 
16355     var = List_Retrieve(array->list);
16356     if(var)
16357     {
16358         ScriptVariant_Copy(*pretvar, var);
16359     }
16360     else
16361     {
16362         ScriptVariant_Clear(*pretvar);
16363     }
16364 
16365     return S_OK;
16366 value_error:
16367     printf("Function requires 1 array handle: %s(array)\n", "value");
16368     (*pretvar) = NULL;
16369     return E_FAIL;
16370 }
16371 
16372 //allocscreen(int w, int h);
openbor_allocscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16373 HRESULT openbor_allocscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16374 {
16375     LONG w, h;
16376     s_screen *screen;
16377 
16378     if(paramCount < 2)
16379     {
16380         goto allocscreen_error;
16381     }
16382 
16383     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &w)))
16384     {
16385         goto allocscreen_error;
16386     }
16387     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &h)))
16388     {
16389         goto allocscreen_error;
16390     }
16391 
16392 
16393     ScriptVariant_ChangeType(*pretvar, VT_PTR);
16394     screen = allocscreen((int)w, (int)h, screenformat);
16395     if(screen)
16396     {
16397         clearscreen(screen);
16398     }
16399     (*pretvar)->ptrVal = (VOID *)screen;
16400 
16401     if((*pretvar)->ptrVal == NULL)
16402     {
16403         printf("Not enough memory: allocscreen(%d, %d)\n", (int)w, (int)h);
16404         (*pretvar) = NULL;
16405         return E_FAIL;
16406     }
16407     List_InsertAfter(&scriptheap, (void *)((*pretvar)->ptrVal), "openbor_allocscreen");
16408     return S_OK;
16409 
16410 allocscreen_error:
16411     printf("Function requires 2 int values: allocscreen(int width, int height)\n");
16412     (*pretvar) = NULL;
16413     return E_FAIL;
16414 }
16415 
16416 //clearscreen(s_screen* screen)
openbor_clearscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16417 HRESULT openbor_clearscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16418 {
16419     s_screen *screen;
16420 
16421     *pretvar = NULL;
16422     if(paramCount != 1)
16423     {
16424         goto clearscreen_error;
16425     }
16426     if(varlist[0]->vt != VT_PTR)
16427     {
16428         goto clearscreen_error;
16429     }
16430 
16431     screen = (s_screen *)varlist[0]->ptrVal;
16432 
16433     if(screen == NULL)
16434     {
16435         printf("Error: NULL pointer passed to clearscreen(void screen)\n");
16436         *pretvar = NULL;
16437         return E_FAIL;
16438     }
16439     clearscreen(screen);
16440     return S_OK;
16441 
16442 clearscreen_error:
16443     printf("Function requires a screen pointer: clearscreen(void screen)\n");
16444     return E_FAIL;
16445 }
16446 
mapstrings_drawmethodproperty(ScriptVariant ** varlist,int paramCount)16447 int mapstrings_drawmethodproperty(ScriptVariant **varlist, int paramCount)
16448 {
16449     char *propname = NULL;
16450     int prop;
16451 
16452     static const char *proplist[] =
16453     {
16454         "alpha",
16455         "amplitude",
16456         "beginsize",
16457         "centerx",
16458         "centery",
16459         "channelb",
16460         "channelg",
16461         "channelr",
16462         "clip",
16463         "cliph",
16464         "clipw",
16465         "clipx",
16466         "clipy",
16467         "enabled",
16468         "endsize",
16469         "fillcolor",
16470         "flag",
16471         "fliprotate",
16472         "flipx",
16473         "flipy",
16474         "perspective",
16475         "remap",
16476         "reset",
16477         "rotate",
16478         "scalex",
16479         "scaley",
16480         "shiftx",
16481         "table",
16482         "tintcolor",
16483         "tintmode",
16484         "transbg",
16485         "watermode",
16486         "wavelength",
16487         "wavespeed",
16488         "wavetime",
16489         "xrepeat",
16490         "xspan",
16491         "yrepeat",
16492         "yspan",
16493     };
16494 
16495 
16496     if(paramCount < 2)
16497     {
16498         return 1;
16499     }
16500     MAPSTRINGS(varlist[1], proplist, _dm_the_end,
16501                "Property name '%s' is not supported by drawmethod.\n");
16502 
16503     return 1;
16504 }
16505 
16506 // changedrawmethod(entity, propertyname, value);
openbor_changedrawmethod(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16507 HRESULT openbor_changedrawmethod(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16508 {
16509     entity *e;
16510     LONG temp = 0;
16511     DOUBLE ftemp = 0;
16512     s_drawmethod *pmethod;
16513     *pretvar = NULL;
16514 
16515     if(paramCount < 3)
16516     {
16517         goto changedm_error;
16518     }
16519 
16520     mapstrings_drawmethodproperty(varlist, paramCount);
16521 
16522     if(varlist[0]->vt == VT_EMPTY)
16523     {
16524         e = NULL;
16525     }
16526     else if(varlist[0]->vt == VT_PTR)
16527     {
16528         e = (entity *)varlist[0]->ptrVal;
16529     }
16530     else
16531     {
16532         goto changedm_error;
16533     }
16534 
16535     if(e)
16536     {
16537         pmethod = &(e->drawmethod);
16538     }
16539     else
16540     {
16541         pmethod = &(drawmethod);
16542     }
16543 
16544     switch(varlist[1]->lVal)
16545     {
16546 
16547     case _dm_alpha:
16548         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16549         {
16550             return E_FAIL;
16551         }
16552         pmethod->alpha = (int)temp;
16553         break;
16554     case _dm_amplitude:
16555         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16556         {
16557             return E_FAIL;
16558         }
16559         pmethod->water.amplitude = (int)temp;
16560         break;
16561     case _dm_beginsize:
16562         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
16563         {
16564             return E_FAIL;
16565         }
16566         pmethod->water.beginsize = (float)ftemp;
16567         break;
16568     case _dm_centerx:
16569         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16570         {
16571             return E_FAIL;
16572         }
16573         pmethod->centerx = (int)temp;
16574         break;
16575     case _dm_centery:
16576         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16577         {
16578             return E_FAIL;
16579         }
16580         pmethod->centery = (int)temp;
16581         break;
16582     case _dm_channelb:
16583         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16584         {
16585             return E_FAIL;
16586         }
16587         pmethod->channelb = (int)temp;
16588         break;
16589     case _dm_channelg:
16590         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16591         {
16592             return E_FAIL;
16593         }
16594         pmethod->channelg = (int)temp;
16595         break;
16596     case _dm_channelr:
16597         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16598         {
16599             return E_FAIL;
16600         }
16601         pmethod->channelr = (int)temp;
16602         break;
16603     case _dm_clip:
16604         if(paramCount < 6)
16605         {
16606             return E_FAIL;
16607         }
16608         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16609         {
16610             return E_FAIL;
16611         }
16612         pmethod->clipx = (int)temp;
16613         if(FAILED(ScriptVariant_IntegerValue(varlist[3], &temp)))
16614         {
16615             return E_FAIL;
16616         }
16617         pmethod->clipy = (int)temp;
16618         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &temp)))
16619         {
16620             return E_FAIL;
16621         }
16622         pmethod->clipw = (int)temp;
16623         if(FAILED(ScriptVariant_IntegerValue(varlist[5], &temp)))
16624         {
16625             return E_FAIL;
16626         }
16627         pmethod->cliph = (int)temp;
16628         break;
16629     case _dm_clipx:
16630         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16631         {
16632             return E_FAIL;
16633         }
16634         pmethod->clipx = (int)temp;
16635         break;
16636     case _dm_clipy:
16637         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16638         {
16639             return E_FAIL;
16640         }
16641         pmethod->clipy = (int)temp;
16642         break;
16643     case _dm_clipw:
16644         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16645         {
16646             return E_FAIL;
16647         }
16648         pmethod->clipw = (int)temp;
16649         break;
16650     case _dm_cliph:
16651         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16652         {
16653             return E_FAIL;
16654         }
16655         pmethod->cliph = (int)temp;
16656         break;
16657     case _dm_enabled:
16658     case _dm_flag:
16659         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16660         {
16661             return E_FAIL;
16662         }
16663         pmethod->flag = (int)temp;
16664         break;
16665     case _dm_endsize:
16666         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
16667         {
16668             return E_FAIL;
16669         }
16670         pmethod->water.endsize = (float)ftemp;
16671         break;
16672     case _dm_fillcolor:
16673         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16674         {
16675             return E_FAIL;
16676         }
16677         pmethod->fillcolor = (int)temp;
16678         break;
16679     case _dm_fliprotate:
16680         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16681         {
16682             return E_FAIL;
16683         }
16684         pmethod->fliprotate = (int)temp;
16685         break;
16686     case _dm_flipx:
16687         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16688         {
16689             return E_FAIL;
16690         }
16691         pmethod->flipx = (int)temp;
16692         break;
16693     case _dm_flipy:
16694         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16695         {
16696             return E_FAIL;
16697         }
16698         pmethod->flipy = (int)temp;
16699         break;
16700     case _dm_perspective:
16701         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16702         {
16703             return E_FAIL;
16704         }
16705         pmethod->water.perspective = (int)temp;
16706         break;
16707     case _dm_remap:
16708         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16709         {
16710             return E_FAIL;
16711         }
16712         pmethod->remap = (int)temp;
16713         break;
16714     case _dm_reset:
16715         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16716         {
16717             return E_FAIL;
16718         }
16719         if(temp)
16720         {
16721             *pmethod = plainmethod;
16722         }
16723         break;
16724     case _dm_rotate:
16725         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16726         {
16727             return E_FAIL;
16728         }
16729         pmethod->rotate = (float)temp;
16730         break;
16731     case _dm_scalex:
16732         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16733         {
16734             return E_FAIL;
16735         }
16736         pmethod->scalex = (int)temp;
16737         break;
16738     case _dm_scaley:
16739         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16740         {
16741             return E_FAIL;
16742         }
16743         pmethod->scaley = (int)temp;
16744         break;
16745     case _dm_shiftx:
16746         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16747         {
16748             return E_FAIL;
16749         }
16750         pmethod->shiftx = (int)temp;
16751         break;
16752     case _dm_table:
16753         if(varlist[2]->vt != VT_PTR && varlist[2]->vt != VT_EMPTY )
16754         {
16755             return E_FAIL;
16756         }
16757         pmethod->table = (void *)varlist[2]->ptrVal;
16758         break;
16759     case _dm_tintmode:
16760         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16761         {
16762             return E_FAIL;
16763         }
16764         pmethod->tintmode = (int)temp;
16765         break;
16766     case _dm_tintcolor:
16767         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16768         {
16769             return E_FAIL;
16770         }
16771         pmethod->tintcolor = (int)temp;
16772         break;
16773     case _dm_transbg:
16774         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16775         {
16776             return E_FAIL;
16777         }
16778         pmethod->transbg = (int)temp;
16779         break;
16780     case _dm_watermode:
16781         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16782         {
16783             return E_FAIL;
16784         }
16785         pmethod->water.watermode = (int)temp;
16786         break;
16787     case _dm_wavelength:
16788         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
16789         {
16790             return E_FAIL;
16791         }
16792         pmethod->water.wavelength = (float)ftemp;
16793         break;
16794     case _dm_wavespeed:
16795         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
16796         {
16797             return E_FAIL;
16798         }
16799         pmethod->water.wavespeed = (float)ftemp;
16800         break;
16801     case _dm_wavetime:
16802         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16803         {
16804             return E_FAIL;
16805         }
16806         pmethod->water.wavetime = (int)(temp * pmethod->water.wavespeed);
16807         break;
16808     case _dm_xrepeat:
16809         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16810         {
16811             return E_FAIL;
16812         }
16813         pmethod->xrepeat = (int)temp;
16814         break;
16815     case _dm_yrepeat:
16816         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16817         {
16818             return E_FAIL;
16819         }
16820         pmethod->yrepeat = (int)temp;
16821         break;
16822     case _dm_xspan:
16823         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16824         {
16825             return E_FAIL;
16826         }
16827         pmethod->xspan = (int)temp;
16828         break;
16829     case _dm_yspan:
16830         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
16831         {
16832             return E_FAIL;
16833         }
16834         pmethod->yspan = (int)temp;
16835         break;
16836     default:
16837         break;
16838 
16839     }
16840 
16841     return S_OK;
16842 
16843 changedm_error:
16844     printf("Function changedrawmethod must have at least 3 parameters: entity, propertyname, value\n");
16845     return E_FAIL;
16846 }
16847 
16848 //getdrawmethod(<entity>, <property>)
openbor_getdrawmethod(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)16849 HRESULT openbor_getdrawmethod(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
16850 {
16851     /*
16852     getdrawmethod
16853     Damon V. Caskey
16854     2013-11-09
16855 
16856     Allow module author to read current drawmethod settings.
16857     */
16858     entity *e;
16859     s_drawmethod *pmethod;
16860     *pretvar = NULL;
16861 
16862     if(paramCount < 2)
16863     {
16864         goto getdm_error;
16865     }
16866 
16867     mapstrings_drawmethodproperty(varlist, paramCount);
16868 
16869     if(varlist[0]->vt == VT_EMPTY)
16870     {
16871         e = NULL;
16872     }
16873     else if(varlist[0]->vt == VT_PTR)
16874     {
16875         e = (entity *)varlist[0]->ptrVal;
16876     }
16877     else
16878     {
16879         goto getdm_error;
16880     }
16881 
16882     if(e)
16883     {
16884         pmethod = &(e->drawmethod);
16885     }
16886     else
16887     {
16888         pmethod = &(drawmethod);
16889     }
16890 
16891     switch(varlist[1]->lVal)
16892     {
16893         case _dm_alpha:
16894             (*pretvar)->lVal = pmethod->alpha;
16895             break;
16896         case _dm_amplitude:
16897             (*pretvar)->lVal = pmethod->water.amplitude;
16898             break;
16899         case _dm_beginsize:
16900             (*pretvar)->dblVal = pmethod->water.beginsize;
16901             break;
16902         case _dm_centerx:
16903             (*pretvar)->lVal = pmethod->centerx;
16904             break;
16905         case _dm_centery:
16906             (*pretvar)->lVal = pmethod->centery;
16907             break;
16908         case _dm_channelb:
16909             (*pretvar)->lVal = pmethod->channelb;
16910             break;
16911         case _dm_channelg:
16912             (*pretvar)->lVal = pmethod->channelg;
16913             break;
16914         case _dm_channelr:
16915             (*pretvar)->lVal = pmethod->channelr;
16916             break;
16917         case _dm_clipx:
16918             (*pretvar)->lVal = pmethod->clipx;
16919             break;
16920         case _dm_clipy:
16921             (*pretvar)->lVal = pmethod->clipy;
16922             break;
16923         case _dm_clipw:
16924             (*pretvar)->lVal = pmethod->clipw;
16925             break;
16926         case _dm_cliph:
16927             (*pretvar)->lVal = pmethod->cliph;
16928             break;
16929         case _dm_endsize:
16930             (*pretvar)->dblVal = pmethod->water.endsize;
16931             break;
16932         case _dm_fillcolor:
16933             (*pretvar)->lVal = pmethod->fillcolor;
16934             break;
16935         case _dm_fliprotate:
16936             (*pretvar)->lVal = pmethod->fliprotate;
16937             break;
16938         case _dm_flipx:
16939             (*pretvar)->lVal = pmethod->flipx;
16940             break;
16941         case _dm_flipy:
16942             (*pretvar)->lVal = pmethod->flipy;
16943             break;
16944         case _dm_perspective:
16945             (*pretvar)->lVal = pmethod->water.perspective;
16946             break;
16947         case _dm_remap:
16948             (*pretvar)->lVal = pmethod->remap;
16949             break;
16950         case _dm_rotate:
16951             (*pretvar)->lVal = pmethod->rotate;
16952             break;
16953         case _dm_scalex:
16954             (*pretvar)->lVal = pmethod->scalex;
16955             break;
16956         case _dm_scaley:
16957             (*pretvar)->lVal = pmethod->scaley;
16958             break;
16959         case _dm_shiftx:
16960             (*pretvar)->lVal = pmethod->shiftx;
16961             break;
16962         case _dm_table:
16963             (*pretvar)->ptrVal = pmethod->table;
16964             break;
16965         case _dm_tintmode:
16966             (*pretvar)->lVal = pmethod->tintmode;
16967             break;
16968         case _dm_tintcolor:
16969             (*pretvar)->lVal = pmethod->tintcolor;
16970             break;
16971         case _dm_transbg:
16972             (*pretvar)->lVal = pmethod->transbg;
16973             break;
16974         case _dm_watermode:
16975             (*pretvar)->lVal = pmethod->water.watermode;
16976             break;
16977         case _dm_wavelength:
16978             (*pretvar)->dblVal = pmethod->water.wavelength;
16979             break;
16980         case _dm_wavespeed:
16981             (*pretvar)->dblVal = pmethod->water.wavespeed;
16982             break;
16983         case _dm_wavetime:
16984             (*pretvar)->lVal = pmethod->water.wavetime;
16985             break;
16986         case _dm_xrepeat:
16987             (*pretvar)->lVal = pmethod->xrepeat;
16988             break;
16989         case _dm_yrepeat:
16990             (*pretvar)->lVal = pmethod->yrepeat;
16991             break;
16992         case _dm_xspan:
16993             (*pretvar)->lVal = pmethod->xspan;
16994             break;
16995         case _dm_yspan:
16996             (*pretvar)->lVal = pmethod->yspan;
16997             break;
16998         default:
16999         case _dm_enabled:
17000         case _dm_flag:
17001             (*pretvar)->lVal = pmethod->flag;
17002             break;
17003     }
17004 
17005     return S_OK;
17006 
17007 getdm_error:
17008     printf("Function getdrawmethod must have at least 2 parameters: entity, propertyname\n");
17009     return E_FAIL;
17010 }
17011 
17012 //deprecated
17013 //setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int remap, int fillcolor, int rotate, int fliprotate, int transparencybg, void* colourmap, int centerx, int centery);
openbor_setdrawmethod(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17014 HRESULT openbor_setdrawmethod(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17015 {
17016     LONG value[14];
17017     entity *e;
17018     s_drawmethod *pmethod;
17019     int i;
17020 
17021     *pretvar = NULL;
17022     if(paramCount < 2)
17023     {
17024         goto setdrawmethod_error;
17025     }
17026 
17027     if(varlist[0]->vt == VT_EMPTY)
17028     {
17029         e = NULL;
17030     }
17031     else if(varlist[0]->vt == VT_PTR)
17032     {
17033         e = (entity *)varlist[0]->ptrVal;
17034     }
17035     else
17036     {
17037         goto setdrawmethod_error;
17038     }
17039 
17040     if(e)
17041     {
17042         pmethod = &(e->drawmethod);
17043     }
17044     else
17045     {
17046         pmethod = &(drawmethod);
17047     }
17048 
17049     memset(value, 0, sizeof(value));
17050     for(i = 1; i < paramCount && i < 13; i++)
17051     {
17052         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
17053         {
17054             goto setdrawmethod_error;
17055         }
17056     }
17057 
17058     if(paramCount >= 14 && varlist[13]->vt != VT_PTR && varlist[13]->vt != VT_EMPTY)
17059     {
17060         goto setdrawmethod_error;
17061     }
17062 
17063     for(i = 14; i < paramCount && i < 16; i++)
17064     {
17065         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 2)))
17066         {
17067             goto setdrawmethod_error;
17068         }
17069     }
17070 
17071     pmethod->flag = (int)value[0];
17072     pmethod->scalex = (int)value[1];
17073     pmethod->scaley = (int)value[2];
17074     pmethod->flipx = (int)value[3];
17075     pmethod->flipy = (int)value[4];
17076     pmethod->shiftx = (int)value[5];
17077     pmethod->alpha = (int)value[6];
17078     pmethod->remap = (int)value[7];
17079     pmethod->fillcolor = (int)value[8];
17080     pmethod->rotate = ((int)value[9]) % 360;
17081     pmethod->fliprotate = (int)value[10];
17082     pmethod->transbg = (int)value[11];
17083     if(paramCount >= 14)
17084     {
17085         pmethod->table = (unsigned char *)varlist[13]->ptrVal;
17086     }
17087     pmethod->centerx = (int)value[12];
17088     pmethod->centery = (int)value[13];
17089 
17090     if(pmethod->rotate < 0)
17091     {
17092         pmethod->rotate += 360;
17093     }
17094     return S_OK;
17095 
17096 setdrawmethod_error:
17097     printf("Function need a valid entity handle and at least 1 interger parameter, setdrawmethod(entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int remap, int fillcolor, int rotate, int fliprotate, int transparencybg, void* colourmap, centerx, centery)\n");
17098     return E_FAIL;
17099 }
17100 
17101 //updateframe(entity, int frame);
openbor_updateframe(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17102 HRESULT openbor_updateframe(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17103 {
17104     LONG f;
17105     entity *e;
17106     void update_frame(entity * ent, int f);
17107 
17108     *pretvar = NULL;
17109     if(paramCount < 2)
17110     {
17111         goto updateframe_error;
17112     }
17113 
17114     if(varlist[0]->vt == VT_EMPTY)
17115     {
17116         e = NULL;
17117     }
17118     else if(varlist[0]->vt == VT_PTR)
17119     {
17120         e = (entity *)varlist[0]->ptrVal;
17121     }
17122     else
17123     {
17124         goto updateframe_error;
17125     }
17126 
17127     if(!e)
17128     {
17129         goto updateframe_error;
17130     }
17131 
17132     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &f)))
17133     {
17134         goto updateframe_error;
17135     }
17136 
17137     update_frame(e, (int)f);
17138 
17139     return S_OK;
17140 
17141 updateframe_error:
17142     printf("Function need a valid entity handle and at an interger parameter: updateframe(entity, int frame)\n");
17143     return E_FAIL;
17144 }
17145 
17146 //executeanimation(entity, int anim, int resetable);
openbor_executeanimation(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17147 HRESULT openbor_executeanimation(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17148 {
17149     LONG anim, resetable = 0;
17150     entity *e;
17151 
17152     *pretvar = NULL;
17153     if(paramCount < 1)
17154     {
17155         goto executeanimation_error;
17156     }
17157 
17158     if(varlist[0]->vt == VT_EMPTY)
17159     {
17160         e = NULL;
17161     }
17162     else if(varlist[0]->vt == VT_PTR)
17163     {
17164         e = (entity *)varlist[0]->ptrVal;
17165     }
17166     else
17167     {
17168         goto executeanimation_error;
17169     }
17170 
17171     if(!e)
17172     {
17173         goto executeanimation_error;
17174     }
17175 
17176     e->takeaction = common_animation_normal;
17177     e->attacking = 0;
17178     e->idling = 0;
17179     e->drop = 0;
17180     e->falling = 0;
17181     e->inpain = 0;
17182     e->inbackpain = 0;
17183     e->blocking = 0;
17184 
17185     if(paramCount == 1)
17186     {
17187         return S_OK;
17188     }
17189 
17190     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
17191     {
17192         goto executeanimation_error;
17193     }
17194     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))
17195     {
17196         goto executeanimation_error;
17197     }
17198     ent_set_anim(e, (int)anim, (int)resetable);
17199 
17200     return S_OK;
17201 
17202 executeanimation_error:
17203     printf("Function need a valid entity handle, the other 2 integer parameters are optional: performattack(entity, int anim, int resetable)\n");
17204     return E_FAIL;
17205 }
17206 
17207 //performattack(entity, int anim, int resetable);
openbor_performattack(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17208 HRESULT openbor_performattack(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17209 {
17210     LONG anim, resetable = 0;
17211     entity *e;
17212 
17213     *pretvar = NULL;
17214     if(paramCount < 1)
17215     {
17216         goto performattack_error;
17217     }
17218 
17219     if(varlist[0]->vt == VT_EMPTY)
17220     {
17221         e = NULL;
17222     }
17223     else if(varlist[0]->vt == VT_PTR)
17224     {
17225         e = (entity *)varlist[0]->ptrVal;
17226     }
17227     else
17228     {
17229         goto performattack_error;
17230     }
17231 
17232     if(!e)
17233     {
17234         goto performattack_error;
17235     }
17236 
17237     e->takeaction = common_attack_proc;
17238     e->attacking = 1;
17239     e->idling = 0;
17240     e->drop = 0;
17241     e->falling = 0;
17242     e->inpain = 0;
17243     e->inbackpain = 0;
17244     e->blocking = 0;
17245 
17246     if(paramCount == 1)
17247     {
17248         return S_OK;
17249     }
17250 
17251     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
17252     {
17253         goto performattack_error;
17254     }
17255     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))
17256     {
17257         goto performattack_error;
17258     }
17259     ent_set_anim(e, (int)anim, (int)resetable);
17260 
17261     return S_OK;
17262 
17263 performattack_error:
17264     printf("Function need a valid entity handle, the other 2 integer parameters are optional: performattack(entity, int anim, int resetable)\n");
17265     return E_FAIL;
17266 }
17267 
17268 //setidle(entity, int anim, int resetable, int stalladd);
openbor_setidle(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17269 HRESULT openbor_setidle(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17270 {
17271     LONG anim = 0, resetable = 0, stalladd = 0;
17272     entity *e;
17273     extern unsigned int time;
17274 
17275     *pretvar = NULL;
17276     if(paramCount < 1)
17277     {
17278         goto setidle_error;
17279     }
17280 
17281     if(varlist[0]->vt == VT_EMPTY)
17282     {
17283         e = NULL;
17284     }
17285     else if(varlist[0]->vt == VT_PTR)
17286     {
17287         e = (entity *)varlist[0]->ptrVal;
17288     }
17289     else
17290     {
17291         goto setidle_error;
17292     }
17293 
17294     if(!e)
17295     {
17296         goto setidle_error;
17297     }
17298 
17299     e->takeaction = NULL;
17300     e->attacking = 0;
17301     e->idling = 1;
17302     e->drop = 0;
17303     e->falling = 0;
17304     e->inpain = 0;
17305     e->inbackpain = 0;
17306     e->blocking = 0;
17307     e->nograb = e->nograb_default; //e->nograb = 0;
17308     e->destx = e->position.x;
17309     e->destz = e->position.z;
17310 
17311     if(paramCount == 1)
17312     {
17313         return S_OK;
17314     }
17315 
17316     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
17317     {
17318         goto setidle_error;
17319     }
17320     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))
17321     {
17322         goto setidle_error;
17323     }
17324     if(paramCount > 3 && FAILED(ScriptVariant_IntegerValue(varlist[3], &stalladd)))
17325     {
17326         goto setidle_error;
17327     }
17328     ent_set_anim(e, (int)anim, (int)resetable);
17329 
17330     if(stalladd > 0)
17331     {
17332         e->stalltime = time + stalladd;
17333     }
17334 
17335     return S_OK;
17336 
17337 setidle_error:
17338     printf("Function need a valid entity handle, the other 3 integer parameters are optional: setidle(entity, int anim, int resetable, int stalladd)\n");
17339     return E_FAIL;
17340 }
17341 
17342 //getentity(int index_from_list)
openbor_getentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17343 HRESULT openbor_getentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17344 {
17345     LONG ind;
17346     extern entity **ent_list;
17347     extern int ent_list_size;
17348 
17349     if(paramCount != 1)
17350     {
17351         goto getentity_error;
17352     }
17353 
17354     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
17355     {
17356         goto getentity_error;
17357     }
17358 
17359     ScriptVariant_Clear(*pretvar);
17360 
17361     if((int)ind < ent_list_size && (int)ind >= 0)
17362     {
17363         ScriptVariant_ChangeType(*pretvar, VT_PTR);
17364         (*pretvar)->ptrVal = (VOID *)ent_list[(int)ind];
17365     }
17366     //else, it should return an empty value
17367     return S_OK;
17368 
17369 getentity_error:
17370     printf("Function need an integer parameter: getentity(int index_in_list)\n");
17371     *pretvar = NULL;
17372     return E_FAIL;
17373 }
17374 
17375 
17376 //loadmodel(name)
openbor_loadmodel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17377 HRESULT openbor_loadmodel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17378 {
17379     LONG unload = 0;
17380     s_model *model;
17381     if(paramCount < 1)
17382     {
17383         goto loadmodel_error;
17384     }
17385     if(varlist[0]->vt != VT_STR)
17386     {
17387         goto loadmodel_error;
17388     }
17389 
17390     ScriptVariant_ChangeType(*pretvar, VT_PTR);
17391     if(paramCount >= 2)
17392         if(FAILED(ScriptVariant_IntegerValue(varlist[1], &unload)))
17393         {
17394             goto loadmodel_error;
17395         }
17396 
17397     model = load_cached_model(StrCache_Get(varlist[0]->strVal), "openbor_loadmodel", (char)unload);
17398 
17399     if(paramCount >= 3 && model)
17400     {
17401         model_cache[model->index].selectable = (char)ScriptVariant_IsTrue(varlist[2]);
17402     }
17403 
17404     (*pretvar)->ptrVal = (VOID *)model;
17405 
17406     //else, it should return an empty value
17407     return S_OK;
17408 
17409 loadmodel_error:
17410     printf("Function needs a string and integer parameters: loadmodel(name, unload, selectable)\n");
17411     ScriptVariant_Clear(*pretvar);
17412     *pretvar = NULL;
17413     return E_FAIL;
17414 }
17415 
17416 // load a sprite which doesn't belong to the sprite_cache
17417 // loadsprite(path, maskpath)
openbor_loadsprite(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17418 HRESULT openbor_loadsprite(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17419 {
17420     extern s_sprite *loadsprite2(char * filename, int * width, int * height);
17421     s_sprite *spr, *mask;
17422     if(paramCount < 1)
17423     {
17424         goto loadsprite_error;
17425     }
17426 
17427     if(varlist[0]->vt != VT_STR)
17428     {
17429         goto loadsprite_error;
17430     }
17431 
17432     ScriptVariant_ChangeType(*pretvar, VT_PTR);
17433     if((spr = loadsprite2(StrCache_Get(varlist[0]->strVal), NULL, NULL)))
17434     {
17435         (*pretvar)->ptrVal = (VOID *)spr;
17436         if(paramCount > 1 && (mask = loadsprite2(StrCache_Get(varlist[1]->strVal), NULL, NULL)))
17437         {
17438             spr->mask = mask;
17439         }
17440         List_InsertAfter(&scriptheap, (void *)spr, "openbor_loadsprite");
17441     }
17442     //else, it should return an empty value
17443     return S_OK;
17444 
17445 loadsprite_error:
17446     printf("Function need a string parameter: loadsprite(path)\n");
17447     ScriptVariant_Clear(*pretvar);
17448     *pretvar = NULL;
17449     return E_FAIL;
17450 }
17451 
17452 // Call options menu, blocked
openbor_menu_options(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17453 HRESULT openbor_menu_options(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17454 {
17455     //void menu_options();
17456 
17457     menu_options();
17458 
17459     *pretvar = NULL;
17460     return S_OK;
17461 }
17462 
openbor_hallfame(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17463 HRESULT openbor_hallfame(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17464 {
17465     hallfame(0);
17466 
17467     *pretvar = NULL;
17468     return S_OK;
17469 }
17470 
17471 //playwebm(path, int noskip)
openbor_playwebm(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17472 HRESULT openbor_playwebm(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17473 {
17474     LONG temp = 0; //noskip
17475     extern int playwebm(char * filename, int noskip); // avoid implicit declaration
17476 
17477     if(paramCount < 1)
17478     {
17479         goto playwebm_error;
17480     }
17481 
17482     if(varlist[0]->vt != VT_STR)
17483     {
17484         goto playwebm_error;
17485     }
17486 
17487     if(paramCount > 1)
17488     {
17489         if(FAILED(ScriptVariant_IntegerValue(varlist[1], &temp)))
17490         {
17491             goto playwebm_error;
17492         }
17493     }
17494 
17495     #ifdef WEBM
17496         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17497         (*pretvar)->lVal = (LONG)playwebm(StrCache_Get(varlist[0]->strVal), (int)temp);
17498     #else
17499         printf("Skipping video %s; WebM playback not supported on this platform\n");
17500         *pretvar = NULL;
17501     #endif
17502 
17503     return S_OK;
17504 
17505 playwebm_error:
17506     printf("Function need a string parameter, other parameters are optional: playwebm(path, int noskip)\n");
17507     *pretvar = NULL;
17508     return E_FAIL;
17509 }
17510 
17511 //playgif(path, int x, int y, int noskip)
openbor_playgif(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17512 HRESULT openbor_playgif(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17513 {
17514     LONG temp[3] = {0, 0, 0}; //x,y,noskip
17515     int i;
17516     extern unsigned char pal[1024];
17517     extern int playgif(char * filename, int x, int y, int noskip);
17518 
17519     if(paramCount < 1)
17520     {
17521         goto playgif_error;
17522     }
17523 
17524     if(varlist[0]->vt != VT_STR)
17525     {
17526         goto playgif_error;
17527     }
17528 
17529     for(i = 0; i < 3 && i < paramCount - 1; i++)
17530     {
17531         if(FAILED(ScriptVariant_IntegerValue(varlist[i + 1], temp + i)))
17532         {
17533             goto playgif_error;
17534         }
17535     }
17536 
17537     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17538     (*pretvar)->lVal = (LONG)playgif(StrCache_Get(varlist[0]->strVal), (int)(temp[0]), (int)(temp[1]), (int)(temp[2]));
17539     palette_set_corrected(pal, savedata.gamma, savedata.gamma, savedata.gamma, savedata.brightness, savedata.brightness, savedata.brightness);
17540     return S_OK;
17541 
17542 playgif_error:
17543     printf("Function need a string parameter, other parameters are optional: playgif(path, int x, int y, int noskip)\n");
17544     *pretvar = NULL;
17545     return E_FAIL;
17546 }
17547 
17548 //open and return a handle
17549 //TODO: error messages
openbor_openanigif(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17550 HRESULT openbor_openanigif(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17551 {
17552     anigif_info *info = NULL;
17553 
17554     if(varlist[0]->vt != VT_STR)
17555     {
17556         goto openanigif_error;
17557     }
17558 
17559     info = calloc(1, sizeof(*info));
17560     if(anigif_open(StrCache_Get(varlist[0]->strVal), packfile, info))
17561     {
17562         info->magic = anigif_magic;
17563         List_InsertAfter(&scriptheap, (void *)info, "openbor_openanigif");
17564         ScriptVariant_ChangeType(*pretvar, VT_PTR);
17565         (*pretvar)->ptrVal = (VOID *)info;
17566         return S_OK;
17567     }
17568 
17569 openanigif_error:
17570     if(info)
17571     {
17572         free(info);
17573     }
17574     *pretvar = NULL;
17575     return E_FAIL;
17576 }
17577 
17578 //decode a frame if any
openbor_decodeanigif(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17579 HRESULT openbor_decodeanigif(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17580 {
17581     anigif_info *info = NULL;
17582 
17583     if(varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
17584     {
17585         goto decodeanigif_error;
17586     }
17587     info = (anigif_info *) varlist[0]->ptrVal;
17588 
17589     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17590     (*pretvar)->lVal = (LONG)anigif_decode_frame(info);
17591     return S_OK;
17592 
17593 decodeanigif_error:
17594     *pretvar = NULL;
17595     return E_FAIL;
17596 }
17597 
17598 //TODO mapstrings
openbor_getanigifinfo(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17599 HRESULT openbor_getanigifinfo(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17600 {
17601     anigif_info *info = NULL;
17602     char *name;
17603 
17604     if(varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
17605     {
17606         goto getanigifinfo_error;
17607     }
17608     info = (anigif_info *) varlist[0]->ptrVal;
17609 
17610     if(varlist[1]->vt != VT_STR)
17611     {
17612         goto getanigifinfo_error;
17613     }
17614     name = StrCache_Get(varlist[1]->strVal);
17615     if(0 == stricmp(name, "buffer"))
17616     {
17617         ScriptVariant_ChangeType(*pretvar, VT_PTR);
17618         (*pretvar)->ptrVal = (VOID *)anigif_getbuffer(info);
17619     }
17620     else if(0 == stricmp(name, "done"))
17621     {
17622         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17623         (*pretvar)->lVal = (LONG)info->done;
17624     }
17625     else if(0 == stricmp(name, "frame"))
17626     {
17627         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17628         (*pretvar)->lVal = (LONG)info->frame;
17629     }
17630     else if(0 == stricmp(name, "isRGB"))
17631     {
17632         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17633         (*pretvar)->lVal = (LONG)info->isRGB;
17634     }
17635     else if(0 == stricmp(name, "width"))
17636     {
17637         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17638         (*pretvar)->lVal = (LONG)(info->gifbuffer[0] ? info->gifbuffer[0]->width : 0);
17639     }
17640     else if(0 == stricmp(name, "height"))
17641     {
17642         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17643         (*pretvar)->lVal = (LONG)(info->gifbuffer[0] ? info->gifbuffer[0]->height : 0);
17644     }
17645     else if(0 == stricmp(name, "nextframe"))
17646     {
17647         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17648         (*pretvar)->lVal = (LONG)info->info[0].nextframe;
17649     }
17650     else if(0 == stricmp(name, "lastdelay"))
17651     {
17652         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17653         (*pretvar)->lVal = (LONG)info->info[0].lastdelay;
17654     }
17655     else
17656     {
17657         goto getanigifinfo_error;
17658     }
17659 
17660     return S_OK;
17661 
17662 getanigifinfo_error:
17663     *pretvar = NULL;
17664     return E_FAIL;
17665 }
17666 
17667 // complex, so make a function for ai
17668 // adjustwalkanimation(ent, target);
openbor_adjustwalkanimation(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17669 HRESULT openbor_adjustwalkanimation(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17670 {
17671 
17672     entity *e, *t, *temp;
17673 
17674     *pretvar = NULL;
17675 
17676     if(paramCount < 1)
17677     {
17678         e = self;
17679     }
17680     else if(varlist[0]->vt == VT_PTR)
17681     {
17682         e = (entity *)varlist[0]->ptrVal;
17683     }
17684     else
17685     {
17686         goto adjustwalkanimation_error;
17687     }
17688 
17689     if(paramCount < 2)
17690     {
17691         t = NULL;
17692     }
17693     else if(varlist[1]->vt == VT_PTR)
17694     {
17695         t = (entity *)varlist[1]->ptrVal;
17696     }
17697     else if(varlist[1]->vt == VT_EMPTY)
17698     {
17699         t = NULL;
17700     }
17701     else
17702     {
17703         goto adjustwalkanimation_error;
17704     }
17705 
17706     temp = self;
17707 
17708     self = e;
17709     adjust_walk_animation(t);
17710     self = temp;
17711 
17712     return S_OK;
17713 adjustwalkanimation_error:
17714     printf("Function adjustwalkanimation(entity, target), both parameters are optional, but must be valid.");
17715     return E_FAIL;
17716 }
17717 
17718 //finditem(entity)
openbor_finditem(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17719 HRESULT openbor_finditem(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17720 {
17721 
17722     entity *e, *t, *temp;
17723 
17724     if(paramCount < 1)
17725     {
17726         e = self;
17727     }
17728     else if(varlist[0]->vt == VT_PTR)
17729     {
17730         e = (entity *)varlist[0]->ptrVal;
17731     }
17732     else
17733     {
17734         goto finditem_error;
17735     }
17736 
17737     temp = self;
17738 
17739     self = e;
17740     t = normal_find_item();
17741     self = temp;
17742 
17743     ScriptVariant_ChangeType(*pretvar, VT_PTR);
17744     (*pretvar)->ptrVal = (VOID *)t;
17745 
17746     return S_OK;
17747 finditem_error:
17748 
17749     *pretvar = NULL;
17750     printf("Function finditem(entity), entity is optional, but must be valid.");
17751     return E_FAIL;
17752 }
17753 
17754 //pickup(entity, item)
openbor_pickup(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17755 HRESULT openbor_pickup(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17756 {
17757 
17758     entity *e, *t, *temp;
17759 
17760     *pretvar = NULL;
17761 
17762     if(paramCount < 2)
17763     {
17764         goto pickup_error;
17765     }
17766 
17767     if(varlist[0]->vt == VT_PTR)
17768     {
17769         e = (entity *)varlist[0]->ptrVal;
17770     }
17771     else
17772     {
17773         goto pickup_error;
17774     }
17775 
17776     if(varlist[1]->vt == VT_PTR)
17777     {
17778         t = (entity *)varlist[1]->ptrVal;
17779     }
17780     else
17781     {
17782         goto pickup_error;
17783     }
17784 
17785     if(!e || !t)
17786     {
17787         goto pickup_error;
17788     }
17789 
17790     temp = self;
17791 
17792     self = e;
17793     common_pickupitem(t);
17794     self = temp;
17795 
17796     return S_OK;
17797 pickup_error:
17798     printf("Function pickup(entity, item), handles must be valid.");
17799     return E_FAIL;
17800 }
17801 
17802 //waypoints(ent, x1, z1, x2, z2, x3, z3, ...)
17803 //zero length list means clear waypoints
openbor_waypoints(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17804 HRESULT openbor_waypoints(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17805 {
17806     int num, i;
17807     s_axis_f *wp = NULL;
17808     DOUBLE x, z;
17809 
17810     entity *e;
17811     *pretvar = NULL;
17812 
17813     if(paramCount < 1)
17814     {
17815         goto wp_error;
17816     }
17817 
17818     if(varlist[0]->vt == VT_PTR)
17819     {
17820         e = (entity *)varlist[0]->ptrVal;
17821     }
17822     else
17823     {
17824         goto wp_error;
17825     }
17826 
17827     num = (paramCount - 1) / 2;
17828     if(num > 0)
17829     {
17830         //append
17831         wp = malloc(sizeof(*wp) * (num + e->numwaypoints));
17832 
17833         for(i = 0; i < num ; i++)
17834         {
17835             if(FAILED(ScriptVariant_DecimalValue(varlist[1], &x)))
17836             {
17837                 goto wp_error;
17838             }
17839 
17840             if(FAILED(ScriptVariant_DecimalValue(varlist[2], &z)))
17841             {
17842                 goto wp_error;
17843             }
17844 
17845             wp[num - i - 1].x = (float)x;
17846             wp[num - i - 1].z = (float)z;
17847         }
17848         if(e->numwaypoints)
17849         {
17850             for(i = 0; i < e->numwaypoints; i++)
17851             {
17852                 wp[i + num] = e->waypoints[i];
17853             }
17854         }
17855 
17856         if(e->waypoints)
17857         {
17858             free(e->waypoints);
17859         }
17860         e->waypoints = wp;
17861         e->numwaypoints = num;
17862     }
17863     else
17864     {
17865         e->numwaypoints = 0;
17866         if(e->waypoints)
17867         {
17868             free(e->waypoints);
17869         }
17870         e->waypoints = NULL;
17871     }
17872     return S_OK;
17873 
17874 wp_error:
17875     if(wp)
17876     {
17877         free(wp);
17878     }
17879     wp = NULL;
17880     printf("Function waypoints requires a valid entity handle and a list of x, z value pairs.");
17881     return E_FAIL;
17882 }
17883 
17884 //testmove(entity, x, z)
openbor_testmove(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17885 HRESULT openbor_testmove(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17886 {
17887 
17888     entity *e;
17889     DOUBLE x, z;
17890 
17891     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
17892 
17893     if(paramCount < 3)
17894     {
17895         goto testmove_error;
17896     }
17897 
17898     if(varlist[0]->vt == VT_PTR)
17899     {
17900         e = (entity *)varlist[0]->ptrVal;
17901     }
17902     else
17903     {
17904         goto testmove_error;
17905     }
17906 
17907     if(FAILED(ScriptVariant_DecimalValue(varlist[1], &x)))
17908     {
17909         goto testmove_error;
17910     }
17911 
17912     if(FAILED(ScriptVariant_DecimalValue(varlist[2], &z)))
17913     {
17914         goto testmove_error;
17915     }
17916 
17917     if(!e)
17918     {
17919         goto testmove_error;
17920     }
17921 
17922     (*pretvar)->lVal = (LONG) testmove(e, e->position.x, e->position.z, x, z);
17923 
17924     return S_OK;
17925 testmove_error:
17926     *pretvar = NULL;
17927     printf("Function testmove(entity, x, z)");
17928     return E_FAIL;
17929 }
17930 
17931 //spriteq_draw(vscreen, 0, MIN_INT, MAX_INT, dx, dy)
openbor_drawspriteq(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17932 HRESULT openbor_drawspriteq(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17933 {
17934 
17935     LONG value[5] = {0, MIN_INT, MAX_INT, 0, 0};
17936     int i;
17937     s_screen *screen;
17938     extern s_screen *vscreen;
17939 
17940     *pretvar = NULL;
17941 
17942     if(paramCount < 1)
17943     {
17944         goto drawsq_error;
17945     }
17946 
17947     if(varlist[0]->vt != VT_PTR && varlist[0]->vt != VT_EMPTY)
17948     {
17949         goto drawsq_error;
17950     }
17951 
17952     if(varlist[0]->ptrVal)
17953     {
17954         screen = (s_screen *)varlist[0]->ptrVal;
17955     }
17956     else
17957     {
17958         screen = vscreen;
17959     }
17960 
17961     for(i = 1; i < paramCount && i <= 5; i++)
17962     {
17963         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
17964         {
17965             goto drawsq_error;
17966         }
17967     }
17968 
17969     spriteq_draw(screen, (int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4]);
17970 
17971     return S_OK;
17972 
17973 drawsq_error:
17974     printf("Function drawspriteq needs a valid screen handle and all other paramaters must be integers.");
17975     return E_FAIL;
17976 
17977 }
17978 
openbor_clearspriteq(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)17979 HRESULT openbor_clearspriteq(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
17980 {
17981     *pretvar = NULL;
17982     spriteq_clear();
17983     return S_OK;
17984 
17985 }
17986 
17987 // ===== gfxproperty ======
17988 enum gfxproperty_enum
17989 {
17990     _gfx_centerx,
17991     _gfx_centery,
17992     _gfx_height,
17993     _gfx_palette,
17994     _gfx_pixel,
17995     _gfx_pixelformat,
17996     _gfx_srcheight,
17997     _gfx_srcwidth,
17998     _gfx_width,
17999     _gfx_the_end,
18000 };
18001 
mapstrings_gfxproperty(ScriptVariant ** varlist,int paramCount)18002 int mapstrings_gfxproperty(ScriptVariant **varlist, int paramCount)
18003 {
18004     char *propname = NULL;
18005     int prop;
18006 
18007     static const char *proplist[] =
18008     {
18009         "centerx",
18010         "centery",
18011         "height",
18012         "palette",
18013         "pixel",
18014         "pixelformat",
18015         "srcheight",
18016         "srcwidth",
18017         "width",
18018     };
18019 
18020 
18021     if(paramCount < 2)
18022     {
18023         return 1;
18024     }
18025     MAPSTRINGS(varlist[1], proplist, _gfx_the_end,
18026                "Property name '%s' is not supported by gfxproperty.\n");
18027 
18028     return 1;
18029 }
18030 
18031 // getgfxproperty(handle, propertyname, ...);
openbor_getgfxproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18032 HRESULT openbor_getgfxproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18033 {
18034     s_screen *screen;
18035     s_sprite *sprite;
18036     s_bitmap *bitmap;
18037     LONG value[2] = {0, 0}, v;
18038     void *handle;
18039     int i, x, y;
18040 
18041     if(paramCount < 2)
18042     {
18043         goto ggp_error;
18044     }
18045 
18046     mapstrings_gfxproperty(varlist, paramCount);
18047 
18048     if(varlist[0]->vt != VT_PTR)
18049     {
18050         goto ggp_error;
18051     }
18052 
18053     handle = varlist[0]->ptrVal;
18054 
18055     if(!handle)
18056     {
18057         goto ggp_error;
18058     }
18059 
18060     screen = (s_screen *)handle;
18061     sprite = (s_sprite *)handle;
18062     bitmap = (s_bitmap *)handle;
18063 
18064     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
18065 
18066 
18067     switch(varlist[1]->lVal)
18068     {
18069     case _gfx_width:
18070         switch(screen->magic)
18071         {
18072         case screen_magic:
18073             (*pretvar)->lVal = screen->width;
18074             break;
18075         case sprite_magic:
18076             (*pretvar)->lVal = sprite->width;
18077             break;
18078         case bitmap_magic:
18079             (*pretvar)->lVal = bitmap->width;
18080             break;
18081         default:
18082             goto ggp_error2;
18083         }
18084         break;
18085     case _gfx_height:
18086         switch(screen->magic)
18087         {
18088         case screen_magic:
18089             (*pretvar)->lVal = screen->height;
18090             break;
18091         case sprite_magic:
18092             (*pretvar)->lVal = sprite->height;
18093             break;
18094         case bitmap_magic:
18095             (*pretvar)->lVal = bitmap->height;
18096             break;
18097         default:
18098             goto ggp_error2;
18099         }
18100         break;
18101     case _gfx_srcwidth:
18102         switch(screen->magic)
18103         {
18104         case sprite_magic:
18105             (*pretvar)->lVal = sprite->srcwidth;
18106             break;
18107         case screen_magic:
18108             (*pretvar)->lVal = screen->width;
18109             break;
18110         case bitmap_magic:
18111             (*pretvar)->lVal = bitmap->width;
18112             break;
18113         default:
18114             goto ggp_error2;
18115         }
18116         break;
18117     case _gfx_srcheight:
18118         switch(screen->magic)
18119         {
18120         case sprite_magic:
18121             (*pretvar)->lVal = sprite->srcheight;
18122             break;
18123         case screen_magic:
18124             (*pretvar)->lVal = screen->height;
18125             break;
18126         case bitmap_magic:
18127             (*pretvar)->lVal = bitmap->height;
18128             break;
18129         default:
18130             goto ggp_error2;
18131         }
18132         break;
18133     case _gfx_centerx:
18134         switch(screen->magic)
18135         {
18136         case screen_magic:
18137         case bitmap_magic:
18138             (*pretvar)->lVal = 0;
18139             break;
18140         case sprite_magic:
18141             (*pretvar)->lVal = sprite->centerx;
18142             break;
18143         default:
18144             goto ggp_error2;
18145         }
18146         break;
18147     case _gfx_centery:
18148         switch(screen->magic)
18149         {
18150         case screen_magic:
18151         case bitmap_magic:
18152             (*pretvar)->lVal = 0;
18153             break;
18154         case sprite_magic:
18155             (*pretvar)->lVal = sprite->centery;
18156             break;
18157         default:
18158             goto ggp_error2;
18159         }
18160         break;
18161     case _gfx_palette:
18162         ScriptVariant_ChangeType(*pretvar, VT_PTR);
18163         switch(screen->magic)
18164         {
18165         case screen_magic:
18166             (*pretvar)->ptrVal = (VOID *)screen->palette;
18167             break;
18168         case sprite_magic:
18169             (*pretvar)->ptrVal = (VOID *)sprite->palette;
18170             break;
18171         case bitmap_magic:
18172             (*pretvar)->ptrVal = (VOID *)bitmap->palette;
18173             break;
18174         default:
18175             goto ggp_error2;
18176         }
18177         break;
18178     case _gfx_pixelformat:
18179         switch(screen->magic)
18180         {
18181         case screen_magic:
18182             (*pretvar)->lVal = screen->pixelformat;
18183             break;
18184         case sprite_magic:
18185             (*pretvar)->lVal = sprite->pixelformat;
18186             break;
18187         case bitmap_magic:
18188             (*pretvar)->lVal = bitmap->pixelformat;
18189             break;
18190         default:
18191             goto ggp_error2;
18192         }
18193         break;
18194     case _gfx_pixel:
18195         if(paramCount < 4)
18196         {
18197             goto ggp_error3;
18198         }
18199         for(i = 2; i < 4; i++)
18200         {
18201             if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 2)))
18202             {
18203                 goto ggp_error4;
18204             }
18205         }
18206         x = value[0];
18207         y = value[1];
18208         switch(screen->magic)
18209         {
18210         case bitmap_magic: //As long as the two structures are identical...
18211         case screen_magic:
18212             if(x < 0 || x >= screen->width || y < 0 || y >= screen->height)
18213             {
18214                 v = 0;
18215             }
18216             else
18217             {
18218                 switch(screen->pixelformat)
18219                 {
18220                 case PIXEL_8:
18221                 case PIXEL_x8:
18222                     v = (LONG)(((unsigned char *)screen->data)[y * screen->width + x]);
18223                     break;
18224                 case PIXEL_16:
18225                     v = (LONG)(((unsigned short *)screen->data)[y * screen->width + x]);
18226                     break;
18227                 case PIXEL_32:
18228                     v = (LONG)(((unsigned *)screen->data)[y * screen->width + x]);
18229                     break;
18230                 default:
18231                     v = 0;
18232                 }
18233             }
18234             break;
18235         case sprite_magic:
18236             if(x < 0 || x >= sprite->width || y < 0 || y >= sprite->height)
18237             {
18238                 v = 0;
18239             }
18240             else
18241             {
18242                 v = (LONG)sprite_get_pixel(sprite, x, y);
18243             }
18244             break;
18245         default:
18246             goto ggp_error2;
18247         }
18248         (*pretvar)->lVal = v;
18249         break;
18250     default:
18251         break;
18252 
18253     }
18254 
18255     return S_OK;
18256 
18257 ggp_error:
18258     printf("Function getgfxproperty must have a valid handle and a property name.\n");
18259     *pretvar = NULL;
18260     return E_FAIL;
18261 ggp_error2:
18262     printf("Function getgfxproperty encountered an invalid handle.\n");
18263     *pretvar = NULL;
18264     return E_FAIL;
18265 ggp_error3:
18266     printf("You need to specify x, y value for getgfxproperty.\n");
18267     *pretvar = NULL;
18268     return E_FAIL;
18269 ggp_error4:
18270     printf("Invalid x or y value for getgfxproperty.\n");
18271     *pretvar = NULL;
18272     return E_FAIL;
18273 }
18274 
18275 //allocscript(name, comment);
openbor_allocscript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18276 HRESULT openbor_allocscript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18277 {
18278     Script *ns;
18279     char *name = NULL, *comment = NULL;
18280 
18281     ns = malloc(sizeof(Script));
18282 
18283     if(ns == NULL)
18284     {
18285         goto as_error;
18286     }
18287 
18288     if(paramCount >= 1 && varlist[0]->vt == VT_STR)
18289     {
18290         name = (char *)StrCache_Get(varlist[0]->strVal);
18291     }
18292     if(paramCount >= 2 && varlist[1]->vt == VT_STR)
18293     {
18294         comment = (char *)StrCache_Get(varlist[1]->strVal);
18295     }
18296 
18297     Script_Init(ns, name, comment, 1);
18298 
18299     List_InsertAfter(&scriptheap, (void *)ns, "openbor_allocscript");
18300 
18301     ScriptVariant_ChangeType(*pretvar, VT_PTR);
18302     (*pretvar)->ptrVal = (VOID *)ns;
18303     return S_OK;
18304 
18305 as_error:
18306     printf("Function allocscript failed to alloc enough memory.\n");
18307     (*pretvar) = NULL;
18308     return E_FAIL;
18309 }
18310 
18311 //loadscript(handle, path);
openbor_loadscript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18312 HRESULT openbor_loadscript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18313 {
18314     Script *ns = NULL;
18315     char *path = NULL;
18316     int load_script(Script * script, char * file);
18317 
18318     (*pretvar) = NULL;
18319 
18320     if(paramCount >= 1 && varlist[0]->vt == VT_PTR)
18321     {
18322         ns = (Script *)varlist[0]->ptrVal;
18323     }
18324     if(ns == NULL || ns->magic != script_magic)
18325     {
18326         goto ls_error;
18327     }
18328     if(paramCount >= 2 && varlist[1]->vt == VT_STR)
18329     {
18330         path = (char *)StrCache_Get(varlist[1]->strVal);
18331     }
18332     if(path == NULL)
18333     {
18334         goto ls_error;
18335     }
18336 
18337     load_script(ns, path);
18338     //Script_Init(ns, name, comment, 1);
18339     //if(!load_script(ns, path)) goto ls_error2;
18340 
18341     return S_OK;
18342 
18343 ls_error:
18344     printf("Function loadscript requires a valid script handle and a path.\n");
18345     return E_FAIL;
18346 }
18347 
18348 //compilescript(handle);
openbor_compilescript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18349 HRESULT openbor_compilescript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18350 {
18351     Script *ns = NULL;
18352 
18353     (*pretvar) = NULL;
18354 
18355     if(paramCount >= 1 && varlist[0]->vt == VT_PTR)
18356     {
18357         ns = (Script *)varlist[0]->ptrVal;
18358     }
18359     if(ns == NULL || ns->magic != script_magic)
18360     {
18361         goto cs_error;
18362     }
18363 
18364     Script_Compile(ns);
18365 
18366     return S_OK;
18367 
18368 cs_error:
18369     printf("Function compilescript requires a valid script handle.\n");
18370     return E_FAIL;
18371 }
18372 
18373 //executescript(handle);
openbor_executescript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18374 HRESULT openbor_executescript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18375 {
18376     Script *ns = NULL;
18377 
18378     (*pretvar) = NULL;
18379 
18380     if(paramCount >= 1 && varlist[0]->vt == VT_PTR)
18381     {
18382         ns = (Script *)varlist[0]->ptrVal;
18383     }
18384     if(ns == NULL || ns->magic != script_magic)
18385     {
18386         goto cs_error;
18387     }
18388 
18389     Script_Execute(ns);
18390 
18391     return S_OK;
18392 
18393 cs_error:
18394     printf("Function executescript requires a valid script handle.\n");
18395     return E_FAIL;
18396 }
18397 
18398 
18399 //loadgamefile() //only reload saved level file from saves
openbor_loadgamefile(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18400 HRESULT openbor_loadgamefile(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18401 {
18402     loadGameFile();
18403     *pretvar = NULL;
18404     return S_OK;
18405 }
18406 
18407 //finishlevel()
openbor_finishlevel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18408 HRESULT openbor_finishlevel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18409 {
18410     *pretvar = NULL;
18411     level->forcefinishlevel = 1;
18412     return S_OK;
18413 }
18414 
18415 //gotomainmenu(flag); flag: 1 = no gameover, 2 = no halloffame, 4 = no intro.txt; you can use a combination like 1+2 = 3 or all 1+2+4 = 7
openbor_gotomainmenu(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18416 HRESULT openbor_gotomainmenu(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18417 {
18418     LONG ltemp = 0;
18419 
18420     *pretvar = NULL;
18421 
18422     if(paramCount >= 1 && FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)) )
18423     {
18424         return E_FAIL;
18425     }
18426 
18427     goto_mainmenu((int)ltemp);
18428 
18429     return S_OK;
18430 }
18431 
18432 //playgame(set, usesave?)
openbor_playgame(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18433 HRESULT openbor_playgame(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18434 {
18435     LONG lset = 0, lsave = -1;
18436     *pretvar = NULL;
18437 
18438     if(paramCount >= 1 && FAILED(ScriptVariant_IntegerValue(varlist[0], &lset)) )
18439     {
18440         goto pg_error;
18441     }
18442     if(paramCount >= 2 && FAILED(ScriptVariant_IntegerValue(varlist[1], &lsave)) )
18443     {
18444         goto pg_error;
18445     }
18446 
18447 
18448     useSave = lsave;
18449     useSet = lset;
18450     endgame = 1;
18451 
18452     return S_OK;
18453 
18454 pg_error:
18455     *pretvar = NULL;
18456     return E_FAIL;
18457 }
18458 
18459 //getrecordingstatus() it returns 0 = stop, 1 = rec, 2 = play, 4 = free buffer
openbor_getrecordingstatus(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18460 HRESULT openbor_getrecordingstatus(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) {
18461     ScriptVariant_Clear(*pretvar);
18462     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
18463     (*pretvar)->lVal = (LONG)playrecstatus->status;
18464     return S_OK;
18465 }
18466 
18467 //recordinputs(value) -> 0 = stop, 1 = rec, 2 = play, 4 = free buffer
openbor_recordinputs(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18468 HRESULT openbor_recordinputs(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18469 {
18470     int ltemp;
18471 
18472     *pretvar = NULL;
18473     if( paramCount < 1 && varlist[0]->vt != VT_INTEGER )
18474     {
18475         return E_FAIL;
18476     }
18477 
18478     ltemp = (int)varlist[0]->lVal;
18479     switch(ltemp)
18480     {
18481         case A_REC_STOP:
18482             stopRecordInputs();
18483             break;
18484         case A_REC_REC:
18485             if( paramCount < 3 || varlist[1]->vt != VT_STR || varlist[2]->vt != VT_STR )
18486             {
18487                 printf("Function recordinputs requires a pathname and filename parameters.\n");
18488                 return E_FAIL;
18489             }
18490             strcpy(playrecstatus->path,(char*)StrCache_Get(varlist[1]->strVal));
18491             strcpy(playrecstatus->filename,(char*)StrCache_Get(varlist[2]->strVal));
18492             //debug_printf("%s/%s",(char*)StrCache_Get(varlist[1]->strVal),(char*)StrCache_Get(varlist[2]->strVal));
18493             stopRecordInputs();
18494             playrecstatus->status = A_REC_REC;
18495             recordInputs();
18496             break;
18497         case A_REC_PLAY:
18498             if( paramCount < 3 || varlist[1]->vt != VT_STR || varlist[2]->vt != VT_STR )
18499             {
18500                 printf("Function recordinputs requires a pathname and filename parameters.\n");
18501                 return E_FAIL;
18502             }
18503             strcpy(playrecstatus->path,(char*)StrCache_Get(varlist[1]->strVal));
18504             strcpy(playrecstatus->filename,(char*)StrCache_Get(varlist[2]->strVal));
18505             stopRecordInputs();
18506             playrecstatus->status = A_REC_PLAY;
18507             playRecordedInputs();
18508             break;
18509         case A_REC_FREE:
18510             freeRecordedInputs();
18511             break;
18512     }
18513 
18514     return S_OK;
18515 }
18516 
18517 //getsaveinfo(set, prop);
openbor_getsaveinfo(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)18518 HRESULT openbor_getsaveinfo(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
18519 {
18520     LONG ltemp;
18521     s_savelevel *slot;
18522     char *prop;
18523     if(paramCount < 2)
18524     {
18525         goto gsi_error;
18526     }
18527 
18528     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)) || varlist[1]->vt != VT_STR)
18529     {
18530         goto gsi_error;
18531     }
18532 
18533     if(!savelevel)
18534     {
18535         ScriptVariant_Clear(*pretvar);
18536         return S_OK;
18537     }
18538 
18539     slot = savelevel + ltemp;
18540     prop = (char *)StrCache_Get(varlist[1]->strVal);
18541 
18542     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
18543     if(0 == stricmp(prop, "flag"))
18544     {
18545         (*pretvar)->lVal = (LONG)slot->flag;
18546     }
18547     else if(0 == stricmp(prop, "level"))
18548     {
18549         (*pretvar)->lVal = (LONG)slot->level;
18550     }
18551     else if(0 == stricmp(prop, "stage"))
18552     {
18553         (*pretvar)->lVal = (LONG)slot->stage;
18554     }
18555     else if(0 == stricmp(prop, "set"))
18556     {
18557         (*pretvar)->lVal = (LONG)slot->which_set;
18558     }
18559     else if(0 == stricmp(prop, "times_completed"))
18560     {
18561         (*pretvar)->lVal = (LONG)slot->times_completed;
18562     }
18563     else if(0 == stricmp(prop, "score"))
18564     {
18565         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
18566         {
18567             goto gsi_error;
18568         }
18569         (*pretvar)->lVal = (LONG)slot->pScores[ltemp];
18570     }
18571     else if(0 == stricmp(prop, "lives"))
18572     {
18573         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
18574         {
18575             goto gsi_error;
18576         }
18577         (*pretvar)->lVal = (LONG)slot->pLives[ltemp];
18578     }
18579     else if(0 == stricmp(prop, "credits"))
18580     {
18581         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
18582         {
18583             goto gsi_error;
18584         }
18585         (*pretvar)->lVal = (LONG)(noshare ? slot->credits : slot->pCredits[ltemp]);
18586     }
18587     else if(0 == stricmp(prop, "name"))
18588     {
18589         ScriptVariant_ChangeType(*pretvar, VT_STR);
18590         StrCache_Copy((*pretvar)->strVal, slot->dName);
18591     }
18592     else if(0 == stricmp(prop, "playername"))
18593     {
18594         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
18595         {
18596             goto gsi_error;
18597         }
18598         ScriptVariant_ChangeType(*pretvar, VT_STR);
18599         StrCache_Copy((*pretvar)->strVal, slot->pName[ltemp]);
18600     }
18601     else if(0 == stricmp(prop, "health"))
18602     {
18603         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
18604         {
18605             goto gsi_error;
18606         }
18607         (*pretvar)->lVal = (LONG)slot->pSpawnhealth[ltemp];
18608     }
18609     else if(0 == stricmp(prop, "mp"))
18610     {
18611         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
18612         {
18613             goto gsi_error;
18614         }
18615         (*pretvar)->lVal = (LONG)slot->pSpawnmp[ltemp];
18616     }
18617     else
18618     {
18619         goto gsi_error;
18620     }
18621     return S_OK;
18622 
18623 gsi_error:
18624     *pretvar = NULL;
18625     return E_FAIL;
18626 }
18627