1 /*************************************************************************** 2 spell.h - Spell and magic school classes 3 ------------------- 4 begin : Sun Sep 28 2003 5 copyright : (C) 2003 by Gabor Torok 6 email : cctorok@yahoo.com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 #ifndef SPELL_H 18 #define SPELL_H 19 #pragma once 20 21 #include <map> 22 #include <string> 23 #include <vector> 24 #include "../storable.h" 25 #include "../util.h" 26 27 /// A dice. You know at least one belongs in every RPG. 28 class Dice { 29 private: 30 enum { S_SIZE = 80 }; 31 char s[ S_SIZE ]; 32 int count; 33 int sides; 34 int mod; 35 36 public: 37 Dice( char const* s ); 38 Dice( int count, int sides, int mod ); 39 ~Dice(); toString()40 inline char *toString() { 41 return s; 42 } roll()43 inline int roll() { 44 int n = 0; 45 for ( int i = 0; i < count; i++ ) { 46 n += Util::pickOne( 1, sides ); 47 } 48 return n + mod; 49 } getMax()50 inline int getMax() { 51 return count * sides + mod; 52 } getMin()53 inline int getMin() { 54 return count + mod; 55 } getCount()56 inline int getCount() { 57 return count; 58 } getSides()59 inline int getSides() { 60 return sides; 61 } getMod()62 inline int getMod() { 63 return mod; 64 } 65 }; 66 67 class MagicSchool; 68 69 /// A magical spell. 70 class Spell : public Storable { 71 private: 72 std::string name; 73 std::string displayName; 74 std::string sound; 75 int level; 76 int mp; 77 int exp; 78 int failureRate; 79 Dice action; 80 int distance; 81 int targetType; 82 char notes[1000]; 83 int speed; 84 int effect; 85 MagicSchool *school; 86 bool creatureTarget, locationTarget, itemTarget, partyTarget, doorTarget; 87 int iconTileX, iconTileY; 88 bool friendly; 89 int stateModPrereq; 90 std::string symbol; 91 92 static std::map<std::string, Spell*> spellMap; 93 94 public: 95 96 Spell( char const* name, char const* displayName, char const* symbol, int level, int mp, int exp, int failureRate, char const* action, 97 int distance, int targetType, int speed, int effect, bool creatureTarget, 98 bool locationTarget, bool itemTarget, bool partyTarget, bool doorTarget, 99 MagicSchool *school, 100 int iconTileX, int iconTileY, bool friendly, int stateModPrereq ); 101 ~Spell(); 102 103 /// The "symbol" of the spell (used in various descriptions). getSymbol()104 inline char const* getSymbol() { 105 return symbol.c_str(); 106 } getStorableType()107 inline int getStorableType() { 108 return Storable::SPELL_STORABLE; 109 } isStorable()110 inline const char *isStorable() { 111 return NULL; 112 } 113 114 /// Is it for friendly or hostile targets? isFriendly()115 inline bool isFriendly() { 116 return friendly; 117 } 118 /// Does it affect a state mod? hasStateModPrereq()119 inline bool hasStateModPrereq() { 120 return( stateModPrereq != -1 ); 121 } 122 /// Which state mod/potion skill is affected? getStateModPrereq()123 inline int getStateModPrereq() { 124 return( stateModPrereq < -1 ? 125 ( -stateModPrereq ) - 2 : // potion skill 126 stateModPrereq ); // regular state mod 127 } 128 /// Does it affect a "potion skill" (HP, MP, armor)? isStateModPrereqAPotionSkill()129 inline bool isStateModPrereqAPotionSkill() { 130 return( stateModPrereq < -1 ); 131 } 132 /// Icon tile within spells.png. getIconTileX()133 inline int getIconTileX() { 134 return iconTileX; 135 } 136 /// Icon tile within spells.png. getIconTileY()137 inline int getIconTileY() { 138 return iconTileY; 139 } 140 /// Unlocalized internal name of the spell. getName()141 inline const char *getName() { 142 return name.c_str(); 143 } 144 /// Localized name of the spell. getDisplayName()145 inline const char *getDisplayName() { 146 return displayName.c_str(); 147 } 148 /// Returns a damage roll (without further modifiers). getAction()149 inline int getAction() { 150 return action.roll(); 151 } 152 153 void getAttack( int casterLevel, float *maxP, float *minP ); 154 155 /// The spell's level. getLevel()156 inline int getLevel() { 157 return level; 158 } 159 /// Magic point cost. getMp()160 inline int getMp() { 161 return mp; 162 } 163 /// Experience gained by successfully casting the spell. getExp()164 inline int getExp() { 165 return exp; 166 } 167 /// Probability of failure. getFailureRate()168 inline int getFailureRate() { 169 return failureRate; 170 } 171 /// Action radius of the spell. getDistance()172 inline int getDistance() { 173 return distance; 174 } 175 /// Which type of target is allowed? getTargetType()176 inline int getTargetType() { 177 return targetType; 178 } 179 /// The spell's long description. getNotes()180 inline char const* getNotes() { 181 return notes; 182 } 183 /// How fast can it be cast? getSpeed()184 inline int getSpeed() { 185 return speed; 186 } 187 /// The visual effect displayed for the spell. getEffect()188 inline int getEffect() { 189 return effect; 190 } 191 /// The spell's magic school. getSchool()192 inline MagicSchool *getSchool() { 193 return school; 194 } 195 /// Unused. isRangedSpell()196 inline bool isRangedSpell() { 197 return distance > 1; 198 } 199 /// Short one-line description of the spell. describe(char * s,size_t count)200 inline void describe( char *s, size_t count ) { 201 snprintf( s, count, _( "%s (L:%d)(M:%d)" ), displayName.c_str(), level, mp ); 202 } 203 /// Adds a string to the long description. addNotes(char * s)204 inline void addNotes( char *s ) { 205 strcat( notes, s ); 206 } 207 /// The sound to play when the spell is cast. setSound(char const * s)208 inline void setSound( char const* s ) { 209 sound = s; 210 } getSound()211 inline char const* getSound() { 212 return sound.c_str(); 213 } 214 215 /// Can it target creatures? isCreatureTargetAllowed()216 inline bool isCreatureTargetAllowed() { 217 return creatureTarget; 218 } 219 /// Can it target a map location (some point on the floor etc.)? isLocationTargetAllowed()220 inline bool isLocationTargetAllowed() { 221 return locationTarget; 222 } 223 /// Can it target items? isItemTargetAllowed()224 inline bool isItemTargetAllowed() { 225 return itemTarget; 226 } 227 /// Can it target a party member? isPartyTargetAllowed()228 inline bool isPartyTargetAllowed() { 229 return partyTarget; 230 } 231 /// Can it target doors? isDoorTargetAllowed()232 inline bool isDoorTargetAllowed() { 233 return doorTarget; 234 } 235 236 static Spell *getSpellByName( char *name ); 237 238 }; 239 240 /// A magic school. 241 class MagicSchool { 242 private: 243 std::string name; 244 std::string displayName; 245 std::string shortName; 246 std::string deity; 247 char deityDescription[3000]; 248 float red, green, blue; 249 std::string symbol; 250 int skill, resistSkill; 251 std::vector<Spell*> spells; 252 std::vector<std::string> lowDonate, neutralDonate, highDonate; 253 float baseAlignment; 254 255 static MagicSchool *schools[10]; 256 static int schoolCount; 257 static std::map<std::string, MagicSchool*> schoolMap; 258 259 public: 260 MagicSchool( char const* name, char const* displayName, char const* deity, int skill, int resistSkill, float alignment, float red, float green, float blue, char const* symbol ); 261 ~MagicSchool(); 262 263 /// The school's internal, unlocalized name. getName()264 inline char const* getName() { 265 return name.c_str(); 266 } 267 /// The school's localized name. getDisplayName()268 inline char const* getDisplayName() { 269 return displayName.c_str(); 270 } getShortName()271 inline char const* getShortName() { 272 return shortName.c_str(); 273 } 274 /// Returns the deity associated to the school. getDeity()275 inline char const* getDeity() { 276 return deity.c_str(); 277 } 278 /// The associated deity's localized name. getDeityDescription()279 inline char *getDeityDescription() { 280 return deityDescription; 281 } 282 /// The school's associated skill. getSkill()283 inline int getSkill() { 284 return skill; 285 } 286 /// The skill used to resist spells from this school. getResistSkill()287 inline int getResistSkill() { 288 return resistSkill; 289 } 290 /// Number of spells in this school. getSpellCount()291 inline int getSpellCount() { 292 return spells.size(); 293 } 294 /// Returns a spell from the school by index. getSpell(int index)295 inline Spell *getSpell( int index ) { 296 return spells[index]; 297 } 298 /// Adds a string to the description of the school's associated deity. addToDeityDescription(char * s)299 inline void addToDeityDescription( char *s ) { 300 if ( strlen( deityDescription ) ) strcat( deityDescription, " " ); strcat( deityDescription, s ); 301 } 302 /// The deity's color. Used to color the effect above pools for example. getDeityRed()303 inline float getDeityRed() { 304 return red; 305 } getDeityGreen()306 inline float getDeityGreen() { 307 return green; 308 } getDeityBlue()309 inline float getDeityBlue() { 310 return blue; 311 } 312 /// The "symbol" of the school (used in various descriptions). getSymbol()313 inline char const* getSymbol() { 314 return symbol.c_str(); 315 } 316 317 /// The base alignment (chaotic, neutral or lawful) of the school. getBaseAlignment()318 inline float getBaseAlignment() { 319 return baseAlignment; 320 } 321 322 static void initMagic(); 323 static void unInitMagic(); 324 325 /// Number of magic schools in the game. getMagicSchoolCount()326 inline static int getMagicSchoolCount() { 327 return schoolCount; 328 } 329 /// Gets magic school by index. getMagicSchool(int index)330 inline static MagicSchool *getMagicSchool( int index ) { 331 return schools[index]; 332 } 333 static Spell *getRandomSpell( int level ); 334 /// Gets magic school by its internal name. getMagicSchoolByName(char const * s)335 static MagicSchool *getMagicSchoolByName( char const* s ) { 336 std::string name = s; return ( schoolMap.find( name ) == schoolMap.end() ? NULL : schoolMap[name] ); 337 } 338 /// Returns a random magic school. getRandomSchool()339 static MagicSchool *getRandomSchool() { 340 return getMagicSchool( getRandomSchoolIndex() ); 341 } 342 /// Returns an index to a random magic school. getRandomSchoolIndex()343 static int getRandomSchoolIndex() { 344 return Util::dice( schoolCount ); 345 } 346 347 const char *getLowDonateMessage(); 348 const char *getNeutralDonateMessage(); 349 const char *getHighDonateMessage(); 350 351 protected: 352 /// Adds a spell to this school. addSpell(Spell * spell)353 inline void addSpell( Spell *spell ) { 354 spells.push_back( spell ); 355 } 356 const char *getRandomString( std::vector<std::string> *v ); 357 358 }; 359 360 #endif 361