forked from NotAShelf/rogged
player: implement manual pickup and descend confirmation
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Icd8d0ffd9bdf92f5c8943590886543566a6a6964
This commit is contained in:
parent
db21bdacdd
commit
e4926a86fe
2 changed files with 108 additions and 46 deletions
127
src/player.c
127
src/player.c
|
|
@ -5,6 +5,7 @@
|
|||
#include "map.h"
|
||||
#include "utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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,36 +111,32 @@ void player_use_item(Player *p, Item *i) {
|
|||
if (i->picked_up)
|
||||
return; // invalid item
|
||||
|
||||
// Apply item effect
|
||||
// Apply item effect (only potions are consumed)
|
||||
if (i->type == ITEM_POTION) {
|
||||
item_use(p, i);
|
||||
|
||||
// Mark item as used (remove from inventory)
|
||||
i->picked_up = 1;
|
||||
}
|
||||
// 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];
|
||||
|
||||
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];
|
||||
}
|
||||
p->inventory_count--;
|
||||
|
||||
// Mark last slot as invalid
|
||||
p->inventory[MAX_INVENTORY - 1].picked_up = 1;
|
||||
|
||||
player_remove_inventory_item(p, i);
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
19
src/player.h
19
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue