ref: d75bee4eea4a52070fef3f25183b05e674fa382d
dir: /src/MycParam.cpp/
#include "MycParam.h" #include "SDL.h" #include "WindowsWrapper.h" #include "ArmsItem.h" #include "CommonDefines.h" #include "Caret.h" #include "Draw.h" #include "Game.h" #include "File.h" #include "MyChar.h" #include "NpChar.h" #include "Sound.h" #include "Tags.h" #include "TextScr.h" #include "ValueView.h" ARMS_LEVEL gArmsLevelTable[14] = { {{0, 0, 100}}, {{30, 40, 16}}, {{10, 20, 10}}, {{10, 20, 20}}, {{30, 40, 10}}, {{10, 20, 10}}, {{10, 20, 30}}, {{10, 20, 5}}, {{10, 20, 100}}, {{30, 60, 0}}, {{30, 60, 10}}, {{10, 20, 100}}, {{1, 1, 1}}, {{40, 60, 200}} }; int time_count; void AddExpMyChar(int x) { int lv = gArmsData[gSelectedArms].level - 1; int arms_code = gArmsData[gSelectedArms].code; gArmsData[gSelectedArms].exp += x; if (lv == 2) { if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[0].exp[3 * arms_code + 2]) { gArmsData[gSelectedArms].exp = gArmsLevelTable[0].exp[3 * arms_code + 2]; if (gMC.equip & 0x80) { if (gMC.star < 3) ++gMC.star; } } } else { while (lv <= 1) { if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[0].exp[lv + 3 * arms_code]) { ++gArmsData[gSelectedArms].level; gArmsData[gSelectedArms].exp = 0; if (gArmsData[gSelectedArms].code != 13) { PlaySoundObject(27, 1); SetCaret(gMC.x, gMC.y, 10, 0); } } ++lv; } } if (gArmsData[gSelectedArms].code == 13) { gMC.exp_wait = 10; } else { gMC.exp_count += x; gMC.exp_wait = 30; } } void ZeroExpMyChar() { gArmsData[gSelectedArms].level = 1; gArmsData[gSelectedArms].exp = 0; } BOOL IsMaxExpMyChar() { return gArmsData[gSelectedArms].level == 3 && gArmsData[gSelectedArms].exp >= gArmsLevelTable[gArmsData[gSelectedArms].code].exp[2]; } void DamageMyChar(int damage) { if (!gMC.shock) { //Damage player PlaySoundObject(16, 1); gMC.cond &= ~1; gMC.shock = 128; if (gMC.unit != 1) gMC.ym = -0x400; gMC.life -= damage; //Lose a whimsical star if (gMC.equip & 0x80 && gMC.star > 0) --gMC.star; //Lose experience if (gMC.equip & 4) gArmsData[gSelectedArms].exp -= damage; else gArmsData[gSelectedArms].exp -= 2 * damage; while (gArmsData[gSelectedArms].exp < 0) { if (gArmsData[gSelectedArms].level <= 1) { gArmsData[gSelectedArms].exp = 0; } else { gArmsData[gSelectedArms].exp += gArmsLevelTable[0].exp[--gArmsData[gSelectedArms].level - 1 + 3 * gArmsData[gSelectedArms].code]; if (gMC.life > 0 && gArmsData[gSelectedArms].code != 13) SetCaret(gMC.x, gMC.y, 10, 2); } } //Tell player how much damage was taken SetValueView(&gMC.x, &gMC.y, -damage); //Death if (gMC.life <= 0) { PlaySoundObject(17, 1); gMC.cond = 0; SetDestroyNpChar(gMC.x, gMC.y, 0x1400, 0x40); StartTextScript(40); } } } void ZeroArmsEnergy_All() { for (int a = 0; a < ARMS_MAX; a++) { gArmsData[a].level = 1; gArmsData[a].exp = 0; } } void AddBulletMyChar(int no, int val) { //Missile Launcher for (int a = 0; a < ARMS_MAX; a++) { if (gArmsData[a].code == 5) { gArmsData[a].num += val; if (gArmsData[a].num > gArmsData[a].max_num) gArmsData[a].num = gArmsData[a].max_num; break; } } //Super Missile Launcher for (int a = 0; a < ARMS_MAX; a++) { if (gArmsData[a].code == 10) { gArmsData[a].num += val; if (gArmsData[a].num > gArmsData[a].max_num) gArmsData[a].num = gArmsData[a].max_num; break; } } } void AddLifeMyChar(int x) { gMC.life += x; if (gMC.life > gMC.max_life) gMC.life = gMC.max_life; gMC.lifeBr = gMC.life; } void AddMaxLifeMyChar(int val) { gMC.max_life += val; if (gMC.max_life > 232) gMC.max_life = 232; gMC.life += val; gMC.lifeBr = gMC.life; } void PutArmsEnergy(bool flash) { RECT rcPer = {72, 48, 80, 56}; RECT rcLv = {80, 80, 96, 88}; RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}; RECT rcNone = {80, 48, 96, 56}; if (gArmsEnergyX > 16) gArmsEnergyX -= 2; if (gArmsEnergyX < 16) gArmsEnergyX += 2; //Draw max ammo if (gArmsData[gSelectedArms].max_num) { PutNumber4(gArmsEnergyX + 32, 16, gArmsData[gSelectedArms].num, 0); PutNumber4(gArmsEnergyX + 32, 24, gArmsData[gSelectedArms].max_num, 0); } else { PutBitmap3(&rcView, gArmsEnergyX + 48, 16, &rcNone, SURFACE_ID_TEXT_BOX); PutBitmap3(&rcView, gArmsEnergyX + 48, 24, &rcNone, SURFACE_ID_TEXT_BOX); } //Draw experience and ammo if (!flash || !((gMC.shock >> 1) & 1)) { PutBitmap3(&rcView, gArmsEnergyX + 32, 24, &rcPer, SURFACE_ID_TEXT_BOX); PutBitmap3(&rcView, gArmsEnergyX, 32, &rcLv, SURFACE_ID_TEXT_BOX); PutNumber4(gArmsEnergyX - 8, 32, gArmsData[gSelectedArms].level, 0); RECT rcExpBox = {0, 72, 40, 80}; RECT rcExpVal = {0, 80, 0, 88}; RECT rcExpMax = {40, 72, 80, 80}; RECT rcExpFlash = {40, 80, 80, 88}; int lv = gArmsData[gSelectedArms].level - 1; int arms_code = gArmsData[gSelectedArms].code; int exp_now = gArmsData[gSelectedArms].exp; int exp_next = gArmsLevelTable[0].exp[lv + 3 * arms_code]; PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpBox, SURFACE_ID_TEXT_BOX); if (lv != 2 || gArmsData[gSelectedArms].exp != gArmsLevelTable[0].exp[3 * arms_code + 2]) { if (exp_next) rcExpVal.right += 40 * exp_now / exp_next; else rcExpVal.right = 0; PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpVal, SURFACE_ID_TEXT_BOX); } else { PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpMax, SURFACE_ID_TEXT_BOX); } static int add_flash = true; if (gMC.exp_wait && ((add_flash++ >> 1) & 1)) PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpFlash, SURFACE_ID_TEXT_BOX); } } void PutActiveArmsList() { RECT rect = {0, 0, 0, 16}; int arms_num; for (arms_num = 0; gArmsData[arms_num].code != 0; ++arms_num); if (arms_num) { for (int a = 0; a < arms_num; a++) { //Get X position to draw at int x = 16 * (a - gSelectedArms) + gArmsEnergyX; if (x >= 8) { if (x >= 24) x += 48; } else { x += 16 * (arms_num + 3); } if (8 * (2 * (arms_num + 3) + 1) <= x) x += 16 * (-3 - arms_num); if (x < 72 && x >= 24) x -= 48; //Draw icon rect.left = 16 * gArmsData[a].code; rect.right = rect.left + 16; PutBitmap3(&grcGame, x, 16, &rect, SURFACE_ID_ARMS_IMAGE); } } } void PutMyLife(bool flash) { RECT rcCase = {0, 40, 232, 48}; RECT rcLife = {0, 24, 232, 32}; RECT rcBr = {0, 32, 232, 40}; if (!flash || !((gMC.shock >> 1) & 1)) { if (gMC.lifeBr < gMC.life) gMC.lifeBr = gMC.life; if (gMC.lifeBr <= gMC.life) gMC.lifeBr_count = 0; else if (++gMC.lifeBr_count > 30) --gMC.lifeBr; //Draw bar rcCase.right = 64; rcLife.right = 40 * gMC.life / gMC.max_life - 1; rcBr.right = 40 * gMC.lifeBr / gMC.max_life - 1; PutBitmap3(&grcGame, 16, 40, &rcCase, SURFACE_ID_TEXT_BOX); PutBitmap3(&grcGame, 40, 40, &rcBr, SURFACE_ID_TEXT_BOX); PutBitmap3(&grcGame, 40, 40, &rcLife, SURFACE_ID_TEXT_BOX); PutNumber4(8, 40, gMC.lifeBr, 0); } } void PutMyAir(int x, int y) { RECT rcAir[2] = { {112, 72, 144, 80}, {112, 80, 144, 88}, }; if (!(gMC.equip & 0x10) && gMC.air_get) { //Draw how much air is left if (gMC.air_get % 6 <= 3) PutNumber4(x + 32, y, gMC.air / 10, 0); //Draw "AIR" text if (gMC.air % 30 <= 10) PutBitmap3(&grcGame, x, y, &rcAir[1], SURFACE_ID_TEXT_BOX); else PutBitmap3(&grcGame, x, y, &rcAir[0], SURFACE_ID_TEXT_BOX); } } void PutTimeCounter(int x, int y) { RECT rcTime[3] = { {112, 104, 120, 112}, {120, 104, 128, 112}, {128, 104, 160, 112}, }; if (gMC.equip & 0x100) { //Draw clock and increase time if (g_GameFlags & 2) { if (time_count < 300000) ++time_count; if (time_count % 30 <= 10) PutBitmap3(&grcGame, x, y, &rcTime[1], SURFACE_ID_TEXT_BOX); else PutBitmap3(&grcGame, x, y, &rcTime[0], SURFACE_ID_TEXT_BOX); } else { PutBitmap3(&grcGame, x, y, &rcTime[0], SURFACE_ID_TEXT_BOX); } //Draw time PutNumber4(x, y, time_count / 3000, false); PutNumber4(x + 20, y, time_count / 50 % 60, true); PutNumber4(x + 32, y, time_count / 5 % 10, false); PutBitmap3(&grcGame, x + 30, y, &rcTime[2], SURFACE_ID_TEXT_BOX); } else { time_count = 0; } } bool SaveTimeCounter() { REC rec; //Quit if player doesn't have the Nikumaru Counter if (!(gMC.equip & 0x100)) return true; //Get last time char path[PATH_LENGTH]; sprintf(path, "%s/290.rec", gModulePath); FILE *fp = fopen(path, "rb"); if (fp) { //Read data rec.counter[0] = File_ReadLE32(fp); rec.counter[1] = File_ReadLE32(fp); rec.counter[2] = File_ReadLE32(fp); rec.counter[3] = File_ReadLE32(fp); rec.random[0] = fgetc(fp); rec.random[1] = fgetc(fp); rec.random[2] = fgetc(fp); rec.random[3] = fgetc(fp); fclose(fp); uint8_t *p = (uint8_t*)&rec.counter[0]; p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0]) : (rec.random[0] >> 1); p[1] -= rec.random[0]; p[2] -= rec.random[0]; p[3] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0] >> 1) : (rec.random[0]); //If this is faster than our new time, quit if (rec.counter[0] < time_count) return true; } //Save new time for (int i = 0; i < 4; i++) { rec.counter[i] = time_count; rec.random[i] = Random(0, 250) + i; uint8_t *p = (uint8_t*)&rec.counter[i]; p[0] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] >> 1); p[1] += rec.random[i]; p[2] += rec.random[i]; p[3] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i] >> 1) : (rec.random[i]); } fp = fopen(path, "wb"); if (fp == NULL) return false; File_WriteLE32(rec.counter[0], fp); File_WriteLE32(rec.counter[1], fp); File_WriteLE32(rec.counter[2], fp); File_WriteLE32(rec.counter[3], fp); fputc(rec.random[0], fp); fputc(rec.random[1], fp); fputc(rec.random[2], fp); fputc(rec.random[3], fp); fclose(fp); return true; } int LoadTimeCounter() { //Open file char path[PATH_LENGTH]; sprintf(path, "%s/290.rec", gModulePath); FILE *fp = fopen(path, "rb"); if (!fp) return 0; REC rec; //Read data rec.counter[0] = File_ReadLE32(fp); rec.counter[1] = File_ReadLE32(fp); rec.counter[2] = File_ReadLE32(fp); rec.counter[3] = File_ReadLE32(fp); rec.random[0] = fgetc(fp); rec.random[1] = fgetc(fp); rec.random[2] = fgetc(fp); rec.random[3] = fgetc(fp); fclose(fp); //Decode from checksum for (int i = 0; i < 4; i++) { uint8_t *p = (uint8_t*)&rec.counter[i]; p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] >> 1); p[1] -= rec.random[i]; p[2] -= rec.random[i]; p[3] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i] >> 1) : (rec.random[i]); } //Verify checksum's result if (rec.counter[0] == rec.counter[1] && rec.counter[0] == rec.counter[2]) { time_count = rec.counter[0]; return rec.counter[0]; } else { time_count = 0; return 0; } }