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