1 /*
2  * OpenBOR - http://www.chronocrash.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2017 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 		 Be sure 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 "config.h"
31 #include "openbor.h"
32 #include "soundmix.h"
33 #include "globals.h"
34 #include "ImportCache.h"
35 #include "models.h"
36 #include "scriptcommon.h"
37 
38 Varlist global_var_list;
39 Script *pcurrentscript = NULL; //used by local script functions
40 List theFunctionList;
41 static List   scriptheap;
42 static s_spawn_entry spawnentry;
43 static s_drawmethod drawmethod;
44 
45 int            max_indexed_vars = 0;
46 int            max_entity_vars = 0;
47 int            max_script_vars = 0;
48 int			   no_nested_script = 0;
49 
50 extern int  ent_count;
51 extern int  ent_max;
52 extern int  gameOver;
53 extern int  selectScreen;
54 extern int	titleScreen;
55 extern int  hallOfFame;
56 extern int	showComplete;
57 extern char	*currentScene;
58 extern int  enginecreditsScreen;
59 extern int	menuScreen;
60 extern int  optionsMenu;
61 extern int	controloptionsMenu;
62 extern int	videooptionsMenu;
63 extern int  soundoptionsMenu;
64 extern int	systemoptionsMenu;
65 extern int	startgameMenu;
66 extern int  newgameMenu;
67 extern int  loadgameMenu;
68 extern int  num_difficulties;
69 extern u32  _time;
70 extern int goto_mainmenu_flag;
71 extern int _pause;
72 extern int timeleft;
73 extern int gfx_x_offset;
74 extern int gfx_y_offset;
75 extern int gfx_y_offset_adj;
76 extern s_lasthit lasthit;
77 extern int current_set;
78 extern int current_level;
79 extern int current_stage;
80 extern int timevar;
81 extern float   bgtravelled;
82 extern float   vbgtravelled;
83 extern int traveltime;
84 extern int texttime;
85 extern int timetoshow;
86 extern int is_total_timeover;
87 extern int showgo;
88 extern float   advancex;
89 extern float   advancey;
90 extern float   scrolldx;
91 extern float   scrolldy;
92 extern float   scrollminz;
93 extern float   scrollmaxz;
94 extern float   blockade;
95 extern float   scrollminx;
96 extern float   scrollmaxx;
97 extern s_videomodes videomodes;
98 extern int  panel_height;
99 extern char branch_name[MAX_NAME_LEN + 1];
100 extern s_set_entry *levelsets;
101 extern unsigned int models_loaded;
102 //extern unsigned int   models_cached;
103 extern int viewportx;
104 extern int viewporty;
105 extern int viewportw;
106 extern int viewporth;
107 extern int nosave;
108 extern int nopause;
109 extern int nofadeout;
110 extern int noscreenshot;
111 extern int nojoin;
112 extern s_screen *vscreen;
113 extern entity *smartbomber;
114 extern entity *textbox;
115 extern s_screen *background;
116 extern int skiptoset;
117 extern s_slow_motion    slowmotion;
118 extern int shadowcolor;
119 extern int shadowalpha;
120 extern int shadowopacity;
121 extern s_axis_plane_vertical_int light;
122 extern int max_attack_types;
123 extern int max_animations;
124 
clear_named_var_list(List * list,int level)125 static void clear_named_var_list(List *list, int level)
126 {
127     ScriptVariant *var;
128     int i, size;
129     size = List_GetSize(list);
130     for(i = 0, List_Reset(list); i < size; i++)
131     {
132         var = (ScriptVariant *)List_Retrieve(list);
133         ScriptVariant_Clear(var);
134         free(var);
135         List_Remove(list);
136     }
137     if(level)
138     {
139         List_Clear(list);
140     }
141 }
142 
Varlist_Init(Varlist * varlist,int size)143 void Varlist_Init(Varlist *varlist, int size)
144 {
145     int i;
146 
147     varlist->magic = varlist_magic;
148     varlist->list = calloc(1, sizeof(*varlist->list));
149     List_Init(varlist->list);
150     varlist->vars = calloc(size + 1, sizeof(*varlist->vars));
151     for(i = 0; i <= size; i++)
152     {
153         ScriptVariant_Init(varlist->vars + i);
154         ScriptVariant_ChangeType(varlist->vars, VT_INTEGER);
155         varlist->vars->lVal = (LONG)size;
156     }
157 }
158 
Varlist_Clear(Varlist * varlist)159 void Varlist_Clear(Varlist *varlist)
160 {
161     int i;
162     clear_named_var_list(varlist->list, 1);
163     free(varlist->list);
164     varlist->list = NULL;
165     // the first one must be an integer variable, so it's safe to leave it alone
166     for(i = 1; i <= varlist->vars->lVal; i++)
167     {
168         ScriptVariant_Clear(varlist->vars + i);
169     }
170     free(varlist->vars);
171     varlist->vars = NULL;
172     varlist->magic = 0;
173 }
174 
Varlist_Cleanup(Varlist * varlist)175 void Varlist_Cleanup(Varlist *varlist)
176 {
177     int i;
178     clear_named_var_list(varlist->list, 0);
179     for(i = 1; i <= varlist->vars->lVal; i++)
180     {
181         ScriptVariant_Clear(varlist->vars + i);
182     }
183 }
184 
Varlist_GetByName(Varlist * varlist,char * theName)185 ScriptVariant *Varlist_GetByName(Varlist *varlist, char *theName)
186 {
187     if(!theName || !theName[0])
188     {
189         return NULL;
190     }
191 
192     if(List_FindByName(varlist->list, theName))
193     {
194         return (ScriptVariant *)List_Retrieve(varlist->list);
195     }
196 
197     return NULL;
198 }
199 
Varlist_SetByName(Varlist * varlist,char * theName,ScriptVariant * var)200 int Varlist_SetByName(Varlist *varlist, char *theName, ScriptVariant *var)
201 {
202     ScriptVariant *v;
203     if(!theName || !theName[0])
204     {
205         return 0;
206     }
207     if(List_FindByName(varlist->list, theName))
208     {
209         ScriptVariant_Copy((ScriptVariant *)List_Retrieve(varlist->list), var);
210     }
211     else
212     {
213         v = calloc(1, sizeof(*v));
214         ScriptVariant_Copy(v, var);
215         List_InsertAfter(varlist->list, v, theName);
216     }
217     return 1;
218 }
219 
Varlist_GetByIndex(Varlist * varlist,int index)220 ScriptVariant *Varlist_GetByIndex(Varlist *varlist, int index)
221 {
222     if(index < 0 || index >= varlist->vars->lVal)
223     {
224         return NULL;
225     }
226     return varlist->vars + index + 1;
227 }
228 
Varlist_SetByIndex(Varlist * varlist,int index,ScriptVariant * var)229 int Varlist_SetByIndex(Varlist *varlist, int index, ScriptVariant *var)
230 {
231     if(index < 0)
232     {
233         return 0;
234     }
235     else if(index >= varlist->vars->lVal)
236     {
237         __reallocto(varlist->vars, varlist->vars->lVal + 1, index + 2);
238         varlist->vars->lVal = index + 1;
239     }
240     ScriptVariant_Copy(varlist->vars + index + 1, var);
241     return 1;
242 }
243 
244 // By White Dragon
Varlist_AddByIndex(Varlist * array,int index,ScriptVariant * var)245 int Varlist_AddByIndex(Varlist *array, int index, ScriptVariant *var)
246 {
247     if(index < 0 || index >= array->vars->lVal+1)
248     {
249         return 0;
250     }
251     else
252     {
253         int i = 0;
254         int size = array->vars->lVal;
255 
256         __reallocto(array->vars, size+1, size+2);
257         size = ++array->vars->lVal;
258 
259         for ( i = size-1; i > index; i-- )
260         {
261             ScriptVariant_Copy(array->vars+1+i, array->vars+1+i-1); // first value of array is his size!
262         }
263         ScriptVariant_Copy(array->vars+1+index, var);
264 
265         //printf("aaa: %s\n", (char*)StrCache_Get(elem->strVal) );
266     }
267 
268     return 1;
269 }
270 
271 // By White Dragon
Varlist_DeleteByIndex(Varlist * array,int index)272 int Varlist_DeleteByIndex(Varlist *array, int index)
273 {
274     if(index < 0 || index >= array->vars->lVal)
275     {
276         return 0;
277     }
278     else
279     {
280         int i = 0;
281         int size = array->vars->lVal;
282         ScriptVariant *elem;
283 
284         for ( i = index; i < size-1; i++ )
285         {
286             ScriptVariant_Copy(array->vars+1+i, array->vars+1+i+1); // first value of array is his size!
287         }
288         --array->vars->lVal;
289 
290         // set last element to NULL
291         elem = array->vars+1+size-1;
292         ScriptVariant_ChangeType(elem, VT_EMPTY);
293         elem->ptrVal = NULL;
294 
295         //realloc mem
296         array->vars = realloc((array->vars), sizeof(*(array->vars))*(array->vars->lVal+1));
297 
298         //printf("aaa: %s\n", (char*)StrCache_Get(elem->strVal) );
299     }
300 
301     return 1;
302 }
303 
304 // By White Dragon
Varlist_DeleteByName(Varlist * array,char * theName)305 int Varlist_DeleteByName(Varlist *array, char *theName)
306 {
307     if(!theName || !theName[0])
308     {
309         return 0;
310     }
311     if(List_FindByName(array->list, theName))
312     {
313         Node* node;
314         Node* prev_node;
315         Node* next_node;
316 
317         node = array->list->current;
318         prev_node = node->prev;
319         next_node = node->next;
320 
321         if ( prev_node ) prev_node->next = next_node;
322         if ( next_node ) next_node->prev = prev_node;
323 
324         if ( array->list->last == node ) array->list->last = prev_node;
325         if ( array->list->first == node ) array->list->first = next_node;
326         if ( array->list->first == array->list->last && array->list->first == node ) {
327             array->list->last = NULL;
328             array->list->first = NULL;
329         }
330 
331         --array->list->size;
332 
333         free(node);
334     } else return 0;
335 
336     return 1;
337 }
338 
339 //this function should be called before all script methods, for once
Script_Global_Init()340 void Script_Global_Init()
341 {
342     memset(&spawnentry, 0, sizeof(spawnentry)); //clear up the spawn entry
343     drawmethod = plainmethod;
344 
345     Varlist_Init(&global_var_list, max_indexed_vars);
346 
347     List_Init(&theFunctionList);
348     Script_LoadSystemFunctions();
349     List_Init(&scriptheap);
350     ImportCache_Init(&theFunctionList);
351 }
352 
_freeheapnode(void * ptr)353 void _freeheapnode(void *ptr)
354 {
355     if(((Script *)ptr)->magic == script_magic)
356     {
357         Script_Clear((Script *)ptr, 2);
358     }
359     else if(((anigif_info *)ptr)->magic == anigif_magic)
360     {
361         anigif_close((anigif_info *)ptr);
362     }
363     else if(((Varlist *)ptr)->magic == varlist_magic)
364     {
365         Varlist_Clear((Varlist *)ptr);
366     }
367     else if(((s_sprite *)ptr)->magic == sprite_magic)
368     {
369         if(((s_sprite *)ptr)->mask)
370         {
371             free(((s_sprite *)ptr)->mask);
372         }
373     }
374     free(ptr);
375 }
376 
377 //this function should only be called when the engine is shutting down
Script_Global_Clear()378 void Script_Global_Clear()
379 {
380     int i, size;
381     List_Clear(&theFunctionList);
382     // dump all un-freed variants
383     size = List_GetSize(&scriptheap);
384     if(size > 0)
385     {
386         printf("\nWarning: %d script variants are not freed, dumping...\n", size);
387     }
388     for(i = 0, List_Reset(&scriptheap); i < size; List_GotoNext(&scriptheap), i++)
389     {
390         printf("%s\n", List_GetName(&scriptheap));
391         _freeheapnode(List_Retrieve(&scriptheap));
392     }
393     List_Clear(&scriptheap);
394     // clear the global list
395     Varlist_Clear(&global_var_list);
396 
397     memset(&spawnentry, 0, sizeof(spawnentry));//clear up the spawn entry
398     for(i = 0; i < numfilestreams; i++)
399     {
400         if(filestreams[i].buf)
401         {
402             free(filestreams[i].buf);
403             filestreams[i].buf = NULL;
404         }
405     }
406     if(filestreams)
407     {
408         free(filestreams);
409     }
410     filestreams = NULL;
411     numfilestreams = 0;
412     ImportCache_Clear();
413     StrCache_Clear();
414 }
415 
Script_Save_Local_Variant(Script * cs,char * namelist[])416 int Script_Save_Local_Variant(Script *cs, char *namelist[])
417 {
418     return 0;
419 }
420 
Script_Load_Local_Variant(Script * cs,int handle)421 void Script_Load_Local_Variant(Script *cs, int handle)
422 {
423 
424 }
425 
alloc_script()426 Script *alloc_script()
427 {
428     Script *pscript = calloc(1, sizeof(*pscript));
429     pscript->magic = script_magic;
430     pscript->varlist = calloc(1, sizeof(*pscript->varlist));
431     Varlist_Init(pscript->varlist, max_script_vars);
432     return pscript;
433 }
434 
Script_Init(Script * pscript,char * theName,char * comment,int first)435 void Script_Init(Script *pscript, char *theName, char *comment, int first)
436 {
437     if(first)
438     {
439         memset(pscript, 0, sizeof(*pscript));
440         pscript->magic = script_magic;
441         pscript->varlist = calloc(1, sizeof(*pscript->varlist));
442         Varlist_Init(pscript->varlist, max_script_vars);
443     }
444     if(!theName || !theName[0])
445     {
446         return;    // if no name specified, only alloc the variants
447     }
448 
449     pscript->pinterpreter = malloc(sizeof(*pscript->pinterpreter));
450     Interpreter_Init(pscript->pinterpreter, theName, &theFunctionList);
451     pscript->interpreterowner = 1; // this is the owner, important
452     pscript->initialized = 1;
453     if(comment)
454     {
455         pscript->comment = malloc(sizeof(*pscript->comment) * (strlen(comment) + 1));
456         strcpy(pscript->comment, comment);
457     }
458 }
459 
execute_init_method(Script * pdest,int iscopy,int localclear)460 static void execute_init_method(Script *pdest, int iscopy, int localclear)
461 {
462     Script *temp;
463     ScriptVariant tempvar;
464     //Execute init method
465     if(pdest->initialized && pdest->pinterpreter->pInitEntry)
466     {
467         temp = pcurrentscript;
468         pcurrentscript = pdest;
469 
470         ScriptVariant_Init(&tempvar);
471         ScriptVariant_ChangeType(&tempvar, VT_INTEGER);
472         tempvar.lVal = (LONG)iscopy;
473         Script_Set_Local_Variant(pdest, "iscopy", &tempvar);
474         tempvar.lVal = (LONG)localclear;
475         Script_Set_Local_Variant(pdest, "localclear", &tempvar);
476         Interpreter_Reset(pdest->pinterpreter);
477         pdest->pinterpreter->pCurrentInstruction = pdest->pinterpreter->pInitEntry;
478         if(FAILED( Interpreter_EvaluateCall(pdest->pinterpreter)))
479         {
480             borShutdown(1, "Fatal: failed to execute 'init' in script %s %s", pdest->pinterpreter->theSymbolTable.name, pdest->comment ? pdest->comment : "");
481         }
482         pdest->pinterpreter->bReset = FALSE; // not needed, perhaps
483         ScriptVariant_Clear(&tempvar);
484         Script_Set_Local_Variant(pdest, "iscopy", &tempvar);
485         Script_Set_Local_Variant(pdest, "localclear", &tempvar);
486         pcurrentscript = temp;
487     }
488 }
489 
490 //safe copy method
Script_Copy(Script * pdest,Script * psrc,int localclear)491 void Script_Copy(Script *pdest, Script *psrc, int localclear)
492 {
493     if(!psrc->initialized)
494     {
495         return;
496     }
497     if(pdest->initialized)
498     {
499         Script_Clear(pdest, localclear);
500     }
501     pdest->pinterpreter = psrc->pinterpreter;
502     pdest->comment = psrc->comment;
503     pdest->interpreterowner = 0; // dont own it
504     pdest->initialized = psrc->initialized; //just copy, it should be 1
505     execute_init_method(pdest, 1, localclear);
506 }
507 
Script_Clear(Script * pscript,int localclear)508 void Script_Clear(Script *pscript, int localclear)
509 {
510     Script *temp;
511     Varlist *pvars;
512 
513     ScriptVariant tempvar;
514     //Execute clear method
515     if(pscript->initialized && pscript->pinterpreter->pClearEntry)
516     {
517         temp = pcurrentscript;
518         pcurrentscript = pscript;
519 
520         ScriptVariant_Init(&tempvar);
521         ScriptVariant_ChangeType(&tempvar, VT_INTEGER);
522         tempvar.lVal = (LONG)localclear;
523         Script_Set_Local_Variant(pscript, "localclear", &tempvar);
524         Interpreter_Reset(pscript->pinterpreter);
525         pscript->pinterpreter->pCurrentInstruction = pscript->pinterpreter->pClearEntry;
526         if(FAILED( Interpreter_EvaluateCall(pscript->pinterpreter)))
527         {
528             borShutdown(1, "Fatal: failed to execute 'clear' in script %s %s", pscript->pinterpreter->theSymbolTable.name, pscript->comment ? pscript->comment : "");
529         }
530         pscript->pinterpreter->bReset = FALSE; // not needed, perhaps
531         ScriptVariant_Clear(&tempvar);
532         Script_Set_Local_Variant(pscript, "localclear", &tempvar);
533         pcurrentscript = temp;
534     }
535 
536     if(localclear && pscript->varlist)
537     {
538         if(localclear == 2)
539         {
540             Varlist_Clear(pscript->varlist);
541             free(pscript->varlist);
542             pscript->varlist = NULL;
543         }
544         else
545         {
546             Varlist_Cleanup(pscript->varlist);
547         }
548     }
549     if(!pscript->initialized)
550     {
551         return;
552     }
553 
554     //if it is the owner, free the interpreter
555     if(pscript->pinterpreter && pscript->interpreterowner)
556     {
557         Interpreter_Clear(pscript->pinterpreter);
558         free(pscript->pinterpreter);
559         pscript->pinterpreter = NULL;
560         if(pscript->comment)
561         {
562             free(pscript->comment);
563         }
564         pscript->comment = NULL;
565     }
566     pvars = pscript->varlist; // in game clear(localclear!=2) just keep this value
567     memset(pscript, 0, sizeof(*pscript));
568     pscript->varlist = pvars; // copy it back
569 }
570 
571 //append part of the script
572 //Because the script might not be initialized in 1 time.
Script_AppendText(Script * pscript,char * text,char * path)573 int Script_AppendText(Script *pscript, char *text, char *path)
574 {
575     int success;
576 
577     //printf(text);
578     Interpreter_Reset(pscript->pinterpreter);
579 
580     success = SUCCEEDED(Interpreter_ParseText(pscript->pinterpreter, text, 1, path));
581 
582     return success;
583 }
584 
585 /* Replace string constants with enum constants at compile time to speed up
586    script execution. */
Script_MapStringConstants(Instruction * pInstruction)587 int Script_MapStringConstants(Instruction *pInstruction)
588 {
589     ScriptVariant **params;
590     int paramCount;
591     int (*pMapstrings)(ScriptVariant **, int);
592 
593     if(pInstruction->functionRef)
594     {
595         params = (ScriptVariant **)pInstruction->theRefList->solidlist;
596         paramCount = (int)pInstruction->theRef->lVal;
597         assert(paramCount <= 32);
598         // Get the pointer to the correct mapstrings function, if one exists.
599         pMapstrings = Script_GetStringMapFunction(pInstruction->functionRef);
600         if(pMapstrings)
601         {
602             // Call the mapstrings function.
603             if(!pMapstrings(params, paramCount))
604             {
605                 return 0;
606             }
607         }
608     }
609 
610     return 1;
611 }
612 
613 //should be called only once after parsing text
Script_Compile(Script * pscript)614 int Script_Compile(Script *pscript)
615 {
616     int result;
617     if(!pscript || !pscript->pinterpreter)
618     {
619         return 1;
620     }
621     //Interpreter_OutputPCode(pscript->pinterpreter, "code");
622     result = SUCCEEDED(Interpreter_CompileInstructions(pscript->pinterpreter));
623     if(!result)
624     {
625         borShutdown(1, "Can't compile script '%s' %s\n", pscript->pinterpreter->theSymbolTable.name, pscript->comment ? pscript->comment : "");
626     }
627 
628     pscript->pinterpreter->bReset = FALSE;
629     execute_init_method(pscript, 0, 1);
630     return result;
631 }
632 
Script_IsInitialized(Script * pscript)633 int Script_IsInitialized(Script *pscript)
634 {
635     //if(pscript && pscript->initialized) pcurrentscript = pscript; //used by local script functions
636     return pscript->initialized;
637 }
638 
639 //execute the script
Script_Execute(Script * pscript)640 int Script_Execute(Script *pscript)
641 {
642     int result, nested;
643     extern int no_cmd_compatible;
644     Script *temp = pcurrentscript;
645     Interpreter tinter, *pinter;
646     pcurrentscript = pscript; //used by local script functions
647     nested = pscript->pinterpreter->bReset;
648     if(no_nested_script && nested)
649     {
650         result = 1;
651     }
652     else
653     {
654         pinter = pscript->pinterpreter;
655         if(nested && no_cmd_compatible)
656         {
657             tinter = *pinter;
658         }
659         Interpreter_Reset(pinter);
660         result = (int)SUCCEEDED(Interpreter_EvaluateImmediate(pinter));
661         if(nested && no_cmd_compatible)
662         {
663             *pinter = tinter;
664         }
665         else if(nested)
666         {
667             pinter->bReset = FALSE;
668         }
669     }
670     pcurrentscript = temp;
671     if(!result)
672     {
673         borShutdown(1, "There's an exception while executing script '%s' %s", pscript->pinterpreter->theSymbolTable.name, pscript->comment ? pscript->comment : "");
674     }
675     return result;
676 }
677 
678 static s_collision_attack attack;
679 
680 //////////////////////////////////////////////////////////
681 ////////////   system functions
682 //////////////////////////////////////////////////////////
683 //isempty(var);
system_isempty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)684 HRESULT system_isempty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
685 {
686     if(paramCount != 1)
687     {
688         *pretvar = NULL;
689         return E_FAIL;
690     }
691 
692     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
693 
694     (*pretvar)->lVal = (LONG)( (varlist[0])->vt == VT_EMPTY );
695 
696     return S_OK;
697 }
698 //NULL();
system_NULL(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)699 HRESULT system_NULL(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
700 {
701     ScriptVariant_Clear(*pretvar);
702 
703     return S_OK;
704 }
system_exit(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)705 HRESULT system_exit(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
706 {
707     *pretvar = NULL;
708     pcurrentscript->pinterpreter->bReset = FALSE;
709     return S_OK;
710 }
system_rand(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)711 HRESULT system_rand(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
712 {
713     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
714     (*pretvar)->lVal = (LONG)rand32();
715     return S_OK;
716 }
system_srand(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)717 HRESULT system_srand(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
718 {
719     LONG ltemp;
720 
721     *pretvar = NULL;
722     if(paramCount != 1)
723     {
724         return E_FAIL;
725     }
726     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
727     {
728         return E_FAIL;
729     }
730 
731     srand32(ltemp);
732     return S_OK;
733 }
734 //getglobalvar(varname);
system_getglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)735 HRESULT system_getglobalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
736 {
737     LONG ltemp;
738     ScriptVariant *ptmpvar;
739 
740     if(paramCount != 1)
741     {
742         goto ggv_error;
743     }
744 
745     if(varlist[0]->vt == VT_STR)
746     {
747         ptmpvar = Varlist_GetByName(&global_var_list, StrCache_Get(varlist[0]->strVal));
748     }
749     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
750     {
751         ptmpvar = Varlist_GetByIndex(&global_var_list, (LONG)ltemp);
752     }
753     else
754     {
755         goto ggv_error;
756     }
757 
758     if(ptmpvar)
759     {
760         ScriptVariant_Copy(*pretvar,  ptmpvar);
761     }
762     else
763     {
764         ScriptVariant_Clear(*pretvar);
765     }
766     return S_OK;
767 
768 ggv_error:
769     *pretvar = NULL;
770     return E_FAIL;
771 }
772 //setglobalvar(varname, value);
system_setglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)773 HRESULT system_setglobalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
774 {
775     LONG ltemp;
776     if(paramCount < 2)
777     {
778         goto sgv_error;
779     }
780 
781     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
782 
783     if(varlist[0]->vt == VT_STR)
784     {
785         (*pretvar)->lVal = (LONG)Varlist_SetByName(&global_var_list, StrCache_Get(varlist[0]->strVal), varlist[1]);
786     }
787     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
788     {
789         (*pretvar)->lVal = (LONG)Varlist_SetByIndex(&global_var_list, (LONG)ltemp, varlist[1]);
790     }
791     else
792     {
793         goto sgv_error;
794     }
795 
796     return S_OK;
797 sgv_error:
798     *pretvar = NULL;
799     return E_FAIL;
800 }
801 //getlocalvar(varname);
system_getlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)802 HRESULT system_getlocalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
803 {
804     LONG ltemp;
805     ScriptVariant *ptmpvar;
806 
807     if(paramCount != 1)
808     {
809         goto glv_error;
810     }
811 
812     if(varlist[0]->vt == VT_STR)
813     {
814         ptmpvar = Varlist_GetByName(pcurrentscript->varlist, StrCache_Get(varlist[0]->strVal));
815     }
816     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
817     {
818         ptmpvar = Varlist_GetByIndex(pcurrentscript->varlist, (LONG)ltemp);
819     }
820     else
821     {
822         goto glv_error;
823     }
824 
825     if(ptmpvar)
826     {
827         ScriptVariant_Copy(*pretvar,  ptmpvar);
828     }
829     else
830     {
831         ScriptVariant_Clear(*pretvar);
832     }
833     return S_OK;
834 
835 glv_error:
836     *pretvar = NULL;
837     return E_FAIL;
838 }
839 //setlocalvar(varname, value);
system_setlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)840 HRESULT system_setlocalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
841 {
842     LONG ltemp;
843     if(paramCount < 2)
844     {
845         goto slv_error;
846     }
847 
848     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
849 
850     if(varlist[0]->vt == VT_STR)
851     {
852         (*pretvar)->lVal = (LONG)Varlist_SetByName(pcurrentscript->varlist, StrCache_Get(varlist[0]->strVal), varlist[1]);
853     }
854     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
855     {
856         (*pretvar)->lVal = (LONG)Varlist_SetByIndex(pcurrentscript->varlist, (LONG)ltemp, varlist[1]);
857     }
858     else
859     {
860         goto slv_error;
861     }
862 
863     return S_OK;
864 slv_error:
865     *pretvar = NULL;
866     return E_FAIL;
867 }
868 //clearlocalvar();
system_clearlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)869 HRESULT system_clearlocalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
870 {
871     *pretvar = NULL;
872     Varlist_Cleanup(pcurrentscript->varlist);
873     return S_OK;
874 }
875 //clearglobalvar();
system_clearglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)876 HRESULT system_clearglobalvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
877 {
878     *pretvar = NULL;
879     Varlist_Cleanup(&global_var_list);
880     return S_OK;
881 }
882 
883 //free();
system_free(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)884 HRESULT system_free(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
885 {
886     *pretvar = NULL;
887     if(paramCount < 1)
888     {
889         return E_FAIL;
890     }
891     if(List_Includes(&scriptheap, varlist[0]->ptrVal))
892     {
893         _freeheapnode(List_Retrieve(&scriptheap));
894         // a script's ondestroy() may free something else and change the list
895         // position, so set the position to this variant again
896         List_Includes(&scriptheap, varlist[0]->ptrVal);
897         List_Remove(&scriptheap);
898         return S_OK;
899     }
900     return E_FAIL;
901 }
902 
903 //typeof(v);
system_typeof(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)904 HRESULT system_typeof(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
905 {
906     if(paramCount < 1)
907     {
908         *pretvar = NULL;
909         return E_FAIL;
910     }
911     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
912     (*pretvar)->lVal = (LONG)varlist[0]->vt;
913     return S_OK;
914 }
915 
916 //////////////////////////////////////////////////////////
917 ////////////   openbor functions
918 //////////////////////////////////////////////////////////
919 
920 //check openborscript.h for systemvariant_enum
921 
922 // arranged list, for searching
923 static const char *svlist[] =
924 {
925     "background",
926     "blockade",
927     "bossescount",
928     "branchname",
929     "cheats",
930     "count_enemies",
931     "count_entities",
932     "count_npcs",
933     "count_players",
934     "current_branch",
935     "current_level",
936     "current_palette",
937     "current_scene",
938     "current_set",
939     "current_stage",
940 	"drawmethod_default",
941     "effectvol",
942     "elapsed_time",
943     "ent_max",
944     "fps",
945     "freeram",
946     "game_paused",
947     "game_speed",
948     "game_time",
949     "gfx_x_offset",
950     "gfx_y_offset",
951     "gfx_y_offset_adj",
952     "hresolution",
953     "in_cheat_options",
954     "in_control_options",
955     "in_enginecreditsscreen",
956     "in_gameoverscreen",
957     "in_halloffamescreen",
958     "in_level",
959     "in_load_game",
960     "in_menuscreen",
961     "in_new_game",
962     "in_options",
963     "in_selectscreen",
964     "in_showcomplete",
965     "in_sound_options",
966     "in_start_game",
967     "in_system_options",
968     "in_titlescreen",
969     "in_video_options",
970 	"lasthit_attack",
971 	"lasthit_attacker",
972 	"lasthit_target",
973 	"lasthita",
974     "lasthitc",
975     "lasthitt",
976     "lasthitx",
977     "lasthity",
978     "lasthitz",
979     "levelheight",
980     "levelpos",
981     "levelwidth",
982     "lightx",
983     "lightz",
984     "maxanimations",
985     "maxattacktypes",
986     "maxentityvars",
987     "maxglobalvars",
988     "maxindexedvars",
989     "maxplayers",
990     "maxscriptvars",
991     "maxsoundchannels",
992     "models_cached",
993     "models_loaded",
994     "musicvol",
995     "nofadeout",
996     "nogameover",
997     "nohof",
998     "nojoin",
999     "nopause",
1000     "nosave",
1001     "noscreenshot",
1002     "noshowcomplete",
1003     "numbasemaps",
1004     "numbosses",
1005     "numholes",
1006     "numlayers",
1007     "numpalettes",
1008     "numwalls",
1009     "pakname",
1010     "pause",
1011     "pixelformat",
1012     "player",
1013     "player1",
1014     "player2",
1015     "player3",
1016     "player4",
1017     "player_max_z",
1018     "player_min_z",
1019     "porting",
1020     "sample_play_id",
1021     "scrollmaxx",
1022     "scrollmaxz",
1023     "scrollminx",
1024     "scrollminz",
1025     "self",
1026     "sets_count",
1027     "shadowalpha",
1028     "shadowcolor",
1029     "shadowopacity",
1030     "skiptoset",
1031     "slowmotion",
1032     "slowmotion_duration",
1033     "smartbomber",
1034     "soundvol",
1035     "textbox",
1036     "ticks",
1037     "totalram",
1038     "usedram",
1039     "viewporth",
1040     "viewportw",
1041     "viewportx",
1042     "viewporty",
1043     "vresolution",
1044     "vscreen",
1045     "waiting",
1046     "xpos",
1047     "ypos",
1048 };
1049 
1050 
1051 // ===== openborvariant =====
mapstrings_systemvariant(ScriptVariant ** varlist,int paramCount)1052 int mapstrings_systemvariant(ScriptVariant **varlist, int paramCount)
1053 {
1054     char *propname;
1055     int prop;
1056 
1057 
1058     MAPSTRINGS(varlist[0], svlist, _sv_the_end,
1059                "openborvariant: System variable name not found: '%s'\n");
1060 
1061     return 1;
1062 }
1063 
1064 //sample function, used for getting a system variant
1065 //openborvariant(varname);
openbor_systemvariant(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1066 HRESULT openbor_systemvariant(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1067 {
1068     //used for getting the index from the enum of properties
1069     int variantindex = -1;
1070     //the paramCount used for checking.
1071     //check it first so the engine wont crash if the list is empty
1072     if(paramCount != 1)
1073     {
1074         goto systemvariant_error;
1075     }
1076     //call this function's mapstrings function to map string constants to enum values
1077     mapstrings_systemvariant(varlist, paramCount);
1078     //the variant name should be here
1079     //you can check the argument type if you like
1080     if(varlist[0]->vt == VT_INTEGER)
1081     {
1082         variantindex = varlist[0]->lVal;
1083     }
1084     else
1085     {
1086         goto systemvariant_error;
1087     }
1088     ///////these should be your get method, ///////
1089     ScriptVariant_Clear(*pretvar);
1090     if(getsyspropertybyindex(*pretvar, variantindex))
1091     {
1092         return S_OK;
1093     }
1094     //else if
1095     //////////////////////////////////////////////
1096 systemvariant_error:
1097     *pretvar = NULL;
1098     // we have finshed, so return
1099     return E_FAIL;
1100 }
1101 
1102 
1103 //used for changing a system variant
1104 //setopenborvariant(varname, value);
openbor_setsystemvariant(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1105 HRESULT openbor_setsystemvariant(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1106 {
1107     //used for getting the enum constant corresponding to the desired variable
1108     int variantindex = 0;
1109     //reference to the arguments
1110     ScriptVariant *arg = NULL;
1111     //the paramCount used for checking.
1112     //check it first so the engine wont crash if the list is empty
1113     if(paramCount != 2)
1114     {
1115         goto changesystemvariant_error;
1116     }
1117     // map string constants to enum constants for speed
1118     mapstrings_systemvariant(varlist, paramCount);
1119     //get the 1st argument
1120     arg = varlist[0];
1121     //the variant name should be here
1122     //you can check the argument type if you like
1123     if(arg->vt == VT_INTEGER)
1124     {
1125         variantindex = arg->lVal;
1126     }
1127     else
1128     {
1129         goto changesystemvariant_error;
1130     }
1131 
1132     if(changesyspropertybyindex(variantindex, varlist[1]))
1133     {
1134         return S_OK;
1135     }
1136 changesystemvariant_error:
1137     *pretvar = NULL;
1138     // we have finshed, so return
1139     return E_FAIL;
1140 
1141 }
1142 
1143 // use font_printf to draw string
1144 //drawstring(x, y, font, string, z);
openbor_drawstring(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1145 HRESULT openbor_drawstring(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1146 {
1147     int i;
1148     char buf[MAX_BUFFER_LEN];
1149     LONG value[4];
1150     *pretvar = NULL;
1151 
1152     if(paramCount < 4)
1153     {
1154         goto drawstring_error;
1155     }
1156 
1157     for(i = 0; i < 3; i++)
1158     {
1159         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
1160         {
1161             goto drawstring_error;
1162         }
1163     }
1164     if(paramCount > 4)
1165     {
1166         if(FAILED(ScriptVariant_IntegerValue(varlist[4], value + 3)))
1167         {
1168             goto drawstring_error;
1169         }
1170     }
1171     else
1172     {
1173         value[3] = 0;
1174     }
1175     ScriptVariant_ToString(varlist[3], buf);
1176     font_printf((int)value[0], (int)value[1], (int)value[2], (int)value[3], "%s", buf);
1177     return S_OK;
1178 
1179 drawstring_error:
1180     printf("First 3 values must be integer values and 4th value a string: drawstring(int x, int y, int font, value)\n");
1181     return E_FAIL;
1182 }
1183 
1184 //use screen_printf
1185 //drawstringtoscreen(screen, x, y, font, string);
openbor_drawstringtoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1186 HRESULT openbor_drawstringtoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1187 {
1188     int i;
1189     s_screen *scr;
1190     char buf[MAX_BUFFER_LEN];
1191     LONG value[3];
1192     *pretvar = NULL;
1193 
1194     if(paramCount != 5)
1195     {
1196         goto drawstring_error;
1197     }
1198 
1199     if(varlist[0]->vt != VT_PTR)
1200     {
1201         goto drawstring_error;
1202     }
1203     scr = (s_screen *)varlist[0]->ptrVal;
1204     if(!scr)
1205     {
1206         goto drawstring_error;
1207     }
1208 
1209     for(i = 0; i < 3; i++)
1210     {
1211         if(FAILED(ScriptVariant_IntegerValue(varlist[i + 1], value + i)))
1212         {
1213             goto drawstring_error;
1214         }
1215     }
1216 
1217     ScriptVariant_ToString(varlist[4], buf);
1218     screen_printf(scr, (int)value[0], (int)value[1], (int)value[2], "%s", buf);
1219     return S_OK;
1220 
1221 drawstring_error:
1222     printf("Function needs a valid screen handle, 3 integers and a string value: drawstringtoscreen(screen, int font, value)\n");
1223     return E_FAIL;
1224 }
1225 
1226 // debug purpose
1227 //log(string);
openbor_log(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1228 HRESULT openbor_log(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1229 {
1230     char buf[MAX_BUFFER_LEN];
1231     *pretvar = NULL;
1232 
1233     if(paramCount != 1)
1234     {
1235         goto drawstring_error;
1236     }
1237 
1238     ScriptVariant_ToString(varlist[0], buf);
1239     printf("%s", buf);
1240     return S_OK;
1241 
1242 drawstring_error:
1243     printf("Function needs 1 parameter: log(value)\n");
1244     return E_FAIL;
1245 }
1246 
1247 //drawbox(x, y, width, height, z, color, lut);
openbor_drawbox(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1248 HRESULT openbor_drawbox(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1249 {
1250     int i;
1251     LONG value[6], l;
1252     *pretvar = NULL;
1253     s_drawmethod dm;
1254 
1255     if(paramCount < 6)
1256     {
1257         goto drawbox_error;
1258     }
1259 
1260     for(i = 0; i < 6; i++)
1261     {
1262         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
1263         {
1264             goto drawbox_error;
1265         }
1266     }
1267 
1268     if(paramCount > 6)
1269     {
1270         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1271         {
1272             goto drawbox_error;
1273         }
1274     }
1275     else
1276     {
1277         l = -1;
1278     }
1279 
1280     if(l >= 0)
1281     {
1282         l %= MAX_BLENDINGS + 1;
1283     }
1284     if(drawmethod.flag)
1285     {
1286         dm = drawmethod;
1287     }
1288     else
1289     {
1290         dm = plainmethod;
1291     }
1292     dm.alpha = l;
1293     spriteq_add_box((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], (int)value[5], &dm);
1294 
1295     return S_OK;
1296 
1297 drawbox_error:
1298     printf("Function requires 6 integer values: drawbox(int x, int y, int width, int height, int z, int color, int lut)\n");
1299     return E_FAIL;
1300 }
1301 
1302 //drawboxtoscreen(screen, x, y, width, height, color, lut);
openbor_drawboxtoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1303 HRESULT openbor_drawboxtoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1304 {
1305     int i;
1306     s_screen *s;
1307     LONG value[5], l;
1308     *pretvar = NULL;
1309     s_drawmethod dm;
1310 
1311     if(paramCount < 6)
1312     {
1313         goto drawbox_error;
1314     }
1315 
1316     s = (s_screen *)varlist[0]->ptrVal;
1317 
1318     if(!s)
1319     {
1320         goto drawbox_error;
1321     }
1322 
1323     for(i = 1; i < 6; i++)
1324     {
1325         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
1326         {
1327             goto drawbox_error;
1328         }
1329     }
1330 
1331     if(paramCount > 6)
1332     {
1333         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1334         {
1335             goto drawbox_error;
1336         }
1337     }
1338     else
1339     {
1340         l = -1;
1341     }
1342 
1343     if(l >= 0)
1344     {
1345         l %= MAX_BLENDINGS + 1;
1346     }
1347     if(drawmethod.flag)
1348     {
1349         dm = drawmethod;
1350     }
1351     else
1352     {
1353         dm = plainmethod;
1354     }
1355     dm.alpha = l;
1356 
1357     putbox((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, &dm);
1358 
1359     return S_OK;
1360 
1361 drawbox_error:
1362     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");
1363     return E_FAIL;
1364 }
1365 
1366 //drawline(x1, y1, x2, y2, z, color, lut);
openbor_drawline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1367 HRESULT openbor_drawline(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1368 {
1369     int i;
1370     LONG value[6], l;
1371     *pretvar = NULL;
1372     s_drawmethod dm;
1373 
1374     if(paramCount < 6)
1375     {
1376         goto drawline_error;
1377     }
1378 
1379     for(i = 0; i < 6; i++)
1380     {
1381         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
1382         {
1383             goto drawline_error;
1384         }
1385     }
1386 
1387     if(paramCount > 6)
1388     {
1389         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1390         {
1391             goto drawline_error;
1392         }
1393     }
1394     else
1395     {
1396         l = -1;
1397     }
1398 
1399     if(l >= 0 )
1400     {
1401         l %= MAX_BLENDINGS + 1;
1402     }
1403     if(drawmethod.flag)
1404     {
1405         dm = drawmethod;
1406     }
1407     else
1408     {
1409         dm = plainmethod;
1410     }
1411     dm.alpha = l;
1412     spriteq_add_line((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], (int)value[5], &dm);
1413 
1414     return S_OK;
1415 
1416 drawline_error:
1417     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");
1418     return E_FAIL;
1419 }
1420 
1421 //drawlinetoscreen(screen, x1, y1, x2, y2, color, lut);
openbor_drawlinetoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1422 HRESULT openbor_drawlinetoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1423 {
1424     int i;
1425     LONG value[5], l;
1426     s_screen *s;
1427     *pretvar = NULL;
1428     s_drawmethod dm;
1429 
1430     if(paramCount < 6)
1431     {
1432         goto drawline_error;
1433     }
1434 
1435     s = (s_screen *)varlist[0]->ptrVal;
1436 
1437     if(!s)
1438     {
1439         goto drawline_error;
1440     }
1441 
1442     for(i = 1; i < 6; i++)
1443     {
1444         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
1445         {
1446             goto drawline_error;
1447         }
1448     }
1449 
1450     if(paramCount > 6)
1451     {
1452         if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1453         {
1454             goto drawline_error;
1455         }
1456     }
1457     else
1458     {
1459         l = -1;
1460     }
1461 
1462     if(l >= 0 )
1463     {
1464         l %= MAX_BLENDINGS + 1;
1465     }
1466     if(drawmethod.flag)
1467     {
1468         dm = drawmethod;
1469     }
1470     else
1471     {
1472         dm = plainmethod;
1473     }
1474     dm.alpha = l;
1475     putline((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, &dm);
1476 
1477     return S_OK;
1478 drawline_error:
1479     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");
1480     return E_FAIL;
1481 }
1482 
1483 //drawsprite(sprite, x, y, z, sortid);
openbor_drawsprite(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1484 HRESULT openbor_drawsprite(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1485 {
1486     int i;
1487     LONG value[4];
1488     s_sprite *spr;
1489     *pretvar = NULL;
1490 
1491     if(paramCount < 4)
1492     {
1493         goto drawsprite_error;
1494     }
1495     if(varlist[0]->vt != VT_PTR)
1496     {
1497         goto drawsprite_error;
1498     }
1499 
1500     spr = varlist[0]->ptrVal;
1501     if(!spr)
1502     {
1503         goto drawsprite_error;
1504     }
1505 
1506     value[3] = (LONG)0;
1507     for(i = 1; i < paramCount && i < 5; i++)
1508     {
1509         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
1510         {
1511             goto drawsprite_error;
1512         }
1513     }
1514 
1515     spriteq_add_frame((int)value[0], (int)value[1], (int)value[2], spr, &drawmethod, (int)value[3]);
1516 
1517     return S_OK;
1518 
1519 drawsprite_error:
1520     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");
1521     return E_FAIL;
1522 }
1523 
1524 //drawspritetoscreen(sprite, screen, x, y);
openbor_drawspritetoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1525 HRESULT openbor_drawspritetoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1526 {
1527     int i;
1528     LONG value[2];
1529     s_sprite *spr;
1530     s_screen *scr;
1531     *pretvar = NULL;
1532 
1533     if(paramCount < 4)
1534     {
1535         goto drawsprite_error;
1536     }
1537     if(varlist[0]->vt != VT_PTR)
1538     {
1539         goto drawsprite_error;
1540     }
1541     spr = varlist[0]->ptrVal;
1542     if(!spr)
1543     {
1544         goto drawsprite_error;
1545     }
1546 
1547     if(varlist[1]->vt != VT_PTR)
1548     {
1549         goto drawsprite_error;
1550     }
1551     scr = varlist[1]->ptrVal;
1552     if(!scr)
1553     {
1554         goto drawsprite_error;
1555     }
1556 
1557     for(i = 2; i < paramCount && i < 4; i++)
1558     {
1559         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 2)))
1560         {
1561             goto drawsprite_error;
1562         }
1563     }
1564 
1565     putsprite((int)value[0], (int)value[1], spr, scr, &drawmethod);
1566 
1567     return S_OK;
1568 
1569 drawsprite_error:
1570     printf("Function requires a valid sprite handle, a valid screen handle and 2 integer values: drawspritetoscreen(sprite, screen, int x, int y)\n");
1571     return E_FAIL;
1572 }
1573 
1574 //drawdot(x, y, z, color, lut);
openbor_drawdot(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1575 HRESULT openbor_drawdot(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1576 {
1577     int i;
1578     LONG value[4], l;
1579     *pretvar = NULL;
1580     s_drawmethod dm;
1581 
1582     if(paramCount < 4)
1583     {
1584         goto drawdot_error;
1585     }
1586 
1587     for(i = 0; i < 4; i++)
1588     {
1589         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
1590         {
1591             goto drawdot_error;
1592         }
1593     }
1594 
1595     if(paramCount > 4)
1596     {
1597         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
1598         {
1599             goto drawdot_error;
1600         }
1601     }
1602     else
1603     {
1604         l = -1;
1605     }
1606 
1607     if(l >= 0 )
1608     {
1609         l %= MAX_BLENDINGS + 1;
1610     }
1611     if(drawmethod.flag)
1612     {
1613         dm = drawmethod;
1614     }
1615     else
1616     {
1617         dm = plainmethod;
1618     }
1619     dm.alpha = l;
1620     spriteq_add_dot((int)value[0], (int)value[1], (int)value[2], (int)value[3], &dm);
1621 
1622     return S_OK;
1623 
1624 drawdot_error:
1625     printf("Function requires 4 integer values, 5th integer value is optional: drawdot(int x, int y, int z, int color, int lut)\n");
1626     return E_FAIL;
1627 }
1628 
1629 //drawdottoscreen(screen, x, y, color, lut);
openbor_drawdottoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1630 HRESULT openbor_drawdottoscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1631 {
1632     int i;
1633     LONG value[3], l;
1634     s_screen *s;
1635     *pretvar = NULL;
1636     s_drawmethod dm;
1637 
1638     if(paramCount < 4)
1639     {
1640         goto drawdot_error;
1641     }
1642 
1643     s = (s_screen *)varlist[0]->ptrVal;
1644 
1645     if(!s)
1646     {
1647         goto drawdot_error;
1648     }
1649 
1650     for(i = 1; i < 4; i++)
1651     {
1652         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
1653         {
1654             goto drawdot_error;
1655         }
1656     }
1657 
1658     if(paramCount > 4)
1659     {
1660         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
1661         {
1662             goto drawdot_error;
1663         }
1664     }
1665     else
1666     {
1667         l = -1;
1668     }
1669 
1670     if(l >= 0 )
1671     {
1672         l %= MAX_BLENDINGS + 1;
1673     }
1674     if(drawmethod.flag)
1675     {
1676         dm = drawmethod;
1677     }
1678     else
1679     {
1680         dm = plainmethod;
1681     }
1682     dm.alpha = l;
1683 
1684     putpixel((int)value[0], (int)value[1], (int)value[2], s, &dm);
1685 
1686     return S_OK;
1687 
1688 drawdot_error:
1689     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");
1690     return E_FAIL;
1691 }
1692 
1693 
1694 //drawscreen(screen, x, y, z, lut);
openbor_drawscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1695 HRESULT openbor_drawscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1696 {
1697     int i;
1698     LONG value[3], l;
1699     s_screen *s;
1700     s_drawmethod screenmethod;
1701     *pretvar = NULL;
1702 
1703     if(paramCount < 4)
1704     {
1705         goto drawscreen_error;
1706     }
1707 
1708     s = (s_screen *)varlist[0]->ptrVal;
1709 
1710     if(!s)
1711     {
1712         goto drawscreen_error;
1713     }
1714 
1715     for(i = 1; i < 4; i++)
1716     {
1717         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
1718         {
1719             goto drawscreen_error;
1720         }
1721     }
1722 
1723     if(paramCount > 4)
1724     {
1725         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
1726         {
1727             goto drawscreen_error;
1728         }
1729     }
1730     else
1731     {
1732         l = -1;
1733     }
1734 
1735     if(l >= 0 )
1736     {
1737         l %= MAX_BLENDINGS + 1;
1738     }
1739     if(paramCount <= 4)
1740     {
1741         screenmethod = drawmethod;
1742     }
1743     else
1744     {
1745         screenmethod = plainmethod;
1746         screenmethod.alpha = l;
1747         screenmethod.transbg = 1;
1748     }
1749 
1750     spriteq_add_screen((int)value[0], (int)value[1], (int)value[2], s, &screenmethod, 0);
1751 
1752     return S_OK;
1753 
1754 drawscreen_error:
1755     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");
1756     return E_FAIL;
1757 }
1758 
1759 //getindexedvar(int index);
openbor_getindexedvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1760 HRESULT openbor_getindexedvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1761 {
1762     return system_getglobalvar(varlist, pretvar, paramCount);
1763 }
1764 
1765 //setindexedvar(int index, var);
openbor_setindexedvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1766 HRESULT openbor_setindexedvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1767 {
1768     return system_setglobalvar(varlist, pretvar, paramCount);
1769 }
1770 
1771 //getscriptvar(int index);
openbor_getscriptvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1772 HRESULT openbor_getscriptvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1773 {
1774     return system_getlocalvar(varlist, pretvar, paramCount);
1775 }
1776 
1777 //setscriptvar(int index, var);
openbor_setscriptvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1778 HRESULT openbor_setscriptvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1779 {
1780     return system_setlocalvar(varlist, pretvar, paramCount);
1781 }
1782 
1783 //getentityvar(entity, int index);
openbor_getentityvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1784 HRESULT openbor_getentityvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1785 {
1786     LONG ltemp;
1787     ScriptVariant *ptmpvar;
1788     entity *ent;
1789 
1790     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
1791     {
1792         goto gev_error;
1793     }
1794 
1795     ent = (entity *)varlist[0]->ptrVal;
1796 
1797     if(varlist[1]->vt == VT_STR)
1798     {
1799         ptmpvar = Varlist_GetByName(ent->varlist, StrCache_Get(varlist[1]->strVal));
1800     }
1801     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
1802     {
1803         ptmpvar = Varlist_GetByIndex(ent->varlist, (LONG)ltemp);
1804     }
1805     else
1806     {
1807         goto gev_error;
1808     }
1809 
1810     if(ptmpvar)
1811     {
1812         ScriptVariant_Copy(*pretvar,  ptmpvar);
1813     }
1814     else
1815     {
1816         ScriptVariant_Clear(*pretvar);
1817     }
1818     return S_OK;
1819 
1820 gev_error:
1821     *pretvar = NULL;
1822     return E_FAIL;
1823 }
1824 
1825 //setentityvar(int index, var);
openbor_setentityvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1826 HRESULT openbor_setentityvar(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1827 {
1828     LONG ltemp;
1829     entity *ent;
1830 
1831     if(paramCount < 3 || varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
1832     {
1833         goto sev_error;
1834     }
1835 
1836     ent = (entity *)varlist[0]->ptrVal;
1837 
1838     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1839 
1840     if(varlist[1]->vt == VT_STR)
1841     {
1842         (*pretvar)->lVal = (LONG)Varlist_SetByName(ent->varlist, StrCache_Get(varlist[1]->strVal), varlist[2]);
1843     }
1844     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
1845     {
1846         (*pretvar)->lVal = (LONG)Varlist_SetByIndex(ent->varlist, (LONG)ltemp, varlist[2]);
1847     }
1848     else
1849     {
1850         goto sev_error;
1851     }
1852 
1853     return S_OK;
1854 sev_error:
1855     *pretvar = NULL;
1856     return E_FAIL;
1857 }
1858 
openbor_getmodelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1859 HRESULT openbor_getmodelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1860 {
1861     int iArg;
1862 
1863     if(paramCount < 2)
1864     {
1865         *pretvar = NULL;
1866         return E_FAIL;
1867     }
1868 
1869     if((varlist[0]->vt != VT_INTEGER && varlist[0]->vt != VT_STR) || varlist[1]->vt != VT_INTEGER)
1870     {
1871         printf("\n Error, getmodelproperty({model}, {property}): Invalid or missing parameter. Getmodelproperty must be passed valid {model} and {property} indexes.\n");
1872     }
1873 
1874     iArg = varlist[0]->vt == VT_INTEGER ? varlist[0]->lVal : get_cached_model_index(StrCache_Get(varlist[0]->strVal));
1875 
1876     if(iArg < 0 || iArg >= models_cached)
1877     {
1878         return E_FAIL;
1879     }
1880 
1881     switch (varlist[1]->lVal)
1882     {
1883     case 0:                                                    //Loaded?
1884     {
1885         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1886         (*pretvar)->lVal = (LONG)model_cache[iArg].loadflag;
1887         break;
1888     }
1889     case 1:
1890     {
1891         ScriptVariant_ChangeType(*pretvar, VT_PTR);
1892         (*pretvar)->ptrVal = (VOID *)model_cache[iArg].model;
1893     }
1894     case 2:
1895     {
1896         ScriptVariant_ChangeType(*pretvar, VT_STR);
1897         (*pretvar)->strVal = StrCache_CreateNewFrom(model_cache[iArg].name);
1898         break;
1899     }
1900     case 3:
1901     {
1902         ScriptVariant_ChangeType(*pretvar, VT_STR);
1903         (*pretvar)->strVal = StrCache_CreateNewFrom(model_cache[iArg].path);
1904         break;
1905     }
1906     case 4:                                                    //Loaded?
1907     {
1908         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1909         (*pretvar)->lVal = (LONG)model_cache[iArg].selectable;
1910         break;
1911     }
1912     }
1913 
1914     return S_OK;
1915 }
1916 
openbor_changemodelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1917 HRESULT openbor_changemodelproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
1918 {
1919     int iArg;
1920     LONG ltemp;
1921 
1922     if(paramCount < 2)
1923     {
1924         *pretvar = NULL;
1925         return E_FAIL;
1926     }
1927 
1928     if((varlist[0]->vt != VT_INTEGER && varlist[0]->vt != VT_STR) || varlist[1]->vt != VT_INTEGER)
1929     {
1930         printf("\n Error, changemodelproperty({model}, {property}, {value}): Invalid or missing parameter. Changemodelproperty must be passed valid {model}, {property} and {value}.\n");
1931     }
1932 
1933     iArg = varlist[0]->vt == VT_INTEGER ? varlist[0]->lVal : get_cached_model_index(StrCache_Get(varlist[0]->strVal));
1934 
1935     if(iArg < 0 || iArg >= models_cached)
1936     {
1937         return E_FAIL;
1938     }
1939 
1940     switch (varlist[1]->lVal)
1941     {
1942     case 0:                                                    //Loaded?
1943     {
1944         /*
1945         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
1946         	model_cache[iArg].loadflag = (LONG)ltemp;
1947         else (*pretvar)->lVal = (LONG)0;
1948         break;
1949         */
1950     }
1951     case 1:
1952     {
1953         /*
1954         if(varlist[2]->vt != VT_STR)
1955         {
1956         	printf("You must give a string value for {value}.\n");
1957         	goto changeentityproperty_error;
1958         }
1959         strcpy(model_cache[iArg].model, (char*)StrCache_Get(varlist[2]->strVal));
1960         (*pretvar)->lVal = (LONG)1;
1961         break;
1962         */
1963     }
1964     case 2:
1965     {
1966         /*
1967         if(varlist[2]->vt != VT_STR)
1968         {
1969         	printf("You must give a string value for {value}.\n");
1970         	goto changeentityproperty_error;
1971         }
1972         strcpy(model_cache[iArg].name, (char*)StrCache_Get(varlist[2]->strVal));
1973         (*pretvar)->lVal = (LONG)1;
1974         break;
1975         */
1976     }
1977     case 3:
1978     {
1979         /*
1980         if(varlist[2]->vt != VT_STR)
1981         {
1982         	printf("You must give a string value for {value}.\n");
1983         	goto changeentityproperty_error;
1984         }
1985         strcpy(model_cache[iArg].path, (char*)StrCache_Get(varlist[2]->strVal));
1986         (*pretvar)->lVal = (LONG)1;
1987         break;
1988         */
1989     }
1990     case 4:
1991     {
1992         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
1993         {
1994             model_cache[iArg].selectable = (LONG)ltemp;
1995         }
1996         else
1997         {
1998             (*pretvar)->lVal = (LONG)0;
1999         }
2000         break;
2001     }
2002     }
2003 
2004     return S_OK;
2005 }
2006 
2007 // ===== getentityproperty =====
2008 enum entityproperty_enum
2009 {
2010     _ep_a,
2011     _ep_aggression,
2012     _ep_aiattack,
2013     _ep_aiflag,
2014     _ep_aimove,
2015     _ep_alpha,
2016     _ep_animal,
2017     _ep_animating,
2018     _ep_animation,
2019     _ep_animation_handle,
2020     _ep_animationid,
2021     _ep_animheight,
2022     _ep_animhits,
2023     _ep_animnum,
2024     _ep_animpos,
2025     _ep_animvalid,
2026     _ep_antigrab,
2027     _ep_antigravity,
2028     _ep_attackid,
2029     _ep_attacking,
2030     _ep_attackthrottle,
2031     _ep_attackthrottletime,
2032     _ep_autokill,
2033     _ep_base,
2034     _ep_bbox,
2035     _ep_bind,
2036     _ep_blink,
2037     _ep_blockback,
2038     _ep_blockodds,
2039     _ep_blockpain,
2040     _ep_boss,
2041     _ep_bounce,
2042     _ep_bound,
2043     _ep_candamage,
2044     _ep_chargerate,
2045     _ep_collidedentity,
2046     _ep_colourmap,
2047     _ep_colourtable,
2048     _ep_combostep,
2049     _ep_combotime,
2050     _ep_custom_target,
2051     _ep_damage_on_landing,
2052     _ep_dead,
2053     _ep_defaultmodel,
2054     _ep_defaultname,
2055     _ep_defense,
2056     _ep_destx,
2057     _ep_destz,
2058     _ep_detect,
2059     _ep_die_on_landing,
2060     _ep_direction,
2061     _ep_dropframe,
2062     _ep_edelay,
2063     _ep_edge,
2064     _ep_edgerange,
2065     _ep_energycost,
2066     _ep_entitypushing,
2067     _ep_escapecount,
2068     _ep_escapehits,
2069     _ep_exists,
2070     _ep_facing,
2071     _ep_falldie,
2072     _ep_flash,
2073     _ep_freezetime,
2074     _ep_frozen,
2075     _ep_gfxshadow,
2076     _ep_grabbing,
2077     _ep_grabforce,
2078     _ep_guardpoints,
2079     _ep_hasplatforms,
2080     _ep_health,
2081     _ep_height,
2082     _ep_hitbyid,
2083     _ep_hitheadplatform,
2084     _ep_hitwall,
2085     _ep_hmapl,
2086     _ep_hmapu,
2087     _ep_hostile,
2088     _ep_icon,
2089     _ep_iconposition,
2090     _ep_invincible,
2091     _ep_invinctime,
2092     _ep_jugglepoints,
2093     _ep_jumpheight,
2094     _ep_jumpmovex,
2095     _ep_jumpmovez,
2096     _ep_jumpspeed,
2097     _ep_knockdowncount,
2098     _ep_komap,
2099     _ep_landedplatform,
2100     _ep_landframe,
2101     _ep_lifeposition,
2102     _ep_lifespancountdown,
2103     _ep_link,
2104     _ep_map,
2105     _ep_mapcount,
2106     _ep_mapdefault,
2107     _ep_maps,
2108     _ep_maptime,
2109     _ep_maxguardpoints,
2110     _ep_maxhealth,
2111     _ep_maxjugglepoints,
2112     _ep_maxmp,
2113     _ep_model,
2114     _ep_movex,
2115     _ep_movez,
2116     _ep_mp,
2117     _ep_mpdroprate,
2118     _ep_mprate,
2119     _ep_mpset,
2120     _ep_mpstable,
2121     _ep_mpstableval,
2122     _ep_name,
2123     _ep_nameposition,
2124     _ep_nextanim,
2125     _ep_nextmove,
2126     _ep_nextthink,
2127     _ep_no_adjust_base,
2128     _ep_noaicontrol,
2129     _ep_nodieblink,
2130     _ep_nodrop,
2131     _ep_nograb,
2132     _ep_nohithead,
2133     _ep_nolife,
2134     _ep_nopain,
2135     _ep_numweapons,
2136     _ep_offense,
2137     _ep_offscreen_noatk_factor,
2138     _ep_offscreenkill,
2139     _ep_opponent,
2140     _ep_owner,
2141     _ep_pain_time,
2142     _ep_parent,
2143     _ep_path,
2144     _ep_pathfindstep,
2145     _ep_playerindex,
2146     _ep_position,
2147     _ep_prevanimationid,
2148     _ep_projectile,
2149     _ep_projectilehit,
2150     _ep_pushingfactor,
2151     _ep_range,
2152     _ep_releasetime,
2153     _ep_running,
2154     _ep_rush_count,
2155     _ep_rush_tally,
2156     _ep_rush_time,
2157     _ep_score,
2158     _ep_scroll,
2159     _ep_seal,
2160     _ep_sealtime,
2161     _ep_setlayer,
2162     _ep_shadowbase,
2163     _ep_sortid,
2164     _ep_spawntype,
2165     _ep_speed,
2166     _ep_sprite,
2167     _ep_spritea,
2168     _ep_stalltime,
2169     _ep_staydown,
2170     _ep_staydownatk,
2171     _ep_stealth,
2172     _ep_subentity,
2173     _ep_subject_to_basemap,
2174     _ep_subject_to_gravity,
2175     _ep_subject_to_hole,
2176     _ep_subject_to_maxz,
2177     _ep_subject_to_minz,
2178     _ep_subject_to_obstacle,
2179     _ep_subject_to_platform,
2180     _ep_subject_to_screen,
2181     _ep_subject_to_wall,
2182     _ep_subtype,
2183     _ep_takeaction,
2184     _ep_think,
2185     _ep_thold,
2186     _ep_throwdamage,
2187     _ep_throwdist,
2188     _ep_throwframewait,
2189     _ep_throwheight,
2190     _ep_tosstime,
2191     _ep_tossv,
2192     _ep_trymove,
2193     _ep_type,
2194     _ep_velocity,
2195     _ep_vulnerable,
2196     _ep_walkoffmovex,
2197     _ep_walkoffmovez,
2198     _ep_weapent,
2199     _ep_weaploss,
2200     _ep_weapnum,
2201     _ep_weapon,
2202     _ep_x,
2203     _ep_xdir,
2204     _ep_y,
2205     _ep_z,
2206     _ep_zdir,
2207     _ep_the_end,
2208 };
2209 
2210 // arranged list, for searching
2211 static const char *eplist[] =
2212 {
2213     "a",
2214     "aggression",
2215     "aiattack",
2216     "aiflag",
2217     "aimove",
2218     "alpha",
2219     "animal",
2220     "animating",
2221     "animation",
2222     "animation.handle",
2223     "animationid",
2224     "animheight",
2225     "animhits",
2226     "animnum",
2227     "animpos",
2228     "animvalid",
2229     "antigrab",
2230     "antigravity",
2231     "attackid",
2232     "attacking",
2233     "attackthrottle",
2234     "attackthrottletime",
2235     "autokill",
2236     "base",
2237     "bbox",
2238     "binding",
2239     "blink",
2240     "blockback",
2241     "blockodds",
2242     "blockpain",
2243     "boss",
2244     "bounce",
2245     "bound",
2246     "candamage",
2247     "chargerate",
2248     "collidedentity",
2249     "colourmap",
2250     "colourtable",
2251     "combostep",
2252     "combotime",
2253     "custom_target",
2254     "damage_on_landing",
2255     "dead",
2256     "defaultmodel",
2257     "defaultname",
2258     "defense",
2259     "destx",
2260     "destz",
2261     "detect",
2262     "die_on_landing",
2263     "direction",
2264     "dropframe",
2265     "edelay",
2266     "edge",
2267     "edgerange",
2268     "energycost",
2269     "entitypushing",
2270     "escapecount",
2271     "escapehits",
2272     "exists",
2273     "facing",
2274     "falldie",
2275     "flash",
2276     "freezetime",
2277     "frozen",
2278     "gfxshadow",
2279     "grabbing",
2280     "grabforce",
2281     "guardpoints",
2282     "hasplatforms",
2283     "health",
2284     "height",
2285     "hitbyid",
2286     "hitheadplatform",
2287     "hitwall",
2288     "hmapl",
2289     "hmapu",
2290     "hostile",
2291     "icon",
2292     "iconposition",
2293     "invincible",
2294     "invinctime",
2295     "jugglepoints",
2296     "jumpheight",
2297     "jumpmovex",
2298     "jumpmovez",
2299     "jumpspeed",
2300     "knockdowncount",
2301     "komap",
2302     "landedplatform",
2303     "landframe",
2304     "lifeposition",
2305     "lifespancountdown",
2306     "link",
2307     "map",
2308     "mapcount",
2309     "mapdefault",
2310     "maps",
2311     "maptime",
2312     "maxguardpoints",
2313     "maxhealth",
2314     "maxjugglepoints",
2315     "maxmp",
2316     "model",
2317     "movex",
2318     "movez",
2319     "mp",
2320     "mpdroprate",
2321     "mprate",
2322     "mpset",
2323     "mpstable",
2324     "mpstableval",
2325     "name",
2326     "nameposition",
2327     "nextanim",
2328     "nextmove",
2329     "nextthink",
2330     "no_adjust_base",
2331     "noaicontrol",
2332     "nodieblink",
2333     "nodrop",
2334     "nograb",
2335     "nohithead",
2336     "nolife",
2337     "nopain",
2338     "numweapons",
2339     "offense",
2340     "offscreennoatkfactor",
2341     "offscreenkill",
2342     "opponent",
2343     "owner",
2344     "pain_time",
2345     "parent",
2346     "path",
2347     "pathfindstep",
2348     "playerindex",
2349     "position",
2350     "prevanimationid",
2351     "projectile",
2352     "projectilehit",
2353     "pushingfactor",
2354     "range",
2355     "releasetime",
2356     "running",
2357     "rush_count",
2358     "rush_tally",
2359     "rush_time",
2360     "score",
2361     "scroll",
2362     "seal",
2363     "sealtime",
2364     "setlayer",
2365     "shadowbase",
2366     "sortid",
2367     "spawntype",
2368     "speed",
2369     "sprite",
2370     "spritea",
2371     "stalltime",
2372     "staydown",
2373     "staydownatk",
2374     "stealth",
2375     "subentity",
2376     "subject_to_basemap",
2377     "subject_to_gravity",
2378     "subject_to_hole",
2379     "subject_to_maxz",
2380     "subject_to_minz",
2381     "subject_to_obstacle",
2382     "subject_to_platform",
2383     "subject_to_screen",
2384     "subject_to_wall",
2385     "subtype",
2386     "takeaction",
2387     "think",
2388     "thold",
2389     "throwdamage",
2390     "throwdist",
2391     "throwframewait",
2392     "throwheight",
2393     "tosstime",
2394     "tossv",
2395     "trymove",
2396     "type",
2397     "velocity",
2398     "vulnerable",
2399     "walkoffmovex",
2400     "walkoffmovez",
2401     "weapent",
2402     "weaploss",
2403     "weapnum",
2404     "weapon",
2405     "x",
2406     "xdir",
2407     "y",
2408     "z",
2409     "zdir",
2410 };
2411 
2412 enum aiflag_enum
2413 {
2414     _ep_aiflag_animating,
2415     _ep_aiflag_attacking,
2416     _ep_aiflag_autokill,
2417     _ep_aiflag_blink,
2418     _ep_aiflag_blocking,
2419     _ep_aiflag_charging,
2420     _ep_aiflag_dead,
2421     _ep_aiflag_drop,
2422     _ep_aiflag_ducking,
2423     _ep_aiflag_falling,
2424     _ep_aiflag_frozen,
2425     _ep_aiflag_getting,
2426     _ep_aiflag_idlemode,
2427     _ep_aiflag_idling,
2428     _ep_aiflag_inbackpain,
2429     _ep_aiflag_inpain,
2430     _ep_aiflag_invincible,
2431     _ep_aiflag_jumpid,
2432     _ep_aiflag_jumping,
2433     _ep_aiflag_projectile,
2434     _ep_aiflag_rising,
2435     _ep_aiflag_running,
2436     _ep_aiflag_toexplode,
2437     _ep_aiflag_turning,
2438     _ep_aiflag_walking,
2439     _ep_aiflag_walkmode,
2440     _ep_aiflag_the_end,
2441 };
2442 
2443 
2444 static const char *eplist_aiflag[] =
2445 {
2446     "animating",
2447     "attacking",
2448     "autokill",
2449     "blink",
2450     "blocking",
2451     "charging",
2452     "dead",
2453     "drop",
2454     "ducking",
2455     "falling",
2456     "frozen",
2457     "getting",
2458     "idlemode",
2459     "idling",
2460     "inbackpain",
2461     "inpain",
2462     "invincible",
2463     "jumpid",
2464     "jumping",
2465     "projectile",
2466     "rising",
2467     "running",
2468     "toexplode",
2469     "turning",
2470     "walking",
2471     "walkmode",
2472 };
2473 
2474 enum edgerange_enum
2475 {
2476     _ep_edgerange_x,
2477     _ep_edgerange_z,
2478     _ep_edgerange_the_end,
2479 };
2480 
2481 static const char *eplist_edgerange[] =
2482 {
2483     "x",
2484     "z",
2485 };
2486 
2487 // ===== changedrawmethod ======
2488 enum drawmethod_enum
2489 {
2490     _dm_alpha,
2491     _dm_amplitude,
2492     _dm_beginsize,
2493     _dm_centerx,
2494     _dm_centery,
2495     _dm_channelb,
2496     _dm_channelg,
2497     _dm_channelr,
2498     _dm_clip,
2499     _dm_cliph,
2500     _dm_clipw,
2501     _dm_clipx,
2502     _dm_clipy,
2503     _dm_enabled,
2504     _dm_endsize,
2505     _dm_fillcolor,
2506     _dm_flag,
2507     _dm_fliprotate,
2508     _dm_flipx,
2509     _dm_flipy,
2510     _dm_perspective,
2511     _dm_remap,
2512     _dm_reset,
2513     _dm_rotate,
2514     _dm_scalex,
2515     _dm_scaley,
2516     _dm_shiftx,
2517     _dm_table,
2518     _dm_tintcolor,
2519     _dm_tintmode,
2520     _dm_transbg,
2521     _dm_watermode,
2522     _dm_wavelength,
2523     _dm_wavespeed,
2524     _dm_wavetime,
2525     _dm_xrepeat,
2526     _dm_xspan,
2527     _dm_yrepeat,
2528     _dm_yspan,
2529     _dm_the_end,
2530 };
2531 
2532 enum _prop_dropframe_enum
2533 {
2534     _PROP_DROPFRAME_FRAME,
2535     _PROP_DROPFRAME_VELOCITY_X,
2536     _PROP_DROPFRAME_VELOCITY_Y,
2537     _PROP_DROPFRAME_VELOCITY_Z,
2538     _PROP_DROPFRAME_THE_END
2539 };
2540 
2541 enum _prop_followup_enum
2542 {
2543     _PROP_FOLLOWUP_ANIMATION,
2544     _PROP_FOLLOWUP_CONDITION,
2545     _PROP_FOLLOWUP_THE_END
2546 };
2547 
2548 enum _prop_jumpframe_enum
2549 {
2550     _PROP_JUMPFRAME_FRAME,
2551     _PROP_JUMPFRAME_VELOCITY_X,
2552     _PROP_JUMPFRAME_VELOCITY_Y,
2553     _PROP_JUMPFRAME_VELOCITY_Z,
2554     _PROP_JUMPFRAME_THE_END
2555 };
2556 
2557 enum _prop_landframe_enum
2558 {
2559     _PROP_LANDFRAME_FRAME,
2560     _PROP_LANDFRAME_VELOCITY_X,
2561     _PROP_LANDFRAME_VELOCITY_Y,
2562     _PROP_LANDFRAME_VELOCITY_Z,
2563     _PROP_LANDFRAME_THE_END
2564 };
2565 
2566 enum _prop_loop_enum
2567 {
2568     _PROP_LOOP_FRAME_MAX,
2569     _PROP_LOOP_FRAME_MIN,
2570     _PROP_LOOP_MODE,
2571     _PROP_LOOP_THE_END
2572 };
2573 
2574  enum _prop_move_enum
2575 {
2576     _PROP_MOVE_BASE,
2577     _PROP_MOVE_X,
2578     _PROP_MOVE_Y,
2579     _PROP_MOVE_Z,
2580     _PROP_MOVE_THE_END
2581 };
2582 
2583  enum _prop_offset_enum
2584 {
2585     _PROP_OFFSET_X,
2586     _PROP_OFFSET_Y,
2587     _PROP_OFFSET_THE_END
2588 };
2589 
2590  enum _prop_platform_enum
2591 {
2592     _PROP_PLATFORM_ALT,
2593     _PROP_PLATFORM_DEPTH,
2594     _PROP_PLATFORM_LOWERLEFT,
2595     _PROP_PLATFORM_LOWERRIGHT,
2596     _PROP_PLATFORM_UPPERLEFT,
2597     _PROP_PLATFORM_UPPERRIGHT,
2598     _PROP_PLATFORM_X,
2599     _PROP_PLATFORM_Z,
2600     _PROP_PLATFORM_THE_END
2601 };
2602 
2603 enum _prop_projectile_enum
2604 {
2605     _PROP_PROJECTILE_BOMB,
2606     _PROP_PROJECTILE_FLASH,
2607     _PROP_PROJECTILE_KNIFE,
2608     _PROP_PROJECTILE_SHOOTFRAME,
2609     _PROP_PROJECTILE_STAR,
2610     _PROP_PROJECTILE_THROWFRAME,
2611     _PROP_PROJECTILE_THROWPOSITION_BASE,
2612     _PROP_PROJECTILE_THROWPOSITION_X,
2613     _PROP_PROJECTILE_THROWPOSITION_Y,
2614     _PROP_PROJECTILE_THROWPOSITION_Z,
2615     _PROP_PROJECTILE_TOSSFRAME,
2616     _PROP_PROJECTILE_THE_END
2617 };
2618 
2619 enum _prop_quakeframe_enum
2620 {
2621     _PROP_QUAKEFRAME_FRAMESTART,
2622     _PROP_QUAKEFRAME_INTENSITY,
2623     _PROP_QUAKEFRAME_REPEAT,
2624     _PROP_QUAKEFRAME_THE_END
2625 };
2626 
2627 enum _prop_range_enum
2628 {
2629     _PROP_RANGEA_MAX,
2630     _PROP_RANGEA_MIN,
2631     _PROP_RANGEB_MAX,
2632     _PROP_RANGEB_MIN,
2633     _PROP_RANGEX_MAX,
2634     _PROP_RANGEX_MIN,
2635     _PROP_RANGEZ_MAX,
2636     _PROP_RANGEZ_MIN,
2637     _PROP_RANGE_THE_END
2638 };
2639 
2640 enum _prop_size_enum
2641 {
2642     _PROP_SIZE_BASE,
2643     _PROP_SIZE_X,
2644     _PROP_SIZE_Y,
2645     _PROP_SIZE_Z,
2646     _PROP_SIZE_THE_END
2647 };
2648 
2649  enum _prop_shadow_enum
2650 {
2651     _PROP_FSHADOW,
2652     _PROP_SHADOW_COORDS_X,
2653     _PROP_SHADOW_COORDS_Y,
2654     _PROP_SHADOW_THE_END
2655 };
2656 
2657 enum _prop_spawnframe_enum
2658 {
2659     _PROP_SPAWNFRAME_FRAME,
2660     _PROP_SPAWNFRAME_RELATIVE,
2661     _PROP_SPAWNFRAME_X,
2662     _PROP_SPAWNFRAME_Y,
2663     _PROP_SPAWNFRAME_Z,
2664     _PROP_SPAWNFRAME_THE_END
2665 };
2666 
2667 enum _prop_spritea_enum
2668 {
2669     _PROP_SPRITEA_CENTERX,
2670     _PROP_SPRITEA_CENTERY,
2671     _PROP_SPRITEA_FILE,
2672     _PROP_SPRITEA_OFFSETX,
2673     _PROP_SPRITEA_OFFSETY,
2674     _PROP_SPRITEA_SPRITE,
2675     _PROP_SPRITEA_THE_END
2676 };
2677 
2678 enum _prop_summonframe_enum
2679 {
2680     _PROP_SUMMONFRAME_FRAME,
2681     _PROP_SUMMONFRAME_RELATIVE,
2682     _PROP_SUMMONFRAME_X,
2683     _PROP_SUMMONFRAME_Y,
2684     _PROP_SUMMONFRAME_Z,
2685     _PROP_SUMMONFRAME_THE_END
2686 };
2687 
2688 enum _prop_starvelocity_enum
2689 {
2690     _PROP_STARVELOCITY_1,
2691     _PROP_STARVELOCITY_2,
2692     _PROP_STARVELOCITY_3,
2693     _PROP_STARVELOCITY_THE_END
2694 };
2695 
2696 enum _prop_weaponframe_enum
2697 {
2698     _PROP_WEAPONFRAME_FRAME,
2699     _PROP_WEAPONFRAME_WEAPON,
2700     _PROP_WEAPONFRAME_THE_END
2701 };
2702 
2703 enum _ep_defense_enum
2704 {
2705     _ep_defense_blockpower,
2706     _ep_defense_blockratio,
2707     _ep_defense_blockthreshold,
2708     _ep_defense_blocktype,
2709     _ep_defense_factor,
2710     _ep_defense_knockdown,
2711     _ep_defense_pain,
2712     _ep_defense_the_end,
2713 };
2714 
2715 enum gep_edelay_enum
2716 {
2717     _ep_edelay_cap_max,
2718     _ep_edelay_cap_min,
2719     _ep_edelay_factor,
2720     _ep_edelay_mode,
2721     _ep_edelay_range_max,
2722     _ep_edelay_range_min,
2723     _ep_edelay_the_end,
2724 };
2725 
2726 enum gep_energycost_enum
2727 {
2728     _ep_energycost_cost,
2729     _ep_energycost_disable,
2730     _ep_energycost_mponly,
2731     _ep_energycost_the_end,
2732 };
2733 
2734 enum gep_flash_enum
2735 {
2736     _ep_flash_block,
2737     _ep_flash_def,
2738     _ep_flash_noattack,
2739     _ep_flash_the_end,
2740 };
2741 
2742 enum gep_icon_enum
2743 {
2744     _ep_icon_def,
2745     _ep_icon_die,
2746     _ep_icon_get,
2747     _ep_icon_mphigh,
2748     _ep_icon_mplow,
2749     _ep_icon_mpmed,
2750     _ep_icon_pain,
2751     _ep_icon_weapon,
2752     _ep_icon_x,
2753     _ep_icon_y,
2754     _ep_icon_the_end,
2755 };
2756 
2757 enum _ep_knockdowncount_enum
2758 {
2759     _ep_knockdowncount_current,
2760     _ep_knockdowncount_max,
2761     _ep_knockdowncount_time,
2762     _ep_knockdowncount_the_end,
2763 };
2764 
2765 enum gep_landframe_enum
2766 {
2767     _ep_landframe_ent,
2768     _ep_landframe_frame,
2769     _ep_landframe_the_end,
2770 };
2771 
2772 enum gep_maps_enum
2773 {
2774     _ep_maps_count,
2775     _ep_maps_current,
2776     _ep_maps_default,
2777     _ep_maps_dying,
2778     _ep_maps_dying_critical,
2779     _ep_maps_dying_low,
2780     _ep_maps_frozen,
2781     _ep_maps_hide_end,
2782     _ep_maps_hide_start,
2783     _ep_maps_ko,
2784     _ep_maps_kotype,
2785     _ep_maps_table,
2786     _ep_maps_time,
2787     _ep_maps_the_end,
2788 };
2789 
2790 enum gep_range_enum
2791 {
2792     _ep_range_amax,
2793     _ep_range_amin,
2794     _ep_range_bmax,
2795     _ep_range_bmin,
2796     _ep_range_xmax,
2797     _ep_range_xmin,
2798     _ep_range_zmax,
2799     _ep_range_zmin,
2800     _ep_range_the_end,
2801 };
2802 
2803 enum gep_running_enum
2804 {
2805     _ep_running_jumpx,
2806     _ep_running_jumpy,
2807     _ep_running_land,
2808     _ep_running_movez,
2809     _ep_running_speed,
2810     _ep_running_the_end,
2811 };
2812 
2813 enum gep_spritea_enum
2814 {
2815     _ep_spritea_centerx,
2816     _ep_spritea_centery,
2817     _ep_spritea_file,
2818     _ep_spritea_offsetx,
2819     _ep_spritea_offsety,
2820     _ep_spritea_sprite,
2821     _ep_spritea_the_end,
2822 };
2823 
2824 enum gep_staydown_enum
2825 {
2826     _ep_staydown_rise,
2827     _ep_staydown_riseattack,
2828     _ep_staydown_riseattack_stall,
2829     _ep_staydown_the_end,
2830 };
2831 
2832 enum cep_hostile_candamage_enum
2833 {
2834     _ep_hcd_ground,
2835     _ep_hcd_type_enemy,
2836     _ep_hcd_type_npc,
2837     _ep_hcd_type_obstacle,
2838     _ep_hcd_type_player,
2839     _ep_hcd_type_shot,
2840     _ep_hcd_the_end,
2841 };
2842 
2843 enum cep_takeaction_enum
2844 {
2845     _ep_ta_bomb_explode,
2846     _ep_ta_common_animation_normal,
2847     _ep_ta_common_attack_proc,
2848     _ep_ta_common_block,
2849     _ep_ta_common_drop,
2850     _ep_ta_common_fall,
2851     _ep_ta_common_get,
2852     _ep_ta_common_grab,
2853     _ep_ta_common_grabattack,
2854     _ep_ta_common_grabbed,
2855     _ep_ta_common_jump,
2856     _ep_ta_common_land,
2857     _ep_ta_common_lie,
2858     _ep_ta_common_pain,
2859     _ep_ta_common_prejump,
2860     _ep_ta_common_rise,
2861     _ep_ta_common_spawn,
2862     _ep_ta_common_turn,
2863     _ep_ta_normal_prepare,
2864     _ep_ta_npc_warp,
2865     _ep_ta_player_blink,
2866     _ep_ta_suicide,
2867     _ep_ta_the_end,
2868 };
2869 
2870 enum cep_think_enum   // 2011_03_03, DC: Think types.
2871 {
2872     _ep_th_common_think,
2873     _ep_th_player_think,
2874     _ep_th_steam_think,
2875     _ep_th_steamer_think,
2876     _ep_th_text_think,
2877     _ep_th_trap_think,
2878     _ep_th_the_end,
2879 };
2880 
mapstrings_animationproperty(ScriptVariant ** varlist,int paramCount)2881 int mapstrings_animationproperty(ScriptVariant **varlist, int paramCount)
2882 {
2883     return 0;
2884 //    char *propname;
2885 //    const char *aps;
2886 //    int prop, ap; //int prop, i, ep, t;
2887 //    int result = 1;
2888 //
2889 //    MAPSTRINGS(varlist[1], list_animation_prop, ANI_PROP_THE_END,
2890 //               "Property name '%s' is not a supported animation property.\n");
2891 //
2892 //    if(paramCount < 3 || varlist[1]->vt != VT_INTEGER)
2893 //    {
2894 //        return result;
2895 //    }
2896 //    else
2897 //    {
2898 //        ap = varlist[1]->lVal;
2899 //        aps = (ap < ANI_PROP_THE_END && ap >= 0) ? list_animation_prop[ap] : "";
2900 //    }
2901 //
2902 //    return result;
2903 }
2904 
mapstrings_entityproperty(ScriptVariant ** varlist,int paramCount)2905 int mapstrings_entityproperty(ScriptVariant **varlist, int paramCount)
2906 {
2907     char *propname;
2908     const char *eps;
2909     int prop, i, ep, t;
2910 
2911     static const char *proplist_defense[] =
2912     {
2913         "blockpower",
2914         "blockratio",
2915         "blockthreshold",
2916         "blocktype",
2917         "factor",
2918         "knockdown",
2919         "pain",
2920     };
2921 
2922     static const char *proplist_edelay[] =
2923     {
2924         "cap_max",
2925         "cap_min",
2926         "factor",
2927         "mode",
2928         "range_max",
2929         "range_min",
2930     };
2931 
2932     static const char *proplist_energycost[] =
2933     {
2934         "cost",
2935         "disable",
2936         "mponly",
2937     };
2938 
2939     static const char *proplist_flash[] =
2940     {
2941         "block",
2942         "default",
2943         "noattack",
2944     };
2945 
2946     static const char *proplist_icon[] =
2947     {
2948         "default",
2949         "die",
2950         "get",
2951         "mphigh",
2952         "mplow",
2953         "mpmed",
2954         "pain",
2955         "weapon",
2956         "x",
2957         "y",
2958     };
2959 
2960     static const char *proplist_knockdowncount[] =
2961     {
2962         "current",
2963         "max",
2964         "time",
2965     };
2966 
2967     static const char *proplist_landframe[] =
2968     {
2969         "ent",
2970         "frame",
2971     };
2972 
2973     static const char *proplist_maps[] =
2974     {
2975         "count",
2976         "current",
2977         "default",
2978         "dying",
2979         "dying_critical",
2980         "dying_low",
2981         "frozen",
2982         "hide_end",
2983         "hide_start",
2984         "ko",
2985         "kotype",
2986         "table",
2987         "time",
2988     };
2989 
2990     static const char *proplist_range[] =
2991     {
2992         "amax",
2993         "amin",
2994         "bmax",
2995         "bmin",
2996         "xmax",
2997         "xmin",
2998         "zmax",
2999         "zmin",
3000     };
3001 
3002     static const char *proplist_running[] =
3003     {
3004         "jumpx",
3005         "jumpy",
3006         "land",
3007         "movez",
3008         "speed",
3009     };
3010 
3011     static const char *proplist_spritea[] =
3012     {
3013         "centerx",
3014         "centery",
3015         "file",
3016         "offsetx",
3017         "offsety",
3018         "sprite",
3019     };
3020 
3021     static const char *proplist_staydown[] =
3022     {
3023         "rise",
3024         "riseattack",
3025         "riseattack_stall",
3026     };
3027 
3028     static const char *proplist_hostile_candamage[] =
3029     {
3030         "ground",
3031         "type_enemy",
3032         "type_npc",
3033         "type_obstacle",
3034         "type_player",
3035         "type_shot",
3036     };
3037 
3038     static const char *proplist_takeaction[] =
3039     {
3040         "bomb_explode",
3041         "common_animation_normal",
3042         "common_attack_proc",
3043         "common_block",
3044         "common_drop",
3045         "common_fall",
3046         "common_get",
3047         "common_grab",
3048         "common_grabattack",
3049         "common_grabbed",
3050         "common_jump",
3051         "common_land",
3052         "common_lie",
3053         "common_pain",
3054         "common_prejump",
3055         "common_rise",
3056         "common_spawn",
3057         "common_turn",
3058         "normal_prepare",
3059         "npc_warp",
3060         "player_blink",
3061         "suicide",
3062     };
3063 
3064     static const char *proplist_think[] =   // 2011_03_03, DC: Think types.
3065     {
3066         "common_think",
3067         "player_think",
3068         "steam_think",
3069         "steamer_think",
3070         "text_think",
3071         "trap_think",
3072     };
3073 
3074     if(paramCount < 2)
3075     {
3076         return 1;
3077     }
3078 
3079     // map entity properties
3080     MAPSTRINGS(varlist[1], eplist, _ep_the_end,
3081                "Property name '%s' is not supported by function getentityproperty.\n");
3082 
3083     if(paramCount < 3 || varlist[1]->vt != VT_INTEGER)
3084     {
3085         return 1;
3086     }
3087 
3088     ep = varlist[1]->lVal;
3089     eps = (ep < _ep_the_end && ep >= 0) ? eplist[ep] : "";
3090 
3091     switch (ep)
3092     {
3093     // deprecation warning for "a" property
3094     case _ep_a:
3095     {
3096         printf("\nNote: Property 'a' has been deprecated. Use 'y' to access the Y (vertical) axis property.\n");
3097         break;
3098     }
3099     // map subproperties of aiflag property
3100     case _ep_aiflag:
3101     {
3102         MAPSTRINGS(varlist[2], eplist_aiflag, _ep_aiflag_the_end,
3103                    _is_not_a_known_subproperty_of_, eps);
3104         break;
3105     }
3106     // map subproperties of edgerange property
3107     case _ep_edgerange:
3108     {
3109         MAPSTRINGS(varlist[2], eplist_edgerange, _ep_edgerange_the_end,
3110                    _is_not_a_known_subproperty_of_, eps);
3111         break;
3112     }
3113     // map subproperties of defense property
3114     case _ep_defense:
3115     {
3116         if(paramCount >= 4)
3117         {
3118             MAPSTRINGS(varlist[3], proplist_defense, _ep_defense_the_end,
3119                        _is_not_a_known_subproperty_of_, eps);
3120         }
3121         break;
3122     }
3123     // map subproperties of Edelay property
3124     case _ep_edelay:
3125     {
3126         MAPSTRINGS(varlist[2], proplist_edelay, _ep_edelay_the_end,
3127                    _is_not_a_known_subproperty_of_, eps);
3128         break;
3129     }
3130     // map subproperties of Energycost
3131     case _ep_energycost:
3132     {
3133         MAPSTRINGS(varlist[2], proplist_energycost, _ep_energycost_the_end,
3134                    _is_not_a_known_subproperty_of_, eps);
3135         break;
3136     }
3137     // map subproperties of Flash
3138     case _ep_flash:
3139     {
3140         MAPSTRINGS(varlist[2], proplist_flash, _ep_flash_the_end,
3141                    _is_not_a_known_subproperty_of_, eps);
3142         break;
3143     }
3144     // map subproperties of Icon
3145     case _ep_icon:
3146     {
3147         MAPSTRINGS(varlist[2], proplist_icon, _ep_icon_the_end,
3148                    _is_not_a_known_subproperty_of_, eps);
3149         break;
3150     }
3151 
3152     // map subproperties of Knockdowncount
3153     case _ep_knockdowncount:
3154     {
3155         MAPSTRINGS(varlist[2], proplist_knockdowncount, _ep_knockdowncount_the_end,
3156                    _is_not_a_known_subproperty_of_, eps);
3157         break;
3158     }
3159     // map subproperties of Landframe
3160     case _ep_landframe:
3161     {
3162         MAPSTRINGS(varlist[2], proplist_landframe, _ep_landframe_the_end,
3163                    _is_not_a_known_subproperty_of_, eps);
3164         break;
3165     }
3166     // map subproperties of Maps
3167     case  _ep_maps:
3168     {
3169         MAPSTRINGS(varlist[2], proplist_maps, _ep_maps_the_end,
3170                    _is_not_a_known_subproperty_of_, eps);
3171         break;
3172     }
3173     // map subproperties of Range
3174     case _ep_range:
3175     {
3176         MAPSTRINGS(varlist[2], proplist_range, _ep_range_the_end,
3177                    _is_not_a_known_subproperty_of_, eps);
3178         break;
3179     }
3180     // map subproperties of Running
3181     case _ep_running:
3182     {
3183         MAPSTRINGS(varlist[2], proplist_running, _ep_running_the_end,
3184                    _is_not_a_known_subproperty_of_, eps);
3185         break;
3186     }
3187 
3188     // map subproperties of Spritea
3189     case _ep_spritea:
3190     {
3191         MAPSTRINGS(varlist[2], proplist_spritea, _ep_spritea_the_end,
3192                    _is_not_a_known_subproperty_of_, eps);
3193         break;
3194     }
3195     // map subproperties of Staydown
3196     case _ep_staydown:
3197     {
3198         MAPSTRINGS(varlist[2], proplist_staydown, _ep_running_the_end,
3199                    _is_not_a_known_subproperty_of_, eps);
3200         break;
3201     }
3202     //hostile, candamage, projectilehit
3203     case _ep_hostile:
3204     case _ep_candamage:
3205     case _ep_projectilehit:
3206     {
3207         for(i = 2; i < paramCount; i++)
3208         {
3209             t = varlist[i]->vt;
3210             MAPSTRINGS(varlist[i], proplist_hostile_candamage, _ep_hcd_the_end,
3211                        _is_not_supported_by_, eps);
3212 
3213             if(varlist[i]->vt == VT_INTEGER && t == VT_STR)
3214             {
3215                 varlist[i]->lVal |= 0x80000000;    //flag it
3216             }
3217         }
3218         break;
3219     }
3220     // action for takeaction
3221     case _ep_takeaction:
3222     {
3223         MAPSTRINGS(varlist[2], proplist_takeaction, _ep_ta_the_end,
3224                    _is_not_supported_by_, eps);
3225         break;
3226     }
3227     // 2011_03_13, DC: Think sets for think.
3228     case _ep_think:
3229     {
3230         MAPSTRINGS(varlist[2], proplist_think, _ep_th_the_end,
3231                    _is_not_supported_by_, eps);
3232         break;
3233     }
3234     }
3235 
3236     return 1;
3237 }
3238 
3239 //getentityproperty(pentity, propname);
openbor_getentityproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3240 HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
3241 {
3242     entity *ent			= NULL;
3243     ScriptVariant *arg	= NULL;
3244     ScriptVariant *arg1	= NULL;
3245     s_sprite *spr;
3246     LONG ltemp, ltemp2;
3247     int i				= 0;
3248     int propind ;
3249     int tempint			= 0;
3250 
3251     if(paramCount < 2)
3252     {
3253         *pretvar = NULL;
3254         return E_FAIL;
3255     }
3256 
3257     ScriptVariant_Clear(*pretvar);
3258     mapstrings_entityproperty(varlist, paramCount);
3259 
3260     arg = varlist[0];
3261     if(arg->vt != VT_PTR && arg->vt != VT_EMPTY)
3262     {
3263         printf("Function getentityproperty must have a valid entity handle.\n");
3264         *pretvar = NULL;
3265         return E_FAIL;
3266     }
3267     ent = (entity *)arg->ptrVal; //retrieve the entity
3268     if(!ent)
3269     {
3270         return S_OK;
3271     }
3272 
3273     arg = varlist[1];
3274     if(arg->vt != VT_INTEGER)
3275     {
3276         printf("Function getentityproperty must have a string property name.\n");
3277     }
3278 
3279     propind = arg->lVal;
3280 
3281     switch(propind)
3282     {
3283     case _ep_a:
3284     case _ep_y:
3285     {
3286         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3287         (*pretvar)->dblVal = (DOUBLE)ent->position.y;
3288         break;
3289     }
3290     case _ep_aggression:
3291     {
3292         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3293         (*pretvar)->lVal = (LONG)ent->modeldata.aggression;
3294         break;
3295     }
3296     case _ep_aiattack:
3297     {
3298         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3299         (*pretvar)->lVal = (LONG)ent->modeldata.aiattack;
3300         break;
3301     }
3302     case _ep_aiflag:
3303     {
3304         if(paramCount < 3)
3305         {
3306             break;
3307         }
3308         arg = varlist[2];
3309         if(arg->vt != VT_INTEGER)
3310         {
3311             printf("You must give a string name for aiflag.\n");
3312             return E_FAIL;
3313         }
3314         ltemp = arg->lVal;
3315 
3316         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3317         switch(ltemp)
3318         {
3319         case _ep_aiflag_dead:
3320             (*pretvar)->lVal = (LONG)ent->dead;
3321             break;
3322         case _ep_aiflag_jumpid:
3323             (*pretvar)->lVal = (LONG)ent->jump.animation_id;
3324             break;
3325         case _ep_aiflag_jumping:
3326             (*pretvar)->lVal = (LONG)ent->jumping;
3327             break;
3328         case _ep_aiflag_idling:
3329             (*pretvar)->lVal = (LONG)ent->idling;
3330             break;
3331         case _ep_aiflag_drop:
3332             (*pretvar)->lVal = (LONG)ent->drop;
3333             break;
3334         case _ep_aiflag_attacking:
3335             (*pretvar)->lVal = (LONG)ent->attacking;
3336             break;
3337         case _ep_aiflag_getting:
3338             (*pretvar)->lVal = (LONG)ent->getting;
3339             break;
3340         case _ep_aiflag_turning:
3341             (*pretvar)->lVal = (LONG)ent->turning;
3342             break;
3343         case _ep_aiflag_charging:
3344             (*pretvar)->lVal = (LONG)ent->charging;
3345             break;
3346         case _ep_aiflag_blocking:
3347             (*pretvar)->lVal = (LONG)ent->blocking;
3348             break;
3349         case _ep_aiflag_ducking:
3350             (*pretvar)->lVal = (LONG)ent->ducking;
3351             break;
3352         case _ep_aiflag_falling:
3353             (*pretvar)->lVal = (LONG)ent->falling;
3354             break;
3355         case _ep_aiflag_running:
3356             (*pretvar)->lVal = (LONG)ent->running;
3357             break;
3358         case _ep_aiflag_inpain:
3359             (*pretvar)->lVal = (LONG)ent->inpain;
3360             break;
3361         case _ep_aiflag_rising:
3362             (*pretvar)->lVal = (LONG)ent->rising;
3363             break;
3364         case _ep_aiflag_inbackpain:
3365             (*pretvar)->lVal = (LONG)ent->inbackpain;
3366             break;
3367         case _ep_aiflag_projectile:
3368             (*pretvar)->lVal = (LONG)ent->projectile;
3369             break;
3370         case _ep_aiflag_frozen:
3371             (*pretvar)->lVal = (LONG)ent->frozen;
3372             break;
3373         case _ep_aiflag_toexplode:
3374             (*pretvar)->lVal = (LONG)ent->toexplode;
3375             break;
3376         case _ep_aiflag_animating:
3377             (*pretvar)->lVal = (LONG)ent->animating;
3378             break;
3379         case _ep_aiflag_blink:
3380             (*pretvar)->lVal = (LONG)ent->blink;
3381             break;
3382         case _ep_aiflag_invincible:
3383             (*pretvar)->lVal = (LONG)ent->invincible;
3384             break;
3385         case _ep_aiflag_autokill:
3386             (*pretvar)->lVal = (LONG)ent->autokill;
3387             break;
3388         case _ep_aiflag_idlemode:
3389             (*pretvar)->lVal = (LONG)ent->idlemode;
3390             break;
3391         case _ep_aiflag_walkmode:
3392             (*pretvar)->lVal = (LONG)ent->walkmode;
3393             break;
3394         case _ep_aiflag_walking:
3395             (*pretvar)->lVal = (LONG)ent->walking;
3396             break;
3397         default:
3398             ScriptVariant_Clear(*pretvar);
3399             return E_FAIL;
3400         }
3401         break;
3402     }
3403     case _ep_aimove:
3404     {
3405         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3406         (*pretvar)->lVal = (LONG)ent->modeldata.aimove;
3407         break;
3408     }
3409     case _ep_alpha:
3410     {
3411         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3412         (*pretvar)->lVal = (LONG)ent->modeldata.alpha;
3413         break;
3414     }
3415     case _ep_animal:
3416     {
3417         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3418         (*pretvar)->lVal = (LONG)ent->modeldata.animal;
3419         break;
3420     }
3421     case _ep_animating:
3422     {
3423         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3424         (*pretvar)->lVal = (LONG)ent->animating;
3425         break;
3426     }
3427     case _ep_animation_handle:
3428     {
3429         #define ARG_ANIMATION_ID 2
3430 
3431         // Did the user provide an animation id?
3432         if(paramCount > 2)
3433         {
3434             arg = varlist[ARG_ANIMATION_ID];
3435 
3436             // If the argument is invalid, use current animation ID instead.
3437             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
3438             {
3439                 ltemp = (LONG)ent->animnum;
3440             }
3441         }
3442         else
3443         {
3444             ltemp = (LONG)ent->animnum;
3445         }
3446 
3447         // If the animation exists, get the handle.
3448         if(validanim(ent, ltemp))
3449         {
3450             ScriptVariant_ChangeType(*pretvar, VT_PTR);
3451             (*pretvar)->ptrVal = (VOID *)ent->modeldata.animation[ltemp];
3452         }
3453 
3454         break;
3455 
3456         #undef ARG_ANIMATION_ID
3457     }
3458     /*
3459     case _ep_animationid: See animnum.
3460     */
3461     case _ep_animheight:
3462     {
3463         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3464         (*pretvar)->lVal = (LONG)ent->animation->size.x;
3465         break;
3466     }
3467     case _ep_animhits:
3468     {
3469         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3470         (*pretvar)->lVal = (LONG)ent->animation->animhits;
3471         break;
3472     }
3473     case _ep_animnum:
3474     case _ep_animationid:
3475     {
3476         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3477         (*pretvar)->lVal = (LONG)ent->animnum;
3478         break;
3479     }
3480     case _ep_prevanimationid:
3481     {
3482         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3483         (*pretvar)->lVal = (LONG)ent->animnum_previous;
3484         break;
3485     }
3486     case _ep_animpos:
3487     {
3488         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3489         (*pretvar)->lVal = (LONG)ent->animpos;
3490         break;
3491     }
3492     case _ep_animvalid:
3493     {
3494         ltemp = 0;
3495         if(paramCount == 3)
3496         {
3497             arg = varlist[2];
3498             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
3499             {
3500                 ltemp = (LONG)0;
3501             }
3502         }
3503         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3504         (*pretvar)->lVal = (LONG)validanim(ent, ltemp);
3505         break;
3506     }
3507     case _ep_antigrab:
3508     {
3509         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3510         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.antigrab;
3511         break;
3512     }
3513     case _ep_antigravity:
3514     {
3515         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3516         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.antigravity;
3517         break;
3518     }
3519     case _ep_attacking:
3520     {
3521         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3522         (*pretvar)->lVal = (LONG)ent->attacking;
3523         break;
3524     }
3525     case _ep_attackid:
3526     {
3527         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3528         (*pretvar)->lVal = (LONG)ent->attack_id_outgoing;
3529         break;
3530     }
3531     case _ep_autokill:
3532     {
3533         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3534         (*pretvar)->lVal = (LONG)ent->autokill;
3535         break;
3536     }
3537     case _ep_base:
3538     {
3539         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3540         (*pretvar)->dblVal = (DOUBLE)ent->base;
3541         break;
3542     }
3543     case _ep_vulnerable:
3544     {
3545         if(paramCount == 2)
3546         {
3547             i		= ent->animnum;
3548             tempint	= ent->animpos;
3549         }
3550         else if(paramCount < 4
3551                 || varlist[2]->vt != VT_INTEGER
3552                 || varlist[3]->vt != VT_INTEGER)
3553         {
3554             printf("\n Error, getentityproperty({ent}, \"vulnerable\", {animation}, {frame}): parameters missing or invalid. \n");
3555             *pretvar = NULL;
3556             return E_FAIL;
3557         }
3558         else
3559         {
3560             i		= varlist[2]->lVal;												//Animation parameter.
3561             tempint	= varlist[3]->lVal;												//Frame parameter.
3562         }
3563         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3564         (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->vulnerable[tempint];
3565         break;
3566     }
3567     case _ep_blink:
3568     {
3569         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3570         (*pretvar)->lVal = (LONG)ent->blink;
3571         break;
3572     }
3573     case _ep_blockback:
3574     {
3575         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3576         (*pretvar)->lVal = (LONG)ent->modeldata.blockback;
3577         break;
3578     }
3579     case _ep_blockodds:
3580     {
3581         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3582         (*pretvar)->lVal = (LONG)ent->modeldata.blockodds;
3583         break;
3584     }
3585     case _ep_blockpain:
3586     {
3587         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3588         (*pretvar)->lVal = (LONG)ent->modeldata.blockpain;
3589         break;
3590     }
3591     case _ep_boss:
3592     {
3593         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3594         (*pretvar)->lVal = (LONG)ent->boss;
3595         break;
3596     }
3597     case _ep_bounce:
3598     {
3599         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3600         (*pretvar)->lVal = (LONG)ent->modeldata.bounce;
3601         break;
3602     }
3603     case _ep_bound:
3604     {
3605         ScriptVariant_ChangeType(*pretvar, VT_PTR);
3606         (*pretvar)->ptrVal = (VOID *)ent->binding.ent;
3607         break;
3608     }
3609     case _ep_bind:
3610     {
3611         ScriptVariant_ChangeType(*pretvar, VT_PTR);
3612         (*pretvar)->ptrVal = (VOID *)&ent->binding;
3613         break;
3614     }
3615     case _ep_candamage:
3616     {
3617         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3618         (*pretvar)->lVal = (LONG)ent->modeldata.candamage;
3619         break;
3620     }
3621     case _ep_combostep:
3622     {
3623         if(paramCount >= 3)
3624         {
3625             if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
3626             {
3627                 *pretvar = NULL;
3628                 return E_FAIL;
3629             }
3630         }
3631         else
3632         {
3633             ltemp2 = 0;
3634         }
3635         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3636         (*pretvar)->lVal = (LONG)ent->combostep[(LONG)ltemp2];
3637         break;
3638     }
3639     case _ep_combotime:
3640     {
3641         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3642         (*pretvar)->lVal = (LONG)ent->combotime;
3643         break;
3644     }
3645     case _ep_collidedentity:
3646     {
3647         ScriptVariant_ChangeType(*pretvar, VT_PTR);
3648         (*pretvar)->ptrVal = (VOID *)&ent->collided_entity;
3649         break;
3650     }
3651     case _ep_hostile:
3652     {
3653         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3654         (*pretvar)->lVal = (LONG)ent->modeldata.hostile;
3655         break;
3656     }
3657     case _ep_projectilehit:
3658     {
3659         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3660         (*pretvar)->lVal = (LONG)ent->modeldata.projectilehit;
3661         break;
3662     }
3663     case _ep_chargerate:
3664     {
3665         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3666         (*pretvar)->lVal = (LONG)ent->modeldata.chargerate;
3667         break;
3668     }
3669     case _ep_colourmap:
3670     {
3671         ScriptVariant_ChangeType(*pretvar, VT_PTR);
3672         (*pretvar)->ptrVal = (VOID *)(ent->colourmap);
3673         break;
3674     }
3675     case _ep_colourtable:
3676     {
3677         ScriptVariant_ChangeType(*pretvar, VT_PTR);
3678         (*pretvar)->ptrVal = (VOID *)model_get_colourmap(&(ent->modeldata), varlist[2]->lVal + 1);
3679         break;
3680     }
3681     case _ep_damage_on_landing:
3682     {
3683         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3684         (*pretvar)->lVal = (LONG)ent->damage_on_landing.attack_force;
3685 
3686 
3687         break;
3688     }
3689     case _ep_dead:
3690     {
3691         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3692         (*pretvar)->lVal = (LONG)ent->dead;
3693         break;
3694     }
3695     case _ep_defaultmodel:
3696     case _ep_defaultname:
3697     {
3698         ScriptVariant_ChangeType(*pretvar, VT_STR);
3699         (*pretvar)->strVal = StrCache_CreateNewFrom(ent->defaultmodel->name);
3700         break;
3701     }
3702     case _ep_defense:
3703     {
3704         ltemp = 0;
3705         if(paramCount >= 3)
3706         {
3707             if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
3708             {
3709                 printf("You must specify an attack type for your defense property.\n");
3710                 *pretvar = NULL;
3711                 return E_FAIL;
3712             }
3713             ltemp2 = _ep_defense_factor;
3714         }
3715 
3716         if(paramCount >= 4)
3717         {
3718             if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
3719             {
3720                 *pretvar = NULL;
3721                 return E_FAIL;
3722             }
3723         }
3724         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3725 
3726         switch(ltemp2)
3727         {
3728         case _ep_defense_factor:
3729         {
3730             (*pretvar)->dblVal = (DOUBLE)ent->defense[(LONG)ltemp].factor;
3731             break;
3732         }
3733         case _ep_defense_blockpower:
3734         {
3735             (*pretvar)->dblVal = (DOUBLE)ent->defense[(LONG)ltemp].blockpower;
3736             break;
3737         }
3738         case _ep_defense_blockratio:
3739         {
3740             (*pretvar)->dblVal = (DOUBLE)ent->defense[(LONG)ltemp].blockratio;
3741             break;
3742         }
3743         case _ep_defense_blockthreshold:
3744         {
3745             (*pretvar)->dblVal = (DOUBLE)ent->defense[(LONG)ltemp].blockthreshold;
3746             break;
3747         }
3748         case _ep_defense_blocktype:
3749         {
3750             (*pretvar)->dblVal = (DOUBLE)ent->defense[(LONG)ltemp].blocktype;
3751             break;
3752         }
3753         case _ep_defense_knockdown:
3754         {
3755             (*pretvar)->dblVal = (DOUBLE)ent->defense[(LONG)ltemp].knockdown;
3756             break;
3757         }
3758         case _ep_defense_pain:
3759         {
3760             (*pretvar)->dblVal = (DOUBLE)ent->defense[(LONG)ltemp].pain;
3761             break;
3762         }
3763         default:
3764             *pretvar = NULL;
3765             return E_FAIL;
3766         }
3767         break;
3768     }
3769     case _ep_destx:
3770     {
3771         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3772         (*pretvar)->dblVal = (DOUBLE)ent->destx;
3773         break;
3774     }
3775     case _ep_destz:
3776     {
3777         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3778         (*pretvar)->dblVal = (DOUBLE)ent->destz;
3779         break;
3780     }
3781     case _ep_detect:
3782     {
3783         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3784         (*pretvar)->lVal = (LONG)ent->modeldata.stealth.detect;
3785         break;
3786     }
3787     case _ep_die_on_landing:
3788     {
3789         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3790         (*pretvar)->lVal = (LONG)ent->die_on_landing;
3791         break;
3792     }
3793     case _ep_direction:
3794     {
3795         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3796         (*pretvar)->lVal = (LONG)ent->direction;
3797         break;
3798     }
3799     case _ep_dropframe:
3800     {
3801         ltemp = 0;
3802         if(paramCount == 3)
3803         {
3804             arg = varlist[2];
3805             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
3806             {
3807                 ltemp = 0;
3808             }
3809         }
3810 
3811         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3812 
3813         if(ent->modeldata.animation[ltemp]->dropframe)
3814         {
3815             (*pretvar)->lVal = ent->modeldata.animation[ltemp]->dropframe->frame;
3816         }
3817 
3818         break;
3819     }
3820     case _ep_edelay:
3821     {
3822         arg = varlist[2];
3823         if(arg->vt != VT_INTEGER)
3824         {
3825             printf("You must provide a string name for edelay subproperty.\n\
3826 	~'cap_max'\n\
3827 	~'cap_min'\n\
3828 	~'factor'\n\
3829 	~'mode'\n\
3830 	~'range_max'\n\
3831 	~'range_min'\n");
3832             *pretvar = NULL;
3833             return E_FAIL;
3834         }
3835         ltemp = arg->lVal;
3836         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3837 
3838         switch(ltemp)
3839         {
3840         case _ep_edelay_mode:
3841         {
3842             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.mode;
3843             break;
3844         }
3845         case _ep_edelay_factor:
3846         {
3847             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3848             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edelay.factor;
3849             break;
3850         }
3851         case _ep_edelay_cap_min:
3852         {
3853             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.cap.min;
3854             break;
3855         }
3856         case _ep_edelay_cap_max:
3857         {
3858             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.cap.max;
3859             break;
3860         }
3861         case _ep_edelay_range_min:
3862         {
3863             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.range.min;
3864             break;
3865         }
3866         case _ep_edelay_range_max:
3867         {
3868             (*pretvar)->lVal = (LONG)ent->modeldata.edelay.range.max;
3869             break;
3870         }
3871         default:
3872             *pretvar = NULL;
3873             return E_FAIL;
3874         }
3875         break;
3876     }
3877     case _ep_edge:
3878     {
3879         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3880         (*pretvar)->lVal = (LONG)ent->edge;
3881         break;
3882     }
3883     case _ep_edgerange:
3884     {
3885         if(paramCount < 3)
3886         {
3887             break;
3888         }
3889         arg = varlist[2];
3890         if(arg->vt != VT_INTEGER)
3891         {
3892             printf("You must give a string name for edgerange.\n");
3893             return E_FAIL;
3894         }
3895         ltemp = arg->lVal;
3896 
3897         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3898         switch(ltemp)
3899         {
3900         case _ep_edgerange_x:
3901             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edgerange.x;
3902             break;
3903         case _ep_edgerange_z:
3904             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edgerange.z;
3905             break;
3906         default:
3907             ScriptVariant_Clear(*pretvar);
3908             return E_FAIL;
3909         }
3910         break;
3911     }
3912     case _ep_energycost:
3913     {
3914         if(paramCount < 4)
3915         {
3916             break;
3917         }
3918 
3919         if(varlist[2]->vt != VT_INTEGER)
3920         {
3921             printf("You must provide a string name for energycost.\n\
3922 	~'cost'\n\
3923 	~'disable'\n\
3924 	~'mponly'\n");
3925             *pretvar = NULL;
3926             return E_FAIL;
3927         }
3928         ltemp	= varlist[2]->lVal;												//Subproperty.
3929         i		= varlist[3]->lVal;												//Animation.
3930 
3931         if(!validanim(ent, i))													//Verify animation.
3932         {
3933             break;
3934         }
3935 
3936         switch(ltemp)
3937         {
3938         case _ep_energycost_cost:
3939             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3940             if(ent->modeldata.animation[i]->energycost)
3941             {
3942                 (*pretvar)->lVal = ent->modeldata.animation[i]->energycost->cost;
3943             }
3944 
3945             break;
3946         case _ep_energycost_disable:
3947             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3948             if(ent->modeldata.animation[i]->energycost)
3949             {
3950                 (*pretvar)->lVal = ent->modeldata.animation[i]->energycost->disable;
3951             }
3952             break;
3953         case _ep_energycost_mponly:
3954             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3955             if(ent->modeldata.animation[i]->energycost)
3956             {
3957                 (*pretvar)->lVal = ent->modeldata.animation[i]->energycost->mponly;
3958             }
3959             break;
3960         default:
3961             *pretvar = NULL;
3962             return E_FAIL;
3963         }
3964         break;
3965     }
3966     case _ep_escapecount:
3967     {
3968         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3969         (*pretvar)->lVal = (LONG)ent->escapecount;
3970         break;
3971     }
3972     case _ep_escapehits:
3973     {
3974         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3975         (*pretvar)->lVal = (LONG)ent->modeldata.escapehits;
3976         break;
3977     }
3978     case _ep_exists:
3979     {
3980         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3981         (*pretvar)->lVal = (LONG)ent->exists;
3982         break;
3983     }
3984     case _ep_facing:
3985     {
3986         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3987         (*pretvar)->lVal = (LONG)ent->modeldata.facing;
3988         break;
3989     }
3990     case _ep_falldie:
3991     {
3992         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3993         (*pretvar)->lVal = (LONG)ent->modeldata.falldie;
3994         break;
3995     }
3996     case _ep_flash:
3997     {
3998         arg = varlist[2];
3999         if(arg->vt != VT_INTEGER)
4000         {
4001             printf("You must give a string name for flash property.\n");
4002             *pretvar = NULL;
4003             return E_FAIL;
4004         }
4005         ltemp = arg->lVal;
4006         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4007 
4008         switch(ltemp)
4009         {
4010         case _ep_flash_block:
4011         {
4012             i = ent->modeldata.bflash;
4013             break;
4014         }
4015         case _ep_flash_def:
4016         {
4017             i = ent->modeldata.flash;
4018             break;
4019         }
4020         case _ep_flash_noattack:
4021         {
4022             i = ent->modeldata.noatflash;
4023             break;
4024         }
4025         default:
4026         {
4027             *pretvar = NULL;
4028             return E_FAIL;
4029         }
4030         }
4031         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4032         (*pretvar)->lVal = (LONG)i;
4033         break;
4034     }
4035     case _ep_pain_time:
4036     {
4037         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4038         (*pretvar)->lVal = (LONG)ent->next_hit_time;
4039         break;
4040     }
4041     case _ep_freezetime:
4042     {
4043         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4044         (*pretvar)->lVal = (LONG)ent->freezetime;
4045         break;
4046     }
4047     case _ep_frozen:
4048     {
4049         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4050         (*pretvar)->lVal = (LONG)ent->frozen;
4051         break;
4052     }
4053     case _ep_gfxshadow:
4054     {
4055         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4056         (*pretvar)->lVal = (LONG)ent->modeldata.gfxshadow;
4057         break;
4058     }
4059     case _ep_shadowbase:
4060     {
4061         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4062         (*pretvar)->lVal = (LONG)ent->modeldata.shadowbase;
4063         break;
4064     }
4065     case _ep_grabbing:
4066     {
4067         if(ent->grabbing) // always return an empty var if it is NULL
4068         {
4069             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4070             (*pretvar)->ptrVal = (VOID *)ent->grabbing;
4071         }
4072         break;
4073     }
4074     case _ep_grabforce:
4075     {
4076         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4077         (*pretvar)->lVal = (LONG)ent->modeldata.grabforce;
4078         break;
4079     }
4080     case _ep_guardpoints:
4081     {
4082         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4083         (*pretvar)->lVal = (LONG)ent->modeldata.guardpoints.current;
4084         break;
4085     }
4086     case _ep_hasplatforms:
4087     {
4088         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4089         (*pretvar)->lVal = (LONG)ent->modeldata.hasPlatforms;
4090         break;
4091     }
4092     case _ep_health:
4093     {
4094         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4095         (*pretvar)->lVal = (LONG)ent->energy_state.health_current;
4096         break;
4097     }
4098     case _ep_height:
4099     {
4100         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4101         (*pretvar)->lVal = (LONG)ent->modeldata.size.y;
4102         break;
4103     }
4104     case _ep_hitbyid:
4105     {
4106         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4107         (*pretvar)->lVal = (LONG)ent->attack_id_incoming;
4108         break;
4109     }
4110     case _ep_hitheadplatform:
4111     {
4112         ScriptVariant_ChangeType(*pretvar, VT_PTR);
4113         (*pretvar)->ptrVal = (VOID *)ent->hithead;
4114         break;
4115     }
4116     case _ep_landedplatform:
4117     {
4118         ScriptVariant_ChangeType(*pretvar, VT_PTR);
4119         (*pretvar)->ptrVal = (VOID *)ent->landed_on_platform;
4120         break;
4121     }
4122     case _ep_hitwall:
4123     {
4124         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4125         (*pretvar)->lVal = (LONG)ent->hitwall;
4126         break;
4127     }
4128     case _ep_hmapl:
4129     {
4130         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4131         (*pretvar)->lVal = (LONG)ent->modeldata.maps.hide_start;
4132         break;
4133     }
4134     case _ep_hmapu:
4135     {
4136         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4137         (*pretvar)->lVal = (LONG)ent->modeldata.maps.hide_end;
4138         break;
4139     }
4140     case _ep_icon:
4141     {
4142         arg = varlist[2];
4143         if(arg->vt != VT_INTEGER)
4144         {
4145             printf("You must provide a string name for icon subproperty:\n\
4146 	getentityproperty({ent}, 'icon', {subproperty});\n\
4147 	~'default'\n\
4148 	~'die'\n\
4149 	~'get'\n\
4150 	~'mphigh'\n\
4151 	~'mplow'\n\
4152 	~'mpmed'\n\
4153 	~'pain'\n\
4154 	~'weapon'\n\
4155 	~'x'\n\
4156 	~'y'\n");
4157             *pretvar = NULL;
4158             return E_FAIL;
4159         }
4160         ltemp = arg->lVal;
4161         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4162 
4163         switch(ltemp)
4164         {
4165         case _ep_icon_def:
4166         {
4167             i = ent->modeldata.icon.def;
4168             break;
4169         }
4170         case _ep_icon_die:
4171         {
4172             i = ent->modeldata.icon.die;
4173             break;
4174         }
4175         case _ep_icon_get:
4176         {
4177             i = ent->modeldata.icon.get;
4178             break;
4179         }
4180         case _ep_icon_mphigh:
4181         {
4182             i = ent->modeldata.icon.mphigh;
4183             break;
4184         }
4185         case _ep_icon_mplow:
4186         {
4187             i = ent->modeldata.icon.mplow;
4188             break;
4189         }
4190         case _ep_icon_mpmed:
4191         {
4192             i = ent->modeldata.icon.mpmed;
4193             break;
4194         }
4195         case _ep_icon_pain:
4196         {
4197             i = ent->modeldata.icon.pain;
4198             break;
4199         }
4200         case _ep_icon_weapon:
4201         {
4202             i = ent->modeldata.icon.weapon;
4203             break;
4204         }
4205         case _ep_icon_x:
4206         {
4207             i = ent->modeldata.icon.position.x;
4208             break;
4209         }
4210         case _ep_icon_y:
4211         {
4212             i = ent->modeldata.icon.position.y;
4213             break;
4214         }
4215         default:
4216         {
4217             *pretvar = NULL;
4218             return E_FAIL;
4219         }
4220         }
4221 
4222         if (i >= 0)
4223         {
4224             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4225             spr = sprite_map[i].node->sprite;
4226             spr->centerx = sprite_map[i].centerx;
4227             spr->centery = sprite_map[i].centery;
4228             (*pretvar)->ptrVal = (VOID *)(spr);
4229         }
4230         else
4231         {
4232             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4233             (*pretvar)->lVal = -1;
4234         }
4235         break;
4236     }
4237     case _ep_invincible:
4238     {
4239         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4240         (*pretvar)->lVal = (LONG)ent->invincible;
4241         break;
4242     }
4243     case _ep_invinctime:
4244     {
4245         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4246         (*pretvar)->lVal = (LONG)ent->invinctime;
4247         break;
4248     }
4249     case _ep_jugglepoints:
4250     {
4251         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4252         (*pretvar)->lVal = (LONG)ent->modeldata.jugglepoints.current;
4253         break;
4254     }
4255     case _ep_jumpheight:
4256     {
4257         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4258         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.jumpheight;
4259         break;
4260     }
4261     case _ep_jumpmovex:
4262     {
4263         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4264         (*pretvar)->lVal = (LONG)ent->modeldata.jumpmovex;
4265         break;
4266     }
4267     case _ep_jumpmovez:
4268     {
4269         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4270         (*pretvar)->lVal = (LONG)ent->modeldata.jumpmovez;
4271         break;
4272     }
4273     case _ep_jumpspeed:
4274     {
4275         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4276         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.jumpspeed;
4277         break;
4278     }
4279     case _ep_knockdowncount:
4280     {
4281         /*
4282         2011_04_14, DC: Backward compatability; default to current if subproperty not provided.
4283         */
4284         if(paramCount < 3)
4285         {
4286             ltemp = _ep_knockdowncount_current;
4287         }
4288         else
4289         {
4290             arg = varlist[2];
4291 
4292             if(arg->vt != VT_INTEGER)
4293             {
4294                 printf("You must provide a string name for knockdowncount subproperty:\n\
4295 		getentityproperty({ent}, 'knockdowncount', {subproperty})\n\
4296 		~'current'\n\
4297 		~'max'\n\
4298 		~'time'\n");
4299                 *pretvar = NULL;
4300                 return E_FAIL;
4301             }
4302 
4303             ltemp = arg->lVal;
4304         }
4305 
4306         switch(ltemp)
4307         {
4308         case _ep_knockdowncount_current:
4309             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4310             (*pretvar)->dblVal = (DOUBLE)ent->knockdowncount;
4311             break;
4312         case _ep_knockdowncount_max:
4313             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4314             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.knockdowncount;
4315             break;
4316         case _ep_knockdowncount_time:
4317             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4318             (*pretvar)->lVal = (LONG)ent->knockdowncount;
4319             break;
4320         default:
4321             *pretvar = NULL;
4322             return E_FAIL;
4323         }
4324         break;
4325     }
4326     case _ep_komap:
4327     {
4328         if(paramCount < 2)
4329         {
4330             break;
4331         }
4332 
4333         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4334         (*pretvar)->lVal = (LONG)ent->modeldata.maps.ko;
4335         break;
4336     }
4337     case _ep_landframe:
4338     {
4339         if(paramCount < 4)
4340         {
4341             break;
4342         }
4343 
4344         if(varlist[2]->vt != VT_INTEGER
4345                 || varlist[3]->vt != VT_INTEGER)
4346         {
4347             printf("\n Error, getentityproperty({ent}, 'landframe', {sub property}, {animation}): {Sub property} or {Animation} parameter is missing or invalid. \n");
4348             *pretvar = NULL;
4349             return E_FAIL;
4350         }
4351         ltemp	= varlist[2]->lVal;												//Subproperty.
4352         i		= varlist[3]->lVal;												//Animation.
4353 
4354         if(!validanim(ent, i))													//Verify animation.
4355         {
4356             break;
4357         }
4358 
4359         // entity must have a land frame set.
4360         if(!ent->modeldata.animation[i]->landframe)
4361         {
4362             break;
4363         }
4364 
4365         switch(ltemp)
4366         {
4367         case _ep_landframe_ent:
4368             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4369             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->landframe->ent;
4370             break;
4371         case _ep_landframe_frame:
4372             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4373             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->landframe->frame;
4374             break;
4375         default:
4376             *pretvar = NULL;
4377             return E_FAIL;
4378         }
4379         break;
4380     }
4381     case _ep_lifespancountdown:
4382     {
4383         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4384         (*pretvar)->lVal = (LONG)ent->lifespancountdown;
4385         break;
4386     }
4387     case _ep_attackthrottle:
4388     {
4389         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4390         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.attackthrottle;
4391         break;
4392     }
4393     case _ep_attackthrottletime:
4394     {
4395         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4396         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.attackthrottletime;
4397         break;
4398     }
4399     case _ep_link:
4400     {
4401         if(ent->link) // always return an empty var if it is NULL
4402         {
4403             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4404             (*pretvar)->ptrVal = (VOID *)ent->link;
4405         }
4406         break;
4407     }
4408     case _ep_map:
4409     {
4410         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4411         (*pretvar)->lVal = (LONG)0;
4412         for(i = 0; i < ent->modeldata.maps_loaded; i++)
4413         {
4414             if(ent->colourmap == ent->modeldata.colourmap[i])
4415             {
4416                 (*pretvar)->lVal = (LONG)(i + 1);
4417                 break;
4418             }
4419         }
4420         break;
4421     }
4422     case _ep_mapcount:
4423     {
4424         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4425         (*pretvar)->lVal = (LONG)(ent->modeldata.maps_loaded + 1);
4426         break;
4427     }
4428     case _ep_mapdefault:
4429     {
4430         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4431         (*pretvar)->lVal = (LONG)(ent->map);
4432         break;
4433     }
4434     case _ep_maps:
4435     {
4436         arg = varlist[2];
4437         if(arg->vt != VT_INTEGER)
4438         {
4439             printf("You must give a string name for maps property.\n");
4440             *pretvar = NULL;
4441             return E_FAIL;
4442         }
4443         ltemp = arg->lVal;
4444         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4445 
4446         switch(ltemp)
4447         {
4448         case _ep_maps_count:
4449         {
4450             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4451             (*pretvar)->lVal = (LONG)(ent->modeldata.maps_loaded + 1);
4452             break;
4453         }
4454 
4455         case _ep_maps_current:
4456         {
4457             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4458             (*pretvar)->lVal = (LONG)0;
4459             for(i = 0; i < ent->modeldata.maps_loaded; i++)
4460             {
4461                 if(ent->colourmap == ent->modeldata.colourmap[i])
4462                 {
4463                     (*pretvar)->lVal = (LONG)(i + 1);
4464                     break;
4465                 }
4466             }
4467             break;
4468         }
4469         case _ep_maps_dying:
4470         {
4471             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4472             if(paramCount >= 3)
4473             {
4474                 if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
4475                 {
4476                     printf("You must specify the integer value for remap.\n");
4477                     *pretvar = NULL;
4478                     return E_FAIL;
4479                 }
4480                 else
4481                 {
4482                     if (ltemp == 0) (*pretvar)->lVal = (LONG)(ent->dying);
4483                     else (*pretvar)->lVal = (LONG)(ent->dying2);
4484                 }
4485             }
4486             else
4487             {
4488                 (*pretvar)->lVal = (LONG)(ent->dying);
4489             }
4490             break;
4491         }
4492         case _ep_maps_dying_critical:
4493         {
4494             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4495             (*pretvar)->lVal = (LONG)(ent->per2);
4496             break;
4497         }
4498         case _ep_maps_dying_low:
4499         {
4500             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4501             (*pretvar)->lVal = (LONG)(ent->per1);
4502             break;
4503         }
4504         case _ep_maps_frozen:
4505         {
4506             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4507             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.frozen);
4508             break;
4509         }
4510         case _ep_maps_hide_end:
4511         {
4512             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4513             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.hide_end);
4514             break;
4515         }
4516         case _ep_maps_hide_start:
4517         {
4518             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4519             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.hide_start);
4520             break;
4521         }
4522         case _ep_maps_ko:
4523         {
4524             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4525             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.ko);
4526             break;
4527         }
4528         case _ep_maps_kotype:
4529         {
4530             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4531             (*pretvar)->lVal = (LONG)(ent->modeldata.maps.kotype);
4532             break;
4533         }
4534         case _ep_maps_table:
4535         {
4536             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4537             (*pretvar)->ptrVal = (VOID *)(ent->colourmap);
4538             break;
4539         }
4540         case _ep_maps_time:
4541         {
4542             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4543             (*pretvar)->lVal = (LONG)(ent->maptime);
4544             break;
4545         }
4546         default:
4547         {
4548             *pretvar = NULL;
4549             return E_FAIL;
4550         }
4551         }
4552         break;
4553     }
4554     case _ep_maxguardpoints:
4555     {
4556         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4557         (*pretvar)->lVal = (LONG)ent->modeldata.guardpoints.max;
4558         break;
4559     }
4560     case _ep_maxhealth:
4561     {
4562         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4563         (*pretvar)->lVal = (LONG)ent->modeldata.health;
4564         break;
4565     }
4566     case _ep_maxjugglepoints:
4567     {
4568         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4569         (*pretvar)->lVal = (LONG)ent->modeldata.jugglepoints.max;
4570         break;
4571     }
4572     case _ep_maxmp:
4573     {
4574         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4575         (*pretvar)->lVal = (LONG)ent->modeldata.mp;
4576         break;
4577     }
4578     case _ep_model:
4579     {
4580         ScriptVariant_ChangeType(*pretvar, VT_STR);
4581         (*pretvar)->strVal = StrCache_CreateNewFrom(ent->model->name);
4582         break;
4583     }
4584     case _ep_movex:
4585     {
4586         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4587         (*pretvar)->dblVal = (DOUBLE)ent->movex;
4588         break;
4589     }
4590     case _ep_movez:
4591     {
4592         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4593         (*pretvar)->dblVal = (DOUBLE)ent->movex;
4594         break;
4595     }
4596     case _ep_entitypushing:
4597     {
4598         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4599         (*pretvar)->lVal = (LONG)ent->modeldata.entitypushing;
4600         break;
4601     }
4602     case _ep_pushingfactor:
4603     {
4604         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4605         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.pushingfactor;
4606         break;
4607     }
4608     case _ep_mp:
4609     {
4610         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4611         (*pretvar)->lVal = (LONG)ent->energy_state.mp_current;
4612         break;
4613     }
4614     case _ep_mpdroprate:
4615     {
4616         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4617         (*pretvar)->lVal = (LONG)ent->modeldata.mpdroprate;
4618         break;
4619     }
4620     case _ep_mprate:
4621     {
4622         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4623         (*pretvar)->lVal = (LONG)ent->modeldata.mprate;
4624         break;
4625     }
4626     case _ep_mpstable:
4627     {
4628         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4629         (*pretvar)->lVal = (LONG)ent->modeldata.mpstable;
4630         break;
4631     }
4632     case _ep_mpstableval:
4633     {
4634         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4635         (*pretvar)->lVal = (LONG)ent->modeldata.mpstableval;
4636         break;
4637     }
4638     case _ep_name:
4639     {
4640         ScriptVariant_ChangeType(*pretvar, VT_STR);
4641         (*pretvar)->strVal = StrCache_CreateNewFrom(ent->name);
4642         break;
4643     }
4644     case _ep_nextanim:
4645     {
4646         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4647         (*pretvar)->lVal = (LONG)ent->nextanim;
4648         break;
4649     }
4650     case _ep_nextmove:
4651     {
4652         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4653         (*pretvar)->lVal = (LONG)ent->nextmove;
4654         break;
4655     }
4656     case _ep_nextthink:
4657     {
4658         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4659         (*pretvar)->lVal = (LONG)ent->nextthink;
4660         break;
4661     }
4662     case _ep_no_adjust_base:
4663     {
4664         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4665         (*pretvar)->lVal = (LONG)ent->modeldata.no_adjust_base;
4666         break;
4667     }
4668     case _ep_noaicontrol:
4669     {
4670         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4671         (*pretvar)->lVal = (LONG)ent->noaicontrol;
4672         break;
4673     }
4674     case _ep_nodieblink:
4675     {
4676         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4677         (*pretvar)->lVal = (LONG)ent->modeldata.nodieblink;
4678         break;
4679     }
4680     case _ep_nodrop:
4681     {
4682         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4683         (*pretvar)->lVal = (LONG)ent->modeldata.nodrop;
4684         break;
4685     }
4686     case _ep_nograb:
4687     {
4688         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4689         (*pretvar)->lVal = (LONG)ent->nograb;
4690         break;
4691     }
4692     case _ep_nohithead:
4693     {
4694         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4695         (*pretvar)->lVal = (LONG)ent->modeldata.nohithead;
4696         break;
4697     }
4698     case _ep_nolife:
4699     {
4700         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4701         (*pretvar)->lVal = (LONG)ent->modeldata.nolife;
4702         break;
4703     }
4704     case _ep_nopain:
4705     {
4706         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4707         (*pretvar)->lVal = (LONG)ent->modeldata.nopain;
4708         break;
4709     }
4710     case _ep_offense:
4711     {
4712         ltemp = 0;
4713         if(paramCount >= 3)
4714         {
4715             arg = varlist[2];
4716             if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
4717             {
4718                 ltemp = (LONG)0;
4719             }
4720         }
4721         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4722         (*pretvar)->dblVal = (DOUBLE)ent->offense_factors[(LONG)ltemp];
4723         break;
4724     }
4725     case _ep_offscreen_noatk_factor:
4726     {
4727         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4728         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.offscreen_noatk_factor;
4729         break;
4730     }
4731     case _ep_offscreenkill:
4732     {
4733         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4734         (*pretvar)->lVal = (LONG)ent->modeldata.offscreenkill;
4735         break;
4736     }
4737     case _ep_opponent:
4738     {
4739         if(ent->opponent) // always return an empty var if it is NULL
4740         {
4741             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4742             (*pretvar)->ptrVal = (VOID *)ent->opponent;
4743         }
4744         break;
4745     }
4746     case _ep_custom_target:
4747     {
4748         if(ent->custom_target) // always return an empty var if it is NULL
4749         {
4750             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4751             (*pretvar)->ptrVal = (VOID *)ent->custom_target;
4752         }
4753         break;
4754     }
4755     case _ep_owner:
4756     {
4757         if(ent->owner) // always return an empty var if it is NULL
4758         {
4759             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4760             (*pretvar)->ptrVal = (VOID *)ent->owner;
4761         }
4762         break;
4763     }
4764     case _ep_parent:
4765     {
4766         if(ent->parent) // always return an empty var if it is NULL
4767         {
4768             ScriptVariant_ChangeType(*pretvar, VT_PTR);
4769             (*pretvar)->ptrVal = (VOID *)ent->parent;
4770         }
4771         break;
4772     }
4773     case _ep_path:
4774     {
4775         ScriptVariant_ChangeType(*pretvar, VT_STR);
4776         (*pretvar)->strVal = StrCache_CreateNewFrom(ent->modeldata.path);
4777         break;
4778     }
4779     case _ep_pathfindstep:
4780     {
4781         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4782         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.pathfindstep;
4783         //printf("%d %s %d\n", ent->sortid, ent->name, ent->playerindex);
4784         break;
4785     }
4786     case _ep_playerindex:
4787     {
4788         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4789         (*pretvar)->lVal = (LONG)ent->playerindex;
4790         //printf("%d %s %d\n", ent->sortid, ent->name, ent->playerindex);
4791         break;
4792     }
4793     case _ep_projectile:
4794     {
4795         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4796         (*pretvar)->lVal = (LONG)ent->projectile;
4797         break;
4798     }
4799     case _ep_range:
4800     {
4801         if(paramCount < 4)
4802         {
4803             break;
4804         }
4805 
4806         if(varlist[2]->vt != VT_INTEGER
4807                 || varlist[3]->vt != VT_INTEGER)
4808         {
4809             printf("\n Error, getentityproperty({ent}, 'range', {sub property}, {animation}): {Sub property} or {Animation} parameter is missing or invalid. \n");
4810             *pretvar = NULL;
4811             return E_FAIL;
4812         }
4813         ltemp	= varlist[2]->lVal;												//Subproperty.
4814         i		= varlist[3]->lVal;												//Animation.
4815 
4816         if(!validanim(ent, i))													//Verify animation.
4817         {
4818             break;
4819         }
4820 
4821         switch(ltemp)
4822         {
4823         case _ep_range_amax:
4824             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4825             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.y.max;
4826             break;
4827         case _ep_range_amin:
4828             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4829             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.y.min;
4830             break;
4831         case _ep_range_bmax:
4832             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4833             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.base.max;
4834             break;
4835         case _ep_range_bmin:
4836             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4837             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.base.min;
4838             break;
4839         case _ep_range_xmax:
4840             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4841             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.x.max;
4842             break;
4843         case _ep_range_xmin:
4844             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4845             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.x.min;
4846             break;
4847         case _ep_range_zmax:
4848             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4849             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.z.max;
4850             break;
4851         case _ep_range_zmin:
4852             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4853             (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.z.min;
4854             break;
4855         default:
4856             *pretvar = NULL;
4857             return E_FAIL;
4858         }
4859         break;
4860     }
4861     case _ep_running:
4862     {
4863         if(paramCount < 3)
4864         {
4865             break;
4866         }
4867         arg = varlist[2];
4868         if(arg->vt != VT_INTEGER)
4869         {
4870             printf("You must give a string name for running property.\n");
4871             *pretvar = NULL;
4872             return E_FAIL;
4873         }
4874         ltemp = arg->lVal;
4875         switch(ltemp)
4876         {
4877         case _ep_running_speed:
4878         {
4879             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4880             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.runspeed;
4881             break;
4882         }
4883         case _ep_running_jumpy:
4884         {
4885             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4886             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.runjumpheight;
4887             break;
4888         }
4889         case _ep_running_jumpx:
4890         {
4891             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4892             (*pretvar)->dblVal = (DOUBLE)ent->modeldata.runjumpdist;
4893             break;
4894         }
4895         case _ep_running_land:
4896         {
4897             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4898             (*pretvar)->lVal = (LONG)ent->modeldata.runhold;
4899             break;
4900         }
4901         case _ep_running_movez:
4902         {
4903             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4904             (*pretvar)->lVal = (LONG)ent->modeldata.runupdown;
4905             break;
4906         }
4907         }
4908         break;
4909     }
4910     case _ep_rush_count:
4911     {
4912         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4913         (*pretvar)->lVal = (LONG)ent->rush.count.current;
4914         break;
4915     }
4916     case _ep_rush_tally:
4917     {
4918         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4919         (*pretvar)->lVal = (LONG)ent->rush.count.max;
4920         break;
4921     }
4922     case _ep_rush_time:
4923     {
4924         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4925         (*pretvar)->lVal = (LONG)ent->rush.time;
4926         break;
4927     }
4928     case _ep_score:
4929     {
4930         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4931         (*pretvar)->lVal = (LONG)ent->modeldata.score;
4932         break;
4933     }
4934     case _ep_scroll:
4935     {
4936         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4937         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.scroll;
4938         break;
4939     }
4940     case _ep_seal:
4941     {
4942         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4943         (*pretvar)->lVal = (LONG)ent->seal;
4944         break;
4945     }
4946     case _ep_sealtime:
4947     {
4948         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4949         (*pretvar)->lVal = (LONG)ent->sealtime;
4950         break;
4951     }
4952     case _ep_setlayer:
4953     {
4954         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4955         (*pretvar)->lVal = (LONG)ent->modeldata.setlayer;
4956         break;
4957     }
4958     case _ep_sortid:
4959     {
4960         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4961         (*pretvar)->lVal = (LONG)ent->sortid;
4962         break;
4963     }
4964     case _ep_spawntype:
4965     {
4966         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4967         (*pretvar)->lVal = (LONG)ent->spawntype;
4968         break;
4969     }
4970     case _ep_speed:
4971     {
4972         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4973         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.speed;
4974         break;
4975     }
4976     case _ep_sprite:
4977     {
4978         ScriptVariant_ChangeType(*pretvar, VT_PTR);
4979         i = ent->animation->sprite[ent->animpos];
4980         spr = sprite_map[i].node->sprite;
4981         spr->centerx = sprite_map[i].centerx;
4982         spr->centery = sprite_map[i].centery;
4983         (*pretvar)->ptrVal = (VOID *)(spr);
4984         break;
4985     }
4986     case _ep_spritea:
4987     {
4988         /*
4989         2011_04_17, DC: Modder can now specify animation and frame to return sprite from.
4990         To retain backward compatibility, sprite from current animation/frame is returned
4991         when animation and/or frame parameters are not provided.
4992         */
4993 
4994         ltemp   = varlist[2]->lVal;
4995         arg     = varlist[3];
4996         arg1    = varlist[4];
4997 
4998         /*
4999         Request from animation or frame that doesn't exist = shutdown.
5000         Let's be more user friendly then that; return empty so modder can evaluate
5001         and take action accordingly.*/
5002         if(!validanim(ent, arg->lVal) || !(ent->modeldata.animation[arg->lVal]->numframes >= arg1->lVal))
5003         {
5004             break;
5005         }
5006 
5007         i = ent->modeldata.animation[arg->lVal]->sprite[arg1->lVal];
5008 
5009         switch(ltemp)
5010         {
5011         case _ep_spritea_centerx:
5012         {
5013             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5014             (*pretvar)->lVal = (LONG)sprite_map[i].centerx;
5015             break;
5016         }
5017         case _ep_spritea_centery:
5018         {
5019             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5020             (*pretvar)->lVal = (LONG)sprite_map[i].centery;
5021             break;
5022         }
5023         case _ep_spritea_file:
5024         {
5025             ScriptVariant_ChangeType(*pretvar, VT_STR);
5026             (*pretvar)->strVal = StrCache_CreateNewFrom(sprite_map[i].node->filename);
5027             break;
5028         }
5029         case _ep_spritea_offsetx:
5030         {
5031             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5032             (*pretvar)->lVal = (LONG)sprite_map[i].node->sprite->offsetx;
5033             break;
5034         }
5035         case _ep_spritea_offsety:
5036         {
5037             ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5038             (*pretvar)->lVal = (LONG)sprite_map[i].node->sprite->offsety;
5039             break;
5040         }
5041         case _ep_spritea_sprite:
5042         {
5043             ScriptVariant_ChangeType(*pretvar, VT_PTR);
5044             spr = sprite_map[i].node->sprite;
5045             spr->centerx = sprite_map[i].centery;
5046             spr->centery = sprite_map[i].centery;
5047             (*pretvar)->ptrVal = (VOID *)(spr);
5048             break;
5049         }
5050         default:
5051         {
5052             *pretvar = NULL;
5053             return E_FAIL;
5054         }
5055         }
5056 
5057         break;
5058 
5059     }
5060     case _ep_stalltime:
5061     {
5062         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5063         (*pretvar)->lVal = (LONG)ent->stalltime;
5064         break;
5065     }
5066     case _ep_releasetime:
5067     {
5068         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5069         (*pretvar)->lVal = (LONG)ent->releasetime;
5070         break;
5071     }
5072     case _ep_staydown:
5073     {
5074         arg = varlist[2];
5075         if(arg->vt != VT_INTEGER)
5076         {
5077 
5078             printf("You must provide a string name for staydown property:\n\
5079 	getentityproperty({ent}, 'staydown', {subproperty})\n\
5080 	~'rise'\n\
5081 	~'riseattack'\n\
5082 	~'riseattack_stall' \n");
5083             *pretvar = NULL;
5084             return E_FAIL;
5085         }
5086         ltemp = arg->lVal;
5087         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5088 
5089         switch(ltemp)
5090         {
5091         case _ep_staydown_rise:
5092         {
5093             i = ent->staydown.rise;
5094             break;
5095         }
5096         case _ep_staydown_riseattack:
5097         {
5098             i = ent->staydown.riseattack;
5099             break;
5100         }
5101         case _ep_staydown_riseattack_stall:
5102         {
5103             i = ent->staydown.riseattack_stall;
5104             break;
5105         }
5106         default:
5107         {
5108             *pretvar = NULL;
5109             return E_FAIL;
5110         }
5111         }
5112         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5113         (*pretvar)->lVal = (LONG)i;
5114         break;
5115     }
5116     case _ep_stealth:
5117     {
5118         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5119         (*pretvar)->lVal = (LONG)ent->modeldata.stealth.hide;
5120         break;
5121     }
5122     case _ep_subentity:
5123     {
5124         if(ent->subentity) // always return an empty var if it is NULL
5125         {
5126             ScriptVariant_ChangeType(*pretvar, VT_PTR);
5127             (*pretvar)->ptrVal = (VOID *)ent->subentity;
5128         }
5129         break;
5130     }
5131     case _ep_subject_to_basemap:
5132     {
5133         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5134         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_basemap;
5135         break;
5136     }
5137     case _ep_subject_to_gravity:
5138     {
5139         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5140         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_gravity;
5141         break;
5142     }
5143     case _ep_subject_to_hole:
5144     {
5145         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5146         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_hole;
5147         break;
5148     }
5149     case _ep_subject_to_maxz:
5150     {
5151         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5152         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_maxz;
5153         break;
5154     }
5155     case _ep_subject_to_minz:
5156     {
5157         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5158         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_minz;
5159         break;
5160     }
5161     case _ep_subject_to_obstacle:
5162     {
5163         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5164         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_obstacle;
5165         break;
5166     }
5167     case _ep_subject_to_platform:
5168     {
5169         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5170         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_platform;
5171         break;
5172     }
5173     case _ep_subject_to_screen:
5174     {
5175         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5176         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_screen;
5177         break;
5178     }
5179     case _ep_subject_to_wall:
5180     {
5181         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5182         (*pretvar)->lVal = (LONG)ent->modeldata.subject_to_wall;
5183         break;
5184     }
5185     case _ep_subtype:
5186     {
5187         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5188         (*pretvar)->lVal = (LONG)ent->modeldata.subtype;
5189         break;
5190     }
5191     case _ep_thold:
5192     {
5193         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5194         (*pretvar)->lVal = (LONG)ent->modeldata.thold;
5195         break;
5196     }
5197     case _ep_throwdamage:
5198     {
5199         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5200         (*pretvar)->lVal = (LONG)ent->modeldata.throwdamage;
5201         break;
5202     }
5203     case _ep_throwdist:
5204     {
5205         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5206         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.throwdist;
5207         break;
5208     }
5209     case _ep_throwframewait:
5210     {
5211         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5212         (*pretvar)->lVal = (LONG)ent->modeldata.throwframewait;
5213         break;
5214     }
5215     case _ep_throwheight:
5216     {
5217         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5218         (*pretvar)->dblVal = (DOUBLE)ent->modeldata.throwheight;
5219         break;
5220     }
5221     case _ep_tosstime:
5222     {
5223         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5224         (*pretvar)->lVal = (LONG)ent->toss_time;
5225         break;
5226     }
5227     case _ep_tossv:
5228     {
5229         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5230         (*pretvar)->dblVal = (DOUBLE)ent->velocity.y;
5231         break;
5232     }
5233     case _ep_type:
5234     {
5235         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5236         (*pretvar)->lVal = (LONG)ent->modeldata.type;
5237         break;
5238     }
5239     case _ep_walkoffmovex:
5240     {
5241         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5242         (*pretvar)->lVal = (LONG)ent->modeldata.walkoffmovex;
5243         break;
5244     }
5245     case _ep_walkoffmovez:
5246     {
5247         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5248         (*pretvar)->lVal = (LONG)ent->modeldata.walkoffmovez;
5249         break;
5250     }
5251     case _ep_weapent:
5252     {
5253         ScriptVariant_ChangeType(*pretvar, VT_PTR);
5254         (*pretvar)->ptrVal = (VOID *)ent->weapent;
5255         break;
5256     }
5257     case _ep_numweapons:
5258     {
5259         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5260         (*pretvar)->lVal = (LONG)ent->modeldata.numweapons;
5261         break;
5262     }
5263     case _ep_weapnum:
5264     {
5265         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5266         (*pretvar)->lVal = (LONG)ent->modeldata.weapnum;
5267         break;
5268     }
5269     case _ep_weaploss:
5270     {
5271         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5272         if(paramCount >= 3)
5273         {
5274             if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5275             {
5276                 printf("You must specify the flag value.\n");
5277                 *pretvar = NULL;
5278                 return E_FAIL;
5279             }
5280 
5281             if (ltemp == 0) (*pretvar)->lVal = (LONG)ent->modeldata.weaploss[0];
5282             else (*pretvar)->lVal = (LONG)ent->modeldata.weaploss[1];
5283         }
5284         else (*pretvar)->lVal = (LONG)ent->modeldata.weaploss[0];
5285 
5286         break;
5287     }
5288     case _ep_x:
5289     {
5290         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5291         (*pretvar)->dblVal = (DOUBLE)ent->position.x;
5292         break;
5293     }
5294     case _ep_xdir:
5295     {
5296         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5297         (*pretvar)->dblVal = (DOUBLE)ent->velocity.x;
5298         break;
5299     }
5300     case _ep_z:
5301     {
5302         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5303         (*pretvar)->dblVal = (DOUBLE)ent->position.z;
5304         break;
5305     }
5306     case _ep_zdir:
5307     {
5308         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5309         (*pretvar)->dblVal = (DOUBLE)ent->velocity.z;
5310         break;
5311     }
5312     default:
5313         //printf("Property name '%s' is not supported by function getentityproperty.\n", propname);
5314         *pretvar = NULL;
5315         return E_FAIL;
5316         break;
5317     }
5318 
5319     return S_OK;
5320 }
5321 
5322 
5323 //changeentityproperty(pentity, propname, value1[ ,value2, value3, ...]);
openbor_changeentityproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5324 HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
5325 {
5326     entity *ent = NULL;
5327     s_model *tempmodel ;
5328     char *tempstr = NULL;
5329     LONG ltemp, ltemp2;
5330     DOUBLE dbltemp;
5331     int propind;
5332     int i = 0;
5333 
5334     static const void *actions[] =   // for takeaction
5335     {
5336         bomb_explode,
5337         common_animation_normal,
5338         common_attack_proc,
5339         common_block,
5340         common_drop,
5341         common_fall,
5342         common_get,
5343         common_grab,
5344         common_grabattack,
5345         common_grabbed,
5346         common_jump,
5347         common_land,
5348         common_lie,
5349         common_pain,
5350         common_prejump,
5351         common_rise,
5352         common_spawn,
5353         common_turn,
5354         normal_prepare,
5355         npc_warp,
5356         player_blink,
5357         suicide,
5358     };
5359 
5360     static const int entitytypes[] =
5361     {
5362         0, // "ground"; not a real entity type
5363         TYPE_ENEMY,
5364         TYPE_NPC,
5365         TYPE_OBSTACLE,
5366         TYPE_PLAYER,
5367         TYPE_SHOT,
5368 
5369     };
5370 
5371     static const void *think[] =   // 2011_03_03, DC: Think types.
5372     {
5373         common_think,
5374         player_think,
5375         steam_think,
5376         steamer_think,
5377         text_think,
5378         trap_think,
5379     };
5380 
5381     *pretvar = NULL;
5382 
5383     if(paramCount < 3)
5384     {
5385         printf("Function changeentityproperty must have have at least 3 parameters.");
5386         goto changeentityproperty_error;
5387     }
5388 
5389     mapstrings_entityproperty(varlist, paramCount);
5390 
5391     if(varlist[0]->vt != VT_PTR && varlist[0]->vt != VT_EMPTY)
5392     {
5393         printf("Function changeentityproperty must have a valid entity handle.");
5394         goto changeentityproperty_error;
5395     }
5396     ent = (entity *)varlist[0]->ptrVal; //retrieve the entity
5397     if(!ent)
5398     {
5399         return S_OK;
5400     }
5401 
5402     if(varlist[1]->vt != VT_INTEGER)
5403     {
5404         if(varlist[1]->vt != VT_STR)
5405         {
5406             printf("Function changeentityproperty must have a string property name.\n");
5407         }
5408         goto changeentityproperty_error;
5409     }
5410 
5411     propind = varlist[1]->lVal;
5412 
5413     switch(propind)
5414     {
5415     case _ep_aggression:
5416     {
5417         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5418         {
5419             ent->modeldata.aggression = (LONG)ltemp;
5420         }
5421         break;
5422     }
5423     case _ep_aiattack:
5424     {
5425         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5426         {
5427             ent->modeldata.aiattack = (LONG)ltemp;
5428         }
5429         break;
5430     }
5431     case _ep_aiflag:
5432     {
5433         if(varlist[2]->vt != VT_INTEGER)
5434         {
5435             if(varlist[2]->vt != VT_STR)
5436             {
5437                 printf("You must give a string value for AI flag name.\n");
5438             }
5439             goto changeentityproperty_error;
5440         }
5441         if(paramCount < 4)
5442         {
5443             break;
5444         }
5445 
5446         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5447         {
5448             switch(varlist[2]->lVal)
5449             {
5450             case _ep_aiflag_dead:
5451                 ent->dead = (LONG)ltemp;
5452                 break;
5453             case _ep_aiflag_jumpid:
5454                 ent->jump.animation_id = (LONG)ltemp;
5455                 break;
5456             case _ep_aiflag_jumping:
5457                 ent->jumping = (LONG)ltemp;
5458                 break;
5459             case _ep_aiflag_idling:
5460                 ent->idling = (LONG)ltemp;
5461                 break;
5462             case _ep_aiflag_drop:
5463                 ent->drop = (LONG)ltemp;
5464                 break;
5465             case _ep_aiflag_attacking:
5466                 ent->attacking = (LONG)ltemp;
5467                 break;
5468             case _ep_aiflag_getting:
5469                 ent->getting = (LONG)ltemp;
5470                 break;
5471             case _ep_aiflag_turning:
5472                 ent->turning = (LONG)ltemp;
5473                 break;
5474             case _ep_aiflag_charging:
5475                 ent->charging = (LONG)ltemp;
5476                 break;
5477             case _ep_aiflag_blocking:
5478                 ent->blocking = (LONG)ltemp;
5479                 break;
5480             case _ep_aiflag_ducking:
5481                 ent->ducking = (LONG)ltemp;
5482                 break;
5483             case _ep_aiflag_falling:
5484                 ent->falling = (LONG)ltemp;
5485                 break;
5486             case _ep_aiflag_running:
5487                 ent->running = (LONG)ltemp;
5488                 break;
5489             case _ep_aiflag_inpain:
5490                 ent->inpain = (LONG)ltemp;
5491                 break;
5492             case _ep_aiflag_rising:
5493                 ent->rising = (LONG)ltemp;
5494                 break;
5495             case _ep_aiflag_inbackpain:
5496                 ent->inbackpain = (LONG)ltemp;
5497                 break;
5498             case _ep_aiflag_projectile:
5499                 ent->projectile = (LONG)ltemp;
5500                 break;
5501             case _ep_aiflag_frozen:
5502                 ent->frozen = (LONG)ltemp;
5503                 break;
5504             case _ep_aiflag_toexplode:
5505                 ent->toexplode = (LONG)ltemp;
5506                 break;
5507             case _ep_aiflag_animating:
5508                 ent->animating = (LONG)ltemp;
5509                 break;
5510             case _ep_aiflag_blink:
5511                 ent->blink = (LONG)ltemp;
5512                 break;
5513             case _ep_aiflag_invincible:
5514                 ent->invincible = (LONG)ltemp;
5515                 break;
5516             case _ep_aiflag_autokill:
5517                 ent->autokill = (LONG)ltemp;
5518                 break;
5519             case _ep_aiflag_idlemode:
5520                 ent->idlemode = (LONG)ltemp;
5521                 break;
5522             case _ep_aiflag_walkmode:
5523                 ent->walkmode = (LONG)ltemp;
5524                 break;
5525             case _ep_aiflag_walking:
5526                 ent->walking = (LONG)ltemp;
5527                 break;
5528             default:
5529                 printf("Unknown AI flag.\n");
5530                 goto changeentityproperty_error;
5531             }
5532         }
5533         break;
5534     }
5535     case _ep_aimove:
5536     {
5537         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5538         {
5539             ent->modeldata.aimove = (LONG)ltemp;
5540         }
5541         break;
5542     }
5543     case _ep_alpha:
5544     {
5545         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5546         {
5547             ent->modeldata.alpha = (LONG)ltemp;
5548         }
5549         break;
5550     }
5551     case _ep_animation:
5552     {
5553         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5554         {
5555             ltemp2 = (LONG)1;
5556             if(paramCount < 4 || SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
5557             {
5558                 ent_set_anim(ent, (LONG)ltemp, (LONG)ltemp2);
5559             }
5560         }
5561         break;
5562     }
5563     case _ep_animhits:
5564     {
5565         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5566         {
5567             ent->animation->animhits = (LONG)ltemp;
5568         }
5569         break;
5570     }
5571     case _ep_animpos:
5572     {
5573         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5574         {
5575             ent->animpos = (LONG)ltemp;
5576         }
5577         break;
5578     }
5579     case _ep_antigrab:
5580     {
5581         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5582         {
5583             ent->modeldata.antigrab = (LONG)ltemp;
5584         }
5585         break;
5586     }
5587     case _ep_antigravity:
5588     {
5589         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
5590         {
5591             ent->modeldata.antigravity = (DOUBLE)dbltemp;
5592         }
5593         break;
5594     }
5595 
5596     case _ep_attacking:
5597     {
5598         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5599         {
5600             ent->attacking = (LONG)ltemp;
5601         }
5602         break;
5603     }
5604     case _ep_attackid:
5605     {
5606         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5607         {
5608             ent->attack_id_outgoing = (LONG)ltemp;
5609         }
5610         break;
5611     }
5612     case _ep_autokill:
5613     {
5614         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5615         {
5616             ent->autokill = (LONG)ltemp;
5617         }
5618         break;
5619     }
5620     case _ep_base:
5621     {
5622         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
5623         {
5624             ent->base = (DOUBLE)dbltemp;
5625         }
5626         break;
5627     }
5628     case _ep_blink:
5629     {
5630         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5631         {
5632             ent->blink = (LONG)ltemp;
5633         }
5634         break;
5635     }
5636     case _ep_blockback:
5637     {
5638         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5639         {
5640             ent->modeldata.blockback = (LONG)ltemp;
5641         }
5642         break;
5643     }
5644     case _ep_blockodds:
5645     {
5646         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5647         {
5648             ent->modeldata.blockodds = (LONG)ltemp;
5649         }
5650         break;
5651     }
5652     case _ep_blockpain:
5653     {
5654         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5655         {
5656             ent->modeldata.blockpain = (LONG)ltemp;
5657         }
5658         break;
5659     }
5660     case _ep_boss:
5661     {
5662         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5663         {
5664             ent->boss = (LONG)ltemp;
5665         }
5666         break;
5667     }
5668     case _ep_bounce:
5669     {
5670         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5671         {
5672             ent->modeldata.bounce = (LONG)ltemp;
5673         }
5674         break;
5675     }
5676     case _ep_candamage:
5677     {
5678         ent->modeldata.candamage = 0;
5679 
5680         for(i = 2; i < paramCount; i++)
5681         {
5682             if(varlist[i]->vt == VT_INTEGER) // known entity type
5683             {
5684                 ltemp = varlist[i]->lVal;
5685                 if(ltemp == (_ep_hcd_ground | 0x80000000)) // "ground" - not needed?
5686                 {
5687                     ent->modeldata.ground = 1;
5688                 }
5689                 else if(ltemp & 0x80000000)
5690                 {
5691                     ent->modeldata.candamage |= entitytypes[ltemp & 0x7fffffff];
5692                 }
5693                 else
5694                 {
5695                     ent->modeldata.candamage |= ltemp;
5696                 }
5697             }
5698             else
5699             {
5700                 printf("You must pass one or more string constants for candamage entity type.\n");
5701                 goto changeentityproperty_error;
5702             }
5703         }
5704         break;
5705     }
5706     case _ep_combostep:
5707     {
5708         if(paramCount >= 4 &&
5709                 SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
5710                 SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
5711         {
5712             ent->combostep[(LONG)ltemp] = (LONG)ltemp2;
5713         }
5714         break;
5715     }
5716     case _ep_combotime:
5717     {
5718         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5719         {
5720             ent->combotime = (LONG)ltemp;
5721         }
5722         break;
5723     }
5724     case _ep_collidedentity:
5725     {
5726         ent->collided_entity = (entity *)varlist[2]->ptrVal;
5727         break;
5728     }
5729     case _ep_colourmap:
5730     {
5731         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5732         {
5733             ent->colourmap = (VOID *)model_get_colourmap(&(ent->modeldata), ltemp);
5734         }
5735         break;
5736     }
5737     case _ep_damage_on_landing:
5738     {
5739         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5740         {
5741             ent->damage_on_landing.attack_force = (LONG)ltemp;
5742         }
5743         break;
5744     }
5745     case _ep_dead:
5746     {
5747         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5748         {
5749             ent->dead = (LONG)ltemp;
5750         }
5751         break;
5752     }
5753     case _ep_defaultname:
5754     {
5755         if(varlist[2]->vt != VT_STR)
5756         {
5757             printf("You must give a string value for entity name.\n");
5758             goto changeentityproperty_error;
5759         }
5760         tempmodel = findmodel((char *)StrCache_Get(varlist[2]->strVal));
5761         if(!tempmodel)
5762         {
5763             printf("Use must give an existing model's name for entity's default model name.\n");
5764             goto changeentityproperty_error;
5765         }
5766         ent->defaultmodel = tempmodel;
5767         break;
5768     }
5769     case _ep_defense:
5770     {
5771         if((ltemp2 =
5772                     (paramCount >= 4 &&
5773                      SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
5774                      ltemp < (LONG)MAX_ATKS && ltemp >= (LONG)0 &&
5775                      SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
5776            ))
5777         {
5778             ent->defense[(LONG)ltemp].factor = (DOUBLE)dbltemp;
5779         }
5780 
5781         if(paramCount >= 5 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp))))
5782         {
5783             ent->defense[(LONG)ltemp].pain = (DOUBLE)dbltemp;
5784         }
5785         if(paramCount >= 6 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp))))
5786         {
5787             ent->defense[(LONG)ltemp].knockdown = (DOUBLE)dbltemp;
5788         }
5789         if(paramCount >= 7 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp))))
5790         {
5791             ent->defense[(LONG)ltemp].blockpower = (DOUBLE)dbltemp;
5792         }
5793         if(paramCount >= 8 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp))))
5794         {
5795             ent->defense[(LONG)ltemp].blockthreshold = (DOUBLE)dbltemp;
5796         }
5797         if(paramCount >= 9 && ltemp2 && (ltemp2 = SUCCEEDED(ScriptVariant_DecimalValue(varlist[8], &dbltemp))))
5798         {
5799             ent->defense[(LONG)ltemp].blockratio = (DOUBLE)dbltemp;
5800         }
5801         if(paramCount >= 10 && ltemp2 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[9], &dbltemp)))
5802         {
5803             ent->defense[(LONG)ltemp].blocktype = dbltemp;
5804         }
5805 
5806         break;
5807     }
5808     case _ep_destx:
5809     {
5810         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
5811         {
5812             ent->destx = (DOUBLE)dbltemp;
5813         }
5814         break;
5815     }
5816     case _ep_destz:
5817     {
5818         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
5819         {
5820             ent->destz = (DOUBLE)dbltemp;
5821         }
5822         break;
5823     }
5824     case _ep_detect:
5825     {
5826         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5827         {
5828             ent->modeldata.stealth.detect = (LONG)ltemp;
5829         }
5830         break;
5831     }
5832     case _ep_direction:
5833     {
5834         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5835         {
5836             ent->direction = (LONG)ltemp;
5837         }
5838         break;
5839     }
5840     case _ep_edelay:
5841     {
5842         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5843         {
5844             ent->modeldata.edelay.mode = (LONG)ltemp;
5845         }
5846         if(paramCount >= 3 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
5847         {
5848             ent->modeldata.edelay.factor = (DOUBLE)dbltemp;
5849         }
5850         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
5851         {
5852             ent->modeldata.edelay.cap.min = (LONG)ltemp;
5853         }
5854         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
5855         {
5856             ent->modeldata.edelay.cap.max = (LONG)ltemp;
5857         }
5858         if(paramCount >= 6 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[6], &ltemp)))
5859         {
5860             ent->modeldata.edelay.range.min = (LONG)ltemp;
5861         }
5862         if(paramCount >= 7 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[7], &ltemp)))
5863         {
5864             ent->modeldata.edelay.range.max = (LONG)ltemp;
5865         }
5866 
5867         break;
5868     }
5869     case _ep_edge:
5870     {
5871         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5872         {
5873             ent->edge = (LONG)ltemp;
5874         }
5875         break;
5876     }
5877     case _ep_edgerange:
5878     {
5879         if(varlist[2]->vt != VT_INTEGER)
5880         {
5881             if(varlist[2]->vt != VT_STR)
5882             {
5883                 printf("You must give a string value for edgerange name.\n");
5884             }
5885             goto changeentityproperty_error;
5886         }
5887         if(paramCount < 4)
5888         {
5889             break;
5890         }
5891 
5892         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
5893         {
5894             switch(varlist[2]->lVal)
5895             {
5896             case _ep_edgerange_x:
5897                 ent->modeldata.edgerange.x = (DOUBLE)dbltemp;
5898                 break;
5899             case _ep_edgerange_z:
5900                 ent->modeldata.edgerange.z = (DOUBLE)dbltemp;
5901                 break;
5902             default:
5903                 printf("Unknown edgerange.\n");
5904                 goto changeentityproperty_error;
5905             }
5906         }
5907         break;
5908     }
5909     case _ep_energycost:
5910     {
5911         if(paramCount != 5)
5912         {
5913             printf("\n Error, changeentityproperty({ent}, 'energycost', {subproperty}, {animation}, {value}): Invalid or missing parameter. \n");
5914             goto changeentityproperty_error;
5915         }
5916 
5917         if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5918         {
5919             printf("\n Error, changeentityproperty has invalid animation id.\n");
5920             goto changeentityproperty_error;
5921         }
5922 
5923         i = (LONG)ltemp;
5924 
5925         if(!validanim(ent, i))
5926         {
5927             printf("\n Error, changeentityproperty({ent}, 'energycost', {subproperty}, {animation}, {value}): {animation} parameter invalid. Make sure the animation exists. \n");
5928             goto changeentityproperty_error;
5929         }
5930 
5931         if(varlist[2]->vt != VT_INTEGER)
5932         {
5933             printf("You must give a string value for energycost flag name.\n");
5934             goto changeentityproperty_error;
5935         }
5936 
5937         switch(varlist[2]->lVal)
5938         {
5939         case _ep_energycost_cost:
5940         {
5941             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
5942             {
5943                 if(ent->modeldata.animation[i]->energycost)
5944                 {
5945                     ent->modeldata.animation[i]->energycost->cost = ltemp;
5946                 }
5947 
5948             }
5949             break;
5950         }
5951         case _ep_energycost_disable:
5952         {
5953             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
5954             {
5955                 if(ent->modeldata.animation[i]->energycost)
5956                 {
5957                     ent->modeldata.animation[i]->energycost->disable = ltemp;
5958                 }
5959             }
5960             break;
5961         }
5962         case _ep_energycost_mponly:
5963         {
5964             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
5965             {
5966                 if(ent->modeldata.animation[i]->energycost)
5967                 {
5968                     ent->modeldata.animation[i]->energycost->mponly = ltemp;
5969                 }
5970             }
5971             break;
5972         }
5973         default:
5974             printf("Unknown Energycost flag.\n");
5975             goto changeentityproperty_error;
5976         }
5977         break;
5978     }
5979     case _ep_escapecount:
5980     {
5981         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5982         {
5983             ent->escapecount = (LONG)ltemp;
5984         }
5985         break;
5986     }
5987     case _ep_escapehits:
5988     {
5989         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5990         {
5991             ent->modeldata.escapehits = (LONG)ltemp;
5992         }
5993         break;
5994     }
5995     case _ep_facing:
5996     {
5997         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5998         {
5999             ent->modeldata.facing = (LONG)ltemp;
6000         }
6001         break;
6002     }
6003     case _ep_falldie:
6004     {
6005         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6006         {
6007             ent->modeldata.falldie = (LONG)ltemp;
6008         }
6009         break;
6010     }
6011     case _ep_playerindex:
6012     {
6013         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6014         {
6015             ent->playerindex = (LONG)ltemp;
6016         }
6017         break;
6018     }
6019     case _ep_pain_time:
6020     {
6021         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6022         {
6023             ent->next_hit_time = (LONG)ltemp;
6024         }
6025         break;
6026     }
6027     case _ep_freezetime:
6028     {
6029         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6030         {
6031             ent->freezetime = (LONG)ltemp;
6032         }
6033         break;
6034     }
6035     case _ep_frozen:
6036     {
6037         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6038         {
6039             ent->frozen = (LONG)ltemp;
6040         }
6041         break;
6042     }
6043     case _ep_gfxshadow:
6044     {
6045         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6046         {
6047             ent->modeldata.gfxshadow = (LONG)ltemp;
6048         }
6049         break;
6050     }
6051     case _ep_shadowbase:
6052     {
6053         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6054         {
6055             ent->modeldata.shadowbase = (LONG)ltemp;
6056         }
6057         break;
6058     }
6059     case _ep_grabforce:
6060     {
6061         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6062         {
6063             ent->modeldata.grabforce = (LONG)ltemp;
6064         }
6065         break;
6066     }
6067     case _ep_guardpoints:
6068     {
6069         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6070         {
6071             ent->modeldata.guardpoints.current = (LONG)ltemp;
6072         }
6073         break;
6074     }
6075     case _ep_hasplatforms:
6076     {
6077         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6078         {
6079             ent->modeldata.hasPlatforms = (LONG)ltemp;
6080         }
6081         break;
6082     }
6083     case _ep_health:
6084     {
6085         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6086         {
6087             ent->energy_state.health_current = (LONG)ltemp;
6088             if(ent->energy_state.health_current > ent->modeldata.health)
6089             {
6090                 ent->energy_state.health_current = ent->modeldata.health;
6091             }
6092             else if(ent->energy_state.health_current < 0)
6093             {
6094                 ent->energy_state.health_current = 0;
6095             }
6096         }
6097         break;
6098     }
6099     case _ep_hitbyid:
6100     {
6101         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6102         {
6103             ent->attack_id_incoming = (LONG)ltemp;
6104         }
6105         break;
6106     }
6107     case _ep_hitheadplatform:
6108     {
6109         ent->hithead = (entity *)varlist[2]->ptrVal;
6110         break;
6111     }
6112     case _ep_landedplatform:
6113     {
6114         ent->landed_on_platform = (entity *)varlist[2]->ptrVal;
6115         break;
6116     }
6117     case _ep_hitwall:
6118     {
6119         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6120         {
6121             ent->hitwall = (LONG)ltemp;
6122         }
6123         break;
6124     }
6125     case _ep_hmapl:
6126     {
6127         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6128         {
6129             ent->modeldata.maps.hide_start = ltemp;
6130         }
6131         break;
6132     }
6133     case _ep_hmapu:
6134     {
6135         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6136         {
6137             ent->modeldata.maps.hide_end = ltemp;
6138         }
6139         break;
6140     }
6141     case _ep_hostile:
6142     {
6143         ent->modeldata.hostile = 0;
6144         for(i = 2; i < paramCount; i++)
6145         {
6146             if(varlist[i]->vt == VT_INTEGER) // known entity type
6147             {
6148                 ltemp = varlist[i]->lVal;
6149                 if(ltemp & 0x80000000)
6150                 {
6151                     ent->modeldata.hostile |= entitytypes[ltemp & 0x7fffffff];
6152                 }
6153                 else
6154                 {
6155                     ent->modeldata.hostile |= ltemp;
6156                 }
6157             }
6158             else
6159             {
6160                 printf("You must pass one or more string constants for hostile entity type.\n");
6161                 goto changeentityproperty_error;
6162             }
6163         }
6164 
6165         break;
6166     }
6167     case _ep_iconposition:
6168     {
6169         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6170         {
6171             ent->modeldata.icon.position.x = (LONG)ltemp;
6172         }
6173         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6174         {
6175             ent->modeldata.icon.position.y = (LONG)ltemp;
6176         }
6177         break;
6178     }
6179     case _ep_invincible:
6180     {
6181         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6182         {
6183             ent->invincible = (LONG)ltemp;
6184         }
6185         break;
6186     }
6187     case _ep_invinctime:
6188     {
6189         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6190         {
6191             ent->invinctime = (LONG)ltemp;
6192         }
6193         break;
6194     }
6195     case _ep_jugglepoints:
6196     {
6197         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6198         {
6199             ent->modeldata.jugglepoints.current = (LONG)ltemp;
6200         }
6201         break;
6202     }
6203     case _ep_jumpheight:
6204     {
6205         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6206         {
6207             ent->modeldata.jumpheight = (DOUBLE)dbltemp;
6208         }
6209         break;
6210     }
6211     case _ep_jumpmovex:
6212     {
6213         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6214         {
6215             ent->modeldata.jumpmovex = (LONG)ltemp;
6216         }
6217         break;
6218     }
6219     case _ep_jumpmovez:
6220     {
6221         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6222         {
6223             ent->modeldata.jumpmovex = (LONG)ltemp;
6224         }
6225         break;
6226     }
6227     case _ep_jumpspeed:
6228     {
6229         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6230         {
6231             ent->modeldata.jumpspeed = (DOUBLE)dbltemp;
6232         }
6233         break;
6234     }
6235     case _ep_knockdowncount:
6236     {
6237         if(varlist[2]->vt != VT_INTEGER)
6238         {
6239             if(varlist[2]->vt != VT_STR)
6240                 printf("You must provide a string value for Knockdowncount subproperty:\n\
6241                     changeentityproperty({ent}, 'knockdowncount', {subproperty}, {value})\n\
6242                     ~'current'\n\
6243                     ~'max'\n\
6244                     ~'time'\n");
6245             goto changeentityproperty_error;
6246         }
6247 
6248         switch(varlist[2]->lVal)
6249         {
6250         case _ep_knockdowncount_current:
6251         {
6252             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6253             {
6254                 ent->knockdowncount = (DOUBLE)dbltemp;
6255             }
6256             break;
6257         }
6258         case _ep_knockdowncount_max:
6259         {
6260             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6261             {
6262                 ent->modeldata.knockdowncount = (DOUBLE)dbltemp;
6263             }
6264             break;
6265             case _ep_knockdowncount_time:
6266                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6267                 {
6268                     ent->knockdowntime = (LONG)ltemp;
6269                 }
6270                 break;
6271             }
6272         default:
6273             printf("Unknown knockdowncount subproperty.\n");
6274             goto changeentityproperty_error;
6275         }
6276         break;
6277     }
6278     case _ep_komap:
6279     {
6280         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6281         {
6282             ent->modeldata.maps.ko = (LONG)ltemp;
6283         }
6284         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6285         {
6286             ent->modeldata.maps.kotype = (LONG)ltemp;
6287         }
6288         break;
6289     }
6290     case _ep_lifeposition:
6291     {
6292         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6293         {
6294             ent->modeldata.hpx = (LONG)ltemp;
6295         }
6296         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6297         {
6298             ent->modeldata.hpy = (LONG)ltemp;
6299         }
6300         break;
6301     }
6302     case _ep_lifespancountdown:
6303     {
6304         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6305         {
6306             ent->lifespancountdown = (LONG)ltemp;
6307         }
6308         break;
6309     }
6310     case _ep_attackthrottle:
6311     {
6312         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6313         {
6314             ent->modeldata.attackthrottle = (DOUBLE)dbltemp;
6315         }
6316         break;
6317     }
6318     case _ep_attackthrottletime:
6319     {
6320         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6321         {
6322             ent->modeldata.attackthrottletime = (DOUBLE)dbltemp;
6323         }
6324         break;
6325     }
6326     case _ep_map:
6327     {
6328         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6329         {
6330             ent_set_colourmap(ent, (LONG)ltemp);
6331         }
6332         break;
6333     }
6334     case _ep_maptime:
6335     {
6336         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6337         {
6338             ent->maptime = (LONG)ltemp;
6339         }
6340         break;
6341     }
6342     case _ep_maxguardpoints:
6343     {
6344         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6345         {
6346             ent->modeldata.guardpoints.max = (LONG)ltemp;
6347         }
6348         break;
6349     }
6350     case _ep_maxhealth:
6351     {
6352         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6353         {
6354             ent->modeldata.health = (LONG)ltemp;
6355             if(ent->modeldata.health < 0)
6356             {
6357                 ent->modeldata.health = 0;    //OK, no need to have ot below 0
6358             }
6359         }
6360         break;
6361     }
6362     case _ep_maxjugglepoints:
6363     {
6364         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6365         {
6366             ent->modeldata.jugglepoints.max = (LONG)ltemp;
6367         }
6368         break;
6369     }
6370     case _ep_maxmp:
6371     {
6372         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6373         {
6374             ent->modeldata.mp = (LONG)ltemp;
6375             if(ent->modeldata.mp < 0)
6376             {
6377                 ent->modeldata.mp = 0;    //OK, no need to have ot below 0
6378             }
6379         }
6380         break;
6381     }
6382     case _ep_model:
6383     {
6384         if(varlist[2]->vt != VT_STR)
6385         {
6386             printf("You must give a string value for model name.\n");
6387             goto changeentityproperty_error;
6388         }
6389         tempstr = (char *)StrCache_Get(varlist[2]->strVal);
6390         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6391         {
6392             set_model_ex(ent, tempstr, -1, NULL, (LONG)ltemp);
6393             if(!ent->weapent)
6394             {
6395                 ent->weapent = ent;
6396             }
6397         }
6398         break;
6399     }
6400     case _ep_movex:
6401     {
6402         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6403         {
6404             ent->movex = (DOUBLE)dbltemp;
6405         }
6406         break;
6407     }
6408     case _ep_movez:
6409     {
6410         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6411         {
6412             ent->movez = (DOUBLE)dbltemp;
6413         }
6414         break;
6415     }
6416     case _ep_entitypushing:
6417     {
6418         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6419         {
6420             ent->modeldata.entitypushing = (LONG)ltemp;
6421         }
6422         break;
6423     }
6424     case _ep_pushingfactor:
6425     {
6426         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6427         {
6428             ent->modeldata.pushingfactor = (DOUBLE)dbltemp;
6429         }
6430         break;
6431     }
6432     case _ep_mp:
6433     {
6434         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6435         {
6436             ent->energy_state.mp_current = (LONG)ltemp;
6437             if(ent->energy_state.mp_current > ent->modeldata.mp)
6438             {
6439                 ent->energy_state.mp_current = ent->modeldata.mp;
6440             }
6441             else if(ent->energy_state.mp_current < 0)
6442             {
6443                 ent->energy_state.mp_current = 0;
6444             }
6445         }
6446         break;
6447     }
6448     case _ep_mpset:
6449     {
6450         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6451         {
6452             ent->modeldata.mp = (int)dbltemp;
6453         }
6454         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6455         {
6456             ent->modeldata.mpstable = (int)dbltemp;
6457         }
6458         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6459         {
6460             ent->modeldata.mpstableval = (int)dbltemp;
6461         }
6462         if(paramCount >= 6 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
6463         {
6464             ent->modeldata.mprate = (int)dbltemp;
6465         }
6466         if(paramCount >= 7 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
6467         {
6468             ent->modeldata.mpdroprate = (int)dbltemp;
6469         }
6470         if(paramCount >= 8 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp)))
6471         {
6472             ent->modeldata.chargerate = (int)dbltemp;
6473         }
6474         break;
6475     }
6476     case _ep_name:
6477     {
6478         if(varlist[2]->vt != VT_STR)
6479         {
6480             printf("You must give a string value for entity name.\n");
6481             goto changeentityproperty_error;
6482         }
6483         strcpy(ent->name, (char *)StrCache_Get(varlist[2]->strVal));
6484         break;
6485     }
6486     case _ep_nameposition:
6487     {
6488         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6489         {
6490             ent->modeldata.namex = (LONG)ltemp;
6491         }
6492         if(paramCount > 3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6493         {
6494             ent->modeldata.namey = (LONG)ltemp;
6495         }
6496         break;
6497     }
6498     case _ep_nextanim:
6499     {
6500         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6501         {
6502             ent->nextanim = (LONG)ltemp;
6503         }
6504         break;
6505     }
6506     case _ep_nextmove:
6507     {
6508         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6509         {
6510             ent->nextmove = (LONG)ltemp;
6511         }
6512         break;
6513     }
6514     case _ep_nextthink:
6515     {
6516         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6517         {
6518             ent->nextthink = (LONG)ltemp;
6519         }
6520         break;
6521     }
6522     case _ep_no_adjust_base:
6523     {
6524         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6525         {
6526             ent->modeldata.no_adjust_base = (LONG)ltemp;
6527         }
6528         break;
6529     }
6530     case _ep_noaicontrol:
6531     {
6532         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6533         {
6534             ent->noaicontrol = (LONG)ltemp;
6535         }
6536         break;
6537     }
6538     case _ep_nodieblink:
6539     {
6540         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6541         {
6542             ent->modeldata.nodieblink = (LONG)ltemp;
6543         }
6544         break;
6545     }
6546     case _ep_nodrop:
6547     {
6548         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6549         {
6550             ent->modeldata.nodrop = (LONG)ltemp;
6551         }
6552         break;
6553     }
6554     case _ep_nograb:
6555     {
6556         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6557         {
6558             ent->nograb = (LONG)ltemp;
6559         }
6560         break;
6561     }
6562     case _ep_nohithead:
6563     {
6564         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6565         {
6566             ent->modeldata.nohithead = (LONG)ltemp;
6567         }
6568         break;
6569     }
6570     case _ep_nolife:
6571     {
6572         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6573         {
6574             ent->modeldata.nolife = (LONG)ltemp;
6575         }
6576         break;
6577     }
6578     case _ep_nopain:
6579     {
6580         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6581         {
6582             ent->modeldata.nopain = (LONG)ltemp;
6583         }
6584         break;
6585     }
6586     case _ep_offense:
6587     {
6588         if(paramCount >= 4 &&
6589                 SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
6590                 ltemp < (LONG)MAX_ATKS && ltemp >= (LONG)0 &&
6591                 SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6592         {
6593             ent->offense_factors[(LONG)ltemp] = (DOUBLE)dbltemp;
6594         }
6595         break;
6596     }
6597     case _ep_offscreen_noatk_factor:
6598     {
6599         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6600         {
6601             ent->modeldata.offscreen_noatk_factor = (DOUBLE)dbltemp;
6602         }
6603         break;
6604     }
6605     case _ep_offscreenkill:
6606     {
6607         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6608         {
6609             ent->modeldata.offscreenkill = (LONG)ltemp;
6610         }
6611         break;
6612     }
6613     case _ep_opponent:
6614     {
6615         ent->opponent = (entity *)varlist[2]->ptrVal;
6616         break;
6617     }
6618     case _ep_custom_target:
6619     {
6620         ent->custom_target = (entity *)varlist[2]->ptrVal;
6621         break;
6622     }
6623     case _ep_owner:
6624     {
6625         ent->owner = (entity *)varlist[2]->ptrVal;
6626         break;
6627     }
6628     case _ep_parent:
6629     {
6630         ent->parent = (entity *)varlist[2]->ptrVal;
6631         break;
6632     }
6633     case _ep_pathfindstep:
6634     {
6635         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6636         {
6637             ent->modeldata.pathfindstep = (DOUBLE)dbltemp;
6638         }
6639         break;
6640     }
6641     case _ep_position:
6642     {
6643         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6644         {
6645             ent->position.x = (DOUBLE)dbltemp;
6646         }
6647         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6648         {
6649             ent->position.z = (DOUBLE)dbltemp;
6650         }
6651         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6652         {
6653             ent->position.y = (DOUBLE)dbltemp;
6654         }
6655         break;
6656     }
6657     case _ep_x:
6658     {
6659         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6660         {
6661             ent->position.x = (DOUBLE)dbltemp;
6662         }
6663         break;
6664     }
6665     case _ep_z:
6666     {
6667         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6668         {
6669             ent->position.z = (DOUBLE)dbltemp;
6670         }
6671         break;
6672     }
6673     case _ep_a:
6674     case _ep_y:
6675     {
6676         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6677         {
6678             ent->position.y = (DOUBLE)dbltemp;
6679         }
6680         break;
6681     }
6682     case _ep_projectile:
6683     {
6684         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6685         {
6686             ent->projectile = (LONG)ltemp;
6687         }
6688         break;
6689     }
6690     case _ep_projectilehit:
6691     {
6692         ent->modeldata.projectilehit = 0;
6693 
6694         for(i = 2; i < paramCount; i++)
6695         {
6696             if(varlist[i]->vt == VT_INTEGER) // known entity type
6697             {
6698                 ltemp = varlist[i]->lVal;
6699                 if(ltemp & 0x80000000)
6700                 {
6701                     ent->modeldata.projectilehit |= entitytypes[ltemp & 0x7fffffff];
6702                 }
6703                 else
6704                 {
6705                     ent->modeldata.projectilehit |= ltemp;
6706                 }
6707             }
6708             else
6709             {
6710                 printf("You must pass one or more string constants for projectilehit entity type.\n");
6711                 goto changeentityproperty_error;
6712             }
6713         }
6714 
6715         break;
6716     }
6717     case _ep_running:
6718     {
6719         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6720         {
6721             ent->modeldata.runspeed = (DOUBLE)dbltemp;
6722         }
6723         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6724         {
6725             ent->modeldata.runjumpheight = (DOUBLE)dbltemp;
6726         }
6727         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6728         {
6729             ent->modeldata.runjumpdist = (DOUBLE)dbltemp;
6730         }
6731         if(paramCount >= 6 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
6732         {
6733             ent->modeldata.runhold = (int)dbltemp;
6734         }
6735         if(paramCount >= 7 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
6736         {
6737             ent->modeldata.runupdown = (int)dbltemp;
6738         }
6739 
6740         break;
6741     }
6742     case _ep_rush_count:
6743     {
6744         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6745         {
6746             ent->rush.count.current = (LONG)ltemp;
6747         }
6748         break;
6749     }
6750     case _ep_rush_tally:
6751     {
6752         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6753         {
6754             ent->rush.count.max = (LONG)ltemp;
6755         }
6756         break;
6757     }
6758     case _ep_rush_time:
6759     {
6760         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6761         {
6762             ent->rush.time = (LONG)ltemp;
6763         }
6764         break;
6765     }
6766     case _ep_score:
6767     {
6768         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6769         {
6770             ent->modeldata.score = (LONG)ltemp;
6771         }
6772         break;
6773     }
6774     case _ep_scroll:
6775     {
6776         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6777         {
6778             ent->modeldata.scroll = (DOUBLE)dbltemp;
6779         }
6780         break;
6781     }
6782     case _ep_seal:
6783     {
6784         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6785         {
6786             ent->seal = (LONG)ltemp;
6787         }
6788         break;
6789     }
6790     case _ep_sealtime:
6791     {
6792         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6793         {
6794             ent->sealtime = (LONG)ltemp;
6795         }
6796         break;
6797     }
6798     case _ep_setlayer:
6799     {
6800         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6801         {
6802             ent->modeldata.setlayer = (LONG)ltemp;
6803         }
6804         break;
6805     }
6806     case _ep_sortid:
6807     {
6808         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6809         {
6810             ent->sortid = (LONG)ltemp;
6811         }
6812         break;
6813     }
6814     case _ep_speed:
6815     {
6816         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6817         {
6818             ent->modeldata.speed = (DOUBLE)dbltemp;
6819         }
6820         break;
6821     }
6822     case _ep_spritea:
6823     {
6824         if(varlist[2]->vt != VT_INTEGER)
6825         {
6826             if(varlist[2]->vt != VT_STR)
6827                 printf("You must provide a string value for Sprite Array subproperty:\n\
6828                     changeentityproperty({ent}, 'spritea', {subproperty}, {animation ID}, {frame}, {value})\n\
6829                     ~'centerx'\n\
6830                     ~'centery'\n\
6831                     ~'file'\n\
6832                     ~'offsetx'\n\
6833                     ~'sprite'\n");
6834             goto changeentityproperty_error;
6835         }
6836 
6837         ltemp   = varlist[2]->lVal;
6838 
6839         /*
6840         Failsafe checks. Any attempt to access a sprite property on invalid frame would cause instant shutdown.
6841         */
6842         if(!validanim(ent, varlist[3]->lVal) || !(ent->modeldata.animation[varlist[3]->lVal]->numframes >= varlist[4]->lVal) || paramCount < 5)
6843         {
6844             break;
6845         }
6846 
6847         i = ent->modeldata.animation[varlist[3]->lVal]->sprite[varlist[4]->lVal];   //Get sprite index.
6848 
6849         switch(ltemp)
6850         {
6851         case _ep_spritea_centerx:
6852         {
6853             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
6854             {
6855                 sprite_map[i].centerx = (LONG)ltemp;
6856             }
6857 
6858             break;
6859         }
6860         case _ep_spritea_centery:
6861         {
6862             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
6863             {
6864                 sprite_map[i].centery = (LONG)ltemp;
6865             }
6866             break;
6867         }
6868         case _ep_spritea_file:
6869         {
6870             if(varlist[5]->vt != VT_STR)
6871             {
6872                 printf("You must provide a string value for file name.\n");
6873                 goto changeentityproperty_error;
6874             }
6875             strcpy(sprite_map[i].node->filename, (char *)StrCache_Get(varlist[5]->strVal));
6876             break;
6877         }
6878         /*
6879         case _ep_spritea_offsetx:
6880         {
6881             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
6882             {
6883                 sprite_map[i].ofsx = (LONG)ltemp;
6884                 (*pretvar)->lVal = (LONG)1;
6885             }
6886             break;
6887         }
6888         case _ep_spritea_offsety:
6889         {
6890             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6891             {
6892                 sprite_map[i].ofsy = (LONG)ltemp;
6893                 (*pretvar)->lVal = (LONG)1;
6894             }
6895             break;
6896         }*/
6897         case _ep_spritea_sprite:
6898         {
6899             sprite_map[i].node->sprite = (VOID *)varlist[5]->ptrVal;
6900 
6901             break;
6902         }
6903         default:
6904             printf("Unknown Sprite Array subproperty.\n");
6905             goto changeentityproperty_error;
6906         }
6907         break;
6908     }
6909     case _ep_stalltime:
6910     {
6911         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6912         {
6913             ent->stalltime = (LONG)ltemp;
6914         }
6915         break;
6916     }
6917     case _ep_releasetime:
6918     {
6919         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6920         {
6921             ent->releasetime = (LONG)ltemp;
6922         }
6923         break;
6924     }
6925     case _ep_staydown:
6926     {
6927         if(varlist[2]->vt != VT_INTEGER)
6928         {
6929             if(varlist[2]->vt != VT_STR)
6930                 printf("You must provide a string value for Staydown subproperty:\n\
6931                     changeentityproperty({ent}, 'staydown', {subproperty}, {value})\n\
6932                     ~'rise'\n\
6933                     ~'riseattack'\n\
6934                     ~'riseattack_stall'\n");
6935             goto changeentityproperty_error;
6936         }
6937         if(paramCount < 4)
6938         {
6939             break;
6940         }
6941 
6942         switch(varlist[2]->lVal)
6943         {
6944         case _ep_staydown_rise:
6945         {
6946             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6947             {
6948                 ent->staydown.rise = (LONG)ltemp;
6949             }
6950             break;
6951         }
6952         case _ep_staydown_riseattack:
6953         {
6954             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6955             {
6956                 ent->staydown.riseattack = (LONG)ltemp;
6957             }
6958             break;
6959         }
6960         case _ep_staydown_riseattack_stall:
6961         {
6962             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6963             {
6964                 ent->staydown.riseattack_stall = (LONG)ltemp;
6965             }
6966             break;
6967         }
6968         default:
6969             printf("Unknown Staydown subproperty.\n");
6970             goto changeentityproperty_error;
6971         }
6972         break;
6973     }
6974     case _ep_stealth:
6975     {
6976         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6977         {
6978             ent->modeldata.stealth.hide = (LONG)ltemp;
6979         }
6980         break;
6981     }
6982     case _ep_subentity:
6983     {
6984         if(ent->subentity)
6985         {
6986             ent->subentity->parent = NULL;
6987         }
6988         ent->subentity = (entity *)varlist[2]->ptrVal;
6989         if(ent->subentity)
6990         {
6991             ent->subentity->parent = ent;
6992         }
6993         break;
6994     }
6995     case _ep_subject_to_basemap:
6996     {
6997         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6998         {
6999             ent->modeldata.subject_to_basemap = (LONG)ltemp;
7000         }
7001         break;
7002     }
7003     case _ep_subject_to_gravity:
7004     {
7005         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7006         {
7007             ent->modeldata.subject_to_gravity = (LONG)ltemp;
7008         }
7009         break;
7010     }
7011     case _ep_subject_to_hole:
7012     {
7013         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7014         {
7015             ent->modeldata.subject_to_hole = (LONG)ltemp;
7016         }
7017         break;
7018     }
7019     case _ep_subject_to_maxz:
7020     {
7021         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7022         {
7023             ent->modeldata.subject_to_maxz = (LONG)ltemp;
7024         }
7025         break;
7026     }
7027     case _ep_subject_to_minz:
7028     {
7029         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7030         {
7031             ent->modeldata.subject_to_minz = (LONG)ltemp;
7032         }
7033         break;
7034     }
7035     case _ep_subject_to_obstacle:
7036     {
7037         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7038         {
7039             ent->modeldata.subject_to_obstacle = (LONG)ltemp;
7040         }
7041         break;
7042     }
7043     case _ep_subject_to_platform:
7044     {
7045         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7046         {
7047             ent->modeldata.subject_to_platform = (LONG)ltemp;
7048         }
7049         break;
7050     }
7051     case _ep_subject_to_screen:
7052     {
7053         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7054         {
7055             ent->modeldata.subject_to_screen = (LONG)ltemp;
7056         }
7057         break;
7058     }
7059     case _ep_subject_to_wall:
7060     {
7061         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7062         {
7063             ent->modeldata.subject_to_wall = (LONG)ltemp;
7064         }
7065         break;
7066     }
7067     case _ep_subtype:
7068     {
7069         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7070         {
7071             ent->modeldata.subtype = (LONG)ltemp;
7072         }
7073         break;
7074     }
7075     case _ep_takeaction:
7076     {
7077         //if(varlist[2]->vt == VT_STRING)
7078         if(varlist[2]->vt == VT_EMPTY)
7079         {
7080             // UT: changed this to only accept NULL(), otherwise the log file is filled with warnings
7081             ent->takeaction = NULL;
7082             break;
7083         }
7084         else if(varlist[2]->vt != VT_INTEGER)
7085         {
7086             printf("You must give a string value for action type.\n");
7087             goto changeentityproperty_error;
7088         }
7089 
7090         // otherwise, the parameter is a known action
7091         ltemp = varlist[2]->lVal;
7092         if((ltemp >= 0) && (ltemp < _ep_ta_the_end))
7093         {
7094             ent->takeaction = actions[(LONG)ltemp];
7095         }
7096 
7097         break;
7098     }
7099     case _ep_think:
7100     {
7101         //if(varlist[2]->vt == VT_STRING)
7102         if(varlist[2]->vt == VT_EMPTY)
7103         {
7104             // UT: changed this to only accept NULL(), otherwise the log file is filled with warnings
7105             break;
7106         }
7107         else if(varlist[2]->vt != VT_INTEGER)
7108         {
7109             printf("You must give a string value for think type.\n");
7110             goto changeentityproperty_error;
7111         }
7112 
7113         // otherwise, the parameter is a known action
7114         ltemp = varlist[2]->lVal;
7115         if((ltemp >= 0) && (ltemp < _ep_th_the_end))
7116         {
7117             ent->think = think[(LONG)ltemp];
7118         }
7119 
7120         break;
7121     }
7122     case _ep_thold:
7123     {
7124         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7125         {
7126             ent->modeldata.thold = (LONG)ltemp;
7127         }
7128         break;
7129     }
7130     case _ep_throwdamage:
7131     {
7132         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7133         {
7134             ent->modeldata.throwdamage = (LONG)ltemp;
7135         }
7136         break;
7137     }
7138     case _ep_throwdist:
7139     {
7140         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7141         {
7142             ent->modeldata.throwdist = (DOUBLE)dbltemp;
7143         }
7144         break;
7145     }
7146     case _ep_throwframewait:
7147     {
7148         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7149         {
7150             ent->modeldata.throwframewait = (LONG)ltemp;
7151         }
7152         break;
7153     }
7154     case _ep_throwheight:
7155     {
7156         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7157         {
7158             ent->modeldata.throwheight = (DOUBLE)dbltemp;
7159         }
7160         break;
7161     }
7162     case _ep_tosstime:
7163     {
7164         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7165         {
7166             ent->toss_time = (LONG)ltemp;
7167         }
7168         break;
7169     }
7170     case _ep_trymove:
7171     {
7172         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7173         {
7174             if(ltemp == 1)
7175             {
7176                 ent->trymove = common_trymove;
7177             }
7178             else if(ltemp == 2)
7179             {
7180                 ent->trymove = player_trymove;
7181             }
7182             else
7183             {
7184                 ent->trymove = NULL;
7185             }
7186         }
7187         break;
7188     }
7189     case _ep_type:
7190     {
7191         if(varlist[2]->vt != VT_INTEGER)
7192         {
7193             printf("You must provide a type constant for type.\n");
7194             goto changeentityproperty_error;
7195         }
7196 
7197         ltemp = varlist[2]->lVal;
7198         ent->modeldata.type = (LONG)ltemp;
7199 
7200         break;
7201     }
7202     case _ep_velocity:
7203     {
7204         if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7205         {
7206             ent->velocity.x = (DOUBLE)dbltemp;
7207         }
7208         if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
7209         {
7210             ent->velocity.z = (DOUBLE)dbltemp;
7211         }
7212         if(paramCount >= 5 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
7213         {
7214             ent->velocity.y = (DOUBLE)dbltemp;
7215         }
7216         break;
7217     }
7218     case _ep_walkoffmovex:
7219     {
7220         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7221         {
7222             ent->modeldata.walkoffmovex = (LONG)ltemp;
7223         }
7224         break;
7225     }
7226     case _ep_walkoffmovez:
7227     {
7228         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7229         {
7230             ent->modeldata.walkoffmovez = (LONG)ltemp;
7231         }
7232         break;
7233     }
7234     case _ep_weapnum:
7235     {
7236         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7237         {
7238             ent->modeldata.weapnum = (LONG)ltemp;
7239         }
7240         break;
7241     }
7242     case _ep_weaploss:
7243     {
7244         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7245         {
7246             ent->modeldata.weaploss[0] = (LONG)ltemp;
7247         }
7248 
7249         if(paramCount >= 4)
7250         {
7251             if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
7252             {
7253                 printf("You must specify the flag value.\n");
7254                 *pretvar = NULL;
7255                 return E_FAIL;
7256             }
7257             ent->modeldata.weaploss[1] = (LONG)ltemp2;
7258         }
7259         break;
7260     }
7261     case _ep_weapon:
7262     {
7263         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7264         {
7265             ltemp2 = (LONG)0;
7266             if(paramCount < 4 ||  SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
7267             {
7268                 set_weapon(ent, (LONG)ltemp, (LONG)ltemp2);
7269             }
7270         }
7271         break;
7272     }
7273     default:
7274         //printf("Property name '%s' is not supported by function changeentityproperty.\n", propname);
7275         goto changeentityproperty_error;
7276         break;
7277     }
7278 
7279     return S_OK;
7280 changeentityproperty_error:
7281     return E_FAIL;
7282 }
7283 
7284 //tossentity(entity, height, speedx, speedz)
openbor_tossentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7285 HRESULT openbor_tossentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
7286 {
7287     entity *ent = NULL;
7288     DOUBLE height = 0, speedx = 0, speedz = 0;
7289 
7290     if(paramCount < 1)
7291     {
7292         goto toss_error;
7293     }
7294 
7295     ent = (entity *)varlist[0]->ptrVal; //retrieve the entity
7296     if(!ent)
7297     {
7298         goto toss_error;
7299     }
7300 
7301     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7302     (*pretvar)->lVal = (LONG)1;
7303 
7304     if(paramCount >= 2)
7305     {
7306         ScriptVariant_DecimalValue(varlist[1], &height);
7307     }
7308     if(paramCount >= 3)
7309     {
7310         ScriptVariant_DecimalValue(varlist[2], &speedx);
7311     }
7312     if(paramCount >= 4)
7313     {
7314         ScriptVariant_DecimalValue(varlist[3], &speedz);
7315     }
7316 
7317     ent->velocity.x = (float)speedx;
7318     ent->velocity.z = (float)speedz;
7319     toss(ent, (float)height);
7320     return S_OK;
7321 
7322 toss_error:
7323     printf("Function tossentity(entity,height, speedx, speedz) requires at least a valid entity handle.\n");
7324     *pretvar = NULL;
7325     return E_FAIL;
7326 }
7327 
7328 // ===== getplayerproperty =====
7329 enum playerproperty_enum
7330 {
7331     _pp_colourmap,
7332     _pp_combokey,
7333     _pp_combostep,
7334     _pp_credits,
7335     _pp_disablekeys,
7336     _pp_ent,
7337     _pp_entity,
7338     _pp_hasplayed,
7339     _pp_hmapl,
7340     _pp_hmapu,
7341     _pp_inputtime,
7342     _pp_joining,
7343     _pp_keys,
7344     _pp_lives,
7345     _pp_mapcount,
7346     _pp_name,
7347     _pp_newkeys,
7348     _pp_numweapons,
7349     _pp_playkeys,
7350     _pp_releasekeys,
7351     _pp_score,
7352     _pp_spawnhealth,
7353     _pp_spawnmp,
7354     _pp_weapnum,
7355     _pp_weapon,
7356     _pp_the_end
7357 };
7358 
mapstrings_playerproperty(ScriptVariant ** varlist,int paramCount)7359 int mapstrings_playerproperty(ScriptVariant **varlist, int paramCount)
7360 {
7361     char *propname;
7362     int prop;
7363 
7364     static const char *proplist[] =
7365     {
7366         "colourmap",
7367         "combokey",
7368         "combostep",
7369         "credits",
7370         "disablekeys",
7371         "ent",
7372         "entity",
7373         "hasplayed",
7374         "hmapl",
7375         "hmapu",
7376         "inputtime",
7377         "joining",
7378         "keys",
7379         "lives",
7380         "mapcount",
7381         "name",
7382         "newkeys",
7383         "numweapons",
7384         "playkeys",
7385         "releasekeys",
7386         "score",
7387         "spawnhealth",
7388         "spawnmp",
7389         "weapnum",
7390         "weapon",
7391     };
7392 
7393     if(paramCount < 2)
7394     {
7395         return 1;
7396     }
7397 
7398     // property name
7399     MAPSTRINGS(varlist[1], proplist, _pp_the_end,
7400                "Player property name '%s' is not supported yet.\n");
7401 
7402     return 1;
7403 }
7404 
7405 //getplayerproperty(index, propname);
openbor_getplayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7406 HRESULT openbor_getplayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
7407 {
7408     LONG ltemp;
7409     int index;
7410     entity *ent = NULL;
7411     int prop = -1;
7412     ScriptVariant *arg = NULL;
7413 
7414     if(paramCount < 2)
7415     {
7416         *pretvar = NULL;
7417         return E_FAIL;
7418     }
7419 
7420     mapstrings_playerproperty(varlist, paramCount);
7421     ScriptVariant_Clear(*pretvar);
7422 
7423     arg = varlist[0];
7424     if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
7425     {
7426         index = 0;
7427     }
7428     else
7429     {
7430         index = (LONG)ltemp;
7431     }
7432 
7433 
7434     ent = player[index].ent;
7435 
7436     arg = varlist[1];
7437     if(arg->vt != VT_INTEGER)
7438     {
7439         if(arg->vt != VT_STR)
7440         {
7441             printf("Function call getplayerproperty has invalid propery name parameter, it must be a string value.\n");
7442         }
7443         *pretvar = NULL;
7444         return E_FAIL;
7445     }
7446     prop = arg->lVal;
7447 
7448     switch(prop)
7449     {
7450     case _pp_ent:
7451     case _pp_entity:
7452     {
7453         if(!ent)
7454         {
7455             ScriptVariant_Clear(*pretvar);    // player not spawned
7456         }
7457         else
7458         {
7459             ScriptVariant_ChangeType(*pretvar, VT_PTR);
7460             (*pretvar)->ptrVal = (VOID *)ent;
7461         }
7462         break;
7463     }
7464     case _pp_name:
7465     {
7466         ScriptVariant_ChangeType(*pretvar, VT_STR);
7467         (*pretvar)->strVal = StrCache_CreateNewFrom(player[index].name);
7468         break;
7469     }
7470     case _pp_colourmap:
7471     {
7472         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7473         (*pretvar)->lVal = (LONG)player[index].colourmap;
7474         break;
7475     }
7476     case _pp_score:
7477     {
7478         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7479         (*pretvar)->lVal = (LONG)player[index].score;
7480         break;
7481     }
7482     case _pp_hasplayed:
7483     {
7484         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7485         (*pretvar)->lVal = (LONG)player[index].hasplayed;
7486         break;
7487     }
7488     case _pp_spawnhealth:
7489     {
7490         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7491         (*pretvar)->lVal = (LONG)player[index].spawnhealth;
7492         break;
7493     }
7494     case _pp_spawnmp:
7495     {
7496         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7497         (*pretvar)->lVal = (LONG)player[index].spawnmp;
7498         break;
7499     }
7500     case _pp_lives:
7501     {
7502         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7503         (*pretvar)->lVal = (LONG)player[index].lives;
7504         break;
7505     }
7506     case _pp_disablekeys:
7507     {
7508         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7509         (*pretvar)->lVal = (LONG)player[index].disablekeys;
7510         break;
7511     }
7512     case _pp_playkeys:
7513     {
7514         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7515         (*pretvar)->lVal = (LONG)player[index].playkeys;
7516         break;
7517     }
7518     case _pp_keys:
7519     {
7520         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7521         (*pretvar)->lVal = (LONG)player[index].keys;
7522         break;
7523     }
7524     case _pp_newkeys:
7525     {
7526         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7527         (*pretvar)->lVal = (LONG)player[index].newkeys;
7528         break;
7529     }
7530     case _pp_releasekeys:
7531     {
7532         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7533         (*pretvar)->lVal = (LONG)player[index].releasekeys;
7534         break;
7535     }
7536     case _pp_credits:
7537     {
7538         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7539         if(noshare)
7540         {
7541             (*pretvar)->lVal = (LONG)player[index].credits;
7542         }
7543         else
7544         {
7545             (*pretvar)->lVal = credits;
7546         }
7547         break;
7548     }
7549     case _pp_weapnum:
7550     {
7551         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7552         (*pretvar)->lVal = (LONG)player[index].weapnum;
7553         break;
7554     }
7555     case _pp_numweapons:
7556     {
7557         int cacheindex;
7558 
7559         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7560 
7561         if ( stricmp(player[index].name,"") != 0 ) {
7562             cacheindex = get_cached_model_index(player[index].name);
7563             if ( cacheindex == -1 )
7564             {
7565                (*pretvar)->lVal = (LONG)0;
7566                break;
7567             }
7568         } else
7569         {
7570            (*pretvar)->lVal = (LONG)0;
7571            break;
7572         }
7573 
7574         (*pretvar)->lVal = (LONG)model_cache[cacheindex].model->numweapons;
7575         break;
7576     }
7577     case _pp_joining:
7578     {
7579         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7580         (*pretvar)->lVal = (LONG)player[index].joining;
7581         break;
7582     }
7583     case _pp_combokey:
7584     {
7585         ScriptVariant *frm = NULL;
7586         frm = varlist[2];
7587         if(frm->vt != VT_INTEGER)
7588         {
7589             printf("Need a combostep value number for this property.\n");
7590             *pretvar = NULL;
7591             return E_FAIL;
7592         }
7593         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7594         (*pretvar)->lVal = (LONG)player[index].combokey[frm->lVal];
7595         break;
7596     }
7597     case _pp_combostep:
7598     {
7599         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7600         (*pretvar)->lVal = (LONG)player[index].combostep;
7601         break;
7602     }
7603     case _pp_inputtime:
7604     {
7605         ScriptVariant *frm = NULL;
7606         frm = varlist[2];
7607         if(frm->vt != VT_INTEGER)
7608         {
7609             printf("Need a combostep value number for this property.\n");
7610             *pretvar = NULL;
7611             return E_FAIL;
7612         }
7613         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7614         (*pretvar)->lVal = (LONG)player[index].inputtime[frm->lVal];
7615         break;
7616     }
7617     case _pp_hmapl:
7618     {
7619         int cacheindex;
7620 
7621         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7622 
7623         if ( stricmp(player[index].name,"") != 0 ) {
7624             cacheindex = get_cached_model_index(player[index].name);
7625             if ( cacheindex == -1 )
7626             {
7627                (*pretvar)->lVal = (LONG)0;
7628                break;
7629             }
7630         } else
7631         {
7632            (*pretvar)->lVal = (LONG)0;
7633            break;
7634         }
7635 
7636         (*pretvar)->lVal = (LONG)model_cache[cacheindex].model->maps.hide_start;
7637         break;
7638     }
7639     case _pp_hmapu:
7640     {
7641         int cacheindex;
7642 
7643         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7644 
7645         if ( stricmp(player[index].name,"") != 0 ) {
7646             cacheindex = get_cached_model_index(player[index].name);
7647             if ( cacheindex == -1 )
7648             {
7649                (*pretvar)->lVal = (LONG)0;
7650                break;
7651             }
7652         } else
7653         {
7654            (*pretvar)->lVal = (LONG)0;
7655            break;
7656         }
7657 
7658         (*pretvar)->lVal = (LONG)model_cache[cacheindex].model->maps.hide_end;
7659         break;
7660     }
7661     case _pp_mapcount:
7662     {
7663         int cacheindex;
7664 
7665         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7666 
7667         if ( stricmp(player[index].name,"") != 0 ) {
7668             cacheindex = get_cached_model_index(player[index].name);
7669             if ( cacheindex == -1 )
7670             {
7671                (*pretvar)->lVal = (LONG)0;
7672                break;
7673             }
7674         } else
7675         {
7676            (*pretvar)->lVal = (LONG)0;
7677            break;
7678         }
7679 
7680         (*pretvar)->lVal = (LONG)(model_cache[cacheindex].model->maps_loaded + 1);
7681         break;
7682     }
7683     default:
7684     {
7685         //printf("Property name '%s' is not supported by function getplayerproperty.\n", propname);
7686         *pretvar = NULL;
7687         return E_FAIL;
7688         break;
7689     }
7690     //this property is not known
7691     //default:{
7692     //  .....
7693     //}
7694     }
7695     return S_OK;
7696 }
7697 
7698 
7699 //changeplayerproperty(index, propname, value[, value2, value3,...]);
openbor_changeplayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7700 HRESULT openbor_changeplayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
7701 {
7702     LONG ltemp, ltemp2;
7703     int index;
7704     entity *ent = NULL;
7705     int prop = -1;
7706     char *tempstr = NULL;
7707     static char buffer[64];
7708     ScriptVariant *arg = NULL;
7709 
7710     *pretvar = NULL;
7711     if(paramCount < 3)
7712     {
7713         printf("Function changeplayerproperty must have at least 3 arguments.\n");
7714         return E_FAIL;
7715     }
7716 
7717     mapstrings_playerproperty(varlist, paramCount);
7718     arg = varlist[0];
7719 
7720     if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
7721     {
7722         index = 0;
7723     }
7724     else
7725     {
7726         index = (LONG)ltemp;
7727     }
7728 
7729     ent = player[index].ent;
7730 
7731     if(varlist[1]->vt != VT_INTEGER)
7732     {
7733         if(varlist[1]->vt != VT_STR)
7734         {
7735             printf("You must give a string value for player property name.\n");
7736         }
7737         return E_FAIL;
7738     }
7739     prop = varlist[1]->lVal;
7740 
7741     arg = varlist[2];
7742 
7743     //change the model
7744     switch(prop)
7745     {
7746     case _pp_ent:
7747     case _pp_entity:
7748     {
7749         if(arg->vt == VT_PTR || arg->vt == VT_EMPTY)
7750         {
7751             player[index].ent = (entity *)arg->ptrVal;
7752         }
7753         else
7754         {
7755             goto cpperror;
7756         }
7757         break;
7758     }
7759     case _pp_weapon:
7760     {
7761         if(ent)
7762         {
7763             if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7764             {
7765                 if(paramCount > 3)
7766                 {
7767                     if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
7768                     {
7769                         goto cpperror;
7770                     }
7771                 }
7772                 else
7773                 {
7774                     ltemp2 = (LONG)0;
7775                 }
7776                 set_weapon(player[index].ent, (LONG)ltemp, (LONG)ltemp2);
7777             }
7778             else
7779             {
7780                 goto cpperror;
7781             }
7782         }
7783         break;
7784     }
7785     case _pp_weapnum:
7786     {
7787         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7788         {
7789             player[index].weapnum = (LONG)ltemp;
7790         }
7791         else
7792         {
7793             goto cpperror;
7794         }
7795         break;
7796     }
7797     case _pp_name:
7798     {
7799         if(arg->vt != VT_STR)
7800         {
7801             goto cpperror;
7802         }
7803         tempstr = (char *)StrCache_Get(arg->strVal);
7804         strcpy(player[index].name, tempstr);
7805         break;
7806     }
7807     case _pp_colourmap:
7808     {
7809         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7810         {
7811             player[index].colourmap = (LONG)ltemp;
7812         }
7813         else
7814         {
7815             goto cpperror;
7816         }
7817         break;
7818     }
7819     case _pp_score:
7820     {
7821         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7822         {
7823             if(ltemp < 0)
7824             {
7825                 ltemp = 0;
7826             }
7827             else if(ltemp > 999999999)
7828             {
7829                 ltemp = 999999999;
7830             }
7831             player[index].score = (unsigned int)ltemp;
7832         }
7833         else
7834         {
7835             goto cpperror;
7836         }
7837         break;
7838     }
7839     case _pp_hasplayed:
7840     {
7841         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7842         {
7843             player[index].hasplayed = (LONG)ltemp;
7844         }
7845         else
7846         {
7847             goto cpperror;
7848         }
7849         break;
7850     }
7851     case _pp_spawnhealth:
7852     {
7853         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7854         {
7855             player[index].spawnhealth = (LONG)ltemp;
7856         }
7857         else
7858         {
7859             goto cpperror;
7860         }
7861         break;
7862     }
7863     case _pp_spawnmp:
7864     {
7865         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7866         {
7867             player[index].spawnmp = (LONG)ltemp;
7868         }
7869         else
7870         {
7871             goto cpperror;
7872         }
7873         break;
7874     }
7875     case _pp_lives:
7876     {
7877         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7878         {
7879             player[index].lives = (LONG)ltemp;
7880         }
7881         else
7882         {
7883             goto cpperror;
7884         }
7885         break;
7886     }
7887     case _pp_disablekeys:
7888     {
7889         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7890         {
7891             player[index].disablekeys = (LONG)ltemp;
7892         }
7893         else
7894         {
7895             goto cpperror;
7896         }
7897         break;
7898     }
7899     case _pp_playkeys:
7900     {
7901         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7902         {
7903             player[index].playkeys = (LONG)ltemp;
7904         }
7905         else
7906         {
7907             goto cpperror;
7908         }
7909         break;
7910     }
7911     case _pp_keys:
7912     {
7913         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7914         {
7915             player[index].keys = (LONG)ltemp;
7916         }
7917         else
7918         {
7919             goto cpperror;
7920         }
7921         break;
7922     }
7923     case _pp_newkeys:
7924     {
7925         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7926         {
7927             player[index].newkeys = (LONG)ltemp;
7928         }
7929         else
7930         {
7931             goto cpperror;
7932         }
7933         break;
7934     }
7935     case _pp_credits:
7936     {
7937         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
7938         {
7939             if(noshare)
7940             {
7941                 player[index].credits = (LONG)ltemp;
7942             }
7943             else
7944             {
7945                 credits = (LONG)ltemp;
7946             }
7947         }
7948         else
7949         {
7950             goto cpperror;
7951         }
7952         break;
7953     }
7954     case _pp_joining:
7955     {
7956         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7957         {
7958             player[index].joining = (LONG)ltemp;
7959         }
7960         else
7961         {
7962             goto cpperror;
7963         }
7964         break;
7965     }
7966     case _pp_releasekeys:
7967     {
7968         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7969         {
7970             player[index].releasekeys = (LONG)ltemp;
7971         }
7972         else
7973         {
7974             goto cpperror;
7975         }
7976         break;
7977     }
7978     case _pp_combokey:
7979     {
7980         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7981         {
7982             ScriptVariant *value = NULL;
7983             value = varlist[3];
7984             if(value->vt != VT_INTEGER)
7985             {
7986                 printf("Need a value and combostep value for this property.\n");
7987                 *pretvar = NULL;
7988                 return E_FAIL;
7989             }
7990             player[index].combokey[ltemp] = (int)value->lVal;
7991         }
7992         else
7993         {
7994             goto cpperror;
7995         }
7996         break;
7997     }
7998     case _pp_combostep:
7999     {
8000         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
8001         {
8002             player[index].combostep = (LONG)ltemp;
8003         }
8004         else
8005         {
8006             goto cpperror;
8007         }
8008         break;
8009     }
8010     case _pp_inputtime:
8011     {
8012         if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
8013         {
8014             ScriptVariant *value = NULL;
8015             value = varlist[3];
8016             if(value->vt != VT_INTEGER)
8017             {
8018                 printf("Need a value and combostep value number for this property.\n");
8019                 *pretvar = NULL;
8020                 return E_FAIL;
8021             }
8022             player[index].inputtime[ltemp] = (int)value->lVal;
8023         }
8024         else
8025         {
8026             goto cpperror;
8027         }
8028         break;
8029     }
8030     default:
8031         printf("Invalid property name for function changeplayerproperty.\n");
8032         return E_FAIL;
8033     }
8034 
8035     return S_OK;
8036 cpperror:
8037     ScriptVariant_ToString(arg, buffer);
8038     printf("Function changeplayerproperty receives an invalid value: %s.\n", buffer);
8039     return E_FAIL;
8040 }
8041 
8042 //this method is used by script engine, we move it here
8043 // it will get a system property, put it in the ScriptVariant
8044 // if failed return 0, otherwise return 1
getsyspropertybyindex(ScriptVariant * var,int index)8045 int getsyspropertybyindex(ScriptVariant *var, int index)
8046 {
8047     if(!var)
8048     {
8049         return 0;
8050     }
8051 
8052     switch(index)
8053     {
8054     case _sv_count_enemies:
8055         ScriptVariant_ChangeType(var, VT_INTEGER);
8056         var->lVal = count_ents(TYPE_ENEMY);
8057         break;
8058     case _sv_count_players:
8059         ScriptVariant_ChangeType(var, VT_INTEGER);
8060         var->lVal = count_ents(TYPE_PLAYER);
8061         break;
8062     case _sv_count_npcs:
8063         ScriptVariant_ChangeType(var, VT_INTEGER);
8064         var->lVal = count_ents(TYPE_NPC);
8065         break;
8066     case _sv_count_entities:
8067         ScriptVariant_ChangeType(var, VT_INTEGER);
8068         var->lVal = ent_count;
8069         break;
8070 	case _sv_drawmethod_default:
8071 		ScriptVariant_ChangeType(var, VT_PTR);
8072 		var->ptrVal = (void *)&plainmethod;
8073 		break;
8074     case _sv_ent_max:
8075         ScriptVariant_ChangeType(var, VT_INTEGER);
8076         var->lVal = ent_max;
8077         break;
8078     case _sv_in_level:
8079         ScriptVariant_ChangeType(var, VT_INTEGER);
8080         var->lVal = (level != NULL);
8081         break;
8082     case _sv_in_gameoverscreen:
8083         ScriptVariant_ChangeType(var, VT_INTEGER);
8084         var->lVal = gameOver;
8085         break;
8086     case _sv_in_menuscreen:
8087         ScriptVariant_ChangeType(var, VT_INTEGER);
8088         if(selectScreen || titleScreen || hallOfFame || gameOver || showComplete || currentScene || level || enginecreditsScreen)
8089         {
8090             var->lVal = 0;
8091         }
8092         else
8093         {
8094             var->lVal = menuScreen;
8095         }
8096         break;
8097     case _sv_in_enginecreditsscreen:
8098     		ScriptVariant_ChangeType(var, VT_INTEGER);
8099     		var->lVal = enginecreditsScreen;
8100     		break;
8101     case _sv_in_options:
8102         ScriptVariant_ChangeType(var, VT_INTEGER);
8103         var->lVal = optionsMenu;
8104         break;
8105     case _sv_in_system_options:
8106         ScriptVariant_ChangeType(var, VT_INTEGER);
8107         var->lVal = systemoptionsMenu;
8108         break;
8109     case _sv_in_cheat_options:
8110         ScriptVariant_ChangeType(var, VT_INTEGER);
8111         var->lVal = (optionsMenu && is_cheat_actived()) ? 1:0;
8112         break;
8113     case _sv_cheats:
8114         ScriptVariant_ChangeType(var, VT_INTEGER);
8115         var->lVal = is_cheat_actived();
8116         break;
8117     case _sv_in_control_options:
8118         ScriptVariant_ChangeType(var, VT_INTEGER);
8119         var->lVal = controloptionsMenu;
8120         break;
8121     case _sv_in_sound_options:
8122         ScriptVariant_ChangeType(var, VT_INTEGER);
8123         var->lVal = soundoptionsMenu;
8124         break;
8125     case _sv_in_video_options:
8126         ScriptVariant_ChangeType(var, VT_INTEGER);
8127         var->lVal = videooptionsMenu;
8128         break;
8129     case _sv_in_start_game:
8130         ScriptVariant_ChangeType(var, VT_INTEGER);
8131         var->lVal = startgameMenu;
8132         break;
8133     case _sv_in_new_game:
8134         ScriptVariant_ChangeType(var, VT_INTEGER);
8135         var->lVal = newgameMenu;
8136         break;
8137     case _sv_in_load_game:
8138         ScriptVariant_ChangeType(var, VT_INTEGER);
8139         var->lVal = loadgameMenu;
8140         break;
8141     case _sv_sets_count:
8142         ScriptVariant_ChangeType(var, VT_INTEGER);
8143         var->lVal = num_difficulties;
8144         break;
8145     case _sv_in_showcomplete:
8146         ScriptVariant_ChangeType(var, VT_INTEGER);
8147         var->lVal = showComplete;
8148         break;
8149     case _sv_in_titlescreen:
8150         ScriptVariant_ChangeType(var, VT_INTEGER);
8151         var->lVal = titleScreen;
8152         break;
8153     case _sv_in_halloffamescreen:
8154         ScriptVariant_ChangeType(var, VT_INTEGER);
8155         var->lVal = (hallOfFame);
8156         break;
8157     case _sv_sample_play_id:
8158         ScriptVariant_ChangeType(var, VT_INTEGER);
8159 		var->lVal = sample_play_id;
8160 		break;
8161     case _sv_effectvol:
8162         ScriptVariant_ChangeType(var, VT_INTEGER);
8163         var->lVal = savedata.effectvol;
8164         break;
8165     case _sv_elapsed_time:
8166         ScriptVariant_ChangeType(var, VT_INTEGER);
8167         var->lVal = _time;
8168         break;
8169     case _sv_game_speed:
8170         if(!level)
8171         {
8172             return 0;
8173         }
8174         ScriptVariant_ChangeType(var, VT_INTEGER);
8175         var->lVal = GAME_SPEED;
8176         break;
8177     case _sv_game_paused:
8178     case _sv_pause:
8179         ScriptVariant_ChangeType(var, VT_INTEGER);
8180         if( !(goto_mainmenu_flag&1) ) var->lVal = (_pause);
8181         else var->lVal = 0;
8182         break;
8183     case _sv_game_time:
8184         ScriptVariant_ChangeType(var, VT_INTEGER);
8185         var->lVal = timeleft;
8186         break;
8187     case _sv_porting:
8188     {
8189         e_porting porting;
8190 
8191         #if ANDROID
8192             porting = PORTING_ANDROID;
8193         #elif DARWIN
8194             porting = PORTING_DARWIN;
8195         #elif DC
8196             porting = PORTING_DREAMCAST;
8197         #elif GPX2
8198             porting = PORTING_GPX2;
8199         #elif LINUX
8200             porting = PORTING_LINUX;
8201         #elif OPENDINGUX
8202             porting = PORTING_OPENDINGUX;
8203         #elif PSP
8204             porting = PORTING_PSP;
8205         #elif WII
8206             porting = PORTING_WII;
8207         #elif WIN
8208             porting = PORTING_WINDOWS;
8209         #elif WIZ
8210             porting = PORTING_WIZ;
8211         #elif XBOX
8212             porting = PORTING_XBOX;
8213         #elif VITA
8214             porting = PORTING_VITA;
8215         #else
8216             porting = PORTING_UNKNOWN;
8217         #endif
8218 
8219         ScriptVariant_ChangeType(var, VT_INTEGER);
8220         var->lVal = porting;
8221         break;
8222     }
8223     case _sv_gfx_x_offset:
8224         if(!level)
8225         {
8226             return 0;
8227         }
8228         ScriptVariant_ChangeType(var, VT_INTEGER);
8229         var->lVal = gfx_x_offset;
8230         break;
8231     case _sv_gfx_y_offset:
8232         if(!level)
8233         {
8234             return 0;
8235         }
8236         ScriptVariant_ChangeType(var, VT_INTEGER);
8237         var->lVal = gfx_y_offset;
8238         break;
8239     case _sv_gfx_y_offset_adj:
8240         if(!level)
8241         {
8242             return 0;
8243         }
8244         ScriptVariant_ChangeType(var, VT_INTEGER);
8245         var->lVal = gfx_y_offset_adj;
8246         break;
8247     case _sv_in_selectscreen:
8248         ScriptVariant_ChangeType(var, VT_INTEGER);
8249         var->lVal = selectScreen;
8250         break;
8251 	case _sv_lasthit_attack:
8252 		ScriptVariant_ChangeType(var, VT_PTR);
8253 		var->ptrVal = lasthit.attack;
8254 		break;
8255 	case _sv_lasthit_attacker:
8256 		ScriptVariant_ChangeType(var, VT_PTR);
8257 		var->ptrVal = lasthit.attacker;
8258 		break;
8259 	case _sv_lasthit_target:
8260 		ScriptVariant_ChangeType(var, VT_PTR);
8261 		var->ptrVal = lasthit.target;
8262 		break;
8263 
8264     case _sv_lasthita:
8265     case _sv_lasthity:
8266         ScriptVariant_ChangeType(var, VT_DECIMAL);
8267         var->dblVal = lasthit.position.y;
8268         break;
8269     case _sv_lasthitc:
8270         ScriptVariant_ChangeType(var, VT_INTEGER);
8271         var->lVal = lasthit.confirm;
8272         break;
8273     case _sv_lasthitt:
8274         ScriptVariant_ChangeType(var, VT_INTEGER);
8275 
8276         if(lasthit.attack)
8277         {
8278             var->lVal = lasthit.attack->attack_type;
8279         }
8280 
8281         break;
8282     case _sv_lasthitx:
8283         ScriptVariant_ChangeType(var, VT_DECIMAL);
8284         var->dblVal = lasthit.position.x;
8285         break;
8286     case _sv_lasthitz:
8287         ScriptVariant_ChangeType(var, VT_DECIMAL);
8288         var->dblVal = lasthit.position.z;
8289         break;
8290     case _sv_xpos:
8291         if(!level)
8292         {
8293             return 0;
8294         }
8295         ScriptVariant_ChangeType(var, VT_DECIMAL);
8296         var->dblVal = advancex;
8297         break;
8298     case _sv_ypos:
8299         if(!level)
8300         {
8301             return 0;
8302         }
8303         ScriptVariant_ChangeType(var, VT_DECIMAL);
8304         var->dblVal = advancey;
8305         break;
8306     case _sv_hresolution:
8307         ScriptVariant_ChangeType(var, VT_INTEGER);
8308         var->lVal = videomodes.hRes;
8309         break;
8310     case _sv_vresolution:
8311         ScriptVariant_ChangeType(var, VT_INTEGER);
8312         var->lVal = videomodes.vRes;
8313         break;
8314     case _sv_current_scene:
8315         if(currentScene)
8316         {
8317             ScriptVariant_ChangeType(var, VT_STR);
8318             var->strVal = StrCache_CreateNewFrom(currentScene);
8319         }
8320         else
8321         {
8322             ScriptVariant_Clear(var);
8323         }
8324         break;
8325     case _sv_current_set:
8326         ScriptVariant_ChangeType(var, VT_INTEGER);
8327         var->lVal = current_set;
8328         break;
8329     case _sv_current_level:
8330         ScriptVariant_ChangeType(var, VT_INTEGER);
8331         var->lVal = current_level;
8332         break;
8333     case _sv_current_palette:
8334         ScriptVariant_ChangeType(var, VT_INTEGER);
8335         var->lVal = current_palette;
8336         break;
8337     case _sv_current_stage:
8338         ScriptVariant_ChangeType(var, VT_INTEGER);
8339         var->lVal = current_stage;
8340         break;
8341     case _sv_levelwidth:
8342         if(!level)
8343         {
8344             return 0;
8345         }
8346         ScriptVariant_ChangeType(var, VT_INTEGER);
8347         var->lVal = level->width;
8348         break;
8349     case _sv_levelheight:
8350         if(!level)
8351         {
8352             return 0;
8353         }
8354         ScriptVariant_ChangeType(var, VT_INTEGER);
8355         var->lVal = panel_height;
8356         break;
8357     case _sv_branchname:
8358         ScriptVariant_ChangeType(var, VT_STR);
8359         var->strVal = StrCache_CreateNewFrom(branch_name);
8360         break;
8361     case _sv_current_branch:
8362         if(level != NULL && levelsets && levelsets[current_set].levelorder && levelsets[current_set].levelorder[current_level].branchname)
8363         {
8364             ScriptVariant_ChangeType(var, VT_STR);
8365             var->strVal = StrCache_CreateNewFrom(levelsets[current_set].levelorder[current_level].branchname);
8366         }
8367         else
8368         {
8369             ScriptVariant_Clear(var);
8370         }
8371         break;
8372     case _sv_pakname:
8373     {
8374         char tempstr[MAX_BUFFER_LEN];
8375         getPakName(tempstr, -1);
8376         ScriptVariant_ChangeType(var, VT_STR);
8377         var->strVal = StrCache_CreateNewFrom(tempstr);
8378         break;
8379     }
8380     case _sv_bossescount:
8381         ScriptVariant_ChangeType(var, VT_INTEGER);
8382         var->lVal = level->bossescount;
8383         break;
8384     case _sv_maxsoundchannels:
8385         ScriptVariant_ChangeType(var, VT_INTEGER);
8386         var->lVal = maxchannels();
8387         break;
8388     case _sv_maxentityvars:
8389         ScriptVariant_ChangeType(var, VT_INTEGER);
8390         var->lVal = max_entity_vars;
8391         break;
8392     case _sv_maxindexedvars:
8393         ScriptVariant_ChangeType(var, VT_INTEGER);
8394         var->lVal = max_indexed_vars;
8395         break;
8396     case _sv_maxplayers:
8397         ScriptVariant_ChangeType(var, VT_INTEGER);
8398         var->lVal = levelsets[current_set].maxplayers;
8399         break;
8400     case _sv_maxscriptvars:
8401         ScriptVariant_ChangeType(var, VT_INTEGER);
8402         var->lVal = max_script_vars;
8403         break;
8404     case _sv_models_cached:
8405         ScriptVariant_ChangeType(var, VT_INTEGER);
8406         var->lVal = models_cached;
8407         break;
8408     case _sv_models_loaded:
8409         ScriptVariant_ChangeType(var, VT_INTEGER);
8410         var->lVal = models_loaded;
8411         break;
8412     case _sv_musicvol:
8413         ScriptVariant_ChangeType(var, VT_INTEGER);
8414         var->lVal = savedata.musicvol;
8415         break;
8416     case _sv_nofadeout:
8417         ScriptVariant_ChangeType(var, VT_INTEGER);
8418         var->lVal = nofadeout;
8419         break;
8420     case _sv_nojoin:
8421         ScriptVariant_ChangeType(var, VT_INTEGER);
8422         var->lVal = nojoin;
8423         break;
8424     case _sv_nopause:
8425         ScriptVariant_ChangeType(var, VT_INTEGER);
8426         var->lVal = nopause;
8427         break;
8428     case _sv_nosave:
8429         ScriptVariant_ChangeType(var, VT_INTEGER);
8430         var->lVal = nosave;
8431         break;
8432     case _sv_noscreenshot:
8433         ScriptVariant_ChangeType(var, VT_INTEGER);
8434         var->lVal = noscreenshot;
8435         break;
8436     case _sv_noshowcomplete:
8437         ScriptVariant_ChangeType(var, VT_INTEGER);
8438         var->lVal = levelsets[current_set].noshowcomplete;
8439         break;
8440     case _sv_numbasemaps:
8441         ScriptVariant_ChangeType(var, VT_INTEGER);
8442         var->lVal = level->numbasemaps;
8443         break;
8444     case _sv_numbosses:
8445         ScriptVariant_ChangeType(var, VT_INTEGER);
8446         var->lVal = level->numbosses;
8447         break;
8448     case _sv_numholes:
8449         ScriptVariant_ChangeType(var, VT_INTEGER);
8450         var->lVal = level->numholes;
8451         break;
8452     case _sv_numlayers:
8453         ScriptVariant_ChangeType(var, VT_INTEGER);
8454         var->lVal = level->numlayers;
8455         break;
8456     case _sv_numpalettes:
8457         ScriptVariant_ChangeType(var, VT_INTEGER);
8458         var->lVal = level->numpalettes;
8459         break;
8460     case _sv_numwalls:
8461         ScriptVariant_ChangeType(var, VT_INTEGER);
8462         var->lVal = level->numwalls;
8463         break;
8464     case _sv_pixelformat:
8465         ScriptVariant_ChangeType(var, VT_INTEGER);
8466         var->lVal = pixelformat;
8467         break;
8468     case _sv_player:
8469     case _sv_player1:
8470         ScriptVariant_ChangeType(var, VT_PTR);
8471         var->ptrVal = player;
8472         break;
8473     case _sv_player2:
8474         ScriptVariant_ChangeType(var, VT_PTR);
8475         var->ptrVal = player + 1;
8476         break;
8477     case _sv_player3:
8478         ScriptVariant_ChangeType(var, VT_PTR);
8479         var->ptrVal = player + 2;
8480         break;
8481     case _sv_player4:
8482         ScriptVariant_ChangeType(var, VT_PTR);
8483         var->ptrVal = player + 3;
8484         break;
8485     case _sv_player_max_z:
8486         ScriptVariant_ChangeType(var, VT_INTEGER);
8487         var->lVal = PLAYER_MAX_Z;
8488         break;
8489     case _sv_player_min_z:
8490         ScriptVariant_ChangeType(var, VT_INTEGER);
8491         var->lVal = PLAYER_MIN_Z;
8492         break;
8493     case _sv_lightx:
8494         ScriptVariant_ChangeType(var, VT_INTEGER);
8495         var->lVal = light.x;
8496         break;
8497     case _sv_lightz:
8498         ScriptVariant_ChangeType(var, VT_INTEGER);
8499         var->lVal = light.y;
8500         break;
8501     case _sv_self:
8502         ScriptVariant_ChangeType(var, VT_PTR);
8503         var->ptrVal = self;
8504         break;
8505     case _sv_shadowalpha:
8506         ScriptVariant_ChangeType(var, VT_INTEGER);
8507         var->lVal = shadowalpha;
8508         break;
8509     case _sv_shadowcolor:
8510         ScriptVariant_ChangeType(var, VT_INTEGER);
8511         var->lVal = shadowcolor;
8512         break;
8513     case _sv_shadowopacity:
8514         ScriptVariant_ChangeType(var, VT_INTEGER);
8515         var->lVal = shadowopacity;
8516         break;
8517     case _sv_skiptoset:
8518         ScriptVariant_ChangeType(var, VT_INTEGER);
8519         var->lVal = skiptoset;
8520         break;
8521     case _sv_slowmotion:
8522         ScriptVariant_ChangeType(var, VT_INTEGER);
8523         var->lVal = slowmotion.toggle;
8524         break;
8525     case _sv_slowmotion_duration:
8526         ScriptVariant_ChangeType(var, VT_INTEGER);
8527         var->lVal = slowmotion.duration;
8528         break;
8529     case _sv_soundvol:
8530         ScriptVariant_ChangeType(var, VT_INTEGER);
8531         var->lVal = savedata.soundvol;
8532         break;
8533     case _sv_totalram:
8534         ScriptVariant_ChangeType(var, VT_INTEGER);
8535         var->lVal = getSystemRam(KBYTES);
8536         break;
8537     case _sv_freeram:
8538         ScriptVariant_ChangeType(var, VT_INTEGER);
8539         var->lVal = getFreeRam(KBYTES);
8540         break;
8541     case _sv_usedram:
8542         ScriptVariant_ChangeType(var, VT_INTEGER);
8543         var->lVal = getUsedRam(KBYTES);
8544         break;
8545     case _sv_textbox:
8546         ScriptVariant_ChangeType(var, VT_PTR);
8547         var->ptrVal = textbox;
8548         break;
8549     case _sv_background:
8550         ScriptVariant_ChangeType(var, VT_PTR);
8551         var->ptrVal = background;
8552         break;
8553     case _sv_vscreen:
8554         ScriptVariant_ChangeType(var, VT_PTR);
8555         var->ptrVal = vscreen;
8556         break;
8557     case _sv_viewportx:
8558         ScriptVariant_ChangeType(var, VT_INTEGER);
8559         var->lVal = viewportx;
8560         break;
8561     case _sv_viewporty:
8562         ScriptVariant_ChangeType(var, VT_INTEGER);
8563         var->lVal = viewporty;
8564         break;
8565     case _sv_viewportw:
8566         ScriptVariant_ChangeType(var, VT_INTEGER);
8567         var->lVal = viewportw;
8568         break;
8569     case _sv_viewporth:
8570         ScriptVariant_ChangeType(var, VT_INTEGER);
8571         var->lVal = viewporth;
8572         break;
8573     case _sv_scrollminx:
8574         ScriptVariant_ChangeType(var, VT_DECIMAL);
8575         var->dblVal = scrollminx;
8576         break;
8577     case _sv_scrollmaxx:
8578         ScriptVariant_ChangeType(var, VT_DECIMAL);
8579         var->dblVal = scrollmaxx;
8580         break;
8581     case _sv_scrollminz:
8582         ScriptVariant_ChangeType(var, VT_DECIMAL);
8583         var->dblVal = scrollminz;
8584         break;
8585     case _sv_scrollmaxz:
8586         ScriptVariant_ChangeType(var, VT_DECIMAL);
8587         var->dblVal = scrollmaxz;
8588         break;
8589     case _sv_blockade:
8590         ScriptVariant_ChangeType(var, VT_DECIMAL);
8591         var->dblVal = blockade;
8592         break;
8593     case _sv_waiting:
8594         ScriptVariant_ChangeType(var, VT_INTEGER);
8595         var->lVal = level ? level->waiting : 0;
8596     case _sv_maxattacktypes:
8597         ScriptVariant_ChangeType(var, VT_INTEGER);
8598         var->lVal = max_attack_types;
8599         break;
8600     case _sv_maxanimations:
8601         ScriptVariant_ChangeType(var, VT_INTEGER);
8602         var->lVal = max_animations;
8603         break;
8604     case _sv_ticks:
8605         ScriptVariant_ChangeType(var, VT_INTEGER);
8606         var->lVal = timer_gettick();
8607         break;
8608     case _sv_nogameover:
8609         ScriptVariant_ChangeType(var, VT_INTEGER);
8610         var->lVal = levelsets[current_set].noshowgameover; // or s_set_entry *set = levelsets + current_set;
8611         break;
8612     case _sv_nohof:
8613         ScriptVariant_ChangeType(var, VT_INTEGER);
8614         var->lVal = levelsets[current_set].noshowhof;
8615         break;
8616     case _sv_fps:
8617         ScriptVariant_ChangeType(var, VT_INTEGER);
8618         var->lVal = getFPS();
8619         break;
8620     default:
8621         // We use indices now, but players/modders don't need to be exposed
8622         // to that implementation detail, so we write "name" and not "index".
8623         printf("Unknown system property name.\n");
8624         return 0;
8625     }
8626     return 1;
8627 }
8628 
8629 // change a system variant, used by script
changesyspropertybyindex(int index,ScriptVariant * value)8630 int changesyspropertybyindex(int index, ScriptVariant *value)
8631 {
8632     //char* tempstr = NULL;
8633     LONG ltemp;
8634     DOUBLE dbltemp;
8635 
8636     switch(index)
8637     {
8638     case _sv_elapsed_time:
8639         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8640         {
8641             _time = (LONG)ltemp;
8642         }
8643         break;
8644     case _sv_current_stage:
8645         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8646         {
8647             current_stage = (LONG)ltemp;
8648         }
8649         break;
8650     case _sv_current_set:
8651         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8652         {
8653             current_set = (LONG)ltemp;
8654         }
8655         break;
8656     case _sv_current_level:
8657         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8658         {
8659             current_level = (LONG)ltemp;
8660         }
8661         break;
8662     case _sv_game_time:
8663         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8664         {
8665             timeleft = (LONG)ltemp;
8666         }
8667         break;
8668     case _sv_gfx_x_offset:
8669         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8670         {
8671             gfx_x_offset = (LONG)ltemp;
8672         }
8673         break;
8674     case _sv_gfx_y_offset:
8675         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8676         {
8677             gfx_y_offset = (LONG)ltemp;
8678         }
8679         break;
8680     case _sv_gfx_y_offset_adj:
8681         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8682         {
8683             gfx_y_offset_adj = (LONG)ltemp;
8684         }
8685         break;
8686     case _sv_levelpos:
8687         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8688         {
8689             level->pos = (LONG)ltemp;
8690         }
8691         break;
8692     case _sv_xpos:
8693         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8694         {
8695             advancex = (float)dbltemp;
8696         }
8697         break;
8698     case _sv_ypos:
8699         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8700         {
8701             advancey = (DOUBLE)dbltemp;
8702         }
8703         break;
8704     case _sv_scrollminz:
8705         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8706         {
8707             scrollminz = (DOUBLE)dbltemp;
8708         }
8709         break;
8710     case _sv_scrollmaxz:
8711         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8712         {
8713             scrollmaxz = (DOUBLE)dbltemp;
8714         }
8715         break;
8716     case _sv_scrollminx:
8717         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8718         {
8719             scrollminx = (DOUBLE)dbltemp;
8720         }
8721         break;
8722     case _sv_scrollmaxx:
8723         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8724         {
8725             scrollmaxx = (DOUBLE)dbltemp;
8726         }
8727         break;
8728     case _sv_blockade:
8729         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8730         {
8731             blockade = (DOUBLE)dbltemp;
8732         }
8733         break;
8734     case _sv_shadowcolor:
8735         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8736         {
8737             shadowcolor = (LONG)ltemp;
8738         }
8739         break;
8740     case _sv_shadowalpha:
8741         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8742         {
8743             shadowalpha = (LONG)ltemp;
8744         }
8745         break;
8746     case _sv_shadowopacity:
8747         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8748         {
8749             shadowopacity = (LONG)ltemp;
8750         }
8751         break;
8752     case _sv_skiptoset:
8753         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8754         {
8755             skiptoset = (LONG)ltemp;
8756         }
8757         break;
8758     case _sv_slowmotion:
8759         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8760         {
8761             slowmotion.toggle = (unsigned)ltemp;
8762         }
8763         break;
8764     case _sv_slowmotion_duration:
8765         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8766         {
8767             slowmotion.duration = (unsigned)ltemp;
8768         }
8769         break;
8770 	case _sv_lasthit_attack:
8771 
8772 		lasthit.attack = (s_collision_attack*)value->ptrVal;
8773 		break;
8774 
8775 	case _sv_lasthit_attacker:
8776 
8777 		lasthit.attacker = (entity*)value->ptrVal;
8778 		break;
8779 
8780 	case _sv_lasthit_target:
8781 
8782 		lasthit.target = (entity*)value->ptrVal;
8783 		break;
8784 
8785     case _sv_lasthita:
8786     case _sv_lasthity:
8787         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8788         {
8789             lasthit.position.y = (DOUBLE)dbltemp;
8790         }
8791         break;
8792     case _sv_lasthitx:
8793         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8794         {
8795             lasthit.position.x = (DOUBLE)dbltemp;
8796         }
8797         break;
8798     case _sv_lasthitz:
8799         if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp)))
8800         {
8801             lasthit.position.z = (DOUBLE)dbltemp;
8802         }
8803         break;
8804     case _sv_lasthitc:
8805         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8806         {
8807             lasthit.confirm = (LONG)ltemp;
8808         }
8809         break;
8810     case _sv_lasthitt:
8811         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8812         {
8813             lasthit.attack->attack_type = (LONG)ltemp;
8814         }
8815         break;
8816     case _sv_smartbomber:
8817         smartbomber = (entity *)value->ptrVal;
8818         break;
8819     case _sv_textbox:
8820         textbox = (entity *)value->ptrVal;
8821         break;
8822     case _sv_background:
8823         background = (s_screen *)value->ptrVal;
8824         break;
8825     case _sv_bossescount:
8826         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8827         {
8828             level->bossescount = (LONG)ltemp;
8829         }
8830         break;
8831     case _sv_vscreen:
8832         vscreen = (s_screen *)value->ptrVal;
8833         break;
8834     case _sv_nofadeout:
8835         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8836         {
8837             nofadeout = (LONG)ltemp;
8838         }
8839         break;
8840     case _sv_nojoin:
8841         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8842         {
8843             nojoin = (LONG)ltemp;
8844         }
8845         break;
8846     case _sv_nopause:
8847         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8848         {
8849             nopause = (LONG)ltemp;
8850         }
8851         break;
8852     case _sv_nosave:
8853         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8854         {
8855             nosave = (LONG)ltemp;
8856         }
8857         break;
8858     case _sv_noscreenshot:
8859         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8860         {
8861             noscreenshot = (LONG)ltemp;
8862         }
8863         break;
8864     case _sv_noshowcomplete:
8865         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8866         {
8867             levelsets[current_set].noshowcomplete = (LONG)ltemp;
8868         }
8869         break;
8870     case _sv_numbosses:
8871         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8872         {
8873             level->numbosses = (LONG)ltemp;
8874         }
8875         break;
8876     case _sv_viewportx:
8877         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8878         {
8879             viewportx = (LONG)ltemp;
8880         }
8881         break;
8882     case _sv_viewporty:
8883         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8884         {
8885             viewporty = (LONG)ltemp;
8886         }
8887         break;
8888     case _sv_viewportw:
8889         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8890         {
8891             viewportw = (LONG)ltemp;
8892         }
8893         break;
8894     case _sv_viewporth:
8895         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8896         {
8897             viewporth = (LONG)ltemp;
8898         }
8899         break;
8900     case _sv_waiting:
8901         if(!level)
8902         {
8903             break;
8904         }
8905         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8906         {
8907             level->waiting = (LONG)ltemp;
8908         }
8909         break;
8910     case _sv_nogameover:
8911         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8912         {
8913             levelsets[current_set].noshowgameover = (LONG)ltemp;
8914         }
8915         break;
8916     case _sv_nohof:
8917         if(SUCCEEDED(ScriptVariant_IntegerValue(value, &ltemp)))
8918         {
8919             levelsets[current_set].noshowhof = (LONG)ltemp;
8920         }
8921         break;
8922     default:
8923         return 0;
8924     }
8925 
8926     return 1;
8927 }
8928 
8929 //checkhole(x,z,a), return 1 if there's hole here
openbor_checkhole(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8930 HRESULT openbor_checkhole(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
8931 {
8932     ScriptVariant *arg = NULL;
8933     DOUBLE x, z, a;
8934 
8935     if(paramCount < 2)
8936     {
8937         *pretvar = NULL;
8938         return E_FAIL;
8939     }
8940 
8941     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8942     (*pretvar)->lVal = (LONG)0;
8943 
8944     arg = varlist[0];
8945     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
8946     {
8947         return S_OK;
8948     }
8949 
8950     arg = varlist[1];
8951     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
8952     {
8953         return S_OK;
8954     }
8955 
8956     if ( paramCount >= 3 )
8957     {
8958         arg = varlist[2];
8959         if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
8960         {
8961             return S_OK;
8962         }
8963 
8964         (*pretvar)->lVal = (LONG)(checkhole_in((float)x, (float)z, (float)a) && checkwall_index((float)x, (float)z) < 0);
8965     }
8966     else (*pretvar)->lVal = (LONG)(checkhole((float)x, (float)z) && checkwall_index((float)x, (float)z) < 0);
8967 
8968     return S_OK;
8969 }
8970 
8971 //checkholeindex(x,z,a), return hole index if there's hole here, else it returns -1
openbor_checkholeindex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8972 HRESULT openbor_checkholeindex(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
8973 {
8974     ScriptVariant *arg = NULL;
8975     DOUBLE x, z, a;
8976 
8977     if(paramCount < 2)
8978     {
8979         *pretvar = NULL;
8980         return E_FAIL;
8981     }
8982 
8983     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8984     (*pretvar)->lVal = (LONG)-1;
8985 
8986     arg = varlist[0];
8987     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
8988     {
8989         return S_OK;
8990     }
8991 
8992     arg = varlist[1];
8993     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
8994     {
8995         return S_OK;
8996     }
8997 
8998     if ( checkwall_index((float)x, (float)z) < 0 )
8999     {
9000         if ( paramCount >= 3 )
9001         {
9002             arg = varlist[2];
9003             if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
9004             {
9005                 return S_OK;
9006             }
9007 
9008             (*pretvar)->lVal = (LONG)checkholeindex_in((float)x, (float)z, (float)a);
9009         }
9010         else (*pretvar)->lVal = (LONG)checkhole_index((float)x, (float)z);
9011     }
9012 
9013     return S_OK;
9014 }
9015 
9016 //checkbase(x,z,y,entity), return base of terrain. -1 if there is a wall and no platform. entity param is optional.
openbor_checkbase(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9017 HRESULT openbor_checkbase(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9018 {
9019     ScriptVariant *arg = NULL;
9020     DOUBLE x, z, y;
9021     entity *ent = NULL;
9022     float base = -1.0f;
9023 
9024     if(paramCount < 3)
9025     {
9026         *pretvar = NULL;
9027         return E_FAIL;
9028     }
9029 
9030     ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9031     (*pretvar)->dblVal = (DOUBLE)base;
9032 
9033     arg = varlist[0];
9034     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9035     {
9036         return S_OK;
9037     }
9038 
9039     arg = varlist[1];
9040     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9041     {
9042         return S_OK;
9043     }
9044 
9045     arg = varlist[2];
9046     if(FAILED(ScriptVariant_DecimalValue(arg, &y)))
9047     {
9048         return S_OK;
9049     }
9050 
9051     if (paramCount > 3)
9052     {
9053         arg = varlist[3];
9054         /*if(arg->vt != VT_PTR && arg->vt != VT_EMPTY)
9055         {
9056             printf("Function checkbase must have a valid entity handle or NULL().\n");
9057             *pretvar = NULL;
9058             return E_FAIL;
9059         }*/
9060         ent = (entity *)arg->ptrVal; //retrieve the entity
9061     }
9062 
9063     if((base = checkbase((float)x, (float)z, (float)y, ent)) >= 0)
9064     {
9065         (*pretvar)->dblVal = (DOUBLE)base;
9066     }
9067     return S_OK;
9068 }
9069 
9070 //checkwall(x,z), return wall height, or 0 | accept checkwall_index(x,z,y) too
openbor_checkwall(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9071 HRESULT openbor_checkwall(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9072 {
9073     ScriptVariant *arg = NULL;
9074     DOUBLE x, z, y;
9075     int wall;
9076     float h = T_MAX_CHECK_ALTITUDE;
9077 
9078     if(paramCount < 2)
9079     {
9080         *pretvar = NULL;
9081         return E_FAIL;
9082     }
9083 
9084     ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9085     (*pretvar)->dblVal = (DOUBLE)0;
9086 
9087     arg = varlist[0];
9088     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9089     {
9090         return S_OK;
9091     }
9092 
9093     arg = varlist[1];
9094     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9095     {
9096         return S_OK;
9097     }
9098 
9099     if (paramCount > 2)
9100     {
9101         arg = varlist[2];
9102         if(FAILED(ScriptVariant_DecimalValue(arg, &y)))
9103         {
9104             return S_OK;
9105         }
9106         h = (float)y;
9107     }
9108 
9109     if((wall = checkwall_below((float)x, (float)z, (float)h)) >= 0)
9110     {
9111         (*pretvar)->dblVal = (DOUBLE)level->walls[wall].height;
9112     }
9113     return S_OK;
9114 }
9115 
9116 //checkwallindex(x,z), return wall index, or -1 | accept checkwallindex(x,z,y) too
openbor_checkwallindex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9117 HRESULT openbor_checkwallindex(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9118 {
9119     ScriptVariant *arg = NULL;
9120     DOUBLE x, z, y;
9121     int wall;
9122     float h = 100000;
9123 
9124     if(paramCount < 2)
9125     {
9126         *pretvar = NULL;
9127         return E_FAIL;
9128     }
9129 
9130     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9131     (*pretvar)->lVal = (LONG)-1;
9132 
9133     arg = varlist[0];
9134     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9135     {
9136         return S_OK;
9137     }
9138 
9139     arg = varlist[1];
9140     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9141     {
9142         return S_OK;
9143     }
9144 
9145     if (paramCount > 2)
9146     {
9147         arg = varlist[2];
9148         if(FAILED(ScriptVariant_DecimalValue(arg, &y)))
9149         {
9150             return S_OK;
9151         }
9152         h = (float)arg->dblVal;
9153     }
9154 
9155     if((wall = checkwall_below((float)x, (float)z, (float)h)) >= 0)
9156     {
9157         (*pretvar)->lVal = (LONG)wall;
9158     }
9159     return S_OK;
9160 }
9161 
9162 //checkplatformbelow(x,z,a), return the highest platfrom entity below
openbor_checkplatformbelow(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9163 HRESULT openbor_checkplatformbelow(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9164 {
9165     ScriptVariant *arg = NULL;
9166     DOUBLE x, z, a;
9167 
9168     if(paramCount < 3)
9169     {
9170         *pretvar = NULL;
9171         return E_FAIL;
9172     }
9173 
9174     //ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9175     //(*pretvar)->dblVal = (DOUBLE)0;
9176     ScriptVariant_ChangeType(*pretvar, VT_PTR);
9177     (*pretvar)->ptrVal = (VOID *)NULL;
9178 
9179     arg = varlist[0];
9180     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9181     {
9182         return S_OK;
9183     }
9184 
9185     arg = varlist[1];
9186     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9187     {
9188         return S_OK;
9189     }
9190 
9191     arg = varlist[2];
9192     if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
9193     {
9194         return S_OK;
9195     }
9196 
9197     ScriptVariant_ChangeType(*pretvar, VT_PTR);
9198     (*pretvar)->ptrVal = (VOID *)check_platform_below((float)x, (float)z, (float)a, NULL);
9199     return S_OK;
9200 }
9201 
9202 //checkplatformabove(x,z,a), find a lowest platform above this altitude
openbor_checkplatformabove(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9203 HRESULT openbor_checkplatformabove(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9204 {
9205     ScriptVariant *arg = NULL;
9206     DOUBLE x, z, a;
9207 
9208     if(paramCount < 3)
9209     {
9210         *pretvar = NULL;
9211         return E_FAIL;
9212     }
9213 
9214     //ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9215     //(*pretvar)->dblVal = (DOUBLE)0;
9216     ScriptVariant_ChangeType(*pretvar, VT_PTR);
9217     (*pretvar)->ptrVal = (VOID *)NULL;
9218 
9219     arg = varlist[0];
9220     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9221     {
9222         return S_OK;
9223     }
9224 
9225     arg = varlist[1];
9226     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9227     {
9228         return S_OK;
9229     }
9230 
9231     arg = varlist[2];
9232     if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
9233     {
9234         return S_OK;
9235     }
9236 
9237     ScriptVariant_ChangeType(*pretvar, VT_PTR);
9238     (*pretvar)->ptrVal = (VOID *)check_platform_above((float)x, (float)z, (float)a, NULL);
9239     return S_OK;
9240 }
9241 
9242 //checkplatformbetween(x,z,a_min,a_max), find the first platform between these 2 altitudes
openbor_checkplatformbetween(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9243 HRESULT openbor_checkplatformbetween(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9244 {
9245     ScriptVariant *arg = NULL;
9246     DOUBLE x, z, amin, amax;
9247 
9248     if(paramCount < 3)
9249     {
9250         *pretvar = NULL;
9251         return E_FAIL;
9252     }
9253 
9254     //ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9255     //(*pretvar)->dblVal = (DOUBLE)0;
9256     ScriptVariant_ChangeType(*pretvar, VT_PTR);
9257     (*pretvar)->ptrVal = (VOID *)NULL;
9258 
9259     arg = varlist[0];
9260     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9261     {
9262         return S_OK;
9263     }
9264 
9265     arg = varlist[1];
9266     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9267     {
9268         return S_OK;
9269     }
9270 
9271     arg = varlist[2];
9272     if(FAILED(ScriptVariant_DecimalValue(arg, &amin)))
9273     {
9274         return S_OK;
9275     }
9276 
9277     arg = varlist[3];
9278     if(FAILED(ScriptVariant_DecimalValue(arg, &amax)))
9279     {
9280         return S_OK;
9281     }
9282 
9283     ScriptVariant_ChangeType(*pretvar, VT_PTR);
9284     (*pretvar)->ptrVal = (VOID *)check_platform_between((float)x, (float)z, (float)amin, (float)amax, NULL);
9285     return S_OK;
9286 }
9287 
9288 //checkbasemap(x,z), return basemap height (float)
openbor_checkbasemap(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9289 HRESULT openbor_checkbasemap(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9290 {
9291     ScriptVariant *arg = NULL;
9292     DOUBLE x, z;
9293 
9294     if(paramCount < 2)
9295     {
9296         *pretvar = NULL;
9297         return E_FAIL;
9298     }
9299 
9300     ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9301     (*pretvar)->dblVal = (DOUBLE)0;
9302 
9303     arg = varlist[0];
9304     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9305     {
9306         return S_OK;
9307     }
9308 
9309     arg = varlist[1];
9310     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9311     {
9312         return S_OK;
9313     }
9314 
9315     (*pretvar)->dblVal = (DOUBLE)check_basemap(x, z);
9316 
9317     return S_OK;
9318 }
9319 
9320 //checkbasemapindex(x,z), return basemap index in (x,z)
openbor_checkbasemapindex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9321 HRESULT openbor_checkbasemapindex(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9322 {
9323     ScriptVariant *arg = NULL;
9324     DOUBLE x, z;
9325 
9326     if(paramCount < 2)
9327     {
9328         *pretvar = NULL;
9329         return E_FAIL;
9330     }
9331 
9332     ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9333     (*pretvar)->dblVal = (DOUBLE)0;
9334 
9335     arg = varlist[0];
9336     if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
9337     {
9338         return S_OK;
9339     }
9340 
9341     arg = varlist[1];
9342     if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
9343     {
9344         return S_OK;
9345     }
9346 
9347     (*pretvar)->dblVal = (DOUBLE)check_basemap_index((float)x, (float)z);
9348 
9349     return S_OK;
9350 }
9351 
9352 //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)9353 HRESULT openbor_generatebasemap(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9354 {
9355     DOUBLE rx, rz, x_size, z_size, min_y, max_y;
9356     LONG index;
9357     LONG x_cont = (LONG)0;
9358 
9359     if(paramCount < 7)
9360     {
9361         *pretvar = NULL;
9362         return E_FAIL;
9363     }
9364 
9365     if ( FAILED(ScriptVariant_IntegerValue(varlist[0], &index)) )
9366     {
9367         *pretvar = NULL;
9368         return E_FAIL;
9369     }
9370     if(paramCount > 7)
9371     {
9372         if ( FAILED(ScriptVariant_IntegerValue(varlist[7], &x_cont)) )
9373         {
9374             *pretvar = NULL;
9375             return E_FAIL;
9376         }
9377     }
9378     if ( FAILED(ScriptVariant_DecimalValue(varlist[1], &rx)) || FAILED(ScriptVariant_DecimalValue(varlist[2], &rz)) ||
9379          FAILED(ScriptVariant_DecimalValue(varlist[3], &x_size)) || FAILED(ScriptVariant_DecimalValue(varlist[4], &z_size)) ||
9380          FAILED(ScriptVariant_DecimalValue(varlist[5], &min_y)) || FAILED(ScriptVariant_DecimalValue(varlist[6], &max_y))
9381     )
9382     {
9383         *pretvar = NULL;
9384         return E_FAIL;
9385     }
9386 
9387     generate_basemap(index, rx, rz, x_size, z_size, min_y, max_y, x_cont);
9388 
9389     return S_OK;
9390 }
9391 
openbor_openfilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9392 HRESULT openbor_openfilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9393 {
9394     char *filename = NULL;
9395     ScriptVariant *arg = NULL;
9396     LONG location = 0;
9397     int fsindex;
9398 
9399     FILE *handle = NULL;
9400     char path[MAX_BUFFER_LEN] = {""};
9401     char tmpname[MAX_BUFFER_LEN] = {""};
9402     long size;
9403 
9404     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9405 
9406     if(paramCount < 1)
9407     {
9408         *pretvar = NULL;
9409         return E_FAIL;
9410     }
9411 
9412     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9413 
9414     arg = varlist[0];
9415     if(arg->vt != VT_STR)
9416     {
9417         printf("Filename for openfilestream must be a string.\n");
9418         *pretvar = NULL;
9419         return E_FAIL;
9420     }
9421 
9422     filename = (char *)StrCache_Get(arg->strVal);
9423 
9424     if(paramCount > 1)
9425     {
9426         arg = varlist[1];
9427         if(FAILED(ScriptVariant_IntegerValue(arg, &location)))
9428         {
9429             *pretvar = NULL;
9430             return E_FAIL;
9431         }
9432     }
9433 
9434     for(fsindex = 0; fsindex < numfilestreams; fsindex++)
9435     {
9436         if(filestreams[fsindex].buf == NULL)
9437         {
9438             break;
9439         }
9440     }
9441 
9442     if(fsindex == numfilestreams)
9443     {
9444         __realloc(filestreams, numfilestreams); //warning, don't ++ here, its a macro
9445         numfilestreams++;
9446     }
9447 
9448     // Load file from saves directory if specified
9449     if(location)
9450     {
9451         getBasePath(path, "Saves", 0);
9452         getPakName(tmpname, -1);
9453         strcat(path, tmpname);
9454         strcat(path, "/");
9455         strcat(path, filename);
9456         //printf("open path: %s", path);
9457 #ifndef DC
9458         if(!(fileExists(path)))
9459         {
9460             /*
9461             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.
9462 
9463             printf("Openfilestream - file specified does not exist.\n"); //Keep this for possible debug mode in the future.
9464             */
9465             (*pretvar)->lVal = -1;
9466 
9467             return S_OK;
9468         }
9469 #endif
9470         handle = fopen(path, "rb");
9471         if(handle == NULL)
9472         {
9473             (*pretvar)->lVal = -1;
9474             return S_OK;
9475         }
9476         //printf("\nfile opened\n");
9477         fseek(handle, 0, SEEK_END);
9478         size = ftell(handle);
9479         //printf("\n file size %d fsindex %d\n", size, fsindex);
9480         rewind(handle);
9481         filestreams[fsindex].buf = malloc(sizeof(*filestreams[fsindex].buf) * (size + 1));
9482         if(filestreams[fsindex].buf == NULL)
9483         {
9484             (*pretvar)->lVal = -1;
9485             return S_OK;
9486         }
9487         fread(filestreams[fsindex].buf, 1, size, handle);
9488         filestreams[fsindex].buf[size] = 0;
9489         filestreams[fsindex].size = size;
9490     }
9491     else if(buffer_pakfile(filename, &filestreams[fsindex].buf, &filestreams[fsindex].size) != 1)
9492     {
9493         printf("Invalid filename used in openfilestream.\n");
9494         (*pretvar)->lVal = -1;
9495         return S_OK;
9496     }
9497 
9498     (*pretvar)->lVal = (LONG)fsindex;
9499 
9500     filestreams[fsindex].pos = 0;
9501     return S_OK;
9502 }
9503 
openbor_getfilestreamline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9504 HRESULT openbor_getfilestreamline(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9505 {
9506     int length;
9507     char *buf;
9508     char *dst;
9509     ScriptVariant *arg = NULL;
9510     LONG filestreamindex;
9511 
9512     if(paramCount < 1)
9513     {
9514         *pretvar = NULL;
9515         return E_FAIL;
9516     }
9517 
9518     arg = varlist[0];
9519     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9520     {
9521         return S_OK;
9522     }
9523 
9524     ScriptVariant_ChangeType(*pretvar, VT_STR);
9525 
9526     length = 0;
9527     buf = filestreams[filestreamindex].buf + filestreams[filestreamindex].pos;
9528     while(buf[length] && buf[length] != '\n' && buf[length] != '\r')
9529     {
9530         ++length;
9531     }
9532 
9533     (*pretvar)->strVal = StrCache_Pop(length);
9534     dst = StrCache_Get((*pretvar)->strVal);
9535     memcpy(dst, buf, length);
9536     dst[length] = '\0';
9537 
9538     return S_OK;
9539 }
9540 
openbor_getfilestreamargument(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9541 HRESULT openbor_getfilestreamargument(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9542 {
9543     ScriptVariant *arg = NULL;
9544     LONG filestreamindex, argument;
9545     char *argtype = NULL;
9546 
9547     if(paramCount < 3)
9548     {
9549         *pretvar = NULL;
9550         return E_FAIL;
9551     }
9552 
9553     arg = varlist[0];
9554     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9555     {
9556         return S_OK;
9557     }
9558 
9559     arg = varlist[1];
9560     if(FAILED(ScriptVariant_IntegerValue(arg, &argument)))
9561     {
9562         return S_OK;
9563     }
9564     ScriptVariant_Clear(*pretvar);
9565 
9566     if(varlist[2]->vt != VT_STR)
9567     {
9568         printf("You must give a string value specifying what kind of value you want the argument converted to.\n");
9569         return E_FAIL;
9570     }
9571     argtype = (char *)StrCache_Get(varlist[2]->strVal);
9572 
9573     if(stricmp(argtype, "string") == 0)
9574     {
9575         ScriptVariant_ChangeType(*pretvar, VT_STR);
9576         (*pretvar)->strVal = StrCache_CreateNewFrom(findarg(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos, argument));
9577     }
9578     else if(stricmp(argtype, "int") == 0)
9579     {
9580         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9581         (*pretvar)->lVal = (LONG)atoi(findarg(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos, argument));
9582     }
9583     else if(stricmp(argtype, "float") == 0)
9584     {
9585         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
9586         (*pretvar)->dblVal = (DOUBLE)atof(findarg(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos, argument));
9587     }
9588     else if(stricmp(argtype, "byte") == 0) // By White Dragon
9589     {
9590         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9591         (*pretvar)->lVal = (LONG)(readByte(filestreams[filestreamindex].buf + filestreams[filestreamindex].pos));
9592     }
9593     else
9594     {
9595         printf("Invalid type for argument converted to (getfilestreamargument).\n");
9596         return E_FAIL;
9597     }
9598 
9599     return S_OK;
9600 }
9601 
openbor_filestreamnextline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9602 HRESULT openbor_filestreamnextline(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9603 {
9604     ScriptVariant *arg = NULL;
9605     char *buf;
9606     size_t pos;
9607     LONG filestreamindex;
9608 
9609     if(paramCount < 1)
9610     {
9611         *pretvar = NULL;
9612         return E_FAIL;
9613     }
9614 
9615     arg = varlist[0];
9616     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9617     {
9618         return S_OK;
9619     }
9620     pos = filestreams[filestreamindex].pos;
9621     buf = filestreams[filestreamindex].buf;
9622     while(buf[pos] && buf[pos] != '\n' && buf[pos] != '\r')
9623     {
9624         ++pos;
9625     }
9626     while(buf[pos] == '\n' || buf[pos] == '\r')
9627     {
9628         ++pos;
9629     }
9630     filestreams[filestreamindex].pos = pos;
9631 
9632     return S_OK;
9633 }
9634 
openbor_getfilestreamposition(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9635 HRESULT openbor_getfilestreamposition(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9636 {
9637     ScriptVariant *arg = NULL;
9638     LONG filestreamindex;
9639 
9640     if(paramCount < 1)
9641     {
9642         *pretvar = NULL;
9643         return E_FAIL;
9644     }
9645 
9646     arg = varlist[0];
9647     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9648     {
9649         return S_OK;
9650     }
9651 
9652     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9653     (*pretvar)->lVal = (LONG)filestreams[filestreamindex].pos;
9654     return S_OK;
9655 }
9656 
openbor_setfilestreamposition(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9657 HRESULT openbor_setfilestreamposition(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9658 {
9659     ScriptVariant *arg = NULL;
9660     LONG filestreamindex, position;
9661 
9662 
9663     if(paramCount < 2)
9664     {
9665         *pretvar = NULL;
9666         return E_FAIL;
9667     }
9668 
9669     arg = varlist[0];
9670     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9671     {
9672         return S_OK;
9673     }
9674 
9675     arg = varlist[1];
9676     if(FAILED(ScriptVariant_IntegerValue(arg, &position)))
9677     {
9678         return S_OK;
9679     }
9680 
9681     filestreams[filestreamindex].pos = position;
9682     return S_OK;
9683 }
9684 
openbor_filestreamappend(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9685 HRESULT openbor_filestreamappend(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9686 {
9687     LONG filestreamindex;
9688     ScriptVariant *arg = NULL;
9689     LONG appendtype = -1;
9690     size_t len1, len2;
9691     char *temp;
9692     static char append[2048];
9693 
9694     *pretvar = NULL;
9695     if(paramCount < 2)
9696     {
9697         goto append_error;
9698     }
9699 
9700     arg = varlist[0];
9701     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9702     {
9703         goto append_error;
9704     }
9705 
9706     if(paramCount >= 3)
9707     {
9708         arg = varlist[2];
9709         if(FAILED(ScriptVariant_IntegerValue(arg, &appendtype)))
9710         {
9711             goto append_error;
9712         }
9713     }
9714 
9715     arg = varlist[1];
9716 
9717     /*
9718      * By White Dragon to write a byte
9719      */
9720     if ( paramCount >= 4 )
9721     {
9722         char* argtype = NULL;
9723         unsigned char byte = (unsigned char)0x00;
9724         if ( varlist[3]->vt != VT_STR ) goto append_error;
9725 
9726         argtype = (char *)StrCache_Get(varlist[3]->strVal);
9727 
9728         if( stricmp(argtype, "byte") != 0 ) goto append_error;
9729         else
9730         {
9731             int inc = -1; // if buf > 0 (prev bytes) you need to begin from size-1 (index)
9732 
9733             len1 = 1+1; // +1 is the NULL to close the buffer
9734             len2 = filestreams[filestreamindex].size;
9735 
9736             filestreams[filestreamindex].buf = realloc( filestreams[filestreamindex].buf, sizeof(*temp)*(len1+len2+0) );
9737 
9738             byte = (unsigned char)varlist[1]->lVal;
9739             //printf("a:%s->%d->%d\n",filestreams[filestreamindex].buf,byte,filestreams[filestreamindex].size);
9740 
9741             if ( len2 <= 0 ) inc = 0;
9742 
9743             filestreams[filestreamindex].buf[filestreams[filestreamindex].size+inc] = byte; // overwrite 0x00 byte
9744             if (appendtype <= 1) filestreams[filestreamindex].buf[filestreams[filestreamindex].size+1+inc] = 0x00;
9745             //printf("b:%s\n",filestreams[filestreamindex].buf);
9746 
9747             filestreams[filestreamindex].size = len1 + len2;
9748         }
9749     } else
9750     {
9751         ScriptVariant_ToString(arg, append);
9752 
9753         len1 = strlen(append);
9754         len2 = filestreams[filestreamindex].size;
9755 
9756         filestreams[filestreamindex].buf = realloc(filestreams[filestreamindex].buf, sizeof(*temp) * (len1 + len2 + 4));
9757 
9758         if(appendtype == 0)
9759         {
9760             append[len1] = ' ';
9761             append[++len1] = '\0';
9762             strcpy(filestreams[filestreamindex].buf + len2, "\r\n");
9763             len2 += 2;
9764             strcpy(filestreams[filestreamindex].buf + len2, append);
9765         }
9766         else if(appendtype == 1)
9767         {
9768             append[len1] = ' ';
9769             append[++len1] = '\0';
9770             strcpy(filestreams[filestreamindex].buf + len2, append);
9771         }
9772         else
9773         {
9774             strcpy(filestreams[filestreamindex].buf + len2, append);
9775         }
9776         filestreams[filestreamindex].size = len1 + len2;
9777     }
9778 
9779     return S_OK;
9780 
9781 append_error:
9782     return E_FAIL;
9783 
9784 }
9785 
openbor_createfilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9786 HRESULT openbor_createfilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9787 {
9788     int fsindex;
9789     ScriptVariant_Clear(*pretvar);
9790 
9791     for(fsindex = 0; fsindex < numfilestreams; fsindex++)
9792     {
9793         if(filestreams[fsindex].buf == NULL)
9794         {
9795             break;
9796         }
9797     }
9798 
9799     if(fsindex == numfilestreams)
9800     {
9801         __realloc(filestreams, numfilestreams); //warning, don't ++ here, its a macro
9802         numfilestreams++;
9803     }
9804 
9805     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9806     (*pretvar)->lVal = (LONG)fsindex;
9807 
9808     // Initialize the new filestream
9809     filestreams[fsindex].pos = 0;
9810     filestreams[fsindex].size = 0;
9811     filestreams[fsindex].buf = malloc(sizeof(*filestreams[fsindex].buf) * 128);
9812     filestreams[fsindex].buf[0] = '\0';
9813     return S_OK;
9814 }
9815 
openbor_savefilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9816 HRESULT openbor_savefilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9817 {
9818     int i;
9819     LONG filestreamindex;
9820     ScriptVariant *arg = NULL;
9821     char *bytearg = NULL, *patharg = NULL;
9822     FILE *handle = NULL;
9823     char path[MAX_BUFFER_LEN] = {""};
9824     char tmpname[MAX_BUFFER_LEN] = {""};
9825 
9826     *pretvar = NULL;
9827 
9828     if(paramCount < 1)
9829     {
9830         return E_FAIL;
9831     }
9832 
9833     arg = varlist[0];
9834     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9835     {
9836         printf("You must give a valid filestrema handle for savefilestream!\n");
9837         return E_FAIL;
9838     }
9839 
9840     arg = varlist[1];
9841     if(arg->vt != VT_STR)
9842     {
9843         printf("Filename for savefilestream must be a string.\n");
9844         return E_FAIL;
9845     }
9846 
9847     if (paramCount > 2)
9848     {
9849         patharg = (char *)StrCache_Get(varlist[2]->strVal);
9850         if( varlist[2]->vt != VT_STR )
9851         {
9852             printf("The pathname parameter must be a string.\n");
9853             return E_FAIL;
9854         }
9855     }
9856 
9857     if (paramCount > 3) // By White Dragon
9858     {
9859         bytearg = (char *)StrCache_Get(varlist[3]->strVal);
9860         if( stricmp(bytearg, "byte") != 0 )
9861         {
9862             printf("%s parameter does not exist.\n",bytearg);
9863             return E_FAIL;
9864         }
9865     }
9866 
9867     // Get the saves directory
9868     if ( paramCount <= 2 || patharg == NULL )
9869     {
9870         getBasePath(path, "Saves", 0);
9871         getPakName(tmpname, -1);
9872         strcat(path, tmpname);
9873         // Add user's filename to path and write the filestream to it
9874         strcat(path, "/");
9875     } else // By White Dragon
9876     {
9877         strcat(path, "./");
9878         strcat(path, patharg);
9879     }
9880     //printf("path:%s\n",path);
9881 
9882     strcat(path, (char *)StrCache_Get(arg->strVal));
9883 
9884     for(i = strlen(path) - 1; i >= 0; i--)
9885     {
9886 
9887         if(path[i] == '/' || path[i] == '\\')
9888         {
9889             path[i] = 0;
9890             // Make folder if it doesn't exist
9891 #ifndef DC
9892             dirExists(path, 1);
9893 #endif
9894             path[i] = '/';
9895             break;
9896         }
9897     }
9898 
9899     //printf("save path: %s", path);
9900     handle = fopen(path, "wb");
9901     if(handle == NULL)
9902     {
9903         return E_FAIL;
9904     }
9905     fwrite(filestreams[filestreamindex].buf, 1, strlen(filestreams[filestreamindex].buf), handle);
9906 
9907     // add blank line so it can be read successfully
9908     if ( paramCount <= 3 || (paramCount > 3 && stricmp(bytearg, "byte") != 0 ) ) fwrite("\r\n", 1, 2, handle);
9909     fclose(handle);
9910 
9911     return S_OK;
9912 }
9913 
openbor_closefilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9914 HRESULT openbor_closefilestream(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9915 {
9916     LONG filestreamindex;
9917     ScriptVariant *arg = NULL;
9918 
9919     *pretvar = NULL;
9920 
9921     if(paramCount < 1)
9922     {
9923         return E_FAIL;
9924     }
9925 
9926     arg = varlist[0];
9927     if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
9928     {
9929         return E_FAIL;
9930     }
9931 
9932 
9933     if(filestreams[filestreamindex].buf)
9934     {
9935         free(filestreams[filestreamindex].buf);
9936         filestreams[filestreamindex].buf = NULL;
9937     }
9938     return S_OK;
9939 }
9940 //damageentity(entity, other, force, drop, type)
openbor_damageentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9941 HRESULT openbor_damageentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
9942 {
9943     entity *ent = NULL;
9944     entity *other = NULL;
9945     entity *temp = NULL;
9946     LONG force, drop, type;
9947     s_collision_attack atk;
9948 
9949     if(paramCount < 1)
9950     {
9951         printf("Function requires at least 1 parameter.\n");
9952         goto de_error;
9953     }
9954 
9955     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9956     (*pretvar)->lVal = (LONG)0;
9957 
9958     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
9959     if(!ent)
9960     {
9961         printf("Invalid entity parameter.\n");
9962         goto de_error;
9963     }
9964 
9965     other = ent;
9966 
9967     if(paramCount >= 2 && varlist[1]->ptrVal)
9968     {
9969         other = (entity *)(varlist[1])->ptrVal;
9970     }
9971 
9972     if(paramCount >= 3 )
9973     {
9974         force = (LONG)1;
9975         drop = (LONG)0;
9976         type = (LONG)ATK_NORMAL;
9977 
9978         if(FAILED(ScriptVariant_IntegerValue((varlist[2]), &force)))
9979         {
9980             printf("Wrong force value.\n");
9981             goto de_error;
9982         }
9983 
9984         if(paramCount >= 4)
9985         {
9986             if(FAILED(ScriptVariant_IntegerValue((varlist[3]), &drop)))
9987             {
9988                 printf("Wrong drop value.\n");
9989                 goto de_error;
9990             }
9991         }
9992         if(paramCount >= 5)
9993         {
9994             if(FAILED(ScriptVariant_IntegerValue((varlist[4]), &type)))
9995             {
9996                 printf("Wrong type value.\n");
9997                 goto de_error;
9998             }
9999         }
10000 
10001         atk = emptyattack;
10002         atk.attack_force = force;
10003         atk.attack_drop = drop;
10004         if(drop)
10005         {
10006             atk.dropv.y = (float)DEFAULT_ATK_DROPV_Y;
10007             atk.dropv.x = (float)DEFAULT_ATK_DROPV_X;
10008             atk.dropv.z = (float)DEFAULT_ATK_DROPV_Z;
10009         }
10010         atk.attack_type = type;
10011     }
10012     else
10013     {
10014         atk = attack;
10015     }
10016 
10017     if(!ent->takedamage)
10018     {
10019         ent->energy_state.health_current -= atk.attack_force;
10020         if(ent->energy_state.health_current <= 0)
10021         {
10022             kill_entity(ent);
10023         }
10024         (*pretvar)->lVal = (LONG)1;
10025     }
10026     else
10027     {
10028         temp = self;
10029         self = ent;
10030         (*pretvar)->lVal = (LONG)self->takedamage(other, &atk, 0);
10031         self = temp;
10032     }
10033     return S_OK;
10034 
10035 de_error:
10036     *pretvar = NULL;
10037     return E_FAIL;
10038 }
10039 
10040 //getcomputeddamage(defender, attacker, force, drop, type), it returns the real damage. Minimum 3 params (defender, attacker, force)
openbor_getcomputeddamage(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10041 HRESULT openbor_getcomputeddamage(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10042 {
10043     entity *defender = NULL;
10044     entity *attacker = NULL;
10045     entity *temp = NULL;
10046     LONG force, drop, type;
10047     s_collision_attack atk;
10048 
10049     if(paramCount < 3)
10050     {
10051         printf("Function requires at least 3 parameters.\n");
10052         goto gcd_error;
10053     }
10054 
10055     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10056     (*pretvar)->lVal = (LONG)0;
10057 
10058     force = (LONG)0;
10059     drop = (LONG)0;
10060     type = (LONG)ATK_NORMAL;
10061 
10062     defender = (entity *)(varlist[0])->ptrVal; //retrieve the entity
10063     if(!defender)
10064     {
10065         printf("Invalid entity parameter.\n");
10066         goto gcd_error;
10067     }
10068 
10069     if(varlist[1]->ptrVal)
10070     {
10071         attacker = (entity *)(varlist[1])->ptrVal;
10072     }
10073 
10074     if(FAILED(ScriptVariant_IntegerValue((varlist[2]), &force)))
10075     {
10076         printf("Wrong force value.\n");
10077         goto gcd_error;
10078     }
10079 
10080     if(paramCount >= 4)
10081     {
10082         if(FAILED(ScriptVariant_IntegerValue((varlist[3]), &drop)))
10083         {
10084             printf("Wrong drop value.\n");
10085             goto gcd_error;
10086         }
10087     }
10088     if(paramCount >= 5)
10089     {
10090         if(FAILED(ScriptVariant_IntegerValue((varlist[4]), &type)))
10091         {
10092             printf("Wrong type value.\n");
10093             goto gcd_error;
10094         }
10095     }
10096 
10097     atk = emptyattack;
10098     atk.attack_force = force;
10099     atk.attack_drop = drop;
10100     if(drop)
10101     {
10102         atk.dropv.y = (float)DEFAULT_ATK_DROPV_Y;
10103         atk.dropv.x = (float)DEFAULT_ATK_DROPV_X;
10104         atk.dropv.z = (float)DEFAULT_ATK_DROPV_Z;
10105     }
10106     atk.attack_type = type;
10107 
10108     temp = self;
10109     self = defender;
10110     (*pretvar)->lVal = (LONG)calculate_force_damage(attacker, &atk);
10111     self = temp;
10112 
10113     return S_OK;
10114 
10115 gcd_error:
10116     *pretvar = NULL;
10117     return E_FAIL;
10118 }
10119 
10120 //killentity(entity)
openbor_killentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10121 HRESULT openbor_killentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10122 {
10123     entity *ent = NULL;
10124 
10125     if(paramCount < 1)
10126     {
10127         *pretvar = NULL;
10128         return E_FAIL;
10129     }
10130 
10131     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10132 
10133     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
10134     if(ent == NULL)
10135     {
10136         (*pretvar)->lVal = (LONG)0;
10137         return S_OK;
10138     }
10139     kill_entity(ent);
10140     (*pretvar)->lVal = (LONG)1;
10141     return S_OK;
10142 }
10143 
10144 // dograb
10145 // Damon V. Caskey
10146 // 2013-12-30
10147 //
10148 // Enables initiation of the engine's default grab state between attacker and
10149 // target entities.
10150 //
10151 // dograb(ptr attacker, ptr target, int adjust);
10152 //
10153 // attacker: Entity attempting grab.
10154 // target: Entity to be grabbed.
10155 // adjustcheck: Engine's dograb adjust check flag.
openbor_dograb(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10156 HRESULT openbor_dograb(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10157 {
10158     #define SELF_NAME           "dograb(void attacker, void target, int adjust)"
10159     #define ARG_MINIMUM         2
10160     #define ARG_ATTACKER        0
10161     #define ARG_TARGET          1
10162     #define ARG_ADJUST          2
10163     #define ARG_ADJUST_DEFAULT  1
10164 
10165     LONG adjust          = ARG_ADJUST_DEFAULT;   // dograb adjust check.
10166     int result          = S_OK;                 // Function pass/fail result.
10167     entity *attacker    = NULL;                 // Attacker entity (attempting grab)
10168     entity *target      = NULL;                 // Target entity (to be grabbed)
10169 
10170     ScriptVariant_Clear(*pretvar);
10171 
10172     // Validate there are at least two parameters (attacker and target entities).
10173     if(paramCount < ARG_MINIMUM)
10174     {
10175         goto error_local;
10176     }
10177 
10178     // Get adjust check.
10179     if(paramCount > ARG_ADJUST)
10180     {
10181         ScriptVariant_IntegerValue(varlist[ARG_ADJUST], &adjust);
10182     }
10183 
10184     // Get attacking and target entity.
10185     attacker = (entity *)(varlist[ARG_ATTACKER])->ptrVal;
10186     target = (entity *)(varlist[ARG_TARGET])->ptrVal;
10187 
10188     // Validate entities.
10189     if(!attacker && !target)
10190     {
10191         goto error_local;
10192     }
10193 
10194     // Execute engine's grab function.
10195     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10196     (*pretvar)->lVal = dograb(attacker, target, adjust);
10197 
10198     return result;
10199 
10200     // Error trap
10201     error_local:
10202 
10203     result = E_FAIL;
10204     printf("\nYou must provide valid entity handles and an optional adjustment: " SELF_NAME);
10205 
10206     // Return result.
10207     return result;
10208 
10209     #undef SELF_NAME
10210     #undef ARG_MINIMUM
10211     #undef ARG_ATTACKER
10212     #undef ARG_TARGET
10213     #undef ARG_ADJUST
10214     #undef ARG_ADJUST_DEFAULT
10215 }
10216 
10217 //findtarget(entity, int animation);
openbor_findtarget(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10218 HRESULT openbor_findtarget(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10219 {
10220     LONG i = 0;
10221     entity *ent = NULL;
10222     entity *tempself, *target;
10223     LONG anim = -1;
10224 
10225     if(paramCount > 2)
10226     {
10227         ScriptVariant_IntegerValue(varlist[2], &i);
10228     }
10229 
10230     if(paramCount < 1)
10231     {
10232         *pretvar = NULL;
10233         return E_FAIL;
10234     }
10235 
10236     ScriptVariant_ChangeType(*pretvar, VT_PTR);
10237 
10238     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
10239     if(!ent)
10240     {
10241         ScriptVariant_Clear(*pretvar);
10242         return S_OK;
10243     }
10244     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
10245     {
10246         return E_FAIL;
10247     }
10248     tempself = self;
10249     self = ent;
10250     target = normal_find_target((int)anim, i);
10251     if(!target)
10252     {
10253         ScriptVariant_Clear(*pretvar);
10254     }
10255     else
10256     {
10257         (*pretvar)->ptrVal = (VOID *)target;
10258     }
10259     self = tempself;
10260     return S_OK;
10261 }
10262 
10263 //checkrange(entity, target, int ani);
openbor_checkrange(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10264 HRESULT openbor_checkrange(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10265 {
10266     entity *ent = NULL, *target = NULL;
10267     LONG ani = 0;
10268     extern int max_animations;
10269 
10270     if(paramCount < 2)
10271     {
10272         goto checkrange_error;
10273     }
10274 
10275     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10276 
10277     if(varlist[0]->vt != VT_PTR || varlist[1]->vt != VT_PTR)
10278     {
10279         goto checkrange_error;
10280     }
10281 
10282     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
10283     target = (entity *)(varlist[1])->ptrVal; //retrieve the target
10284 
10285     if(!ent || !target)
10286     {
10287         goto checkrange_error;
10288     }
10289 
10290     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &ani)))
10291     {
10292         goto checkrange_error;
10293     }
10294     else if(paramCount <= 2)
10295     {
10296         ani = ent->animnum;
10297     }
10298 
10299     if(ani < 0 || ani >= max_animations)
10300     {
10301         printf("Animation id out of range: %d / %d.\n", (int)ani, max_animations);
10302         goto checkrange_error;
10303     }
10304 
10305     (*pretvar)->lVal = check_range_target_all(ent, target, ani);
10306 
10307     return S_OK;
10308 
10309 checkrange_error:
10310     printf("Function needs at least 2 valid entity handles, the third parameter is optional: checkrange(entity, target, int animnum)\n");
10311     *pretvar = NULL;
10312     return E_FAIL;
10313 }
10314 
10315 //clearspawnentry();
openbor_clearspawnentry(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10316 HRESULT openbor_clearspawnentry(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10317 {
10318     *pretvar = NULL;
10319     memset(&spawnentry, 0, sizeof(spawnentry));
10320     spawnentry.index = spawnentry.item_properties.index = spawnentry.weaponindex = -1;
10321     return S_OK;
10322 }
10323 
10324 // ===== setspawnentry =====
10325 enum setspawnentry_enum
10326 {
10327     _sse_2phealth,
10328     _sse_2pitem,
10329     _sse_3phealth,
10330     _sse_3pitem,
10331     _sse_4phealth,
10332     _sse_4pitem,
10333     _sse_aggression,
10334     _sse_alias,
10335     _sse_alpha,
10336     _sse_boss,
10337     _sse_coords,
10338     _sse_credit,
10339     _sse_dying,
10340     _sse_flip,
10341     _sse_health,
10342     _sse_item,
10343     _sse_itemalias,
10344     _sse_itemhealth,
10345     _sse_itemmap,
10346     _sse_map,
10347     _sse_mp,
10348     _sse_multiple,
10349     _sse_name,
10350     _sse_nolife,
10351     _sse_parent,
10352     _sse_type,
10353     _sse_weapon,
10354     _sse_the_end,
10355 };
10356 
mapstrings_setspawnentry(ScriptVariant ** varlist,int paramCount)10357 int mapstrings_setspawnentry(ScriptVariant **varlist, int paramCount)
10358 {
10359     char *propname;
10360     int prop;
10361     static const char *proplist[] =
10362     {
10363         "2phealth",
10364         "2pitem",
10365         "3phealth",
10366         "3pitem",
10367         "4phealth",
10368         "4pitem",
10369         "aggression",
10370         "alias",
10371         "alpha",
10372         "boss",
10373         "coords",
10374         "credit",
10375         "dying",
10376         "flip",
10377         "health",
10378         "item",
10379         "itemalias",
10380         "itemhealth",
10381         "itemmap",
10382         "map",
10383         "mp",
10384         "multiple",
10385         "name",
10386         "nolife",
10387         "parent",
10388         "type",
10389         "weapon",
10390     };
10391 
10392     MAPSTRINGS(varlist[0], proplist, _sse_the_end,
10393                "Property name '%s' is not supported by setspawnentry.\n");
10394 
10395     return 1;
10396 }
10397 
10398 //setspawnentry(propname, value1[, value2, value3, ...]);
openbor_setspawnentry(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10399 HRESULT openbor_setspawnentry(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount)
10400 {
10401     LONG ltemp;
10402     s_model *tempmodel;
10403     DOUBLE dbltemp;
10404     int temp, prop;
10405     ScriptVariant *arg = NULL;
10406 
10407     if(paramCount < 2)
10408     {
10409         *pretvar = NULL;
10410         return E_FAIL;
10411     }
10412 
10413     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10414     (*pretvar)->lVal = (LONG)1;
10415 
10416     mapstrings_setspawnentry(varlist, paramCount);
10417     if(varlist[0]->vt != VT_INTEGER)
10418     {
10419         if(varlist[0]->vt != VT_STR)
10420         {
10421             printf("You must give a string value for spawn entry property name.\n");
10422         }
10423         *pretvar = NULL;
10424         return E_FAIL;
10425     }
10426 
10427     prop = varlist[0]->lVal;
10428 
10429     arg = varlist[1];
10430 
10431     switch(prop)
10432     {
10433     case _sse_name:
10434         if(arg->vt != VT_STR)
10435         {
10436             printf("You must use a string value for spawn entry's name property: function setspawnentry.\n");
10437             goto setspawnentry_error;
10438         }
10439         spawnentry.model = findmodel((char *)StrCache_Get(arg->strVal));
10440         break;
10441     case _sse_alias:
10442         if(arg->vt != VT_STR)
10443         {
10444             goto setspawnentry_error;
10445         }
10446         strcpy(spawnentry.alias, (char *)StrCache_Get(arg->strVal));
10447         break;
10448     case _sse_item:
10449         if(arg->vt != VT_STR)
10450         {
10451             goto setspawnentry_error;
10452         }
10453         spawnentry.itemmodel = findmodel((char *)StrCache_Get(arg->strVal));
10454         spawnentry.item = spawnentry.itemmodel->name;
10455         spawnentry.item_properties.index = get_cached_model_index(spawnentry.item);
10456         spawnentry.item_properties.player_count = 0;
10457         break;
10458     case _sse_2pitem:
10459         if(arg->vt != VT_STR)
10460         {
10461             goto setspawnentry_error;
10462         }
10463         tempmodel = findmodel((char *)StrCache_Get(arg->strVal));
10464         if(!tempmodel)
10465         {
10466             spawnentry.item = NULL;
10467         }
10468         else
10469         {
10470             spawnentry.item = tempmodel->name;
10471         }
10472         spawnentry.item_properties.player_count = 1;
10473         break;
10474     case _sse_3pitem:
10475         if(arg->vt != VT_STR)
10476         {
10477             goto setspawnentry_error;
10478         }
10479         spawnentry.itemmodel = findmodel((char *)StrCache_Get(arg->strVal));
10480         spawnentry.item_properties.player_count = 2;
10481         break;
10482     case _sse_4pitem:
10483         if(arg->vt != VT_STR)
10484         {
10485             goto setspawnentry_error;
10486         }
10487         spawnentry.itemmodel = findmodel((char *)StrCache_Get(arg->strVal));
10488         spawnentry.item_properties.player_count = 3;
10489         break;
10490     case _sse_health:
10491         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10492         {
10493             spawnentry.health[0] = (LONG)ltemp;
10494         }
10495         else
10496         {
10497             (*pretvar)->lVal = (LONG)0;
10498         }
10499         break;
10500     case _sse_itemhealth:
10501         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10502         {
10503             spawnentry.item_properties.health = (LONG)ltemp;
10504         }
10505         else
10506         {
10507             (*pretvar)->lVal = (LONG)0;
10508         }
10509         break;
10510     case _sse_itemalias:
10511         if(arg->vt != VT_STR)
10512         {
10513             return E_FAIL;
10514         }
10515         strcpy(spawnentry.item_properties.alias, (char *)StrCache_Get(arg->strVal));
10516         break;
10517     case _sse_2phealth:
10518         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10519         {
10520             spawnentry.health[1] = (LONG)ltemp;
10521         }
10522         else
10523         {
10524             (*pretvar)->lVal = (LONG)0;
10525         }
10526         break;
10527     case _sse_3phealth:
10528         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10529         {
10530             spawnentry.health[2] = (LONG)ltemp;
10531         }
10532         else
10533         {
10534             (*pretvar)->lVal = (LONG)0;
10535         }
10536         break;
10537     case _sse_4phealth:
10538         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10539         {
10540             spawnentry.health[3] = (LONG)ltemp;
10541         }
10542         else
10543         {
10544             (*pretvar)->lVal = (LONG)0;
10545         }
10546         break;
10547     case _sse_coords:
10548         temp = 1;
10549         if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp)))
10550         {
10551             spawnentry.position.x = (DOUBLE)dbltemp;
10552         }
10553         else
10554         {
10555             temp = 0;
10556         }
10557         if(paramCount >= 3 && temp)
10558         {
10559             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10560             {
10561                 spawnentry.position.z = (DOUBLE)dbltemp;
10562             }
10563             else
10564             {
10565                 temp = 0;
10566             }
10567         }
10568         if(paramCount >= 4 && temp)
10569         {
10570             if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
10571             {
10572                 spawnentry.position.y = (DOUBLE)dbltemp;
10573             }
10574             else
10575             {
10576                 temp = 0;
10577             }
10578         }
10579         (*pretvar)->lVal = (LONG)temp;
10580         break;
10581     case _sse_mp:
10582         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10583         {
10584             spawnentry.mp = (LONG)ltemp;
10585         }
10586         else
10587         {
10588             (*pretvar)->lVal = (LONG)0;
10589         }
10590         break;
10591     case _sse_map:
10592         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10593         {
10594             spawnentry.colourmap = (LONG)ltemp;
10595         }
10596         else
10597         {
10598             (*pretvar)->lVal = (LONG)0;
10599         }
10600         break;
10601     case _sse_itemmap:
10602         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10603         {
10604             spawnentry.item_properties.colorset = (LONG)ltemp;
10605         }
10606         else
10607         {
10608             (*pretvar)->lVal = (LONG)0;
10609         }
10610         break;
10611     case _sse_alpha:
10612         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10613         {
10614             spawnentry.alpha = (LONG)ltemp;
10615         }
10616         else
10617         {
10618             (*pretvar)->lVal = (LONG)0;
10619         }
10620         break;
10621     case _sse_multiple:
10622         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10623         {
10624             spawnentry.multiple = (LONG)ltemp;
10625         }
10626         else
10627         {
10628             (*pretvar)->lVal = (LONG)0;
10629         }
10630         break;
10631     case _sse_dying:
10632         temp = 1;
10633         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10634         {
10635             spawnentry.dying = (LONG)ltemp;
10636         }
10637         else
10638         {
10639             temp = 0;
10640         }
10641         if(paramCount >= 3 && temp)
10642         {
10643             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10644             {
10645                 spawnentry.per1 = (LONG)ltemp;
10646             }
10647             else
10648             {
10649                 temp = 0;
10650             }
10651         }
10652         if(paramCount >= 4 && temp)
10653         {
10654             if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
10655             {
10656                 spawnentry.per2 = (LONG)ltemp;
10657             }
10658             else
10659             {
10660                 temp = 0;
10661             }
10662         }
10663         (*pretvar)->lVal = (LONG)temp;
10664         break;
10665     case _sse_nolife:
10666         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10667         {
10668             spawnentry.nolife = (LONG)ltemp;
10669         }
10670         else
10671         {
10672             (*pretvar)->lVal = (LONG)0;
10673         }
10674         break;
10675     case _sse_boss:
10676         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10677         {
10678             spawnentry.boss = (LONG)ltemp;
10679         }
10680         else
10681         {
10682             (*pretvar)->lVal = (LONG)0;
10683         }
10684         break;
10685     case _sse_flip:
10686         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10687         {
10688             spawnentry.flip = (LONG)ltemp;
10689         }
10690         else
10691         {
10692             (*pretvar)->lVal = (LONG)0;
10693         }
10694         break;
10695     case _sse_credit:
10696         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10697         {
10698             spawnentry.credit = (LONG)ltemp;
10699         }
10700         else
10701         {
10702             (*pretvar)->lVal = (LONG)0;
10703         }
10704         break;
10705     case _sse_aggression:
10706         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10707         {
10708             spawnentry.aggression = (LONG)ltemp;
10709         }
10710         else
10711         {
10712             (*pretvar)->lVal = (LONG)0;
10713         }
10714         break;
10715     case _sse_parent:
10716         if( arg->vt == VT_PTR ) //&& arg->vt != VT_EMPTY
10717         {
10718             spawnentry.parent = (entity *)arg->ptrVal;
10719         }
10720         else
10721         {
10722             (*pretvar)->ptrVal = (VOID *)NULL;
10723         }
10724         break;
10725     case _sse_type:
10726         if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
10727         {
10728             spawnentry.entitytype = (LONG)ltemp;
10729         }
10730         else
10731         {
10732             (*pretvar)->lVal = (LONG)0;
10733         }
10734         break;
10735     case _sse_weapon:
10736         if(arg->vt != VT_STR)
10737         {
10738             goto setspawnentry_error;
10739         }
10740         spawnentry.weaponmodel = findmodel((char *)StrCache_Get(arg->strVal));
10741         break;
10742     default:
10743         //printf("Property name '%s' is not supported by setspawnentry.\n", propname);
10744         goto setspawnentry_error;
10745     }
10746 
10747     return S_OK;
10748 setspawnentry_error:
10749     *pretvar = NULL;
10750     return E_FAIL;
10751 }
10752 
10753 //spawn();
openbor_spawn(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10754 HRESULT openbor_spawn(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10755 {
10756     entity *ent;
10757 
10758     if(spawnentry.boss && level)
10759     {
10760         level->bossescount++;
10761         level->numbosses++;
10762     }
10763 
10764     ent = smartspawn(&spawnentry);
10765 
10766     if(ent)
10767     {
10768         ScriptVariant_ChangeType(*pretvar, VT_PTR);
10769         (*pretvar)->ptrVal = (VOID *) ent;
10770     }
10771     else
10772     {
10773         ScriptVariant_Clear(*pretvar);
10774     }
10775 
10776     return S_OK;
10777 }
10778 
10779 //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)10780 HRESULT openbor_projectile(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10781 {
10782     DOUBLE temp = 0;
10783     LONG ltemp = 0;
10784     entity *ent;
10785     char *name = NULL;
10786     float x = 0, z = 0, a = 0;
10787     int direction = DIRECTION_LEFT;
10788     int type = 0;
10789     int projectile_prime = 0;
10790     int map = 0;
10791 
10792     int relative;
10793 
10794     if(paramCount >= 1 && varlist[0]->vt == VT_INTEGER && varlist[0]->lVal)
10795     {
10796         relative = 1;
10797         paramCount--;
10798         varlist++;
10799     }
10800     else
10801     {
10802         relative = 0;
10803     }
10804 
10805     if(paramCount >= 1 && varlist[0]->vt == VT_STR)
10806     {
10807         name = StrCache_Get(varlist[0]->strVal);
10808     }
10809 
10810     // X offset.
10811 	if(paramCount >= 2 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[1], &temp)))
10812     {
10813         x = (float)temp;
10814     }
10815     else if(relative)
10816     {
10817         x = 0;
10818     }
10819     else
10820     {
10821         x = self->position.x;
10822     }
10823 
10824 	// Z offset.
10825     if(paramCount >= 3 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &temp)))
10826     {
10827         z = (float)temp;
10828     }
10829     else if(relative)
10830     {
10831         z = 0;
10832     }
10833     else
10834     {
10835         z = self->position.z;
10836     }
10837 
10838 	// Y offset.
10839     if(paramCount >= 4 && SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &temp)))
10840     {
10841         a = (float)temp;
10842     }
10843     else if(relative)
10844     {
10845         a  = self->animation->projectile.position.y;
10846     }
10847     else
10848     {
10849         a = self->position.y + self->animation->projectile.position.y;
10850     }
10851 
10852 	// Direction.
10853     if(paramCount >= 5 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
10854     {
10855         direction = (LONG)ltemp;
10856     }
10857     else if(relative)
10858     {
10859         direction  = DIRECTION_RIGHT;
10860     }
10861     else
10862     {
10863         direction = self->direction;
10864     }
10865 
10866 	// PType
10867     if(paramCount >= 6 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
10868     {
10869 
10870         // Backwards compatibility for modules made before bitwise update
10871         // of projectile_prime and expect base vs. floor and moving
10872         // behavior to both be tied to a single 0 or 1 value.
10873         if((LONG)ltemp)
10874         {
10875             projectile_prime |= PROJECTILE_PRIME_BASE_FLOOR;
10876             projectile_prime |= PROJECTILE_PRIME_LAUNCH_STATIONARY;
10877         }
10878         else
10879         {
10880             projectile_prime |= PROJECTILE_PRIME_BASE_Y;
10881             projectile_prime |= PROJECTILE_PRIME_LAUNCH_MOVING;
10882         }
10883     }
10884 
10885 	// Type (Spawn as knife or bomb).
10886     if(paramCount >= 7 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[6], &ltemp)))
10887     {
10888         type = (LONG)ltemp;
10889     }
10890 
10891 	// Map
10892 	if(paramCount >= 8 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[7], &ltemp)))
10893     {
10894         map = (LONG)ltemp;
10895     }
10896 
10897 	// Reverse X if using relative offset.
10898     if(relative)
10899     {
10900         if(self->direction == DIRECTION_RIGHT)
10901         {
10902             x += self->position.x;
10903         }
10904         else
10905         {
10906             x = self->position.x - x;
10907             direction = DIRECTION_LEFT;
10908         }
10909         z += self->position.z;
10910         a += self->position.y;
10911     }
10912 
10913     switch(type)
10914     {
10915     default:
10916     case 0:
10917         ent = knife_spawn(name, -1, x, z, a, direction, projectile_prime, map);
10918         break;
10919     case 1:
10920         ent = bomb_spawn(name, -1, x, z, a, direction, map);
10921         break;
10922     }
10923 
10924     ScriptVariant_ChangeType(*pretvar, VT_PTR);
10925     (*pretvar)->ptrVal = (VOID *) ent;
10926 
10927     return S_OK;
10928 }
10929 
10930 
10931 
10932 
10933 //int rgbcolor(int r, int g, int b);
openbor_rgbcolor(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10934 HRESULT openbor_rgbcolor(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
10935 {
10936     LONG r, g, b;
10937 
10938     if(paramCount != 3)
10939     {
10940         goto rgbcolor_error;
10941     }
10942     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &r)))
10943     {
10944         goto rgbcolor_error;    // decimal/integer value for red?
10945     }
10946     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &g)))
10947     {
10948         goto rgbcolor_error;    // decimal/integer value for green?
10949     }
10950     if(FAILED(ScriptVariant_IntegerValue(varlist[2], &b)))
10951     {
10952         goto rgbcolor_error;    // decimal/integer value for blue?
10953     }
10954 
10955     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10956     (*pretvar)->lVal = _makecolour(r, g, b);
10957     return S_OK;
10958 
10959 rgbcolor_error:
10960     *pretvar = NULL;
10961     return E_FAIL;
10962 }
10963 
10964 // ===== playerkeys =====
10965 enum playerkeys_enum
10966 {
10967     _pk_anybutton,
10968     _pk_attack,
10969     _pk_attack2,
10970     _pk_attack3,
10971     _pk_attack4,
10972     _pk_esc,
10973     _pk_jump,
10974     _pk_movedown,
10975     _pk_moveleft,
10976     _pk_moveright,
10977     _pk_moveup,
10978     _pk_screenshot,
10979     _pk_special,
10980     _pk_start,
10981     _pk_the_end,
10982 };
10983 
mapstrings_playerkeys(ScriptVariant ** varlist,int paramCount)10984 int mapstrings_playerkeys(ScriptVariant **varlist, int paramCount)
10985 {
10986     char *propname = NULL;
10987     int i, prop;
10988 
10989     static const char *proplist[] = // for args 2+
10990     {
10991         "anybutton",
10992         "attack",
10993         "attack2",
10994         "attack3",
10995         "attack4",
10996         "esc",
10997         "jump",
10998         "movedown",
10999         "moveleft",
11000         "moveright",
11001         "moveup",
11002         "screenshot",
11003         "special",
11004         "start",
11005     };
11006 
11007     for(i = 2; i < paramCount; i++)
11008     {
11009         MAPSTRINGS(varlist[i], proplist, _pk_the_end,
11010                    "Button name '%s' is not supported by playerkeys.");
11011     }
11012 
11013     return 1;
11014 }
11015 
11016 //playerkeys(playerindex, newkey?, key1, key2, ...);
openbor_playerkeys(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11017 HRESULT openbor_playerkeys(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11018 {
11019     LONG ltemp;
11020     int index, newkey;
11021     int i;
11022     u64 keys;
11023     ScriptVariant *arg = NULL;
11024 
11025     if(paramCount < 3)
11026     {
11027         *pretvar = NULL;
11028         return E_FAIL;
11029     }
11030 
11031     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11032     (*pretvar)->lVal = (LONG)1;
11033 
11034     mapstrings_playerkeys(varlist, paramCount);
11035 
11036     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &ltemp)))
11037     {
11038         index = 0;
11039     }
11040     else
11041     {
11042         index = (LONG)ltemp;
11043     }
11044 
11045     if(SUCCEEDED(ScriptVariant_IntegerValue((varlist[1]), &ltemp)))
11046     {
11047         newkey = (LONG)ltemp;
11048     }
11049     else
11050     {
11051         newkey = 0;
11052     }
11053 
11054     if(newkey == 1)
11055     {
11056         keys = player[index].newkeys;
11057     }
11058     else if(newkey == 2)
11059     {
11060         keys = player[index].releasekeys;
11061     }
11062     else
11063     {
11064         keys = player[index].keys;
11065     }
11066 
11067     for(i = 2; i < paramCount; i++)
11068     {
11069         arg = varlist[i];
11070         if(arg->vt == VT_INTEGER)
11071         {
11072             switch(arg->lVal)
11073             {
11074             case _pk_jump:
11075                 (*pretvar)->lVal = (LONG)(keys & FLAG_JUMP);
11076                 break;
11077             case _pk_attack:
11078                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK);
11079                 break;
11080             case _pk_attack2:
11081                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK2);
11082                 break;
11083             case _pk_attack3:
11084                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK3);
11085                 break;
11086             case _pk_attack4:
11087                 (*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK4);
11088                 break;
11089             case _pk_special:
11090                 (*pretvar)->lVal = (LONG)(keys & FLAG_SPECIAL);
11091                 break;
11092             case _pk_esc:
11093                 (*pretvar)->lVal = (LONG)(keys & FLAG_ESC);
11094                 break;
11095             case _pk_start:
11096                 (*pretvar)->lVal = (LONG)(keys & FLAG_START);
11097                 break;
11098             case _pk_moveleft:
11099                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVELEFT);
11100                 break;
11101             case _pk_moveright:
11102                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVERIGHT);
11103                 break;
11104             case _pk_moveup:
11105                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVEUP);
11106                 break;
11107             case _pk_movedown:
11108                 (*pretvar)->lVal = (LONG)(keys & FLAG_MOVEDOWN);
11109                 break;
11110             case _pk_screenshot:
11111                 (*pretvar)->lVal = (LONG)(keys & FLAG_SCREENSHOT);
11112                 break;
11113             case _pk_anybutton:
11114                 (*pretvar)->lVal = (LONG)(keys & FLAG_ANYBUTTON);
11115                 break;
11116             default:
11117                 (*pretvar)->lVal = (LONG)0;
11118             }
11119         }
11120         else
11121         {
11122             (*pretvar)->lVal = (LONG)0;
11123         }
11124         if(!((*pretvar)->lVal))
11125         {
11126             break;
11127         }
11128     }
11129 
11130     return S_OK;
11131 }
11132 
11133 //playmusic(name, loop)
openbor_playmusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11134 HRESULT openbor_playmusic(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11135 {
11136     int loop = 0;
11137     LONG offset = 0;
11138     char *thename = NULL;
11139 
11140     *pretvar = NULL;
11141     if(paramCount < 1)
11142     {
11143         sound_close_music();
11144         return S_OK;
11145     }
11146     if(varlist[0]->vt != VT_STR)
11147     {
11148         //printf("");
11149         return E_FAIL;
11150     }
11151     thename = StrCache_Get(varlist[0]->strVal);
11152 
11153     if(paramCount > 1)
11154     {
11155         loop = (int)ScriptVariant_IsTrue(varlist[1]);
11156     }
11157 
11158     if(paramCount > 2)
11159     {
11160         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &offset)))
11161         {
11162             return E_FAIL;
11163         }
11164     }
11165 
11166 
11167     music(thename, loop, offset);
11168     return S_OK;
11169 }
11170 
11171 //fademusic(fade, name, loop, offset)
openbor_fademusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11172 HRESULT openbor_fademusic(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11173 {
11174     DOUBLE value = 0;
11175     LONG values[2] = {0, 0};
11176     *pretvar = NULL;
11177     if(paramCount < 1)
11178     {
11179         goto fademusic_error;
11180     }
11181     if(FAILED(ScriptVariant_DecimalValue(varlist[0], &value)))
11182     {
11183         goto fademusic_error;
11184     }
11185     musicfade[0] = value;
11186     musicfade[1] = (float)savedata.musicvol;
11187 
11188     if(paramCount == 4)
11189     {
11190         strncpy(musicname, StrCache_Get(varlist[1]->strVal), MAX_STR_LEN - 1);
11191         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &values[0])))
11192         {
11193             goto fademusic_error;
11194         }
11195         if(FAILED(ScriptVariant_IntegerValue(varlist[3], &values[1])))
11196         {
11197             goto fademusic_error;
11198         }
11199         musicloop = values[0];
11200         musicoffset = values[1];
11201     }
11202     return S_OK;
11203 
11204 fademusic_error:
11205     printf("Function requires 1 value, with an optional 3 for music triggering: fademusic_error(float fade, char name, int loop, unsigned long offset)\n");
11206     return E_FAIL;
11207 }
11208 
11209 //setmusicvolume(left, right)
openbor_setmusicvolume(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11210 HRESULT openbor_setmusicvolume(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11211 {
11212     LONG channels[2];
11213 
11214     if(paramCount < 1)
11215     {
11216         return S_OK;
11217     }
11218 
11219     if(FAILED(ScriptVariant_IntegerValue(varlist[0], channels)))
11220     {
11221         goto setmusicvolume_error;
11222     }
11223 
11224     if(paramCount > 1)
11225     {
11226         if(FAILED(ScriptVariant_IntegerValue(varlist[1], channels + 1)))
11227         {
11228             goto setmusicvolume_error;
11229         }
11230     }
11231     else
11232     {
11233         channels[1] = channels[0];
11234     }
11235 
11236     sound_volume_music((int)channels[0], (int)channels[1]);
11237     return S_OK;
11238 
11239 setmusicvolume_error:
11240     printf("values must be integers: setmusicvolume(int left, (optional)int right)\n");
11241     return E_FAIL;
11242 }
11243 
11244 //setmusicvolume(left, right)
openbor_setmusictempo(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11245 HRESULT openbor_setmusictempo(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11246 {
11247     LONG new_tempo;
11248 
11249     if(paramCount < 1)
11250     {
11251         return S_OK;
11252     }
11253 
11254     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &new_tempo)))
11255     {
11256         return E_FAIL;
11257     }
11258 
11259     sound_music_tempo(new_tempo);
11260     return S_OK;
11261 }
11262 
11263 //pausemusic(togglr)
openbor_pausemusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11264 HRESULT openbor_pausemusic(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11265 {
11266     int pause = 0;
11267     if(paramCount < 1)
11268     {
11269         return S_OK;
11270     }
11271 
11272     pause = (int)ScriptVariant_IsTrue(varlist[0]);
11273 
11274     sound_pause_music(pause);
11275     return S_OK;
11276 }
11277 
11278 //pausesamples(toggle)
openbor_pausesamples(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11279 HRESULT openbor_pausesamples(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11280 {
11281     int pause = 0;
11282     if(paramCount < 1)
11283     {
11284         return S_OK;
11285     }
11286 
11287     pause = (int)ScriptVariant_IsTrue(varlist[0]);
11288 
11289     sound_pause_sample(pause);
11290     return S_OK;
11291 }
11292 
11293 //pausesample(toggle,channel)
openbor_pausesample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11294 HRESULT openbor_pausesample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11295 {
11296     int pause = 0;
11297     LONG channel = 0;
11298     if(paramCount < 2)
11299     {
11300         return S_OK;
11301     }
11302 
11303     pause = (int)ScriptVariant_IsTrue(varlist[0]);
11304     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &channel)))
11305     {
11306         return S_OK;
11307     }
11308 
11309     sound_pause_single_sample(pause,channel);
11310     return S_OK;
11311 }
11312 
openbor_querychannel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11313 HRESULT openbor_querychannel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11314 {
11315     LONG ltemp;
11316     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
11317     {
11318         goto query_error;
11319     }
11320     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11321     (*pretvar)->lVal = sound_query_channel((LONG)ltemp);
11322 
11323 	return S_OK;
11324 
11325     query_error:
11326     *pretvar = NULL;
11327     return E_FAIL;
11328 }
11329 
openbor_stopchannel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11330 HRESULT openbor_stopchannel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11331 {
11332     LONG ltemp;
11333     *pretvar = NULL;
11334     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
11335     {
11336         goto sc_error;
11337     }
11338     sound_stop_sample((LONG)ltemp);
11339 
11340 	return S_OK;
11341 
11342     sc_error:
11343     return E_FAIL;
11344 }
11345 
11346 //isactivesample(channel): returns 1 is sample is active, returns 0 otherwise
openbor_isactivesample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11347 HRESULT openbor_isactivesample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11348 {
11349     LONG ltemp;
11350     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
11351     {
11352         goto error;
11353     }
11354     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11355     (*pretvar)->lVal = sound_is_active((LONG)ltemp);
11356 
11357 	return S_OK;
11358 
11359     error:
11360     *pretvar = NULL;
11361     return E_FAIL;
11362 }
11363 
11364 //sampleid(channel): returns sample id in channel if sample is active, it returns -1 otherwise
openbor_sampleid(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11365 HRESULT openbor_sampleid(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11366 {
11367     LONG ltemp;
11368     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
11369     {
11370         goto error;
11371     }
11372     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11373     (*pretvar)->lVal = sound_id((LONG)ltemp);
11374 
11375 	return S_OK;
11376 
11377     error:
11378     *pretvar = NULL;
11379     return E_FAIL;
11380 }
11381 
11382 //playsample(id, priority, lvolume, rvolume, speed, loop)
openbor_playsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11383 HRESULT openbor_playsample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11384 {
11385     int i, result;
11386     LONG value[6] = { -1, 0, savedata.effectvol, savedata.effectvol, 100, 0};
11387 
11388     for(i = 0; i < 6 && i < paramCount; i++)
11389     {
11390         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i)))
11391         {
11392             goto playsample_error;
11393         }
11394     }
11395     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11396     if((int)value[5])
11397     {
11398         result = sound_loop_sample((int)value[0], (unsigned int)value[1], (int)value[2], (int)value[3], (unsigned int)value[4]);
11399     }
11400     else
11401     {
11402         result = sound_play_sample((int)value[0], (unsigned int)value[1], (int)value[2], (int)value[3], (unsigned int)value[4]);
11403     }
11404     (*pretvar)->lVal = (LONG)result;
11405     return S_OK;
11406 
11407 playsample_error:
11408     *pretvar = NULL;
11409     printf("Function requires 6 integer values: playsample(int id, unsigned int priority, int lvolume, int rvolume, unsigned int speed, int loop)\n");
11410     return E_FAIL;
11411 }
11412 
11413 // int loadsample(filename, log)
openbor_loadsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11414 HRESULT openbor_loadsample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11415 {
11416     int arg = 0;
11417 
11418     if(paramCount < 1)
11419     {
11420         goto loadsample_error;
11421     }
11422     if(varlist[0]->vt != VT_STR)
11423     {
11424         goto loadsample_error;
11425     }
11426 
11427     if(paramCount > 1)
11428     {
11429         if(varlist[1]->vt == VT_INTEGER)
11430         {
11431             arg = varlist[1]->lVal;
11432         }
11433         else
11434         {
11435             goto loadsample_error;
11436         }
11437     }
11438 
11439     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11440     (*pretvar)->lVal = (LONG)sound_load_sample(StrCache_Get(varlist[0]->strVal), packfile, arg);
11441     return S_OK;
11442 
11443 loadsample_error:
11444     printf("Function requires 1 string value and optional log value: loadsample(string {filename} integer {log})\n");
11445     *pretvar = NULL;
11446     return E_FAIL;
11447 }
11448 
11449 // void unloadsample(id)
openbor_unloadsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11450 HRESULT openbor_unloadsample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11451 {
11452     LONG id;
11453     *pretvar = NULL;
11454     if(paramCount != 1 )
11455     {
11456         goto unloadsample_error;
11457     }
11458 
11459     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &id)))
11460     {
11461         goto unloadsample_error;
11462     }
11463 
11464     sound_unload_sample((int)id);
11465     return S_OK;
11466 
11467 unloadsample_error:
11468     printf("Function requires 1 integer value: unloadsample(int id)\n");
11469     return E_FAIL;
11470 }
11471 
11472 //fadeout(type, speed);
openbor_fadeout(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11473 HRESULT openbor_fadeout(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11474 {
11475     LONG type;
11476     LONG speed;
11477     *pretvar = NULL;
11478     if(paramCount < 1 )
11479     {
11480         goto fade_out_error;
11481     }
11482 
11483     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &type)))
11484     {
11485         goto fade_out_error;
11486     }
11487     if(FAILED(ScriptVariant_IntegerValue((varlist[1]), &speed)))
11488 
11489     {
11490         fade_out((int)type, (int)speed);
11491     }
11492     return S_OK;
11493 
11494 fade_out_error:
11495     printf("Function requires 2 integer values: fade_out(int type, int speed)\n");
11496     return E_FAIL;
11497 }
11498 
11499 //changepalette(index);
openbor_changepalette(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11500 HRESULT openbor_changepalette(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11501 {
11502     LONG index;
11503 
11504     *pretvar = NULL;
11505 
11506     if(paramCount < 1)
11507     {
11508         goto changepalette_error;
11509     }
11510 
11511     if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &index)))
11512     {
11513         goto changepalette_error;
11514     }
11515 
11516     change_system_palette((int)index);
11517 
11518     return S_OK;
11519 
11520 changepalette_error:
11521     printf("Function requires 1 integer value: changepalette(int index)\n");
11522     return E_FAIL;
11523 }
11524 
11525 //changelight(x, z);
openbor_changelight(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11526 HRESULT openbor_changelight(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11527 {
11528     LONG x, z;
11529     extern s_axis_plane_vertical_int light;
11530     ScriptVariant *arg = NULL;
11531 
11532     *pretvar = NULL;
11533     if(paramCount < 2)
11534     {
11535         goto changelight_error;
11536     }
11537 
11538     arg = varlist[0];
11539     if(arg->vt != VT_EMPTY)
11540     {
11541         if(FAILED(ScriptVariant_IntegerValue(arg, &x)))
11542         {
11543             goto changelight_error;
11544         }
11545         light.x = (int)x;
11546     }
11547 
11548     arg = varlist[1];
11549     if(arg->vt != VT_EMPTY)
11550     {
11551         if(FAILED(ScriptVariant_IntegerValue(arg, &z)))
11552         {
11553             goto changelight_error;
11554         }
11555         light.y = (int)z;
11556     }
11557 
11558     return S_OK;
11559 changelight_error:
11560     printf("Function requires 2 integer values: changepalette(int x, int z)\n");
11561     return E_FAIL;
11562 }
11563 
11564 //changeshadowcolor(color, alpha);
11565 // color = 0 means no gfxshadow, -1 means don't fill the shadow with colour
11566 // alpha default to 2, <=0 means no alpha effect
openbor_changeshadowcolor(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11567 HRESULT openbor_changeshadowcolor(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11568 {
11569     LONG c, a;
11570     extern int            shadowcolor;
11571     extern int            shadowalpha;
11572 
11573     *pretvar = NULL;
11574     if(paramCount < 1)
11575     {
11576         goto changeshadowcolor_error;
11577     }
11578 
11579     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &c)))
11580     {
11581         goto changeshadowcolor_error;
11582     }
11583 
11584     shadowcolor = (int)c;
11585 
11586     if(paramCount > 1)
11587     {
11588         if(FAILED(ScriptVariant_IntegerValue(varlist[1], &a)))
11589         {
11590             goto changeshadowcolor_error;
11591         }
11592         shadowalpha = (int)a;
11593     }
11594 
11595     return S_OK;
11596 changeshadowcolor_error:
11597     printf("Function requires at least 1 integer value, the 2nd integer parameter is optional: changepalette(int colorindex, int alpha)\n");
11598     return E_FAIL;
11599 }
11600 
11601 // ===== gettextobjproperty(name, value) =====
11602 enum gtop_enum
11603 {
11604     _top_a,
11605     _top_font,
11606     _top_text,
11607     _top_time,
11608     _top_x,
11609     _top_y,
11610     _top_z,
11611     _top_the_end,
11612 };
11613 
mapstrings_textobjproperty(ScriptVariant ** varlist,int paramCount)11614 int mapstrings_textobjproperty(ScriptVariant **varlist, int paramCount)
11615 {
11616     char *propname = NULL;
11617     int prop;
11618 
11619     static const char *proplist[] =
11620     {
11621         "a",
11622         "font",
11623         "text",
11624         "time",
11625         "x",
11626         "y",
11627         "z",
11628     };
11629 
11630     if(paramCount < 2)
11631     {
11632         return 1;
11633     }
11634 
11635     MAPSTRINGS(varlist[1], proplist, _top_the_end,
11636                "'%s' is not a valid textobj property.\n");
11637 
11638     return 1;
11639 }
11640 
openbor_gettextobjproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11641 HRESULT openbor_gettextobjproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11642 {
11643     LONG ind;
11644     int propind;
11645 
11646     if(paramCount < 2)
11647     {
11648         goto gettextobjproperty_error;
11649     }
11650 
11651 
11652     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
11653     {
11654         printf("Function's 1st argument must be a numeric value: gettextproperty(int index, \"property\")\n");
11655         goto gettextobjproperty_error;
11656     }
11657 
11658     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11659     mapstrings_textobjproperty(varlist, paramCount);
11660 
11661     if(ind < 0 || ind >= level->numtextobjs)
11662     {
11663         (*pretvar)->lVal = 0;
11664         return S_OK;
11665     }
11666 
11667     if(varlist[1]->vt != VT_INTEGER)
11668     {
11669         if(varlist[1]->vt != VT_STR)
11670         {
11671             printf("Function gettextobjproperty must have a string property name.\n");
11672         }
11673         goto gettextobjproperty_error;
11674     }
11675 
11676     propind = varlist[1]->lVal;
11677 
11678     switch(propind)
11679     {
11680     case _top_font:
11681     {
11682         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11683         (*pretvar)->lVal = (LONG)level->textobjs[ind].font;
11684         break;
11685     }
11686     case _top_text:
11687     {
11688         ScriptVariant_ChangeType(*pretvar, VT_STR);
11689         (*pretvar)->strVal = StrCache_CreateNewFrom(level->textobjs[ind].text);
11690         break;
11691     }
11692     case _top_time:
11693     {
11694         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11695         (*pretvar)->lVal = (LONG)level->textobjs[ind].time;
11696         break;
11697     }
11698     case _top_x:
11699     {
11700         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11701         (*pretvar)->lVal = (LONG)level->textobjs[ind].position.x;
11702         break;
11703     }
11704     case _top_y:
11705     case _top_a:
11706     {
11707         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11708         (*pretvar)->lVal = (LONG)level->textobjs[ind].position.y;
11709         break;
11710     }
11711     case _top_z:
11712     {
11713         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11714         (*pretvar)->lVal = (LONG)level->textobjs[ind].position.z;
11715         break;
11716     }
11717     default:
11718         //printf("Property name '%s' is not supported by function gettextobjproperty.\n", propname);
11719         goto gettextobjproperty_error;
11720         break;
11721     }
11722 
11723     return S_OK;
11724 
11725 gettextobjproperty_error:
11726     *pretvar = NULL;
11727     return E_FAIL;
11728 }
11729 
openbor_changetextobjproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11730 HRESULT openbor_changetextobjproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11731 {
11732     LONG ind;
11733     int propind;
11734     static char buf[MAX_STR_VAR_LEN];
11735     LONG ltemp;
11736     const char *ctotext = "changetextobjproperty(int index, \"property\", value)";
11737 
11738     *pretvar = NULL;
11739 
11740     if(paramCount < 3)
11741     {
11742         printf("Function needs at last 3 parameters: %s\n", ctotext);
11743         return E_FAIL;
11744     }
11745 
11746     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
11747     {
11748         printf("Function's 1st argument must be a numeric value: %s\n", ctotext);
11749         return E_FAIL;
11750     }
11751 
11752     mapstrings_textobjproperty(varlist, paramCount);
11753 
11754     if(ind < 0)
11755     {
11756         printf("Invalid textobj index, must be >= 0\n");
11757         return E_FAIL;
11758     }
11759     else if (ind >= level->numtextobjs)
11760     {
11761         __reallocto(level->textobjs, level->numtextobjs, ind + 1);
11762         level->numtextobjs = ind + 1;
11763     }
11764 
11765     if(varlist[1]->vt != VT_INTEGER)
11766     {
11767         printf("Invalid property type for changetextobjproperty.\n");
11768         return E_FAIL;
11769     }
11770 
11771     propind = varlist[1]->lVal;
11772 
11773     switch(propind)
11774     {
11775     case _top_font:
11776     {
11777         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
11778         {
11779             level->textobjs[ind].font = (LONG)ltemp;
11780         }
11781         else
11782         {
11783             goto changetextobjproperty_error;
11784         }
11785         break;
11786     }
11787     case _top_text:
11788     {
11789         ScriptVariant_ToString(varlist[2], buf);
11790         level->textobjs[ind].text = malloc(MAX_STR_VAR_LEN);
11791         strncpy(level->textobjs[ind].text, buf, MAX_STR_VAR_LEN);
11792         break;
11793     }
11794     case _top_time:
11795     {
11796         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
11797         {
11798             level->textobjs[ind].time = (LONG)ltemp;
11799         }
11800         else
11801         {
11802             goto changetextobjproperty_error;
11803         }
11804         break;
11805     }
11806     case _top_x:
11807     {
11808         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
11809         {
11810             level->textobjs[ind].position.x = (LONG)ltemp;
11811         }
11812         else
11813         {
11814             goto changetextobjproperty_error;
11815         }
11816         break;
11817     }
11818     case _top_a:
11819     case _top_y:
11820     {
11821         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
11822         {
11823             level->textobjs[ind].position.y = (LONG)ltemp;
11824         }
11825         else
11826         {
11827             goto changetextobjproperty_error;
11828         }
11829         break;
11830     }
11831     case _top_z:
11832     {
11833         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
11834         {
11835             level->textobjs[ind].position.z = (LONG)ltemp;
11836         }
11837         else
11838         {
11839             goto changetextobjproperty_error;
11840         }
11841         break;
11842     }
11843     default:
11844         //printf("Property name '%s' is not supported by function changetextobjproperty.\n", propname);
11845         return E_FAIL;
11846         break;
11847     }
11848 
11849     return S_OK;
11850 
11851 changetextobjproperty_error:
11852     ScriptVariant_ToString(varlist[2], buf);
11853     printf("Invalid textobj value: %s\n", buf);
11854     return E_FAIL;
11855 }
11856 
11857 // settextobj(int index, int x, int y, int font, int z, char text, int time {optional})
openbor_settextobj(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11858 HRESULT openbor_settextobj(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11859 {
11860     LONG ind;
11861     LONG X, Y, Z, F, T = 0;
11862     static char buf[MAX_STR_VAR_LEN];
11863     const char *stotext = "settextobj(int index, int x, int y, int font, int z, char text, int time {optional})";
11864 
11865     *pretvar = NULL;
11866 
11867 
11868     if(paramCount < 6)
11869     {
11870         printf("Function needs at least 6 parameters: %s\n", stotext);
11871         return E_FAIL;
11872     }
11873 
11874     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
11875     {
11876         printf("Function's 1st argument must be a numeric value: %s\n", stotext);
11877         return E_FAIL;
11878     }
11879 
11880     if(ind < 0)
11881     {
11882         printf("Invalid textobj index, must be >= 0\n");
11883         return E_FAIL;
11884     }
11885     else if(ind >= level->numtextobjs)
11886     {
11887         __reallocto(level->textobjs, level->numtextobjs, ind + 1);
11888         level->numtextobjs = ind + 1;
11889     }
11890 
11891     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &X)))
11892     {
11893         goto settextobj_error;
11894     }
11895     if(FAILED(ScriptVariant_IntegerValue(varlist[2], &Y)))
11896     {
11897         goto settextobj_error;
11898     }
11899     if(FAILED(ScriptVariant_IntegerValue(varlist[3], &F)))
11900     {
11901         goto settextobj_error;
11902     }
11903     if(FAILED(ScriptVariant_IntegerValue(varlist[4], &Z)))
11904     {
11905         goto settextobj_error;
11906     }
11907     ScriptVariant_ToString(varlist[5], buf);
11908     if(paramCount >= 7 && FAILED(ScriptVariant_IntegerValue(varlist[6], &T)))
11909     {
11910         goto settextobj_error;
11911     }
11912 
11913     level->textobjs[ind].time = (int)T;
11914     level->textobjs[ind].position.x = (int)X;
11915     level->textobjs[ind].position.y = (int)Y;
11916     level->textobjs[ind].position.z = (int)Z;
11917     level->textobjs[ind].font = (int)F;
11918 
11919     if(!level->textobjs[ind].text)
11920     {
11921         level->textobjs[ind].text = (char *)malloc(MAX_STR_VAR_LEN);
11922     }
11923     strncpy(level->textobjs[ind].text, buf, MAX_STR_VAR_LEN);
11924 
11925     return S_OK;
11926 
11927 settextobj_error:
11928     printf("Invalid value(s) for settextobj: %s\n", stotext);
11929     return E_FAIL;
11930 }
11931 
openbor_cleartextobj(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11932 HRESULT openbor_cleartextobj(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
11933 {
11934     LONG ind;
11935     const char *cltotext = "cleartextobj(int index)";
11936 
11937     *pretvar = NULL;
11938 
11939     if(paramCount < 1)
11940     {
11941         printf("Function needs at least 1 parameter: %s\n", cltotext);
11942         return E_FAIL;
11943     }
11944 
11945     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
11946     {
11947         printf("Function's 1st argument must be a numeric value: %s\n", cltotext);
11948         return E_FAIL;
11949     }
11950 
11951     if(ind < 0 || ind >= level->numtextobjs)
11952     {
11953         return S_OK;
11954     }
11955 
11956     level->textobjs[ind].time = 0;
11957     level->textobjs[ind].position.x = 0;
11958     level->textobjs[ind].position.y = 0;
11959     level->textobjs[ind].font = 0;
11960     level->textobjs[ind].position.z = 0;
11961     if(level->textobjs[ind].text)
11962     {
11963         free(level->textobjs[ind].text);
11964     }
11965     level->textobjs[ind].text = NULL;
11966     return S_OK;
11967 }
11968 
11969 // ===== get layer type ======
11970 enum getlt_enum
11971 {
11972     _glt_background,
11973     _glt_bglayer,
11974     _glt_fglayer,
11975     _glt_frontpanel,
11976     _glt_generic,
11977     _glt_neon,
11978     _glt_panel,
11979     _glt_screen,
11980     _glt_water,
11981     _glt_the_end,
11982 };
11983 
11984 
11985 // ===== getbglayerproperty ======
11986 enum getbglp_enum
11987 {
11988     _glp_alpha,
11989     _glp_amplitude,
11990     _glp_bgspeedratio,
11991     _glp_enabled,
11992     _glp_neon,
11993     _glp_quake,
11994     _glp_transparency,
11995     _glp_watermode,
11996     _glp_wavelength,
11997     _glp_wavespeed,
11998     _glp_xoffset,
11999     _glp_xratio,
12000     _glp_xrepeat,
12001     _glp_xspacing,
12002     _glp_z,
12003     _glp_zoffset,
12004     _glp_zratio,
12005     _glp_zrepeat,
12006     _glp_zspacing,
12007     _glp_the_end,
12008 };
12009 
mapstrings_layerproperty(ScriptVariant ** varlist,int paramCount)12010 int mapstrings_layerproperty(ScriptVariant **varlist, int paramCount)
12011 {
12012     char *propname = NULL;
12013     int prop;
12014 
12015     static const char *proplist[] =
12016     {
12017         "alpha",
12018         "amplitude",
12019         "bgspeedratio",
12020         "enabled",
12021         "neon",
12022         "quake",
12023         "transparency",
12024         "watermode",
12025         "wavelength",
12026         "wavespeed",
12027         "xoffset",
12028         "xratio",
12029         "xrepeat",
12030         "xspacing",
12031         "z",
12032         "zoffset",
12033         "zratio",
12034         "zrepeat",
12035         "zspacing",
12036     };
12037 
12038     static const char *typelist[] =
12039     {
12040         "background",
12041         "bglayer",
12042         "fglayer",
12043         "frontpanel",
12044         "generic",
12045         "neon",
12046         "panel",
12047         "water",
12048     };
12049 
12050     if(paramCount < 3)
12051     {
12052         return 1;
12053     }
12054     MAPSTRINGS(varlist[0], typelist, _glt_the_end,
12055                "Type name '%s' is not supported by function getlayerproperty.\n");
12056     MAPSTRINGS(varlist[2], proplist, _glp_the_end,
12057                "Property name '%s' is not supported by function getlayerproperty.\n");
12058 
12059     return 1;
12060 }
12061 
_getlayerproperty(s_layer * layer,int propind,ScriptVariant ** pretvar)12062 HRESULT _getlayerproperty(s_layer *layer, int propind, ScriptVariant **pretvar)
12063 {
12064 
12065     switch(propind)
12066     {
12067     case _glp_alpha:
12068     {
12069         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12070         (*pretvar)->lVal = (LONG)layer->drawmethod.alpha;
12071         break;
12072     }
12073     case _glp_amplitude:
12074     {
12075         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12076         (*pretvar)->lVal = (LONG)layer->drawmethod.water.amplitude;
12077         break;
12078     }
12079     case _glp_bgspeedratio:
12080     {
12081         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
12082         (*pretvar)->dblVal = (DOUBLE)layer->bgspeedratio;
12083         break;
12084     }
12085     case _glp_enabled:
12086     {
12087         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12088         (*pretvar)->lVal = (LONG)layer->enabled;
12089         break;
12090     }
12091     case _glp_neon:
12092     {
12093         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12094         (*pretvar)->lVal = (LONG)layer->neon;
12095         break;
12096     }
12097     case _glp_quake:
12098     {
12099         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12100         (*pretvar)->lVal = (LONG)layer->quake;
12101         break;
12102     }
12103     case _glp_transparency:
12104     {
12105         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12106         (*pretvar)->lVal = (LONG)layer->drawmethod.transbg;
12107         break;
12108     }
12109     case _glp_watermode:
12110     {
12111         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12112         (*pretvar)->lVal = (LONG)layer->drawmethod.water.watermode;
12113         break;
12114     }
12115 
12116     case _glp_wavelength:
12117     {
12118         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12119         (*pretvar)->lVal = (LONG)layer->drawmethod.water.wavelength;
12120         break;
12121     }
12122     case _glp_wavespeed:
12123     {
12124         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
12125         (*pretvar)->dblVal = (DOUBLE)layer->drawmethod.water.wavespeed;
12126         break;
12127     }
12128     case _glp_xoffset:
12129     {
12130         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12131         (*pretvar)->lVal = (LONG)layer->offset.x;
12132         break;
12133     }
12134     case _glp_xratio:
12135     {
12136         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
12137         (*pretvar)->dblVal = (DOUBLE)layer->ratio.x;
12138         break;
12139     }
12140     case _glp_xrepeat:
12141     {
12142         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12143         (*pretvar)->lVal = (LONG)layer->drawmethod.xrepeat;
12144         break;
12145     }
12146     case _glp_xspacing:
12147     {
12148         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12149         (*pretvar)->lVal = (LONG)layer->spacing.x;
12150         break;
12151     }
12152     case _glp_z:
12153     {
12154         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12155         (*pretvar)->lVal = (LONG)layer->z;
12156         break;
12157     }
12158     case _glp_zoffset:
12159     {
12160         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12161         (*pretvar)->lVal = (LONG)layer->offset.z;
12162         break;
12163     }
12164     case _glp_zratio:
12165     {
12166         ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
12167         (*pretvar)->dblVal = (DOUBLE)layer->ratio.z;
12168         break;
12169     }
12170     case _glp_zrepeat:
12171     {
12172         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12173         (*pretvar)->lVal = (LONG)layer->drawmethod.yrepeat;
12174         break;
12175     }
12176     case _glp_zspacing:
12177     {
12178         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12179         (*pretvar)->lVal = (LONG)layer->spacing.z;
12180         break;
12181     }
12182     default:
12183         *pretvar = NULL;
12184         return E_FAIL;
12185     }
12186     return S_OK;
12187 }
12188 
_changelayerproperty(s_layer * layer,int propind,ScriptVariant * var)12189 HRESULT _changelayerproperty(s_layer *layer, int propind, ScriptVariant *var)
12190 {
12191     LONG temp;
12192     DOUBLE temp2;
12193     switch(propind)
12194     {
12195     case _glp_alpha:
12196     {
12197         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12198         {
12199             return E_FAIL;
12200         }
12201         layer->drawmethod.alpha = temp;
12202         break;
12203     }
12204     case _glp_amplitude:
12205     {
12206         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12207         {
12208             return E_FAIL;
12209         }
12210         layer->drawmethod.water.amplitude = temp;
12211         break;
12212     }
12213     case _glp_bgspeedratio:
12214     {
12215         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
12216         {
12217             return E_FAIL;
12218         }
12219         layer->bgspeedratio = temp2;
12220         break;
12221     }
12222     case _glp_enabled:
12223     {
12224         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12225         {
12226             return E_FAIL;
12227         }
12228         layer->enabled = temp;
12229         break;
12230     }
12231     case _glp_neon:
12232     {
12233         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12234         {
12235             return E_FAIL;
12236         }
12237         layer->neon = temp;
12238         break;
12239     }
12240     case _glp_quake:
12241     {
12242         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12243         {
12244             return E_FAIL;
12245         }
12246         layer->quake = temp;
12247         break;
12248     }
12249     case _glp_transparency:
12250     {
12251         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12252         {
12253             return E_FAIL;
12254         }
12255         layer->drawmethod.transbg = temp;
12256         break;
12257     }
12258     case _glp_watermode:
12259     {
12260         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12261         {
12262             return E_FAIL;
12263         }
12264         layer->drawmethod.water.watermode = temp;
12265         break;
12266     }
12267 
12268     case _glp_wavelength:
12269     {
12270         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
12271         {
12272             return E_FAIL;
12273         }
12274         layer->drawmethod.water.wavelength = temp2;
12275         break;
12276     }
12277     case _glp_wavespeed:
12278     {
12279         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
12280         {
12281             return E_FAIL;
12282         }
12283         layer->drawmethod.water.wavespeed = temp2;
12284         break;
12285     }
12286     case _glp_xoffset:
12287     {
12288         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12289         {
12290             return E_FAIL;
12291         }
12292         layer->offset.x = temp;
12293         break;
12294     }
12295     case _glp_xratio:
12296     {
12297         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
12298         {
12299             return E_FAIL;
12300         }
12301         layer->ratio.x = temp2;
12302         break;
12303     }
12304     case _glp_xrepeat:
12305     {
12306         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12307         {
12308             return E_FAIL;
12309         }
12310         layer->drawmethod.xrepeat = temp;
12311         break;
12312     }
12313     case _glp_xspacing:
12314     {
12315         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12316         {
12317             return E_FAIL;
12318         }
12319         layer->spacing.x = temp;
12320         break;
12321     }
12322     case _glp_z:
12323     {
12324         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12325         {
12326             return E_FAIL;
12327         }
12328         layer->z = temp;
12329         break;
12330     }
12331     case _glp_zoffset:
12332     {
12333         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12334         {
12335             return E_FAIL;
12336         }
12337         layer->offset.z = temp;
12338         break;
12339     }
12340     case _glp_zratio:
12341     {
12342         if(FAILED(ScriptVariant_DecimalValue(var, &temp2)))
12343         {
12344             return E_FAIL;
12345         }
12346         layer->ratio.z = temp2;
12347         break;
12348     }
12349     case _glp_zrepeat:
12350     {
12351         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12352         {
12353             return E_FAIL;
12354         }
12355         layer->drawmethod.yrepeat = temp;
12356         break;
12357     }
12358     case _glp_zspacing:
12359     {
12360         if(FAILED(ScriptVariant_IntegerValue(var, &temp)))
12361         {
12362             return E_FAIL;
12363         }
12364         layer->spacing.z = temp;
12365         break;
12366     }
12367     default:
12368         return E_FAIL;
12369     }
12370     return S_OK;
12371 }
12372 
_getlayer(int type,int ind)12373 s_layer *_getlayer(int type, int ind)
12374 {
12375     switch(type)
12376     {
12377     case _glt_background:
12378         return level->background;
12379     case _glt_bglayer:
12380         if(ind < 0 || ind >= level->numbglayers)
12381         {
12382             return NULL;
12383         }
12384         return level->bglayers[ind];
12385     case _glt_fglayer:
12386         if(ind < 0 || ind >= level->numfglayers)
12387         {
12388             return NULL;
12389         }
12390         return level->fglayers[ind];
12391     case _glt_frontpanel:
12392         if(ind < 0 || ind >= level->numfrontpanels)
12393         {
12394             return NULL;
12395         }
12396         return level->frontpanels[ind];
12397     case _glt_generic:
12398         if(ind < 0 || ind >= level->numgenericlayers)
12399         {
12400             return NULL;
12401         }
12402         return level->genericlayers[ind];
12403     case _glt_neon:
12404         if(ind < 0 || ind >= level->numpanels)
12405         {
12406             return NULL;
12407         }
12408         return level->panels[ind][1];
12409     case _glt_panel:
12410         if(ind < 0 || ind >= level->numpanels)
12411         {
12412             return NULL;
12413         }
12414         return level->panels[ind][0];
12415     case _glt_screen:
12416         if(ind < 0 || ind >= level->numpanels)
12417         {
12418             return NULL;
12419         }
12420         return level->panels[ind][2];
12421     case _glt_water:
12422         if(ind < 0 || ind >= level->numwaters)
12423         {
12424             return NULL;
12425         }
12426         return level->waters[ind];
12427     default:
12428         return NULL;
12429     }
12430 }
12431 
12432 // getlayerproperty(type, index, propertyname);
openbor_getlayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12433 HRESULT openbor_getlayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12434 {
12435     LONG ind;
12436     int propind, type;
12437     s_layer *layer = NULL;
12438 
12439     if(paramCount < 3)
12440     {
12441         goto getlayerproperty_error;
12442     }
12443 
12444     mapstrings_layerproperty(varlist, paramCount);
12445 
12446     type = varlist[0]->lVal;
12447     propind = varlist[2]->lVal;
12448 
12449     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
12450     {
12451         goto getlayerproperty_error2;
12452     }
12453 
12454     layer = _getlayer(type, (int)ind);
12455 
12456     if(layer == NULL)
12457     {
12458         goto getlayerproperty_error2;
12459     }
12460 
12461     if(FAILED(_getlayerproperty(layer, propind, pretvar)))
12462     {
12463         goto getlayerproperty_error3;
12464     }
12465 
12466     return S_OK;
12467 
12468 getlayerproperty_error:
12469     *pretvar = NULL;
12470     printf("Function getlayerproperty must have 3 parameters: layertype, index and propertyname\n");
12471     return E_FAIL;
12472 getlayerproperty_error2:
12473     *pretvar = NULL;
12474     printf("Layer not found!\n");
12475     return E_FAIL;
12476 getlayerproperty_error3:
12477     *pretvar = NULL;
12478     printf("Bad property name or value.\n");
12479     return E_FAIL;
12480 }
12481 
12482 // changelayerproperty(type, index, propertyname);
openbor_changelayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12483 HRESULT openbor_changelayerproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12484 {
12485     LONG ind;
12486     int propind, type;
12487     s_layer *layer = NULL;
12488     *pretvar = NULL;
12489 
12490     if(paramCount < 4)
12491     {
12492         goto chglayerproperty_error;
12493     }
12494 
12495     mapstrings_layerproperty(varlist, paramCount);
12496 
12497     type = varlist[0]->lVal;
12498     propind = varlist[2]->lVal;
12499 
12500     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
12501     {
12502         goto chglayerproperty_error2;
12503     }
12504 
12505     layer = _getlayer(type, (int)ind);
12506 
12507     if(layer == NULL)
12508     {
12509         goto chglayerproperty_error2;
12510     }
12511 
12512     if(FAILED(_changelayerproperty(layer, propind, varlist[3])))
12513     {
12514         goto chglayerproperty_error3;
12515     }
12516 
12517     return S_OK;
12518 
12519 chglayerproperty_error:
12520     printf("Function changelayerproperty must have 4 parameters: layertype, index, propertyname and value\n");
12521     return E_FAIL;
12522 chglayerproperty_error2:
12523     printf("Layer not found!\n");
12524     return E_FAIL;
12525 chglayerproperty_error3:
12526     printf("Layer property not understood or bad value.\n");
12527     return E_FAIL;
12528 }
12529 
12530 //shutdown(status, message)
openbor_shutdown(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12531 HRESULT openbor_shutdown(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12532 {
12533     LONG ltemp = 0;
12534 
12535     *pretvar = NULL;
12536 
12537     if(paramCount > 0 && FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)))
12538     {
12539         goto shutdown_error;
12540     }
12541     if(paramCount > 1 && varlist[1]->vt != VT_STR)
12542     {
12543         goto shutdown_error;
12544     }
12545 
12546     borShutdown((LONG)ltemp,  paramCount > 1 ? StrCache_Get(varlist[1]->strVal) : (DEFAULT_SHUTDOWN_MESSAGE));
12547 
12548     return S_OK;
12549 shutdown_error:
12550     printf("shutdown(status, message): both parameters are optional but must be valid.\n");
12551     return E_FAIL;
12552 }
12553 
12554 //jumptobranch(name, immediate)
openbor_jumptobranch(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12555 HRESULT openbor_jumptobranch(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12556 {
12557     LONG ltemp;
12558     extern char branch_name[MAX_NAME_LEN + 1];
12559     *pretvar = NULL;
12560     if(paramCount < 1)
12561     {
12562         goto jumptobranch_error;
12563     }
12564     if(varlist[0]->vt != VT_STR)
12565     {
12566         goto jumptobranch_error;
12567     }
12568 
12569     strncpy(branch_name, StrCache_Get(varlist[0]->strVal), MIN(MAX_NAME_LEN, MAX_STR_VAR_LEN)); // copy the string value to branch name
12570 
12571     if(paramCount >= 2)
12572     {
12573         if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
12574         {
12575             endgame = (LONG)ltemp;
12576             // 1 means goto that level immediately, or, wait until the level is complete
12577         }
12578         else
12579         {
12580             goto jumptobranch_error;
12581         }
12582     }
12583 
12584     return S_OK;
12585 jumptobranch_error:
12586     printf("Function requires 1 string value, the second argument is optional(int): jumptobranch(name, immediate)\n");
12587     return E_FAIL;
12588 }
12589 
12590 //bindentity(entity, target, x, z, a, direction, binding.matching);
12591 //bindentity(entity, NULL()); // unbind
openbor_bindentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12592 HRESULT openbor_bindentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12593 {
12594     entity *ent = NULL;
12595     entity *other = NULL;
12596     ScriptVariant *arg = NULL;
12597     void adjust_bind(entity * e);
12598     LONG x = 0, z = 0, a = 0, dir = 0, anim = 0, sortid = -1;
12599 
12600     *pretvar = NULL;
12601     if(paramCount < 2)
12602     {
12603         return E_FAIL;
12604     }
12605 
12606     ent = (entity *)(varlist[0])->ptrVal; //retrieve the entity
12607     if(!ent)
12608     {
12609         return S_OK;
12610     }
12611 
12612     other = (entity *)(varlist[1])->ptrVal;
12613     if(!other)
12614     {
12615         ent->binding.ent = NULL;
12616         ent->binding.positioning.x = 0;
12617         ent->binding.positioning.z = 0;
12618         ent->binding.positioning.y = 0;
12619         return S_OK;
12620     }
12621 
12622     ent->binding.ent = other;
12623     ent->binding.sortid = sortid;
12624 
12625     if(paramCount < 3)
12626     {
12627         goto BIND;
12628     }
12629     // x
12630     arg = varlist[2];
12631     if(arg->vt != VT_EMPTY)
12632     {
12633         if(FAILED(ScriptVariant_IntegerValue(arg, &x)))
12634         {
12635             return E_FAIL;
12636         }
12637 
12638         ent->binding.offset.x = (int)x;
12639         ent->binding.positioning.x = 1;
12640     } else ent->binding.positioning.x = 0;
12641     if(paramCount < 4)
12642     {
12643         goto BIND;
12644     }
12645     // z
12646     arg = varlist[3];
12647     if(arg->vt != VT_EMPTY)
12648     {
12649         if(FAILED(ScriptVariant_IntegerValue(arg, &z)))
12650         {
12651             return E_FAIL;
12652         }
12653         ent->binding.offset.z = (int)z;
12654         ent->binding.positioning.z = 1;
12655     } else ent->binding.positioning.z = 0;
12656     if(paramCount < 5)
12657     {
12658         goto BIND;
12659     }
12660     // a
12661     arg = varlist[4];
12662     if(arg->vt != VT_EMPTY)
12663     {
12664         if(FAILED(ScriptVariant_IntegerValue(arg, &a)))
12665         {
12666             return E_FAIL;
12667         }
12668         ent->binding.offset.y = (int)a;
12669         ent->binding.positioning.y = 1;
12670     } else ent->binding.positioning.y = 0;
12671     if(paramCount < 6)
12672     {
12673         goto BIND;
12674     }
12675     // direction
12676     arg = varlist[5];
12677     if(arg->vt != VT_EMPTY)
12678     {
12679         if(FAILED(ScriptVariant_IntegerValue(arg, &dir)))
12680         {
12681             return E_FAIL;
12682         }
12683         ent->binding.direction = (int)dir;
12684     }
12685     if(paramCount < 7)
12686     {
12687         goto BIND;
12688     }
12689     // animation
12690     arg = varlist[6];
12691     if(arg->vt != VT_EMPTY)
12692     {
12693         if(FAILED(ScriptVariant_IntegerValue(arg, &anim)))
12694         {
12695             return E_FAIL;
12696         }
12697         ent->binding.match = (int)anim;
12698     }
12699     if(paramCount < 8)
12700     {
12701         goto BIND;
12702     }
12703     // sortid
12704     arg = varlist[7];
12705     if(arg->vt != VT_EMPTY)
12706     {
12707         if(FAILED(ScriptVariant_IntegerValue(arg, &sortid)))
12708         {
12709             return E_FAIL;
12710         }
12711         ent->binding.sortid = (int)sortid;
12712     }
12713 
12714 BIND:
12715     adjust_bind(ent);
12716 
12717     return S_OK;
12718 }
12719 
12720 //array(size);
openbor_array(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12721 HRESULT openbor_array(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12722 {
12723     LONG size;
12724     Varlist *array;
12725 
12726     if(paramCount < 1 || FAILED(ScriptVariant_IntegerValue(varlist[0], &size)) || size < 0)
12727     {
12728         printf("Function requires 1 positive int value: array(int size)\n");
12729         goto array_error;
12730     }
12731 
12732     ScriptVariant_ChangeType(*pretvar, VT_PTR);
12733     array = malloc(sizeof(*array));
12734     (*pretvar)->ptrVal = (VOID *)array;
12735 
12736     if((*pretvar)->ptrVal == NULL)
12737     {
12738         printf("Not enough memory: array(%d)\n", (int)size);
12739         goto array_error;
12740     }
12741 
12742     Varlist_Init(array, size);
12743 
12744     List_InsertAfter(&scriptheap, (void *)(array), "openbor_array");
12745     return S_OK;
12746 
12747 array_error:
12748     (*pretvar) = NULL;
12749     return E_FAIL;
12750 }
12751 
12752 //size(array)
openbor_size(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12753 HRESULT openbor_size(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12754 {
12755     Varlist *array;
12756     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12757     {
12758         goto size_error;
12759     }
12760 
12761     // By White Dragon
12762     if( array->list->size != 0 ) //or array->list->first
12763     {
12764         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12765         (*pretvar)->lVal = (LONG)array->list->size;
12766     }
12767     else
12768     {
12769         ScriptVariant_Copy(*pretvar, array->vars);
12770     }
12771 
12772     return S_OK;
12773 size_error:
12774     printf("Function requires 1 array handle: %s(array)\n", "size");
12775     (*pretvar) = NULL;
12776     return E_FAIL;
12777 }
12778 
12779 //get(array, index);
openbor_get(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12780 HRESULT openbor_get(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12781 {
12782     ScriptVariant *ptmpvar;
12783     Varlist *array;
12784     LONG ltemp;
12785 
12786     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12787     {
12788         goto get_error;
12789     }
12790 
12791     if(varlist[1]->vt == VT_STR)
12792     {
12793         ptmpvar = Varlist_GetByName(array, StrCache_Get(varlist[1]->strVal));
12794     }
12795     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
12796     {
12797         ptmpvar = Varlist_GetByIndex(array, (LONG)ltemp);
12798     }
12799     else
12800     {
12801         goto get_error;
12802     }
12803 
12804     if(ptmpvar)
12805     {
12806         ScriptVariant_Copy(*pretvar,  ptmpvar);
12807     }
12808     else
12809     {
12810         ScriptVariant_Clear(*pretvar);
12811     }
12812     return S_OK;
12813 
12814 get_error:
12815     printf("Function requires 1 array handle and 1 int value: get(array, int index)\n");
12816     (*pretvar) = NULL;
12817     return E_FAIL;
12818 }
12819 
12820 //set(array, index, value);
openbor_set(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12821 HRESULT openbor_set(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12822 {
12823     Varlist *array;
12824     LONG ltemp;
12825 
12826     *pretvar = NULL;
12827     if(paramCount < 3 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12828     {
12829         goto set_error;
12830     }
12831 
12832     if(varlist[1]->vt == VT_STR)
12833     {
12834         Varlist_SetByName(array, StrCache_Get(varlist[1]->strVal), varlist[2]);
12835     }
12836     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
12837     {
12838         Varlist_SetByIndex(array, (LONG)ltemp, varlist[2]);
12839     }
12840     else
12841     {
12842         goto set_error;
12843     }
12844 
12845     return S_OK;
12846 
12847 set_error:
12848     printf("Function requires 1 array handle, 1 int value and 1 value: set(array, int index, value)\n");
12849     return E_FAIL;
12850 }
12851 
12852 //delete(array, index); // By White Dragon
openbor_delete(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12853 HRESULT openbor_delete(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12854 {
12855     Varlist *array;
12856     LONG index;
12857 
12858     *pretvar = NULL;
12859     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12860     {
12861         goto set_error;
12862     }
12863 
12864     if(varlist[1]->vt == VT_STR)
12865     {
12866         if ( !Varlist_DeleteByName(array, StrCache_Get(varlist[1]->strVal)) ) goto set_error;
12867     }
12868     else if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &index)))
12869     {
12870         if ( !Varlist_DeleteByIndex(array, (int)index) ) goto set_error;
12871     }
12872     else
12873     {
12874         goto set_error;
12875     }
12876 
12877     return S_OK;
12878 
12879 set_error:
12880     printf("Function requires 1 array handle and 1 int value (index): delete(array, index)\n");
12881     return E_FAIL;
12882 }
12883 
12884 //add(array, index); // By White Dragon
openbor_add(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12885 HRESULT openbor_add(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12886 {
12887     Varlist *array;
12888     LONG index;
12889 
12890     *pretvar = NULL;
12891     if(paramCount < 2 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12892     {
12893         goto add_error;
12894     }
12895 
12896     if(varlist[1]->vt == VT_STR)
12897     {
12898         Varlist_SetByName(array, StrCache_Get(varlist[1]->strVal), varlist[2]);
12899     }
12900     else if( SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &index)) )
12901     {
12902         if ( !Varlist_AddByIndex(array, (int)index, varlist[2]) ) goto add_error;
12903     }
12904     else
12905     {
12906         goto add_error;
12907     }
12908 
12909     return S_OK;
12910 
12911 add_error:
12912     printf("Function requires 1 array handle and 1 int value (index): add(array, index)\n");
12913     return E_FAIL;
12914 }
12915 
12916 //reset(array)
openbor_reset(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12917 HRESULT openbor_reset(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12918 {
12919     Varlist *array;
12920     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12921     {
12922         goto reset_error;
12923     }
12924     List_Reset(array->list);
12925 
12926     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12927     (*pretvar)->lVal = (LONG)(array->list->current != NULL);
12928 
12929     return S_OK;
12930 reset_error:
12931     printf("Function requires 1 array handle: %s(array)\n", "reset");
12932     (*pretvar) = NULL;
12933     return E_FAIL;
12934 }
12935 
12936 //next(array)
openbor_next(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12937 HRESULT openbor_next(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12938 {
12939     Varlist *array;
12940     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12941     {
12942         goto next_error;
12943     }
12944 
12945     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12946     (*pretvar)->lVal = (LONG)(List_GotoNext(array->list));
12947 
12948     return S_OK;
12949 next_error:
12950     printf("Function requires 1 array handle: %s(array)\n", "next");
12951     (*pretvar) = NULL;
12952     return E_FAIL;
12953 }
12954 
12955 //previous(array)
openbor_previous(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12956 HRESULT openbor_previous(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12957 {
12958     Varlist *array;
12959     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12960     {
12961         goto previous_error;
12962     }
12963 
12964     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12965     (*pretvar)->lVal = (LONG)(List_GotoPrevious(array->list));
12966 
12967     return S_OK;
12968 previous_error:
12969     printf("Function requires 1 array handle: %s(array)\n", "previous");
12970     (*pretvar) = NULL;
12971     return E_FAIL;
12972 }
12973 
12974 //islast(array)
openbor_islast(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12975 HRESULT openbor_islast(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12976 {
12977     Varlist *array;
12978     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12979     {
12980         goto islast_error;
12981     }
12982 
12983     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
12984     (*pretvar)->lVal = (LONG)(  List_Retrieve(array->list) == List_GetLast(array->list) );
12985 
12986     return S_OK;
12987 islast_error:
12988     printf("Function requires 1 array handle: %s(array)\n", "islast");
12989     (*pretvar) = NULL;
12990     return E_FAIL;
12991 }
12992 
12993 //isfirst(array)
openbor_isfirst(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)12994 HRESULT openbor_isfirst(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
12995 {
12996     Varlist *array;
12997     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
12998     {
12999         goto isfirst_error;
13000     }
13001 
13002     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13003     (*pretvar)->lVal = (LONG)(  List_Retrieve(array->list) == List_GetFirst(array->list) );
13004 
13005     return S_OK;
13006 isfirst_error:
13007     printf("Function requires 1 array handle: %s(array)\n", "isfirst");
13008     (*pretvar) = NULL;
13009     return E_FAIL;
13010 }
13011 
13012 //key(array)
openbor_key(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13013 HRESULT openbor_key(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13014 {
13015     char *name;
13016     Varlist *array;
13017     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
13018     {
13019         goto key_error;
13020     }
13021 
13022     name = List_GetName(array->list);
13023     if(name)
13024     {
13025         ScriptVariant_ChangeType(*pretvar, VT_STR);
13026         (*pretvar)->strVal = StrCache_CreateNewFrom(name);
13027     }
13028     else
13029     {
13030         ScriptVariant_Clear(*pretvar);
13031     }
13032 
13033     return S_OK;
13034 key_error:
13035     printf("Function requires 1 array handle: %s(array)\n", "key");
13036     (*pretvar) = NULL;
13037     return E_FAIL;
13038 }
13039 
13040 //value(array)
openbor_value(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13041 HRESULT openbor_value(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13042 {
13043     ScriptVariant *var;
13044     Varlist *array;
13045     if(paramCount < 1 || varlist[0]->vt != VT_PTR || !(array = (Varlist *)varlist[0]->ptrVal) || array->magic != varlist_magic)
13046     {
13047         goto value_error;
13048     }
13049 
13050     var = List_Retrieve(array->list);
13051     if(var)
13052     {
13053         ScriptVariant_Copy(*pretvar, var);
13054     }
13055     else
13056     {
13057         ScriptVariant_Clear(*pretvar);
13058     }
13059 
13060     return S_OK;
13061 value_error:
13062     printf("Function requires 1 array handle: %s(array)\n", "value");
13063     (*pretvar) = NULL;
13064     return E_FAIL;
13065 }
13066 
13067 //allocscreen(int w, int h);
openbor_allocscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13068 HRESULT openbor_allocscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13069 {
13070     LONG w, h;
13071     s_screen *screen;
13072 
13073     if(paramCount < 2)
13074     {
13075         goto allocscreen_error;
13076     }
13077 
13078     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &w)))
13079     {
13080         goto allocscreen_error;
13081     }
13082     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &h)))
13083     {
13084         goto allocscreen_error;
13085     }
13086 
13087 
13088     ScriptVariant_ChangeType(*pretvar, VT_PTR);
13089     screen = allocscreen((int)w, (int)h, PIXEL_32);
13090     if(screen)
13091     {
13092         clearscreen(screen);
13093     }
13094     (*pretvar)->ptrVal = (VOID *)screen;
13095 
13096     if((*pretvar)->ptrVal == NULL)
13097     {
13098         printf("Not enough memory: allocscreen(%d, %d)\n", (int)w, (int)h);
13099         (*pretvar) = NULL;
13100         return E_FAIL;
13101     }
13102     List_InsertAfter(&scriptheap, (void *)((*pretvar)->ptrVal), "openbor_allocscreen");
13103     return S_OK;
13104 
13105 allocscreen_error:
13106     printf("Function requires 2 int values: allocscreen(int width, int height)\n");
13107     (*pretvar) = NULL;
13108     return E_FAIL;
13109 }
13110 
13111 //clearscreen(s_screen* screen)
openbor_clearscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13112 HRESULT openbor_clearscreen(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13113 {
13114     s_screen *screen;
13115 
13116     *pretvar = NULL;
13117     if(paramCount != 1)
13118     {
13119         goto clearscreen_error;
13120     }
13121     if(varlist[0]->vt != VT_PTR)
13122     {
13123         goto clearscreen_error;
13124     }
13125 
13126     screen = (s_screen *)varlist[0]->ptrVal;
13127 
13128     if(screen == NULL)
13129     {
13130         printf("Error: NULL pointer passed to clearscreen(void screen)\n");
13131         *pretvar = NULL;
13132         return E_FAIL;
13133     }
13134     clearscreen(screen);
13135     return S_OK;
13136 
13137 clearscreen_error:
13138     printf("Function requires a screen pointer: clearscreen(void screen)\n");
13139     return E_FAIL;
13140 }
13141 
mapstrings_drawmethodproperty(ScriptVariant ** varlist,int paramCount)13142 int mapstrings_drawmethodproperty(ScriptVariant **varlist, int paramCount)
13143 {
13144     char *propname = NULL;
13145     int prop;
13146 
13147     static const char *proplist[] =
13148     {
13149         "alpha",
13150         "amplitude",
13151         "beginsize",
13152         "centerx",
13153         "centery",
13154         "channelb",
13155         "channelg",
13156         "channelr",
13157         "clip",
13158         "cliph",
13159         "clipw",
13160         "clipx",
13161         "clipy",
13162         "enabled",
13163         "endsize",
13164         "fillcolor",
13165         "flag",
13166         "fliprotate",
13167         "flipx",
13168         "flipy",
13169         "perspective",
13170         "remap",
13171         "reset",
13172         "rotate",
13173         "scalex",
13174         "scaley",
13175         "shiftx",
13176         "table",
13177         "tintcolor",
13178         "tintmode",
13179         "transbg",
13180         "watermode",
13181         "wavelength",
13182         "wavespeed",
13183         "wavetime",
13184         "xrepeat",
13185         "xspan",
13186         "yrepeat",
13187         "yspan",
13188     };
13189 
13190 
13191     if(paramCount < 2)
13192     {
13193         return 1;
13194     }
13195     MAPSTRINGS(varlist[1], proplist, _dm_the_end,
13196                "Property name '%s' is not supported by drawmethod.\n");
13197 
13198     return 1;
13199 }
13200 
13201 // changedrawmethod(entity, propertyname, value);
openbor_changedrawmethod(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13202 HRESULT openbor_changedrawmethod(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13203 {
13204     entity *e;
13205     LONG temp = 0;
13206     DOUBLE ftemp = 0;
13207     s_drawmethod *pmethod;
13208     *pretvar = NULL;
13209 
13210     if(paramCount < 3)
13211     {
13212         goto changedm_error;
13213     }
13214 
13215     mapstrings_drawmethodproperty(varlist, paramCount);
13216 
13217     if(varlist[0]->vt == VT_EMPTY)
13218     {
13219         e = NULL;
13220     }
13221     else if(varlist[0]->vt == VT_PTR)
13222     {
13223         e = (entity *)varlist[0]->ptrVal;
13224     }
13225     else
13226     {
13227         goto changedm_error;
13228     }
13229 
13230     if(e)
13231     {
13232         pmethod = (e->drawmethod);
13233     }
13234     else
13235     {
13236         pmethod = &(drawmethod);
13237     }
13238 
13239     switch(varlist[1]->lVal)
13240     {
13241 
13242     case _dm_alpha:
13243         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13244         {
13245             return E_FAIL;
13246         }
13247         pmethod->alpha = (int)temp;
13248         break;
13249     case _dm_amplitude:
13250         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13251         {
13252             return E_FAIL;
13253         }
13254         pmethod->water.amplitude = (int)temp;
13255         break;
13256     case _dm_beginsize:
13257         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
13258         {
13259             return E_FAIL;
13260         }
13261         pmethod->water.beginsize = (float)ftemp;
13262         break;
13263     case _dm_centerx:
13264         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13265         {
13266             return E_FAIL;
13267         }
13268         pmethod->centerx = (int)temp;
13269         break;
13270     case _dm_centery:
13271         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13272         {
13273             return E_FAIL;
13274         }
13275         pmethod->centery = (int)temp;
13276         break;
13277     case _dm_channelb:
13278         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13279         {
13280             return E_FAIL;
13281         }
13282         pmethod->channelb = (int)temp;
13283         break;
13284     case _dm_channelg:
13285         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13286         {
13287             return E_FAIL;
13288         }
13289         pmethod->channelg = (int)temp;
13290         break;
13291     case _dm_channelr:
13292         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13293         {
13294             return E_FAIL;
13295         }
13296         pmethod->channelr = (int)temp;
13297         break;
13298     case _dm_clip:
13299         if(paramCount < 6)
13300         {
13301             return E_FAIL;
13302         }
13303         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13304         {
13305             return E_FAIL;
13306         }
13307         pmethod->clipx = (int)temp;
13308         if(FAILED(ScriptVariant_IntegerValue(varlist[3], &temp)))
13309         {
13310             return E_FAIL;
13311         }
13312         pmethod->clipy = (int)temp;
13313         if(FAILED(ScriptVariant_IntegerValue(varlist[4], &temp)))
13314         {
13315             return E_FAIL;
13316         }
13317         pmethod->clipw = (int)temp;
13318         if(FAILED(ScriptVariant_IntegerValue(varlist[5], &temp)))
13319         {
13320             return E_FAIL;
13321         }
13322         pmethod->cliph = (int)temp;
13323         break;
13324     case _dm_clipx:
13325         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13326         {
13327             return E_FAIL;
13328         }
13329         pmethod->clipx = (int)temp;
13330         break;
13331     case _dm_clipy:
13332         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13333         {
13334             return E_FAIL;
13335         }
13336         pmethod->clipy = (int)temp;
13337         break;
13338     case _dm_clipw:
13339         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13340         {
13341             return E_FAIL;
13342         }
13343         pmethod->clipw = (int)temp;
13344         break;
13345     case _dm_cliph:
13346         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13347         {
13348             return E_FAIL;
13349         }
13350         pmethod->cliph = (int)temp;
13351         break;
13352     case _dm_enabled:
13353     case _dm_flag:
13354         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13355         {
13356             return E_FAIL;
13357         }
13358         pmethod->flag = (int)temp;
13359         break;
13360     case _dm_endsize:
13361         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
13362         {
13363             return E_FAIL;
13364         }
13365         pmethod->water.endsize = (float)ftemp;
13366         break;
13367     case _dm_fillcolor:
13368         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13369         {
13370             return E_FAIL;
13371         }
13372         pmethod->fillcolor = (int)temp;
13373         break;
13374     case _dm_fliprotate:
13375         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13376         {
13377             return E_FAIL;
13378         }
13379         pmethod->fliprotate = (int)temp;
13380         break;
13381     case _dm_flipx:
13382         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13383         {
13384             return E_FAIL;
13385         }
13386         pmethod->flipx = (int)temp;
13387         break;
13388     case _dm_flipy:
13389         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13390         {
13391             return E_FAIL;
13392         }
13393         pmethod->flipy = (int)temp;
13394         break;
13395     case _dm_perspective:
13396         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13397         {
13398             return E_FAIL;
13399         }
13400         pmethod->water.perspective = (int)temp;
13401         break;
13402     case _dm_remap:
13403         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13404         {
13405             return E_FAIL;
13406         }
13407         pmethod->remap = (int)temp;
13408         break;
13409     case _dm_reset:
13410         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13411         {
13412             return E_FAIL;
13413         }
13414         if(temp)
13415         {
13416             *pmethod = plainmethod;
13417         }
13418         break;
13419     case _dm_rotate:
13420         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13421         {
13422             return E_FAIL;
13423         }
13424         pmethod->rotate = (float)temp;
13425         break;
13426     case _dm_scalex:
13427         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13428         {
13429             return E_FAIL;
13430         }
13431         pmethod->scalex = (int)temp;
13432         break;
13433     case _dm_scaley:
13434         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13435         {
13436             return E_FAIL;
13437         }
13438         pmethod->scaley = (int)temp;
13439         break;
13440     case _dm_shiftx:
13441         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13442         {
13443             return E_FAIL;
13444         }
13445         pmethod->shiftx = (int)temp;
13446         break;
13447     case _dm_table:
13448         if(varlist[2]->vt != VT_PTR && varlist[2]->vt != VT_EMPTY )
13449         {
13450             return E_FAIL;
13451         }
13452         pmethod->table = (void *)varlist[2]->ptrVal;
13453         break;
13454     case _dm_tintmode:
13455         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13456         {
13457             return E_FAIL;
13458         }
13459         pmethod->tintmode = (int)temp;
13460         break;
13461     case _dm_tintcolor:
13462         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13463         {
13464             return E_FAIL;
13465         }
13466         pmethod->tintcolor = (int)temp;
13467         break;
13468     case _dm_transbg:
13469         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13470         {
13471             return E_FAIL;
13472         }
13473         pmethod->transbg = (int)temp;
13474         break;
13475     case _dm_watermode:
13476         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13477         {
13478             return E_FAIL;
13479         }
13480         pmethod->water.watermode = (int)temp;
13481         break;
13482     case _dm_wavelength:
13483         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
13484         {
13485             return E_FAIL;
13486         }
13487         pmethod->water.wavelength = (float)ftemp;
13488         break;
13489     case _dm_wavespeed:
13490         if(FAILED(ScriptVariant_DecimalValue(varlist[2], &ftemp)))
13491         {
13492             return E_FAIL;
13493         }
13494         pmethod->water.wavespeed = (float)ftemp;
13495         break;
13496     case _dm_wavetime:
13497         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13498         {
13499             return E_FAIL;
13500         }
13501         pmethod->water.wavetime = (int)(temp * pmethod->water.wavespeed);
13502         break;
13503     case _dm_xrepeat:
13504         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13505         {
13506             return E_FAIL;
13507         }
13508         pmethod->xrepeat = (int)temp;
13509         break;
13510     case _dm_yrepeat:
13511         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13512         {
13513             return E_FAIL;
13514         }
13515         pmethod->yrepeat = (int)temp;
13516         break;
13517     case _dm_xspan:
13518         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13519         {
13520             return E_FAIL;
13521         }
13522         pmethod->xspan = (int)temp;
13523         break;
13524     case _dm_yspan:
13525         if(FAILED(ScriptVariant_IntegerValue(varlist[2], &temp)))
13526         {
13527             return E_FAIL;
13528         }
13529         pmethod->yspan = (int)temp;
13530         break;
13531     default:
13532         break;
13533 
13534     }
13535 
13536     return S_OK;
13537 
13538 changedm_error:
13539     printf("Function changedrawmethod must have at least 3 parameters: entity, propertyname, value\n");
13540     return E_FAIL;
13541 }
13542 
13543 //getdrawmethod(<entity>, <property>)
openbor_getdrawmethod(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13544 HRESULT openbor_getdrawmethod(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13545 {
13546     /*
13547     getdrawmethod
13548     Damon V. Caskey
13549     2013-11-09
13550 
13551     Allow module author to read current drawmethod settings.
13552     */
13553     entity *e;
13554     s_drawmethod *pmethod;
13555 
13556     if(paramCount < 2)
13557     {
13558         goto getdm_error;
13559     }
13560 
13561     ScriptVariant_Clear(*pretvar);
13562     mapstrings_drawmethodproperty(varlist, paramCount);
13563 
13564     if(varlist[0]->vt == VT_EMPTY)
13565     {
13566         e = NULL;
13567     }
13568     else if(varlist[0]->vt == VT_PTR)
13569     {
13570         e = (entity *)varlist[0]->ptrVal;
13571     }
13572     else
13573     {
13574         goto getdm_error;
13575     }
13576 
13577     if(e)
13578     {
13579         pmethod = (e->drawmethod);
13580     }
13581     else
13582     {
13583         pmethod = &(drawmethod);
13584     }
13585 
13586     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
13587 
13588     switch(varlist[1]->lVal)
13589     {
13590         case _dm_alpha:
13591             (*pretvar)->lVal = (int)pmethod->alpha;
13592             break;
13593         case _dm_amplitude:
13594             (*pretvar)->lVal = (int)pmethod->water.amplitude;
13595             break;
13596         case _dm_beginsize:
13597             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
13598             (*pretvar)->dblVal = (float)pmethod->water.beginsize;
13599             break;
13600         case _dm_centerx:
13601             (*pretvar)->lVal = (int)pmethod->centerx;
13602             break;
13603         case _dm_centery:
13604             (*pretvar)->lVal = (int)pmethod->centery;
13605             break;
13606         case _dm_channelb:
13607             (*pretvar)->lVal = (int)pmethod->channelb;
13608             break;
13609         case _dm_channelg:
13610             (*pretvar)->lVal = (int)pmethod->channelg;
13611             break;
13612         case _dm_channelr:
13613             (*pretvar)->lVal = (int)pmethod->channelr;
13614             break;
13615         case _dm_clipx:
13616             (*pretvar)->lVal = (int)pmethod->clipx;
13617             break;
13618         case _dm_clipy:
13619             (*pretvar)->lVal = (int)pmethod->clipy;
13620             break;
13621         case _dm_clipw:
13622             (*pretvar)->lVal = (int)pmethod->clipw;
13623             break;
13624         case _dm_cliph:
13625             (*pretvar)->lVal = (int)pmethod->cliph;
13626             break;
13627         case _dm_endsize:
13628             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
13629             (*pretvar)->dblVal = (float)pmethod->water.endsize;
13630             break;
13631         case _dm_fillcolor:
13632             (*pretvar)->lVal = (int)pmethod->fillcolor;
13633             break;
13634         case _dm_fliprotate:
13635             (*pretvar)->lVal = (int)pmethod->fliprotate;
13636             break;
13637         case _dm_flipx:
13638             (*pretvar)->lVal = (int)pmethod->flipx;
13639             break;
13640         case _dm_flipy:
13641             (*pretvar)->lVal = (int)pmethod->flipy;
13642             break;
13643         case _dm_perspective:
13644             (*pretvar)->lVal = (int)pmethod->water.perspective;
13645             break;
13646         case _dm_remap:
13647             (*pretvar)->lVal = (int)pmethod->remap;
13648             break;
13649         case _dm_rotate:
13650             (*pretvar)->lVal = (int)pmethod->rotate;
13651             break;
13652         case _dm_scalex:
13653             (*pretvar)->lVal = (int)pmethod->scalex;
13654             break;
13655         case _dm_scaley:
13656             (*pretvar)->lVal = (int)pmethod->scaley;
13657             break;
13658         case _dm_shiftx:
13659             (*pretvar)->lVal = (int)pmethod->shiftx;
13660             break;
13661         case _dm_table:
13662             ScriptVariant_ChangeType(*pretvar, VT_PTR);
13663             (*pretvar)->ptrVal = (void *)pmethod->table;
13664             break;
13665         case _dm_tintmode:
13666             (*pretvar)->lVal = (int)pmethod->tintmode;
13667             break;
13668         case _dm_tintcolor:
13669             (*pretvar)->lVal = (int)pmethod->tintcolor;
13670             break;
13671         case _dm_transbg:
13672             (*pretvar)->lVal = (int)pmethod->transbg;
13673             break;
13674         case _dm_watermode:
13675             (*pretvar)->lVal = (int)pmethod->water.watermode;
13676             break;
13677         case _dm_wavelength:
13678             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
13679             (*pretvar)->dblVal = (float)pmethod->water.wavelength;
13680             break;
13681         case _dm_wavespeed:
13682             ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
13683             (*pretvar)->dblVal = (float)pmethod->water.wavespeed;
13684             break;
13685         case _dm_wavetime:
13686             (*pretvar)->lVal = (int)pmethod->water.wavetime;
13687             break;
13688         case _dm_xrepeat:
13689             (*pretvar)->lVal = (int)pmethod->xrepeat;
13690             break;
13691         case _dm_yrepeat:
13692             (*pretvar)->lVal = (int)pmethod->yrepeat;
13693             break;
13694         case _dm_xspan:
13695             (*pretvar)->lVal = (int)pmethod->xspan;
13696             break;
13697         case _dm_yspan:
13698             (*pretvar)->lVal = pmethod->yspan;
13699             break;
13700         default:
13701         case _dm_enabled:
13702         case _dm_flag:
13703             (*pretvar)->lVal = (int)pmethod->flag;
13704             break;
13705     }
13706 
13707     return S_OK;
13708 
13709 getdm_error:
13710     printf("Function getdrawmethod must have at least 2 parameters: entity, propertyname\n");
13711     *pretvar = NULL;
13712     return E_FAIL;
13713 }
13714 
13715 //deprecated
13716 //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)13717 HRESULT openbor_setdrawmethod(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13718 {
13719     LONG value[14];
13720     entity *e;
13721     s_drawmethod *pmethod;
13722     int i;
13723 
13724     *pretvar = NULL;
13725     if(paramCount < 2)
13726     {
13727         goto setdrawmethod_error;
13728     }
13729 
13730     if(varlist[0]->vt == VT_EMPTY)
13731     {
13732         e = NULL;
13733     }
13734     else if(varlist[0]->vt == VT_PTR)
13735     {
13736         e = (entity *)varlist[0]->ptrVal;
13737     }
13738     else
13739     {
13740         goto setdrawmethod_error;
13741     }
13742 
13743     if(e)
13744     {
13745         pmethod = (e->drawmethod);
13746     }
13747     else
13748     {
13749         pmethod = &(drawmethod);
13750     }
13751 
13752     memset(value, 0, sizeof(value));
13753     for(i = 1; i < paramCount && i < 13; i++)
13754     {
13755         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
13756         {
13757             goto setdrawmethod_error;
13758         }
13759     }
13760 
13761     if(paramCount >= 14 && varlist[13]->vt != VT_PTR && varlist[13]->vt != VT_EMPTY)
13762     {
13763         goto setdrawmethod_error;
13764     }
13765 
13766     for(i = 14; i < paramCount && i < 16; i++)
13767     {
13768         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 2)))
13769         {
13770             goto setdrawmethod_error;
13771         }
13772     }
13773 
13774     pmethod->flag = (int)value[0];
13775     pmethod->scalex = (int)value[1];
13776     pmethod->scaley = (int)value[2];
13777     pmethod->flipx = (int)value[3];
13778     pmethod->flipy = (int)value[4];
13779     pmethod->shiftx = (int)value[5];
13780     pmethod->alpha = (int)value[6];
13781     pmethod->remap = (int)value[7];
13782     pmethod->fillcolor = (int)value[8];
13783     pmethod->rotate = ((int)value[9]) % 360;
13784     pmethod->fliprotate = (int)value[10];
13785     pmethod->transbg = (int)value[11];
13786     if(paramCount >= 14)
13787     {
13788         pmethod->table = (unsigned char *)varlist[13]->ptrVal;
13789     }
13790     pmethod->centerx = (int)value[12];
13791     pmethod->centery = (int)value[13];
13792 
13793     if(pmethod->rotate < 0)
13794     {
13795         pmethod->rotate += 360;
13796     }
13797     return S_OK;
13798 
13799 setdrawmethod_error:
13800     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");
13801     return E_FAIL;
13802 }
13803 
13804 //updateframe(entity, int frame);
openbor_updateframe(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13805 HRESULT openbor_updateframe(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13806 {
13807     LONG f;
13808     entity *e;
13809     void update_frame(entity * ent, int f);
13810 
13811     *pretvar = NULL;
13812     if(paramCount < 2)
13813     {
13814         goto updateframe_error;
13815     }
13816 
13817     if(varlist[0]->vt == VT_EMPTY)
13818     {
13819         e = NULL;
13820     }
13821     else if(varlist[0]->vt == VT_PTR)
13822     {
13823         e = (entity *)varlist[0]->ptrVal;
13824     }
13825     else
13826     {
13827         goto updateframe_error;
13828     }
13829 
13830     if(!e)
13831     {
13832         goto updateframe_error;
13833     }
13834 
13835     if(FAILED(ScriptVariant_IntegerValue(varlist[1], &f)))
13836     {
13837         goto updateframe_error;
13838     }
13839 
13840     update_frame(e, (int)f);
13841 
13842     return S_OK;
13843 
13844 updateframe_error:
13845     printf("Function need a valid entity handle and at an interger parameter: updateframe(entity, int frame)\n");
13846     return E_FAIL;
13847 }
13848 
13849 //executeanimation(entity, int anim, int resetable);
openbor_executeanimation(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13850 HRESULT openbor_executeanimation(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13851 {
13852     LONG anim, resetable = 0;
13853     entity *e;
13854 
13855     *pretvar = NULL;
13856     if(paramCount < 1)
13857     {
13858         goto executeanimation_error;
13859     }
13860 
13861     if(varlist[0]->vt == VT_EMPTY)
13862     {
13863         e = NULL;
13864     }
13865     else if(varlist[0]->vt == VT_PTR)
13866     {
13867         e = (entity *)varlist[0]->ptrVal;
13868     }
13869     else
13870     {
13871         goto executeanimation_error;
13872     }
13873 
13874     if(!e)
13875     {
13876         goto executeanimation_error;
13877     }
13878 
13879     e->takeaction = common_animation_normal;
13880     e->attacking = ATTACKING_NONE;
13881     e->idling = IDLING_NONE;
13882     e->drop = 0;
13883     e->falling = 0;
13884     e->inpain = 0;
13885     e->rising = RISING_NONE;
13886     e->edge = EDGE_NONE;
13887     e->ducking = DUCK_NONE;
13888     e->inbackpain = 0;
13889     e->blocking = 0;
13890 
13891     if(paramCount == 1)
13892     {
13893         return S_OK;
13894     }
13895 
13896     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
13897     {
13898         goto executeanimation_error;
13899     }
13900     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))
13901     {
13902         goto executeanimation_error;
13903     }
13904     ent_set_anim(e, (int)anim, (int)resetable);
13905 
13906     return S_OK;
13907 
13908 executeanimation_error:
13909     printf("Function need a valid entity handle, the other 2 integer parameters are optional: performattack(entity, int anim, int resetable)\n");
13910     return E_FAIL;
13911 }
13912 
13913 //performattack(entity, int anim, int resetable);
openbor_performattack(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13914 HRESULT openbor_performattack(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13915 {
13916     LONG anim, resetable = 0;
13917     entity *e;
13918 
13919     *pretvar = NULL;
13920     if(paramCount < 1)
13921     {
13922         goto performattack_error;
13923     }
13924 
13925     if(varlist[0]->vt == VT_EMPTY)
13926     {
13927         e = NULL;
13928     }
13929     else if(varlist[0]->vt == VT_PTR)
13930     {
13931         e = (entity *)varlist[0]->ptrVal;
13932     }
13933     else
13934     {
13935         goto performattack_error;
13936     }
13937 
13938     if(!e)
13939     {
13940         goto performattack_error;
13941     }
13942 
13943     e->takeaction = common_attack_proc;
13944     e->attacking = ATTACKING_ACTIVE;
13945     e->idling = IDLING_NONE;
13946     e->drop = 0;
13947     e->falling = 0;
13948     e->inpain = 0;
13949     e->rising = RISING_NONE;
13950     e->edge = EDGE_NONE;
13951     e->inbackpain = 0;
13952     e->blocking = 0;
13953 
13954     if(paramCount == 1)
13955     {
13956         return S_OK;
13957     }
13958 
13959     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
13960     {
13961         goto performattack_error;
13962     }
13963     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))
13964     {
13965         goto performattack_error;
13966     }
13967     ent_set_anim(e, (int)anim, (int)resetable);
13968 
13969     return S_OK;
13970 
13971 performattack_error:
13972     printf("Function need a valid entity handle, the other 2 integer parameters are optional: performattack(entity, int anim, int resetable)\n");
13973     return E_FAIL;
13974 }
13975 
13976 //setidle(entity, int anim, int resetable, int stalladd);
openbor_setidle(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)13977 HRESULT openbor_setidle(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
13978 {
13979     LONG anim = 0, resetable = 0, stalladd = 0;
13980     entity *e;
13981     extern unsigned int _time;
13982 
13983     *pretvar = NULL;
13984     if(paramCount < 1)
13985     {
13986         goto setidle_error;
13987     }
13988 
13989     if(varlist[0]->vt == VT_EMPTY)
13990     {
13991         e = NULL;
13992     }
13993     else if(varlist[0]->vt == VT_PTR)
13994     {
13995         e = (entity *)varlist[0]->ptrVal;
13996     }
13997     else
13998     {
13999         goto setidle_error;
14000     }
14001 
14002     if(!e)
14003     {
14004         goto setidle_error;
14005     }
14006 
14007     e->takeaction = NULL;
14008     e->attacking = ATTACKING_NONE;
14009     e->idling = 1;
14010     e->drop = 0;
14011     e->falling = 0;
14012     e->inpain = 0;
14013     e->rising = RISING_NONE;
14014     e->edge = EDGE_NONE;
14015     e->ducking = DUCK_NONE;
14016     e->inbackpain = 0;
14017     e->blocking = 0;
14018     e->nograb = e->nograb_default; //e->nograb = 0;
14019     e->destx = e->position.x;
14020     e->destz = e->position.z;
14021 
14022     if(paramCount == 1)
14023     {
14024         return S_OK;
14025     }
14026 
14027     if(paramCount > 1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim)))
14028     {
14029         goto setidle_error;
14030     }
14031     if(paramCount > 2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))
14032     {
14033         goto setidle_error;
14034     }
14035     if(paramCount > 3 && FAILED(ScriptVariant_IntegerValue(varlist[3], &stalladd)))
14036     {
14037         goto setidle_error;
14038     }
14039     ent_set_anim(e, (int)anim, (int)resetable);
14040 
14041     if(stalladd > 0)
14042     {
14043         e->stalltime = _time + stalladd;
14044     }
14045 
14046     return S_OK;
14047 
14048 setidle_error:
14049     printf("Function need a valid entity handle, the other 3 integer parameters are optional: setidle(entity, int anim, int resetable, int stalladd)\n");
14050     return E_FAIL;
14051 }
14052 
14053 //getentity(int index_from_list)
openbor_getentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14054 HRESULT openbor_getentity(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14055 {
14056     LONG ind;
14057     extern entity **ent_list;
14058     extern int ent_list_size;
14059 
14060     if(paramCount != 1)
14061     {
14062         goto getentity_error;
14063     }
14064 
14065     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
14066     {
14067         goto getentity_error;
14068     }
14069 
14070     ScriptVariant_Clear(*pretvar);
14071 
14072     if((int)ind < ent_list_size && (int)ind >= 0)
14073     {
14074         ScriptVariant_ChangeType(*pretvar, VT_PTR);
14075         (*pretvar)->ptrVal = (VOID *)ent_list[(int)ind];
14076     }
14077     //else, it should return an empty value
14078     return S_OK;
14079 
14080 getentity_error:
14081     printf("Function need an integer parameter: getentity(int index_in_list)\n");
14082     *pretvar = NULL;
14083     return E_FAIL;
14084 }
14085 
14086 
14087 //loadmodel(name)
openbor_loadmodel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14088 HRESULT openbor_loadmodel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14089 {
14090     LONG unload = 0;
14091     s_model *model;
14092     if(paramCount < 1)
14093     {
14094         goto loadmodel_error;
14095     }
14096     if(varlist[0]->vt != VT_STR)
14097     {
14098         goto loadmodel_error;
14099     }
14100 
14101     ScriptVariant_ChangeType(*pretvar, VT_PTR);
14102     if(paramCount >= 2)
14103         if(FAILED(ScriptVariant_IntegerValue(varlist[1], &unload)))
14104         {
14105             goto loadmodel_error;
14106         }
14107 
14108     model = load_cached_model(StrCache_Get(varlist[0]->strVal), "openbor_loadmodel", (char)unload);
14109 
14110     if(paramCount >= 3 && model)
14111     {
14112         model_cache[model->index].selectable = (char)ScriptVariant_IsTrue(varlist[2]);
14113     }
14114 
14115     (*pretvar)->ptrVal = (VOID *)model;
14116 
14117     //else, it should return an empty value
14118     return S_OK;
14119 
14120 loadmodel_error:
14121     printf("Function needs a string and integer parameters: loadmodel(name, unload, selectable)\n");
14122     ScriptVariant_Clear(*pretvar);
14123     *pretvar = NULL;
14124     return E_FAIL;
14125 }
14126 
14127 //unload_model("name");
openbor_unload_model(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14128 HRESULT openbor_unload_model(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14129 {
14130     LONG unload = 0;
14131     s_model *model;
14132     if(paramCount < 1)
14133     {
14134         goto unload_model_error;
14135     }
14136     if(varlist[0]->vt != VT_STR)
14137     {
14138         goto unload_model_error;
14139     }
14140 
14141     model = load_cached_model(StrCache_Get(varlist[0]->strVal), "openbor_loadmodel", (char)unload);
14142 
14143     if(paramCount >= 1 && model)
14144     {
14145 		cache_model_sprites(model,0);
14146 		free_model(model);
14147     }
14148 
14149     //(*pretvar)->ptrVal = (VOID *)model;
14150 
14151     //else, it should return an empty value
14152 	return S_OK;
14153 
14154 	unload_model_error:
14155     printf("Function needs a string parameter: unload_model(name)\n");
14156     ScriptVariant_Clear(*pretvar);
14157     *pretvar = NULL;
14158     return E_FAIL;
14159 }
14160 
14161 // load a sprite which doesn't belong to the sprite_cache
14162 // loadsprite(path, maskpath)
openbor_loadsprite(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14163 HRESULT openbor_loadsprite(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14164 {
14165     extern s_sprite *loadsprite2(char * filename, int * width, int * height);
14166     s_sprite *spr, *mask;
14167     if(paramCount < 1)
14168     {
14169         goto loadsprite_error;
14170     }
14171 
14172     if(varlist[0]->vt != VT_STR)
14173     {
14174         goto loadsprite_error;
14175     }
14176 
14177     ScriptVariant_ChangeType(*pretvar, VT_PTR);
14178     if((spr = loadsprite2(StrCache_Get(varlist[0]->strVal), NULL, NULL)))
14179     {
14180         (*pretvar)->ptrVal = (VOID *)spr;
14181         if(paramCount > 1 && (mask = loadsprite2(StrCache_Get(varlist[1]->strVal), NULL, NULL)))
14182         {
14183             spr->mask = mask;
14184         }
14185         List_InsertAfter(&scriptheap, (void *)spr, "openbor_loadsprite");
14186     }
14187     //else, it should return an empty value
14188     return S_OK;
14189 
14190 loadsprite_error:
14191     printf("Function need a string parameter: loadsprite(path)\n");
14192     ScriptVariant_Clear(*pretvar);
14193     *pretvar = NULL;
14194     return E_FAIL;
14195 }
14196 
14197 // Call options menu, blocked
openbor_menu_options(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14198 HRESULT openbor_menu_options(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14199 {
14200     //void menu_options();
14201 
14202     menu_options();
14203 
14204     *pretvar = NULL;
14205     return S_OK;
14206 }
14207 
openbor_hallfame(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14208 HRESULT openbor_hallfame(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14209 {
14210     hallfame(0);
14211 
14212     *pretvar = NULL;
14213     return S_OK;
14214 }
14215 
14216 //playwebm(path, int noskip)
openbor_playwebm(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14217 HRESULT openbor_playwebm(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14218 {
14219     LONG temp = 0; //noskip
14220     extern int playwebm(char * filename, int noskip); // avoid implicit declaration
14221 
14222     if(paramCount < 1)
14223     {
14224         goto playwebm_error;
14225     }
14226 
14227     if(varlist[0]->vt != VT_STR)
14228     {
14229         goto playwebm_error;
14230     }
14231 
14232     if(paramCount > 1)
14233     {
14234         if(FAILED(ScriptVariant_IntegerValue(varlist[1], &temp)))
14235         {
14236             goto playwebm_error;
14237         }
14238     }
14239 
14240     #ifdef WEBM
14241         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14242         (*pretvar)->lVal = (LONG)playwebm(StrCache_Get(varlist[0]->strVal), (int)temp);
14243     #else
14244         printf("Skipping video %s; WebM playback not supported on this platform\n");
14245         *pretvar = NULL;
14246     #endif
14247 
14248     return S_OK;
14249 
14250 playwebm_error:
14251     printf("Function need a string parameter, other parameters are optional: playwebm(path, int noskip)\n");
14252     *pretvar = NULL;
14253     return E_FAIL;
14254 }
14255 
14256 //playgif(path, int x, int y, int noskip)
openbor_playgif(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14257 HRESULT openbor_playgif(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14258 {
14259     LONG temp[3] = {0, 0, 0}; //x,y,noskip
14260     int i;
14261     extern unsigned char pal[1024];
14262     extern int playgif(char * filename, int x, int y, int noskip);
14263 
14264     if(paramCount < 1)
14265     {
14266         goto playgif_error;
14267     }
14268 
14269     if(varlist[0]->vt != VT_STR)
14270     {
14271         goto playgif_error;
14272     }
14273 
14274     for(i = 0; i < 3 && i < paramCount - 1; i++)
14275     {
14276         if(FAILED(ScriptVariant_IntegerValue(varlist[i + 1], temp + i)))
14277         {
14278             goto playgif_error;
14279         }
14280     }
14281 
14282     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14283     (*pretvar)->lVal = (LONG)playgif(StrCache_Get(varlist[0]->strVal), (int)(temp[0]), (int)(temp[1]), (int)(temp[2]));
14284     palette_set_corrected(pal, savedata.gamma, savedata.gamma, savedata.gamma, savedata.brightness, savedata.brightness, savedata.brightness);
14285     return S_OK;
14286 
14287 playgif_error:
14288     printf("Function need a string parameter, other parameters are optional: playgif(path, int x, int y, int noskip)\n");
14289     *pretvar = NULL;
14290     return E_FAIL;
14291 }
14292 
14293 //open and return a handle
14294 //TODO: error messages
openbor_openanigif(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14295 HRESULT openbor_openanigif(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14296 {
14297     anigif_info *info = NULL;
14298 
14299     if(varlist[0]->vt != VT_STR)
14300     {
14301         goto openanigif_error;
14302     }
14303 
14304     info = calloc(1, sizeof(*info));
14305     if(anigif_open(StrCache_Get(varlist[0]->strVal), packfile, info))
14306     {
14307         info->magic = anigif_magic;
14308         List_InsertAfter(&scriptheap, (void *)info, "openbor_openanigif");
14309         ScriptVariant_ChangeType(*pretvar, VT_PTR);
14310         (*pretvar)->ptrVal = (VOID *)info;
14311         return S_OK;
14312     }
14313 
14314 openanigif_error:
14315     if(info)
14316     {
14317         free(info);
14318     }
14319     *pretvar = NULL;
14320     return E_FAIL;
14321 }
14322 
14323 //decode a frame if any
openbor_decodeanigif(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14324 HRESULT openbor_decodeanigif(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14325 {
14326     anigif_info *info = NULL;
14327 
14328     if(varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
14329     {
14330         goto decodeanigif_error;
14331     }
14332     info = (anigif_info *) varlist[0]->ptrVal;
14333 
14334     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14335     (*pretvar)->lVal = (LONG)anigif_decode_frame(info);
14336     return S_OK;
14337 
14338 decodeanigif_error:
14339     *pretvar = NULL;
14340     return E_FAIL;
14341 }
14342 
14343 //TODO mapstrings
openbor_getanigifinfo(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14344 HRESULT openbor_getanigifinfo(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14345 {
14346     anigif_info *info = NULL;
14347     char *name;
14348 
14349     if(varlist[0]->vt != VT_PTR || !varlist[0]->ptrVal)
14350     {
14351         goto getanigifinfo_error;
14352     }
14353     info = (anigif_info *) varlist[0]->ptrVal;
14354 
14355     if(varlist[1]->vt != VT_STR)
14356     {
14357         goto getanigifinfo_error;
14358     }
14359     name = StrCache_Get(varlist[1]->strVal);
14360     if(0 == stricmp(name, "buffer"))
14361     {
14362         ScriptVariant_ChangeType(*pretvar, VT_PTR);
14363         (*pretvar)->ptrVal = (VOID *)anigif_getbuffer(info);
14364     }
14365     else if(0 == stricmp(name, "done"))
14366     {
14367         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14368         (*pretvar)->lVal = (LONG)info->done;
14369     }
14370     else if(0 == stricmp(name, "frame"))
14371     {
14372         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14373         (*pretvar)->lVal = (LONG)info->frame;
14374     }
14375     else if(0 == stricmp(name, "isRGB"))
14376     {
14377         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14378         (*pretvar)->lVal = (LONG)info->isRGB;
14379     }
14380     else if(0 == stricmp(name, "width"))
14381     {
14382         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14383         (*pretvar)->lVal = (LONG)(info->gifbuffer[0] ? info->gifbuffer[0]->width : 0);
14384     }
14385     else if(0 == stricmp(name, "height"))
14386     {
14387         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14388         (*pretvar)->lVal = (LONG)(info->gifbuffer[0] ? info->gifbuffer[0]->height : 0);
14389     }
14390     else if(0 == stricmp(name, "nextframe"))
14391     {
14392         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14393         (*pretvar)->lVal = (LONG)info->info[0].nextframe;
14394     }
14395     else if(0 == stricmp(name, "lastdelay"))
14396     {
14397         ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14398         (*pretvar)->lVal = (LONG)info->info[0].lastdelay;
14399     }
14400     else
14401     {
14402         goto getanigifinfo_error;
14403     }
14404 
14405     return S_OK;
14406 
14407 getanigifinfo_error:
14408     *pretvar = NULL;
14409     return E_FAIL;
14410 }
14411 
14412 // complex, so make a function for ai
14413 // adjustwalkanimation(ent, target);
openbor_adjustwalkanimation(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14414 HRESULT openbor_adjustwalkanimation(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14415 {
14416 
14417     entity *e, *t, *temp;
14418 
14419     *pretvar = NULL;
14420 
14421     if(paramCount < 1)
14422     {
14423         e = self;
14424     }
14425     else if(varlist[0]->vt == VT_PTR)
14426     {
14427         e = (entity *)varlist[0]->ptrVal;
14428     }
14429     else
14430     {
14431         goto adjustwalkanimation_error;
14432     }
14433 
14434     if(paramCount < 2)
14435     {
14436         t = NULL;
14437     }
14438     else if(varlist[1]->vt == VT_PTR)
14439     {
14440         t = (entity *)varlist[1]->ptrVal;
14441     }
14442     else if(varlist[1]->vt == VT_EMPTY)
14443     {
14444         t = NULL;
14445     }
14446     else
14447     {
14448         goto adjustwalkanimation_error;
14449     }
14450 
14451     temp = self;
14452 
14453     self = e;
14454     adjust_walk_animation(t);
14455     self = temp;
14456 
14457     return S_OK;
14458 adjustwalkanimation_error:
14459     printf("Function adjustwalkanimation(entity, target), both parameters are optional, but must be valid.");
14460     return E_FAIL;
14461 }
14462 
14463 //finditem(entity)
openbor_finditem(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14464 HRESULT openbor_finditem(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14465 {
14466 
14467     entity *e, *t, *temp;
14468 
14469     if(paramCount < 1)
14470     {
14471         e = self;
14472     }
14473     else if(varlist[0]->vt == VT_PTR)
14474     {
14475         e = (entity *)varlist[0]->ptrVal;
14476     }
14477     else
14478     {
14479         goto finditem_error;
14480     }
14481 
14482     temp = self;
14483 
14484     self = e;
14485     t = normal_find_item();
14486     self = temp;
14487 
14488     ScriptVariant_ChangeType(*pretvar, VT_PTR);
14489     (*pretvar)->ptrVal = (VOID *)t;
14490 
14491     return S_OK;
14492 finditem_error:
14493 
14494     *pretvar = NULL;
14495     printf("Function finditem(entity), entity is optional, but must be valid.");
14496     return E_FAIL;
14497 }
14498 
14499 //pickup(entity, item)
openbor_pickup(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14500 HRESULT openbor_pickup(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14501 {
14502 
14503     entity *e, *t, *temp;
14504 
14505     *pretvar = NULL;
14506 
14507     if(paramCount < 2)
14508     {
14509         goto pickup_error;
14510     }
14511 
14512     if(varlist[0]->vt == VT_PTR)
14513     {
14514         e = (entity *)varlist[0]->ptrVal;
14515     }
14516     else
14517     {
14518         goto pickup_error;
14519     }
14520 
14521     if(varlist[1]->vt == VT_PTR)
14522     {
14523         t = (entity *)varlist[1]->ptrVal;
14524     }
14525     else
14526     {
14527         goto pickup_error;
14528     }
14529 
14530     if(!e || !t)
14531     {
14532         goto pickup_error;
14533     }
14534 
14535     temp = self;
14536 
14537     self = e;
14538     common_pickupitem(t);
14539     self = temp;
14540 
14541     return S_OK;
14542 pickup_error:
14543     printf("Function pickup(entity, item), handles must be valid.");
14544     return E_FAIL;
14545 }
14546 
14547 //waypoints(ent, x1, z1, x2, z2, x3, z3, ...)
14548 //zero length list means clear waypoints
openbor_waypoints(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14549 HRESULT openbor_waypoints(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14550 {
14551     int num, i;
14552 	s_axis_plane_lateral_float *wp = NULL;
14553     DOUBLE x, z;
14554 
14555     entity *e;
14556     *pretvar = NULL;
14557 
14558     if(paramCount < 1)
14559     {
14560         goto wp_error;
14561     }
14562 
14563     if(varlist[0]->vt == VT_PTR)
14564     {
14565         e = (entity *)varlist[0]->ptrVal;
14566     }
14567     else
14568     {
14569         goto wp_error;
14570     }
14571 
14572     num = (paramCount - 1) / 2;
14573     if(num > 0)
14574     {
14575         //append
14576         wp = malloc(sizeof(*wp) * (num + e->numwaypoints));
14577 
14578         for(i = 0; i < num ; i++)
14579         {
14580             if(FAILED(ScriptVariant_DecimalValue(varlist[1], &x)))
14581             {
14582                 goto wp_error;
14583             }
14584 
14585             if(FAILED(ScriptVariant_DecimalValue(varlist[2], &z)))
14586             {
14587                 goto wp_error;
14588             }
14589 
14590             wp[num - i - 1].x = (float)x;
14591             wp[num - i - 1].z = (float)z;
14592         }
14593         if(e->numwaypoints)
14594         {
14595             for(i = 0; i < e->numwaypoints; i++)
14596             {
14597                 wp[i + num] = e->waypoints[i];
14598             }
14599         }
14600 
14601         if(e->waypoints)
14602         {
14603             free(e->waypoints);
14604         }
14605         e->waypoints = wp;
14606         e->numwaypoints = num;
14607     }
14608     else
14609     {
14610         e->numwaypoints = 0;
14611         if(e->waypoints)
14612         {
14613             free(e->waypoints);
14614         }
14615         e->waypoints = NULL;
14616     }
14617     return S_OK;
14618 
14619 wp_error:
14620     if(wp)
14621     {
14622         free(wp);
14623     }
14624     wp = NULL;
14625     printf("Function waypoints requires a valid entity handle and a list of x, z value pairs.");
14626     return E_FAIL;
14627 }
14628 
14629 //testmove(entity, x, z)
openbor_testmove(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14630 HRESULT openbor_testmove(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14631 {
14632 
14633     entity *e;
14634     DOUBLE x, z;
14635 
14636     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14637 
14638     if(paramCount < 3)
14639     {
14640         goto testmove_error;
14641     }
14642 
14643     if(varlist[0]->vt == VT_PTR)
14644     {
14645         e = (entity *)varlist[0]->ptrVal;
14646     }
14647     else
14648     {
14649         goto testmove_error;
14650     }
14651 
14652     if(FAILED(ScriptVariant_DecimalValue(varlist[1], &x)))
14653     {
14654         goto testmove_error;
14655     }
14656 
14657     if(FAILED(ScriptVariant_DecimalValue(varlist[2], &z)))
14658     {
14659         goto testmove_error;
14660     }
14661 
14662     if(!e)
14663     {
14664         goto testmove_error;
14665     }
14666 
14667     (*pretvar)->lVal = (LONG) testmove(e, e->position.x, e->position.z, x, z);
14668 
14669     return S_OK;
14670 testmove_error:
14671     *pretvar = NULL;
14672     printf("Function testmove(entity, x, z)");
14673     return E_FAIL;
14674 }
14675 
14676 //spriteq_draw(vscreen, 0, MIN_INT, MAX_INT, dx, dy)
openbor_drawspriteq(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14677 HRESULT openbor_drawspriteq(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14678 {
14679 
14680     LONG value[5] = {0, MIN_INT, MAX_INT, 0, 0};
14681     int i;
14682     s_screen *screen;
14683     extern s_screen *vscreen;
14684 
14685     *pretvar = NULL;
14686 
14687     if(paramCount < 1)
14688     {
14689         goto drawsq_error;
14690     }
14691 
14692     if(varlist[0]->vt != VT_PTR && varlist[0]->vt != VT_EMPTY)
14693     {
14694         goto drawsq_error;
14695     }
14696 
14697     if(varlist[0]->ptrVal)
14698     {
14699         screen = (s_screen *)varlist[0]->ptrVal;
14700     }
14701     else
14702     {
14703         screen = vscreen;
14704     }
14705 
14706     for(i = 1; i < paramCount && i <= 5; i++)
14707     {
14708         if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 1)))
14709         {
14710             goto drawsq_error;
14711         }
14712     }
14713 
14714     spriteq_draw(screen, (int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4]);
14715 
14716     return S_OK;
14717 
14718 drawsq_error:
14719     printf("Function drawspriteq needs a valid screen handle and all other paramaters must be integers.");
14720     return E_FAIL;
14721 
14722 }
14723 
openbor_clearspriteq(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14724 HRESULT openbor_clearspriteq(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14725 {
14726     *pretvar = NULL;
14727     spriteq_clear();
14728     return S_OK;
14729 
14730 }
14731 
14732 // ===== gfxproperty ======
14733 enum gfxproperty_enum
14734 {
14735     _gfx_centerx,
14736     _gfx_centery,
14737     _gfx_height,
14738     _gfx_palette,
14739     _gfx_pixel,
14740     _gfx_pixelformat,
14741     _gfx_srcheight,
14742     _gfx_srcwidth,
14743     _gfx_width,
14744     _gfx_the_end,
14745 };
14746 
mapstrings_gfxproperty(ScriptVariant ** varlist,int paramCount)14747 int mapstrings_gfxproperty(ScriptVariant **varlist, int paramCount)
14748 {
14749     char *propname = NULL;
14750     int prop;
14751 
14752     static const char *proplist[] =
14753     {
14754         "centerx",
14755         "centery",
14756         "height",
14757         "palette",
14758         "pixel",
14759         "pixelformat",
14760         "srcheight",
14761         "srcwidth",
14762         "width",
14763     };
14764 
14765 
14766     if(paramCount < 2)
14767     {
14768         return 1;
14769     }
14770     MAPSTRINGS(varlist[1], proplist, _gfx_the_end,
14771                "Property name '%s' is not supported by gfxproperty.\n");
14772 
14773     return 1;
14774 }
14775 
14776 // getgfxproperty(handle, propertyname, ...);
openbor_getgfxproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)14777 HRESULT openbor_getgfxproperty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
14778 {
14779     s_screen *screen;
14780     s_sprite *sprite;
14781     s_bitmap *bitmap;
14782     LONG value[2] = {0, 0}, v;
14783     void *handle;
14784     int i, x, y;
14785 
14786     if(paramCount < 2)
14787     {
14788         goto ggp_error;
14789     }
14790 
14791     mapstrings_gfxproperty(varlist, paramCount);
14792 
14793     if(varlist[0]->vt != VT_PTR)
14794     {
14795         goto ggp_error;
14796     }
14797 
14798     handle = varlist[0]->ptrVal;
14799 
14800     if(!handle)
14801     {
14802         goto ggp_error;
14803     }
14804 
14805     screen = (s_screen *)handle;
14806     sprite = (s_sprite *)handle;
14807     bitmap = (s_bitmap *)handle;
14808 
14809     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
14810 
14811 
14812     switch(varlist[1]->lVal)
14813     {
14814     case _gfx_width:
14815         switch(screen->magic)
14816         {
14817         case screen_magic:
14818             (*pretvar)->lVal = screen->width;
14819             break;
14820         case sprite_magic:
14821             (*pretvar)->lVal = sprite->width;
14822             break;
14823         case bitmap_magic:
14824             (*pretvar)->lVal = bitmap->width;
14825             break;
14826         default:
14827             goto ggp_error2;
14828         }
14829         break;
14830     case _gfx_height:
14831         switch(screen->magic)
14832         {
14833         case screen_magic:
14834             (*pretvar)->lVal = screen->height;
14835             break;
14836         case sprite_magic:
14837             (*pretvar)->lVal = sprite->height;
14838             break;
14839         case bitmap_magic:
14840             (*pretvar)->lVal = bitmap->height;
14841             break;
14842         default:
14843             goto ggp_error2;
14844         }
14845         break;
14846     case _gfx_srcwidth:
14847         switch(screen->magic)
14848         {
14849         case sprite_magic:
14850             (*pretvar)->lVal = sprite->srcwidth;
14851             break;
14852         case screen_magic:
14853             (*pretvar)->lVal = screen->width;
14854             break;
14855         case bitmap_magic:
14856             (*pretvar)->lVal = bitmap->width;
14857             break;
14858         default:
14859             goto ggp_error2;
14860         }
14861         break;
14862     case _gfx_srcheight:
14863         switch(screen->magic)
14864         {
14865         case sprite_magic:
14866             (*pretvar)->lVal = sprite->srcheight;
14867             break;
14868         case screen_magic:
14869             (*pretvar)->lVal = screen->height;
14870             break;
14871         case bitmap_magic:
14872             (*pretvar)->lVal = bitmap->height;
14873             break;
14874         default:
14875             goto ggp_error2;
14876         }
14877         break;
14878     case _gfx_centerx:
14879         switch(screen->magic)
14880         {
14881         case screen_magic:
14882         case bitmap_magic:
14883             (*pretvar)->lVal = 0;
14884             break;
14885         case sprite_magic:
14886             (*pretvar)->lVal = sprite->centerx;
14887             break;
14888         default:
14889             goto ggp_error2;
14890         }
14891         break;
14892     case _gfx_centery:
14893         switch(screen->magic)
14894         {
14895         case screen_magic:
14896         case bitmap_magic:
14897             (*pretvar)->lVal = 0;
14898             break;
14899         case sprite_magic:
14900             (*pretvar)->lVal = sprite->centery;
14901             break;
14902         default:
14903             goto ggp_error2;
14904         }
14905         break;
14906     case _gfx_palette:
14907         ScriptVariant_ChangeType(*pretvar, VT_PTR);
14908         switch(screen->magic)
14909         {
14910         case screen_magic:
14911             (*pretvar)->ptrVal = (VOID *)screen->palette;
14912             break;
14913         case sprite_magic:
14914             (*pretvar)->ptrVal = (VOID *)sprite->palette;
14915             break;
14916         case bitmap_magic:
14917             (*pretvar)->ptrVal = (VOID *)bitmap->palette;
14918             break;
14919         default:
14920             goto ggp_error2;
14921         }
14922         break;
14923     case _gfx_pixelformat:
14924         switch(screen->magic)
14925         {
14926         case screen_magic:
14927             (*pretvar)->lVal = screen->pixelformat;
14928             break;
14929         case sprite_magic:
14930             (*pretvar)->lVal = sprite->pixelformat;
14931             break;
14932         case bitmap_magic:
14933             (*pretvar)->lVal = bitmap->pixelformat;
14934             break;
14935         default:
14936             goto ggp_error2;
14937         }
14938         break;
14939     case _gfx_pixel:
14940         if(paramCount < 4)
14941         {
14942             goto ggp_error3;
14943         }
14944         for(i = 2; i < 4; i++)
14945         {
14946             if(FAILED(ScriptVariant_IntegerValue(varlist[i], value + i - 2)))
14947             {
14948                 goto ggp_error4;
14949             }
14950         }
14951         x = value[0];
14952         y = value[1];
14953         switch(screen->magic)
14954         {
14955         case bitmap_magic: //As long as the two structures are identical...
14956         case screen_magic:
14957             if(x < 0 || x >= screen->width || y < 0 || y >= screen->height)
14958             {
14959                 v = 0;
14960             }
14961             else
14962             {
14963                 switch(screen->pixelformat)
14964                 {
14965                 case PIXEL_8:
14966                 case PIXEL_x8:
14967                     v = (LONG)(((unsigned char *)screen->data)[y * screen->width + x]);
14968                     break;
14969                 case PIXEL_16:
14970                     v = (LONG)(((unsigned short *)screen->data)[y * screen->width + x]);
14971                     break;
14972                 case PIXEL_32:
14973                     v = (LONG)(((unsigned *)screen->data)[y * screen->width + x]);
14974                     break;
14975                 default:
14976                     v = 0;
14977                 }
14978             }
14979             break;
14980         case sprite_magic:
14981             if(x < 0 || x >= sprite->width || y < 0 || y >= sprite->height)
14982             {
14983                 v = 0;
14984             }
14985             else
14986             {
14987                 v = (LONG)sprite_get_pixel(sprite, x, y);
14988             }
14989             break;
14990         default:
14991             goto ggp_error2;
14992         }
14993         (*pretvar)->lVal = v;
14994         break;
14995     default:
14996         break;
14997 
14998     }
14999 
15000     return S_OK;
15001 
15002 ggp_error:
15003     printf("Function getgfxproperty must have a valid handle and a property name.\n");
15004     *pretvar = NULL;
15005     return E_FAIL;
15006 ggp_error2:
15007     printf("Function getgfxproperty encountered an invalid handle.\n");
15008     *pretvar = NULL;
15009     return E_FAIL;
15010 ggp_error3:
15011     printf("You need to specify x, y value for getgfxproperty.\n");
15012     *pretvar = NULL;
15013     return E_FAIL;
15014 ggp_error4:
15015     printf("Invalid x or y value for getgfxproperty.\n");
15016     *pretvar = NULL;
15017     return E_FAIL;
15018 }
15019 
15020 //allocscript(name, comment);
openbor_allocscript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15021 HRESULT openbor_allocscript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15022 {
15023     Script *ns;
15024     char *name = NULL, *comment = NULL;
15025 
15026     ns = malloc(sizeof(Script));
15027 
15028     if(ns == NULL)
15029     {
15030         goto as_error;
15031     }
15032 
15033     if(paramCount >= 1 && varlist[0]->vt == VT_STR)
15034     {
15035         name = (char *)StrCache_Get(varlist[0]->strVal);
15036     }
15037     if(paramCount >= 2 && varlist[1]->vt == VT_STR)
15038     {
15039         comment = (char *)StrCache_Get(varlist[1]->strVal);
15040     }
15041 
15042     Script_Init(ns, name, comment, 1);
15043 
15044     List_InsertAfter(&scriptheap, (void *)ns, "openbor_allocscript");
15045 
15046     ScriptVariant_ChangeType(*pretvar, VT_PTR);
15047     (*pretvar)->ptrVal = (VOID *)ns;
15048     return S_OK;
15049 
15050 as_error:
15051     printf("Function allocscript failed to alloc enough memory.\n");
15052     (*pretvar) = NULL;
15053     return E_FAIL;
15054 }
15055 
15056 //loadscript(handle, path);
openbor_loadscript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15057 HRESULT openbor_loadscript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15058 {
15059     Script *ns = NULL;
15060     char *path = NULL;
15061     int load_script(Script * script, char * file);
15062 
15063     (*pretvar) = NULL;
15064 
15065     if(paramCount >= 1 && varlist[0]->vt == VT_PTR)
15066     {
15067         ns = (Script *)varlist[0]->ptrVal;
15068     }
15069     if(ns == NULL || ns->magic != script_magic)
15070     {
15071         goto ls_error;
15072     }
15073     if(paramCount >= 2 && varlist[1]->vt == VT_STR)
15074     {
15075         path = (char *)StrCache_Get(varlist[1]->strVal);
15076     }
15077     if(path == NULL)
15078     {
15079         goto ls_error;
15080     }
15081 
15082     load_script(ns, path);
15083     //Script_Init(ns, name, comment, 1);
15084     //if(!load_script(ns, path)) goto ls_error2;
15085 
15086     return S_OK;
15087 
15088 ls_error:
15089     printf("Function loadscript requires a valid script handle and a path.\n");
15090     return E_FAIL;
15091 }
15092 
15093 //compilescript(handle);
openbor_compilescript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15094 HRESULT openbor_compilescript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15095 {
15096     Script *ns = NULL;
15097 
15098     (*pretvar) = NULL;
15099 
15100     if(paramCount >= 1 && varlist[0]->vt == VT_PTR)
15101     {
15102         ns = (Script *)varlist[0]->ptrVal;
15103     }
15104     if(ns == NULL || ns->magic != script_magic)
15105     {
15106         goto cs_error;
15107     }
15108 
15109     Script_Compile(ns);
15110 
15111     return S_OK;
15112 
15113 cs_error:
15114     printf("Function compilescript requires a valid script handle.\n");
15115     return E_FAIL;
15116 }
15117 
15118 //executescript(handle);
openbor_executescript(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15119 HRESULT openbor_executescript(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15120 {
15121     Script *ns = NULL;
15122 
15123     (*pretvar) = NULL;
15124 
15125     if(paramCount >= 1 && varlist[0]->vt == VT_PTR)
15126     {
15127         ns = (Script *)varlist[0]->ptrVal;
15128     }
15129     if(ns == NULL || ns->magic != script_magic)
15130     {
15131         goto cs_error;
15132     }
15133 
15134     Script_Execute(ns);
15135 
15136     return S_OK;
15137 
15138 cs_error:
15139     printf("Function executescript requires a valid script handle.\n");
15140     return E_FAIL;
15141 }
15142 
15143 
15144 //loadgamefile() //only reload saved level file from saves
openbor_loadgamefile(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15145 HRESULT openbor_loadgamefile(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15146 {
15147     loadGameFile();
15148     *pretvar = NULL;
15149     return S_OK;
15150 }
15151 
15152 //finishlevel()
openbor_finishlevel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15153 HRESULT openbor_finishlevel(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15154 {
15155     *pretvar = NULL;
15156     level->force_finishlevel = 1;
15157     return S_OK;
15158 }
15159 
15160 //gameover()
openbor_gameover(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15161 HRESULT openbor_gameover(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15162 {
15163     *pretvar = NULL;
15164     level->force_gameover = 1;
15165     return S_OK;
15166 }
15167 
15168 //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)15169 HRESULT openbor_gotomainmenu(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15170 {
15171     LONG ltemp = 0;
15172 
15173     *pretvar = NULL;
15174 
15175     if(paramCount >= 1 && FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)) )
15176     {
15177         return E_FAIL;
15178     }
15179 
15180     goto_mainmenu((LONG)ltemp);
15181 
15182     return S_OK;
15183 }
15184 
15185 //playgame(set, usesave?)
openbor_playgame(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15186 HRESULT openbor_playgame(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15187 {
15188     LONG lset = 0, lsave = -1;
15189     *pretvar = NULL;
15190 
15191     if(paramCount >= 1 && FAILED(ScriptVariant_IntegerValue(varlist[0], &lset)) )
15192     {
15193         goto pg_error;
15194     }
15195     if(paramCount >= 2 && FAILED(ScriptVariant_IntegerValue(varlist[1], &lsave)) )
15196     {
15197         goto pg_error;
15198     }
15199 
15200 
15201     useSave = lsave;
15202     useSet = lset;
15203     endgame = 1;
15204 
15205     return S_OK;
15206 
15207 pg_error:
15208     *pretvar = NULL;
15209     return E_FAIL;
15210 }
15211 
15212 //getrecordingstatus() it returns 0 = stop, 1 = rec, 2 = play, 4 = free buffer
openbor_getrecordingstatus(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15213 HRESULT openbor_getrecordingstatus(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) {
15214     ScriptVariant_Clear(*pretvar);
15215     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15216     (*pretvar)->lVal = (LONG)playrecstatus->status;
15217     return S_OK;
15218 }
15219 
15220 //recordinputs(value) -> 0 = stop, 1 = rec, 2 = play, 4 = free buffer
openbor_recordinputs(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15221 HRESULT openbor_recordinputs(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15222 {
15223     int ltemp;
15224 
15225     *pretvar = NULL;
15226     if( paramCount < 1 && varlist[0]->vt != VT_INTEGER )
15227     {
15228         return E_FAIL;
15229     }
15230 
15231     ltemp = (int)varlist[0]->lVal;
15232     switch(ltemp)
15233     {
15234         case A_REC_STOP:
15235             stopRecordInputs();
15236             break;
15237         case A_REC_REC:
15238             if( paramCount < 3 || varlist[1]->vt != VT_STR || varlist[2]->vt != VT_STR )
15239             {
15240                 printf("Function recordinputs requires a pathname and filename parameters.\n");
15241                 return E_FAIL;
15242             }
15243             strcpy(playrecstatus->path,(char*)StrCache_Get(varlist[1]->strVal));
15244             strcpy(playrecstatus->filename,(char*)StrCache_Get(varlist[2]->strVal));
15245             //debug_printf("%s/%s",(char*)StrCache_Get(varlist[1]->strVal),(char*)StrCache_Get(varlist[2]->strVal));
15246             stopRecordInputs();
15247             playrecstatus->status = A_REC_REC;
15248             recordInputs();
15249             break;
15250         case A_REC_PLAY:
15251             if( paramCount < 3 || varlist[1]->vt != VT_STR || varlist[2]->vt != VT_STR )
15252             {
15253                 printf("Function recordinputs requires a pathname and filename parameters.\n");
15254                 return E_FAIL;
15255             }
15256             strcpy(playrecstatus->path,(char*)StrCache_Get(varlist[1]->strVal));
15257             strcpy(playrecstatus->filename,(char*)StrCache_Get(varlist[2]->strVal));
15258             stopRecordInputs();
15259             playrecstatus->status = A_REC_PLAY;
15260             playRecordedInputs();
15261             break;
15262         case A_REC_FREE:
15263             freeRecordedInputs();
15264             break;
15265     }
15266 
15267     return S_OK;
15268 }
15269 
15270 // getsaveinfo(set, prop);
openbor_getsaveinfo(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)15271 HRESULT openbor_getsaveinfo(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount)
15272 {
15273     LONG ltemp;
15274     s_savelevel *slot;
15275     char *prop;
15276     if(paramCount < 2)
15277     {
15278         goto gsi_error;
15279     }
15280 
15281     if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ltemp)) || varlist[1]->vt != VT_STR)
15282     {
15283         goto gsi_error;
15284     }
15285 
15286     if(!savelevel)
15287     {
15288         ScriptVariant_Clear(*pretvar);
15289         return S_OK;
15290     }
15291 
15292     slot = savelevel + ltemp;
15293     prop = (char *)StrCache_Get(varlist[1]->strVal);
15294 
15295     ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
15296     if(0 == stricmp(prop, "flag"))
15297     {
15298         (*pretvar)->lVal = (LONG)slot->flag;
15299     }
15300     else if(0 == stricmp(prop, "level"))
15301     {
15302         (*pretvar)->lVal = (LONG)slot->level;
15303     }
15304     else if(0 == stricmp(prop, "stage"))
15305     {
15306         (*pretvar)->lVal = (LONG)slot->stage;
15307     }
15308     else if(0 == stricmp(prop, "set"))
15309     {
15310         (*pretvar)->lVal = (LONG)slot->which_set;
15311     }
15312     else if(0 == stricmp(prop, "times_completed"))
15313     {
15314         (*pretvar)->lVal = (LONG)slot->times_completed;
15315     }
15316     else if(0 == stricmp(prop, "score"))
15317     {
15318         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
15319         {
15320             goto gsi_error;
15321         }
15322         (*pretvar)->lVal = (LONG)slot->pScores[ltemp];
15323     }
15324     else if(0 == stricmp(prop, "lives"))
15325     {
15326         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
15327         {
15328             goto gsi_error;
15329         }
15330         (*pretvar)->lVal = (LONG)slot->pLives[ltemp];
15331     }
15332     else if(0 == stricmp(prop, "credits"))
15333     {
15334         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
15335         {
15336             goto gsi_error;
15337         }
15338         (*pretvar)->lVal = (LONG)(noshare ? slot->credits : slot->pCredits[ltemp]);
15339     }
15340     else if(0 == stricmp(prop, "name"))
15341     {
15342         ScriptVariant_ChangeType(*pretvar, VT_STR);
15343         (*pretvar)->strVal = StrCache_CreateNewFrom(slot->dName);
15344     }
15345     else if(0 == stricmp(prop, "playername"))
15346     {
15347         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
15348         {
15349             goto gsi_error;
15350         }
15351         ScriptVariant_ChangeType(*pretvar, VT_STR);
15352         (*pretvar)->strVal = StrCache_CreateNewFrom(slot->pName[ltemp]);
15353     }
15354     else if(0 == stricmp(prop, "health"))
15355     {
15356         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
15357         {
15358             goto gsi_error;
15359         }
15360         (*pretvar)->lVal = (LONG)slot->pSpawnhealth[ltemp];
15361     }
15362     else if(0 == stricmp(prop, "mp"))
15363     {
15364         if(paramCount < 3 || FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) )
15365         {
15366             goto gsi_error;
15367         }
15368         (*pretvar)->lVal = (LONG)slot->pSpawnmp[ltemp];
15369     }
15370     else
15371     {
15372         goto gsi_error;
15373     }
15374     return S_OK;
15375 
15376 gsi_error:
15377     *pretvar = NULL;
15378     return E_FAIL;
15379 }
15380 
15381