#include "../player.h" #include #include #include // @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; player->world = world; player->bulletsLoaded = PLAYER_BULLET_COUNT; player->currentArea = WORLD_AREA_OUTSIDE; player->health = 3; player->collision.size.x = 1; player->collision.size.x = 2; G_Outfit *outfit = &player->outfit; 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); } } } } } void PlayerInput(SDL_Event *event, Player *player) { SDL_KeyboardEvent key = event->key; SDL_MouseButtonEvent mouseBtn = event->button; if(event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_KEY_UP) { bool val = event->type == SDL_EVENT_KEY_DOWN; switch (key.key) { case SDLK_W: { player->controls.upDown = val; break; } case SDLK_A: { player->controls.leftDown = val; break; } case SDLK_D: { player->controls.rightDown = val; break; } case SDLK_S: { player->controls.downDown = val; break; } } } if ( event->type == SDL_EVENT_MOUSE_BUTTON_DOWN && mouseBtn.button == SDL_BUTTON_LEFT ) { if(player->bulletsLoaded > 0) { // shooting player->bulletsLoaded -= 1; player->controls.shot = true; player->shotPos = player->world->mouseProjected; printf("shot %f %f\n", player->shotPos.x, player->shotPos.y); } else if(player->reloadTimer == 0) { player->reloadTimer = PLAYER_RELOAD_TIME; printf("reloading\n"); }; } } void PlayerUpdate(F32 delta, Player *player) { player->controls.shot = false; V2f dir = V2F(0, 0); if(player->health == 0){ player->health = 3; } if(player->controls.upDown) { dir.y -= 1; player->outfit.dir = G_OUTFIT_DIR_BACK; } if(player->controls.downDown) { dir.y += 1; player->outfit.dir = G_OUTFIT_DIR_FRONT; } if(player->controls.leftDown) { dir.x -= 1; player->outfit.dir = G_OUTFIT_DIR_SIDE | G_OUTFIT_DIR_FLIPPED; } if(player->controls.rightDown) { dir.x += 1; player->outfit.dir = G_OUTFIT_DIR_SIDE; } if (dir.x != 0 || dir.y != 0) { D_AnimationUpdate(&player->outfit.state, delta); } else { player->outfit.state.index = 0; } if(player->reloadTimer > 0) { player->reloadTimer-=delta; if(player->reloadTimer <= 0) { player->bulletsLoaded = PLAYER_BULLET_COUNT; player->reloadTimer = 0; } } dir = V2f_Scale(NormaliseV2F(dir), PLAYER_SPEED*delta); player->collision.pos.x += dir.x; player->collision.pos.y += dir.y; } void PlayerDraw(D_Context *draw, Player *player) { G_Outfit *outfit = &player->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, player->collision.pos.x, player->collision.pos.y, .texture = tid, .uv = pframe, .flags = flags); } } }