ref: 17b0b503a940ef0cfb70ed1506a3132c0b6146d6
dir: /src/NpChar.cpp/
#include <stdint.h> #include <SDL_rwops.h> #include "WindowsWrapper.h" #include "CommonDefines.h" #include "Tags.h" #include "NpChar.h" #include "Game.h" #include "Flags.h" #include "NpcTbl.h" #include "Draw.h" NPCHAR gNPC[NPC_MAX]; const char *gPassPixEve = "PXE\0"; void InitNpChar() { memset(gNPC, 0, sizeof(gNPC)); } void SetUniqueParameter(NPCHAR *npc) { int code = npc->code_char; npc->surf = gNpcTable[code].surf; npc->hit_voice = gNpcTable[code].hit_voice; npc->destroy_voice = gNpcTable[code].destroy_voice; npc->damage = gNpcTable[code].damage; npc->size = gNpcTable[code].size; npc->life = gNpcTable[code].life; npc->hit.front = gNpcTable[code].hit.front << 9; npc->hit.back = gNpcTable[code].hit.back << 9; npc->hit.top = gNpcTable[code].hit.top << 9; npc->hit.bottom = gNpcTable[code].hit.bottom << 9; npc->view.front = gNpcTable[code].view.front << 9; npc->view.back = gNpcTable[code].view.back << 9; npc->view.top = gNpcTable[code].view.top << 9; npc->view.bottom = gNpcTable[code].view.bottom << 9; } bool LoadEvent(char *path_event) { char path[PATH_LENGTH]; sprintf(path, "%s/%s", gDataPath, path_event); SDL_RWops *fp = SDL_RWFromFile(path, "rb"); if (!fp) return false; //Read "PXE" check char code[4]; fp->read(fp, code, 1, 4); if (memcmp(code, gPassPixEve, 3)) return false; //Get amount of NPCs int count = SDL_ReadLE32(fp); //Load NPCs memset(gNPC, 0, sizeof(gNPC)); int n = 170; for (int i = 0; i < count; i++) { //Get data from file EVENT eve; eve.x = SDL_ReadLE16(fp); eve.y = SDL_ReadLE16(fp); eve.code_flag = SDL_ReadLE16(fp); eve.code_event = SDL_ReadLE16(fp); eve.code_char = SDL_ReadLE16(fp); eve.bits = SDL_ReadLE16(fp); //Set NPC parameters if (eve.bits & npc_altDir) gNPC[n].direct = 2; else gNPC[n].direct = 0; gNPC[n].code_char = eve.code_char; gNPC[n].code_event = eve.code_event; gNPC[n].code_flag = eve.code_flag; gNPC[n].x = eve.x << 13; gNPC[n].y = eve.y << 13; gNPC[n].bits = eve.bits; gNPC[n].bits |= gNpcTable[gNPC[n].code_char].bits; gNPC[n].exp = gNpcTable[gNPC[n].code_char].exp; SetUniqueParameter(&gNPC[n]); //Check flags if (gNPC[n].bits & npc_appearSet) { if (GetNPCFlag(gNPC[n].code_flag)) gNPC[n].cond |= 0x80u; } else if (gNPC[n].bits & npc_hideSet) { if (!GetNPCFlag(gNPC[n].code_flag)) gNPC[n].cond |= 0x80u; } else { gNPC[n].cond = 0x80; } //Increase index n++; } return true; } void SetNpChar(int code_char, int x, int y, int xm, int ym, int dir, NPCHAR *npc, int start_index) { for (int n = start_index; n < NPC_MAX; n++) { if (!gNPC[n].cond) { //Set NPC parameters memset(&gNPC[n], 0, sizeof(NPCHAR)); gNPC[n].cond |= 0x80u; gNPC[n].direct = dir; gNPC[n].code_char = code_char; gNPC[n].x = x; gNPC[n].y = y; gNPC[n].xm = xm; gNPC[n].ym = ym; gNPC[n].pNpc = npc; gNPC[n].bits = gNpcTable[gNPC[n].code_char].bits; gNPC[n].exp = gNpcTable[gNPC[n].code_char].exp; SetUniqueParameter(&gNPC[n]); break; } } } void SetDestroyNpChar(int x, int y, int w, int num) { //Create smoke int wa = w / 0x200; for (int i = 0; i < num; i++) { int offset_x = Random(-wa, wa) << 9; int offset_y = Random(-wa, wa) << 9; SetNpChar(4, x + offset_x, offset_y + y, 0, 0, 0, NULL, 0x100); } //Flash effect //SetCaret(x, y, 12, 0); } void SetDestroyNpCharUp(int x, int y, int w, int num) { //Create smoke int wa = w / 0x200; for (int i = 0; i < num; i++) { int offset_x = Random(-wa, wa) << 9; int offset_y = Random(-wa, wa) << 9; SetNpChar(4, x + offset_x, offset_y + y, 0, 0, 1, NULL, 0x100); } //Flash effect //SetCaret(x, y, 12, 0); } void SetExpObjects(int x, int y, int exp) { for (int n = 0x100; exp; SetUniqueParameter(&gNPC[n])) { if (!gNPC[n].cond) { memset(&gNPC[n], 0, sizeof(NPCHAR)); int sub_exp = 0; if (exp < 20) { if (exp < 5) { if (exp > 0) { --exp; sub_exp = 1; } } else { exp -= 5; sub_exp = 5; } } else { exp -= 20; sub_exp = 20; } gNPC[n].cond |= 0x80u; gNPC[n].direct = 0; gNPC[n].code_char = 1; gNPC[n].x = x; gNPC[n].y = y; gNPC[n].bits = gNpcTable[gNPC[n].code_char].bits; gNPC[n].exp = sub_exp; } } } bool SetBulletObject(int x, int y, int val) { int tamakazu_ari[10]; int t = 0; memset(tamakazu_ari, 0, sizeof(tamakazu_ari)); for (int n = 0; n < 8; n++) { int code = 0; //gArmsData[n].code; if (code == 5) tamakazu_ari[t++] = 0; else if (code == 10) tamakazu_ari[t++] = 1; else tamakazu_ari[t] = 0; } if (!t) return false; int n = Random(1, 10 * t); int bullet_no = tamakazu_ari[n % t]; for (n = 0x100; n < NPC_MAX; n++) { if (!gNPC[n].cond) { memset(&gNPC[n], 0, sizeof(NPCHAR)); gNPC[n].cond |= 0x80u; gNPC[n].direct = 0; gNPC[n].code_event = bullet_no; gNPC[n].code_char = 86; gNPC[n].x = x; gNPC[n].y = y; gNPC[n].bits = gNpcTable[gNPC[n].code_char].bits; gNPC[n].exp = val; SetUniqueParameter(&gNPC[n]); return true; } } return false; } bool SetLifeObject(int x, int y, int val) { for (int n = 0x100; n < NPC_MAX; n++) { if (!gNPC[n].cond) { memset(&gNPC[n], 0, sizeof(NPCHAR)); gNPC[n].cond |= 0x80u; gNPC[n].direct = 0; gNPC[n].code_char = 87; gNPC[n].x = x; gNPC[n].y = y; gNPC[n].bits = gNpcTable[gNPC[n].code_char].bits; gNPC[n].exp = val; SetUniqueParameter(&gNPC[n]); return true; } } return false; } void VanishNpChar(NPCHAR *npc) { int x = npc->x; int y = npc->y; memset(npc, 0, sizeof(NPCHAR)); npc->count1 = 0; npc->x = x; npc->y = y; npc->cond |= 0x80u; npc->direct = 0; npc->code_char = 3; npc->bits = gNpcTable[npc->code_char].bits; npc->exp = gNpcTable[npc->code_char].exp; SetUniqueParameter(npc); } void PutNpChar(int fx, int fy) { for (int n = 0; n < NPC_MAX; n++) { if (gNPC[n].cond & 0x80) { int8_t a; if (gNPC[n].shock) { a = 2 * ((gNPC[n].shock >> 1) & 1) - 1; } else { a = 0; if (gNPC[n].bits & npc_showDamage && gNPC[n].damage_view) { //SetValueView(&gNPC[n].x, &gNPC[n].y, gNPC[n].damage_view); gNPC[n].damage_view = 0; } } int side; if (gNPC[n].direct) side = gNPC[n].view.back; else side = gNPC[n].view.front; PutBitmap3( &grcGame, (gNPC[n].x - side) / 0x200 - fx / 0x200 + a, (gNPC[n].y - gNPC[n].view.top) / 0x200 - fy / 0x200, &gNPC[n].rect, gNPC[n].surf); } } } void ActNpChar() { for (int i = 0; i < NPC_MAX; i++) { if (gNPC[i].cond & 0x80) { if (gpNpcFuncTbl[gNPC[i].code_char] != nullptr) gpNpcFuncTbl[gNPC[i].code_char](&gNPC[i]); if (gNPC[i].shock) --gNPC[i].shock; } } }