#include #include "bool.h" #include //#include #include #include "inifile.h" #include "Daodan_BSL.h" #include "Daodan_Utility.h" #include "Daodan_Patch.h" #include "Daodan_Console.h" #include "BFW_ScriptLang.h" #include "Oni.h" #include "Oni_Character.h" #include "oni_gl.h" #include "Daodan_Character.h" #include "BFW_Utility.h" uint16_t ONICALL bsl_int32mul(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { ret->value_int32 = args[0].value_int32 * args[1].value_int32; ret->type = sl_int32; return 0; } uint16_t ONICALL bsl_mul(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { double val1; double val2; if (args[0].type == sl_int32) val1 = args[0].value_int32; else val1 = args[0].value_float; if (args[1].type == sl_int32) val2 = args[1].value_int32; else val2 = args[1].value_float; ret->value_float = (float)(val1 * val2); ret->type = sl_float; return 0; } uint16_t ONICALL bsl_int32div(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { ret->value_int32 = args[0].value_int32 / args[1].value_int32; ret->type = sl_int32; return 0; } uint16_t ONICALL bsl_div(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { double val1; double val2; if (args[0].type == sl_int32) val1 = args[0].value_int32; else val1 = args[0].value_float; if (args[1].type == sl_int32) val2 = args[1].value_int32; else val2 = args[1].value_float; ret->value_float = (float)(val1 / val2); ret->type = sl_float; return 0; } uint16_t ONICALL bsl_int32rand(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int32_t start = 0; int32_t end = 0; if (args[0].value_int32 == args[1].value_int32) return 1; else if (args[0].value_int32 > args[1].value_int32) { start = args[1].value_int32; end = args[0].value_int32; } else { start = args[0].value_int32; end = args[1].value_int32; } ret->value_int32 = start + (rand() % (uint32_t)(end - start + 1)); ret->type = sl_int32; return 0; } uint16_t ONICALL bsl_getkills(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; if (numargs == 0) index = 0; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; //killcount = ONgGameState->CharacterStorage[index].Kills; //ONgGameState + index * 0x16A0 + 0x1260 + 0x1670; ret->value_int32 = ONgGameState->CharacterStorage[index].Kills; ret->type = sl_int32; return 0; } uint16_t ONICALL bsl_getdamage(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; if (numargs == 0) index = 0; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; ret->value_int32 = ONgGameState->CharacterStorage[index].Damage; ret->type = sl_int32; return 0; } uint16_t ONICALL bsl_powerup(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; void* returnval; bool is_lsi = 0; Character* Chr = ONgGameState->CharacterStorage; if (numargs < 2 || args[1].type != sl_str32) return 1; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; if(!strcmp(args[1].value_str32,"ammo")) { returnval = &(Chr[index].Inventory.AmmoUsed); } else if(!strcmp(args[1].value_str32,"hypo")) { returnval = &(Chr[index].Inventory.HypoUsed); } else if(!strcmp(args[1].value_str32,"cells")) { returnval = &(Chr[index].Inventory.CellsUsed); } else if(!strcmp(args[1].value_str32,"invis")) { returnval = &(Chr[index].Inventory.CloakUsed); } else if(!strcmp(args[1].value_str32,"shield")) { returnval = &(Chr[index].Inventory.ShieldUsed); } else if(!strcmp(args[1].value_str32,"lsi")) { returnval = &(Chr[index].Inventory.hasLSI); is_lsi = 1; } // else if(!strcmp(args[1].value_str32,"bossshield")) // { // ret->value_int32 = Chr[index].Flags & char_bossshield; // ret->type = sl_int32; // if (numargs >=3) { // if (Chr[index].Flags & char_bossshield) Chr[index].Flags = Chr[index].Flags & ~char_bossshield; // else Chr[index].Flags = Chr[index].Flags | char_bossshield; // } // return 0; // } else return 1; //todo, add setting if(is_lsi) ret->value_int32 = (int)*(bool*)returnval; else ret->value_int32 = *(int*)returnval; ret->type = sl_int32; if (numargs >= 3) { if(is_lsi) *(bool*)returnval = args[2].value_int32; else *(int*)returnval = args[2].value_int32; } return 0; } uint16_t ONICALL bsl_health(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; Character* Chr; int* health; if (numargs == 0) index = 0; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; Chr = ONgGameState->CharacterStorage; health = &Chr[index].Health; ret->value_int32 = *health; ret->type = sl_int32; if (args[1].value_int32) { *health = args[1].value_int32; } ret->value_int32 = *health; ret->type = sl_int32; return 0; } uint16_t ONICALL bsl_regen(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; Character* Chr; if (numargs == 0) index = 0; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; Chr = ONgGameState->CharacterStorage ; /* DDrConsole_PrintF("Character %s", Chr[index].Name); DDrConsole_PrintF("Spawn %s", Chr[index].ScriptSpawn); DDrConsole_PrintF("Death %s", Chr[index].ScriptDie); DDrConsole_PrintF("Aware %s", Chr[index].ScriptAware); DDrConsole_PrintF("Alarm %s", Chr[index].ScriptAlarm); DDrConsole_PrintF("Hurt %s", Chr[index].ScriptHurt); DDrConsole_PrintF("Defeat %s", Chr[index].ScriptDefeat); DDrConsole_PrintF("NoAmmo %s", Chr[index].ScriptNoAmmo); DDrConsole_PrintF("NoPath %s", Chr[index].ScriptNoPath); */ ret->value_int32 = Chr[index].RegenHax; ret->type = sl_int32; if (numargs >= 2) { Chr[index].RegenHax = args[1].value_int32; } return 0; } //wow this is broken. uint16_t ONICALL bsl_distance(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; int index2; Character* Chr = ONgGameState->CharacterStorage; Character* Char1; Character* Char2; if (numargs < 2) return 1; if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; if (index == -1) index = args[0].value_int32; if (args[1].type == sl_str32) index2 = DDrGetCharacterIndexFromName(args[1].value_str32); else index2 = args[1].value_int32; if (index2 == -1) index2 = args[1].value_int32; Char1 = &Chr[index]; Char2 = &Chr[index2]; 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)); ret->type = sl_float; return 0; } uint16_t ONICALL bsl_location(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index, i; float* loc; Character* Chr; numargs = 0; for(i = 0; args[i].type < sl_void; i++) { numargs++; } if (numargs < 2) return 1; if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; if (index == -1) index = args[0].value_int32; Chr = ONgGameState->CharacterStorage; if(numargs == 3) { if (!strcmp(args[1].value_str32,"X") || !strcmp(args[1].value_str32,"x")) loc = &(Chr[index].Position.X); else if (!strcmp(args[1].value_str32,"Y") || !strcmp(args[1].value_str32,"y")) loc = &(Chr[index].Position.Y); else if (!strcmp(args[1].value_str32,"Z") || !strcmp(args[1].value_str32,"z")) loc = &(Chr[index].Position.Z); } else if (numargs == 4) { ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]); Chr[index].Location.X = args[1].value_float; Chr[index].Location.Y = args[2].value_float; Chr[index].Location.Z = args[3].value_float; if(Active) { Active->PhyContext->Position = Chr[index].Location; } ret->value_float = 1; ret->type = sl_float; return 0; } else return 1; ret->value_float = *loc; ret->type = sl_float; if(numargs == 3) { //currently broken, does nothing. *loc = args[2].value_float; } return 0; } uint16_t ONICALL bsl_maxhealth(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; if (numargs == 0) index = 0; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; if(1) { Character* Chr = ONgGameState->CharacterStorage ; int* maxhealth = &Chr[index].MaxHealth; int oldmaxhealth = Chr[index].MaxHealth; int oldhealth = Chr->Health; if (numargs >= 2) { *maxhealth = args[1].value_int32; } if (numargs >= 3 && args[2].value_bool) { Chr->Health = (int)(((float)args[1].value_int32 / (float)oldmaxhealth) * (float)oldhealth); } ret->value_int32 = oldmaxhealth; ret->type = sl_int32; return 0; } } uint16_t ONICALL bsl_getattacker(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { //broken int index; if (numargs == 0) index = 0; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; if(1) { Character* Chr = ONgGameState->CharacterStorage; ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]); if (!Active) return 1; // ret->value_int32 = Active->LastDamageSourceCharacter; ret->type = sl_int32; return 0; } } uint16_t ONICALL bsl_chrname(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int index; char* name; if (numargs == 0) index = 0; else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; if (index == -1) { ret->type = sl_str32; ret->value_str32 = "NULL"; return 0; } name = &ONgGameState->CharacterStorage[index].Name; if (numargs == 2) { strncpy(name, (char*)args[1].value_str32, 31); } ret->type = sl_str32; ret->value_str32 = name; return 0; } uint16_t ONICALL bsl_count(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { //testing numargs... ret->type = sl_int32; ret->value_int32 = numargs; return 0; } uint16_t ONICALL bsl_dprintcolored(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { //TODO: figure out why our implementation of dprint shows after dev mode is turned off RGBA color; RGBA shade; int i; numargs = 0; for(i = 0; args[i].type < sl_void; i++) { numargs++; } if(numargs == 0) return 0; if(numargs > 1 ) color.R = (char)args[1].value_int32; else color.R = 255; if(numargs > 2 ) color.G = (char)args[2].value_int32; else color.G = 255; if(numargs > 3 ) color.B = (char)args[3].value_int32; else color.B = 255; color.A = 0; if(numargs > 5 ) shade.R = (char)args[5].value_int32; else shade.R = 0x3F; if(numargs > 6 ) shade.G = (char)args[6].value_int32; else shade.G = 0x3F; if(numargs > 7 ) shade.B = (char)args[7].value_int32; else shade.B = 0x3F; shade.A = 0; DDrConsole_PrintColored(args[0].value_str32, 1, color, shade); return 0; } uint16_t ONICALL bsl_nametoindex(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { ret->type = sl_int32; ret->value_int32 = DDrGetCharacterIndexFromName(args[0].value_str32); return 0; } typedef struct { char Name[16]; int Bit; } KeyBit; KeyBit Actions1[32] = { {"Escape", Action_Escape}, {"Console", Action_Console}, {"PauseScreen", Action_PauseScreen}, {"Cutscene1", Action_Cutscene_1 }, {"Cutscene2", Action_Cutscene_2 }, {"F4", Action_F4 }, {"F5", Action_F5 }, {"F6", Action_F6 }, {"F7", Action_F7 }, {"F8", Action_F8 }, {"StartRecorn", Action_StartRecord }, {"StopRecord", Action_StopRecord }, {"PlayRecord", Action_PlayRecord }, {"F12", Action_F12 }, {"Unknown1", Action_Unknown1 }, {"LookMode", Action_LookMode }, {"Screenshot", Action_Screenshot }, {"Unknown2", Action_Unknown2 }, {"Unknown3", Action_Unknown3 }, {"Unknown4", Action_Unknown4 }, {"Unknown5", Action_Unknown5 }, {"Forward", Action_Forward }, {"Backward", Action_Backward }, {"TurnLeft", Action_TurnLeft }, {"TurnRight", Action_TurnRight }, {"StepLeft", Action_StepLeft }, {"StepRight", Action_StepRight }, {"Jump", Action_Jump }, {"Crouch", Action_Crouch }, {"Punch",Action_Punch }, {"Kick", Action_Kick }, {"Block", Action_Block } }; KeyBit Actions2[9] = { {"Walk", Action2_Walk}, {"Action", Action2_Action}, {"Hypo", Action2_Hypo}, {"Reload", Action2_Reload }, {"Swap", Action2_Swap }, {"Drop", Action2_Drop }, {"Fire1", Action2_Fire1 }, {"Fire2", Action2_Fire2 }, {"Fire3", Action2_Fire3 } }; uint16_t ONICALL bsl_holdkey(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { uint32_t index; uint32_t i = 2; uint32_t j = 0; int Input1 = 0; int Input2 = 0; Character* Chr; ActiveCharacter* Active; if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); else index = args[0].value_int32; Chr = &(ONgGameState->CharacterStorage[index]); Active = ONrGetActiveCharacter(Chr); if (!Active) return 1; for(i = 1; i < numargs - 1; i++) { for(j = 0; j < 32; j++) { if(!strcmp(args[i].value_str32, Actions1[j].Name)) { Input1 = Input1 | Actions1[j].Bit; } } for(j = 0; j < 9; j++) { if(!strcmp(args[i].value_str32, Actions2[j].Name)) { Input2 = Input2 | Actions2[j].Bit; } } } Active->Input.Current.Actions1 = Active->Input.Current.Actions1 | Input1; Active->Input.Current.Actions2 = Active->Input.Current.Actions2 | Input2; if( Input1 + Input2 == 0 ) { DDrConsole_PrintF("Func \"%s\", File \"%s\", Line %d: semantic error, \"%s\": No valid keys given.", callinfo->name, callinfo->calllocation, callinfo->linenumber, callinfo->name); return 0; } if ( args[numargs - 1].value_int32 <= 0) { return 0; } else { args[numargs - 1].value_int32 -= 1; *dontuse2 = 1; *dontuse1 = 1; } return 0; } uint16_t ONICALL bsl_isheld(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { // int index; // if (numargs < 4) index = 0; // else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); // else index = args[0].value_int32; // Character* Chr = ONgGameState->CharacterStorage; // ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]); // if ((int)Active == 0) return 1; uint32_t i = 2; uint32_t j = 0; int Input1 = 0; int Input2 = 0; for(i = 0; i < numargs; i++) { for(j = 0; j < 32; j++) { //DDrConsole_PrintF("Testing %s against %s 0x%x", args[i].value_str32, Actions1[j].Name, Actions1[j].Bit); if(!strcmp(args[i].value_str32, Actions1[j].Name)) { Input1 = Input1 | Actions1[j].Bit; //DDrConsole_PrintF("Success!"); } } for(j = 0; j < 9; j++) { if(!strcmp(args[i].value_str32, Actions2[j].Name)) Input2 = Input2 | Actions2[j].Bit; } } //DDrConsole_PrintF("Testing: 0x%x Input: 0x%x",Input1, *(int*)(ONgGameState + 0xB8 + 0x10)); ret->value_int32 = 0; ret->type = sl_int32; if ( (ONgGameState->Input.Current.Actions1 == Input1) && (ONgGameState->Input.Current.Actions2 == Input2)) ret->value_int32 = 1; return 0; } uint16_t ONICALL bsl_waitforkey(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { // int index; // if (numargs < 4) index = 0; // else if (args[0].type == sl_str32) index = DDrGetCharacterIndexFromName(args[0].value_str32); // else index = args[0].value_int32; // Character* Chr = ONgGameState->CharacterStorage; // ActiveCharacter* Active = (ActiveCharacter*)ONrGetActiveCharacter(&Chr[index]); // if ((int)Active == 0) return 1; int i = 2; int j = 0; int Input1 = 0; int Input2 = 0; /* numargs = 0; for(i = 0; args[i].type <= sl_void; i++) { //DDrConsole_PrintF("%i", args[i].type ); numargs++; } if(numargs < 1 || args[0].value == 0) return; //for(i = 0; i < numargs; i++) { */ i = 0; for(j = 0; j < 32; j++) { //DDrConsole_PrintF("Testing %s against %s 0x%x", args[i].value_str32, Actions1[j].Name, Actions1[j].Bit); if(!strcmp(args[i].value_str32, Actions1[j].Name)) { Input1 = Input1 | Actions1[j].Bit; //DDrConsole_PrintF("Success!"); } } for(j = 0; j < 9; j++) { if(!strcmp(args[i].value_str32, Actions2[j].Name)) Input2 = Input2 | Actions2[j].Bit; } // } DDrConsole_PrintF("Waiting..."); if ( (( ONgGameState->Input.Current.Actions1 & Input1) == Input1) && (( ONgGameState->Input.Current.Actions2 & Input2) == Input2) ) { DDrConsole_PrintF("Found key!"); } else { //else (int)*ret = 1; *dontuse2 = 1; *dontuse1 = 1; } return 0; } uint16_t ONICALL bsl_sprintf(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { char output[1024]; char buffer[1024]; int i; char* placeinoutput = output; char* placeininput = args[0].value_str32; int formatnum = 0; //fix the broken bsl numargs... numargs = 0; for(i = 0; args[i].type < sl_void; i++) { numargs++; } if (numargs < 1) return 1; while(1) { int size; //s is the pointer to the args char* s = strchr(placeininput , '%'); //we didnt find a %, break! if(!s) { strcpy(placeinoutput, placeininput); break; } size = (int)s - (int)placeininput ; //we found one, so copy the portion of string memcpy( placeinoutput,placeininput, size); placeininput += size; placeinoutput += size; memset( placeinoutput, '%', (int)pow(2, formatnum)); placeinoutput += (int)pow(2, formatnum); placeininput += 1; *placeinoutput = 0; formatnum++; } //strcpy( output, args[0].value_str32 ); for(i = 1; i < numargs; i++) { //sprintf(output, output, args[i].value_str32); memcpy(buffer, output, 1024); if(args[i].value == 0) break; switch(args[i].type) { case sl_bool: case sl_int32: sprintf(output, buffer, args[i].value_int32); break; case sl_float: //crashes oni, why? // sprintf(output, output, args[i].value_float); break; case sl_str32: sprintf(output, buffer, args[i].value_str32); break; case sl_void: default: break; } } //output[32] = 0; ret->value_str32 = output; ret->type = sl_str32; return 0; } //Sorry rossy, I broke this. FFI isnt in windows /* uint16_t ONICALL bsl_sprintf(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { int ffi_ret; char* str = NULL; int size = 0; ffi_cif cif; ffi_type* ffi_args[256]; void* values[256]; int i; numargs = 0; for(i = 0; args[i].type <= sl_void; i++) { //DDrConsole_PrintF("%i", args[i].type ); numargs++; } if (numargs < 1 || args[0].type != sl_str32) { 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); return 0; } if (!args[0].value_str32) args[0].value_str32 = ""; ffi_args[0] = &ffi_type_pointer; values[0] = &str; ffi_args[1] = &ffi_type_uint32; values[1] = &size; for(i = 2; i < numargs + 2; i ++) { if (args[i - 2].type == sl_float) { float value_float = args[i - 2].value_float; double* value_double = (double*)&(args[i - 2]); *value_double = value_float; ffi_args[i] = &ffi_type_double; values[i] = value_double; } else { ffi_args[i] = &ffi_type_pointer; values[i] = &(args[i - 2].value); } } if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, i, &ffi_type_sint32, ffi_args) != FFI_OK) return 1; ffi_call(&cif, (void*)_snprintf, (void*)&ffi_ret, values); str = malloc(ffi_ret + 1); size = ffi_ret + 1; ffi_call(&cif, (void*)_snprintf, (void*)&ffi_ret, values); ret->value_str32 = str; ret->type = sl_str32; return 0; } */ // Widescreen patch for talking heads. uint16_t ONICALL cinematic_start_patch(sl_callinfo* callinfo, unsigned int numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { args[1].value_int32 = (double)args[1].value_int32 / (double)(gl_eng->DisplayMode.Width) * (4.0 / 3.0 * (double)(gl_eng->DisplayMode.Height)); return ((sl_func)(OniExe + 0x000f3830))(callinfo, numargs, args, dontuse1, dontuse2, ret); } bool ini_inbsl = false; bool SLrIniCallback(char* section, bool newsection, char* name, char* value) { if (newsection && !_stricmp(section, "bsl")) ini_inbsl = true; if (ini_inbsl) { char* type = value; bool isptr = false; sl_type bsl_type; if (value[0] == 'p' && value[1] == 't' && value[2] == 'r' && value[3] == ':') { isptr = true; value += 4; } for (; *type; type++) if (*type == ':') { *type = '\0'; type++; break; } if (!*type) DDrStartupMessage("badly formed bsl definition for \"%s\"", name); if (!strcmp(type, "int")) bsl_type = sl_int32; else if (!strcmp(type, "string")) bsl_type = sl_str32; else if (!strcmp(type, "float")) bsl_type = sl_float; else if (!strcmp(type, "bool")) bsl_type = sl_bool; else { DDrStartupMessage("unknown type in bsl definition for \"%s\"", name); return true; } if (isptr) { char* bsl_var = malloc(strlen(name) + 1); memcpy(bsl_var, name, strlen(name) + 1); switch (bsl_type) { case sl_int32: SLrGlobalVariable_Register_Int32(bsl_var, "see daodan.ini", (int32_t*)(uint32_t)inifile_parseint(value, false)); break; case sl_float: SLrGlobalVariable_Register_Float(bsl_var, "see daodan.ini", (float*)(uint32_t)inifile_parseint(value, false)); break; default: break; } } else { char* bsl_var = malloc(strlen(name) + 1 + sizeof(int32_t)); int32_t* bsl_val = (int32_t*)bsl_var; bsl_var += sizeof(int32_t); memcpy(bsl_var, name, strlen(name) + 1); switch (bsl_type) { case sl_int32: *bsl_val = inifile_parseint(value, false); SLrGlobalVariable_Register_Int32(bsl_var, "see daodan.ini", bsl_val); break; case sl_float: break; default: break; } } } return true; } void SLrConfig() { DDrStartupMessage("re-parsing daodan.ini for bsl..."); inifile_read("daodan.ini", SLrIniCallback); DDrStartupMessage("finished parsing"); } void ONICALL SLrDaodan_Register_ReturnType(char* name, char* desc, char* argfmt, sl_type type, sl_func callback) { char argfmt2[512]; uint16_t errornum; if (argfmt && strlen(argfmt) < 507) { sprintf(argfmt2, "%s [|]", argfmt); errornum = SLrScript_Command_Register_ReturnType(name, desc, argfmt2, type, callback); if(errornum) { DDrStartupMessage("Registration of script command %s failed with error %i", name, errornum); } } else { DDrStartupMessage("Registration of script command %s failed because of a too long argfmt", name); } } void* TSrTest = 0; uint16_t ONICALL new_text(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret) { void* TSFFTahoma; int returnval; if(!TSrTest){ TMrInstance_GetDataPtr( 'TSFF', "Tahoma", &TSFFTahoma); returnval = TSrContext_New( TSFFTahoma, 7, 1, 1, 0, &TSrTest); } DDrPatch_MakeCall(0x004FBCEA, DDrText_Hook); *dontuse2 = 1; return 0; } void SLrDaodan_Initalize() { SLrConfig(); SLrScript_Command_Register_Void("debug_daodan","Adds text to screen", "", new_text); SLrScript_Command_Register_ReturnType("int32mul", "Multiplies two numbers", "n1:int n2:int", sl_int32, bsl_int32mul); SLrScript_Command_Register_ReturnType("mul", "Multiplies two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_mul); SLrScript_Command_Register_ReturnType("int32div", "Divides two numbers", "n1:int n2:int", sl_int32, bsl_int32div); SLrScript_Command_Register_ReturnType("div", "Divides two numbers", "[int1:int|float1:float] [int2:int|float2:float]", sl_float, bsl_div); srand((uint32_t)time(NULL)); SLrScript_Command_Register_ReturnType("int32rand", "Returns a pseudo-random number between two numbers (inclusive).", "start:int end:int", sl_int32, bsl_int32rand); SLrScript_Command_Register_ReturnType("d_getkills","Gets the number of kills a character has", "[ai_name:string | script_id:int] [|]", sl_int32, bsl_getkills); 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); SLrScript_Command_Register_ReturnType("d_name","Gets or sets a character's name", "[ai_name:string | script_id:int] [newname:string|]", sl_str32, bsl_chrname); SLrScript_Command_Register_ReturnType("d_getindex","Converts a character's name to its index", "ai_name:string", sl_int32, bsl_nametoindex); SLrScript_Command_Register_ReturnType("d_health","Gets or sets a character's health", "[ai_name:string | script_id:int] [newhealth:int]", sl_str32, bsl_health); SLrScript_Command_Register_ReturnType("d_regen","Gets or sets a character's regeneration abilities", "[ai_name:string | script_id:int] [newhealth:int]", sl_str32, bsl_regen); SLrScript_Command_Register_ReturnType("d_maxhealth","Gets or sets a character's maximum health", "[ai_name:string | script_id:int] [newmaxhealth:int] [scalehealth:bool]", sl_str32, bsl_maxhealth); SLrScript_Command_Register_ReturnType("d_powerup","Gets or sets a character's powerups", "[ai_name:string | script_id:int] powerup:string", sl_int32, bsl_powerup); //d_holdkey is broken! SLrScript_Command_Register_ReturnType("d_holdkey","Makes a character hold a key", "[ai_name:string | script_id:int] frames:int keys:string", sl_int32, bsl_holdkey); SLrScript_Command_Register_ReturnType("d_isheld","Checks if player is holding a key", "[ai_name:string | script_id:int] [keys:string]", sl_int32, bsl_isheld); SLrScript_Command_Register_ReturnType("d_location","Returns the X, Y or Z coord of a character", "", sl_float, bsl_location); SLrScript_Command_Register_ReturnType("d_distance","Returns the distance between two characters", "ai_name:string | script_id:int ai_name:string | script_id:int", sl_float, bsl_distance); SLrScript_Command_Register_Void("d_waitforkey","Waits for a keypress from the player", "key:string", bsl_waitforkey); //broken, only works for one damage type. //SLrDaodan_Register_ReturnType("d_getattacker","Gets the last person to hurt a character", "[ai_name:string | script_id:int]", sl_int32, bsl_getattacker); //used for debugging. // SLrDaodan_Register_ReturnType("d_active","Returns a hex offset. ;)", "[ai_name:string | script_id:int]", sl_int32, bsl_getactiveoffset); SLrScript_Command_Register_Void("sprintf", "C-style sprintf.", "", bsl_sprintf); SLrScript_Command_Register_ReturnType("st", "prints to console in color", "", sl_void, bsl_dprintcolored); SLrScript_Command_Register_ReturnType("d_dprint", "prints to console in color", "", sl_void, bsl_dprintcolored); } void SLrDaodan_Patch() { DDrPatch_Int32(OniExe + 0x000f3755, (int)cinematic_start_patch); }