1 /***************************************************************************
2            character.h  -  Class describing a playable character
3                              -------------------
4     begin                : Mon Jul 7 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 
18 #ifndef CHARACTER_H
19 #define CHARACTER_H
20 #pragma once
21 
22 #include "../util.h"
23 #include <map>
24 #include <set>
25 #include <vector>
26 #include <string>
27 
28 /**
29   *@author Gabor Torok
30   */
31 
32 class RpgItem;
33 class Skill;
34 class SkillGroup;
35 class Character;
36 
37 /// Collection of all characters.
38 
39 class Characters {
40 public:
41 	Characters(); // was Character::initCharacters()
42 	~Characters(); // was Character::unInitCharacters()
43 
getRandom()44 	Character* getRandom() {
45 		return rootCharacters[ Util::dice( rootCharacters.size() ) ];
46 	}
47 
48 	static int getRootIndexByName( char const* p );
getByName(char const * p)49 	static Character* getByName( char const* p ) {
50 		if ( instance == NULL ) {
51 			std::cerr << "*** Characters::getByName() Characters uninitialized" << std::endl;
52 			return NULL;
53 		}
54 		return instance->getCharacterByName( p );
55 	}
getRootByIndex(int i)56 	static Character* getRootByIndex( int i ) {
57 		if ( instance == NULL ) {
58 			std::cerr << "*** Characters::getRootByIndex() Characters uninitialized" << std::endl;
59 			return NULL;
60 		}
61 		return instance->rootCharacters[i];
62 	}
getRootCount()63 	static int getRootCount() {
64 		if ( instance == NULL ) {
65 			std::cerr << "*** Characters::getRootCount() Characters uninitialized" << std::endl;
66 			return 0;
67 		}
68 		return instance->rootCharacters.size();
69 	}
70 
71 private:
72 	std::map<std::string, Character*> character_class;
73 	std::vector<Character*> character_list;
74 	std::vector<Character*> rootCharacters;
75 	// Character is designed to know all of its kind
76 	friend class Character;
77 	static Characters* instance;
78 
79 	void addItemTags( const char *s, std::set<std::string> *list );
80 	void buildTree();
81 
getCharacterByName(char const * p)82 	Character* getCharacterByName( char const* p ) {
83 		std::string s = p; return character_class[s];
84 	}
85 
86 	// undefine all unused implicits
87 	Characters( Characters const& that ); // undefined
88 	Characters& operator=( Characters const& that ); // undefined
89 
90 };
91 
92 /// A playable character.
93 
94 class Character  {
95 	friend class Characters;
96 private:
97 	std::string name;
98 	std::string displayName;
99 	std::string parentName;
100 	int startingHp, startingMp, level_progression;
101 	int minLevelReq;
102 	char description[3000];
103 	Character *parent;
104 	std::vector<Character*> children;
105 	std::map<int, int> skills;
106 	std::map<std::string, int> groups;
107 	std::vector<std::string> capabilities;
108 	std::set<std::string> allowedWeaponTags;
109 	std::set<std::string> forbiddenWeaponTags;
110 	std::set<std::string> allowedArmorTags;
111 	std::set<std::string> forbiddenArmorTags;
112 
113 public:
114 	Character(  char const* name, char const* displayName, char const* parentName,
115 	           int startingHp, int startingMp,
116 	           int level_progression, int minLevelReq );
117 	~Character();
118 
119 	static Character *getRandomCharacter();
120 	static Character *getRandomCharacter( int level );
121 
getName()122 	inline char const* getName() {
123 		return name.c_str();
124 	};
getDisplayName()125 	inline char const* getDisplayName() {
126 		return displayName.c_str();
127 	};
getStartingHp()128 	inline int getStartingHp() {
129 		return startingHp;
130 	}
getStartingMp()131 	inline int getStartingMp() {
132 		return startingMp;
133 	}
getLevelProgression()134 	inline int getLevelProgression() {
135 		return level_progression;
136 	}
getDescription()137 	inline char *getDescription() {
138 		return description;
139 	}
getMinLevelReq()140 	inline int getMinLevelReq() {
141 		return minLevelReq;
142 	}
getParentName()143 	inline char const* getParentName() {
144 		return parentName.c_str();
145 	}
getParent()146 	inline Character *getParent() {
147 		return parent;
148 	}
getChildCount()149 	inline int getChildCount() {
150 		return children.size();
151 	}
getChild(int index)152 	inline Character *getChild( int index ) {
153 		return children[index];
154 	}
getCapabilityCount()155 	inline int getCapabilityCount() {
156 		return capabilities.size();
157 	}
getCapability(int index)158 	inline const char *getCapability( int index ) {
159 		return capabilities[index].c_str();
160 	}
getSkill(int skillIndex)161 	inline int getSkill( int skillIndex ) {
162 		return( skills.find( skillIndex ) == skills.end() ? -1 : skills[skillIndex] );
163 	}
164 	bool canEquip( RpgItem *item );
165 	// FIXME: hard-coded for now
getSkillBonus()166 	inline int getSkillBonus() {
167 		return 5;
168 	}
169 
170 	void finishProfessionTag();
171 	void printSet( std::set<std::string> *s, char *tagName );
172 protected:
173 	void describeProfession();
174 	bool canEquip( RpgItem *item, std::set<std::string> *allowed, std::set<std::string> *forbidden );
175 	void describeAcl( char *s, std::set<std::string> *allowed, std::set<std::string> *forbidden, int itemType );
176 };
177 
178 #endif
179 
180