Files
ld58/code/game/impl/player.c
2025-10-06 23:09:53 +01:00

163 lines
4.3 KiB
C

#include "../player.h"
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_keycode.h>
#include <stdio.h>
#include "../outfit.h"
#include <npc.h>
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;
}
case SDLK_E:
{
for(int i = 0; player->world->npmCount; 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 (
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){
printf("dead :(");
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;
for(int i = 0; i < player->world->portalCount; i++) {
if(AABB_Collide(player->world->portals[0].box, player->collision)) {
player->currentArea = player->world->portals[0].area;
}
}
}
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);
}
}
}