1 /* 2 * player.h 3 * Copyright (C) 2009-2020 Joachim de Groot <jdegroot@web.de> 4 * 5 * NLarn is free software: you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * NLarn is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * See the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef __PLAYER_H_ 20 #define __PLAYER_H_ 21 22 #include "amulets.h" 23 #include "armour.h" 24 #include "buildings.h" 25 #include "fov.h" 26 #include "map.h" 27 #include "monsters.h" 28 #include "position.h" 29 #include "potions.h" 30 #include "rings.h" 31 #include "scrolls.h" 32 #include "spells.h" 33 #include "utils.h" 34 #include "weapons.h" 35 36 /* forward declaration */ 37 struct game; 38 39 typedef struct _player_stats 40 { 41 guint deepest_level; 42 gint monsters_killed[MT_MAX]; 43 guint spells_cast; 44 guint potions_quaffed; 45 guint scrolls_read; 46 guint books_read; 47 guint weapons_wasted; 48 guint life_protected; 49 guint vandalism; 50 51 // Keep track of the dungeon economy. 52 guint items_bought; 53 guint items_sold; 54 guint gems_sold; 55 guint gold_found; 56 guint gold_sold_items; 57 guint gold_sold_gems; 58 guint gold_bank_interest; 59 guint gold_spent_shop; 60 guint gold_spent_id_repair; 61 guint gold_spent_donation; 62 guint gold_spent_college; 63 guint gold_spent_taxes; 64 65 guint max_level; 66 guint max_xp; 67 guint str_orig; 68 guint int_orig; 69 guint wis_orig; 70 guint con_orig; 71 guint dex_orig; 72 } player_stats; 73 74 typedef enum _player_sex 75 { 76 PS_NONE, 77 PS_MALE, 78 PS_FEMALE, 79 PS_MAX 80 } player_sex; 81 82 typedef struct _player_settings 83 { 84 gboolean auto_pickup[IT_MAX]; /* automatically pick up item of enabled types */ 85 } player_settings; 86 87 typedef struct _player_tile_memory 88 { 89 map_tile_t type; 90 sobject_t sobject; 91 item_t item; /* type of item located here */ 92 int item_colour; /* colour of item located here */ 93 trap_t trap; 94 } player_tile_memory; 95 96 typedef struct _player_sobject_memory 97 { 98 position pos; 99 sobject_t sobject; 100 } player_sobject_memory; 101 102 typedef struct player 103 { 104 char *name; 105 player_sex sex; 106 107 guint strength; 108 guint intelligence; 109 guint wisdom; 110 guint constitution; 111 guint dexterity; 112 113 gint hp; /* current hp */ 114 guint hp_max; /* max hp */ 115 gint mp; /* magic points */ 116 guint mp_max; /* max mp */ 117 guint regen_counter; /* regeneration counter */ 118 119 guint bank_account; /* There is nothing quite as wonderful as money */ 120 guint bank_ieslvtb; /* The interest earned since last visiting the bank */ 121 guint outstanding_taxes; 122 123 guint experience; /* experience points */ 124 guint level; /* current experience level */ 125 126 speed speed; /* player's speed */ 127 guint movement; /* player's movement points */ 128 129 /* other stuff */ 130 GPtrArray *known_spells; 131 inventory *inventory; 132 GPtrArray *effects; /* temporary effects from potions, spells, ... */ 133 134 /* pointers to elements of items which are currently equipped */ 135 item *eq_amulet; 136 item *eq_weapon; 137 item *eq_sweapon; 138 item *eq_quiver; 139 140 /* armour */ 141 item *eq_boots; 142 item *eq_cloak; 143 item *eq_gloves; 144 item *eq_helmet; 145 item *eq_shield; 146 item *eq_suit; 147 148 /* rings */ 149 item *eq_ring_l; 150 item *eq_ring_r; 151 /* enough items for now */ 152 153 /* items identified */ 154 amulet_t identified_amulets[AM_MAX]; 155 armour_t identified_armour[AT_MAX]; 156 spell_t identified_books[SP_MAX]; 157 potion_t identified_potions[PO_MAX]; 158 ring_t identified_rings[RT_MAX]; 159 scroll_t identified_scrolls[ST_MAX]; 160 161 position pos; /* player's position */ 162 player_stats stats; /* statistics */ 163 164 /* oid of the last targeted monster */ 165 gpointer *ptarget; 166 167 /* player's field of vision */ 168 fov *fv; 169 170 /* player's memory of the map */ 171 player_tile_memory memory[MAP_MAX][MAP_MAX_Y][MAP_MAX_X]; 172 173 /* remembered positions of stationary objects */ 174 GArray *sobjmem; 175 176 /* flag to store if the player has been attacked during the current turn */ 177 gboolean attacked; 178 179 /* courses available in school */ 180 gint school_courses_taken[SCHOOL_COURSE_COUNT]; 181 182 player_settings settings; /* game configuration */ 183 } player; 184 185 /* various causes of death */ 186 typedef enum _player_cod 187 { 188 PD_NONE, /* 0, required by setjmp for initialisation */ 189 PD_EFFECT, 190 PD_LASTLEVEL, /* lost a level at level 1 */ 191 PD_MONSTER, 192 PD_SPHERE, 193 PD_TRAP, 194 PD_MAP, /* damaged by map effects */ 195 PD_SPELL, /* damaged by own spell */ 196 PD_CURSE, /* damaged by a cursed item */ 197 PD_SOBJECT, /* killed by stationary object */ 198 /* *** causes above this line can be stopped by live protection *** */ 199 PD_STUCK, /* stuck in a wall */ 200 PD_DROWNED, /* drowned in deep water */ 201 PD_MELTED, /* stuck in lava */ 202 PD_GENOCIDE, /* genocided themselves */ 203 /* *** caused below this line are described as "returning home" *** */ 204 PD_TOO_LATE, /* returned with potion too late */ 205 PD_WON, /* won the game */ 206 PD_LOST, /* daughter has died, potion not found */ 207 PD_QUIT, /* quit the game */ 208 PD_MAX 209 } player_cod; 210 211 /* function declarations */ 212 213 player *player_new(); 214 215 /* an array with textual descriptions of the player stac configurations */ 216 extern const char *player_bonus_stat_desc[]; 217 char player_select_bonus_stats(); 218 /** 219 * @brief Assigns player's stats to the given preset 220 * 221 * @param the player 222 * @param the preset (between 'a' and 'f') 223 * @return TRUE for valid presets, FALSE for invalid presets 224 */ 225 gboolean player_assign_bonus_stats(player *p, char preset); 226 void player_destroy(player *p); 227 228 cJSON *player_serialize(player *p); 229 player *player_deserialize(cJSON *pser); 230 231 /** 232 * @brief consume time for an action by the player 233 * 234 * @param the player 235 * @param the number of turns the move takes 236 * @param TRUE if the action can be interrupted 237 * @param (optional) the description of the action in the form "reading the book of foo" 238 * @return TRUE if the action has completed, FALSE if it has been interrupted 239 * 240 */ 241 gboolean player_make_move(player *p, int turns, gboolean interruptible, const char *desc, ...); 242 243 /** 244 * Kill the player 245 * 246 * @param the player 247 * @param the cause, e.g. PD_TRAP 248 * @param the id of the specific cause, e.g. TT_DART 249 * 250 */ 251 void player_die(player *p, player_cod cause_type, int cause); 252 253 guint64 player_calc_score(player *p, int won); 254 gboolean player_movement_possible(player *p); 255 int player_move(player *p, direction dir, gboolean open_door); 256 int player_attack(player *p, monster *m); 257 void player_update_fov(player *p); 258 259 /** 260 * Function to enter a map. 261 * 262 * @param the player 263 * @param entered map 264 * @param has to be TRUE if the player didn't enter the map regularly 265 * @return TRUE 266 */ 267 int player_map_enter(player *p, map *l, gboolean teleported); 268 269 /** 270 * Choose a random armour the player is wearing. 271 * 272 * @param the player 273 * @return a pointer to the slot of the armour 274 * 275 */ 276 item **player_get_random_armour(player *p, int enchantable); 277 278 void player_pickup(player *p); 279 280 void player_level_gain(player *p, int count); 281 void player_level_lose(player *p, int count); 282 283 void player_exp_gain(player *p, int count); 284 void player_exp_lose(player *p, guint count); 285 286 int player_hp_gain(player *p, int count); 287 int player_hp_lose(player *p, int count, player_cod cause_type, int cause); 288 289 /** 290 * Inflict damage upon the player 291 * 292 * @param the player 293 * @param pointer to the damage (will be freed) 294 * @param of the damage originator 295 * @param the id of the damage originator, specific to the damage originator 296 */ 297 void player_damage_take(player *p, damage *dam, player_cod cause_type, int cause); 298 299 int player_hp_max_gain(player *p, int count); 300 int player_hp_max_lose(player *p, int count); 301 302 int player_mp_gain(player *p, int count); 303 int player_mp_lose(player *p, int count); 304 int player_mp_max_gain(player *p, int count); 305 int player_mp_max_lose(player *p, int count); 306 307 /* dealing with temporary effects */ 308 effect *player_effect_add(player *p, effect *e); 309 void player_effects_add(player *p, GPtrArray *effects); 310 int player_effect_del(player *p, effect *e); 311 void player_effects_del(player *p, GPtrArray *effects); 312 effect *player_effect_get(player *p, effect_t et); 313 int player_effect(player *p, effect_t et); /* check if a effect is set */ 314 char **player_effect_text(player *p); 315 316 /* dealing with the inventory */ 317 int player_inv_display(player *p); 318 char *player_can_carry(player *p); 319 char *player_inv_weight(player *p); 320 321 /** 322 * Callback function used from inv_add() for the player's inventory. Here it 323 * is determined it an item can be picked up or if the weight of the player's 324 * pack would be larger than the player could carry afterwards. 325 * 326 * @param the inventory to check 327 * @param the item which is about to be added 328 * 329 */ 330 int player_inv_pre_add(inventory *inv, item *it); 331 332 /** 333 * Callback function used from inv_add() for the player's inventory. Here the 334 * weight of the inventory gets calculated and the burdened or overstrained 335 * mode is set or removed. 336 * 337 * @param the inventory to check 338 * @param the item which is about to be added 339 * 340 */ 341 void player_inv_weight_recalc(inventory *inv, item *it); 342 343 /** 344 * @brief Display a message window with a list of equipped items 345 * 346 * @param The player. 347 */ 348 void player_paperdoll(player *p); 349 350 /* dealing with items */ 351 352 /** 353 * @brief Function used to equip an item. 354 * 355 * @param the player 356 * @param unused, needed to make function signature match display_inventory requirements 357 * @param the item 358 */ 359 void player_item_equip(player *p, inventory **inv, item *it); 360 361 /** 362 * @brief Function used to unequip an item. 363 * 364 * @param the player 365 * @param unused, needed to make function signature match display_inventory requirements 366 * @param the item 367 */ 368 void player_item_unequip_wrapper(player *p, inventory **inv, item *it); 369 370 /** 371 * @brief Function used to unequip an item. 372 * 373 * @param the player 374 * @param unused, needed to make function signature match display_inventory requirements 375 * @param the item 376 * @param TRUE if the removal does not occur interactively. No time is consumed in this case. 377 */ 378 void player_item_unequip(player *p, 379 inventory **inv __attribute__((unused)), 380 item *it, 381 gboolean forced); 382 383 int player_item_is_container(player *p, item *it); 384 int player_item_can_be_added_to_container(player *p, item *it); 385 int player_item_filter_unequippable(item* it); 386 387 /** 388 * Callback funtion used to check if an item is equipped. 389 * 390 * @param the player 391 * @param the item 392 * @return place where item is equipped 393 */ 394 int player_item_is_equipped(player *p, item *it); 395 396 int player_item_is_equippable(player *p, item *it); 397 int player_item_is_unequippable(player *p, item *it); 398 int player_item_is_usable(player *p, item *it); 399 int player_item_is_dropable(player *p, item *it); 400 int player_item_is_damaged(player *p, item *it); 401 int player_item_is_affordable(player *p, item *it); 402 int player_item_is_sellable(player *p, item *it); 403 int player_item_is_identifiable(player *p, item *it); 404 int player_item_known(player *p, item *it); 405 int player_item_identified(player *p, item *it); 406 int player_item_not_equipped(item *it); 407 char *player_item_identified_list(player *p); 408 void player_item_identify(player *p, inventory **inv, item *it); 409 void player_item_use(player *p, inventory **inv, item *it); 410 void player_item_destroy(player *p, item *it); 411 void player_item_drop(player *p, inventory **inv, item *it); 412 413 /** 414 * @brief Take notes about an item. 415 */ 416 void player_item_notes(player *p, inventory **inv, item *it); 417 418 /* item usage shortcuts */ 419 void player_read(player *p); 420 void player_quaff(player *p); 421 void player_equip(player *p); 422 void player_take_off(player *p); 423 void player_drop(player *p); 424 425 /* query values */ 426 guint player_get_ac(player *p); 427 int player_get_hp_max(player *p); 428 int player_get_mp_max(player *p); 429 int player_get_str(player *p); 430 int player_get_int(player *p); 431 int player_get_wis(player *p); 432 int player_get_con(player *p); 433 int player_get_dex(player *p); 434 int player_get_cha(player *p); 435 int player_get_speed(player *p); 436 437 /* deal with money */ 438 guint player_get_gold(player *p); 439 /** 440 * @brief Remove a given number of gold coins from the Player's inventory 441 * 442 * @param The player 443 * @param The amount of gold to remove 444 */ 445 void player_remove_gold(player *p, guint amount); 446 447 const char *player_get_level_desc(player *p); 448 449 /** 450 * @brief Look for traps on adjacent map tiles. 451 * 452 * @param the player 453 */ 454 void player_search(player *p); 455 456 void player_list_sobjmem(player *p); 457 void player_sobject_forget(player *p, position pos); 458 459 /** 460 * @brief Check for adjacent monsters. 461 * 462 * @param The player. 463 * @param TRUE if harmless monsters shall be ignored. 464 * 465 * @return TRUE if there are adjacent monsters. 466 */ 467 gboolean player_adjacent_monster(player *p, gboolean ignore_harmless); 468 469 /* fighting simulation */ 470 void calc_fighting_stats(player *p); 471 472 /* macros */ 473 474 #define player_memory_of(p,pos) ((p)->memory[Z(pos)][Y(pos)][X(pos)]) 475 476 #endif 477