rogged/src/player.c
NotAShelf b381e2efbd
initial commit
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ie3b66d17f6f660c9b9a719210bd86f9f6a6a6964
2026-03-19 17:01:54 +03:00

142 lines
3.6 KiB
C

#include "player.h"
#include "common.h"
#include "map.h"
#include "utils.h"
#include "combat.h"
#include "items.h"
#include <stdlib.h>
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
}
}
// 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];
}
}
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];
}
}
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;
}
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];
}