diff --git a/assets/heart.png b/assets/heart.png new file mode 100644 index 0000000..8e03d25 Binary files /dev/null and b/assets/heart.png differ diff --git a/assets/poster.png b/assets/poster.png new file mode 100644 index 0000000..8cc415a Binary files /dev/null and b/assets/poster.png differ diff --git a/code/first.c b/code/first.c index 30c84bd..aef8c0f 100644 --- a/code/first.c +++ b/code/first.c @@ -24,6 +24,7 @@ #include "game/impl/world.c" #include "game/impl/npc.c" #include "game/impl/bandit.c" +#include "game/impl/outfit.c" int main(int argc, char **argv) { @@ -90,7 +91,7 @@ int main(int argc, char **argv) world->arena = arena; world->random = Random_Seed(29237489723847); - world->npcCount = 127; + world->npcCount = 12; for(U32 i = 0; i < world->npcCount; i++) { NPC *npc1 = &world->npcs[i]; npc1->collision.pos.x = 0; @@ -103,6 +104,7 @@ int main(int argc, char **argv) npc1->waitTime = 0; npc1->maxWaitTime = 1; npc1->currentNavNode = 0; + GenOutfit(&npc1->outfit,world,game); } Bandit *badman = &world->bandit; @@ -116,7 +118,7 @@ int main(int argc, char **argv) badman->maxWaitTime = 2; badman->poiCount = 2; badman->shootoutTimer = 1.5; - badman->agroRadius = 600.0; + badman->agroRadius = 6.0; badman->bullets = 6; badman->shootDelay = 1; badman->accuracyRange = 0.25; @@ -124,6 +126,8 @@ int main(int argc, char **argv) badman->reloadTimer = 0; badman->pointsOfInterest[0] = 937; badman->pointsOfInterest[1] = 12; + badman->outfitChoices = GenOutfit(&badman->outfit, world, game); + badman->currentArea = WORLD_AREA_OUTSIDE; world->npcPOI[0] = 100; @@ -236,6 +240,7 @@ int main(int argc, char **argv) Player *player = &game->world->player; switch (e.key.key) { case SDLK_R: { PlayerInit(game, player); } break; + case SDLK_F: {game->world->showPoster=!game->world->showPoster;}break; } } @@ -408,8 +413,19 @@ int main(int argc, char **argv) D_Begin(&game->draw, frame, D_MAX_RECTS); + RenderWorld(game->world, &game->draw); + R3f bounds = G_CameraBounds(&game->camera); + + if (game->world->showPoster) { + D_Rect(&game->draw, bounds.min.x + 4.8f, bounds.min.y + 6.4f, .texture = D_ImageHandle(&game->draw, S("poster")), .scale = 12.0f); + } + + for (U32 i = 0; i < game->world->player.health; i++) { + D_Rect(&game->draw, (bounds.max.x - 3) + i, bounds.min.y + 1, .texture = D_ImageHandle(&game->draw, S("heart"))); + } + //D_Text(&game->draw, game->draw.fonts, S("Small Test"), 0, 0); if(game->editor.enabled) { diff --git a/code/game/bandit.h b/code/game/bandit.h index b9eb7f8..0aceecf 100644 --- a/code/game/bandit.h +++ b/code/game/bandit.h @@ -1,5 +1,6 @@ #if !defined(LD_GAME_BANDIT_H_) #define LD_GAME_BANDIT_H_ +#include "outfit.h" typedef enum BANDIT_ACTION BANDIT_ACTION; enum BANDIT_ACTION @@ -62,8 +63,12 @@ struct Bandit { F32 accuracyRange; // A the circle around the bandit where they will trigger the quicktime reaction scene F32 agroRadius; + // What the bandit is wearing + G_Outfit outfit; + // What the bandit's outfit id's are + U32 *outfitChoices; }; -function V2f shootTowards(Bandit* bandit, V2f target, Random* r); - +function V2f ShootTowards(Bandit* bandit, V2f target, Random* r); +function void BanditDraw(D_Context *draw, Bandit *bandit); #endif // LD_GAME_BANDIT_H_ diff --git a/code/game/impl/bandit.c b/code/game/impl/bandit.c index 2c22d6a..dd4bcf5 100644 --- a/code/game/impl/bandit.c +++ b/code/game/impl/bandit.c @@ -1,7 +1,7 @@ #include "game/world.h" #include "game/bandit.h" -V2f shootTowards(Bandit *bandit, V2f target, Random* r) +V2f ShootTowards(Bandit *bandit, V2f target, Random* r) { V2f shooterV2 = bandit->collision.pos; F32 randX = Random_F32(r, -bandit->accuracyRange, bandit->accuracyRange); @@ -71,7 +71,7 @@ void UpdateBandit(F32 delta, Bandit *bandit, World *world) { { bandit->bullets--; bandit->shootCooldownTimer = bandit->shootDelay; - V2f banditShot = shootTowards(bandit, world->player.collision.pos, &world->random); + V2f banditShot = ShootTowards(bandit, world->player.collision.pos, &world->random); if(AABB_Slab(bandit->collision.pos, banditShot, world->player.collision)){ // gets shot lmao world->player.health--; @@ -85,3 +85,23 @@ void UpdateBandit(F32 delta, Bandit *bandit, World *world) { // TODO Running away } } + +void BanditDraw(D_Context *draw, Bandit *bandit) +{ + G_Outfit *outfit = &bandit->outfit; + + R2f pframe = D_AnimationFrame(&outfit->state); + + for (U32 it = 0; it < G_OUTFIT_COMPONENT_COUNT; ++it) + { + U32 flipped = (outfit->dir & G_OUTFIT_DIR_FLIPPED) != 0; + U32 dir = (outfit->dir & ~G_OUTFIT_DIR_FLIPPED); + + U32 tid = outfit->e[dir].e[it]; + if (tid != 0) + { + U32 flags = D_RECT_UV_ASPECT | (flipped ? D_RECT_FLIP_X : 0); + D_Rect(draw, bandit->collision.pos.x, bandit->collision.pos.y, .texture = tid, .uv = pframe, .flags = flags); + } + } +} diff --git a/code/game/impl/npc.c b/code/game/impl/npc.c index c3febc6..dd4a5a4 100644 --- a/code/game/impl/npc.c +++ b/code/game/impl/npc.c @@ -46,3 +46,23 @@ void UpdateNPC(F32 delta, NPC *npc, World *world) { break; } } + +void NPCDraw(D_Context *draw, NPC *npc) +{ + G_Outfit *outfit = &npc->outfit; + + R2f pframe = D_AnimationFrame(&outfit->state); + + for (U32 it = 0; it < G_OUTFIT_COMPONENT_COUNT; ++it) + { + U32 flipped = (outfit->dir & G_OUTFIT_DIR_FLIPPED) != 0; + U32 dir = (outfit->dir & ~G_OUTFIT_DIR_FLIPPED); + + U32 tid = outfit->e[dir].e[it]; + if (tid != 0) + { + U32 flags = D_RECT_UV_ASPECT | (flipped ? D_RECT_FLIP_X : 0); + D_Rect(draw, npc->collision.pos.x, npc->collision.pos.y, .texture = tid, .uv = pframe, .flags = flags); + } + } +} \ No newline at end of file diff --git a/code/game/impl/outfit.c b/code/game/impl/outfit.c new file mode 100644 index 0000000..fbe15d7 --- /dev/null +++ b/code/game/impl/outfit.c @@ -0,0 +1,31 @@ + + +U32* GenOutfit(G_Outfit *o, World *world, G_State *game) +{ + U32 *outfitChoices = M_ArenaPush(world->arena, U32, .count = 8); + G_Outfit *outfit = o; + + D_AnimationInit(&outfit->state, 0, 1, 4, 1.0f / 6.0f); + + M_TempScope(0, 0) + { + for (U32 it = 0; it < G_OUTFIT_COMPONENT_COUNT; ++it) + { + U32 idx = Random_Next(&world->random) % __outfit_counts[it]; + + // We just allow face, hair and hat to default to 0 meaning the player doesn't have one + if (idx != 0 || it < 2 || it > 4) + { + outfit->front.e[it] = OUTFIT_IMG(front, idx); + outfit->side.e[it] = OUTFIT_IMG(side, idx); + + if ((idx + 1) <= __outfit_counts[it]) + { + outfit->back.e[it] = OUTFIT_IMG(back, idx); + } + } + outfitChoices[it] = idx; + } + } + return outfitChoices; +} \ No newline at end of file diff --git a/code/game/impl/player.c b/code/game/impl/player.c index 7b95b5e..e7100b9 100644 --- a/code/game/impl/player.c +++ b/code/game/impl/player.c @@ -2,47 +2,9 @@ #include #include #include +#include "../outfit.h" +#include "../npc.h" -// @Todo: move/extern these so the npc/bandit can use them -// -#define G_OUTFIT_COMPONENT_COUNT 8 - -global_var Str8 __outfit_names[] = { - Sl("npc_%s_base_%d"), - Sl("npc_%s_eyes_%d"), - Sl("npc_%s_face_%d"), - Sl("npc_%s_hair_%d"), - Sl("npc_%s_hat_%d"), - Sl("npc_%s_shirt_%d"), - Sl("npc_%s_shoes_%d"), - Sl("npc_%s_trousers_%d") -}; - -global_var U32 __outfit_counts[] = { - 2, // base - 3, // eyes - 5, // face - 4, // hair - 3, // hat - 2, // shirt - 1, // shoes - 2 // trousers -}; - -global_var U32 __outfit_back_counts[] = { - 2, // base - 0, // eyes - 3, // face - 4, // hair - 3, // hat - 2, // shirt - 1, // shoes - 2 // trousers -}; - -StaticAssert(ArraySize(__outfit_names) == ArraySize(__outfit_counts)); - -#define OUTFIT_IMG(dir, n) D_ImageHandle(&game->draw, Sf(temp.arena, (const char *) __outfit_names[it].data, #dir, n)) void PlayerInit(G_State *game, Player *player) { World *world = game->world; @@ -105,6 +67,16 @@ void PlayerInput(SDL_Event *event, Player *player) player->controls.downDown = val; break; } + case SDLK_E: + { + for(int i = 0; player->world->npcCount; i++){ + NPC *npc = &player->world->npcs[i]; + if(AABB_Circle(npc->interationRadius, npc->collision.pos, player->collision) && !npc->infoGiven){ + npc->infoGiven=true; + player->knownDetails[player->detailCount] = player->world->bandit.outfitChoices[player->detailCount]; + } + } + } } } if ( diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 2a67b6d..43635f1 100644 --- a/code/game/impl/world.c +++ b/code/game/impl/world.c @@ -67,15 +67,11 @@ void RenderWorld(World *world, D_Context *draw) { for(U32 i = 0; i < world->npcCount; i++) { NPC npc = world->npcs[i]; if(npc.currentArea == world->player.currentArea) { - V2f drawPos = AABB_Centre(npc.collision); - D_Rect(draw, drawPos.x, drawPos.y, .texture = 1); + NPCDraw(draw, &world->npcs[i]); } } - if(world->bandit.currentArea == world->player.currentArea) { - V2f drawPos = AABB_Centre(world->bandit.collision); - D_Rect(draw, drawPos.x, drawPos.y, .texture = 9); - } + BanditDraw(draw, &world->bandit); PlayerDraw(draw, &world->player); } diff --git a/code/game/npc.h b/code/game/npc.h index eff6157..8ff3512 100644 --- a/code/game/npc.h +++ b/code/game/npc.h @@ -46,10 +46,15 @@ struct NPC { U32 targetNavNode; // How long the npc has been walking to the next index F32 walkTimer; - + // Space within you can interact with the NPC. + F32 interationRadius; //// Knowledge // What the NPC knows about the bandit. NPC_LOOK banditKnowledge; + // NPC clothes + G_Outfit outfit; + // if the NPC has given info + bool infoGiven; }; - +function void NPCDraw(D_Context *draw, NPC *npc); #endif // LD_GAME_NPC_H_ diff --git a/code/game/outfit.h b/code/game/outfit.h new file mode 100644 index 0000000..27a54cb --- /dev/null +++ b/code/game/outfit.h @@ -0,0 +1,45 @@ + +#if !defined(LD_GAME_OUTFIT_H) +#define LD_GAME_OUTFIT_H + +#define G_OUTFIT_COMPONENT_COUNT 8 + +global_var Str8 __outfit_names[] = { + Sl("npc_%s_base_%d"), + Sl("npc_%s_eyes_%d"), + Sl("npc_%s_face_%d"), + Sl("npc_%s_hair_%d"), + Sl("npc_%s_hat_%d"), + Sl("npc_%s_shirt_%d"), + Sl("npc_%s_shoes_%d"), + Sl("npc_%s_trousers_%d")}; + +global_var U32 __outfit_counts[] = { + 2, // base + 3, // eyes + 5, // face + 4, // hair + 3, // hat + 2, // shirt + 1, // shoes + 2 // trousers +}; + +global_var U32 __outfit_back_counts[] = { + 2, // base + 0, // eyes + 3, // face + 4, // hair + 3, // hat + 2, // shirt + 1, // shoes + 2 // trousers +}; + +StaticAssert(ArraySize(__outfit_names) == ArraySize(__outfit_counts)); + +#define OUTFIT_IMG(dir, n) D_ImageHandle(&game->draw, Sf(temp.arena, (const char *)__outfit_names[it].data, #dir, n)) + +function U32* GenOutfit(G_Outfit *o, World *world, G_State *game); + +#endif // LD_GAME_OUTFIT_H \ No newline at end of file diff --git a/code/game/player.h b/code/game/player.h index 441793e..b6986f1 100644 --- a/code/game/player.h +++ b/code/game/player.h @@ -34,6 +34,9 @@ struct Player U32 health; F32 reloadTimer; + + U32 *knownDetails; + U32 detailCount; }; function void PlayerInit(G_State *game, Player *player); diff --git a/code/game/world.h b/code/game/world.h index e68fdfd..4a0ec83 100644 --- a/code/game/world.h +++ b/code/game/world.h @@ -67,7 +67,7 @@ struct World { World_Hitbox *hitboxes; World_Portal *portals; U32 *map; - + bool showPoster; U32 propCount; U32 portalCount; U32 hitboxCount;