source: Daodan/src/Daodan_BSL.c@ 604

Last change on this file since 604 was 484, checked in by gumby, 15 years ago

ZOMG FLATLINE

File size: 26.6 KB
Line 
1#include <stdio.h>
2#include <stdbool.h>
3#include <time.h>
4#include <ffi.h>
5#include <math.h>
6#include "inifile.h"
7
8#include "Daodan_BSL.h"
9#include "Flatline_BSL.h"
10#include "Daodan_Utility.h"
11#include "Daodan_Patch.h"
12#include "Daodan_Console.h"
13#include "BFW_ScriptLang.h"
14#include "Oni.h"
15#include "Oni_Character.h"
16#include "oni_gl.h"
17#include "dSFMT\dSFMT.h"
18#include "Daodan_Character.h"
19
20
21
22uint16_t ONICALL bsl_int32mul(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
23{
24 ret->value_int32 = args[0].value_int32 * args[1].value_int32;
25 ret->type = sl_int32;
26 return 0;
27}
28
29uint16_t ONICALL bsl_mul(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
30{
31 double val1;
32 double val2;
33
34 if (args[0].type == sl_int32)
35 val1 = args[0].value_int32;
36 else
37 val1 = args[0].value_float;
38
39 if (args[1].type == sl_int32)
40 val2 = args[1].value_int32;
41 else
42 val2 = args[1].value_float;
43
44 ret->value_float = (float)(val1 * val2);
45 ret->type = sl_float;
46 return 0;
47}
48
49uint16_t ONICALL bsl_int32div(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
50{
51 ret->value_int32 = args[0].value_int32 / args[1].value_int32;
52 ret->type = sl_int32;
53 return 0;
54}
55uint16_t ONICALL bsl_div(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
56{
57 double val1;
58 double val2;
59
60 if (args[0].type == sl_int32)
61 val1 = args[0].value_int32;
62 else
63 val1 = args[0].value_float;
64
65 if (args[1].type == sl_int32)
66 val2 = args[1].value_int32;
67 else
68 val2 = args[1].value_float;
69
70 ret->value_float = (float)(val1 / val2);
71 ret->type = sl_float;
72 return 0;
73}
74
75uint16_t ONICALL bsl_int32rand(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
76{
77 int32_t start = 0;
78 int32_t end = 0;
79
80 if (args[0].value_int32 == args[1].value_int32)
81 return 1;
82 else if (args[0].value_int32 > args[1].value_int32)
83 {
84 start = args[1].value_int32;
85 end = args[0].value_int32;
86 }
87 else
88 {
89 start = args[0].value_int32;
90 end = args[1].value_int32;
91 }
92
93 ret->value_int32 = start + (dsfmt_gv_genrand_uint32() % (uint32_t)(end - start + 1));
94 ret->type = sl_int32;
95 return 0;
96}
97
98uint16_t ONICALL bsl_getkills(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
99{
100 int index;
101 if (numargs == 0) index = 0;
102 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
103 else index = args[0].value_int32;
104 int* killcount = ONgGameState + index * 0x16A0 + 0x1260 + 0x1670;
105 ret->value_int32 = *killcount;
106 ret->type = sl_int32;
107 return 0;
108}
109
110uint16_t ONICALL bsl_getdamage(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
111{
112 int index;
113 if (numargs == 0) index = 0;
114 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
115 else index = args[0].value_int32;
116 int* killcount = ONgGameState + index * 0x16A0 + 0x1260 + 0x1674;
117 ret->value_int32 = *killcount;
118 ret->type = sl_int32;
119 return 0;
120}
121
122uint16_t ONICALL bsl_returnoffset(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
123{
124 //int offset = 140;
125 //if (== 1) offset = 148;
126 //else index = args[0].value_int32;
127 int* killcount = ONgGameState + args[0].value_int32;
128 ret->value_int32 = *killcount;
129 ret->type = sl_int32;
130 return 0;
131}
132
133
134uint16_t ONICALL bsl_powerup(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
135{
136 int index;
137 if (numargs < 2 || args[1].type != sl_str32) return 1;
138 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
139 else index = args[0].value_int32;
140 void* returnval;
141 bool is_lsi = 0;
142 Character* Chr = ONgGameState + 0x1260;
143 if(!strcmp(args[1].value_str32,"ammo"))
144 {
145 returnval = &(Chr[index].Inventory_.AmmoUsed);
146 }
147 else if(!strcmp(args[1].value_str32,"hypo"))
148 {
149 returnval = &(Chr[index].Inventory_.HypoUsed);
150 }
151 else if(!strcmp(args[1].value_str32,"cells"))
152 {
153 returnval = &(Chr[index].Inventory_.CellsUsed);
154 }
155 else if(!strcmp(args[1].value_str32,"invis"))
156 {
157 returnval = &(Chr[index].Inventory_.CloakUsed);
158 }
159 else if(!strcmp(args[1].value_str32,"shield"))
160 {
161 returnval = &(Chr[index].Inventory_.ShieldUsed);
162 }
163 else if(!strcmp(args[1].value_str32,"lsi"))
164 {
165 returnval = &(Chr[index].Inventory_.hasLSI);
166 is_lsi = 1;
167 }
168// else if(!strcmp(args[1].value_str32,"bossshield"))
169// {
170// ret->value_int32 = Chr[index].Flags & char_bossshield;
171// ret->type = sl_int32;
172// if (numargs >=3) {
173// if (Chr[index].Flags & char_bossshield) Chr[index].Flags = Chr[index].Flags & ~char_bossshield;
174// else Chr[index].Flags = Chr[index].Flags | char_bossshield;
175// }
176// return 0;
177// }
178 else return 1;
179 //todo, add setting
180
181 if(is_lsi) ret->value_int32 = (int)*(bool*)returnval;
182 else ret->value_int32 = *(int*)returnval;
183 ret->type = sl_int32;
184
185 if (numargs >= 3)
186 {
187 if(is_lsi) *(bool*)returnval = args[2].value_int32;
188 else *(int*)returnval = args[2].value_int32;
189 }
190
191
192 return 0;
193}
194
195uint16_t ONICALL bsl_health(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
196{
197 int index;
198 if (numargs == 0) index = 0;
199 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
200 else index = args[0].value_int32;
201 Character* Chr = ONgGameState + 0x1260 ;
202 int* health = &Chr[index].Health;
203
204 ret->value_int32 = *health;
205 ret->type = sl_int32;
206
207 if (numargs >= 2) {
208 *health = args[1].value_int32;
209 }
210 ret->value_int32 = *health;
211 ret->type = sl_int32;
212 return 0;
213}
214
215uint16_t ONICALL bsl_regen(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
216{
217 int index;
218 if (numargs == 0) index = 0;
219 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
220 else index = args[0].value_int32;
221 Character* Chr = ONgGameState + 0x1260 ;
222 int* health = (int*)Chr[index].ScriptNoPath;
223
224 /*
225 DDrConsole_PrintF("Character %s", Chr[index].Name);
226 DDrConsole_PrintF("Spawn %s", Chr[index].ScriptSpawn);
227 DDrConsole_PrintF("Death %s", Chr[index].ScriptDie);
228 DDrConsole_PrintF("Aware %s", Chr[index].ScriptAware);
229 DDrConsole_PrintF("Alarm %s", Chr[index].ScriptAlarm);
230 DDrConsole_PrintF("Hurt %s", Chr[index].ScriptHurt);
231 DDrConsole_PrintF("Defeat %s", Chr[index].ScriptDefeat);
232 DDrConsole_PrintF("NoAmmo %s", Chr[index].ScriptNoAmmo);
233 DDrConsole_PrintF("NoPath %s", Chr[index].ScriptNoPath);
234 */
235 ret->value_int32 = *health;
236 ret->type = sl_int32;
237
238 if (numargs >= 2) {
239 *health = args[1].value_int32;
240 }
241 return 0;
242}
243
244uint16_t ONICALL bsl_distance(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) {
245
246 if (numargs < 2) return 1;
247 int index;
248 int index2;
249 if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
250 else index = args[0].value_int32;
251 if (index == -1) index = args[0].value_int32;
252
253 if (args[1].type == sl_str32) index2 = DDrGetCharacterIndexFromName(args[1].value_str32);
254 else index2 = args[1].value_int32;
255 if (index2 == -1) index2 = args[1].value_int32;
256
257 Character* Chr = ONgGameState + 0x1260;
258 Character* Char1 = &Chr[index];
259 Character* Char2 = &Chr[index2];
260
261 ret->value_float = sqrt( pow((Char1->Location.X - Char2->Location.X), 2) + pow((Char1->Location.Y - Char2->Location.Y), 2) + pow((Char1->Location.Z - Char2->Location.Z),2));
262 ret->type = sl_float;
263 return 0;
264}
265uint16_t ONICALL bsl_location(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) {
266 int index;
267 if (numargs < 2) return 1;
268 if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
269 else index = args[0].value_int32;
270 if (index == -1) index = args[0].value_int32;
271 Character* Chr = ONgGameState + 0x1260;
272 float* loc;
273 if (!strcmp(args[1].value_str32,"X") || !strcmp(args[1].value_str32,"x"))
274 loc = &(Chr[index].Position.X);
275 else if (!strcmp(args[1].value_str32,"Y") || !strcmp(args[1].value_str32,"y"))
276 loc = &(Chr[index].Position.Y);
277 else if (!strcmp(args[1].value_str32,"Z") || !strcmp(args[1].value_str32,"z"))
278 loc = &(Chr[index].Position.Z);
279 else if (numargs == 4) {
280 //currently broken. crashes oni.
281 Chr[index].Position.X = args[1].value_float;
282 Chr[index].Position.Y = args[2].value_float;
283 Chr[index].Position.Z = args[3].value_float;
284 ret->value_float = 1;
285 ret->type = sl_float;
286 return 0;
287 }
288 else return 1;
289
290 ret->value_float = *loc;
291 ret->type = sl_float;
292
293 if(numargs == 3) {
294 //currently broken, does nothing.
295 *loc = args[2].value_float;
296 }
297 return 0;
298}
299
300uint16_t ONICALL bsl_maxhealth(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
301{
302 int index;
303 if (numargs == 0) index = 0;
304 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
305 else index = args[0].value_int32;
306 Character* Chr = ONgGameState + 0x1260 ;
307 int* maxhealth = &Chr[index].MaxHealth;
308 int oldmaxhealth = Chr[index].MaxHealth;
309 int oldhealth = Chr->Health;
310 if (numargs >= 2) {
311 *maxhealth = args[1].value_int32;
312 }
313 if (numargs >= 3 && args[2].value_bool) {
314 Chr->Health = (int)(((float)args[1].value_int32 / (float)oldmaxhealth) * (float)oldhealth);
315 }
316 ret->value_int32 = oldmaxhealth;
317 ret->type = sl_int32;
318 return 0;
319}
320
321uint16_t ONICALL bsl_getattacker(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
322{
323 //broken
324
325 int index;
326 if (numargs == 0) index = 0;
327 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
328 else index = args[0].value_int32;
329
330 Character* Chr = ONgGameState + 0x1260;
331 ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]);
332 if ((int)Active == 0) return 1;
333// ret->value_int32 = Active->LastDamageSourceCharacter;
334 ret->type = sl_int32;
335 return 0;
336}
337
338
339
340uint16_t ONICALL bsl_chrname(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
341{
342 int index;
343 if (numargs == 0) index = 0;
344 else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
345 else index = args[0].value_int32;
346 if (index == -1) {
347 ret->type = sl_str32;
348 ret->value_str32 = "NULL";
349 return 0;
350 }
351 char* name = ONgGameState + 0x1260 + index * 0x16A0 + 0x14;
352 if (numargs == 2) {
353 strncpy(name, (char*)args[1].value_str32, 31);
354 }
355
356 ret->type = sl_str32;
357 ret->value_str32 = name;
358
359 return 0;
360}
361
362
363uint16_t ONICALL bsl_count(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
364{
365 //testing numargs...
366 ret->type = sl_int32;
367 ret->value_int32 = numargs;
368 return 0;
369}
370
371uint16_t ONICALL bsl_dprintcolored(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
372{
373 //TODO: figure out why our implementation of dprint shows after dev mode is turned off
374 RGBA color;
375 RGBA shade;
376
377 if(numargs == 0) return 0;
378 if(numargs > 1 ) color.R = (char)args[1].value_int32;
379 else color.R = 255;
380 if(numargs > 2 ) color.G = (char)args[2].value_int32;
381 else color.G = 255;
382 if(numargs > 3 ) color.B = (char)args[3].value_int32;
383 else color.B = 255;
384 color.A = 0;
385 if(numargs > 5 ) shade.R = (char)args[5].value_int32;
386 else shade.R = 0x3F;
387 if(numargs > 6 ) shade.G = (char)args[6].value_int32;
388 else shade.G = 0x3F;
389 if(numargs > 7 ) shade.B = (char)args[7].value_int32;
390 else shade.B = 0x3F;
391 shade.A = 0;
392
393 DDrConsole_PrintColored(args[0].value_str32, 1, color, shade);
394 return 0;
395}
396
397
398uint16_t ONICALL bsl_nametoindex(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
399{
400
401 ret->type = sl_int32;
402 ret->value_int32 = DDrGetCharacterIndexFromName(args[0].value_str32);
403
404 return 0;
405}
406
407uint16_t ONICALL bsl_getactiveoffset(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
408{
409 DDrConsole_PrintF("Character: 0x%x",(int)ONgGameState + 0x1260);
410 DDrConsole_PrintF("ActiveChar: 0x%x",(int)ONrGetActiveCharacter((void*)((int)ONgGameState + 0x1260)));
411 return 0;
412}
413typedef struct {
414char Name[16];
415int Bit;
416} KeyBit;
417
418KeyBit Actions1[32] = {
419 {"Escape", Action_Escape},
420 {"Console", Action_Console},
421 {"PauseScreen", Action_PauseScreen},
422 {"Cutscene1", Action_Cutscene_1 },
423 {"Cutscene2", Action_Cutscene_2 },
424 {"F4", Action_F4 },
425 {"F5", Action_F5 },
426 {"F6", Action_F6 },
427 {"F7", Action_F7 },
428 {"F8", Action_F8 },
429 {"StartRecorn", Action_StartRecord },
430 {"StopRecord", Action_StopRecord },
431 {"PlayRecord", Action_PlayRecord },
432 {"F12", Action_F12 },
433 {"Unknown1", Action_Unknown1 },
434 {"LookMode", Action_LookMode },
435 {"Screenshot", Action_Screenshot },
436 {"Unknown2", Action_Unknown2 },
437 {"Unknown3", Action_Unknown3 },
438 {"Unknown4", Action_Unknown4 },
439 {"Unknown5", Action_Unknown5 },
440 {"Forward", Action_Forward },
441 {"Backward", Action_Backward },
442 {"TurnLeft", Action_TurnLeft },
443 {"TurnRight", Action_TurnRight },
444 {"StepLeft", Action_StepLeft },
445 {"StepRight", Action_StepRight },
446 {"Jump", Action_Jump },
447 {"Crouch", Action_Crouch },
448 {"Punch",Action_Punch },
449 {"Kick", Action_Kick },
450 {"Block", Action_Block }
451};
452
453KeyBit Actions2[9] = {
454 {"Walk", Action2_Walk},
455 {"Action", Action2_Action},
456 {"Hypo", Action2_Hypo},
457 {"Reload", Action2_Reload },
458 {"Swap", Action2_Swap },
459 {"Drop", Action2_Drop },
460 {"Fire1", Action2_Fire1 },
461 {"Fire2", Action2_Fire2 },
462 {"Fire3", Action2_Fire3 }
463};
464uint16_t ONICALL bsl_holdkey(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
465 {
466 int index;
467
468 if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
469 else index = args[0].value_int32;
470
471 Character* Chr = ONgGameState + 0x1260;
472 ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]);
473 if ((int)Active == 0) return 1;
474 int i = 2;
475 int j = 0;
476 int Input1 = 0;
477 int Input2 = 0;
478 for(i = 1; i < numargs - 1; i++) {
479 for(j = 0; j < 32; j++) {
480 if(!strcmp(args[i].value_str32, Actions1[j].Name)) {
481 Input1 = Input1 | Actions1[j].Bit;
482 }
483 }
484 for(j = 0; j < 9; j++) {
485 if(!strcmp(args[i].value_str32, Actions2[j].Name)) {
486 Input2 = Input2 | Actions2[j].Bit;
487 }
488 }
489 }
490 Active->Input.Current.Actions1 = Active->Input.Current.Actions1 | Input1;
491 Active->Input.Current.Actions2 = Active->Input.Current.Actions1 | Input2;
492 if( Input1 + Input2 == 0 ) {
493 DDrConsole_PrintF("Func \"%s\", File \"%s\", Line %d: semantic error, \"%s\": No valid keys given.", callinfo->name, callinfo->calllocation, callinfo->linenumber, callinfo->name);
494 return 0;
495 }
496 if ( args[numargs - 1].value_int32 <= 0) {
497 return 0;
498 }
499 else {
500 args[numargs - 1].value_int32 -= 1;
501 *dontuse2 = 1;
502 *dontuse1 = 1;
503 }
504 return 0;
505}
506
507uint16_t ONICALL bsl_isheld(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
508 {
509// int index;
510// if (numargs < 4) index = 0;
511// else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
512// else index = args[0].value_int32;
513
514// Character* Chr = ONgGameState + 0x1260;
515// ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]);
516// if ((int)Active == 0) return 1;
517 int i = 2;
518 int j = 0;
519 int Input1 = 0;
520 int Input2 = 0;
521 for(i = 0; i < numargs; i++) {
522 for(j = 0; j < 32; j++) {
523 //DDrConsole_PrintF("Testing %s against %s 0x%x", args[i].value_str32, Actions1[j].Name, Actions1[j].Bit);
524 if(!strcmp(args[i].value_str32, Actions1[j].Name)) {
525 Input1 = Input1 | Actions1[j].Bit;
526 //DDrConsole_PrintF("Success!");
527 }
528
529 }
530 for(j = 0; j < 9; j++) {
531 if(!strcmp(args[i].value_str32, Actions2[j].Name)) Input2 = Input2 | Actions2[j].Bit;
532
533 }
534 }
535 //DDrConsole_PrintF("Testing: 0x%x Input: 0x%x",Input1, *(int*)(ONgGameState + 0xB8 + 0x10));
536 ret->value_int32 = 0;
537 ret->type = sl_int32;
538 if ( ((*(int*)(ONgGameState + 0xB8 + 0x10) & Input1) == Input1) && ((*(int*)(ONgGameState + 0xB8 + 0x14) & Input2) == Input2)) ret->value_int32 = 1;
539 return 0;
540}
541
542uint16_t ONICALL bsl_waitforkey(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
543 {
544// int index;
545// if (numargs < 4) index = 0;
546// else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32);
547// else index = args[0].value_int32;
548
549// Character* Chr = ONgGameState + 0x1260;
550// ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]);
551// if ((int)Active == 0) return 1;
552 int i = 2;
553 int j = 0;
554 int Input1 = 0;
555 int Input2 = 0;
556 for(i = 0; i < numargs; i++) {
557 for(j = 0; j < 32; j++) {
558 //DDrConsole_PrintF("Testing %s against %s 0x%x", args[i].value_str32, Actions1[j].Name, Actions1[j].Bit);
559 if(!strcmp(args[i].value_str32, Actions1[j].Name)) {
560 Input1 = Input1 | Actions1[j].Bit;
561 //DDrConsole_PrintF("Success!");
562 }
563
564 }
565 for(j = 0; j < 9; j++) {
566 if(!strcmp(args[i].value_str32, Actions2[j].Name)) Input2 = Input2 | Actions2[j].Bit;
567
568 }
569 }
570 //DDrConsole_PrintF("Waiting...");
571 if ( ((*(int*)(ONgGameState + 0xB8 + 0x10) & Input1) == Input1) && ((*(int*)(ONgGameState + 0xB8 + 0x14) & Input2) == Input2)) {
572 }
573 else {
574 //else (int)*ret = 1;
575 *dontuse2 = 1;
576 *dontuse1 = 1;
577 }
578/*
579 __asm__(
580 "movl 0x10(%esp), %edx\n\t"
581 "movl $1,(%eax)\n\t"
582 );
583 //ret->type = sl_void
584*/ return 0;
585}
586
587/*
588uint16_t ONICALL bsl_sprintf(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
589{
590 if (numargs < 2)
591 return 1;
592
593 char output[255];
594 int i;
595 for(i = 1; i < numargs; i++) {
596 sprintf(output, args[0].value_str32, args[i].value_str32);
597 }
598
599 ret->value_str32 = output;
600 ret->type = sl_str32;
601 return 0;
602}
603*/
604uint16_t ONICALL bsl_sprintf(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
605{
606 if (numargs < 1 || args[0].type != sl_str32)
607 {
608 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);
609 return 0;
610 }
611
612 if (!args[0].value_str32)
613 args[0].value_str32 = "";
614
615 int ffi_ret;
616 char* str = NULL;
617 int size = 0;
618
619 ffi_cif cif;
620 ffi_type* ffi_args[256];
621 void* values[256];
622
623 ffi_args[0] = &ffi_type_pointer;
624 values[0] = &str;
625 ffi_args[1] = &ffi_type_uint32;
626 values[1] = &size;
627
628 int i;
629 for(i = 2; i < numargs + 2; i ++)
630 {
631 if (args[i - 2].type == sl_float)
632 {
633 float value_float = args[i - 2].value_float;
634 double* value_double = (double*)&(args[i - 2]);
635 *value_double = value_float;
636
637 ffi_args[i] = &ffi_type_double;
638 values[i] = value_double;
639 }
640 else
641 {
642 ffi_args[i] = &ffi_type_pointer;
643 values[i] = &(args[i - 2].value);
644 }
645 }
646
647 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, i, &ffi_type_sint32, ffi_args) != FFI_OK)
648 return 1;
649 ffi_call(&cif, (void*)snprintf, (void*)&ffi_ret, values);
650 str = malloc(ffi_ret + 1);
651 size = ffi_ret + 1;
652 ffi_call(&cif, (void*)snprintf, (void*)&ffi_ret, values);
653 ret->value_str32 = str;
654 ret->type = sl_str32;
655 return 0;
656}
657
658// Widescreen patch for talking heads.
659uint16_t ONICALL cinematic_start_patch(sl_callinfo* callinfo, unsigned int numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
660{
661 args[1].value_int32 = (double)args[1].value_int32 / (double)(gl->DisplayMode.Width) * (4.0 / 3.0 * (double)(gl->DisplayMode.Height));
662 return ((sl_func)(OniExe + 0x000f3830))(callinfo, numargs, args, dontuse1, dontuse2, ret);
663}
664
665bool ini_inbsl = false;
666bool SLrIniCallback(char* section, bool newsection, char* name, char* value)
667{
668 if (newsection && !stricmp(section, "bsl"))
669 ini_inbsl = true;
670
671 if (ini_inbsl)
672 {
673 bool isptr = false;
674 sl_type bsl_type;
675
676 if (value[0] == 'p' && value[1] == 't' && value[2] == 'r' && value[3] == ':')
677 {
678 isptr = true;
679 value += 4;
680 }
681
682 char* type = value;
683
684 for (; *type; type++)
685 if (*type == ':')
686 {
687 *type = '\0';
688 type++;
689 break;
690 }
691
692 if (!*type)
693 DDrStartupMessage("badly formed bsl definition for \"%s\"", name);
694
695 if (!strcmp(type, "int"))
696 bsl_type = sl_int32;
697 else if (!strcmp(type, "string"))
698 bsl_type = sl_str32;
699 else if (!strcmp(type, "float"))
700 bsl_type = sl_float;
701 else if (!strcmp(type, "bool"))
702 bsl_type = sl_bool;
703 else
704 {
705 DDrStartupMessage("unknown type in bsl definition for \"%s\"", name);
706 return true;
707 }
708
709 if (isptr)
710 {
711 char* bsl_var = malloc(strlen(name) + 1);
712 memcpy(bsl_var, name, strlen(name) + 1);
713 switch (bsl_type)
714 {
715 case sl_int32:
716 SLrGlobalVariable_Register_Int32(bsl_var, "see daodan.ini", (int32_t*)(uint32_t)inifile_parseint(value, false));
717 break;
718 case sl_float:
719 SLrGlobalVariable_Register_Float(bsl_var, "see daodan.ini", (float*)(uint32_t)inifile_parseint(value, false));
720 break;
721 default:
722 break;
723 }
724 }
725 else
726 {
727 char* bsl_var = malloc(strlen(name) + 1 + sizeof(int32_t));
728 int32_t* bsl_val = (int32_t*)bsl_var;
729 bsl_var += sizeof(int32_t);
730 memcpy(bsl_var, name, strlen(name) + 1);
731
732 switch (bsl_type)
733 {
734 case sl_int32:
735 *bsl_val = inifile_parseint(value, false);
736 SLrGlobalVariable_Register_Int32(bsl_var, "see daodan.ini", bsl_val);
737 break;
738 case sl_float:
739 break;
740 default:
741 break;
742 }
743 }
744 }
745 return true;
746}
747
748void SLrConfig()
749{
750 DDrStartupMessage("re-parsing daodan.ini for bsl...");
751 inifile_read("daodan.ini", SLrIniCallback);
752 DDrStartupMessage("finished parsing");
753}
754
755void SLrDaodan_Initalize()
756{
757
758
759 //Calculating the value of the needed offset is much more reliable when the compiler does it for you.
760
761 //TODO: fix moonshadow.
762 Character * Chr = 0;
763 char NoPath = (char)(0x100 - (int)(Chr->ScriptNoPath));
764 const char regen_patch[] =
765 {0x90, 0x90, 0x90, 0x90, 0x90, // mov al, _WPgRegenerationCheat
766 0x90, 0x90, // test al, al
767 0x90, 0x90, // jz short loc_51BB98
768 0x8B, 0x86, NoPath};
769 DDrPatch_Const(OniExe + 0x0011BB64, regen_patch);
770
771 SLrConfig();
772
773 SLrScript_Command_Register_ReturnType("int32mul", "Multiplies two numbers", "n1:int n2:int", sl_int32, bsl_int32mul);
774 SLrScript_Command_Register_ReturnType("mul", "Multiplies two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_mul);
775
776 SLrScript_Command_Register_ReturnType("int32div", "Divides two numbers", "n1:int n2:int", sl_int32, bsl_int32div);
777 SLrScript_Command_Register_ReturnType("div", "Divides two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_div);
778
779 dsfmt_gv_init_gen_rand((uint32_t)time(NULL));
780 SLrScript_Command_Register_ReturnType("int32rand", "Returns a pseudo-random number between two numbers (inclusive).", "start:int end:int", sl_int32, bsl_int32rand);
781
782 SLrScript_Command_Register_ReturnType("d_getkills","Gets the number of kills a character has", "[ai_name:str | script_id:int]", sl_int32, bsl_getkills);
783 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);
784 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);
785 SLrScript_Command_Register_ReturnType("d_getindex","Converts a character's name to its index", "ai_name:string", sl_int32, bsl_nametoindex);
786 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);
787 SLrScript_Command_Register_ReturnType("d_regen","Gets or sets a character's health", "[ai_name:str | script_id:int] [newhealth:int]", sl_str32, bsl_regen);
788 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);
789 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);
790 SLrScript_Command_Register_ReturnType("d_holdkey","Makes a character hold a key", "[ai_name:string | script_id:int] keys frames:int", sl_int32, bsl_holdkey);
791 SLrScript_Command_Register_ReturnType("d_isheld","Checks if player is holding a key", "keys", sl_int32, bsl_isheld);
792 SLrScript_Command_Register_ReturnType("d_location","Returns the X, Y or Z coord of a character", "ai_name:str | script_id:int xyz:string [newlocation:float]", sl_float, bsl_location);
793 SLrScript_Command_Register_ReturnType("d_distance","Returns the distance between two characters", "ai_name:str | script_id:int ai_name:str | script_id:int ", sl_float, bsl_distance);
794 SLrScript_Command_Register_Void("d_waitforkey","Waits for a keypress from the player", "keys", bsl_waitforkey);
795
796 //broken, only works for one damage type.
797 //SLrScript_Command_Register_ReturnType("d_getattacker","Gets the last person to hurt a character", "[ai_name:string | script_id:int]", sl_int32, bsl_getattacker);
798
799 //used for debugging.
800 SLrScript_Command_Register_ReturnType("d_active","Returns a hex offset. ;)", "[ai_name:string | script_id:int]", sl_int32, bsl_getactiveoffset);
801
802 SLrScript_Command_Register_ReturnType("sprintf", "C-style sprintf.", "format:string arg1 arg2 ...", sl_str32, bsl_sprintf);
803
804 SLrScript_Command_Register_ReturnType("st", "prints to console in color", "text:string [color: r b g] [color: r b g]", sl_void, bsl_dprintcolored);
805
806 //Flatline
807 SLrFlatline_Initialize();
808
809}
810
811void SLrDaodan_Patch()
812{
813 DDrPatch_Int32(OniExe + 0x000f3755, (int)cinematic_start_patch);
814}
Note: See TracBrowser for help on using the repository browser.