source: Daodan/src/Daodan_BSL.c@ 468

Last change on this file since 468 was 451, checked in by rossy, 15 years ago

bsl thingy

File size: 16.2 KB
RevLine 
[443]1#include <stdio.h>
[451]2#include <stdbool.h>
[440]3#include <time.h>
[443]4#include <ffi.h>
[440]5
[451]6#include "inifile.h"
7
[439]8#include "Daodan_BSL.h"
[444]9#include "Daodan_Utility.h"
[447]10#include "Daodan_Patch.h"
[444]11#include "Daodan_Console.h"
[445]12#include "BFW_ScriptLang.h"
[441]13#include "Oni.h"
14#include "Oni_Character.h"
[447]15#include "oni_gl.h"
[440]16#include "dSFMT\dSFMT.h"
[446]17#include "Daodan_Character.h"
[440]18
[444]19uint16_t ONICALL bsl_int32mul(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[439]20{
21 ret->value_int32 = args[0].value_int32 * args[1].value_int32;
22 ret->type = sl_int32;
23 return 0;
24}
25
[444]26uint16_t ONICALL bsl_mul(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[439]27{
28 double val1;
29 double val2;
30
31 if (args[0].type == sl_int32)
32 val1 = args[0].value_int32;
33 else
34 val1 = args[0].value_float;
35
36 if (args[1].type == sl_int32)
37 val2 = args[1].value_int32;
38 else
39 val2 = args[1].value_float;
40
41 ret->value_float = (float)(val1 * val2);
42 ret->type = sl_float;
43 return 0;
44}
45
[444]46uint16_t ONICALL bsl_int32div(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[439]47{
48 ret->value_int32 = args[0].value_int32 / args[1].value_int32;
49 ret->type = sl_int32;
50 return 0;
51}
52
[444]53uint16_t ONICALL bsl_div(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[439]54{
55 double val1;
56 double val2;
57
58 if (args[0].type == sl_int32)
59 val1 = args[0].value_int32;
60 else
61 val1 = args[0].value_float;
62
63 if (args[1].type == sl_int32)
64 val2 = args[1].value_int32;
65 else
66 val2 = args[1].value_float;
67
68 ret->value_float = (float)(val1 / val2);
69 ret->type = sl_float;
70 return 0;
71}
[443]72
[444]73uint16_t ONICALL bsl_int32rand(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[443]74{
75 int32_t start = 0;
76 int32_t end = 0;
77
78 if (args[0].value_int32 == args[1].value_int32)
79 return 1;
80 else if (args[0].value_int32 > args[1].value_int32)
81 {
82 start = args[1].value_int32;
83 end = args[0].value_int32;
84 }
85 else
86 {
87 start = args[0].value_int32;
88 end = args[1].value_int32;
89 }
90
91 ret->value_int32 = start + (dsfmt_gv_genrand_uint32() % (uint32_t)(end - start + 1));
92 ret->type = sl_int32;
93 return 0;
94}
95
[444]96uint16_t ONICALL bsl_getkills(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[443]97{
98 int index;
99 if (numargs == 0) index = 0;
[446]100 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
[443]101 else index = args[0].value_int32;
102 int* killcount = ONgGameState + index * 0x16A0 + 0x1260 + 0x1670;
103 ret->value_int32 = *killcount;
104 ret->type = sl_int32;
105 return 0;
106}
107
[444]108uint16_t ONICALL bsl_getdamage(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[443]109{
110 int index;
111 if (numargs == 0) index = 0;
[446]112 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
[443]113 else index = args[0].value_int32;
114 int* killcount = ONgGameState + index * 0x16A0 + 0x1260 + 0x1674;
115 ret->value_int32 = *killcount;
116 ret->type = sl_int32;
117 return 0;
118}
[446]119
120uint16_t ONICALL bsl_powerup(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
121{
122 int index;
123 if (numargs < 2 || args[1].type != sl_str32) return 1;
124 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
125 else index = args[0].value_int32;
[450]126 void* returnval;
127 bool is_lsi = 0;
128 Character* Chr = ONgGameState + 0x1260;
129 if(!strcmp(args[1].value_str32,"ammo"))
[446]130 {
[450]131 returnval = &(Chr[index].Inventory_.AmmoUsed);
132 }
133 else if(!strcmp(args[1].value_str32,"hypo"))
134 {
135 returnval = &(Chr[index].Inventory_.HypoUsed);
136 }
137 else if(!strcmp(args[1].value_str32,"cells"))
138 {
139 returnval = &(Chr[index].Inventory_.CellsUsed);
140 }
141 else if(!strcmp(args[1].value_str32,"invis"))
142 {
143 returnval = &(Chr[index].Inventory_.CloakUsed);
144 }
145 else if(!strcmp(args[1].value_str32,"shield"))
146 {
147 returnval = &(Chr[index].Inventory_.ShieldUsed);
148 }
149 else if(!strcmp(args[1].value_str32,"lsi"))
150 {
151 returnval = &(Chr[index].Inventory_.hasLSI);
152 is_lsi = 1;
153 }
[451]154// else if(!strcmp(args[1].value_str32,"bossshield"))
155// {
156// ret->value_int32 = Chr[index].Flags & char_bossshield;
157// ret->type = sl_int32;
158// if (numargs >=3) {
159// if (Chr[index].Flags & char_bossshield) Chr[index].Flags = Chr[index].Flags & ~char_bossshield;
160// else Chr[index].Flags = Chr[index].Flags | char_bossshield;
161// }
162// return 0;
163// }
[450]164 else return 1;
[446]165 //todo, add setting
166
[450]167 if(is_lsi) ret->value_int32 = (int)*(bool*)returnval;
168 else ret->value_int32 = *(int*)returnval;
169 ret->type = sl_int32;
170
171 if (numargs >= 3)
[446]172 {
[450]173 if(is_lsi) *(bool*)returnval = args[2].value_int32;
174 else *(int*)returnval = args[2].value_int32;
[446]175 }
[450]176
177
[446]178 return 0;
179}
180
181uint16_t ONICALL bsl_health(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
182{
183 int index;
184 if (numargs == 0) index = 0;
185 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
186 else index = args[0].value_int32;
187 Character* Chr = ONgGameState + 0x1260 ;
188 int* health = &Chr[index].Health;
189
190 ret->value_int32 = *health;
191 ret->type = sl_int32;
192
193 if (numargs >= 2) {
194 *health = args[1].value_int32;
195 }
196 ret->value_int32 = *health;
197 ret->type = sl_int32;
198 return 0;
199}
200
201uint16_t ONICALL bsl_maxhealth(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
202{
203 int index;
204 if (numargs == 0) index = 0;
205 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
206 else index = args[0].value_int32;
207 Character* Chr = ONgGameState + 0x1260 ;
208 int* maxhealth = &Chr[index].MaxHealth;
209 int oldmaxhealth = Chr[index].MaxHealth;
210 int oldhealth = Chr->Health;
211 if (numargs >= 2) {
212 *maxhealth = args[1].value_int32;
213 }
214 if (numargs >= 3 && args[2].value_bool) {
215 Chr->Health = (int)(((float)args[1].value_int32 / (float)oldmaxhealth) * (float)oldhealth);
216 }
217 ret->value_int32 = oldmaxhealth;
218 ret->type = sl_int32;
219 return 0;
220}
221
222uint16_t ONICALL bsl_getattacker(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
223{
224 //broken...not only does it sometimes blam, but it returns a string when i want an int so i can study it :<
225 int index;
[450]226 if (numargs == 0) index = 0;
227 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
[446]228 else index = args[0].value_int32;
229
[450]230 Character* Chr = ONgGameState + 0x1260;
231 ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]);
232 if ((int)Active == 0) return 1;
[451]233// ret->value_int32 = Active->LastDamageSourceCharacter;
[446]234 ret->type = sl_int32;
235 return 0;
236}
237
238
[450]239
[446]240uint16_t ONICALL bsl_chrname(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
241{
242 int index;
243 if (numargs == 0) index = 0;
244 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
245 else index = args[0].value_int32;
246 if (index == -1) {
247 ret->type = sl_str32;
248 ret->value_str32 = "NULL";
249 return 0;
250 }
251 char* name = ONgGameState + 0x1260 + index * 0x16A0 + 0x14;
252 if (numargs == 2) {
253 strncpy(name, (char*)args[1].value_str32, 31);
254 }
255
256 ret->type = sl_str32;
257 ret->value_str32 = name;
258
259 return 0;
260}
261
262
263uint16_t ONICALL bsl_count(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
264{
265 //testing numargs...
266 ret->type = sl_int32;
267 ret->value_int32 = numargs;
268 return 0;
269}
270
271uint16_t ONICALL bsl_dprintcolored(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
272{
273 //TODO: figure out why our implementation of dprint shows after dev mode is turned off
274 RGBA color;
275 RGBA shade;
276
277 if(numargs == 0) return 0;
278 if(numargs > 1 ) color.R = (char)args[1].value_int32;
279 else color.R = 255;
280 if(numargs > 2 ) color.G = (char)args[2].value_int32;
281 else color.G = 255;
282 if(numargs > 3 ) color.B = (char)args[3].value_int32;
283 else color.B = 255;
284 color.A = 0;
285 if(numargs > 5 ) shade.R = (char)args[5].value_int32;
286 else shade.R = 0x3F;
287 if(numargs > 6 ) shade.G = (char)args[6].value_int32;
288 else shade.G = 0x3F;
289 if(numargs > 7 ) shade.B = (char)args[7].value_int32;
290 else shade.B = 0x3F;
291 shade.A = 0;
292
293 DDrConsole_PrintColored(args[0].value_str32, 1, color, shade);
294 return 0;
295}
296
297
298uint16_t ONICALL bsl_nametoindex(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
299{
300 ret->type = sl_int32;
301 ret->value_int32 = DDrGetCharacterIndexFromName(args[0].value_str32);
302 return 0;
303}
[450]304
305uint16_t ONICALL bsl_getactiveoffset(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
306{
307 DDrConsole_PrintF("Character: 0x%x",(int)ONgGameState + 0x1260);
308 DDrConsole_PrintF("ActiveChar: 0x%x",(int)ONrGetActiveCharacter((void*)((int)ONgGameState + 0x1260)));
309 return 0;
310}
[444]311/*
312uint16_t ONICALL bsl_sprintf(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[441]313{
314 if (numargs < 2)
315 return 1;
[445]316
[441]317 char output[255];
[444]318 int i;
319 for(i = 1; i < numargs; i++) {
320 sprintf(output, args[0].value_str32, args[i].value_str32);
[441]321 }
322
323 ret->value_str32 = output;
324 ret->type = sl_str32;
325 return 0;
326}
[444]327*/
328uint16_t ONICALL bsl_sprintf(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
[440]329{
[445]330 DDrConsole_PrintF("%d", numargs);
331
332 if (numargs < 1 || args[0].type != sl_str32)
333 {
334 DDrConsole_PrintF("Func \"%s\", File \"%s\", Line %d: semantic error, \"%s\": parameter list does not match: format:string arg1 arg2 ...", callinfo->name, callinfo->calllocation, callinfo->linenumber, callinfo->name);
335 return 0;
336 }
337
338 if (!args[0].value_str32)
339 args[0].value_str32 = "";
340
[444]341 int ffi_ret;
342 char* str = NULL;
343 int size = 0;
[440]344
[443]345 ffi_cif cif;
[444]346 ffi_type* ffi_args[256];
347 void* values[256];
[440]348
[443]349 ffi_args[0] = &ffi_type_pointer;
[444]350 values[0] = &str;
[443]351 ffi_args[1] = &ffi_type_uint32;
[444]352 values[1] = &size;
[443]353
354 int i;
355 for(i = 2; i < numargs + 2; i ++)
[440]356 {
[444]357 if (args[i - 2].type == sl_float)
358 {
359 float value_float = args[i - 2].value_float;
360 double* value_double = (double*)&(args[i - 2]);
361 *value_double = value_float;
362
363 ffi_args[i] = &ffi_type_double;
364 values[i] = value_double;
365 }
366 else
367 {
368 ffi_args[i] = &ffi_type_pointer;
369 values[i] = &(args[i - 2].value);
370 }
[440]371 }
372
[444]373 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, i, &ffi_type_sint32, ffi_args) != FFI_OK)
[445]374 return 1;
[443]375 ffi_call(&cif, (void*)snprintf, (void*)&ffi_ret, values);
[444]376 str = malloc(ffi_ret + 1);
377 size = ffi_ret + 1;
378 ffi_call(&cif, (void*)snprintf, (void*)&ffi_ret, values);
379 ret->value_str32 = str;
[443]380 ret->type = sl_str32;
[440]381 return 0;
382}
383
[447]384// Widescreen patch for talking heads.
385uint16_t ONICALL cinematic_start_patch(sl_callinfo* callinfo, unsigned int numargs, sl_arg args[], void* dontuse1, void* dontuse2, sl_arg* ret)
386{
387 args[1].value_int32 = (double)args[1].value_int32 / (double)(gl->DisplayMode.Width) * (4.0 / 3.0 * (double)(gl->DisplayMode.Height));
388 return ((sl_func)(OniExe + 0x000f3830))(callinfo, numargs, args, dontuse1, dontuse2, ret);
389}
390
[451]391bool ini_inbsl = false;
392bool SLrIniCallback(char* section, bool newsection, char* name, char* value)
393{
394 if (newsection && !stricmp(section, "bsl"))
395 ini_inbsl = true;
396
397 if (ini_inbsl)
398 {
399 bool isptr = false;
400 sl_type bsl_type;
401
402 if (value[0] == 'p' && value[1] == 't' && value[2] == 'r' && value[3] == ':')
403 {
404 isptr = true;
405 value += 4;
406 }
407
408 char* type = value;
409
410 for (; *type; type++)
411 if (*type == ':')
412 {
413 *type = '\0';
414 type++;
415 break;
416 }
417
418 if (!*type)
419 DDrStartupMessage("badly formed bsl definition for \"%s\"", name);
420
421 if (!strcmp(type, "int"))
422 bsl_type = sl_int32;
423 else if (!strcmp(type, "string"))
424 bsl_type = sl_str32;
425 else if (!strcmp(type, "float"))
426 bsl_type = sl_float;
427 else if (!strcmp(type, "bool"))
428 bsl_type = sl_bool;
429 else
430 {
431 DDrStartupMessage("unknown type in bsl definition for \"%s\"", name);
432 return true;
433 }
434
435 if (isptr)
436 {
437 char* bsl_var = malloc(strlen(name) + 1);
438 memcpy(bsl_var, name, strlen(name) + 1);
439 switch (bsl_type)
440 {
441 case sl_int32:
442 SLrGlobalVariable_Register_Int32(bsl_var, "see daodan.ini", (int32_t*)(uint32_t)inifile_parseint(value, false));
443 break;
444 case sl_float:
445 SLrGlobalVariable_Register_Float(bsl_var, "see daodan.ini", (float*)(uint32_t)inifile_parseint(value, false));
446 break;
447 default:
448 break;
449 }
450 }
451 else
452 {
453 char* bsl_var = malloc(strlen(name) + 1 + sizeof(int32_t));
454 int32_t* bsl_val = (int32_t*)bsl_var;
455 bsl_var += sizeof(int32_t);
456 memcpy(bsl_var, name, strlen(name) + 1);
457
458 switch (bsl_type)
459 {
460 case sl_int32:
461 *bsl_val = inifile_parseint(value, false);
462 SLrGlobalVariable_Register_Int32(bsl_var, "see daodan.ini", bsl_val);
463 break;
464 case sl_float:
465 break;
466 default:
467 break;
468 }
469 }
470 }
471 return true;
472}
473
474void SLrConfig()
475{
476 DDrStartupMessage("re-parsing daodan.ini for bsl...");
477 inifile_read("daodan.ini", SLrIniCallback);
478 DDrStartupMessage("finished parsing");
479}
480
[439]481void SLrDaodan_Initalize()
482{
[451]483 SLrConfig();
484
[439]485 SLrScript_Command_Register_ReturnType("int32mul", "Multiplies two numbers", "n1:int n2:int", sl_int32, bsl_int32mul);
486 SLrScript_Command_Register_ReturnType("mul", "Multiplies two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_mul);
487
488 SLrScript_Command_Register_ReturnType("int32div", "Divides two numbers", "n1:int n2:int", sl_int32, bsl_int32div);
489 SLrScript_Command_Register_ReturnType("div", "Divides two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_div);
[440]490
[443]491 dsfmt_gv_init_gen_rand((uint32_t)time(NULL));
492 SLrScript_Command_Register_ReturnType("int32rand", "Returns a pseudo-random number between two numbers (inclusive).", "start:int end:int", sl_int32, bsl_int32rand);
493
[446]494 SLrScript_Command_Register_ReturnType("d_getkills","Gets the number of kills a character has", "[ai_name:str | script_id:int]", sl_int32, bsl_getkills);
495 SLrScript_Command_Register_ReturnType("d_getdamage","Gets the amount of damage a character has caused", "[ai_name:string | script_id:int]", sl_int32, bsl_getdamage);
496 SLrScript_Command_Register_ReturnType("d_name","Gets or sets a character's name", "[ai_name:str | script_id:int] [newname:string]", sl_str32, bsl_chrname);
497 SLrScript_Command_Register_ReturnType("d_getindex","Converts a character's name to its index", "script_id:int", sl_int32, bsl_nametoindex);
498 SLrScript_Command_Register_ReturnType("d_health","Gets or sets a character's health", "[ai_name:str | script_id:int] [newhealth:int]", sl_str32, bsl_health);
499 SLrScript_Command_Register_ReturnType("d_maxhealth","Gets or sets a character's maximum health", "[ai_name:str | script_id:int] [newmaxhealth:int] [scalehealth:bool]", sl_str32, bsl_maxhealth);
500 SLrScript_Command_Register_ReturnType("d_powerup","Gets or sets a character's powerups", "ai_name:str|script_id:int powerup:str", sl_int32, bsl_powerup);
501 //broken. sometimes crashes, and sometimes returns a string... : /
[450]502 SLrScript_Command_Register_ReturnType("d_getattacker","Gets the last person to hurt a character", "[ai_name:string | script_id:int]", sl_int32, bsl_getattacker);
[441]503
[450]504 SLrScript_Command_Register_ReturnType("d_active","Gets the last person to hurt a character", "[ai_name:string | script_id:int]", sl_int32, bsl_getactiveoffset);
505
[445]506 SLrScript_Command_Register_ReturnType("sprintf", "C-style sprintf.", "format:string arg1 arg2 ...", sl_str32, bsl_sprintf);
[447]507 SLrScript_Command_Register_ReturnType("dprintcolor", "prints to console in color", "text:string [color: r b g] [color: r b g]", sl_void, bsl_dprintcolored);
[451]508
[450]509 SLrScript_Command_Register_ReturnType("d_dprint", "prints to console in color", "text:string [color: r b g] [color: r b g]", sl_void, bsl_dprintcolored);
[447]510}
[451]511
[447]512void SLrDaodan_Patch()
513{
514 DDrPatch_Int32(OniExe + 0x000f3755, (int)cinematic_start_patch);
515}
Note: See TracBrowser for help on using the repository browser.