From 1e7b07a102253b4fb0a2fd0f66acc1043c545619 Mon Sep 17 00:00:00 2001 From: cuckydev Date: Mon, 28 Jan 2019 12:26:35 -0500 Subject: [PATCH] working on arms and items --- Makefile | 1 + src/ArmsItem.cpp | 302 ++++++++++++++++++++++++++++++++++++++++++++++ src/ArmsItem.h | 46 +++++++ src/Caret.cpp | 18 ++- src/Draw.cpp | 28 ++++- src/Game.cpp | 58 +++++++-- src/MyChar.cpp | 89 +++++++------- src/MycHit.cpp | 2 +- src/MycParam.cpp | 288 ++++++++++++++++++++++++++++++++++++++++--- src/MycParam.h | 13 ++ src/NpcAct.h | 2 + src/NpcAct020.cpp | 19 +++ src/NpcTbl.cpp | 2 +- src/Profile.cpp | 9 +- src/TextScr.cpp | 153 ++++++++++++++++------- src/TextScr.h | 1 + 16 files changed, 902 insertions(+), 129 deletions(-) create mode 100644 src/ArmsItem.cpp create mode 100644 src/ArmsItem.h diff --git a/Makefile b/Makefile index 84c7df01..34111235 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ endif # For an accurate result to the original's code, compile in alphabetical order SOURCES = \ + ArmsItem \ Back \ Caret \ Config \ diff --git a/src/ArmsItem.cpp b/src/ArmsItem.cpp new file mode 100644 index 00000000..bc3f4a07 --- /dev/null +++ b/src/ArmsItem.cpp @@ -0,0 +1,302 @@ +#include + +#include "CommonDefines.h" +#include "TextScr.h" +#include "ArmsItem.h" +#include "Draw.h" +#include "KeyControl.h" +#include "Escape.h" +#include "Sound.h" +#include "Main.h" +#include "Game.h" + +int gArmsEnergyX = 16; + +ARMS gArmsData[ARMS_MAX]; +ITEM gItemData[ITEM_MAX]; +int gSelectedArms; +int gSelectedItem; +int gCampTitleY; +int gCampActive; + +void ClearArmsData() +{ + gArmsEnergyX = 32; + memset(gArmsData, 0, sizeof(gArmsData)); +} + +void ClearItemData() +{ + memset(gItemData, 0, sizeof(gItemData)); +} + +bool AddArmsData(int code, int max_num) +{ + for (int i = 0; i < ARMS_MAX; i++) + { + if (gArmsData[i].code == code || !gArmsData[i].code) + { + if (!gArmsData[i].code) + { + memset(&gArmsData[i], 0, sizeof(ARMS)); + gArmsData[i].level = 1; + } + + gArmsData[i].code = code; + gArmsData[i].max_num += max_num; + gArmsData[i].num += max_num; + if (gArmsData[i].num > gArmsData[i].max_num) + gArmsData[i].num = gArmsData[i].max_num; + return true; + } + } + + return false; +} + +bool SubArmsData(int code) +{ + for (int i = 0; i < ARMS_MAX; i++) + { + if (gArmsData[i].code == code) + { + //Shift all arms from the right to the left + int ia; + for (ia = i + 1; ia < ARMS_MAX; ++ia) + { + gArmsData[ia - 1].code = gArmsData[ia].code; + gArmsData[ia - 1].level = gArmsData[ia].level; + gArmsData[ia - 1].exp = gArmsData[ia].exp; + gArmsData[ia - 1].max_num = gArmsData[ia].max_num; + gArmsData[ia - 1].num = gArmsData[ia].num; + } + + gArmsData[ia - 1].code = 0; + gSelectedArms = 0; + return true; + } + } + + return false; +} + +bool TradeArms(int code1, int code2, int max_num) +{ + for (int i = 0; i < ARMS_MAX; i++) + { + if (gArmsData[i].code == code1) + { + gArmsData[i].level = 1; + gArmsData[i].code = code2; + gArmsData[i].max_num += max_num; + gArmsData[i].num += max_num; + gArmsData[i].exp = 0; + return true; + } + } + + return false; +} + +bool AddItemData(int code) +{ + for (int i = 0; i < ITEM_MAX; i++) + { + if (gItemData[i].code == code || !gItemData[i].code) + { + gItemData[i].code = code; + return true; + } + } + + return false; +} + +bool SubItemData(int code) +{ + for (int i = 0; i < ITEM_MAX; i++) + { + if (gItemData[i].code == code) + { + //Shift all items from the right to the left + int ia; + for (ia = i + 1; ia < ITEM_MAX; ++ia) + gItemData[ia - 1].code = gItemData[ia].code; + + gItemData[ia - 1].code = 0; + gSelectedItem = 0; + return true; + } + } + + return false; +} + +int CampLoop() +{ + RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}; + + //Load the inventory script + char old_script_path[PATH_LENGTH]; + GetTextScriptPath(old_script_path); + + char name[13]; + strcpy(name, "ArmsItem.tsc"); + LoadTextScript2(name); + + gCampTitleY = 24; + gCampActive = 0; + gSelectedItem = 0; + + //Run script + int arms_num; + for (arms_num = 0; gArmsData[arms_num].code != 0; arms_num++); + + if (arms_num) + StartTextScript(gArmsData[gSelectedArms].code + 1000); + else + StartTextScript(gItemData[gSelectedItem].code + 5000); + + while (true) + { + GetTrg(); + + if (gKeyTrg & KEY_ESCAPE) + { + int escRet = Call_Escape(); + if (escRet == 0) + return 0; + if (escRet == 2) + return 1; + } + + //if (g_GameFlags & 2) + // MoveCampCursor(); + + int tscRet = TextScriptProc(); + if (tscRet == 0) + return 0; + if (tscRet == 2) + return 2; + + PutBitmap4(&rcView, 0, 0, &rcView, 10); + //PutCampObject(); + PutTextScript(); + PutFramePerSecound(); + + if (!gCampActive && (gKeyItem | gKeyCancel | gKeyOk) & gKeyTrg) + break; + + if (g_GameFlags & 2 && (gKeyItem | gKeyCancel) & gKeyTrg) + break; + + if (!Flip_SystemTask()) + return 0; + } + + //Resume original script + StopTextScript(); + LoadTextScript_Stage(old_script_path); + gArmsEnergyX = 32; + return 1; +} + +bool CheckItem(int a) +{ + for (int i = 0; i < ITEM_MAX; i++) + { + if (gItemData[i].code == a) + return true; + } + + return false; +} + +bool CheckArms(int a) +{ + for (int i = 0; i < ARMS_MAX; i++) + { + if (gArmsData[i].code == a) + return true; + } + + return false; +} + +bool UseArmsEnergy(int num) +{ + if (!gArmsData[gSelectedArms].max_num) + return true; + if (!gArmsData[gSelectedArms].num) + return false; + gArmsData[gSelectedArms].num -= num; + if (gArmsData[gSelectedArms].num < 0) + gArmsData[gSelectedArms].num = 0; + return true; +} + +bool ChargeArmsEnergy(int num) +{ + gArmsData[gSelectedArms].num += num; + if (gArmsData[gSelectedArms].num > gArmsData[gSelectedArms].max_num) + gArmsData[gSelectedArms].num = gArmsData[gSelectedArms].max_num; + return true; +} + +void FullArmsEnergy() +{ + for (int a = 0; a < ARMS_MAX; a++) + { + if (gArmsData[a].code) + gArmsData[a].num = gArmsData[a].max_num; + } +} + +int RotationArms() +{ + int arms_num; + for ( arms_num = 0; gArmsData[arms_num].code != 0; arms_num++); + if (!arms_num) + return 0; + + //ResetSpurCharge(); + + ++gSelectedArms; + while (gSelectedArms < arms_num && !gArmsData[gSelectedArms].code) + ++gSelectedArms; + + if (gSelectedArms == arms_num) + gSelectedArms = 0; + + gArmsEnergyX = 32; + PlaySoundObject(4, 1); + + return gArmsData[gSelectedArms].code; +} + +int RotationArmsRev() +{ + int arms_num; + for (arms_num = 0; gArmsData[arms_num].code != 0; arms_num++); + if (!arms_num) + return 0; + + //ResetSpurCharge(); + + if (--gSelectedArms < 0) + gSelectedArms = arms_num - 1; + while (gSelectedArms < arms_num && !gArmsData[gSelectedArms].code) + --gSelectedArms; + + gArmsEnergyX = 0; + PlaySoundObject(4, 1); + + return gArmsData[gSelectedArms].code; +} + +void ChangeToFirstArms() +{ + gSelectedArms = 0; + gArmsEnergyX = 32; + PlaySoundObject(4, 1); +} \ No newline at end of file diff --git a/src/ArmsItem.h b/src/ArmsItem.h new file mode 100644 index 00000000..99349121 --- /dev/null +++ b/src/ArmsItem.h @@ -0,0 +1,46 @@ +#pragma once +struct ARMS +{ + int code; + int level; + int exp; + int max_num; + int num; +}; + +struct ITEM +{ + int code; +}; + +#define ARMS_MAX 8 +#define ITEM_MAX 32 + +extern int gArmsEnergyX; + +extern int gSelectedArms; +extern int gSelectedItem; + +extern ARMS gArmsData[ARMS_MAX]; +extern ITEM gItemData[ITEM_MAX]; +extern int gSelectedArms; +extern int gSelectedItem; +extern int gCampTitleY; +extern int gCampActive; + +void ClearArmsData(); +void ClearItemData(); +bool AddArmsData(int code, int max_num); +bool SubArmsData(int code); +bool TradeArms(int code1, int code2, int max_num); +bool AddItemData(int code); +bool SubItemData(int code); +int CampLoop(); +bool CheckItem(int a); +bool CheckArms(int a); +bool UseArmsEnergy(int num); +bool ChargeArmsEnergy(int num); +void FullArmsEnergy(); +int RotationArms(); +int RotationArmsRev(); +void ChangeToFirstArms(); diff --git a/src/Caret.cpp b/src/Caret.cpp index 08e1e561..9d7ea299 100644 --- a/src/Caret.cpp +++ b/src/Caret.cpp @@ -58,6 +58,14 @@ void ActCaret01(CARET *crt) crt->rect = rcLeft[crt->ani_no]; } +void ActCaret08(CARET *crt) +{ + if (crt->direct) + crt->rect = {32, 80, 48, 96}; + else + crt->rect = {16, 80, 32, 96}; +} + void ActCaret09(CARET *crt) { if (++crt->ani_wait <= 4) @@ -138,20 +146,20 @@ CARET_TABLE gCaretTable[18] = typedef void (*CARETFUNCTION)(CARET*); CARETFUNCTION gpCaretFuncTbl[] = { - &ActCaret00, - &ActCaret01, + ActCaret00, + ActCaret01, nullptr, //&ActCaret02, nullptr, //&ActCaret03, nullptr, //&ActCaret04, nullptr, //&ActCaret05, nullptr, //&ActCaret04, nullptr, //&ActCaret07, - nullptr, //&ActCaret08, - &ActCaret09, + ActCaret08, + ActCaret09, nullptr, //&ActCaret10, nullptr, //&ActCaret11, nullptr, //&ActCaret12, - &ActCaret13, + ActCaret13, nullptr, //&ActCaret14, nullptr, //&ActCaret15, nullptr, //&ActCaret16, diff --git a/src/Draw.cpp b/src/Draw.cpp index 68c0027d..27d6b6f0 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -243,14 +243,30 @@ void BackupSurface(int surf_no, RECT *rect) SDL_FreeSurface(surface); //Get rects - SDL_Rect frameRect = {0, 0, frameRect.w, frameRect.h}; - SDL_Rect destRect = RectToSDLRect(rect); + SDL_Rect frameRect = RectToSDLRect(rect); + frameRect = {frameRect.x * gWindowScale, frameRect.y * gWindowScale, frameRect.w * gWindowScale, frameRect.h * gWindowScale}; - //Draw texture onto surface - SDL_SetRenderTarget(gRenderer, surf[surf_no].texture); - SDL_RenderCopy(gRenderer, screenTexture, &frameRect, &destRect); + SDL_Texture *textureAccessible = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, frameRect.w, frameRect.h); + + if (!textureAccessible) + { + printf("Failed to create real texture for surface id %d\nSDL Error: %s\n", surf_no, SDL_GetError()); + return; + } + + SDL_SetTextureBlendMode(textureAccessible, SDL_BLENDMODE_BLEND); + + SDL_SetRenderTarget(gRenderer, textureAccessible); + SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0); + SDL_RenderClear(gRenderer); + SDL_RenderCopy(gRenderer, screenTexture, &frameRect, NULL); + SDL_RenderPresent(gRenderer); SDL_SetRenderTarget(gRenderer, NULL); - + + //Set surface's metadata + surf[surf_no].texture = textureAccessible; + + //Free stuff SDL_DestroyTexture(screenTexture); } diff --git a/src/Game.cpp b/src/Game.cpp index f7d273c7..1209e9bb 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -10,6 +10,7 @@ #include "NpcHit.h" #include "Generic.h" #include "GenericLoad.h" +#include "ArmsItem.h" #include "TextScr.h" #include "Fade.h" #include "Frame.h" @@ -25,6 +26,7 @@ #include "Sound.h" #include "Organya.h" #include "Profile.h" +#include "MycParam.h" #include "Back.h" #include "KeyControl.h" #include "ValueView.h" @@ -278,15 +280,10 @@ int ModeTitle() break; } - //Reset cliprect, flags, and give the player the booster 0.8? + //Reset cliprect, flags, and give the player the nikumaru counter grcGame.left = 0; g_GameFlags = 0; - - /* - v0 = unk_81C8598; - BYTE1(v0) |= 1u; - unk_81C8598 = v0; - */ + gMC.equip & 0x100; //Start loop int wait = 0; @@ -434,8 +431,8 @@ int ModeAction() //InitStar(); InitFade(); //InitFlash(); - //ClearArmsData(); - //ClearItemData(); + ClearArmsData(); + ClearItemData(); //ClearPermitStage(); //StartMapping(); InitFlags(); @@ -518,6 +515,41 @@ int ModeAction() //PutBossLife(); PutFade(); + if (!(g_GameFlags & 4)) + { + //Open inventory + if (gKeyTrg & gKeyItem) + { + BackupSurface(10, &grcGame); + + int campRet = CampLoop(); + if (campRet == 0) + return 0; + if (campRet == 2) + return 1; + gMC.cond &= ~1; + } + /* + else if ( unk_81C8598 & 2 && gKeyTrg & gKeyMap ) + { + BackupSurface(10, &grcGame); + v3 = MiniMapLoop(); + if ( !v3 ) + return 0; + if ( v3 == 2 ) + return 1; + } + */ + } + + if (g_GameFlags & 2) + { + if (gKeyTrg & gKeyArms) + RotationArms(); + else if (gKeyTrg & gKeyArmsRev) + RotationArmsRev(); + } + if (swPlay & 1) { int tscRet = TextScriptProc(); @@ -529,6 +561,14 @@ int ModeAction() PutMapName(false); + if (g_GameFlags & 2) + { + PutMyLife(true); + PutArmsEnergy(true); + PutMyAir((WINDOW_WIDTH - 80) / 2, (WINDOW_HEIGHT - 32) / 2); + PutActiveArmsList(); + } + if (g_GameFlags & 8) { PutIllust(); diff --git a/src/MyChar.cpp b/src/MyChar.cpp index a212658f..c7d579df 100644 --- a/src/MyChar.cpp +++ b/src/MyChar.cpp @@ -5,10 +5,14 @@ #include "MyChar.h" #include "MycParam.h" +#include "ArmsItem.h" #include "NpChar.h" #include "Draw.h" #include "Sound.h" +#include "ValueView.h" #include "KeyControl.h" +#include "TextScr.h" +#include "Flags.h" #include "Game.h" #include "Caret.h" @@ -147,9 +151,9 @@ void PutMyChar(int fx, int fy) if ((gMC.cond & 0x80u) && !(gMC.cond & 2)) { //Draw weapon - gMC.rect_arms.left = 24 * 0;//(gArmsData[gSelectedArms].code % 13); + gMC.rect_arms.left = 24 * (gArmsData[gSelectedArms].code % 13); gMC.rect_arms.right = gMC.rect_arms.left + 24; - gMC.rect_arms.top = 96 * 0;//(gArmsData[gSelectedArms].code / 13); + gMC.rect_arms.top = 96 * (gArmsData[gSelectedArms].code / 13); gMC.rect_arms.bottom = gMC.rect_arms.top + 16; if (gMC.direct == 2) @@ -183,14 +187,14 @@ void PutMyChar(int fx, int fy) PutBitmap3( &grcGame, (gMC.x - gMC.view.left) / 0x200 - fx / 0x200, - arms_offset_y + (gMC.y - gMC.view.top) / 0x200 - fy / 0x200, + (gMC.y - gMC.view.top) / 0x200 - fy / 0x200 + arms_offset_y, &gMC.rect_arms, 11); else PutBitmap3( &grcGame, (gMC.x - gMC.view.left) / 0x200 - fx / 0x200 - 8, - arms_offset_y + (gMC.y - gMC.view.top) / 0x200 - fy / 0x200, + (gMC.y - gMC.view.top) / 0x200 - fy / 0x200 + arms_offset_y, &gMC.rect_arms, 11); @@ -633,47 +637,50 @@ void ActMyChar_Normal(bool bKey) void AirProcess() { - /* - if ( unk_81C8598 & 0x10 ) + if (gMC.equip & 0x10) { - unk_81C8624 = 1000; - unk_81C8628 = 0; + gMC.air = 1000; + gMC.air_get = 0; } else { - if ( gMC.flag & 0x100 ) - { - if ( --unk_81C8624 <= 0 ) - { - if ( (unsigned __int8)GetNPCFlag(4000) ) - { - StartTextScript(1100); + if (gMC.flag & 0x100) + { + if (--gMC.air <= 0) + { + if (GetNPCFlag(4000)) + { + //Core cutscene + StartTextScript(1100); + } + else + { + //Drown + StartTextScript(41); + + if (gMC.direct) + SetCaret(gMC.x, gMC.y, 8, 2); + else + SetCaret(gMC.x, gMC.y, 8, 0); + + gMC.cond &= ~0x80; + } + } + } + else + { + gMC.air = 1000; + } + + if ( gMC.flag & 0x100 ) + { + gMC.air_get = 60; + } + else if (gMC.air_get) + { + --gMC.air_get; + } } - else - { - StartTextScript(41); - if ( dir ) - SetCaret(x, y, 8, 2); - else - SetCaret(x, y, 8, 0); - gMC.cond &= 0x7Fu; - } - } - } - else - { - unk_81C8624 = 1000; - } - if ( gMC.flag & 0x100 ) - { - unk_81C8628 = 60; - } - else if ( unk_81C8628 ) - { - --unk_81C8628; - } - } - */ } void ActMyChar(bool bKey) @@ -689,7 +696,7 @@ void ActMyChar(bool bKey) } else if (gMC.exp_count) { - //SetValueView(&x, &y, gMC.exp_count); + SetValueView(&gMC.x, &gMC.y, gMC.exp_count); gMC.exp_count = 0; } diff --git a/src/MycHit.cpp b/src/MycHit.cpp index 8590d66d..518fb236 100644 --- a/src/MycHit.cpp +++ b/src/MycHit.cpp @@ -784,7 +784,7 @@ void HitMyCharNpChar() if (hit && gNPC[i].code_char == 87) { PlaySoundObject(20, 1); - //AddLifeMyChar(gNPC[i].exp); + AddLifeMyChar(gNPC[i].exp); gNPC[i].cond = 0; } diff --git a/src/MycParam.cpp b/src/MycParam.cpp index 408e2695..9ad488be 100644 --- a/src/MycParam.cpp +++ b/src/MycParam.cpp @@ -1,8 +1,95 @@ #include "Sound.h" #include "MyChar.h" +#include "MycParam.h" #include "NpChar.h" +#include "CommonDefines.h" +#include "ArmsItem.h" #include "ValueView.h" #include "TextScr.h" +#include "Game.h" +#include "Draw.h" +#include "Caret.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}} +}; + +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) { @@ -21,28 +108,24 @@ void DamageMyChar(int damage) --gMC.star; //Lose experience - /* - if ( unk_81C8598 & 4 ) - v1 = gArmsData[gSelectedArms].exp - damage; + if (gMC.equip & 4) + gArmsData[gSelectedArms].exp -= damage; else - v1 = gArmsData[gSelectedArms].exp - 2 * damage; - gArmsData[gSelectedArms].exp = v1; - while ( gArmsData[gSelectedArms].exp < 0 ) + gArmsData[gSelectedArms].exp -= 2 * damage; + + while (gArmsData[gSelectedArms].exp < 0) { - if ( gArmsData[gSelectedArms].level <= 1 ) - { - 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); + } } - else - { - gArmsData[gSelectedArms].exp += gArmsLevelTable[0].exp[--gArmsData[gSelectedArms].level - - 1 - + 3 * gArmsData[gSelectedArms].code]; - if ( word_81C8614 > 0 && gArmsData[gSelectedArms].code != 13 ) - SetCaret(x, y, 10, 2); - } - } - */ //Tell player how much damage was taken SetValueView(&gMC.x, &gMC.y, -damage); @@ -56,4 +139,169 @@ void DamageMyChar(int damage) StartTextScript(40); } } -} \ No newline at end of file +} + +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, 26); + PutBitmap3(&rcView, gArmsEnergyX + 48, 24, &rcNone, 26); + } + + //Draw experience and ammo + if (!flash || !((gMC.shock >> 1) & 1)) + { + PutBitmap3(&rcView, gArmsEnergyX + 32, 24, &rcPer, 26); + PutBitmap3(&rcView, gArmsEnergyX, 32, &rcLv, 26); + 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, 26); + + 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, 26); + } + else + { + PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpMax, 26); + } + + static int add_flash = true; + if (gMC.exp_wait && ((add_flash++ >> 1) & 1)) + PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpFlash, 26); + } +} + +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, 12); + } + } +} + +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, 26); + PutBitmap3(&grcGame, 40, 40, &rcBr, 26); + PutBitmap3(&grcGame, 40, 40, &rcLife, 26); + PutNumber4(8, 40, gMC.lifeBr, 0); + } +} + +void PutMyAir(int x, int y) +{ + RECT rcAir[2]; + rcAir[0] = {112, 72, 144, 80}; + rcAir[1] = {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], 26); + else + PutBitmap3(&grcGame, x, y, &rcAir[0], 26); + } +} diff --git a/src/MycParam.h b/src/MycParam.h index 17532118..e8bd1d07 100644 --- a/src/MycParam.h +++ b/src/MycParam.h @@ -1,2 +1,15 @@ #pragma once +struct ARMS_LEVEL +{ + int exp[3]; +}; + +extern ARMS_LEVEL gArmsLevelTable[14]; + void DamageMyChar(int damage); +void AddLifeMyChar(int x); +void AddMaxLifeMyChar(int val); +void PutArmsEnergy(bool flash); +void PutActiveArmsList(); +void PutMyLife(bool flash); +void PutMyAir(int x, int y); diff --git a/src/NpcAct.h b/src/NpcAct.h index 6da5916a..aee50daa 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -13,3 +13,5 @@ void ActNpc017(NPCHAR *npc); void ActNpc018(NPCHAR *npc); void ActNpc021(NPCHAR *npc); + +void ActNpc032(NPCHAR *npc); diff --git a/src/NpcAct020.cpp b/src/NpcAct020.cpp index 9a1c0808..4075ba9d 100644 --- a/src/NpcAct020.cpp +++ b/src/NpcAct020.cpp @@ -27,3 +27,22 @@ void ActNpc021(NPCHAR *npc) npc->rect = rect[0]; } + +//Life capsule +void ActNpc032(NPCHAR *npc) +{ + RECT rect[2]; + rect[0] = {32, 96, 48, 112}; + rect[1] = {48, 96, 64, 112}; + + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + npc->rect = rect[npc->ani_no]; +} \ No newline at end of file diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index 6ee7f722..227fdb2a 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -88,7 +88,7 @@ NPCFUNCTION gpNpcFuncTbl[] = nullptr, nullptr, nullptr, - nullptr, + ActNpc032, nullptr, nullptr, nullptr, diff --git a/src/Profile.cpp b/src/Profile.cpp index fea7d373..e454e83c 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -7,6 +7,7 @@ #include "Tags.h" #include "Profile.h" #include "Fade.h" +#include "ArmsItem.h" #include "Flags.h" #include "MyChar.h" #include "Frame.h" @@ -43,11 +44,11 @@ bool LoadProfile(char *name) bool InitializeGame() { InitMyChar(); - //gSelectedArms = 0; - //gSelectedItem = 0; + gSelectedArms = 0; + gSelectedItem = 0; gCounter = 0; - //ClearArmsData(); - //ClearItemData(); + ClearArmsData(); + ClearItemData(); //ClearPermitStage(); //StartMapping(); InitFlags(); diff --git a/src/TextScr.cpp b/src/TextScr.cpp index 28fb5809..166009d7 100644 --- a/src/TextScr.cpp +++ b/src/TextScr.cpp @@ -7,10 +7,13 @@ #include "TextScr.h" #include "Draw.h" #include "Tags.h" +#include "ArmsItem.h" #include "MyChar.h" #include "Fade.h" #include "Stage.h" +#include "MycParam.h" #include "Flags.h" +#include "Profile.h" #include "MapName.h" #include "KeyControl.h" #include "NpChar.h" @@ -489,6 +492,7 @@ int TextScriptProc() gTS.wait = 0; //Parsing time + int w, x, y, z; bExit = false; while (!bExit) @@ -510,7 +514,7 @@ int TextScriptProc() else if (gTS.flags & 0x10) { //SAT/CAT/TUR printing - int x; + x; for (x = gTS.p_read; ; x++) { //Break if reaches command, or new-line @@ -604,19 +608,65 @@ int TextScriptProc() gTS.face = 0; bExit = true; } + else if (IS_COMMAND('L','I','+')) + { + x = GetTextScriptNo(gTS.p_read + 4); + AddLifeMyChar(x); + gTS.p_read += 8; + } + else if (IS_COMMAND('M','L','+')) + { + z = GetTextScriptNo(gTS.p_read + 4); + AddMaxLifeMyChar(z); + gTS.p_read += 8; + } + else if (IS_COMMAND('A','E','+')) + { + FullArmsEnergy(); + gTS.p_read += 4; + } + else if (IS_COMMAND('I','T','+')) + { + x = GetTextScriptNo(gTS.p_read + 4); + PlaySoundObject(38, 1); + AddItemData(x); + gTS.p_read += 8; + } + else if (IS_COMMAND('I','T','-')) + { + z = GetTextScriptNo(gTS.p_read + 4); + SubItemData(z); + gTS.p_read += 8; + } + else if (IS_COMMAND('A','M','+')) + { + w = GetTextScriptNo(gTS.p_read + 4); + x = GetTextScriptNo(gTS.p_read + 9); + gNumberTextScript[0] = x; + gNumberTextScript[1] = z; + PlaySoundObject(38, 1); + AddArmsData(w, x); + gTS.p_read += 13; + } + else if (IS_COMMAND('A','M','-')) + { + z = GetTextScriptNo(gTS.p_read + 4); + SubArmsData(z); + gTS.p_read += 8; + } else if (IS_COMMAND('T','R','A')) { - int z = GetTextScriptNo(gTS.p_read + 4); - int w = GetTextScriptNo(gTS.p_read + 9); - int x = GetTextScriptNo(gTS.p_read + 14); - int y = GetTextScriptNo(gTS.p_read + 19); + z = GetTextScriptNo(gTS.p_read + 4); + w = GetTextScriptNo(gTS.p_read + 9); + x = GetTextScriptNo(gTS.p_read + 14); + y = GetTextScriptNo(gTS.p_read + 19); if (!TransferStage(z, w, x, y)) return 0; } else if (IS_COMMAND('M','O','V')) { - int x = GetTextScriptNo(gTS.p_read + 4); - int y = GetTextScriptNo(gTS.p_read + 9); + x = GetTextScriptNo(gTS.p_read + 4); + y = GetTextScriptNo(gTS.p_read + 9); SetMyCharPosition(x << 13, y << 13); gTS.p_read += 13; } @@ -632,25 +682,25 @@ int TextScriptProc() } else if (IS_COMMAND('F','L','+')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); SetNPCFlag(z); gTS.p_read += 8; } else if (IS_COMMAND('F','L','-')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); CutNPCFlag(z); gTS.p_read += 8; } else if (IS_COMMAND('S','K','+')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); SetSkipFlag(z); gTS.p_read += 8; } else if (IS_COMMAND('S','K','-')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); CutSkipFlag(z); gTS.p_read += 8; } @@ -744,7 +794,7 @@ int TextScriptProc() } else if (IS_COMMAND('E','V','E')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); JumpTextScript(z); } else if (IS_COMMAND('Y','N','J')) @@ -759,8 +809,8 @@ int TextScriptProc() } else if (IS_COMMAND('F','L','J')) { - int x = GetTextScriptNo(gTS.p_read + 4); - int z = GetTextScriptNo(gTS.p_read + 9); + x = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 9); if (GetNPCFlag(x)) JumpTextScript(z); @@ -769,8 +819,8 @@ int TextScriptProc() } else if (IS_COMMAND('S','K','J')) { - int x = GetTextScriptNo(gTS.p_read + 4); - int z = GetTextScriptNo(gTS.p_read + 9); + x = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 9); if (GetSkipFlag(x)) JumpTextScript(z); @@ -779,7 +829,7 @@ int TextScriptProc() } else if (IS_COMMAND('F','A','I')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); StartFadeIn(z); gTS.mode = 5; gTS.p_read += 8; @@ -787,7 +837,7 @@ int TextScriptProc() } else if (IS_COMMAND('F','A','O')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); StartFadeOut(z); gTS.mode = 5; gTS.p_read += 8; @@ -800,13 +850,13 @@ int TextScriptProc() } else if (IS_COMMAND('S','O','U')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); PlaySoundObject(z, 1); gTS.p_read += 8; } else if (IS_COMMAND('C','M','U')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); ChangeMusic(z); gTS.p_read += 8; } @@ -822,61 +872,76 @@ int TextScriptProc() } else if (IS_COMMAND('D','N','P')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); DeleteNpCharEvent(z); gTS.p_read += 8; } else if (IS_COMMAND('D','N','A')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); DeleteNpCharCode(z, 1); gTS.p_read += 8; } else if (IS_COMMAND('C','N','P')) { - int x = GetTextScriptNo(gTS.p_read + 4); - int y = GetTextScriptNo(gTS.p_read + 9); - int z = GetTextScriptNo(gTS.p_read + 14); + x = GetTextScriptNo(gTS.p_read + 4); + y = GetTextScriptNo(gTS.p_read + 9); + z = GetTextScriptNo(gTS.p_read + 14); ChangeNpCharByEvent(x, y, z); gTS.p_read += 18; } else if (IS_COMMAND('A','N','P')) { - int x = GetTextScriptNo(gTS.p_read + 4); - int y = GetTextScriptNo(gTS.p_read + 9); - int z = GetTextScriptNo(gTS.p_read + 14); + x = GetTextScriptNo(gTS.p_read + 4); + y = GetTextScriptNo(gTS.p_read + 9); + z = GetTextScriptNo(gTS.p_read + 14); SetNpCharActionNo(x, y, z); gTS.p_read += 18; } else if (IS_COMMAND('I','N','P')) { - int x = GetTextScriptNo(gTS.p_read + 4); - int y = GetTextScriptNo(gTS.p_read + 9); - int z = GetTextScriptNo(gTS.p_read + 14); + x = GetTextScriptNo(gTS.p_read + 4); + y = GetTextScriptNo(gTS.p_read + 9); + z = GetTextScriptNo(gTS.p_read + 14); ChangeCheckableNpCharByEvent(x, y, z); gTS.p_read += 18; } else if (IS_COMMAND('S','N','P')) { - int w = GetTextScriptNo(gTS.p_read + 4); - int x = GetTextScriptNo(gTS.p_read + 9); - int y = GetTextScriptNo(gTS.p_read + 14); - int z = GetTextScriptNo(gTS.p_read + 19); + w = GetTextScriptNo(gTS.p_read + 4); + x = GetTextScriptNo(gTS.p_read + 9); + y = GetTextScriptNo(gTS.p_read + 14); + z = GetTextScriptNo(gTS.p_read + 19); SetNpChar(w, x << 13, y << 13, 0, 0, z, 0, 0x100); gTS.p_read += 23; } else if (IS_COMMAND('M','N','P')) { - int w = GetTextScriptNo(gTS.p_read + 4); - int x = GetTextScriptNo(gTS.p_read + 9); - int y = GetTextScriptNo(gTS.p_read + 14); - int z = GetTextScriptNo(gTS.p_read + 19); + w = GetTextScriptNo(gTS.p_read + 4); + x = GetTextScriptNo(gTS.p_read + 9); + y = GetTextScriptNo(gTS.p_read + 14); + z = GetTextScriptNo(gTS.p_read + 19); MoveNpChar(w, x << 13, y << 13, z); gTS.p_read += 23; } + else if (IS_COMMAND('I','N','I')) + { + InitializeGame(); + gTS.p_read += 4; + } + else if (IS_COMMAND('S','V','P')) + { + SaveProfile(NULL); + gTS.p_read += 4; + } + else if (IS_COMMAND('L','D','P')) + { + if (!LoadProfile(NULL)) + InitializeGame(); + } else if (IS_COMMAND('F','A','C')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); if (gTS.face != z) { gTS.face = z; @@ -886,7 +951,7 @@ int TextScriptProc() } else if (IS_COMMAND('F','A','C')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); if (gTS.face != z) { gTS.face = z; @@ -896,11 +961,15 @@ int TextScriptProc() } else if (IS_COMMAND('G','I','T')) { - int z = GetTextScriptNo(gTS.p_read + 4); + z = GetTextScriptNo(gTS.p_read + 4); gTS.item = z; gTS.item_y = WINDOW_HEIGHT - 112; gTS.p_read += 8; } + else if (IS_COMMAND('E','S','C')) + { + return 2; + } else { printf("Unimplemented command: <%c%c%c\n", (char)gTS.data[gTS.p_read + 1], (char)gTS.data[gTS.p_read + 2], (char)gTS.data[gTS.p_read + 3]); diff --git a/src/TextScr.h b/src/TextScr.h index 5e37bf60..e43caba8 100644 --- a/src/TextScr.h +++ b/src/TextScr.h @@ -61,5 +61,6 @@ bool LoadTextScript2(char *name); bool LoadTextScript_Stage(char *name); void GetTextScriptPath(char *path); bool StartTextScript(int no); +void StopTextScript(); void PutTextScript(); int TextScriptProc(); \ No newline at end of file