diff --git a/src/common.h b/src/common.h index 85c6be1..5474109 100644 --- a/src/common.h +++ b/src/common.h @@ -44,6 +44,7 @@ typedef struct { int attack; int defense; int floor; + int step_count; Item inventory[MAX_INVENTORY]; int inventory_count; } Player; diff --git a/src/player.c b/src/player.c index 0d3e326..dcabebc 100644 --- a/src/player.c +++ b/src/player.c @@ -1,142 +1,154 @@ #include "player.h" +#include "combat.h" #include "common.h" +#include "items.h" #include "map.h" #include "utils.h" -#include "combat.h" -#include "items.h" #include -void player_init(Player* p, int x, int y) { - p->x = x; - p->y = y; - p->hp = PLAYER_BASE_HP; - p->max_hp = PLAYER_BASE_HP; - p->attack = PLAYER_BASE_ATTACK; - p->defense = 0; - p->floor = 1; - p->inventory_count = 0; - - // Initialize inventory to empty - for (int i = 0; i < MAX_INVENTORY; i++) { - p->inventory[i].picked_up = 1; // mark as invalid - } +void player_init(Player *p, int x, int y) { + p->x = x; + p->y = y; + p->hp = PLAYER_BASE_HP; + p->max_hp = PLAYER_BASE_HP; + p->attack = PLAYER_BASE_ATTACK; + p->defense = 0; + p->floor = 1; + p->step_count = 0; + p->inventory_count = 0; + + // Initialize inventory to empty + for (int i = 0; i < MAX_INVENTORY; i++) { + p->inventory[i].picked_up = 1; // mark as invalid + } } // Check if position has an enemy -static Enemy* get_enemy_at(Enemy* enemies, int count, int x, int y) { - for (int i = 0; i < count; i++) { - if (enemies[i].alive && enemies[i].x == x && enemies[i].y == y) { - return &enemies[i]; - } +static Enemy *get_enemy_at(Enemy *enemies, int count, int x, int y) { + for (int i = 0; i < count; i++) { + if (enemies[i].alive && enemies[i].x == x && enemies[i].y == y) { + return &enemies[i]; } - return NULL; + } + return NULL; } // Check if position has an item -static Item* get_item_at(Item* items, int count, int x, int y) { - for (int i = 0; i < count; i++) { - if (!items[i].picked_up && items[i].x == x && items[i].y == y) { - return &items[i]; - } +static Item *get_item_at(Item *items, int count, int x, int y) { + for (int i = 0; i < count; i++) { + if (!items[i].picked_up && items[i].x == x && items[i].y == y) { + return &items[i]; } - return NULL; + } + return NULL; } -int player_move(Player* p, int dx, int dy, Map* map, Enemy* enemies, int enemy_count, Item* items, int item_count) { - int new_x = p->x + dx; - int new_y = p->y + dy; - - // Check bounds - if (!in_bounds(new_x, new_y, MAP_WIDTH, MAP_HEIGHT)) { - return 0; - } - - // Check if walkable - if (!is_floor(map, new_x, new_y)) { - return 0; - } - - // Check for enemy at target position - Enemy* enemy = get_enemy_at(enemies, enemy_count, new_x, new_y); - if (enemy != NULL) { - // Attack the enemy - player_attack(p, enemy); - return 1; - } - - // Check for item at target position - Item* item = get_item_at(items, item_count, new_x, new_y); - if (item != NULL) { - // Pick up the item - player_pickup(p, item); - } - - // Move player - p->x = new_x; - p->y = new_y; - - return 1; -} +int player_move(Player *p, int dx, int dy, Map *map, Enemy *enemies, + int enemy_count, Item *items, int item_count) { + int new_x = p->x + dx; + int new_y = p->y + dy; -void player_attack(Player* p, Enemy* e) { - // Use combat system - combat_player_attack(p, e); -} - -void player_pickup(Player* p, Item* i) { - if (p->inventory_count >= MAX_INVENTORY) { - return; // inventory full - } - - if (i->picked_up) { - return; // already picked up - } - - i->picked_up = 1; - p->inventory[p->inventory_count] = *i; // copy item to inventory - p->inventory_count++; -} - -void player_use_item(Player* p, Item* i) { - if (p == NULL || i == NULL) return; - if (i->picked_up) return; // invalid item - - // Apply item effect - item_use(p, i); - - // Mark item as used (remove from inventory) - i->picked_up = 1; -} - -int player_use_first_item(Player* p) { - if (p == NULL || p->inventory_count == 0) return 0; - - // Find first valid item in inventory - for (int i = 0; i < MAX_INVENTORY; i++) { - if (!p->inventory[i].picked_up) { - Item* item = &p->inventory[i]; - - // Apply item effect - item_use(p, item); - - // Remove from inventory (shift remaining items) - for (int j = i; j < MAX_INVENTORY - 1; j++) { - p->inventory[j] = p->inventory[j + 1]; - } - p->inventory_count--; - - // Mark last slot as invalid - p->inventory[MAX_INVENTORY - 1].picked_up = 1; - - return 1; - } - } + // Check bounds + if (!in_bounds(new_x, new_y, MAP_WIDTH, MAP_HEIGHT)) { return 0; + } + + // Check if walkable + if (!is_floor(map, new_x, new_y)) { + return 0; + } + + // Check for enemy at target position + Enemy *enemy = get_enemy_at(enemies, enemy_count, new_x, new_y); + if (enemy != NULL) { + // Attack the enemy + player_attack(p, enemy); + return 1; + } + + // Check for item at target position + Item *item = get_item_at(items, item_count, new_x, new_y); + if (item != NULL) { + // Pick up the item + player_pickup(p, item); + } + + // Move player + p->x = new_x; + p->y = new_y; + p->step_count += 1; + if (p->step_count % 15 == 0 && p->hp < p->max_hp) { + p->hp += 1; + // p->hunger -= 0.1; ?? + } + return 1; } -Item* player_get_inventory_item(Player* p, int index) { - if (p == NULL) return NULL; - if (index < 0 || index >= MAX_INVENTORY) return NULL; - if (p->inventory[index].picked_up) return NULL; // invalid/empty - return &p->inventory[index]; +void player_attack(Player *p, Enemy *e) { + // Use combat system + combat_player_attack(p, e); +} + +void player_pickup(Player *p, Item *i) { + if (p->inventory_count >= MAX_INVENTORY) { + return; // inventory full + } + + if (i->picked_up) { + return; // already picked up + } + + i->picked_up = 1; + p->inventory[p->inventory_count] = *i; // copy item to inventory + p->inventory_count++; +} + +void player_use_item(Player *p, Item *i) { + if (p == NULL || i == NULL) + return; + if (i->picked_up) + return; // invalid item + + // Apply item effect + item_use(p, i); + + // Mark item as used (remove from inventory) + i->picked_up = 1; +} + +int player_use_first_item(Player *p) { + if (p == NULL || p->inventory_count == 0) + return 0; + + // Find first valid item in inventory + for (int i = 0; i < MAX_INVENTORY; i++) { + if (!p->inventory[i].picked_up) { + Item *item = &p->inventory[i]; + + // Apply item effect + item_use(p, item); + + // Remove from inventory (shift remaining items) + for (int j = i; j < MAX_INVENTORY - 1; j++) { + p->inventory[j] = p->inventory[j + 1]; + } + p->inventory_count--; + + // Mark last slot as invalid + p->inventory[MAX_INVENTORY - 1].picked_up = 1; + + return 1; + } + } + return 0; +} + +Item *player_get_inventory_item(Player *p, int index) { + if (p == NULL) + return NULL; + if (index < 0 || index >= MAX_INVENTORY) + return NULL; + if (p->inventory[index].picked_up) + return NULL; // invalid/empty + return &p->inventory[index]; }