Improved stats processing. Added pages to stats screen.

This commit is contained in:
Steve 2015-10-25 00:01:46 +01:00
parent 5081b011cf
commit c322cced55
19 changed files with 164 additions and 128 deletions

View File

@ -73,12 +73,6 @@ void initBattle(void)
getWidget("quit", "battleLost")->action = quitBattle; getWidget("quit", "battleLost")->action = quitBattle;
selectWidget("ok", "startBattle"); selectWidget("ok", "startBattle");
/* only increment the missions started if there are objectives (Free Flight) */
if (battle.objectiveHead.next)
{
game.stats.missionsStarted++;
}
} }
static void logic(void) static void logic(void)
@ -297,15 +291,12 @@ static void quitBattle(void)
static void postBattle(void) static void postBattle(void)
{ {
game.stats.shotsFired += battle.stats.shotsFired; int i;
game.stats.shotsHit += battle.stats.shotsHit;
game.stats.missilesFired += battle.stats.missilesFired; for (i = 0 ; i < STAT_MAX ; i++)
game.stats.missilesHit += battle.stats.missilesHit; {
game.stats.enemiesKilled += battle.stats.enemiesKilled; game.stats[i] += battle.stats[i];
game.stats.alliesKilled += battle.stats.alliesKilled; }
game.stats.playerKilled += battle.stats.playerKilled;
game.stats.playerKills += battle.stats.playerKills;
game.stats.time += battle.stats.time;
if (game.currentMission && !game.currentMission->completed) if (game.currentMission && !game.currentMission->completed)
{ {

View File

@ -111,7 +111,7 @@ static void checkCollisions(Bullet *b)
} }
else if (b->owner == player) else if (b->owner == player)
{ {
battle.stats.shotsHit++; battle.stats[STAT_SHOTS_HIT]++;
} }
damageFighter(f, b->damage, b->flags); damageFighter(f, b->damage, b->flags);
@ -126,7 +126,12 @@ static void checkCollisions(Bullet *b)
/* assuming that health <= 0 will always mean killed */ /* assuming that health <= 0 will always mean killed */
if (f->health <= 0 && b->owner == player) if (f->health <= 0 && b->owner == player)
{ {
battle.stats.playerKills++; battle.stats[STAT_ENEMIES_KILLED_PLAYER]++;
}
if (b->owner == player && b->type == BT_MISSILE)
{
battle.stats[STAT_MISSILES_HIT]++;
} }
return; return;
@ -257,7 +262,7 @@ void fireGuns(Fighter *owner)
if (owner == player) if (owner == player)
{ {
battle.stats.shotsFired++; battle.stats[STAT_SHOTS_FIRED]++;
} }
} }
} }
@ -277,6 +282,11 @@ void fireMissile(Fighter *owner)
owner->missiles.ammo--; owner->missiles.ammo--;
if (owner == player)
{
battle.stats[STAT_MISSILES_FIRED]++;
}
playBattleSound(b->sound, owner->x, owner->y); playBattleSound(b->sound, owner->x, owner->y);
} }

View File

@ -89,14 +89,14 @@ static void updateTimeChallenge(Challenge *c)
switch (c->type) switch (c->type)
{ {
case CHALLENGE_TIME: case CHALLENGE_TIME:
if (battle.stats.time / FPS <= c->targetValue) if (battle.stats[STAT_TIME] / FPS <= c->targetValue)
{ {
c->passed = 1; c->passed = 1;
} }
break; break;
case CHALLENGE_TIME_MINS: case CHALLENGE_TIME_MINS:
if ((battle.stats.time / FPS) / 60 <= c->targetValue) if ((battle.stats[STAT_TIME] / FPS) / 60 <= c->targetValue)
{ {
c->passed = 1; c->passed = 1;
} }
@ -108,8 +108,8 @@ static void updateAccuracyChallenge(Challenge *c)
{ {
float percent; float percent;
percent = battle.stats.shotsHit; percent = battle.stats[STAT_SHOTS_HIT];
percent /= battle.stats.shotsFired; percent /= battle.stats[STAT_SHOTS_FIRED];
percent *= 100; percent *= 100;
if (percent >= c->targetValue) if (percent >= c->targetValue)
@ -136,7 +136,7 @@ static void updateLossesChallenge(Challenge *c)
{ {
if (!c->passed) if (!c->passed)
{ {
c->passed = battle.stats.alliesKilled <= c->targetValue; c->passed = battle.stats[STAT_ALLIES_KILLED] <= c->targetValue;
} }
} }
@ -144,7 +144,7 @@ static void updatePlayerKillsChallenge(Challenge *c)
{ {
if (!c->passed) if (!c->passed)
{ {
c->passed = battle.stats.playerKills >= c->targetValue; c->passed = battle.stats[STAT_ENEMIES_KILLED_PLAYER] >= c->targetValue;
} }
} }
@ -152,7 +152,7 @@ static void updateDisabledChallenge(Challenge *c)
{ {
if (!c->passed) if (!c->passed)
{ {
c->passed = battle.stats.disabled >= c->targetValue; c->passed = battle.stats[STAT_DISABLED] >= c->targetValue;
} }
} }

View File

@ -260,7 +260,7 @@ void doFighters(void)
if (f->alive == ALIVE_ALIVE) if (f->alive == ALIVE_ALIVE)
{ {
updateObjective(f->name, TT_DISABLE); updateObjective(f->name, TT_DISABLE);
battle.stats.disabled++; battle.stats[STAT_DISABLED]++;
} }
} }
} }
@ -269,7 +269,7 @@ void doFighters(void)
{ {
if (f == player) if (f == player)
{ {
battle.stats.playerKilled++; battle.stats[STAT_PLAYER_KILLED]++;
} }
else if (player != NULL) else if (player != NULL)
{ {
@ -277,11 +277,11 @@ void doFighters(void)
{ {
if (f->side != player->side) if (f->side != player->side)
{ {
battle.stats.enemiesKilled++; battle.stats[STAT_ENEMIES_KILLED]++;
} }
else else
{ {
battle.stats.alliesKilled++; battle.stats[STAT_ALLIES_KILLED]++;
addHudMessage(colors.red, "Ally has been killed"); addHudMessage(colors.red, "Ally has been killed");
} }

View File

@ -63,7 +63,7 @@ void doObjectives(void)
battle.status = MS_COMPLETE; battle.status = MS_COMPLETE;
battle.missionFinishedTimer = FPS; battle.missionFinishedTimer = FPS;
game.stats.missionsCompleted++; game.stats[STAT_MISSIONS_COMPLETED]++;
completeConditions(); completeConditions();

View File

@ -170,3 +170,20 @@ enum
CHALLENGE_DISABLE, CHALLENGE_DISABLE,
CHALLENGE_TIME_MINS CHALLENGE_TIME_MINS
}; };
enum
{
STAT_MISSIONS_STARTED,
STAT_MISSIONS_COMPLETED,
STAT_SHOTS_FIRED,
STAT_SHOTS_HIT,
STAT_MISSILES_FIRED,
STAT_MISSILES_HIT,
STAT_ENEMIES_KILLED,
STAT_ENEMIES_KILLED_PLAYER,
STAT_ALLIES_KILLED,
STAT_PLAYER_KILLED,
STAT_DISABLED,
STAT_TIME,
STAT_MAX
};

View File

@ -558,7 +558,12 @@ static void handleKeyboard(void)
handleGalaxyKB(); handleGalaxyKB();
} }
} }
else if (app.keyboard[SDL_SCANCODE_ESCAPE]) else if (show == SHOW_STATS)
{
handleStatsKB();
}
if (app.keyboard[SDL_SCANCODE_ESCAPE])
{ {
switch (show) switch (show)
{ {
@ -743,6 +748,8 @@ static void stats(void)
selectWidget("ok", "stats"); selectWidget("ok", "stats");
show = SHOW_STATS; show = SHOW_STATS;
initStatsDisplay();
} }
static void statsOK(void) static void statsOK(void)

View File

@ -62,6 +62,8 @@ extern void initOptions(void (*returnFromOptions)(void));
extern void drawStats(void); extern void drawStats(void);
extern void playSound(int id); extern void playSound(int id);
extern void blitRotated(SDL_Texture *texture, int x, int y, int angle); extern void blitRotated(SDL_Texture *texture, int x, int y, int angle);
extern void initStatsDisplay(void);
extern void handleStatsKB(void);
extern App app; extern App app;
extern Colors colors; extern Colors colors;

View File

@ -63,7 +63,12 @@ void loadMission(char *filename)
endSectionTransition(); endSectionTransition();
if (!battle.objectiveHead.next) /* only increment num missions started if there are objectives (Free Flight excluded, for example) */
if (battle.objectiveHead.next)
{
game.stats[STAT_MISSIONS_STARTED]++;
}
else
{ {
battle.status = MS_IN_PROGRESS; battle.status = MS_IN_PROGRESS;
} }

View File

@ -38,3 +38,4 @@ extern long flagsToLong(char *flags);
extern Battle battle; extern Battle battle;
extern Fighter *player; extern Fighter *player;
extern Game game;

View File

@ -20,9 +20,51 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stats.h" #include "stats.h"
static char *statDescription[] = {
"Missions Started",
"Missons Completed",
"Shots Fired",
"Shots Hit",
"Missiles Fired",
"Missiles Hit",
"Enemies Killed",
"Enemies Killed (Player)",
"Allies Killed",
"Times Killed",
"Enemies Disabled",
"STAT_TIME"
};
static int page;
static int maxPages;
static SDL_Texture *pagePrev;
static SDL_Texture *pageNext;
void initStatsDisplay(void)
{
page = 0;
maxPages = (STAT_MAX / MAX_STAT_ITEMS);
pagePrev = getTexture("gfx/widgets/optionsLeft.png");
pageNext = getTexture("gfx/widgets/optionsRight.png");
}
void handleStatsKB(void)
{
if (app.keyboard[SDL_SCANCODE_LEFT])
{
page = MIN(MAX(page - 1, 0), maxPages);
}
if (app.keyboard[SDL_SCANCODE_RIGHT])
{
page = MIN(MAX(page + 1, 0), maxPages);
}
}
void drawStats(void) void drawStats(void)
{ {
int y, hours, minutes, seconds; int i, y, hours, minutes, seconds, startIndex;
SDL_Rect r; SDL_Rect r;
char timePlayed[MAX_NAME_LENGTH]; char timePlayed[MAX_NAME_LENGTH];
@ -43,60 +85,41 @@ void drawStats(void)
drawText(SCREEN_WIDTH / 2, 70, 28, TA_CENTER, colors.white, "Stats"); drawText(SCREEN_WIDTH / 2, 70, 28, TA_CENTER, colors.white, "Stats");
SDL_SetRenderDrawColor(app.renderer, 128, 128, 128, 255); drawText(SCREEN_WIDTH / 2, 110, 16, TA_CENTER, colors.lightGrey, "Page %d / %d", page + 1, maxPages + 1);
SDL_RenderDrawLine(app.renderer, r.x, 120, r.x + r.w, 120);
y = 140; if (page > 0)
{
blit(pagePrev, (SCREEN_WIDTH / 2) - 100, 120, 1);
}
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Missions Started"); if (page < maxPages)
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.missionsStarted); {
blit(pageNext, (SCREEN_WIDTH / 2) + 100, 120, 1);
}
y = 170;
startIndex = (page * MAX_STAT_ITEMS);
for (i = startIndex ; i < startIndex + MAX_STAT_ITEMS ; i++)
{
if (i < STAT_TIME)
{
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, statDescription[i]);
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats[i]);
y += 40; y += 40;
}
}
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Missions Completed"); seconds = game.stats[STAT_TIME] / FPS;
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.missionsCompleted);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Shots Fired");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.shotsFired);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Shots Hit");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.shotsHit);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Missiles Fired");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.missilesFired);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Missiles Hit");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.missilesHit);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Enemies Killed (Player)");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.playerKills);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Enemies Killed (All)");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.enemiesKilled);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Allies Lost");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.alliesKilled);
y += 40;
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Times Killed");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.playerKilled);
y += 60;
seconds = game.stats.time / FPS;
minutes = (seconds / 60) % 60; minutes = (seconds / 60) % 60;
hours = seconds / (60 * 60); hours = seconds / (60 * 60);
seconds %= 60; seconds %= 60;
sprintf(timePlayed, "%dh:%02dm:%02ds", hours, minutes, seconds); sprintf(timePlayed, "%dh:%02dm:%02ds", hours, minutes, seconds);
drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Time Played"); drawText(r.x + 20, 565, 18, TA_LEFT, colors.white, "Time Played");
drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, timePlayed); drawText(r.x + r.w - 20, 565, 18, TA_RIGHT, colors.white, timePlayed);
drawWidgets("stats"); drawWidgets("stats");
} }

View File

@ -23,10 +23,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../defs.h" #include "../defs.h"
#include "../structs.h" #include "../structs.h"
#define MAX_STAT_ITEMS 9
extern void selectWidget(const char *name, const char *group); extern void selectWidget(const char *name, const char *group);
extern Widget *getWidget(const char *name, const char *group); extern Widget *getWidget(const char *name, const char *group);
extern void drawWidgets(char *groupName); extern void drawWidgets(char *groupName);
extern void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...); extern void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...);
extern void blit(SDL_Texture *texture, int x, int y, int centered);
extern SDL_Texture *getTexture(char *filename);
extern App app; extern App app;
extern Colors colors; extern Colors colors;

View File

@ -33,7 +33,7 @@ void resetGame(void)
Mission *mission; Mission *mission;
Challenge *challenge; Challenge *challenge;
memset(&game.stats, 0, sizeof(Stats)); memset(&game.stats, 0, sizeof(int) * STAT_MAX);
for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next) for (starSystem = game.starSystemHead.next ; starSystem != NULL ; starSystem = starSystem->next)
{ {

View File

@ -87,7 +87,7 @@ int main(int argc, char *argv[])
app.delegate.logic(); app.delegate.logic();
td -= LOGIC_RATE; td -= LOGIC_RATE;
game.stats.time++; game.stats[STAT_TIME]++;
} }
app.delegate.draw(); app.delegate.draw();

View File

@ -201,21 +201,6 @@ struct StarSystem {
StarSystem *next; StarSystem *next;
}; };
typedef struct {
unsigned int missionsStarted;
unsigned int missionsCompleted;
unsigned int shotsFired;
unsigned int shotsHit;
unsigned int missilesFired;
unsigned int missilesHit;
unsigned int enemiesKilled;
unsigned int alliesKilled;
unsigned int playerKilled;
unsigned int playerKills;
unsigned int disabled;
unsigned int time;
} Stats;
typedef struct { typedef struct {
float ssx; float ssx;
float ssy; float ssy;
@ -231,13 +216,13 @@ typedef struct {
Bullet bulletHead, *bulletTail; Bullet bulletHead, *bulletTail;
Effect effectHead, *effectTail; Effect effectHead, *effectTail;
Objective objectiveHead, *objectiveTail; Objective objectiveHead, *objectiveTail;
Stats stats; unsigned int stats[STAT_MAX];
} Battle; } Battle;
typedef struct { typedef struct {
StarSystem starSystemHead, *starSystemTail; StarSystem starSystemHead, *starSystemTail;
Mission *currentMission; Mission *currentMission;
Stats stats; unsigned int stats[STAT_MAX];
} Game; } Game;
struct Widget { struct Widget {

View File

@ -24,7 +24,6 @@ static void loadStats(cJSON *stats);
static void loadStarSystems(cJSON *starSystemsJSON); static void loadStarSystems(cJSON *starSystemsJSON);
static void loadMissions(StarSystem *starSystem, cJSON *missionsCJSON); static void loadMissions(StarSystem *starSystem, cJSON *missionsCJSON);
static void loadChallenges(Mission *mission, cJSON *challengesCJSON); static void loadChallenges(Mission *mission, cJSON *challengesCJSON);
static int getStat(cJSON *stats, char *name);
void loadGame(void) void loadGame(void)
{ {
@ -96,26 +95,10 @@ static void loadChallenges(Mission *mission, cJSON *challengesCJSON)
static void loadStats(cJSON *stats) static void loadStats(cJSON *stats)
{ {
game.stats.missionsStarted = getStat(stats, "missionsStarted"); int i;
game.stats.missionsCompleted = getStat(stats, "missionsCompleted");
game.stats.shotsFired = getStat(stats, "shotsFired");
game.stats.shotsHit = getStat(stats, "shotsHit");
game.stats.missilesFired = getStat(stats, "missilesFired");
game.stats.missilesHit = getStat(stats, "missilesHit");
game.stats.enemiesKilled = getStat(stats, "enemiesKilled");
game.stats.alliesKilled = getStat(stats, "alliesKilled");
game.stats.playerKilled = getStat(stats, "playerKilled");
game.stats.playerKills = getStat(stats, "playerKills");
game.stats.disabled = getStat(stats, "disabled");
game.stats.time = getStat(stats, "time");
}
static int getStat(cJSON *stats, char *name) for (i = 0 ; i < STAT_MAX ; i++)
{
if (cJSON_GetObjectItem(stats, name))
{ {
return cJSON_GetObjectItem(stats, name)->valueint; game.stats[i] = cJSON_GetObjectItem(stats, getLookupName("STAT_", i))->valueint;
} }
return 0;
} }

View File

@ -30,5 +30,6 @@ extern Mission *getMission(StarSystem *starSystem, char *filename);
extern Challenge *getChallenge(Mission *mission, int type); extern Challenge *getChallenge(Mission *mission, int type);
extern int lookup(char *lookup); extern int lookup(char *lookup);
extern char *getSaveFilePath(char *filename); extern char *getSaveFilePath(char *filename);
extern char *getLookupName(char *prefix, long num);
extern Game game; extern Game game;

View File

@ -78,6 +78,19 @@ void initLookups(void)
addLookup("CHALLENGE_PLAYER_KILLS", CHALLENGE_PLAYER_KILLS); addLookup("CHALLENGE_PLAYER_KILLS", CHALLENGE_PLAYER_KILLS);
addLookup("CHALLENGE_DISABLE", CHALLENGE_DISABLE); addLookup("CHALLENGE_DISABLE", CHALLENGE_DISABLE);
addLookup("CHALLENGE_TIME_MINS", CHALLENGE_TIME_MINS); addLookup("CHALLENGE_TIME_MINS", CHALLENGE_TIME_MINS);
addLookup("STAT_MISSIONS_STARTED", STAT_MISSIONS_STARTED);
addLookup("STAT_MISSIONS_COMPLETED", STAT_MISSIONS_COMPLETED);
addLookup("STAT_SHOTS_FIRED", STAT_SHOTS_FIRED);
addLookup("STAT_SHOTS_HIT", STAT_SHOTS_HIT);
addLookup("STAT_MISSILES_FIRED", STAT_MISSILES_FIRED);
addLookup("STAT_MISSILES_HIT", STAT_MISSILES_HIT);
addLookup("STAT_ENEMIES_KILLED", STAT_ENEMIES_KILLED);
addLookup("STAT_ENEMIES_KILLED_PLAYER", STAT_ENEMIES_KILLED_PLAYER);
addLookup("STAT_ALLIES_KILLED", STAT_ALLIES_KILLED);
addLookup("STAT_PLAYER_KILLED", STAT_PLAYER_KILLED);
addLookup("STAT_DISABLED", STAT_DISABLED);
addLookup("STAT_TIME", STAT_TIME);
} }
static void addLookup(char *name, long value) static void addLookup(char *name, long value)

View File

@ -116,20 +116,14 @@ static cJSON *getChallengesJSON(Mission *mission)
static void saveStats(cJSON *gameJSON) static void saveStats(cJSON *gameJSON)
{ {
int i;
cJSON *stats = cJSON_CreateObject(); cJSON *stats = cJSON_CreateObject();
cJSON_AddNumberToObject(stats, "missionsStarted", game.stats.missionsStarted); for (i = 0 ; i < STAT_MAX ; i++)
cJSON_AddNumberToObject(stats, "missionsCompleted", game.stats.missionsCompleted); {
cJSON_AddNumberToObject(stats, "shotsFired", game.stats.shotsFired); cJSON_AddNumberToObject(stats, getLookupName("STAT_", i), game.stats[i]);
cJSON_AddNumberToObject(stats, "shotsHit", game.stats.shotsHit); }
cJSON_AddNumberToObject(stats, "missilesFired", game.stats.missilesFired);
cJSON_AddNumberToObject(stats, "missilesHit", game.stats.missilesHit);
cJSON_AddNumberToObject(stats, "enemiesKilled", game.stats.enemiesKilled);
cJSON_AddNumberToObject(stats, "alliesKilled", game.stats.alliesKilled);
cJSON_AddNumberToObject(stats, "playerKilled", game.stats.playerKilled);
cJSON_AddNumberToObject(stats, "playerKills", game.stats.playerKills);
cJSON_AddNumberToObject(stats, "disabled", game.stats.disabled);
cJSON_AddNumberToObject(stats, "time", game.stats.time);
cJSON_AddItemToObject(gameJSON, "stats", stats); cJSON_AddItemToObject(gameJSON, "stats", stats);
} }