-
Notifications
You must be signed in to change notification settings - Fork 248
/
character.h
2288 lines (2024 loc) · 101 KB
/
character.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#pragma once
#ifndef CATA_SRC_CHARACTER_H
#define CATA_SRC_CHARACTER_H
#include <array>
#include <bitset>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "action.h"
#include "bodypart.h"
#include "calendar.h"
#include "cata_utility.h"
#include "character_id.h"
#include "character_martial_arts.h"
#include "color.h"
#include "creature.h"
#include "cursesdef.h"
#include "damage.h"
#include "enums.h"
#include "flat_set.h"
#include "game_constants.h"
#include "inventory.h"
#include "item.h"
#include "item_location.h"
#include "magic.h"
#include "magic_enchantment.h"
#include "memory_fast.h"
#include "monster.h"
#include "mtype.h"
#include "optional.h"
#include "pimpl.h"
#include "player_activity.h"
#include "pldata.h"
#include "point.h"
#include "ret_val.h"
#include "stomach.h"
#include "string_formatter.h"
#include "type_id.h"
#include "units.h"
#include "visitable.h"
#include "weighted_list.h"
class JsonIn;
class JsonObject;
class JsonOut;
class SkillLevel;
class SkillLevelMap;
class bionic_collection;
class faction;
class ma_technique;
class player;
class player_morale;
class vehicle;
struct bionic;
struct construction;
struct dealt_projectile_attack;
struct islot_comestible;
struct itype;
struct mutation_branch;
struct needs_rates;
struct pathfinding_settings;
struct points_left;
struct trap;
template <typename E> struct enum_traits;
using drop_location = std::pair<item_location, int>;
using drop_locations = std::list<drop_location>;
#define MAX_CLAIRVOYANCE 40
enum vision_modes {
DEBUG_NIGHTVISION,
NV_GOGGLES,
NIGHTVISION_1,
NIGHTVISION_2,
NIGHTVISION_3,
FULL_ELFA_VISION,
ELFA_VISION,
CEPH_VISION,
FELINE_VISION,
BIRD_EYE,
URSINE_VISION,
BOOMERED,
DARKNESS,
IR_VISION,
VISION_CLAIRVOYANCE,
VISION_CLAIRVOYANCE_PLUS,
VISION_CLAIRVOYANCE_SUPER,
NUM_VISION_MODES
};
enum character_movemode : int {
CMM_WALK = 0,
CMM_RUN,
CMM_CROUCH,
CMM_COUNT
};
template<>
struct enum_traits<character_movemode> {
static constexpr auto last = character_movemode::CMM_COUNT;
};
enum fatigue_levels {
TIRED = 191,
DEAD_TIRED = 383,
EXHAUSTED = 575,
MASSIVE_FATIGUE = 1000
};
const std::unordered_map<std::string, fatigue_levels> fatigue_level_strs = { {
{ "TIRED", TIRED },
{ "DEAD_TIRED", DEAD_TIRED },
{ "EXHAUSTED", EXHAUSTED },
{ "MASSIVE_FATIGUE", MASSIVE_FATIGUE }
}
};
// Sleep deprivation is defined in minutes, and although most calculations scale linearly,
// maluses are bestowed only upon reaching the tiers defined below.
enum sleep_deprivation_levels {
SLEEP_DEPRIVATION_HARMLESS = 2 * 24 * 60,
SLEEP_DEPRIVATION_MINOR = 4 * 24 * 60,
SLEEP_DEPRIVATION_SERIOUS = 7 * 24 * 60,
SLEEP_DEPRIVATION_MAJOR = 10 * 24 * 60,
SLEEP_DEPRIVATION_MASSIVE = 14 * 24 * 60
};
// This tries to represent both rating and
// character's decision to respect said rating
enum class edible_rating {
// Edible or we pretend it is
edible,
// Not food at all
inedible,
// Not food because mutated mouth/system
inedible_mutation,
// You can eat it, but it will hurt morale
allergy,
// Smaller allergy penalty
allergy_weak,
// Cannibalism (unless psycho/cannibal)
cannibalism,
// Rotten or not rotten enough (for saprophages)
rotten,
// Can provoke vomiting if you already feel nauseous.
nausea,
// We did overeat, cramming more will surely cause vomiting.
bloated,
// We can eat this, but we'll overeat
too_full,
// Some weird stuff that requires a tool we don't have
no_tool
};
enum class rechargeable_cbm {
none = 0,
reactor,
furnace,
other
};
struct layer_details {
std::vector<int> pieces;
int max = 0;
int total = 0;
void reset();
int layer( int encumbrance );
bool operator ==( const layer_details &rhs ) const {
return max == rhs.max &&
total == rhs.total &&
pieces == rhs.pieces;
}
};
struct encumbrance_data {
int encumbrance = 0;
int armor_encumbrance = 0;
int layer_penalty = 0;
std::array<layer_details, static_cast<size_t>( layer_level::MAX_CLOTHING_LAYER )>
layer_penalty_details;
void layer( const layer_level level, const int encumbrance ) {
layer_penalty += layer_penalty_details[static_cast<size_t>( level )].layer( encumbrance );
}
void reset() {
*this = encumbrance_data();
}
bool operator ==( const encumbrance_data &rhs ) const {
return encumbrance == rhs.encumbrance &&
armor_encumbrance == rhs.armor_encumbrance &&
layer_penalty == rhs.layer_penalty &&
layer_penalty_details == rhs.layer_penalty_details;
}
};
struct aim_type {
std::string name;
std::string action;
std::string help;
bool has_threshold;
int threshold;
};
struct special_attack {
std::string text;
damage_instance damage;
};
struct social_modifiers {
int lie = 0;
int persuade = 0;
int intimidate = 0;
social_modifiers &operator+=( const social_modifiers &other ) {
this->lie += other.lie;
this->persuade += other.persuade;
this->intimidate += other.intimidate;
return *this;
}
};
struct consumption_event {
time_point time;
itype_id type_id;
uint64_t component_hash;
consumption_event() = default;
consumption_event( const item &food ) : time( calendar::turn ) {
type_id = food.typeId();
component_hash = food.make_component_hash();
}
void serialize( JsonOut &json ) const;
void deserialize( JsonIn &jsin );
};
inline social_modifiers operator+( social_modifiers lhs, const social_modifiers &rhs )
{
lhs += rhs;
return lhs;
}
class Character : public Creature, public visitable<Character>
{
public:
Character( const Character & ) = delete;
Character &operator=( const Character & ) = delete;
~Character() override;
Character *as_character() override {
return this;
}
const Character *as_character() const override {
return this;
}
character_id getID() const;
// sets the ID, will *only* succeed when the current id is not valid
// allows forcing a -1 id which is required for templates to not throw errors
void setID( character_id i, bool force = false );
field_type_id bloodType() const override;
field_type_id gibType() const override;
bool is_warm() const override;
bool in_species( const species_id &spec ) const override;
// Turned to false for simulating NPCs on distant missions so they don't drop all their gear in sight
bool death_drops;
const std::string &symbol() const override;
enum class comfort_level {
impossible = -999,
uncomfortable = -7,
neutral = 0,
slightly_comfortable = 3,
comfortable = 5,
very_comfortable = 10
};
enum stat {
STRENGTH,
DEXTERITY,
INTELLIGENCE,
PERCEPTION,
DUMMY_STAT
};
// Character stats
// TODO: Make those protected
int str_max;
int dex_max;
int int_max;
int per_max;
int str_cur;
int dex_cur;
int int_cur;
int per_cur;
// The prevalence of getter, setter, and mutator functions here is partially
// a result of the slow, piece-wise migration of the player class upwards into
// the character class. As enough logic is moved upwards to fully separate
// utility upwards out of the player class, as many of these as possible should
// be eliminated to allow for proper code separation. (Note: Not "all", many").
/** Getters for stats exclusive to characters */
virtual int get_str() const;
virtual int get_dex() const;
virtual int get_per() const;
virtual int get_int() const;
virtual int get_str_base() const;
virtual int get_dex_base() const;
virtual int get_per_base() const;
virtual int get_int_base() const;
virtual int get_str_bonus() const;
virtual int get_dex_bonus() const;
virtual int get_per_bonus() const;
virtual int get_int_bonus() const;
int get_speed() const override;
// Penalty modifiers applied for ranged attacks due to low stats
virtual int ranged_dex_mod() const;
virtual int ranged_per_mod() const;
/** Setters for stats exclusive to characters */
virtual void set_str_bonus( int nstr );
virtual void set_dex_bonus( int ndex );
virtual void set_per_bonus( int nper );
virtual void set_int_bonus( int nint );
virtual void mod_str_bonus( int nstr );
virtual void mod_dex_bonus( int ndex );
virtual void mod_per_bonus( int nper );
virtual void mod_int_bonus( int nint );
// Prints message(s) about current health
void print_health() const;
/** Getters for health values exclusive to characters */
virtual int get_healthy() const;
virtual int get_healthy_mod() const;
/** Modifiers for health values exclusive to characters */
virtual void mod_healthy( int nhealthy );
virtual void mod_healthy_mod( int nhealthy_mod, int cap );
/** Setters for health values exclusive to characters */
virtual void set_healthy( int nhealthy );
virtual void set_healthy_mod( int nhealthy_mod );
/** Getter for need values exclusive to characters */
int get_stored_kcal() const;
int get_healthy_kcal() const;
// Maximum stored calories, excluding stomach.
// If more would be digested, it is instead wasted.
int max_stored_calories() const;
float get_kcal_percent() const;
float get_hunger() const;
int get_thirst() const;
std::pair<std::string, nc_color> get_thirst_description() const;
std::pair<std::string, nc_color> get_hunger_description() const;
std::pair<std::string, nc_color> get_fatigue_description() const;
int get_fatigue() const;
int get_sleep_deprivation() const;
std::pair<std::string, nc_color> get_pain_description() const override;
/** Modifiers for need values exclusive to characters */
virtual void mod_stored_kcal( int nkcal );
virtual void mod_stored_nutr( int nnutr );
virtual void mod_hunger( float nhunger );
virtual void mod_thirst( int nthirst );
virtual void mod_fatigue( int nfatigue );
virtual void mod_sleep_deprivation( int nsleep_deprivation );
/** Setters for need values exclusive to characters */
virtual void set_stored_kcal( int kcal );
virtual void set_hunger( float nhunger );
virtual void set_thirst( int nthirst );
virtual void set_fatigue( int nfatigue );
virtual void set_sleep_deprivation( int nsleep_deprivation );
void mod_stat( const std::string &stat, float modifier ) override;
/** Get size class of character **/
m_size get_size() const override;
/** Returns either "you" or the player's name. capitalize_first assumes
that the character's name is already upper case and uses it only for
possessive "your" and "you"
**/
std::string disp_name( bool possessive = false, bool capitalize_first = false ) const override;
/** Returns the name of the player's outer layer, e.g. "armor plates" */
std::string skin_name() const override;
/* returns the character's faction */
virtual faction *get_faction() const {
return nullptr;
}
void set_fac_id( const std::string &my_fac_id );
/* Adjusts provided sight dispersion to account for player stats */
int effective_dispersion( int dispersion ) const;
/* Accessors for aspects of aim speed. */
std::vector<aim_type> get_aim_types( const item &gun ) const;
std::pair<int, int> get_fastest_sight( const item &gun, double recoil ) const;
int get_most_accurate_sight( const item &gun ) const;
double aim_speed_skill_modifier( const skill_id &gun_skill ) const;
double aim_speed_dex_modifier() const;
double aim_speed_encumbrance_modifier() const;
double aim_cap_from_volume( const item &gun ) const;
/* Calculate aim improvement per move spent aiming at a given @ref recoil */
double aim_per_move( const item &gun, double recoil ) const;
/** Combat getters */
float get_dodge_base() const override;
float get_hit_base() const override;
const tripoint &pos() const override;
/** Returns the player's sight range */
int sight_range( int light_level ) const override;
/** Returns the player maximum vision range factoring in mutations, diseases, and other effects */
int unimpaired_range() const;
/** Returns true if overmap tile is within player line-of-sight */
bool overmap_los( const tripoint &omt, int sight_points );
/** Returns the distance the player can see on the overmap */
int overmap_sight_range( int light_level ) const;
/** Returns the distance the player can see through walls */
int clairvoyance() const;
/** Returns true if the player has some form of impaired sight */
bool sight_impaired() const;
/** Returns true if the player or their vehicle has an alarm clock */
bool has_alarm_clock() const;
/** Returns true if the player or their vehicle has a watch */
bool has_watch() const;
/** Called after every action, invalidates player caches */
void action_taken();
/** Returns true if the player is knocked over or has broken legs */
bool is_on_ground() const override;
/** Returns the player's speed for swimming across water tiles */
int swim_speed() const;
/**
* Adds a reason for why the player would miss a melee attack.
*
* To possibly be messaged to the player when he misses a melee attack.
* @param reason A message for the player that gives a reason for him missing.
* @param weight The weight used when choosing what reason to pick when the
* player misses.
*/
void add_miss_reason( const std::string &reason, unsigned int weight );
/** Clears the list of reasons for why the player would miss a melee attack. */
void clear_miss_reasons();
/**
* Returns an explanation for why the player would miss a melee attack.
*/
std::string get_miss_reason();
/**
* Handles passive regeneration of pain and maybe hp.
*/
void regen( int rate_multiplier );
// called once per 24 hours to enforce the minimum of 1 hp healed per day
// TODO: Move to Character once heal() is moved
void enforce_minimum_healing();
/** get best quality item that this character has */
item *best_quality_item( const quality_id &qual );
/** Handles health fluctuations over time */
virtual void update_health( int external_modifiers = 0 );
/** Updates all "biology" by one turn. Should be called once every turn. */
void update_body();
/** Updates all "biology" as if time between `from` and `to` passed. */
void update_body( const time_point &from, const time_point &to );
/** Updates the stomach to give accurate hunger messages */
void update_stomach( const time_point &from, const time_point &to );
/** Increases hunger, thirst, fatigue and stimulants wearing off. `rate_multiplier` is for retroactive updates. */
void update_needs( int rate_multiplier );
needs_rates calc_needs_rates() const;
/** Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings. */
void check_needs_extremes();
/** Returns if the player has hibernation mutation and is asleep and well fed */
bool is_hibernating() const;
/** Maintains body temperature */
void update_bodytemp();
/** Equalizes heat between body parts */
void temp_equalizer( body_part bp1, body_part bp2 );
struct comfort_response_t {
comfort_level level = comfort_level::neutral;
const item *aid = nullptr;
};
/** Rate point's ability to serve as a bed. Only takes certain mutations into account, and not fatigue nor stimulants. */
comfort_response_t base_comfort_value( const tripoint &p ) const;
/** Define blood loss (in percents) */
int blood_loss( body_part bp ) const;
/** Resets the value of all bonus fields to 0. */
void reset_bonuses() override;
/** Resets stats, and applies effects in an idempotent manner */
void reset_stats() override;
/** Handles stat and bonus reset. */
void reset() override;
/** Recalculates encumbrance cache. */
void reset_encumbrance();
/** Returns ENC provided by armor, etc. */
int encumb( body_part bp ) const;
/** Returns body weight plus weight of inventory and worn/wielded items */
units::mass get_weight() const override;
/** Get encumbrance for all body parts. */
std::array<encumbrance_data, num_bp> get_encumbrance() const;
/** Get encumbrance for all body parts as if `new_item` was also worn. */
std::array<encumbrance_data, num_bp> get_encumbrance( const item &new_item ) const;
/** Get encumbrance penalty per layer & body part */
int extraEncumbrance( layer_level level, int bp ) const;
/** Returns true if the character is wearing power armor */
bool is_wearing_power_armor( bool *hasHelmet = nullptr ) const;
/** Returns true if the character is wearing active power */
bool is_wearing_active_power_armor() const;
/** Returns true if the player is wearing an active optical cloak */
bool is_wearing_active_optcloak() const;
/** Returns true if the player is in a climate controlled area or armor */
bool in_climate_control();
/** Returns wind resistance provided by armor, etc **/
int get_wind_resistance( body_part bp ) const;
/** Returns true if the player isn't able to see */
bool is_blind() const;
bool is_invisible() const;
/** Checks is_invisible() as well as other factors */
int visibility( bool check_color = false, int stillness = 0 ) const;
/** Returns character luminosity based on the brightest active item they are carrying */
float active_light() const;
bool sees_with_specials( const Creature &critter ) const;
/** Bitset of all the body parts covered only with items with `flag` (or nothing) */
body_part_set exclusive_flag_coverage( const std::string &flag ) const;
/** Processes effects which may prevent the Character from moving (bear traps, crushed, etc.).
* Returns false if movement is stopped. */
bool move_effects( bool attacking ) override;
/** Check against the character's current movement mode */
bool movement_mode_is( character_movemode mode ) const;
character_movemode get_movement_mode() const;
virtual void set_movement_mode( character_movemode mode ) = 0;
/** Performs any Character-specific modifications to the arguments before passing to Creature::add_effect(). */
void add_effect( const efftype_id &eff_id, const time_duration &dur, body_part bp = num_bp,
bool permanent = false,
int intensity = 0, bool force = false, bool deferred = false ) override;
/**Determine if character is susceptible to dis_type and if so apply the symptoms*/
void expose_to_disease( diseasetype_id dis_type );
/**
* Handles end-of-turn processing.
*/
void process_turn() override;
/** Recalculates HP after a change to max strength */
void recalc_hp();
/** Modifies the player's sight values
* Must be called when any of the following change:
* This must be called when any of the following change:
* - effects
* - bionics
* - traits
* - underwater
* - clothes
*/
void recalc_sight_limits();
/**
* Returns the apparent light level at which the player can see.
* This is adjusted by the light level at the *character's* position
* to simulate glare, etc, night vision only works if you are in the dark.
*/
float get_vision_threshold( float light_level ) const;
/**
* Flag encumbrance for updating.
*/
void flag_encumbrance();
/**
* Checks worn items for the "RESET_ENCUMBRANCE" flag, which indicates
* that encumbrance may have changed and require recalculating.
*/
void check_item_encumbrance_flag();
/** Returns true if the character is wearing something on the entered body_part, ignoring items with the ALLOWS_NATURAL_ATTACKS flag */
bool natural_attack_restricted_on( body_part bp ) const;
int blocks_left;
int dodges_left;
double recoil = MAX_RECOIL;
/** Returns true if the player is able to use a miss recovery technique */
bool can_miss_recovery( const item &weap ) const;
/** Returns true if the player has quiet melee attacks */
bool is_quiet() const;
// melee.cpp
/** Checks for valid block abilities and reduces damage accordingly. Returns true if the player blocks */
bool block_hit( Creature *source, body_part &bp_hit, damage_instance &dam ) override;
/** Returns the best item for blocking with */
item &best_shield();
/** Calculates melee weapon wear-and-tear through use, returns true if item is destroyed. */
bool handle_melee_wear( item &shield, float wear_multiplier = 1.0f );
/** Returns a random valid technique */
matec_id pick_technique( Creature &t, const item &weap,
bool crit, bool dodge_counter, bool block_counter );
void perform_technique( const ma_technique &technique, Creature &t, damage_instance &di,
int &move_cost );
/**
* Sets up a melee attack and handles melee attack function calls
* @param t Creature to attack
* @param allow_special whether non-forced martial art technique or mutation attack should be
* possible with this attack.
* @param force_technique special technique to use in attack.
* @param allow_unarmed always uses the wielded weapon regardless of martialarts style
*/
void melee_attack( Creature &t, bool allow_special, const matec_id &force_technique,
bool allow_unarmed = true );
/**
* Calls the to other melee_attack function with an empty technique id (meaning no specific
* technique should be used).
*/
void melee_attack( Creature &t, bool allow_special );
/** Handles combat effects, returns a string of any valid combat effect messages */
std::string melee_special_effects( Creature &t, damage_instance &d, item &weap );
/** Performs special attacks and their effects (poisonous, stinger, etc.) */
void perform_special_attacks( Creature &t, dealt_damage_instance &dealt_dam );
bool reach_attacking = false;
/** Returns a vector of valid mutation attacks */
std::vector<special_attack> mutation_attacks( Creature &t ) const;
/** Returns the bonus bashing damage the player deals based on their stats */
float bonus_damage( bool random ) const;
/** Returns weapon skill */
float get_melee_hit_base() const;
/** Returns the player's basic hit roll that is compared to the target's dodge roll */
float hit_roll() const override;
/** Returns the chance to critical given a hit roll and target's dodge roll */
double crit_chance( float roll_hit, float target_dodge, const item &weap ) const;
/** Returns true if the player scores a critical hit */
bool scored_crit( float target_dodge, const item &weap ) const;
/** Returns cost (in moves) of attacking with given item (no modifiers, like stuck) */
int attack_speed( const item &weap ) const;
/** Gets melee accuracy component from weapon+skills */
float get_hit_weapon( const item &weap ) const;
// If average == true, adds expected values of random rolls instead of rolling.
/** Adds all 3 types of physical damage to instance */
void roll_all_damage( bool crit, damage_instance &di, bool average, const item &weap ) const;
/** Adds player's total bash damage to the damage instance */
void roll_bash_damage( bool crit, damage_instance &di, bool average, const item &weap ) const;
/** Adds player's total cut damage to the damage instance */
void roll_cut_damage( bool crit, damage_instance &di, bool average, const item &weap ) const;
/** Adds player's total stab damage to the damage instance */
void roll_stab_damage( bool crit, damage_instance &di, bool average, const item &weap ) const;
private:
/** Check if an area-of-effect technique has valid targets */
bool valid_aoe_technique( Creature &t, const ma_technique &technique );
bool valid_aoe_technique( Creature &t, const ma_technique &technique,
std::vector<Creature *> &targets );
public:
// any side effects that might happen when the Character is hit
void on_hit( Creature *source, bodypart_id /*bp_hit*/,
float /*difficulty*/, dealt_projectile_attack const * /*proj*/ ) override;
// any side effects that might happen when the Character hits a Creature
void did_hit( Creature &target );
/** Actually hurt the player, hurts a body_part directly, no armor reduction */
void apply_damage( Creature *source, bodypart_id hurt, int dam,
bool bypass_med = false ) override;
/** Calls Creature::deal_damage and handles damaged effects (waking up, etc.) */
dealt_damage_instance deal_damage( Creature *source, bodypart_id bp,
const damage_instance &d ) override;
/** Reduce healing effect intensity, return initial intensity of the effect */
int reduce_healing_effect( const efftype_id &eff_id, int remove_med, body_part hurt );
void cough( bool harmful = false, int loudness = 4 );
/**
* Check for relevant passive, non-clothing that can absorb damage, and reduce by specified
* damage unit. Only flat bonuses are checked here. Multiplicative ones are checked in
* @ref player::absorb_hit. The damage amount will never be reduced to less than 0.
* This is called from @ref player::absorb_hit
*/
void passive_absorb_hit( body_part bp, damage_unit &du ) const;
/** Runs through all bionics and armor on a part and reduces damage through their armor_absorb */
void absorb_hit( body_part bp, damage_instance &dam ) override;
/**
* Reduces and mutates du, prints messages about armor taking damage.
* @return true if the armor was completely destroyed (and the item must be deleted).
*/
bool armor_absorb( damage_unit &du, item &armor );
/**
* Check for passive bionics that provide armor, and returns the armor bonus
* This is called from player::passive_absorb_hit
*/
float bionic_armor_bonus( body_part bp, damage_type dt ) const;
/** Returns the armor bonus against given type from martial arts buffs */
int mabuff_armor_bonus( damage_type type ) const;
/** Returns overall fire resistance for the body part */
int get_armor_fire( body_part bp ) const;
// --------------- Mutation Stuff ---------------
// In newcharacter.cpp
/** Returns the id of a random starting trait that costs >= 0 points */
trait_id random_good_trait();
/** Returns the id of a random starting trait that costs < 0 points */
trait_id random_bad_trait();
// In mutation.cpp
/** Returns true if the player has the entered trait */
bool has_trait( const trait_id &b ) const override;
/** Returns true if the player has the entered starting trait */
bool has_base_trait( const trait_id &b ) const;
/** Returns true if player has a trait with a flag */
bool has_trait_flag( const std::string &b ) const;
/** Returns the trait id with the given invlet, or an empty string if no trait has that invlet */
trait_id trait_by_invlet( int ch ) const;
/** Toggles a trait on the player and in their mutation list */
void toggle_trait( const trait_id & );
/** Add or removes a mutation on the player, but does not trigger mutation loss/gain effects. */
void set_mutation( const trait_id & );
void unset_mutation( const trait_id & );
/**Unset switched mutation and set target mutation instead*/
void switch_mutations( const trait_id &switched, const trait_id &target, bool start_powered );
// Trigger and disable mutations that can be so toggled.
void activate_mutation( const trait_id &mutation );
void deactivate_mutation( const trait_id &mut );
/** Converts a body_part to an hp_part */
static hp_part bp_to_hp( body_part bp );
/** Converts an hp_part to a body_part */
static body_part hp_to_bp( hp_part hpart );
bool can_mount( const monster &critter ) const;
void mount_creature( monster &z );
bool is_mounted() const;
bool check_mount_will_move( const tripoint &dest_loc );
bool check_mount_is_spooked();
void dismount();
void forced_dismount();
bool is_deaf() const;
/** Returns true if the player has two functioning arms */
bool has_two_arms() const;
/** Returns the number of functioning arms */
int get_working_arm_count() const;
/** Returns the number of functioning legs */
int get_working_leg_count() const;
/** Returns true if the limb is disabled(12.5% or less hp)*/
bool is_limb_disabled( hp_part limb ) const;
/** Returns true if the limb is hindered(40% or less hp) */
bool is_limb_hindered( hp_part limb ) const;
/** Returns true if the limb is broken */
bool is_limb_broken( hp_part limb ) const;
/** source of truth of whether a Character can run */
bool can_run();
/** Hurts all body parts for dam, no armor reduction */
void hurtall( int dam, Creature *source, bool disturb = true );
/** Harms all body parts for dam, with armor reduction. If vary > 0 damage to parts are random within vary % (1-100) */
int hitall( int dam, int vary, Creature *source );
/** Handles effects that happen when the player is damaged and aware of the fact. */
void on_hurt( Creature *source, bool disturb = true );
/** Heals a body_part for dam */
void heal( body_part healed, int dam );
/** Heals an hp_part for dam */
void heal( hp_part healed, int dam );
/** Heals all body parts for dam */
void healall( int dam );
/**
* Displays menu with body part hp, optionally with hp estimation after healing.
* Returns selected part.
* menu_header - name of item that triggers this menu
* show_all - show and enable choice of all limbs, not only healable
* precise - show numerical hp
* normal_bonus - heal normal limb
* head_bonus - heal head
* torso_bonus - heal torso
* bleed - chance to stop bleeding
* bite - chance to remove bite
* infect - chance to remove infection
* bandage_power - quality of bandage
* disinfectant_power - quality of disinfectant
*/
hp_part body_window( const std::string &menu_header,
bool show_all, bool precise,
int normal_bonus, int head_bonus, int torso_bonus,
float bleed, float bite, float infect, float bandage_power, float disinfectant_power ) const;
// Returns color which this limb would have in healing menus
nc_color limb_color( body_part bp, bool bleed, bool bite, bool infect ) const;
static const std::vector<material_id> fleshy;
bool made_of( const material_id &m ) const override;
bool made_of_any( const std::set<material_id> &ms ) const override;
// Drench cache
enum water_tolerance {
WT_IGNORED = 0,
WT_NEUTRAL,
WT_GOOD,
NUM_WATER_TOLERANCE
};
inline int posx() const override {
return position.x;
}
inline int posy() const override {
return position.y;
}
inline int posz() const override {
return position.z;
}
inline void setx( int x ) {
setpos( tripoint( x, position.y, position.z ) );
}
inline void sety( int y ) {
setpos( tripoint( position.x, y, position.z ) );
}
inline void setz( int z ) {
setpos( tripoint( position.xy(), z ) );
}
inline void setpos( const tripoint &p ) override {
position = p;
}
/**
* Global position, expressed in map square coordinate system
* (the most detailed coordinate system), used by the @ref map.
*/
virtual tripoint global_square_location() const;
/**
* Returns the location of the player in global submap coordinates.
*/
tripoint global_sm_location() const;
/**
* Returns the location of the player in global overmap terrain coordinates.
*/
tripoint global_omt_location() const;
private:
/** Retrieves a stat mod of a mutation. */
int get_mod( const trait_id &mut, const std::string &arg ) const;
/** Applies skill-based boosts to stats **/
void apply_skill_boost();
protected:
void do_skill_rust();
/** Applies stat mods to character. */
void apply_mods( const trait_id &mut, bool add_remove );
/** Recalculate encumbrance for all body parts. */
std::array<encumbrance_data, num_bp> calc_encumbrance() const;
/** Recalculate encumbrance for all body parts as if `new_item` was also worn. */
std::array<encumbrance_data, num_bp> calc_encumbrance( const item &new_item ) const;
/** Applies encumbrance from mutations and bionics only */
void mut_cbm_encumb( std::array<encumbrance_data, num_bp> &vals ) const;
/** Return the position in the worn list where new_item would be
* put by default */
std::list<item>::iterator position_to_wear_new_item( const item &new_item );
/** Applies encumbrance from items only
* If new_item is not null, then calculate under the asumption that it
* is added to existing work items. */
void item_encumb( std::array<encumbrance_data, num_bp> &vals,
const item &new_item ) const;
std::array<std::array<int, NUM_WATER_TOLERANCE>, num_bp> mut_drench;
public:
// recalculates enchantment cache by iterating through all held, worn, and wielded items
void recalculate_enchantment_cache();
// gets add and mult value from enchantment cache
double calculate_by_enchantment( double modify, enchantment::mod value,
bool round_output = false ) const;
/** Returns true if the player has any martial arts buffs attached */
bool has_mabuff( const mabuff_id &buff_id ) const;
/** Returns true if the player has a grab breaking technique available */
bool has_grab_break_tec() const override {
return martial_arts_data.has_grab_break_tec();
}
/** Returns the to hit bonus from martial arts buffs */
float mabuff_tohit_bonus() const;
/** Returns the dodge bonus from martial arts buffs */
float mabuff_dodge_bonus() const;
/** Returns the block bonus from martial arts buffs */
int mabuff_block_bonus() const;
/** Returns the speed bonus from martial arts buffs */
int mabuff_speed_bonus() const;
/** Returns the damage multiplier to given type from martial arts buffs */
float mabuff_damage_mult( damage_type type ) const;
/** Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier */
int mabuff_damage_bonus( damage_type type ) const;
/** Returns the flat penalty to move cost of attacks. If negative, that's a bonus. Applied after multiplier. */
int mabuff_attack_cost_penalty() const;
/** Returns the multiplier on move cost of attacks. */
float mabuff_attack_cost_mult() const;
/** Handles things like destruction of armor, etc. */
void mutation_effect( const trait_id &mut );
/** Handles what happens when you lose a mutation. */
void mutation_loss_effect( const trait_id &mut );
bool has_active_mutation( const trait_id &b ) const;
private:
// The old mutation algorithm
void old_mutate();
public:
/** Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way */
void mutate();
/** Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing */
bool mutation_ok( const trait_id &mutation, bool force_good, bool force_bad ) const;
/** Picks a random valid mutation in a category and mutate_towards() it */
void mutate_category( const std::string &mut_cat );
/** Mutates toward one of the given mutations, upgrading or removing conflicts if necessary */
bool mutate_towards( std::vector<trait_id> muts, int num_tries = INT_MAX );
/** Mutates toward the entered mutation, upgrading or removing conflicts if necessary */
bool mutate_towards( const trait_id &mut );
/** Removes a mutation, downgrading to the previous level if possible */
void remove_mutation( const trait_id &mut, bool silent = false );
/** Calculate percentage chances for mutations */
std::map<trait_id, float> mutation_chances() const;
/** Returns true if the player has the entered mutation child flag */
bool has_child_flag( const trait_id &flag ) const;
/** Removes the mutation's child flag from the player's list */
void remove_child_flag( const trait_id &flag );
/** Recalculates mutation_category_level[] values for the player */
void set_highest_cat_level();
/** Returns the highest mutation category */
std::string get_highest_category() const;
/** Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats) */
void drench_mut_calc();
/** Recursively traverses the mutation's prerequisites and replacements, building up a map */
void build_mut_dependency_map( const trait_id &mut,
std::unordered_map<trait_id, int> &dependency_map, int distance );
/**
* Returns true if this category of mutation is allowed.
*/
bool is_category_allowed( const std::vector<std::string> &category ) const;
bool is_category_allowed( const std::string &category ) const;
bool is_weak_to_water() const;
/**Check for mutation disallowing the use of an healing item*/
bool can_use_heal_item( const item &med ) const;
bool can_install_cbm_on_bp( const std::vector<body_part> &bps ) const;
/**
* Returns resistances on a body part provided by mutations
*/
// TODO: Cache this, it's kinda expensive to compute
resistances mutation_armor( body_part bp ) const;
float mutation_armor( body_part bp, damage_type dt ) const;
float mutation_armor( body_part bp, const damage_unit &du ) const;
// --------------- Bionic Stuff ---------------
/** Handles bionic activation effects of the entered bionic, returns if anything activated */
bool activate_bionic( int b, bool eff_only = false );
std::vector<bionic_id> get_bionics() const;
/** Returns amount of Storage CBMs in the corpse **/
std::pair<int, int> amount_of_storage_bionics() const;
/** Returns true if the player has the entered bionic id */