2012-07-02 20:49:24 +00:00
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// phrase_generator.cpp : Defines the entry point for the console application.
//
//-b -p r:\code\ryzom\data_leveldesign -o r:/code/ryzom/data_leveldesign/leveldesign/game_element/sphrase/magic/ magic_bricks.csv -d -m
// -p r:\code\ryzom\data_leveldesign -o r:/code/ryzom/data_leveldesign/leveldesign/game_element/sphrase/magic/ magic_bricks.csv -d -m
# include "stdafx.h"
// Misc
# include <nel/misc/types_nl.h>
# include "nel/misc/path.h"
# include "nel/misc/file.h"
# include "nel/misc/smart_ptr.h"
# include "nel/misc/command.h"
# include "nel/misc/path.h"
# include <nel/misc/sstring.h>
# include <nel/misc/diff_tool.h>
# include "nel/misc/algo.h"
# include "nel/misc/words_dictionary.h"
// Georges
# include "nel/georges/u_form.h"
# include "nel/georges/u_form_elm.h"
# include "nel/georges/u_form_dfn.h"
# include "nel/georges/u_form_loader.h"
# include "nel/georges/u_type.h"
// Georges, bypassing interface
# include "georges/stdgeorges.h"
# include "georges/form.h"
// Game share
//#include "game_share/xml.h"
// Unicode language file
// C
# include <time.h>
# include <stdio.h>
# include <conio.h>
# include <fstream>
// stl
# include <map>
# include "skill_tree.h"
using namespace NLMISC ;
using namespace NLGEORGES ;
using namespace std ;
typedef vector < string > vs ;
typedef map < string , string > mss ;
typedef map < string , vs > msvs ;
bool GenerateBrickProgression = false ;
bool ProduceDocFromExistingPhrases = false ;
bool MultipleDocFiles = false ;
bool Hypertext = true ;
string PhrasePath = " r:/code/ryzom/data_leveldesign/leveldesign/game_element/sphrase/ " ;
uint NbSheetsGenTries = 0 ;
uint NbSheetsWritten = 0 ;
uint NbSheetsRead = 0 ;
uint NbSheetsRejected = 0 ;
bool UseBricks ;
const string brSheetType = " sbrick " ;
const string phSheetType = " sphrase " ;
const string PHRASE_MAGIC_PREFIX = " abm_ " ; // action bricks magic (bm for brick filter)
struct CBrickInfo
{
CBrickInfo ( const string & ls = " " , const string & t = " " ,
const vs & props = vs ( ) ) :
LearnSkills ( ls ) , Text ( t ) , Props ( props ) { }
string LearnSkills ;
string Text ; // UTF-8
vs Props ;
} ;
vs OptionBricks , CounterpartBricks , AllBricks , PhrasesWithInvalidCost , InvalidPhrases ;
set < string > UsedCounterpartBricks , UsedCounterpartBrickFamiliesInPhrase ;
map < string , sint > SabrinaCosts ;
map < string , sint > PhraseSabrinaCosts ;
map < string , bool > PhraseCastable ;
map < string , CBrickInfo > BrickInfo ;
mss TextToBrick ;
multimap < uint , pair < string , string > > Progression ; // phrase code, min. skill
mss PhraseNames , PhraseTitles ;
vector < vs > ValidPhrases ;
set < string > UsedBricks , GeneratedPhrases ;
map < string , vs > GrammarMandatParamBrickFamilies , GrammarOptionCreditBrickFamilies ;
UFormLoader * FormLoader ;
vector < FILE * > PhraseDocFiles ( 26 ) ;
string DocFileName , DocFileNameRoot ;
msvs Phrases ;
map < string , uint > SkillNameToMaxSkill ;
map < string , string > PhraseCodeToLink ;
CWordsDictionary Dico ;
CStaticSkillsTree SkillsTree ;
/*
*
*/
string inputSheetPath ;
bool inputSheetPathLoaded = false ;
map < string , string > inputSheetPathContent ; // short filename without ext, full filename with path
//-----------------------------------------------
// getBrickTypeLetterRPos
//
//-----------------------------------------------
uint getBrickTypeLetterRPos ( string & brick )
{
/*
uint i = 0 ;
while ( i < brick . size ( ) & & ! isdigit ( brick [ i ] ) )
i + + ;
nlassert ( i < brick . size ( ) ) ;
return ( brick . size ( ) - i + 2 ) ;
*/
uint i = brick . size ( ) - 1 ;
while ( i > = 0 & & ( isdigit ( brick [ i ] ) | | brick [ i ] = = ' _ ' ) )
i - - ;
return ( brick . size ( ) - i + 1 ) ;
} // getBrickTypeLetterRPos //
//-----------------------------------------------
// loadSheetPath
//
// from georges2csv
//-----------------------------------------------
void loadSheetPath ( )
{
if ( inputSheetPathLoaded )
return ;
NLMISC : : createDebug ( ) ;
NLMISC : : WarningLog - > addNegativeFilter ( " CPath::insertFileInMap " ) ;
CPath : : addSearchPath ( inputSheetPath , true , false ) ; // for Georges to work properly
vector < string > files ;
CPath : : getPathContent ( inputSheetPath , true , false , true , files ) ;
uint i ;
for ( i = 0 ; i < files . size ( ) ; + + i )
{
string filename = files [ i ] ;
string filebase = CFile : : getFilenameWithoutExtension ( filename ) ;
if ( CFile : : getExtension ( filename ) ! = " saibrick " & & CFile : : getExtension ( filename ) ! = " saiphrase " )
{
inputSheetPathContent [ filebase ] = filename ;
}
}
inputSheetPathLoaded = true ;
} // loadSheetPath //
/*
*
*/
void displayList ( const string & title , const vector < string > & v , CLog * log = DebugLog )
{
if ( ! title . empty ( ) )
log - > displayRaw ( " %s: " , title . c_str ( ) ) ;
vector < string > : : const_iterator ist ;
for ( ist = v . begin ( ) ; ist ! = v . end ( ) ; + + ist )
log - > displayRaw ( " %s " , ( * ist ) . c_str ( ) ) ;
log - > displayRawNL ( " " ) ;
}
/*
*
*/
class CStrIComparator : public binary_function < string , string , bool >
{
public :
bool operator ( ) ( const string & s1 , const string & s2 ) const
{
return ( nlstricmp ( s1 , s2 ) = = 0 ) ;
}
} ;
/*
*
*/
uint getIndexFromString ( const string & s , const vector < string > & v , bool displayWarning = true )
{
if ( v . empty ( ) )
{
nlwarning ( " Can't find '%s' in empty array " , s . c_str ( ) ) ;
return ~ 0 ;
}
else
{
vector < string > : : const_iterator ist = find_if ( v . begin ( ) , v . end ( ) , bind2nd ( CStrIComparator ( ) , s ) ) ;
if ( ist = = v . end ( ) )
{
if ( displayWarning )
{
nlwarning ( " Can't find '%s' in: " , s . c_str ( ) ) ;
displayList ( " " , v , WarningLog ) ;
}
return ~ 0 ;
}
else
return ist - v . begin ( ) ;
}
}
//-----------------------------------------------
// Erase every carriage returns of the string
//
//-----------------------------------------------
void eraseCarriageReturns ( string & s )
{
const char CR = ' \n ' ;
string : : size_type p = s . find ( CR ) ;
while ( ( p = s . find ( CR ) ) ! = string : : npos )
s . erase ( p , 1 ) ;
} //
// First param: vector of indices of columns matching wantedColumnNames
// Second param: vector of fields matching wantedColumnNames
typedef void ( * TDeliveryCallback ) ( mss & ) ;
//-----------------------------------------------
// loadCSVFile
//
//-----------------------------------------------
void loadCSVFile ( const char * filename , TDeliveryCallback deliveryCallback )
{
char lineBuffer [ 2048 ] ;
FILE * file ;
const char * SEPARATOR = " ; " ;
vector < string > args ;
vector < string > : : iterator iarg ;
if ( ( file = fopen ( filename , " r " ) ) = = NULL )
{
nlwarning ( " Can't find file %s " , filename ) ;
}
else
{
// Read first line as header with column names
lineBuffer [ 0 ] = ' \0 ' ;
fgets ( lineBuffer , 2048 , file ) ;
explode ( lineBuffer , SEPARATOR , args ) ;
// Store column names (and get rid of carriage returns!)
vector < string > columnNames ;
mss valuesByName ;
for ( iarg = args . begin ( ) ; iarg ! = args . end ( ) ; + + iarg )
{
eraseCarriageReturns ( * iarg ) ;
columnNames . push_back ( * iarg ) ;
valuesByName . insert ( make_pair ( * iarg , string ( " " ) ) ) ;
}
// for each line, deliver the value of the fields
while ( ! feof ( file ) )
{
// Get from file
lineBuffer [ 0 ] = ' \0 ' ;
fgets ( lineBuffer , 2048 , file ) ;
explode ( lineBuffer , SEPARATOR , args ) ;
// Set values (and get rid of carriage returns!)
for ( iarg = args . begin ( ) ; iarg ! = args . end ( ) ; + + iarg )
{
eraseCarriageReturns ( * iarg ) ;
valuesByName [ columnNames [ iarg - args . begin ( ) ] ] = * iarg ;
}
// Deliver the wanted fields
deliveryCallback ( valuesByName ) ;
}
}
} // loadCSVFile //
//set<string> Skills;
//-----------------------------------------------
// brickDeliveryCallback
//
// Fetch brick code and sabrina cost
// - AllBricks
// - BrickInfo
// - OptionBricks
// - CounterpartBricks
// - SabrinaCosts
//-----------------------------------------------
void brickDeliveryCallback ( mss & values )
{
string s = values [ " Brick_id " ] ;
if ( s . empty ( ) )
{
s = values [ " FILE " ] ;
if ( s . empty ( ) )
s = values [ " fileName " ] ;
}
string brick = CFile : : getFilenameWithoutExtension ( s ) ;
strupr ( brick ) ;
if ( brick . empty ( ) )
{
nlwarning ( " <brickDeliveryCallback> can't get root filename of %s " , s . c_str ( ) ) ;
return ;
}
string sc = values [ " Basics.SabrinaCost " ] ;
string ls = values [ " Basics.LearnRequiresOneOfSkills " ] ;
string txt = values [ " name " ] ; // TODO: only for combat
string fmn = values [ " familyName " ] ;
string propIdent = " Basics.Property " ;
if ( UseBricks )
{
AllBricks . push_back ( brick ) ;
string name = ( txt . empty ( ) ) ? fmn : txt ;
vs props ;
// Find all Basics.Property N (assumes they are subsequent)
mss : : const_iterator imv = values . find ( propIdent + " 0 " ) ;
for ( ; imv ! = values . end ( ) ; + + imv )
{
const string & colName = ( * imv ) . first ;
const string & v = ( * imv ) . second ;
if ( colName . find ( propIdent ) ! = string : : npos )
{
if ( v ! = " NULL " & & ! v . empty ( ) )
props . push_back ( v ) ;
}
else
break ;
}
BrickInfo . insert ( make_pair ( brick , CBrickInfo ( ls , name , props ) ) ) ;
}
// Store brick in right container
string : : size_type p = brick . size ( ) - getBrickTypeLetterRPos ( brick ) ;
if ( ( ( sint ) p ) > = 0 )
{
switch ( brick [ p ] )
{
case ' O ' : OptionBricks . push_back ( brick ) ;
break ;
case ' C ' : CounterpartBricks . push_back ( brick ) ;
break ;
}
}
else
{
nlwarning ( " Invalid brick code: %s " , brick . c_str ( ) ) ;
return ;
}
// Store cost
sint sabrinaCost ;
if ( sc . empty ( ) )
{
nldebug ( " No sabrina cost for %s, assuming cost 0 " , brick . c_str ( ) ) ;
sabrinaCost = 0 ;
}
else
{
sabrinaCost = atoi ( sc . c_str ( ) ) ;
}
SabrinaCosts . insert ( make_pair ( brick , sabrinaCost ) ) ;
/* // Quick hack to generate skill codes
string skill = brick . substr ( 1 , p - 1 ) ;
if ( ! skill . empty ( ) )
Skills . insert ( skill ) ; */
} // brickDeliveryCallback //
//-----------------------------------------------
// loadBricks
//
//-----------------------------------------------
void loadBricks ( const char * filename )
{
loadCSVFile ( filename , brickDeliveryCallback ) ;
if ( ProduceDocFromExistingPhrases )
nlinfo ( " Loaded %u option bricks, %u counterpart bricks, %u sabrina costs " , OptionBricks . size ( ) , CounterpartBricks . size ( ) , SabrinaCosts . size ( ) ) ;
else if ( UseBricks )
nlinfo ( " Loaded %u bricks " , AllBricks . size ( ) ) ;
/*set<string>::const_iterator iss;
for ( iss = Skills . begin ( ) ; iss ! = Skills . end ( ) ; + + iss )
{
const string & skill = ( * iss ) ;
InfoLog - > displayRawNL ( " <DEFINITION Label= \" S%s \" Value= \" S%s \" /> " , skill . c_str ( ) , skill . c_str ( ) ) ;
} */
} // loadBricks //
/*
*
*/
string getRootBrickForOptionOrCredit ( const string & ob )
{
// Extract brick code radix
string : : size_type p = ob . size ( ) - getBrickTypeLetterRPos ( const_cast < string & > ( ob ) ) ;
if ( ( ob . size ( ) < = getBrickTypeLetterRPos ( const_cast < string & > ( ob ) ) ) | |
( ( ob [ p ] ! = ' O ' ) & & ( ob [ p ] ! = ' C ' ) ) )
nlerror ( " %s is not an option or credit brick " , ob . c_str ( ) ) ;
string radix = ob . substr ( 0 , p ) ;
// Append root brick suffix
return radix + " PA01 " ;
}
/*
*
*/
string getBrickFamily ( const string & b )
{
if ( b . size ( ) > = getBrickTypeLetterRPos ( const_cast < string & > ( b ) ) + 2 )
{
string : : size_type p = b . size ( ) - getBrickTypeLetterRPos ( const_cast < string & > ( b ) ) ;
return b . substr ( 0 , p + 2 ) ;
}
return string ( ) ;
}
/*
*
*/
bool isFromBrickFamily ( const string & brick , const string & fam )
{
return nlstricmp ( brick . substr ( 0 , fam . size ( ) ) , fam ) = = 0 ;
}
/*
*
*/
string getFirstBrickOfFamily ( const string & family )
{
vs : : const_iterator ib ;
for ( ib = AllBricks . begin ( ) ; ib ! = AllBricks . end ( ) ; + + ib )
{
const string & brick = * ib ;
if ( isFromBrickFamily ( brick , family ) )
return brick ;
}
return string ( ) ;
}
/*
*
*/
vs getAllBricksOfFamily ( const string & family )
{
vs res ;
vs : : const_iterator ib ;
for ( ib = AllBricks . begin ( ) ; ib ! = AllBricks . end ( ) ; + + ib )
{
const string & brick = * ib ;
if ( isFromBrickFamily ( brick , family ) )
res . push_back ( brick ) ;
}
return res ;
}
/*
*
*/
uint getCompatibleCounterpartBrickForCost ( uint phraseCost , vs & phrase )
{
//nlinfo( "Searching credit for cost %u", phraseCost );
// Get the lowest matching counterpart brick
uint minHigherCounterpartValue = ~ 0 , maxLowerCounterpartValue = 0 , counterpartValue ;
vs : : const_iterator icb , iPerfectMatch = CounterpartBricks . end ( ) , iMinCb = CounterpartBricks . end ( ) , iMaxCb = CounterpartBricks . end ( ) ;
for ( icb = CounterpartBricks . begin ( ) ; icb ! = CounterpartBricks . end ( ) ; + + icb )
{
const string & cb = * icb ;
// Skip if family already used in current phrase
if ( UsedCounterpartBrickFamiliesInPhrase . find ( getBrickFamily ( cb ) ) ! = UsedCounterpartBrickFamiliesInPhrase . end ( ) )
continue ;
counterpartValue = abs ( SabrinaCosts [ cb ] ) ;
//nldebug( "Trying with credit %u", counterpartValue );
if ( counterpartValue = = phraseCost )
{
// Perfect match, check if not already taken
if ( UsedCounterpartBricks . insert ( cb ) . second )
{
UsedCounterpartBrickFamiliesInPhrase . insert ( getBrickFamily ( cb ) ) ;
phrase . push_back ( cb ) ;
return counterpartValue ;
}
else
{
// If already taken, we will come back to it later
iPerfectMatch = icb ;
}
}
else if ( counterpartValue > phraseCost )
{
// Higher => get the minimum
if ( counterpartValue < minHigherCounterpartValue )
{
minHigherCounterpartValue = counterpartValue ;
iMinCb = icb ;
}
}
else // counterpartValue < phraseCost : store the max
{
if ( counterpartValue > = maxLowerCounterpartValue )
{
maxLowerCounterpartValue = counterpartValue ;
iMaxCb = icb ;
}
}
}
if ( iPerfectMatch ! = CounterpartBricks . end ( ) )
{
// We skipped a perfect match in order to try to get a new value. But none found. Now get back to the last value.
phrase . push_back ( * iPerfectMatch ) ;
UsedCounterpartBrickFamiliesInPhrase . insert ( getBrickFamily ( * iPerfectMatch ) ) ;
return abs ( SabrinaCosts [ * iPerfectMatch ] ) ;
}
else if ( iMinCb = = CounterpartBricks . end ( ) )
{
if ( iMaxCb = = CounterpartBricks . end ( ) )
{
nlerror ( " No matching counterpart " ) ;
return ~ 0 ;
}
else
{
// No phrase possible with only one (more) counterpart, try with the max and more (recurse)
UsedCounterpartBricks . insert ( * iMaxCb ) ;
UsedCounterpartBrickFamiliesInPhrase . insert ( getBrickFamily ( * iMaxCb ) ) ;
phrase . push_back ( * iMaxCb ) ;
return maxLowerCounterpartValue + getCompatibleCounterpartBrickForCost ( phraseCost - maxLowerCounterpartValue , phrase ) ;
}
}
else
{
// Phrase possible with one (more) counterpart
UsedCounterpartBricks . insert ( * iMinCb ) ;
UsedCounterpartBrickFamiliesInPhrase . insert ( getBrickFamily ( * iMinCb ) ) ;
phrase . push_back ( * iMinCb ) ;
return minHigherCounterpartValue ;
}
}
/*
*
*/
void getCompatibleCounterpartBricks ( vs & phrase )
{
// Calculate the cost of the phrase
sint phraseCost = 0 ;
string phraseStr ;
vs : : const_iterator ip ;
for ( ip = phrase . begin ( ) ; ip ! = phrase . end ( ) ; + + ip )
{
const string & brick = * ip ;
sint sabrinaCost ;
map < string , sint > : : const_iterator isc = SabrinaCosts . find ( brick ) ;
if ( isc ! = SabrinaCosts . end ( ) )
sabrinaCost = ( * isc ) . second ;
else
sabrinaCost = 0 ;
phraseCost + = sabrinaCost ;
phraseStr + = brick + " " ;
}
// Find matching counterpart(s), only 1 per family
UsedCounterpartBrickFamiliesInPhrase . clear ( ) ;
uint counterpartValue = getCompatibleCounterpartBrickForCost ( phraseCost , phrase ) ;
displayList ( toString ( " +%3u -%3u " , phraseCost , counterpartValue ) , phrase ) ;
}
/*
*
*/
/*void getCompatiblePhraseByCounterpart( const string& counterpartBrick, vs& phrase )
{
sint sabrinaCost = SabrinaCosts [ counterpartBrick ] ;
// Assuming root brick cost is zero!
vs : : const_iterator iob ;
for ( iob = OptionBricks . begin ( ) ; iob ! = OptionBricks . end ( ) ; + + iob )
{
// TODO: Find the highest cost that is lower or equal than the counterpart value
const string & ob = * iob ;
if ( SabrinaCosts [ ob ] < = SabrinaCosts [ counterpartBrick ] )
break ; // currently, take the first found
}
if ( iob ! = OptionBricks . end ( ) )
{
string rb = getRootBrickForOptionOrCredit ( * iob ) ;
phrase . push_back ( rb ) ;
phrase . push_back ( * iob ) ;
phrase . push_back ( counterpartBrick ) ;
nldebug ( " %s %s %s: +%u -%u " , rb . c_str ( ) , ( * iob ) . c_str ( ) , counterpartBrick . c_str ( ) ,
SabrinaCosts [ rb ] + SabrinaCosts [ * iob ] , SabrinaCosts [ counterpartBrick ] ) ;
}
else
nlwarning ( " No matching phrase for counterpart %s " , counterpartBrick . c_str ( ) ) ;
} */
/*
* Clear the form to reuse it ( and all contents below node )
*/
void clearSheet ( CForm * form , UFormElm * node )
{
( ( CFormElm * ) node ) - > clean ( ) ;
form - > clean ( ) ;
}
/*
*
*/
inline void explodeBrickAndParameters ( const string & brickAndParams , vs & bricks )
{
explode ( brickAndParams , " " , bricks ) ;
}
/*
*
*/
string getBrickType ( const string & brick )
{
if ( brick . size ( ) < 4 )
return " INVALID TYPE in " + brick ;
else
{
switch ( brick [ brick . size ( ) - getBrickTypeLetterRPos ( const_cast < string & > ( brick ) ) ] )
{
case ' P ' : return " Root " ;
break ;
case ' E ' : return " Effect " ;
break ;
case ' O ' : return " Option " ;
break ;
case ' M ' : return " Modifier " ;
break ;
case ' C ' : return " Credit " ;
break ;
default :
return " INVALID TYPE in " + brick ;
}
}
}
//-----------------------------------------------
// printBrickInfo
//
//-----------------------------------------------
void printBrickInfo ( FILE * htmlfile , const string & brick , const string & grammarError , sint & sabrinaCost , uint & minSkillValue , string & minSkill )
{
minSkill . clear ( ) ;
string b = brick ;
strupr ( b ) ;
string brickType = getBrickType ( b ) ;
sint sc = ( brickType = = " Credit " ) ? - abs ( SabrinaCosts [ b ] ) : SabrinaCosts [ b ] ;
CBrickInfo & bInfo = BrickInfo [ b ] ;
fprintf ( htmlfile , " <LI><B>%s %s</B> %s<BR> \n " , brickType . c_str ( ) , b . c_str ( ) , bInfo . Text . c_str ( ) ) ;
if ( ! grammarError . empty ( ) )
{
fprintf ( htmlfile , " <FONT COLOR= \" RED \" >%s</FONT><BR> \n " , grammarError . c_str ( ) ) ;
}
else
{
fprintf ( htmlfile , " Sabrina Cost: %d <BR> \n " , sc ) ;
if ( ! bInfo . LearnSkills . empty ( ) )
{
fprintf ( htmlfile , " Skills required: %s<BR> \n " , bInfo . LearnSkills . c_str ( ) ) ;
}
if ( bInfo . Props . size ( ) )
{
fprintf ( htmlfile , " Properties: " ) ;
for ( vs : : const_iterator ip = bInfo . Props . begin ( ) ; ip ! = bInfo . Props . end ( ) ; + + ip )
{
fprintf ( htmlfile , " %s " , ( * ip ) ) ;
}
}
}
fprintf ( htmlfile , " </LI> \n " ) ;
// Calculate sabrina cost & skill value
sabrinaCost = sc ;
if ( bInfo . LearnSkills . empty ( ) )
minSkillValue = 0 ;
else
{
minSkillValue = ~ 0 ;
vector < string > skillsAndValues ;
explode ( bInfo . LearnSkills , " : " , skillsAndValues , true ) ;
vector < uint > skillValues ( skillsAndValues . size ( ) , ~ 0 ) ;
vector < string > : : iterator isv ;
for ( isv = skillsAndValues . begin ( ) ; isv ! = skillsAndValues . end ( ) ; + + isv )
{
const string & sav = * isv ;
string : : size_type p = sav . find ( ' ' ) ;
if ( ( p = = string : : npos ) | | ( sav . size ( ) = = p + 1 ) )
nlwarning ( " Invalid LearnRequiresOneOfSkills value '%s' " , sav . c_str ( ) ) ;
else
{
uint sv = atoi ( sav . substr ( p + 1 ) . c_str ( ) ) ;
skillValues [ isv - skillsAndValues . begin ( ) ] = sv ;
if ( sv < minSkillValue )
minSkillValue = sv ;
}
}
for ( isv = skillsAndValues . begin ( ) ; isv ! = skillsAndValues . end ( ) ; + + isv )
{
if ( skillValues [ isv - skillsAndValues . begin ( ) ] = = minSkillValue )
{
string & sav = * isv ;
if ( ( ! sav . empty ( ) ) & & ( sav [ 0 ] ! = ' S ' ) )
sav = ' S ' + sav ;
if ( minSkill . find ( sav ) = = string : : npos )
{
if ( ! minSkill . empty ( ) )
minSkill + = " , " ;
minSkill + = sav ;
}
}
}
}
} // printBrickInfo //
//-----------------------------------------------
// loadBrickGrammar
//
//-----------------------------------------------
void loadBrickGrammar ( )
{
uint nbRootBricks = 0 ;
vs : : const_iterator ib ;
for ( ib = AllBricks . begin ( ) ; ib ! = AllBricks . end ( ) ; + + ib )
{
string brick = * ib ;
strupr ( brick ) ;
if ( brick . size ( ) > = 4 )
{
char brickType = brick [ brick . size ( ) - getBrickTypeLetterRPos ( brick ) ] ;
/*// As the root bricks may be absent from the table, deduce them (obsolete)
if ( brickType = = ' O ' )
{
string rootBrick = getRootBrickForOptionOrCredit ( brick ) ;
if ( GrammarOptionCreditBrickFamilies . find ( rootBrick ) = = GrammarOptionCreditBrickFamilies . end ( ) )
{
brick = rootBrick ;
brickType = ' P ' ;
}
else
{
continue ;
}
} */
// If not skipped by previous 'continue'
if ( ( brickType = = ' P ' ) | | ( brickType = = ' E ' ) | | ( brickType = = ' O ' ) ) // root, effect, option
{
NLMISC : : CSmartPtr < CForm > form = ( CForm * ) FormLoader - > loadForm ( ( strlwr ( static_cast < const string & > ( brick ) ) + " . " + brSheetType ) . c_str ( ) ) ;
if ( ! form )
{
nlwarning ( " Can't load sheet %s " , ( ( strlwr ( static_cast < const string & > ( brick ) ) ) + " . " + phSheetType ) . c_str ( ) ) ;
continue ;
}
for ( uint i = 0 ; i ! = 12 ; + + i )
{
string value ;
form - > getRootNode ( ) . getValueByName ( value , toString ( " Mandatory.f%u " , i ) . c_str ( ) ) ;
if ( ( ! value . empty ( ) ) & & ( value ! = " Unknown " ) )
{
GrammarMandatParamBrickFamilies [ brick ] . push_back ( value ) ;
}
}
if ( brickType = = ' O ' )
{
for ( uint i = 0 ; i ! = 4 ; + + i )
{
string value ;
form - > getRootNode ( ) . getValueByName ( value , toString ( " Parameter.f%u " , i ) . c_str ( ) ) ;
if ( ( ! value . empty ( ) ) & & ( value ! = " Unknown " ) )
{
GrammarMandatParamBrickFamilies [ brick ] . push_back ( value ) ;
}
}
}
if ( brickType = = ' P ' ) // root
{
+ + nbRootBricks ;
for ( uint i = 0 ; i ! = 32 ; + + i )
{
string value ;
form - > getRootNode ( ) . getValueByName ( value , toString ( " Optional.f%u " , i ) . c_str ( ) ) ;
if ( ( ! value . empty ( ) ) & & ( value ! = " Unknown " ) )
{
GrammarOptionCreditBrickFamilies [ brick ] . push_back ( value ) ;
}
}
for ( uint i = 0 ; i ! = 12 ; + + i )
{
string value ;
form - > getRootNode ( ) . getValueByName ( value , toString ( " Credit.f%u " , i ) . c_str ( ) ) ;
if ( ( ! value . empty ( ) ) & & ( value ! = " Unknown " ) )
{
GrammarOptionCreditBrickFamilies [ brick ] . push_back ( value ) ;
}
}
}
}
}
else
{
nlwarning ( " Invalid brick code %s " , brick . c_str ( ) ) ;
}
}
nlinfo ( " %u bricks have mandatory/parameter grammar rules " , GrammarMandatParamBrickFamilies . size ( ) ) ;
nlinfo ( " %u bricks have option/credit grammar rules " , GrammarOptionCreditBrickFamilies . size ( ) ) ;
nlinfo ( " Found or deduced %u root bricks " , nbRootBricks ) ;
} // loadBrickGrammar //
//-----------------------------------------------
// loadPhraseTitles
//
//-----------------------------------------------
void loadPhraseTitles ( )
{
STRING_MANAGER : : TWorksheet worksheet ;
STRING_MANAGER : : loadExcelSheet ( " r:/code/ryzom/translation/translated/sphrase_words_en.txt " , worksheet ) ;
uint cp , cn ;
if ( worksheet . findCol ( ucstring ( " sphrase ID " ) , cp ) & & worksheet . findCol ( ucstring ( " name " ) , cn ) )
{
for ( std : : vector < STRING_MANAGER : : TWorksheet : : TRow > : : iterator ip = worksheet . begin ( ) ; ip ! = worksheet . end ( ) ; + + ip )
{
if ( ip = = worksheet . begin ( ) ) // skip first row
continue ;
STRING_MANAGER : : TWorksheet : : TRow & row = * ip ;
PhraseTitles . insert ( make_pair ( strlwr ( row [ cp ] . toString ( ) ) , row [ cn ] . toUtf8 ( ) ) ) ;
}
}
else
nlwarning ( " sphrase ID or name not found " ) ;
nlinfo ( " Loaded %u phrase titles " , PhraseTitles . size ( ) ) ;
} // loadPhraseTitles //
//-----------------------------------------------
// loadBrickTitles
//
//-----------------------------------------------
void loadBrickTitles ( )
{
STRING_MANAGER : : TWorksheet worksheet ;
STRING_MANAGER : : loadExcelSheet ( " r:/code/ryzom/translation/translated/sbrick_words_en.txt " , worksheet ) ;
uint cp , cn , nbTitles = 0 ;
if ( worksheet . findCol ( ucstring ( " sbrick ID " ) , cp ) & & worksheet . findCol ( ucstring ( " name " ) , cn ) )
{
for ( std : : vector < STRING_MANAGER : : TWorksheet : : TRow > : : iterator ip = worksheet . begin ( ) ; ip ! = worksheet . end ( ) ; + + ip )
{
if ( ip = = worksheet . begin ( ) ) // skip first row
continue ;
STRING_MANAGER : : TWorksheet : : TRow & row = * ip ;
BrickInfo [ strupr ( row [ cp ] . toString ( ) ) ] . Text = row [ cn ] . toUtf8 ( ) ; ;
+ + nbTitles ;
}
}
else
nlwarning ( " sbrick ID or name not found " ) ;
nlinfo ( " Loaded %u brick titles " , nbTitles ) ;
} // loadBrickTitles //
/*
*
*/
void getChildrenBricks ( const string & brick , vs & chFamilies )
{
chFamilies = GrammarMandatParamBrickFamilies [ brick ] ;
}
/*
*
*/
void addError ( string & errorStr , string & newError , uint & nbGrammarErrors )
{
if ( ! errorStr . empty ( ) )
errorStr + = " <BR> " ;
errorStr + = newError ;
+ + nbGrammarErrors ;
}
/*
*
*/
void checkOptionOrCreditCompatibility ( string & errorStr , const string & currentBrick , const string & rootBrick , uint & nbGrammarErrors )
{
string brick = currentBrick ;
strupr ( brick ) ;
if ( brick . size ( ) > = 4 & & brick [ 1 ] ! = ' C ' & & brick [ 1 ] ! = ' H ' ) // C & H for craft and harvest
{
char brickType = brick [ brick . size ( ) - getBrickTypeLetterRPos ( brick ) ] ;
if ( ( brickType = = ' O ' ) | | ( brickType = = ' C ' ) )
{
string rootBrick = getRootBrickForOptionOrCredit ( brick ) ;
const vs & compatibleOptionOrCredits = GrammarOptionCreditBrickFamilies [ rootBrick ] ;
vs : : const_iterator ic ;
for ( ic = compatibleOptionOrCredits . begin ( ) ; ic ! = compatibleOptionOrCredits . end ( ) ; + + ic )
{
if ( isFromBrickFamily ( brick , ( * ic ) ) )
break ;
}
if ( ic = = compatibleOptionOrCredits . end ( ) )
{
addError ( errorStr , toString ( " This family is not compatible with options/credits of root %s " , rootBrick . c_str ( ) ) , nbGrammarErrors ) ;
}
}
}
}
/*
* Preconditions :
* - grammarErrors . size ( ) = = phrase . size ( )
* - r < phrase . size ( )
*
* Note : does not check that all bricks should have a different family
*/
void checkGrammar ( const vs & phrase , uint & r , vs & grammarErrors , uint & nbGrammarErrors , const string & rootBrick , bool readNext = true )
{
uint origR = r ;
string grammarBrick = phrase [ origR ] ;
strupr ( grammarBrick ) ;
// Check option/credit
checkOptionOrCreditCompatibility ( grammarErrors [ r ] , phrase [ r ] , rootBrick , nbGrammarErrors ) ;
// Check mandatory/parameter
vs chFamilies ;
getChildrenBricks ( grammarBrick , chFamilies ) ;
+ + r ;
for ( vs : : const_iterator icf = chFamilies . begin ( ) ; icf ! = chFamilies . end ( ) ; + + icf )
{
// Detect incomplete phrase
if ( r > = phrase . size ( ) )
{
addError ( grammarErrors [ origR ] , " Missing mandatory/parameter " + ( * icf ) + " at the end " , nbGrammarErrors ) ;
break ;
}
// Detect wrong brick family
if ( isFromBrickFamily ( phrase [ r ] , ( * icf ) ) )
{
// Check grammar using child as root
checkGrammar ( phrase , r , grammarErrors , nbGrammarErrors , phrase [ r ] , false ) ;
}
else
{
addError ( grammarErrors [ r ] , " Error: " + ( * icf ) + " expected (mandatory/parameter of " + grammarBrick + " ) " , nbGrammarErrors ) ;
+ + r ;
}
}
// Next
if ( readNext & & ( r < phrase . size ( ) ) )
{
checkGrammar ( phrase , r , grammarErrors , nbGrammarErrors , rootBrick ) ;
}
}
/*
*
*/
char getDocFileLetter ( const string & sheetName )
{
// skip abm_mt_, abm_ml_...
char letter = ' a ' ;
uint nbUnderscoresToSkip = 2 , nbUnderscoresFound = 0 ;
for ( uint c = 0 ; c ! = sheetName . size ( ) ; + + c )
{
if ( nbUnderscoresFound = = nbUnderscoresToSkip )
{
letter = sheetName [ c ] ;
break ;
}
if ( sheetName [ c ] = = ' _ ' )
+ + nbUnderscoresFound ;
}
return tolower ( letter ) ;
}
//-----------------------------------------------
// testPhraseGrammarAndProduceDoc
//
//-----------------------------------------------
bool testPhraseGrammarAndProduceDoc ( const string & sheetName , const vs & phrase )
{
string filename = strlwr ( sheetName ) + " . " + phSheetType ;
string phraseStatus ;
bool isPhraseCorrect = true ;
const char * rejectedstr = " (grammatically invalid) " ;
// Check grammar for this phrase
vs grammarErrors ( phrase . size ( ) ) ;
uint nbGrammarErrors = 0 , r = 0 ;
checkGrammar ( phrase , r , grammarErrors , nbGrammarErrors , phrase [ 0 ] ) ;
if ( nbGrammarErrors ! = 0 )
{
InvalidPhrases . push_back ( sheetName ) ;
isPhraseCorrect = false ;
phraseStatus = rejectedstr ;
}
// Look-up phrase title
string phraseTitle = PhraseTitles [ sheetName ] ;
// Output phrase description
char letter = ' a ' ;
if ( ( ! MultipleDocFiles ) & & ( sheetName . size ( ) > 3 ) )
{
letter = tolower ( sheetName [ 3 ] ) ;
}
else
{
letter = getDocFileLetter ( sheetName ) ;
}
if ( letter < ' a ' )
letter = ' a ' ;
else if ( letter > ' z ' )
letter = ' z ' ;
FILE * htmlFile = PhraseDocFiles [ letter - ' a ' ] ;
sint sabrinaCost ;
fprintf ( htmlFile , " <A NAME= \" %s \" ></A><P><B>%s</B> %s %s<BR><UL> \n " , sheetName . c_str ( ) , filename . c_str ( ) , phraseTitle . c_str ( ) , phraseStatus . c_str ( ) ) ;
vector < string > minBrickSkills ( phrase . size ( ) ) ;
vector < uint > minBrickSkillValues ( phrase . size ( ) , 0 ) ;
string brickMinSkill , maxSkill ;
sint posCost = 0 , negCost = 0 , totalCost ;
uint maxSkillValue = 0 , brickMinSkillValue ;
for ( uint i = 0 ; i ! = phrase . size ( ) ; + + i )
{
printBrickInfo ( htmlFile , phrase [ i ] , grammarErrors [ i ] , sabrinaCost , brickMinSkillValue , brickMinSkill ) ;
if ( sabrinaCost > 0 )
posCost + = sabrinaCost ;
else
negCost + = sabrinaCost ;
minBrickSkillValues [ i ] = brickMinSkillValue ;
minBrickSkills [ i ] = brickMinSkill ;
if ( brickMinSkillValue > maxSkillValue )
maxSkillValue = brickMinSkillValue ;
}
for ( uint i = 0 ; i ! = phrase . size ( ) ; + + i )
{
if ( minBrickSkillValues [ i ] = = maxSkillValue )
{
if ( maxSkill . find ( minBrickSkills [ i ] ) = = string : : npos )
{
if ( ! maxSkill . empty ( ) )
maxSkill + = " ; " ;
maxSkill + = minBrickSkills [ i ] ;
}
}
}
if ( phrase . size ( ) > 1 )
{
string effectOrOptionBrick = phrase [ 1 ] ;
strupr ( effectOrOptionBrick ) ;
if ( ! PhraseNames . insert ( make_pair ( sheetName , BrickInfo [ effectOrOptionBrick ] . Text ) ) . second )
nlwarning ( " Found duplicate phrase %s " , sheetName . c_str ( ) ) ;
}
Progression . insert ( make_pair ( maxSkillValue , make_pair ( sheetName , maxSkill ) ) ) ;
totalCost = posCost + negCost ;
PhraseSabrinaCosts . insert ( make_pair ( sheetName , totalCost ) ) ;
char * redbegin = " " , * redend = " " ;
if ( totalCost > 0 )
{
map < string , bool > : : const_iterator itCastable = PhraseCastable . find ( sheetName ) ;
if ( itCastable ! = PhraseCastable . end ( ) )
{
if ( ( * itCastable ) . second )
{
redbegin = " <FONT COLOR= \" RED \" > " ;
redend = " </FONT> " ;
PhrasesWithInvalidCost . push_back ( sheetName ) ;
isPhraseCorrect = false ;
}
}
}
fprintf ( htmlFile , " <LI>%s<B>Total sabrina cost: </B>+%d %d = %d%s</LI> \n " , redbegin , posCost , negCost , totalCost , redend ) ;
fprintf ( htmlFile , " <LI><B>Minimum skill value required: %d</B></LI> \n " , maxSkillValue ) ;
fprintf ( htmlFile , " </UL></P> \n " ) ;
if ( ! isPhraseCorrect )
{
+ + NbSheetsRejected ;
}
return isPhraseCorrect ;
} // testPhraseGrammarAndProduceDoc //
/*
*
*/
inline bool isSeparator ( char c )
{
return ( c = = ' ' ) | | ( c = = ' \t ' ) ;
}
//-----------------------------------------------
// produceDocFromExistingPhrases
//
// - Phrases
//-----------------------------------------------
void produceDocFromExistingPhrases ( )
{
vs files ;
CPath : : getPathContent ( PhrasePath , true , false , true , files ) ;
NbSheetsRead = 0 ;
for ( vs : : const_iterator ip = files . begin ( ) ; ip ! = files . end ( ) ; + + ip )
{
if ( CFile : : getExtension ( * ip ) = = phSheetType )
{
// Read george sheet
NLMISC : : CSmartPtr < UForm > form = ( UForm * ) FormLoader - > loadForm ( ( * ip ) . c_str ( ) ) ;
if ( ! form )
nlerror ( " Can't load sheet %s " , ( * ip ) . c_str ( ) ) ;
// Get the bricks of the phrase
vs phrase ;
for ( uint i = 0 ; i ! = 100 ; + + i )
{
string value ;
form - > getRootNode ( ) . getValueByName ( value , toString ( " brick %u " , i ) . c_str ( ) ) ;
if ( ! value . empty ( ) )
{
strupr ( value ) ;
phrase . push_back ( CFile : : getFilenameWithoutExtension ( value ) ) ;
}
}
Phrases . insert ( make_pair ( CFile : : getFilenameWithoutExtension ( * ip ) , phrase ) ) ;
// look if phrase is castable
bool castable ;
form - > getRootNode ( ) . getValueByName ( castable , " castable " ) ;
PhraseCastable . insert ( make_pair ( CFile : : getFilenameWithoutExtension ( * ip ) , castable ) ) ;
// Test grammar and produce doc
testPhraseGrammarAndProduceDoc ( CFile : : getFilenameWithoutExtension ( * ip ) , phrase ) ;
+ + NbSheetsRead ;
}
}
nlinfo ( " Total: %u phrases " , NbSheetsRead ) ;
} // produceDocFromExistingPhrases //
/*
*
*/
string getLink ( const string & phrase )
{
string res ;
if ( MultipleDocFiles & & ( ! phrase . empty ( ) ) )
{
res + = DocFileName + " _ " + getDocFileLetter ( phrase ) + " .html " ;
}
else
{
res + = DocFileName + " .html " ;
}
res + = " # " + phrase ;
//nlinfo( "%s", res.c_str() );
return res ;
}
/*
*
*/
void usage ( char * argv0 , FILE * out )
{
fprintf ( out , " \n " ) ;
fprintf ( out , " Syntax: %s [-p <sheet path>] <bricksFilename> [-o <phrasePath>] [-b] [-d] [-m] [-n] \n " , argv0 ) ;
fprintf ( out , " -o: output phrase path (or input if -d is set) \n " ) ;
fprintf ( out , " -b: produce doc about brick learning infos \n " ) ;
fprintf ( out , " -d: browse existing phrases in <phrasePath> (and subdirs) and produce doc \n " ) ;
fprintf ( out , " -m: multiple doc html files, alphabetically (use with -g,-c,-d with numerous phrases) \n " ) ;
fprintf ( out , " -n: no hypertext (don't produce links phrases) \n " ) ;
fprintf ( out , " \n " ) ;
}
//-----------------------------------------------
// makeIndexFile
//
//-----------------------------------------------
void makeIndexFile ( )
{
FILE * indexFile = fopen ( ( " _ " + DocFileNameRoot + " _INDEX.html " ) . c_str ( ) , " wt " ) ;
if ( indexFile )
{
fprintf ( indexFile , ( " <html><head> \n <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n <title>Summary of " + DocFileNameRoot + " </title> \n </head><body> \n " ) . c_str ( ) ) ;
DocFileName = DocFileNameRoot + " _actions " ;
if ( MultipleDocFiles )
{
// One HTML file per alphabet letter
for ( uint l = 0 ; l ! = 26 ; + + l )
{
string filename = toString ( " %s_%c.html " , DocFileName . c_str ( ) , ' a ' + l ) ;
PhraseDocFiles [ l ] = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( PhraseDocFiles [ l ] , ( " <html><head> \n <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n <title> " + DocFileName + toString ( " - %c " , ( char ) ( ' A ' + l ) ) + " </title> \n </head><body> \n " ) . c_str ( ) ) ;
fprintf ( indexFile , ( " <A HREF= \" " + filename + " \" > " + ( char ) ( ' A ' + l ) + " </A> " ) . c_str ( ) ) ;
}
}
else
{
// One single HTML file
fprintf ( indexFile , ( " <A HREF= \" " + DocFileName + " .html \" >Go to action details</A> " ) . c_str ( ) ) ;
PhraseDocFiles [ 0 ] = fopen ( ( DocFileName + " .html " ) . c_str ( ) , " wt " ) ;
fprintf ( PhraseDocFiles [ 0 ] , ( " <html><head> \n <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n <title> " + DocFileName + " </title> \n </head><body> \n " ) . c_str ( ) ) ;
for ( uint l = 1 ; l ! = 26 ; + + l )
{
PhraseDocFiles [ l ] = PhraseDocFiles [ 0 ] ;
}
}
fprintf ( indexFile , ( " <BR><A HREF= \" " + DocFileName + " __by_skill_value.html " + " \" >Go to action by skill value</A> \n " ) . c_str ( ) ) ;
fprintf ( indexFile , ( " <BR><A HREF= \" " + DocFileName + " __by_skill_value_detail.html " + " \" >Go to action by skill value (detail)</A> \n " ) . c_str ( ) ) ;
fprintf ( indexFile , ( " <BR><A HREF= \" " + DocFileName + " __by_skill.html " + " \" >Go to action by skill</A><BR> \n " ) . c_str ( ) ) ;
if ( GenerateBrickProgression )
{
fprintf ( indexFile , ( " <BR><BR><A HREF= \" " + DocFileNameRoot + " .html " + " \" >Go to brick list</A><BR> \n " ) . c_str ( ) ) ;
}
produceDocFromExistingPhrases ( ) ;
for ( map < uint , pair < string , string > > : : const_iterator ip = Progression . begin ( ) ; ip ! = Progression . end ( ) ; + + ip )
{
const string & phraseCode = ( * ip ) . second . first ;
string link = Hypertext ? toString ( " <A HREF= \" %s \" >%s</A> " , getLink ( phraseCode ) . c_str ( ) , phraseCode . c_str ( ) ) : " <B> " + phraseCode + " </B> " ;
PhraseCodeToLink . insert ( make_pair ( phraseCode , link ) ) ;
}
// Summary (errors in phrases)
fprintf ( indexFile , " <BR><A NAME= \" summary \" ></A> \n " ) ;
fprintf ( indexFile , ( " <FONT SIZE= \" 20 \" >Summary of " + DocFileName + " </FONT><BR> \n " ) . c_str ( ) ) ;
if ( NbSheetsGenTries ! = 0 )
fprintf ( indexFile , " <P>%u valid sheets written on %u</P> \n " , NbSheetsWritten , NbSheetsGenTries ) ;
if ( NbSheetsRead ! = 0 )
fprintf ( indexFile , " <P>%u sheets read</P> \n " , NbSheetsRead ) ;
fprintf ( indexFile , " <P>%u invalid sheets rejected " , NbSheetsRejected ) ;
if ( ! PhrasesWithInvalidCost . empty ( ) )
{
fprintf ( indexFile , " <P><B>Phrases with invalid sabrina cost:</B><BR> \n " ) ;
for ( vs : : const_iterator iip = PhrasesWithInvalidCost . begin ( ) ; iip ! = PhrasesWithInvalidCost . end ( ) ; + + iip )
{
string link = Hypertext ? toString ( " <A HREF= \" %s \" >%s</A> " , getLink ( * iip ) . c_str ( ) , ( * iip ) . c_str ( ) ) : " <B> " + ( * iip ) + " </B> " ;
fprintf ( indexFile , " %s<BR> \n " , link . c_str ( ) ) ;
}
fprintf ( indexFile , " </P> \n " ) ;
}
else
{
fprintf ( indexFile , " <P><B>All phrases have valid sabrina cost.</B></P> \n " ) ;
}
if ( ! InvalidPhrases . empty ( ) )
{
fprintf ( indexFile , " <P><B>Grammatically invalid phrases:</B><BR> \n " ) ;
for ( vs : : const_iterator iip = InvalidPhrases . begin ( ) ; iip ! = InvalidPhrases . end ( ) ; + + iip )
{
string link = Hypertext ? toString ( " <A HREF= \" %s \" >%s</A> " , getLink ( * iip ) . c_str ( ) , ( * iip ) . c_str ( ) ) : " <B> " + ( * iip ) + " </B> " ;
fprintf ( indexFile , " %s<BR> \n " , link . c_str ( ) ) ;
}
fprintf ( indexFile , " </P> \n " ) ;
}
else
{
fprintf ( indexFile , " <P><B>All phrases are grammatically valid.</B></P> \n " ) ;
}
fprintf ( indexFile , " </body></html> \n " ) ;
fclose ( indexFile ) ;
if ( MultipleDocFiles )
{
for ( uint l = 0 ; l ! = 26 ; + + l )
{
fprintf ( PhraseDocFiles [ l ] , " </body></html> \n " ) ;
fclose ( PhraseDocFiles [ l ] ) ;
}
}
else
{
fprintf ( PhraseDocFiles [ 0 ] , " </body></html> \n " ) ;
fclose ( PhraseDocFiles [ 0 ] ) ;
}
}
} // makeIndexFile //
//-----------------------------------------------
// makeActionsBySkillGroupFile
//
//-----------------------------------------------
void makeActionsBySkillGroupFile ( )
{
// progression by skill
FILE * actionsBySkillGroupFile = fopen ( ( DocFileName + " __by_skill.html " ) . c_str ( ) , " wt " ) ;
if ( actionsBySkillGroupFile )
{
fprintf ( actionsBySkillGroupFile , ( " <html><head> \n <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n <title>Progression of " + DocFileName + " </title> \n </head><body> \n " ) . c_str ( ) ) ;
fprintf ( actionsBySkillGroupFile , " <BR><A NAME= \" by_skill_group \" ></A> \n " ) ;
fprintf ( actionsBySkillGroupFile , " <P><B>ACTIONS BY SKILL GROUP:</B><BR> \n <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
map < string , multimap < uint , string > > phrasesBySkill ;
for ( map < uint , pair < string , string > > : : const_iterator ip = Progression . begin ( ) ; ip ! = Progression . end ( ) ; + + ip )
{
const string & phraseCode = ( * ip ) . second . first ;
string skillName = ( * ip ) . second . second . substr ( 0 , ( * ip ) . second . second . find ( " " ) ) ;
string skillValueStr = ( * ip ) . second . second . substr ( ( * ip ) . second . second . find ( " " ) + 1 , ( * ip ) . second . second . size ( ) - ( * ip ) . second . second . find ( " " ) - 1 ) ;
uint skillValue = atoi ( skillValueStr . c_str ( ) ) ;
map < string , multimap < uint , string > > : : iterator it = phrasesBySkill . find ( skillName ) ;
if ( it ! = phrasesBySkill . end ( ) )
{
( * it ) . second . insert ( make_pair ( skillValue , phraseCode ) ) ;
}
else
{
multimap < uint , string > m ;
m . insert ( make_pair ( skillValue , phraseCode ) ) ;
phrasesBySkill . insert ( make_pair ( skillName , m ) ) ;
}
}
map < string , multimap < uint , string > > : : iterator itPhrasesBySkill ;
for ( itPhrasesBySkill = phrasesBySkill . begin ( ) ; itPhrasesBySkill ! = phrasesBySkill . end ( ) ; + + itPhrasesBySkill )
{
CVectorSString dicoResult ;
Dico . lookup ( ( * itPhrasesBySkill ) . first , dicoResult , true ) ;
if ( ! dicoResult . empty ( ) )
fprintf ( actionsBySkillGroupFile , " <tr><td><A HREF= \" #%s \" >%s</A></td></tr> \n " , ( * itPhrasesBySkill ) . first . c_str ( ) , dicoResult [ 0 ] . c_str ( ) ) ;
else
fprintf ( actionsBySkillGroupFile , " <tr><td><A HREF= \" #%s \" >%s</A></td></tr> \n " , ( * itPhrasesBySkill ) . first . c_str ( ) , ( * itPhrasesBySkill ) . first . c_str ( ) ) ;
}
for ( itPhrasesBySkill = phrasesBySkill . begin ( ) ; itPhrasesBySkill ! = phrasesBySkill . end ( ) ; + + itPhrasesBySkill )
{
CVectorSString dicoResult ;
Dico . lookup ( ( * itPhrasesBySkill ) . first , dicoResult , true ) ;
if ( ! dicoResult . empty ( ) )
fprintf ( actionsBySkillGroupFile , " <tr><td><A NAME= \" %s \" ><B>%s</B></A><BR></td></tr> \n " , ( * itPhrasesBySkill ) . first . c_str ( ) , dicoResult [ 0 ] . c_str ( ) ) ;
else
fprintf ( actionsBySkillGroupFile , " <tr><td><A NAME= \" %s \" ><B>%s</B></A><BR></td></tr> \n " , ( * itPhrasesBySkill ) . first . c_str ( ) , ( * itPhrasesBySkill ) . first . c_str ( ) ) ;
multimap < uint , string > : : iterator it ;
for ( it = ( * itPhrasesBySkill ) . second . begin ( ) ; it ! = ( * itPhrasesBySkill ) . second . end ( ) ; + + it )
{
fprintf ( actionsBySkillGroupFile , " <tr><td>%d</td><td>%s</td><td>%s<BR></td></tr> \n " , ( * it ) . first , PhraseCodeToLink [ ( * it ) . second ] . c_str ( ) , PhraseTitles [ ( * it ) . second ] . c_str ( ) ) ;
}
}
fprintf ( actionsBySkillGroupFile , " </tbody><table></P> \n " ) ;
fprintf ( actionsBySkillGroupFile , " </body></html> \n " ) ;
fclose ( actionsBySkillGroupFile ) ;
}
} // makeActionsBySkillGroupFile //
//-----------------------------------------------
// makeActionsBySkillValueFile
//
//-----------------------------------------------
void makeActionsBySkillValueFile ( )
{
FILE * actionsBySkillValueFile = fopen ( ( DocFileName + " __by_skill_value.html " ) . c_str ( ) , " wt " ) ;
if ( actionsBySkillValueFile )
{
fprintf ( actionsBySkillValueFile , ( " <html><head> \n <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n <title>Progression of " + DocFileName + " </title> \n </head><body> \n " ) . c_str ( ) ) ;
// Progression (phrases sorted by skill value)
fprintf ( actionsBySkillValueFile , " <BR><A NAME= \" by_skill_value \" ></A> \n " ) ;
fprintf ( actionsBySkillValueFile , " <P><B>ACTIONS BY SKILL VALUE: <A HREF= \" %s \" >[detail]</A></B> \n <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " , ( DocFileName + " __by_skill_value_detail.html " ) . c_str ( ) ) ;
fprintf ( actionsBySkillValueFile , " <tr><td><B>File</B></td><td><B>Name</B></td><td><B>Skill needed</B><BR></td></tr> \n " ) ;
map < string , string > phraseCodeToLink ;
for ( map < uint , pair < string , string > > : : const_iterator ip = Progression . begin ( ) ; ip ! = Progression . end ( ) ; + + ip )
{
const string & phraseCode = ( * ip ) . second . first ;
fprintf ( actionsBySkillValueFile , " <tr><td><font size=2>%s</font></td><td><font size=2>%s</font></td><td><B><font size=2>%s</font></B><BR></td></tr> \n " , PhraseCodeToLink [ phraseCode ] . c_str ( ) , /*newbrickTitle.c_str(),*/ PhraseTitles [ phraseCode ] . c_str ( ) , ( * ip ) . second . second . c_str ( ) ) ;
}
fprintf ( actionsBySkillValueFile , " </tbody><table></P> \n " ) ;
fprintf ( actionsBySkillValueFile , " </body></html> \n " ) ;
fclose ( actionsBySkillValueFile ) ;
}
} // makeActionsBySkillValueFile //
//-----------------------------------------------
// makeActionsBySkillValueDetailFile
//
//-----------------------------------------------
void makeActionsBySkillValueDetailFile ( )
{
FILE * actionsBySkillValueDetailFile = fopen ( ( DocFileName + " __by_skill_value_detail.html " ) . c_str ( ) , " wt " ) ;
if ( actionsBySkillValueDetailFile )
{
fprintf ( actionsBySkillValueDetailFile , ( " <html><head> \n <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n <title>Progression of " + DocFileName + " </title> \n </head><body> \n " ) . c_str ( ) ) ;
// Progression summary (phrases sorted by skill value)
fprintf ( actionsBySkillValueDetailFile , " <BR><A NAME= \" progression \" ></A> \n " ) ;
fprintf ( actionsBySkillValueDetailFile , " <P><B>ACTIONS BY SKILL VALUE:</B><BR> \n <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
fprintf ( actionsBySkillValueDetailFile , " <tr><td><B>File</B></td><td><B>Name</B></td><td><B>Skill needed</B><BR></td><td><B>Sabrina cost</B></td><td><B>Bricks ...</B></td></tr> \n " ) ;
set < string > effects ;
map < string , set < string > > effectAndModifiers ;
for ( map < uint , pair < string , string > > : : const_iterator ip = Progression . begin ( ) ; ip ! = Progression . end ( ) ; + + ip )
{
const string & phraseCode = ( * ip ) . second . first ;
fprintf ( actionsBySkillValueDetailFile , " <tr><td><font size=2>%s</font></td><td><font size=2>%s</font></td><td><B><font size=2>%s</font></B></td><td><font size=2>%d</font></td> " , PhraseCodeToLink [ phraseCode ] . c_str ( ) , PhraseTitles [ phraseCode ] . c_str ( ) , ( * ip ) . second . second . c_str ( ) , PhraseSabrinaCosts [ phraseCode ] ) ;
msvs : : iterator itPhrases = Phrases . find ( phraseCode ) ;
if ( itPhrases ! = Phrases . end ( ) )
{
string effect ;
uint modifierCount = 0 ;
uint creditCount = 0 ;
for ( uint i = 0 ; i < ( * itPhrases ) . second . size ( ) ; + + i )
{
string brick = ( * itPhrases ) . second [ i ] ;
string color ;
switch ( brick [ brick . size ( ) - getBrickTypeLetterRPos ( brick ) ] )
{
case ' P ' : color = " Black " ;
break ;
case ' E ' :
{
color = " Brown " ;
effects . insert ( brick ) ;
if ( effectAndModifiers . find ( brick ) = = effectAndModifiers . end ( ) )
{
set < string > s ;
effectAndModifiers . insert ( make_pair ( brick , s ) ) ;
}
effect = brick ;
}
break ;
case ' O ' : color = " Green " ;
break ;
case ' M ' :
{
color = " Blue " ;
effectAndModifiers [ effect ] . insert ( brick ) ;
modifierCount + + ;
}
break ;
case ' C ' : color = " Red " ; creditCount + + ;
break ;
default :
color = " Black " ;
}
string text = BrickInfo [ brick ] . Text ;
if ( text . empty ( ) )
{
text = strlwr ( brick ) ;
nlwarning ( " %s not found in BrickInfo " , brick . c_str ( ) ) ;
}
else
{
if ( text . find ( " $|sap " ) ! = - 1 )
{
text = text . substr ( 0 , text . size ( ) - 5 ) ;
string str = brick . substr ( brick . size ( ) - 5 , 5 ) ;
text + = toString ( atoi ( str . c_str ( ) ) ) ;
}
}
fprintf ( actionsBySkillValueDetailFile , " <td><FONT COLOR= \" %s \" SIZE=2>%s</FONT></td> " , color . c_str ( ) , text . c_str ( ) ) ;
}
}
else
{
nlerror ( " not found : %s " , phraseCode . c_str ( ) ) ;
}
fprintf ( actionsBySkillValueDetailFile , " </tr> \n " ) ;
}
fprintf ( actionsBySkillValueDetailFile , " </tbody><table></P> \n " ) ;
fprintf ( actionsBySkillValueDetailFile , " </body></html> \n " ) ;
fclose ( actionsBySkillValueDetailFile ) ;
}
} // makeActionsBySkillValueDetailFile //
//-----------------------------------------------
// validateBrick
//
//-----------------------------------------------
bool validateBrick ( const string & brk )
{
if ( brk [ 1 ] = = ' C ' ) return true ;
if ( brk [ 1 ] = = ' F ' ) return true ;
if ( brk [ 1 ] = = ' H ' ) return true ;
if ( brk [ 1 ] = = ' M ' ) return true ;
if ( brk [ 1 ] = = ' S ' ) return true ;
return false ;
} // validateBrick //
//-----------------------------------------------
// makeSkillTreeFile
//
//-----------------------------------------------
void makeSkillTreeFile ( char filter , string skillFamily , bool withTraduction )
{
vector < map < string , uint16 > > skillsArray ;
skillsArray . resize ( 6 ) ; // 6 tranches de skill
uint i ;
for ( i = 0 ; i < SkillsTree . SkillsTree . size ( ) ; + + i )
{
string skillCode = SkillsTree . SkillsTree [ i ] . SkillCode ;
if ( skillCode [ 1 ] = = filter )
{
uint sIdx = skillCode . length ( ) - 2 ; // -1 for 'S', -1 for 0
skillsArray [ sIdx ] . insert ( make_pair ( skillCode , SkillsTree . SkillsTree [ i ] . MaxSkillValue ) ) ;
}
}
uint16 maxLine = 0 ;
for ( i = 0 ; i < skillsArray . size ( ) ; + + i )
{
if ( skillsArray [ i ] . size ( ) > maxLine )
{
maxLine = skillsArray [ i ] . size ( ) ;
}
}
string filename = skillFamily + " _skill_tree.html " ;
string filenameWithTraduction = skillFamily + " _skill_tree_detailed.html " ;
FILE * skillTreeFile ;
if ( withTraduction )
skillTreeFile = fopen ( filenameWithTraduction . c_str ( ) , " wt " ) ;
else
skillTreeFile = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( skillTreeFile , " <html><head> \n " ) ;
fprintf ( skillTreeFile , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( skillTreeFile , " <title>SKILL TREE ( %s )</title> \n " , skillFamily . c_str ( ) ) ;
fprintf ( skillTreeFile , " </head><body> \n " ) ;
if ( withTraduction )
fprintf ( skillTreeFile , " <b>SKILL TREE ( %s )</b> \n " , skillFamily . c_str ( ) ) ;
else
fprintf ( skillTreeFile , " <b>SKILL TREE ( %s )</b> [<A HREF= \" %s \" >display traduction</A>]<BR> \n " , skillFamily . c_str ( ) , filenameWithTraduction . c_str ( ) ) ;
fprintf ( skillTreeFile , " <table cellpadding= \" 2 \" cellspacing= \" 2 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
fprintf ( skillTreeFile , " <tr><td><b>0 to 20</b></td><td><b>20 to 50</b></td><td><b>50 to 100</b></td><td><b>100 to 150</b></td><td><b>150 to 200</b></td><td><b>200 to 250</b></td></tr> \n " ) ;
uint j ;
// print line by line
for ( j = 0 ; j < maxLine ; + + j )
{
fprintf ( skillTreeFile , " <tr> " ) ;
// for each column
for ( i = 0 ; i < skillsArray . size ( ) ; + + i )
{
uint p ;
map < string , uint16 > : : iterator itSkillcode ;
for ( itSkillcode = skillsArray [ i ] . begin ( ) , p = 0 ; itSkillcode ! = skillsArray [ i ] . end ( ) & & p < j ; + + itSkillcode , + + p ) ;
if ( itSkillcode ! = skillsArray [ i ] . end ( ) )
{
if ( withTraduction )
{
CVectorSString dicoResult ;
Dico . lookup ( ( * itSkillcode ) . first , dicoResult , true ) ;
if ( dicoResult . empty ( ) )
fprintf ( skillTreeFile , " <td>%s : ???</td> " , ( * itSkillcode ) . first . c_str ( ) ) ;
else
fprintf ( skillTreeFile , " <td>%s</td> " , dicoResult [ 0 ] . c_str ( ) ) ;
}
else
fprintf ( skillTreeFile , " <td>%s</td> " , ( * itSkillcode ) . first . c_str ( ) ) ;
}
else
fprintf ( skillTreeFile , " <td></td> " ) ;
}
fprintf ( skillTreeFile , " </tr> \n " ) ;
}
fprintf ( skillTreeFile , " </tbody><table></P> \n " ) ;
fprintf ( skillTreeFile , " </body></html> \n " ) ;
fclose ( skillTreeFile ) ;
} // makeSkillTreeFile //
//-----------------------------------------------
// MAIN
//
//-----------------------------------------------
int main ( int argc , char * argv [ ] )
{
// parse command line
const char * inputFilename = NULL ;
for ( uint i = 1 ; ( sint ) i ! = argc ; i + + )
{
const char * arg = argv [ i ] ;
if ( arg [ 0 ] = = ' - ' )
{
switch ( arg [ 1 ] )
{
case ' p ' :
+ + i ;
if ( ( sint ) i = = argc )
{
fprintf ( stderr , " Missing <sheet path> after -p option \n " ) ;
usage ( argv [ 0 ] , stderr ) ;
exit ( 0 ) ;
}
inputSheetPath = argv [ i ] ;
break ;
case ' o ' :
+ + i ;
if ( ( sint ) i = = argc )
{
fprintf ( stderr , " Missing <phrasePath> after -o option \n " ) ;
usage ( argv [ 0 ] , stderr ) ;
exit ( 0 ) ;
}
PhrasePath = argv [ i ] ;
if ( PhrasePath [ PhrasePath . size ( ) - 1 ] ! = ' / ' )
PhrasePath + = ' / ' ;
break ;
case ' b ' :
GenerateBrickProgression = true ;
break ;
case ' d ' :
ProduceDocFromExistingPhrases = true ;
break ;
case ' m ' :
MultipleDocFiles = true ;
break ;
case ' n ' :
Hypertext = false ;
break ;
}
}
else
{
if ( CFile : : getExtension ( arg ) = = " csv " )
{
inputFilename = arg ;
}
else
nlerror ( " Unrecognized extension in %s " , arg ) ;
}
}
Dico . init ( ) ;
loadSheetPath ( ) ;
FormLoader = UFormLoader : : createLoader ( ) ;
CSheetId : : init ( ) ;
CSheetId skillTreeSheet ( " skills.skill_tree " ) ;
CSmartPtr < UForm > skillTreeForm = FormLoader - > loadForm ( " skills.skill_tree " ) ;
SkillsTree . readGeorges ( skillTreeForm , skillTreeSheet ) ;
makeSkillTreeFile ( ' C ' , " craft " , false ) ;
makeSkillTreeFile ( ' F ' , " fight " , false ) ;
makeSkillTreeFile ( ' H ' , " forage " , false ) ;
makeSkillTreeFile ( ' M ' , " magic " , false ) ;
makeSkillTreeFile ( ' C ' , " craft " , true ) ;
makeSkillTreeFile ( ' F ' , " fight " , true ) ;
makeSkillTreeFile ( ' H ' , " forage " , true ) ;
makeSkillTreeFile ( ' M ' , " magic " , true ) ;
// Load bricks from the csv
UseBricks = ProduceDocFromExistingPhrases ;
if ( UseBricks )
{
if ( ! inputFilename )
{
usage ( argv [ 0 ] , stderr ) ;
exit ( 0 ) ;
}
loadBricks ( inputFilename ) ;
}
// Phrases
if ( ProduceDocFromExistingPhrases )
{
loadBrickGrammar ( ) ;
loadBrickTitles ( ) ;
loadPhraseTitles ( ) ;
DocFileNameRoot = toString ( " %s " , CFile : : getFilenameWithoutExtension ( inputFilename ) . c_str ( ) ) ;
// index
makeIndexFile ( ) ;
// progression by skill
makeActionsBySkillGroupFile ( ) ;
// Progression (phrases sorted by skill value)
makeActionsBySkillValueFile ( ) ;
// Progression (phrases sorted by skill value + detail)
makeActionsBySkillValueDetailFile ( ) ;
}
if ( GenerateBrickProgression )
{
map < uint , map < string , set < string > > > levelToBrick ;
map < string , string > phraseToSkill ;
for ( map < uint , pair < string , string > > : : const_iterator ip = Progression . begin ( ) ; ip ! = Progression . end ( ) ; + + ip )
{
const string & phraseCode = ( * ip ) . second . first ;
string skillTmp = ( * ip ) . second . second . c_str ( ) ;
phraseToSkill . insert ( make_pair ( phraseCode , skillTmp ) ) ;
if ( skillTmp . empty ( ) = = false )
{
// get skill
string skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
// get level
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
if ( levelStr . find ( " . " ) ! = - 1 ) levelStr = levelStr . substr ( 0 , levelStr . size ( ) - 1 ) ;
uint level = atoi ( levelStr . c_str ( ) ) ;
map < uint , map < string , set < string > > > : : iterator itLvl = levelToBrick . find ( level ) ;
if ( itLvl = = levelToBrick . end ( ) )
{
set < string > s ;
map < string , set < string > > mp ;
mp . insert ( make_pair ( skill , s ) ) ;
levelToBrick . insert ( make_pair ( level , mp ) ) ;
}
else
{
if ( ( * itLvl ) . second . find ( skill ) = = ( * itLvl ) . second . end ( ) )
{
set < string > s ;
( * itLvl ) . second . insert ( make_pair ( skill , s ) ) ;
}
}
msvs : : iterator itPhrases = Phrases . find ( phraseCode ) ;
if ( itPhrases ! = Phrases . end ( ) )
{
string effect ;
for ( uint i = 0 ; i < ( * itPhrases ) . second . size ( ) ; + + i )
{
string brick = ( * itPhrases ) . second [ i ] ;
if ( levelToBrick [ level ] [ skill ] . find ( brick ) = = levelToBrick [ level ] [ skill ] . end ( ) )
{
levelToBrick [ level ] [ skill ] . insert ( brick ) ;
}
}
}
}
}
// get family & color
map < string , string > brickToColor ;
map < string , string > brickToFamily ;
map < string , CBrickInfo > : : iterator itBInf ;
for ( itBInf = BrickInfo . begin ( ) ; itBInf ! = BrickInfo . end ( ) ; + + itBInf )
{
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
string color ;
string family ;
if ( brk [ brk . size ( ) - getBrickTypeLetterRPos ( brk ) ] = = ' M ' )
{
color = " Blue " ;
family = " Modifier " ;
}
if ( brk [ brk . size ( ) - getBrickTypeLetterRPos ( brk ) ] = = ' C ' )
{
color = " Red " ;
family = " Credit " ;
}
if ( brk [ brk . size ( ) - getBrickTypeLetterRPos ( brk ) ] = = ' O ' )
{
color = " Green " ;
family = " Option " ;
}
if ( brk [ brk . size ( ) - getBrickTypeLetterRPos ( brk ) ] = = ' P ' )
{
color = " Black " ;
family = " Root " ;
}
if ( brk [ brk . size ( ) - getBrickTypeLetterRPos ( brk ) ] = = ' E ' )
{
color = " Brown " ;
family = " Effect " ;
}
brickToColor . insert ( make_pair ( brk , color ) ) ;
brickToFamily . insert ( make_pair ( brk , family ) ) ;
}
// get phrases where the brick can be found
map < string , map < string , string > > brickToPhrases ;
msvs : : iterator itPhrases ;
for ( itPhrases = Phrases . begin ( ) ; itPhrases ! = Phrases . end ( ) ; + + itPhrases )
{
for ( uint i = 0 ; i < ( * itPhrases ) . second . size ( ) ; + + i )
{
string brick = ( * itPhrases ) . second [ i ] ;
if ( brickToPhrases . find ( brick ) = = brickToPhrases . end ( ) )
{
map < string , string > m ;
m . insert ( make_pair ( ( * itPhrases ) . first , phraseToSkill [ ( * itPhrases ) . first ] ) ) ;
brickToPhrases . insert ( make_pair ( brick , m ) ) ;
}
else
{
brickToPhrases [ brick ] . insert ( make_pair ( ( * itPhrases ) . first , phraseToSkill [ ( * itPhrases ) . first ] ) ) ;
}
}
}
// get skill when a brick is learnt
map < string , string > brickToLearnSkill ;
map < string , map < string , string > > : : iterator itLearn ;
for ( itLearn = brickToPhrases . begin ( ) ; itLearn ! = brickToPhrases . end ( ) ; + + itLearn )
{
string minSkill ;
uint minLevel = 250 ;
mss : : iterator itPh ;
for ( itPh = ( * itLearn ) . second . begin ( ) ; itPh ! = ( * itLearn ) . second . end ( ) ; + + itPh )
{
string skillTmp = ( * itPh ) . second ;
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
uint level = atoi ( levelStr . c_str ( ) ) ;
if ( level < minLevel | | minSkill . empty ( ) )
{
minSkill = skillTmp ;
minLevel = level ;
}
}
brickToLearnSkill . insert ( make_pair ( ( * itLearn ) . first , minSkill ) ) ;
}
// PHRASES
// write header and title bar
string filename ;
filename = DocFileNameRoot + " _m.html " ;
FILE * brickPhraseDocFile_m = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickPhraseDocFile_m , " <html><head> \n " ) ;
fprintf ( brickPhraseDocFile_m , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickPhraseDocFile_m , " <title>Brick phrases</title> \n " ) ;
fprintf ( brickPhraseDocFile_m , " </head><body> \n " ) ;
fprintf ( brickPhraseDocFile_m , " <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
filename = DocFileNameRoot + " _c.html " ;
FILE * brickPhraseDocFile_c = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickPhraseDocFile_c , " <html><head> \n " ) ;
fprintf ( brickPhraseDocFile_c , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickPhraseDocFile_c , " <title>Brick phrases</title> \n " ) ;
fprintf ( brickPhraseDocFile_c , " </head><body> \n " ) ;
fprintf ( brickPhraseDocFile_c , " <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
filename = DocFileNameRoot + " _o.html " ;
FILE * brickPhraseDocFile_o = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickPhraseDocFile_o , " <html><head> \n " ) ;
fprintf ( brickPhraseDocFile_o , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickPhraseDocFile_o , " <title>Brick phrases</title> \n " ) ;
fprintf ( brickPhraseDocFile_o , " </head><body> \n " ) ;
fprintf ( brickPhraseDocFile_o , " <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
filename = DocFileNameRoot + " _p.html " ;
FILE * brickPhraseDocFile_p = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickPhraseDocFile_p , " <html><head> \n " ) ;
fprintf ( brickPhraseDocFile_p , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickPhraseDocFile_p , " <title>Brick phrases</title> \n " ) ;
fprintf ( brickPhraseDocFile_p , " </head><body> \n " ) ;
fprintf ( brickPhraseDocFile_p , " <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
filename = DocFileNameRoot + " _e.html " ;
FILE * brickPhraseDocFile_e = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickPhraseDocFile_e , " <html><head> \n " ) ;
fprintf ( brickPhraseDocFile_e , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickPhraseDocFile_e , " <title>Brick phrases</title> \n " ) ;
fprintf ( brickPhraseDocFile_e , " </head><body> \n " ) ;
fprintf ( brickPhraseDocFile_e , " <table cellpadding= \" 0 \" cellspacing= \" 1 \" border= \" 0 \" style= \" text-align: left; \" ><tbody> \n " ) ;
for ( itBInf = BrickInfo . begin ( ) ; itBInf ! = BrickInfo . end ( ) ; + + itBInf )
{
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
string code = strlwr ( brk . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Modifier " )
fprintf ( brickPhraseDocFile_m , " <tr><td><A NAME= \" %s \" ><FONT COLOR= \" Blue \" >%s</FONT></A></td><td></td></tr> \n " , brk . c_str ( ) , code . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Credit " )
fprintf ( brickPhraseDocFile_c , " <tr><td><A NAME= \" %s \" ><FONT COLOR= \" Red \" >%s</FONT></A></td><td></td></tr> \n " , brk . c_str ( ) , code . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Option " )
fprintf ( brickPhraseDocFile_o , " <tr><td><A NAME= \" %s \" ><FONT COLOR= \" Green \" >%s</FONT></A></td><td></td></tr> \n " , brk . c_str ( ) , code . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Effect " )
fprintf ( brickPhraseDocFile_e , " <tr><td><A NAME= \" %s \" ><FONT COLOR= \" Brown \" >%s</FONT></A></td><td></td></tr> \n " , brk . c_str ( ) , code . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Root " )
fprintf ( brickPhraseDocFile_p , " <tr><td><A NAME= \" %s \" ><FONT COLOR= \" Black \" >%s</FONT></A></td><td></td></tr> \n " , brk . c_str ( ) , code . c_str ( ) ) ;
map < string , map < string , string > > : : iterator itPhrases = brickToPhrases . find ( brk ) ;
if ( itPhrases ! = brickToPhrases . end ( ) )
{
map < string , string > : : iterator itPh ;
for ( itPh = ( * itPhrases ) . second . begin ( ) ; itPh ! = ( * itPhrases ) . second . end ( ) ; + + itPh )
{
if ( brickToFamily [ brk ] = = " Modifier " )
fprintf ( brickPhraseDocFile_m , " <tr><td></td><td><A HREF= \" %s_%c.html#%s \" >%s</A></td></tr> \n " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Credit " )
fprintf ( brickPhraseDocFile_c , " <tr><td></td><td><A HREF= \" %s_%c.html#%s \" >%s</A></td></tr> \n " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Option " )
fprintf ( brickPhraseDocFile_o , " <tr><td></td><td><A HREF= \" %s_%c.html#%s \" >%s</A></td></tr> \n " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Effect " )
fprintf ( brickPhraseDocFile_e , " <tr><td></td><td><A HREF= \" %s_%c.html#%s \" >%s</A></td></tr> \n " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
if ( brickToFamily [ brk ] = = " Root " )
fprintf ( brickPhraseDocFile_p , " <tr><td></td><td><A HREF= \" %s_%c.html#%s \" >%s</A></td></tr> \n " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
}
}
}
fprintf ( brickPhraseDocFile_m , " </tbody><table></P> \n " ) ;
fprintf ( brickPhraseDocFile_m , " </body></html> \n " ) ;
fclose ( brickPhraseDocFile_m ) ;
fprintf ( brickPhraseDocFile_c , " </tbody><table></P> \n " ) ;
fprintf ( brickPhraseDocFile_c , " </body></html> \n " ) ;
fclose ( brickPhraseDocFile_c ) ;
fprintf ( brickPhraseDocFile_o , " </tbody><table></P> \n " ) ;
fprintf ( brickPhraseDocFile_o , " </body></html> \n " ) ;
fclose ( brickPhraseDocFile_o ) ;
fprintf ( brickPhraseDocFile_e , " </tbody><table></P> \n " ) ;
fprintf ( brickPhraseDocFile_e , " </body></html> \n " ) ;
fclose ( brickPhraseDocFile_e ) ;
fprintf ( brickPhraseDocFile_p , " </tbody><table></P> \n " ) ;
fprintf ( brickPhraseDocFile_p , " </body></html> \n " ) ;
fclose ( brickPhraseDocFile_p ) ;
// CODE
// write header and title bar
filename = DocFileNameRoot + " .html " ;
FILE * brickDocFile = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickDocFile , " <html><head> \n " ) ;
fprintf ( brickDocFile , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickDocFile , " <title>Bricks infos</title> \n " ) ;
fprintf ( brickDocFile , " </head><body> \n " ) ;
fprintf ( brickDocFile , " <table cellpadding= \" 1 \" cellspacing= \" 1 \" border= \" 0 \" ><tbody> \n " ) ;
fprintf ( brickDocFile , " <tr> \n " ) ;
fprintf ( brickDocFile , " <td><b>*Code*</b></td> \n " ) ;
fprintf ( brickDocFile , " <td><b><a href= \" %s_name.html \" >Name</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickDocFile , " <td><b><a href= \" %s_family.html \" >Family</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickDocFile , " <td><b>Required Skill Name</b></td> \n " ) ;
fprintf ( brickDocFile , " <td><b><a href= \" %s_required_skill_value.html \" >Required Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickDocFile , " <td><b>Learn Skill Name</b></td> \n " ) ;
fprintf ( brickDocFile , " <td><b><a href= \" %s_learn_skill_value.html \" >Learn Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickDocFile , " <td><b>Found In Phrases</b></td> \n " ) ;
fprintf ( brickDocFile , " </tr> \n " ) ;
// write infos
for ( itBInf = BrickInfo . begin ( ) ; itBInf ! = BrickInfo . end ( ) ; + + itBInf )
{
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
string skillTmp = ( * itBInf ) . second . LearnSkills ;
string skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
CVectorSString dicoResult ;
Dico . lookup ( skill , dicoResult , true ) ;
if ( dicoResult . empty ( ) ) continue ;
// color
string color = brickToColor [ brk ] ;
// code
string code = strlwr ( brk . c_str ( ) ) ;
fprintf ( brickDocFile , " <tr><td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , code . c_str ( ) ) ;
// name
string name = ( * itBInf ) . second . Text ;
fprintf ( brickDocFile , " <td>%s</td> \n " , name . c_str ( ) ) ;
// family
string family = brickToFamily [ brk ] ;
fprintf ( brickDocFile , " <td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , family . c_str ( ) ) ;
// required skill name
fprintf ( brickDocFile , " <td>%s</td> \n " , dicoResult [ 0 ] . c_str ( ) ) ;
// required skill value
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// learn skill name
string learnSkillTmp = brickToLearnSkill [ brk ] ;
skill = learnSkillTmp . substr ( 0 , learnSkillTmp . find_first_of ( " " ) ) ;
fprintf ( brickDocFile , " <td>%s</td> \n " , skill . c_str ( ) ) ;
// learn skill value
if ( learnSkillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = learnSkillTmp . find_first_of ( " " ) ;
levelStr = learnSkillTmp . substr ( idx + 1 , learnSkillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = learnSkillTmp . find_first_of ( " " ) ;
levelStr = learnSkillTmp . substr ( idx + 1 , learnSkillTmp . size ( ) - idx ) ;
}
fprintf ( brickDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// phrase list
fprintf ( brickDocFile , " <td> " ) ;
map < string , map < string , string > > : : iterator itPhrases = brickToPhrases . find ( brk ) ;
if ( itPhrases ! = brickToPhrases . end ( ) )
{
map < string , string > : : iterator itPh ;
uint i ;
for ( itPh = ( * itPhrases ) . second . begin ( ) , i = 0 ; itPh ! = ( * itPhrases ) . second . end ( ) & & i < 2 ; + + itPh , + + i )
{
if ( MultipleDocFiles )
fprintf ( brickDocFile , " <A HREF= \" %s_%c.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
else
fprintf ( brickDocFile , " <A HREF= \" %s.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
}
if ( i = = 2 )
{
char type = family [ 0 ] ;
fprintf ( brickDocFile , " [<A HREF= \" %s_%c.html#%s \" >...</A>] " , DocFileNameRoot . c_str ( ) , type , brk . c_str ( ) ) ;
}
}
fprintf ( brickDocFile , " </td></tr> \n " ) ;
}
fprintf ( brickDocFile , " </tbody><table></P> \n " ) ;
fprintf ( brickDocFile , " </body></html> \n " ) ;
fclose ( brickDocFile ) ;
// NAME
// write header and title bar
filename = DocFileNameRoot + " _name.html " ;
FILE * brickNameDocFile = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickNameDocFile , " <html><head> \n " ) ;
fprintf ( brickNameDocFile , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickNameDocFile , " <title>Bricks infos</title> \n " ) ;
fprintf ( brickNameDocFile , " </head><body> \n " ) ;
fprintf ( brickNameDocFile , " <table cellpadding= \" 1 \" cellspacing= \" 1 \" border= \" 0 \" ><tbody> \n " ) ;
fprintf ( brickNameDocFile , " <tr> \n " ) ;
fprintf ( brickNameDocFile , " <td><b><a href= \" %s.html \" >Code</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickNameDocFile , " <td><b>*Name*</b></td> \n " ) ;
fprintf ( brickNameDocFile , " <td><b><a href= \" %s_family.html \" >Family</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickNameDocFile , " <td><b>Required Skill Name</b></td> \n " ) ;
fprintf ( brickNameDocFile , " <td><b><a href= \" %s_required_skill_value.html \" >Required Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickNameDocFile , " <td><b>Learn Skill Name</b></td> \n " ) ;
fprintf ( brickNameDocFile , " <td><b><a href= \" %s_learn_skill_value.html \" >Learn Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickNameDocFile , " <td><b>Found In Phrases</b></td> \n " ) ;
fprintf ( brickNameDocFile , " </tr> \n " ) ;
map < string , string > nameToCode ;
for ( itBInf = BrickInfo . begin ( ) ; itBInf ! = BrickInfo . end ( ) ; + + itBInf )
{
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
// code
string code = strlwr ( brk . c_str ( ) ) ;
// name
string name = ( * itBInf ) . second . Text ;
if ( ! name . empty ( ) )
nameToCode . insert ( make_pair ( name , brk ) ) ;
}
mss : : iterator itNTC ;
for ( itNTC = nameToCode . begin ( ) ; itNTC ! = nameToCode . end ( ) ; + + itNTC )
{
itBInf = BrickInfo . find ( ( * itNTC ) . second ) ;
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
string skillTmp = ( * itBInf ) . second . LearnSkills ;
string skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
CVectorSString dicoResult ;
Dico . lookup ( skill , dicoResult , true ) ;
if ( dicoResult . empty ( ) ) continue ;
// color
string color = brickToColor [ brk ] ;
// code
string code = strlwr ( brk . c_str ( ) ) ;
fprintf ( brickNameDocFile , " <tr><td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , code . c_str ( ) ) ;
// name
string name = ( * itBInf ) . second . Text ;
fprintf ( brickNameDocFile , " <td>%s</td> \n " , name . c_str ( ) ) ;
// family
string family = brickToFamily [ brk ] ;
fprintf ( brickNameDocFile , " <td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , family . c_str ( ) ) ;
// required skill name
fprintf ( brickNameDocFile , " <td>%s</td> \n " , dicoResult [ 0 ] . c_str ( ) ) ;
// required skill value
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickNameDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// learn skill name
skillTmp = brickToLearnSkill [ brk ] ;
skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
fprintf ( brickNameDocFile , " <td>%s</td> \n " , skill . c_str ( ) ) ;
// learn skill value
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickNameDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// phrase list
fprintf ( brickNameDocFile , " <td> " ) ;
map < string , map < string , string > > : : iterator itPhrases = brickToPhrases . find ( brk ) ;
if ( itPhrases ! = brickToPhrases . end ( ) )
{
map < string , string > : : iterator itPh ;
uint i ;
for ( itPh = ( * itPhrases ) . second . begin ( ) , i = 0 ; itPh ! = ( * itPhrases ) . second . end ( ) & & i < 2 ; + + itPh , + + i )
{
if ( MultipleDocFiles )
fprintf ( brickNameDocFile , " <A HREF= \" %s_%c.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
else
fprintf ( brickNameDocFile , " <A HREF= \" %s.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
}
if ( i = = 2 )
{
char type = family [ 0 ] ;
fprintf ( brickNameDocFile , " [<A HREF= \" %s_%c.html#%s \" >...</A>] " , DocFileNameRoot . c_str ( ) , type , brk . c_str ( ) ) ;
}
}
fprintf ( brickNameDocFile , " </td></tr> \n " ) ;
}
fprintf ( brickNameDocFile , " </tbody><table></P> \n " ) ;
fprintf ( brickNameDocFile , " </body></html> \n " ) ;
fclose ( brickNameDocFile ) ;
// FAMILY
// write header and title bar
filename = DocFileNameRoot + " _family.html " ;
FILE * brickFamilyDocFile = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickFamilyDocFile , " <html><head> \n " ) ;
fprintf ( brickFamilyDocFile , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickFamilyDocFile , " <title>Bricks infos</title> \n " ) ;
fprintf ( brickFamilyDocFile , " </head><body> \n " ) ;
fprintf ( brickFamilyDocFile , " <table cellpadding= \" 1 \" cellspacing= \" 1 \" border= \" 0 \" ><tbody> \n " ) ;
fprintf ( brickFamilyDocFile , " <tr> \n " ) ;
fprintf ( brickFamilyDocFile , " <td><b><a href= \" %s.html \" >Code</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickFamilyDocFile , " <td><b><a href= \" %s_name.html \" >Name</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickFamilyDocFile , " <td><b>*Family*</b></td> \n " ) ;
fprintf ( brickFamilyDocFile , " <td><b>Required Skill Name</b></td> \n " ) ;
fprintf ( brickFamilyDocFile , " <td><b><a href= \" %s_required_skill_value.html \" >Required Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickFamilyDocFile , " <td><b>Learn Skill Name</b></td> \n " ) ;
fprintf ( brickFamilyDocFile , " <td><b><a href= \" %s_learn_skill_value.html \" >Learn Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickFamilyDocFile , " <td><b>Found In Phrases</b></td> \n " ) ;
fprintf ( brickFamilyDocFile , " </tr> \n " ) ;
// write infos
multimap < string , string > familyToCode ;
for ( itBInf = BrickInfo . begin ( ) ; itBInf ! = BrickInfo . end ( ) ; + + itBInf )
{
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
// family
string family = brickToFamily [ brk ] ;
familyToCode . insert ( make_pair ( family , brk ) ) ;
}
multimap < string , string > : : iterator itFTC ;
for ( itFTC = familyToCode . begin ( ) ; itFTC ! = familyToCode . end ( ) ; + + itFTC )
{
itBInf = BrickInfo . find ( ( * itFTC ) . second ) ;
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
string skillTmp = ( * itBInf ) . second . LearnSkills ;
string skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
CVectorSString dicoResult ;
Dico . lookup ( skill , dicoResult , true ) ;
if ( dicoResult . empty ( ) ) continue ;
// color
string color = brickToColor [ brk ] ;
// code
string code = strlwr ( brk . c_str ( ) ) ;
fprintf ( brickFamilyDocFile , " <tr><td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , code . c_str ( ) ) ;
// name
string name = ( * itBInf ) . second . Text ;
fprintf ( brickFamilyDocFile , " <td>%s</td> \n " , name . c_str ( ) ) ;
// family
string family = brickToFamily [ brk ] ;
fprintf ( brickFamilyDocFile , " <td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , family . c_str ( ) ) ;
// required skill name
fprintf ( brickFamilyDocFile , " <td>%s</td> \n " , dicoResult [ 0 ] . c_str ( ) ) ;
// required skill value
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickFamilyDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// learn skill name
skillTmp = brickToLearnSkill [ brk ] ;
skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
fprintf ( brickFamilyDocFile , " <td>%s</td> \n " , skill . c_str ( ) ) ;
// learn skill value
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickFamilyDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// phrase list
fprintf ( brickFamilyDocFile , " <td> " ) ;
map < string , map < string , string > > : : iterator itPhrases = brickToPhrases . find ( brk ) ;
if ( itPhrases ! = brickToPhrases . end ( ) )
{
map < string , string > : : iterator itPh ;
uint i ;
for ( itPh = ( * itPhrases ) . second . begin ( ) , i = 0 ; itPh ! = ( * itPhrases ) . second . end ( ) & & i < 2 ; + + itPh , + + i )
{
if ( MultipleDocFiles )
fprintf ( brickFamilyDocFile , " <A HREF= \" %s_%c.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
else
fprintf ( brickFamilyDocFile , " <A HREF= \" %s.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
}
if ( i = = 2 )
{
char type = family [ 0 ] ;
fprintf ( brickFamilyDocFile , " [<A HREF= \" %s_%c.html#%s \" >...</A>] " , DocFileNameRoot . c_str ( ) , type , brk . c_str ( ) ) ;
}
}
fprintf ( brickFamilyDocFile , " </td></tr> \n " ) ;
}
fprintf ( brickFamilyDocFile , " </tbody><table></P> \n " ) ;
fprintf ( brickFamilyDocFile , " </body></html> \n " ) ;
fclose ( brickFamilyDocFile ) ;
// REQUIRED SKILL VALUE
// write header and title bar
filename = DocFileNameRoot + " _required_skill_value.html " ;
FILE * brickRequiredDocFile = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickRequiredDocFile , " <html><head> \n " ) ;
fprintf ( brickRequiredDocFile , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickRequiredDocFile , " <title>Bricks infos</title> \n " ) ;
fprintf ( brickRequiredDocFile , " </head><body> \n " ) ;
fprintf ( brickRequiredDocFile , " <table cellpadding= \" 1 \" cellspacing= \" 1 \" border= \" 0 \" ><tbody> \n " ) ;
fprintf ( brickRequiredDocFile , " <tr> \n " ) ;
fprintf ( brickRequiredDocFile , " <td><b><a href= \" %s.html \" >Code</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickRequiredDocFile , " <td><b><a href= \" %s_name.html \" >Name</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickRequiredDocFile , " <td><b><a href= \" %s_family.html \" >Family</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickRequiredDocFile , " <td><b>Required Skill Name</b></td> \n " ) ;
fprintf ( brickRequiredDocFile , " <td><b>*Required Skill Value*</b></td> \n " ) ;
fprintf ( brickRequiredDocFile , " <td><b>Learn Skill Name</b></td> \n " ) ;
fprintf ( brickRequiredDocFile , " <td><b><a href= \" %s_learn_skill_value.html \" >Learn Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickRequiredDocFile , " <td><b>Found In Phrases</b></td> \n " ) ;
fprintf ( brickRequiredDocFile , " </tr> \n " ) ;
// write infos
multimap < uint , string > requiredSkillValueToCode ;
for ( itBInf = BrickInfo . begin ( ) ; itBInf ! = BrickInfo . end ( ) ; + + itBInf )
{
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
// required skill value
string skillTmp = ( * itBInf ) . second . LearnSkills ;
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
uint level = atoi ( levelStr . c_str ( ) ) ;
requiredSkillValueToCode . insert ( make_pair ( level , brk ) ) ;
}
multimap < uint , string > : : iterator itRTC ;
for ( itRTC = requiredSkillValueToCode . begin ( ) ; itRTC ! = requiredSkillValueToCode . end ( ) ; + + itRTC )
{
itBInf = BrickInfo . find ( ( * itRTC ) . second ) ;
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
string skillTmp = ( * itBInf ) . second . LearnSkills ;
string skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
CVectorSString dicoResult ;
Dico . lookup ( skill , dicoResult , true ) ;
if ( dicoResult . empty ( ) ) continue ;
// color
string color = brickToColor [ brk ] ;
// code
string code = strlwr ( brk . c_str ( ) ) ;
fprintf ( brickRequiredDocFile , " <tr><td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , code . c_str ( ) ) ;
// name
string name = ( * itBInf ) . second . Text ;
fprintf ( brickRequiredDocFile , " <td>%s</td> \n " , name . c_str ( ) ) ;
// family
string family = brickToFamily [ brk ] ;
fprintf ( brickRequiredDocFile , " <td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , family . c_str ( ) ) ;
// required skill name
fprintf ( brickRequiredDocFile , " <td>%s</td> \n " , dicoResult [ 0 ] . c_str ( ) ) ;
// required skill value
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickRequiredDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// learn skill name
skillTmp = brickToLearnSkill [ brk ] ;
skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
fprintf ( brickRequiredDocFile , " <td>%s</td> \n " , skill . c_str ( ) ) ;
// learn skill value
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickRequiredDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// phrase list
fprintf ( brickRequiredDocFile , " <td> " ) ;
map < string , map < string , string > > : : iterator itPhrases = brickToPhrases . find ( brk ) ;
if ( itPhrases ! = brickToPhrases . end ( ) )
{
map < string , string > : : iterator itPh ;
uint i ;
for ( itPh = ( * itPhrases ) . second . begin ( ) , i = 0 ; itPh ! = ( * itPhrases ) . second . end ( ) & & i < 2 ; + + itPh , + + i )
{
if ( MultipleDocFiles )
fprintf ( brickRequiredDocFile , " <A HREF= \" %s_%c.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
else
fprintf ( brickRequiredDocFile , " <A HREF= \" %s.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
}
if ( i = = 2 )
{
char type = family [ 0 ] ;
fprintf ( brickRequiredDocFile , " [<A HREF= \" %s_%c.html#%s \" >...</A>] " , DocFileNameRoot . c_str ( ) , type , brk . c_str ( ) ) ;
}
}
fprintf ( brickRequiredDocFile , " </td></tr> \n " ) ;
}
fprintf ( brickRequiredDocFile , " </tbody><table></P> \n " ) ;
fprintf ( brickRequiredDocFile , " </body></html> \n " ) ;
fclose ( brickRequiredDocFile ) ;
// LEARN SKILL VALUE
// write header and title bar
filename = DocFileNameRoot + " _learn_skill_value.html " ;
FILE * brickLearnDocFile = fopen ( filename . c_str ( ) , " wt " ) ;
fprintf ( brickLearnDocFile , " <html><head> \n " ) ;
fprintf ( brickLearnDocFile , " <meta http-equiv= \" content-type \" content= \" text/html; charset=UTF-8 \" > \n " ) ;
fprintf ( brickLearnDocFile , " <title>Bricks infos</title> \n " ) ;
fprintf ( brickLearnDocFile , " </head><body> \n " ) ;
fprintf ( brickLearnDocFile , " <table cellpadding= \" 1 \" cellspacing= \" 1 \" border= \" 0 \" ><tbody> \n " ) ;
fprintf ( brickLearnDocFile , " <tr> \n " ) ;
fprintf ( brickLearnDocFile , " <td><b><a href= \" %s.html \" >Code</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickLearnDocFile , " <td><b><a href= \" %s_name.html \" >Name</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickLearnDocFile , " <td><b><a href= \" %s_family.html \" >Family</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickLearnDocFile , " <td><b>Required Skill Name</b></td> \n " ) ;
fprintf ( brickLearnDocFile , " <td><b><a href= \" %s_required_skill_value.html \" >Required Skill Value</a></b></td> \n " , DocFileNameRoot . c_str ( ) ) ;
fprintf ( brickLearnDocFile , " <td><b>Learn Skill Name</b></td> \n " ) ;
fprintf ( brickLearnDocFile , " <td><b>*Learn Skill Value*</b></td> \n " ) ;
fprintf ( brickLearnDocFile , " <td><b>Found In Phrases</b></td> \n " ) ;
fprintf ( brickLearnDocFile , " </tr> \n " ) ;
// write infos
multimap < uint , string > learnSkillValueToCode ;
for ( itBInf = BrickInfo . begin ( ) ; itBInf ! = BrickInfo . end ( ) ; + + itBInf )
{
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
// learn skill value
string skillTmp = brickToLearnSkill [ brk ] ;
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
uint level = atoi ( levelStr . c_str ( ) ) ;
learnSkillValueToCode . insert ( make_pair ( level , brk ) ) ;
}
multimap < uint , string > : : iterator itLTC ;
for ( itLTC = learnSkillValueToCode . begin ( ) ; itLTC ! = learnSkillValueToCode . end ( ) ; + + itLTC )
{
itBInf = BrickInfo . find ( ( * itLTC ) . second ) ;
string brk = ( * itBInf ) . first ;
if ( ! validateBrick ( brk ) ) continue ;
string skillTmp = ( * itBInf ) . second . LearnSkills ;
string skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
CVectorSString dicoResult ;
Dico . lookup ( skill , dicoResult , true ) ;
if ( dicoResult . empty ( ) ) continue ;
// color
string color = brickToColor [ brk ] ;
// code
string code = strlwr ( brk . c_str ( ) ) ;
fprintf ( brickLearnDocFile , " <tr><td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , code . c_str ( ) ) ;
// name
string name = ( * itBInf ) . second . Text ;
fprintf ( brickLearnDocFile , " <td>%s</td> \n " , name . c_str ( ) ) ;
// family
string family = brickToFamily [ brk ] ;
fprintf ( brickLearnDocFile , " <td><FONT COLOR= \" %s \" >%s</FONT></td> \n " , color . c_str ( ) , family . c_str ( ) ) ;
// required skill name
fprintf ( brickLearnDocFile , " <td>%s</td> \n " , dicoResult [ 0 ] . c_str ( ) ) ;
// required skill value
string levelStr ;
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickLearnDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// learn skill name
skillTmp = brickToLearnSkill [ brk ] ;
skill = skillTmp . substr ( 0 , skillTmp . find_first_of ( " " ) ) ;
fprintf ( brickLearnDocFile , " <td>%s</td> \n " , skill . c_str ( ) ) ;
// learn skill value
if ( skillTmp . find ( " ; " ) ! = - 1 )
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . find_first_of ( " ; " ) - idx - 1 ) ;
}
else
{
sint idx = skillTmp . find_first_of ( " " ) ;
levelStr = skillTmp . substr ( idx + 1 , skillTmp . size ( ) - idx ) ;
}
fprintf ( brickLearnDocFile , " <td>%s</td> \n " , levelStr . c_str ( ) ) ;
// phrase list
fprintf ( brickLearnDocFile , " <td> " ) ;
map < string , map < string , string > > : : iterator itPhrases = brickToPhrases . find ( brk ) ;
if ( itPhrases ! = brickToPhrases . end ( ) )
{
map < string , string > : : iterator itPh ;
uint i ;
for ( itPh = ( * itPhrases ) . second . begin ( ) , i = 0 ; itPh ! = ( * itPhrases ) . second . end ( ) & & i < 2 ; + + itPh , + + i )
{
if ( MultipleDocFiles )
fprintf ( brickLearnDocFile , " <A HREF= \" %s_%c.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first [ 7 ] , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
else
fprintf ( brickLearnDocFile , " <A HREF= \" %s.html#%s \" >%s</A>,   " , DocFileName . c_str ( ) , ( * itPh ) . first . c_str ( ) , ( * itPh ) . first . c_str ( ) ) ;
}
if ( i = = 2 )
{
char type = family [ 0 ] ;
fprintf ( brickLearnDocFile , " [<A HREF= \" %s_%c.html#%s \" >...</A>] " , DocFileNameRoot . c_str ( ) , type , brk . c_str ( ) ) ;
}
}
fprintf ( brickLearnDocFile , " </td></tr> \n " ) ;
}
fprintf ( brickLearnDocFile , " </tbody><table></P> \n " ) ;
fprintf ( brickLearnDocFile , " </body></html> \n " ) ;
fclose ( brickLearnDocFile ) ;
}
return 0 ;
} // main //