preview and apply stat changes for equipment
This commit is contained in:
parent
99f7c06b05
commit
e0c46db0d7
|
@ -4,8 +4,28 @@
|
|||
#include "enemies.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <gint/defs/util.h>
|
||||
|
||||
fighter_stat_model_t fighter_stat_model_add(int amount, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, amount);
|
||||
|
||||
fighter_stat_model_t model = { 0 };
|
||||
|
||||
for(int i = 0; i < amount; i++) {
|
||||
fighter_stat_model_t op = va_arg(args, fighter_stat_model_t);
|
||||
model.HP += op.HP;
|
||||
model.ATK += op.ATK;
|
||||
model.DEF += op.DEF;
|
||||
model.MAG += op.MAG;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
return model;
|
||||
}
|
||||
|
||||
static int instantiate_stat(fixed_t affinity, fixed_t multiplier, int level)
|
||||
{
|
||||
float a = f2double(affinity);
|
||||
|
@ -14,13 +34,23 @@ static int instantiate_stat(fixed_t affinity, fixed_t multiplier, int level)
|
|||
return fround(multiplier * (int)y);
|
||||
}
|
||||
|
||||
void fighter_set_stats(fighter_t *f, fighter_stat_model_t const *model,
|
||||
int level, fixed_t factor)
|
||||
fighter_stat_model_t fighter_stat_model_instantiate(
|
||||
fighter_stat_model_t const *model, int level, fixed_t multiplier)
|
||||
{
|
||||
f->HP_max = instantiate_stat(model->HP, fmul(fix(2.0), factor), level);
|
||||
f->ATK = instantiate_stat(model->ATK, fix(1.6), level);
|
||||
f->MAG = instantiate_stat(model->MAG, fix(1.6), level);
|
||||
f->DEF = instantiate_stat(model->DEF, fix(0.7), level);
|
||||
fighter_stat_model_t m;
|
||||
m.HP = fix(instantiate_stat(model->HP, 2 * multiplier, level));
|
||||
m.ATK = fix(instantiate_stat(model->ATK, fix(1.6), level));
|
||||
m.DEF = fix(instantiate_stat(model->DEF, fix(0.9), level));
|
||||
m.MAG = fix(instantiate_stat(model->MAG, fix(1.2), level));
|
||||
return m;
|
||||
}
|
||||
|
||||
void fighter_set_stats(fighter_t *f, fighter_stat_model_t const *instance)
|
||||
{
|
||||
f->HP_max = ffloor(instance->HP);
|
||||
f->ATK = ffloor(instance->ATK);
|
||||
f->MAG = ffloor(instance->MAG);
|
||||
f->DEF = ffloor(instance->DEF);
|
||||
}
|
||||
|
||||
int fighter_damage(entity_t *e, int base_damage)
|
||||
|
|
|
@ -54,9 +54,15 @@ typedef struct
|
|||
|
||||
} fighter_t;
|
||||
|
||||
/* Initialize fighter's stats by using the provided stat model */
|
||||
void fighter_set_stats(fighter_t *f, fighter_stat_model_t const *model,
|
||||
int level, fixed_t multiplier);
|
||||
/* Adds two or more stat models */
|
||||
fighter_stat_model_t fighter_stat_model_add(int amount, ...);
|
||||
|
||||
/* Instantiate a statistics model */
|
||||
fighter_stat_model_t fighter_stat_model_instantiate(
|
||||
fighter_stat_model_t const *model, int level, fixed_t multiplier);
|
||||
|
||||
/* Initialize fighter's stats by using the instantiated stat model */
|
||||
void fighter_set_stats(fighter_t *f, fighter_stat_model_t const *instance);
|
||||
|
||||
/* Damage entity for that amount of raw strength. Returns actual damage after
|
||||
DES is subtracted, and randomization. */
|
||||
|
|
|
@ -157,7 +157,9 @@ entity_t *enemy_make(int enemy_id)
|
|||
fighter_t *f = getcomp(e, fighter);
|
||||
memset(f, 0, sizeof *f);
|
||||
|
||||
fighter_set_stats(f, &data->stats, data->level, fix(1.0));
|
||||
fighter_stat_model_t inst = fighter_stat_model_instantiate(&data->stats,
|
||||
data->level, fix(1.0));
|
||||
fighter_set_stats(f, &inst);
|
||||
f->HP = f->HP_max;
|
||||
f->combo_length = 1;
|
||||
f->enemy = malloc(sizeof *f->enemy + data->ai_data_size);
|
||||
|
|
25
src/item.c
25
src/item.c
|
@ -105,3 +105,28 @@ int item_equipment_slot(int item)
|
|||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fighter_stat_model_t item_stat_model(int item)
|
||||
{
|
||||
switch(item) {
|
||||
case ITEM_SWORD1: return (fighter_stat_model_t){
|
||||
.ATK = fix(0.4),
|
||||
.MAG = fix(0.2),
|
||||
};
|
||||
case ITEM_SWORD2: return (fighter_stat_model_t){
|
||||
.ATK = fix(0.8),
|
||||
.MAG = fix(0.3),
|
||||
};
|
||||
case ITEM_SCEPTER1: return (fighter_stat_model_t){
|
||||
.ATK = fix(0.15),
|
||||
.DEF = fix(0.1),
|
||||
.MAG = fix(0.3),
|
||||
};
|
||||
case ITEM_SCEPTER2: return (fighter_stat_model_t){
|
||||
.ATK = fix(0.3),
|
||||
.DEF = fix(0.15),
|
||||
.MAG = fix(0.6),
|
||||
};
|
||||
default: return (fighter_stat_model_t){ 0 };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "comp/entity.h"
|
||||
#include "comp/fighter.h"
|
||||
#include "geometry.h"
|
||||
#include "anim.h"
|
||||
|
||||
|
@ -36,3 +37,6 @@ 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);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <gint/kmalloc.h>
|
||||
#include <gint/drivers/r61524.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/rtc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -42,7 +43,7 @@ int main(void)
|
|||
/* Enable %D for decimal fixed-point in printf()-like functions */
|
||||
__printf_enable_fixed();
|
||||
/* Initialize the PRNG */
|
||||
srand(0xc0ffee + 1);
|
||||
srand(rtc_ticks());
|
||||
/* Initialize the benchmarking/profiling library */
|
||||
prof_init();
|
||||
/* Open the USB connection (for screenshots with fxlink) */
|
||||
|
@ -383,6 +384,11 @@ int main(void)
|
|||
int e = player_data.equipment[slot];
|
||||
player_data.equipment[slot] = item;
|
||||
player_data.inventory[game.menu_cursor] = e;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
src/player.c
23
src/player.c
|
@ -1,4 +1,5 @@
|
|||
#include "player.h"
|
||||
#include "item.h"
|
||||
#include <gint/defs/util.h>
|
||||
|
||||
static int xp_to_next_level(int level)
|
||||
|
@ -24,14 +25,32 @@ bool player_add_xp(entity_t *e, int points)
|
|||
if(leveled_up) {
|
||||
fighter_t *f = getcomp(p->entity, fighter);
|
||||
int previous_HP_max = f->HP_max;
|
||||
fighter_set_stats(getcomp(p->entity, fighter), &p->stat_model,
|
||||
p->xp_level, fix(2.0));
|
||||
|
||||
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[4] = {
|
||||
p->stat_model,
|
||||
item_stat_model(equips[0]),
|
||||
item_stat_model(equips[1]),
|
||||
item_stat_model(equips[2]),
|
||||
};
|
||||
|
||||
fighter_stat_model_t model = fighter_stat_model_add(4,
|
||||
m[0], m[1], m[2], m[3]);
|
||||
|
||||
return fighter_stat_model_instantiate(&model, p->xp_level, fix(2.0));
|
||||
}
|
||||
|
||||
bool player_give_item(entity_t *e, int item)
|
||||
{
|
||||
player_data_t *p = getcomp(e, fighter)->player;
|
||||
|
|
|
@ -30,5 +30,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);
|
||||
|
||||
/* Put an item into the player's inventory. false if inventory is full */
|
||||
bool player_give_item(entity_t *p, int item);
|
||||
|
|
41
src/render.c
41
src/render.c
|
@ -14,6 +14,7 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libprof.h>
|
||||
|
||||
//---
|
||||
|
@ -412,6 +413,26 @@ void render_panel(int x, int y, bool hflip)
|
|||
uint32_t time_render_map = 0;
|
||||
uint32_t time_render_hud = 0;
|
||||
|
||||
static void print_stat_opt(int x, int y, int stat, int reference,
|
||||
char const *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
char str[32];
|
||||
vsnprintf(str, 32, format, args);
|
||||
va_end(args);
|
||||
|
||||
int color = C_WHITE;
|
||||
if(stat < reference) color = RGB24(0xc05458);
|
||||
if(stat > reference) color = RGB24(0x21c24f);
|
||||
dtext(x, y, color, str);
|
||||
}
|
||||
|
||||
static void print_stat(int x, int y, int stat, int reference)
|
||||
{
|
||||
print_stat_opt(x, y, stat, reference, "%d", stat);
|
||||
}
|
||||
|
||||
void render_game(game_t const *g, bool show_hitboxes)
|
||||
{
|
||||
camera_t const *camera = &g->camera;
|
||||
|
@ -577,14 +598,26 @@ void render_game(game_t const *g, bool show_hitboxes)
|
|||
}
|
||||
}
|
||||
|
||||
/* What the stats would be if the selected item is equipped */
|
||||
fighter_stat_model_t stats_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);
|
||||
|
||||
dprint(x2+14, 103, C_WHITE, "HP");
|
||||
dprint(x2+54, 103, C_WHITE, "%d/%d", player_f->HP, player_f->HP_max);
|
||||
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");
|
||||
dprint(x2+54, 118, C_WHITE, "%d", player_f->ATK);
|
||||
print_stat(x2+54, 118, ffloor(stats_equip.ATK), player_f->ATK);
|
||||
dprint(x2+14, 133, C_WHITE, "MAG");
|
||||
dprint(x2+54, 133, C_WHITE, "%d", player_f->MAG);
|
||||
print_stat(x2+54, 133, ffloor(stats_equip.MAG), player_f->MAG);
|
||||
dprint(x2+14, 148, C_WHITE, "DEF");
|
||||
dprint(x2+54, 148, C_WHITE, "%d", player_f->DEF);
|
||||
print_stat(x2+54, 148, ffloor(stats_equip.DEF), player_f->DEF);
|
||||
dfont(old_font);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue