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