1 /***************************************************************************
2 rpglib.cpp - description
3 -------------------
4 begin : Sat May 3 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 #include "../common/constants.h"
18 #include "rpg.h"
19 #include "rpgitem.h"
20
21 // ###### MS Visual C++ specific ######
22 #if defined(_MSC_VER) && defined(_DEBUG)
23 # define new DEBUG_NEW
24 # undef THIS_FILE
25 static char THIS_FILE[] = __FILE__;
26 #endif
27
28 using namespace std;
29
30 map<string, Skill*> Skill::skillsByName;
31 vector<Skill*> Skill::skills;
32
33 SkillGroup *SkillGroup::stats;
34 map<string, SkillGroup *> SkillGroup::groupsByName;
35 vector<SkillGroup*> SkillGroup::groups;
36
37 vector<std::string> Rpg::firstSyl;
38 vector<std::string> Rpg::midSyl;
39 vector<std::string> Rpg::endSyl;
40
41 map<string, StateMod*> StateMod::stateModsByName;
42 vector<StateMod*> StateMod::stateMods;
43 vector<StateMod*> StateMod::goodStateMods;
44 vector<StateMod*> StateMod::badStateMods;
45
initSkills(ConfigLang * config)46 void Rpg::initSkills( ConfigLang *config ) {
47 Skill *lastSkill = NULL;
48 SkillGroup *lastGroup = NULL;
49 char line[255];
50 char skillName[80], skillDisplayName[255], skillSymbol[80], skillDescription[255], skillAlign[32];
51 char groupName[80], groupDisplayName[255], groupDescription[255];
52 float alignment;
53
54 vector<ConfigNode*> *v = config->getDocument()->
55 getChildrenByName( "group" );
56
57 for ( unsigned int i = 0; i < v->size(); i++ ) {
58 ConfigNode *node = ( *v )[i];
59
60 config->setUpdate( _( "Loading Skills" ), i, v->size() );
61
62 strcpy( groupName, node->getValueAsString( "name" ) );
63 strcpy( groupDisplayName, node->getValueAsString( "display_name" ) );
64 strcpy( groupDescription, node->getValueAsString( "description" ) );
65
66 lastGroup = new SkillGroup( groupName, groupDisplayName, groupDescription );
67
68 vector<ConfigNode*> *vv = node->getChildrenByName( "skill" );
69 for ( unsigned int i = 0; vv && i < vv->size(); i++ ) {
70 ConfigNode *skillNode = ( *vv )[i];
71
72 strcpy( skillName, skillNode->getValueAsString( "name" ) );
73 strcpy( skillDisplayName, skillNode->getValueAsString( "display_name" ) );
74 strcpy( skillSymbol, skillNode->getValueAsString( "symbol" ) );
75 strcpy( skillDescription, skillNode->getValueAsString( "description" ) );
76 strcpy( skillAlign, node->getValueAsString( "alignment" ) );
77 if ( strcmp( skillAlign, "chaotic" ) == 0 ) {
78 alignment = ALIGNMENT_CHAOTIC;
79 } else if ( strcmp( skillAlign, "lawful" ) == 0 ) {
80 alignment = ALIGNMENT_LAWFUL;
81 } else {
82 alignment = ALIGNMENT_NEUTRAL;
83 }
84 lastSkill = new Skill( skillName, skillDisplayName, skillDescription, skillSymbol, alignment, lastGroup );
85
86 lastSkill->setPreReqMultiplier( skillNode->getValueAsInt( "prereq_multiplier" ) );
87 strcpy( line, skillNode->getValueAsString( "prereq_skills" ) );
88 char *p = strtok( line, "," );
89 while ( p ) {
90 Skill *stat = Skill::getSkillByName( p );
91 if ( !stat ) {
92 cerr << "*** Error: Can't find stat named: " << p << endl;
93 exit( 1 );
94 }
95 lastSkill->addPreReqStat( stat );
96 p = strtok( NULL, "," );
97 }
98 }
99 }
100 }
101
initNames(ConfigLang * config)102 void Rpg::initNames( ConfigLang *config ) {
103 char line[4000];
104 vector<ConfigNode*> *v = config->getDocument()->
105 getChildrenByName( "names" );
106 if ( v ) {
107 ConfigNode *node = ( *v )[0];
108 strcpy( line, node ->getValueAsString( "first" ) );
109 char *p = strtok( line, "," );
110 while ( p != NULL ) {
111 firstSyl.push_back( p );
112 //cerr << "first: " << firstSyl[ firstSyl.size() - 1 ] << endl;
113 p = strtok( NULL, "," );
114 }
115 strcpy( line, node ->getValueAsString( "middle" ) );
116 p = strtok( line, "," );
117 while ( p != NULL ) {
118 midSyl.push_back( p );
119 //cerr << "mid: " << midSyl[ midSyl.size() - 1 ] << endl;
120 p = strtok( NULL, "," );
121 }
122 strcpy( line, node ->getValueAsString( "last" ) );
123 p = strtok( line, "," );
124 while ( p != NULL ) {
125 endSyl.push_back( p );
126 //cerr << "last: " << endSyl[ endSyl.size() - 1 ] << endl;
127 p = strtok( NULL, "," );
128 }
129 }
130 //cerr << "first: " << firstSyl.size() << " mid: " << midSyl.size() << " end: " << endSyl.size() << endl;
131 }
132
initStateMods(ConfigLang * config)133 void Rpg::initStateMods( ConfigLang *config ) {
134 vector<ConfigNode*> *v = config->getDocument()->
135 getChildrenByName( "state-mod" );
136
137 for ( unsigned int i = 0; i < v->size(); i++ ) {
138 ConfigNode *node = ( *v )[i];
139
140 config->setUpdate( _( "Loading StateMods" ), i, v->size() );
141
142 string name = node->getValueAsString( "name" );
143 int type = ( !strcmp( node->getValueAsString( "type" ), "bad" ) ?
144 StateMod::BAD :
145 ( !strcmp( node->getValueAsString( "type" ), "good" ) ? StateMod::GOOD : StateMod::NEITHER ) );
146 StateMod *stateMod = new StateMod( name.c_str(),
147 node->getValueAsString( "display_name" ),
148 node->getValueAsString( "symbol" ),
149 node->getValueAsString( "setstate" ),
150 node->getValueAsString( "unsetstate" ),
151 type,
152 static_cast<int>( StateMod::stateMods.size() ) );
153 StateMod::stateMods.push_back( stateMod );
154 StateMod::stateModsByName[ name ] = stateMod;
155 if ( type == StateMod::GOOD ) StateMod::goodStateMods.push_back( stateMod );
156 if ( type == StateMod::BAD ) StateMod::badStateMods.push_back( stateMod );
157 }
158 //cerr << "** Read " << StateMod::stateMods.size() << " state mods." << endl;
159 }
160
initRpg()161 void Rpg::initRpg() {
162 ConfigLang *config = ConfigLang::load( "config/rpg.cfg" );
163 initSkills( config );
164 initStateMods( config );
165 initNames( config );
166 delete config;
167 }
168
unInitRpg()169 void Rpg::unInitRpg() {
170 for ( size_t i = 0; i < StateMod::stateMods.size(); ++i ) {
171 delete StateMod::stateMods[i];
172 }
173 StateMod::stateMods.clear();
174 StateMod::stateModsByName.clear();
175 for ( size_t i = 0; i < SkillGroup::groups.size(); ++i ) {
176 delete SkillGroup::groups[i];
177 }
178 SkillGroup::groups.clear();
179
180 }
181
182 // Create a random, cheeseball, fantasy name
createName()183 std::string Rpg::createName() {
184 string ret = firstSyl[ Util::dice( firstSyl.size() ) ];
185 int sylCount = Util::dice( 3 );
186 for ( int i = 0; i < sylCount; i++ ) {
187 ret += midSyl[ Util::dice( midSyl.size() ) ];
188 }
189 if ( 0 == Util::dice( 2 ) ) {
190 ret += endSyl[ Util::dice( endSyl.size() ) ];
191 }
192 return ret;
193 }
194
195
Skill(char * name,char * displayName,char * description,char * symbol,float alignment,SkillGroup * group)196 Skill::Skill( char *name, char *displayName, char *description, char *symbol, float alignment, SkillGroup *group ) {
197 strcpy( this->name, name );
198 strcpy( this->displayName, displayName );
199 strcpy( this->description, description );
200 strcpy( this->symbol, symbol );
201 this->alignment = alignment;
202 this->group = group;
203
204 // store the skill
205 this->index = static_cast<int>( skills.size() );
206 skills.push_back( this );
207 string s = name;
208 skillsByName[ s ] = this;
209 group->addSkill( this );
210 }
211
~Skill()212 Skill::~Skill() {
213 }
214
SkillGroup(char * name,char * displayName,char * description)215 SkillGroup::SkillGroup( char *name, char *displayName, char *description ) {
216 strcpy( this->name, name );
217 strcpy( this->displayName, displayName );
218 strcpy( this->description, description );
219 // hack: first group is the stats
220 this->isStatSkill = groups.empty();
221 if ( isStatSkill ) stats = this;
222
223 // store the group
224 this->index = static_cast<int>( groups.size() );
225 groups.push_back( this );
226 string s = name;
227 groupsByName[ s ] = this;
228 }
229
~SkillGroup()230 SkillGroup::~SkillGroup() {
231 for ( size_t i = 0; i < skills.size(); ++i ) {
232 delete skills[i];
233 }
234 skills.clear();
235 }
236
StateMod(char const * name,char const * displayName,char const * symbol,char const * setState,char const * unsetState,int type,int index)237 StateMod::StateMod( char const* name, char const* displayName
238 , char const* symbol, char const* setState
239 , char const* unsetState, int type, int index ) {
240 strcpy( this->name, name );
241 strcpy( this->displayName, displayName );
242 strcpy( this->symbol, symbol );
243 strcpy( this->setState, setState );
244 strcpy( this->unsetState, unsetState );
245 this->type = type;
246 this->index = index;
247 }
248
~StateMod()249 StateMod::~StateMod() {
250 }
251
getRandomGood()252 StateMod *StateMod::getRandomGood() {
253 return goodStateMods[ Util::dice( goodStateMods.size() ) ];
254 }
255
getRandomBad()256 StateMod *StateMod::getRandomBad() {
257 return badStateMods[ Util::dice( badStateMods.size() ) ];
258 }
259
isStateModTransitionWanted(bool setting)260 bool StateMod::isStateModTransitionWanted( bool setting ) {
261 bool effectFound = false;
262 for ( int i = 0; i < static_cast<int>( goodStateMods.size() ); i++ ) {
263 if ( goodStateMods[i] == this ) {
264 effectFound = true;
265 break;
266 }
267 }
268 if ( effectFound && setting ) return true;
269
270 effectFound = false;
271 for ( int i = 0; i < static_cast<int>( badStateMods.size() ); i++ ) {
272 if ( badStateMods[i] == this ) {
273 effectFound = true;
274 break;
275 }
276 }
277 if ( ( effectFound || this == stateMods[StateMod::dead] ) && !setting ) return true;
278 return false;
279 }
280
281