1 #pragma once 2 3 #include "util.h" 4 #include "unique_entity.h" 5 #include "position.h" 6 #include "sound.h" 7 8 #undef HUGE 9 10 RICH_ENUM(BodyPart, 11 HEAD, 12 TORSO, 13 ARM, 14 WING, 15 LEG, 16 BACK 17 ); 18 19 extern const char* getName(BodyPart); 20 21 class Attack; 22 struct AdjectiveInfo; 23 24 class Body { 25 public: 26 27 enum class Material { 28 FLESH, 29 SPIRIT, 30 FIRE, 31 WATER, 32 UNDEAD_FLESH, 33 BONE, 34 ROCK, 35 CLAY, 36 WOOD, 37 IRON, 38 LAVA, 39 }; 40 41 enum class Size { 42 SMALL, 43 MEDIUM, 44 LARGE, 45 HUGE 46 }; 47 48 static Body humanoid(Material, Size); 49 static Body humanoid(Size); 50 static Body nonHumanoid(Material, Size); 51 static Body nonHumanoid(Size); 52 static Body humanoidSpirit(Size); 53 static Body nonHumanoidSpirit(Size); 54 Body(bool humanoid, Material, Size); 55 56 Body& addWings(); 57 Body& setWeight(double); 58 Body& setBodyParts(const EnumMap<BodyPart, int>&); 59 Body& setHumanoidBodyParts(); 60 Body& setHorseBodyParts(); 61 Body& setBirdBodyParts(); 62 Body& setMinionFood(); 63 Body& setDeathSound(optional<SoundId>); 64 Body& setNoCarryLimit(); 65 Body& setDoesntEat(); 66 67 void affectPosition(Position); 68 69 bool takeDamage(const Attack&, WCreature, double damage); 70 71 bool tick(WConstCreature); 72 bool heal(WCreature, double amount); 73 bool affectByFire(WCreature, double amount); 74 bool isIntrinsicallyAffected(LastingEffect) const; 75 bool affectByPoisonGas(WCreature, double amount); 76 void affectByTorture(WCreature); 77 bool affectBySilver(WCreature); 78 bool affectByAcid(WCreature); 79 bool isKilledByBoulder() const; 80 bool canWade() const; 81 bool isMinionFood() const; 82 bool canCopulateWith() const; 83 bool canConsume() const; 84 bool isWounded() const; 85 bool isSeriouslyWounded() const; 86 double getHealth() const; 87 bool hasBrain() const; 88 bool needsToEat() const; 89 vector<PItem> getCorpseItem(const string& name, UniqueEntity<Creature>::Id); 90 91 vector<AttackLevel> getAttackLevels() const; 92 double modifyAttr(AttrType, double) const; 93 94 bool isCollapsed(WConstCreature) const; 95 int numGood(BodyPart) const; 96 int numLost(BodyPart) const; 97 int numBodyParts(BodyPart) const; 98 void getBadAdjectives(vector<AdjectiveInfo>&) const; 99 optional<Sound> getDeathSound() const; 100 void injureBodyPart(WCreature, BodyPart, bool drop); 101 102 void healBodyParts(WCreature, bool regrow); 103 int lostOrInjuredBodyParts() const; 104 bool canHeal() const; 105 bool isImmuneTo(LastingEffect effect) const; 106 bool hasHealth() const; 107 108 void consumeBodyParts(WCreature, const Body& other, vector<string>& adjectives); 109 110 bool isHumanoid() const; 111 string getDescription() const; 112 void updateViewObject(ViewObject&) const; 113 const optional<double>& getCarryLimit() const; 114 void bleed(WCreature, double amount); 115 116 bool isUndead() const; 117 double getBoulderDamage() const; 118 119 SERIALIZATION_DECL(Body); 120 121 private: 122 friend class Test; 123 BodyPart getBodyPart(AttackLevel attack, bool flying, bool collapsed) const; 124 BodyPart armOrWing() const; 125 int numInjured(BodyPart) const; 126 void clearInjured(BodyPart); 127 void clearLost(BodyPart); 128 void looseBodyPart(BodyPart); 129 void injureBodyPart(BodyPart); 130 void decreaseHealth(double amount); 131 bool isPartDamaged(BodyPart, double damage) const; 132 bool isCritical(BodyPart) const; 133 PItem getBodyPartItem(const string& creatureName, BodyPart); 134 string getMaterialAndSizeAdjectives() const; 135 bool fallsApartFromDamage() const; 136 bool SERIAL(xhumanoid); 137 Size SERIAL(size); 138 double SERIAL(weight); 139 EnumMap<BodyPart, int> SERIAL(bodyParts) = {{BodyPart::TORSO, 1}, {BodyPart::BACK, 1}}; 140 EnumMap<BodyPart, int> SERIAL(injuredBodyParts); 141 EnumMap<BodyPart, int> SERIAL(lostBodyParts); 142 Material SERIAL(material); 143 double SERIAL(health) = 1; 144 bool SERIAL(minionFood) = false; 145 optional<SoundId> SERIAL(deathSound); 146 optional<double> SERIAL(carryLimit); 147 bool SERIAL(doesntEat) = false; 148 }; 149 150