File: transform.h

package info (click to toggle)
crawl 2%3A0.33.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 95,264 kB
  • sloc: cpp: 358,145; ansic: 27,203; javascript: 9,491; python: 8,359; perl: 3,327; java: 2,667; xml: 2,191; makefile: 1,830; sh: 611; objc: 250; cs: 15; sed: 9; lisp: 3
file content (370 lines) | stat: -rw-r--r-- 12,714 bytes parent folder | download | duplicates (2)
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
/**
 * @file
 * @brief Misc function related to player transformations.
**/

#pragma once

#include <set>

#include "enum.h"
#include "player.h"

constexpr int DRAGON_CLAWS = 3;
constexpr int DRAGON_FANGS = 5;

#define FLUX_ENERGY_KEY "flux_energy"
constexpr int FLUX_ENERGY_WARNING = 10;

enum form_capability
{
    FC_DEFAULT,
    FC_ENABLE,
    FC_FORBID
};

class FormAttackVerbs
{
public:
    FormAttackVerbs(const char *_weak, const char *_medium,
                    const char *_strong, const char *_devastating)
        : weak(_weak), medium(_medium), strong(_strong),
          devastating(_devastating)
    { }

    FormAttackVerbs(const char *msg)
        : weak(msg), medium(msg), strong(msg), devastating(msg)
    { }

public:
    const char * const weak;
    const char * const medium;
    const char * const strong;
    const char * const devastating;
};

class FormScaling {
public:
    FormScaling() : base(0), scaling(0), xl_based(false) {}
    FormScaling& Base(int b) { base = b; return *this; }
    FormScaling& Scaling(int s) { scaling = s; return *this; }
    FormScaling& XLBased() { xl_based = true; return *this; }

    int base;      // value at 0 XL/skill (as applicable)
    int scaling;   // value added to base at max XL/skill
    bool xl_based; // if false, scale on Shapeshifting skill
};

struct form_entry; // defined in form-data.h (private)
class Form
{
private:
    Form() = delete;
    DISALLOW_COPY_AND_ASSIGN(Form);
    Form(const form_entry &fe);
protected:
    Form(transformation tran);
public:
    bool slot_is_blocked(equipment_slot slot) const;
    bool can_wield() const { return !slot_is_blocked(SLOT_WEAPON); }

    int get_level(int scale) const;

    int mult_hp(int base_hp, bool force_talisman = false, int skill = -1) const;

    /// Is the player below the minimum skill for this form?
    bool underskilled() const { return get_level(1) < min_skill; }

    /**
     * What monster corresponds to this form?
     *
     * Used for console player glyphs.
     *
     * @return The monster_type corresponding to this form.
     */
    virtual monster_type get_equivalent_mons() const { return equivalent_mons; }

    /**
     * A name for the form longer than that used by the status light.
     *
     * E.g. "foo-form", "blade tentacles", &c. Used for dumps, morgues &
     * the % screen.
     *
     * @return The 'long name' of the form.
     */
    virtual string get_long_name() const { return long_name; }

    /**
     * A description of this form.
     *
     * E.g. "a fearsome dragon!", punctuation included.
     *
     * Used for the @ screen and, by default, transformation messages.
     *
     * @return A description of the form.
     */
    virtual string get_transform_description() const { return description; }

    virtual string get_description(bool past_tense = false) const;
    virtual string transform_message() const;
    virtual string get_untransform_message() const;

    virtual int res_fire() const;
    virtual int res_cold() const;
    int res_neg() const;
    bool res_elec() const;
    int res_pois() const;
    bool res_rot() const;
    bool res_corr() const;
    bool res_miasma() const;
    bool res_petrify() const;

    /**
     * Base unarmed damage provided by the form.
     */
    int get_base_unarmed_damage(bool random = true, int skill = -1) const;

    /// Damage done by a custom aux attack of this form.
    virtual int get_aux_damage(bool /*random*/ = true,
                               int /*skill*/ = -1) const {
        return 0;
    }

    /// Does this form care about skill for UC damage and accuracy, or only XL?
    virtual bool get_unarmed_uses_skill() const { return !unarmed_bonus_dam.xl_based; }

    /**
     * The brand of this form's unarmed attacks (SPWPN_FREEZING, etc).
     */
    virtual brand_type get_uc_brand() const { return uc_brand; }

    virtual string get_uc_attack_name(string default_name) const;
    virtual int slay_bonus(bool /*random*/ = true, int /*skill*/ = -1) const { return 0; }
    virtual int will_bonus() const { return 0; };
    virtual int get_ac_bonus(int skill = -1) const;
    virtual int ev_bonus(int /*skill*/ = -1) const;
    virtual int get_body_ac_mult(int /*skill*/ = -1) const;
    virtual int get_vamp_chance(int /*skill*/ = -1) const { return 0; }
    virtual int get_web_chance(int /*skill*/ = -1) const {return 0; }
    virtual int regen_bonus(int /*skill*/ = -1) const {return 0; }
    virtual int mp_regen_bonus(int /*skill*/ = -1) const {return 0; }
    virtual int max_mp_bonus(int /*skill*/ = -1) const {return 0; }
    virtual dice_def get_special_damage(bool /*random*/ = true, int /*skill*/ = -1) const;

    // XXX: Werewolf-specific
    virtual int get_werefury_kill_bonus(int /*skill*/ = -1) const { return 0; }
    virtual int get_takedown_multiplier(int /*skill*/ = -1) const { return 0; }
    virtual int get_howl_power(int /*skill*/ = -1) const { return 0; }

    virtual int get_effect_size(int /*skill*/ = -1) const { return 0; }
    virtual int get_effect_chance(int /*skill*/ = -1) const { return 0; }

    bool enables_flight() const;
    bool forbids_flight() const;

    bool player_can_fly() const;
    bool player_can_swim() const;
    bool player_likes_water() const;
    bool can_offhand_punch() const;

    string player_prayer_action() const;
    string melding_description(bool itemized) const;

    virtual vector<pair<string, string>> get_fakemuts() const;
    virtual vector<pair<string, string>> get_bad_fakemuts() const;

public:
    /// Status light ("Foo"); "" for none
    const string short_name;
    /// "foo"; used for wizmode transformation dialogue
    const string wiz_name;

    /// The skill level below which the player gets HP penalties for using the form.
    const int min_skill;
    /// The skill level beyond which further skill provides no benefit.
    const int max_skill;

    /// flat str bonus
    const int str_mod;
    /// flat dex bonus
    const int dex_mod;

    /// base move speed
    const int base_move_speed;

    /// Equipment types unusable in this form.
    /** A bitfield representing a union of (1 << equipment_slot) values for
     * equipment slots that are melded in this form.
     */
    const int blocked_slots; // XX check enum size at compile time?
    /// size of the form
    const size_type size;

    /// can the player cast while in this form?
    const bool can_cast;

    /// colour of 'weapon' in UI
    const int uc_colour;
    /// a set of verbs to use based on damage done, when using UC in this form
    const FormAttackVerbs uc_attack_verbs;

    /// "Used to mark forms which keep most form-based mutations."
    const bool changes_anatomy;
    //
    const bool changes_substance;
    /// What does this form change the player's holiness to? (MH_NONE if it leaves it unchanged)
    /// Note that vampire is special-cased in player::holiness().
    const mon_holy_type holiness;

    /// Does this form have blood (used for sublimation and bloodsplatters)?
    const form_capability has_blood;
    /// Does this form have hair?
    const form_capability has_hair;
    /// Does this form have bones?
    const form_capability has_bones;
    /// Does this form have feet?
    const form_capability has_feet;
    /// Does this form have ears?
    const form_capability has_ears;

    /// what verb does the player use when shouting in this form?
    const string shout_verb;
    /// a flat bonus (or penalty) to shout volume
    const int shout_volume_modifier;

    /// The name of this form's hand-equivalents; "" defaults to species.
    const string hand_name;
    /// The name of this form's foot-equivalents; "" defaults to species.
    const string foot_name;
    /// The name of this form's flesh-equivalent; "" defaults to species.
    const string flesh_equivalent;

    /// Identifier for the meaning of the special dice for this form (for the
    /// form properties screen).
    const string special_dice_name;

protected:
    /// See Form::get_long_name().
    const string long_name;
    /// See Form::get_transform_description().
    const string description;

    /// Resistances granted by this form.
    /** A bitfield holding a union of mon_resist_flags for resists granted
     * by the form.
     */
    const int resists;

    /// bonuses to AC when in this form, potentially scaling with skill or XL
    const FormScaling ac;

    /// bonuses to EV when in this form, potentially scaling with skill or XL
    const FormScaling ev;

    /// mulplier to base body armour AC when in this form, potentially scaling with skill or XL
    const FormScaling body_ac_mult;

    /// See Form::get_base_unarmed_damage().
    const FormScaling unarmed_bonus_dam;

    vector<pair<string,string>> fakemuts;
    vector<pair<string,string>> badmuts;

    /// Calculate the given FormScaling for this form, multiplied by scale.
    int scaling_value(const FormScaling &sc, bool random,
                      int level = -1, int scale = 1) const;
    /// Calculate the given FormScaling for this form, with math internally multiplied by scale.
    int divided_scaling(const FormScaling &sc, bool random,
                        int level = -1, int scale = 1) const;

private:
    /// Can this form fly?
    /** Whether the form enables, forbids, or does nothing to the player's
     * ability to fly.
     */
    const form_capability can_fly;
    /// Can this form swim?
    /** Whether the form enables, forbids, or does nothing to the player's
     * ability to swim (traverse deep water).
     */
    const form_capability can_swim;

    const form_capability offhand_punch;

    /// See Form::get_uc_brand().
    const brand_type uc_brand;
    /// the name of the uc 'weapon' in the HUD; "" uses species defaults.
    const string uc_attack;

    /// Altar prayer action; "" uses defaults. See Form::player_prayer_action()
    const string prayer_action;

    /// See Form::get_equivalent_mons().
    const monster_type equivalent_mons;

    /// 100 * multiplier to hp/mhp (that is, 100 is base, 150 is 1.5x, etc)
    const int hp_mod;

    /// Calculator for form-specific 'special' damage done by this form (eg:
    /// Blinkbolt damage or Contam damage)
    const dam_deducer* special_dice;
};
const Form* get_form(transformation form = you.form);
const Form* cur_form(bool temp = true);

bool lifeless_prevents_form(transformation form = you.form);

bool form_can_wield(transformation form = you.form);
bool form_can_wear(transformation form = you.form);
bool form_can_fly(transformation form = you.form);
bool form_can_swim(transformation form = you.form);
bool form_changes_substance(transformation form = you.form);
bool form_changes_anatomy(transformation form = you.form);
bool form_has_blood(transformation form = you.form);
bool form_has_hair(transformation form = you.form);
bool form_has_bones(transformation form = you.form);
bool form_has_feet(transformation form = you.form);
bool form_has_ears(transformation form = you.form);

bool feat_dangerous_for_form(transformation which_trans,
                             dungeon_feature_type feat,
                             const item_def* talisman = nullptr);
bool transforming_is_unsafe(transformation which_trans);

string cant_transform_reason(transformation which_trans, bool involuntary = false,
                             bool temp = true);
bool check_transform_into(transformation which_trans, bool involuntary = false,
                          const item_def* talisman = nullptr);
bool transform(int dur, transformation which_trans, bool involuntary = false,
               bool using_talisman = false);

// skip_move: don't make player re-enter current cell
void untransform(bool skip_move = false, bool scale_hp = true,
                 bool preserve_equipment = false,
                 transformation new_form = transformation::none);

void unset_default_form();
void set_default_form(transformation t, const item_def *source);

void set_form(transformation which_trans, int dur, bool scale_hp = true);
void return_to_default_form(bool new_form = false);

monster_type transform_mons();
string blade_parts(bool terse = false);
const char* transform_name(transformation form = you.form);

void merfolk_check_swimming(dungeon_feature_type old_grid,
                            bool stepped = false);
void merfolk_start_swimming(bool step = false);
void merfolk_stop_swimming();

transformation form_for_talisman(const item_def &talisman);
void clear_form_info_on_exit();

void sphinx_notice_riddle_target(monster* mon);
void sphinx_check_riddle();

void sun_scarab_spawn_ember(bool first_time);
monster* get_solar_ember();

bool maw_growl_check(const monster* mon);