1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // phrase_generator.cpp : Defines the entry point for the console application.
21 //-b -p r:\code\ryzom\data_leveldesign -o r:/code/ryzom/data_leveldesign/leveldesign/game_element/sphrase/magic/ magic_bricks.csv -d -m
22 // -p r:\code\ryzom\data_leveldesign -o r:/code/ryzom/data_leveldesign/leveldesign/game_element/sphrase/magic/ magic_bricks.csv -d -m
31 #include <nel/misc/types_nl.h>
32 #include "nel/misc/path.h"
33 #include "nel/misc/file.h"
34 #include "nel/misc/smart_ptr.h"
35 #include "nel/misc/command.h"
36 #include "nel/misc/common.h"
37 #include "nel/misc/path.h"
38 #include <nel/misc/sstring.h>
39 #include <nel/misc/diff_tool.h>
40 #include "nel/misc/algo.h"
41 #include "nel/misc/words_dictionary.h"
43 #include "nel/georges/u_form.h"
44 #include "nel/georges/u_form_elm.h"
45 #include "nel/georges/u_form_dfn.h"
46 #include "nel/georges/u_form_loader.h"
47 #include "nel/georges/u_type.h"
48 // Georges, bypassing interface
49 #include "georges/stdgeorges.h"
50 #include "georges/form.h"
52 //#include "game_share/xml.h"
53 // Unicode language file
62 #include "skill_tree.h"
64 using namespace NLMISC
;
65 using namespace NLGEORGES
;
69 typedef vector
<string
> vs
;
70 typedef map
< string
, string
> mss
;
71 typedef map
< string
, vs
> msvs
;
73 bool GenerateBrickProgression
= false;
74 bool ProduceDocFromExistingPhrases
= false;
75 bool MultipleDocFiles
= false;
76 bool Hypertext
= true;
77 string PhrasePath
= "r:/code/ryzom/data_leveldesign/leveldesign/game_element/sphrase/";
78 uint NbSheetsGenTries
= 0;
79 uint NbSheetsWritten
= 0;
80 uint NbSheetsRead
= 0;
81 uint NbSheetsRejected
= 0;
86 const string brSheetType
= "sbrick";
87 const string phSheetType
= "sphrase";
88 const string PHRASE_MAGIC_PREFIX
= "abm_"; // action bricks magic (bm for brick filter)
92 CBrickInfo( const string
& ls
="", const string
& t
="",
93 const vs
& props
=vs() ) :
94 LearnSkills(ls
), Text(t
), Props(props
) {}
102 vs OptionBricks
, CounterpartBricks
, AllBricks
, PhrasesWithInvalidCost
, InvalidPhrases
;
103 set
<string
> UsedCounterpartBricks
, UsedCounterpartBrickFamiliesInPhrase
;
104 map
<string
, sint
> SabrinaCosts
;
105 map
<string
, sint
> PhraseSabrinaCosts
;
106 map
<string
, bool> PhraseCastable
;
107 map
<string
, CBrickInfo
> BrickInfo
;
109 multimap
< uint
, pair
<string
, string
> > Progression
; // phrase code, min. skill
110 mss PhraseNames
, PhraseTitles
;
111 vector
<vs
> ValidPhrases
;
112 set
<string
> UsedBricks
, GeneratedPhrases
;
113 map
<string
, vs
> GrammarMandatParamBrickFamilies
, GrammarOptionCreditBrickFamilies
;
114 UFormLoader
*FormLoader
;
115 vector
<FILE*> PhraseDocFiles( 26 );
116 string DocFileName
,DocFileNameRoot
;
118 map
<string
,uint
> SkillNameToMaxSkill
;
119 map
<string
,string
> PhraseCodeToLink
;
120 CWordsDictionary Dico
;
121 CStaticSkillsTree SkillsTree
;
127 string inputSheetPath
;
128 bool inputSheetPathLoaded
= false;
129 map
<string
, string
> inputSheetPathContent
; // short filename without ext, full filename with path
132 //-----------------------------------------------
133 // getBrickTypeLetterRPos
135 //-----------------------------------------------
136 uint
getBrickTypeLetterRPos( string
& brick
)
140 while( i<brick.size() && !isdigit(brick[i]) )
143 nlassert(i<brick.size());
145 return (brick.size() - i + 2);
148 uint i
=brick
.size()-1;
149 while( i
>=0 && (isdigit(brick
[i
]) || brick
[i
]=='_') )
152 return (brick
.size() - i
+ 1);
154 } // getBrickTypeLetterRPos //
159 //-----------------------------------------------
163 //-----------------------------------------------
166 if (inputSheetPathLoaded
)
169 NLMISC::createDebug();
170 NLMISC::WarningLog
->addNegativeFilter( "CPath::insertFileInMap" );
172 CPath::addSearchPath(inputSheetPath
, true, false); // for Georges to work properly
174 vector
<string
> files
;
175 CPath::getPathContent (inputSheetPath
, true, false, true, files
);
178 for (i
=0; i
<files
.size(); ++i
)
180 string filename
= files
[i
];
181 string filebase
= CFile::getFilenameWithoutExtension(filename
);
182 if( CFile::getExtension(filename
)!="saibrick" && CFile::getExtension(filename
)!="saiphrase" )
184 inputSheetPathContent
[filebase
] = filename
;
188 inputSheetPathLoaded
= true;
190 } // loadSheetPath //
196 void displayList( const string
& title
, const vector
<string
>& v
, CLog
*log
=DebugLog
)
198 if ( ! title
.empty() )
199 log
->displayRaw( "%s: ", title
.c_str() );
200 vector
<string
>::const_iterator ist
;
201 for ( ist
=v
.begin(); ist
!=v
.end(); ++ist
)
202 log
->displayRaw( "%s ", (*ist
).c_str() );
203 log
->displayRawNL( "" );
210 class CStrIComparator
: public binary_function
<string
, string
, bool>
213 bool operator() ( const string
& s1
, const string
& s2
) const
215 return (nlstricmp( s1
, s2
) == 0);
223 uint
getIndexFromString( const string
& s
, const vector
<string
>& v
, bool displayWarning
=true )
227 nlwarning( "Can't find '%s' in empty array", s
.c_str() );
232 vector
<string
>::const_iterator ist
= find_if( v
.begin(), v
.end(), bind2nd(CStrIComparator(), s
) );
233 if ( ist
== v
.end() )
235 if ( displayWarning
)
237 nlwarning( "Can't find '%s' in:", s
.c_str() );
238 displayList( "", v
, WarningLog
);
243 return ist
- v
.begin();
248 //-----------------------------------------------
249 // Erase every carriage returns of the string
251 //-----------------------------------------------
252 void eraseCarriageReturns( string
& s
)
254 const char CR
= '\n';
255 string::size_type p
= s
.find( CR
);
256 while ( (p
=s
.find( CR
)) != string::npos
)
262 // First param: vector of indices of columns matching wantedColumnNames
263 // Second param: vector of fields matching wantedColumnNames
264 typedef void (*TDeliveryCallback
) ( mss
& );
267 //-----------------------------------------------
270 //-----------------------------------------------
271 void loadCSVFile( const char *filename
, TDeliveryCallback deliveryCallback
)
273 char lineBuffer
[2048];
275 const char *SEPARATOR
= ";";
277 vector
<string
>::iterator iarg
;
279 if ( (file
= nlfopen( filename
, "r" )) == NULL
)
281 nlwarning( "Can't find file %s", filename
);
285 // Read first line as header with column names
286 lineBuffer
[0] = '\0';
287 fgets( lineBuffer
, 2048, file
);
288 explode( lineBuffer
, SEPARATOR
, args
);
290 // Store column names (and get rid of carriage returns!)
291 vector
< string
> columnNames
;
293 for ( iarg
=args
.begin(); iarg
!=args
.end(); ++iarg
)
295 eraseCarriageReturns( *iarg
);
296 columnNames
.push_back( *iarg
);
297 valuesByName
.insert( make_pair( *iarg
, string("") ) );
300 // for each line, deliver the value of the fields
301 while ( ! feof(file
) )
304 lineBuffer
[0] = '\0';
305 fgets( lineBuffer
, 2048, file
);
306 explode( lineBuffer
, SEPARATOR
, args
);
308 // Set values (and get rid of carriage returns!)
309 for ( iarg
=args
.begin(); iarg
!=args
.end(); ++iarg
)
311 eraseCarriageReturns( *iarg
);
312 valuesByName
[columnNames
[iarg
-args
.begin()]] = *iarg
;
315 // Deliver the wanted fields
316 deliveryCallback( valuesByName
);
323 //set<string> Skills;
326 //-----------------------------------------------
327 // brickDeliveryCallback
329 // Fetch brick code and sabrina cost
333 // - CounterpartBricks
335 //-----------------------------------------------
336 void brickDeliveryCallback( mss
& values
)
338 string s
= values
["Brick_id"];
343 s
= values
["fileName"];
346 string brick
= CFile::getFilenameWithoutExtension( s
);
350 nlwarning("<brickDeliveryCallback> can't get root filename of %s",s
.c_str());
354 string sc
= values
["Basics.SabrinaCost"];
355 string ls
= values
["Basics.LearnRequiresOneOfSkills"];
356 string txt
= values
["name"]; // TODO: only for combat
357 string fmn
= values
["familyName"];
358 string propIdent
= "Basics.Property";
362 AllBricks
.push_back( brick
);
363 string name
= (txt
.empty()) ? fmn
: txt
;
366 // Find all Basics.Property N (assumes they are subsequent)
367 mss::const_iterator imv
= values
.find( propIdent
+ " 0" );
368 for ( ; imv
!=values
.end(); ++imv
)
370 const string
& colName
= (*imv
).first
;
371 const string
& v
= (*imv
).second
;
372 if ( colName
.find( propIdent
) != string::npos
)
374 if ( v
!= "NULL" && !v
.empty() )
375 props
.push_back( v
);
380 BrickInfo
.insert( make_pair( brick
, CBrickInfo( ls
, name
, props
) ) );
383 // Store brick in right container
384 string::size_type p
= brick
.size() - getBrickTypeLetterRPos(brick
);
385 if ( ((sint
)p
) >= 0 )
389 case 'O': OptionBricks
.push_back( brick
);
391 case 'C': CounterpartBricks
.push_back( brick
);
397 nlwarning( "Invalid brick code: %s", brick
.c_str() );
405 nldebug( "No sabrina cost for %s, assuming cost 0", brick
.c_str() );
410 sabrinaCost
= atoi( sc
.c_str() );
412 SabrinaCosts
.insert( make_pair( brick
, sabrinaCost
) );
414 /* // Quick hack to generate skill codes
415 string skill = brick.substr( 1, p-1 );
416 if ( ! skill.empty() )
417 Skills.insert( skill );*/
419 } // brickDeliveryCallback //
423 //-----------------------------------------------
426 //-----------------------------------------------
427 void loadBricks( const char* filename
)
429 loadCSVFile( filename
, brickDeliveryCallback
);
430 if ( ProduceDocFromExistingPhrases
)
431 nlinfo( "Loaded %u option bricks, %u counterpart bricks, %u sabrina costs", OptionBricks
.size(), CounterpartBricks
.size(), SabrinaCosts
.size() );
432 else if ( UseBricks
)
433 nlinfo( "Loaded %u bricks", AllBricks
.size() );
435 /*set<string>::const_iterator iss;
436 for ( iss=Skills.begin(); iss!=Skills.end(); ++iss )
438 const string& skill = (*iss);
439 InfoLog->displayRawNL( " <DEFINITION Label=\"S%s\" Value=\"S%s\"/>", skill.c_str(), skill.c_str() );
448 string
getRootBrickForOptionOrCredit( const string
& ob
)
450 // Extract brick code radix
451 string::size_type p
= ob
.size() - getBrickTypeLetterRPos(const_cast<string
&>(ob
));
452 if ( (ob
.size() <= getBrickTypeLetterRPos(const_cast<string
&>(ob
))) ||
453 ((ob
[p
] != 'O') && (ob
[p
] != 'C')) )
454 nlerror( "%s is not an option or credit brick", ob
.c_str() );
455 string radix
= ob
.substr( 0, p
);
457 // Append root brick suffix
458 return radix
+ "PA01";
465 string
getBrickFamily( const string
& b
)
467 if ( b
.size() >= getBrickTypeLetterRPos(const_cast<string
&>(b
))+2 )
469 string::size_type p
= b
.size() - getBrickTypeLetterRPos(const_cast<string
&>(b
));
470 return b
.substr( 0, p
+2 );
479 bool isFromBrickFamily( const string
& brick
, const string
& fam
)
481 return nlstricmp( brick
.substr( 0, fam
.size() ), fam
) == 0;
488 string
getFirstBrickOfFamily( const string
& family
)
490 vs::const_iterator ib
;
491 for ( ib
=AllBricks
.begin(); ib
!=AllBricks
.end(); ++ib
)
493 const string
& brick
= *ib
;
494 if ( isFromBrickFamily( brick
, family
) )
504 vs
getAllBricksOfFamily( const string
& family
)
507 vs::const_iterator ib
;
508 for ( ib
=AllBricks
.begin(); ib
!=AllBricks
.end(); ++ib
)
510 const string
& brick
= *ib
;
511 if ( isFromBrickFamily( brick
, family
) )
512 res
.push_back( brick
);
521 uint
getCompatibleCounterpartBrickForCost( uint phraseCost
, vs
& phrase
)
523 //nlinfo( "Searching credit for cost %u", phraseCost );
525 // Get the lowest matching counterpart brick
526 uint minHigherCounterpartValue
= ~0, maxLowerCounterpartValue
= 0, counterpartValue
;
527 vs::const_iterator icb
, iPerfectMatch
= CounterpartBricks
.end(), iMinCb
= CounterpartBricks
.end(), iMaxCb
= CounterpartBricks
.end();
528 for ( icb
=CounterpartBricks
.begin(); icb
!=CounterpartBricks
.end(); ++icb
)
530 const string
& cb
= *icb
;
532 // Skip if family already used in current phrase
533 if ( UsedCounterpartBrickFamiliesInPhrase
.find( getBrickFamily( cb
) ) != UsedCounterpartBrickFamiliesInPhrase
.end() )
536 counterpartValue
= abs( SabrinaCosts
[cb
] );
537 //nldebug( "Trying with credit %u", counterpartValue );
538 if ( counterpartValue
== phraseCost
)
540 // Perfect match, check if not already taken
541 if ( UsedCounterpartBricks
.insert( cb
).second
)
543 UsedCounterpartBrickFamiliesInPhrase
.insert( getBrickFamily( cb
) );
544 phrase
.push_back( cb
);
545 return counterpartValue
;
549 // If already taken, we will come back to it later
553 else if ( counterpartValue
> phraseCost
)
555 // Higher => get the minimum
556 if ( counterpartValue
< minHigherCounterpartValue
)
558 minHigherCounterpartValue
= counterpartValue
;
562 else // counterpartValue < phraseCost : store the max
564 if ( counterpartValue
>= maxLowerCounterpartValue
)
566 maxLowerCounterpartValue
= counterpartValue
;
571 if ( iPerfectMatch
!= CounterpartBricks
.end() )
573 // We skipped a perfect match in order to try to get a new value. But none found. Now get back to the last value.
574 phrase
.push_back( *iPerfectMatch
);
575 UsedCounterpartBrickFamiliesInPhrase
.insert( getBrickFamily( *iPerfectMatch
) );
576 return abs( SabrinaCosts
[*iPerfectMatch
] );
578 else if ( iMinCb
== CounterpartBricks
.end() )
580 if ( iMaxCb
== CounterpartBricks
.end() )
582 nlerror( "No matching counterpart" );
587 // No phrase possible with only one (more) counterpart, try with the max and more (recurse)
588 UsedCounterpartBricks
.insert( *iMaxCb
);
589 UsedCounterpartBrickFamiliesInPhrase
.insert( getBrickFamily( *iMaxCb
) );
590 phrase
.push_back( *iMaxCb
);
591 return maxLowerCounterpartValue
+ getCompatibleCounterpartBrickForCost( phraseCost
- maxLowerCounterpartValue
, phrase
);
596 // Phrase possible with one (more) counterpart
597 UsedCounterpartBricks
.insert( *iMinCb
);
598 UsedCounterpartBrickFamiliesInPhrase
.insert( getBrickFamily( *iMinCb
) );
599 phrase
.push_back( *iMinCb
);
600 return minHigherCounterpartValue
;
608 void getCompatibleCounterpartBricks( vs
& phrase
)
610 // Calculate the cost of the phrase
613 vs::const_iterator ip
;
614 for ( ip
=phrase
.begin(); ip
!=phrase
.end(); ++ip
)
616 const string
& brick
= *ip
;
618 map
<string
, sint
>::const_iterator isc
= SabrinaCosts
.find( brick
);
619 if ( isc
!= SabrinaCosts
.end() )
620 sabrinaCost
= (*isc
).second
;
623 phraseCost
+= sabrinaCost
;
624 phraseStr
+= brick
+ " ";
627 // Find matching counterpart(s), only 1 per family
628 UsedCounterpartBrickFamiliesInPhrase
.clear();
629 uint counterpartValue
= getCompatibleCounterpartBrickForCost( phraseCost
, phrase
);
631 displayList( toString( "+%3u -%3u", phraseCost
, counterpartValue
), phrase
);
638 /*void getCompatiblePhraseByCounterpart( const string& counterpartBrick, vs& phrase )
640 sint sabrinaCost = SabrinaCosts[counterpartBrick];
642 // Assuming root brick cost is zero!
643 vs::const_iterator iob;
644 for ( iob=OptionBricks.begin(); iob!=OptionBricks.end(); ++iob )
646 // TODO: Find the highest cost that is lower or equal than the counterpart value
647 const string& ob = *iob;
648 if ( SabrinaCosts[ob] <= SabrinaCosts[counterpartBrick] )
649 break; // currently, take the first found
651 if ( iob != OptionBricks.end() )
653 string rb = getRootBrickForOptionOrCredit( *iob );
654 phrase.push_back( rb );
655 phrase.push_back( *iob );
656 phrase.push_back( counterpartBrick );
657 nldebug( "%s %s %s: +%u -%u", rb.c_str(), (*iob).c_str(), counterpartBrick.c_str(),
658 SabrinaCosts[rb]+SabrinaCosts[*iob], SabrinaCosts[counterpartBrick] );
661 nlwarning( "No matching phrase for counterpart %s", counterpartBrick.c_str() );
666 * Clear the form to reuse it (and all contents below node)
668 void clearSheet( CForm
*form
, UFormElm
* node
)
670 ((CFormElm
*)node
)->clean();
679 inline void explodeBrickAndParameters( const string
& brickAndParams
, vs
& bricks
)
681 explode( brickAndParams
, " ", bricks
);
688 string
getBrickType( const string
& brick
)
690 if ( brick
.size() < 4 )
691 return "INVALID TYPE in " + brick
;
694 switch ( brick
[brick
.size()-getBrickTypeLetterRPos(const_cast<string
&>(brick
))] )
696 case 'P': return "Root";
698 case 'E': return "Effect";
700 case 'O': return "Option";
702 case 'M': return "Modifier";
704 case 'C': return "Credit";
707 return "INVALID TYPE in " + brick
;
713 //-----------------------------------------------
716 //-----------------------------------------------
717 void printBrickInfo( FILE *htmlfile
, const string
& brick
, const string
& grammarError
, sint
& sabrinaCost
, uint
& minSkillValue
, string
& minSkill
)
722 string brickType
= getBrickType( b
);
723 sint sc
= (brickType
=="Credit") ? -abs( SabrinaCosts
[b
] ) : SabrinaCosts
[b
];
724 CBrickInfo
& bInfo
= BrickInfo
[b
];
725 fprintf( htmlfile
, "<LI><B>%s %s</B> %s<BR>\n", brickType
.c_str(), b
.c_str(), bInfo
.Text
.c_str() );
726 if ( ! grammarError
.empty() )
728 fprintf( htmlfile
, "<FONT COLOR=\"RED\">%s</FONT><BR>\n", grammarError
.c_str() );
732 fprintf( htmlfile
, "Sabrina Cost: %d <BR>\n", sc
);
733 if( !bInfo
.LearnSkills
.empty() )
735 fprintf( htmlfile
, "Skills required: %s<BR>\n", bInfo
.LearnSkills
.c_str() );
737 if( bInfo
.Props
.size() )
739 fprintf( htmlfile
, "Properties:" );
740 for ( vs::const_iterator ip
= bInfo
.Props
.begin(); ip
!=bInfo
.Props
.end(); ++ip
)
742 fprintf( htmlfile
, " %s", (*ip
) );
746 fprintf( htmlfile
, "</LI>\n" );
748 // Calculate sabrina cost & skill value
750 if ( bInfo
.LearnSkills
.empty() )
755 vector
<string
> skillsAndValues
;
756 explode( bInfo
.LearnSkills
, ":", skillsAndValues
, true );
757 vector
<uint
> skillValues( skillsAndValues
.size(), ~0 );
758 vector
<string
>::iterator isv
;
759 for ( isv
=skillsAndValues
.begin(); isv
!=skillsAndValues
.end(); ++isv
)
761 const string
& sav
= *isv
;
762 string::size_type p
= sav
.find( ' ' );
763 if ( (p
== string::npos
) || (sav
.size() == p
+1) )
764 nlwarning( "Invalid LearnRequiresOneOfSkills value '%s'", sav
.c_str() );
767 uint sv
= atoi( sav
.substr( p
+1 ).c_str() );
768 skillValues
[isv
-skillsAndValues
.begin()] = sv
;
769 if ( sv
< minSkillValue
)
774 for ( isv
=skillsAndValues
.begin(); isv
!=skillsAndValues
.end(); ++isv
)
776 if ( skillValues
[isv
-skillsAndValues
.begin()] == minSkillValue
)
779 if ( (! sav
.empty()) && (sav
[0] != 'S') )
781 if ( minSkill
.find( sav
) == string::npos
)
783 if ( ! minSkill
.empty() )
791 } // printBrickInfo //
794 //-----------------------------------------------
797 //-----------------------------------------------
798 void loadBrickGrammar()
800 uint nbRootBricks
= 0;
801 vs::const_iterator ib
;
802 for ( ib
=AllBricks
.begin(); ib
!=AllBricks
.end(); ++ib
)
806 if ( brick
.size() >= 4 )
808 char brickType
= brick
[brick
.size()-getBrickTypeLetterRPos(brick
)];
810 /*// As the root bricks may be absent from the table, deduce them (obsolete)
811 if ( brickType == 'O' )
813 string rootBrick = getRootBrickForOptionOrCredit( brick );
814 if ( GrammarOptionCreditBrickFamilies.find( rootBrick ) == GrammarOptionCreditBrickFamilies.end() )
825 // If not skipped by previous 'continue'
826 if ( (brickType
== 'P') || (brickType
== 'E') || (brickType
== 'O' ) ) // root, effect, option
828 NLMISC::CSmartPtr
<CForm
> form
= (CForm
*)FormLoader
->loadForm( (strlwr(static_cast<const string
&>(brick
))+"."+brSheetType
).c_str() );
831 nlwarning( "Can't load sheet %s", ((strlwr(static_cast<const string
&>(brick
)))+"."+phSheetType
).c_str() );
834 for ( uint i
=0; i
!=12; ++i
)
837 form
->getRootNode().getValueByName( value
, toString( "Mandatory.f%u", i
).c_str() );
838 if ( (! value
.empty()) && (value
!= "Unknown") )
840 GrammarMandatParamBrickFamilies
[brick
].push_back( value
);
843 if ( brickType
== 'O' )
845 for ( uint i
=0; i
!=4; ++i
)
848 form
->getRootNode().getValueByName( value
, toString( "Parameter.f%u", i
).c_str() );
849 if ( (! value
.empty()) && (value
!= "Unknown") )
851 GrammarMandatParamBrickFamilies
[brick
].push_back( value
);
855 if ( brickType
== 'P' ) // root
858 for ( uint i
=0; i
!=32; ++i
)
861 form
->getRootNode().getValueByName( value
, toString( "Optional.f%u", i
).c_str() );
862 if ( (! value
.empty()) && (value
!= "Unknown") )
864 GrammarOptionCreditBrickFamilies
[brick
].push_back( value
);
867 for ( uint i
=0; i
!=12; ++i
)
870 form
->getRootNode().getValueByName( value
, toString( "Credit.f%u", i
).c_str() );
871 if ( (! value
.empty()) && (value
!= "Unknown") )
873 GrammarOptionCreditBrickFamilies
[brick
].push_back( value
);
881 nlwarning( "Invalid brick code %s", brick
.c_str() );
884 nlinfo( "%u bricks have mandatory/parameter grammar rules", GrammarMandatParamBrickFamilies
.size() );
885 nlinfo( "%u bricks have option/credit grammar rules", GrammarOptionCreditBrickFamilies
.size() );
886 nlinfo( "Found or deduced %u root bricks", nbRootBricks
);
888 } // loadBrickGrammar //
892 //-----------------------------------------------
895 //-----------------------------------------------
896 void loadPhraseTitles()
898 STRING_MANAGER::TWorksheet worksheet
;
899 STRING_MANAGER::loadExcelSheet( "r:/code/ryzom/translation/translated/sphrase_words_en.txt", worksheet
);
901 if ( worksheet
.findCol( ucstring("sphrase ID"), cp
) && worksheet
.findCol( ucstring("name"), cn
) )
903 for ( std::vector
<STRING_MANAGER::TWorksheet::TRow
>::iterator ip
= worksheet
.begin(); ip
!=worksheet
.end(); ++ip
)
905 if ( ip
== worksheet
.begin() ) // skip first row
907 STRING_MANAGER::TWorksheet::TRow
& row
= *ip
;
908 PhraseTitles
.insert( make_pair( strlwr(row
[cp
].toString()), row
[cn
].toUtf8() ) );
912 nlwarning( "sphrase ID or name not found" );
914 nlinfo( "Loaded %u phrase titles", PhraseTitles
.size() );
916 } // loadPhraseTitles //
919 //-----------------------------------------------
922 //-----------------------------------------------
923 void loadBrickTitles()
925 STRING_MANAGER::TWorksheet worksheet
;
926 STRING_MANAGER::loadExcelSheet( "r:/code/ryzom/translation/translated/sbrick_words_en.txt", worksheet
);
927 uint cp
, cn
, nbTitles
= 0;
928 if ( worksheet
.findCol( ucstring("sbrick ID"), cp
) && worksheet
.findCol( ucstring("name"), cn
) )
930 for ( std::vector
<STRING_MANAGER::TWorksheet::TRow
>::iterator ip
= worksheet
.begin(); ip
!=worksheet
.end(); ++ip
)
932 if ( ip
== worksheet
.begin() ) // skip first row
934 STRING_MANAGER::TWorksheet::TRow
& row
= *ip
;
935 BrickInfo
[strupr(row
[cp
].toString())].Text
= row
[cn
].toUtf8();;
940 nlwarning( "sbrick ID or name not found" );
942 nlinfo( "Loaded %u brick titles", nbTitles
);
944 } // loadBrickTitles //
950 void getChildrenBricks( const string
& brick
, vs
& chFamilies
)
952 chFamilies
= GrammarMandatParamBrickFamilies
[brick
];
959 void addError( string
& errorStr
, string
& newError
, uint
& nbGrammarErrors
)
961 if ( ! errorStr
.empty() )
963 errorStr
+= newError
;
971 void checkOptionOrCreditCompatibility( string
& errorStr
, const string
& currentBrick
, const string
& rootBrick
, uint
& nbGrammarErrors
)
973 string brick
= currentBrick
;
975 if ( brick
.size() >= 4 && brick
[1]!='C' && brick
[1]!='H') // C & H for craft and harvest
977 char brickType
= brick
[brick
.size()-getBrickTypeLetterRPos(brick
)];
978 if ( (brickType
== 'O') || (brickType
== 'C') )
980 string rootBrick
= getRootBrickForOptionOrCredit( brick
);
981 const vs
& compatibleOptionOrCredits
= GrammarOptionCreditBrickFamilies
[rootBrick
];
982 vs::const_iterator ic
;
983 for ( ic
=compatibleOptionOrCredits
.begin(); ic
!=compatibleOptionOrCredits
.end(); ++ic
)
985 if ( isFromBrickFamily( brick
, (*ic
) ) )
988 if ( ic
== compatibleOptionOrCredits
.end() )
990 addError( errorStr
, toString( "This family is not compatible with options/credits of root %s", rootBrick
.c_str() ), nbGrammarErrors
);
999 * - grammarErrors.size() == phrase.size()
1000 * - r < phrase.size()
1002 * Note: does not check that all bricks should have a different family
1004 void checkGrammar( const vs
& phrase
, uint
& r
, vs
& grammarErrors
, uint
& nbGrammarErrors
, const string
& rootBrick
, bool readNext
=true )
1007 string grammarBrick
= phrase
[origR
];
1008 strupr( grammarBrick
);
1010 // Check option/credit
1011 checkOptionOrCreditCompatibility( grammarErrors
[r
], phrase
[r
], rootBrick
, nbGrammarErrors
);
1013 // Check mandatory/parameter
1015 getChildrenBricks( grammarBrick
, chFamilies
);
1017 for ( vs::const_iterator icf
=chFamilies
.begin(); icf
!=chFamilies
.end(); ++icf
)
1019 // Detect incomplete phrase
1020 if ( r
>= phrase
.size() )
1022 addError( grammarErrors
[origR
], "Missing mandatory/parameter " + (*icf
) + " at the end", nbGrammarErrors
);
1026 // Detect wrong brick family
1027 if ( isFromBrickFamily( phrase
[r
], (*icf
) ) )
1029 // Check grammar using child as root
1030 checkGrammar( phrase
, r
, grammarErrors
, nbGrammarErrors
, phrase
[r
], false );
1034 addError( grammarErrors
[r
], "Error: " + (*icf
) + " expected (mandatory/parameter of " + grammarBrick
+ ")", nbGrammarErrors
);
1040 if ( readNext
&& (r
< phrase
.size()) )
1042 checkGrammar( phrase
, r
, grammarErrors
, nbGrammarErrors
, rootBrick
);
1050 char getDocFileLetter( const string
& sheetName
)
1052 // skip abm_mt_, abm_ml_...
1054 uint nbUnderscoresToSkip
= 2, nbUnderscoresFound
= 0;
1055 for ( uint c
=0; c
!=sheetName
.size(); ++c
)
1057 if ( nbUnderscoresFound
== nbUnderscoresToSkip
)
1059 letter
= sheetName
[c
];
1062 if ( sheetName
[c
] == '_' )
1063 ++nbUnderscoresFound
;
1065 return tolower( letter
);
1069 //-----------------------------------------------
1070 // testPhraseGrammarAndProduceDoc
1072 //-----------------------------------------------
1073 bool testPhraseGrammarAndProduceDoc( const string
& sheetName
, const vs
& phrase
)
1075 string filename
= strlwr( sheetName
) + "." + phSheetType
;
1076 string phraseStatus
;
1077 bool isPhraseCorrect
= true;
1078 const char *rejectedstr
= "(grammatically invalid)";
1080 // Check grammar for this phrase
1081 vs
grammarErrors( phrase
.size() );
1082 uint nbGrammarErrors
= 0, r
= 0;
1083 checkGrammar( phrase
, r
, grammarErrors
, nbGrammarErrors
, phrase
[0] );
1084 if ( nbGrammarErrors
!= 0 )
1086 InvalidPhrases
.push_back( sheetName
);
1087 isPhraseCorrect
= false;
1088 phraseStatus
= rejectedstr
;
1091 // Look-up phrase title
1092 string phraseTitle
= PhraseTitles
[sheetName
];
1094 // Output phrase description
1096 if ( (! MultipleDocFiles
) && (sheetName
.size() > 3) )
1098 letter
= tolower( sheetName
[3] );
1102 letter
= getDocFileLetter( sheetName
);
1106 else if ( letter
> 'z' )
1108 FILE *htmlFile
= PhraseDocFiles
[letter
- 'a'];
1110 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() );
1111 vector
<string
> minBrickSkills( phrase
.size() );
1112 vector
<uint
> minBrickSkillValues( phrase
.size(), 0 );
1113 string brickMinSkill
, maxSkill
;
1114 sint posCost
= 0, negCost
= 0, totalCost
;
1115 uint maxSkillValue
= 0, brickMinSkillValue
;
1116 for ( uint i
=0; i
!=phrase
.size(); ++i
)
1118 printBrickInfo( htmlFile
, phrase
[i
], grammarErrors
[i
], sabrinaCost
, brickMinSkillValue
, brickMinSkill
);
1119 if ( sabrinaCost
> 0 )
1120 posCost
+= sabrinaCost
;
1122 negCost
+= sabrinaCost
;
1123 minBrickSkillValues
[i
] = brickMinSkillValue
;
1124 minBrickSkills
[i
] = brickMinSkill
;
1125 if ( brickMinSkillValue
> maxSkillValue
)
1126 maxSkillValue
= brickMinSkillValue
;
1128 for ( uint i
=0; i
!=phrase
.size(); ++i
)
1130 if ( minBrickSkillValues
[i
] == maxSkillValue
)
1132 if ( maxSkill
.find( minBrickSkills
[i
] ) == string::npos
)
1134 if ( ! maxSkill
.empty() )
1136 maxSkill
+= minBrickSkills
[i
];
1140 if ( phrase
.size() > 1 )
1142 string effectOrOptionBrick
= phrase
[1];
1143 strupr( effectOrOptionBrick
);
1144 if ( ! PhraseNames
.insert( make_pair( sheetName
, BrickInfo
[effectOrOptionBrick
].Text
) ).second
)
1145 nlwarning( "Found duplicate phrase %s", sheetName
.c_str() );
1147 Progression
.insert( make_pair( maxSkillValue
, make_pair( sheetName
, maxSkill
) ) );
1148 totalCost
= posCost
+ negCost
;
1149 PhraseSabrinaCosts
.insert( make_pair(sheetName
,totalCost
) );
1150 char *redbegin
= "", *redend
= "";
1151 if ( totalCost
> 0 )
1153 map
<string
,bool>::const_iterator itCastable
= PhraseCastable
.find(sheetName
);
1154 if( itCastable
!= PhraseCastable
.end() )
1156 if( (*itCastable
).second
)
1158 redbegin
= "<FONT COLOR=\"RED\">";
1160 PhrasesWithInvalidCost
.push_back( sheetName
);
1161 isPhraseCorrect
= false;
1165 fprintf( htmlFile
, "<LI>%s<B>Total sabrina cost: </B>+%d %d = %d%s</LI>\n", redbegin
, posCost
, negCost
, totalCost
, redend
);
1166 fprintf( htmlFile
, "<LI><B>Minimum skill value required: %d</B></LI>\n", maxSkillValue
);
1167 fprintf( htmlFile
, "</UL></P>\n" );
1168 if ( ! isPhraseCorrect
)
1172 return isPhraseCorrect
;
1174 } // testPhraseGrammarAndProduceDoc //
1183 inline bool isSeparator( char c
)
1185 return (c
== ' ') || (c
== '\t');
1190 //-----------------------------------------------
1191 // produceDocFromExistingPhrases
1194 //-----------------------------------------------
1195 void produceDocFromExistingPhrases()
1198 CPath::getPathContent( PhrasePath
, true, false, true, files
);
1201 for ( vs::const_iterator ip
=files
.begin(); ip
!=files
.end(); ++ip
)
1203 if ( CFile::getExtension( *ip
) == phSheetType
)
1205 // Read george sheet
1206 NLMISC::CSmartPtr
<UForm
> form
= (UForm
*)FormLoader
->loadForm( (*ip
).c_str() );
1208 nlerror( "Can't load sheet %s", (*ip
).c_str() );
1210 // Get the bricks of the phrase
1212 for ( uint i
=0; i
!=100; ++i
)
1215 form
->getRootNode().getValueByName( value
, toString( "brick %u", i
).c_str() );
1216 if ( !value
.empty() )
1219 phrase
.push_back( CFile::getFilenameWithoutExtension( value
) );
1223 Phrases
.insert( make_pair(CFile::getFilenameWithoutExtension( *ip
), phrase
) );
1225 // look if phrase is castable
1227 form
->getRootNode().getValueByName( castable
, "castable");
1228 PhraseCastable
.insert( make_pair(CFile::getFilenameWithoutExtension( *ip
), castable
) );
1230 // Test grammar and produce doc
1231 testPhraseGrammarAndProduceDoc( CFile::getFilenameWithoutExtension( *ip
), phrase
);
1236 nlinfo( "Total: %u phrases", NbSheetsRead
);
1238 } // produceDocFromExistingPhrases //
1244 string
getLink( const string
& phrase
)
1247 if ( MultipleDocFiles
&& (! phrase
.empty()) )
1249 res
+= DocFileName
+ "_" + getDocFileLetter( phrase
) + ".html";
1253 res
+= DocFileName
+ ".html";
1255 res
+= "#" + phrase
;
1256 //nlinfo( "%s", res.c_str() );
1264 void usage(char *argv0
, FILE *out
)
1267 fprintf(out
, "Syntax: %s [-p <sheet path>] <bricksFilename> [-o <phrasePath>] [-b] [-d] [-m] [-n]\n", argv0
);
1268 fprintf(out
, "-o: output phrase path (or input if -d is set)\n");
1269 fprintf(out
, "-b: produce doc about brick learning infos\n");
1270 fprintf(out
, "-d: browse existing phrases in <phrasePath> (and subdirs) and produce doc\n");
1271 fprintf(out
, "-m: multiple doc html files, alphabetically (use with -g,-c,-d with numerous phrases)\n");
1272 fprintf(out
, "-n: no hypertext (don't produce links phrases)\n");
1280 //-----------------------------------------------
1283 //-----------------------------------------------
1284 void makeIndexFile()
1286 FILE * indexFile
= nlfopen( "_" + DocFileNameRoot
+ "_INDEX.html", "wt" );
1289 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() );
1291 DocFileName
= DocFileNameRoot
+ "_actions";
1293 if ( MultipleDocFiles
)
1295 // One HTML file per alphabet letter
1296 for ( uint l
=0; l
!=26; ++l
)
1298 string filename
= toString( "%s_%c.html", DocFileName
.c_str(), 'a'+l
);
1299 PhraseDocFiles
[l
] = nlfopen( filename
, "wt" );
1300 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() );
1301 fprintf( indexFile
, ("<A HREF=\"" + filename
+ "\">" + (char)('A'+l
) + "</A> ").c_str() );
1306 // One single HTML file
1307 fprintf( indexFile
, ("<A HREF=\"" + DocFileName
+ ".html\">Go to action details</A>").c_str() );
1308 PhraseDocFiles
[0] = nlfopen( DocFileName
+ ".html", "wt" );
1309 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() );
1310 for ( uint l
=1; l
!=26; ++l
)
1312 PhraseDocFiles
[l
] = PhraseDocFiles
[0];
1315 fprintf( indexFile
, ("<BR><A HREF=\"" + DocFileName
+ "__by_skill_value.html" + "\">Go to action by skill value</A>\n").c_str() );
1316 fprintf( indexFile
, ("<BR><A HREF=\"" + DocFileName
+ "__by_skill_value_detail.html" + "\">Go to action by skill value (detail)</A>\n").c_str() );
1317 fprintf( indexFile
, ("<BR><A HREF=\"" + DocFileName
+ "__by_skill.html" + "\">Go to action by skill</A><BR>\n").c_str() );
1319 if( GenerateBrickProgression
)
1321 fprintf( indexFile
, ("<BR><BR><A HREF=\"" + DocFileNameRoot
+ ".html" + "\">Go to brick list</A><BR>\n").c_str() );
1324 produceDocFromExistingPhrases();
1326 for ( map
< uint
, pair
<string
, string
> >::const_iterator ip
=Progression
.begin(); ip
!=Progression
.end(); ++ip
)
1328 const string
& phraseCode
= (*ip
).second
.first
;
1329 string link
= Hypertext
? toString( "<A HREF=\"%s\">%s</A>", getLink(phraseCode
).c_str(), phraseCode
.c_str() ) : "<B>" + phraseCode
+ "</B>";
1330 PhraseCodeToLink
.insert( make_pair(phraseCode
,link
) );
1333 // Summary (errors in phrases)
1334 fprintf( indexFile
, "<BR><A NAME=\"summary\"></A>\n" );
1335 fprintf( indexFile
, ("<FONT SIZE=\"20\">Summary of " + DocFileName
+ "</FONT><BR>\n").c_str() );
1336 if ( NbSheetsGenTries
!= 0 )
1337 fprintf( indexFile
, "<P>%u valid sheets written on %u</P>\n", NbSheetsWritten
, NbSheetsGenTries
);
1338 if ( NbSheetsRead
!= 0 )
1339 fprintf( indexFile
, "<P>%u sheets read</P>\n", NbSheetsRead
);
1340 fprintf( indexFile
, "<P>%u invalid sheets rejected", NbSheetsRejected
);
1341 if ( ! PhrasesWithInvalidCost
.empty() )
1343 fprintf( indexFile
, "<P><B>Phrases with invalid sabrina cost:</B><BR>\n" );
1344 for ( vs::const_iterator iip
=PhrasesWithInvalidCost
.begin(); iip
!=PhrasesWithInvalidCost
.end(); ++iip
)
1346 string link
= Hypertext
? toString( "<A HREF=\"%s\">%s</A>", getLink(*iip
).c_str(), (*iip
).c_str() ) : "<B>" + (*iip
) + "</B>";
1347 fprintf( indexFile
, "%s<BR>\n", link
.c_str() );
1349 fprintf( indexFile
, "</P>\n" );
1353 fprintf( indexFile
, "<P><B>All phrases have valid sabrina cost.</B></P>\n" );
1355 if ( ! InvalidPhrases
.empty() )
1357 fprintf( indexFile
, "<P><B>Grammatically invalid phrases:</B><BR>\n" );
1358 for ( vs::const_iterator iip
=InvalidPhrases
.begin(); iip
!=InvalidPhrases
.end(); ++iip
)
1360 string link
= Hypertext
? toString( "<A HREF=\"%s\">%s</A>", getLink(*iip
).c_str(), (*iip
).c_str() ) : "<B>" + (*iip
) + "</B>";
1361 fprintf( indexFile
, "%s<BR>\n", link
.c_str() );
1363 fprintf( indexFile
, "</P>\n" );
1367 fprintf( indexFile
, "<P><B>All phrases are grammatically valid.</B></P>\n" );
1369 fprintf( indexFile
, "</body></html>\n" );
1370 fclose( indexFile
);
1372 if ( MultipleDocFiles
)
1374 for ( uint l
=0; l
!=26; ++l
)
1376 fprintf( PhraseDocFiles
[l
], "</body></html>\n" );
1377 fclose( PhraseDocFiles
[l
] );
1382 fprintf( PhraseDocFiles
[0], "</body></html>\n" );
1383 fclose( PhraseDocFiles
[0] );
1387 } // makeIndexFile //
1390 //-----------------------------------------------
1391 // makeActionsBySkillGroupFile
1393 //-----------------------------------------------
1394 void makeActionsBySkillGroupFile()
1396 // progression by skill
1397 FILE * actionsBySkillGroupFile
= nlfopen( DocFileName
+ "__by_skill.html", "wt" );
1398 if( actionsBySkillGroupFile
)
1400 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() );
1401 fprintf( actionsBySkillGroupFile
, "<BR><A NAME=\"by_skill_group\"></A>\n" );
1402 fprintf( actionsBySkillGroupFile
, "<P><B>ACTIONS BY SKILL GROUP:</B><BR>\n<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" style=\"text-align: left;\"><tbody>\n" );
1403 map
<string
, multimap
<uint
,string
> > phrasesBySkill
;
1404 for ( map
< uint
, pair
<string
, string
> >::const_iterator ip
=Progression
.begin(); ip
!=Progression
.end(); ++ip
)
1406 const string
& phraseCode
= (*ip
).second
.first
;
1407 string skillName
= (*ip
).second
.second
.substr(0,(*ip
).second
.second
.find(" "));
1408 string skillValueStr
= (*ip
).second
.second
.substr((*ip
).second
.second
.find(" ")+1,(*ip
).second
.second
.size()-(*ip
).second
.second
.find(" ")-1);
1409 uint skillValue
= atoi(skillValueStr
.c_str());
1411 map
<string
, multimap
<uint
,string
> >::iterator it
= phrasesBySkill
.find(skillName
);
1412 if( it
!= phrasesBySkill
.end() )
1414 (*it
).second
.insert(make_pair(skillValue
,phraseCode
));
1418 multimap
<uint
,string
> m
;
1419 m
.insert(make_pair(skillValue
,phraseCode
));
1420 phrasesBySkill
.insert( make_pair(skillName
,m
) );
1424 map
<string
, multimap
<uint
,string
> >::iterator itPhrasesBySkill
;
1425 for( itPhrasesBySkill
= phrasesBySkill
.begin(); itPhrasesBySkill
!= phrasesBySkill
.end(); ++itPhrasesBySkill
)
1427 CVectorSString dicoResult
;
1428 Dico
.lookup( (*itPhrasesBySkill
).first
, dicoResult
, true );
1429 if( !dicoResult
.empty() )
1430 fprintf( actionsBySkillGroupFile
, "<tr><td><A HREF=\"#%s\">%s</A></td></tr>\n", (*itPhrasesBySkill
).first
.c_str(),dicoResult
[0].c_str());
1432 fprintf( actionsBySkillGroupFile
, "<tr><td><A HREF=\"#%s\">%s</A></td></tr>\n", (*itPhrasesBySkill
).first
.c_str(),(*itPhrasesBySkill
).first
.c_str());
1434 for( itPhrasesBySkill
= phrasesBySkill
.begin(); itPhrasesBySkill
!= phrasesBySkill
.end(); ++itPhrasesBySkill
)
1436 CVectorSString dicoResult
;
1437 Dico
.lookup( (*itPhrasesBySkill
).first
, dicoResult
, true );
1438 if( !dicoResult
.empty() )
1439 fprintf( actionsBySkillGroupFile
, "<tr><td><A NAME=\"%s\"><B>%s</B></A><BR></td></tr>\n", (*itPhrasesBySkill
).first
.c_str(), dicoResult
[0].c_str() );
1441 fprintf( actionsBySkillGroupFile
, "<tr><td><A NAME=\"%s\"><B>%s</B></A><BR></td></tr>\n", (*itPhrasesBySkill
).first
.c_str(),(*itPhrasesBySkill
).first
.c_str() );
1443 multimap
<uint
,string
>::iterator it
;
1444 for( it
= (*itPhrasesBySkill
).second
.begin(); it
!= (*itPhrasesBySkill
).second
.end(); ++it
)
1446 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());
1449 fprintf( actionsBySkillGroupFile
, "</tbody><table></P>\n" );
1450 fprintf( actionsBySkillGroupFile
, "</body></html>\n" );
1451 fclose( actionsBySkillGroupFile
);
1454 } // makeActionsBySkillGroupFile //
1458 //-----------------------------------------------
1459 // makeActionsBySkillValueFile
1461 //-----------------------------------------------
1462 void makeActionsBySkillValueFile()
1464 FILE * actionsBySkillValueFile
= fopen( (DocFileName
+ "__by_skill_value.html").c_str(), "wt" );
1465 if( actionsBySkillValueFile
)
1467 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() );
1469 // Progression (phrases sorted by skill value)
1470 fprintf( actionsBySkillValueFile
, "<BR><A NAME=\"by_skill_value\"></A>\n" );
1471 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() );
1472 fprintf( actionsBySkillValueFile
, "<tr><td><B>File</B></td><td><B>Name</B></td><td><B>Skill needed</B><BR></td></tr>\n");
1473 map
<string
,string
> phraseCodeToLink
;
1474 for ( map
< uint
, pair
<string
, string
> >::const_iterator ip
=Progression
.begin(); ip
!=Progression
.end(); ++ip
)
1476 const string
& phraseCode
= (*ip
).second
.first
;
1477 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() );
1479 fprintf( actionsBySkillValueFile
, "</tbody><table></P>\n" );
1480 fprintf( actionsBySkillValueFile
, "</body></html>\n" );
1481 fclose( actionsBySkillValueFile
);
1484 } // makeActionsBySkillValueFile //
1487 //-----------------------------------------------
1488 // makeActionsBySkillValueDetailFile
1490 //-----------------------------------------------
1491 void makeActionsBySkillValueDetailFile()
1493 FILE * actionsBySkillValueDetailFile
= nlfopen( DocFileName
+ "__by_skill_value_detail.html", "wt" );
1494 if( actionsBySkillValueDetailFile
)
1496 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() );
1498 // Progression summary (phrases sorted by skill value)
1499 fprintf( actionsBySkillValueDetailFile
, "<BR><A NAME=\"progression\"></A>\n" );
1500 fprintf( actionsBySkillValueDetailFile
, "<P><B>ACTIONS BY SKILL VALUE:</B><BR>\n<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" style=\"text-align: left;\"><tbody>\n" );
1501 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");
1503 set
<string
> effects
;
1504 map
<string
,set
<string
> > effectAndModifiers
;
1505 for ( map
< uint
, pair
<string
, string
> >::const_iterator ip
=Progression
.begin(); ip
!=Progression
.end(); ++ip
)
1507 const string
& phraseCode
= (*ip
).second
.first
;
1508 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
]);
1510 msvs::iterator itPhrases
= Phrases
.find( phraseCode
);
1511 if( itPhrases
!= Phrases
.end() )
1514 uint modifierCount
= 0;
1515 uint creditCount
= 0;
1516 for( uint i
= 0; i
<(*itPhrases
).second
.size(); ++i
)
1518 string brick
= (*itPhrases
).second
[i
];
1520 switch ( brick
[brick
.size()-getBrickTypeLetterRPos(brick
)] )
1522 case 'P': color
= "Black";
1527 effects
.insert(brick
);
1528 if( effectAndModifiers
.find(brick
) == effectAndModifiers
.end() )
1531 effectAndModifiers
.insert( make_pair(brick
,s
) );
1536 case 'O': color
= "Green";
1541 effectAndModifiers
[effect
].insert(brick
);
1545 case 'C': color
= "Red"; creditCount
++;
1550 string text
= BrickInfo
[brick
].Text
;
1553 text
= strlwr(brick
);
1554 nlwarning("%s not found in BrickInfo",brick
.c_str());
1558 if(text
.find("$|sap")!=-1)
1560 text
= text
.substr(0,text
.size()-5);
1561 string str
= brick
.substr(brick
.size()-5,5);
1562 text
+= toString(atoi(str
.c_str()));
1565 fprintf( actionsBySkillValueDetailFile
, "<td><FONT COLOR=\"%s\" SIZE=2>%s</FONT></td>",color
.c_str(),text
.c_str());
1570 nlerror("not found : %s",phraseCode
.c_str());
1572 fprintf( actionsBySkillValueDetailFile
, "</tr>\n");
1574 fprintf( actionsBySkillValueDetailFile
, "</tbody><table></P>\n" );
1575 fprintf( actionsBySkillValueDetailFile
, "</body></html>\n" );
1576 fclose( actionsBySkillValueDetailFile
);
1579 } // makeActionsBySkillValueDetailFile //
1582 //-----------------------------------------------
1585 //-----------------------------------------------
1586 bool validateBrick( const string
& brk
)
1588 if(brk
[1]=='C') return true;
1589 if(brk
[1]=='F') return true;
1590 if(brk
[1]=='H') return true;
1591 if(brk
[1]=='M') return true;
1592 if(brk
[1]=='S') return true;
1595 } // validateBrick //
1599 //-----------------------------------------------
1600 // makeSkillTreeFile
1602 //-----------------------------------------------
1603 void makeSkillTreeFile( char filter
, string skillFamily
, bool withTraduction
)
1605 vector
<map
<string
,uint16
> > skillsArray
;
1606 skillsArray
.resize(6); // 6 tranches de skill
1608 for( i
= 0; i
<SkillsTree
.SkillsTree
.size(); ++i
)
1610 string skillCode
= SkillsTree
.SkillsTree
[i
].SkillCode
;
1611 if( skillCode
[1] == filter
)
1613 uint sIdx
= skillCode
.length()-2; // -1 for 'S', -1 for 0
1614 skillsArray
[sIdx
].insert( make_pair(skillCode
,SkillsTree
.SkillsTree
[i
].MaxSkillValue
) );
1619 for( i
=0; i
<skillsArray
.size(); ++i
)
1621 if( skillsArray
[i
].size() > maxLine
)
1623 maxLine
= skillsArray
[i
].size();
1627 string filename
= skillFamily
+ "_skill_tree.html";
1628 string filenameWithTraduction
= skillFamily
+ "_skill_tree_detailed.html";
1629 FILE * skillTreeFile
;
1630 if( withTraduction
)
1631 skillTreeFile
= nlfopen( filenameWithTraduction
, "wt" );
1633 skillTreeFile
= nlfopen( filename
, "wt" );
1634 fprintf( skillTreeFile
,"<html><head>\n");
1635 fprintf( skillTreeFile
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
1636 fprintf( skillTreeFile
,"<title>SKILL TREE ( %s )</title>\n",skillFamily
.c_str());
1637 fprintf( skillTreeFile
,"</head><body>\n");
1638 if( withTraduction
)
1639 fprintf( skillTreeFile
,"<b>SKILL TREE ( %s )</b>\n",skillFamily
.c_str());
1641 fprintf( skillTreeFile
,"<b>SKILL TREE ( %s )</b> [<A HREF=\"%s\">display traduction</A>]<BR>\n",skillFamily
.c_str(),filenameWithTraduction
.c_str());
1642 fprintf( skillTreeFile
,"<table cellpadding=\"2\" cellspacing=\"2\" border=\"0\" style=\"text-align: left;\"><tbody>\n");
1643 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");
1646 // print line by line
1647 for( j
=0; j
<maxLine
; ++j
)
1649 fprintf( skillTreeFile
,"<tr>");
1651 for( i
=0; i
<skillsArray
.size(); ++i
)
1654 map
<string
,uint16
>::iterator itSkillcode
;
1655 for( itSkillcode
= skillsArray
[i
].begin(), p
=0; itSkillcode
!= skillsArray
[i
].end() && p
<j
; ++itSkillcode
,++p
);
1656 if( itSkillcode
!= skillsArray
[i
].end() )
1658 if( withTraduction
)
1660 CVectorSString dicoResult
;
1661 Dico
.lookup( (*itSkillcode
).first
, dicoResult
, true );
1662 if(dicoResult
.empty())
1663 fprintf( skillTreeFile
,"<td>%s : ???</td>",(*itSkillcode
).first
.c_str());
1665 fprintf( skillTreeFile
,"<td>%s</td>",dicoResult
[0].c_str());
1668 fprintf( skillTreeFile
,"<td>%s</td>",(*itSkillcode
).first
.c_str());
1671 fprintf( skillTreeFile
,"<td></td>");
1673 fprintf( skillTreeFile
,"</tr>\n");
1676 fprintf( skillTreeFile
, "</tbody><table></P>\n" );
1677 fprintf( skillTreeFile
, "</body></html>\n" );
1678 fclose( skillTreeFile
);
1680 } // makeSkillTreeFile //
1686 //-----------------------------------------------
1689 //-----------------------------------------------
1690 int main(int argc
, char* argv
[])
1692 // parse command line
1693 const char *inputFilename
= NULL
;
1694 for ( uint i
=1; (sint
)i
!=argc
; i
++ )
1696 const char *arg
= argv
[i
];
1697 if ( arg
[0] == '-' )
1703 if ( (sint
)i
== argc
)
1705 fprintf( stderr
, "Missing <sheet path> after -p option\n" );
1706 usage( argv
[0], stderr
);
1709 inputSheetPath
= argv
[i
];
1713 if ( (sint
)i
== argc
)
1715 fprintf( stderr
, "Missing <phrasePath> after -o option\n" );
1716 usage( argv
[0], stderr
);
1719 PhrasePath
= argv
[i
];
1720 if ( PhrasePath
[PhrasePath
.size()-1] != '/' )
1724 GenerateBrickProgression
= true;
1727 ProduceDocFromExistingPhrases
= true;
1730 MultipleDocFiles
= true;
1739 if ( CFile::getExtension(arg
) == "csv" )
1741 inputFilename
= arg
;
1744 nlerror( "Unrecognized extension in %s", arg
);
1752 FormLoader
= UFormLoader::createLoader();
1755 CSheetId
skillTreeSheet("skills.skill_tree");
1756 CSmartPtr
<UForm
> skillTreeForm
= FormLoader
->loadForm( "skills.skill_tree" );
1757 SkillsTree
.readGeorges( skillTreeForm
, skillTreeSheet
);
1760 makeSkillTreeFile('C',"craft", false);
1761 makeSkillTreeFile('F',"fight", false);
1762 makeSkillTreeFile('H',"forage", false);
1763 makeSkillTreeFile('M',"magic", false);
1765 makeSkillTreeFile('C',"craft", true);
1766 makeSkillTreeFile('F',"fight", true);
1767 makeSkillTreeFile('H',"forage", true);
1768 makeSkillTreeFile('M',"magic", true);
1771 // Load bricks from the csv
1772 UseBricks
= ProduceDocFromExistingPhrases
;
1775 if ( ! inputFilename
)
1777 usage( argv
[0], stderr
);
1780 loadBricks( inputFilename
);
1785 if ( ProduceDocFromExistingPhrases
)
1791 DocFileNameRoot
= toString( "%s", CFile::getFilenameWithoutExtension( inputFilename
).c_str() );
1796 // progression by skill
1797 makeActionsBySkillGroupFile();
1799 // Progression (phrases sorted by skill value)
1800 makeActionsBySkillValueFile();
1802 // Progression (phrases sorted by skill value + detail)
1803 makeActionsBySkillValueDetailFile();
1808 if( GenerateBrickProgression
)
1810 map
<uint
,map
<string
,set
<string
> > > levelToBrick
;
1812 map
<string
,string
> phraseToSkill
;
1814 for ( map
< uint
, pair
<string
, string
> >::const_iterator ip
=Progression
.begin(); ip
!=Progression
.end(); ++ip
)
1816 const string
& phraseCode
= (*ip
).second
.first
;
1818 string skillTmp
= (*ip
).second
.second
.c_str();
1820 phraseToSkill
.insert( make_pair(phraseCode
,skillTmp
) );
1822 if(skillTmp
.empty()==false)
1825 string skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
1829 if( skillTmp
.find(";") != -1 )
1831 sint idx
= skillTmp
.find_first_of(" ");
1832 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
1836 sint idx
= skillTmp
.find_first_of(" ");
1837 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
1839 if(levelStr
.find(".")!=-1) levelStr
= levelStr
.substr(0,levelStr
.size()-1);
1840 uint level
= atoi(levelStr
.c_str());
1843 map
<uint
,map
<string
,set
<string
> > >::iterator itLvl
= levelToBrick
.find(level
);
1844 if( itLvl
== levelToBrick
.end() )
1847 map
<string
,set
<string
> > mp
;
1848 mp
.insert(make_pair(skill
,s
));
1849 levelToBrick
.insert(make_pair(level
,mp
));
1853 if( (*itLvl
).second
.find(skill
) == (*itLvl
).second
.end() )
1856 (*itLvl
).second
.insert( make_pair(skill
,s
) );
1860 msvs::iterator itPhrases
= Phrases
.find( phraseCode
);
1861 if( itPhrases
!= Phrases
.end() )
1864 for( uint i
= 0; i
<(*itPhrases
).second
.size(); ++i
)
1866 string brick
= (*itPhrases
).second
[i
];
1868 if( levelToBrick
[level
][skill
].find(brick
) == levelToBrick
[level
][skill
].end() )
1870 levelToBrick
[level
][skill
].insert(brick
);
1880 // get family & color
1881 map
<string
,string
> brickToColor
;
1882 map
<string
,string
> brickToFamily
;
1883 map
<string
, CBrickInfo
>::iterator itBInf
;
1884 for( itBInf
=BrickInfo
.begin(); itBInf
!=BrickInfo
.end(); ++itBInf
)
1886 string brk
= (*itBInf
).first
;
1888 if(!validateBrick(brk
)) continue;
1892 if( brk
[brk
.size()-getBrickTypeLetterRPos(brk
)] =='M' )
1895 family
= "Modifier";
1897 if( brk
[brk
.size()-getBrickTypeLetterRPos(brk
)] =='C' )
1902 if( brk
[brk
.size()-getBrickTypeLetterRPos(brk
)] =='O' )
1907 if( brk
[brk
.size()-getBrickTypeLetterRPos(brk
)] =='P' )
1912 if( brk
[brk
.size()-getBrickTypeLetterRPos(brk
)] =='E' )
1918 brickToColor
.insert(make_pair(brk
,color
));
1919 brickToFamily
.insert(make_pair(brk
,family
));
1922 // get phrases where the brick can be found
1923 map
<string
,map
<string
,string
> > brickToPhrases
;
1924 msvs::iterator itPhrases
;
1925 for( itPhrases
=Phrases
.begin(); itPhrases
!=Phrases
.end(); ++itPhrases
)
1927 for( uint i
= 0; i
<(*itPhrases
).second
.size(); ++i
)
1929 string brick
= (*itPhrases
).second
[i
];
1930 if( brickToPhrases
.find(brick
)==brickToPhrases
.end() )
1932 map
<string
,string
> m
;
1934 m
.insert(make_pair((*itPhrases
).first
,phraseToSkill
[(*itPhrases
).first
]));
1935 brickToPhrases
.insert(make_pair(brick
,m
));
1939 brickToPhrases
[brick
].insert(make_pair((*itPhrases
).first
,phraseToSkill
[(*itPhrases
).first
]));
1944 // get skill when a brick is learnt
1945 map
<string
,string
> brickToLearnSkill
;
1946 map
<string
,map
<string
,string
> >::iterator itLearn
;
1947 for( itLearn
=brickToPhrases
.begin(); itLearn
!=brickToPhrases
.end(); ++itLearn
)
1950 uint minLevel
= 250;
1953 for( itPh
=(*itLearn
).second
.begin(); itPh
!=(*itLearn
).second
.end(); ++itPh
)
1955 string skillTmp
= (*itPh
).second
;
1957 if( skillTmp
.find(";") != -1 )
1959 sint idx
= skillTmp
.find_first_of(" ");
1960 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
1964 sint idx
= skillTmp
.find_first_of(" ");
1965 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
1967 uint level
= atoi(levelStr
.c_str());
1969 if( level
<minLevel
|| minSkill
.empty() )
1971 minSkill
= skillTmp
;
1976 brickToLearnSkill
.insert(make_pair((*itLearn
).first
,minSkill
));
1981 // write header and title bar
1983 filename
= DocFileNameRoot
+ "_m.html";
1984 FILE * brickPhraseDocFile_m
= nlfopen( filename
, "wt" );
1985 fprintf( brickPhraseDocFile_m
,"<html><head>\n");
1986 fprintf( brickPhraseDocFile_m
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
1987 fprintf( brickPhraseDocFile_m
,"<title>Brick phrases</title>\n");
1988 fprintf( brickPhraseDocFile_m
,"</head><body>\n");
1989 fprintf( brickPhraseDocFile_m
,"<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" style=\"text-align: left;\"><tbody>\n");
1991 filename
= DocFileNameRoot
+ "_c.html";
1992 FILE * brickPhraseDocFile_c
= nlfopen( filename
, "wt" );
1993 fprintf( brickPhraseDocFile_c
,"<html><head>\n");
1994 fprintf( brickPhraseDocFile_c
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
1995 fprintf( brickPhraseDocFile_c
,"<title>Brick phrases</title>\n");
1996 fprintf( brickPhraseDocFile_c
,"</head><body>\n");
1997 fprintf( brickPhraseDocFile_c
,"<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" style=\"text-align: left;\"><tbody>\n");
1999 filename
= DocFileNameRoot
+ "_o.html";
2000 FILE * brickPhraseDocFile_o
= nlfopen( filename
, "wt" );
2001 fprintf( brickPhraseDocFile_o
,"<html><head>\n");
2002 fprintf( brickPhraseDocFile_o
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2003 fprintf( brickPhraseDocFile_o
,"<title>Brick phrases</title>\n");
2004 fprintf( brickPhraseDocFile_o
,"</head><body>\n");
2005 fprintf( brickPhraseDocFile_o
,"<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" style=\"text-align: left;\"><tbody>\n");
2007 filename
= DocFileNameRoot
+ "_p.html";
2008 FILE * brickPhraseDocFile_p
= nlfopen( filename
, "wt" );
2009 fprintf( brickPhraseDocFile_p
,"<html><head>\n");
2010 fprintf( brickPhraseDocFile_p
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2011 fprintf( brickPhraseDocFile_p
,"<title>Brick phrases</title>\n");
2012 fprintf( brickPhraseDocFile_p
,"</head><body>\n");
2013 fprintf( brickPhraseDocFile_p
,"<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" style=\"text-align: left;\"><tbody>\n");
2015 filename
= DocFileNameRoot
+ "_e.html";
2016 FILE * brickPhraseDocFile_e
= nlfopen( filename
, "wt" );
2017 fprintf( brickPhraseDocFile_e
,"<html><head>\n");
2018 fprintf( brickPhraseDocFile_e
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2019 fprintf( brickPhraseDocFile_e
,"<title>Brick phrases</title>\n");
2020 fprintf( brickPhraseDocFile_e
,"</head><body>\n");
2021 fprintf( brickPhraseDocFile_e
,"<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" style=\"text-align: left;\"><tbody>\n");
2023 for( itBInf
=BrickInfo
.begin(); itBInf
!=BrickInfo
.end(); ++itBInf
)
2025 string brk
= (*itBInf
).first
;
2027 if(!validateBrick(brk
)) continue;
2029 string code
= strlwr(brk
.c_str());
2031 if(brickToFamily
[brk
]=="Modifier")
2032 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());
2033 if(brickToFamily
[brk
]=="Credit")
2034 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());
2035 if(brickToFamily
[brk
]=="Option")
2036 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());
2037 if(brickToFamily
[brk
]=="Effect")
2038 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());
2039 if(brickToFamily
[brk
]=="Root")
2040 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());
2042 map
<string
,map
<string
,string
> >::iterator itPhrases
= brickToPhrases
.find(brk
);
2043 if( itPhrases
!= brickToPhrases
.end() )
2045 map
<string
,string
>::iterator itPh
;
2046 for( itPh
=(*itPhrases
).second
.begin(); itPh
!=(*itPhrases
).second
.end(); ++itPh
)
2048 if(brickToFamily
[brk
]=="Modifier")
2049 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());
2050 if(brickToFamily
[brk
]=="Credit")
2051 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());
2052 if(brickToFamily
[brk
]=="Option")
2053 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());
2054 if(brickToFamily
[brk
]=="Effect")
2055 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());
2056 if(brickToFamily
[brk
]=="Root")
2057 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());
2061 fprintf( brickPhraseDocFile_m
, "</tbody><table></P>\n" );
2062 fprintf( brickPhraseDocFile_m
, "</body></html>\n" );
2063 fclose( brickPhraseDocFile_m
);
2065 fprintf( brickPhraseDocFile_c
, "</tbody><table></P>\n" );
2066 fprintf( brickPhraseDocFile_c
, "</body></html>\n" );
2067 fclose( brickPhraseDocFile_c
);
2069 fprintf( brickPhraseDocFile_o
, "</tbody><table></P>\n" );
2070 fprintf( brickPhraseDocFile_o
, "</body></html>\n" );
2071 fclose( brickPhraseDocFile_o
);
2073 fprintf( brickPhraseDocFile_e
, "</tbody><table></P>\n" );
2074 fprintf( brickPhraseDocFile_e
, "</body></html>\n" );
2075 fclose( brickPhraseDocFile_e
);
2077 fprintf( brickPhraseDocFile_p
, "</tbody><table></P>\n" );
2078 fprintf( brickPhraseDocFile_p
, "</body></html>\n" );
2079 fclose( brickPhraseDocFile_p
);
2084 // write header and title bar
2085 filename
= DocFileNameRoot
+ ".html";
2086 FILE * brickDocFile
= nlfopen( filename
, "wt" );
2087 fprintf( brickDocFile
,"<html><head>\n");
2088 fprintf( brickDocFile
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2089 fprintf( brickDocFile
,"<title>Bricks infos</title>\n");
2090 fprintf( brickDocFile
,"</head><body>\n");
2091 fprintf( brickDocFile
,"<table cellpadding=\"1\" cellspacing=\"1\" border=\"0\"><tbody>\n");
2092 fprintf( brickDocFile
,"<tr>\n");
2093 fprintf( brickDocFile
,"<td><b>*Code*</b></td>\n");
2094 fprintf( brickDocFile
,"<td><b><a href=\"%s_name.html\">Name</a></b></td>\n",DocFileNameRoot
.c_str());
2095 fprintf( brickDocFile
,"<td><b><a href=\"%s_family.html\">Family</a></b></td>\n",DocFileNameRoot
.c_str());
2096 fprintf( brickDocFile
,"<td><b>Required Skill Name</b></td>\n");
2097 fprintf( brickDocFile
,"<td><b><a href=\"%s_required_skill_value.html\">Required Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2098 fprintf( brickDocFile
,"<td><b>Learn Skill Name</b></td>\n");
2099 fprintf( brickDocFile
,"<td><b><a href=\"%s_learn_skill_value.html\">Learn Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2100 fprintf( brickDocFile
,"<td><b>Found In Phrases</b></td>\n");
2101 fprintf( brickDocFile
,"</tr>\n");
2105 for( itBInf
=BrickInfo
.begin(); itBInf
!=BrickInfo
.end(); ++itBInf
)
2107 string brk
= (*itBInf
).first
;
2109 if(!validateBrick(brk
)) continue;
2111 string skillTmp
= (*itBInf
).second
.LearnSkills
;
2112 string skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2113 CVectorSString dicoResult
;
2114 Dico
.lookup( skill
, dicoResult
, true );
2115 if(dicoResult
.empty()) continue;
2118 string color
= brickToColor
[brk
];
2121 string code
= strlwr(brk
.c_str());
2122 fprintf( brickDocFile
, "<tr><td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),code
.c_str());
2125 string name
= (*itBInf
).second
.Text
;
2126 fprintf( brickDocFile
, "<td>%s</td>\n",name
.c_str());
2129 string family
= brickToFamily
[brk
];
2130 fprintf( brickDocFile
, "<td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),family
.c_str());
2132 // required skill name
2133 fprintf( brickDocFile
, "<td>%s</td>\n",dicoResult
[0].c_str());
2135 // required skill value
2137 if( skillTmp
.find(";") != -1 )
2139 sint idx
= skillTmp
.find_first_of(" ");
2140 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2144 sint idx
= skillTmp
.find_first_of(" ");
2145 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2147 fprintf( brickDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2150 string learnSkillTmp
= brickToLearnSkill
[brk
];
2151 skill
= learnSkillTmp
.substr(0,learnSkillTmp
.find_first_of(" "));
2152 fprintf( brickDocFile
, "<td>%s</td>\n",skill
.c_str());
2154 // learn skill value
2155 if( learnSkillTmp
.find(";") != -1 )
2157 sint idx
= learnSkillTmp
.find_first_of(" ");
2158 levelStr
= learnSkillTmp
.substr(idx
+1,learnSkillTmp
.find_first_of(";")-idx
-1);
2162 sint idx
= learnSkillTmp
.find_first_of(" ");
2163 levelStr
= learnSkillTmp
.substr(idx
+1,learnSkillTmp
.size()-idx
);
2165 fprintf( brickDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2169 fprintf( brickDocFile
, "<td>");
2170 map
<string
,map
<string
,string
> >::iterator itPhrases
= brickToPhrases
.find(brk
);
2171 if( itPhrases
!= brickToPhrases
.end() )
2173 map
<string
,string
>::iterator itPh
;
2175 for( itPh
=(*itPhrases
).second
.begin(),i
=0; itPh
!=(*itPhrases
).second
.end() && i
<2; ++itPh
,++i
)
2177 if( MultipleDocFiles
)
2178 fprintf( brickDocFile
,"<A HREF=\"%s_%c.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
[7],(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2180 fprintf( brickDocFile
,"<A HREF=\"%s.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2184 char type
= family
[0];
2185 fprintf( brickDocFile
,"[<A HREF=\"%s_%c.html#%s\">...</A>]",DocFileNameRoot
.c_str(),type
,brk
.c_str());
2189 fprintf( brickDocFile
, "</td></tr>\n");
2191 fprintf( brickDocFile
, "</tbody><table></P>\n" );
2192 fprintf( brickDocFile
, "</body></html>\n" );
2193 fclose( brickDocFile
);
2199 // write header and title bar
2200 filename
= DocFileNameRoot
+ "_name.html";
2201 FILE * brickNameDocFile
= nlfopen( filename
, "wt" );
2202 fprintf( brickNameDocFile
,"<html><head>\n");
2203 fprintf( brickNameDocFile
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2204 fprintf( brickNameDocFile
,"<title>Bricks infos</title>\n");
2205 fprintf( brickNameDocFile
,"</head><body>\n");
2206 fprintf( brickNameDocFile
,"<table cellpadding=\"1\" cellspacing=\"1\" border=\"0\"><tbody>\n");
2207 fprintf( brickNameDocFile
,"<tr>\n");
2208 fprintf( brickNameDocFile
,"<td><b><a href=\"%s.html\">Code</a></b></td>\n",DocFileNameRoot
.c_str());
2209 fprintf( brickNameDocFile
,"<td><b>*Name*</b></td>\n");
2210 fprintf( brickNameDocFile
,"<td><b><a href=\"%s_family.html\">Family</a></b></td>\n",DocFileNameRoot
.c_str());
2211 fprintf( brickNameDocFile
,"<td><b>Required Skill Name</b></td>\n");
2212 fprintf( brickNameDocFile
,"<td><b><a href=\"%s_required_skill_value.html\">Required Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2213 fprintf( brickNameDocFile
,"<td><b>Learn Skill Name</b></td>\n");
2214 fprintf( brickNameDocFile
,"<td><b><a href=\"%s_learn_skill_value.html\">Learn Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2215 fprintf( brickNameDocFile
,"<td><b>Found In Phrases</b></td>\n");
2216 fprintf( brickNameDocFile
,"</tr>\n");
2218 map
<string
,string
> nameToCode
;
2219 for( itBInf
=BrickInfo
.begin(); itBInf
!=BrickInfo
.end(); ++itBInf
)
2221 string brk
= (*itBInf
).first
;
2223 if(!validateBrick(brk
)) continue;
2226 string code
= strlwr(brk
.c_str());
2229 string name
= (*itBInf
).second
.Text
;
2231 nameToCode
.insert( make_pair(name
,brk
) );
2234 mss::iterator itNTC
;
2235 for( itNTC
=nameToCode
.begin(); itNTC
!=nameToCode
.end(); ++itNTC
)
2237 itBInf
=BrickInfo
.find((*itNTC
).second
);
2239 string brk
= (*itBInf
).first
;
2241 if(!validateBrick(brk
)) continue;
2243 string skillTmp
= (*itBInf
).second
.LearnSkills
;
2244 string skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2245 CVectorSString dicoResult
;
2246 Dico
.lookup( skill
, dicoResult
, true );
2247 if(dicoResult
.empty()) continue;
2250 string color
= brickToColor
[brk
];
2253 string code
= strlwr(brk
.c_str());
2254 fprintf( brickNameDocFile
, "<tr><td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),code
.c_str());
2257 string name
= (*itBInf
).second
.Text
;
2258 fprintf( brickNameDocFile
, "<td>%s</td>\n",name
.c_str());
2261 string family
= brickToFamily
[brk
];
2262 fprintf( brickNameDocFile
, "<td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),family
.c_str());
2264 // required skill name
2265 fprintf( brickNameDocFile
, "<td>%s</td>\n",dicoResult
[0].c_str());
2267 // required skill value
2269 if( skillTmp
.find(";") != -1 )
2271 sint idx
= skillTmp
.find_first_of(" ");
2272 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2276 sint idx
= skillTmp
.find_first_of(" ");
2277 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2279 fprintf( brickNameDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2282 skillTmp
= brickToLearnSkill
[brk
];
2283 skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2284 fprintf( brickNameDocFile
, "<td>%s</td>\n",skill
.c_str());
2286 // learn skill value
2287 if( skillTmp
.find(";") != -1 )
2289 sint idx
= skillTmp
.find_first_of(" ");
2290 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2294 sint idx
= skillTmp
.find_first_of(" ");
2295 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2297 fprintf( brickNameDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2301 fprintf( brickNameDocFile
, "<td>");
2302 map
<string
,map
<string
,string
> >::iterator itPhrases
= brickToPhrases
.find(brk
);
2303 if( itPhrases
!= brickToPhrases
.end() )
2305 map
<string
,string
>::iterator itPh
;
2307 for( itPh
=(*itPhrases
).second
.begin(),i
=0; itPh
!=(*itPhrases
).second
.end() && i
<2; ++itPh
,++i
)
2309 if( MultipleDocFiles
)
2310 fprintf( brickNameDocFile
,"<A HREF=\"%s_%c.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
[7],(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2312 fprintf( brickNameDocFile
,"<A HREF=\"%s.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2316 char type
= family
[0];
2317 fprintf( brickNameDocFile
,"[<A HREF=\"%s_%c.html#%s\">...</A>]",DocFileNameRoot
.c_str(),type
,brk
.c_str());
2321 fprintf( brickNameDocFile
, "</td></tr>\n");
2325 fprintf( brickNameDocFile
, "</tbody><table></P>\n" );
2326 fprintf( brickNameDocFile
, "</body></html>\n" );
2327 fclose( brickNameDocFile
);
2334 // write header and title bar
2335 filename
= DocFileNameRoot
+ "_family.html";
2336 FILE * brickFamilyDocFile
= nlfopen( filename
, "wt" );
2337 fprintf( brickFamilyDocFile
,"<html><head>\n");
2338 fprintf( brickFamilyDocFile
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2339 fprintf( brickFamilyDocFile
,"<title>Bricks infos</title>\n");
2340 fprintf( brickFamilyDocFile
,"</head><body>\n");
2341 fprintf( brickFamilyDocFile
,"<table cellpadding=\"1\" cellspacing=\"1\" border=\"0\"><tbody>\n");
2342 fprintf( brickFamilyDocFile
,"<tr>\n");
2343 fprintf( brickFamilyDocFile
,"<td><b><a href=\"%s.html\">Code</a></b></td>\n",DocFileNameRoot
.c_str());
2344 fprintf( brickFamilyDocFile
,"<td><b><a href=\"%s_name.html\">Name</a></b></td>\n",DocFileNameRoot
.c_str());
2345 fprintf( brickFamilyDocFile
,"<td><b>*Family*</b></td>\n");
2346 fprintf( brickFamilyDocFile
,"<td><b>Required Skill Name</b></td>\n");
2347 fprintf( brickFamilyDocFile
,"<td><b><a href=\"%s_required_skill_value.html\">Required Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2348 fprintf( brickFamilyDocFile
,"<td><b>Learn Skill Name</b></td>\n");
2349 fprintf( brickFamilyDocFile
,"<td><b><a href=\"%s_learn_skill_value.html\">Learn Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2350 fprintf( brickFamilyDocFile
,"<td><b>Found In Phrases</b></td>\n");
2351 fprintf( brickFamilyDocFile
,"</tr>\n");
2355 multimap
<string
,string
> familyToCode
;
2356 for( itBInf
=BrickInfo
.begin(); itBInf
!=BrickInfo
.end(); ++itBInf
)
2358 string brk
= (*itBInf
).first
;
2360 if(!validateBrick(brk
)) continue;
2363 string family
= brickToFamily
[brk
];
2365 familyToCode
.insert( make_pair(family
,brk
) );
2368 multimap
<string
,string
>::iterator itFTC
;
2369 for( itFTC
=familyToCode
.begin(); itFTC
!=familyToCode
.end(); ++itFTC
)
2371 itBInf
=BrickInfo
.find((*itFTC
).second
);
2373 string brk
= (*itBInf
).first
;
2375 if(!validateBrick(brk
)) continue;
2377 string skillTmp
= (*itBInf
).second
.LearnSkills
;
2378 string skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2379 CVectorSString dicoResult
;
2380 Dico
.lookup( skill
, dicoResult
, true );
2381 if(dicoResult
.empty()) continue;
2384 string color
= brickToColor
[brk
];
2387 string code
= strlwr(brk
.c_str());
2388 fprintf( brickFamilyDocFile
, "<tr><td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),code
.c_str());
2391 string name
= (*itBInf
).second
.Text
;
2392 fprintf( brickFamilyDocFile
, "<td>%s</td>\n",name
.c_str());
2395 string family
= brickToFamily
[brk
];
2396 fprintf( brickFamilyDocFile
, "<td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),family
.c_str());
2398 // required skill name
2399 fprintf( brickFamilyDocFile
, "<td>%s</td>\n",dicoResult
[0].c_str());
2401 // required skill value
2403 if( skillTmp
.find(";") != -1 )
2405 sint idx
= skillTmp
.find_first_of(" ");
2406 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2410 sint idx
= skillTmp
.find_first_of(" ");
2411 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2413 fprintf( brickFamilyDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2416 skillTmp
= brickToLearnSkill
[brk
];
2417 skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2418 fprintf( brickFamilyDocFile
, "<td>%s</td>\n",skill
.c_str());
2420 // learn skill value
2421 if( skillTmp
.find(";") != -1 )
2423 sint idx
= skillTmp
.find_first_of(" ");
2424 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2428 sint idx
= skillTmp
.find_first_of(" ");
2429 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2431 fprintf( brickFamilyDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2435 fprintf( brickFamilyDocFile
, "<td>");
2436 map
<string
,map
<string
,string
> >::iterator itPhrases
= brickToPhrases
.find(brk
);
2437 if( itPhrases
!= brickToPhrases
.end() )
2439 map
<string
,string
>::iterator itPh
;
2441 for( itPh
=(*itPhrases
).second
.begin(),i
=0; itPh
!=(*itPhrases
).second
.end() && i
<2; ++itPh
,++i
)
2443 if( MultipleDocFiles
)
2444 fprintf( brickFamilyDocFile
,"<A HREF=\"%s_%c.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
[7],(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2446 fprintf( brickFamilyDocFile
,"<A HREF=\"%s.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2450 char type
= family
[0];
2451 fprintf( brickFamilyDocFile
,"[<A HREF=\"%s_%c.html#%s\">...</A>]",DocFileNameRoot
.c_str(),type
,brk
.c_str());
2455 fprintf( brickFamilyDocFile
, "</td></tr>\n");
2457 fprintf( brickFamilyDocFile
, "</tbody><table></P>\n" );
2458 fprintf( brickFamilyDocFile
, "</body></html>\n" );
2459 fclose( brickFamilyDocFile
);
2464 // REQUIRED SKILL VALUE
2466 // write header and title bar
2467 filename
= DocFileNameRoot
+ "_required_skill_value.html";
2468 FILE * brickRequiredDocFile
= nlfopen( filename
, "wt" );
2469 fprintf( brickRequiredDocFile
,"<html><head>\n");
2470 fprintf( brickRequiredDocFile
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2471 fprintf( brickRequiredDocFile
,"<title>Bricks infos</title>\n");
2472 fprintf( brickRequiredDocFile
,"</head><body>\n");
2473 fprintf( brickRequiredDocFile
,"<table cellpadding=\"1\" cellspacing=\"1\" border=\"0\"><tbody>\n");
2474 fprintf( brickRequiredDocFile
,"<tr>\n");
2475 fprintf( brickRequiredDocFile
,"<td><b><a href=\"%s.html\">Code</a></b></td>\n",DocFileNameRoot
.c_str());
2476 fprintf( brickRequiredDocFile
,"<td><b><a href=\"%s_name.html\">Name</a></b></td>\n",DocFileNameRoot
.c_str());
2477 fprintf( brickRequiredDocFile
,"<td><b><a href=\"%s_family.html\">Family</a></b></td>\n",DocFileNameRoot
.c_str());
2478 fprintf( brickRequiredDocFile
,"<td><b>Required Skill Name</b></td>\n");
2479 fprintf( brickRequiredDocFile
,"<td><b>*Required Skill Value*</b></td>\n");
2480 fprintf( brickRequiredDocFile
,"<td><b>Learn Skill Name</b></td>\n");
2481 fprintf( brickRequiredDocFile
,"<td><b><a href=\"%s_learn_skill_value.html\">Learn Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2482 fprintf( brickRequiredDocFile
,"<td><b>Found In Phrases</b></td>\n");
2483 fprintf( brickRequiredDocFile
,"</tr>\n");
2487 multimap
<uint
,string
> requiredSkillValueToCode
;
2488 for( itBInf
=BrickInfo
.begin(); itBInf
!=BrickInfo
.end(); ++itBInf
)
2490 string brk
= (*itBInf
).first
;
2492 if(!validateBrick(brk
)) continue;
2494 // required skill value
2495 string skillTmp
= (*itBInf
).second
.LearnSkills
;
2497 if( skillTmp
.find(";") != -1 )
2499 sint idx
= skillTmp
.find_first_of(" ");
2500 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2504 sint idx
= skillTmp
.find_first_of(" ");
2505 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2507 uint level
= atoi(levelStr
.c_str());
2509 requiredSkillValueToCode
.insert( make_pair(level
,brk
) );
2512 multimap
<uint
,string
>::iterator itRTC
;
2513 for( itRTC
=requiredSkillValueToCode
.begin(); itRTC
!=requiredSkillValueToCode
.end(); ++itRTC
)
2515 itBInf
=BrickInfo
.find((*itRTC
).second
);
2517 string brk
= (*itBInf
).first
;
2519 if(!validateBrick(brk
)) continue;
2521 string skillTmp
= (*itBInf
).second
.LearnSkills
;
2522 string skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2523 CVectorSString dicoResult
;
2524 Dico
.lookup( skill
, dicoResult
, true );
2525 if(dicoResult
.empty()) continue;
2528 string color
= brickToColor
[brk
];
2531 string code
= strlwr(brk
.c_str());
2532 fprintf( brickRequiredDocFile
, "<tr><td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),code
.c_str());
2535 string name
= (*itBInf
).second
.Text
;
2536 fprintf( brickRequiredDocFile
, "<td>%s</td>\n",name
.c_str());
2539 string family
= brickToFamily
[brk
];
2540 fprintf( brickRequiredDocFile
, "<td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),family
.c_str());
2542 // required skill name
2543 fprintf( brickRequiredDocFile
, "<td>%s</td>\n",dicoResult
[0].c_str());
2545 // required skill value
2547 if( skillTmp
.find(";") != -1 )
2549 sint idx
= skillTmp
.find_first_of(" ");
2550 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2554 sint idx
= skillTmp
.find_first_of(" ");
2555 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2557 fprintf( brickRequiredDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2560 skillTmp
= brickToLearnSkill
[brk
];
2561 skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2562 fprintf( brickRequiredDocFile
, "<td>%s</td>\n",skill
.c_str());
2564 // learn skill value
2565 if( skillTmp
.find(";") != -1 )
2567 sint idx
= skillTmp
.find_first_of(" ");
2568 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2572 sint idx
= skillTmp
.find_first_of(" ");
2573 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2575 fprintf( brickRequiredDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2579 fprintf( brickRequiredDocFile
, "<td>");
2580 map
<string
,map
<string
,string
> >::iterator itPhrases
= brickToPhrases
.find(brk
);
2581 if( itPhrases
!= brickToPhrases
.end() )
2583 map
<string
,string
>::iterator itPh
;
2585 for( itPh
=(*itPhrases
).second
.begin(),i
=0; itPh
!=(*itPhrases
).second
.end() && i
<2; ++itPh
,++i
)
2587 if( MultipleDocFiles
)
2588 fprintf( brickRequiredDocFile
,"<A HREF=\"%s_%c.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
[7],(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2590 fprintf( brickRequiredDocFile
,"<A HREF=\"%s.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2594 char type
= family
[0];
2595 fprintf( brickRequiredDocFile
,"[<A HREF=\"%s_%c.html#%s\">...</A>]",DocFileNameRoot
.c_str(),type
,brk
.c_str());
2599 fprintf( brickRequiredDocFile
, "</td></tr>\n");
2601 fprintf( brickRequiredDocFile
, "</tbody><table></P>\n" );
2602 fprintf( brickRequiredDocFile
, "</body></html>\n" );
2603 fclose( brickRequiredDocFile
);
2607 // LEARN SKILL VALUE
2609 // write header and title bar
2610 filename
= DocFileNameRoot
+ "_learn_skill_value.html";
2611 FILE * brickLearnDocFile
= nlfopen( filename
, "wt" );
2612 fprintf( brickLearnDocFile
,"<html><head>\n");
2613 fprintf( brickLearnDocFile
,"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
2614 fprintf( brickLearnDocFile
,"<title>Bricks infos</title>\n");
2615 fprintf( brickLearnDocFile
,"</head><body>\n");
2616 fprintf( brickLearnDocFile
,"<table cellpadding=\"1\" cellspacing=\"1\" border=\"0\"><tbody>\n");
2617 fprintf( brickLearnDocFile
,"<tr>\n");
2618 fprintf( brickLearnDocFile
,"<td><b><a href=\"%s.html\">Code</a></b></td>\n",DocFileNameRoot
.c_str());
2619 fprintf( brickLearnDocFile
,"<td><b><a href=\"%s_name.html\">Name</a></b></td>\n",DocFileNameRoot
.c_str());
2620 fprintf( brickLearnDocFile
,"<td><b><a href=\"%s_family.html\">Family</a></b></td>\n",DocFileNameRoot
.c_str());
2621 fprintf( brickLearnDocFile
,"<td><b>Required Skill Name</b></td>\n");
2622 fprintf( brickLearnDocFile
,"<td><b><a href=\"%s_required_skill_value.html\">Required Skill Value</a></b></td>\n",DocFileNameRoot
.c_str());
2623 fprintf( brickLearnDocFile
,"<td><b>Learn Skill Name</b></td>\n");
2624 fprintf( brickLearnDocFile
,"<td><b>*Learn Skill Value*</b></td>\n");
2625 fprintf( brickLearnDocFile
,"<td><b>Found In Phrases</b></td>\n");
2626 fprintf( brickLearnDocFile
,"</tr>\n");
2630 multimap
<uint
,string
> learnSkillValueToCode
;
2631 for( itBInf
=BrickInfo
.begin(); itBInf
!=BrickInfo
.end(); ++itBInf
)
2633 string brk
= (*itBInf
).first
;
2635 if(!validateBrick(brk
)) continue;
2637 // learn skill value
2638 string skillTmp
= brickToLearnSkill
[brk
];
2640 if( skillTmp
.find(";") != -1 )
2642 sint idx
= skillTmp
.find_first_of(" ");
2643 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2647 sint idx
= skillTmp
.find_first_of(" ");
2648 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2650 uint level
= atoi(levelStr
.c_str());
2652 learnSkillValueToCode
.insert( make_pair(level
,brk
) );
2655 multimap
<uint
,string
>::iterator itLTC
;
2656 for( itLTC
=learnSkillValueToCode
.begin(); itLTC
!=learnSkillValueToCode
.end(); ++itLTC
)
2658 itBInf
=BrickInfo
.find((*itLTC
).second
);
2660 string brk
= (*itBInf
).first
;
2662 if(!validateBrick(brk
)) continue;
2664 string skillTmp
= (*itBInf
).second
.LearnSkills
;
2665 string skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2666 CVectorSString dicoResult
;
2667 Dico
.lookup( skill
, dicoResult
, true );
2668 if(dicoResult
.empty()) continue;
2671 string color
= brickToColor
[brk
];
2674 string code
= strlwr(brk
.c_str());
2675 fprintf( brickLearnDocFile
, "<tr><td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),code
.c_str());
2678 string name
= (*itBInf
).second
.Text
;
2679 fprintf( brickLearnDocFile
, "<td>%s</td>\n",name
.c_str());
2682 string family
= brickToFamily
[brk
];
2683 fprintf( brickLearnDocFile
, "<td><FONT COLOR=\"%s\">%s</FONT></td>\n",color
.c_str(),family
.c_str());
2685 // required skill name
2686 fprintf( brickLearnDocFile
, "<td>%s</td>\n",dicoResult
[0].c_str());
2688 // required skill value
2690 if( skillTmp
.find(";") != -1 )
2692 sint idx
= skillTmp
.find_first_of(" ");
2693 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2697 sint idx
= skillTmp
.find_first_of(" ");
2698 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2700 fprintf( brickLearnDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2703 skillTmp
= brickToLearnSkill
[brk
];
2704 skill
= skillTmp
.substr(0,skillTmp
.find_first_of(" "));
2705 fprintf( brickLearnDocFile
, "<td>%s</td>\n",skill
.c_str());
2707 // learn skill value
2708 if( skillTmp
.find(";") != -1 )
2710 sint idx
= skillTmp
.find_first_of(" ");
2711 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.find_first_of(";")-idx
-1);
2715 sint idx
= skillTmp
.find_first_of(" ");
2716 levelStr
= skillTmp
.substr(idx
+1,skillTmp
.size()-idx
);
2718 fprintf( brickLearnDocFile
, "<td>%s</td>\n",levelStr
.c_str());
2722 fprintf( brickLearnDocFile
, "<td>");
2723 map
<string
,map
<string
,string
> >::iterator itPhrases
= brickToPhrases
.find(brk
);
2724 if( itPhrases
!= brickToPhrases
.end() )
2726 map
<string
,string
>::iterator itPh
;
2728 for( itPh
=(*itPhrases
).second
.begin(),i
=0; itPh
!=(*itPhrases
).second
.end() && i
<2; ++itPh
,++i
)
2730 if( MultipleDocFiles
)
2731 fprintf( brickLearnDocFile
,"<A HREF=\"%s_%c.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
[7],(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2733 fprintf( brickLearnDocFile
,"<A HREF=\"%s.html#%s\">%s</A>,  ",DocFileName
.c_str(),(*itPh
).first
.c_str(),(*itPh
).first
.c_str());
2737 char type
= family
[0];
2738 fprintf( brickLearnDocFile
,"[<A HREF=\"%s_%c.html#%s\">...</A>]",DocFileNameRoot
.c_str(),type
,brk
.c_str());
2742 fprintf( brickLearnDocFile
, "</td></tr>\n");
2744 fprintf( brickLearnDocFile
, "</tbody><table></P>\n" );
2745 fprintf( brickLearnDocFile
, "</body></html>\n" );
2746 fclose( brickLearnDocFile
);