//Version 0.5.6 for RPG.zh 0.9.6.1 //Backup Arrays int GameEvents[214747]; //Main array. bool GameDynamics[214747]; //We shouldn't use this. //Backup Arrays bool Equipment_BAK[256]; int GameDynamics_BAK[8192]; bool GameEvents_BAL[8192]; int Counters_BAK[32]; int MCounters_BAK[32]; //DMap Saving const int HIGHEST_DMAP_ID = 100; //Set to the highest numbered DMap in the quest. //Screen D (10 per screen) int ScreenD_BAK[213760]; //Holds 167 DMaps of Screen->D const int SCREEN_D_OFFSET = 1280; void BackupScreenD(){ for ( int q = 0; q < HIGHEST_DMAP_ID; q++ ) { //dmap for ( int w = 0; w < 128; w++ ) { //screen for ( int e = 0; e < 10; e++ ) { //reg ScreenD_BAK[ ( SCREEN_D_OFFSET*q ) + (w* 10) + e ] = Game->GetDMapScreenD(q,w,e); //I hope this calc is proper. } } } } void RestoreScreenD(){ for ( int q = 0; q < HIGHEST_DMAP_ID; q++ ) { //dmap for ( int w = 0; w < 128; w++ ) { //screen for ( int e = 0; e < 10; e++ ) { //reg Game->SetDMapScreenD(q,w,e, ScreenD_BAK[( SCREEN_D_OFFSET*q ) + (w* 10) + e]; //likewise... } } } } //Dmap 10, screen 16, reg 0 // //Screen->State ( 15 per screen , 1920 per dmap ) //111 dmaps bool ScreenState_BAK[213120]; //111 DMaps void BackupScreenState(){ for ( int q = 0; q < HIGHEST_DMAP_ID; q++ ) { //dmap for ( int w = 0; w < 128; w++ ) { //screen for ( int e = 0; e < 10; e++ ) { //reg ScreenState_BAK[ ( SCREEN_D_OFFSET*q ) + (w* 15) + e ] = Game->GetScreenState(Game->DMapOffset[q],w,e); //I hope this calc is proper. } } } } void RestoreScreenState(){ for ( int q = 0; q < HIGHEST_DMAP_ID; q++ ) { //dmap for ( int w = 0; w < 128; w++ ) { //screen for ( int e = 0; e < 15; e++ ) { //secrets index Game->SetScreenState(Game->DMapOffset[q],w,e, ScreenState_BAK[( SCREEN_D_OFFSET*q ) + (w* 15) + e]); //likewise... } } } } int ScreenDoors[214528]; void SetScreenDoors(){ int doors[4]; int q; bool match; if ( !SaveFlags(BACKUP_DOORS) ) { //Stores the doors on this screen when we visit it, if they differ from what s stored. for ( q = 0; q < 4; q++ ) doors[q] = ScreenDoors[ ( Game->GetCurDMap()*512 ) + Game->GetCurScreen() + q]; for ( q = 0; q < 4; q++ ) { if ( Screen->Door[q] == doors[q] ) match = true; else { match = false; break; } } if ( !match ) { //if the doors differ, save them. for ( q = 0; q < 4; q++ ) ScreenDoors[ ( Game->GetCurDMap()*512 ) + Game->GetCurScreen() + q] = Screen->Doors[q]; } } else { //We load the from the backup datum. //This is still a problem. } } //Flid this is a wretched pain in the arse. ... //We need a way to tell the game that we restored the game, so that we know not to back up the doors. This will need a screen D register... const int SCREEN_D_BACKUPFLAGS = 10; //! These are the binary flags for items, used in conjunction with one-time-only sales. const int BACKUP_DOORS = 000000001b; const int BACKUP_1 = 000000010b; const int BACKUP_2 = 000000100b; const int BACKUP_3 = 000001000b; const int BACKUP_4 = 000010000b; const int BACKUP_5 = 000100000b; const int BACKUP_6 = 001000000b; const int BACKUP_7 = 010000000b; const int BACKUP_8 = 100000000b; //bool DoorsSaved(){ return Screen->D[SCREEN_D_DOORS bool SaveFlags(int flag){ return ( Screen->D[SCREEN_D_BACKUPFLAGS]&flag ) != 0; } //Set a shop item sold-out flag. void SaveFlags(int flag, bool state){ if ( state ) Screen->D[SCREEN_D_BACKUPFLAGS] |= flag; else Screen->D[SCREEN_D_BACKUPFLAGS] &= ~flag; } int SaveFlags(int init_val, int flag, bool state){ if ( state ) { init_val |= flag; return init_val;} else { init_val &= ~flag; return init_val; } } //! ! ! READ: ABOUT SAVING DOORS // In order to save doors, because there is no equivalent of GetDMapScreenD() or GetScreenState() for DOORS... // The only viable option is to somehow store into an array, the state of doors on a screen that we visit. // // The problem, is that we need to save it only when they change from what we previously had, but we ALSO // need to ensure that when we restore a game, and revisit that screen, we load the BACKUP settings. // // The tricky part, is ensuring that values that we saved, are only read when we visit a screen after doing a restore. // Furthermore, how to ensure that .... // Idea // When we visit a screen for the first time, store its doors in one array, and mark a flag that it's the first visit. // If the doors change, store their changed values in a second array, and set a flag that they differ. // If we do a backup, copy the changed values to the first array. // When we visit a screen, if it is the first time, we set that flag, and do the initial copying. // If it is flagged as visited, but not flagged as backed up, and we revisit it: // ! // if it is flagged as backed up, and we have restored the game: // ! How do we know that we restored the game, but the doors on the screen are non-current //! This is going to require some fancy flag usage and logic. // Store doors in an array when we visit a screen. If they change, update the array. // //We need a way to read DMap Screen Doors... void RestoreScreenDoors(){ } void BackupScreenDoors(){ for ( int q = 0; q <= SizeOfArray(ScreenDoor_BAK); q++ ) ScreenDoor_BAK[q] = ScreenDoors[q]; } void MarkScreenDoorsBackup(){ for ( int q = 0; q < HIGHEST_DMAP_ID; q++ ) { //dmap for ( int w = 0; w < 128; w++ ) { //screen Game->SetDMapScreenD(q,w,SCREEN_D_BACKUPFLAGS, SaveFlags(GetDMapScreenD(q,w,SCREEN_D_BACKUPFLAGS), BACKUP_DOORS, true){; //What a pain... } } } } //Backup Screen->D last. //Screen->Door ( 4 per screen, 512 per dmap int ScreenDoor_BAK[214528]; //419 DMaps of these //! There is no way to read doors on screens other than the current screen! void BackupScreenDoors(){ for ( int q = 0; q < HIGHEST_DMAP_ID; q++ ) { //dmap for ( int w = 0; w < 128; w++ ) { //screen for ( int e = 0; e < 10; e++ ) { //reg //ScreenDoor_BAK[ ( SCREEN_D_OFFSET*q ) + (w* 15) + e ] = Game->GetScreenState(Game->DMapOffset[q],w,e); //I hope this calc is proper. } } } } void RestoreScreenDoors(){ for ( int q = 0; q < HIGHEST_DMAP_ID; q++ ) { //dmap for ( int w = 0; w < 128; w++ ) { //screen for ( int e = 0; e < 15; e++ ) { //secrets index //Game->SetScreenState(Game->DMapOffset[q],w,e, ScreenState_BAK[( SCREEN_D_OFFSET*q ) + (w* 15) + e]); //likewise... } } } } const int GAMESAVESTATED = 498; const int SAVINGEQUIPMENT = 496; const int RESTORINGEQUIPMENT = 497; const int SAVESCREEN= 1020; const int SAVEDMAP = 1021; const int SAVEX = 1022; const int SAVEY = 1023; const int GAME_SAVED = 1024; const int SOLID_BLACK = 1; const int CMB_SAVE = 0; //COmbo ID of combo with inherent Save Point type. bool GameSaveStated(){ return GameEvents[GAMESAVESTATED]; } bool GameSaveStated(bool set){ GameEvents[GAMESAVESTATED] = set; } //bool EverSaved = false; //This is used exactly once, to prevent the //player from using the restore command if he has never saved using a Save command. //Call this from the Tango menu for 'Game->Restore' and if false, report //'No Saved Game to Restore' instead of restoring a blank game! //bool SaveAndQuit = false; //This boolean is used to determine if the game was quit via the save and quit command, and not by death, or F6. //If this boolean is true, the onContinue punishment is skipped. This boolean is set to false when the game starts every time, and set to true if the player // Uses Game->Save and Quit or Game->Quit. // Because it is set to false EVERY TIME THE GAME STARTS and ONLY set to TRUE when the game is SAVED FULLy with the MENU // and NOT with QUICK SAVE, we do not need to store it in a _BAK table. void SavePoint(){ int curScreen = Game->GetCurScreen(); int curDMAP = Game->GetCurDMap(); int curX = Link->X; int curY = Link->Y; //Screen->FastCombo(0, curX, curY, CMB_SAVE, 0, 0); GameDynamics[SAVESCREEN] = curScreen; GameDynamics[SAVEDMAP] = curDMAP; GameDynamics[SAVEX] = curX; GameDynamics[SAVEY] = curY; GameEvents[GAME_SAVED] = true; SaveState(); // ! // ! Do save point combos store XY coordinates for a return point, or do they use the A warp return on a screen? // ! //Link->InputStart; //Waitframes(1); //Link->InputDown; //Waitframes(1); //Link->InputDown; //Game->ShowSaveQuitScreen(); Game->Save(); //Display SAVED Message in menu. offer Quit Menu. //End(); //Do this if the player selects to quit. } void SaveGame(){ int curScreen = Game->GetCurScreen(); int curDMAP = Game->GetCurDMap(); int curX = Link->X; int curY = Link->Y; Screen->FastCombo(0, curX, curY, CMB_SAVE, 0, 0); GameDynamics[SAVESCREEN] = curScreen; GameDynamics[SAVEDMAP] = curDMAP; GameDynamics[SAVEX] = curX; GameDynamics[SAVEY] = curY; SaveState(); GameEvents[GAME_SAVED] = true; } void SaveGame(bool full){ int curScreen = Game->GetCurScreen(); int curDMAP = Game->GetCurDMap(); int curX = Link->X; int curY = Link->Y; Screen->FastCombo(0, curX, curY, CMB_SAVE, 0, 0); GameDynamics[SAVESCREEN] = curScreen; GameDynamics[SAVEDMAP] = curDMAP; GameDynamics[SAVEX] = curX; GameDynamics[SAVEY] = curY; SaveState(); GameEvents[GAME_SAVED] = true; if ( full ) { Game->Save(); } } void SaveGameAndQuit(){ int curScreen = Game->GetCurScreen(); int curDMAP = Game->GetCurDMap(); int curX = Link->X; int curY = Link->Y; Screen->FastCombo(0, curX, curY, CMB_SAVE, 0, 0); GameDynamics[SAVESCREEN] = curScreen; GameDynamics[SAVEDMAP] = curDMAP; GameDynamics[SAVEX] = curX; GameDynamics[SAVEY] = curY; SaveState(); GameEvents[GAME_SAVED] = true; Game->Save(); Game->End(); } void RestoreGame(bool AndClearSave){ int menuFFC = FindFFCRunning(FFCMENU); //Externally kill FFC 51? bool restoring = true; int restScreen = GameDynamics[SAVESCREEN]; int restDMAP = GameDynamics[SAVEDMAP]; int restX = GameDynamics[SAVEX]; int restY = GameDynamics[SAVEY]; do{ restoring=false; Screen->Rectangle(6, 0, 0, 256, 172, SOLID_BLACK, 1, 0, 0, 0, true, 100); Link->CollDetection = false; Link->PitWarp(restDMAP, restScreen); Link->X = restX; Link->Y = restY; RestoreState(); Link->CollDetection = true; if ( AndClearSave ) { ClearSave(); } } while(restoring); } void ClearSave(){ GameEvents[GAME_SAVED] = false; } bool CheckEquipment(int equip){ for ( int i = 1; i < 255; i++){ if ( Link->Item[equip] == true ){ return true; } } } void RestoreEquipment(){ //int state; for ( int i = 0; i < 255; i++ ) { if ( Link->Item[i] == true && Equipment_BAK[i] == false ) { Link->Item[i] = false; } else if ( Link->Item[i] == false && Equipment_BAK[i] == true ) { Link->Item[i] = true; } //Waitframe(); } } void BackupEquipment(){ //int state; for ( int i = 0; i < 255; i++ ) { if ( Link->Item[i] == true && Equipment_BAK[i] == false ) { Equipment_BAK[i] = true; } else if ( Link->Item[i] == false && Equipment_BAK[i] == true ) { Equipment_BAK[i] = false; } //Waitframe(); } } void BackupCounters(){ for (int i = 0; i < 32; i++){ Counters_BAK[i] = Game->Counter[i]; //Trace(Counters_BAK[i]); } } void RestoreCounters(){ for (int i = 0; i < 32; i++){ Game->Counter[i] = Counters_BAK[i]; } } void BackupMCounters(){ for (int i = 0; i < 32; i++){ MCounters_BAK[i] = Game->MCounter[i]; //Trace(Counters_BAK[i]); } } void RestoreMCounters(){ for (int i = 0; i < 32; i++){ Game->MCounter[i] = MCounters_BAK[i]; } } void BackupGameArrays(){ for (int i =0; i < SizeOfArray(GameDynamics); i++){ GameEvents_BAK[i] = GameEvents[i]; GameDynamics_BAK[i] = GameDynamics[i]; } } void RestoreGameArrays(){ for (int i = 0; i < SizeOfArray(GameDynamics); i++){ GameEvents[i] = GameEvents_BAK[i]; GameDynamics[i] = GameDynamics_BAK[i]; } } bool RestoringEquipment(){ if ( GameEvents[RESTORINGEQUIPMENT] == true ) { return true; } else { return false; } } bool RestoringEquipment(bool set){ if ( set ) { GameEvents[RESTORINGEQUIPMENT] = true; } else if ( !set ) { GameEvents[RESTORINGEQUIPMENT] = false; } } bool SavingEquipment(){ if ( GameEvents[SAVINGEQUIPMENT] == true ) { return true; } else { return false; } } bool SavingEquipment(bool set){ if ( set ) { GameEvents[SAVINGEQUIPMENT] = true; } else if ( !set ) { GameEvents[SAVINGEQUIPMENT] = false; } } void DoEquipmentRestore(){ for ( int i = 0; i < 256; i++ ) { if ( i < 256 ) { if ( Link->Item[i] == true && Equipment_BAK[i] == false ) { Link->Item[i] == false; } else if ( Link->Item[i] == false && Equipment_BAK[i] == true ) { Link->Item[i] == true; } } else if ( i == 256 ) { RestoringEquipment(false); } Waitframe(); } } void DoEquipmentBackup(){ for ( int i = 0; i < 256; i++ ) { if ( i < 256 ) { if ( Link->Item[i] == true && Equipment_BAK[i] == false ) { Equipment_BAK[i] = true; } else if ( Link->Item[i] == false && Equipment_BAK[i] == true ) { Equipment_BAK[i] = false; } } else if ( i == 256 ) { RestoringEquipment(false); } Waitframe(); } } void SaveState(){ //FreezeAction(); GameSaveStated(true); BackupEquipment(); BackupGameArrays(); BackupEquipmentArrays(); BackupMCounters(); BackupCounters(); //BackupTeleportMatrixArrays(); //SavingEquipment(true); //Restore stat arrays, and other arrays. //Read all screen NPCs and store them in an array. BackupScreenState(); BackupScreenD(); //!!! BackupDoors(); TraceNL(); int string1[]="State Saved"; TraceS(string1); TraceNL(); //UnfreezeAction(); } void RestoreState(){ //FreezeAction(); RestoreEquipment(); RestoreScreenD(); RestoreScreenState(); //!!! RestoreDoors(); //RestoringEquipment(true); //Waitframes(1); RestoreGameArrays(); RestoreEquipmentArrays(); RestoreMCounters(); RestoreCounters(); //RestoreTeleportMatrixArrays(); //GameSaveStated(true); //Restore stat arrays, and other arrays. //Remove all screen NPCs. //Read ScreenNPCs array and reconstruct onto screen. TraceNL(); int string1[]="State Restored"; TraceS(string1); TraceNL(); //UnfreezeAction(); } //const int SFX_SAVE_ERROR = 88; //In gc_menus_GameMenu.z //const int SFX_SAVE_SUCCESS = 93; //In gc_menus_GameMenu.z bool SaveMenu(){ int lineBreak[]="@26"; int menuEnd[]="@domenu(1)@suspend()"; int line1[]="@choice(1)Quick Save@26"; int line2[]="@choice(2)Full Save@26"; int line3[]="@choice(3)Save and Quit@26"; int line4[]="@choice(4)Cancel@26"; int line5[]="@26@choice(5)CLEAR SAVE"; SetUpWindow(WINDOW_SLOT_3, WINDOW_STYLE_3, 32, 32, SIZE_LARGE); Tango_LoadString(WINDOW_SLOT_3, line1); Tango_AppendString(WINDOW_SLOT_3, line2); Tango_AppendString(WINDOW_SLOT_3, line3); Tango_AppendString(WINDOW_SLOT_3, line4); Tango_AppendString(WINDOW_SLOT_3, line5); Tango_AppendString(WINDOW_SLOT_3, menuEnd); Tango_ActivateSlot(WINDOW_SLOT_3); while(!Tango_MenuIsActive()){ Waitframe(); } // Save the state again... int slotState[278]; int menuState[960]; int cursorPos; Tango_SaveSlotState(WINDOW_SLOT_3, slotState); Tango_SaveMenuState(menuState); int done=0; int choice; while(true) { while(Tango_MenuIsActive()) { cursorPos=Tango_GetMenuCursorPosition(); Waitframe(); } choice=Tango_GetLastMenuChoice(); if(choice==0) // Canceled done=2; else if(choice == 1) { done = 1; SaveGame(); Game->PlaySound(SFX_SAVE_SUCCESS); int text[]="Game State Saved"; Tango_ClearSlot(3); ShowString(text, WINDOW_SLOT_5, WINDOW_STYLE_2, 48, 48); menuArg=choice; } else if(choice == 2) { done = 1; SaveGame(true); Game->PlaySound(SFX_SAVE_SUCCESS); int text[]="Game Fully Saved"; Tango_ClearSlot(3); ShowString(text, WINDOW_SLOT_5, WINDOW_STYLE_2, 48, 48); menuArg=choice; } else if(choice == 3) { done = 1; SaveGameAndQuit(); menuArg = choice; } else if(choice == 4) { done = 1; menuArg = choice; } else if(choice == 5) { done = 1; ClearSave(); int text[]="Save Cleared"; Tango_ClearSlot(3); ShowString(text, WINDOW_SLOT_5, WINDOW_STYLE_2, 48, 48); menuArg = choice; } else if (Link->PressEx1){ done = 2; } else done=2; if(done>0){ break; } else { Tango_RestoreSlotState(WINDOW_SLOT_3, slotState); Tango_RestoreMenuState(menuState); Tango_SetMenuCursorPosition(cursorPos); } } Tango_ClearSlot(WINDOW_SLOT_3); if(done==1) return true; // Tell parent menu to close else return false; // Tell parent not to close } //const int SFX_SAVE_ERROR = 88; //In gc_menus_GameMenu.z //const int SFX_SAVE_SUCCESS = 93; //In gc_menus_GameMenu.z bool RestoreMenu() { //SetUpWindow(WINDOW_SLOT_2, WINDOW_STYLE_2, 32, 32, SIZE_LARGE); //int spellFormat[]="@choice(%d)Spell %d"; int lineBreak[]="@26"; int menuEnd[]="@domenu(1)@suspend()"; //int spellIce[]="@choice(%d)Water/Ice"; //int spellFire[]="@choice(%d)Fire/Heat"; //for(int i=1; i<9; i++) //{ // int buffer[40]; // sprintf(buffer, spellFormat, i, i); // Tango_AppendString(WINDOW_SLOT_2, buffer); // if(i<7) // Tango_AppendString(WINDOW_SLOT_2, lineBreak); //} int line1[]="@choice(1)Restore@26"; int line2[]="@choice(2)Cancel@26"; //@choice(2)Light@domenu(1)@suspend() SetUpWindow(WINDOW_SLOT_2, WINDOW_STYLE_2, 32, 32, SIZE_LARGE); Tango_LoadString(WINDOW_SLOT_2, line1); Tango_AppendString(WINDOW_SLOT_2, line2); Tango_AppendString(WINDOW_SLOT_2, menuEnd); Tango_ActivateSlot(WINDOW_SLOT_2); //Tango_AppendString(WINDOW_SLOT_2, menuEnd); //Tango_ActivateSlot(WINDOW_SLOT_2); while(!Tango_MenuIsActive()){ Waitframe(); } // Save the state again... int slotState[278]; int menuState[960]; int cursorPos; Tango_SaveSlotState(WINDOW_SLOT_2, slotState); Tango_SaveMenuState(menuState); bool done = false; int choice; while(true) { while(Tango_MenuIsActive()) { cursorPos=Tango_GetMenuCursorPosition(); Waitframe(); } choice=Tango_GetLastMenuChoice(); if(choice==0) // Canceled done=true; else if(choice == 1) { if ( !GameSaveStated() ) { Game->PlaySound(SFX_SAVE_ERROR); int text[]="No Quick Save to Restore"; Tango_ClearSlot(3); ShowString(text, WINDOW_SLOT_5, WINDOW_STYLE_2, 48, 48); menuArg=choice; } else{ RestoreGame(false); return true; done = true; //menuArg=choice; } } else if(choice == 2) { done = true; } else if (Link->PressEx1){ done = true; } else done=true; if(done){ break; } else { Tango_RestoreSlotState(WINDOW_SLOT_2, slotState); Tango_RestoreMenuState(menuState); Tango_SetMenuCursorPosition(cursorPos); } } Tango_ClearSlot(WINDOW_SLOT_2); if(done) return true; // Tell parent menu to close else return false; // Tell parent not to close } //Enemy savestates void BackupScreenEnemies(){ //if ( q == ENEM_BAK_COLLISION ) { // int col; // if ( enem->CollDetection ) { // col = 1; // } // else { // col = 0; // } // ScreenEnemies[pass+q] = col; // if ( ScreenEnemies[pass+ENEM_BAK_ID] == 0 ) { //if we reach a blank field for enemy ID, the rest should all be empty. // break; //Stop copying. // } //BackupScreenEnemyMisc(pass); //BackupScreenEnemyDefs(pass); } void RestoreScreenEnemies(){ // We need to find the first instance of ID 0, to determine how many NPCs to create. int n; // n = ScreenEnemies[pass+ENEM_BAK_ID]; // Screen->CreateNPC(n); // Create Nth npcs first. They should be constructed in a way that allows us to later reference thhem in the order created? // Then set their attribs and vars in the same order with a second set of for loops. //if ( q == ENEM_BAK_COLLISION ) { // boll col; // if ( ScreenEnemies[pass+q] == 1 ) { // col = true // } // else { // col = false // } // enem->CollDetection = col; // // if ( ScreenEnemies[pass+ENEM_BAK_ID] == 0 ) { //if we reach a blank field for enemy ID, the rest should all be empty. // break; //Stop copying. // } // // } void CleanupEnemyBackups(){ for (int w = 0; w < SizeOfArray(ScreenEnemies); w++){ ScreenEnemies[q] = 0; } } //Note, summoners will break a ten-slot array. We need 1,000 slots, to be certain. float ScreenEnemies[630]={ 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; const int ENEM_BAK_PRIORITY = 0; const int ENEM_BAK_ID = 1; const int ENEM_BAK_X = 2; const int ENEM_BAK_Y = 3; const int ENEM_BAK_Z = 4; const int ENEM_BAK_JUMP = 5; const int ENEM_BAK_DIR = 6; const int ENEM_BAK_COLLISION = 7; const int ENEM_BAK_HP = 8; const int ENEM_BAK_DAMAGE = 9; const int ENEM_BAK_WEAPDAMAGE = 10; const int ENEM_BAK_STUN = 11; const int ENEM_BAK_ORIGTILE = 12; const int ENEM_BAK_WEAP = 13; const int ENEM_BAK_ITEMSET = 14; const int ENEM_BAK_CSET = 15; const int ENEM_BAK_BOSSPAL = 16; const int ENEM_BAK_SFX = 17; const int ENEM_BAK_EXTEND = 18; const int ENEM_BAK_TILEWIDTH = 19; const int ENEM_BAK_TILEHEIGHT = 20; const int ENEM_BAK_HITWIDTH = 21; const int ENEM_BAK_HITHEIGHT = 22; const int ENEM_BAK_HITXOFFSET = 23; const int ENEM_BAK_HITYOFFSET = 24; const int ENEM_BAK_HITZHEIGHT = 25; const int ENEM_BAK_DRAWX = 26; const int ENEM_BAK_DRAWY = 27; const int ENEM_BAK_DRAWZ = 28; const int ENEM_BAK_DEF0 = 29; const int ENEM_BAK_DEF1 = 30; const int ENEM_BAK_DEF2 = 31; const int ENEM_BAK_DEF3 = 32; const int ENEM_BAK_DEF4 = 33; const int ENEM_BAK_DEF5 = 34; const int ENEM_BAK_DEF6 = 35; const int ENEM_BAK_DEF7 = 36; const int ENEM_BAK_DEF8 = 37; const int ENEM_BAK_DEF9 = 38; const int ENEM_BAK_DEF10 = 39; const int ENEM_BAK_DEF11 = 40; const int ENEM_BAK_DEF12 = 41; const int ENEM_BAK_DEF13 = 42; const int ENEM_BAK_DEF14 = 43; const int ENEM_BAK_DEF15 = 44; const int ENEM_BAK_DEF16 = 45; const int ENEM_BAK_DEF17 = 46; const int ENEM_BAK_MISC0 = 47; const int ENEM_BAK_MISC1 = 48; const int ENEM_BAK_MISC2 = 49; const int ENEM_BAK_MISC3 = 50; const int ENEM_BAK_MISC4 = 51; const int ENEM_BAK_MISC5 = 52; const int ENEM_BAK_MISC6 = 53; const int ENEM_BAK_MISC7 = 54; const int ENEM_BAK_MISC8 = 55; const int ENEM_BAK_MISC9 = 56; const int ENEM_BAK_MISC10 = 57; const int ENEM_BAK_MISC11 = 58; const int ENEM_BAK_MISC12 = 59; const int ENEM_BAK_MISC13 = 60; const int ENEM_BAK_MISC14 = 61; const int ENEM_BAK_MISC15 = 62; const int ENEMY_BAK_ENEMY = 63; const int ENEM_BAK_MISC_VALUES = 47; const int ENEM_BAK_DEF_VALUES = 29; void BackupScreenEnemyMisc(){ //for loop copies enem->Misc[q] to ScreenEnemies[ENEMy_BAK_ENEMY * pass + ENEM_BAK_MISC_VALUES + q]; } void BackupScreenEnemyDefs(){ //for loop copies enem->Misc[q] to ScreenEnemies[ENEMY_BAK_ENEMY * pass + ENEM_BAK_DEF_VALUES + q]; } void BackupScreenEnemyCollision(){ } //Number on List, ID, X, Y, Z, Jump, Dir, CollDetection (BOOLEAN), HP, Damage, WeaponDamage, Stun, //OriginalTile, Weapon, ItemSet, CSet, BossPal (SHOULD WE SAVE THIS?), SFX, Extend, TileWidth, //TileHeight, HitWidth, HitHeight, HitZHeight, HitXOffset, HitYOffset, DrawXOffset, DrawYOffset, //DrawZOffset //12+ 8 + 9 = 29 main values, + 18 for Defense [18] = 47 + 16 for Misc[16] == 63 total values. //Defense [ 18 ] // Misc [ 16 ] //Read, copy, backup, and restore BossPal only if CSet is 14. //Store CollDetection as 0.1, and write back as a boolean. //How do we know if its shield is broken? we need to read its flags, and then do BreakShield() if it's broken? // MiscFlags // The npc's Misc. Flags as 14 bits ORed together, starting with 'Damaged by Power 0 Weapons', * and working down the flags in the order they are shown in the Enemy Editor. //* npc->MiscFlags is read-only; while setting it is not syntactically incorrect, it does nothing. //* If you are not comfortable with binary operations, you can use 'GetNPCMiscFlag' from std.zh