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 macro for string mapping
38 #define MAPSTRINGS(VAR, LIST, MAXINDEX, FAILMSG) \
39 if(VAR->vt == VT_STR) { \
40 	propname = (char*)StrCache_Get(VAR->strVal); \
41 	prop = searchList(LIST, propname, MAXINDEX); \
42 	if(prop >= 0) { \
43 		ScriptVariant_ChangeType(VAR, VT_INTEGER); \
44 		VAR->lVal = prop; \
45 	} else { printf(FAILMSG, propname); } \
46 }
47 
48 extern int			  PLAYER_MIN_Z;
49 extern int			  PLAYER_MAX_Z;
50 extern int			  BGHEIGHT;
51 extern int            MAX_WALL_HEIGHT;
52 extern int			  SAMPLE_GO;
53 extern int			  SAMPLE_BEAT;
54 extern int			  SAMPLE_BLOCK;
55 extern int			  SAMPLE_INDIRECT;
56 extern int			  SAMPLE_GET;
57 extern int			  SAMPLE_GET2;
58 extern int			  SAMPLE_FALL;
59 extern int			  SAMPLE_JUMP;
60 extern int			  SAMPLE_PUNCH;
61 extern int			  SAMPLE_1UP;
62 extern int			  SAMPLE_TIMEOVER;
63 extern int			  SAMPLE_BEEP;
64 extern int			  SAMPLE_BEEP2;
65 extern int			  SAMPLE_BIKE;
66 extern int            current_palette;
67 extern s_player       player[4];
68 extern s_savedata     savedata;
69 extern s_savelevel    savelevel[MAX_DIFFICULTIES];
70 extern s_savescore    savescore;
71 extern s_level        *level;
72 extern entity         *self;
73 extern int            *animspecials;
74 extern int            *animattacks;
75 extern int            *animfollows;
76 extern int            *animpains;
77 extern int            *animfalls;
78 extern int            *animrises;
79 extern int            *animriseattacks;
80 extern int            *animdies;
81 extern int            *animidles;
82 extern int            *animwalks;
83 extern int            *animbackwalks;
84 extern int            *animups;
85 extern int            *animdowns;
86 extern int            noshare;
87 extern int            credits;
88 extern char           musicname[128];
89 extern float          musicfade[2];
90 extern int            musicloop;
91 extern u32            musicoffset;
92 extern int            models_cached;
93 
94 extern unsigned char* blendings[MAX_BLENDINGS];
95 extern int            current_palette;
96 s_variantnode** global_var_list = NULL;
97 Script* pcurrentscript = NULL;//used by local script functions
98 List theFunctionList;
99 static List   scriptheap;
100 static s_spawn_entry spawnentry;
101 extern s_drawmethod plainmethod;
102 static s_drawmethod drawmethod;
103 //fake 3d draw
104 static gfx_entry	texture;
105 #define	vert_buf_size	256
106 static  vert2d		verts[vert_buf_size];
107 
108 
109 int max_global_var_index = -1;
110 
111 ScriptVariant* indexed_var_list = NULL;
112 int            max_global_vars = MAX_GLOBAL_VAR;
113 int            max_indexed_vars = 0;
114 int            max_entity_vars = 0;
115 int            max_script_vars = 0;
116 
117 
118 //this function should be called before all script methods, for once
Script_Global_Init()119 void Script_Global_Init()
120 {
121 	ptrdiff_t i;
122 	size_t csize, psize;
123 	if(max_global_vars>0)
124 	{
125 		psize = (sizeof(s_variantnode*) * max_global_vars);
126 		csize = psize + (sizeof(s_variantnode) * max_global_vars);
127 		global_var_list = malloc(csize);
128 		assert(global_var_list != NULL);
129 		memset(global_var_list, 0, csize);
130 		for (i=0; i < max_global_vars; i++) {
131 			global_var_list[i] = (s_variantnode*) (((char*) global_var_list) + psize + (i * sizeof(s_variantnode)));
132 		}
133 	}
134 	/*
135 	for(i=0; i<max_global_vars; i++)
136 	{
137 		global_var_list[i] = malloc(sizeof(s_variantnode));
138 		assert(global_var_list[i] != NULL);
139 		memset(global_var_list[i], 0, sizeof(s_variantnode));
140 	} */
141 	max_global_var_index = -1;
142 	memset(&spawnentry, 0, sizeof(s_spawn_entry));//clear up the spawn entry
143 	drawmethod = plainmethod;
144 
145 	if(max_indexed_vars>0)
146 	{
147 		csize = sizeof(ScriptVariant)*(max_indexed_vars + 1);
148 		indexed_var_list = (ScriptVariant*)malloc(csize);
149 		assert(indexed_var_list != NULL);
150 		memset(indexed_var_list, 0, csize);
151 	}
152 	List_Init(&theFunctionList);
153 	Script_LoadSystemFunctions();
154 	List_Init(&scriptheap);
155 	ImportCache_Init();
156 }
157 
158 //this function should only be called when the engine is shutting down
Script_Global_Clear()159 void Script_Global_Clear()
160 {
161 	int i, size;
162 	List_Clear(&theFunctionList);
163 	// dump all un-freed variants
164 	size = List_GetSize(&scriptheap);
165 	if(size>0) printf("\nWarning: %d script variants are not freed, dumping...\n", size);
166 	for(i=0, List_Reset(&scriptheap); i<size; List_GotoNext(&scriptheap), i++)
167 	{
168 		printf("%s\n", List_GetName(&scriptheap));
169 		free(List_Retrieve(&scriptheap));
170 	}
171 	List_Clear(&scriptheap);
172 	// clear the global list
173 	if(global_var_list)
174 	{
175 		for(i=0; i<max_global_vars; i++)
176 		{
177 			if(global_var_list[i] != NULL) {
178 				ScriptVariant_Clear(&(global_var_list[i]->value));
179 				//free(global_var_list[i]);
180 			}
181 			//global_var_list[i] = NULL;
182 		}
183 		free(global_var_list);
184 		global_var_list = NULL;
185 	}
186 	if(indexed_var_list)
187 	{
188 		for(i=0; i<max_indexed_vars; i++) ScriptVariant_Clear(indexed_var_list+i);
189 		free(indexed_var_list);
190 	}
191 	indexed_var_list = NULL;
192 	max_global_var_index = -1;
193 	memset(&spawnentry, 0, sizeof(s_spawn_entry));//clear up the spawn entry
194 	StrCache_Clear();
195 	ImportCache_Clear();
196 }
197 
198 
Script_Get_Global_Variant(char * theName)199 ScriptVariant* Script_Get_Global_Variant(char* theName)
200 {
201 	int i;
202 
203 	if(!theName || !theName[0]) return NULL;
204 
205 	for(i=0; i<=max_global_var_index; i++){
206 		if(!global_var_list[i]->owner &&
207 		   strcmp(theName, global_var_list[i]->key)==0)
208 			return &(global_var_list[i]->value);
209 	}
210 
211 	return NULL;
212 }
213 
214 // local function
_set_var(char * theName,ScriptVariant * var,Script * owner)215 int _set_var(char* theName, ScriptVariant* var, Script* owner)
216 {
217 	int i;
218 	s_variantnode* tempnode;
219 	if(!theName[0] || !theName || (owner && !owner->initialized)) return 0;
220 	// search the name
221 	for(i=0; i<=max_global_var_index; i++)
222 	{
223 		if(global_var_list[i]->owner == owner &&
224 		   !strcmp(theName, global_var_list[i]->key))
225 		{
226 			if(var->vt != VT_EMPTY)
227 				ScriptVariant_Copy(&(global_var_list[i]->value), var);
228 			else // set to null, so remove this value
229 			{
230 				/// re-adjust bounds, swap with last node
231 				if(i!=max_global_var_index)
232 				{
233 					tempnode = global_var_list[i];
234 					global_var_list[i] = global_var_list[max_global_var_index];
235 					global_var_list[max_global_var_index] = tempnode;
236 				}
237 				max_global_var_index--;
238 			}
239 			return 1;
240 		}
241 	}
242 	if(var->vt == VT_EMPTY) return 1;
243 	// all slots are taken
244 	if(max_global_var_index >= max_global_vars-1)
245 		return 0;
246 	// so out of bounds, find another slot
247 	else
248 	{
249 		++max_global_var_index;
250 		ScriptVariant_Copy(&(global_var_list[max_global_var_index]->value), var);
251 		global_var_list[max_global_var_index]->owner = owner;
252 		strcpy(global_var_list[max_global_var_index]->key, theName);
253 		return 1;
254 	}
255 }// end of _set_var
256 
Script_Set_Global_Variant(char * theName,ScriptVariant * var)257 int Script_Set_Global_Variant(char* theName, ScriptVariant* var)
258 {
259 	return _set_var(theName, var, NULL);
260 }
261 
Script_Local_Clear()262 void Script_Local_Clear()
263 {
264 	int i;
265 	//s_variantnode* tempnode;
266 	if(!pcurrentscript) return;
267 	for(i=0; i<=max_global_var_index; i++)
268 	{
269 		if(global_var_list[i]->owner == pcurrentscript)
270 		{
271 			/*
272 			printf("local var %s cleared\n", global_var_list[i]->key);
273 			if(i!=max_global_var_index)
274 			{
275 				tempnode = global_var_list[i];
276 				global_var_list[i] = global_var_list[max_global_var_index];
277 				global_var_list[max_global_var_index] = tempnode;
278 			}
279 			max_global_var_index--;*/
280 			ScriptVariant_Clear(&global_var_list[i]->value);
281 		}
282 	}
283 	if(pcurrentscript->vars)
284 		for(i=0; i<max_script_vars; i++) ScriptVariant_Clear(pcurrentscript->vars+i);
285 }
286 
287 
Script_Get_Local_Variant(char * theName)288 ScriptVariant* Script_Get_Local_Variant(char* theName)
289 {
290 	int i;
291 
292 	if(!pcurrentscript || !pcurrentscript->initialized ||
293 	   !theName || !theName[0]) return NULL;
294 
295 	for(i=0; i<=max_global_var_index; i++)
296 	{
297 		if(global_var_list[i]->owner == pcurrentscript &&
298 		   strcmp(theName, global_var_list[i]->key)==0)
299 			return &(global_var_list[i]->value);
300 	}
301 
302 	return NULL;
303 }
304 
Script_Set_Local_Variant(char * theName,ScriptVariant * var)305 int Script_Set_Local_Variant(char* theName, ScriptVariant* var)
306 {
307 	if(!pcurrentscript) return 0;
308 	return _set_var(theName, var, pcurrentscript);
309 }
310 
alloc_script()311 Script* alloc_script()
312 {
313 	int i;
314 	Script* pscript = (Script*)malloc(sizeof(Script));
315 	memset(pscript, 0, sizeof(Script));
316 	if(max_script_vars>0)
317 	{
318 		pscript->vars = (ScriptVariant*)malloc(sizeof(ScriptVariant)*max_script_vars);
319 		for(i=0; i<max_script_vars; i++) ScriptVariant_Init(pscript->vars+i);
320 	}
321 	return pscript;
322 }
323 
Script_Init(Script * pscript,char * theName,int first)324 void Script_Init(Script* pscript, char* theName, int first)
325 {
326 	int i;
327 	if(first)
328 	{
329 		memset(pscript, 0, sizeof(Script));
330 		if(max_script_vars>0)
331 		{
332 			pscript->vars = (ScriptVariant*)malloc(sizeof(ScriptVariant)*max_script_vars);
333 			for(i=0; i<max_script_vars; i++) ScriptVariant_Init(pscript->vars+i);
334 		}
335 	}
336 	if(!theName || !theName[0])  return; // if no name specified, only alloc the variants
337 	pcurrentscript = pscript; //used by local script functions
338 	pscript->pinterpreter = (Interpreter*)malloc(sizeof(Interpreter));
339 	Interpreter_Init(pscript->pinterpreter, theName, &theFunctionList);
340 	pscript->interpreterowner = 1; // this is the owner, important
341 	pscript->initialized = 1;
342 }
343 
344 //safe copy method
Script_Copy(Script * pdest,Script * psrc,int localclear)345 void Script_Copy(Script* pdest, Script* psrc, int localclear)
346 {
347 	if(!psrc->initialized) return;
348 	if(pdest->initialized) Script_Clear(pdest, localclear);
349 	pdest->pinterpreter = psrc->pinterpreter;
350 	pdest->interpreterowner = 0; // dont own it
351 	pdest->initialized = psrc->initialized; //just copy, it should be 1
352 }
353 
Script_Clear(Script * pscript,int localclear)354 void Script_Clear(Script* pscript, int localclear)
355 {
356 	Script* temp;
357 	int i;
358 	ScriptVariant* pvars;
359 
360 	ScriptVariant tempvar;
361 	//Execute clear method
362 	if(pscript->initialized && pscript->pinterpreter->pClearEntry){
363 		temp = pcurrentscript;
364 		pcurrentscript = pscript;
365 
366 		ScriptVariant_Init(&tempvar);
367 		ScriptVariant_ChangeType(&tempvar, VT_INTEGER);
368 		tempvar.lVal = (LONG)localclear;
369 		Script_Set_Local_Variant("localclear", &tempvar);
370 		pscript->pinterpreter->pCurrentInstruction = pscript->pinterpreter->pClearEntry;
371 		if(FAILED( Interpreter_EvaluateCall(pscript->pinterpreter))){
372 			shutdown(1, "Fatal: failed to execute 'clear' in script %s", pscript->pinterpreter->theSymbolTable.name);
373 		}
374 		ScriptVariant_Clear(&tempvar);
375 		Script_Set_Local_Variant("localclear", &tempvar);
376 		pcurrentscript = temp;
377 	}
378 
379 	if(localclear==2 && pscript->vars)
380 	{
381 		for(i=0; i<max_script_vars; i++)
382 		{
383 			ScriptVariant_Clear(pscript->vars+i);
384 		}
385 		free(pscript->vars);
386 		pscript->vars = NULL;
387 	}
388 	if(!pscript->initialized) return;
389 	temp = pcurrentscript;
390 	pcurrentscript = pscript; //used by local script functions
391 	//if it is the owner, free the interpreter
392 	if(pscript->pinterpreter && pscript->interpreterowner){
393 		Interpreter_Clear(pscript->pinterpreter);
394 		free(pscript->pinterpreter);
395 		pscript->pinterpreter = NULL;
396 	}
397 	if(localclear) Script_Local_Clear();
398 	pvars = pscript->vars; // in game clear(localclear!=2) just keep this value
399 	memset(pscript, 0, sizeof(Script));
400 	pscript->vars = pvars; // copy it back
401 	pcurrentscript = temp;
402 }
403 
404 //append part of the script
405 //Because the script might not be initialized in 1 time.
Script_AppendText(Script * pscript,char * text,char * path)406 int Script_AppendText(Script* pscript, char* text, char* path)
407 {
408 	int success;
409 
410 	pcurrentscript = pscript; //used by local script functions
411 	//printf(text);
412 	Interpreter_Reset(pscript->pinterpreter);
413 
414 	success = SUCCEEDED(Interpreter_ParseText(pscript->pinterpreter, text, 1, path));
415 
416 	return success;
417 }
418 
419 //return name of function from pointer to function
Script_GetFunctionName(void * functionRef)420 const char* Script_GetFunctionName(void* functionRef)
421 {
422 	if (functionRef==((void*)system_isempty)) return "isempty";
423 	else if (functionRef==((void*)system_NULL)) return "NULL";
424 	else if (functionRef==((void*)system_rand)) return "rand";
425 	else if (functionRef==((void*)system_maxglobalvarindex)) return "maxglobalvarindex";
426 	else if (functionRef==((void*)system_getglobalvar)) return "getglobalvar";
427 	else if (functionRef==((void*)system_setglobalvar)) return "setglobalvar";
428 	else if (functionRef==((void*)system_getlocalvar)) return "getlocalvar";
429 	else if (functionRef==((void*)system_setlocalvar)) return "setlocalvar";
430 	else if (functionRef==((void*)system_clearglobalvar)) return "clearglobalvar";
431 	else if (functionRef==((void*)system_clearindexedvar)) return "clearindexedvar";
432 	else if (functionRef==((void*)system_clearlocalvar)) return "clearlocalvar";
433 	else if (functionRef==((void*)system_free)) return "free";
434 	else if (functionRef==((void*)openbor_systemvariant)) return "openborvariant";
435 	else if (functionRef==((void*)openbor_changesystemvariant)) return "changeopenborvariant";
436 	else if (functionRef==((void*)openbor_drawstring)) return "drawstring";
437 	else if (functionRef==((void*)openbor_drawstringtoscreen)) return "drawstringtoscreen";
438 	else if (functionRef==((void*)openbor_log)) return "log";
439 	else if (functionRef==((void*)openbor_drawbox)) return "drawbox";
440 	else if (functionRef==((void*)openbor_drawboxtoscreen)) return "drawboxtoscreen";
441 	else if (functionRef==((void*)openbor_drawline)) return "drawline";
442 	else if (functionRef==((void*)openbor_drawlinetoscreen)) return "drawlinetoscreen";
443 	else if (functionRef==((void*)openbor_drawsprite)) return "drawsprite";
444 	else if (functionRef==((void*)openbor_drawspritetoscreen)) return "drawspritetoscreen";
445 	else if (functionRef==((void*)openbor_drawdot)) return "drawdot";
446 	else if (functionRef==((void*)openbor_drawdottoscreen)) return "drawdottoscreen";
447 	else if (functionRef==((void*)openbor_drawscreen)) return "drawscreen";
448 	else if (functionRef==((void*)openbor_changeplayerproperty)) return "changeplayerproperty";
449 	else if (functionRef==((void*)openbor_changeentityproperty)) return "changeentityproperty";
450 	else if (functionRef==((void*)openbor_getplayerproperty)) return "getplayerproperty";
451 	else if (functionRef==((void*)openbor_getentityproperty)) return "getentityproperty";
452 	else if (functionRef==((void*)openbor_tossentity)) return "tossentity";
453 	else if (functionRef==((void*)openbor_clearspawnentry)) return "clearspawnentry";
454 	else if (functionRef==((void*)openbor_setspawnentry)) return "setspawnentry";
455 	else if (functionRef==((void*)openbor_spawn)) return "spawn";
456 	else if (functionRef==((void*)openbor_projectile)) return "projectile";
457 	else if (functionRef==((void*)openbor_transconst)) return "openborconstant";
458 	else if (functionRef==((void*)openbor_playmusic)) return "playmusic";
459 	else if (functionRef==((void*)openbor_fademusic)) return "fademusic";
460 	else if (functionRef==((void*)openbor_setmusicvolume)) return "setmusicvolume";
461 	else if (functionRef==((void*)openbor_setmusictempo)) return "setmusictempo";
462 	else if (functionRef==((void*)openbor_pausemusic)) return "pausemusic";
463 	else if (functionRef==((void*)openbor_playsample)) return "playsample";
464 	else if (functionRef==((void*)openbor_loadsample)) return "loadsample";
465 	else if (functionRef==((void*)openbor_unloadsample)) return "unloadsample";
466 	else if (functionRef==((void*)openbor_fadeout)) return "fadeout";
467 	else if (functionRef==((void*)openbor_playerkeys)) return "playerkeys";
468 	else if (functionRef==((void*)openbor_changepalette)) return "changepalette";
469 	else if (functionRef==((void*)openbor_damageentity)) return "damageentity";
470 	else if (functionRef==((void*)openbor_killentity)) return "killentity";
471 	else if (functionRef==((void*)openbor_findtarget)) return "findtarget";
472 	else if (functionRef==((void*)openbor_checkrange)) return "checkrange";
473 	else if (functionRef==((void*)openbor_gettextobjproperty)) return "gettextobjproperty";
474 	else if (functionRef==((void*)openbor_changetextobjproperty)) return "changetextobjproperty";
475 	else if (functionRef==((void*)openbor_settextobj)) return "settextobj";
476 	else if (functionRef==((void*)openbor_cleartextobj)) return "cleartextobj";
477 	else if (functionRef==((void*)openbor_getbglayerproperty)) return "getbglayerproperty";
478 	else if (functionRef==((void*)openbor_changebglayerproperty)) return "changebglayerproperty";
479 	else if (functionRef==((void*)openbor_getfglayerproperty)) return "getfglayerproperty";
480 	else if (functionRef==((void*)openbor_changefglayerproperty)) return "changefglayerproperty";
481 	else if (functionRef==((void*)openbor_getlevelproperty)) return "getlevelproperty";
482 	else if (functionRef==((void*)openbor_changelevelproperty)) return "changelevelproperty";
483 	else if (functionRef==((void*)openbor_checkhole)) return "checkhole";
484 	else if (functionRef==((void*)openbor_checkwall)) return "checkwall";
485 	else if (functionRef==((void*)openbor_checkplatformbelow)) return "checkplatformbelow";
486 	else if (functionRef==((void*)openbor_openfilestream)) return "openfilestream";
487 	else if (functionRef==((void*)openbor_getfilestreamline)) return "getfilestreamline";
488 	else if (functionRef==((void*)openbor_getfilestreamargument)) return "getfilestreamargument";
489 	else if (functionRef==((void*)openbor_filestreamnextline)) return "filestreamnextline";
490 	else if (functionRef==((void*)openbor_getfilestreamposition)) return "getfilestreamposition";
491 	else if (functionRef==((void*)openbor_setfilestreamposition)) return "setfilestreamposition";
492 	else if (functionRef==((void*)openbor_filestreamappend)) return "filestreamappend";
493 	else if (functionRef==((void*)openbor_createfilestream)) return "createfilestream";
494 	else if (functionRef==((void*)openbor_closefilestream)) return "closefilestream";
495 	else if (functionRef==((void*)openbor_savefilestream)) return "savefilestream";
496 	else if (functionRef==((void*)openbor_getindexedvar)) return "getindexedvar";
497 	else if (functionRef==((void*)openbor_setindexedvar)) return "setindexedvar";
498 	else if (functionRef==((void*)openbor_getscriptvar)) return "getscriptvar";
499 	else if (functionRef==((void*)openbor_setscriptvar)) return "setscriptvar";
500 	else if (functionRef==((void*)openbor_getentityvar)) return "getentityvar";
501 	else if (functionRef==((void*)openbor_setentityvar)) return "setentityvar";
502 	else if (functionRef==((void*)openbor_jumptobranch)) return "jumptobranch";
503 	else if (functionRef==((void*)openbor_changelight)) return "changelight";
504 	else if (functionRef==((void*)openbor_changeshadowcolor)) return "changeshadowcolor";
505 	else if (functionRef==((void*)openbor_bindentity)) return "bindentity";
506 	else if (functionRef==((void*)openbor_array)) return "array";
507 	else if (functionRef==((void*)openbor_size)) return "size";
508 	else if (functionRef==((void*)openbor_get)) return "get";
509 	else if (functionRef==((void*)openbor_set)) return "set";
510 	else if (functionRef==((void*)openbor_allocscreen)) return "allocscreen";
511 	else if (functionRef==((void*)openbor_clearscreen)) return "clearscreen";
512 	else if (functionRef==((void*)openbor_setdrawmethod)) return "setdrawmethod";
513 	else if (functionRef==((void*)openbor_updateframe)) return "updateframe";
514 	else if (functionRef==((void*)openbor_performattack)) return "performattack";
515 	else if (functionRef==((void*)openbor_setidle)) return "setidle";
516 	else if (functionRef==((void*)openbor_getentity)) return "getentity";
517 	else if (functionRef==((void*)openbor_loadmodel)) return "loadmodel";
518 	else if (functionRef==((void*)openbor_loadsprite)) return "loadsprite";
519 	else if (functionRef==((void*)openbor_playgif)) return "playgif";
520 	else if (functionRef==((void*)openbor_strinfirst)) return "strinfirst";
521 	else if (functionRef==((void*)openbor_strinlast)) return "strinlast";
522 	else if (functionRef==((void*)openbor_strleft)) return "strleft";
523 	else if (functionRef==((void*)openbor_strlength)) return "strlength";
524 	else if (functionRef==((void*)openbor_strright)) return "strright";
525 	else if (functionRef==((void*)openbor_getmodelproperty)) return "getmodelproperty";
526 	else if (functionRef==((void*)openbor_changemodelproperty)) return "changemodelproperty";
527 	else if (functionRef==((void*)openbor_rgbcolor)) return "rgbcolor";
528 	else if (functionRef==((void*)openbor_zoom)) return "zoom";
529 	else if (functionRef==((void*)openbor_settexture)) return "settexture";
530 	else if (functionRef==((void*)openbor_setvertex)) return "setvertex";
531 	else if (functionRef==((void*)openbor_trianglelist)) return "trianglelist";
532 	else return "<unknown function>";
533 }
534 
535 //return string mapping function corresponding to a given function
Script_GetStringMapFunction(void * functionRef)536 void* Script_GetStringMapFunction(void* functionRef)
537 {
538 	if (functionRef==((void*)openbor_systemvariant)) return (void*)mapstrings_systemvariant;
539 	else if (functionRef==((void*)openbor_changesystemvariant)) return (void*)mapstrings_changesystemvariant;
540 	else if (functionRef==((void*)openbor_getentityproperty)) return (void*)mapstrings_getentityproperty;
541 	else if (functionRef==((void*)openbor_changeentityproperty)) return (void*)mapstrings_changeentityproperty;
542 	else if (functionRef==((void*)openbor_getplayerproperty)) return (void*)mapstrings_getplayerproperty;
543 	else if (functionRef==((void*)openbor_changeplayerproperty)) return (void*)mapstrings_changeplayerproperty;
544 	else if (functionRef==((void*)openbor_setspawnentry)) return (void*)mapstrings_setspawnentry;
545 	else if (functionRef==((void*)openbor_transconst)) return (void*)mapstrings_transconst;
546 	else if (functionRef==((void*)openbor_playerkeys)) return (void*)mapstrings_playerkeys;
547 	else if (functionRef==((void*)openbor_gettextobjproperty)) return (void*)mapstrings_gettextobjproperty;
548 	else if (functionRef==((void*)openbor_changetextobjproperty)) return (void*)mapstrings_changetextobjproperty;
549 	else if (functionRef==((void*)openbor_getbglayerproperty)) return (void*)mapstrings_getbglayerproperty;
550 	else if (functionRef==((void*)openbor_changebglayerproperty)) return (void*)mapstrings_changebglayerproperty;
551 	else if (functionRef==((void*)openbor_getfglayerproperty)) return (void*)mapstrings_getfglayerproperty;
552 	else if (functionRef==((void*)openbor_changefglayerproperty)) return (void*)mapstrings_changefglayerproperty;
553 	else return NULL;
554 }
555 
556 /* Replace string constants with enum constants at compile time to speed up
557    script execution. */
Script_MapStringConstants(Script * pscript)558 int Script_MapStringConstants(Script* pscript)
559 {
560 	Interpreter* pinterpreter = pscript->pinterpreter;
561 	Instruction* pInstruction, *pInstruction2;
562 	ScriptVariant** params;
563 	//ScriptVariant* var;
564 	void (*pMapstrings)(ScriptVariant**, int);
565 	int i, j, k, size, paramCount;
566 
567 	size = List_GetSize(&(pinterpreter->theInstructionList));
568 	for(i=0; i<size; i++)
569 	{
570 		pInstruction = (Instruction*)(pinterpreter->theInstructionList.solidlist[i]);
571 		if(pInstruction->functionRef)
572 		{
573 			params = (ScriptVariant**)pInstruction->theRefList->solidlist;
574 			paramCount = (int)pInstruction->theRef->lVal;
575 
576 			// Get the pointer to the correct mapstrings function, if one exists.
577 			pMapstrings = Script_GetStringMapFunction(pInstruction->functionRef);
578 			if(pMapstrings)
579 			{
580 				// Call the mapstrings function.
581 				pMapstrings(params, paramCount);
582 
583 				// Find the instruction containing each constant and update its value.
584 				for(j=0; j<paramCount; j++)
585 				{
586 					for(k=i; k>0; k--)
587 					{
588 						pInstruction2 = (Instruction*)(pinterpreter->theInstructionList.solidlist[k]);
589 						if(pInstruction2->theVal2 == params[j])
590 						{
591 							ScriptVariant_Copy(pInstruction2->theVal, pInstruction2->theVal2);
592 							break;
593 						}
594 					}
595 					if(k<0) return 0;
596 				}
597 			}
598 		}
599 	}
600 
601 	return 1;
602 }
603 
604 // replaces the entire instruction list with a new instruction list after optimization
Script_ReplaceInstructionList(Interpreter * pInterpreter,List * newList)605 int Script_ReplaceInstructionList(Interpreter* pInterpreter, List* newList)
606 {
607 	int i, j, newSize = List_GetSize(newList);
608 	Instruction* pInstruction, *pTarget;
609 	Instruction** oldList = (Instruction**)pInterpreter->theInstructionList.solidlist;
610 	List_Solidify(newList);
611 
612 	char buf[256];
613 
614 	for(i=0; i<newSize; i++)
615 	{
616 		pInstruction = (Instruction*)newList->solidlist[i];
617 		if(pInstruction->theJumpTargetIndex >= 0)
618 		{
619 			pTarget = (Instruction*)oldList[pInstruction->theJumpTargetIndex];
620 			for(j=0; j<newSize; j++)
621 			{
622 				if(newList->solidlist[j] == pTarget)
623 				{
624 					pInstruction->theJumpTargetIndex = j;
625 					break;
626 				}
627 			}
628 			// if the jump target isn't found, it must have been removed in an optimization - whoops!
629 			if(j == newSize)
630 			{
631 				Instruction_ToString(pTarget, buf);
632 				printf("Error: jump target %i (%s) not found - overzealous optimization!\n", pInstruction->theJumpTargetIndex, buf);
633 				return 0;
634 			}
635 		}
636 	}
637 
638 	// replace new list with old list
639 	List_Clear(&(pInterpreter->theInstructionList));
640 	memcpy(&(pInterpreter->theInstructionList), newList, sizeof(List));
641 
642 	return 1;
643 }
644 
645 // prints lots of debugging stuff about optimizations that can be made
Script_LowerConstants(Script * pscript)646 void Script_LowerConstants(Script* pscript)
647 {
648 	Interpreter* pinterpreter = pscript->pinterpreter;
649 	Instruction* pInstruction, *pInstruction2;
650 	List* newInstructionList = malloc(sizeof(List));
651 	int i, j, size;
652 
653 	List_Init(newInstructionList);
654 
655 	size = List_GetSize(&(pinterpreter->theInstructionList));
656 
657 	for(i=0; i<size; i++)
658 	{
659 		pInstruction = (Instruction*)(pinterpreter->theInstructionList.solidlist[i]);
660 		if(pInstruction->OpCode == DATA)
661 		{
662 			int numRefs = 0;
663 			for(j=0; j<size; j++)
664 			{
665 				pInstruction2 = (Instruction*)(pinterpreter->theInstructionList.solidlist[j]);
666 				if(pInstruction2->OpCode == LOAD && pInstruction2->theRef == pInstruction->theVal)
667 					numRefs++;
668 			}
669 			//printf("Variable declared, %i references\n", numRefs, pInstruction->theToken->theSource);
670 			//printf("DATA (theVal=0x%08X, theRef=0x%08X)\n", pInstruction->theVal, pInstruction->theRef);
671 			if(numRefs > 0) List_InsertAfter(newInstructionList, pInstruction, NULL);
672 			else
673 			{
674 				printf("Unused variable\n");
675 				free(pInstruction);
676 			}
677 		}
678 		else List_InsertAfter(newInstructionList, pInstruction, NULL);
679 #define ISCONST(x) ((x) && ((x->OpCode==CONSTINT)||(x->OpCode==CONSTSTR)||(x->OpCode==CONSTDBL)))
680 		// Look for constant binary ops
681 		if(pInstruction->OpCode == ADD)
682 		{
683 			Instruction *pSrc1 = NULL, *pSrc2 = NULL;
684 			char buf[1024], buf2[1024], buf3[1024];
685 			for(j=0; j<size; j++)
686 			{
687 				Instruction* tmp = (Instruction*)(pinterpreter->theInstructionList.solidlist[j]);
688 				if(tmp->theVal == pInstruction->theRef || tmp->theVal2 == pInstruction->theRef)   pSrc1 = tmp;
689 				if(tmp->theVal == pInstruction->theRef2 || tmp->theVal2 == pInstruction->theRef2) pSrc2 = tmp;
690 			}
691 
692 			if(ISCONST(pSrc1) && ISCONST(pSrc2))
693 			{
694 				ScriptVariant* sum = ScriptVariant_Add(pSrc1->theVal2, pSrc2->theVal2);
695 				ScriptVariant_ToString(pSrc1->theVal2, buf);
696 		    	ScriptVariant_ToString(pSrc2->theVal2, buf2);
697 		    	ScriptVariant_ToString(sum, buf3);
698 		    	//printf("ADD 0x%08X: %s + %s = %s\n", pInstruction, buf, buf2, buf3);
699 			}
700 #if 0
701 			else if(pSrc1 && pSrc2)
702 			{
703 		    	Instruction_ToString(pSrc1, buf);
704 		    	Instruction_ToString(pSrc2, buf2);
705 		    	printf("ADD 0x%08X: %s + %s\n", pInstruction, buf, buf2);
706 		    }
707 		    else printf("ADD 0x%08X: Non-constant addition?\n");
708 #endif
709 		}
710 #undef ISCONST
711 	}
712 
713 	// replace old instruction list with optimized one (TODO: enable when this function actually does optimizations)
714 	//Script_ReplaceInstructionList(pinterpreter, &newInstructionList);
715 }
716 
717 // detect unused functions in scripts (to save memory)
Script_DetectUnusedFunctions(Script * pScript)718 int Script_DetectUnusedFunctions(Script* pScript)
719 {
720 	Interpreter* pInterpreter = pScript->pinterpreter;
721 	Instruction* pInstruction, *pInstruction2, **instructionList = (Instruction**)pInterpreter->theInstructionList.solidlist;
722 	List newInstructionList;
723 	int i, size = List_GetSize(&(pInterpreter->theInstructionList));
724 
725 	List_Init(&newInstructionList);
726 
727 	for(i=0; i<size; i++)
728 	{
729 		pInstruction = instructionList[i];
730 		// detect function declarations (FIXME: should have an opcode for function declarations other than NOOP)
731 		if(pInstruction->OpCode == NOOP && pInstruction->theToken && strlen(pInstruction->theToken->theSource) > 0)
732 		{
733 			int j, numCalls = 0;
734 
735 			// find all calls to this function
736 			for(j=0; j<size; j++)
737 			{
738 				pInstruction2 = instructionList[j];
739 				if(pInstruction2->OpCode == CALL && pInstruction2->theJumpTargetIndex == i) numCalls++;
740 			}
741 
742 			if(numCalls == 0 && strcmp(pInstruction->theToken->theSource, "main") != 0)
743 			{
744 				printf("Unused function %s()\n", pInstruction->theToken->theSource);
745 				while(instructionList[i]->OpCode != RET) // skip function without adding to new instruction list
746 				{
747 					free(instructionList[i++]);
748 					if(i >= size) {List_Clear(&newInstructionList); return 0;} // this shouldn't happen!
749 				}
750 				free(instructionList[i]); // free the final RET instruction too
751 			}
752 			else List_InsertAfter(&newInstructionList, pInstruction, NULL);
753 		}
754 		else List_InsertAfter(&newInstructionList, pInstruction, NULL);
755 
756 		List_InsertAfter(&newInstructionList, pInstruction, NULL);
757 
758 		//if(pInstruction->theToken) {free(pInstruction->theToken); pInstruction->theToken=NULL;} // TODO: move somewhere else
759 	}
760 
761 	return Script_ReplaceInstructionList(pInterpreter, &newInstructionList);
762 }
763 
764 //should be called only once after parsing text
Script_Compile(Script * pscript)765 int Script_Compile(Script* pscript)
766 {
767 	int result;
768 	if(!pscript || !pscript->pinterpreter) return 1;
769 	//Interpreter_OutputPCode(pscript->pinterpreter, "code");
770 	result = SUCCEEDED(Interpreter_CompileInstructions(pscript->pinterpreter));
771 	if(!result) {Script_Clear(pscript, 1);shutdown(1, "Can't compile script!\n");}
772 	result = Script_MapStringConstants(pscript);
773 	if(!result) {Script_Clear(pscript, 1);shutdown(1, "Can't compile script!\n");}
774 
775 	//result = Script_DetectUnusedFunctions(pscript);
776 	//if(!result) {Script_Clear(pscript, 1);shutdown(1, "Script optimization failed!\n");}
777 	//Script_LowerConstants(pscript);
778 
779 	return result;
780 }
781 
Script_IsInitialized(Script * pscript)782 int Script_IsInitialized(Script* pscript)
783 {
784 	if(pscript && pscript->initialized) pcurrentscript = pscript; //used by local script functions
785 	return pscript->initialized;
786 }
787 
788 //execute the script
Script_Execute(Script * pscript)789 int Script_Execute(Script* pscript)
790 {
791 	int result=S_OK;
792 	Script* temp = pcurrentscript;
793 	pcurrentscript = pscript; //used by local script functions
794 	Interpreter_Reset(pscript->pinterpreter);
795 	result = (int)SUCCEEDED(Interpreter_EvaluateImmediate(pscript->pinterpreter));
796 	pcurrentscript = temp;
797 	if(!result) shutdown(1, "There's an exception while executing script '%s'.\n", pscript->pinterpreter->theSymbolTable.name);
798 	return result;
799 }
800 
801 #ifndef COMPILED_SCRIPT
802 //this method is for debug purpose
Script_Call(Script * pscript,char * method,ScriptVariant * pretvar)803 int Script_Call(Script* pscript, char* method, ScriptVariant* pretvar)
804 {
805 	pcurrentscript = pscript; //used by local script functions
806 	Interpreter_Reset(pscript->pinterpreter);
807 	return (int)SUCCEEDED(Interpreter_Call(pscript->pinterpreter, method, pretvar));
808 }
809 #endif
810 
811 //used by Script_Global_Init
Script_LoadSystemFunctions()812 void Script_LoadSystemFunctions()
813 {
814 	//printf("Loading system script functions....");
815 	//load system functions if we need
816 	List_Reset(&theFunctionList);
817 
818 	List_InsertAfter(&theFunctionList,
819 					  (void*)system_isempty, "isempty");
820 	List_InsertAfter(&theFunctionList,
821 					  (void*)system_NULL, "NULL");
822 	List_InsertAfter(&theFunctionList,
823 					  (void*)system_rand, "rand");
824 	List_InsertAfter(&theFunctionList,
825 					  (void*)system_maxglobalvarindex, "maxglobalvarindex");
826 	List_InsertAfter(&theFunctionList,
827 					  (void*)system_getglobalvar, "getglobalvar");
828 	List_InsertAfter(&theFunctionList,
829 					  (void*)system_setglobalvar, "setglobalvar");
830 	List_InsertAfter(&theFunctionList,
831 					  (void*)system_getlocalvar, "getlocalvar");
832 	List_InsertAfter(&theFunctionList,
833 					  (void*)system_setlocalvar, "setlocalvar");
834 	List_InsertAfter(&theFunctionList,
835 					  (void*)system_clearglobalvar, "clearglobalvar");
836 	List_InsertAfter(&theFunctionList,
837 					  (void*)system_clearindexedvar, "clearindexedvar");
838 	List_InsertAfter(&theFunctionList,
839 					  (void*)system_clearlocalvar, "clearlocalvar");
840 	List_InsertAfter(&theFunctionList,
841 					  (void*)system_free, "free");
842 	List_InsertAfter(&theFunctionList,
843 					  (void*)openbor_systemvariant, "openborvariant");
844 	List_InsertAfter(&theFunctionList,
845 					  (void*)openbor_changesystemvariant, "changeopenborvariant");
846 	List_InsertAfter(&theFunctionList,
847 					  (void*)openbor_drawstring, "drawstring");
848 	List_InsertAfter(&theFunctionList,
849 					  (void*)openbor_drawstringtoscreen, "drawstringtoscreen");
850 	List_InsertAfter(&theFunctionList,
851 					  (void*)openbor_log, "log");
852 	List_InsertAfter(&theFunctionList,
853 					  (void*)openbor_drawbox, "drawbox");
854 	List_InsertAfter(&theFunctionList,
855 					  (void*)openbor_drawboxtoscreen, "drawboxtoscreen");
856 	List_InsertAfter(&theFunctionList,
857 					  (void*)openbor_drawline, "drawline");
858 	List_InsertAfter(&theFunctionList,
859 					  (void*)openbor_drawlinetoscreen, "drawlinetoscreen");
860 	List_InsertAfter(&theFunctionList,
861 					  (void*)openbor_drawsprite, "drawsprite");
862 	List_InsertAfter(&theFunctionList,
863 					  (void*)openbor_drawspritetoscreen, "drawspritetoscreen");
864 	List_InsertAfter(&theFunctionList,
865 					  (void*)openbor_drawdot, "drawdot");
866 	List_InsertAfter(&theFunctionList,
867 					  (void*)openbor_drawdottoscreen, "drawdottoscreen");
868 	List_InsertAfter(&theFunctionList,
869 					  (void*)openbor_drawscreen, "drawscreen");
870 	List_InsertAfter(&theFunctionList,
871 					  (void*)openbor_changeplayerproperty, "changeplayerproperty");
872 	List_InsertAfter(&theFunctionList,
873 					  (void*)openbor_changeentityproperty, "changeentityproperty");
874 	List_InsertAfter(&theFunctionList,
875 					  (void*)openbor_getplayerproperty, "getplayerproperty");
876 	List_InsertAfter(&theFunctionList,
877 					  (void*)openbor_getentityproperty, "getentityproperty");
878 	List_InsertAfter(&theFunctionList,
879 					  (void*)openbor_tossentity, "tossentity");
880 	List_InsertAfter(&theFunctionList,
881 					  (void*)openbor_clearspawnentry, "clearspawnentry");
882 	List_InsertAfter(&theFunctionList,
883 					  (void*)openbor_setspawnentry, "setspawnentry");
884 	List_InsertAfter(&theFunctionList,
885 					  (void*)openbor_spawn, "spawn");
886 	List_InsertAfter(&theFunctionList,
887 					  (void*)openbor_projectile, "projectile");
888 	List_InsertAfter(&theFunctionList,
889 					  (void*)openbor_transconst, "openborconstant");
890 	List_InsertAfter(&theFunctionList,
891 					  (void*)openbor_playmusic, "playmusic");
892 	List_InsertAfter(&theFunctionList,
893 					  (void*)openbor_fademusic, "fademusic");
894 	List_InsertAfter(&theFunctionList,
895 					  (void*)openbor_setmusicvolume, "setmusicvolume");
896 	List_InsertAfter(&theFunctionList,
897 					  (void*)openbor_setmusictempo, "setmusictempo");
898 	List_InsertAfter(&theFunctionList,
899 					  (void*)openbor_pausemusic, "pausemusic");
900 	List_InsertAfter(&theFunctionList,
901 					  (void*)openbor_playsample, "playsample");
902 	List_InsertAfter(&theFunctionList,
903 					  (void*)openbor_loadsample, "loadsample");
904 	List_InsertAfter(&theFunctionList,
905 					  (void*)openbor_unloadsample, "unloadsample");
906 	List_InsertAfter(&theFunctionList,
907 					  (void*)openbor_fadeout, "fadeout");
908 	List_InsertAfter(&theFunctionList,
909 					  (void*)openbor_playerkeys, "playerkeys");
910 	List_InsertAfter(&theFunctionList,
911 					  (void*)openbor_changepalette, "changepalette");
912 	List_InsertAfter(&theFunctionList,
913 					  (void*)openbor_damageentity, "damageentity");
914 	List_InsertAfter(&theFunctionList,
915 					  (void*)openbor_killentity, "killentity");
916 	List_InsertAfter(&theFunctionList,
917 					  (void*)openbor_findtarget, "findtarget");
918 	List_InsertAfter(&theFunctionList,
919 					  (void*)openbor_checkrange, "checkrange");
920 	List_InsertAfter(&theFunctionList,
921 					  (void*)openbor_gettextobjproperty, "gettextobjproperty");
922 	List_InsertAfter(&theFunctionList,
923 					  (void*)openbor_changetextobjproperty, "changetextobjproperty");
924 	List_InsertAfter(&theFunctionList,
925 					  (void*)openbor_settextobj, "settextobj");
926 	List_InsertAfter(&theFunctionList,
927 					  (void*)openbor_cleartextobj, "cleartextobj");
928 	List_InsertAfter(&theFunctionList,
929 					  (void*)openbor_getbglayerproperty, "getbglayerproperty");
930 	List_InsertAfter(&theFunctionList,
931 					  (void*)openbor_changebglayerproperty, "changebglayerproperty");
932 	List_InsertAfter(&theFunctionList,
933 					  (void*)openbor_getfglayerproperty, "getfglayerproperty");
934 	List_InsertAfter(&theFunctionList,
935 					  (void*)openbor_changefglayerproperty, "changefglayerproperty");
936 	List_InsertAfter(&theFunctionList,
937 					  (void*)openbor_getlevelproperty, "getlevelproperty");
938 	List_InsertAfter(&theFunctionList,
939 					  (void*)openbor_changelevelproperty, "changelevelproperty");
940 	List_InsertAfter(&theFunctionList,
941 					  (void*)openbor_checkhole, "checkhole");
942 	List_InsertAfter(&theFunctionList,
943 					  (void*)openbor_checkwall, "checkwall");
944 	List_InsertAfter(&theFunctionList,
945 					  (void*)openbor_checkplatformbelow, "checkplatformbelow");
946 	List_InsertAfter(&theFunctionList,
947 					  (void*)openbor_openfilestream, "openfilestream");
948 	List_InsertAfter(&theFunctionList,
949 					  (void*)openbor_getfilestreamline, "getfilestreamline");
950 	List_InsertAfter(&theFunctionList,
951 					  (void*)openbor_getfilestreamargument, "getfilestreamargument");
952 	List_InsertAfter(&theFunctionList,
953 					  (void*)openbor_filestreamnextline, "filestreamnextline");
954 	List_InsertAfter(&theFunctionList,
955 					  (void*)openbor_getfilestreamposition, "getfilestreamposition");
956 	List_InsertAfter(&theFunctionList,
957 					  (void*)openbor_setfilestreamposition, "setfilestreamposition");
958 	List_InsertAfter(&theFunctionList,
959 					  (void*)openbor_filestreamappend, "filestreamappend");
960 	List_InsertAfter(&theFunctionList,
961 					  (void*)openbor_createfilestream, "createfilestream");
962 	List_InsertAfter(&theFunctionList,
963 					  (void*)openbor_closefilestream, "closefilestream");
964 	List_InsertAfter(&theFunctionList,
965 					  (void*)openbor_savefilestream, "savefilestream");
966 	List_InsertAfter(&theFunctionList,
967 					  (void*)openbor_getindexedvar, "getindexedvar");
968 	List_InsertAfter(&theFunctionList,
969 					  (void*)openbor_setindexedvar, "setindexedvar");
970 	List_InsertAfter(&theFunctionList,
971 					  (void*)openbor_getscriptvar, "getscriptvar");
972 	List_InsertAfter(&theFunctionList,
973 					  (void*)openbor_setscriptvar, "setscriptvar");
974 	List_InsertAfter(&theFunctionList,
975 					  (void*)openbor_getentityvar, "getentityvar");
976 	List_InsertAfter(&theFunctionList,
977 					  (void*)openbor_setentityvar, "setentityvar");
978 	List_InsertAfter(&theFunctionList,
979 					  (void*)openbor_jumptobranch, "jumptobranch");
980 	List_InsertAfter(&theFunctionList,
981 					  (void*)openbor_changelight, "changelight");
982 	List_InsertAfter(&theFunctionList,
983 					  (void*)openbor_changeshadowcolor, "changeshadowcolor");
984 	List_InsertAfter(&theFunctionList,
985 					  (void*)openbor_bindentity, "bindentity");
986 	List_InsertAfter(&theFunctionList,
987 					  (void*)openbor_array, "array");
988 	List_InsertAfter(&theFunctionList,
989 					  (void*)openbor_size, "size");
990 	List_InsertAfter(&theFunctionList,
991 					  (void*)openbor_get, "get");
992 	List_InsertAfter(&theFunctionList,
993 					  (void*)openbor_set, "set");
994 	List_InsertAfter(&theFunctionList,
995 					  (void*)openbor_allocscreen, "allocscreen");
996 	List_InsertAfter(&theFunctionList,
997 					  (void*)openbor_clearscreen, "clearscreen");
998 	List_InsertAfter(&theFunctionList,
999 					  (void*)openbor_setdrawmethod, "setdrawmethod");
1000 	List_InsertAfter(&theFunctionList,
1001 					  (void*)openbor_updateframe, "updateframe");
1002 	List_InsertAfter(&theFunctionList,
1003 					  (void*)openbor_performattack, "performattack");
1004 	List_InsertAfter(&theFunctionList,
1005 					  (void*)openbor_setidle, "setidle");
1006 	List_InsertAfter(&theFunctionList,
1007 					  (void*)openbor_getentity, "getentity");
1008 	List_InsertAfter(&theFunctionList,
1009 					  (void*)openbor_loadmodel, "loadmodel");
1010 	List_InsertAfter(&theFunctionList,
1011 					  (void*)openbor_loadsprite, "loadsprite");
1012 	List_InsertAfter(&theFunctionList,
1013 					  (void*)openbor_playgif, "playgif");
1014 	List_InsertAfter(&theFunctionList,
1015 					  (void*)openbor_strinfirst, "strinfirst");
1016 	List_InsertAfter(&theFunctionList,
1017 					  (void*)openbor_strinlast, "strinlast");
1018 	List_InsertAfter(&theFunctionList,
1019 					  (void*)openbor_strleft, "strleft");
1020 	List_InsertAfter(&theFunctionList,
1021 					  (void*)openbor_strlength, "strlength");
1022 	List_InsertAfter(&theFunctionList,
1023 					  (void*)openbor_strright, "strright");
1024 	List_InsertAfter(&theFunctionList,
1025 					  (void*)openbor_getmodelproperty, "getmodelproperty");
1026 	List_InsertAfter(&theFunctionList,
1027 					  (void*)openbor_changemodelproperty, "changemodelproperty");
1028 	List_InsertAfter(&theFunctionList,
1029 					  (void*)openbor_rgbcolor, "rgbcolor");
1030 	List_InsertAfter(&theFunctionList,
1031 					  (void*)openbor_zoom, "zoom");
1032 	List_InsertAfter(&theFunctionList,
1033 					  (void*)openbor_settexture, "settexture");
1034 	List_InsertAfter(&theFunctionList,
1035 					  (void*)openbor_setvertex, "setvertex");
1036 	List_InsertAfter(&theFunctionList,
1037 					  (void*)openbor_trianglelist, "trianglelist");
1038 	//printf("Done!\n");
1039 
1040 }
1041 
1042 //////////////////////////////////////////////////////////
1043 ////////////   system functions
1044 //////////////////////////////////////////////////////////
1045 //isempty(var);
system_isempty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1046 HRESULT system_isempty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1047 {
1048 	*pretvar = NULL;
1049 	if(paramCount != 1) return E_FAIL;
1050 
1051 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1052 	(*pretvar)->lVal = (LONG)((varlist[0])->vt == VT_EMPTY );
1053 
1054 	return S_OK;
1055 }
1056 //NULL();
system_NULL(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1057 HRESULT system_NULL(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1058 {
1059 	ScriptVariant_Clear(*pretvar);
1060 
1061 	return S_OK;
1062 }
system_rand(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1063 HRESULT system_rand(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1064 {
1065 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1066 	(*pretvar)->lVal = (LONG)rand32();
1067 	return S_OK;
1068 }
1069 //getglobalvar(varname);
system_getglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1070 HRESULT system_getglobalvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1071 {
1072 	ScriptVariant * ptmpvar;
1073 	if(paramCount != 1)
1074 	{
1075 		*pretvar = NULL;
1076 		return E_FAIL;
1077 	}
1078 	if(varlist[0]->vt != VT_STR)
1079 	{
1080 		printf("Function getglobalvar must have a string parameter.\n");
1081 		*pretvar = NULL;
1082 		return E_FAIL;
1083 	}
1084 	ptmpvar = Script_Get_Global_Variant(StrCache_Get(varlist[0]->strVal));
1085 	if(ptmpvar) ScriptVariant_Copy(*pretvar, ptmpvar);
1086 	else ScriptVariant_ChangeType(*pretvar, VT_EMPTY);
1087 	return S_OK;
1088 }
1089 //maxglobalvarindex();
system_maxglobalvarindex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1090 HRESULT system_maxglobalvarindex(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1091 {
1092 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1093 	(*pretvar)->lVal = (LONG)max_global_var_index;
1094 	return S_OK;
1095 }
1096 //setglobalvar(varname, value);
system_setglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1097 HRESULT system_setglobalvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1098 {
1099 	if(paramCount != 2) {
1100 		*pretvar = NULL;
1101 		return E_FAIL;
1102 	}
1103 	if(varlist[0]->vt != VT_STR)
1104 	{
1105 		printf("Function setglobalvar's first parameter must be a string value.\n");
1106 		*pretvar = NULL;
1107 		return E_FAIL;
1108 	}
1109 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1110 
1111 	(*pretvar)->lVal = (LONG)Script_Set_Global_Variant(StrCache_Get(varlist[0]->strVal), (varlist[1]));
1112 
1113 	return S_OK;
1114 }
1115 //getlocalvar(varname);
system_getlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1116 HRESULT system_getlocalvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1117 {
1118 	ScriptVariant *ptmpvar;
1119 
1120 	if(paramCount != 1) {
1121 		*pretvar = NULL;
1122 		return E_FAIL;
1123 	}
1124 	if(varlist[0]->vt != VT_STR)
1125 	{
1126 		printf("Function getlocalvar must have a string parameter.\n");
1127 		*pretvar = NULL;
1128 		return E_FAIL;
1129 	}
1130 	ptmpvar = Script_Get_Local_Variant(StrCache_Get(varlist[0]->strVal));
1131 	if(ptmpvar) ScriptVariant_Copy(*pretvar,  ptmpvar);
1132 	else        ScriptVariant_ChangeType(*pretvar, VT_EMPTY);
1133 	return S_OK;
1134 }
1135 //setlocalvar(varname, value);
system_setlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1136 HRESULT system_setlocalvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1137 {
1138 	if(paramCount < 2) {
1139 		*pretvar = NULL;
1140 		return E_FAIL;
1141 	}
1142 	if(varlist[0]->vt != VT_STR)
1143 	{
1144 		printf("Function setlocalvar's first parameter must be a string value.\n");
1145 		*pretvar = NULL;
1146 		return E_FAIL;
1147 	}
1148 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
1149 
1150 	(*pretvar)->lVal = (LONG)Script_Set_Local_Variant(StrCache_Get(varlist[0]->strVal), varlist[1]);
1151 
1152 	return S_OK;;
1153 }
1154 //clearlocalvar();
system_clearlocalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1155 HRESULT system_clearlocalvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1156 {
1157 	*pretvar = NULL;
1158 	Script_Local_Clear();
1159 	return S_OK;
1160 }
1161 //clearglobalvar();
system_clearglobalvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1162 HRESULT system_clearglobalvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1163 {
1164 	*pretvar = NULL;
1165 	max_global_var_index = -1;
1166 	return S_OK;
1167 }
1168 
1169 //clearindexedvar();
system_clearindexedvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1170 HRESULT system_clearindexedvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1171 {
1172 	int i;
1173 	*pretvar = NULL;
1174 	for(i=0; i<max_indexed_vars; i++) ScriptVariant_Clear(indexed_var_list+i);
1175 	return S_OK;
1176 }
1177 
1178 //free();
system_free(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1179 HRESULT system_free(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1180 {
1181 	*pretvar = NULL;
1182 	if(paramCount<1) return E_FAIL;
1183 	if(List_Includes(&scriptheap, varlist[0]->ptrVal))
1184 	{
1185 		free(List_Retrieve(&scriptheap));
1186 		List_Remove(&scriptheap);
1187 		return S_OK;
1188 	}
1189 	return E_FAIL;
1190 }
1191 //////////////////////////////////////////////////////////
1192 ////////////   openbor functions
1193 //////////////////////////////////////////////////////////
1194 
1195 // ===== openborvariant =====
mapstrings_systemvariant(ScriptVariant ** varlist,int paramCount)1196 void mapstrings_systemvariant(ScriptVariant** varlist, int paramCount)
1197 {
1198 	char* propname;
1199 	int prop;
1200 
1201 	// This enum is replicated in getsyspropertybyindex in openbor.c. If you
1202 	// change one, you must change the other as well!!!!
1203 	enum systemvariant_enum
1204 	{
1205 		_sv_branchname,
1206 		_sv_count_enemies,
1207 		_sv_count_entities,
1208 		_sv_count_npcs,
1209 		_sv_count_players,
1210 		_sv_current_level,
1211 		_sv_current_palette,
1212 		_sv_current_scene,
1213 		_sv_current_set,
1214 		_sv_current_stage,
1215 		_sv_effectvol,
1216 		_sv_elapsed_time,
1217 		_sv_ent_max,
1218 		_sv_game_paused,
1219 		_sv_game_speed,
1220 		_sv_gfx_x_offset,
1221 		_sv_gfx_y_offset,
1222 		_sv_gfx_y_offset_adj,
1223 		_sv_hResolution,
1224 		_sv_in_gameoverscreen,
1225 		_sv_in_halloffamescreen,
1226 		_sv_in_level,
1227 		_sv_in_menuscreen,
1228 		_sv_in_selectscreen,
1229 		_sv_in_showcomplete,
1230 		_sv_in_titlescreen,
1231 		_sv_lasthita,
1232 		_sv_lasthitc,
1233 		_sv_lasthitt,
1234 		_sv_lasthitx,
1235 		_sv_lasthitz,
1236 		_sv_levelheight,
1237 		_sv_levelwidth,
1238 		_sv_lightx,
1239 		_sv_lightz,
1240 		_sv_maxentityvars,
1241 		_sv_maxglobalvars,
1242 		_sv_maxindexedvars,
1243 		_sv_maxplayers,
1244 		_sv_maxscriptvars,
1245 		_sv_models_cached,
1246 		_sv_models_loaded,
1247 		_sv_musicvol,
1248 		_sv_numpalettes,
1249 		_sv_pause,
1250 		_sv_pixelformat,
1251 		_sv_player,
1252 		_sv_player1,
1253 		_sv_player2,
1254 		_sv_player3,
1255 		_sv_player4,
1256 		_sv_player_max_z,
1257 		_sv_player_min_z,
1258 		_sv_shadowalpha,
1259 		_sv_shadowcolor,
1260 		_sv_slowmotion,
1261 		_sv_slowmotion_duration,
1262 		_sv_soundvol,
1263 		_sv_totalram,
1264 		_sv_freeram,
1265 		_sv_usedram,
1266 		_sv_vResolution,
1267 		_sv_xpos,
1268 		_sv_ypos,
1269 		_sv_the_end,
1270 	 };
1271 
1272 	// arranged list, for searching
1273 	static const char* proplist[] = {
1274 		"branchname",
1275 		"count_enemies",
1276 		"count_entities",
1277 		"count_npcs",
1278 		"count_players",
1279 		"current_level",
1280 		"current_palette",
1281 		"current_scene",
1282 		"current_set",
1283 		"current_stage",
1284 		"effectvol",
1285 		"elapsed_time",
1286 		"ent_max",
1287 		"game_paused",
1288 		"game_speed",
1289 		"gfx_x_offset",
1290 		"gfx_y_offset",
1291 		"gfx_y_offset_adj",
1292 		"hResolution",
1293 		"in_gameoverscreen",
1294 		"in_halloffamescreen",
1295 		"in_level",
1296 		"in_menuscreen",
1297 		"in_selectscreen",
1298 		"in_showcomplete",
1299 		"in_titlescreen",
1300 		"lasthita",
1301 		"lasthitc",
1302 		"lasthitt",
1303 		"lasthitx",
1304 		"lasthitz",
1305 		"levelheight",
1306 		"levelwidth",
1307 		"lightx",
1308 		"lightz",
1309 		"maxentityvars",
1310 		"maxglobalvars",
1311 		"maxindexedvars",
1312 		"maxplayers",
1313 		"maxscriptvars",
1314 		"models_cached",
1315 		"models_loaded",
1316 		"musicvol",
1317 		"numpalettes",
1318 		"pause",
1319 		"pixelformat",
1320 		"player",
1321 		"player1",
1322 		"player2",
1323 		"player3",
1324 		"player4",
1325 		"player_max_z",
1326 		"player_min_z",
1327 		"shadowalpha",
1328 		"shadowcolor",
1329 		"slowmotion",
1330 		"slowmotion_duration",
1331 		"soundvol",
1332 		"totalram",
1333 		"freeram",
1334 		"usedram",
1335 		"vResolution",
1336 		"xpos",
1337 		"ypos",
1338 	 };
1339 
1340 	MAPSTRINGS(varlist[0], proplist, _sv_the_end,
1341 		"openborvariant: System variable name not found: '%s'\n");
1342 }
1343 
1344 //sample function, used for getting a system variant
1345 //openborvariant(varname);
openbor_systemvariant(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1346 HRESULT openbor_systemvariant(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1347 {
1348 	//used for getting the index from the enum of properties
1349 	int variantindex = -1;
1350 	//the paramCount used for checking.
1351 	//check it first so the engine wont crash if the list is empty
1352 	if(paramCount != 1)  goto systemvariant_error;
1353 	//call this function's mapstrings function to map string constants to enum values
1354 	mapstrings_systemvariant(varlist, paramCount);
1355 	//the variant name should be here
1356 	//you can check the argument type if you like
1357 	if(varlist[0]->vt == VT_INTEGER)
1358 		variantindex = varlist[0]->lVal;
1359 	else  goto systemvariant_error;
1360 	///////these should be your get method, ///////
1361 	ScriptVariant_Clear(*pretvar);
1362 	if(getsyspropertybyindex(*pretvar, variantindex))
1363 	{
1364 		return S_OK;
1365 	}
1366 	//else if
1367 	//////////////////////////////////////////////
1368 systemvariant_error:
1369 	*pretvar = NULL;
1370 	// we have finshed, so return
1371 	return E_FAIL;
1372 }
1373 
1374 
1375 // ===== changeopenborvariant =====
mapstrings_changesystemvariant(ScriptVariant ** varlist,int paramCount)1376 void mapstrings_changesystemvariant(ScriptVariant** varlist, int paramCount)
1377 {
1378 	char* propname;
1379 	int prop;
1380 
1381 	// This enum is replicated in changesyspropertybyindex in openbor.c. If you
1382 	// change one, you must change the other as well!!!!
1383 	enum changesystemvariant_enum
1384 	{
1385 		_csv_blockade,
1386 		_csv_elapsed_time,
1387 		_csv_gfx_x_offset,
1388 		_csv_gfx_y_offset,
1389 		_csv_gfx_y_offset_adj,
1390 		_csv_lasthita,
1391 		_csv_lasthitc,
1392 		_csv_lasthitt,
1393 		_csv_lasthitx,
1394 		_csv_lasthitz,
1395 		_csv_levelpos,
1396 		_csv_scrollmaxz,
1397 		_csv_scrollminz,
1398 		_csv_slowmotion,
1399 		_csv_slowmotion_duration,
1400 		_csv_smartbomber,
1401 		_csv_textbox,
1402 		_csv_xpos,
1403 		_csv_ypos,
1404 		_csv_the_end,
1405 	 };
1406 
1407 	// arranged list, for searching
1408 	static const char* proplist[] = {
1409 		"blockade",
1410 		"elapsed_time",
1411 		"gfx_x_offset",
1412 		"gfx_y_offset",
1413 		"gfx_y_offset_adj",
1414 		"lasthita",
1415 		"lasthitc",
1416 		"lasthitt",
1417 		"lasthitx",
1418 		"lasthitz",
1419 		"levelpos",
1420 		"scrollmaxz",
1421 		"scrollminz",
1422 		"slowmotion",
1423 		"slowmotion_duration",
1424 		"smartbomber",
1425 		"textbox",
1426 		"xpos",
1427 		"ypos",
1428 	 };
1429 
1430 	 MAPSTRINGS(varlist[0], proplist, _csv_the_end,
1431 		"changeopenborvariant: System variable name not found: '%s'\n");
1432 }
1433 
1434 //used for changing a system variant
1435 //changeopenborvariant(varname, value);
openbor_changesystemvariant(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1436 HRESULT openbor_changesystemvariant(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1437 {
1438 	//used for getting the enum constant corresponding to the desired variable
1439 	int variantindex = 0;
1440 	//reference to the arguments
1441 	ScriptVariant* arg = NULL;
1442 	//the paramCount used for checking.
1443 	//check it first so the engine wont crash if the list is empty
1444 	if(paramCount != 2)   goto changesystemvariant_error;
1445 	// map string constants to enum constants for speed
1446 	mapstrings_changesystemvariant(varlist, paramCount);
1447 	//get the 1st argument
1448 	arg = varlist[0];
1449 	//the variant name should be here
1450 	//you can check the argument type if you like
1451 	if(arg->vt == VT_INTEGER)
1452 		variantindex = arg->lVal;
1453 	else goto changesystemvariant_error;
1454 
1455 	if(changesyspropertybyindex(variantindex, varlist[1]))
1456 	{
1457 		return S_OK;
1458 	}
1459 changesystemvariant_error:
1460 	*pretvar = NULL;
1461 	// we have finshed, so return
1462 	return E_FAIL;
1463 
1464 }
1465 
1466 // use font_printf to draw string
1467 //drawstring(x, y, font, string, z);
openbor_drawstring(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1468 HRESULT openbor_drawstring(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1469 {
1470 	int i;
1471 	char buf[256];
1472 	LONG value[4];
1473 	*pretvar = NULL;
1474 
1475 	if(paramCount < 4) goto drawstring_error;
1476 
1477 	for(i=0; i<3; i++)
1478 	{
1479 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i)))
1480 			goto drawstring_error;
1481 	}
1482 	if(paramCount>4)
1483 	{
1484 		if(FAILED(ScriptVariant_IntegerValue(varlist[4], value+3)))
1485 			goto drawstring_error;
1486 	}
1487 	else value[3] = 0;
1488 	ScriptVariant_ToString(varlist[3], buf);
1489 	font_printf((int)value[0], (int)value[1], (int)value[2], (int)value[3], "%s", buf);
1490 	return S_OK;
1491 
1492 drawstring_error:
1493 	printf("First 3 values must be integer values and 4th value a string: drawstring(int x, int y, int font, value)\n");
1494 	return E_FAIL;
1495 }
1496 
1497 //use screen_printf
1498 //drawstringtoscreen(screen, x, y, font, string);
openbor_drawstringtoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1499 HRESULT openbor_drawstringtoscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1500 {
1501 	int i;
1502 	s_screen* scr;
1503 	char buf[256];
1504 	LONG value[3];
1505 	*pretvar = NULL;
1506 
1507 	if(paramCount != 5) goto drawstring_error;
1508 
1509 	if(varlist[0]->vt!=VT_PTR) goto drawstring_error;
1510 	scr = (s_screen*)varlist[0]->ptrVal;
1511 	if(!scr)  goto drawstring_error;
1512 
1513 	for(i=0; i<3; i++)
1514 	{
1515 		if(FAILED(ScriptVariant_IntegerValue(varlist[i+1], value+i)))
1516 			goto drawstring_error;
1517 	}
1518 
1519 	ScriptVariant_ToString(varlist[4], buf);
1520 	screen_printf(scr, (int)value[0], (int)value[1], (int)value[2], "%s", buf);
1521 	return S_OK;
1522 
1523 drawstring_error:
1524 	printf("Function needs a valid screen handle, 3 integers and a string value: drawstringtoscreen(screen, int font, value)\n");
1525 	return E_FAIL;
1526 }
1527 
1528 // debug purpose
1529 //log(string);
openbor_log(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1530 HRESULT openbor_log(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1531 {
1532 	char buf[256];
1533 	*pretvar = NULL;
1534 
1535 	if(paramCount != 1) goto drawstring_error;
1536 
1537 	ScriptVariant_ToString(varlist[0], buf);
1538 	printf("%s", buf);
1539 	return S_OK;
1540 
1541 drawstring_error:
1542 	printf("Function needs 1 parameter: log(value)\n");
1543 	return E_FAIL;
1544 }
1545 
1546 //drawbox(x, y, width, height, z, color, lut);
openbor_drawbox(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1547 HRESULT openbor_drawbox(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1548 {
1549 	int i;
1550 	LONG value[6], l;
1551 	*pretvar = NULL;
1552 
1553 	if(paramCount < 6) goto drawbox_error;
1554 
1555 	for(i=0; i<6; i++)
1556 	{
1557 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i)))
1558 			goto drawbox_error;
1559 	}
1560 
1561 	if(paramCount > 6)
1562 	{
1563 		if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1564 			goto drawbox_error;
1565 	}
1566 	else l = -1;
1567 
1568 	if(l >= 0)
1569 	{
1570 		l %= MAX_BLENDINGS+1;
1571 	}
1572 	spriteq_add_box((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], (int)value[5], l);
1573 
1574 	return S_OK;
1575 
1576 drawbox_error:
1577 	printf("Function requires 6 integer values: drawbox(int x, int y, int width, int height, int z, int color, int lut)\n");
1578 	return E_FAIL;
1579 }
1580 
1581 //drawboxtoscreen(screen, x, y, width, height, color, lut);
openbor_drawboxtoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1582 HRESULT openbor_drawboxtoscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1583 {
1584 	int i;
1585 	s_screen* s;
1586 	LONG value[5], l;
1587 	*pretvar = NULL;
1588 
1589 	if(paramCount < 6) goto drawbox_error;
1590 
1591 	s = (s_screen*)varlist[0]->ptrVal;
1592 
1593 	if(!s) goto drawbox_error;
1594 
1595 	for(i=1; i<6; i++)
1596 	{
1597 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i-1)))
1598 			goto drawbox_error;
1599 	}
1600 
1601 	if(paramCount > 6)
1602 	{
1603 		if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1604 			goto drawbox_error;
1605 	}
1606 	else l = -1;
1607 
1608 	if(l >= 0)
1609 	{
1610 		l %= MAX_BLENDINGS+1;
1611 	}
1612 	switch(s->pixelformat)
1613 	{
1614 	case PIXEL_8:
1615 		drawbox((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, l);
1616 		break;
1617 	case PIXEL_16:
1618 		drawbox16((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, l);
1619 		break;
1620 	case PIXEL_32:
1621 		drawbox32((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, l);
1622 		break;
1623 	}
1624 
1625 	return S_OK;
1626 
1627 drawbox_error:
1628 	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");
1629 	return E_FAIL;
1630 }
1631 
1632 //drawline(x1, y1, x2, y2, z, color, lut);
openbor_drawline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1633 HRESULT openbor_drawline(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1634 {
1635 	int i;
1636 	LONG value[6], l;
1637 	*pretvar = NULL;
1638 
1639 	if(paramCount < 6) goto drawline_error;
1640 
1641 	for(i=0; i<6; i++)
1642 	{
1643 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i)))
1644 			goto drawline_error;
1645 	}
1646 
1647 	if(paramCount > 6)
1648 	{
1649 		if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1650 			goto drawline_error;
1651 	}
1652 	else l = -1;
1653 
1654 	if(l >=0 )
1655 	{
1656 		l %= MAX_BLENDINGS+1;
1657 	}
1658 	spriteq_add_line((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], (int)value[5], l);
1659 
1660 	return S_OK;
1661 
1662 drawline_error:
1663 	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");
1664 	return E_FAIL;
1665 }
1666 
1667 //drawlinetoscreen(screen, x1, y1, x2, y2, color, lut);
openbor_drawlinetoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1668 HRESULT openbor_drawlinetoscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1669 {
1670 	int i;
1671 	LONG value[5], l;
1672 	s_screen *s;
1673 	*pretvar = NULL;
1674 
1675 	if(paramCount < 6) goto drawline_error;
1676 
1677 	s = (s_screen*)varlist[0]->ptrVal;
1678 
1679 	if(!s) goto drawline_error;
1680 
1681 	for(i=1; i<6; i++)
1682 	{
1683 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i-1)))
1684 			goto drawline_error;
1685 	}
1686 
1687 	if(paramCount > 6)
1688 	{
1689 		if(FAILED(ScriptVariant_IntegerValue(varlist[6], &l)))
1690 			goto drawline_error;
1691 	}
1692 	else l = -1;
1693 
1694 	if(l >=0 )
1695 	{
1696 		l %= MAX_BLENDINGS+1;
1697 	}
1698 	switch(s->pixelformat)
1699 	{
1700 	case PIXEL_8:
1701 		line((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, l);
1702 		break;
1703 	case PIXEL_16:
1704 		line16((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, l);
1705 		break;
1706 	case PIXEL_32:
1707 		line32((int)value[0], (int)value[1], (int)value[2], (int)value[3], (int)value[4], s, l);
1708 		break;
1709 	}
1710 
1711 	return S_OK;
1712 drawline_error:
1713 	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");
1714 	return E_FAIL;
1715 }
1716 
1717 //drawsprite(sprite, x, y, z, sortid);
openbor_drawsprite(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1718 HRESULT openbor_drawsprite(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1719 {
1720 	int i;
1721 	LONG value[4];
1722 	s_sprite* spr;
1723 	*pretvar = NULL;
1724 
1725 	if(paramCount < 4) goto drawsprite_error;
1726 	if(varlist[0]->vt!=VT_PTR) goto drawsprite_error;
1727 
1728 	spr = varlist[0]->ptrVal;
1729 	if(!spr) goto drawsprite_error;
1730 
1731 	value[3] = (LONG)0;
1732 	for(i=1; i<paramCount && i<5; i++)
1733 	{
1734 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i-1)))
1735 			goto drawsprite_error;
1736 	}
1737 
1738 	spriteq_add_frame((int)value[0], (int)value[1], (int)value[2], spr, &drawmethod, (int)value[3]);
1739 
1740 	return S_OK;
1741 
1742 drawsprite_error:
1743 	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");
1744 	return E_FAIL;
1745 }
1746 
1747 //drawspritetoscreen(sprite, screen, x, y);
openbor_drawspritetoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1748 HRESULT openbor_drawspritetoscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1749 {
1750 	int i;
1751 	LONG value[2];
1752 	s_sprite* spr;
1753 	s_screen* scr;
1754 	*pretvar = NULL;
1755 
1756 	if(paramCount < 4) goto drawsprite_error;
1757 	if(varlist[0]->vt!=VT_PTR) goto drawsprite_error;
1758 	spr = varlist[0]->ptrVal;
1759 	if(!spr) goto drawsprite_error;
1760 
1761 	if(varlist[1]->vt!=VT_PTR) goto drawsprite_error;
1762 	scr = varlist[1]->ptrVal;
1763 	if(!scr) goto drawsprite_error;
1764 
1765 	for(i=2; i<paramCount && i<4; i++)
1766 	{
1767 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i-2)))
1768 			goto drawsprite_error;
1769 	}
1770 
1771 	putsprite((int)value[0], (int)value[1], spr, scr, &drawmethod);
1772 
1773 	return S_OK;
1774 
1775 drawsprite_error:
1776 	printf("Function requires a valid sprite handle, a valid screen handle and 2 integer values: drawspritetoscreen(sprite, screen, int x, int y)\n");
1777 	return E_FAIL;
1778 }
1779 
1780 //setvertex(index, x, y, tx, ty)
openbor_setvertex(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1781 HRESULT openbor_setvertex(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1782 {
1783 	LONG value[5], i;
1784 	*pretvar = NULL;
1785 
1786 	if(paramCount<5) goto vertex_error;
1787 
1788 	for(i=0; i<5; i++)
1789 	{
1790 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i)))
1791 			goto vertex_error;
1792 	}
1793 
1794 	if(value[0]<0 || value[0]>=vert_buf_size) goto vertex_error2;
1795 
1796 	verts[value[0]].x = value[1];
1797 	verts[value[0]].y = value[2];
1798 	verts[value[0]].tx = value[3];
1799 	verts[value[0]].ty = value[4];
1800 
1801 	return S_OK;
1802 
1803 vertex_error:
1804 	printf("Function requires 5 integer values: setvertex(index, x, y, tx, ty)\n");
1805 	return E_FAIL;
1806 
1807 vertex_error2:
1808 	printf("Index out of range in function setvertext: range from 0 to %d, %ld is given.\n", vert_buf_size-1, value[0]);
1809 	return E_FAIL;
1810 }
1811 
1812 //settexture(handle, type)
openbor_settexture(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1813 HRESULT openbor_settexture(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1814 {
1815 	LONG	type;
1816 	*pretvar = NULL;
1817 
1818 	if(paramCount<2) goto texture_error;
1819 
1820 	if(varlist[0]->vt!=VT_PTR) goto texture_error;
1821 
1822 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &type)))
1823 		goto texture_error;
1824 
1825 	switch(type){
1826 	case 0:
1827 		texture.type = gfx_screen;
1828 		texture.screen = (s_screen*)varlist[0]->ptrVal;
1829 		break;
1830 	case 1:
1831 		texture.type = gfx_bitmap;
1832 		texture.bitmap = (s_bitmap*)varlist[0]->ptrVal;
1833 		break;
1834 	case 2:
1835 		texture.type = gfx_sprite;
1836 		texture.sprite = (s_sprite*)varlist[0]->ptrVal;
1837 		break;
1838 	default:
1839 		goto texture_error2;
1840 		break;
1841 	}
1842 
1843 	return S_OK;
1844 
1845 texture_error:
1846 	printf("Function requires a valid texture handle and a integer values: settexture(handle, type)\n");
1847 	return E_FAIL;
1848 
1849 texture_error2:
1850 	printf("Invalid texture type for function settexture: %ld\n", type);
1851 	return E_FAIL;
1852 }
1853 
1854 // TODO: add a new entry type to the sprite queue (may not happen since you can always use a buffer screen)
1855 //trianglelist(screen, start, count);  //screen could be NULL
openbor_trianglelist(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1856 HRESULT openbor_trianglelist(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1857 {
1858 	s_screen* scr = NULL;
1859 	extern s_screen* vscreen;
1860 	LONG triangle_start = 0;
1861 	LONG triangle_count = 2;
1862 	*pretvar = NULL;
1863 
1864 	if(paramCount<3) goto trianglelist_error;
1865 
1866 	if(varlist[0]->vt!=VT_PTR && varlist[0]->vt!=VT_EMPTY) goto trianglelist_error;
1867 	scr = (s_screen*)varlist[0]->ptrVal;
1868 
1869 	if(!scr) scr = vscreen;
1870 
1871 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &triangle_start)))
1872 		goto trianglelist_error;
1873 
1874 	if(FAILED(ScriptVariant_IntegerValue(varlist[2], &triangle_count)))
1875 		goto trianglelist_error;
1876 
1877 	if(triangle_count<=0) return S_OK; // though we does nothing
1878 
1879 	 //check for overflow
1880 	if(triangle_start<0) triangle_start = 0;
1881 	else if(triangle_start>vert_buf_size-3) triangle_start = vert_buf_size-3;
1882 	//check for overflow
1883 	if(triangle_count>vert_buf_size-triangle_start-2) triangle_count = vert_buf_size-triangle_start-2;
1884 
1885 	//go ahead and draw
1886 	draw_triangle_list(verts + triangle_start, scr, &texture, &drawmethod, triangle_count);
1887 
1888 	return S_OK;
1889 
1890 trianglelist_error:
1891 	printf("Function requires a valid screen handle(can be NULL) and two integer values: trianglelist(screen, start, count)\n");
1892 	return E_FAIL;
1893 }
1894 
1895 
1896 //drawdot(x, y, z, color, lut);
openbor_drawdot(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1897 HRESULT openbor_drawdot(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1898 {
1899 	int i;
1900 	LONG value[4], l;
1901 	*pretvar = NULL;
1902 
1903 	if(paramCount < 4) goto drawdot_error;
1904 
1905 	for(i=0; i<4; i++)
1906 	{
1907 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i)))
1908 			goto drawdot_error;
1909 	}
1910 
1911 	if(paramCount > 4)
1912 	{
1913 		if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
1914 			goto drawdot_error;
1915 	}
1916 	else l = -1;
1917 
1918 	if(l >=0 )
1919 	{
1920 		l %= MAX_BLENDINGS+1;
1921 	}
1922 	spriteq_add_dot((int)value[0], (int)value[1], (int)value[2], (int)value[3], l);
1923 
1924 	return S_OK;
1925 
1926 drawdot_error:
1927 	printf("Function requires 4 integer values, 5th integer value is optional: drawdot(int x, int y, int z, int color, int lut)\n");
1928 	return E_FAIL;
1929 }
1930 
1931 //drawdottoscreen(screen, x, y, color, lut);
openbor_drawdottoscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1932 HRESULT openbor_drawdottoscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1933 {
1934 	int i;
1935 	LONG value[3], l;
1936 	s_screen* s;
1937 	*pretvar = NULL;
1938 
1939 	if(paramCount < 4) goto drawdot_error;
1940 
1941 	s = (s_screen*)varlist[0]->ptrVal;
1942 
1943 	if(!s) goto drawdot_error;
1944 
1945 	for(i=1; i<4; i++)
1946 	{
1947 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i-1)))
1948 			goto drawdot_error;
1949 	}
1950 
1951 	if(paramCount > 4)
1952 	{
1953 		if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
1954 			goto drawdot_error;
1955 	}
1956 	else l = -1;
1957 
1958 	if(l >=0 )
1959 	{
1960 		l %= MAX_BLENDINGS+1;
1961 	}
1962 	switch(s->pixelformat)
1963 	{
1964 	case PIXEL_8:
1965 		putpixel((int)value[0], (int)value[1], (int)value[2], s, l);
1966 		break;
1967 	case PIXEL_16:
1968 		putpixel16((int)value[0], (int)value[1], (int)value[2], s, l);
1969 		break;
1970 	case PIXEL_32:
1971 		putpixel32((int)value[0], (int)value[1], (int)value[2], s, l);
1972 		break;
1973 	}
1974 
1975 	return S_OK;
1976 
1977 drawdot_error:
1978 	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");
1979 	return E_FAIL;
1980 }
1981 
1982 
1983 //drawscreen(screen, x, y, z, lut);
openbor_drawscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)1984 HRESULT openbor_drawscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
1985 {
1986 	int i;
1987 	LONG value[3], l;
1988 	s_screen* s;
1989 	extern s_drawmethod plainmethod;
1990 	s_drawmethod screenmethod;
1991 	*pretvar = NULL;
1992 
1993 	if(paramCount < 4) goto drawscreen_error;
1994 
1995 	s = (s_screen*)varlist[0]->ptrVal;
1996 
1997 	if(!s) goto drawscreen_error;
1998 
1999 	for(i=1; i<4; i++)
2000 	{
2001 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i-1)))
2002 			goto drawscreen_error;
2003 	}
2004 
2005 	if(paramCount > 4)
2006 	{
2007 		if(FAILED(ScriptVariant_IntegerValue(varlist[4], &l)))
2008 			goto drawscreen_error;
2009 	}
2010 	else l = -1;
2011 
2012 	if(l >=0 )
2013 	{
2014 		l %= MAX_BLENDINGS+1;
2015 	}
2016 	if(paramCount<=4) screenmethod = drawmethod;
2017 	else
2018 	{
2019 		screenmethod = plainmethod;
2020 		screenmethod.alpha = l;
2021 		screenmethod.transbg = 1;
2022 	}
2023 
2024 	spriteq_add_screen((int)value[0], (int)value[1], (int)value[2], s, &screenmethod, 0);
2025 
2026 	return S_OK;
2027 
2028 drawscreen_error:
2029 	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");
2030 	return E_FAIL;
2031 }
2032 
2033 //getindexedvar(int index);
openbor_getindexedvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2034 HRESULT openbor_getindexedvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2035 {
2036 	LONG ind;
2037 
2038 	if(paramCount < 1 || max_indexed_vars<=0)
2039 	{
2040 		*pretvar = NULL;
2041 		return E_FAIL;
2042 	}
2043 
2044 	ScriptVariant_Clear(*pretvar);
2045 
2046 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
2047 	{
2048 		printf("Function requires 1 numberic value: getindexedvar(int index)\n");
2049 		*pretvar = NULL;
2050 		return E_FAIL;
2051 	}
2052 
2053 	if(ind<0 || ind>=max_indexed_vars) return S_OK;
2054 
2055 	ScriptVariant_Copy(*pretvar, indexed_var_list+ind);
2056 
2057 	return S_OK;
2058 }
2059 
2060 //setindexedvar(int index, var);
openbor_setindexedvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2061 HRESULT openbor_setindexedvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2062 {
2063 	LONG ind;
2064 
2065 	if(paramCount < 2 || max_indexed_vars<=0)
2066 	{
2067 		*pretvar = NULL;
2068 		return E_FAIL;
2069 	}
2070 
2071 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
2072 	{
2073 		printf("Function's 1st argument must be a numberic value: setindexedvar(int index, var)\n");
2074 		*pretvar = NULL;
2075 		return E_FAIL;
2076 	}
2077 
2078 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2079 
2080 	if(ind<0 || ind>=max_indexed_vars)
2081 	{
2082 		(*pretvar)->lVal = 0;
2083 		return S_OK;
2084 	}
2085 
2086 	ScriptVariant_Copy(indexed_var_list+ind, varlist[1]);
2087 	(*pretvar)->lVal = 1;
2088 
2089 	return S_OK;
2090 }
2091 
2092 //getscriptvar(int index);
openbor_getscriptvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2093 HRESULT openbor_getscriptvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2094 {
2095 	LONG ind;
2096 
2097 	if(paramCount < 1 || max_script_vars<=0 || !pcurrentscript || !pcurrentscript->vars)
2098 	{
2099 		*pretvar = NULL;
2100 		return E_FAIL;
2101 	}
2102 
2103 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
2104 	{
2105 		printf("Function requires 1 numberic value: getscriptvar(int index)\n");
2106 		*pretvar = NULL;
2107 		return E_FAIL;
2108 	}
2109 
2110 	ScriptVariant_Clear(*pretvar);
2111 
2112 	if(ind<0 || ind>=max_script_vars) return S_OK;
2113 
2114 	ScriptVariant_Copy(*pretvar, pcurrentscript->vars+ind);
2115 
2116 	return S_OK;
2117 }
2118 
2119 //setscriptvar(int index, var);
openbor_setscriptvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2120 HRESULT openbor_setscriptvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2121 {
2122 	LONG ind;
2123 
2124 	if(paramCount < 2 || max_script_vars<=0 || !pcurrentscript || !pcurrentscript->vars)
2125 	{
2126 		*pretvar = NULL;
2127 		return E_FAIL;
2128 	}
2129 
2130 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
2131 	{
2132 		printf("Function's 1st argument must be a numberic value: setscriptvar(int index, var)\n");
2133 		*pretvar = NULL;
2134 		return E_FAIL;
2135 	}
2136 
2137 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2138 
2139 	if(ind<0 || ind>=max_script_vars)
2140 	{
2141 		(*pretvar)->lVal = 0;
2142 		return S_OK;
2143 	}
2144 
2145 	ScriptVariant_Copy(pcurrentscript->vars+ind, varlist[1]);
2146 	(*pretvar)->lVal = 1;
2147 
2148 	return S_OK;
2149 }
2150 
2151 //getentityvar(entity, int index);
openbor_getentityvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2152 HRESULT openbor_getentityvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2153 {
2154 	ScriptVariant* arg = NULL;
2155 	LONG ind;
2156 	entity* ent;
2157 
2158 	if(paramCount < 2 || max_entity_vars<=0 )
2159 	{
2160 		*pretvar = NULL;
2161 		return E_FAIL;
2162 	}
2163 
2164 
2165 	arg = varlist[0];
2166 
2167 	ScriptVariant_Clear(*pretvar);
2168 	if(arg->vt == VT_EMPTY) ent= NULL;
2169 	else if(arg->vt == VT_PTR) ent = (entity*)arg->ptrVal;
2170 	else
2171 	{
2172 		printf("Function's 1st argument must be a valid entity handle value or empty value: getentityvar(entity, int index)\n");
2173 		*pretvar = NULL;
2174 		return E_FAIL;
2175 	}
2176 	if(!ent || !ent->entvars) return S_OK;
2177 
2178 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
2179 	{
2180 		printf("Function's 2nd argument must be a numberic value: getentityvar(entity, int index)\n");
2181 		*pretvar = NULL;
2182 		return E_FAIL;
2183 	}
2184 
2185 	if(ind<0 || ind>=max_entity_vars) return S_OK;
2186 
2187 	ScriptVariant_Copy(*pretvar, ent->entvars+ind);
2188 
2189 	return S_OK;
2190 }
2191 
2192 //setentityvar(int index, var);
openbor_setentityvar(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2193 HRESULT openbor_setentityvar(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2194 {
2195 	ScriptVariant* arg = NULL;
2196 	LONG ind;
2197 	entity* ent;
2198 
2199 	if(paramCount < 3 || max_entity_vars<=0)
2200 	{
2201 		*pretvar = NULL;
2202 		return E_FAIL;
2203 	}
2204 
2205 	arg = varlist[0];
2206 
2207 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2208 	(*pretvar)->lVal = 0;
2209 
2210 	if(arg->vt == VT_EMPTY) ent = NULL;
2211 	else if(arg->vt == VT_PTR)
2212 		ent = (entity*)arg->ptrVal;
2213 	else
2214 	{
2215 		printf("Function's 1st argument must be a valid entity handle value or empty value: setentityvar(entity, int index, var)\n");
2216 		*pretvar = NULL;
2217 		return E_FAIL;
2218 	}
2219 	if(!ent || !ent->entvars) return S_OK;
2220 
2221 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
2222 	{
2223 		printf("Function's 2nd argument must be a numberic value: setentityvar(entity, int index, var)\n");
2224 		*pretvar = NULL;
2225 		return E_FAIL;
2226 	}
2227 
2228 	if(ind<0 || ind>=max_entity_vars) return S_OK;
2229 
2230 	ScriptVariant_Copy(ent->entvars+ind, varlist[2]);
2231 	(*pretvar)->lVal = 1;
2232 
2233 	return S_OK;
2234 }
2235 
2236 //strinfirst(char string, char search_string);
openbor_strinfirst(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2237 HRESULT openbor_strinfirst(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2238 {
2239 	char* tempstr = NULL;
2240 
2241 	if(paramCount < 2)
2242 	{
2243 		*pretvar = NULL;
2244 		return E_FAIL;
2245 	}
2246 
2247 	ScriptVariant_Clear(*pretvar);
2248 
2249 	if(varlist[0]->vt!=VT_STR || varlist[1]->vt!=VT_STR)
2250 	{
2251 		printf("\n Error, strinfirst({string}, {search string}): Strinfirst must be passed valid {string} and {search string}. \n");
2252 	}
2253 
2254 	tempstr = strstr((char*)StrCache_Get(varlist[0]->strVal), (char*)StrCache_Get(varlist[1]->strVal));
2255 
2256 	if (tempstr != NULL)
2257 	{
2258 		ScriptVariant_ChangeType(*pretvar, VT_STR);
2259 		strcpy(StrCache_Get((*pretvar)->strVal), tempstr);
2260 	}
2261 	else
2262 	{
2263 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2264 		(*pretvar)->lVal = -1;
2265 	}
2266 	return S_OK;
2267 }
2268 
2269 //strinlast(char string, char search_string);
openbor_strinlast(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2270 HRESULT openbor_strinlast(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2271 {
2272 	char* tempstr = NULL;
2273 
2274 	if(paramCount < 2)
2275 	{
2276 		*pretvar = NULL;
2277 		return E_FAIL;
2278 	}
2279 
2280 	ScriptVariant_Clear(*pretvar);
2281 
2282 	if(varlist[0]->vt!=VT_STR || varlist[1]->vt!=VT_STR)
2283 	{
2284 		printf("\n Error, strinlast({string}, {search string}): Strinlast must be passed valid {string} and {search string}. \n");
2285 	}
2286 
2287 	tempstr = strrchr((char*)StrCache_Get(varlist[0]->strVal), varlist[1]->strVal);
2288 
2289 	if (tempstr != NULL)
2290 	{
2291 		ScriptVariant_ChangeType(*pretvar, VT_STR);
2292 		strcpy(StrCache_Get((*pretvar)->strVal), tempstr);
2293 	}
2294 	else
2295 	{
2296 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2297 		(*pretvar)->lVal = -1;
2298 	}
2299 	return S_OK;
2300 }
2301 
2302 //strleft(char string, int i);
openbor_strleft(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2303 HRESULT openbor_strleft(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2304 {
2305 	char tempstr[66] = {0};
2306 
2307 	if(paramCount < 2)
2308 	{
2309 		*pretvar = NULL;
2310 		return E_FAIL;
2311 	}
2312 	if(varlist[0]->vt!=VT_STR || varlist[1]->vt!=VT_INTEGER)
2313 	{
2314 		printf("\n Error, strleft({string}, {characters}): Invalid or missing parameter. Strleft must be passed valid {string} and number of {characters}.\n");
2315 	}
2316 
2317 	strncpy(tempstr, (char*)StrCache_Get(varlist[0]->strVal), varlist[1]->lVal);
2318 	ScriptVariant_Clear(*pretvar);
2319 
2320 	if (tempstr != NULL)
2321 	{
2322 		ScriptVariant_ChangeType(*pretvar, VT_STR);
2323 		strcpy(StrCache_Get((*pretvar)->strVal),tempstr);
2324 	}
2325 	else
2326 	{
2327 		 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2328 		(*pretvar)->lVal = -1;
2329 	}
2330 
2331 	return S_OK;
2332 }
2333 
2334 //strlength(char string);
openbor_strlength(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2335 HRESULT openbor_strlength(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2336 {
2337 	if(paramCount < 1)
2338 	{
2339 		*pretvar = NULL;
2340 		return E_FAIL;
2341 	}
2342 
2343 	ScriptVariant_Clear(*pretvar);
2344 
2345 	if(varlist[0]->vt!=VT_STR)
2346 	{
2347 		printf("Error, strlength({string}): Invalid or missing parameter. Strlength must be passed a valid {string}.\n");
2348 	}
2349 
2350 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2351 	(*pretvar)->lVal = strlen((char*)StrCache_Get(varlist[0]->strVal));
2352 	return S_OK;
2353 }
2354 
2355 //strright(char string, int i);
openbor_strright(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2356 HRESULT openbor_strright(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2357 {
2358 	char* tempstr = NULL;
2359 
2360 	if(paramCount < 2)
2361 	{
2362 		*pretvar = NULL;
2363 		return E_FAIL;
2364 	}
2365 
2366 	if(varlist[0]->vt!=VT_STR || varlist[1]->vt!=VT_INTEGER)
2367 	{
2368 		printf("\n Error, strright({string}, {characters}): Invalid or missing parameter. Strright must be passed valid {string} and number of {characters}.\n");
2369 	}
2370 
2371 	ScriptVariant_Clear(*pretvar);
2372 	tempstr = (char*)StrCache_Get(varlist[0]->strVal);
2373 
2374 	if (tempstr != NULL || strlen(tempstr)>0)
2375 	{
2376 		ScriptVariant_ChangeType(*pretvar, VT_STR);
2377 		strcpy(StrCache_Get((*pretvar)->strVal), &tempstr[varlist[1]->lVal]);
2378 	}
2379 	else
2380 	{
2381 		 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2382 		(*pretvar)->lVal = -1;
2383 	}
2384 
2385 	return S_OK;
2386 }
2387 
openbor_getmodelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2388 HRESULT openbor_getmodelproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2389 {
2390 	int iArg;
2391 
2392 	if(paramCount < 2)
2393 	{
2394 		*pretvar = NULL;
2395 		return E_FAIL;
2396 	}
2397 
2398 	if(varlist[0]->vt!=VT_INTEGER || varlist[1]->vt!=VT_INTEGER)
2399 	{
2400 		printf("\n Error, getmodelproperty({model}, {property}): Invalid or missing parameter. Getmodelproperty must be passed valid {model} and {property} indexes.\n");
2401 	}
2402 
2403 	iArg = varlist[0]->lVal;
2404 
2405 	switch (varlist[1]->lVal)
2406 	{
2407 		case 0:                                                    //Loaded?
2408 		{
2409 			ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2410 			(*pretvar)->lVal = (LONG)model_cache[iArg].loadflag;
2411 			break;
2412 		}
2413 		case 1:
2414 		{
2415 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
2416 			(*pretvar)->ptrVal = (VOID*)model_cache[iArg].model;
2417 		}
2418 		case 2:
2419 		{
2420 			ScriptVariant_ChangeType(*pretvar, VT_STR);
2421 			strcpy(StrCache_Get((*pretvar)->strVal), model_cache[iArg].name);
2422 			break;
2423 		}
2424 		case 3:
2425 		{
2426 			ScriptVariant_ChangeType(*pretvar, VT_STR);
2427 			strcpy(StrCache_Get((*pretvar)->strVal), model_cache[iArg].path);
2428 			break;
2429 		}
2430 		case 4:                                                    //Loaded?
2431 		{
2432 			ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
2433 			(*pretvar)->lVal = (LONG)model_cache[iArg].selectable;
2434 			break;
2435 		}
2436 	}
2437 
2438 	return S_OK;
2439 }
2440 
openbor_changemodelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)2441 HRESULT openbor_changemodelproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
2442 {
2443 	int iArg;
2444 	LONG ltemp;
2445 
2446 	if(paramCount < 2)
2447 	{
2448 		*pretvar = NULL;
2449 		return E_FAIL;
2450 	}
2451 
2452 	if(varlist[0]->vt!=VT_INTEGER || varlist[1]->vt!=VT_INTEGER)
2453 	{
2454 		printf("\n Error, changemodelproperty({model}, {property}, {value}): Invalid or missing parameter. Changemodelproperty must be passed valid {model}, {property} and {value}.\n");
2455 	}
2456 
2457 	iArg = varlist[0]->lVal;
2458 
2459 	switch (varlist[1]->lVal)
2460 	{
2461 		case 0:                                                    //Loaded?
2462 		{
2463 			/*
2464 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
2465 				model_cache[iArg].loadflag = (int)ltemp;
2466 			else (*pretvar)->lVal = (LONG)0;
2467 			break;
2468 			*/
2469 		}
2470 		case 1:
2471 		{
2472 			/*
2473 			if(varlist[2]->vt != VT_STR)
2474 			{
2475 				printf("You must give a string value for {value}.\n");
2476 				goto changeentityproperty_error;
2477 			}
2478 			strcpy(model_cache[iArg].model, (char*)StrCache_Get(varlist[2]->strVal));
2479 			(*pretvar)->lVal = (LONG)1;
2480 			break;
2481 			*/
2482 		}
2483 		case 2:
2484 		{
2485 			/*
2486 			if(varlist[2]->vt != VT_STR)
2487 			{
2488 				printf("You must give a string value for {value}.\n");
2489 				goto changeentityproperty_error;
2490 			}
2491 			strcpy(model_cache[iArg].name, (char*)StrCache_Get(varlist[2]->strVal));
2492 			(*pretvar)->lVal = (LONG)1;
2493 			break;
2494 			*/
2495 		}
2496 		case 3:
2497 		{
2498 			/*
2499 			if(varlist[2]->vt != VT_STR)
2500 			{
2501 				printf("You must give a string value for {value}.\n");
2502 				goto changeentityproperty_error;
2503 			}
2504 			strcpy(model_cache[iArg].path, (char*)StrCache_Get(varlist[2]->strVal));
2505 			(*pretvar)->lVal = (LONG)1;
2506 			break;
2507 			*/
2508 		}
2509 		case 4:
2510 		{
2511 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
2512 				model_cache[iArg].selectable = (int)ltemp;
2513 			else (*pretvar)->lVal = (LONG)0;
2514 			break;
2515 		}
2516 	}
2517 
2518 	return S_OK;
2519 }
2520 
2521 // ===== getentityproperty =====
2522 enum getentityproperty_enum {
2523 	_gep_a,
2524 	_gep_aggression,
2525 	_gep_aiattack,
2526 	_gep_aiflag,
2527 	_gep_aimove,
2528 	_gep_alpha,
2529 	_gep_animal,
2530 	_gep_animating,
2531 	_gep_animation,
2532 	_gep_animationid,
2533 	_gep_animheight,
2534 	_gep_animhits,
2535 	_gep_animnum,
2536 	_gep_animpos,
2537 	_gep_animvalid,
2538 	_gep_antigrab,
2539 	_gep_antigravity,
2540 	_gep_attack,
2541 	_gep_attacking,
2542 	_gep_attackid,
2543 	_gep_autokill,
2544 	_gep_base,
2545 	_gep_bbox,
2546 	_gep_blink,
2547 	_gep_blockback,
2548 	_gep_blockodds,
2549 	_gep_blockpain,
2550 	_gep_bounce,
2551 	_gep_chargerate,
2552 	_gep_colourmap,
2553 	_gep_colourtable,
2554 	_gep_damage_on_landing,
2555 	_gep_dead,
2556 	_gep_defaultmodel,
2557 	_gep_defaultname,
2558 	_gep_defense,
2559 	_gep_detect,
2560 	_gep_direction,
2561 	_gep_dot,
2562 	_gep_dropframe,
2563 	_gep_edelay,
2564 	_gep_energycost,
2565 	_gep_escapecount,
2566 	_gep_escapehits,
2567 	_gep_exists,
2568 	_gep_falldie,
2569 	_gep_flash,
2570 	_gep_freezetime,
2571 	_gep_frozen,
2572 	_gep_gfxshadow,
2573 	_gep_grabbing,
2574 	_gep_grabforce,
2575 	_gep_guardpoints,
2576 	_gep_health,
2577 	_gep_height,
2578 	_gep_hitbyid,
2579 	_gep_hmapl,
2580 	_gep_hmapu,
2581 	_gep_icon,
2582 	_gep_invincible,
2583 	_gep_invinctime,
2584 	_gep_jugglepoints,
2585 	_gep_knockdowncount,
2586 	_gep_komap,
2587 	_gep_landframe,
2588 	_gep_lifespancountdown,
2589 	_gep_link,
2590 	_gep_map,
2591 	_gep_mapcount,
2592 	_gep_mapdefault,
2593 	_gep_maps,
2594 	_gep_maxguardpoints,
2595 	_gep_maxhealth,
2596 	_gep_maxjugglepoints,
2597 	_gep_maxmp,
2598 	_gep_model,
2599 	_gep_mp,
2600 	_gep_mpdroprate,
2601 	_gep_mprate,
2602 	_gep_mpstable,
2603 	_gep_mpstableval,
2604 	_gep_name,
2605 	_gep_nextanim,
2606 	_gep_nextthink,
2607 	_gep_no_adjust_base,
2608 	_gep_noaicontrol,
2609 	_gep_nodieblink,
2610 	_gep_nodrop,
2611 	_gep_nograb,
2612 	_gep_nolife,
2613 	_gep_nopain,
2614 	_gep_offense,
2615 	_gep_opponent,
2616 	_gep_owner,
2617 	_gep_pain_time,
2618 	_gep_parent,
2619 	_gep_path,
2620 	_gep_playerindex,
2621 	_gep_projectile,
2622 	_gep_range,
2623 	_gep_running,
2624 	_gep_rush_count,
2625 	_gep_rush_tally,
2626 	_gep_rush_time,
2627 	_gep_score,
2628 	_gep_scroll,
2629 	_gep_seal,
2630 	_gep_sealtime,
2631 	_gep_setlayer,
2632 	_gep_spawntype,
2633 	_gep_speed,
2634 	_gep_sprite,
2635 	_gep_spritea,
2636 	_gep_stalltime,
2637 	_gep_stats,
2638 	_gep_staydown,
2639 	_gep_stealth,
2640 	_gep_subentity,
2641 	_gep_subject_to_gravity,
2642 	_gep_subject_to_hole,
2643 	_gep_subject_to_maxz,
2644 	_gep_subject_to_minz,
2645 	_gep_subject_to_obstacle,
2646 	_gep_subject_to_platform,
2647 	_gep_subject_to_screen,
2648 	_gep_subject_to_wall,
2649 	_gep_subtype,
2650 	_gep_thold,
2651 	_gep_throwdamage,
2652 	_gep_throwdist,
2653 	_gep_throwframewait,
2654 	_gep_throwheight,
2655 	_gep_tosstime,
2656 	_gep_tossv,
2657 	_gep_type,
2658 	_gep_weapent,
2659 	_gep_x,
2660 	_gep_xdir,
2661 	_gep_z,
2662 	_gep_zdir,
2663 	_gep_the_end,
2664 };
2665 
2666 enum gep_aiflag_enum {
2667 	_gep_aiflag_animating,
2668 	_gep_aiflag_attacking,
2669 	_gep_aiflag_autokill,
2670 	_gep_aiflag_blink,
2671 	_gep_aiflag_blocking,
2672 	_gep_aiflag_charging,
2673 	_gep_aiflag_dead,
2674 	_gep_aiflag_drop,
2675 	_gep_aiflag_falling,
2676 	_gep_aiflag_freezetime,
2677 	_gep_aiflag_frozen,
2678 	_gep_aiflag_getting,
2679 	_gep_aiflag_idling,
2680 	_gep_aiflag_inpain,
2681 	_gep_aiflag_invincible,
2682 	_gep_aiflag_jumpid,
2683 	_gep_aiflag_jumping,
2684 	_gep_aiflag_pain_time,
2685 	_gep_aiflag_projectile,
2686 	_gep_aiflag_running,
2687 	_gep_aiflag_toexplode,
2688 	_gep_aiflag_turning,
2689 	_gep_aiflag_walking,
2690 	_gep_aiflag_the_end,
2691 };
2692 
2693 enum gep_attack_enum {
2694 	_gep_attack_blast,
2695 	_gep_attack_blockflash,
2696 	_gep_attack_blocksound,
2697 	_gep_attack_coords,
2698 	_gep_attack_counterattack,
2699 	_gep_attack_direction,
2700 	_gep_attack_dol,
2701 	_gep_attack_dot,
2702 	_gep_attack_dotforce,
2703 	_gep_attack_dotindex,
2704 	_gep_attack_dotrate,
2705 	_gep_attack_dottime,
2706 	_gep_attack_drop,
2707 	_gep_attack_dropv,
2708 	_gep_attack_force,
2709 	_gep_attack_forcemap,
2710 	_gep_attack_freeze,
2711 	_gep_attack_freezetime,
2712 	_gep_attack_grab,
2713 	_gep_attack_grabdistance,
2714 	_gep_attack_guardcost,
2715 	_gep_attack_hitflash,
2716 	_gep_attack_hitsound,
2717 	_gep_attack_jugglecost,
2718 	_gep_attack_maptime,
2719 	_gep_attack_noblock,
2720 	_gep_attack_noflash,
2721 	_gep_attack_nokill,
2722 	_gep_attack_nopain,
2723 	_gep_attack_otg,
2724 	_gep_attack_pause,
2725 	_gep_attack_seal,
2726 	_gep_attack_sealtime,
2727 	_gep_attack_staydown,
2728 	_gep_attack_steal,
2729 	_gep_attack_type,
2730 	_gep_attack_the_end,
2731 };
2732 
2733 enum _gep_defense_enum {
2734     _gep_defense_blockpower,
2735     _gep_defense_blockratio,
2736     _gep_defense_blockthreshold,
2737     _gep_defense_blocktype,
2738     _gep_defense_factor,
2739     _gep_defense_knockdown,
2740 	_gep_defense_pain,
2741 	_gep_defense_the_end,
2742 };
2743 
2744 enum gep_dot_enum {
2745 	_gep_dot_force,
2746 	_gep_dot_mode,
2747 	_gep_dot_owner,
2748 	_gep_dot_rate,
2749 	_gep_dot_time,
2750 	_gep_dot_type,
2751 	_gep_dot_the_end,
2752 };
2753 
2754 enum gep_edelay_enum {
2755 	_gep_edelay_cap_max,
2756 	_gep_edelay_cap_min,
2757 	_gep_edelay_factor,
2758 	_gep_edelay_mode,
2759 	_gep_edelay_range_max,
2760 	_gep_edelay_range_min,
2761 	_gep_edelay_the_end,
2762 };
2763 
2764 enum gep_energycost_enum {
2765     _gep_energycost_cost,
2766     _gep_energycost_disable,
2767     _gep_energycost_mponly,
2768     _gep_energycost_the_end,
2769 };
2770 
2771 enum gep_flash_enum {
2772     _gep_flash_block,
2773     _gep_flash_def,
2774     _gep_flash_noattack,
2775     _gep_flash_the_end,
2776 };
2777 
2778 enum gep_icon_enum {
2779     _gep_icon_def,
2780     _gep_icon_die,
2781     _gep_icon_get,
2782     _gep_icon_mphigh,
2783     _gep_icon_mplow,
2784     _gep_icon_mpmed,
2785     _gep_icon_pain,
2786     _gep_icon_weapon,
2787     _gep_icon_x,
2788     _gep_icon_y,
2789     _gep_icon_the_end,
2790 };
2791 
2792 enum _gep_knockdowncount_enum {
2793     _gep_knockdowncount_current,
2794     _gep_knockdowncount_max,
2795     _gep_knockdowncount_time,
2796     _gep_knockdowncount_the_end,
2797 };
2798 
2799 enum gep_landframe_enum {
2800     _gep_landframe_ent,
2801     _gep_landframe_frame,
2802     _gep_landframe_the_end,
2803 };
2804 
2805 enum gep_maps_enum {
2806     _gep_maps_count,
2807     _gep_maps_current,
2808     _gep_maps_default,
2809     _gep_maps_dying,
2810     _gep_maps_dying_critical,
2811     _gep_maps_dying_low,
2812     _gep_maps_frozen,
2813     _gep_maps_hide_end,
2814     _gep_maps_hide_start,
2815     _gep_maps_ko,
2816     _gep_maps_kotype,
2817     _gep_maps_table,
2818     _gep_maps_time,
2819     _gep_maps_the_end,
2820 };
2821 
2822 enum gep_range_enum {
2823     _gep_range_amax,
2824     _gep_range_amin,
2825     _gep_range_bmax,
2826     _gep_range_bmin,
2827     _gep_range_xmax,
2828     _gep_range_xmin,
2829     _gep_range_zmax,
2830     _gep_range_zmin,
2831     _gep_range_the_end,
2832 };
2833 
2834 enum gep_running_enum {
2835 	_gep_running_jumpx,
2836 	_gep_running_jumpy,
2837 	_gep_running_land,
2838 	_gep_running_movez,
2839 	_gep_running_speed,
2840 	_gep_running_the_end,
2841 };
2842 
2843 enum gep_spritea_enum {
2844     _gep_spritea_centerx,
2845     _gep_spritea_centery,
2846     _gep_spritea_file,
2847     _gep_spritea_offsetx,
2848     _gep_spritea_offsety,
2849     _gep_spritea_sprite,
2850     _gep_spritea_the_end,
2851 };
2852 
2853 enum gep_staydown_enum {
2854     _gep_staydown_rise,
2855     _gep_staydown_riseattack,
2856     _gep_staydown_riseattack_stall,
2857     _gep_staydown_the_end,
2858 };
2859 
mapstrings_getentityproperty(ScriptVariant ** varlist,int paramCount)2860 void mapstrings_getentityproperty(ScriptVariant** varlist, int paramCount)
2861 {
2862 	char* propname;
2863 	int prop;
2864 
2865 	// arranged list, for searching
2866 	static const char* proplist[] = {
2867 		"a",
2868 		"aggression",
2869 		"aiattack",
2870 		"aiflag",
2871 		"aimove",
2872 		"alpha",
2873 		"animal",
2874 		"animating",
2875 		"animation",
2876 		"animationid",
2877 		"animheight",
2878 		"animhits",
2879 		"animnum",
2880 		"animpos",
2881 		"animvalid",
2882 		"antigrab",
2883 		"antigravity",
2884 		"attack",
2885 		"attacking",
2886 		"attackid",
2887 		"autokill",
2888 		"base",
2889 		"bbox",
2890 		"blink",
2891 		"blockback",
2892 		"blockodds",
2893 		"blockpain",
2894 		"bounce",
2895 		"chargerate",
2896 		"colourmap",
2897 		"colourtable",
2898 		"damage_on_landing",
2899 		"dead",
2900 		"defaultmodel",
2901 		"defaultname",
2902 		"defense",
2903 		"detect",
2904 		"direction",
2905 		"dot",
2906 		"dropframe",
2907 		"edelay",
2908 		"energycost",
2909 		"escapecount",
2910 		"escapehits",
2911 		"exists",
2912 		"falldie",
2913 		"flash",
2914 		"freezetime",
2915 		"frozen",
2916 		"gfxshadow",
2917 		"grabbing",
2918 		"grabforce",
2919 		"guardpoints",
2920 		"health",
2921 		"height",
2922 		"hitbyid",
2923 		"hmapl",
2924 		"hmapu",
2925 		"icon",
2926 		"invincible",
2927 		"invinctime",
2928 		"jugglepoints",
2929 		"knockdowncount",
2930 		"komap",
2931 		"landframe",
2932 		"lifespancountdown",
2933 		"link",
2934 		"map",
2935 		"mapcount",
2936 		"mapdefault",
2937 		"maps",
2938 		"maxguardpoints",
2939 		"maxhealth",
2940 		"maxjugglepoints",
2941 		"maxmp",
2942 		"model",
2943 		"mp",
2944 		"mpdroprate",
2945 		"mprate",
2946 		"mpstable",
2947 		"mpstableval",
2948 		"name",
2949 		"nextanim",
2950 		"nextthink",
2951 		"no_adjust_base",
2952 		"noaicontrol",
2953 		"nodieblink",
2954 		"nodrop",
2955 		"nograb",
2956 		"nolife",
2957 		"nopain",
2958 		"offense",
2959 		"opponent",
2960 		"owner",
2961 		"pain_time",
2962 		"parent",
2963 		"path",
2964 		"playerindex",
2965 		"projectile",
2966 		"range",
2967 		"running",
2968 		"rush_count",
2969 		"rush_tally",
2970 		"rush_time",
2971 		"score",
2972 		"scroll",
2973 		"seal",
2974 		"sealtime",
2975 		"setlayer",
2976 		"spawntype",
2977 		"speed",
2978 		"sprite",
2979 		"spritea",
2980 		"stalltime",
2981 		"stats",
2982 		"staydown",
2983 		"stealth",
2984 		"subentity",
2985 		"subject_to_gravity",
2986 		"subject_to_hole",
2987 		"subject_to_maxz",
2988 		"subject_to_minz",
2989 		"subject_to_obstacle",
2990 		"subject_to_platform",
2991 		"subject_to_screen",
2992 		"subject_to_wall",
2993 		"subtype",
2994 		"thold",
2995 		"throwdamage",
2996 		"throwdist",
2997 		"throwframewait",
2998 		"throwheight",
2999 		"tosstime",
3000 		"tossv",
3001 		"type",
3002 		"weapent",
3003 		"x",
3004 		"xdir",
3005 		"z",
3006 		"zdir",
3007 	};
3008 
3009 	static const char* proplist_aiflag[] = {
3010 		"animating",
3011 		"attacking",
3012 		"autokill",
3013 		"blink",
3014 		"blocking",
3015 		"charging",
3016 		"dead",
3017 		"drop",
3018 		"falling",
3019 		"freezetime",
3020 		"frozen",
3021 		"getting",
3022 		"idling",
3023 		"inpain",
3024 		"invincible",
3025 		"jumpid",
3026 		"jumping",
3027 		"pain_time",
3028 		"projectile",
3029 		"running",
3030 		"toexplode",
3031 		"turning",
3032 		"walking",
3033 	};
3034 
3035     static const char* proplist_attack[] = {
3036 		"blast",
3037 		"blockflash",
3038 		"blocksound",
3039 		"coords",
3040 		"counterattack",
3041 		"direction",
3042 		"dol",
3043 		"dot",
3044 		"dotforce",
3045 		"dotindex",
3046 		"dotrate",
3047 		"dottime",
3048 		"drop",
3049 		"dropv",
3050 		"force",
3051 		"forcemap",
3052 		"freeze",
3053 		"freezetime",
3054 		"grab",
3055 		"grabdistance",
3056 		"guardcost",
3057 		"hitflash",
3058 		"hitsound",
3059 		"jugglecost",
3060 		"maptime",
3061 		"noblock",
3062 		"noflash",
3063 		"nokill",
3064 		"nopain",
3065 		"otg",
3066 		"pause",
3067 		"seal",
3068 		"sealtime",
3069 		"staydown",
3070 		"steal",
3071 		"type",
3072 	};
3073 
3074 	static const char* proplist_defense[] = {
3075 		"blockpower",
3076 		"blockratio",
3077 		"blockthreshold",
3078 		"blocktype",
3079 		"factor",
3080 		"knockdown",
3081 		"pain",
3082 	};
3083 
3084     static const char* proplist_dot[] = {
3085 		"force",
3086 		"mode",
3087 		"owner",
3088 		"rate",
3089 		"time",
3090 		"type",
3091 	};
3092 
3093     static const char* proplist_edelay[] = {
3094 		"cap_max",
3095 		"cap_min",
3096 		"factor",
3097 		"mode",
3098 		"range_max",
3099 		"range_min",
3100 	};
3101 
3102     static const char* proplist_energycost[] = {
3103 		"cost",
3104 		"disable",
3105 		"mponly",
3106 	};
3107 
3108     static const char* proplist_flash[] = {
3109         "block",
3110         "default",
3111         "noattack",
3112     };
3113 
3114     static const char* proplist_icon[] = {
3115         "default",
3116         "die",
3117         "get",
3118         "mphigh",
3119         "mplow",
3120         "mpmed",
3121         "pain",
3122         "weapon",
3123         "x",
3124         "y",
3125     };
3126 
3127     static const char* proplist_knockdowncount[] = {
3128         "current",
3129         "max",
3130         "time",
3131     };
3132 
3133     static const char* proplist_landframe[] = {
3134         "ent",
3135         "frame",
3136 	};
3137 
3138     static const char* proplist_maps[] = {
3139         "count",
3140         "current",
3141         "default",
3142         "dying",
3143         "dying_critical",
3144         "dying_low",
3145         "frozen",
3146         "hide_end",
3147         "hide_start",
3148         "ko",
3149         "kotype",
3150         "table",
3151         "time",
3152     };
3153 
3154 	static const char* proplist_range[] = {
3155 		"amax",
3156 		"amin",
3157 		"bmax",
3158 		"bmin",
3159 		"xmax",
3160 		"xmin",
3161 		"zmax",
3162 		"zmin",
3163 	};
3164 
3165 	static const char* proplist_running[] = {
3166 		"jumpx",
3167 		"jumpy",
3168 		"land",
3169 		"movez",
3170 		"speed",
3171 	};
3172 
3173     static const char* proplist_spritea[] = {
3174         "centerx",
3175         "centery",
3176         "file",
3177         "offsetx",
3178         "offsety",
3179         "sprite",
3180 	};
3181 
3182     static const char* proplist_staydown[] = {
3183         "rise",
3184         "riseattack",
3185         "riseattack_stall",
3186     };
3187 
3188 	if(paramCount < 2) return;
3189 
3190 	// map entity properties
3191 	MAPSTRINGS(varlist[1], proplist, _gep_the_end,
3192 		"Property name '%s' is not supported by function getentityproperty.\n");
3193 
3194 	if(paramCount < 3) return;
3195 
3196 	// map subproperties of aiflag property
3197 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_aiflag))
3198 	{
3199 		MAPSTRINGS(varlist[2], proplist_aiflag, _gep_aiflag_the_end,
3200 			"'%s' is not a known subproperty of 'aiflag'.\n");
3201 	}
3202 
3203 	// map subproperties of Attack
3204 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_attack))
3205 	{
3206 		MAPSTRINGS(varlist[2], proplist_attack, _gep_attack_the_end,
3207 			"Property name '%s' is not a known subproperty of 'attack'.\n");
3208 	}
3209 
3210 	// map subproperties of defense property
3211 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_defense))
3212 	{
3213 		if(paramCount >= 4)
3214 		{
3215 			MAPSTRINGS(varlist[3], proplist_defense, _gep_defense_the_end,
3216 				"'%s' is not a known subproperty of 'defense'.\n");
3217 		}
3218 	}
3219 
3220     // map subproperties of DOT
3221 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_dot))
3222 	{
3223 		MAPSTRINGS(varlist[2], proplist_dot, _gep_dot_the_end,
3224 			"Property name '%s' is not a known subproperty of 'dot'.\n");
3225 	}
3226 
3227     // map subproperties of Edelay property
3228 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_edelay))
3229 	{
3230 		MAPSTRINGS(varlist[2], proplist_edelay, _gep_edelay_the_end,
3231 			"'%s' is not a known subproperty of 'edelay'.\n");
3232 	}
3233 
3234 	// map subproperties of Energycost
3235 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_energycost))
3236 	{
3237 		MAPSTRINGS(varlist[2], proplist_energycost, _gep_energycost_the_end,
3238 			"Property name '%s' is not a known subproperty of 'energycost'.\n");
3239 	}
3240 
3241 	// map subproperties of Flash
3242 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_flash))
3243 	{
3244 		MAPSTRINGS(varlist[2], proplist_flash, _gep_flash_the_end,
3245 			"Property name '%s' is not a known subproperty of 'flash'.\n");
3246 	}
3247 
3248     // map subproperties of Icon
3249 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_icon))
3250 	{
3251 		MAPSTRINGS(varlist[2], proplist_icon, _gep_icon_the_end,
3252 			"Property name '%s' is not a known subproperty of 'icon'.\n");
3253 	}
3254 
3255 	// map subproperties of Knockdowncount
3256 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_knockdowncount))
3257 	{
3258 		MAPSTRINGS(varlist[2], proplist_knockdowncount, _gep_knockdowncount_the_end,
3259 			"Property name '%s' is not a known subproperty of 'knockdowncount'.\n");
3260 	}
3261 
3262 	// map subproperties of Landframe
3263 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_landframe))
3264 	{
3265 		MAPSTRINGS(varlist[2], proplist_landframe, _gep_landframe_the_end,
3266 			"Property name '%s' is not a known subproperty of 'landframe'.\n");
3267 	}
3268 
3269 	// map subproperties of Maps
3270 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_maps))
3271 	{
3272 		MAPSTRINGS(varlist[2], proplist_maps, _gep_maps_the_end,
3273 			"Property name '%s' is not a known subproperty of 'maps'.\n");
3274 	}
3275 
3276 	// map subproperties of Range
3277 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_range))
3278 	{
3279 		MAPSTRINGS(varlist[2], proplist_range, _gep_range_the_end,
3280 			"Property name '%s' is not a known subproperty of 'range'.\n");
3281 	}
3282 
3283 	// map subproperties of Running
3284 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_running))
3285 	{
3286 		MAPSTRINGS(varlist[2], proplist_running, _gep_running_the_end,
3287 			"Property name '%s' is not a known subproperty of 'running'.\n");
3288 	}
3289 
3290 	// map subproperties of Spritea
3291 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_spritea))
3292 	{
3293 		MAPSTRINGS(varlist[2], proplist_spritea, _gep_spritea_the_end,
3294 			"Property name '%s' is not a known subproperty of 'spritea'.\n");
3295 	}
3296 
3297 	// map subproperties of Staydown
3298 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _gep_staydown))
3299 	{
3300 		MAPSTRINGS(varlist[2], proplist_staydown, _gep_running_the_end,
3301 			"Property name '%s' is not a known subproperty of 'staydown'.\n");
3302 	}
3303 }
3304 
3305 //getentityproperty(pentity, propname);
openbor_getentityproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)3306 HRESULT openbor_getentityproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
3307 {
3308 	entity* ent			= NULL;
3309 	char* tempstr		= NULL;
3310 	ScriptVariant* arg	= NULL;
3311 	ScriptVariant* arg1	= NULL;
3312 	s_sprite* spr;
3313 	s_attack* attack;
3314 	LONG ltemp, ltemp2;
3315 	int i				= 0;
3316 	int propind ;
3317 	int tempint			= 0;
3318 	short *coords;
3319 
3320 	if(paramCount < 2)  {
3321 		*pretvar = NULL;
3322 		return E_FAIL;
3323 	}
3324 
3325 	ScriptVariant_Clear(*pretvar);
3326 	mapstrings_getentityproperty(varlist, paramCount);
3327 
3328 	arg = varlist[0];
3329 	if(arg->vt != VT_PTR && arg->vt != VT_EMPTY)
3330 	{
3331 		printf("Function getentityproperty must have a valid entity handle.\n");
3332 		*pretvar = NULL;
3333 		return E_FAIL;
3334 	}
3335 	ent = (entity*)arg->ptrVal; //retrieve the entity
3336 	if(!ent) return S_OK;
3337 
3338 	arg = varlist[1];
3339 	if(arg->vt!=VT_INTEGER)
3340 	{
3341 		printf("Function getentityproperty must have a string property name.\n");
3342 	}
3343 
3344 	propind = arg->lVal;
3345 
3346 	switch(propind)
3347 	{
3348     case _gep_a:
3349 	{
3350 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3351 		(*pretvar)->dblVal = (DOUBLE)ent->a;
3352 		break;
3353 	}
3354 	case _gep_aggression:
3355 	{
3356 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3357 		(*pretvar)->lVal = (LONG)ent->modeldata.aggression;
3358 		break;
3359 	}
3360 	case _gep_aiattack:
3361 	{
3362 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3363 		(*pretvar)->lVal = (LONG)ent->modeldata.aiattack;
3364 		break;
3365 	}
3366 	case _gep_aiflag:
3367 	{
3368 		if(paramCount<3) break;
3369 		arg = varlist[2];
3370 		if(arg->vt != VT_INTEGER)
3371 		{
3372 			printf("You must give a string name for aiflag.\n");
3373 			return E_FAIL;
3374 		}
3375 		ltemp = arg->lVal;
3376 		switch(ltemp)
3377 		{
3378 		case _gep_aiflag_dead:
3379 		{
3380 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3381 			 (*pretvar)->lVal = (LONG)ent->dead;
3382 			 break;
3383 		}
3384 		case _gep_aiflag_jumpid:
3385 		{
3386 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3387 			 (*pretvar)->lVal = (LONG)ent->jumpid;
3388 			 break;
3389 		}
3390 		case _gep_aiflag_jumping:
3391 		{
3392 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3393 			 (*pretvar)->lVal = (LONG)ent->jumping;
3394 			 break;
3395 		}
3396 		case _gep_aiflag_idling:
3397 		{
3398 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3399 			 (*pretvar)->lVal = (LONG)ent->idling;
3400 			 break;
3401 		}
3402 		case _gep_aiflag_drop:
3403 		{
3404 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3405 			 (*pretvar)->lVal = (LONG)ent->drop;
3406 			 break;
3407 		}
3408 		case _gep_aiflag_attacking:
3409 		{
3410 			ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3411 			(*pretvar)->lVal = (LONG)ent->attacking;
3412 			break;
3413 		}
3414 		case _gep_aiflag_getting:
3415 		{
3416 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3417 			 (*pretvar)->lVal = (LONG)ent->getting;
3418 			 break;
3419 		}
3420 		case _gep_aiflag_turning:
3421 		{
3422 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3423 			 (*pretvar)->lVal = (LONG)ent->turning;
3424 			 break;
3425 		}
3426 		case _gep_aiflag_charging:
3427 		{
3428 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3429 			 (*pretvar)->lVal = (LONG)ent->charging;
3430 			 break;
3431 		}
3432 		case _gep_aiflag_blocking:
3433 		{
3434 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3435 			 (*pretvar)->lVal = (LONG)ent->blocking;
3436 			 break;
3437 		}
3438 		case _gep_aiflag_falling:
3439 		{
3440 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3441 			 (*pretvar)->lVal = (LONG)ent->falling;
3442 			 break;
3443 		}
3444 		case _gep_aiflag_running:
3445 		{
3446 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3447 			 (*pretvar)->lVal = (LONG)ent->running;
3448 			 break;
3449 		}
3450 		case _gep_aiflag_inpain:
3451 		{
3452 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3453 			 (*pretvar)->lVal = (LONG)ent->inpain;
3454 			 break;
3455 		}
3456 		case _gep_aiflag_pain_time:
3457 		{
3458 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3459 			 (*pretvar)->lVal = (LONG)ent->pain_time;
3460 			 break;
3461 		}
3462 		case _gep_aiflag_projectile:
3463 		{
3464 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3465 			 (*pretvar)->lVal = (LONG)ent->projectile;
3466 			 break;
3467 		}
3468 		case _gep_aiflag_frozen:
3469 		{
3470 			ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3471 			(*pretvar)->lVal = (LONG)ent->frozen;
3472 			break;
3473 		}
3474 		case _gep_aiflag_freezetime:
3475 		{
3476 			ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3477 			(*pretvar)->lVal = (LONG)ent->freezetime;
3478 			break;
3479 		}
3480 		case _gep_aiflag_toexplode:
3481 		{
3482 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3483 			 (*pretvar)->lVal = (LONG)ent->toexplode;
3484 			 break;
3485 		}
3486 		case _gep_aiflag_animating:
3487 		{
3488 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3489 			 (*pretvar)->lVal = (LONG)ent->animating;
3490 			 break;
3491 		}
3492 		case _gep_aiflag_blink:
3493 		{
3494 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3495 			 (*pretvar)->lVal = (LONG)ent->blink;
3496 			 break;
3497 		}
3498 		case _gep_aiflag_invincible:
3499 		{
3500 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3501 			 (*pretvar)->lVal = (LONG)ent->invincible;
3502 			 break;
3503 		}
3504 		case _gep_aiflag_autokill:
3505 		{
3506 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3507 			 (*pretvar)->lVal = (LONG)ent->autokill;
3508 			 break;
3509 		}
3510 		case _gep_aiflag_walking:
3511 		{
3512 			 ScriptVariant_Clear(*pretvar); // depracated, just don't let it crash
3513 			 break;
3514 		}
3515 		default:
3516 			ScriptVariant_Clear(*pretvar);
3517 			return E_FAIL;
3518 		}
3519 		break;
3520 	}
3521 	case _gep_aimove:
3522 	{
3523 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3524 		(*pretvar)->lVal = (LONG)ent->modeldata.aimove;
3525 		break;
3526 	}
3527     case _gep_alpha:
3528 	{
3529 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3530 		(*pretvar)->lVal = (LONG)ent->modeldata.alpha;
3531 		break;
3532 	}
3533     case _gep_animal:
3534 	{
3535 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3536 		(*pretvar)->lVal = (LONG)ent->modeldata.animal;
3537 		break;
3538 	}
3539 	case _gep_animating:
3540 	{
3541 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3542 		(*pretvar)->lVal = (LONG)ent->animating;
3543 		break;
3544 	}
3545 	case _gep_animation:
3546 	{
3547 		ScriptVariant_ChangeType(*pretvar, VT_PTR);
3548 		(*pretvar)->ptrVal = (VOID*)ent->animation;
3549 		break;
3550 	}
3551 
3552 	/*
3553 	case _gep_animationid: See animnum.
3554 	*/
3555 
3556 	case _gep_animheight:
3557 	{
3558 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3559 		(*pretvar)->lVal = (LONG)ent->animation->height;
3560 		break;
3561 	}
3562 	case _gep_animhits:
3563 	{
3564 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3565 		(*pretvar)->lVal = (LONG)ent->animation->animhits;
3566 		break;
3567 	}
3568 	case _gep_animnum:
3569 	case _gep_animationid:
3570 	{
3571 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3572 		(*pretvar)->lVal = (LONG)ent->animnum;
3573 		break;
3574 	}
3575 	case _gep_animpos:
3576 	{
3577 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3578 		(*pretvar)->lVal = (LONG)ent->animpos;
3579 		break;
3580 	}
3581 	case _gep_animvalid:
3582 	{
3583 		ltemp = 0;
3584 		if(paramCount == 3)
3585 		{
3586 			arg = varlist[2];
3587 			if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
3588 			ltemp = (LONG)0;
3589 		}
3590 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3591 		(*pretvar)->lVal = (LONG)validanim(ent, ltemp);
3592 		break;
3593 	}
3594 	case _gep_antigrab:
3595 	{
3596 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3597 		(*pretvar)->dblVal = (DOUBLE)ent->modeldata.antigrab;
3598 		break;
3599 	}
3600 	case _gep_antigravity:
3601 	{
3602 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3603 		(*pretvar)->dblVal = (DOUBLE)ent->antigravity;
3604 		break;
3605 	}
3606 	case _gep_attack:
3607 	{
3608 		if(paramCount<6) break;
3609 		arg = varlist[2];
3610 		if(arg->vt != VT_INTEGER)
3611 		{
3612 			printf("Error, getentityproperty({ent}, 'attack', {sub property}, {index}, {animation}, {frame}): You must give a string name for {sub property}.\n");
3613 			return E_FAIL;
3614 		}
3615 		ltemp = arg->lVal;
3616 
3617 		if(varlist[3]->vt != VT_INTEGER
3618 			|| varlist[4]->vt != VT_INTEGER
3619 			|| varlist[5]->vt != VT_INTEGER)
3620 		{
3621 			printf("\n Error, getentityproperty({ent}, 'attack', {sub property}, {index}, {animation}, {frame}): {Animation} or {frame} parameter is missing or invalid. \n");
3622 			return E_FAIL;
3623 		}
3624 
3625 		//varlist[3]->lval														//Attack box index (multiple attack boxes).
3626 		i		= varlist[4]->lVal;												//Animation parameter.
3627 		tempint	= varlist[5]->lVal;												//Frame parameter.
3628 
3629 		if(!validanim(ent,i) || !ent->modeldata.animation[i]->attacks || !ent->modeldata.animation[i]->attacks[tempint])	//Verify animation and active attack on frame.
3630 		{
3631 			break;
3632 		}
3633 
3634 		attack = ent->modeldata.animation[i]->attacks[tempint];					//Get attack struct.
3635 
3636 		switch(ltemp)
3637 		{
3638 			case _gep_attack_blockflash:
3639 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3640 				 (*pretvar)->lVal = (LONG)attack->blockflash;
3641 				 break;
3642 			case _gep_attack_blocksound:
3643 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3644 				 (*pretvar)->lVal = (LONG)attack->blocksound;
3645 				 break;
3646 			case _gep_attack_coords:
3647 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3648 				 (*pretvar)->lVal = (LONG)attack->attack_coords[varlist[6]->lVal];
3649 				 break;
3650 			case _gep_attack_counterattack:
3651 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3652 				 (*pretvar)->lVal = (LONG)attack->counterattack;
3653 				 break;
3654 			case _gep_attack_direction:
3655 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3656 				 (*pretvar)->lVal = (LONG)attack->force_direction;
3657 				 break;
3658 			case _gep_attack_dol:
3659 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3660 				 (*pretvar)->lVal = (LONG)attack->damage_on_landing;
3661 				 break;
3662 			case _gep_attack_dot:
3663 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3664 				 (*pretvar)->lVal = (LONG)attack->dot;
3665 				 break;
3666 			case _gep_attack_dotforce:
3667 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3668 				 (*pretvar)->lVal = (LONG)attack->dot_force;
3669 				 break;
3670 			case _gep_attack_dotindex:
3671 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3672 				 (*pretvar)->lVal = (LONG)attack->dot_index;
3673 				 break;
3674 			case _gep_attack_dotrate:
3675 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3676 				 (*pretvar)->lVal = (LONG)attack->dot_rate;
3677 				 break;
3678 			case _gep_attack_dottime:
3679 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3680 				 (*pretvar)->lVal = (LONG)attack->dot_time;
3681 				 break;
3682 			case _gep_attack_drop:
3683 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3684 				 (*pretvar)->lVal = (LONG)attack->attack_drop;
3685 				 break;
3686 			case _gep_attack_dropv:
3687 				 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3688 				 (*pretvar)->dblVal = (DOUBLE)attack->dropv[varlist[6]->lVal];
3689 				 break;
3690 			case _gep_attack_force:
3691 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3692 				 (*pretvar)->lVal = (LONG)attack->attack_force;
3693 				 break;
3694 			case _gep_attack_forcemap:
3695 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3696 				 (*pretvar)->lVal = (LONG)attack->forcemap;
3697 				 break;
3698 			case _gep_attack_freeze:
3699 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3700 				 (*pretvar)->lVal = (LONG)attack->freeze;
3701 				 break;
3702 			case _gep_attack_freezetime:
3703 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3704 				 (*pretvar)->lVal = (LONG)attack->freezetime;
3705 				 break;
3706 			case _gep_attack_grab:
3707 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3708 				 (*pretvar)->lVal = (LONG)attack->grab;
3709 				 break;
3710 			case _gep_attack_grabdistance:
3711 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3712 				 (*pretvar)->lVal = (LONG)attack->grab_distance;
3713 				 break;
3714 			case _gep_attack_guardcost:
3715 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3716 				 (*pretvar)->lVal = (LONG)attack->guardcost;
3717 				 break;
3718 			case _gep_attack_hitflash:
3719 				ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3720 				(*pretvar)->lVal = (LONG)attack->hitflash;
3721 				break;
3722 			case _gep_attack_hitsound:
3723 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3724 				 (*pretvar)->lVal = (LONG)attack->hitsound;
3725 				 break;
3726 			case _gep_attack_jugglecost:
3727 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3728 				 (*pretvar)->lVal = (LONG)attack->jugglecost;
3729 				 break;
3730 			case _gep_attack_maptime:
3731 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3732 				 (*pretvar)->lVal = (LONG)attack->maptime;
3733 				 break;
3734 			case _gep_attack_noblock:
3735 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3736 				 (*pretvar)->lVal = (LONG)attack->no_block;
3737 				 break;
3738 			case _gep_attack_noflash:
3739 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3740 				 (*pretvar)->lVal = (LONG)attack->no_flash;
3741 				 break;
3742 			case _gep_attack_nokill:
3743 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3744 				 (*pretvar)->lVal = (LONG)attack->no_kill;
3745 				 break;
3746 			case _gep_attack_nopain:
3747 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3748 				 (*pretvar)->lVal = (LONG)attack->no_pain;
3749 				 break;
3750 			case _gep_attack_otg:
3751 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3752 				 (*pretvar)->lVal = (LONG)attack->otg;
3753 				 break;
3754 			case _gep_attack_pause:
3755 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3756 				 (*pretvar)->lVal = (LONG)attack->pause_add;
3757 				 break;
3758 			case _gep_attack_seal:
3759 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3760 				 (*pretvar)->lVal = (LONG)attack->seal;
3761 				 break;
3762 			case _gep_attack_sealtime:
3763 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3764 				 (*pretvar)->lVal = (LONG)attack->sealtime;
3765 				 break;
3766 			case _gep_attack_staydown:
3767 				 ScriptVariant_ChangeType(*pretvar, VT_PTR);
3768 				 (*pretvar)->ptrVal = (VOID*)attack->staydown;
3769 				 break;
3770 			case _gep_attack_steal:
3771 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3772 				 (*pretvar)->lVal = (LONG)attack->steal;
3773 				 break;
3774 			case _gep_attack_type:
3775 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3776 				 (*pretvar)->lVal = (LONG)attack->attack_type;
3777 				 break;
3778 			default:
3779 				ScriptVariant_Clear(*pretvar);
3780 				return E_FAIL;
3781 		}
3782 		break;
3783 	}
3784 	case _gep_attacking:
3785 	{
3786 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3787 		(*pretvar)->lVal = (LONG)ent->attacking;
3788 		break;
3789 	}
3790 	case _gep_attackid:
3791 	{
3792 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3793 		(*pretvar)->lVal = (LONG)ent->attack_id;
3794 		break;
3795 	}
3796 	case _gep_autokill:
3797 	{
3798 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3799 		(*pretvar)->lVal = (LONG)ent->autokill;
3800 		break;
3801 	}
3802 	case _gep_base:
3803 	{
3804 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3805 		(*pretvar)->dblVal = (DOUBLE)ent->base;
3806 		break;
3807 	}
3808 	case _gep_bbox:
3809 	{
3810 		if(paramCount<6) break;
3811 
3812 		if(varlist[2]->vt != VT_INTEGER
3813 			|| varlist[3]->vt != VT_INTEGER
3814 			|| varlist[4]->vt != VT_INTEGER
3815 			|| varlist[5]->vt != VT_INTEGER)
3816 		{
3817 			printf("\n Error, getentityproperty({ent}, 'bbox', {index}, {animation}, {frame}, {arg}): {index}, {Animation}, {frame}, or {arg} parameter is missing or invalid. \n");
3818 			return E_FAIL;
3819 		}
3820 
3821 		//varlist[3]->lval;														//bbox index (multiple bbox support).
3822 		i		= varlist[3]->lVal;												//Animation parameter.
3823 		tempint	= varlist[4]->lVal;												//Frame parameter.
3824 
3825 		if(!ent->modeldata.animation[i]->bbox_coords)
3826 		{
3827 			break;
3828 		}
3829 
3830 		coords = ent->modeldata.animation[i]->bbox_coords[tempint];
3831 
3832 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3833 		(*pretvar)->lVal = (LONG)coords[varlist[5]->lVal];
3834 		break;
3835 	}
3836 	case _gep_blink:
3837 	{
3838 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3839 		(*pretvar)->lVal = (LONG)ent->blink;
3840 		break;
3841 	}
3842 	case _gep_blockback:
3843 	{
3844 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
3845 			ent->modeldata.blockback = (int)ltemp;
3846 		break;
3847 	}
3848 	case _gep_blockodds:
3849 	{
3850 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3851 		(*pretvar)->lVal = (LONG)ent->modeldata.blockodds;
3852 		break;
3853 	}
3854 	case _gep_blockpain:
3855 	{
3856 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
3857 			ent->modeldata.blockpain = (int)ltemp;
3858 		break;
3859 	}
3860 	case _gep_bounce:
3861 	{
3862 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3863 		(*pretvar)->lVal = (LONG)ent->modeldata.bounce;
3864 		break;
3865 	}
3866 	case _gep_chargerate:
3867 	{
3868 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3869 		(*pretvar)->lVal = (LONG)ent->modeldata.chargerate;
3870 		break;
3871 	}
3872 	case _gep_colourmap:
3873 	{
3874 		ScriptVariant_ChangeType(*pretvar, VT_PTR);
3875 		(*pretvar)->ptrVal = (VOID*)(ent->colourmap);
3876 		break;
3877 	}
3878 	case _gep_colourtable:
3879 	{
3880 		ScriptVariant_ChangeType(*pretvar, VT_PTR);
3881 		(*pretvar)->ptrVal = (VOID*)(ent->modeldata.colourmap[varlist[2]->lVal]);
3882 		break;
3883 	}
3884 	case _gep_damage_on_landing:
3885 	{
3886 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3887 		(*pretvar)->lVal = (LONG)ent->damage_on_landing;
3888 		break;
3889 	}
3890 	case _gep_dead:
3891 	{
3892 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3893 		(*pretvar)->lVal = (LONG)ent->dead;
3894 		break;
3895 	}
3896 	case _gep_defaultmodel:
3897 	case _gep_defaultname:
3898 	{
3899 		ScriptVariant_ChangeType(*pretvar, VT_STR);
3900 		strcpy(StrCache_Get((*pretvar)->strVal), ent->defaultmodel->name);
3901 		break;
3902 	}
3903 	case _gep_defense:
3904 	{
3905 		ltemp = 0;
3906 		if(paramCount >= 3)
3907 		{
3908 			if(FAILED(ScriptVariant_IntegerValue(varlist[2], &ltemp))){
3909 				printf("You must specify an attack type for your defense property.\n");
3910 				return E_FAIL;
3911 			}
3912 			ltemp2 = _gep_defense_factor;
3913 		}
3914 
3915 		if(paramCount >= 4){
3916 			if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
3917 				return E_FAIL;
3918 		}
3919 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
3920 
3921 		switch(ltemp2)
3922 		{
3923 		case _gep_defense_factor:
3924 		{
3925 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.defense_factors[(int)ltemp];
3926 			break;
3927 		}
3928 		case _gep_defense_blockpower:
3929 		{
3930 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.defense_blockpower[(int)ltemp];
3931 			break;
3932 		}
3933 		case _gep_defense_blockratio:
3934 		{
3935 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.defense_blockratio[(int)ltemp];
3936 			break;
3937 		}
3938 		case _gep_defense_blockthreshold:
3939 		{
3940 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.defense_blockthreshold[(int)ltemp];
3941 			break;
3942 		}
3943 		case _gep_defense_blocktype:
3944 		{
3945 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.defense_blocktype[(int)ltemp];
3946 			break;
3947 		}
3948 		case _gep_defense_knockdown:
3949 		{
3950 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.defense_knockdown[(int)ltemp];
3951 			break;
3952 		}
3953 		case _gep_defense_pain:
3954 		{
3955 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.defense_pain[(int)ltemp];
3956 			break;
3957 		}
3958 		default:
3959 			return E_FAIL;
3960 		}
3961 		break;
3962 	}
3963 	case _gep_detect:
3964 	{
3965 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3966 		(*pretvar)->lVal = (LONG)ent->modeldata.stealth.detect;
3967 		break;
3968 	}
3969 	case _gep_direction:
3970 	{
3971 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
3972 		(*pretvar)->lVal = (LONG)ent->direction;
3973 		break;
3974 	}
3975 	case _gep_dot:
3976 	{
3977 		if(paramCount<4) break;
3978 
3979 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
3980 			i = (int)ltemp;
3981 
3982 		arg = varlist[3];
3983 		if(arg->vt != VT_INTEGER)
3984 		{
3985 			if(arg->vt != VT_STR)
3986 				printf("You must provide a string name for dot subproperty.\n\
3987                         ~'time'\n\
3988                         ~'mode'\n\
3989                         ~'force'\n\
3990                         ~'rate'\n\
3991                         ~'type'\n\
3992                         ~'owner'\n");
3993 			return E_FAIL;
3994 		}
3995 		switch(arg->lVal)
3996 		{
3997 		case _gep_dot_time:
3998 		{
3999 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4000 			 (*pretvar)->lVal = (LONG)ent->dot_time[i];
4001 			 break;
4002 		}
4003 		case _gep_dot_mode:
4004 		{
4005 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4006 			 (*pretvar)->lVal = (LONG)ent->dot[i];
4007 			 break;
4008 		}
4009 		case _gep_dot_force:
4010 
4011 		{
4012 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4013 			 (*pretvar)->lVal = (LONG)ent->dot_force[i];
4014 			 break;
4015 		}
4016 		case _gep_dot_rate:
4017 		{
4018 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4019 			 (*pretvar)->lVal = (LONG)ent->dot_rate[i];
4020 			 break;
4021 		}
4022 		case _gep_dot_type:
4023 		{
4024 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4025 			 (*pretvar)->lVal = (LONG)ent->dot_atk[i];
4026 			 break;
4027 		}
4028 		case _gep_dot_owner:
4029 		{
4030 			 ScriptVariant_ChangeType(*pretvar, VT_PTR);
4031 			 (*pretvar)->ptrVal = (VOID*)ent->dot_owner[i];
4032 			 break;
4033 		}
4034 		break;
4035 		}
4036 	}
4037 	case _gep_dropframe:
4038 	{
4039 		ltemp = 0;
4040 		if(paramCount == 3)
4041 		{
4042 			arg = varlist[2];
4043 			if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
4044 			ltemp = (LONG)0;
4045 		}
4046 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4047 		(*pretvar)->lVal = (LONG)ent->modeldata.animation[ltemp]->dropframe;
4048 		break;
4049 	}
4050 	case _gep_edelay:
4051 	{
4052 		arg = varlist[2];
4053 		if(arg->vt != VT_INTEGER)
4054 		{
4055 			if(arg->vt != VT_STR)
4056 				printf("You must provide a string name for edelay subproperty.\n\
4057                         ~'cap_max'\n\
4058                         ~'cap_min'\n\
4059                         ~'factor'\n\
4060                         ~'mode'\n\
4061                         ~'range_max'\n\
4062                         ~'range_min'\n");
4063 			return E_FAIL;
4064 		}
4065 		ltemp = arg->lVal;
4066 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4067 
4068 		switch(ltemp)
4069 		{
4070 		case _gep_edelay_mode:
4071 		{
4072 			(*pretvar)->lVal = (LONG)ent->modeldata.edelay.mode;
4073 			break;
4074 		}
4075 		case _gep_edelay_factor:
4076 		{
4077 			(*pretvar)->dblVal = (float)ent->modeldata.edelay.factor;
4078 			break;
4079 		}
4080 		case _gep_edelay_cap_min:
4081 		{
4082 			(*pretvar)->lVal = (LONG)ent->modeldata.edelay.cap_min;
4083 			break;
4084 		}
4085 		case _gep_edelay_cap_max:
4086 		{
4087 			(*pretvar)->lVal = (LONG)ent->modeldata.edelay.cap_max;
4088 			break;
4089 		}
4090 		case _gep_edelay_range_min:
4091 		{
4092 			(*pretvar)->lVal = (LONG)ent->modeldata.edelay.range_min;
4093 			break;
4094 		}
4095 		case _gep_edelay_range_max:
4096 		{
4097 			(*pretvar)->lVal = (LONG)ent->modeldata.edelay.range_max;
4098 			break;
4099 		}
4100 		default:
4101 			ScriptVariant_Clear(*pretvar);
4102 			return E_FAIL;
4103 		}
4104 		break;
4105 	}
4106 	case _gep_energycost:
4107 	{
4108 		if(paramCount<4) break;
4109 
4110 		if(varlist[2]->vt != VT_INTEGER)
4111 		{
4112 			if(varlist[2]->vt != VT_STR)
4113 				printf("You must provide a string name for edelay energycost.\n\
4114                         ~'cost'\n\
4115                         ~'disable'\n\
4116                         ~'mponly'\n");
4117 			return E_FAIL;
4118 		}
4119 		ltemp	= varlist[2]->lVal;												//Subproperty.
4120 		i		= varlist[3]->lVal;												//Animation.
4121 
4122 		if(!validanim(ent,i))													//Verify animation.
4123 		{
4124 			break;
4125 		}
4126 
4127 		switch(ltemp)
4128 		{
4129 			case _gep_energycost_cost:
4130 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4131 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->energycost.cost;
4132 				 break;
4133 			case _gep_energycost_disable:
4134 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4135 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->energycost.disable;
4136 				 break;
4137 			case _gep_energycost_mponly:
4138 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4139 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->energycost.mponly;
4140 				 break;
4141 			default:
4142 				ScriptVariant_Clear(*pretvar);
4143 				return E_FAIL;
4144 		}
4145 		break;
4146 	}
4147 	case _gep_escapecount:
4148 	{
4149 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4150 		(*pretvar)->lVal = (LONG)ent->escapecount;
4151 		break;
4152 	}
4153 	case _gep_escapehits:
4154 	{
4155 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4156 		(*pretvar)->lVal = (LONG)ent->modeldata.escapehits;
4157 		break;
4158 	}
4159 	case _gep_exists:
4160 	{
4161 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4162 		(*pretvar)->lVal = (LONG)ent->exists;
4163 		break;
4164 	}
4165 	case _gep_falldie:
4166 	{
4167 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4168 		(*pretvar)->lVal = (LONG)ent->modeldata.falldie;
4169 		break;
4170 	}
4171 	case _gep_flash:
4172 	{
4173 		arg = varlist[2];
4174 		if(arg->vt != VT_INTEGER)
4175 		{
4176 			if(arg->vt != VT_STR)
4177 				printf("You must give a string name for flash property.\n");
4178 			return E_FAIL;
4179 		}
4180 		ltemp = arg->lVal;
4181 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4182 
4183 		switch(ltemp)
4184 		{
4185             case _gep_flash_block:
4186             {
4187                 i = ent->modeldata.bflash;
4188                 break;
4189             }
4190             case _gep_flash_def:
4191             {
4192                 i = ent->modeldata.flash;
4193                 break;
4194             }
4195             case _gep_flash_noattack:
4196             {
4197                 i = ent->modeldata.noatflash;
4198                 break;
4199             }
4200             default:
4201 			{
4202                 ScriptVariant_Clear(*pretvar);
4203                 return E_FAIL;
4204             }
4205 		}
4206 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4207 		(*pretvar)->lVal = (LONG)i;
4208 		break;
4209 	}
4210 	case _gep_pain_time:
4211 	{
4212 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4213 		(*pretvar)->lVal = (LONG)ent->pain_time;
4214 		break;
4215 	}
4216 	case _gep_freezetime:
4217 	{
4218 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4219 		(*pretvar)->lVal = (LONG)ent->freezetime;
4220 		break;
4221 	}
4222 	case _gep_frozen:
4223 	{
4224 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4225 		(*pretvar)->lVal = (LONG)ent->frozen;
4226 		break;
4227 	}
4228 	case _gep_gfxshadow:
4229 	{
4230 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4231 		(*pretvar)->lVal = (LONG)ent->modeldata.gfxshadow;
4232 		break;
4233 	}
4234 	case _gep_grabbing:
4235 	{
4236 		if(ent->grabbing) // always return an empty var if it is NULL
4237 		{
4238 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
4239 			(*pretvar)->ptrVal = (VOID*)ent->grabbing;
4240 		}
4241 		break;
4242 	}
4243 	case _gep_grabforce:
4244 	{
4245 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4246 		(*pretvar)->lVal = (LONG)ent->modeldata.grabforce;
4247 		break;
4248 	}
4249 	case _gep_guardpoints:
4250 	{
4251 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4252 		(*pretvar)->lVal = (LONG)ent->modeldata.guardpoints.current;
4253 		break;
4254 	}
4255 	case _gep_health:
4256 	{
4257 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4258 		(*pretvar)->lVal = (LONG)ent->health;
4259 		break;
4260 	}
4261 	case _gep_height:
4262 	{
4263 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4264 		(*pretvar)->lVal = (LONG)ent->modeldata.height;
4265 		break;
4266 	}
4267 	case _gep_hitbyid:
4268 	{
4269 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4270 		(*pretvar)->lVal = (LONG)ent->hit_by_attack_id;
4271 		break;
4272 	}
4273 	case _gep_hmapl:
4274 	{
4275 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4276 		(*pretvar)->lVal = (LONG)ent->modeldata.maps.hide_start;
4277 		 break;
4278 	}
4279 	case _gep_hmapu:
4280 	{
4281 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4282 		(*pretvar)->lVal = (LONG)ent->modeldata.maps.hide_end;
4283 		 break;
4284 	}
4285 	case _gep_icon:
4286 	{
4287 	    arg = varlist[2];
4288 		if(arg->vt != VT_INTEGER)
4289 		{
4290 			if(arg->vt != VT_STR)
4291 				printf("You must provide a string name for icon subproperty:\n\
4292                         getentityproperty({ent}, 'icon', {subproperty});\n\
4293                         ~'default'\n\
4294                         ~'die'\n\
4295                         ~'get'\n\
4296                         ~'mphigh'\n\
4297                         ~'mplow'\n\
4298                         ~'mpmed'\n\
4299                         ~'pain'\n\
4300                         ~'weapon'\n\
4301                         ~'x'\n\
4302                         ~'y'\n");
4303 			return E_FAIL;
4304 		}
4305 		ltemp = arg->lVal;
4306 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4307 
4308 		switch(ltemp)
4309 		{
4310             case _gep_icon_def:
4311             {
4312                 i = ent->modeldata.icon.def;
4313                 break;
4314             }
4315             case _gep_icon_die:
4316             {
4317                 i = ent->modeldata.icon.die;
4318                 break;
4319             }
4320             case _gep_icon_get:
4321             {
4322                 i = ent->modeldata.icon.get;
4323                 break;
4324             }
4325             case _gep_icon_mphigh:
4326             {
4327                 i = ent->modeldata.icon.mphigh;
4328                 break;
4329             }
4330             case _gep_icon_mplow:
4331             {
4332                 i = ent->modeldata.icon.mplow;
4333                 break;
4334             }
4335             case _gep_icon_mpmed:
4336             {
4337                 i = ent->modeldata.icon.mpmed;
4338                 break;
4339             }
4340             case _gep_icon_pain:
4341             {
4342                 i = ent->modeldata.icon.pain;
4343                 break;
4344             }
4345             case _gep_icon_weapon:
4346             {
4347                 i = ent->modeldata.icon.weapon;
4348                 break;
4349             }
4350             case _gep_icon_x:
4351             {
4352                 i = ent->modeldata.icon.x;
4353                 break;
4354             }
4355             case _gep_icon_y:
4356             {
4357                 i = ent->modeldata.icon.y;
4358                 break;
4359             }
4360             default:
4361             {
4362                 ScriptVariant_Clear(*pretvar);
4363                 return E_FAIL;
4364             }
4365 		}
4366 
4367 		if (i >= 0)
4368 		{
4369 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
4370 			spr = sprite_map[i].sprite;
4371 			spr->centerx = sprite_map[i].centerx;
4372 			spr->centery = sprite_map[i].centery;
4373 			(*pretvar)->ptrVal = (VOID*)(spr);
4374 		}
4375 		else
4376 		{
4377 			ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4378 			(*pretvar)->lVal = -1;
4379 		}
4380 		break;
4381 	}
4382 	case _gep_invincible:
4383 	{
4384 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4385 		(*pretvar)->lVal = (LONG)ent->invincible;
4386 		break;
4387 	}
4388 	case _gep_invinctime:
4389 	{
4390 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4391 		(*pretvar)->lVal = (LONG)ent->invinctime;
4392 		break;
4393 	}
4394 	case _gep_jugglepoints:
4395 	{
4396 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4397 		(*pretvar)->lVal = (LONG)ent->modeldata.jugglepoints.current;
4398 		break;
4399 	}
4400 	case _gep_knockdowncount:
4401 	{
4402 	    /*
4403 	    2011_04_14, DC: Backward compatability; default to current if subproperty not provided.
4404 	    */
4405 	    if(paramCount<3)
4406 	    {
4407             ltemp = _gep_knockdowncount_current;
4408 	    }
4409 	    else
4410 	    {
4411             arg = varlist[2];
4412 
4413             if(arg->vt != VT_INTEGER)
4414             {
4415                 if(arg->vt != VT_STR)
4416                 {
4417                     printf("You must provide a string name for knockdowncount subproperty:\n\
4418                             getentityproperty({ent}, 'knockdowncount', {subproperty})\n\
4419                             ~'current'\n\
4420                             ~'max'\n\
4421                             ~'time'\n");
4422                     return E_FAIL;
4423                 }
4424             }
4425 
4426             ltemp = arg->lVal;
4427 	    }
4428 
4429 		switch(ltemp)
4430 		{
4431 			case _gep_knockdowncount_current:
4432                 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4433                 (*pretvar)->dblVal = (DOUBLE)ent->knockdowncount;
4434 				break;
4435 			case _gep_knockdowncount_max:
4436                 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4437                 (*pretvar)->dblVal = (DOUBLE)ent->modeldata.knockdowncount;
4438 				 break;
4439             case _gep_knockdowncount_time:
4440                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4441                 (*pretvar)->lVal = (LONG)ent->knockdowncount;
4442 				break;
4443 			default:
4444 				ScriptVariant_Clear(*pretvar);
4445 				return E_FAIL;
4446 		}
4447 		break;
4448 	}
4449 	case _gep_komap:
4450 	{
4451 		if(paramCount<2) break;
4452 
4453 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4454 		(*pretvar)->lVal = (LONG)ent->modeldata.maps.ko;
4455 		break;
4456 	}
4457 	case _gep_landframe:
4458 	{
4459 	    if(paramCount<4) break;
4460 
4461 		if(varlist[2]->vt != VT_INTEGER
4462 			|| varlist[3]->vt != VT_INTEGER)
4463 		{
4464 			printf("\n Error, getentityproperty({ent}, 'landframe', {sub property}, {animation}): {Sub property} or {Animation} parameter is missing or invalid. \n");
4465 			return E_FAIL;
4466 		}
4467 		ltemp	= varlist[2]->lVal;												//Subproperty.
4468 		i		= varlist[3]->lVal;												//Animation.
4469 
4470 		if(!validanim(ent,i))													//Verify animation.
4471 		{
4472 			break;
4473 		}
4474 
4475 		switch(ltemp)
4476 		{
4477 			case _gep_landframe_ent:
4478 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4479 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->landframe.ent;
4480 				 break;
4481 			case _gep_landframe_frame:
4482 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4483 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->landframe.frame;
4484 				 break;
4485 			default:
4486 				ScriptVariant_Clear(*pretvar);
4487 				return E_FAIL;
4488 		}
4489 		break;
4490 	}
4491 	case _gep_lifespancountdown:
4492 	{
4493 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4494 		(*pretvar)->dblVal = (DOUBLE)ent->lifespancountdown;
4495 		break;
4496 	}
4497 	case _gep_link:
4498 	{
4499 		if(ent->link) // always return an empty var if it is NULL
4500 		{
4501 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
4502 			(*pretvar)->ptrVal = (VOID*)ent->link;
4503 		}
4504 		break;
4505 	}
4506 	case _gep_map:
4507 	{
4508 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4509 		(*pretvar)->lVal = (LONG)0;
4510 		for(i=0;i<ent->modeldata.maps_loaded;i++)
4511 		{
4512 			if(ent->colourmap == ent->modeldata.colourmap[i])
4513 			{
4514 				(*pretvar)->lVal = (LONG)(i+1);
4515 				break;
4516 			}
4517 		}
4518 		break;
4519 	}
4520 	case _gep_mapcount:
4521 	{
4522 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4523 		(*pretvar)->lVal = (LONG)(ent->modeldata.maps_loaded+1);
4524 		 break;
4525 	}
4526 	case _gep_mapdefault:
4527 	{
4528 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4529 		(*pretvar)->lVal = (LONG)(ent->map);
4530 		 break;
4531 	}
4532 	case _gep_maps:
4533 	{
4534 	    arg = varlist[2];
4535 		if(arg->vt != VT_INTEGER)
4536 		{
4537 			if(arg->vt != VT_STR)
4538 				printf("You must give a string name for maps property.\n");
4539 			return E_FAIL;
4540 		}
4541 		ltemp = arg->lVal;
4542 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4543 
4544 		switch(ltemp)
4545 		{
4546 		    case _gep_maps_count:
4547             {
4548                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4549                 (*pretvar)->lVal = (LONG)(ent->modeldata.maps_loaded+1);
4550                 break;
4551             }
4552 
4553             case _gep_maps_current:
4554             {
4555                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4556                 (*pretvar)->lVal = (LONG)0;
4557                 for(i=0;i<ent->modeldata.maps_loaded;i++)
4558                 {
4559                     if(ent->colourmap == ent->modeldata.colourmap[i])
4560                     {
4561                         (*pretvar)->lVal = (LONG)(i+1);
4562                         break;
4563                     }
4564                 }
4565                 break;
4566             }
4567             case _gep_maps_dying:
4568             {
4569                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4570                 (*pretvar)->lVal = (LONG)(ent->dying);
4571                 break;
4572             }
4573             case _gep_maps_dying_critical:
4574             {
4575                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4576                 (*pretvar)->lVal = (LONG)(ent->per2);
4577                 break;
4578             }
4579             case _gep_maps_dying_low:
4580             {
4581                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4582                 (*pretvar)->lVal = (LONG)(ent->per1);
4583                 break;
4584             }
4585             case _gep_maps_frozen:
4586             {
4587                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4588                 (*pretvar)->lVal = (LONG)(ent->modeldata.maps.frozen);
4589                 break;
4590             }
4591             case _gep_maps_hide_end:
4592             {
4593                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4594                 (*pretvar)->lVal = (LONG)(ent->modeldata.maps.hide_end);
4595                 break;
4596             }
4597             case _gep_maps_hide_start:
4598             {
4599                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4600                 (*pretvar)->lVal = (LONG)(ent->modeldata.maps.hide_start);
4601                 break;
4602             }
4603             case _gep_maps_ko:
4604             {
4605                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4606                 (*pretvar)->lVal = (LONG)(ent->modeldata.maps.ko);
4607                 break;
4608             }
4609             case _gep_maps_kotype:
4610             {
4611                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4612                 (*pretvar)->lVal = (LONG)(ent->modeldata.maps.kotype);
4613                 break;
4614             }
4615             case _gep_maps_table:
4616             {
4617                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
4618                 (*pretvar)->ptrVal = (VOID*)(ent->colourmap);
4619                 break;
4620             }
4621             case _gep_maps_time:
4622             {
4623                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4624                 (*pretvar)->lVal = (LONG)(ent->maptime);
4625                 break;
4626             }
4627             default:
4628             {
4629                 ScriptVariant_Clear(*pretvar);
4630                 return E_FAIL;
4631             }
4632 		}
4633 		break;
4634 	}
4635 	case _gep_maxguardpoints:
4636 	{
4637 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4638 		(*pretvar)->lVal = (LONG)ent->modeldata.guardpoints.maximum;
4639 		break;
4640 	}
4641 	case _gep_maxhealth:
4642 	{
4643 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4644 		(*pretvar)->lVal = (LONG)ent->modeldata.health;
4645 		break;
4646 	}
4647 	case _gep_maxjugglepoints:
4648 	{
4649 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4650 		(*pretvar)->lVal = (LONG)ent->modeldata.jugglepoints.maximum;
4651 		break;
4652 	}
4653 	case _gep_maxmp:
4654 	{
4655 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4656 		(*pretvar)->lVal = (LONG)ent->modeldata.mp;
4657 		break;
4658 	}
4659 	case _gep_model:
4660 	{
4661 		ScriptVariant_ChangeType(*pretvar, VT_STR);
4662 		strcpy(StrCache_Get((*pretvar)->strVal), ent->model->name);
4663 		break;
4664 	}
4665 	case _gep_mp:
4666 	{
4667 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4668 		(*pretvar)->lVal = (LONG)ent->mp;
4669 		break;
4670 	}
4671 	case _gep_mpdroprate:
4672 	{
4673 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4674 		(*pretvar)->lVal = (LONG)ent->modeldata.mpdroprate;
4675 		break;
4676 	}
4677 	case _gep_mprate:
4678 	{
4679 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4680 		(*pretvar)->lVal = (LONG)ent->modeldata.mprate;
4681 		break;
4682 	}
4683 	case _gep_mpstable:
4684 	{
4685 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4686 		(*pretvar)->lVal = (LONG)ent->modeldata.mpstable;
4687 		break;
4688 	}
4689 	case _gep_mpstableval:
4690 	{
4691 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4692 		(*pretvar)->lVal = (LONG)ent->modeldata.mpstableval;
4693 		break;
4694 	}
4695 	case _gep_name:
4696 	{
4697 		ScriptVariant_ChangeType(*pretvar, VT_STR);
4698 		strcpy(StrCache_Get((*pretvar)->strVal), ent->name);
4699 		break;
4700 	}
4701 	case _gep_nextanim:
4702 	{
4703 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4704 		(*pretvar)->lVal = (LONG)ent->nextanim;
4705 		break;
4706 	}
4707 	case _gep_nextthink:
4708 	{
4709 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4710 		(*pretvar)->lVal = (LONG)ent->nextthink;
4711 		break;
4712 	}
4713 	case _gep_no_adjust_base:
4714 	{
4715 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4716 		(*pretvar)->lVal = (LONG)ent->modeldata.no_adjust_base;
4717 		break;
4718 	}
4719 	case _gep_noaicontrol:
4720 	{
4721 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4722 		(*pretvar)->lVal = (LONG)ent->noaicontrol;
4723 		break;
4724 	}
4725 	case _gep_nodieblink:
4726 	{
4727 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4728 		(*pretvar)->lVal = (LONG)ent->modeldata.nodieblink;
4729 		break;
4730 	}
4731 	case _gep_nodrop:
4732 	{
4733 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4734 		(*pretvar)->lVal = (LONG)ent->modeldata.nodrop;
4735 		break;
4736 	}
4737 	case _gep_nograb:
4738 	{
4739 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4740 		(*pretvar)->lVal = (LONG)ent->nograb;
4741 		break;
4742 	}
4743 	case _gep_nolife:
4744 	{
4745 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4746 		(*pretvar)->lVal = (LONG)ent->modeldata.nolife;
4747 		break;
4748 	}
4749 	case _gep_nopain:
4750 	{
4751 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4752 		(*pretvar)->lVal = (LONG)ent->modeldata.nopain;
4753 		break;
4754 	}
4755 	case _gep_offense:
4756 	{
4757 		ltemp = 0;
4758 		if(paramCount >= 3)
4759 		{
4760 			arg = varlist[2];
4761 			if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
4762 				ltemp = (LONG)0;
4763 		}
4764 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4765 		(*pretvar)->dblVal = (DOUBLE)ent->modeldata.offense_factors[(int)ltemp];
4766 		break;
4767 	}
4768 	case _gep_opponent:
4769 	{
4770 		if(ent->opponent) // always return an empty var if it is NULL
4771 		{
4772 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
4773 			(*pretvar)->ptrVal = (VOID*)ent->opponent;
4774 		}
4775 		break;
4776 	}
4777 	case _gep_owner:
4778 	{
4779 		if(ent->owner) // always return an empty var if it is NULL
4780 		{
4781 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
4782 			(*pretvar)->ptrVal = (VOID*)ent->owner;
4783 		}
4784 		break;
4785 	}
4786 	case _gep_parent:
4787 	{
4788 		if(ent->parent) // always return an empty var if it is NULL
4789 		{
4790 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
4791 			(*pretvar)->ptrVal = (VOID*)ent->parent;
4792 		}
4793 		break;
4794 	}
4795 	case _gep_path:
4796 	{
4797 		ScriptVariant_ChangeType(*pretvar, VT_STR);
4798 		tempstr = ent->modeldata.path;
4799 
4800 		strcpy(StrCache_Get((*pretvar)->strVal), tempstr);
4801 		break;
4802 	}
4803 	case _gep_playerindex:
4804 	{
4805 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4806 		(*pretvar)->lVal = (LONG)ent->playerindex;
4807 		//printf("%d %s %d\n", ent->sortid, ent->name, ent->playerindex);
4808 		break;
4809 	}
4810     case _gep_projectile:
4811 	{
4812 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4813 		(*pretvar)->lVal = (LONG)ent->projectile;
4814 		break;
4815 	}
4816 	case _gep_range:
4817 	{
4818 		if(paramCount<4) break;
4819 
4820 		if(varlist[2]->vt != VT_INTEGER
4821 			|| varlist[3]->vt != VT_INTEGER)
4822 		{
4823 			printf("\n Error, getentityproperty({ent}, 'range', {sub property}, {animation}): {Sub property} or {Animation} parameter is missing or invalid. \n");
4824 			return E_FAIL;
4825 		}
4826 		ltemp	= varlist[2]->lVal;												//Subproperty.
4827 		i		= varlist[3]->lVal;												//Animation.
4828 
4829 		if(!validanim(ent,i))													//Verify animation.
4830 		{
4831 			break;
4832 		}
4833 
4834 		switch(ltemp)
4835 		{
4836 			case _gep_range_amax:
4837 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4838 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.amax;
4839 				 break;
4840 			case _gep_range_amin:
4841 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4842 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.amin;
4843 				 break;
4844 			case _gep_range_bmax:
4845 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4846 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.bmax;
4847 				 break;
4848 			case _gep_range_bmin:
4849 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4850 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.bmin;
4851 				 break;
4852 			case _gep_range_xmax:
4853 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4854 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.xmax;
4855 				 break;
4856 			case _gep_range_xmin:
4857 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4858 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.xmin;
4859 				 break;
4860 			case _gep_range_zmax:
4861 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4862 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.zmax;
4863 				 break;
4864 			case _gep_range_zmin:
4865 				 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4866 				 (*pretvar)->lVal = (LONG)ent->modeldata.animation[i]->range.zmin;
4867 				 break;
4868 			default:
4869 				ScriptVariant_Clear(*pretvar);
4870 				return E_FAIL;
4871 		}
4872 		break;
4873 
4874 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4875 		(*pretvar)->lVal = (LONG)coords[varlist[4]->lVal];
4876 		break;
4877 	}
4878 	case _gep_running:
4879 	{
4880 		if(paramCount<3) break;
4881 		arg = varlist[2];
4882 		if(arg->vt != VT_INTEGER)
4883 		{
4884 			if(arg->vt != VT_STR)
4885 				printf("You must give a string name for running property.\n");
4886 			return E_FAIL;
4887 		}
4888 		ltemp = arg->lVal;
4889 		switch(ltemp)
4890 		{
4891 		case _gep_running_speed:
4892 		{
4893 			 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4894 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.runspeed;
4895 			break;
4896 		}
4897 		case _gep_running_jumpy:
4898 		{
4899 			 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4900 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.runjumpheight;
4901 			break;
4902 		}
4903 		case _gep_running_jumpx:
4904 		{
4905 			 ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4906 			(*pretvar)->dblVal = (DOUBLE)ent->modeldata.runjumpdist;
4907 			break;
4908 		}
4909 		case _gep_running_land:
4910 		{
4911 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4912 			(*pretvar)->lVal = (LONG)ent->modeldata.runhold;
4913 			break;
4914 		}
4915 		case _gep_running_movez:
4916 		{
4917 			 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4918 			 (*pretvar)->lVal = (LONG)ent->modeldata.runupdown;
4919 			 break;
4920 		}
4921 		}
4922 		break;
4923 	}
4924 	case _gep_rush_count:
4925 	{
4926 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4927 		(*pretvar)->lVal = (LONG)ent->rush[0];
4928 		break;
4929 	}
4930 	case _gep_rush_tally:
4931 	{
4932 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4933 		(*pretvar)->lVal = (LONG)ent->rush[1];
4934 		break;
4935 	}
4936 	case _gep_rush_time:
4937 	{
4938 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4939 		(*pretvar)->lVal = (LONG)ent->rushtime;
4940 		break;
4941 	}
4942 	case _gep_score:
4943 	{
4944 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4945 		(*pretvar)->lVal = (LONG)ent->modeldata.score;
4946 		break;
4947 	}
4948 	case _gep_scroll:
4949 	{
4950 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4951 		(*pretvar)->dblVal = (DOUBLE)ent->modeldata.scroll;
4952 		break;
4953 	}
4954 	case _gep_seal:
4955 	{
4956 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4957 		(*pretvar)->lVal = (LONG)ent->seal;
4958 		break;
4959 	}
4960 	case _gep_sealtime:
4961 	{
4962 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4963 		(*pretvar)->lVal = (LONG)ent->sealtime;
4964 		break;
4965 	}
4966 	case _gep_setlayer:
4967 	{
4968 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4969 		(*pretvar)->lVal = (LONG)ent->modeldata.setlayer;
4970 		break;
4971 	}
4972 	case _gep_spawntype:
4973 	{
4974 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
4975 		(*pretvar)->lVal = (LONG)ent->spawntype;
4976 		break;
4977 	}
4978 	case _gep_speed:
4979 	{
4980 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
4981 		(*pretvar)->dblVal = (DOUBLE)ent->modeldata.speed;
4982 		break;
4983 	}
4984 	case _gep_sprite:
4985 	{
4986 		ScriptVariant_ChangeType(*pretvar, VT_PTR);
4987 		i = ent->animation->sprite[ent->animpos];
4988 		spr = sprite_map[i].sprite;
4989 		spr->centerx = sprite_map[i].centerx;
4990 		spr->centery = sprite_map[i].centery;
4991 		(*pretvar)->ptrVal = (VOID*)(spr);
4992 		break;
4993 	}
4994 	case _gep_spritea:
4995 	{
4996 		/*
4997 	    2011_04_17, DC: Modder can now specify animation and frame to return sprite from.
4998 	    To retain backward compatibility, sprite from current animation/frame is returned
4999 	    when animation and/or frame parameters are not provided.
5000 	    */
5001 
5002         ltemp   = varlist[2]->lVal;
5003         arg     = varlist[3];
5004         arg1    = varlist[4];
5005 
5006         /*
5007         Request from animation or frame that doesn't exist = shutdown.
5008         Let's be more user friendly then that; return empty so modder can evaluate
5009         and take action accordingly.*/
5010         if(!validanim(ent, arg->lVal) || !(ent->modeldata.animation[arg->lVal]->numframes >= arg1->lVal))
5011         {
5012             break;
5013         }
5014 
5015         i = ent->modeldata.animation[arg->lVal]->sprite[arg1->lVal];
5016 
5017 		switch(ltemp)
5018 		{
5019            case _gep_spritea_centerx:
5020             {
5021                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5022                 (*pretvar)->lVal = (LONG)sprite_map[i].centerx;
5023                 break;
5024             }
5025             case _gep_spritea_centery:
5026             {
5027                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5028                 (*pretvar)->lVal = (LONG)sprite_map[i].centery;
5029                 break;
5030             }
5031             case _gep_spritea_file:
5032             {
5033                 ScriptVariant_ChangeType(*pretvar, VT_STR);
5034                 strcpy(StrCache_Get((*pretvar)->strVal), sprite_map[i].filename);
5035                 break;
5036             }
5037             case _gep_spritea_offsetx:
5038             {
5039                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5040                 (*pretvar)->lVal = (LONG)sprite_map[i].ofsx;
5041                 break;
5042             }
5043             case _gep_spritea_offsety:
5044             {
5045                 ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5046                 (*pretvar)->lVal = (LONG)sprite_map[i].ofsy;
5047                 break;
5048             }
5049             case _gep_spritea_sprite:
5050             {
5051                 ScriptVariant_ChangeType(*pretvar, VT_PTR);
5052                 spr = sprite_map[i].sprite;
5053                 spr->centerx = sprite_map[i].centery;
5054                 spr->centery = sprite_map[i].centery;
5055                 (*pretvar)->ptrVal = (VOID*)(spr);
5056                 break;
5057             }
5058             default:
5059 			{
5060                 ScriptVariant_Clear(*pretvar);
5061                 return E_FAIL;
5062             }
5063 		}
5064 
5065 		break;
5066 
5067 	}
5068 	case _gep_stalltime:
5069 	{
5070 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5071 		(*pretvar)->lVal = (LONG)ent->stalltime;
5072 		break;
5073 	}
5074 	case _gep_stats:
5075 	{
5076 		if(paramCount<4) break;
5077 		arg = varlist[2];
5078 		arg1 = varlist[3];
5079 
5080 		if(arg->vt != VT_INTEGER || arg1->vt != VT_INTEGER)
5081 		{
5082 			printf("Incorrect parameters: getentityproperty({ent}, 'stats', {type}, {index}) \n {type}: \n 0 = Model. \n 1 = Entity. \n");
5083 			return E_FAIL;
5084 		}
5085 
5086 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5087 
5088 		switch(arg->lVal)
5089 		{
5090 			default:
5091 				if (ent->modeldata.stats[arg1->lVal])
5092 				{
5093 					(*pretvar)->dblVal = (DOUBLE)ent->modeldata.stats[arg1->lVal];
5094 				}
5095 				break;
5096 			case 1:
5097 				if (ent->stats[arg1->lVal])
5098 				{
5099 					(*pretvar)->dblVal = (DOUBLE)ent->stats[arg1->lVal];
5100 				}
5101 				break;
5102 		}
5103 		break;
5104 	}
5105 	case _gep_staydown:
5106 	{
5107 		arg = varlist[2];
5108 		if(arg->vt != VT_INTEGER)
5109 		{
5110 			if(arg->vt != VT_STR)
5111 				printf("You must provide a string name for staydown property:\n\
5112                         getentityproperty({ent}, 'staydown', {subproperty})\n\
5113                         ~'rise'\n\
5114                         ~'riseattack'\n\
5115                         ~'riseattack_stall' \n");
5116 			return E_FAIL;
5117 		}
5118 		ltemp = arg->lVal;
5119 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5120 
5121 		switch(ltemp)
5122 		{
5123             case _gep_staydown_rise:
5124             {
5125                 i = ent->staydown.rise;
5126                 break;
5127             }
5128             case _gep_staydown_riseattack:
5129             {
5130                 i = ent->staydown.riseattack;
5131                 break;
5132             }
5133             case _gep_staydown_riseattack_stall:
5134             {
5135                 i = ent->staydown.riseattack_stall;
5136                 break;
5137             }
5138             default:
5139 			{
5140                 ScriptVariant_Clear(*pretvar);
5141                 return E_FAIL;
5142             }
5143 		}
5144 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5145 		(*pretvar)->lVal = (LONG)i;
5146 		break;
5147 	}
5148 	case _gep_stealth:
5149 	{
5150 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5151 		(*pretvar)->lVal = (LONG)ent->modeldata.stealth.hide;
5152 		break;
5153 	}
5154 	case _gep_subentity:
5155 	{
5156 		if(ent->subentity) // always return an empty var if it is NULL
5157 		{
5158 			ScriptVariant_ChangeType(*pretvar, VT_PTR);
5159 			(*pretvar)->ptrVal = (VOID*)ent->subentity;
5160 		}
5161 		break;
5162 	}
5163 	case _gep_subject_to_gravity:
5164 	{
5165 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5166 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_gravity;
5167 		break;
5168 	}
5169 	case _gep_subject_to_hole:
5170 	{
5171 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5172 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_hole;
5173 		break;
5174 	}
5175 	case _gep_subject_to_maxz:
5176 	{
5177 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5178 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_maxz;
5179 		break;
5180 	}
5181 	case _gep_subject_to_minz:
5182 	{
5183 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5184 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_minz;
5185 		break;
5186 	}
5187 	case _gep_subject_to_obstacle:
5188 	{
5189 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5190 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_obstacle;
5191 		break;
5192 	}
5193 	case _gep_subject_to_platform:
5194 	{
5195 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5196 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_platform;
5197 		break;
5198 	}
5199 	case _gep_subject_to_screen:
5200 	{
5201 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5202 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_screen;
5203 		break;
5204 	}
5205 	case _gep_subject_to_wall:
5206 	{
5207 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5208 		(*pretvar)->lVal = (LONG)ent->modeldata.subject_to_wall;
5209 		break;
5210 	}
5211 	case _gep_subtype:
5212 	{
5213 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5214 		(*pretvar)->lVal = (LONG)ent->modeldata.subtype;
5215 		break;
5216 	}
5217 	case _gep_thold:
5218 	{
5219 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5220 		(*pretvar)->lVal = (LONG)ent->modeldata.thold;
5221 		break;
5222 	}
5223 	case _gep_throwdamage:
5224 	{
5225 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5226 		(*pretvar)->lVal = (LONG)ent->modeldata.throwdamage;
5227 		break;
5228 	}
5229 	case _gep_throwdist:
5230 	{
5231 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5232 		(*pretvar)->dblVal = (DOUBLE)ent->modeldata.throwdist;
5233 		break;
5234 	}
5235 	case _gep_throwframewait:
5236 	{
5237 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5238 		(*pretvar)->lVal = (LONG)ent->modeldata.throwframewait;
5239 		break;
5240 	}
5241 	case _gep_throwheight:
5242 	{
5243 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5244 		(*pretvar)->dblVal = (DOUBLE)ent->modeldata.throwheight;
5245 		break;
5246 	}
5247 	case _gep_tosstime:
5248 	{
5249 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5250 		(*pretvar)->lVal = (LONG)ent->toss_time;
5251 		break;
5252 	}
5253 	case _gep_tossv:
5254 	{
5255 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5256 		(*pretvar)->dblVal = (DOUBLE)ent->tossv;
5257 		break;
5258 	}
5259 	case _gep_type:
5260 	{
5261 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5262 		(*pretvar)->lVal = (LONG)ent->modeldata.type;
5263 		break;
5264 	}
5265 	case _gep_weapent:
5266 	{
5267         ScriptVariant_ChangeType(*pretvar, VT_PTR);
5268         (*pretvar)->ptrVal = (VOID*)ent->weapent;
5269         break;
5270 	}
5271 	case _gep_x:
5272 	{
5273 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5274 		(*pretvar)->dblVal = (DOUBLE)ent->x;
5275 		break;
5276 	}
5277 	case _gep_xdir:
5278 	{
5279 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5280 		(*pretvar)->dblVal = (DOUBLE)ent->xdir;
5281 		break;
5282 	}
5283 	case _gep_z:
5284 	{
5285 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5286 		(*pretvar)->dblVal = (DOUBLE)ent->z;
5287 		break;
5288 	}
5289 	case _gep_zdir:
5290 	{
5291 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
5292 		(*pretvar)->dblVal = (DOUBLE)ent->zdir;
5293 		break;
5294 	}
5295 	default:
5296 		//printf("Property name '%s' is not supported by function getentityproperty.\n", propname);
5297 		*pretvar = NULL;
5298 		return E_FAIL;
5299 		break;
5300 	}
5301 
5302 	return S_OK;
5303 }
5304 
5305 // ===== changeentityproperty =====
5306 enum changeentityproperty_enum {
5307 	_cep_aggression,
5308     _cep_aiattack,
5309     _cep_aiflag,
5310     _cep_aimove,
5311     _cep_alpha,
5312     _cep_animation,
5313     _cep_animhits,
5314     _cep_animpos,
5315     _cep_antigrab,
5316     _cep_antigravity,
5317     _cep_attacking,
5318     _cep_attackid,
5319     _cep_autokill,
5320     _cep_base,
5321     _cep_blink,
5322     _cep_blockback,
5323     _cep_blockodds,
5324     _cep_blockpain,
5325     _cep_bounce,
5326     _cep_candamage,
5327     _cep_combostep,
5328     _cep_colourmap,
5329     _cep_damage_on_landing,
5330     _cep_dead,
5331     _cep_defaultname,
5332     _cep_defense,
5333     _cep_detect,
5334     _cep_direction,
5335     _cep_dot,
5336     _cep_edelay,
5337     _cep_energycost,
5338     _cep_escapecount,
5339     _cep_escapehits,
5340     _cep_falldie,
5341     _cep_freezetime,
5342     _cep_frozen,
5343     _cep_gfxshadow,
5344     _cep_grabforce,
5345     _cep_guardpoints,
5346     _cep_health,
5347     _cep_hitbyid,
5348     _cep_hmapl,
5349     _cep_hmapu,
5350     _cep_hostile,
5351     _cep_iconposition,
5352     _cep_invincible,
5353     _cep_invinctime,
5354     _cep_jugglepoints,
5355     _cep_knockdowncount,
5356     _cep_komap,
5357     _cep_lifeposition,
5358     _cep_lifespancountdown,
5359     _cep_map,
5360     _cep_maptime,
5361     _cep_maxguardpoints,
5362     _cep_maxhealth,
5363     _cep_maxjugglepoints,
5364     _cep_maxmp,
5365     _cep_model,
5366     _cep_mp,
5367     _cep_mpset,
5368     _cep_name,
5369     _cep_nameposition,
5370     _cep_nextanim,
5371     _cep_nextthink,
5372     _cep_no_adjust_base,
5373     _cep_noaicontrol,
5374     _cep_nodieblink,
5375     _cep_nodrop,
5376     _cep_nograb,
5377 	_cep_nolife,
5378     _cep_nopain,
5379     _cep_offense,
5380     _cep_opponent,
5381     _cep_owner,
5382     _cep_pain_time,
5383     _cep_parent,
5384     _cep_position,
5385     _cep_projectile,
5386     _cep_projectilehit,
5387     _cep_running,
5388     _cep_rush_count,
5389     _cep_rush_tally,
5390     _cep_rush_time,
5391     _cep_score,
5392     _cep_scroll,
5393     _cep_seal,
5394     _cep_sealtime,
5395     _cep_setlayer,
5396     _cep_speed,
5397     _cep_spritea,
5398     _cep_stalltime,
5399     _cep_stats,
5400     _cep_staydown,
5401     _cep_staydownatk,
5402     _cep_stealth,
5403     _cep_subentity,
5404     _cep_subject_to_gravity,
5405     _cep_subject_to_hole,
5406     _cep_subject_to_maxz,
5407     _cep_subject_to_minz,
5408     _cep_subject_to_obstacle,
5409     _cep_subject_to_platform,
5410     _cep_subject_to_screen,
5411     _cep_subject_to_wall,
5412     _cep_takeaction,
5413     _cep_think,
5414     _cep_thold,
5415     _cep_throwdamage,
5416     _cep_throwdist,
5417     _cep_throwframewait,
5418     _cep_throwheight,
5419     _cep_tosstime,
5420     _cep_trymove,
5421     _cep_type,
5422     _cep_velocity,
5423     _cep_weapon,
5424 	_cep_the_end,
5425 };
5426 
5427 enum cep_aiflag_enum {
5428 	_cep_aiflag_animating,
5429 	_cep_aiflag_attacking,
5430 	_cep_aiflag_autokill,
5431 	_cep_aiflag_blink,
5432 	_cep_aiflag_blocking,
5433 	_cep_aiflag_charging,
5434 	_cep_aiflag_dead,
5435 	_cep_aiflag_drop,
5436 	_cep_aiflag_falling,
5437 	_cep_aiflag_frozen,
5438 	_cep_aiflag_getting,
5439 	_cep_aiflag_idling,
5440 	_cep_aiflag_inpain,
5441 	_cep_aiflag_invincible,
5442 	_cep_aiflag_jumpid,
5443 	_cep_aiflag_jumping,
5444 	_cep_aiflag_projectile,
5445 	_cep_aiflag_running,
5446 	_cep_aiflag_toexplode,
5447 	_cep_aiflag_turning,
5448 	_cep_aiflag_walking,
5449 	_cep_aiflag_the_end,
5450 };
5451 
5452 enum cep_energycost_enum {
5453     _cep_energycost_cost,
5454     _cep_energycost_disable,
5455     _cep_energycost_mponly,
5456     _cep_energycost_the_end,
5457 };
5458 
5459 enum cep_hostile_candamage_enum {
5460 	_cep_hcd_ground,
5461 	_cep_hcd_type_enemy,
5462 	_cep_hcd_type_npc,
5463 	_cep_hcd_type_obstacle,
5464 	_cep_hcd_type_player,
5465 	_cep_hcd_type_shot,
5466 	_cep_hcd_the_end,
5467 };
5468 
5469 enum cep_knockdowncount_enum {
5470     _cep_knockdowncount_current,
5471     _cep_knockdowncount_max,
5472     _cep_knockdowncount_time,
5473     _cep_knockdowncount_the_end,
5474 };
5475 
5476 enum cep_spritea_enum {
5477     _cep_spritea_centerx,
5478     _cep_spritea_centery,
5479     _cep_spritea_file,
5480     _cep_spritea_offsetx,
5481     _cep_spritea_offsety,
5482     _cep_spritea_sprite,
5483     _cep_spritea_the_end,
5484 };
5485 
5486 enum cep_staydown_enum {
5487     _cep_staydown_rise,
5488     _cep_staydown_riseattack,
5489     _cep_staydown_riseattack_stall,
5490     _cep_staydown_the_end,
5491 };
5492 
5493 enum cep_takeaction_enum {
5494 	_cep_ta_bomb_explode,
5495 	_cep_ta_common_attack_proc,
5496 	_cep_ta_common_block,
5497 	_cep_ta_common_drop,
5498 	_cep_ta_common_fall,
5499 	_cep_ta_common_get,
5500 	_cep_ta_common_grab,
5501 	_cep_ta_common_grabattack,
5502 	_cep_ta_common_grabbed,
5503 	_cep_ta_common_jump,
5504 	_cep_ta_common_land,
5505 	_cep_ta_common_lie,
5506 	_cep_ta_common_pain,
5507 	_cep_ta_common_prejump,
5508 	_cep_ta_common_rise,
5509 	_cep_ta_common_spawn,
5510 	_cep_ta_common_turn,
5511 	_cep_ta_common_vault,
5512 	_cep_ta_normal_prepare,
5513 	_cep_ta_npc_warp,
5514 	_cep_ta_player_blink,
5515 	_cep_ta_suicide,
5516 	_cep_ta_the_end,
5517 };
5518 
5519 enum cep_think_enum { // 2011_03_03, DC: Think types.
5520     _cep_th_common_think,
5521     _cep_th_player_think,
5522     _cep_th_steam_think,
5523     _cep_th_steamer_think,
5524     _cep_th_text_think,
5525     _cep_th_trap_think,
5526     _cep_th_the_end,
5527 };
5528 
mapstrings_changeentityproperty(ScriptVariant ** varlist,int paramCount)5529 void mapstrings_changeentityproperty(ScriptVariant** varlist, int paramCount)
5530 {
5531 	char* propname;
5532 	int prop, i;
5533 
5534 	static const char* proplist[] = {
5535 		"aggression",
5536 		"aiattack",
5537 		"aiflag",
5538 		"aimove",
5539 		"alpha",
5540 		"animation",
5541 		"animhits",
5542 		"animpos",
5543 		"antigrab",
5544 		"antigravity",
5545 		"attacking",
5546 		"attackid",
5547 		"autokill",
5548 		"base",
5549 		"blink",
5550 		"blockback",
5551 		"blockodds",
5552 		"blockpain",
5553 		"bounce",
5554 		"candamage",
5555 		"combostep",
5556 		"colourmap",
5557 		"damage_on_landing",
5558 		"dead",
5559 		"defaultname",
5560 		"defense",
5561 		"detect",
5562 		"direction",
5563 		"dot",
5564 		"edelay",
5565 		"energycost",
5566 		"escapehits",
5567 		"escapecount",
5568 		"falldie",
5569 		"freezetime",
5570 		"frozen",
5571 		"gfxshadow",
5572 		"grabforce",
5573 		"guardpoints",
5574 		"health",
5575 		"hitbyid",
5576 		"hmapl",
5577 		"hmapu",
5578 		"hostile",
5579 		"iconposition",
5580 		"invincible",
5581 		"invinctime",
5582 		"jugglepoints",
5583 		"knockdowncount",
5584 		"komap",
5585 		"lifeposition",
5586 		"lifespancountdown",
5587 		"map",
5588 		"maptime",
5589 		"maxguardpoints",
5590 		"maxhealth",
5591 		"maxjugglepoints",
5592 		"maxmp",
5593 		"model",
5594 		"mp",
5595 		"mpset",
5596 		"name",
5597 		"nameposition",
5598 		"nextanim",
5599 		"nextthink",
5600 		"no_adjust_base",
5601 		"noaicontrol",
5602 		"nodieblink",
5603 		"nodrop",
5604 		"nograb",
5605 		"nolife",
5606 		"nopain",
5607 		"offense",
5608 		"opponent",
5609 		"owner",
5610 		"pain_time",
5611 		"parent",
5612 		"position",
5613 		"projectile",
5614 		"projectilehit",
5615 		"running",
5616 		"rush_count",
5617 		"rush_tally",
5618 		"rush_time",
5619 		"score",
5620 		"scroll",
5621 		"seal",
5622 		"sealtime",
5623 		"setlayer",
5624 		"speed",
5625 		"spritea",
5626 		"stalltime",
5627 		"stats",
5628 		"staydown",
5629 		"staydownatk",
5630 		"stealth",
5631 		"subentity",
5632 		"subject_to_gravity",
5633 		"subject_to_hole",
5634 		"subject_to_maxz",
5635 		"subject_to_minz",
5636 		"subject_to_obstacle",
5637 		"subject_to_platform",
5638 		"subject_to_screen",
5639 		"subject_to_wall",
5640 		"takeaction",
5641 		"think",
5642 		"thold",
5643 		"throwdamage",
5644 		"throwdist",
5645 		"throwframewait",
5646 		"throwheight",
5647 		"tosstime",
5648 		"trymove",
5649 		"type",
5650 		"velocity",
5651 		"weapon",
5652 	};
5653 
5654     static const char* proplist_aiflag[] = {
5655 		"animating",
5656 		"attacking",
5657 		"autokill",
5658 		"blink",
5659 		"blocking",
5660 		"charging",
5661 		"dead",
5662 		"drop",
5663 		"falling",
5664 		"frozen",
5665 		"getting",
5666 		"idling",
5667 		"inpain",
5668 		"invincible",
5669 		"jumpid",
5670 		"jumping",
5671 		"projectile",
5672 		"running",
5673 		"toexplode",
5674 		"turning",
5675 		"walking",
5676 	};
5677 
5678     static const char* proplist_energycost[] = {
5679         "cost",
5680         "disable",
5681         "mponly",
5682     };
5683 
5684     static const char* proplist_hostile_candamage[] = {
5685         "ground",
5686         "type_enemy",
5687         "type_npc",
5688         "type_obstacle",
5689         "type_player",
5690         "type_shot",
5691     };
5692 
5693     static const char* proplist_knockdowncount[] = { //2011_04_14, DC: Knockdowncount colleciton.
5694 	    "current",
5695 	    "max",
5696 	    "time",
5697 	};
5698 
5699     static const char* proplist_spritea[] = {       //2011_05_15, DC: Sprite array.
5700         "centerx",
5701         "centery",
5702         "file",
5703         "offsetx",
5704         "offsety",
5705         "sprite",
5706 	};
5707 
5708     static const char* proplist_staydown[] = { //2011_04_08, DC: Staydown colleciton.
5709 	    "rise",
5710 	    "riseattack",
5711 	    "riseattack_stall",
5712 	};
5713 
5714 	static const char* proplist_takeaction[] = {
5715 		"bomb_explode",
5716 		"common_attack_proc",
5717 		"common_block",
5718 		"common_drop",
5719 		"common_fall",
5720 		"common_get",
5721 		"common_grab",
5722 		"common_grabattack",
5723 		"common_grabbed",
5724 		"common_jump",
5725 		"common_land",
5726 		"common_lie",
5727 		"common_pain",
5728 		"common_prejump",
5729 		"common_rise",
5730 		"common_spawn",
5731 		"common_turn",
5732 		"common_vault",
5733 		"normal_prepare",
5734 		"npc_warp",
5735 		"player_blink",
5736 		"suicide",
5737 	};
5738 
5739 	static const char* proplist_think[] = { // 2011_03_03, DC: Think types.
5740 		"common_think",
5741 		"player_think",
5742 		"steam_think",
5743 		"steamer_think",
5744 		"text_think",
5745 		"trap_think",
5746 	};
5747 
5748 	// property name
5749 	MAPSTRINGS(varlist[1], proplist, _cep_the_end,
5750 		"Property name '%s' is not supported by function changeentityproperty.\n");
5751 
5752     // AI flag name for aiflag
5753 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _cep_aiflag))
5754 	{
5755 		MAPSTRINGS(varlist[2], proplist_aiflag, _cep_aiflag_the_end,
5756 			"Flag '%s' is not supported by 'aiflag'.\n");
5757 	}
5758 
5759 	//2011_03_31, DC: Energycost
5760 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _cep_energycost))
5761 	{
5762 		MAPSTRINGS(varlist[2], proplist_energycost, _cep_energycost_the_end,
5763 			"Flag '%s' is not supported by 'energycost'.\n");
5764 	}
5765 
5766     // entity type(s) for hostile, candamage, and projectilehit.
5767 	if((varlist[1]->vt == VT_INTEGER) &&
5768 		((varlist[1]->lVal == _cep_hostile) || (varlist[1]->lVal == _cep_candamage) || (varlist[1]->lVal == _cep_projectilehit)))
5769 	{
5770 		for(i=2; i<paramCount; i++)
5771 		{
5772 			MAPSTRINGS(varlist[i], proplist_hostile_candamage, _cep_hcd_the_end,
5773 				"Entity type '%s' is not supported by 'hostile', 'candamage', or 'projectilehit'\n");
5774 		}
5775 	}
5776 
5777 	// 2011_04_14, DC: Knockdowncount
5778 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _cep_knockdowncount))
5779 	{
5780 		MAPSTRINGS(varlist[2], proplist_knockdowncount, _cep_knockdowncount_the_end,
5781 			"Subproperty '%s' is not supported by 'knockdowncount'.\n");
5782 	}
5783 
5784 	// 2011_05_15, DC: Sprite array
5785 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _cep_spritea))
5786 	{
5787 		MAPSTRINGS(varlist[2], proplist_spritea, _cep_spritea_the_end,
5788 			"Property name '%s' is not a known subproperty of 'spritea'.\n");
5789 	}
5790 
5791     // 2011_04_08, DC: Staydown
5792 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _cep_staydown))
5793 	{
5794 		MAPSTRINGS(varlist[2], proplist_staydown, _cep_staydown_the_end,
5795 			"Subproperty '%s' is not supported by 'staydown'.\n");
5796 	}
5797 
5798 	// action for takeaction
5799 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _cep_takeaction))
5800 	{
5801 		MAPSTRINGS(varlist[2], proplist_takeaction, _cep_ta_the_end,
5802 			"Action '%s' is not supported by 'takeaction'.\n");
5803 	}
5804 
5805     // 2011_03_13, DC: Think sets for think.
5806 	if((varlist[1]->vt == VT_INTEGER) && (varlist[1]->lVal == _cep_think))
5807 	{
5808 		MAPSTRINGS(varlist[2], proplist_think, _cep_th_the_end,
5809 			"Set '%s' is not supported by 'think'.\n");
5810 	}
5811 }
5812 
5813 //changeentityproperty(pentity, propname, value1[ ,value2, value3, ...]);
openbor_changeentityproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)5814 HRESULT openbor_changeentityproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
5815 {
5816 	entity* ent = NULL;
5817 	s_model* tempmodel ;
5818 	char* tempstr = NULL;
5819 	LONG ltemp, ltemp2;
5820 	DOUBLE dbltemp;
5821 	int propind;
5822 	int i = 0;
5823 
5824 	static const void* actions[] = { // for takeaction
5825 		bomb_explode,
5826 		common_attack_proc,
5827 		common_block,
5828 		common_drop,
5829 		common_fall,
5830 		common_get,
5831 		common_grab,
5832 		common_grabattack,
5833 		common_grabbed,
5834 		common_jump,
5835 		common_land,
5836 		common_lie,
5837 		common_pain,
5838 		common_prejump,
5839 		common_rise,
5840 		common_spawn,
5841 		common_turn,
5842 		common_vault,
5843 		normal_prepare,
5844 		npc_warp,
5845 		player_blink,
5846 		suicide,
5847 	};
5848 
5849 	static const int entitytypes[] = {
5850         0, // "ground"; not a real entity type
5851         TYPE_ENEMY,
5852         TYPE_NPC,
5853         TYPE_OBSTACLE,
5854         TYPE_PLAYER,
5855         TYPE_SHOT,
5856 
5857     };
5858 
5859 	static const void* think[] = { // 2011_03_03, DC: Think types.
5860 		common_think,
5861 		player_think,
5862 		steam_think,
5863 		steamer_think,
5864 		text_think,
5865 		trap_think,
5866 	};
5867 
5868 	if(paramCount < 3)
5869 	{
5870 		printf("Function changeentityproperty must have have at least 3 parameters.");
5871 		goto changeentityproperty_error;
5872 	}
5873 
5874 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
5875 	(*pretvar)->lVal = (LONG)0;
5876 	mapstrings_changeentityproperty(varlist, paramCount);
5877 
5878 	if(varlist[0]->vt != VT_PTR && varlist[0]->vt != VT_EMPTY)
5879 	{
5880 		printf("Function changeentityproperty must have a valid entity handle.");
5881 		goto changeentityproperty_error;
5882 	}
5883 	ent = (entity*)varlist[0]->ptrVal; //retrieve the entity
5884 	if(!ent)
5885 	{
5886 		(*pretvar)->lVal = (LONG)0;
5887 		return S_OK;
5888 	}
5889 
5890 	if(varlist[1]->vt != VT_INTEGER)
5891 	{
5892 		if(varlist[1]->vt != VT_STR)
5893 			printf("Function changeentityproperty must have a string property name.\n");
5894 		goto changeentityproperty_error;
5895 	}
5896 
5897 	propind = varlist[1]->lVal;
5898 
5899 	switch(propind)
5900 	{
5901     case _cep_aggression:
5902 	{
5903 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5904 			ent->modeldata.aggression = (int)ltemp;
5905 		break;
5906 	}
5907 	case _cep_aiattack:
5908 	{
5909 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
5910 			ent->modeldata.aiattack = (int)ltemp;
5911 		break;
5912 	}
5913 	case _cep_aiflag:
5914 	{
5915 		if(varlist[2]->vt != VT_INTEGER)
5916 		{
5917 			if(varlist[2]->vt != VT_STR)
5918 				printf("You must give a string value for AI flag name.\n");
5919 			goto changeentityproperty_error;
5920 		}
5921 		if(paramCount<4) break;
5922 
5923 		switch(varlist[2]->lVal)
5924 		{
5925 		case _cep_aiflag_dead:
5926 		{
5927 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5928 				ent->dead = (int)ltemp;
5929 			break;
5930 		}
5931 		case _cep_aiflag_jumpid:
5932 		{
5933 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5934 				ent->jumpid = (int)ltemp;
5935 			break;
5936 		}
5937 		case _cep_aiflag_jumping:
5938 		{
5939 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5940 				ent->jumping = (int)ltemp;
5941 			break;
5942 		}
5943 		case _cep_aiflag_idling:
5944 		{
5945 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5946 				ent->idling = (int)ltemp;
5947 			break;
5948 		}
5949 		case _cep_aiflag_drop:
5950 		{
5951 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5952 				ent->drop = (int)ltemp;
5953 			break;
5954 		}
5955 		case _cep_aiflag_attacking:
5956 		{
5957 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5958 				ent->attacking = (int)ltemp;
5959 			break;
5960 		}
5961 		case _cep_aiflag_getting:
5962 		{
5963 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5964 				ent->getting = (int)ltemp;
5965 			break;
5966 		}
5967 		case _cep_aiflag_turning:
5968 		{
5969 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5970 				 ent->turning = (int)ltemp;
5971 			 break;
5972 		}
5973 		case _cep_aiflag_charging:
5974 		{
5975 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5976 				 ent->charging = (int)ltemp;
5977 			 break;
5978 		}
5979 		case _cep_aiflag_blocking:
5980 		{
5981 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5982 				 ent->blocking = (int)ltemp;
5983 			 break;
5984 		}
5985 		case _cep_aiflag_falling:
5986 		{
5987 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5988 				 ent->falling = (int)ltemp;
5989 			 break;
5990 		}
5991 		case _cep_aiflag_running:
5992 		{
5993 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
5994 				  ent->running = (int)ltemp;
5995 			 break;
5996 		}
5997 		case _cep_aiflag_inpain:
5998 		{
5999 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6000 				  ent->inpain = (int)ltemp;
6001 			 break;
6002 		}
6003 		case _cep_aiflag_projectile:
6004 		{
6005 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6006 				  ent->projectile = (int)ltemp;
6007 			 break;
6008 		}
6009 		case _cep_aiflag_frozen:
6010 		{
6011 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6012 				  ent->frozen = (int)ltemp;
6013 			 break;
6014 		}
6015 		case _cep_aiflag_toexplode:
6016 		{
6017 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6018 				  ent->toexplode = (int)ltemp;
6019 			 break;
6020 		}
6021 		case _cep_aiflag_animating:
6022 		{
6023 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6024 				  ent->animating = (int)ltemp;
6025 			 break;
6026 		}
6027 		case _cep_aiflag_blink:
6028 		{
6029 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6030 				  ent->blink = (int)ltemp;
6031 			 break;
6032 		}
6033 		case _cep_aiflag_invincible:
6034 		{
6035 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6036 				  ent->invincible = (int)ltemp;
6037 			 break;
6038 		}
6039 		case _cep_aiflag_autokill:
6040 		{
6041 			 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6042 				  ent->autokill = (int)ltemp;
6043 			 break;
6044 		}
6045 		case _cep_aiflag_walking:
6046 		{
6047 			 // do nothing, deprecated property
6048 			 break;
6049 		}
6050 		default:
6051 			printf("Unknown AI flag.\n");
6052 			goto changeentityproperty_error;
6053 		}
6054 		break;
6055 	}
6056 	case _cep_aimove:
6057 	{
6058 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6059 			ent->modeldata.aimove = (int)ltemp;
6060 		break;
6061 	}
6062 	case _cep_alpha:
6063 	{
6064 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6065 		{
6066 			(*pretvar)->lVal = (LONG)1;
6067 			ent->modeldata.alpha = (int)ltemp;
6068 		}
6069 		break;
6070 	}
6071     case _cep_animation:
6072 	{
6073 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6074 			(*pretvar)->lVal = (LONG)1;
6075 		if(paramCount >= 4)
6076 		{
6077 			if(FAILED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
6078 				(*pretvar)->lVal = (LONG)0;
6079 		}
6080 		else ltemp2 = (LONG)1;
6081 		if((*pretvar)->lVal == (LONG)1)
6082 		{
6083 			ent_set_anim(ent, (int)ltemp, (int)ltemp2);
6084 		}
6085 		break;
6086 	}
6087 	case _cep_animhits:
6088 	{
6089 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6090 		{
6091 			(*pretvar)->lVal = (LONG)1;
6092 			ent->animation->animhits = (int)ltemp;
6093 		}
6094 		break;
6095 	}
6096 	case _cep_animpos:
6097 	{
6098 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6099 			ent->animpos = (int)ltemp;
6100 		break;
6101 	}
6102 	case _cep_antigrab:
6103 	{
6104 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6105 			ent->modeldata.antigrab = (int)ltemp;
6106 		break;
6107 	}
6108     case _cep_antigravity:
6109 	{
6110 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6111 		{
6112 			(*pretvar)->lVal = (LONG)1;
6113 			ent->modeldata.antigravity = (float)dbltemp;
6114 		}
6115 		break;
6116 	}
6117 	case _cep_attacking:
6118 	{
6119 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6120 		{
6121 		   ent->attacking = (int)ltemp;
6122 		   (*pretvar)->lVal = (LONG)1;
6123 		}
6124 		break;
6125 	}
6126 	case _cep_attackid:
6127 	{
6128 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6129 			ent->attack_id = (int)ltemp;
6130 		break;
6131 	}
6132     case _cep_autokill:
6133 	{
6134 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6135 		{
6136 			ent->autokill = (int)ltemp;
6137 		   (*pretvar)->lVal = (LONG)1;
6138 		}
6139 		break;
6140 	}
6141 	case _cep_base:
6142 	{
6143 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6144 		{
6145 			ent->base = (float)dbltemp;
6146 			(*pretvar)->lVal = (LONG)1;
6147 		}
6148 		break;
6149 	}
6150 	case _cep_blink:
6151 	{
6152 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6153 		{
6154 			ent->blink = (int)ltemp;
6155 			(*pretvar)->lVal = (LONG)1;
6156 		}
6157 		break;
6158 	}
6159 	case _cep_blockback:
6160 	{
6161 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6162 			ent->modeldata.blockback = (int)ltemp;
6163 		break;
6164 	}
6165     case _cep_blockodds:
6166 	{
6167 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6168 		{
6169 			(*pretvar)->lVal = (LONG)1;
6170 			ent->modeldata.blockodds = (int)ltemp;
6171 		}
6172 		break;
6173 	}
6174 	case _cep_blockpain:
6175 	{
6176 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6177 			ent->modeldata.blockpain = (int)ltemp;
6178 		break;
6179 	}
6180 	case _cep_bounce:
6181 	{
6182 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6183 			ent->modeldata.bounce = (int)ltemp;
6184 		break;
6185 	}
6186 	case _cep_candamage:
6187 	{
6188 		ent->modeldata.candamage = 0;
6189 
6190 		for(i=2; i<paramCount; i++)
6191 		{
6192 			if(varlist[i]->vt == VT_INTEGER) // known entity type
6193 			{
6194 				ltemp = varlist[i]->lVal;
6195 				if(ltemp==_cep_hcd_ground) // "ground" - not needed?
6196 					ent->modeldata.ground = 1;
6197 				else
6198 					ent->modeldata.candamage |= entitytypes[(int)ltemp];
6199 			}
6200 			else
6201 			{
6202 				printf("You must pass one or more string constants for entity type.\n");
6203 				goto changeentityproperty_error;
6204 			}
6205 		}
6206 		break;
6207 	}
6208 	case _cep_combostep:
6209 	{
6210 		if(paramCount >= 4 &&
6211 		   SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6212 		{
6213 			(*pretvar)->lVal = (LONG)1;
6214 		}
6215 		if((*pretvar)->lVal == (LONG)1)
6216 		{
6217 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
6218 				ent->combostep[(int)ltemp]=(int)ltemp2;
6219 			else (*pretvar)->lVal = (LONG)0;
6220 		}
6221 		break;
6222 	}
6223 	case _cep_colourmap:
6224 	{
6225 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6226 		{
6227 			(*pretvar)->lVal = (LONG)1;
6228 			self->colourmap = self->modeldata.colourmap[ltemp-1];
6229 		}
6230 		break;
6231 	}
6232 	case _cep_damage_on_landing:
6233 	{
6234 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6235 			ent->damage_on_landing = (int)ltemp;
6236 		break;
6237 	}
6238     case _cep_dead:
6239 	{
6240 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6241 			ent->dead = (int)ltemp;
6242 		break;
6243 	}
6244     case _cep_defaultname:
6245 	{
6246 		if(varlist[2]->vt != VT_STR)
6247 		{
6248 			printf("You must give a string value for entity name.\n");
6249 			goto changeentityproperty_error;
6250 		}
6251 		tempmodel = findmodel((char*)StrCache_Get(varlist[2]->strVal));
6252 		if(!tempmodel)
6253 		{
6254 			printf("Use must give an existing model's name for entity's default model name.\n");
6255 			goto changeentityproperty_error;
6256 		}
6257 		ent->defaultmodel = tempmodel;
6258 		(*pretvar)->lVal = (LONG)1;
6259 		break;
6260 	}
6261 	case _cep_defense:
6262 	{
6263 		if(paramCount >= 4 &&
6264 		   SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
6265 		   ltemp < (LONG)MAX_ATKS && ltemp >= (LONG)0)
6266 		{
6267 			(*pretvar)->lVal = (LONG)1;
6268 		}
6269 		if((*pretvar)->lVal == (LONG)1)
6270 		{
6271 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6272 				ent->modeldata.defense_factors[(int)ltemp] = (float)dbltemp;
6273 			else (*pretvar)->lVal = (LONG)0;
6274 		}
6275 		if(paramCount >= 5 && (*pretvar)->lVal == (LONG)1)
6276 		{
6277 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6278 				ent->modeldata.defense_pain[(int)ltemp] = (float)dbltemp;
6279 			else (*pretvar)->lVal = (LONG)0;
6280 		}
6281 		if(paramCount >= 6 && (*pretvar)->lVal == (LONG)1)
6282 		{
6283 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
6284 				ent->modeldata.defense_knockdown[(int)ltemp] = (float)dbltemp;
6285 			else (*pretvar)->lVal = (LONG)0;
6286 		}
6287 		if(paramCount >= 7 && (*pretvar)->lVal == (LONG)1)
6288 		{
6289 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
6290 				ent->modeldata.defense_blockpower[(int)ltemp] = (float)dbltemp;
6291 			else (*pretvar)->lVal = (LONG)0;
6292 		}
6293 		if(paramCount >= 8 && (*pretvar)->lVal == (LONG)1)
6294 		{
6295 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp)))
6296 				ent->modeldata.defense_blockthreshold[(int)ltemp] = (float)dbltemp;
6297 			else (*pretvar)->lVal = (LONG)0;
6298 		}
6299 		if(paramCount >= 9 && (*pretvar)->lVal == (LONG)1)
6300 		{
6301 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[8], &dbltemp)))
6302 				ent->modeldata.defense_blockratio[(int)ltemp] = (float)dbltemp;
6303 			else (*pretvar)->lVal = (LONG)0;
6304 		}
6305 		if(paramCount >= 10 && (*pretvar)->lVal == (LONG)1)
6306 		{
6307 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[9], &dbltemp)))
6308 				ent->modeldata.defense_blocktype[(int)ltemp] = (float)dbltemp;
6309 			else (*pretvar)->lVal = (LONG)0;
6310 		}
6311 		break;
6312 	}
6313     case _cep_detect:
6314 	{
6315 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6316 			ent->modeldata.stealth.detect = (int)ltemp;
6317 		break;
6318 	}
6319 	case _cep_direction:
6320 	{
6321 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6322 		{
6323 			ent->direction = (int)dbltemp;
6324 			(*pretvar)->lVal = (LONG)1;
6325 		}
6326 		break;
6327 	}
6328 	case _cep_dot:
6329 	{
6330 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6331 		{
6332 			i = (int)ltemp;
6333 		}
6334 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6335 		{
6336 			(*pretvar)->lVal = (LONG)1;
6337 			ent->dot_time[i] = (int)dbltemp;
6338 		}
6339 		if(paramCount >= 5 && (*pretvar)->lVal == (LONG)1)
6340 		{
6341 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6342 				ent->dot[i] = (int)dbltemp;
6343 			else (*pretvar)->lVal = (LONG)0;
6344 		}
6345 		if(paramCount >= 6 && (*pretvar)->lVal == (LONG)1)
6346 		{
6347 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
6348 				ent->dot_force[i] = (int)dbltemp;
6349 			else (*pretvar)->lVal = (LONG)0;
6350 		}
6351 		if(paramCount >= 7 && (*pretvar)->lVal == (LONG)1)
6352 		{
6353 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
6354 				ent->dot_rate[i] = (int)dbltemp;
6355 			else (*pretvar)->lVal = (LONG)0;
6356 		}
6357 		if(paramCount >= 8 && (*pretvar)->lVal == (LONG)1)
6358 		{
6359 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp)))
6360 				ent->dot_atk[i] = (int)dbltemp;
6361 			else (*pretvar)->lVal = (LONG)0;
6362 		}
6363 		if(paramCount >= 9)
6364 		{
6365 			ent->dot_owner[i] = (entity*)varlist[8]->ptrVal;
6366 		}
6367 		break;
6368 	}
6369 	case _cep_edelay:
6370 	{
6371 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6372 		{
6373 			(*pretvar)->lVal = (LONG)1;
6374 			ent->modeldata.edelay.mode = (int)ltemp;
6375 		}
6376 		if(paramCount >= 3 && (*pretvar)->lVal == (LONG)1)
6377 		{
6378 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6379 				ent->modeldata.edelay.factor = (float)dbltemp;
6380 		}
6381 		if(paramCount >= 4 && (*pretvar)->lVal == (LONG)1)
6382 		{
6383 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
6384 				ent->modeldata.edelay.cap_min = (int)ltemp;
6385 			else (*pretvar)->lVal = (LONG)0;
6386 		}
6387 		if(paramCount >= 5 && (*pretvar)->lVal == (LONG)1)
6388 		{
6389 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
6390 				ent->modeldata.edelay.cap_max = (int)ltemp;
6391 			else (*pretvar)->lVal = (LONG)0;
6392 		}
6393 		if(paramCount >= 6 && (*pretvar)->lVal == (LONG)1)
6394 		{
6395 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[6], &ltemp)))
6396 				ent->modeldata.edelay.range_min = (int)ltemp;
6397 			else (*pretvar)->lVal = (LONG)0;
6398 		}
6399 		if(paramCount >= 7 && (*pretvar)->lVal == (LONG)1)
6400 		{
6401 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[7], &ltemp)))
6402 				ent->modeldata.edelay.range_max = (int)ltemp;
6403 			else (*pretvar)->lVal = (LONG)0;
6404 		}
6405 		break;
6406 	}
6407 	case _cep_energycost:
6408 	{
6409 		if(paramCount != 5)
6410 		{
6411 			printf("\n Error, changeentityproperty({ent}, 'energycost', {subproperty}, {animation}, {value}): Invalid or missing parameter. \n");
6412 			goto changeentityproperty_error;
6413 		}
6414 
6415 		(*pretvar)->lVal = (LONG)1;
6416 
6417 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6418 		{
6419 			i = (int)ltemp;
6420 		}
6421 
6422 		if(!validanim(ent,i))
6423 		{
6424 			printf("\n Error, changeentityproperty({ent}, 'energycost', {subproperty}, {animation}, {value}): {animation} parameter invalid. Make sure the animation exists. \n");
6425 			goto changeentityproperty_error;
6426 		}
6427 
6428 		if(varlist[2]->vt != VT_INTEGER)
6429 		{
6430 			if(varlist[2]->vt != VT_STR)
6431 				printf("You must give a string value for energycost flag name.\n");
6432 			goto changeentityproperty_error;
6433 		}
6434 
6435 		switch(varlist[2]->lVal)
6436 		{
6437 		case _cep_energycost_cost:
6438 		{
6439 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
6440 				ent->modeldata.animation[i]->energycost.cost = (int)ltemp;
6441 			break;
6442 		}
6443 		case _cep_energycost_disable:
6444 		{
6445 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
6446 				ent->modeldata.animation[i]->energycost.disable = (int)ltemp;
6447 			break;
6448 		}
6449 		case _cep_energycost_mponly:
6450 		{
6451 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
6452 				ent->modeldata.animation[i]->energycost.mponly = (int)ltemp;
6453 			break;
6454 		}
6455 		default:
6456 			printf("Unknown Energycost flag.\n");
6457 			goto changeentityproperty_error;
6458 		}
6459 		break;
6460 	}
6461 	case _cep_escapecount:
6462 	{
6463 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6464 		{
6465 			(*pretvar)->lVal = (LONG)1;
6466 			ent->escapecount = (int)ltemp;
6467 		}
6468 		break;
6469 	}
6470 	case _cep_escapehits:
6471 	{
6472 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6473 		{
6474 			(*pretvar)->lVal = (LONG)1;
6475 			ent->modeldata.escapehits = (int)ltemp;
6476 		}
6477 		break;
6478 	}
6479     case _cep_falldie:
6480 	{
6481 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6482 			ent->modeldata.falldie = (int)ltemp;
6483 		break;
6484 	}
6485 	case _cep_pain_time:
6486 	{
6487 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6488 			ent->pain_time = (int)ltemp;
6489 		break;
6490 	}
6491 	case _cep_freezetime:
6492 	{
6493 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6494 			ent->freezetime = (int)ltemp;
6495 		break;
6496 	}
6497 	case _cep_frozen:
6498 	{
6499 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6500 			ent->frozen = (int)ltemp;
6501 		break;
6502 	}
6503     case _cep_gfxshadow:
6504 	{
6505 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6506 			ent->modeldata.gfxshadow = (int)ltemp;
6507 		break;
6508 	}
6509     case _cep_grabforce:
6510 	{
6511 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6512 			ent->modeldata.grabforce = (int)ltemp;
6513 		break;
6514 	}
6515 	case _cep_guardpoints:
6516 	{
6517 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6518 		{
6519 			(*pretvar)->lVal = (LONG)1;
6520 			ent->modeldata.guardpoints.current = (int)ltemp;
6521 		}
6522 		break;
6523 	}
6524     case _cep_health:
6525 	{
6526 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6527 		{
6528 			ent->health = (int)ltemp;
6529 			if(ent->health > ent->modeldata.health) ent->health = ent->modeldata.health;
6530 			else if(ent->health < 0) ent->health = 0;
6531 			(*pretvar)->lVal = (LONG)1;
6532 		}
6533 		break;
6534 	}
6535     case _cep_hitbyid:
6536 	{
6537 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6538 			ent->hit_by_attack_id = (int)ltemp;
6539 		break;
6540 	}
6541     case _cep_hmapl:
6542 	{
6543 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6544 			(*pretvar)->lVal = (LONG)1;
6545 			self->modeldata.maps.hide_start = ltemp;
6546 		break;
6547 	}
6548 	case _cep_hmapu:
6549 	{
6550 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6551 			(*pretvar)->lVal = (LONG)1;
6552 			self->modeldata.maps.hide_end = ltemp;
6553 		break;
6554 	}
6555     case _cep_hostile:
6556 	{
6557 
6558 		ent->modeldata.hostile = 0;
6559 
6560 		for(i=2; i<paramCount; i++)
6561 		{
6562 			if(varlist[i]->vt == VT_INTEGER) // known entity type
6563 			{
6564 				ltemp = varlist[i]->lVal;
6565 				ent->modeldata.hostile |= entitytypes[(int)ltemp];
6566 			}
6567 			else
6568 			{
6569 				printf("You must pass one or more string constants for entity type.\n");
6570 				goto changeentityproperty_error;
6571 			}
6572 		}
6573 
6574 		break;
6575 	}
6576 	case _cep_iconposition:
6577 	{
6578 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6579 			ent->modeldata.icon.x = (int)ltemp;
6580 		if(paramCount>3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6581 			ent->modeldata.icon.y = (int)ltemp;
6582 		break;
6583 	}
6584 	case _cep_invincible:
6585 	{
6586 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6587 		{
6588 			ent->invincible = (int)ltemp;
6589 			(*pretvar)->lVal = (LONG)1;
6590 		}
6591 		break;
6592 	}
6593 	case _cep_invinctime:
6594 	{
6595 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6596 			ent->invinctime = (int)ltemp;
6597 		break;
6598 	}
6599 	case _cep_jugglepoints:
6600 	{
6601 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6602 		{
6603 			(*pretvar)->lVal = (LONG)1;
6604 			ent->modeldata.jugglepoints.current = (int)ltemp;
6605 		}
6606 		break;
6607 	}
6608 	case _cep_knockdowncount:
6609 	{
6610 		if(varlist[2]->vt != VT_INTEGER)
6611 		{
6612 			if(varlist[2]->vt != VT_STR)
6613 				printf("You must provide a string value for Knockdowncount subproperty:\n\
6614                         changeentityproperty({ent}, 'knockdowncount', {subproperty}, {value})\n\
6615                         ~'current'\n\
6616                         ~'max'\n\
6617                         ~'time'\n");
6618 			goto changeentityproperty_error;
6619 		}
6620 
6621 		switch(varlist[2]->lVal)
6622 		{
6623             case _cep_knockdowncount_current:
6624             {
6625                 if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6626                 {
6627                     (*pretvar)->lVal = (LONG)1;
6628                     ent->knockdowncount = (float)dbltemp;
6629                 }
6630 				break;
6631             }
6632             case _cep_knockdowncount_max:
6633             {
6634                 if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6635                 {
6636                     (*pretvar)->lVal = (LONG)1;
6637                     ent->modeldata.knockdowncount = (float)dbltemp;
6638                 }
6639 				break;
6640             case _cep_knockdowncount_time:
6641                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6642                 {
6643                     (*pretvar)->lVal = (LONG)1;
6644                     ent->knockdowntime = (int)ltemp;
6645                 }
6646 				break;
6647             }
6648             default:
6649                 printf("Unknown knockdowncount subproperty.\n");
6650                 goto changeentityproperty_error;
6651 		}
6652 		break;
6653 	}
6654     case _cep_komap:
6655 	{
6656 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6657 		{
6658 			(*pretvar)->lVal = (LONG)1;
6659 			ent->modeldata.maps.ko = (int)ltemp;
6660 		}
6661 		if(paramCount >= 4 && (*pretvar)->lVal == (LONG)1)
6662 		{
6663 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6664 				ent->modeldata.maps.kotype = (int)ltemp;
6665 			else (*pretvar)->lVal = (LONG)0;
6666 		}
6667 		break;
6668 	}
6669     case _cep_lifeposition:
6670 	{
6671 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6672 			ent->modeldata.hpx = (int)ltemp;
6673 		if(paramCount>3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6674 			ent->modeldata.hpy = (int)ltemp;
6675 		break;
6676 	}
6677     case _cep_lifespancountdown:
6678 	{
6679 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6680 			ent->lifespancountdown = (float)dbltemp;
6681 		break;
6682 	}
6683     case _cep_map:
6684 	{
6685 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6686 		{
6687 			ent_set_colourmap(ent, (int)ltemp);
6688 			(*pretvar)->lVal = (LONG)1;
6689 		}
6690 		break;
6691 	}
6692     case _cep_maptime:
6693 	{
6694 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6695 		{
6696 			(*pretvar)->lVal = (LONG)1;
6697 			ent->maptime = (int)ltemp;
6698 		}
6699 		break;
6700 	}
6701     case _cep_maxguardpoints:
6702 	{
6703 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6704 		{
6705 			(*pretvar)->lVal = (LONG)1;
6706 			ent->modeldata.guardpoints.maximum = (int)ltemp;
6707 		}
6708 		break;
6709 	}
6710 	case _cep_maxhealth:
6711 	{
6712 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6713 		{
6714 			(*pretvar)->lVal = (LONG)1;
6715 			ent->modeldata.health = (int)ltemp;
6716 			if(ent->modeldata.health < 0) ent->modeldata.health = 0; //OK, no need to have ot below 0
6717 		}
6718 		break;
6719 	}
6720 	case _cep_maxjugglepoints:
6721 	{
6722 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6723 		{
6724 			(*pretvar)->lVal = (LONG)1;
6725 			ent->modeldata.jugglepoints.maximum = (int)ltemp;
6726 		}
6727 		break;
6728 	}
6729     case _cep_maxmp:
6730 	{
6731 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6732 		{
6733 			ent->modeldata.mp = (int)ltemp;
6734 			if(ent->modeldata.mp < 0) ent->modeldata.mp = 0; //OK, no need to have ot below 0
6735 			(*pretvar)->lVal = (LONG)1;
6736 		}
6737 		break;
6738 	}
6739     case _cep_model:
6740 	{
6741 		if(varlist[2]->vt != VT_STR)
6742 		{
6743 			printf("You must give a string value for model name.\n");
6744 			goto changeentityproperty_error;
6745 		}
6746 		tempstr = (char*)StrCache_Get(varlist[2]->strVal);
6747 		if(paramCount > 3)
6748 		{
6749 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6750 				(*pretvar)->lVal = (LONG)1;
6751 		}
6752 		else
6753 		{
6754 			ltemp = (LONG)0;
6755 			(*pretvar)->lVal = (LONG)1;
6756 		}
6757 		if((*pretvar)->lVal == (LONG)1) set_model_ex(ent, tempstr, -1, NULL, (int)ltemp);
6758 		if(!ent->weapent) ent->weapent = ent;
6759 		break;
6760 	}
6761     case _cep_mp:
6762 	{
6763 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6764 		{
6765 			ent->mp = (int)ltemp;
6766 			if(ent->mp > ent->modeldata.mp) ent->mp = ent->modeldata.mp;
6767 			else if(ent->mp < 0) ent->mp = 0;
6768 			(*pretvar)->lVal = (LONG)1;
6769 		}
6770 		break;
6771 	}
6772     case _cep_mpset:
6773 	{
6774 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6775 		{
6776 			(*pretvar)->lVal = (LONG)1;
6777 			ent->modeldata.mp = (int)dbltemp;
6778 		}
6779 		if(paramCount >= 4 && (*pretvar)->lVal == (LONG)1)
6780 		{
6781 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6782 				ent->modeldata.mpstable = (int)dbltemp;
6783 		}
6784 		if(paramCount >= 5 && (*pretvar)->lVal == (LONG)1)
6785 		{
6786 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6787 				ent->modeldata.mpstableval = (int)dbltemp;
6788 		}
6789 		if(paramCount >= 6 && (*pretvar)->lVal == (LONG)1)
6790 		{
6791 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
6792 				ent->modeldata.mprate = (int)dbltemp;
6793 		}
6794 		if(paramCount >= 7 && (*pretvar)->lVal == (LONG)1)
6795 		{
6796 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
6797 				ent->modeldata.mpdroprate = (int)dbltemp;
6798 		}
6799 		if(paramCount >= 8 && (*pretvar)->lVal == (LONG)1)
6800 		{
6801 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[7], &dbltemp)))
6802 				ent->modeldata.chargerate = (int)dbltemp;
6803 		}
6804 		break;
6805 	}
6806     case _cep_name:
6807 	{
6808 		if(varlist[2]->vt != VT_STR)
6809 		{
6810 			printf("You must give a string value for entity name.\n");
6811 			goto changeentityproperty_error;
6812 		}
6813 		strcpy(ent->name, (char*)StrCache_Get(varlist[2]->strVal));
6814 		(*pretvar)->lVal = (LONG)1;
6815 		break;
6816 	}
6817     case _cep_nameposition:
6818 	{
6819 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6820 			ent->modeldata.namex = (int)ltemp;
6821 		if(paramCount>3 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
6822 			ent->modeldata.namey = (int)ltemp;
6823 		break;
6824 	}
6825     case _cep_nextanim:
6826 	{
6827 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6828 		{
6829 			(*pretvar)->lVal = (LONG)1;
6830 			ent->nextanim = (int)ltemp;
6831 		}
6832 		break;
6833 	}
6834 	case _cep_nextthink:
6835 	{
6836 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6837 		{
6838 			(*pretvar)->lVal = (LONG)1;
6839 			ent->nextthink = (int)ltemp;
6840 		}
6841 		break;
6842 	}
6843     case _cep_no_adjust_base:
6844 	{
6845 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6846 			ent->modeldata.no_adjust_base = (int)ltemp;
6847 		break;
6848 	}
6849 	case _cep_noaicontrol:
6850 	{
6851 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6852 			ent->noaicontrol = (int)ltemp;
6853 		break;
6854 	}
6855 	case _cep_nodieblink:
6856 	{
6857 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6858 			ent->modeldata.nodieblink = (int)ltemp;
6859 		break;
6860 	}
6861     case _cep_nodrop:
6862 	{
6863 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6864 			ent->modeldata.nodrop = (int)ltemp;
6865 		break;
6866 	}
6867 	case _cep_nograb:
6868 	{
6869 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6870 			ent->nograb = (int)ltemp;
6871 		break;
6872 	}
6873 	case _cep_nolife:
6874 	{
6875 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6876 			ent->modeldata.nolife = (int)ltemp;
6877 		break;
6878 	}
6879 	case _cep_nopain:
6880 	{
6881 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6882 			ent->modeldata.nopain = (int)ltemp;
6883 		break;
6884 	}
6885     case _cep_offense:
6886 	{
6887 		if(paramCount >= 4 &&
6888 		   SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)) &&
6889 		   ltemp < (LONG)MAX_ATKS && ltemp >= (LONG)0)
6890 		{
6891 			(*pretvar)->lVal = (LONG)1;
6892 		}
6893 		if((*pretvar)->lVal == (LONG)1)
6894 		{
6895 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6896 				ent->modeldata.offense_factors[(int)ltemp] = (float)dbltemp;
6897 			else (*pretvar)->lVal = (LONG)0;
6898 		}
6899 		break;
6900 	}
6901     case _cep_opponent:
6902 	{
6903 		ent->opponent = (entity*)varlist[2]->ptrVal;
6904 		break;
6905 	}
6906     case _cep_owner:
6907 	{
6908 		ent->owner = (entity*)varlist[2]->ptrVal;
6909 		break;
6910 	}
6911 	case _cep_parent:
6912 	{
6913 		ent->parent = (entity*)varlist[2]->ptrVal;
6914 		break;
6915 	}
6916     case _cep_position:
6917 	{
6918 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6919 		{
6920 			(*pretvar)->lVal = (LONG)1;
6921 			ent->x = (float)dbltemp;
6922 		}
6923 		if(paramCount >= 4 && (*pretvar)->lVal == (LONG)1)
6924 		{
6925 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6926 				ent->z = (float)dbltemp;
6927 			else (*pretvar)->lVal = (LONG)0;
6928 		}
6929 		if(paramCount >= 5 && (*pretvar)->lVal == (LONG)1)
6930 		{
6931 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6932 				ent->a = (float)dbltemp;
6933 			else (*pretvar)->lVal = (LONG)0;
6934 		}
6935 		break;
6936 	}
6937     case _cep_projectile:
6938 	{
6939 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6940 			ent->projectile = (int)ltemp;
6941 		break;
6942 	}
6943     case _cep_projectilehit:
6944 	{
6945 
6946 		ent->modeldata.projectilehit = 0;
6947 
6948 		for(i=2; i<paramCount; i++)
6949 		{
6950 			if(varlist[i]->vt == VT_INTEGER) // known entity type
6951 			{
6952 				ltemp = varlist[i]->lVal;
6953 				ent->modeldata.projectilehit |= entitytypes[(int)ltemp];
6954 			}
6955 			else
6956 			{
6957 				printf("You must pass one or more string constants for entity type.\n");
6958 				goto changeentityproperty_error;
6959 			}
6960 		}
6961 
6962 		break;
6963 	}
6964     case _cep_running:
6965 	{
6966 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
6967 		{
6968 			(*pretvar)->lVal = (LONG)1;
6969 			ent->modeldata.runspeed = (float)dbltemp;
6970 		}
6971 		if(paramCount >= 4 && (*pretvar)->lVal == (LONG)1)
6972 		{
6973 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
6974 				ent->modeldata.runjumpheight = (float)dbltemp;
6975 		}
6976 		if(paramCount >= 5 && (*pretvar)->lVal == (LONG)1)
6977 		{
6978 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
6979 				ent->modeldata.runjumpdist = (float)dbltemp;
6980 		}
6981 		if(paramCount >= 6 && (*pretvar)->lVal == (LONG)1)
6982 		{
6983 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[5], &dbltemp)))
6984 				ent->modeldata.runhold = (int)dbltemp;
6985 		}
6986 		if(paramCount >= 7 && (*pretvar)->lVal == (LONG)1)
6987 		{
6988 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[6], &dbltemp)))
6989 				ent->modeldata.runupdown = (int)dbltemp;
6990 		}
6991 
6992 		break;
6993 	}
6994     case _cep_rush_count:
6995 	{
6996 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
6997 		{
6998 			(*pretvar)->lVal = (LONG)1;
6999 			ent->rush[0] = (int)ltemp;
7000 		}
7001 		break;
7002 	}
7003 	case _cep_rush_tally:
7004 	{
7005 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7006 		{
7007 			(*pretvar)->lVal = (LONG)1;
7008 			ent->rush[1] = (int)ltemp;
7009 		}
7010 		break;
7011 	}
7012 	case _cep_rush_time:
7013 	{
7014 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7015 			ent->rushtime = (int)ltemp;
7016 		break;
7017 	}
7018 	case _cep_score:
7019 	{
7020 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7021 		{
7022 			(*pretvar)->lVal = (LONG)1;
7023 			ent->modeldata.score = (int)ltemp;
7024 		}
7025 		break;
7026 	}
7027     case _cep_scroll:
7028 	{
7029 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7030 		{
7031 			(*pretvar)->lVal = (LONG)1;
7032 			ent->modeldata.scroll = (float)dbltemp;
7033 		}
7034 		break;
7035 	}
7036     case _cep_seal:
7037 	{
7038 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7039 			ent->seal = (int)ltemp;
7040 		break;
7041 	}
7042 	case _cep_sealtime:
7043 	{
7044 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7045 			ent->sealtime = (int)ltemp;
7046 		break;
7047 	}
7048     case _cep_setlayer:
7049 	{
7050 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7051 		{
7052 			ent->modeldata.setlayer = (int)ltemp;
7053 			(*pretvar)->lVal = (LONG)1;
7054 		}
7055 		break;
7056 	}
7057 	case _cep_speed:
7058 	{
7059 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7060 		{
7061 			(*pretvar)->lVal = (LONG)1;
7062 			ent->modeldata.speed = (float)dbltemp;
7063 		}
7064 		break;
7065 	}
7066 	case _cep_spritea:
7067 	{
7068 	    if(varlist[2]->vt != VT_INTEGER)
7069 		{
7070 			if(varlist[2]->vt != VT_STR)
7071 				printf("You must provide a string value for Sprite Array subproperty:\n\
7072                         changeentityproperty({ent}, 'spritea', {subproperty}, {animation ID}, {frame}, {value})\n\
7073                         ~'centerx'\n\
7074                         ~'centery'\n\
7075                         ~'file'\n\
7076                         ~'offsetx'\n\
7077                         ~'sprite'\n");
7078 			goto changeentityproperty_error;
7079 		}
7080 
7081         ltemp   = varlist[2]->lVal;
7082 
7083         /*
7084         Failsafe checks. Any attempt to access a sprite property on invalid frame would cause instant shutdown.
7085         */
7086         if(!validanim(ent, varlist[3]->lVal) || !(ent->modeldata.animation[varlist[3]->lVal]->numframes >= varlist[4]->lVal) || paramCount<5)
7087         {
7088             break;
7089         }
7090 
7091         i = ent->modeldata.animation[varlist[3]->lVal]->sprite[varlist[4]->lVal];   //Get sprite index.
7092 
7093 		switch(ltemp)
7094 		{
7095             case _cep_spritea_centerx:
7096             {
7097                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
7098                 {
7099                     sprite_map[i].centerx = (int)ltemp;
7100                     (*pretvar)->lVal = (LONG)1;
7101                 }
7102                 break;
7103             }
7104             case _cep_spritea_centery:
7105             {
7106                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
7107                 {
7108                     sprite_map[i].centery = (int)ltemp;
7109                     (*pretvar)->lVal = (LONG)1;
7110                 }
7111                 break;
7112             }
7113             case _cep_spritea_file:
7114             {
7115                 if(varlist[5]->vt != VT_STR)
7116                 {
7117                     printf("You must provide a string value for file name.\n");
7118                     goto changeentityproperty_error;
7119                 }
7120                 strcpy(sprite_map[i].filename, (char*)StrCache_Get(varlist[5]->strVal));
7121                 (*pretvar)->lVal = (LONG)1;
7122                 break;
7123             }
7124             case _cep_spritea_offsetx:
7125             {
7126                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], &ltemp)))
7127                 {
7128                     sprite_map[i].ofsx = (int)ltemp;
7129                     (*pretvar)->lVal = (LONG)1;
7130                 }
7131                 break;
7132             }
7133             case _cep_spritea_offsety:
7134             {
7135                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7136                 {
7137                     sprite_map[i].ofsy = (int)ltemp;
7138                     (*pretvar)->lVal = (LONG)1;
7139                 }
7140                 break;
7141             }
7142             case _cep_spritea_sprite:
7143             {
7144                 sprite_map[i].sprite = (VOID*)varlist[5]->ptrVal;
7145                 (*pretvar)->lVal = (LONG)1;
7146                 break;
7147             }
7148             default:
7149                 printf("Unknown Sprite Array subproperty.\n");
7150                 goto changeentityproperty_error;
7151 		}
7152 		break;
7153 	}
7154     case _cep_stalltime:
7155 	{
7156 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7157 			ent->stalltime = (int)ltemp;
7158 		break;
7159 	}
7160 	case _cep_stats:
7161 	{
7162 		if(paramCount<4) break;
7163 
7164 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
7165 		{
7166 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
7167 			{
7168 				switch(varlist[2]->lVal)
7169 				{
7170 					default:
7171 						ent->modeldata.stats[(int)ltemp] = (float)dbltemp;
7172 						break;
7173 					case 1:
7174 						ent->stats[(int)ltemp] = (float)dbltemp;
7175 						break;
7176 				}
7177 			}
7178 		}
7179 		break;
7180 	}
7181 	case _cep_staydown:
7182 	{
7183 		if(varlist[2]->vt != VT_INTEGER)
7184 		{
7185 			if(varlist[2]->vt != VT_STR)
7186 				printf("You must provide a string value for Staydown subproperty:\n\
7187                         changeentityproperty({ent}, 'staydown', {subproperty}, {value})\n\
7188                         ~'rise'\n\
7189                         ~'riseattack'\n\
7190                         ~'riseattack_stall'\n");
7191 			goto changeentityproperty_error;
7192 		}
7193 		if(paramCount<4) break;
7194 
7195 		switch(varlist[2]->lVal)
7196 		{
7197             case _cep_staydown_rise:
7198             {
7199                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
7200                     ent->staydown.rise = (int)ltemp;
7201                 break;
7202             }
7203             case _cep_staydown_riseattack:
7204             {
7205                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
7206                     ent->staydown.riseattack = (int)ltemp;
7207                 break;
7208             }
7209             case _cep_staydown_riseattack_stall:
7210             {
7211                 if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
7212                     ent->staydown.riseattack_stall = (int)ltemp;
7213                 break;
7214             }
7215             default:
7216                 printf("Unknown Staydown subproperty.\n");
7217                 goto changeentityproperty_error;
7218 		}
7219 		break;
7220 	}
7221     case _cep_stealth:
7222 	{
7223 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7224 			ent->modeldata.stealth.hide = (int)ltemp;
7225 		break;
7226 	}
7227     case _cep_subentity:
7228 	{
7229 		if(ent->subentity) ent->subentity->parent = NULL;
7230 		ent->subentity = (entity*)varlist[2]->ptrVal;
7231 		if(ent->subentity) ent->subentity->parent = ent;
7232 		break;
7233 	}
7234     case _cep_subject_to_gravity:
7235 	{
7236 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7237 		{
7238 			ent->modeldata.subject_to_gravity = (int)ltemp;
7239 			(*pretvar)->lVal = (LONG)1;
7240 		}
7241 		break;
7242 	}
7243 	case _cep_subject_to_hole:
7244 	{
7245 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7246 		{
7247 			ent->modeldata.subject_to_hole = (int)ltemp;
7248 			(*pretvar)->lVal = (LONG)1;
7249 		}
7250 		break;
7251 	}
7252 	case _cep_subject_to_maxz:
7253 	{
7254 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7255 		{
7256 			ent->modeldata.subject_to_maxz = (int)ltemp;
7257 			(*pretvar)->lVal = (LONG)1;
7258 		}
7259 		break;
7260 	}
7261 	case _cep_subject_to_minz:
7262 	{
7263 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7264 		{
7265 			ent->modeldata.subject_to_minz = (int)ltemp;
7266 			(*pretvar)->lVal = (LONG)1;
7267 		}
7268 		break;
7269 	}
7270 	case _cep_subject_to_obstacle:
7271 	{
7272 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7273 		{
7274 			ent->modeldata.subject_to_obstacle = (int)ltemp;
7275 			(*pretvar)->lVal = (LONG)1;
7276 		}
7277 		break;
7278 	}
7279 	case _cep_subject_to_platform:
7280 	{
7281 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7282 		{
7283 			ent->modeldata.subject_to_platform = (int)ltemp;
7284 			(*pretvar)->lVal = (LONG)1;
7285 		}
7286 		break;
7287 	}
7288 	case _cep_subject_to_screen:
7289 	{
7290 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7291 		{
7292 			ent->modeldata.subject_to_screen = (int)ltemp;
7293 			(*pretvar)->lVal = (LONG)1;
7294 		}
7295 		break;
7296 	}
7297 	case _cep_subject_to_wall:
7298 	{
7299 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7300 		{
7301 			ent->modeldata.subject_to_wall = (int)ltemp;
7302 			(*pretvar)->lVal = (LONG)1;
7303 		}
7304 		break;
7305 	}
7306 	case _cep_takeaction:
7307 	{
7308 		if(varlist[2]->vt == VT_STR)
7309 		{ // not a known action; if it were it would been mapped by mapstrings
7310 			ent->takeaction = NULL;
7311 			break;
7312 		}
7313 		else if(varlist[2]->vt != VT_INTEGER)
7314 		{
7315 			printf("You must give a string value for action type.\n");
7316 			goto changeentityproperty_error;
7317 		}
7318 
7319 		// otherwise, the parameter is a known action
7320 		ltemp = varlist[2]->lVal;
7321 		if((ltemp >= 0) && (ltemp < _cep_ta_the_end))
7322 		{
7323 			ent->takeaction = actions[(int)ltemp];
7324 		}
7325 
7326 		break;
7327 	}
7328 	case _cep_think:
7329 	{
7330 		if(varlist[2]->vt == VT_STR)
7331 		{ // not a known action; if it were it would been mapped by mapstrings
7332 			//ent->think = NULL;
7333 			break;
7334 		}
7335 		else if(varlist[2]->vt != VT_INTEGER)
7336 		{
7337 			printf("You must give a string value for think type.\n");
7338 			goto changeentityproperty_error;
7339 		}
7340 
7341 		// otherwise, the parameter is a known action
7342 		ltemp = varlist[2]->lVal;
7343 		if((ltemp >= 0) && (ltemp < _cep_th_the_end))
7344 		{
7345 			ent->think = think[(int)ltemp];
7346 		}
7347 
7348 		break;
7349 	}
7350 	case _cep_thold:
7351 	{
7352 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7353 		{
7354 			(*pretvar)->lVal = (LONG)1;
7355 			ent->modeldata.thold = (int)ltemp;
7356 		}
7357 		break;
7358 	}
7359     case _cep_throwdamage:
7360 	{
7361 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7362 		{
7363 			ent->modeldata.throwdamage = (int)ltemp;
7364 			(*pretvar)->lVal = (LONG)1;
7365 		}
7366 		break;
7367 	}
7368 	case _cep_throwdist:
7369 	{
7370 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7371 		{
7372 			(*pretvar)->lVal = (LONG)1;
7373 			ent->modeldata.throwdist = (float)dbltemp;
7374 		}
7375 		break;
7376 	}
7377 	case _cep_throwframewait:
7378 	{
7379 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7380 		{
7381 			ent->modeldata.throwframewait = (int)ltemp;
7382 			(*pretvar)->lVal = (LONG)1;
7383 		}
7384 		break;
7385 	}
7386 	case _cep_throwheight:
7387 	{
7388 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7389 		{
7390 			(*pretvar)->lVal = (LONG)1;
7391 			ent->modeldata.throwheight = (float)dbltemp;
7392 		}
7393 		break;
7394 	}
7395     case _cep_tosstime:
7396 	{
7397 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7398 		{
7399 			(*pretvar)->lVal = (LONG)1;
7400 			ent->toss_time = (int)ltemp;
7401 		}
7402 		break;
7403 	}
7404     case _cep_trymove:
7405 	{
7406 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7407 		{
7408 			(*pretvar)->lVal = (LONG)1;
7409 			if(ltemp == 1)
7410 				 ent->trymove = common_trymove;
7411 			else if(ltemp == 2)
7412 				 ent->trymove = player_trymove;
7413 			else
7414 				 ent->trymove = NULL;
7415 		}
7416 		break;
7417 	}
7418 	case _cep_type:
7419 	{
7420 		if(varlist[2]->vt != VT_INTEGER)
7421 		{
7422 			printf("You must provide a type constant for type.\n");
7423 			goto changeentityproperty_error;
7424 		}
7425 
7426 		ltemp = varlist[2]->lVal;
7427         ent->modeldata.type = (int)ltemp;
7428 
7429 		break;
7430 	}
7431     case _cep_velocity:
7432 	{
7433 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
7434 		{
7435 			(*pretvar)->lVal = (LONG)1;
7436 			ent->xdir = (float)dbltemp;
7437 		}
7438 		if(paramCount >= 4 && (*pretvar)->lVal == (LONG)1)
7439 		{
7440 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp)))
7441 				ent->zdir = (float)dbltemp;
7442 			else (*pretvar)->lVal = (LONG)0;
7443 		}
7444 		if(paramCount >= 5 && (*pretvar)->lVal == (LONG)1)
7445 		{
7446 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[4], &dbltemp)))
7447 				ent->tossv = (float)dbltemp;
7448 			else (*pretvar)->lVal = (LONG)0;
7449 		}
7450 		break;
7451 	}
7452 	case _cep_weapon:
7453 	{
7454 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
7455 		{
7456 			if(paramCount > 3)
7457 			{
7458 				if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp2)))
7459 					(*pretvar)->lVal = (LONG)1;
7460 			}
7461 			else
7462 			{
7463 				ltemp2 = (LONG)0;
7464 				(*pretvar)->lVal = (LONG)1;
7465 			}
7466 			set_weapon(ent, (int)ltemp, (int)ltemp2);
7467 			(*pretvar)->lVal = (LONG)1;
7468 		}
7469 		break;
7470 	}
7471 	default:
7472 		//printf("Property name '%s' is not supported by function changeentityproperty.\n", propname);
7473 		goto changeentityproperty_error;
7474 		break;
7475 	}
7476 
7477 	return S_OK;
7478 changeentityproperty_error:
7479 	*pretvar = NULL;
7480 	return E_FAIL;
7481 }
7482 
7483 //tossentity(entity, height, speedx, speedz)
openbor_tossentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7484 HRESULT openbor_tossentity(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
7485 {
7486 	entity* ent = NULL;
7487 	DOUBLE height=0, speedx=0, speedz=0;
7488 
7489 	if(paramCount < 1)
7490 	{
7491 		*pretvar = NULL;
7492 		return E_FAIL;
7493 	}
7494 
7495 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7496 	(*pretvar)->lVal = (LONG)1;
7497 
7498 	ent = (entity*)varlist[0]->ptrVal; //retrieve the entity
7499 	if(!ent)
7500 	{
7501 		(*pretvar)->lVal = (LONG)0;
7502 
7503 		return S_OK;
7504 	}
7505 
7506 	if(paramCount >= 2)
7507 	{
7508 		if(FAILED(ScriptVariant_DecimalValue(varlist[1], &height)))
7509 		{
7510 			(*pretvar)->lVal = (LONG)0;
7511 			return S_OK;
7512 		}
7513 	}
7514 	if(paramCount >= 3)
7515 	{
7516 		if(FAILED(ScriptVariant_DecimalValue(varlist[2], &speedx)))
7517 		{
7518 			(*pretvar)->lVal = (LONG)0;
7519 			return S_OK;
7520 		}
7521 	}
7522 	if(paramCount >= 4)
7523 	{
7524 		if(FAILED(ScriptVariant_DecimalValue(varlist[3], &speedz)))
7525 		{
7526 			(*pretvar)->lVal = (LONG)0;
7527 			return S_OK;
7528 		}
7529 	}
7530 	ent->xdir = (float)speedx;
7531 	ent->zdir = (float)speedz;
7532 	toss(ent, (float)height);
7533 	return S_OK;
7534 }
7535 
7536 // ===== getplayerproperty =====
7537 enum getplayerproperty_enum {
7538 	_gpp_credits,
7539 	_gpp_ent,
7540 	_gpp_entity,
7541 	_gpp_keys,
7542 	_gpp_lives,
7543 	_gpp_name,
7544 	_gpp_playkeys,
7545 	_gpp_score,
7546 	_gpp_weaponum,
7547 	_gpp_the_end,
7548 };
7549 
mapstrings_getplayerproperty(ScriptVariant ** varlist,int paramCount)7550 void mapstrings_getplayerproperty(ScriptVariant** varlist, int paramCount)
7551 {
7552 	char* propname;
7553 	int prop;
7554 
7555 	static const char* proplist[] = {
7556 		"credits",
7557 		"ent",
7558 		"entity",
7559 		"keys",
7560 		"lives",
7561 		"name",
7562 		"playkeys",
7563 		"score",
7564 		"weaponum"
7565 	};
7566 
7567 	if(paramCount < 2) return;
7568 
7569 	// property name
7570 	MAPSTRINGS(varlist[1], proplist, _gpp_the_end,
7571 		"Property name '%s' is not supported by function getplayerproperty.\n");
7572 }
7573 
7574 //getplayerproperty(index, propname);
openbor_getplayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7575 HRESULT openbor_getplayerproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
7576 {
7577 	LONG ltemp;
7578 	int index;
7579 	entity* ent = NULL;
7580 	int prop = -1;
7581 	ScriptVariant* arg = NULL;
7582 
7583 	if(paramCount < 2)
7584 	{
7585 		*pretvar = NULL;
7586 		return E_FAIL;
7587 	}
7588 
7589 	mapstrings_getplayerproperty(varlist, paramCount);
7590 	ScriptVariant_Clear(*pretvar);
7591 
7592 	arg = varlist[0];
7593 	if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
7594 	{
7595 		index = 0;
7596 	} else index = (int)ltemp;
7597 	if(!(ent = player[index].ent))  //this player is not selected, so just return
7598 	{
7599 		return S_OK; //return S_OK, to tell the engine it is not a FATAL error
7600 	}
7601 
7602 	arg = varlist[1];
7603 	if(arg->vt!=VT_INTEGER)
7604 	{
7605 		if(arg->vt!=VT_STR)
7606 			printf("Function call getplayerproperty has invalid propery name parameter, it must be a string value.\n");
7607 		*pretvar = NULL;
7608 		return E_FAIL;
7609 	}
7610 	prop = arg->lVal;
7611 
7612 	//change the model
7613 	switch(prop)
7614 	{
7615 	case _gpp_ent:
7616 	case _gpp_entity:
7617 	{
7618 		ScriptVariant_ChangeType(*pretvar, VT_PTR);
7619 		(*pretvar)->ptrVal = (VOID*)ent;
7620 		break;
7621 	}
7622 	case _gpp_name:
7623 	{
7624 		ScriptVariant_ChangeType(*pretvar, VT_STR);
7625 		strncpy(StrCache_Get((*pretvar)->strVal), (char*)player[index].name, MAX_STR_VAR_LEN);
7626 		break;
7627 	}
7628 	case _gpp_score:
7629 	{
7630 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7631 		(*pretvar)->lVal = (LONG)player[index].score;
7632 		break;
7633 	}
7634 	case _gpp_lives:
7635 	{
7636 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7637 		(*pretvar)->lVal = (LONG)player[index].lives;
7638 		break;
7639 	}
7640 	case _gpp_playkeys:
7641 	{
7642 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7643 		(*pretvar)->lVal = (LONG)player[index].playkeys;
7644 		break;
7645 	}
7646 	case _gpp_keys:
7647 	{
7648 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7649 		(*pretvar)->lVal = (LONG)player[index].keys;
7650 		break;
7651 	}
7652 	case _gpp_credits:
7653 	{
7654 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7655 		if(noshare) (*pretvar)->lVal = (LONG)player[index].credits;
7656 		else        (*pretvar)->lVal = credits;
7657 		break;
7658 	}
7659 	case _gpp_weaponum:
7660 	{
7661 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7662 		(*pretvar)->lVal = (LONG)player[index].weapnum;
7663 		break;
7664 	}
7665 	//this property is not known
7666 	//default:{
7667 	//  .....
7668 	//}
7669 	}
7670 	return S_OK;
7671 }
7672 
7673 // ===== changeplayerproperty =====
7674 enum changeplayerproperty_enum {
7675 	_cpp_credits,
7676 	_cpp_lives,
7677 	_cpp_name,
7678 	_cpp_playkeys,
7679 	_cpp_score,
7680 	_cpp_weapon,
7681 	_cpp_the_end,
7682 };
7683 
mapstrings_changeplayerproperty(ScriptVariant ** varlist,int paramCount)7684 void mapstrings_changeplayerproperty(ScriptVariant** varlist, int paramCount)
7685 {
7686 	char* propname;
7687 	int prop;
7688 
7689 	static const char* proplist[] = {
7690 		"credits",
7691 		"lives",
7692 		"name",
7693 		"playkeys",
7694 		"score",
7695 		"weapon",
7696 	};
7697 
7698 	if(paramCount < 3) return;
7699 
7700 	// property name
7701 	MAPSTRINGS(varlist[1], proplist, _cpp_the_end,
7702 		"Property name '%s' is not supported by function changeplayerproperty.\n");
7703 }
7704 
7705 //changeplayerproperty(index, propname, value[, value2, value3,...]);
openbor_changeplayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7706 HRESULT openbor_changeplayerproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
7707 {
7708 	LONG ltemp, ltemp2;
7709 	int index;
7710 	entity* ent = NULL;
7711 	int prop = -1;
7712 	char* tempstr = NULL;
7713 	ScriptVariant* arg = NULL;
7714 
7715 	if(paramCount < 3)
7716 	{
7717 		*pretvar = NULL;
7718 		return E_FAIL;
7719 	}
7720 
7721 	mapstrings_changeplayerproperty(varlist, paramCount);
7722 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7723 	(*pretvar)->lVal = (LONG)1;
7724 	arg = varlist[0];
7725 	if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
7726 	{
7727 		index = 0;
7728 	} else index = (int)ltemp;
7729 
7730 	if(!(ent = player[index].ent))  //this player is not selected, so just return
7731 	{
7732 		return S_OK; //return S_OK, to tell the engine it is not a FATAL error
7733 	}
7734 
7735 	if(varlist[1]->vt != VT_INTEGER)
7736 	{
7737 		if(varlist[1]->vt != VT_STR)
7738 			printf("You must give a string value for player property name.\n");
7739 		return E_FAIL;
7740 	}
7741 	prop = varlist[1]->lVal;
7742 
7743 	arg = varlist[2];
7744 
7745 	//change the model
7746 	switch(prop)
7747 	{
7748 	case _cpp_weapon:
7749 	{
7750 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp))){
7751 			if(paramCount > 3)
7752 			{
7753 				arg = varlist[3];
7754 				if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp2)))
7755 					(*pretvar)->lVal = (LONG)1;
7756 			}
7757 			else
7758 			{
7759 				ltemp2 = (LONG)0;
7760 				(*pretvar)->lVal = (LONG)1;
7761 			}
7762 			set_weapon(player[index].ent, (int)ltemp, (int)ltemp2);
7763 			(*pretvar)->lVal = (LONG)1;
7764 		}
7765 		else (*pretvar)->lVal = (LONG)0;
7766 		break;
7767 	}
7768 	case _cpp_name:
7769 	{
7770 		if(arg->vt != VT_STR)
7771 		{
7772 			//printf();
7773 			return E_FAIL;
7774 		}
7775 		tempstr = (char*)StrCache_Get(arg->strVal);
7776 		strcpy(player[index].name, tempstr);
7777 		(*pretvar)->lVal = (LONG)1;
7778 		break;
7779 	}
7780 	case _cpp_score:
7781 	{
7782 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7783 		{
7784 			if(ltemp < 0) ltemp = 0;
7785 			else if(ltemp > 999999999) ltemp = 999999999;
7786 			player[index].score = (unsigned int)ltemp;
7787 		}
7788 		else (*pretvar)->lVal = (LONG)0;
7789 		break;
7790 	}
7791 	case _cpp_lives:
7792 	{
7793 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7794 			player[index].lives = (int)ltemp;
7795 		else (*pretvar)->lVal = (LONG)0;
7796 		break;
7797 	}
7798 	case _cpp_playkeys:
7799 	{
7800 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7801 			player[index].playkeys = (int)ltemp;
7802 		else (*pretvar)->lVal = (LONG)0;
7803 		break;
7804 	}
7805 	case _cpp_credits:
7806 	{
7807 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg,&ltemp)))
7808 		{
7809 		   	if(noshare) player[index].credits = (int)ltemp;
7810 			else        credits = (int)ltemp;
7811 		}
7812 		else (*pretvar)->lVal = (LONG)0;
7813 		break;
7814 	}
7815 	//this property is not known, so return 0
7816 	//default:
7817 	//    (*pretvar)->lVal = (LONG)0;
7818 	}
7819 
7820 	return S_OK;
7821 }
7822 
7823 //checkhole(x,z), return 1 if there's hole here
openbor_checkhole(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7824 HRESULT openbor_checkhole(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
7825 {
7826 	ScriptVariant* arg = NULL;
7827 	DOUBLE x, z;
7828 
7829 	if(paramCount < 2)
7830 	{
7831 		*pretvar = NULL;
7832 		return E_FAIL;
7833 	}
7834 
7835 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7836 	(*pretvar)->lVal = (LONG)0;
7837 
7838 	arg = varlist[0];
7839 	if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
7840 		return S_OK;
7841 
7842 	arg = varlist[1];
7843 	if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
7844 		return S_OK;
7845 
7846 	(*pretvar)->lVal = (LONG)(checkhole((float)x, (float)z) && checkwall((float)x, (float)z)<0);
7847 	return S_OK;
7848 }
7849 
7850 //checkwall(x,z), return wall height, or 0
openbor_checkwall(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7851 HRESULT openbor_checkwall(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
7852 {
7853 	ScriptVariant* arg = NULL;
7854 	DOUBLE x, z;
7855 	int wall;
7856 
7857 	if(paramCount < 2)
7858 	{
7859 		*pretvar = NULL;
7860 		return E_FAIL;
7861 	}
7862 
7863 	ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7864 	(*pretvar)->dblVal = (DOUBLE)0;
7865 
7866 	arg = varlist[0];
7867 	if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
7868 		return S_OK;
7869 
7870 	arg = varlist[1];
7871 	if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
7872 		return S_OK;
7873 
7874 	if((wall=checkwall_below((float)x, (float)z, 100000))>=0)
7875 	{
7876 		(*pretvar)->dblVal = (DOUBLE)level->walls[wall][7];
7877 	}
7878 	return S_OK;
7879 }
7880 
7881 //checkplatformbelow(x,z,a), return the highest platfrom entity below
openbor_checkplatformbelow(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7882 HRESULT openbor_checkplatformbelow(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
7883 {
7884 	ScriptVariant* arg = NULL;
7885 	DOUBLE x, z, a;
7886 
7887 	if(paramCount < 3)
7888 	{
7889 		*pretvar = NULL;
7890 		return E_FAIL;
7891 	}
7892 
7893 	ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
7894 	(*pretvar)->dblVal = (DOUBLE)0;
7895 
7896 	arg = varlist[0];
7897 	if(FAILED(ScriptVariant_DecimalValue(arg, &x)))
7898 		return S_OK;
7899 
7900 	arg = varlist[1];
7901 	if(FAILED(ScriptVariant_DecimalValue(arg, &z)))
7902 		return S_OK;
7903 
7904 	arg = varlist[2];
7905 	if(FAILED(ScriptVariant_DecimalValue(arg, &a)))
7906 		return S_OK;
7907 
7908 	ScriptVariant_ChangeType(*pretvar, VT_PTR);
7909 	(*pretvar)->ptrVal = (VOID*)check_platform_below((float)x,(float)z,(float)a, NULL);
7910 	return S_OK;
7911 }
7912 
openbor_openfilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)7913 HRESULT openbor_openfilestream(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
7914 {
7915 	char* filename = NULL;
7916 	ScriptVariant* arg = NULL;
7917 	LONG location = 0;
7918 	int fsindex;
7919 
7920 	int disCcWarns;
7921 	FILE *handle = NULL;
7922 	char path[128] = {""};
7923 	long size;
7924 
7925 	if(paramCount < 1)
7926 	{
7927 		*pretvar = NULL;
7928 		return E_FAIL;
7929 	}
7930 
7931 	ScriptVariant_Clear(*pretvar);
7932 
7933 	arg = varlist[0];
7934 	if(arg->vt!=VT_STR)
7935 	{
7936 		printf("Filename for openfilestream must be a string.\n");
7937 		*pretvar = NULL;
7938 		return E_FAIL;
7939 	}
7940 
7941 	filename = (char*)StrCache_Get(arg->strVal);
7942 
7943 	if(paramCount > 1)
7944 	{
7945 		arg = varlist[1];
7946 		if(FAILED(ScriptVariant_IntegerValue(arg, &location)))
7947 			return S_OK;
7948 	}
7949 
7950 	for(fsindex=0; fsindex<LEVEL_MAX_FILESTREAMS; fsindex++){
7951 		if(level->filestreams[fsindex].buf==NULL){
7952 			break;
7953 		}
7954 	}
7955 
7956 	if(fsindex == LEVEL_MAX_FILESTREAMS)
7957 	{
7958 		printf("Maximum file streams exceeded.\n");
7959 		*pretvar = NULL;
7960 		return E_FAIL;
7961 	}
7962 
7963 	// Load file from saves directory if specified
7964 	if(location)
7965 	{
7966 		getBasePath(path, "Saves", 0);
7967 		strcat(path, "/");
7968 		strcat(path, filename);
7969 #ifndef DC
7970 		if(!(fileExists(path)))
7971 		{
7972 		    /*
7973 		    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.
7974 
7975 			printf("Openfilestream - file specified does not exist.\n"); //Keep this for possible debug mode in the future.
7976 			*/
7977 
7978 			ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
7979             (*pretvar)->lVal = -1;
7980 
7981 			return S_OK;
7982 		}
7983 #endif
7984 		handle = fopen(path, "rb");
7985 		if(handle == NULL) return E_FAIL;
7986 		fseek(handle, 0, SEEK_END);
7987 		size = ftell(handle);
7988 		rewind(handle);
7989 		level->filestreams[fsindex].buf = (char*)malloc(sizeof(char)*size);
7990 		if(level->filestreams[fsindex].buf == NULL) return E_FAIL;
7991 		disCcWarns = fread(level->filestreams[fsindex].buf, 1, size, handle);
7992 	}
7993 	else if(buffer_pakfile(filename, &level->filestreams[fsindex].buf, &level->filestreams[fsindex].size)!=1)
7994 	{
7995 		  printf("Invalid filename used in openfilestream.\n");
7996 		  *pretvar = NULL;
7997 		  return E_FAIL;
7998 	}
7999 
8000 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8001 	(*pretvar)->lVal = (LONG)fsindex;
8002 
8003 	level->filestreams[fsindex].pos = 0;
8004 	return S_OK;
8005 }
8006 
openbor_getfilestreamline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8007 HRESULT openbor_getfilestreamline(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8008 {
8009 	char line[MAX_STR_VAR_LEN];
8010 	int length;
8011 	ScriptVariant* arg = NULL;
8012 	LONG filestreamindex;
8013 
8014 	if(paramCount < 1)
8015 	{
8016 		*pretvar = NULL;
8017 		return E_FAIL;
8018 	}
8019 
8020 	arg = varlist[0];
8021 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8022 		return S_OK;
8023 
8024 	ScriptVariant_Clear(*pretvar);
8025 	ScriptVariant_ChangeType(*pretvar, VT_STR);
8026 
8027 	length = 0;
8028 	strncpy(line, "it's initialized now", MAX_STR_VAR_LEN);
8029 
8030 	while(level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos+length] && level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos+length]!='\n' && level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos+length]!='\r') ++length;
8031 	if(length >= MAX_STR_VAR_LEN)
8032 		strncpy(StrCache_Get((*pretvar)->strVal), (char*)(level->filestreams[filestreamindex].buf+level->filestreams[filestreamindex].pos), MAX_STR_VAR_LEN);
8033 	else
8034 	{
8035 		strncpy(line, (char*)(level->filestreams[filestreamindex].buf+level->filestreams[filestreamindex].pos), length);
8036 		line[length] = '\0';
8037 		strncpy(StrCache_Get((*pretvar)->strVal), line, MAX_STR_VAR_LEN);
8038 	}
8039 	return S_OK;
8040 }
8041 
openbor_getfilestreamargument(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8042 HRESULT openbor_getfilestreamargument(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8043 {
8044 	ScriptVariant* arg = NULL;
8045 	LONG filestreamindex, argument;
8046 	char* argtype = NULL;
8047 
8048 	if(paramCount < 3)
8049 	{
8050 		*pretvar = NULL;
8051 		return E_FAIL;
8052 	}
8053 
8054 	arg = varlist[0];
8055 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8056 		return S_OK;
8057 
8058 	arg = varlist[1];
8059 	if(FAILED(ScriptVariant_IntegerValue(arg, &argument)))
8060 		return S_OK;
8061 	ScriptVariant_Clear(*pretvar);
8062 
8063 	if(varlist[2]->vt != VT_STR)
8064 	{
8065 		printf("You must give a string value specifying what kind of value you want the argument converted to.\n");
8066 		return E_FAIL;
8067 	}
8068 	argtype = (char*)StrCache_Get(varlist[2]->strVal);
8069 
8070 	if(stricmp(argtype, "string")==0)
8071 	{
8072 		ScriptVariant_ChangeType(*pretvar, VT_STR);
8073 		strncpy(StrCache_Get((*pretvar)->strVal), (char*)findarg(level->filestreams[filestreamindex].buf+level->filestreams[filestreamindex].pos, argument), MAX_STR_VAR_LEN);
8074 	}
8075 	else if(stricmp(argtype, "int")==0)
8076 	{
8077 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8078 		(*pretvar)->lVal = (LONG)atoi(findarg(level->filestreams[filestreamindex].buf+level->filestreams[filestreamindex].pos, argument));
8079 	}
8080 	else if(stricmp(argtype, "float")==0)
8081 	{
8082 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
8083 		(*pretvar)->dblVal = (DOUBLE)atof(findarg(level->filestreams[filestreamindex].buf+level->filestreams[filestreamindex].pos, argument));
8084 	}
8085 	else
8086 	{
8087 		printf("Invalid type for argument converted to (getfilestreamargument).\n");
8088 		return E_FAIL;
8089 	}
8090 
8091 	return S_OK;
8092 }
8093 
openbor_filestreamnextline(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8094 HRESULT openbor_filestreamnextline(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8095 {
8096 	ScriptVariant* arg = NULL;
8097 	LONG filestreamindex;
8098 
8099 	if(paramCount < 1)
8100 	{
8101 		*pretvar = NULL;
8102 		return E_FAIL;
8103 	}
8104 
8105 	arg = varlist[0];
8106 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8107 		return S_OK;
8108 	while(level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos] && level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos]!='\n' && level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos]!='\r') ++level->filestreams[filestreamindex].pos;
8109 	while(level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos]=='\n' || level->filestreams[filestreamindex].buf[level->filestreams[filestreamindex].pos]=='\r') ++level->filestreams[filestreamindex].pos;
8110 
8111 	return S_OK;
8112 }
8113 
openbor_getfilestreamposition(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8114 HRESULT openbor_getfilestreamposition(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8115 {
8116 	ScriptVariant* arg = NULL;
8117 	LONG filestreamindex;
8118 
8119 	if(paramCount < 1)
8120 	{
8121 		*pretvar = NULL;
8122 		return E_FAIL;
8123 	}
8124 
8125 	arg = varlist[0];
8126 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8127 		return S_OK;
8128 
8129 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8130 	(*pretvar)->lVal = (LONG)level->filestreams[filestreamindex].pos;
8131 	return S_OK;
8132 }
8133 
openbor_setfilestreamposition(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8134 HRESULT openbor_setfilestreamposition(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8135 {
8136 	ScriptVariant* arg = NULL;
8137 	LONG filestreamindex, position;
8138 
8139 
8140 	if(paramCount < 2)
8141 	{
8142 		*pretvar = NULL;
8143 		return E_FAIL;
8144 	}
8145 
8146 	arg = varlist[0];
8147 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8148 		return S_OK;
8149 
8150 	arg = varlist[1];
8151 	if(FAILED(ScriptVariant_IntegerValue(arg, &position)))
8152 		return S_OK;
8153 
8154 	level->filestreams[filestreamindex].pos = position;
8155 	return S_OK;
8156 }
8157 
openbor_filestreamappend(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8158 HRESULT openbor_filestreamappend(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8159 {
8160 	LONG filestreamindex;
8161 	ScriptVariant* arg = NULL;
8162 	LONG appendtype;
8163 	LONG ltemp;
8164 	DOUBLE dbltemp;
8165 	char* temp;
8166 	char append[MAX_STR_VAR_LEN];
8167 
8168 
8169 	if(paramCount < 3)
8170 	{
8171 		*pretvar = NULL;
8172 		return E_FAIL;
8173 	}
8174 
8175 	ScriptVariant_Clear(*pretvar);
8176 
8177 	arg = varlist[0];
8178 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8179 		return S_OK;
8180 
8181 	arg = varlist[1];
8182 	if(arg->vt==VT_STR)
8183 	{
8184 		strcpy(append, StrCache_Get(arg->strVal));
8185 	}
8186 	else if(arg->vt==VT_INTEGER)
8187 	{
8188 		if(FAILED(ScriptVariant_IntegerValue(arg, &ltemp)))
8189 			return S_OK;
8190 		sprintf(append, "%d", (int)ltemp);
8191 	}
8192 	else if(arg->vt==VT_DECIMAL)
8193 	{
8194 		if(FAILED(ScriptVariant_DecimalValue(arg, &dbltemp)))
8195 			return S_OK;
8196 		sprintf(append, "%f", dbltemp);
8197 	}
8198 	else
8199 	{
8200 		printf("Filename for filestreamappend must be a string.\n");
8201 		*pretvar = NULL;
8202 		return E_FAIL;
8203 	}
8204 
8205 
8206 
8207 	arg = varlist[2];
8208 	if(FAILED(ScriptVariant_IntegerValue(arg, &appendtype)))
8209 		return S_OK;
8210 
8211 	temp = (char*)malloc(sizeof(char)*(strlen(level->filestreams[filestreamindex].buf) + strlen(append) + 4));
8212 	strcpy(temp, level->filestreams[filestreamindex].buf);
8213 
8214 	if(appendtype == 0)
8215 	{
8216 		strcat(temp, "\r\n");
8217 		strcat(temp, append);
8218 		temp[strlen(level->filestreams[filestreamindex].buf) + strlen(append) + 2] = ' ';
8219 		temp[strlen(level->filestreams[filestreamindex].buf) + strlen(append) + 3] = '\0';
8220 	}
8221 	else if(appendtype == 1)
8222 	{
8223 		strcat(temp, append);
8224 		temp[strlen(level->filestreams[filestreamindex].buf) + strlen(append)] = ' ';
8225 		temp[strlen(level->filestreams[filestreamindex].buf) + strlen(append) + 1] = '\0';
8226 	}
8227 	free(level->filestreams[filestreamindex].buf);
8228 	level->filestreams[filestreamindex].buf = temp;
8229 
8230 	return S_OK;
8231 }
8232 
openbor_createfilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8233 HRESULT openbor_createfilestream(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8234 {
8235 	int fsindex;
8236 	ScriptVariant_Clear(*pretvar);
8237 
8238 	for(fsindex=0; fsindex<LEVEL_MAX_FILESTREAMS; fsindex++){
8239 		if(level->filestreams[fsindex].buf==NULL){
8240 			break;
8241 		}
8242 	}
8243 
8244 	if(fsindex == LEVEL_MAX_FILESTREAMS)
8245 	{
8246 		printf("Maximum file streams exceeded.\n");
8247 		*pretvar = NULL;
8248 		return E_FAIL;
8249 	}
8250 
8251 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8252 	(*pretvar)->lVal = (LONG)fsindex;
8253 
8254 	// Initialize the new filestream
8255 	level->filestreams[fsindex].pos = 0;
8256 	level->filestreams[fsindex].buf = (char*)malloc(sizeof(char)*128);
8257 	level->filestreams[fsindex].buf[0] = '\0';
8258 	return S_OK;
8259 }
8260 
openbor_savefilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8261 HRESULT openbor_savefilestream(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8262 {
8263 	int i, x, y;
8264 	LONG filestreamindex;
8265 	ScriptVariant* arg = NULL;
8266 	int disCcWarns;
8267 	FILE *handle = NULL;
8268 	char path[128] = {""};
8269 	char tmpname[128] = {""};
8270 	char mod[256] = {""};
8271 
8272 	if(paramCount < 1)
8273 	{
8274 		*pretvar = NULL;
8275 		return E_FAIL;
8276 	}
8277 
8278 	ScriptVariant_Clear(*pretvar);
8279 
8280 	arg = varlist[0];
8281 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8282 		return S_OK;
8283 
8284 	arg = varlist[1];
8285 	if(arg->vt!=VT_STR)
8286 	{
8287 		printf("Filename for savefilestream must be a string.\n");
8288 		*pretvar = NULL;
8289 		return E_FAIL;
8290 	}
8291 
8292 	// Get the saves directory
8293 	getBasePath(path, "Saves/", 0);
8294 
8295 	// get the packfile's name by chopping off the rest of the path
8296 	strncpy(mod,packfile,strlen(packfile)-4);
8297 	x=0;
8298 	for(i=0; i<(int)strlen(mod); i++){
8299 		if((mod[i] == '/') || (mod[i] == '\\')) x = i;
8300 	}
8301 	y=0;
8302 	for(i=0; i<(int)strlen(mod); i++){
8303 		// For packfiles without '/'
8304 		if(x == 0){
8305 			tmpname[y] = mod[i];
8306 			y++;
8307 		}
8308 		// For packfiles with '/'
8309 		if(x != 0 && i > x){
8310 			tmpname[y] = mod[i];
8311 			y++;
8312 		}
8313 	}
8314 
8315 	// Make ./Saves/PAKNAME if it doesn't exist
8316 	strcat(path,tmpname);
8317 #ifndef DC
8318 	dirExists(path, 1);
8319 #endif
8320 
8321 	// Add user's filename to path and write the filestream to it
8322 	strcat(path, "/");
8323 	strcat(path, (char*)StrCache_Get(arg->strVal));
8324 	handle = fopen(path, "wb");
8325 	if(handle==NULL) return E_FAIL;
8326 	disCcWarns = fwrite(level->filestreams[filestreamindex].buf, 1, strlen(level->filestreams[filestreamindex].buf), handle);
8327 
8328 	// add blank line so it can be read successfully
8329 	fwrite("\r\n", 1, 2, handle);
8330 	fclose(handle);
8331 
8332 	return S_OK;
8333 }
8334 
openbor_closefilestream(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8335 HRESULT openbor_closefilestream(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8336 {
8337 	LONG filestreamindex;
8338 	ScriptVariant* arg = NULL;
8339 
8340 	*pretvar = NULL;
8341 
8342 	if(paramCount < 1)
8343 		return E_FAIL;
8344 
8345 	arg = varlist[0];
8346 	if(FAILED(ScriptVariant_IntegerValue(arg, &filestreamindex)))
8347 		return E_FAIL;
8348 
8349 
8350 	if(level->filestreams[filestreamindex].buf){
8351 		free(level->filestreams[filestreamindex].buf);
8352 		level->filestreams[filestreamindex].buf = NULL;
8353 	}
8354 	return S_OK;
8355 }
8356 
8357 //damageentity(entity, other, force, drop, type)
openbor_damageentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8358 HRESULT openbor_damageentity(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8359 {
8360 	entity* ent = NULL;
8361 	entity* other = NULL;
8362 	entity* temp = NULL;
8363 	LONG force, drop, type;
8364 	s_attack attack;
8365 	extern s_attack emptyattack;
8366 
8367 	if(paramCount < 1)
8368 	{
8369 		*pretvar = NULL;
8370 		return E_FAIL;
8371 	}
8372 
8373 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8374 	(*pretvar)->lVal = (LONG)0;
8375 
8376 	ent = (entity*)(varlist[0])->ptrVal; //retrieve the entity
8377 	if(!ent)  return S_OK;
8378 
8379 	other = ent;
8380 	force = (LONG)1;
8381 	drop = (LONG)0;
8382 	type = (LONG)ATK_NORMAL;
8383 
8384 	if(paramCount >= 2)
8385 	{
8386 		other = (entity*)(varlist[1])->ptrVal;
8387 		if(!other)
8388 			return S_OK;
8389 	}
8390 	if(paramCount >= 3)
8391 	{
8392 		if(FAILED(ScriptVariant_IntegerValue((varlist[2]), &force)))
8393 			return S_OK;
8394 	}
8395 
8396 	if(!ent->takedamage)
8397 	{
8398 		ent->health -= force;
8399 		if(ent->health <= 0) kill(ent);
8400 		(*pretvar)->lVal = (LONG)1;
8401 		return S_OK;
8402 	}
8403 
8404 	if(paramCount >= 4)
8405 	{
8406 		if(FAILED(ScriptVariant_IntegerValue((varlist[3]), &drop)))
8407 			return S_OK;
8408 	}
8409 	if(paramCount >= 5)
8410 	{
8411 		if(FAILED(ScriptVariant_IntegerValue((varlist[4]), &type)))
8412 			return S_OK;
8413 	}
8414 
8415 	temp = self; self = ent;
8416 	attack = emptyattack;
8417 	attack.attack_force = force;
8418 	attack.attack_drop = drop;
8419 	if(drop) {attack.dropv[0] = (float)3; attack.dropv[1] = (float)1.2; attack.dropv[2] = (float)0;}
8420 	attack.attack_type = type;
8421 	self->takedamage(other, &attack);
8422 	self = temp;
8423 	return S_OK;
8424 }
8425 
8426 //killentity(entity)
openbor_killentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8427 HRESULT openbor_killentity(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8428 {
8429 	entity* ent = NULL;
8430 
8431 	if(paramCount < 1)
8432 	{
8433 		*pretvar = NULL;
8434 		return E_FAIL;
8435 	}
8436 
8437 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8438 
8439 	ent = (entity*)(varlist[0])->ptrVal; //retrieve the entity
8440 	if(!ent)
8441 	{
8442 		(*pretvar)->lVal = (LONG)0;
8443 		return S_OK;
8444 	}
8445 	kill(ent);
8446 	(*pretvar)->lVal = (LONG)1;
8447 	return S_OK;
8448 }
8449 
8450 //findtarget(entity, int animation);
openbor_findtarget(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8451 HRESULT openbor_findtarget(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8452 {
8453 	int i = 0;
8454 	entity* ent = NULL;
8455 	entity* tempself, *target;
8456 	LONG anim = -1;
8457 
8458     if(paramCount>2) ScriptVariant_IntegerValue(varlist[2], &i);
8459 
8460 	if(paramCount < 1)
8461 	{
8462 		*pretvar = NULL;
8463 		return E_FAIL;
8464 	}
8465 
8466 	ScriptVariant_ChangeType(*pretvar, VT_PTR);
8467 
8468 	ent = (entity*)(varlist[0])->ptrVal; //retrieve the entity
8469 	if(!ent)
8470 	{
8471 		ScriptVariant_Clear(*pretvar);
8472 		return S_OK;
8473 	}
8474 	if(paramCount>1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim))) return E_FAIL;
8475 	tempself = self;
8476 	self = ent;
8477 	target = normal_find_target((int)anim, i);
8478 	if(!target) ScriptVariant_Clear(*pretvar);
8479 	else (*pretvar)->ptrVal = (VOID*)target;
8480 	self = tempself;
8481 	return S_OK;
8482 }
8483 
8484 //checkrange(entity, target, int ani);
openbor_checkrange(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8485 HRESULT openbor_checkrange(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8486 {
8487 	entity* ent = NULL, *target = NULL;
8488 	LONG ani = 0;
8489 	extern int max_animations;
8490 
8491 	if(paramCount < 2) goto checkrange_error;
8492 
8493 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8494 
8495 	if(varlist[0]->vt !=VT_PTR || varlist[1]->vt!=VT_PTR) goto checkrange_error;
8496 
8497 	ent = (entity*)(varlist[0])->ptrVal; //retrieve the entity
8498 	target = (entity*)(varlist[1])->ptrVal; //retrieve the target
8499 
8500 	if(!ent || !target) goto checkrange_error;
8501 
8502 	if(paramCount >2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &ani))) goto checkrange_error;
8503 	else if(paramCount<=2) ani = ent->animnum;
8504 
8505 	if(ani<0 || ani>=max_animations)
8506 	{
8507 		printf("Animation id out of range: %d / %d.\n", (int)ani, max_animations);
8508 		goto checkrange_error;
8509 	}
8510 
8511 	(*pretvar)->lVal = check_range(ent, target, ani);
8512 
8513 	return S_OK;
8514 
8515 checkrange_error:
8516 	printf("Function needs at least 2 valid entity handles, the third parameter is optional: checkrange(entity, target, int animnum)\n");
8517 	*pretvar = NULL;
8518 	return E_FAIL;
8519 }
8520 
8521 //clearspawnentry();
openbor_clearspawnentry(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8522 HRESULT openbor_clearspawnentry(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8523 {
8524 	*pretvar = NULL;
8525 	memset(&spawnentry, 0, sizeof(s_spawn_entry));
8526 	spawnentry.index = spawnentry.itemindex = spawnentry.weaponindex = -1;
8527 	return S_OK;
8528 }
8529 
8530 // ===== setspawnentry =====
8531 enum setspawnentry_enum
8532 {
8533 	_sse_2phealth,
8534 	_sse_2pitem,
8535 	_sse_3phealth,
8536 	_sse_3pitem,
8537 	_sse_4phealth,
8538 	_sse_4pitem,
8539 	_sse_aggression,
8540 	_sse_alias,
8541 	_sse_alpha,
8542 	_sse_boss,
8543 	_sse_coords,
8544 	_sse_credit,
8545 	_sse_dying,
8546 	_sse_flip,
8547 	_sse_health,
8548 	_sse_item,
8549 	_sse_itemalias,
8550 	_sse_itemhealth,
8551 	_sse_itemmap,
8552 	_sse_map,
8553 	_sse_mp,
8554 	_sse_multiple,
8555 	_sse_name,
8556 	_sse_nolife,
8557 	_sse_weapon,
8558 	_sse_the_end,
8559 };
8560 
mapstrings_setspawnentry(ScriptVariant ** varlist,int paramCount)8561 void mapstrings_setspawnentry(ScriptVariant** varlist, int paramCount)
8562 {
8563 	char* propname;
8564 	int prop;
8565 	static const char* proplist[] =
8566 	{
8567 		"2phealth",
8568 		"2pitem",
8569 		"3phealth",
8570 		"3pitem",
8571 		"4phealth",
8572 		"4pitem",
8573 		"aggression",
8574 		"alias",
8575 		"alpha",
8576 		"boss",
8577 		"coords",
8578 		"credit",
8579 		"dying",
8580 		"flip",
8581 		"health",
8582 		"item",
8583 		"itemalias",
8584 		"itemhealth",
8585 		"itemmap",
8586 		"map",
8587 		"mp",
8588 		"multiple",
8589 		"name",
8590 		"nolife",
8591 		"weapon",
8592 	};
8593 
8594 	MAPSTRINGS(varlist[0], proplist, _sse_the_end,
8595 		"Property name '%s' is not supported by setspawnentry.\n");
8596 }
8597 
8598 //setspawnentry(propname, value1[, value2, value3, ...]);
openbor_setspawnentry(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8599 HRESULT openbor_setspawnentry(ScriptVariant** varlist, ScriptVariant** pretvar, int paramCount)
8600 {
8601 	LONG ltemp;
8602 	s_model* tempmodel;
8603 	DOUBLE dbltemp;
8604 	int temp, prop;
8605 	ScriptVariant* arg = NULL;
8606 
8607 	if(paramCount < 2)
8608 	{
8609 		*pretvar = NULL;
8610 		return E_FAIL;
8611 	}
8612 
8613 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
8614 	(*pretvar)->lVal = (LONG)1;
8615 
8616 	mapstrings_setspawnentry(varlist, paramCount);
8617 	if(varlist[0]->vt != VT_INTEGER)
8618 	{
8619 		if(varlist[0]->vt != VT_STR)
8620 			printf("You must give a string value for spawn entry property name.\n");
8621 		*pretvar = NULL;
8622 		return E_FAIL;
8623 	}
8624 
8625 	prop = varlist[0]->lVal;
8626 
8627 	arg = varlist[1];
8628 
8629 	switch(prop)
8630 	{
8631 	case _sse_name:
8632 		if(arg->vt != VT_STR)
8633 		{
8634 			printf("You must use a string value for spawn entry's name property: function setspawnentry.\n");
8635 			goto setspawnentry_error;
8636 		}
8637 		spawnentry.model = findmodel((char*)StrCache_Get(arg->strVal));
8638 		break;
8639 	case _sse_alias:
8640 		if(arg->vt != VT_STR) goto setspawnentry_error;
8641 		strcpy(spawnentry.alias, (char*)StrCache_Get(arg->strVal));
8642 		break;
8643 	case _sse_item:
8644 		if(arg->vt != VT_STR) goto setspawnentry_error;
8645 		spawnentry.itemmodel = findmodel((char*)StrCache_Get(arg->strVal));
8646 		spawnentry.item = spawnentry.itemmodel->name;
8647 		spawnentry.itemindex = get_cached_model_index(spawnentry.item);
8648 		spawnentry.itemplayer_count = 0;
8649 		break;
8650 	case _sse_2pitem:
8651 		if(arg->vt != VT_STR) goto setspawnentry_error;
8652 		tempmodel = findmodel((char*)StrCache_Get(arg->strVal));
8653 		if(!tempmodel) spawnentry.item = NULL;
8654 		else spawnentry.item = tempmodel->name;
8655 		spawnentry.itemplayer_count = 1;
8656 		break;
8657 	case _sse_3pitem:
8658 		if(arg->vt != VT_STR) goto setspawnentry_error;
8659 		spawnentry.itemmodel = findmodel((char*)StrCache_Get(arg->strVal));
8660 		spawnentry.itemplayer_count = 2;
8661 		break;
8662 	case _sse_4pitem:
8663 		if(arg->vt != VT_STR) goto setspawnentry_error;
8664 		spawnentry.itemmodel = findmodel((char*)StrCache_Get(arg->strVal));
8665 		spawnentry.itemplayer_count = 3;
8666 		break;
8667 	case _sse_health:
8668 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8669 			spawnentry.health[0] = (int)ltemp;
8670 		else (*pretvar)->lVal = (LONG)0;
8671 		break;
8672 	case _sse_itemhealth:
8673 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8674 			spawnentry.itemhealth = (int)ltemp;
8675 		else (*pretvar)->lVal = (LONG)0;
8676 		break;
8677 	case _sse_itemalias:
8678 		if(arg->vt != VT_STR) return E_FAIL;
8679 		strcpy(spawnentry.itemalias, (char*)StrCache_Get(arg->strVal));
8680 		break;
8681 	case _sse_2phealth:
8682 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8683 			spawnentry.health[1] = (int)ltemp;
8684 		else (*pretvar)->lVal = (LONG)0;
8685 		break;
8686 	case _sse_3phealth:
8687 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8688 			spawnentry.health[2] = (int)ltemp;
8689 		else (*pretvar)->lVal = (LONG)0;
8690 		break;
8691 	case _sse_4phealth:
8692 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8693 			spawnentry.health[3] = (int)ltemp;
8694 		else (*pretvar)->lVal = (LONG)0;
8695 		break;
8696 	case _sse_coords:
8697 		temp = 1;
8698 		if(SUCCEEDED(ScriptVariant_DecimalValue(arg, &dbltemp))) spawnentry.x = (float)dbltemp;
8699 		else temp = 0;
8700 		if(paramCount >= 3 && temp)
8701 		{
8702 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp))) spawnentry.z = (float)dbltemp;
8703 			else temp = 0;
8704 		}
8705 		if(paramCount >= 4 && temp)
8706 		{
8707 			if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp))) spawnentry.a = (float)dbltemp;
8708 			else temp = 0;
8709 		}
8710 		(*pretvar)->lVal = (LONG)temp;
8711 		break;
8712 	case _sse_mp:
8713 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8714 			spawnentry.mp = (int)ltemp;
8715 		else (*pretvar)->lVal = (LONG)0;
8716 		break;
8717 	case _sse_map:
8718 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8719 			spawnentry.colourmap = (int)ltemp;
8720 		else (*pretvar)->lVal = (LONG)0;
8721 		break;
8722 	case _sse_itemmap:
8723 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8724 			spawnentry.itemmap = (int)ltemp;
8725 		else (*pretvar)->lVal = (LONG)0;
8726 		break;
8727 	case _sse_alpha:
8728 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8729 			spawnentry.alpha = (int)ltemp;
8730 		else (*pretvar)->lVal = (LONG)0;
8731 		break;
8732 	case _sse_multiple:
8733 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8734 			spawnentry.multiple = (int)ltemp;
8735 		else (*pretvar)->lVal = (LONG)0;
8736 		break;
8737 	case _sse_dying:
8738 		temp = 1;
8739 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8740 			spawnentry.dying = (int)ltemp;
8741 		else temp = 0;
8742 		if(paramCount >= 3 && temp)
8743 		{
8744 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
8745 				spawnentry.per1 = (int)ltemp;
8746 			else temp = 0;
8747 		}
8748 		if(paramCount >= 4 && temp)
8749 		{
8750 			if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
8751 				spawnentry.per2 = (int)ltemp;
8752 			else temp = 0;
8753 		}
8754 		(*pretvar)->lVal = (LONG)temp;
8755 		break;
8756 	case _sse_nolife:
8757 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8758 			spawnentry.nolife = (int)ltemp;
8759 		else (*pretvar)->lVal = (LONG)0;
8760 		break;
8761 	case _sse_boss:
8762 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8763 			spawnentry.boss = (int)ltemp;
8764 		else (*pretvar)->lVal = (LONG)0;
8765 		break;
8766 	case _sse_flip:
8767 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8768 			spawnentry.flip = (int)ltemp;
8769 		else (*pretvar)->lVal = (LONG)0;
8770 		break;
8771 	case _sse_credit:
8772 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8773 			spawnentry.credit = (int)ltemp;
8774 		else (*pretvar)->lVal = (LONG)0;
8775 		break;
8776 	case _sse_aggression:
8777 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
8778 			spawnentry.aggression = (int)ltemp;
8779 		else (*pretvar)->lVal = (LONG)0;
8780 		break;
8781 	case _sse_weapon:
8782 		if(arg->vt != VT_STR) goto setspawnentry_error;
8783 		spawnentry.weaponmodel = findmodel((char*)StrCache_Get(arg->strVal));
8784 		break;
8785 	default:
8786 		//printf("Property name '%s' is not supported by setspawnentry.\n", propname);
8787 		goto setspawnentry_error;
8788 	}
8789 
8790 	return S_OK;
8791 setspawnentry_error:
8792 	*pretvar = NULL;
8793 	return E_FAIL;
8794 }
8795 
8796 //spawn();
openbor_spawn(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8797 HRESULT openbor_spawn(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8798 {
8799 	entity* ent;
8800 
8801 	ent = smartspawn(&spawnentry);
8802 
8803 	if(ent)
8804 	{
8805 		ScriptVariant_ChangeType(*pretvar, VT_PTR);
8806 		(*pretvar)->ptrVal = (VOID*) ent;
8807 	}
8808 	else     ScriptVariant_Clear(*pretvar);
8809 
8810 	return S_OK;
8811 }
8812 
8813 //entity * projectile(char *name, float x, float z, float a, int direction, int type, int ptype, int map);
openbor_projectile(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)8814 HRESULT openbor_projectile(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
8815 {
8816 	int i;
8817 	LONG value[7];
8818 	entity* ent;
8819 	char name[64] = {""};
8820 
8821 	if(paramCount != 8) goto projectile_error;
8822 	if(varlist[0]->vt != VT_STR) goto projectile_error;
8823 
8824 	ScriptVariant_Clear(*pretvar);
8825 
8826 	strncpy(name, StrCache_Get(varlist[0]->strVal), MAX_STR_VAR_LEN);
8827 
8828 	for(i=1; i<=7; i++)
8829 	{
8830 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], &value[i-1])))
8831 		    goto projectile_error;
8832 	}
8833 
8834 	switch((int)value[5])
8835 	{
8836 		default:
8837 		case 0:
8838 			ent = knife_spawn(name, -1, (float)value[0], (float)value[1], (float)value[2], (int)value[3], (int)value[4], (int)value[6]);
8839 			break;
8840 		case 1:
8841 			ent = bomb_spawn(name, -1, (float)value[0], (float)value[1], (float)value[2], (int)value[3], (int)value[6]);
8842 			break;
8843 	}
8844 
8845 	ScriptVariant_ChangeType(*pretvar, VT_PTR);
8846 	(*pretvar)->ptrVal = (VOID*) ent;
8847 
8848 	return S_OK;
8849 
8850 projectile_error:
8851 	printf("Function requires 8 values: entity * projectile(char *name, float x, float z, float a, int direction, int type, int ptype, int map)\n");
8852 	return E_FAIL;
8853 }
8854 
8855 
8856 // ===== openborconstant =====
8857 #define ICMPCONST(x) \
8858 if(stricmp(#x, constname)==0) {\
8859 	ScriptVariant_ChangeType(varlist[0], VT_INTEGER);\
8860 	varlist[0]->lVal = (LONG)x;\
8861 	return;\
8862 }
mapstrings_transconst(ScriptVariant ** varlist,int paramCount)8863 void mapstrings_transconst(ScriptVariant** varlist, int paramCount)
8864 {
8865 	char* constname = NULL;
8866 
8867 	if(paramCount < 1) return;
8868 
8869 	if(varlist[0]->vt == VT_STR)
8870 	{
8871 		constname = (char*)StrCache_Get(varlist[0]->strVal);
8872 
8873 		ICMPCONST(COMPATIBLEVERSION)
8874 		ICMPCONST(PIXEL_8)
8875 		ICMPCONST(PIXEL_x8)
8876 		ICMPCONST(PIXEL_16)
8877 		ICMPCONST(PIXEL_32)
8878 		ICMPCONST(CV_SAVED_GAME)
8879 		ICMPCONST(CV_HIGH_SCORE)
8880 		ICMPCONST(THINK_SPEED)
8881 		ICMPCONST(COUNTER_SPEED)
8882 		ICMPCONST(MAX_ENTS)
8883 		ICMPCONST(MAX_PANELS)
8884 		ICMPCONST(MAX_WEAPONS)
8885 		ICMPCONST(MAX_COLOUR_MAPS)
8886 		ICMPCONST(MAX_NAME_LEN)
8887 		ICMPCONST(LEVEL_MAX_SPAWNS)
8888 		ICMPCONST(LEVEL_MAX_PANELS)
8889 		ICMPCONST(LEVEL_MAX_HOLES)
8890 		ICMPCONST(LEVEL_MAX_WALLS)
8891 		ICMPCONST(MAX_LEVELS)
8892 		ICMPCONST(MAX_DIFFICULTIES)
8893 		ICMPCONST(MAX_SPECIALS)
8894 		ICMPCONST(MAX_ATCHAIN)
8895 		ICMPCONST(MAX_ATTACKS)
8896 		ICMPCONST(MAX_FOLLOWS)
8897 		ICMPCONST(MAX_PLAYERS)
8898 		ICMPCONST(MAX_ARG_LEN)
8899 		ICMPCONST(FLAG_ESC)
8900 		ICMPCONST(FLAG_START)
8901 		ICMPCONST(FLAG_MOVELEFT)
8902 		ICMPCONST(FLAG_MOVERIGHT)
8903 		ICMPCONST(FLAG_MOVEUP)
8904 		ICMPCONST(FLAG_MOVEDOWN)
8905 		ICMPCONST(FLAG_ATTACK)
8906 		ICMPCONST(FLAG_ATTACK2)
8907 		ICMPCONST(FLAG_ATTACK3)
8908 		ICMPCONST(FLAG_ATTACK4)
8909 		ICMPCONST(FLAG_JUMP)
8910 		ICMPCONST(FLAG_SPECIAL)
8911 		ICMPCONST(FLAG_SCREENSHOT)
8912 		ICMPCONST(FLAG_ANYBUTTON)
8913 		ICMPCONST(FLAG_FORWARD)
8914 		ICMPCONST(FLAG_BACKWARD)
8915 		ICMPCONST(SDID_MOVEUP)
8916 		ICMPCONST(SDID_MOVEDOWN)
8917 		ICMPCONST(SDID_MOVELEFT)
8918 		ICMPCONST(SDID_MOVERIGHT)
8919 		ICMPCONST(SDID_SPECIAL)
8920 		ICMPCONST(SDID_ATTACK)
8921 		ICMPCONST(SDID_ATTACK2)
8922 		ICMPCONST(SDID_ATTACK3)
8923 		ICMPCONST(SDID_ATTACK4)
8924 		ICMPCONST(SDID_JUMP)
8925 		ICMPCONST(SDID_START)
8926 		ICMPCONST(SDID_SCREENSHOT)
8927 		ICMPCONST(TYPE_NONE)
8928 		ICMPCONST(TYPE_PLAYER)
8929 		ICMPCONST(TYPE_ENEMY)
8930 		ICMPCONST(TYPE_ITEM)
8931 		ICMPCONST(TYPE_OBSTACLE)
8932 		ICMPCONST(TYPE_STEAMER)
8933 		ICMPCONST(TYPE_SHOT)
8934 		ICMPCONST(TYPE_TRAP)
8935 		ICMPCONST(TYPE_TEXTBOX)
8936 		ICMPCONST(TYPE_ENDLEVEL)
8937 		ICMPCONST(TYPE_NPC)
8938 		ICMPCONST(TYPE_PANEL)
8939 		ICMPCONST(SUBTYPE_NONE)
8940 		ICMPCONST(SUBTYPE_BIKER)
8941 		ICMPCONST(SUBTYPE_NOTGRAB)
8942 		ICMPCONST(SUBTYPE_ARROW)
8943 		ICMPCONST(SUBTYPE_TOUCH)
8944 		ICMPCONST(SUBTYPE_WEAPON)
8945 		ICMPCONST(SUBTYPE_NOSKIP)
8946 		ICMPCONST(SUBTYPE_FLYDIE)
8947 		ICMPCONST(SUBTYPE_BOTH)
8948 		ICMPCONST(SUBTYPE_PROJECTILE)
8949 		ICMPCONST(SUBTYPE_FOLLOW)
8950 		ICMPCONST(SUBTYPE_CHASE)
8951 		ICMPCONST(AIMOVE1_NORMAL)
8952 		ICMPCONST(AIMOVE1_CHASE)
8953 		ICMPCONST(AIMOVE1_CHASEZ)
8954 		ICMPCONST(AIMOVE1_CHASEX)
8955 		ICMPCONST(AIMOVE1_AVOID)
8956 		ICMPCONST(AIMOVE1_AVOIDZ)
8957 		ICMPCONST(AIMOVE1_AVOIDX)
8958 		ICMPCONST(AIMOVE1_WANDER)
8959 		ICMPCONST(AIMOVE1_NOMOVE)
8960 		ICMPCONST(AIMOVE1_BIKER)
8961 		ICMPCONST(AIMOVE1_STAR)
8962 		ICMPCONST(AIMOVE1_ARROW)
8963 		ICMPCONST(AIMOVE1_BOMB)
8964 		ICMPCONST(AIMOVE2_NORMAL)
8965 		ICMPCONST(AIMOVE2_IGNOREHOLES)
8966 		ICMPCONST(AIATTACK1_NORMAL)
8967 		ICMPCONST(AIATTACK1_LONG)
8968 		ICMPCONST(AIATTACK1_MELEE)
8969 		ICMPCONST(AIATTACK1_NOATTACK)
8970 		ICMPCONST(AIATTACK2_NORMAL)
8971 		ICMPCONST(AIATTACK2_DODGE)
8972 		ICMPCONST(AIATTACK2_DODGEMOVE)
8973 		ICMPCONST(FRONTPANEL_Z)
8974 		ICMPCONST(HOLE_Z)
8975 		ICMPCONST(NEONPANEL_Z)
8976 		ICMPCONST(SHADOW_Z)
8977 		ICMPCONST(SCREENPANEL_Z)
8978 		ICMPCONST(PANEL_Z)
8979 		ICMPCONST(MIRROR_Z)
8980 		ICMPCONST(PIT_DEPTH)
8981 		ICMPCONST(P2_STATS_DIST)
8982 		ICMPCONST(CONTACT_DIST_H)
8983 		ICMPCONST(CONTACT_DIST_V)
8984 		ICMPCONST(GRAB_DIST)
8985 		ICMPCONST(GRAB_STALL)
8986 		ICMPCONST(ATK_NORMAL)
8987 		ICMPCONST(ATK_NORMAL2)
8988 		ICMPCONST(ATK_NORMAL3)
8989 		ICMPCONST(ATK_NORMAL4)
8990 		ICMPCONST(ATK_BLAST)
8991 		ICMPCONST(ATK_BURN)
8992 		ICMPCONST(ATK_FREEZE)
8993 		ICMPCONST(ATK_SHOCK)
8994 		ICMPCONST(ATK_STEAL)
8995 		ICMPCONST(ATK_NORMAL5)
8996 		ICMPCONST(ATK_NORMAL6)
8997 		ICMPCONST(ATK_NORMAL7)
8998 		ICMPCONST(ATK_NORMAL8)
8999 		ICMPCONST(ATK_NORMAL9)
9000 		ICMPCONST(ATK_NORMAL10)
9001 		ICMPCONST(ATK_ITEM)
9002 		ICMPCONST(SCROLL_RIGHT)
9003 		ICMPCONST(SCROLL_DOWN)
9004 		ICMPCONST(SCROLL_LEFT)
9005 		ICMPCONST(SCROLL_UP)
9006 		ICMPCONST(SCROLL_BOTH)
9007 		ICMPCONST(SCROLL_LEFTRIGHT)
9008 		ICMPCONST(SCROLL_RIGHTLEFT)
9009 		ICMPCONST(SCROLL_INWARD)
9010 		ICMPCONST(SCROLL_OUTWARD)
9011 		ICMPCONST(SCROLL_INOUT)
9012 		ICMPCONST(SCROLL_OUTIN)
9013 		ICMPCONST(SCROLL_UPWARD)
9014 		ICMPCONST(SCROLL_DOWNWARD)
9015 		ICMPCONST(ANI_IDLE)
9016 		ICMPCONST(ANI_WALK)
9017 		ICMPCONST(ANI_JUMP)
9018 		ICMPCONST(ANI_LAND)
9019 		ICMPCONST(ANI_PAIN)
9020 		ICMPCONST(ANI_FALL)
9021 		ICMPCONST(ANI_RISE)
9022 		//ICMPCONST(ANI_ATTACK1)// move these below because we have some dynamic animation ids
9023 		//ICMPCONST(ANI_ATTACK2)
9024 		//ICMPCONST(ANI_ATTACK3)
9025 		//ICMPCONST(ANI_ATTACK4)
9026 		ICMPCONST(ANI_UPPER)
9027 		ICMPCONST(ANI_BLOCK)
9028 		ICMPCONST(ANI_JUMPATTACK)
9029 		ICMPCONST(ANI_JUMPATTACK2)
9030 		ICMPCONST(ANI_GET)
9031 		ICMPCONST(ANI_GRAB)
9032 		ICMPCONST(ANI_GRABATTACK)
9033 		ICMPCONST(ANI_GRABATTACK2)
9034 		ICMPCONST(ANI_THROW)
9035 		ICMPCONST(ANI_SPECIAL)
9036 		//ICMPCONST(ANI_FREESPECIAL)// move these below because we have some dynamic animation ids
9037 		ICMPCONST(ANI_SPAWN)
9038 		ICMPCONST(ANI_DIE)
9039 		ICMPCONST(ANI_PICK)
9040 		//ICMPCONST(ANI_FREESPECIAL2)
9041 		ICMPCONST(ANI_JUMPATTACK3)
9042 		//ICMPCONST(ANI_FREESPECIAL3)
9043 		ICMPCONST(ANI_UP)
9044 		ICMPCONST(ANI_DOWN)
9045 		ICMPCONST(ANI_SHOCK)
9046 		ICMPCONST(ANI_BURN)
9047 
9048 		ICMPCONST(ANI_SHOCKPAIN)
9049 		ICMPCONST(ANI_BURNPAIN)
9050 		ICMPCONST(ANI_GRABBED)
9051 		ICMPCONST(ANI_SPECIAL2)
9052 		ICMPCONST(ANI_RUN)
9053 		ICMPCONST(ANI_RUNATTACK)
9054 		ICMPCONST(ANI_RUNJUMPATTACK)
9055 		ICMPCONST(ANI_ATTACKUP)
9056 		ICMPCONST(ANI_ATTACKDOWN)
9057 		ICMPCONST(ANI_ATTACKFORWARD)
9058 		ICMPCONST(ANI_ATTACKBACKWARD)
9059 		//ICMPCONST(ANI_FREESPECIAL4)
9060 		//ICMPCONST(ANI_FREESPECIAL5)
9061 		//ICMPCONST(ANI_FREESPECIAL6)
9062 		//ICMPCONST(ANI_FREESPECIAL7)
9063 		//ICMPCONST(ANI_FREESPECIAL8)
9064 		ICMPCONST(ANI_RISEATTACK)
9065 		ICMPCONST(ANI_DODGE)
9066 		ICMPCONST(ANI_ATTACKBOTH)
9067 		ICMPCONST(ANI_GRABFORWARD)
9068 		ICMPCONST(ANI_GRABFORWARD2)
9069 		ICMPCONST(ANI_JUMPFORWARD)
9070 		ICMPCONST(ANI_GRABDOWN)
9071 		ICMPCONST(ANI_GRABDOWN2)
9072 		ICMPCONST(ANI_GRABUP)
9073 		ICMPCONST(ANI_GRABUP2)
9074 		ICMPCONST(ANI_SELECT)
9075 		ICMPCONST(ANI_DUCK)
9076 		ICMPCONST(ANI_FAINT)
9077 		ICMPCONST(ANI_CANT)
9078 		ICMPCONST(ANI_THROWATTACK)
9079 		ICMPCONST(ANI_CHARGEATTACK)
9080 		ICMPCONST(ANI_VAULT)
9081 		ICMPCONST(ANI_JUMPCANT)
9082 		ICMPCONST(ANI_JUMPSPECIAL)
9083 		ICMPCONST(ANI_BURNDIE)
9084 		ICMPCONST(ANI_SHOCKDIE)
9085 		ICMPCONST(ANI_PAIN2)
9086 		ICMPCONST(ANI_PAIN3)
9087 		ICMPCONST(ANI_PAIN4)
9088 		ICMPCONST(ANI_FALL2)
9089 		ICMPCONST(ANI_FALL3)
9090 		ICMPCONST(ANI_FALL4)
9091 		ICMPCONST(ANI_DIE2)
9092 		ICMPCONST(ANI_DIE3)
9093 		ICMPCONST(ANI_DIE4)
9094 		ICMPCONST(ANI_CHARGE)
9095 		ICMPCONST(ANI_BACKWALK)
9096 		ICMPCONST(ANI_SLEEP)
9097 		//ICMPCONST(ANI_FOLLOW1) // move these below because we have some dynamic animation ids
9098 		//ICMPCONST(ANI_FOLLOW2)
9099 		//ICMPCONST(ANI_FOLLOW3)
9100 		//ICMPCONST(ANI_FOLLOW4)
9101 		ICMPCONST(ANI_PAIN5)
9102 		ICMPCONST(ANI_PAIN6)
9103 		ICMPCONST(ANI_PAIN7)
9104 		ICMPCONST(ANI_PAIN8)
9105 		ICMPCONST(ANI_PAIN9)
9106 		ICMPCONST(ANI_PAIN10)
9107 		ICMPCONST(ANI_FALL5)
9108 		ICMPCONST(ANI_FALL6)
9109 		ICMPCONST(ANI_FALL7)
9110 		ICMPCONST(ANI_FALL8)
9111 		ICMPCONST(ANI_FALL9)
9112 		ICMPCONST(ANI_FALL10)
9113 		ICMPCONST(ANI_DIE5)
9114 		ICMPCONST(ANI_DIE6)
9115 		ICMPCONST(ANI_DIE7)
9116 		ICMPCONST(ANI_DIE8)
9117 		ICMPCONST(ANI_DIE9)
9118 		ICMPCONST(ANI_DIE10)
9119 		ICMPCONST(ANI_TURN)
9120 		ICMPCONST(ANI_RESPAWN)
9121 		ICMPCONST(ANI_FORWARDJUMP)
9122 		ICMPCONST(ANI_RUNJUMP)
9123 		ICMPCONST(ANI_JUMPLAND)
9124 		ICMPCONST(ANI_JUMPDELAY)
9125 		ICMPCONST(ANI_HITWALL)
9126 		ICMPCONST(ANI_GRABBACKWARD)
9127 		ICMPCONST(ANI_GRABBACKWARD2)
9128 		ICMPCONST(ANI_GRABWALK)
9129 		ICMPCONST(ANI_GRABBEDWALK)
9130 		ICMPCONST(ANI_GRABWALKUP)
9131 		ICMPCONST(ANI_GRABBEDWALKUP)
9132 		ICMPCONST(ANI_GRABWALKDOWN)
9133 		ICMPCONST(ANI_GRABBEDWALKDOWN)
9134 		ICMPCONST(ANI_GRABTURN)
9135 		ICMPCONST(ANI_GRABBEDTURN)
9136 		ICMPCONST(ANI_GRABBACKWALK)
9137 		ICMPCONST(ANI_GRABBEDBACKWALK)
9138 
9139 		ICMPCONST(ANI_SLIDE)
9140 		ICMPCONST(ANI_RUNSLIDE)
9141 		ICMPCONST(ANI_BLOCKPAIN)
9142 		ICMPCONST(ANI_DUCKATTACK)
9143 		ICMPCONST(MAX_ANIS)
9144 		ICMPCONST(PLAYER_MIN_Z)
9145 		ICMPCONST(PLAYER_MAX_Z)
9146 		ICMPCONST(BGHEIGHT)
9147 		ICMPCONST(MAX_WALL_HEIGHT)
9148 		ICMPCONST(SAMPLE_GO);
9149 		ICMPCONST(SAMPLE_BEAT);
9150 		ICMPCONST(SAMPLE_BLOCK);
9151 		ICMPCONST(SAMPLE_INDIRECT);
9152 		ICMPCONST(SAMPLE_GET);
9153 		ICMPCONST(SAMPLE_GET2);
9154 		ICMPCONST(SAMPLE_FALL);
9155 		ICMPCONST(SAMPLE_JUMP);
9156 		ICMPCONST(SAMPLE_PUNCH);
9157 		ICMPCONST(SAMPLE_1UP);
9158 		ICMPCONST(SAMPLE_TIMEOVER);
9159 		ICMPCONST(SAMPLE_BEEP);
9160 		ICMPCONST(SAMPLE_BEEP2);
9161 		ICMPCONST(SAMPLE_BIKE);
9162 		ICMPCONST(ANI_RISE2);
9163 		ICMPCONST(ANI_RISE3);
9164 		ICMPCONST(ANI_RISE4);
9165 		ICMPCONST(ANI_RISE5);
9166 		ICMPCONST(ANI_RISE6);
9167 		ICMPCONST(ANI_RISE7);
9168 		ICMPCONST(ANI_RISE8);
9169 		ICMPCONST(ANI_RISE9);
9170 		ICMPCONST(ANI_RISE10);
9171 		ICMPCONST(ANI_RISEB);
9172 		ICMPCONST(ANI_RISES);
9173 		ICMPCONST(ANI_BLOCKPAIN2);
9174 		ICMPCONST(ANI_BLOCKPAIN3);
9175 		ICMPCONST(ANI_BLOCKPAIN4);
9176 		ICMPCONST(ANI_BLOCKPAIN5);
9177 		ICMPCONST(ANI_BLOCKPAIN6);
9178 		ICMPCONST(ANI_BLOCKPAIN7);
9179 		ICMPCONST(ANI_BLOCKPAIN8);
9180 		ICMPCONST(ANI_BLOCKPAIN9);
9181 		ICMPCONST(ANI_BLOCKPAIN10);
9182 		ICMPCONST(ANI_BLOCKPAINB);
9183 		ICMPCONST(ANI_BLOCKPAINS);
9184 		ICMPCONST(ANI_CHIPDEATH);
9185 		ICMPCONST(ANI_GUARDBREAK);
9186 		ICMPCONST(ANI_RISEATTACK2);
9187 		ICMPCONST(ANI_RISEATTACK3);
9188 		ICMPCONST(ANI_RISEATTACK4);
9189 		ICMPCONST(ANI_RISEATTACK5);
9190 		ICMPCONST(ANI_RISEATTACK6);
9191 		ICMPCONST(ANI_RISEATTACK7);
9192 		ICMPCONST(ANI_RISEATTACK8);
9193 		ICMPCONST(ANI_RISEATTACK9);
9194 		ICMPCONST(ANI_RISEATTACK10);
9195 		ICMPCONST(ANI_RISEATTACKB);
9196 		ICMPCONST(ANI_RISEATTACKS);
9197 		ICMPCONST(ANI_SLIDE);
9198 		ICMPCONST(ANI_RUNSLIDE);
9199 		ICMPCONST(ANI_DUCKATTACK);
9200 		ICMPCONST(ANI_WALKOFF);
9201 	}
9202 }
9203 //openborconstant(constname);
9204 //translate a constant by string, used to retrieve a constant or macro of openbor
openbor_transconst(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9205 HRESULT openbor_transconst(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9206 {
9207 	char* constname = NULL;
9208 	int temp;
9209 
9210 	if(paramCount < 1)
9211 	{
9212 		*pretvar = NULL;
9213 		return E_FAIL;
9214 	}
9215 
9216 	mapstrings_transconst(varlist, paramCount);
9217 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9218 
9219 	if(varlist[0]->vt == VT_INTEGER) // return value already determined by mapstrings
9220 	{
9221 		(*pretvar)->lVal = varlist[0]->lVal;
9222 		return S_OK;
9223 	}
9224 	else if(varlist[0]->vt != VT_STR)
9225 	{
9226 		*pretvar = NULL;
9227 		return E_FAIL;
9228 	}
9229 
9230 	// if we get to this point, it's a dynamic animation id
9231 	constname = StrCache_Get(varlist[0]->strVal);
9232 
9233 	// for the extra animation ids
9234 	// for the extra animation ids
9235 	if(strnicmp(constname, "ANI_DOWN", 8)==0 && constname[8] >= '1') // new down walk?
9236 	{
9237 		temp = atoi(constname+8);
9238 		(*pretvar)->lVal = (LONG)(animdowns[temp-1]);
9239 		return S_OK;
9240 	}
9241 	if(strnicmp(constname, "ANI_UP", 8)==0 && constname[8] >= '1') // new up walk?
9242 	{
9243 		temp = atoi(constname+8);
9244 		(*pretvar)->lVal = (LONG)(animups[temp-1]);
9245 		return S_OK;
9246 	}
9247 	if(strnicmp(constname, "ANI_BACKWALK", 8)==0 && constname[8] >= '1') // new backwalk?
9248 	{
9249 		temp = atoi(constname+8);
9250 		(*pretvar)->lVal = (LONG)(animbackwalks[temp-1]);
9251 		return S_OK;
9252 	}
9253 	if(strnicmp(constname, "ANI_WALK", 8)==0 && constname[8] >= '1') // new Walk?
9254 	{
9255 		temp = atoi(constname+8);
9256 		(*pretvar)->lVal = (LONG)(animwalks[temp-1]);
9257 		return S_OK;
9258 	}
9259 	if(strnicmp(constname, "ANI_IDLE", 8)==0 && constname[8] >= '1') // new idle?
9260 	{
9261 		temp = atoi(constname+8);
9262 		(*pretvar)->lVal = (LONG)(animidles[temp-1]);
9263 		return S_OK;
9264 	}
9265 	if(strnicmp(constname, "ANI_FALL", 8)==0 && constname[8] >= '1' && constname[8]<='9') // new fall?
9266 	{
9267 		temp = atoi(constname+8); // so must be greater than 10
9268 		if(temp<MAX_ATKS-STA_ATKS+1) temp = MAX_ATKS-STA_ATKS+1; // just in case
9269 		(*pretvar)->lVal = (LONG)(animfalls[temp+STA_ATKS-1]);
9270 		return S_OK;
9271 	}
9272 	if(strnicmp(constname, "ANI_RISE", 8)==0 && constname[8] >= '1' && constname[8]<='9') // new fall?
9273 	{
9274 		temp = atoi(constname+8);
9275 		if(temp<MAX_ATKS-STA_ATKS+1) temp = MAX_ATKS-STA_ATKS+1; // just in case
9276 		(*pretvar)->lVal = (LONG)(animrises[temp+STA_ATKS-1]);
9277 		return S_OK;
9278 	}
9279 	if(strnicmp(constname, "ANI_RISEATTACK", 14)==0 && constname[14] >= '1' && constname[14]<='9') // new fall?
9280 	{
9281 		temp = atoi(constname+14);
9282 		if(temp<MAX_ATKS-STA_ATKS+1) temp = MAX_ATKS-STA_ATKS+1; // just in case
9283 		(*pretvar)->lVal = (LONG)(animriseattacks[temp+STA_ATKS-1]);
9284 		return S_OK;
9285 	}
9286 	if(strnicmp(constname, "ANI_PAIN", 8)==0 && constname[8] >= '1' && constname[8]<='9') // new fall?
9287 	{
9288 		temp = atoi(constname+8); // so must be greater than 10
9289 		if(temp<MAX_ATKS-STA_ATKS+1) temp = MAX_ATKS-STA_ATKS+1; // just in case
9290 		(*pretvar)->lVal = (LONG)(animpains[temp+STA_ATKS-1]);
9291 		return S_OK;
9292 	}
9293 	if(strnicmp(constname, "ANI_DIE", 7)==0 && constname[7] >= '1' && constname[7]<='9') // new fall?
9294 	{
9295 		temp = atoi(constname+7); // so must be greater than 10
9296 		if(temp<MAX_ATKS-STA_ATKS+1) temp = MAX_ATKS-STA_ATKS+1; // just in case
9297 		(*pretvar)->lVal = (LONG)(animdies[temp+STA_ATKS-1]);
9298 		return S_OK;
9299 	}
9300 	if(strnicmp(constname, "ANI_ATTACK", 10)==0 && constname[10] >= '1' && constname[10]<='9')
9301 	{
9302 		temp = atoi(constname+10);
9303 		(*pretvar)->lVal = (LONG)(animattacks[temp-1]);
9304 		return S_OK;
9305 	}
9306 	if(strnicmp(constname, "ANI_FOLLOW", 10)==0 && constname[10] >= '1' && constname[10]<='9')
9307 	{
9308 		temp = atoi(constname+10);
9309 		(*pretvar)->lVal = (LONG)(animfollows[temp-1]);
9310 		return S_OK;
9311 	}
9312 	if(strnicmp(constname, "ANI_FREESPECIAL", 15)==0 && (!constname[15] ||(constname[15] >= '1' && constname[15]<='9')))
9313 	{
9314 		temp = atoi(constname+15);
9315 		if(temp<1) temp = 1;
9316 		(*pretvar)->lVal = (LONG)(animspecials[temp-1]);
9317 		return S_OK;
9318 	}
9319 	ScriptVariant_Clear(*pretvar);
9320 	return S_OK;
9321 }
9322 
9323 //int rgbcolor(int r, int g, int b);
openbor_rgbcolor(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9324 HRESULT openbor_rgbcolor(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9325 {
9326 	LONG r, g, b;
9327 
9328 	if(paramCount != 3) goto rgbcolor_error;
9329 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &r))) goto rgbcolor_error; // decimal/integer value for red?
9330 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &g))) goto rgbcolor_error; // decimal/integer value for green?
9331 	if(FAILED(ScriptVariant_IntegerValue(varlist[2], &b))) goto rgbcolor_error; // decimal/integer value for blue?
9332 
9333 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9334 	(*pretvar)->lVal = _makecolour(r, g, b);
9335 	return S_OK;
9336 
9337 rgbcolor_error:
9338 	*pretvar = NULL;
9339 	return E_FAIL;
9340 }
9341 
9342 // ===== playerkeys =====
9343 enum playerkeys_enum
9344 {
9345 	_pk_anybutton,
9346 	_pk_attack,
9347 	_pk_attack2,
9348 	_pk_attack3,
9349 	_pk_attack4,
9350 	_pk_esc,
9351 	_pk_jump,
9352 	_pk_movedown,
9353 	_pk_moveleft,
9354 	_pk_moveright,
9355 	_pk_moveup,
9356 	_pk_screenshot,
9357 	_pk_special,
9358 	_pk_start,
9359 	_pk_the_end,
9360 };
9361 
mapstrings_playerkeys(ScriptVariant ** varlist,int paramCount)9362 void mapstrings_playerkeys(ScriptVariant** varlist, int paramCount)
9363 {
9364 	char* propname = NULL;
9365 	int i, prop;
9366 
9367 	static const char* proplist[] = // for args 2+
9368 	{
9369 		"anybutton",
9370 		"attack",
9371 		"attack2",
9372 		"attack3",
9373 		"attack4",
9374 		"esc",
9375 		"jump",
9376 		"movedown",
9377 		"moveleft",
9378 		"moveright",
9379 		"moveup",
9380 		"screenshot",
9381 		"special",
9382 		"start",
9383 	};
9384 
9385 	for(i=2; i<paramCount; i++)
9386 	{
9387 		MAPSTRINGS(varlist[i], proplist, _pk_the_end,
9388 			"Button name '%s' is not supported by playerkeys.");
9389 	}
9390 }
9391 
9392 //playerkeys(playerindex, newkey?, key1, key2, ...);
openbor_playerkeys(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9393 HRESULT openbor_playerkeys(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9394 {
9395 	LONG ltemp;
9396 	int index, newkey;
9397 	int i;
9398 	u32 keys;
9399 	ScriptVariant* arg = NULL;
9400 
9401 	if(paramCount < 3)
9402 	{
9403 		*pretvar = NULL;
9404 		return E_FAIL;
9405 	}
9406 
9407 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9408 	(*pretvar)->lVal = (LONG)1;
9409 
9410 	mapstrings_playerkeys(varlist, paramCount);
9411 
9412 	if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &ltemp)))
9413 	{
9414 		index = 0;
9415 	} else index = (int)ltemp;
9416 
9417 	if(SUCCEEDED(ScriptVariant_IntegerValue((varlist[1]), &ltemp)))
9418 		newkey = (int)ltemp;
9419 	else newkey = 0;
9420 
9421 	if(newkey == 1) keys = player[index].newkeys;
9422 	else if(newkey == 2) keys = player[index].releasekeys;
9423 	else keys = player[index].keys;
9424 
9425 	for(i=2; i<paramCount; i++)
9426 	{
9427 		arg = varlist[i];
9428 		if(arg->vt == VT_INTEGER)
9429 		{
9430 			switch(arg->lVal)
9431 			{
9432 		    case _pk_jump:
9433 				(*pretvar)->lVal = (LONG)(keys & FLAG_JUMP);
9434 				break;
9435 			case _pk_attack:
9436 				(*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK);
9437 				break;
9438 			case _pk_attack2:
9439 				(*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK2);
9440 				break;
9441 			case _pk_attack3:
9442 				(*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK3);
9443 				break;
9444 			case _pk_attack4:
9445 				(*pretvar)->lVal = (LONG)(keys & FLAG_ATTACK4);
9446 				break;
9447 			case _pk_special:
9448 				(*pretvar)->lVal = (LONG)(keys & FLAG_SPECIAL);
9449 				break;
9450 			case _pk_esc:
9451 				(*pretvar)->lVal = (LONG)(keys & FLAG_ESC);
9452 				break;
9453 			case _pk_start:
9454 				(*pretvar)->lVal = (LONG)(keys & FLAG_START);
9455 				break;
9456 			case _pk_moveleft:
9457 				(*pretvar)->lVal = (LONG)(keys & FLAG_MOVELEFT);
9458 				break;
9459 			case _pk_moveright:
9460 				(*pretvar)->lVal = (LONG)(keys & FLAG_MOVERIGHT);
9461 				break;
9462 			case _pk_moveup:
9463 				(*pretvar)->lVal = (LONG)(keys & FLAG_MOVEUP);
9464 				break;
9465 			case _pk_movedown:
9466 				(*pretvar)->lVal = (LONG)(keys & FLAG_MOVEDOWN);
9467 				break;
9468 			case _pk_screenshot:
9469 				(*pretvar)->lVal = (LONG)(keys & FLAG_SCREENSHOT);
9470 				break;
9471 			case _pk_anybutton:
9472 				(*pretvar)->lVal = (LONG)(keys & FLAG_ANYBUTTON);
9473 				break;
9474 			default:
9475 				(*pretvar)->lVal = (LONG)0;
9476 			}
9477 		}
9478 		else (*pretvar)->lVal = (LONG)0;
9479 		if(!((*pretvar)->lVal)) break;
9480 	}
9481 
9482 	return S_OK;
9483 }
9484 
9485 //playmusic(name, loop)
openbor_playmusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9486 HRESULT openbor_playmusic(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9487 {
9488 	int loop = 0;
9489 	LONG offset = 0;
9490 	char* thename = NULL;
9491 
9492 	*pretvar = NULL;
9493 	if(paramCount < 1)
9494 	{
9495 		sound_close_music();
9496 		return S_OK;
9497 	}
9498 	if(varlist[0]->vt != VT_STR)
9499 	{
9500 		//printf("");
9501 		return E_FAIL;
9502 	}
9503 	thename = StrCache_Get(varlist[0]->strVal);
9504 
9505 	if(paramCount > 1)
9506 	{
9507 		loop = (int)ScriptVariant_IsTrue(varlist[1]);
9508 	}
9509 
9510 	if(paramCount > 2)
9511 	{
9512 		if(FAILED(ScriptVariant_IntegerValue(varlist[2], &offset)))
9513 			return E_FAIL;
9514 	}
9515 
9516 
9517 	music(thename, loop, offset);
9518 	return S_OK;
9519 }
9520 
9521 //fademusic(fade, name, loop, offset)
openbor_fademusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9522 HRESULT openbor_fademusic(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9523 {
9524 	DOUBLE value = 0;
9525 	LONG values[2] = {0,0};
9526 	*pretvar = NULL;
9527 	if(paramCount < 1) goto fademusic_error;
9528 	if(FAILED(ScriptVariant_DecimalValue(varlist[0], &value))) goto fademusic_error;
9529 	musicfade[0] = value;
9530 	musicfade[1] = (float)savedata.musicvol;
9531 
9532 	if(paramCount == 4)
9533 	{
9534 		strncpy(musicname, StrCache_Get(varlist[1]->strVal), 128);
9535 		if(FAILED(ScriptVariant_IntegerValue(varlist[2], &values[0]))) goto fademusic_error;
9536 		if(FAILED(ScriptVariant_IntegerValue(varlist[3], &values[1]))) goto fademusic_error;
9537 		musicloop = values[0];
9538 		musicoffset = values[1];
9539 	}
9540 	return S_OK;
9541 
9542 fademusic_error:
9543 	printf("Function requires 1 value, with an optional 3 for music triggering: fademusic_error(float fade, char name, int loop, unsigned long offset)\n");
9544 	return E_FAIL;
9545 }
9546 
9547 //setmusicvolume(left, right)
openbor_setmusicvolume(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9548 HRESULT openbor_setmusicvolume(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9549 {
9550 	LONG channels[2];
9551 
9552 	if(paramCount < 1)
9553 	{
9554 		return S_OK;
9555 	}
9556 
9557 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], channels)))
9558 			goto setmusicvolume_error;
9559 
9560 	if(paramCount > 1)
9561 	{
9562 		if(FAILED(ScriptVariant_IntegerValue(varlist[1], channels+1)))
9563 			goto setmusicvolume_error;
9564 	}
9565 	else
9566 		channels[1] = channels[0];
9567 
9568 	sound_volume_music((int)channels[0], (int)channels[1]);
9569 	return S_OK;
9570 
9571 setmusicvolume_error:
9572 	printf("values must be integers: setmusicvolume(int left, (optional)int right)\n");
9573 	return E_FAIL;
9574 }
9575 
9576 //setmusicvolume(left, right)
openbor_setmusictempo(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9577 HRESULT openbor_setmusictempo(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9578 {
9579 	LONG new_tempo;
9580 
9581 	if(paramCount < 1)
9582 	{
9583 		return S_OK;
9584 	}
9585 
9586 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &new_tempo)))
9587 		return E_FAIL;
9588 
9589 	sound_music_tempo(new_tempo);
9590 	return S_OK;
9591 }
9592 
9593 //pausemusic(value)
openbor_pausemusic(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9594 HRESULT openbor_pausemusic(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9595 {
9596 	int pause = 0;
9597 	if(paramCount < 1)
9598 	{
9599 		return S_OK;
9600 	}
9601 
9602 	pause = (int)ScriptVariant_IsTrue(varlist[0]);
9603 
9604 	sound_pause_music(pause);
9605 	return S_OK;
9606 }
9607 
9608 //playsample(id, priority, lvolume, rvolume, speed, loop)
openbor_playsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9609 HRESULT openbor_playsample(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9610 {
9611 	int i;
9612 	LONG value[6];
9613 
9614 	if(paramCount != 6) goto playsample_error;
9615 
9616 	*pretvar = NULL;
9617 	for(i=0; i<6; i++)
9618 	{
9619 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i)))
9620 			goto playsample_error;
9621 	}
9622 	if((int)value[0] < 0)
9623 	{
9624 		printf("Invalid Id for playsample(id=%d, priority=%d, lvolume=%d, rvolume=%d, speed=%d, loop=%d)\n", (int)value[0], (unsigned int)value[1], (int)value[2], (int)value[3], (unsigned int)value[4], (int)value[5]);
9625 		return E_FAIL;
9626 	}
9627 	if((int)value[5]) sound_loop_sample((int)value[0], (unsigned int)value[1], (int)value[2], (int)value[3], (unsigned int)value[4]);
9628 	else sound_play_sample((int)value[0], (unsigned int)value[1], (int)value[2], (int)value[3], (unsigned int)value[4]);
9629 	return S_OK;
9630 
9631 playsample_error:
9632 
9633 	printf("Function requires 6 integer values: playsample(int id, unsigned int priority, int lvolume, int rvolume, unsigned int speed, int loop)\n");
9634 	return E_FAIL;
9635 }
9636 
9637 // int loadsample(filename, log)
openbor_loadsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9638 HRESULT openbor_loadsample(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9639 {
9640 	int arg = 0;
9641 
9642 	if(paramCount < 1)
9643 	{
9644 		goto loadsample_error;
9645 	}
9646 	if(varlist[0]->vt != VT_STR) goto loadsample_error;
9647 
9648 	if(paramCount > 1)
9649 	{
9650 		if(varlist[1]->vt == VT_INTEGER)
9651 		{
9652 			arg = varlist[1]->lVal;
9653 		}
9654 		else
9655 		{
9656 			goto loadsample_error;
9657 		}
9658 	}
9659 
9660 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9661 	(*pretvar)->lVal = (LONG)sound_load_sample(StrCache_Get(varlist[0]->strVal), packfile, arg);
9662 	return S_OK;
9663 
9664 loadsample_error:
9665 	printf("Function requires 1 string value and optional log value: loadsample(string {filename} integer {log})\n");
9666 	*pretvar = NULL;
9667 	return E_FAIL;
9668 }
9669 
9670 // void unloadsample(id)
openbor_unloadsample(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9671 HRESULT openbor_unloadsample(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9672 {
9673 	LONG id;
9674 	*pretvar = NULL;
9675 	if(paramCount != 1 ) goto unloadsample_error;
9676 
9677 	if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &id)))
9678 		goto unloadsample_error;
9679 
9680 	sound_unload_sample((int)id);
9681 	return S_OK;
9682 
9683 unloadsample_error:
9684 	printf("Function requires 1 integer value: unloadsample(int id)\n");
9685 	return E_FAIL;
9686 }
9687 
9688 //fadeout(type, speed);
openbor_fadeout(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9689 HRESULT openbor_fadeout(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9690 {
9691 	LONG type;
9692 	LONG speed;
9693 	*pretvar = NULL;
9694 	if(paramCount < 1 ) goto fade_out_error;
9695 
9696 	if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &type)))
9697 		goto fade_out_error;
9698 	if(FAILED(ScriptVariant_IntegerValue((varlist[1]), &speed)))
9699 
9700 	fade_out((int)type, (int)speed);
9701 	return S_OK;
9702 
9703 fade_out_error:
9704 	printf("Function requires 2 integer values: fade_out(int type, int speed)\n");
9705 	return E_FAIL;
9706 }
9707 
9708 //changepalette(index);
openbor_changepalette(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9709 HRESULT openbor_changepalette(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9710 {
9711 	LONG index;
9712 
9713 	*pretvar = NULL;
9714 
9715 	if(paramCount < 1) goto changepalette_error;
9716 
9717 	if(FAILED(ScriptVariant_IntegerValue((varlist[0]), &index)))
9718 		goto changepalette_error;
9719 
9720 	change_system_palette((int)index);
9721 
9722 	return S_OK;
9723 
9724 changepalette_error:
9725 	printf("Function requires 1 integer value: changepalette(int index)\n");
9726 	return E_FAIL;
9727 }
9728 
9729 //changelight(x, z);
openbor_changelight(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9730 HRESULT openbor_changelight(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9731 {
9732 	LONG x, z;
9733 	extern int            light[2];
9734 	ScriptVariant* arg = NULL;
9735 
9736 	*pretvar = NULL;
9737 	if(paramCount < 2) goto changelight_error;
9738 
9739 	arg = varlist[0];
9740 	if(arg->vt!=VT_EMPTY)
9741 	{
9742 		if(FAILED(ScriptVariant_IntegerValue(arg, &x)))
9743 			goto changelight_error;
9744 		light[0] = (int)x;
9745 	}
9746 
9747 	arg = varlist[1];
9748 	if(arg->vt!=VT_EMPTY)
9749 	{
9750 		if(FAILED(ScriptVariant_IntegerValue(arg, &z)))
9751 			goto changelight_error;
9752 		light[1] = (int)z;
9753 	}
9754 
9755 	return S_OK;
9756 changelight_error:
9757 	printf("Function requires 2 integer values: changepalette(int x, int z)\n");
9758 	return E_FAIL;
9759 }
9760 
9761 //changeshadowcolor(color, alpha);
9762 // color = 0 means no gfxshadow, -1 means don't fill the shadow with colour
9763 // alpha default to 2, <=0 means no alpha effect
openbor_changeshadowcolor(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9764 HRESULT openbor_changeshadowcolor(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9765 {
9766 	LONG c, a;
9767 	extern int            shadowcolor;
9768 	extern int            shadowalpha;
9769 
9770 	*pretvar = NULL;
9771 	if(paramCount < 1) goto changeshadowcolor_error;
9772 
9773 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &c)))
9774 		goto changeshadowcolor_error;
9775 
9776 	shadowcolor = (int)c;
9777 
9778 	if(paramCount>1)
9779 	{
9780 		if(FAILED(ScriptVariant_IntegerValue(varlist[1], &a)))
9781 			goto changeshadowcolor_error;
9782 		shadowalpha = (int)a;
9783 	}
9784 
9785 	return S_OK;
9786 changeshadowcolor_error:
9787 	printf("Function requires at least 1 integer value, the 2nd integer parameter is optional: changepalette(int colorindex, int alpha)\n");
9788 	return E_FAIL;
9789 }
9790 
9791 // ===== gettextobjproperty(name, value) =====
9792 enum gtop_enum
9793 {
9794 	_gtop_font,
9795 	_gtop_text,
9796 	_gtop_time,
9797 	_gtop_x,
9798 	_gtop_y,
9799 	_gtop_z,
9800 	_gtop_the_end,
9801 };
9802 
mapstrings_gettextobjproperty(ScriptVariant ** varlist,int paramCount)9803 void mapstrings_gettextobjproperty(ScriptVariant** varlist, int paramCount)
9804 {
9805 	char* propname = NULL;
9806 	int prop;
9807 
9808 	static const char* proplist[] = {
9809 		"font",
9810 		"text",
9811 		"time"
9812 		"x",
9813 		"y",
9814 		"z",
9815 	};
9816 
9817 	if(paramCount < 2) return;
9818 
9819 	MAPSTRINGS(varlist[1], proplist, _gtop_the_end,
9820 		"Property name '%s' is not supported by function gettextobjproperty.\n");
9821 }
9822 
openbor_gettextobjproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9823 HRESULT openbor_gettextobjproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9824 {
9825 	LONG ind;
9826 	int propind;
9827 
9828 	if(paramCount < 2)
9829 		goto gettextobjproperty_error;
9830 
9831 
9832 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
9833 	{
9834 		printf("Function's 1st argument must be a numeric value: gettextproperty(int index, \"property\")\n");
9835 		goto gettextobjproperty_error;
9836 	}
9837 
9838 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9839 	mapstrings_gettextobjproperty(varlist, paramCount);
9840 
9841 	if(ind<0 || ind >= LEVEL_MAX_TEXTOBJS)
9842 	{
9843 		(*pretvar)->lVal = 0;
9844 		return S_OK;
9845 	}
9846 
9847 	if(varlist[1]->vt != VT_INTEGER)
9848 	{
9849 		if(varlist[1]->vt != VT_STR)
9850 			printf("Function gettextobjproperty must have a string property name.\n");
9851 		goto gettextobjproperty_error;
9852 	}
9853 
9854 	propind = varlist[1]->lVal;
9855 
9856 	switch(propind)
9857 	{
9858 	case _gtop_font:
9859 	{
9860 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9861 		(*pretvar)->lVal = (LONG)level->textobjs[ind].font;
9862 		break;
9863 	}
9864 	case _gtop_text:
9865 	{
9866 		ScriptVariant_ChangeType(*pretvar, VT_STR);
9867 		strcpy(StrCache_Get((*pretvar)->strVal), level->textobjs[ind].text);
9868 		break;
9869 	}
9870 	case _gtop_time:
9871 	{
9872 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9873 		(*pretvar)->lVal = (LONG)level->textobjs[ind].t;
9874 		break;
9875 	}
9876 	case _gtop_x:
9877 	{
9878 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9879 		(*pretvar)->lVal = (LONG)level->textobjs[ind].x;
9880 		break;
9881 	}
9882 	case _gtop_y:
9883 	{
9884 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9885 		(*pretvar)->lVal = (LONG)level->textobjs[ind].y;
9886 		break;
9887 	}
9888 	case _gtop_z:
9889 	{
9890 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9891 		(*pretvar)->lVal = (LONG)level->textobjs[ind].z;
9892 		break;
9893 	}
9894 	default:
9895 		//printf("Property name '%s' is not supported by function gettextobjproperty.\n", propname);
9896 		goto gettextobjproperty_error;
9897 		break;
9898 	}
9899 
9900 	return S_OK;
9901 
9902 gettextobjproperty_error:
9903 	*pretvar = NULL;
9904 	return E_FAIL;
9905 }
9906 
9907 // ===== changetextobjproperty(name, value) =====
9908 enum ctop_enum
9909 {
9910 	_ctop_font,
9911 	_ctop_text,
9912 	_ctop_time,
9913 	_ctop_x,
9914 	_ctop_y,
9915 	_ctop_z,
9916 	_ctop_the_end,
9917 };
9918 
mapstrings_changetextobjproperty(ScriptVariant ** varlist,int paramCount)9919 void mapstrings_changetextobjproperty(ScriptVariant** varlist, int paramCount)
9920 {
9921 	char* propname = NULL;
9922 	int prop;
9923 
9924 	static const char* proplist[] = {
9925 		"font",
9926 		"text",
9927 		"time",
9928 		"x",
9929 		"y",
9930 		"z",
9931 	};
9932 
9933 	if(paramCount < 2) return;
9934 	MAPSTRINGS(varlist[1], proplist, _ctop_the_end,
9935 		"Property name '%s' is not supported by function changetextobjproperty.\n");
9936 }
9937 
openbor_changetextobjproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)9938 HRESULT openbor_changetextobjproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
9939 {
9940 	LONG ind;
9941 	int propind;
9942 	LONG ltemp;
9943 
9944 	if(paramCount < 3)
9945 		goto changetextobjproperty_error;
9946 
9947 
9948 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
9949 	{
9950 		printf("Function's 1st argument must be a numeric value: changetextobjproperty(int index, \"property\", value)\n");
9951 		goto changetextobjproperty_error;
9952 	}
9953 
9954 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
9955 	mapstrings_changetextobjproperty(varlist, paramCount);
9956 
9957 	if(ind<0 || ind >= LEVEL_MAX_TEXTOBJS)
9958 	{
9959 		(*pretvar)->lVal = 0;
9960 		return S_OK;
9961 	}
9962 
9963 	if(varlist[1]->vt != VT_INTEGER)
9964 	{
9965 		if(varlist[1]->vt != VT_STR)
9966 			printf("Function changetextobjproperty must have a string property name.\n");
9967 		goto changetextobjproperty_error;
9968 	}
9969 
9970 	propind = varlist[1]->lVal;
9971 
9972 	switch(propind)
9973 	{
9974 	case _ctop_font:
9975 	{
9976 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
9977 		{
9978 			(*pretvar)->lVal = (LONG)1;
9979 			level->textobjs[ind].font = (int)ltemp;
9980 		}
9981 		break;
9982 	}
9983 	case _ctop_text:
9984 	{
9985 		if(varlist[2]->vt != VT_STR)
9986 		{
9987 			printf("You must give a string value for textobj text.\n");
9988 			goto changetextobjproperty_error;
9989 		}
9990 		if(!level->textobjs[ind].text)
9991 		{
9992 			level->textobjs[ind].text = (char*)malloc(MAX_STR_VAR_LEN);
9993 		}
9994 		strncpy(level->textobjs[ind].text, (char*)StrCache_Get(varlist[2]->strVal), MAX_STR_VAR_LEN);
9995 		//level->textobjs[ind].text = (char*)StrCache_Get(varlist[2]->strVal);
9996 		(*pretvar)->lVal = (LONG)1;
9997 		break;
9998 	}
9999 	case _ctop_time:
10000 	{
10001 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10002 		{
10003 			(*pretvar)->lVal = (LONG)1;
10004 			level->textobjs[ind].t = (int)ltemp;
10005 		}
10006 		break;
10007 	}
10008 	case _ctop_x:
10009 	{
10010 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10011 		{
10012 			(*pretvar)->lVal = (LONG)1;
10013 			level->textobjs[ind].x = (int)ltemp;
10014 		}
10015 		break;
10016 	}
10017 	case _ctop_y:
10018 	{
10019 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10020 		{
10021 			(*pretvar)->lVal = (LONG)1;
10022 			level->textobjs[ind].y = (int)ltemp;
10023 		}
10024 		break;
10025 	}
10026 	case _ctop_z:
10027 	{
10028 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10029 		{
10030 			(*pretvar)->lVal = (LONG)1;
10031 			level->textobjs[ind].z = (int)ltemp;
10032 		}
10033 		break;
10034 	}
10035 	default:
10036 		//printf("Property name '%s' is not supported by function changetextobjproperty.\n", propname);
10037 		goto changetextobjproperty_error;
10038 		break;
10039 	}
10040 
10041 	return S_OK;
10042 
10043 changetextobjproperty_error:
10044 	*pretvar = NULL;
10045 	return E_FAIL;
10046 }
10047 
10048 // settextobj(int index, int x, int y, int font, int z, char text, int time {optional})
openbor_settextobj(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10049 HRESULT openbor_settextobj(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
10050 {
10051 	LONG ind;
10052 	LONG ltemp;
10053 
10054 	if(paramCount < 6)
10055 		goto settextobj_error;
10056 
10057 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
10058 	{
10059 		printf("Function's 1st argument must be a numeric value: settextobj(int index, int x, int y, int font, int z, char text, int time {optional})\n");
10060 		goto settextobj_error;
10061 	}
10062 
10063 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10064 
10065 	if(ind<0 || ind >= LEVEL_MAX_TEXTOBJS)
10066 	{
10067 		(*pretvar)->lVal = 0;
10068 		return S_OK;
10069 	}
10070 
10071 	if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
10072 	{
10073 		(*pretvar)->lVal = (LONG)1;
10074 		level->textobjs[ind].x = (int)ltemp;
10075 	}
10076 
10077 	if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10078 	{
10079 		(*pretvar)->lVal = (LONG)1;
10080 		level->textobjs[ind].y = (int)ltemp;
10081 	}
10082 
10083 	if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[3], &ltemp)))
10084 	{
10085 		(*pretvar)->lVal = (LONG)1;
10086 		level->textobjs[ind].font = (int)ltemp;
10087 	}
10088 
10089 	if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[4], &ltemp)))
10090 	{
10091 		(*pretvar)->lVal = (LONG)1;
10092 		level->textobjs[ind].z = (int)ltemp;
10093 	}
10094 
10095 	if(varlist[5]->vt != VT_STR)
10096 	{
10097 		printf("You must give a string value for textobj text.\n");
10098 		goto settextobj_error;
10099 	}
10100 
10101 	if(paramCount >= 7)
10102 	{
10103 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[6], &ltemp)))
10104 		{
10105 			(*pretvar)->lVal = (LONG)1;
10106 			level->textobjs[ind].t = (int)ltemp;
10107 		}
10108 	}
10109 
10110 	if(!level->textobjs[ind].text)
10111 	{
10112 		level->textobjs[ind].text = (char*)malloc(MAX_STR_VAR_LEN);
10113 	}
10114 	strncpy(level->textobjs[ind].text, (char*)StrCache_Get(varlist[5]->strVal), MAX_STR_VAR_LEN);
10115 	(*pretvar)->lVal = (LONG)1;
10116 
10117 	return S_OK;
10118 
10119 settextobj_error:
10120 	*pretvar = NULL;
10121 	return E_FAIL;
10122 }
10123 
openbor_cleartextobj(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10124 HRESULT openbor_cleartextobj(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
10125 {
10126 	LONG ind;
10127 
10128 	if(paramCount < 1)
10129 		goto cleartextobj_error;
10130 
10131 
10132 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
10133 	{
10134 		printf("Function's 1st argument must be a numeric value: cleartextobj(int index)\n");
10135 		goto cleartextobj_error;
10136 	}
10137 
10138 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10139 
10140 	if(ind<0 || ind >= LEVEL_MAX_TEXTOBJS)
10141 	{
10142 		(*pretvar)->lVal = 0;
10143 		return S_OK;
10144 	}
10145 
10146 	level->textobjs[ind].t = 0;
10147 	level->textobjs[ind].x = 0;
10148 	level->textobjs[ind].y = 0;
10149 	level->textobjs[ind].font = 0;
10150 	level->textobjs[ind].z = 0;
10151 	if(level->textobjs[ind].text)
10152 		 free(level->textobjs[ind].text);
10153 	level->textobjs[ind].text = NULL;
10154 	return S_OK;
10155 
10156 cleartextobj_error:
10157 	*pretvar = NULL;
10158 	return E_FAIL;
10159 }
10160 
10161 
10162 // ===== getbglayerproperty ======
10163 enum getbglp_enum
10164 {
10165 	_gbglp_alpha,
10166 	_gbglp_amplitude,
10167 	_gbglp_bgspeedratio,
10168 	_gbglp_enabled,
10169 	_gbglp_transparency,
10170 	_gbglp_watermode,
10171 	_gbglp_wavelength,
10172 	_gbglp_wavespeed,
10173 	_gbglp_xoffset,
10174 	_gbglp_xratio,
10175 	_gbglp_xrepeat,
10176 	_gbglp_xspacing,
10177 	_gbglp_zoffset,
10178 	_gbglp_zratio,
10179 	_gbglp_zrepeat,
10180 	_gbglp_zspacing,
10181 	_gbglp_the_end,
10182 };
10183 
mapstrings_getbglayerproperty(ScriptVariant ** varlist,int paramCount)10184 void mapstrings_getbglayerproperty(ScriptVariant** varlist, int paramCount)
10185 {
10186 	char *propname = NULL;
10187 	int prop;
10188 
10189 	static const char* proplist[] = {
10190 		"alpha",
10191 		"amplitude",
10192 		"bgspeedratio",
10193 		"enabled",
10194 		"transparency",
10195 		"watermode",
10196 		"wavelength",
10197 		"wavespeed",
10198 		"xoffset",
10199 		"xratio",
10200 		"xrepeat",
10201 		"xspacing",
10202 		"zoffset",
10203 		"zratio",
10204 		"zrepeat",
10205 		"zspacing",
10206 	};
10207 
10208 	if(paramCount < 2) return;
10209 	MAPSTRINGS(varlist[1], proplist, _gbglp_the_end,
10210 		"Property name '%s' is not supported by function getbglayerproperty.\n");
10211 }
10212 
openbor_getbglayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10213 HRESULT openbor_getbglayerproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
10214 {
10215 	LONG ind;
10216 	int propind;
10217 
10218 	if(paramCount < 2)
10219 		goto getbglayerproperty_error;
10220 
10221 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
10222 	{
10223 		printf("Function's 1st argument must be a numeric value: getbglayerproperty(int index, \"property\", value)\n");
10224 		goto getbglayerproperty_error;
10225 	}
10226 
10227 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10228 	mapstrings_getbglayerproperty(varlist, paramCount);
10229 
10230 	if(ind<0 || ind >= level->numbglayers)
10231 	{
10232 		(*pretvar)->lVal = 0;
10233 		return S_OK;
10234 	}
10235 
10236 	if(varlist[1]->vt != VT_INTEGER)
10237 	{
10238 		printf("Function getbglayerproperty must have a string property name.\n");
10239 		goto getbglayerproperty_error;
10240 	}
10241 
10242 	propind = varlist[1]->lVal;
10243 
10244 	switch(propind)
10245 	{
10246 	case _gbglp_alpha:
10247 	{
10248 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10249 		(*pretvar)->lVal = (LONG)level->bglayers[ind].drawmethod.alpha;
10250 		break;
10251 	}
10252 	case _gbglp_amplitude:
10253 	{
10254 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10255 		(*pretvar)->lVal = (LONG)level->bglayers[ind].drawmethod.water.amplitude;
10256 		break;
10257 	}
10258 	case _gbglp_bgspeedratio:
10259 	{
10260 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10261 		(*pretvar)->dblVal = (DOUBLE)level->bglayers[ind].bgspeedratio;
10262 		break;
10263 	}
10264 	case _gbglp_enabled:
10265 	{
10266 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10267 		(*pretvar)->lVal = (LONG)level->bglayers[ind].enabled;
10268 		break;
10269 	}
10270 	case _gbglp_transparency:
10271 	{
10272 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10273 		(*pretvar)->lVal = (LONG)level->bglayers[ind].drawmethod.transbg;
10274 		break;
10275 	}
10276 	case _gbglp_watermode:
10277 	{
10278 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10279 		(*pretvar)->lVal = (LONG)level->bglayers[ind].drawmethod.water.watermode;
10280 		break;
10281 	}
10282 
10283 	case _gbglp_wavelength:
10284 	{
10285 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10286 		(*pretvar)->lVal = (LONG)level->bglayers[ind].drawmethod.water.wavelength;
10287 		break;
10288 	}
10289 	case _gbglp_wavespeed:
10290 	{
10291 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10292 		(*pretvar)->dblVal = (DOUBLE)level->bglayers[ind].drawmethod.water.wavespeed;
10293 		break;
10294 	}
10295 	case _gbglp_xoffset:
10296 	{
10297 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10298 		(*pretvar)->lVal = (LONG)level->bglayers[ind].xoffset;
10299 		break;
10300 	}
10301 	case _gbglp_xratio:
10302 	{
10303 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10304 		(*pretvar)->dblVal = (DOUBLE)level->bglayers[ind].xratio;
10305 		break;
10306 	}
10307 	case _gbglp_xrepeat:
10308 	{
10309 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10310 		(*pretvar)->lVal = (LONG)level->bglayers[ind].xrepeat;
10311 		break;
10312 	}
10313 	case _gbglp_xspacing:
10314 	{
10315 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10316 		(*pretvar)->lVal = (LONG)level->bglayers[ind].xspacing;
10317 		break;
10318 	}
10319 	case _gbglp_zoffset:
10320 	{
10321 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10322 		(*pretvar)->lVal = (LONG)level->bglayers[ind].zoffset;
10323 		break;
10324 	}
10325 	case _gbglp_zratio:
10326 	{
10327 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10328 		(*pretvar)->dblVal = (DOUBLE)level->bglayers[ind].zratio;
10329 		break;
10330 	}
10331 	case _gbglp_zrepeat:
10332 	{
10333 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10334 		(*pretvar)->lVal = (LONG)level->bglayers[ind].zrepeat;
10335 		break;
10336 	}
10337 	case _gbglp_zspacing:
10338 	{
10339 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10340 		(*pretvar)->lVal = (LONG)level->bglayers[ind].zspacing;
10341 		break;
10342 	}
10343 	default:
10344 		//printf("Property name '%s' is not supported by function getbglayerproperty.\n", propname);
10345 		goto getbglayerproperty_error;
10346 		break;
10347 	}
10348 
10349 	return S_OK;
10350 
10351 getbglayerproperty_error:
10352 	*pretvar = NULL;
10353 	return E_FAIL;
10354 }
10355 
10356 // ===== changebglayerproperty =====
10357 enum cbglp_enum
10358 {
10359 	_cbglp_alpha,
10360 	_cbglp_amplitude,
10361 	_cbglp_bgspeedratio,
10362 	_cbglp_enabled,
10363 	_cbglp_transparency,
10364 	_cbglp_watermode,
10365 	_cbglp_wavelength,
10366 	_cbglp_wavespeed,
10367 	_cbglp_xoffset,
10368 	_cbglp_xratio,
10369 	_cbglp_xrepeat,
10370 	_cbglp_xspacing,
10371 	_cbglp_zoffset,
10372 	_cbglp_zratio,
10373 	_cbglp_zrepeat,
10374 	_cbglp_zspacing,
10375 	_cbglp_the_end,
10376 };
10377 
mapstrings_changebglayerproperty(ScriptVariant ** varlist,int paramCount)10378 void mapstrings_changebglayerproperty(ScriptVariant** varlist, int paramCount)
10379 {
10380 	char *propname = NULL;
10381 	int prop;
10382 
10383 	static const char* proplist[] = {
10384 		"alpha",
10385 		"amplitude",
10386 		"bgspeedratio",
10387 		"enabled",
10388 		"transparency",
10389 		"watermode",
10390 		"wavelength",
10391 		"wavespeed",
10392 		"xoffset",
10393 		"xratio",
10394 		"xrepeat",
10395 		"xspacing",
10396 		"zoffset",
10397 		"zratio",
10398 		"zrepeat",
10399 		"zspacing",
10400 	};
10401 
10402 	if(paramCount < 2) return;
10403 	MAPSTRINGS(varlist[1], proplist, _cbglp_the_end,
10404 		"Property name '%s' is not supported by function changebglayerproperty.\n");
10405 }
10406 
openbor_changebglayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10407 HRESULT openbor_changebglayerproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
10408 {
10409 	LONG ind;
10410 	int propind;
10411 	LONG ltemp;
10412 	DOUBLE dbltemp;
10413 
10414 	if(paramCount < 3)
10415 		goto changebglayerproperty_error;
10416 
10417 
10418 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
10419 	{
10420 		printf("Function's 1st argument must be a numeric value: changebglayerproperty(int index, \"property\", value)\n");
10421 		goto changebglayerproperty_error;
10422 	}
10423 
10424 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10425 	mapstrings_changebglayerproperty(varlist, paramCount);
10426 
10427 	if(ind<0 || ind >= level->numbglayers)
10428 	{
10429 		(*pretvar)->lVal = 0;
10430 		return S_OK;
10431 	}
10432 
10433 	if(varlist[1]->vt != VT_INTEGER)
10434 	{
10435 		printf("Function changebglayerproperty must have a string property name.\n");
10436 		goto changebglayerproperty_error;
10437 	}
10438 
10439 	propind = varlist[1]->lVal;
10440 
10441 	switch(propind)
10442 	{
10443 	case _cbglp_alpha:
10444 	{
10445 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10446 		{
10447 			(*pretvar)->lVal = (LONG)1;
10448 			level->bglayers[ind].drawmethod.alpha = (int)ltemp;
10449 		}
10450 		break;
10451 	}
10452 	case _cbglp_amplitude:
10453 	{
10454 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10455 		{
10456 			(*pretvar)->lVal = (LONG)1;
10457 			level->bglayers[ind].drawmethod.water.amplitude = (int)ltemp;
10458 		}
10459 		break;
10460 	}
10461 	case _cbglp_bgspeedratio:
10462 	{
10463 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10464 		{
10465 			(*pretvar)->lVal = (LONG)1;
10466 			level->bglayers[ind].bgspeedratio = (float)dbltemp;
10467 		}
10468 		break;
10469 	}
10470 	case _cbglp_enabled:
10471 	{
10472 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10473 		{
10474 			(*pretvar)->lVal = (LONG)1;
10475 			level->bglayers[ind].enabled = (int)ltemp;
10476 		}
10477 		break;
10478 	}
10479 	case _cbglp_transparency:
10480 	{
10481 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10482 		{
10483 			(*pretvar)->lVal = (LONG)1;
10484 			level->bglayers[ind].drawmethod.transbg = (int)ltemp;
10485 		}
10486 		break;
10487 	}
10488 	case _cbglp_watermode:
10489 	{
10490 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10491 		{
10492 			(*pretvar)->lVal = (LONG)1;
10493 			level->bglayers[ind].drawmethod.water.watermode = (int)ltemp;
10494 		}
10495 		break;
10496 	}
10497 
10498 	case _cbglp_wavelength:
10499 	{
10500 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10501 		{
10502 			(*pretvar)->lVal = (LONG)1;
10503 			level->bglayers[ind].drawmethod.water.wavelength = (int)ltemp;
10504 		}
10505 		break;
10506 	}
10507 	case _cbglp_wavespeed:
10508 	{
10509 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10510 		{
10511 			(*pretvar)->lVal = (LONG)1;
10512 			level->bglayers[ind].drawmethod.water.wavespeed = (float)dbltemp;
10513 		}
10514 		break;
10515 	}
10516 	case _cbglp_xoffset:
10517 	{
10518 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10519 		{
10520 			(*pretvar)->lVal = (LONG)1;
10521 			level->bglayers[ind].xoffset = (int)ltemp;
10522 		}
10523 		break;
10524 	}
10525 	case _cbglp_xratio:
10526 	{
10527 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10528 		{
10529 			(*pretvar)->lVal = (LONG)1;
10530 			level->bglayers[ind].xratio = (float)dbltemp;
10531 		}
10532 		break;
10533 	}
10534 	case _cbglp_xrepeat:
10535 	{
10536 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10537 		{
10538 			(*pretvar)->lVal = (LONG)1;
10539 			level->bglayers[ind].xrepeat = (int)ltemp;
10540 		}
10541 		break;
10542 	}
10543 	case _cbglp_xspacing:
10544 	{
10545 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10546 		{
10547 			(*pretvar)->lVal = (LONG)1;
10548 			level->bglayers[ind].xspacing = (int)ltemp;
10549 		}
10550 		break;
10551 	}
10552 	case _cbglp_zoffset:
10553 	{
10554 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10555 		{
10556 			(*pretvar)->lVal = (LONG)1;
10557 			level->bglayers[ind].zoffset = (int)ltemp;
10558 		}
10559 		break;
10560 	}
10561 	case _cbglp_zratio:
10562 	{
10563 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10564 		{
10565 			(*pretvar)->lVal = (LONG)1;
10566 			level->bglayers[ind].zratio = (float)dbltemp;
10567 		}
10568 		break;
10569 	}
10570 	case _cbglp_zrepeat:
10571 	{
10572 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10573 		{
10574 			(*pretvar)->lVal = (LONG)1;
10575 			level->bglayers[ind].zrepeat = (int)ltemp;
10576 		}
10577 		break;
10578 	}
10579 	case _cbglp_zspacing:
10580 	{
10581 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10582 		{
10583 			(*pretvar)->lVal = (LONG)1;
10584 			level->bglayers[ind].zspacing = (int)ltemp;
10585 		}
10586 		break;
10587 	}
10588 	default:
10589 		//printf("Property name '%s' is not supported by function changebglayerproperty.\n", propname);
10590 		goto changebglayerproperty_error;
10591 		break;
10592 	}
10593 
10594 	return S_OK;
10595 
10596 changebglayerproperty_error:
10597 	*pretvar = NULL;
10598 	return E_FAIL;
10599 }
10600 
10601 // ===== getfglayerproperty =====
10602 enum gfglp_enum
10603 {
10604 	_gfglp_alpha,
10605 	_gfglp_amplitude,
10606 	_gfglp_bgspeedratio,
10607 	_gfglp_enabled,
10608 	_gfglp_transparency,
10609 	_gfglp_watermode,
10610 	_gfglp_wavelength,
10611 	_gfglp_wavespeed,
10612 	_gfglp_xoffset,
10613 	_gfglp_xratio,
10614 	_gfglp_xrepeat,
10615 	_gfglp_xspacing,
10616 	_gfglp_zoffset,
10617 	_gfglp_zratio,
10618 	_gfglp_zrepeat,
10619 	_gfglp_zspacing,
10620 	_gfglp_the_end,
10621 };
10622 
mapstrings_getfglayerproperty(ScriptVariant ** varlist,int paramCount)10623 void mapstrings_getfglayerproperty(ScriptVariant** varlist, int paramCount)
10624 {
10625 	char *propname = NULL;
10626 	int prop;
10627 
10628 	static const char* proplist[] = {
10629 		"alpha",
10630 		"amplitude",
10631 		"bgspeedratio",
10632 		"enabled",
10633 		"transparency",
10634 		"watermode",
10635 		"wavelength",
10636 		"wavespeed",
10637 		"xoffset",
10638 		"xratio",
10639 		"xrepeat",
10640 		"xspacing",
10641 		"zoffset",
10642 		"zratio",
10643 		"zrepeat",
10644 		"zspacing",
10645 	};
10646 
10647 	if(paramCount < 2) return;
10648 	MAPSTRINGS(varlist[1], proplist, _gfglp_the_end,
10649 		"Property name '%s' is not supported by function getfglayerproperty.\n");
10650 }
10651 
openbor_getfglayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10652 HRESULT openbor_getfglayerproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
10653 {
10654 	LONG ind;
10655 	int propind;
10656 
10657 	if(paramCount < 2)
10658 		goto getfglayerproperty_error;
10659 
10660 
10661 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
10662 	{
10663 		printf("Function's 1st argument must be a numeric value: getfglayerproperty(int index, \"property\", value)\n");
10664 		goto getfglayerproperty_error;
10665 	}
10666 
10667 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10668 	mapstrings_getfglayerproperty(varlist, paramCount);
10669 
10670 	if(ind<0 || ind >= level->numfglayers)
10671 	{
10672 		(*pretvar)->lVal = 0;
10673 		return S_OK;
10674 	}
10675 
10676 	if(varlist[1]->vt != VT_INTEGER)
10677 	{
10678 		printf("Function getfglayerproperty must have a string property name.\n");
10679 		goto getfglayerproperty_error;
10680 	}
10681 
10682 	propind = varlist[1]->lVal;
10683 
10684 	switch(propind)
10685 	{
10686 	case _gfglp_alpha:
10687 	{
10688 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10689 		(*pretvar)->lVal = (LONG)level->fglayers[ind].drawmethod.alpha;
10690 		break;
10691 	}
10692 	case _gfglp_amplitude:
10693 	{
10694 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10695 		(*pretvar)->lVal = (LONG)level->fglayers[ind].drawmethod.water.amplitude;
10696 		break;
10697 	}
10698 	case _gfglp_bgspeedratio:
10699 	{
10700 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10701 		(*pretvar)->dblVal = (DOUBLE)level->fglayers[ind].bgspeedratio;
10702 		break;
10703 	}
10704 	case _gfglp_enabled:
10705 	{
10706 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10707 		(*pretvar)->lVal = (LONG)level->fglayers[ind].enabled;
10708 		break;
10709 	}
10710 	case _gfglp_transparency:
10711 	{
10712 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10713 		(*pretvar)->lVal = (LONG)level->fglayers[ind].drawmethod.transbg;
10714 		break;
10715 	}
10716 	case _gfglp_watermode:
10717 	{
10718 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10719 		(*pretvar)->lVal = (LONG)level->fglayers[ind].drawmethod.water.watermode;
10720 		break;
10721 	}
10722 
10723 	case _gfglp_wavelength:
10724 	{
10725 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10726 		(*pretvar)->lVal = (LONG)level->fglayers[ind].drawmethod.water.wavelength;
10727 		break;
10728 	}
10729 	case _gfglp_wavespeed:
10730 	{
10731 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10732 		(*pretvar)->dblVal = (DOUBLE)level->fglayers[ind].drawmethod.water.wavespeed;
10733 		break;
10734 	}
10735 	case _gfglp_xoffset:
10736 	{
10737 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10738 		(*pretvar)->lVal = (LONG)level->fglayers[ind].xoffset;
10739 		break;
10740 	}
10741 	case _gfglp_xratio:
10742 	{
10743 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10744 		(*pretvar)->dblVal = (DOUBLE)level->fglayers[ind].xratio;
10745 		break;
10746 	}
10747 	case _gfglp_xrepeat:
10748 	{
10749 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10750 		(*pretvar)->lVal = (LONG)level->fglayers[ind].xrepeat;
10751 		break;
10752 	}
10753 	case _gfglp_xspacing:
10754 	{
10755 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10756 		(*pretvar)->lVal = (LONG)level->fglayers[ind].xspacing;
10757 		break;
10758 	}
10759 	case _gfglp_zoffset:
10760 	{
10761 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10762 		(*pretvar)->lVal = (LONG)level->fglayers[ind].zoffset;
10763 		break;
10764 	}
10765 	case _gfglp_zratio:
10766 	{
10767 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
10768 		(*pretvar)->dblVal = (DOUBLE)level->fglayers[ind].zratio;
10769 		break;
10770 	}
10771 	case _gfglp_zrepeat:
10772 	{
10773 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10774 		(*pretvar)->lVal = (LONG)level->fglayers[ind].zrepeat;
10775 		break;
10776 	}
10777 	case _gfglp_zspacing:
10778 	{
10779 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10780 		(*pretvar)->lVal = (LONG)level->fglayers[ind].zspacing;
10781 		break;
10782 	}
10783 	default:
10784 		//printf("Property name '%s' is not supported by function getfglayerproperty.\n", propname);
10785 		goto getfglayerproperty_error;
10786 		break;
10787 	}
10788 
10789 	return S_OK;
10790 
10791 getfglayerproperty_error:
10792 	*pretvar = NULL;
10793 	return E_FAIL;
10794 }
10795 
10796 // ===== changefglayerproperty =====
10797 typedef enum
10798 {
10799 	_cfglp_alpha,
10800 	_cfglp_amplitude,
10801 	_cfglp_bgspeedratio,
10802 	_cfglp_enabled,
10803 	_cfglp_transparency,
10804 	_cfglp_watermode,
10805 	_cfglp_wavelength,
10806 	_cfglp_wavespeed,
10807 	_cfglp_xoffset,
10808 	_cfglp_xratio,
10809 	_cfglp_xrepeat,
10810 	_cfglp_xspacing,
10811 	_cfglp_zoffset,
10812 	_cfglp_zratio,
10813 	_cfglp_zrepeat,
10814 	_cfglp_zspacing,
10815 	_cfglp_the_end,
10816 } prop_enum;
10817 
mapstrings_changefglayerproperty(ScriptVariant ** varlist,int paramCount)10818 void mapstrings_changefglayerproperty(ScriptVariant** varlist, int paramCount)
10819 {
10820 	char *propname = NULL;
10821 	int prop;
10822 
10823 	static const char* proplist[] = {
10824 		"alpha",
10825 		"amplitude",
10826 		"bgspeedratio",
10827 		"enabled",
10828 		"transparency",
10829 		"watermode",
10830 		"wavelength",
10831 		"wavespeed",
10832 		"xoffset",
10833 		"xratio",
10834 		"xrepeat",
10835 		"xspacing",
10836 		"zoffset",
10837 		"zratio",
10838 		"zrepeat",
10839 		"zspacing",
10840 	};
10841 
10842 	if(paramCount < 2) return;
10843 	MAPSTRINGS(varlist[1], proplist, _cfglp_the_end,
10844 		"Property name '%s' is not supported by function changefglayerproperty.\n");
10845 }
10846 
openbor_changefglayerproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)10847 HRESULT openbor_changefglayerproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
10848 {
10849 	LONG ind;
10850 	int propind;
10851 	LONG ltemp;
10852 	DOUBLE dbltemp;
10853 
10854 	if(paramCount < 3)
10855 		goto changefglayerproperty_error;
10856 
10857 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind)))
10858 	{
10859 		printf("Function's 1st argument must be a numeric value: changefglayerproperty(int index, \"property\", value)\n");
10860 		goto changefglayerproperty_error;
10861 	}
10862 
10863 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
10864 	mapstrings_changefglayerproperty(varlist, paramCount);
10865 
10866 	if(ind<0 || ind >= level->numfglayers)
10867 	{
10868 		(*pretvar)->lVal = 0;
10869 		return S_OK;
10870 	}
10871 
10872 	if(varlist[1]->vt != VT_INTEGER)
10873 	{
10874 		printf("Function changefglayerproperty must have a string property name.\n");
10875 		goto changefglayerproperty_error;
10876 	}
10877 
10878 	propind = varlist[1]->lVal;
10879 
10880 	switch(propind)
10881 	{
10882 	case _cfglp_alpha:
10883 	{
10884 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10885 		{
10886 			(*pretvar)->lVal = (LONG)1;
10887 			level->fglayers[ind].drawmethod.alpha = (int)ltemp;
10888 		}
10889 		break;
10890 	}
10891 	case _cfglp_amplitude:
10892 	{
10893 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10894 		{
10895 			(*pretvar)->lVal = (LONG)1;
10896 			level->fglayers[ind].drawmethod.water.amplitude = (int)ltemp;
10897 		}
10898 		break;
10899 	}
10900 	case _cfglp_bgspeedratio:
10901 	{
10902 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10903 		{
10904 			(*pretvar)->lVal = (LONG)1;
10905 			level->fglayers[ind].bgspeedratio = (float)dbltemp;
10906 		}
10907 		break;
10908 	}
10909 	case _cfglp_enabled:
10910 	{
10911 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10912 		{
10913 			(*pretvar)->lVal = (LONG)1;
10914 			level->fglayers[ind].enabled = (int)ltemp;
10915 		}
10916 		break;
10917 	}
10918 	case _cfglp_transparency:
10919 	{
10920 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10921 		{
10922 			(*pretvar)->lVal = (LONG)1;
10923 			level->fglayers[ind].drawmethod.transbg = (int)ltemp;
10924 		}
10925 		break;
10926 	}
10927 	case _cfglp_watermode:
10928 	{
10929 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10930 		{
10931 			(*pretvar)->lVal = (LONG)1;
10932 			level->fglayers[ind].drawmethod.water.watermode = (int)ltemp;
10933 		}
10934 		break;
10935 	}
10936 
10937 	case _cfglp_wavelength:
10938 	{
10939 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10940 		{
10941 			(*pretvar)->lVal = (LONG)1;
10942 			level->fglayers[ind].drawmethod.water.wavelength = (int)ltemp;
10943 		}
10944 		break;
10945 	}
10946 	case _cfglp_wavespeed:
10947 	{
10948 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10949 		{
10950 			(*pretvar)->lVal = (LONG)1;
10951 			level->fglayers[ind].drawmethod.water.wavespeed = (float)dbltemp;
10952 		}
10953 		break;
10954 	}
10955 	case _cfglp_xoffset:
10956 	{
10957 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10958 		{
10959 			(*pretvar)->lVal = (LONG)1;
10960 			level->fglayers[ind].xoffset = (int)ltemp;
10961 		}
10962 		break;
10963 	}
10964 	case _cfglp_xratio:
10965 	{
10966 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
10967 		{
10968 			(*pretvar)->lVal = (LONG)1;
10969 			level->fglayers[ind].xratio = (float)dbltemp;
10970 		}
10971 		break;
10972 	}
10973 	case _cfglp_xrepeat:
10974 	{
10975 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10976 		{
10977 			(*pretvar)->lVal = (LONG)1;
10978 			level->fglayers[ind].xrepeat = (int)ltemp;
10979 		}
10980 		break;
10981 	}
10982 	case _cfglp_xspacing:
10983 	{
10984 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10985 		{
10986 			(*pretvar)->lVal = (LONG)1;
10987 			level->fglayers[ind].xspacing = (int)ltemp;
10988 		}
10989 		break;
10990 	}
10991 	case _cfglp_zoffset:
10992 	{
10993 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
10994 		{
10995 			(*pretvar)->lVal = (LONG)1;
10996 			level->fglayers[ind].zoffset = (int)ltemp;
10997 		}
10998 		break;
10999 	}
11000 	case _cfglp_zratio:
11001 	{
11002 		if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp)))
11003 		{
11004 			(*pretvar)->lVal = (LONG)1;
11005 			level->fglayers[ind].zratio = (float)dbltemp;
11006 		}
11007 		break;
11008 	}
11009 	case _cfglp_zrepeat:
11010 	{
11011 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
11012 		{
11013 			(*pretvar)->lVal = (LONG)1;
11014 			level->fglayers[ind].zrepeat = (int)ltemp;
11015 		}
11016 		break;
11017 	}
11018 	case _cfglp_zspacing:
11019 	{
11020 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], &ltemp)))
11021 		{
11022 			(*pretvar)->lVal = (LONG)1;
11023 			level->fglayers[ind].zspacing = (int)ltemp;
11024 		}
11025 		break;
11026 	}
11027 	default:
11028 		//printf("Property name '%s' is not supported by function changefglayerproperty.\n", propname);
11029 		goto changefglayerproperty_error;
11030 		break;
11031 	}
11032 
11033 	return S_OK;
11034 
11035 changefglayerproperty_error:
11036 	*pretvar = NULL;
11037 	return E_FAIL;
11038 }
11039 
openbor_getlevelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11040 HRESULT openbor_getlevelproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11041 {
11042 	char* propname = NULL;
11043 	int propind;
11044 
11045 	static const char* proplist[] = {
11046 		"bgspeed",
11047 		"cameraxoffset",
11048 		"camerazoffset",
11049 		"scrollspeed",
11050 	};
11051 
11052 	typedef enum
11053 	{
11054 		_lp_bgspeed,
11055 		_lp_cameraxoffset,
11056 		_lp_camerazoffset,
11057 		_lp_scrollspeed,
11058 		_lp_the_end, // lol
11059 	} prop_enum;
11060 
11061 
11062 
11063 	if(varlist[0]->vt != VT_STR)
11064 	{
11065 		printf("Function getlevelproperty must have a string property name.\n");
11066 		goto getlevelproperty_error;
11067 	}
11068 
11069 
11070 	propname = (char*)StrCache_Get(varlist[0]->strVal);//see what property it is
11071 
11072 	propind = searchList(proplist, propname, _lp_the_end);
11073 
11074 	switch(propind)
11075 	{
11076 	case _lp_bgspeed:
11077 	{
11078 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11079 		(*pretvar)->lVal = (LONG)level->bgspeed;
11080 		break;
11081 	}
11082 	case _lp_cameraxoffset:
11083 	{
11084 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11085 		(*pretvar)->lVal = (LONG)level->cameraxoffset;
11086 		break;
11087 	}
11088 	case _lp_camerazoffset:
11089 	{
11090 		ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11091 		(*pretvar)->lVal = (LONG)level->camerazoffset;
11092 		break;
11093 	}
11094 	case _lp_scrollspeed:
11095 	{
11096 		ScriptVariant_ChangeType(*pretvar, VT_DECIMAL);
11097 		(*pretvar)->dblVal = (DOUBLE)level->scrollspeed;
11098 		break;
11099 	}
11100 	default:
11101 		printf("Property name '%s' is not supported by function getlevelproperty.\n", propname);
11102 		goto getlevelproperty_error;
11103 		break;
11104 	}
11105 
11106 	return S_OK;
11107 
11108 getlevelproperty_error:
11109 	*pretvar = NULL;
11110 	return E_FAIL;
11111 }
11112 
11113 //changelevelproperty(name, value)
openbor_changelevelproperty(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11114 HRESULT openbor_changelevelproperty(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11115 {
11116 	char* propname = NULL;
11117 	LONG ltemp;
11118 	ScriptVariant* arg = NULL;
11119 
11120 	if(paramCount < 2)
11121 	{
11122 		*pretvar = NULL;
11123 		return E_FAIL;
11124 	}
11125 
11126 	if(varlist[0]->vt != VT_STR)
11127 	{
11128 		*pretvar = NULL;
11129 		return E_FAIL;
11130 	}
11131 
11132 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11133 	(*pretvar)->lVal = (LONG)1;
11134 
11135 	propname = (char*)StrCache_Get(varlist[0]->strVal);
11136 
11137 	arg = varlist[1];
11138 
11139 	if(strcmp(propname, "rock")==0)
11140 	{
11141 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
11142 			level->rocking = (int)ltemp;
11143 		else (*pretvar)->lVal = (LONG)0;
11144 	}
11145 	else if(strcmp(propname, "bgspeed")==0)
11146 	{
11147 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
11148 			level->bgspeed = (float)ltemp;
11149 		else (*pretvar)->lVal = (LONG)0;
11150 	}
11151 	else if(strcmp(propname, "scrollspeed")==0)
11152 	{
11153 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
11154 			level->scrollspeed = (float)ltemp;
11155 		else (*pretvar)->lVal = (LONG)0;
11156 	}
11157 	else if(strcmp(propname, "cameraxoffset")==0)
11158 	{
11159 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
11160 			level->cameraxoffset = (int)ltemp;
11161 		else (*pretvar)->lVal = (LONG)0;
11162 	}
11163 	else if(strcmp(propname, "camerazoffset")==0)
11164 	{
11165 		if(SUCCEEDED(ScriptVariant_IntegerValue(arg, &ltemp)))
11166 			level->camerazoffset = (int)ltemp;
11167 		else (*pretvar)->lVal = (LONG)0;
11168 	}
11169 
11170 	return S_OK;
11171 }
11172 
11173 //jumptobranch(name, immediate)
openbor_jumptobranch(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11174 HRESULT openbor_jumptobranch(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11175 {
11176 	LONG ltemp;
11177 	extern char branch_name[MAX_NAME_LEN+1];
11178 	extern int  endgame;
11179 
11180 	*pretvar = NULL;
11181 	if(paramCount < 1) goto jumptobranch_error;
11182 	if(varlist[0]->vt != VT_STR) goto jumptobranch_error;
11183 
11184 	strncpy(branch_name, StrCache_Get(varlist[0]->strVal), MIN(MAX_NAME_LEN, MAX_STR_VAR_LEN)); // copy the string value to branch name
11185 
11186 	if(paramCount >= 2)
11187 	{
11188 		if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[1], &ltemp)))
11189 		{
11190 			endgame = (int)ltemp;
11191 			// 1 means goto that level immediately, or, wait until the level is complete
11192 		}
11193 		else goto jumptobranch_error;
11194 	}
11195 
11196 	return S_OK;
11197 jumptobranch_error:
11198 	printf("Function requires 1 string value, the second argument is optional(int): jumptobranch(name, immediate)\n");
11199 	return E_FAIL;
11200 }
11201 
11202 //bindentity(entity, target, x, z, a, direction, bindanim);
11203 //bindentity(entity, NULL()); // unbind
openbor_bindentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11204 HRESULT openbor_bindentity(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11205 {
11206 	entity* ent = NULL;
11207 	entity* other = NULL;
11208 	ScriptVariant* arg = NULL;
11209 	void adjust_bind(entity* e);
11210 	LONG x=0, z=0, a=0, dir=0, anim=0;
11211 
11212    *pretvar = NULL;
11213 	if(paramCount < 2)
11214 	{
11215 		return E_FAIL;
11216 	}
11217 
11218 	ent = (entity*)(varlist[0])->ptrVal; //retrieve the entity
11219 	if(!ent)  return S_OK;
11220 
11221 	other = (entity*)(varlist[1])->ptrVal;
11222 	if(!other)  {ent->bound = NULL; return S_OK;}
11223 
11224 	ent->bound = other;
11225 
11226 	if(paramCount < 3) goto BIND;
11227 	// x
11228 	arg = varlist[2];
11229 	if(arg->vt != VT_EMPTY)
11230 	{
11231 		if(FAILED(ScriptVariant_IntegerValue(arg, &x)))  return E_FAIL;
11232 
11233 		ent->bindoffset[0] = (int)x;
11234 	}
11235 	if(paramCount < 4) goto BIND;
11236 	// z
11237 	arg = varlist[3];
11238 	if(arg->vt != VT_EMPTY)
11239 	{
11240 		if(FAILED(ScriptVariant_IntegerValue(arg, &z)))  return E_FAIL;
11241 		ent->bindoffset[1] = (int)z;
11242 	}
11243 	if(paramCount < 5) goto BIND;
11244 	// a
11245 	arg = varlist[4];
11246 	if(arg->vt != VT_EMPTY)
11247 	{
11248 		if(FAILED(ScriptVariant_IntegerValue(arg, &a)))  return E_FAIL;
11249 		ent->bindoffset[2] = (int)a;
11250 	}
11251 	if(paramCount < 6) goto BIND;
11252 	// direction
11253 	arg = varlist[5];
11254 	if(arg->vt != VT_EMPTY)
11255 	{
11256 		if(FAILED(ScriptVariant_IntegerValue(arg, &dir)))  return E_FAIL;
11257 		ent->bindoffset[3] = (int)dir;
11258 	}
11259 	if(paramCount < 7) goto BIND;
11260 	// animation
11261 	arg = varlist[6];
11262 	if(arg->vt != VT_EMPTY)
11263 	{
11264 		if(FAILED(ScriptVariant_IntegerValue(arg, &anim)))  return E_FAIL;
11265 		ent->bindanim = (int)anim;
11266 	}
11267 
11268 BIND:
11269 	adjust_bind(ent);
11270 
11271 	return S_OK;
11272 }
11273 
11274 //array(size);
openbor_array(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11275 HRESULT openbor_array(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11276 {
11277 	LONG size;
11278 	void* array;
11279 
11280 	if(paramCount < 1) goto array_error;
11281 
11282 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &size)))
11283 		goto array_error;
11284 
11285 	if(size<=0) goto array_error;
11286 
11287 	ScriptVariant_ChangeType(*pretvar, VT_PTR);
11288 	array = malloc(sizeof(ScriptVariant)*(size+1));
11289 	if(array) memset(array, 0, sizeof(ScriptVariant)*(size+1));
11290 	(*pretvar)->ptrVal = (VOID*)array;
11291 
11292 	if((*pretvar)->ptrVal==NULL)
11293 	{
11294 		printf("Not enough memory: array(%d)\n", (int)size);
11295 		(*pretvar) = NULL;
11296 		return E_FAIL;
11297 	}
11298 
11299 	ScriptVariant_ChangeType((ScriptVariant*)array, VT_INTEGER);
11300 	((ScriptVariant*)array)->lVal = (LONG)size;
11301 
11302 	List_InsertAfter(&scriptheap, (void*)((*pretvar)->ptrVal), "openbor_array");
11303 	return S_OK;
11304 
11305 array_error:
11306 	printf("Function requires 1 positive int value: array(int size)\n");
11307 	(*pretvar) = NULL;
11308 	return E_FAIL;
11309 }
11310 
11311 
11312 //size(array)
openbor_size(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11313 HRESULT openbor_size(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11314 {
11315 	if(paramCount < 1 ) goto size_error;
11316 	if(varlist[0]->vt!=VT_PTR)  goto size_error;
11317 
11318 	ScriptVariant_Copy(*pretvar, ((ScriptVariant*)varlist[0]->ptrVal));
11319 
11320 	return S_OK;
11321 
11322 size_error:
11323 	printf("Function requires 1 array handle and 1 int value: get(array, int index)\n");
11324 	(*pretvar) = NULL;
11325 	return E_FAIL;
11326 }
11327 
11328 //get(array, index);
openbor_get(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11329 HRESULT openbor_get(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11330 {
11331 	LONG ind, size;
11332 
11333 	if(paramCount < 2 ) goto get_error;
11334 
11335 	if(varlist[0]->vt!=VT_PTR)  goto get_error;
11336 
11337 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
11338 		goto get_error;
11339 
11340 	ScriptVariant_IntegerValue(((ScriptVariant*)varlist[0]->ptrVal), &size);
11341 	if(ind<0 || ind>=size) goto get_error2;
11342 
11343 	ScriptVariant_Copy(*pretvar, ((ScriptVariant*)varlist[0]->ptrVal)+ind+1);
11344 
11345 	return S_OK;
11346 
11347 get_error:
11348 	printf("Function requires 1 array handle and 1 int value: get(array, int index)\n");
11349 	(*pretvar) = NULL;
11350 	return E_FAIL;
11351 get_error2:
11352 	printf("Array bound out of range: %d, max %d\n", ind, size-1);
11353 	(*pretvar) = NULL;
11354 	return E_FAIL;
11355 }
11356 
11357 //set(array, index, value);
openbor_set(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11358 HRESULT openbor_set(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11359 {
11360 	LONG ind, size;
11361 	(*pretvar) = NULL;
11362 
11363 	if(paramCount < 3 ) goto set_error;
11364 
11365 	if(varlist[0]->vt!=VT_PTR)  goto set_error;
11366 
11367 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &ind)))
11368 		goto set_error;
11369 
11370 	ScriptVariant_IntegerValue(((ScriptVariant*)varlist[0]->ptrVal), &size);
11371 	if(ind<0 || ind>=size) goto set_error2;
11372 
11373 	ScriptVariant_Copy(((ScriptVariant*)varlist[0]->ptrVal)+ind+1, varlist[2]);
11374 
11375 	return S_OK;
11376 
11377 set_error:
11378 	printf("Function requires 1 array handle, 1 int value and 1 value: set(array, int index, value)\n");
11379 	return E_FAIL;
11380 set_error2:
11381 	printf("Array bound out of range: %d, max %d\n", ind, size-1);
11382 	return E_FAIL;
11383 }
11384 
11385 //allocscreen(int w, int h);
openbor_allocscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11386 HRESULT openbor_allocscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11387 {
11388 	LONG w, h;
11389 	s_screen* screen;
11390 
11391 	if(paramCount < 2) goto allocscreen_error;
11392 
11393 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &w)))
11394 		goto allocscreen_error;
11395 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &h)))
11396 		goto allocscreen_error;
11397 
11398 
11399 	ScriptVariant_ChangeType(*pretvar, VT_PTR);
11400 	screen = allocscreen((int)w, (int)h, screenformat);
11401 	if(screen) clearscreen(screen);
11402 	(*pretvar)->ptrVal = (VOID*)screen;
11403 
11404 	if((*pretvar)->ptrVal==NULL)
11405 	{
11406 		printf("Not enough memory: allocscreen(%d, %d)\n", (int)w, (int)h);
11407 		(*pretvar) = NULL;
11408 		return E_FAIL;
11409 	}
11410 	List_InsertAfter(&scriptheap, (void*)((*pretvar)->ptrVal), "openbor_allocscreen");
11411 	return S_OK;
11412 
11413 allocscreen_error:
11414 	printf("Function requires 2 int values: allocscreen(int width, int height)\n");
11415 	(*pretvar) = NULL;
11416 	return E_FAIL;
11417 }
11418 
11419 //clearscreen(s_screen* screen)
openbor_clearscreen(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11420 HRESULT openbor_clearscreen(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11421 {
11422 	s_screen* screen;
11423 
11424 	*pretvar = NULL;
11425 	if(paramCount != 1) goto clearscreen_error;
11426 	if(varlist[0]->vt != VT_PTR) goto clearscreen_error;
11427 
11428 	screen = (s_screen*)varlist[0]->ptrVal;
11429 
11430 	if(screen == NULL)
11431 	{
11432 		printf("Error: NULL pointer passed to clearscreen(void screen)\n");
11433 		*pretvar = NULL;
11434 		return E_FAIL;
11435 	}
11436 	clearscreen(screen);
11437 	return S_OK;
11438 
11439 clearscreen_error:
11440 	printf("Function requires a screen pointer: clearscreen(void screen)\n");
11441 	return E_FAIL;
11442 }
11443 
11444 //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);
openbor_setdrawmethod(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11445 HRESULT openbor_setdrawmethod(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11446 {
11447 	LONG value[12];
11448 	entity* e;
11449 	s_drawmethod *pmethod;
11450 	int i;
11451 
11452 	*pretvar = NULL;
11453 	if(paramCount<2) goto setdrawmethod_error;
11454 
11455 	if(varlist[0]->vt==VT_EMPTY) e = NULL;
11456 	else if(varlist[0]->vt==VT_PTR) e = (entity*)varlist[0]->ptrVal;
11457 	else goto setdrawmethod_error;
11458 
11459 	if(e) pmethod = &(e->drawmethod);
11460 	else  pmethod = &(drawmethod);
11461 
11462 	memset(value, 0, sizeof(LONG)*12);
11463 	for(i=1; i<paramCount && i<13; i++)
11464 	{
11465 		if(FAILED(ScriptVariant_IntegerValue(varlist[i], value+i-1))) goto setdrawmethod_error;
11466 	}
11467 
11468 	if(paramCount>=15 && varlist[13]->vt!=VT_PTR && varlist[13]->vt!=VT_EMPTY) goto setdrawmethod_error;
11469 
11470 	pmethod->flag = (int)value[0];
11471 	pmethod->scalex = (int)value[1];
11472 	pmethod->scaley = (int)value[2];
11473 	pmethod->flipx = (int)value[3];
11474 	pmethod->flipy = (int)value[4];
11475 	pmethod->shiftx = (int)value[5];
11476 	pmethod->alpha = (int)value[6];
11477 	pmethod->remap = (int)value[7];
11478 	pmethod->fillcolor = (int)value[8];
11479 	pmethod->rotate = ((int)value[9])%360;
11480 	pmethod->fliprotate = (int)value[10];
11481 	pmethod->transbg = (int)value[11];
11482 	if(paramCount>=14) pmethod->table=(unsigned char*)varlist[13]->ptrVal;
11483 
11484 	if(pmethod->rotate)
11485 	{
11486 		if(pmethod->rotate<0) pmethod->rotate += 360;
11487 	}
11488 	return S_OK;
11489 
11490 setdrawmethod_error:
11491 	printf("Function need a valid entity handle and at least 1 interger parameter, all other parameters should be integers: 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)\n");
11492 	return E_FAIL;
11493 }
11494 
11495 //updateframe(entity, int frame);
openbor_updateframe(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11496 HRESULT openbor_updateframe(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11497 {
11498 	LONG f;
11499 	entity* e;
11500 	void update_frame(entity* ent, int f);
11501 
11502 	*pretvar = NULL;
11503 	if(paramCount<2) goto updateframe_error;
11504 
11505 	if(varlist[0]->vt==VT_EMPTY) e = NULL;
11506 	else if(varlist[0]->vt==VT_PTR) e = (entity*)varlist[0]->ptrVal;
11507 	else goto updateframe_error;
11508 
11509 	if(!e) goto updateframe_error;
11510 
11511 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &f))) goto updateframe_error;
11512 
11513 	update_frame(e, (int)f);
11514 
11515 	return S_OK;
11516 
11517 updateframe_error:
11518 	printf("Function need a valid entity handle and at an interger parameter: updateframe(entity, int frame)\n");
11519 	return E_FAIL;
11520 }
11521 
11522 //performattack(entity, int anim, int resetable);
openbor_performattack(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11523 HRESULT openbor_performattack(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11524 {
11525 	LONG anim, resetable=0;
11526 	entity* e;
11527 
11528 	*pretvar = NULL;
11529 	if(paramCount<1) goto performattack_error;
11530 
11531 	if(varlist[0]->vt==VT_EMPTY) e = NULL;
11532 	else if(varlist[0]->vt==VT_PTR) e = (entity*)varlist[0]->ptrVal;
11533 	else goto performattack_error;
11534 
11535 	if(!e) goto performattack_error;
11536 
11537 	e->takeaction = common_attack_proc;
11538 	e->attacking = 1;
11539 	e->idling = 0;
11540 	e->drop = 0;
11541 	e->falling = 0;
11542 	e->inpain = 0;
11543 	e->blocking = 0;
11544 
11545 	if(paramCount==1) return S_OK;
11546 
11547 	if(paramCount>1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim))) goto performattack_error;
11548 	if(paramCount>2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))  goto performattack_error;
11549 	ent_set_anim(e, (int)anim, (int)resetable);
11550 
11551 	return S_OK;
11552 
11553 performattack_error:
11554 	printf("Function need a valid entity handle, the other 2 integer parameters are optional: performattack(entity, int anim, int resetable)\n");
11555 	return E_FAIL;
11556 }
11557 
11558 //setidle(entity, int anim, int resetable, int stalladd);
openbor_setidle(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11559 HRESULT openbor_setidle(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11560 {
11561 	LONG anim=0, resetable=0, stalladd=0;
11562 	entity* e;
11563 	extern unsigned int time;
11564 
11565 	*pretvar = NULL;
11566 	if(paramCount<1) goto setidle_error;
11567 
11568 	if(varlist[0]->vt==VT_EMPTY) e = NULL;
11569 	else if(varlist[0]->vt==VT_PTR) e = (entity*)varlist[0]->ptrVal;
11570 	else goto setidle_error;
11571 
11572 	if(!e) goto setidle_error;
11573 
11574 	e->takeaction = NULL;
11575 	e->attacking = 0;
11576 	e->idling = 1;
11577 	e->drop = 0;
11578 	e->falling = 0;
11579 	e->inpain = 0;
11580 	e->blocking = 0;
11581 	e->nograb = 0;
11582 
11583 	if(paramCount==1) return S_OK;
11584 
11585 	if(paramCount>1 && FAILED(ScriptVariant_IntegerValue(varlist[1], &anim))) goto setidle_error;
11586 	if(paramCount>2 && FAILED(ScriptVariant_IntegerValue(varlist[2], &resetable)))  goto setidle_error;
11587 	if(paramCount>3 && FAILED(ScriptVariant_IntegerValue(varlist[3], &stalladd)))  goto setidle_error;
11588 	ent_set_anim(e, (int)anim, (int)resetable);
11589 
11590 	if(stalladd>0) e->stalltime = time+stalladd;
11591 
11592 	return S_OK;
11593 
11594 setidle_error:
11595 	printf("Function need a valid entity handle, the other 3 integer parameters are optional: setidle(entity, int anim, int resetable, int stalladd)\n");
11596 	return E_FAIL;
11597 }
11598 
11599 //getentity(int index_from_list)
openbor_getentity(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11600 HRESULT openbor_getentity(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11601 {
11602 	LONG ind;
11603 	extern entity* ent_list[MAX_ENTS];
11604 
11605 	if(paramCount!=1) goto getentity_error;
11606 
11607 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &ind))) goto getentity_error;
11608 
11609 	ScriptVariant_Clear(*pretvar);
11610 
11611 	if((int)ind<MAX_ENTS && (int)ind>=0)
11612 	{
11613 		ScriptVariant_ChangeType(*pretvar, VT_PTR);
11614 		(*pretvar)->ptrVal = (VOID*)ent_list[(int)ind];
11615 	}
11616 	//else, it should return an empty value
11617 	return S_OK;
11618 
11619 getentity_error:
11620 	printf("Function need an integer parameter: getentity(int index_in_list)\n");
11621 	*pretvar = NULL;
11622 	return E_FAIL;
11623 }
11624 
11625 
11626 //loadmodel(name)
openbor_loadmodel(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11627 HRESULT openbor_loadmodel(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11628 {
11629 	LONG unload = 0;
11630 	if(paramCount<1) goto loadmodel_error;
11631 	if(varlist[0]->vt!=VT_STR) goto loadmodel_error;
11632 
11633 	 ScriptVariant_ChangeType(*pretvar, VT_PTR);
11634 	 if(paramCount == 2)
11635 		 if(FAILED(ScriptVariant_IntegerValue(varlist[1], &unload))) goto loadmodel_error;
11636 
11637 	(*pretvar)->ptrVal = (VOID*)load_cached_model(StrCache_Get(varlist[0]->strVal), "openbor_loadmodel", (char)unload);
11638 	//else, it should return an empty value
11639 	return S_OK;
11640 
11641 loadmodel_error:
11642 	printf("Function needs a string and boolean parameters: loadmodel(name, unload)\n");
11643 	ScriptVariant_Clear(*pretvar);
11644 	*pretvar = NULL;
11645 	return E_FAIL;
11646 }
11647 
11648 // load a sprite which doesn't belong to the sprite_cache
11649 // loadsprite(path)
openbor_loadsprite(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11650 HRESULT openbor_loadsprite(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11651 {
11652 	extern s_sprite * loadsprite2(char *filename, int* width, int* height);
11653 	if(paramCount!=1) goto loadsprite_error;
11654 
11655 	if(varlist[0]->vt!=VT_STR) goto loadsprite_error;
11656 
11657 	ScriptVariant_ChangeType(*pretvar, VT_PTR);
11658 	if(((*pretvar)->ptrVal = (VOID*)loadsprite2(StrCache_Get(varlist[0]->strVal), NULL, NULL)))
11659 	{
11660 		List_InsertAfter(&scriptheap, (void*)((*pretvar)->ptrVal), "openbor_loadsprite");
11661 	}
11662 	//else, it should return an empty value
11663 	return S_OK;
11664 
11665 loadsprite_error:
11666 	printf("Function need a string parameter: loadsprite(path)\n");
11667 	ScriptVariant_Clear(*pretvar);
11668 	*pretvar = NULL;
11669 	return E_FAIL;
11670 }
11671 
11672 //playgif(path, int x, int y, int noskip)
openbor_playgif(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11673 HRESULT openbor_playgif(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11674 {
11675 	LONG temp[3] = {0,0,0}; //x,y,noskip
11676 	int i;
11677 	extern unsigned char pal[1024];
11678 	extern int playgif(char *filename, int x, int y, int noskip);
11679 	if(paramCount<1) goto playgif_error;
11680 
11681 	if(varlist[0]->vt!=VT_STR) goto playgif_error;
11682 
11683 	ScriptVariant_ChangeType(*pretvar, VT_INTEGER);
11684 	for(i=0; i<3 && i<paramCount-1; i++)
11685 	{
11686 		if(FAILED(ScriptVariant_IntegerValue(varlist[i+1], temp+i))) goto playgif_error;
11687 	}
11688 	(*pretvar)->lVal = (LONG)playgif(StrCache_Get(varlist[0]->strVal), (int)(temp[0]), (int)(temp[1]), (int)(temp[2]));
11689 	palette_set_corrected(pal, savedata.gamma,savedata.gamma,savedata.gamma, savedata.brightness,savedata.brightness,savedata.brightness);
11690 	return S_OK;
11691 
11692 playgif_error:
11693 	printf("Function need a string parameter, other parameters are optional: playgif(path, int x, int y, int noskip)\n");
11694 	*pretvar = NULL;
11695 	return E_FAIL;
11696 }
11697 
11698 
11699 //zoom(int x, int y, int scalex, int scaley, int z)
openbor_zoom(ScriptVariant ** varlist,ScriptVariant ** pretvar,int paramCount)11700 HRESULT openbor_zoom(ScriptVariant** varlist , ScriptVariant** pretvar, int paramCount)
11701 {
11702 
11703 	extern int zoom_center_x, zoom_center_y, zoom_scale_x, zoom_scale_y, zoom_z;
11704 
11705 	*pretvar = NULL;
11706 	if(paramCount<4) goto zoom_error;
11707 
11708 	if(FAILED(ScriptVariant_IntegerValue(varlist[0], &zoom_center_x)))
11709 		goto zoom_error;
11710 	if(FAILED(ScriptVariant_IntegerValue(varlist[1], &zoom_center_y)))
11711 		goto zoom_error;
11712 	if(FAILED(ScriptVariant_IntegerValue(varlist[2], &zoom_scale_x)))
11713 		goto zoom_error;
11714 	if(FAILED(ScriptVariant_IntegerValue(varlist[3], &zoom_scale_y)))
11715 		goto zoom_error;
11716 	if(FAILED(ScriptVariant_IntegerValue(varlist[4], &zoom_z)))
11717 		goto zoom_error;
11718 
11719 	return S_OK;
11720 
11721 zoom_error:
11722 	printf("Function requires 5 int values: zoom(int x, int y, int scalex, int scaley, int z)\n");
11723 	return E_FAIL;
11724 }
11725