From 3b77165e92abeb41f9a9e04782ef0c08193e7b07 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Tue, 31 May 2022 20:42:43 +0100 Subject: [PATCH] general improvements to UI and strategy --- CMakeLists.txt | 1 + assets-cg/hud_itemslots.png | Bin 803 -> 7725 bytes assets-cg/hud_panel.png | Bin 1149 -> 7005 bytes assets-cg/hud_small.png | Bin 0 -> 12959 bytes src/comp/fighter.c | 78 ++++++-------- src/comp/fighter.h | 25 ++--- src/enemies.c | 54 ++++------ src/enemies.h | 2 +- src/item.c | 88 ++++++++++++---- src/item.h | 14 ++- src/main.c | 38 ++++--- src/player.c | 57 +++++----- src/player.h | 13 +-- src/render.c | 204 ++++++++++++++++++++++++++++-------- src/render.h | 3 - 15 files changed, 362 insertions(+), 215 deletions(-) create mode 100644 assets-cg/hud_small.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 806d521..ec66af8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ set(ASSETS assets-cg/hud_itemslots.png assets-cg/hud_life.png assets-cg/hud_panel.png + assets-cg/hud_small.png assets-cg/hud_xp.ase assets-cg/skillicons.png assets-cg/font_hud.png diff --git a/assets-cg/hud_itemslots.png b/assets-cg/hud_itemslots.png index 4ff3f240ccbf0ff459f386e237b1ce24cb95ff17..a8ce64bd4a25df99b08d6459d6f82720ec33fda9 100644 GIT binary patch literal 7725 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 delta 787 zcmV+u1MK{*JfjAGiBL{Q4GJ0x0000DNk~Le0000v0000J2m$~A0HsYbf&c&kglR)V zP)S2WAaHVTW@&6?001bFeUUv#!$2IxUsI(b6;V5gh-9cv7DPoIwF*V35Nd^19ZW9$ zf+h_~ii@M*T5#}VvFhOBtgC~oAP9bdI665gx=4xtOA0N2Vm&zS$GdxvyLW(4Ei%n& z8v``mHWRU^m`bmTfmis^gI-KyNM@EXCrNR%9AEeF@%1jkvs$0~b9AX0ivd27c$OKa zO}s%owP_oi_lZL+FRR4o#G@u%kob}7ipOu9b1n-!Gh`+c^TZ)yG1tUO6SKUj5l<3_ zRZXXSA?2}u%6W^kRxGpnJ^2fR8GU7$>of-u!y=X-L4<-b3Mj%xgjSst3klkfw(t+Q zeu-QPxe8$9SU?FHWY-V=2fw?uvJ>N8QZNd%zc|jvFc8=UY8A)%K6aei3E+PQuJne# zR0U=}Nv|}t@Db3x4P0C|G-VIC+yVNZ4B3=j$xl->$Yz1}Gy0}9(02=Tu6e!H_i_3F zB&njN~YLy~VpbntS{AOufG!qHuD$R*i_JllL4Se*+Q|7%U&!UT6RS0WwKM zK~zY`?Uyl%!!Qs<<;7Ll1Gr2%MGml~Y7+)we3leGfQy_Z7$b~o9U?3yC-4D+>n;AS z5Mgab+nM!L(l8%=jR*9c9f_1uMNuemOw$x36*H2ZwM+FcHAIB1_g-?G)*6dEq{jOw zQPPQGN%tdcf11mZq;0Pdj`tDr{??n?%+FaVRi4Wwp&J|)sLwvMmK%-jR?O&A(j_bA z&&MOq_qTpYVrmm_^Hig#$H7U$?_y@}{rsHEbGhO&zJ{rd8{Faj@TRsCfA`v1yE3D{ zM$=p{Hj<{s-Nj7*kG}3+cdxtG-RqXTR?L7Bd9>{nRm|lE_wv@S1m4(<^)(N)mdaUS zkqVQ6N6}gdXW@;_0nT!}bRtMPYXfje_%-k@5rIeXWmkp)1%L-rn`}e>1z%evql)VW R0i6H<002ovPDHLkV1kLHWS#&3 diff --git a/assets-cg/hud_panel.png b/assets-cg/hud_panel.png index 6e2a6e1e6ba44bbdea0dfce6f5178476606f7652..1620ce38d748301fe5f8f7180177b92d71642cf0 100644 GIT binary patch literal 7005 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 N1mpeqO2b1({{!h;W`6(x delta 1100 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 #include -fighter_stat_model_t fighter_stat_model_mul(int amount, ...) +fighter_stats_t fighter_stats_add(int amount, ...) { va_list args; va_start(args, amount); - fighter_stat_model_t model = { - .HP = fix(1), - .ATK = fix(1), - .DEF = fix(1), - .MAG = fix(1), }; + fighter_stats_t m = { 0 }; for(int i = 0; i < amount; i++) { - fighter_stat_model_t op = va_arg(args, fighter_stat_model_t); - model.HP = fmul(model.HP , op.HP); - model.ATK = fmul(model.ATK, op.ATK); - model.DEF = fmul(model.DEF, op.DEF); - model.MAG = fmul(model.MAG, op.MAG); + fighter_stats_t op = va_arg(args, fighter_stats_t); + m.HP += op.HP; + m.ATK += op.ATK; + m.DEF += op.DEF; + m.MAG += op.MAG; } va_end(args); - return model; -} - -static int instantiate_stat(fixed_t affinity, fixed_t multiplier, int level) -{ - float a = f2double(affinity); - float x = level; - float y = powf(x, a) + x + 3 * a; - return fround(multiplier * (int)y); -} - -fighter_stat_model_t fighter_stat_model_instantiate( - fighter_stat_model_t const *model, fighter_stat_model_t const *equipment, - int level, fixed_t hp_multiplier) -{ - fighter_stat_model_t m; - m.HP = fix(instantiate_stat(model->HP, 3 * hp_multiplier, level)); - m.ATK = fix(instantiate_stat(model->ATK, fix(1.6), level)); - m.DEF = fix(instantiate_stat(model->DEF, fix(0.7), level)); - m.MAG = fix(instantiate_stat(model->MAG, fix(1.2), level)); - - /* Apply equipment boost */ - if(equipment) { - m.HP = fmul(m.HP, equipment->HP); - m.ATK = fmul(m.ATK, equipment->ATK); - m.DEF = fmul(m.DEF, equipment->DEF); - m.MAG = fmul(m.MAG, equipment->MAG); - } - return m; } -void fighter_set_stats(fighter_t *f, fighter_stat_model_t const *instance) +fighter_stats_t fighter_stats_instantiate(fighter_stats_t const *base, + fighter_stats_t const *slope, int level) { - f->HP_max = ffloor(instance->HP); - f->ATK = ffloor(instance->ATK); - f->MAG = ffloor(instance->MAG); - f->DEF = ffloor(instance->DEF); + fighter_stats_t m; + m.HP = base->HP + level * slope->HP; + m.ATK = base->ATK + level * slope->ATK; + m.DEF = base->DEF + level * slope->DEF; + m.MAG = base->MAG + level * slope->MAG; + return m; +} + +void fighter_set_stats(fighter_t *f, fighter_stats_t const *stats) +{ + f->HP_max = stats->HP; + f->ATK = stats->ATK; + f->MAG = stats->MAG; + f->DEF = stats->DEF; +} + +void fighter_increase_stats(fighter_t *f, fighter_stats_t const *growth) +{ + int previous_HP_max = f->HP_max; + f->HP_max += growth->HP; + f->HP += (f->HP_max - previous_HP_max); + f->ATK += growth->ATK; + f->MAG += growth->MAG; + f->DEF += growth->DEF; } int fighter_damage(entity_t *e, int base_damage) diff --git a/src/comp/fighter.h b/src/comp/fighter.h index 6630268..5179b05 100644 --- a/src/comp/fighter.h +++ b/src/comp/fighter.h @@ -12,15 +12,15 @@ typedef struct { /* Hit Points */ - fixed_t HP; + int HP; /* Physical attack */ - fixed_t ATK; + int ATK; /* Magical attack */ - fixed_t MAG; + int MAG; /* Physical and magical defense */ - fixed_t DEF; + int DEF; -} fighter_stat_model_t; +} fighter_stats_t; typedef struct { @@ -55,16 +55,17 @@ typedef struct } fighter_t; -/* Multiply equipment stat modifiers */ -fighter_stat_model_t fighter_stat_model_mul(int amount, ...); +/* Add equipment stat modifiers */ +fighter_stats_t fighter_stats_add(int amount, ...); -/* Instantiate a statistics model with optional equipment and HP multiplier */ -fighter_stat_model_t fighter_stat_model_instantiate( - fighter_stat_model_t const *model, fighter_stat_model_t const *equipment, - int level, fixed_t hp_multiplier); +/* Instantiate a statistics model at any level */ +fighter_stats_t fighter_stats_instantiate(fighter_stats_t const *base,fighter_stats_t const *slope, int level); /* Initialize fighter's stats by using the instantiated stat model */ -void fighter_set_stats(fighter_t *f, fighter_stat_model_t const *instance); +void fighter_set_stats(fighter_t *f, fighter_stats_t const *instance); + +/* Increase fighter's stats by specified amount */ +void fighter_increase_stats(fighter_t *f, fighter_stats_t const *growth); /* Damage entity for that amount of raw strength. Returns actual damage after DES is subtracted, and randomization. */ diff --git a/src/enemies.c b/src/enemies.c index 30ea46b..6e64b1d 100644 --- a/src/enemies.c +++ b/src/enemies.c @@ -31,12 +31,9 @@ static enemy_t const slime_1 = { .friction = fix(0.6), .max_disruption_speed = fix(999.0), }, - .stats = { - .HP = fix(1.4), - .ATK = fix(1.3), - .MAG = fix(1.0), - .DEF = fix(1.4), - }, + .stats_base = { .HP=10, .ATK=8, .MAG=5, .DEF=4 }, + .stats_growth = { .HP=8, .ATK=4, .MAG=4, .DEF=3 }, + .shadow_size = 4, .xp = 2, .z = 0, @@ -53,12 +50,9 @@ static enemy_t const bat_2 = { .friction = fix(0.8), .max_disruption_speed = fix(999.0), }, - .stats = { - .HP = fix(1.5), - .ATK = fix(1.5), - .MAG = fix(1.3), - .DEF = fix(1.2), - }, + .stats_base = { .HP=12, .ATK=10, .MAG=5, .DEF=5 }, + .stats_growth = { .HP=10, .ATK=3, .MAG=2, .DEF=1 }, + .shadow_size = 4, .xp = 6, .z = fix(0.75), @@ -75,12 +69,10 @@ static enemy_t const fire_slime_4 = { .friction = fix(0.6), .max_disruption_speed = fix(999.0), }, - .stats = { - .HP = fix(1.4), - .ATK = fix(1.2), - .MAG = fix(1.4), - .DEF = fix(1.4), - }, + /* Same as slime/1 */ + .stats_base = { .HP=10, .ATK=8, .MAG=5, .DEF=4 }, + .stats_growth = { .HP=8, .ATK=4, .MAG=4, .DEF=3 }, + .shadow_size = 4, .xp = 14, .z = 0, @@ -97,13 +89,10 @@ static enemy_t const albinos_bat_6 = { .friction = fix(0.7), .max_disruption_speed = fix(999.0), }, - .stats = { - /* Same as bat/2 */ - .HP = fix(1.5), - .ATK = fix(1.5), - .MAG = fix(1.3), - .DEF = fix(1.2), - }, + /* Same as bat/2 */ + .stats_base = { .HP=12, .ATK=10, .MAG=5, .DEF=5 }, + .stats_growth = { .HP=10, .ATK=3, .MAG=2, .DEF=1 }, + .shadow_size = 4, .xp = 20, .z = fix(0.5), @@ -120,12 +109,9 @@ static enemy_t const gunslinger_8 = { .friction = fix(0.8), .max_disruption_speed = fix(999.0), }, - .stats = { - .HP = fix(1.3), - .ATK = fix(1.6), - .MAG = fix(1.4), - .DEF = fix(1.2), - }, + .stats_base = { .HP=16, .ATK=12, .MAG=3, .DEF=6 }, + .stats_growth = { .HP=12, .ATK=4, .MAG=1, .DEF=1 }, + .shadow_size = 4, .xp = 30, .z = fix(0.25), @@ -184,9 +170,9 @@ entity_t *enemy_make(int enemy_id) fighter_t *f = getcomp(e, fighter); memset(f, 0, sizeof *f); - fighter_stat_model_t inst = fighter_stat_model_instantiate(&data->stats, - NULL, data->level, fix(1.0)); - fighter_set_stats(f, &inst); + fighter_stats_t stats = fighter_stats_instantiate(&data->stats_base, + &data->stats_growth, data->level); + fighter_set_stats(f, &stats); f->HP = f->HP_max; f->combo_length = 1; f->enemy = malloc(sizeof *f->enemy + data->ai_data_size); diff --git a/src/enemies.h b/src/enemies.h index 9db624d..a024d0c 100644 --- a/src/enemies.h +++ b/src/enemies.h @@ -23,7 +23,7 @@ typedef struct /* Movement parameters */ mechanical_limits_t limits; /* Statistics model */ - fighter_stat_model_t stats; + fighter_stats_t stats_base, stats_growth; /* Level */ uint8_t level; /* Shadow size */ diff --git a/src/item.c b/src/item.c index 45a67c9..6a41526 100644 --- a/src/item.c +++ b/src/item.c @@ -36,6 +36,64 @@ anim_t const *item_anim(int item) return NULL; } +char const *item_name(int item) +{ + if(item == ITEM_LIFE) + return "Heart transpl."; + else if(item == ITEM_POTION_ATK) + return "Berserk elixir"; + else if(item == ITEM_POTION_COOLDOWN) + return "Quick reload"; + else if(item == ITEM_POTION_DEF) + return "Turtle potion"; + else if(item == ITEM_POTION_FRZ) + return "Time freeze"; + else if(item == ITEM_POTION_HP) + return "Health potion"; + else if(item == ITEM_POTION_SPD) + return "Speed potion"; + else if(item == ITEM_SCEPTER1) + return "Cypress wand"; + else if(item == ITEM_SCEPTER2) + return "Holy staff"; + else if(item == ITEM_SWORD1) + return "Short sword"; + else if(item == ITEM_SWORD2) + return "Golden blade"; + else if(item == ITEM_ARMOR1) + return "Leather armor"; + return "???"; +} + +char const *item_description(int item) +{ + if(item == ITEM_LIFE) + return NULL; + else if(item == ITEM_POTION_ATK) + return NULL; + else if(item == ITEM_POTION_COOLDOWN) + return NULL; + else if(item == ITEM_POTION_DEF) + return NULL; + else if(item == ITEM_POTION_FRZ) + return NULL; + else if(item == ITEM_POTION_HP) + return NULL; + else if(item == ITEM_POTION_SPD) + return NULL; + else if(item == ITEM_SCEPTER1) + return "On level up:\n ATK+1 MAG+3 DEF+1"; + else if(item == ITEM_SCEPTER2) + return "On level up:\n MAG+5 DEF+1"; + else if(item == ITEM_SWORD1) + return "On level up:\n ATK+3 MAG+1"; + else if(item == ITEM_SWORD2) + return "On level up:\n ATK+5 MAG+0"; + else if(item == ITEM_ARMOR1) + return "On level up:\n DEF+2"; + return NULL; +} + entity_t *item_make(int type, vec2 position) { entity_t *e = aoe_make(AOE_ITEM, position, fix(9999.0)); @@ -110,36 +168,30 @@ int item_equipment_slot(int item) } } -fighter_stat_model_t item_stat_model(int item) +fighter_stats_t item_stat_model(int item) { - fighter_stat_model_t m = { - .HP = fix(1.0), - .ATK = fix(1.0), - .DEF = fix(1.0), - .MAG = fix(1.0), - }; + fighter_stats_t m = { 0 }; switch(item) { case ITEM_SWORD1: - m.ATK = fix(1.4); - m.MAG = fix(1.2); + m.ATK = 3; + m.MAG = 1; break; case ITEM_SWORD2: - m.ATK = fix(1.8); - m.MAG = fix(1.3); + m.ATK = 5; + m.MAG = 0; break; case ITEM_SCEPTER1: - m.ATK = fix(1.15); - m.DEF = fix(1.1); - m.MAG = fix(1.3); + m.ATK = 1; + m.MAG = 3; + m.DEF = 1; break; case ITEM_SCEPTER2: - m.ATK = fix(1.25); - m.DEF = fix(1.15); - m.MAG = fix(1.6); + m.MAG = 5; + m.DEF = 1; break; case ITEM_ARMOR1: - m.DEF = fix(1.3); + m.DEF = 2; break; } diff --git a/src/item.h b/src/item.h index 2216dc5..ef0b743 100644 --- a/src/item.h +++ b/src/item.h @@ -30,6 +30,16 @@ enum { /* Animation for each item. */ anim_t const *item_anim(int item); +/* Item name (fancy huh?). */ +char const *item_name(int item); + +/* Item description, can be multi-line. NULL if none specified. */ +char const *item_description(int item); + +/* Whether an item is a piece of equipment. */ +#define item_is_equip(item) \ + ((item) >= ITEM_EQUIPMENT_START && (item) <= ITEM_EQUIPMENT_END) + /* Create an item. This is just an AOE with a particular type. */ entity_t *item_make(int item, vec2 position); @@ -39,8 +49,8 @@ bool item_pick_up(int item, entity_t *player); /* Which equipment slot an item goes in. */ int item_equipment_slot(int item); -/* Stat increases for each item that can be equipped. */ -fighter_stat_model_t item_stat_model(int item); +/* Stat increases for each item that can be equipped, per level. */ +fighter_stats_t item_stat_model(int item); /* Get skills associated with each item that can be equipped. */ void item_skills(int item, int *skill1, int *skill2, int *skill3); diff --git a/src/main.c b/src/main.c index a40aee3..b88f753 100644 --- a/src/main.c +++ b/src/main.c @@ -100,16 +100,14 @@ int main(void) .dash_duration = fix(1) / 8, .max_disruption_speed = fix(3.0), }, - .stat_model = { - .HP = fix(1.5), - .ATK = fix(1.5), - .DEF = fix(1.5), - .MAG = fix(1.5), - }, + .stats = { .HP=60, .ATK=13, .MAG=10, .DEF=6 }, + .stats_growth = { .HP=25, .ATK=1, .MAG=1, .DEF=1 }, + .xp_level = 0, .xp_to_next_level = 0, .xp_current = 0, - .inventory = { -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +// .inventory = { -1, -1, -1, -1, -1, -1, -1, -1 }, + .inventory = { 1, 2, 3, 5, 101, -1, -1, -1 }, .equipment = { -1, -1, -1 }, }; @@ -131,6 +129,10 @@ int main(void) for(int i = 0; i < 6; i++) player_f->actions_cooldown[i] = fix(0.0); /* Initialize stats. This will level up to level 1 */ + player_f->HP_max = player_data.stats.HP; + player_f->ATK = player_data.stats.ATK; + player_f->MAG = player_data.stats.MAG; + player_f->DEF = player_data.stats.DEF; player_add_xp(player, 0); player_f->HP = player_f->HP_max; @@ -439,29 +441,25 @@ int main(void) /* Inventory movement */ if(!debug.paused && game.menu_open) { - int y = game.menu_cursor / 3, x = game.menu_cursor % 3; + int y = game.menu_cursor / 4, x = game.menu_cursor % 4; y = y + (ev.key == KEY_DOWN) - (ev.key == KEY_UP); x = x + (ev.key == KEY_RIGHT) - (ev.key == KEY_LEFT); - y = max(0, min(y, 2)); - x = max(0, min(x, 2)); - game.menu_cursor = 3 * y + x; + y = max(0, min(y, 1)); + x = max(0, min(x, 3)); + game.menu_cursor = 4 * y + x; } - /* Equipping items */ + /* Equipping and unequipping items */ if(!debug.paused && game.menu_open && ev.key == KEY_SHIFT) { int item = player_data.inventory[game.menu_cursor]; int slot = item_equipment_slot(item); if(item >= 0 && slot >= 0) { - int e = player_data.equipment[slot]; - player_data.equipment[slot] = item; - player_data.inventory[game.menu_cursor] = e; + if(player_data.equipment[slot] == game.menu_cursor) + player_data.equipment[slot] = -1; + else + player_data.equipment[slot] = game.menu_cursor; - /* Update stats */ - fighter_stat_model_t stats = player_compute_stats(player, - player_data.equipment); - fighter_set_stats(player_f, &stats); - player_f->HP = min(player_f->HP, player_f->HP_max); /* Update skills */ player_compute_skills(player, player_data.equipment, player_f->skills); diff --git a/src/player.c b/src/player.c index 8c0c525..637e23d 100644 --- a/src/player.c +++ b/src/player.c @@ -7,10 +7,24 @@ static int xp_to_next_level(int level) return 5 * (level + 2) * (level + 2); } -bool player_add_xp(entity_t *e, int points) +fighter_stats_t player_compute_growth(entity_t *e, int *equips) { player_data_t *p = getcomp(e, fighter)->player; + fighter_stats_t m[3] = { + item_stat_model(p->inventory[equips[0]]), + item_stat_model(p->inventory[equips[1]]), + item_stat_model(p->inventory[equips[2]]), + }; + + return fighter_stats_add(4, m[0], m[1], m[2], p->stats_growth); +} + +bool player_add_xp(entity_t *e, int points) +{ + fighter_t *f = getcomp(e, fighter); + player_data_t *p = f->player; + bool leveled_up = false; p->xp_current += max(points, 0); @@ -18,62 +32,39 @@ bool player_add_xp(entity_t *e, int points) p->xp_current -= p->xp_to_next_level; p->xp_level++; p->xp_to_next_level = xp_to_next_level(p->xp_level); + + fighter_stats_t growth = player_compute_growth(e, p->equipment); + fighter_increase_stats(f, &growth); leveled_up = true; } - /* Recompute statistics */ - if(leveled_up) { - fighter_t *f = getcomp(p->entity, fighter); - int previous_HP_max = f->HP_max; - - fighter_stat_model_t stats = player_compute_stats(e, p->equipment); - fighter_set_stats(getcomp(p->entity, fighter), &stats); - f->HP += (f->HP_max - previous_HP_max); - } - return leveled_up; } -fighter_stat_model_t player_compute_stats(entity_t *e, int *equips) -{ - player_data_t *p = getcomp(e, fighter)->player; - - fighter_stat_model_t m[3] = { - item_stat_model(equips[0]), - item_stat_model(equips[1]), - item_stat_model(equips[2]), - }; - - fighter_stat_model_t equip_model = fighter_stat_model_mul(3, - m[0], m[1], m[2]); - - return fighter_stat_model_instantiate(&p->stat_model, &equip_model, - p->xp_level, fix(3.0)); -} - void player_compute_skills(entity_t *e, int *equips, int *skills) { - (void)e; + player_data_t *p = getcomp(e, fighter)->player; + int *inv = p->inventory; for(int i = 0; i < 6; i++) skills[i] = -1; /* Sword/staff */ if(equips[0] >= 0) - item_skills(equips[0], &skills[0], &skills[1], &skills[2]); + item_skills(inv[equips[0]], &skills[0], &skills[1], &skills[2]); /* Armor */ if(equips[1] >= 0) - item_skills(equips[1], &skills[3], &skills[4], NULL); + item_skills(inv[equips[1]], &skills[3], &skills[4], NULL); /* Accessory */ if(equips[2] >= 0) - item_skills(equips[2], &skills[5], NULL, NULL); + item_skills(inv[equips[2]], &skills[5], NULL, NULL); } bool player_give_item(entity_t *e, int item) { player_data_t *p = getcomp(e, fighter)->player; - for(int i = 0; i < 9; i++) { + for(int i = 0; i < 8; i++) { if(p->inventory[i] < 0) { p->inventory[i] = item; return true; diff --git a/src/player.h b/src/player.h index 4f05d99..a9a9ec9 100644 --- a/src/player.h +++ b/src/player.h @@ -14,15 +14,16 @@ typedef struct player_data { entity_t *entity; /* Mechanical limits (dynamically recomputed) */ mechanical_limits_t mechanical_limits; - /* Fighter model (dynamically recomputed) */ - fighter_stat_model_t stat_model; + /* Fighter model */ + fighter_stats_t stats, stats_growth; /* Experience level, total to next level, current points (within level) */ int xp_level; int xp_to_next_level; int xp_current; /* Inventory */ - int inventory[9]; - /* Current equipped items */ + int inventory[8]; + /* IDs of inventory slots holding currently-equipped item for each kind of + equipment (-1 if none equipped) */ int equipment[3]; } player_data_t; @@ -30,8 +31,8 @@ typedef struct player_data { /* Add XP points to a player. Returns true if levels up */ bool player_add_xp(entity_t *p, int points); -/* Compute player's statistics under hypothetical equips */ -fighter_stat_model_t player_compute_stats(entity_t *e, int *equips); +/* Compute player's statistics growth under hypothetical equips */ +fighter_stats_t player_compute_growth(entity_t *e, int *equips); /* Compute player's skills under hypothetical equips */ void player_compute_skills(entity_t *e, int *equips, int *skills); diff --git a/src/render.c b/src/render.c index 4182b88..2c975e0 100644 --- a/src/render.c +++ b/src/render.c @@ -392,17 +392,17 @@ static void render_info(int x, int y, game_t const *g) } } -void render_panel(int x, int y, bool hflip) +static void render_panel(int x, int y, bool hflip) { extern bopti_image_t img_hud_panel; - int sx = hflip ? 0 : 14; + int w = 130; + int sx = hflip ? 0 : img_hud_panel.width - w; int sy = 0; - int w = 94; dsubimage(x, y, &img_hud_panel, sx, sy, w, 30, DIMAGE_NONE); y += 30; sy += 30; - for(int i = 0; i < 9; i++) { + for(int i = 0; i < 10; i++) { dsubimage(x, y, &img_hud_panel, sx, sy, w, 10, DIMAGE_NONE); y += 10; } @@ -413,6 +413,70 @@ void render_panel(int x, int y, bool hflip) uint32_t time_render_map = 0; uint32_t time_render_hud = 0; +static void subimage_outline(int x, int y, image_t const *img, int left, + int top, size_t w, size_t h, int color) +{ + int alpha = image_alpha(img->format); + + for(int iy = -1; iy < (int)h+1; iy++) + for(int ix = -1; ix < (int)w+1; ix++) { + bool inb = ((size_t)ix < w && (size_t)iy < h); + int pixel = inb ? image_get_pixel(img, left+ix, top+iy) : alpha; + + if(pixel != alpha) { + dpixel(x+ix, y+iy, image_decode_pixel(img, pixel)); + continue; + } + + bool linked = false; + for(int i = 0; i < 4; i++) { + int dy = (i == 0) - (i == 1); + int dx = (i == 2) - (i == 3); + if((size_t)(ix+dx) < w && (size_t)(iy+dy) < h) + linked |= image_get_pixel(img, left+ix+dx, top+iy+dy) != alpha; + } + if(linked) + dpixel(x+ix, y+iy, color); + } +} + +static void anim_frame_render_outline(int x, int y, anim_frame_t const *frame, + int color) +{ + if(!frame) return; + subimage_outline(x - frame->cx, y - frame->cy, frame->sheet, + frame->x, frame->y, frame->w, frame->h, color); +} + +static int small_text(int x, int y, int color, char const *text, int size) +{ + extern bopti_image_t img_hud_small; + if(size < 0) + size = strlen(text); + + if(!strncmp(text, "SHIFT", size)) { + dsubimage(x-1, y+3, &img_hud_small, 0, 0, 27, 8, DIMAGE_NONE); + return 27-1; + } + if(!strncmp(text, "HP", size)) { + dsubimage(x-1, y+3, &img_hud_small, 0, 8, 12, 8, DIMAGE_NONE); + return 12-1; + } + if(!strncmp(text, "ATK", size)) { + dsubimage(x-1, y+3, &img_hud_small, 0, 16, 17, 8, DIMAGE_NONE); + return 17-1; + } + if(!strncmp(text, "MAG", size)) { + dsubimage(x-1, y+3, &img_hud_small, 0, 24, 19, 8, DIMAGE_NONE); + return 19-1; + } + if(!strncmp(text, "DEF", size)) { + dsubimage(x-1, y+3, &img_hud_small, 0, 32, 18, 8, DIMAGE_NONE); + return 18-1; + } + return 0; +} + static void print_stat_opt(int x, int y, int stat, int reference, char const *format, ...) { @@ -428,9 +492,43 @@ static void print_stat_opt(int x, int y, int stat, int reference, dtext(x, y, color, str); } -static void print_stat(int x, int y, int stat, int reference) +static void print_stat(int x, int y, int current, int g_vis, int g_base) { - print_stat_opt(x, y, stat, reference, "%d", stat); + dprint(x, y, C_WHITE, "%d", current); + + int color = C_RGB(10, 10, 10); + if(g_vis < g_base) color = RGB24(0xc05458); + if(g_vis > g_base) color = RGB24(0x21c24f); + dprint(x+30, y, color, "+%d/Lv", g_vis); +} + +static void dtext_multi(int x0, int y, int color, char const *str) +{ + int x = x0; + + while(*str) { + if(!strncmp(str, "HP", 2)) { + x += small_text(x, y, color, str, 2) + 1; + str += 2; + } + else if(!strncmp(str, "ATK", 3) || !strncmp(str, "MAG", 3) || + !strncmp(str, "DEF", 3)) { + x += small_text(x, y, color, str, 3) + 1; + str += 3; + } + else if(*str == '\n') { + str++; + y += 13; + x = x0; + } + else { + int w; + dnsize(str, 1, NULL, &w, NULL); + dtext_opt(x, y, color, C_NONE, DTEXT_LEFT, DTEXT_TOP, str, 1); + x += w + 1; + str++; + } + } } void render_game(game_t const *g, bool show_hitboxes) @@ -551,69 +649,93 @@ void render_game(game_t const *g, bool show_hitboxes) } if(g->menu_time > 0) { - int x1 = cubic(-94, 0, g->menu_time, fix(1)); - int x2 = DWIDTH - 94 - x1; + int x1 = cubic(-130, 0, g->menu_time, fix(1)); + int x2 = DWIDTH - 130 - x1; fighter_t *player_f = getcomp(g->player, fighter); player_data_t *player_data = player_f->player; - render_panel(x1, 27, false); - render_panel(x2, 27, true); + render_panel(x1, 22, false); + render_panel(x2, 22, true); extern font_t font_rogue; font_t const *old_font = dfont(&font_rogue); - dprint_opt(x1+42, 38, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP, + dprint_opt(x1+61, 33, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP, "Inventory"); - dprint_opt(x2+52, 38, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP, + dprint_opt(x2+72, 33, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP, "Status"); - dprint_opt(x2+52, 49, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP, + dprint_opt(x2+72, 44, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP, "Lv.%d (%d/%d)", player_data->xp_level, player_data->xp_current, player_data->xp_to_next_level); + int selected_item = player_data->inventory[g->menu_cursor]; + extern bopti_image_t img_hud_itemslots; - for(int y = 0; y < 3; y++) - for(int x = 0; x < 3; x++) { - int sx = g->menu_cursor == 3*y + x ? 19 : 0; - dsubimage(x1+8+24*x, 58+24*y, &img_hud_itemslots, sx, 0, 19, 19, - DIMAGE_NONE); + for(int y = 0; y < 2; y++) + for(int x = 0; x < 4; x++) { + int sx = g->menu_cursor == 4*y + x ? 21 : 0; + int x2 = x1 + 15 + 24*x; + int y2 = 48 + 24*y; + dsubimage(x2, y2, &img_hud_itemslots, sx, 0, 21, 21, DIMAGE_NONE); - int item = player_data->inventory[3*y + x]; + int item = player_data->inventory[4*y + x]; + int slot = item_equipment_slot(item); if(item > 0) { anim_t const *anim = item_anim(item); - anim_frame_render(x1+8+24*x + 9, 58+24*y + 9, anim->start[0]); + if(anim) { + if(slot >= 0 && player_data->equipment[slot] == 4*y + x) + anim_frame_render_outline(x2+10, y2+10, anim->start[0], + RGB24(0x979515)); + else + anim_frame_render(x2+10, y2+10, anim->start[0]); + } } } + if(selected_item >= 0) { + int w, h; + dsize(item_name(selected_item), NULL, &w, &h); + drect(x1+5, 99, x1+w+8, 98+h+4, RGB24(0x3d5050)); + dtext(x1+7, 100, C_WHITE, item_name(selected_item)); - for(int x = 0; x < 3; x++) { - dsubimage(x2+20+24*x, 73, &img_hud_itemslots, 38, 0, 19, 19, - DIMAGE_NONE); + char const *desc = item_description(selected_item); + if(desc) + dtext_multi(x1+7, 116, C_WHITE, desc); - int item = player_data->equipment[x]; - if(item > 0) { - anim_t const *anim = item_anim(item); - anim_frame_render(x2+20+24*x + 9, 73 + 9, anim->start[0]); + int dx = small_text(x1+7, 158, -1, "SHIFT", -1); + char const *use_str = "Use"; + if(item_is_equip(selected_item)) { + use_str = "Equip"; + int slot = item_equipment_slot(selected_item); + if(slot >= 0 && player_data->equipment[slot] == g->menu_cursor) + use_str = "Unequip"; } + dtext(x1+7+dx+4, 158, C_WHITE, use_str); } + /* What the growth is with the current equips */ + fighter_stats_t growth_base; + growth_base = player_compute_growth(g->player, player_data->equipment); + /* What the stats would be if the selected item is equipped */ - fighter_stat_model_t stats_equip; + fighter_stats_t growth_equip; int switched_equipment[3]; memcpy(switched_equipment, player_data->equipment, 3*sizeof(int)); - int selected_item = player_data->inventory[g->menu_cursor]; int selected_slot = item_equipment_slot(selected_item); if(selected_item >= 0 && selected_slot >= 0) - switched_equipment[selected_slot] = selected_item; - stats_equip = player_compute_stats(g->player, switched_equipment); - int max_HP_equip = ffloor(stats_equip.HP); + switched_equipment[selected_slot] = g->menu_cursor; + growth_equip = player_compute_growth(g->player, switched_equipment); - dprint(x2+14, 103, C_WHITE, "HP"); - print_stat_opt(x2+54, 103, max_HP_equip, player_f->HP_max, - "%d/%d", player_f->HP, max_HP_equip); - dprint(x2+14, 118, C_WHITE, "ATK"); - print_stat(x2+54, 118, ffloor(stats_equip.ATK), player_f->ATK); - dprint(x2+14, 133, C_WHITE, "MAG"); - print_stat(x2+54, 133, ffloor(stats_equip.MAG), player_f->MAG); - dprint(x2+14, 148, C_WHITE, "DEF"); - print_stat(x2+54, 148, ffloor(stats_equip.DEF), player_f->DEF); + small_text(x2+14, 100, C_WHITE, "HP", -1); + print_stat_opt(x2+44, 100, growth_equip.HP, growth_base.HP, + "%d/%d", player_f->HP, player_f->HP_max); + small_text(x2+14, 114, C_WHITE, "ATK", -1); + print_stat(x2+44, 114, player_f->ATK, growth_equip.ATK, + growth_base.ATK); + small_text(x2+14, 128, C_WHITE, "MAG", -1); + print_stat(x2+44, 128, player_f->MAG, growth_equip.MAG, + growth_base.MAG); + small_text(x2+14, 142, C_WHITE, "DEF", -1); + print_stat(x2+44, 142, player_f->DEF, growth_equip.DEF, + growth_base.DEF); dfont(old_font); /* What the skills would be if the selected item is equipped */ diff --git a/src/render.h b/src/render.h index d9dcb29..ee54967 100644 --- a/src/render.h +++ b/src/render.h @@ -56,9 +56,6 @@ fixed_t camera_ppu(camera_t const *c); // Rendering //--- -/* Render panel overlay. */ -void render_panel(int x, int y, bool hflip); - /* Render a single layer of the map, with animated tiles. ss_x and ss_y are additional displacement for screenshake; default 0. layer is HORIZONTAL (floor), VERTICAL (wall), or CEILING.