From c322cced55b8a21ad6533c5b724ffda1e240726c Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 25 Oct 2015 00:01:46 +0100 Subject: [PATCH] Improved stats processing. Added pages to stats screen. --- src/battle/battle.c | 21 +++----- src/battle/bullets.c | 16 ++++-- src/battle/challenges.c | 14 ++--- src/battle/fighters.c | 8 +-- src/battle/objectives.c | 2 +- src/defs.h | 17 ++++++ src/galaxy/galacticMap.c | 9 +++- src/galaxy/galacticMap.h | 2 + src/galaxy/mission.c | 7 ++- src/galaxy/mission.h | 1 + src/galaxy/stats.c | 109 ++++++++++++++++++++++++--------------- src/galaxy/stats.h | 4 ++ src/game/game.c | 2 +- src/main.c | 2 +- src/structs.h | 19 +------ src/system/load.c | 27 ++-------- src/system/load.h | 1 + src/system/lookup.c | 13 +++++ src/system/save.c | 18 +++---- 19 files changed, 164 insertions(+), 128 deletions(-) diff --git a/src/battle/battle.c b/src/battle/battle.c index bf623ef..02497f6 100644 --- a/src/battle/battle.c +++ b/src/battle/battle.c @@ -73,12 +73,6 @@ void initBattle(void) getWidget("quit", "battleLost")->action = quitBattle; 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) @@ -297,15 +291,12 @@ static void quitBattle(void) static void postBattle(void) { - game.stats.shotsFired += battle.stats.shotsFired; - game.stats.shotsHit += battle.stats.shotsHit; - game.stats.missilesFired += battle.stats.missilesFired; - game.stats.missilesHit += battle.stats.missilesHit; - game.stats.enemiesKilled += battle.stats.enemiesKilled; - game.stats.alliesKilled += battle.stats.alliesKilled; - game.stats.playerKilled += battle.stats.playerKilled; - game.stats.playerKills += battle.stats.playerKills; - game.stats.time += battle.stats.time; + int i; + + for (i = 0 ; i < STAT_MAX ; i++) + { + game.stats[i] += battle.stats[i]; + } if (game.currentMission && !game.currentMission->completed) { diff --git a/src/battle/bullets.c b/src/battle/bullets.c index 28debb3..3347525 100644 --- a/src/battle/bullets.c +++ b/src/battle/bullets.c @@ -111,7 +111,7 @@ static void checkCollisions(Bullet *b) } else if (b->owner == player) { - battle.stats.shotsHit++; + battle.stats[STAT_SHOTS_HIT]++; } damageFighter(f, b->damage, b->flags); @@ -126,7 +126,12 @@ static void checkCollisions(Bullet *b) /* assuming that health <= 0 will always mean killed */ 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; @@ -257,7 +262,7 @@ void fireGuns(Fighter *owner) if (owner == player) { - battle.stats.shotsFired++; + battle.stats[STAT_SHOTS_FIRED]++; } } } @@ -277,6 +282,11 @@ void fireMissile(Fighter *owner) owner->missiles.ammo--; + if (owner == player) + { + battle.stats[STAT_MISSILES_FIRED]++; + } + playBattleSound(b->sound, owner->x, owner->y); } diff --git a/src/battle/challenges.c b/src/battle/challenges.c index 18b1e05..cc7677b 100644 --- a/src/battle/challenges.c +++ b/src/battle/challenges.c @@ -89,14 +89,14 @@ static void updateTimeChallenge(Challenge *c) switch (c->type) { case CHALLENGE_TIME: - if (battle.stats.time / FPS <= c->targetValue) + if (battle.stats[STAT_TIME] / FPS <= c->targetValue) { c->passed = 1; } break; case CHALLENGE_TIME_MINS: - if ((battle.stats.time / FPS) / 60 <= c->targetValue) + if ((battle.stats[STAT_TIME] / FPS) / 60 <= c->targetValue) { c->passed = 1; } @@ -108,8 +108,8 @@ static void updateAccuracyChallenge(Challenge *c) { float percent; - percent = battle.stats.shotsHit; - percent /= battle.stats.shotsFired; + percent = battle.stats[STAT_SHOTS_HIT]; + percent /= battle.stats[STAT_SHOTS_FIRED]; percent *= 100; if (percent >= c->targetValue) @@ -136,7 +136,7 @@ static void updateLossesChallenge(Challenge *c) { 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) { - 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) { - c->passed = battle.stats.disabled >= c->targetValue; + c->passed = battle.stats[STAT_DISABLED] >= c->targetValue; } } diff --git a/src/battle/fighters.c b/src/battle/fighters.c index 1dafad6..9a683b9 100644 --- a/src/battle/fighters.c +++ b/src/battle/fighters.c @@ -260,7 +260,7 @@ void doFighters(void) if (f->alive == ALIVE_ALIVE) { updateObjective(f->name, TT_DISABLE); - battle.stats.disabled++; + battle.stats[STAT_DISABLED]++; } } } @@ -269,7 +269,7 @@ void doFighters(void) { if (f == player) { - battle.stats.playerKilled++; + battle.stats[STAT_PLAYER_KILLED]++; } else if (player != NULL) { @@ -277,11 +277,11 @@ void doFighters(void) { if (f->side != player->side) { - battle.stats.enemiesKilled++; + battle.stats[STAT_ENEMIES_KILLED]++; } else { - battle.stats.alliesKilled++; + battle.stats[STAT_ALLIES_KILLED]++; addHudMessage(colors.red, "Ally has been killed"); } diff --git a/src/battle/objectives.c b/src/battle/objectives.c index c143228..bc7ff82 100644 --- a/src/battle/objectives.c +++ b/src/battle/objectives.c @@ -63,7 +63,7 @@ void doObjectives(void) battle.status = MS_COMPLETE; battle.missionFinishedTimer = FPS; - game.stats.missionsCompleted++; + game.stats[STAT_MISSIONS_COMPLETED]++; completeConditions(); diff --git a/src/defs.h b/src/defs.h index 8f2cb40..31f15ac 100644 --- a/src/defs.h +++ b/src/defs.h @@ -170,3 +170,20 @@ enum CHALLENGE_DISABLE, 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 +}; diff --git a/src/galaxy/galacticMap.c b/src/galaxy/galacticMap.c index e1cf6d5..24bb2c2 100644 --- a/src/galaxy/galacticMap.c +++ b/src/galaxy/galacticMap.c @@ -558,7 +558,12 @@ static void handleKeyboard(void) handleGalaxyKB(); } } - else if (app.keyboard[SDL_SCANCODE_ESCAPE]) + else if (show == SHOW_STATS) + { + handleStatsKB(); + } + + if (app.keyboard[SDL_SCANCODE_ESCAPE]) { switch (show) { @@ -743,6 +748,8 @@ static void stats(void) selectWidget("ok", "stats"); show = SHOW_STATS; + + initStatsDisplay(); } static void statsOK(void) diff --git a/src/galaxy/galacticMap.h b/src/galaxy/galacticMap.h index 074377b..91ba33d 100644 --- a/src/galaxy/galacticMap.h +++ b/src/galaxy/galacticMap.h @@ -62,6 +62,8 @@ extern void initOptions(void (*returnFromOptions)(void)); extern void drawStats(void); extern void playSound(int id); extern void blitRotated(SDL_Texture *texture, int x, int y, int angle); +extern void initStatsDisplay(void); +extern void handleStatsKB(void); extern App app; extern Colors colors; diff --git a/src/galaxy/mission.c b/src/galaxy/mission.c index 2dd669e..3801ed0 100644 --- a/src/galaxy/mission.c +++ b/src/galaxy/mission.c @@ -63,7 +63,12 @@ void loadMission(char *filename) 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; } diff --git a/src/galaxy/mission.h b/src/galaxy/mission.h index ed7391d..b1e1282 100644 --- a/src/galaxy/mission.h +++ b/src/galaxy/mission.h @@ -38,3 +38,4 @@ extern long flagsToLong(char *flags); extern Battle battle; extern Fighter *player; +extern Game game; diff --git a/src/galaxy/stats.c b/src/galaxy/stats.c index ec4d1f9..2bc5592 100644 --- a/src/galaxy/stats.c +++ b/src/galaxy/stats.c @@ -20,9 +20,51 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #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) { - int y, hours, minutes, seconds; + int i, y, hours, minutes, seconds, startIndex; SDL_Rect r; char timePlayed[MAX_NAME_LENGTH]; @@ -43,60 +85,41 @@ void drawStats(void) drawText(SCREEN_WIDTH / 2, 70, 28, TA_CENTER, colors.white, "Stats"); - SDL_SetRenderDrawColor(app.renderer, 128, 128, 128, 255); - SDL_RenderDrawLine(app.renderer, r.x, 120, r.x + r.w, 120); + drawText(SCREEN_WIDTH / 2, 110, 16, TA_CENTER, colors.lightGrey, "Page %d / %d", page + 1, maxPages + 1); - 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"); - drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.missionsStarted); - y += 40; + if (page < maxPages) + { + blit(pageNext, (SCREEN_WIDTH / 2) + 100, 120, 1); + } - drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Missions Completed"); - drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats.missionsCompleted); - y += 40; + y = 170; - 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; + startIndex = (page * MAX_STAT_ITEMS); - 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; + 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; + } + } - 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; + seconds = game.stats[STAT_TIME] / FPS; minutes = (seconds / 60) % 60; hours = seconds / (60 * 60); seconds %= 60; sprintf(timePlayed, "%dh:%02dm:%02ds", hours, minutes, seconds); - drawText(r.x + 20, y, 18, TA_LEFT, colors.white, "Time Played"); - drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, timePlayed); + drawText(r.x + 20, 565, 18, TA_LEFT, colors.white, "Time Played"); + drawText(r.x + r.w - 20, 565, 18, TA_RIGHT, colors.white, timePlayed); drawWidgets("stats"); } diff --git a/src/galaxy/stats.h b/src/galaxy/stats.h index 2639869..627f123 100644 --- a/src/galaxy/stats.h +++ b/src/galaxy/stats.h @@ -23,10 +23,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../defs.h" #include "../structs.h" +#define MAX_STAT_ITEMS 9 + extern void selectWidget(const char *name, const char *group); extern Widget *getWidget(const char *name, const char *group); extern void drawWidgets(char *groupName); 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 Colors colors; diff --git a/src/game/game.c b/src/game/game.c index 622df15..638afb5 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -33,7 +33,7 @@ void resetGame(void) Mission *mission; 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) { diff --git a/src/main.c b/src/main.c index 2210aa7..df0a305 100644 --- a/src/main.c +++ b/src/main.c @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) app.delegate.logic(); td -= LOGIC_RATE; - game.stats.time++; + game.stats[STAT_TIME]++; } app.delegate.draw(); diff --git a/src/structs.h b/src/structs.h index 28ebfb3..23ba54c 100644 --- a/src/structs.h +++ b/src/structs.h @@ -201,21 +201,6 @@ struct StarSystem { 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 { float ssx; float ssy; @@ -231,13 +216,13 @@ typedef struct { Bullet bulletHead, *bulletTail; Effect effectHead, *effectTail; Objective objectiveHead, *objectiveTail; - Stats stats; + unsigned int stats[STAT_MAX]; } Battle; typedef struct { StarSystem starSystemHead, *starSystemTail; Mission *currentMission; - Stats stats; + unsigned int stats[STAT_MAX]; } Game; struct Widget { diff --git a/src/system/load.c b/src/system/load.c index 9d25d01..56714ba 100644 --- a/src/system/load.c +++ b/src/system/load.c @@ -24,7 +24,6 @@ static void loadStats(cJSON *stats); static void loadStarSystems(cJSON *starSystemsJSON); static void loadMissions(StarSystem *starSystem, cJSON *missionsCJSON); static void loadChallenges(Mission *mission, cJSON *challengesCJSON); -static int getStat(cJSON *stats, char *name); void loadGame(void) { @@ -96,26 +95,10 @@ static void loadChallenges(Mission *mission, cJSON *challengesCJSON) static void loadStats(cJSON *stats) { - game.stats.missionsStarted = getStat(stats, "missionsStarted"); - 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) -{ - if (cJSON_GetObjectItem(stats, name)) - { - return cJSON_GetObjectItem(stats, name)->valueint; - } + int i; - return 0; + for (i = 0 ; i < STAT_MAX ; i++) + { + game.stats[i] = cJSON_GetObjectItem(stats, getLookupName("STAT_", i))->valueint; + } } diff --git a/src/system/load.h b/src/system/load.h index 0fcca55..c7ad636 100644 --- a/src/system/load.h +++ b/src/system/load.h @@ -30,5 +30,6 @@ extern Mission *getMission(StarSystem *starSystem, char *filename); extern Challenge *getChallenge(Mission *mission, int type); extern int lookup(char *lookup); extern char *getSaveFilePath(char *filename); +extern char *getLookupName(char *prefix, long num); extern Game game; diff --git a/src/system/lookup.c b/src/system/lookup.c index 580da7f..aed5e5c 100644 --- a/src/system/lookup.c +++ b/src/system/lookup.c @@ -78,6 +78,19 @@ void initLookups(void) addLookup("CHALLENGE_PLAYER_KILLS", CHALLENGE_PLAYER_KILLS); addLookup("CHALLENGE_DISABLE", CHALLENGE_DISABLE); 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) diff --git a/src/system/save.c b/src/system/save.c index 4c521ac..d95ae5d 100644 --- a/src/system/save.c +++ b/src/system/save.c @@ -116,20 +116,14 @@ static cJSON *getChallengesJSON(Mission *mission) static void saveStats(cJSON *gameJSON) { + int i; + cJSON *stats = cJSON_CreateObject(); - cJSON_AddNumberToObject(stats, "missionsStarted", game.stats.missionsStarted); - cJSON_AddNumberToObject(stats, "missionsCompleted", game.stats.missionsCompleted); - cJSON_AddNumberToObject(stats, "shotsFired", game.stats.shotsFired); - 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); + for (i = 0 ; i < STAT_MAX ; i++) + { + cJSON_AddNumberToObject(stats, getLookupName("STAT_", i), game.stats[i]); + } cJSON_AddItemToObject(gameJSON, "stats", stats); }