aboutsummaryrefslogtreecommitdiff
#include "game.h"
#include <string.h>

void update_score(void)
{
  char buffer[48];
  struct Player *p1 = &game->players[0], *p2 = &game->players[1];

  sprintf(buffer, "%s: %d - %s: %d", p1->name, p1->score, p2->name, p2->score);
  set_text(game->score, buffer);

  p1->life = p2->life = 12;
}

static const float reload_time = 2.0f;

static void player_on_collision(struct Entity *this, struct Entity *other)
{
  struct Player *p = (struct Player *)this - offsetof(struct Player, entity);

  if(other->collidable && this->y <= other->y)
    {
      p->entity.i = 0;
      p->on_ground = true;
      this->d2y = 0.0f;
    }

  if(!other->collidable)
    {
      struct Bullet *b = (struct Bullet *)other;

      if(b->owner == p)
	return;

      p->life -= b->damage;

      int i;

      if(p->life > 8)
	{
	  i = p->life - 8;
	  p->hearts[2]->src_rect.x = 16 * (4 - i);
	  p->hearts[1]->src_rect.x = 0;
	  p->hearts[0]->src_rect.x = 0;

	}
      else if(p->life > 4)
	{
	  i = p->life - 4;
	  p->hearts[2]->src_rect.x = 64;
	  p->hearts[1]->src_rect.x = 16 * (4 - i);
	  p->hearts[0]->src_rect.x = 0;
	}
      else
	{
	  i = p->life;
	  p->hearts[2]->src_rect.x = 64;
	  p->hearts[1]->src_rect.x = 64;
	  p->hearts[0]->src_rect.x = 16 * (4 - i);
	}

      if(p->life <= 0)
	{
	  b->owner->score ++;

	  p->hearts[2]->src_rect.x = 0;
	  p->hearts[1]->src_rect.x = 0;
	  p->hearts[0]->src_rect.x = 0;

	  update_score();
	}
    }
}

void init_player(struct Player *p, struct PlayerKeys *keys,
		 float x, float y, const char *name)
{
  struct Entity *e;
  p->keys = *keys;
  e = &p->entity;

  e->texture = load_texture("resources/cowboy.png");
  e->use_src_rect = true;
  e->src_rect.x = 0;
  e->src_rect.y = 0;
  e->src_rect.w = 43;
  e->src_rect.h = 51;

  e->i = 0;

  e->x = x;
  e->y = y;

  e->collidable = true;
  e->w = 43;
  e->h = 55;
  e->on_collision = player_on_collision;

  p->reloading = false;
  p->on_ground = false;
  p->current_gun = REVOLVER;
  p->life = 12;
  p->counter = 0;

  p->guns[0] = (struct Gun)
    {
      .type = REVOLVER,
      .angle = 0.0f,
      .projectiles_per_shot = 1,
      .cooldown = 0.5f,
      .ready = true,
      .sound_effect = game->revolver_sound,
      .bullets = 6,
      .max_bullets = 6,
      .damage = 2,
    };

  p->guns[1] = (struct Gun)
    {
      .type = RIFLE,
      .angle = 0.0f,
      .projectiles_per_shot = 1,
      .cooldown = 1.0f,
      .ready = true,
      .sound_effect = game->rifle_sound,
      .bullets = 5,
      .max_bullets = 5,
      .damage = 3,
    };

  p->guns[2] = (struct Gun)
    {
      .type = SHOTGUN,
      .angle = 5.0f,
      .projectiles_per_shot = 5,
      .cooldown = 2.0f,
      .ready = true,
      .sound_effect = game->rifle_sound,
      .bullets = 2,
      .max_bullets = 2,
      .damage = 1,
    };

  if(strlen(name) > 16)
    die("Player's name is too long: %s", name);

  strcpy(p->name, name);
}

void update_player(struct Player *p)
{
  struct PlayerKeys *k = &p->keys;
  struct Gun *g = &p->guns[p->current_gun];
  float dt = game->frame_time;

  // Movement related code
  if(game->keys[k->left])
    {
      p->entity.dx = -300.0f;
      p->entity.mirror = true;

      p->counter ++;

      if(p->counter % 5 == 0 && p->on_ground)
	{
	  p->entity.i ++;
	  p->entity.i %= 5;
	}
    }
  else if(game->keys[k->right])
    {
      p->entity.dx = 300.0f;
      p->entity.mirror = false;

      p->counter ++;

      if(p->counter % 10 == 0 && p->on_ground)
	{
	  p->entity.i ++;
	  p->entity.i %= 5;
	}
    }
  else
    {
      p->counter = 0;
      p->entity.d2x = -18.0f * p->entity.dx;

      if(p->on_ground)
	{
	  p->entity.i = 0;
	}
    }

  if(p->entity.y < game->height - p->entity.h)
    {
      p->entity.d2y = game->gravity;
    }
  else
    {
      p->on_ground = true;
      p->entity.d2y = 0;
      p->entity.dy = 0;
      p->entity.y = (game->height - p->entity.h);

      if(p->entity.i == 5)
	p->entity.i = 0;
    }
  if(game->keys[k->jump]
     && p->on_ground)
    {
      p->entity.dy = -700.0f;
      p->on_ground = false;
      p->entity.i = 5;
    }

  p->entity.x += p->entity.dx * dt + (0.5f * p->entity.d2x * dt * dt);
  p->entity.y += p->entity.dy * dt + (0.5f * p->entity.d2y * dt * dt);

  p->entity.dx += p->entity.d2x * dt;
  p->entity.dy += p->entity.d2y * dt;

  if(p->entity.x + p->entity.w > game->width)
    p->entity.x = game->width - p->entity.w;
  else if(p->entity.x < 0)
    p->entity.x = 0;

  if(p->entity.y < 0)
    p->entity.y = 0;

  // Guns related code
  if(game->keys[k->weaponds[0]])
    {
      p->current_gun = REVOLVER;
      p->reloading = false;
      p->reload_time = 0.0f;

      p->gun->texture = game->guns[0];
      SDL_QueryTexture(game->guns[0], NULL, NULL, &p->gun->rect.w, &p->gun->rect.h);
      p->gun->rect.w *= 2;
      p->gun->rect.h *= 2;
    }
  else if(game->keys[k->weaponds[1]])
    {
      p->current_gun = RIFLE;
      p->reloading = false;
      p->reload_time = 0.0f;

      p->gun->texture = game->guns[1];
      SDL_QueryTexture(game->guns[1], NULL, NULL, &p->gun->rect.w, &p->gun->rect.h);
      p->gun->rect.w *= 2;
      p->gun->rect.h *= 2;
    }
  else if(game->keys[k->weaponds[2]])
    {
      p->current_gun = SHOTGUN;
      p->reloading = false;
      p->reload_time = 0.0f;

      p->gun->texture = game->guns[2];
      SDL_QueryTexture(game->guns[2], NULL, NULL, &p->gun->rect.w, &p->gun->rect.h);
      p->gun->rect.w *= 2;
      p->gun->rect.h *= 2;
    }

  // Check & Update gun's cooldown
  if(!g->ready)
    {
      g->cooldown_elapsed += game->frame_time;

      if(g->cooldown_elapsed >= g->cooldown)
	g->ready = true;
    }

  if(p->reload_time > 0)
    p->reload_time -= game->frame_time;
  if(p->reload_time < 0)
    p->reload_time = 0.0f;

  if(p->reloading && p->reload_time == 0.0f)
    {
      g->bullets = g->max_bullets;
      p->reloading = false;
    }

  if(game->keys[k->fire])
    shoot_bullet(p);

  if(game->keys[k->reload])
    {
      p->reloading = true;
      p->reload_time = reload_time;
    }

  p->entity.src_rect.x = p->entity.i * 43;

  // Add to game's entity list
  game->entities[game->num_entities ++] = &p->entity;
}