From e4926a86fec9d6395cc300fe703e33bd13e8f19d Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 3 Apr 2026 15:40:35 +0300 Subject: [PATCH] player: implement manual pickup and descend confirmation Signed-off-by: NotAShelf Change-Id: Icd8d0ffd9bdf92f5c8943590886543566a6a6964 --- src/player.c | 135 +++++++++++++++++++++++++++++++++++---------------- src/player.h | 19 ++++++-- 2 files changed, 108 insertions(+), 46 deletions(-) diff --git a/src/player.c b/src/player.c index fff8f7a..f6a0e30 100644 --- a/src/player.c +++ b/src/player.c @@ -5,6 +5,7 @@ #include "map.h" #include "utils.h" #include +#include void player_init(Player *p, int x, int y) { p->x = x; @@ -15,6 +16,14 @@ void player_init(Player *p, int x, int y) { p->defense = 0; p->floor = 1; p->step_count = 0; + p->speed = 100; + p->cooldown = 0; + p->has_weapon = 0; + p->has_armor = 0; + memset(&p->equipped_weapon, 0, sizeof(Item)); + memset(&p->equipped_armor, 0, sizeof(Item)); + p->equipped_weapon.picked_up = 1; + p->equipped_armor.picked_up = 1; // mark as invalid p->inventory_count = 0; // Initialize inventory to empty @@ -33,17 +42,7 @@ static Enemy *get_enemy_at(Enemy *enemies, int count, int x, int y) { 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 player_move(Player *p, int dx, int dy, Map *map, Enemy *enemies, int enemy_count) { int new_x = p->x + dx; int new_y = p->y + dy; @@ -65,20 +64,12 @@ int player_move(Player *p, int dx, int dy, Map *map, Enemy *enemies, int enemy_c 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; } @@ -88,21 +79,30 @@ void player_attack(Player *p, Enemy *e) { combat_player_attack(p, e); } -void player_pickup(Player *p, Item *i) { +// Get item at player's current position (for pickup) +Item *get_item_at_floor(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_pickup(Player *p, Item *i) { if (p->inventory_count >= MAX_INVENTORY) { - return; // inventory full + return 0; } if (i->picked_up) { - return; // already picked up + return 0; } - // Copy item to inventory p->inventory[p->inventory_count] = *i; p->inventory_count++; - // Mark original as picked up i->picked_up = 1; + return 1; } void player_use_item(Player *p, Item *i) { @@ -111,35 +111,31 @@ void player_use_item(Player *p, Item *i) { 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; + // Apply item effect (only potions are consumed) + if (i->type == ITEM_POTION) { + item_use(p, i); + } + // Weapons and armor are equipped, not consumed } int player_use_first_item(Player *p) { if (p == NULL || p->inventory_count == 0) return 0; - // Find first valid item in inventory + // Find first valid item in inventory (skip weapons/armor - must equip explicitly) 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); + if (item->type == ITEM_POTION) { + // 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]; + // Remove from inventory (shift remaining items) + player_remove_inventory_item(p, i); + return 1; } - p->inventory_count--; - - // Mark last slot as invalid - p->inventory[MAX_INVENTORY - 1].picked_up = 1; - - return 1; + // Weapons/armor can't be used this way - must equip } } return 0; @@ -154,3 +150,60 @@ Item *player_get_inventory_item(Player *p, int index) { return NULL; // invalid/empty return &p->inventory[index]; } + +void player_remove_inventory_item(Player *p, int index) { + if (p == NULL) + return; + if (index < 0 || index >= MAX_INVENTORY) + return; + if (p->inventory[index].picked_up) + return; + + // Shift remaining items + for (int j = index; j < MAX_INVENTORY - 1; j++) { + p->inventory[j] = p->inventory[j + 1]; + } + p->inventory_count--; + p->inventory[MAX_INVENTORY - 1].picked_up = 1; +} + +int player_equip_item(Player *p, int inv_index) { + if (p == NULL) + return 0; + if (inv_index < 0 || inv_index >= MAX_INVENTORY) + return 0; + + Item *item = player_get_inventory_item(p, inv_index); + if (item == NULL) + return 0; + + if (item->type == ITEM_WEAPON) { + // Unequip current weapon first + if (p->has_weapon) { + p->attack -= p->equipped_weapon.power; + } + // Equip new weapon + p->equipped_weapon = *item; + p->has_weapon = 1; + p->attack += item->power; + // Remove from inventory + player_remove_inventory_item(p, inv_index); + return 1; + } + + if (item->type == ITEM_ARMOR) { + // Unequip current armor first + if (p->has_armor) { + p->defense -= p->equipped_armor.power; + } + // Equip new armor + p->equipped_armor = *item; + p->has_armor = 1; + p->defense += item->power; + // Remove from inventory + player_remove_inventory_item(p, inv_index); + return 1; + } + + return 0; // Not equippable (potion) +} diff --git a/src/player.h b/src/player.h index 0ccab25..a0460bd 100644 --- a/src/player.h +++ b/src/player.h @@ -7,21 +7,30 @@ void player_init(Player *p, int x, int y); // Move player, return 1 if moved/attacked, 0 if blocked -int player_move(Player *p, int dx, int dy, Map *map, Enemy *enemies, int enemy_count, Item *items, int item_count); +int player_move(Player *p, int dx, int dy, Map *map, Enemy *enemies, int enemy_count); // Player attacks enemy (deal damage) void player_attack(Player *p, Enemy *e); -// Pick up item -void player_pickup(Player *p, Item *i); +// Get item at floor position (x, y), returns NULL if none +Item *get_item_at_floor(Item *items, int count, int x, int y); -// Use item +// Pick up item, return 1 if successful, 0 if failed (full/invalid) +int player_pickup(Player *p, Item *i); + +// Use item (potions only - weapons/armor are equipped) void player_use_item(Player *p, Item *i); -// Use first available item in inventory, return 1 if used +// Use first available potion in inventory, return 1 if used int player_use_first_item(Player *p); // Get item at inventory index, returns NULL if invalid Item *player_get_inventory_item(Player *p, int index); +// Remove item from inventory at index (shifts remaining items) +void player_remove_inventory_item(Player *p, int index); + +// Equip weapon/armor from inventory, return 1 if successful +int player_equip_item(Player *p, int inv_index); + #endif // PLAYER_H