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