diff --git a/.vimrc b/.vimrc index bab9024..f769d1a 100644 --- a/.vimrc +++ b/.vimrc @@ -5,5 +5,5 @@ nnoremap :ter ++close env LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./ ./_build/debu packadd termdebug let g:termdebug_wide = 1 -let g:syntastic_c_include_dirs = [ '_build/debug', '/usr/include/SDL2', 'steamworks_c_wrapper/src' ] +let g:syntastic_c_include_dirs = [ '_build/debug', '/usr/include/SDL2', 'steamworks_c_wrapper/src', 'physfs-3.0/src' ] let g:syntastic_cpp_include_dirs = [ 'steamworks_c_wrapper/sdk/public/steam' ] diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bab448..bbe3895 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,6 +184,7 @@ add_executable(breakhack src/stats src/actiontext src/random + src/time src/linkedlist src/hashtable src/gui diff --git a/src/actiontext.c b/src/actiontext.c index d62b96d..ed55dd5 100644 --- a/src/actiontext.c +++ b/src/actiontext.c @@ -27,7 +27,7 @@ actiontext_create(Sprite *sprite) ActionText *t = ec_malloc(sizeof(ActionText)); t->pos = (Position) { 0, 0 }; t->sprite = sprite; - t->timer = timer_create(); + t->timer = _timer_create(); t->dead = false; t->velocity = (Vector2d) { 0, -100 }; t->color = C_WHITE; diff --git a/src/animation.c b/src/animation.c index cd63542..15a1f54 100644 --- a/src/animation.c +++ b/src/animation.c @@ -27,7 +27,7 @@ animation_create(unsigned int clipCount) { Animation *animation = ec_malloc(sizeof(Animation) + clipCount * sizeof(AnimationClip)); - animation->clipTimer = timer_create(); + animation->clipTimer = _timer_create(); animation->clipCount = clipCount; animation->currentClip = 0; animation->loop = true; diff --git a/src/camera.c b/src/camera.c index 8c76f55..877e80d 100644 --- a/src/camera.c +++ b/src/camera.c @@ -30,7 +30,7 @@ Camera *camera_create(SDL_Renderer *renderer) { gCamera = ec_malloc(sizeof(Camera)); gCamera->renderer = renderer; - gCamera->shakeTimer = timer_create(); + gCamera->shakeTimer = _timer_create(); gCamera->velocity = VECTOR2D_NODIR; gCamera->pos = (Position) { 0, 0 }; gCamera->basePos = (Position) { 0, 0 }; diff --git a/src/gui.c b/src/gui.c index b70ec5e..26842f9 100644 --- a/src/gui.c +++ b/src/gui.c @@ -195,7 +195,7 @@ gui_create(Camera *cam) gui->event_message = texture_create(); texture_load_font(gui->event_message, "GUI/SDS_8x8.ttf", EVENT_MESSAGE_FONT_SIZE, 2); - gui->event_message_timer = timer_create(); + gui->event_message_timer = _timer_create(); gui->labels[CURRENT_XP_LABEL] = create_label_sprite((Position) { 16, POS_Y_XPBAR + 18 }); gui->labels[LEVEL_LABEL] = create_label_sprite((Position) { 16, POS_Y_XPBAR + 18 + 14 }); diff --git a/src/main.c b/src/main.c index c85584b..16df0bb 100644 --- a/src/main.c +++ b/src/main.c @@ -54,6 +54,7 @@ #include "io_util.h" #include "tooltip.h" #include "gamecontroller.h" +#include "time.h" #ifdef STEAM_BUILD #include "steam/steamworks_api_wrapper.h" @@ -165,6 +166,7 @@ static Turn currentTurn = PLAYER; static class_t playerClass = WARRIOR; static bool quickGame = false; static bool arcadeGame = false; +static bool weeklyGame = false; static GameState gGameState; static SDL_Rect mainViewport; static SDL_Rect gameViewport; @@ -316,7 +318,7 @@ initGame(void) gPointer = pointer_create(gRenderer); #endif // DEBUG particle_engine_init(); - menuTimer = timer_create(); + menuTimer = _timer_create(); actiontextbuilder_init(gRenderer); #ifdef DEBUG @@ -410,6 +412,7 @@ static void startRegularGame(void *unused) { quickGame = false; + weeklyGame = false; goToCharacterMenu(unused); } @@ -417,9 +420,21 @@ static void startQuickGame(void *unused) { quickGame = true; + weeklyGame = false; goToCharacterMenu(unused); } +#ifdef STEAM_BUILD +static void +startWeeklyGame(void *unused) +{ + quickGame = true; + weeklyGame = true; + set_random_seed((unsigned int) time_get_weekly_seed()); + goToCharacterMenu(unused); +} +#endif + static void startArcadeGame(void *unused) { @@ -452,6 +467,13 @@ goToGameSelectMenu(void *unused) "Standard 20 level game, recommended for new players", startRegularGame }, +#ifdef STEAM_BUILD + { + "WEEKLY CHALLENGE", + "Quck game with weekly leaderboards at breakhack.net", + startWeeklyGame + }, +#endif { "QUICK GAME", "Shorter 12 level game, with more action earlier in the game", @@ -464,7 +486,12 @@ goToGameSelectMenu(void *unused) } }; - menu_create_text_menu(&gameSelectMenu, &menuItems[0], 3, gRenderer); +#ifdef STEAM_BUILD + int count = 4; +#else + int count = 3; +#endif + menu_create_text_menu(&gameSelectMenu, &menuItems[0], count, gRenderer); gGameState = GAME_SELECT; } @@ -540,6 +567,7 @@ initMainMenu(void) creditsScreen = screen_create_credits(gRenderer); scoreScreen = screen_create_hiscore(gRenderer); quickGame = false; + weeklyGame = false; arcadeGame = false; } @@ -614,12 +642,14 @@ static bool init(void) { #ifdef STEAM_BUILD +#ifndef DEBUG if (!steam_restart_needed()) { steam_init(); } else { error("%s needs to be started through Steam", GAME_TITLE); return false; } +#endif #endif // STEAM_BUILD if (!initSDL()) { @@ -1003,21 +1033,33 @@ run_game_render(void) static inline void register_scores(void) { - uint8_t details[4] = { (uint8_t) gPlayer->stats.lvl, (uint8_t) cLevel, (uint8_t) (gPlayer->class + 1), 0 }; - steam_register_score((int) gPlayer->gold, (int32_t*) &details, 1); - steam_register_kills((int) gPlayer->stat_data.kills, (int32_t*) &details, 1); + uint8_t details[4] = { + (uint8_t) gPlayer->stats.lvl, + (uint8_t) cLevel, (uint8_t) (gPlayer->class + 1), 0 + }; + steam_register_score((int) gPlayer->gold, (int32_t*) + &details, 1); + steam_register_kills((int) gPlayer->stat_data.kills, + (int32_t*) &details, 1); if (quickGame) { - steam_register_qp_score((int) gPlayer->gold, (int32_t*) &details, 1); + steam_register_qp_score((int) gPlayer->gold, + (int32_t*) &details, 1); + } + if (weeklyGame) { + //steam_register_weekly_score((int) gPlayer->gold, (int32_t*) &details, 1); } if (arcadeGame) { - steam_register_arcade_score((int)gPlayer->gold, (int32_t*) &details, 1); + steam_register_arcade_score((int)gPlayer->gold, + (int32_t*) &details, 1); } if (gPlayer->class == ROGUE) { steam_set_achievement(ROGUE_LIKE); - steam_register_rogue_score((int) gPlayer->gold, (int32_t*) &details, 1); + steam_register_rogue_score((int) gPlayer->gold, + (int32_t*) &details, 1); } else if (gPlayer->class == WARRIOR) { - steam_register_warrior_score((int) gPlayer->gold, (int32_t*) &details, 1); + steam_register_warrior_score((int) gPlayer->gold, + (int32_t*) &details, 1); } } #endif @@ -1046,6 +1088,8 @@ run_game(void) gGameState = GAME_OVER; createInGameGameOverMenu(); hiscore_register(gPlayer, cLevel); + if (weeklyGame) + set_random_seed(0); #ifdef STEAM_BUILD register_scores(); #endif // STEAM_BUILD @@ -1061,6 +1105,8 @@ run_game(void) gui_log("Your break is over!"); gui_event_message("Well done!"); end_game_details(); + if (weeklyGame) + set_random_seed(0); #ifdef STEAM_BUILD if (cLevel >= 20 && !arcadeGame) steam_set_achievement(BACK_TO_WORK); @@ -1140,13 +1186,13 @@ run(void) #ifdef DEBUG Uint32 frame = 0; - Timer *fpsTime = timer_create(); - Timer *updateTimer = timer_create(); + Timer *fpsTime = _timer_create(); + Timer *updateTimer = _timer_create(); timer_start(fpsTime); timer_start(updateTimer); #endif // DEBUG - Timer *fpsTimer = timer_create(); + Timer *fpsTimer = _timer_create(); while (!quit) { diff --git a/src/map.c b/src/map.c index 54f519f..a89ece3 100644 --- a/src/map.c +++ b/src/map.c @@ -58,7 +58,7 @@ map_create(void) map->artifacts = linkedlist_create(); map->objects = linkedlist_create(); map->currentRoom = (Position) { 0, 0 }; - map->monsterMoveTimer = timer_create(); + map->monsterMoveTimer = _timer_create(); map->level = 1; for (i=0; i < MAP_H_ROOM_COUNT; ++i) { diff --git a/src/player.c b/src/player.c index 96eb962..76567ac 100644 --- a/src/player.c +++ b/src/player.c @@ -513,7 +513,7 @@ player_create(class_t class, Camera *cam) player->class = class; player->state = ALIVE; player->projectiles = linkedlist_create(); - player->animationTimer = timer_create(); + player->animationTimer = _timer_create(); player->swordAnimation = animation_create(5); player->equipment.hasArtifacts = false; diff --git a/src/projectile.c b/src/projectile.c index d54b295..7d3f4c8 100644 --- a/src/projectile.c +++ b/src/projectile.c @@ -62,7 +62,7 @@ projectile_create(void) p->sprite = sprite_create(); p->velocity = VECTOR2D_NODIR; p->alive = true; - p->lifetime = timer_create(); + p->lifetime = _timer_create(); p->onRender = NULL; timer_start(p->lifetime); return p; diff --git a/src/skillbar.c b/src/skillbar.c index 6ebe29d..67f1a41 100644 --- a/src/skillbar.c +++ b/src/skillbar.c @@ -181,8 +181,8 @@ skillbar_create(Camera *cam) { SkillBar *bar = ec_malloc(sizeof(SkillBar)); bar->sprites = linkedlist_create(); - bar->activationTimer = timer_create(); - bar->skillSparkleTimer = timer_create(); + bar->activationTimer = _timer_create(); + bar->skillSparkleTimer = _timer_create(); bar->lastActivation = 0; bar->frame = create_frame_sprite(cam); bar->artifactDisplayOffset = 5 * 32 + 8; diff --git a/src/sprite.c b/src/sprite.c index 34ed977..835a3a2 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -35,8 +35,8 @@ sprite_create_default(void) s->angle = 0; s->rotationPoint = (SDL_Point) { 0, 0 }; s->flip = SDL_FLIP_NONE; - s->renderTimer = timer_create(); - s->animationTimer = timer_create(); + s->renderTimer = _timer_create(); + s->animationTimer = _timer_create(); s->texture_index = 0; s->fixed = false; s->animate = true; diff --git a/src/steam/steamworks_api_wrapper.c b/src/steam/steamworks_api_wrapper.c index e51e863..1c6971e 100644 --- a/src/steam/steamworks_api_wrapper.c +++ b/src/steam/steamworks_api_wrapper.c @@ -88,7 +88,7 @@ steam_init() m_Initiated = m_AppID != 0; if (m_Initiated) c_SteamAPI_SetCallbacks(stats_received, stats_stored, leaderboard_received); - requestDataTimer = timer_create(); + requestDataTimer = _timer_create(); } void steam_shutdown(void) diff --git a/src/time.c b/src/time.c new file mode 100644 index 0000000..f17a7d4 --- /dev/null +++ b/src/time.c @@ -0,0 +1,29 @@ +#include "time.h" +#include "util.h" + +#define SECONDS_PER_DAY 86400 +#define SECONDS_PER_HOUR 3600 +#define SECONDS_PER_MINUTE 60 + +time_t +time_get_weekly_seed(void) +{ + time_t now = time(NULL); + + struct tm *tm; + tm = localtime(&now); + + // Zero out the hour and minutes to 00:00:01 + now -= tm->tm_hour * SECONDS_PER_HOUR; + now -= tm->tm_min * SECONDS_PER_MINUTE; + now -= tm->tm_sec; + now += 1; + + // Reverse time back to last monday + unsigned int dayOfWeek = tm->tm_wday; + now -= (dayOfWeek == 0 ? 6 : dayOfWeek - 1) * SECONDS_PER_DAY; + + info("Monday: %s", ctime(&now)); + + return now; +} diff --git a/src/time.h b/src/time.h new file mode 100644 index 0000000..bc888b9 --- /dev/null +++ b/src/time.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +time_t +time_get_weekly_seed(void); diff --git a/src/timer.c b/src/timer.c index c7af4b6..ea83d03 100644 --- a/src/timer.c +++ b/src/timer.c @@ -21,7 +21,7 @@ #include "util.h" #include "timer.h" -Timer* timer_create() +Timer* _timer_create() { Timer *t = ec_malloc(sizeof(Timer)); t->startTime = 0; diff --git a/src/timer.h b/src/timer.h index 86c45c1..9cb2788 100644 --- a/src/timer.h +++ b/src/timer.h @@ -25,7 +25,7 @@ typedef struct Timer { unsigned int startTime; } Timer; -Timer* timer_create(void); +Timer* _timer_create(void); void timer_start(Timer*); void timer_stop(Timer*); bool timer_started(Timer*);