refactor battle display

This commit is contained in:
quenousimporte 2025-04-05 17:41:44 +02:00
parent d7dd26e64c
commit be68819603
1 changed files with 89 additions and 32 deletions

121
w/w.c
View File

@ -5,7 +5,6 @@
#define CMD_LEN 10 #define CMD_LEN 10
#define NAME_LEN 10 #define NAME_LEN 10
#define SUMMARY_LEN 255
#define POV_3D_SIZE 10 #define POV_3D_SIZE 10
#define POV_SIZE 3 #define POV_SIZE 3
@ -36,6 +35,13 @@
#define TILE_DOOR 'd' #define TILE_DOOR 'd'
#define TILE_START 's' #define TILE_START 's'
typedef struct Round {
char action;
int herodmg;
int monsterdmg;
struct Round* next;
} Round;
typedef struct { typedef struct {
int x; int x;
int y; int y;
@ -55,7 +61,6 @@ typedef struct {
Character monster; Character monster;
Position position; Position position;
char screen; char screen;
char summary[SUMMARY_LEN];
} Gamestate; } Gamestate;
const char* statepath = "w.state"; const char* statepath = "w.state";
@ -63,6 +68,9 @@ char pov[POV_SIZE][POV_SIZE];
unsigned char pov3d[POV_3D_SIZE][POV_3D_SIZE]; unsigned char pov3d[POV_3D_SIZE][POV_3D_SIZE];
Gamestate state; Gamestate state;
struct Round* firstround = NULL;
struct Round* currentround = NULL;
int mapsize = 15; int mapsize = 15;
char map[15][15] = { char map[15][15] = {
"wwwwwwwwwwwwwww", "wwwwwwwwwwwwwww",
@ -412,11 +420,10 @@ void init()
else else
{ {
state.screen = SC_TITLE; state.screen = SC_TITLE;
strcpy(state.summary, "");
} }
} }
void attack(Character* attacker, Character* defender) int attack(Character* attacker, Character* defender)
{ {
char tmp[50]; char tmp[50];
@ -426,19 +433,11 @@ void attack(Character* attacker, Character* defender)
if (a > d) if (a > d)
{ {
int dmg = a - d; int dmg = a - d;
// todo: store fight sequence history instead, and write things in draw()?
// and disable 'q' during fight, to avoid having serializing this?
sprintf(tmp, "%s inflige %d à %s.\n", attacker->name, dmg, defender->name);
strcat(state.summary, tmp);
defender->hp -= dmg; defender->hp -= dmg;
return dmg;
} }
else
{ return 0;
sprintf(tmp, "%s parre le coup de %s.\n", defender->name, attacker->name);
strcat(state.summary, tmp);
}
} }
void createhero(char* name) void createhero(char* name)
@ -450,6 +449,38 @@ void createhero(char* name)
state.hero.def = 1; state.hero.def = 1;
} }
void createround(char action, int herodmg, int monsterdmg)
{
Round* newround = malloc(sizeof(Round));
newround->next = NULL;
newround->action = action;
newround->herodmg = herodmg;
newround->monsterdmg = monsterdmg;
if (firstround == NULL)
{
firstround = newround;
}
else
{
currentround->next = newround;
}
currentround = newround;
}
void freerounds()
{
Round* p = firstround;
while (p)
{
Round* n = p->next;
free(p);
p = n;
}
firstround = NULL;
currentround = NULL;
}
void update(char* command) void update(char* command)
{ {
char c = command[0]; char c = command[0];
@ -518,14 +549,12 @@ void update(char* command)
{ {
if (dice() > 3) if (dice() > 3)
{ {
strcpy(state.summary, "");
state.screen = SC_MAP; state.screen = SC_MAP;
createround(c, 0, 0);
freerounds();
} }
else else
{ {
char tmp[50];
sprintf(tmp, "%s ne parvient pas à fuir.\n", state.hero.name);
strcat(state.summary, tmp);
fleefails = 1; fleefails = 1;
} }
} }
@ -533,9 +562,11 @@ void update(char* command)
if (c == CMD_ATTACK || fleefails) if (c == CMD_ATTACK || fleefails)
{ {
// hero attacks // hero attacks
int monsterdmg = 0;
int herodmg = 0;
if (!fleefails) if (!fleefails)
{ {
attack(&state.hero, &state.monster); monsterdmg = attack(&state.hero, &state.monster);
} }
if (state.monster.hp <= 0) if (state.monster.hp <= 0)
@ -546,27 +577,59 @@ void update(char* command)
else else
{ {
// monster attacks // monster attacks
attack(&state.monster, &state.hero); herodmg = attack(&state.monster, &state.hero);
if (state.hero.hp <= 0) if (state.hero.hp <= 0)
{ {
state.hero.hp = 0; state.hero.hp = 0;
state.screen = SC_GAMEOVER; state.screen = SC_GAMEOVER;
} }
} }
createround(c, herodmg, monsterdmg);
} }
} }
else if (state.screen == SC_GAMEOVER) else if (state.screen == SC_GAMEOVER)
{ {
state.hero.hp = 10; state.hero.hp = 10;
state.screen = SC_STATION; state.screen = SC_STATION;
freerounds();
} }
else if (state.screen == SC_WON)
{
state.screen = SC_MAP;
freerounds();
}
} }
void debugoutput() void debugoutput()
{ {
//drawmap(); //drawmap();
} }
void drawrounds()
{
printf("Rencontre avec %s.\n\n", state.monster.name);
Round* p = firstround;
while (p)
{
if (p->action == CMD_ATTACK)
{
printf("%s perd %d points de vie\n", state.monster.name, p->monsterdmg);
printf("%s perd %d points de vie\n\n", state.hero.name, p->herodmg);
}
else if (p->action == CMD_FLEE)
{
printf("%s n'arrive pas à fuir et perd %d points de vie\n\n", state.hero.name, p->herodmg);
}
else
{
printf("??\n");
}
p = p->next;
}
}
void draw() void draw()
{ {
clearscreen(); clearscreen();
@ -642,27 +705,21 @@ void draw()
} }
else if (state.screen == SC_MONSTER) else if (state.screen == SC_MONSTER)
{ {
printf("Rencontre avec %s.\n\n", state.monster.name); drawrounds();
if (strlen(state.summary) > 0)
{
printf("%s\n", state.summary);
}
printf("a: Attaquer\n"); printf("a: Attaquer\n");
printf("f: Tenter de fuir\n"); printf("f: Tenter de fuir\n");
} }
else if (state.screen == SC_WON) else if (state.screen == SC_WON)
{ {
printf("Rencontre avec %s.\n\n", state.monster.name); drawrounds();
printf("%s\n", state.summary);
printf("%s est vaincu.\n", state.monster.name); printf("%s est vaincu.\n", state.monster.name);
printf("%s gagne %d crédits galactiques.\n", state.hero.name, state.monster.gold); printf("%s gagne %d crédits galactiques.\n", state.hero.name, state.monster.gold);
strcpy(state.summary, "");
state.screen = SC_MAP;
} }
else if (state.screen == SC_GAMEOVER) else if (state.screen == SC_GAMEOVER)
{ {
drawrounds();
printf("%s est fatigué.e.\nIel retourne à la station.\n", state.hero.name); printf("%s est fatigué.e.\nIel retourne à la station.\n", state.hero.name);
} }
@ -717,7 +774,7 @@ int main()
char command[CMD_LEN] = CMD_NULL; char command[CMD_LEN] = CMD_NULL;
while (command[0] != 'q') while (command[0] != 'q' || state.screen == SC_MONSTER)
{ {
update(command); update(command);
draw(); draw();