// Ryzom - MMORPG Framework // 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 . #include "moulinette.h" #include "utils.h" #include "nel/misc/algo.h" #include "nel/misc/common.h" TRMItem currentDocItem; CRMData SortableData; // Preloaded Files CSString FamilyTypContent; CSString GroupTypContent; CSString WKContent; // Assign a new raw mat to a creature void AssignerMP( const CSString& creatureName, const CSString& materialName ) { // we check if a creature is degenerated or not if ( ( creatureName.c_str()[3] != 'c' ) && ( creatureName.c_str()[3] != 'd' ) && ( creatureName.c_str()[3] != 'f' ) && ( creatureName.c_str()[3] != 'j' ) && ( creatureName.c_str()[3] != 'l' ) && ( creatureName.c_str()[3] != 'p' ) ) { } else { // lecture du fichier d'assignement CSString fileName = toString( "%s//_%s_mp.creature", RAW_MATERIAL_ASSIGN.c_str(), creatureName.c_str() ); CSString data; // create file if not exists if(!CFile::fileExists(fileName)) { CSString str; str = "\r\n"; str+= "
\r\n"; str+= " \r\n"; str+= " \r\n"; str+= " \r\n"; str+= " \r\n"; str+= " \r\n"; str+= " \r\n"; str+= " \r\n"; str+= " \r\n"; str+= "\r\n"; str.writeToFile( fileName ); } // lecture data.readFromFile( fileName ); if ( !data.contains( materialName.c_str() ) ) { // look for first number of unused raw mat CSString str = data; int nb= 0; while ( str.contains( "Name=\"MP" ) ) { str = str.splitFrom( "Name=\"MP" ); nb = str.firstWord().atoi(); } // insert new raw mat str = " \r\n \r\n \r\n \r\n \r\n", materialName.c_str() ); data = data.replace( " \r\n
\r\n", str.c_str() ); data.writeToFile( fileName ); } } } // save stats for each craft part void LoadCraftParts() { CSString data, ligne, info; data.readFromFile( ITEM_MP_PARAM_DFN ); int index; printf( "-- LOADING CRAFT PARTS --\n" ); do { data = data.splitFrom( "Name=\"" ); int index; index = data.c_str()[0] - 'A'; craftParts[index].Desc = data.splitTo( "\"" ); } while ( data.c_str()[0] != 'Z' ); if ( ! CFile::fileExists( "rm_item_parts.csv" ) ) { nlError( "rm_item_parts.csv not found\n"); exit( 1 ); } data.readFromFile( "rm_item_parts.csv" ); while ( !data.empty() ) { ligne = data.splitTo( "\n", true ); // look for line concerning our craft part info = ligne.splitTo( ";", true ); if ( !info.empty() ) { index = info.c_str()[0] - 'A'; for ( int i=0; i<6; i++ ) ligne.splitTo( ";", true ); // browse each characteristics for ( int i=0; i files; // on parcours les fichiers dans le repertoire CPath::getPathContent ( inputSheetPath, true, false, true, files ); for (uint32 i=0; i::const_iterator it; if ( ! CFile::fileExists( "creature_models.csv" ) ) { nlError( "creature_models.csv not found\n"); exit( 1 ); } data.readFromFile( "creature_models.csv" ); while ( !data.empty() ) { ligneN = data.splitTo( "\n", true ); ligneM = data.splitTo( "\n", true ); // check if line is valid if ( !ligneN.splitTo( ";", true ).empty() ) { ligneM.splitTo( ";", true ); // move until data ligneN.splitTo( ";", true ); ligneM.splitTo( ";", true ); ligneN.splitTo( ";", true ); ligneM.splitTo( ";", true ); while ( !ligneN.empty() ) { ListeCreatureMP listeCreatureMP; if ( ligneN.contains( ";" ) ) { code = ligneN.splitTo( ";", true ); nom = ligneM.splitTo( ";", true ); } else { code = ligneN.firstWord(); nom = ligneM.firstWord(); ligneN.clear(); } // save items to generate for each new creature name found for ( char eco='a'; eco<='z'; eco++ ) { for ( int level=0; level<10; level++ ) { for ( int creatureLevel=1; creatureLevel<=8; creatureLevel++ ) { CSString fileName = toString( "c%s%c%c%d", code.toLower().c_str(), eco, 'a' + level, creatureLevel ); // look for corresponding creature it = creatureFiles.find( fileName ); if ( it != creatureFiles.end() ) { // if yes, this item should be generated CreatureMPItem* creatureMP = new CreatureMPItem; creatureMP->creatureLevel = creatureLevel; creatureMP->eco = eco; creatureMP->itemLevel = level; creatureMP->codeCreature = code; creatureMP->creatureFileName = fileName; listeCreatureMP.push_back( creatureMP ); } } } } itemsAGenerer[ nom ] = listeCreatureMP; } } } } // Return quality maximum foran item level int GetMaxQuality( int level ) { if ( level == 0 ) return 50; return ( level * 50 ); } // Return energy maximum for an item level int GetStatEnergy( int level ) { if ( level == 0 ) return 20; return ( 20 + ( level-1 ) * 15 ); } // Return item class name depending on its characteristics void GetItemClass( int level, bool mission, bool creature, CSString& outClassName ) { static CSString missionClasses[] = { "Plain", "Average", "Prime", "Select", "Superb", "Magnificient" }; static CSString nonMissionClasses[] = { "", "Basic", "Fine", "Choice", "Excellent", "Supreme" }; if ( mission ) outClassName = missionClasses[ level ]; else if ( creature ) outClassName = nonMissionClasses[ level+1 ]; else outClassName = nonMissionClasses[ level ]; } // Retourne la couleur de l'item void GetItemColor( int color, char eco, int level, CSString& outStr ) { CSString commonColors [4] = { "Beige", "Green", "Turquoise", "Violet" }; CSString rareColors [2] = { "Red", "Blue" }; CSString primeRootColors [2] = { "White", "Black" }; if ( eco == 'p' ) outStr = primeRootColors[ color % 2 ]; else if ( ( eco != 'c' ) && ( level >= 2 ) ) outStr = rareColors[ color % 2 ]; else if ( ( eco == 'c' ) && ( level >= 3 ) ) outStr = rareColors[ color % 2 ]; else outStr = commonColors[ color % 4 ]; } bool endsWith( const CSString& s, const CSString& substring ) { return (s.right( (uint)substring.size() ) == substring); } // Generate item names void GenerateItemNames( const CSString& nomMP, char eco, int level, bool mission, bool creature, CSString& outStr ) { CSString itemClass, prefix, singularWithNoPrefix; CSString ia = "a"; GetItemClass( level, mission, creature, itemClass ); currentDocItem.push( DtStatQuality, itemClass ); if ( !mission ) { if ( ( creature && ( level == 3 ) ) || ( !creature && ( level == 4 ) ) ) ia = "an"; } singularWithNoPrefix = itemClass + " "; // selection de l'eco-systeme switch ( eco ) { case 'c' : break; case 'd' : singularWithNoPrefix += "Desert "; break; case 'f' : singularWithNoPrefix += "Forest "; break; case 'j' : singularWithNoPrefix += "Jungle "; break; case 'l' : singularWithNoPrefix += "Lake "; break; case 'p' : singularWithNoPrefix += "Prime Root "; break; } singularWithNoPrefix += nomMP; // Contenant if ( endsWith( nomMP, "Wood" ) ) prefix = "Bundle"; else if ( endsWith( nomMP, "Bark" ) || endsWith( nomMP, "Moss" ) || endsWith( nomMP, "Sawdust" ) || endsWith( nomMP, "Straw" ) || endsWith( nomMP, "Dust" ) || endsWith( nomMP, "Soil" ) || endsWith( nomMP, "Cereal" ) ) prefix = "Handful"; else if ( endsWith( nomMP, "Resin" ) || endsWith( nomMP, "Wax" ) ) prefix = "Portion"; else if ( endsWith( nomMP, "Whiskers" ) || endsWith( nomMP, "Hairs" ) ) prefix = "Tuft"; else if ( endsWith( nomMP, "Silk" ) ) prefix = "Ball"; else if ( endsWith( nomMP, "Sap" ) || endsWith( nomMP, "Residue" ) || endsWith( nomMP, "Honey" ) || endsWith( nomMP, "Blood" ) ) prefix = "Phial"; else if ( endsWith( nomMP, "Fruit" ) ) prefix = "Piece"; else if ( endsWith( nomMP, "Flesh" ) ) prefix = "Morsel"; else if ( endsWith( nomMP, "Saliva" ) ) prefix = "Sample"; else if ( endsWith( nomMP, "Pollen" ) || endsWith( nomMP, "Fiber" ) || endsWith( nomMP, "Amber" ) || endsWith( nomMP, "Leather" ) || endsWith( nomMP, "Oil" ) ) ia = "some"; else if ( endsWith( nomMP, "Pelvis" ) || endsWith( nomMP, "Eye" ) || endsWith( nomMP, "Spine" ) || endsWith( nomMP, "Hoof" ) || endsWith( nomMP, "Mandible" ) || endsWith( nomMP, "Claw") || endsWith( nomMP, "Tail" ) || endsWith( nomMP, "Trunk" ) || endsWith( nomMP, "Shell" ) || endsWith( nomMP, "Sting" ) || endsWith( nomMP, "Skin" ) || endsWith( nomMP, "Beak" ) || endsWith( nomMP, "Wing" ) || endsWith( nomMP, "Horn" ) || endsWith( nomMP, "Rostrum" ) || endsWith( nomMP, "Skull" ) || endsWith( nomMP, "Pistil" ) ) prefix = "Fragment"; // number-limited creature objects if ( ! prefix.empty() ) { outStr = prefix + " of " + singularWithNoPrefix; ia = "a"; } else outStr = singularWithNoPrefix; CSString singular = outStr; currentDocItem.push( DtTitle, outStr ); // A, The outStr += "\t" + ia + "\tthe\t"; // Plural if ( prefix.empty() ) outStr += singular + "s"; else outStr += prefix + "s" + " of " + singularWithNoPrefix; outStr += "\t\tthe"; } // Return number of specified family int GetNumeroMP( const CSString& nomMP ) { CSString result; char buffer[100]; char buffer2[100]; int res; // *** Get the family number, and add it to faimly.typ if not already done // look for raw mat existence in item_mp_family.typ file sprintf( buffer, "%s\" Value=\"", nomMP.c_str() ); result = FamilyTypContent.splitFrom( buffer ); // if yes, return raw mat number if ( !result.empty() ) res = result.splitTo( "\"" ).atoi(); else { // else, generate a new number: // get last raw mat number (the max) result = FamilyTypContent.splitTo( "" ).right(10); result.splitTo( "\"", true ); result = result.splitTo( "\"" ); // increase by 1 to get the unused number res = result.atoi() + 1; // add new raw mat in file item_mp_family.typ sprintf( buffer, " \n", nomMP.c_str(), res ); FamilyTypContent= FamilyTypContent.replace( "", buffer ); FamilyTypContent.writeToFile( ITEM_MP_FAMILY_TYP ); } // *** Add the text in wk.uxt (if not done) // Exist in wk.uxt ??? sprintf( buffer, "mpfam%d\t", res ); sprintf( buffer2, "mpfam%d ", res ); // if not found if ( !WKContent.contains(buffer) && !WKContent.contains(buffer2) ) { // add it at end sprintf( buffer, "mpfam%d\t\t\t[%s]\n\r\nmpgroup0", res, nomMP.c_str() ); WKContent= WKContent.replace( "\r\nmpgroup0", buffer ); WKContent.writeToFile( WK_UXT ); } return res; } // Return number from specified group int GetNumeroGroupe( const CSString& groupe ) { CSString result; char buffer[100]; char buffer2[100]; int res; // *** Get the group number, and add it to group.typ if not already done // look for group existence in item_mp_group.typ file sprintf( buffer, "%s\" Value=\"", groupe.c_str() ); result = GroupTypContent.splitFrom( buffer ); // if yes, return its group number if ( !result.empty() ) res = result.splitTo( "\"" ).atoi(); else { // else, generate a new number : // get the last group number (the max) result = GroupTypContent.splitTo( "" ).right(10); result.splitTo( "\"", true ); result = result.splitTo( "\"" ); // increase by 1 to get the unused number res = result.atoi() + 1; // add new raw mat in file item_mp_group.typ sprintf( buffer, "\n", groupe.c_str(), res ); GroupTypContent= GroupTypContent.replace( "", buffer ); GroupTypContent.writeToFile( ITEM_MP_GROUPE_TYP ); } // *** Add the text in wk.uxt (if not done) // Exist in wk.uxt ??? sprintf( buffer, "mpgroup%d\t", res ); sprintf( buffer2, "mpgroup%d ", res ); // if not found if ( !WKContent.contains(buffer) && !WKContent.contains(buffer2) ) { // add it at end sprintf( buffer, "mpgroup%d\t\t\t[%s]\n\r\nmpSource", res, groupe.c_str() ); WKContent= WKContent.replace( "\r\nmpSource", buffer ); WKContent.writeToFile( WK_UXT ); } return res; } // Generate parent item for a raw mat void CreateParentSItem( int numMP, const CSString& nomMP, const CSString& groupe, bool dropOrSell, const CSString& icon, const CSString& overlay ) { CSString output; CSString outputFileName; // output filename outputFileName = toString( "%s_parent\\_m%04d.sitem", MP_DIRECTORY.c_str(), numMP ); // xml header output = "\n
\n"; // basics output += " \n \n"; output += " \n"; else // the others, yes output += "true\"/>\n"; output += " \n \n"; // raw mat output += " \n"; output += " \n \n \n"; // 3d output += " \n"; if ( !icon.empty() ) { output += " \n"; } if ( !overlay.empty() ) { output += " \n"; } output += " \n \n"; // end of file output += " \n \n \n \n\n"; // final write output.writeToFile( outputFileName ); } // Fill information related to craft with an item void FillCraftData( char craft, int eco, int level, bool creature, int bestStat, int worstStat1, int worstStat2, CSString& outStr ) { CSString data; char buf[10]; int index; static CSString carac[] = { "Durability", "Weight", "SapLoad", "DMG", "Speed", "Range", "DodgeModifier", "ParryModifier", "AdversaryDodgeModifier", "AdversaryParryModifier", "ProtectionFactor", "MaxSlashingProtection", "MaxBluntProtection", "MaxPiercingProtection", "ElementalCastingTimeFactor", "ElementalPowerFactor", "OffensiveAfflictionCastingTimeFactor", "OffensiveAfflictionPowerFactor", "HealCastingTimeFactor", "HealPowerFactor", "DefensiveAfflictionCastingTimeFactor", "DefensiveAfflictionPowerFactor", "AcidProtection", "ColdProtection", "FireProtection", "RotProtection", "ShockWaveProtection", "PoisonProtection", "ElectricityProtection", "DesertResistance", "ForestResistance", "LacustreResistance", "JungleResistance", "PrimaryRootResistance", }; nlctassert((sizeof(carac)/sizeof(carac[0]))==NumMPStats); static int mediumStatsByStatQuality[] = { 20, 35, 50, 65, 80 }; int stat, remaining, nbToRaise, ajout; int stats[NumMPStats]; index = craft - 'A'; outStr = " \n"; nbToRaise = 0; remaining = 0; ajout = 0; currentDocItem.push( DtCraftSlotName, craftParts[index].Desc.splitFrom( "(" ).splitTo( ")" ) ); // save stats for each characteristic for ( int i=0; i 100 ) { // if a stat exceeds 100, other are increased remaining = stat - 100; stat = 100; } } else if ( ( i == worstStat1 ) || ( i == worstStat2 ) ) { stat -= 20; // minimum durability if ( ( i == 0 ) && ( stat < 1 ) ) stat = 1; } else nbToRaise++; stats[i] = stat; } else stats[i] = -1; } if ( nbToRaise != 0 ) ajout = remaining/nbToRaise; // add information for each characteristic for ( int i=0; i\n"; } } // CraftCivSpec depending on ecosystem outStr += " \n \n"; } // Create item sheets void CreateSheet( int numMP, const CSString& nomMP, const CSString& code, char eco, int level, const MPCraftStats& craftStats, bool specialItem = false, int variation = 1 ) { CSString output, directory, itemName, craftInfo, color; CSString outputFileName, ecoStr; char chaineNum[5]; bool creature = ( code != "dxa" ) && ( code != "cxx" ) && ( code != "ixx" ); // Creation du nom de fichier sprintf( chaineNum, "%04d", numMP ); switch ( eco ) { case 'd' : directory = "desert"; ecoStr = "Desert"; break; case 'f' : directory = "forest"; ecoStr = "Forest"; break; case 'j' : directory = "jungle"; ecoStr = "Jungle"; break; case 'l' : directory = "lacustre"; ecoStr = "Lacustre"; break; case 'p' : directory = "prime_roots"; ecoStr = "PrimeRoots"; break; default : directory = "common"; ecoStr = "Common"; eco = 'c'; break; } if ( ( eco == 'c' ) && creature && ( craftStats.Craft.empty() ) ) return; outputFileName = toString( "m%04d%s%c%c%02d.sitem", numMP, code.c_str(), eco, 'a' + level, variation ); if ( craftStats.Craft.empty() ) { CSString levelZone = toString( "%c", 'a' + level ); currentDocItem.push( DtLevelZone, levelZone.toUpper() ); } else currentDocItem.push( DtLevelZone, "-" ); // fill sheets information output = "\n
\n"; output += " \n \n"; // if a creature code, add it its parent if ( creature ) { output += " \n"; creature = true; } output += " \n"; output += " \n"; output += " \n"; if(craftStats.UsedAsCraftRequirement) output += " \n"; } else { // get the color GetItemColor( craftStats.color, eco, level, color ); output += color; output += "\"/>\n"; currentDocItem.push( DtColor, color ); // add craft data output += " \n"; for ( uint i=0; i\n \n \n \n \n \n \n \n\n"; output.writeToFile( toString( "%s%s\\%s", MP_DIRECTORY.c_str(), directory.c_str(), outputFileName.c_str() ) ); // Generate names if ( !specialItem ) { outputFileName = toString( "m%04d%s%c%c%02d", numMP, code.c_str(), eco, 'a' + level, variation ); output = outputFileName; GenerateItemNames( nomMP, eco, level, ( craftStats.Craft.empty() ), creature, itemName ); output += "\t" + itemName; itemNames.insert( output ); } currentDocItem.push( DtEcosystem, ecoStr ); currentDocItem.push( DtName, outputFileName ); SortableData.updateItemAppend( currentDocItem, DtName ); currentDocItem.reset( DtName ); currentDocItem.reset( DtEcosystem ); currentDocItem.reset( DtMaxLevel ); currentDocItem.reset( DtAverageEnergy ); currentDocItem.reset( DtTitle ); currentDocItem.reset( DtLevelZone ); currentDocItem.reset( DtStatQuality ); currentDocItem.reset( DtCraftSlotName ); currentDocItem.reset( DtCraftCivSpec ); currentDocItem.reset( DtColor ); } // Generate deposits items for harvested raw mats void GenerateDepositItems( int numMP, const CSString& nomMP, const MPCraftStats& craftStats, const CSString& loc ) { CSString code; if ( loc.left(1) == "I" ) code = "ixx"; else if ( loc.left(1) == "D" ) code = "dxa"; else code = "cxx"; // pas de craft = items de mission if ( craftStats.Craft.empty() ) { if ( loc != "G" ) CreateSheet( numMP, nomMP, code, 'c', 0, craftStats ); for ( int i=1; i<6; i++ ) { CreateSheet( numMP, nomMP, code, 'c', i, craftStats ); } } else { // 2 items in common CreateSheet( numMP, nomMP, code, 'c', 1, craftStats ); CreateSheet( numMP, nomMP, code, 'c', 2, craftStats ); // 3 items per zone for ( int i=0; i<3; i++ ) { CreateSheet( numMP, nomMP, code, 'd', 3+i, craftStats ); CreateSheet( numMP, nomMP, code, 'f', 3+i, craftStats ); CreateSheet( numMP, nomMP, code, 'j', 3+i, craftStats ); CreateSheet( numMP, nomMP, code, 'l', 3+i, craftStats ); CreateSheet( numMP, nomMP, code, 'p', 3+i, craftStats ); } } } // Generate creatures items for a looted raw mat void GenerateCreatureItems( int numMP, CSString& nomMP, const MPCraftStats& craftStats ) { map::const_iterator itLCMP; int quality; static int statQuality[] = { 0, 1, 0, 1, 3, 6, 4, 2 }; // Get items levels to generate for the creature itLCMP = itemsAGenerer.find( nomMP.firstWord() ); if ( itLCMP != itemsAGenerer.end() ) { ListeCreatureMP::const_iterator itMP = (*itLCMP).second.begin(); // for each level of an item to generate while ( itMP != (*itLCMP).second.end() ) { // save its stats char eco = (*itMP)->eco; int creatureLevel = (*itMP)->creatureLevel; int itemLevel = (*itMP)->itemLevel; CSString creatureFileName = "c"; creatureFileName += (*itMP)->codeCreature.toLower(); if ( !craftStats.Craft.empty() ) { quality = statQuality[creatureLevel-1]; if ( quality != 6 ) { if ( quality < 2 ) { CreateSheet( numMP, nomMP, creatureFileName, 'c', quality, craftStats ); AssignerMP( (*itMP)->creatureFileName, toString( "m%04d%s%c%c01.sitem", numMP, creatureFileName.c_str(), 'c', 'a' + quality ) ); } else { CreateSheet( numMP, nomMP, creatureFileName, eco, quality, craftStats ); AssignerMP( (*itMP)->creatureFileName, toString( "m%04d%s%c%c01.sitem", numMP, creatureFileName.c_str(), eco, 'a' + quality ) ); } currentDocItem.push( DtCreature, (*itMP)->creatureFileName ); } } else { // pas de MP de mission pour les boss if ( creatureLevel < 5 ) { CreateSheet( numMP, nomMP, creatureFileName, eco, itemLevel, craftStats ); AssignerMP( (*itMP)->creatureFileName, toString( "m%04d%s%c%c01.sitem", numMP, creatureFileName.c_str(), eco, 'a' + itemLevel ) ); currentDocItem.push( DtCreature, (*itMP)->creatureFileName ); } } itMP++; } } } // Generate special item void GenerateSpecialItem( int numMP, const CSString& nomMP, const MPCraftStats& craftStats, const CSString& loc,CSString& itemData, int variation ) { CSString info, code, name; info = itemData.splitTo( "/", true ).toLower(); if ( loc.left(1) == "I" ) code = "ixx"; else if ( loc.left(1) == "D" ) code = "dxa"; else code = "cxx"; CreateSheet( numMP, nomMP, code, info.c_str()[0], info.c_str()[1]-'a', craftStats, true, variation ); name = toString( "m%04d%s%s%02d\t", numMP, code.c_str(), info.c_str(), variation ); name += itemData.splitTo( "/", true ); // singular name += "\t"; name += itemData.splitTo( "/", true ); // undefined article name += "\t"; name += itemData.splitTo( "/", true ); // defined article name += "\t"; name += itemData.splitTo( "/", true ); // plural name += "\t\t"; name += itemData.splitTo( "/", true ); // plural article itemNames.insert( name ); } // Special Attrib parsing. craftStats must be good for extraInfo init void parseSpecialAttributes(const CSString &specialAttributes, MPCraftStats &craftStats, CExtraInfo &extraInfo) { // evaluate DropOrSell according to CraftStats: can DropOrSell if it is a MP Craft extraInfo.DropOrSell= !craftStats.Craft.empty(); // parse attributes vector strArray; splitString(specialAttributes, "-", strArray); for(uint i=0;i=(sint)MPFamilies.size()) MPFamilies.resize(numMP+1); MPFamilies[numMP].Name= nomMP; MPFamilies[numMP].Icon= icon; // raw mats found in deposits or goo if ( loc.left(1) != "C" ) { if ( !specialOnly ) { // Generate items GenerateDepositItems( numMP, nomMP, craftStats, loc ); } // on enregistre les items se trouvant dans les deposits if ( loc.left(1) == "D" ) { CSString output; output.writeToFile( toString( "%s%s_%d.mp", DEPOSIT_MPS.c_str(), nomMP.toLower().replace( " ", "_" ).c_str(), numMP ) ); } overlay = nomMP.firstWord().toUpper().left(6); } // looted raw mats else { GenerateCreatureItems( numMP, nomMP, craftStats ); } // special items CSString codeSpecial, nouveauCode; int variation = 1; CSortedStringSet::const_iterator it = specialNames.begin(); while ( it != specialNames.end() ) { CSString name = (*it); nouveauCode = name.left(2).toLower(); if ( nouveauCode == codeSpecial ) variation++; else variation = 1; GenerateSpecialItem( numMP, nomMP, craftStats, loc, name, variation ); codeSpecial = nouveauCode; it++; } // Create parent sheet for raw mat CreateParentSItem( numMP, nomMP, groupe, extraInfo.DropOrSell, icon, overlay ); currentDocItem.reset( DtRMFamily ); currentDocItem.reset( DtGroup ); currentDocItem.reset( DtProp ); currentDocItem.reset( DtCreature ); } // Generate Primitive Necklace (special object) void CreatePrimitiveNecklace() { CSString output; output = "\n"; output += "
\n"; output += " \n"; output += " \n"; output += " \n \n"; output += " \n"; output += " \n"; output += " \n"; output += " \n \n \n \n"; output += " \n \n\n"; output.writeToFile( toString( "%scommon\\m0696ixxcc01.sitem", MP_DIRECTORY.c_str() ) ); itemNames.insert( "m0696ixxcc01 Primitive Necklace a the Primitive Necklaces the" ); } // Save names void ItemNamesSave() { printf( "-- SAVING ITEM NAMES --\n"); CSString data, output; FILE *file = nlfopen( ITEM_WORDS_WK, "rb" ); char c; if (fread(&c, 1, 1, file) != 1) { nlwarning("Unable to read 1 byte from %s", ITEM_WORDS_WK.c_str()); return; } while ( !feof( file ) ) { data += toString( "%c", c ); if (fread(&c, 1, 1, file) != 1) { nlwarning("Unable to read 1 byte from %s", ITEM_WORDS_WK.c_str()); return; } } fclose( file ); data.splitTo( "i", true ); output = "i"; output += data.splitTo( "prospector", true ); CSortedStringSet::const_iterator it = itemNames.begin(); while ( it != itemNames.end() ) { if ( !output.contains( (*it).left(5).c_str() ) ) { output += (*it); output += "\r\n"; } it++; } output += "p"; output += data; output.writeToFile( ITEM_WORDS_WK.c_str() ); } // Load Customized Properties defined in raw_material_generation.cfg void LoadCustomizedProperties() { CSString data, name, prop, val; printf( "-- REGISTERING CUSTOMIZED PROPERTIES --\n" ); data.readFromFile( "raw_material_generation.cfg" ); data = data.splitFrom( "{\r\n\t" ); CPath::addSearchPath( MP_DIRECTORY, true, false ); while ( data.contains( "};" ) ) { name = data.splitTo( ",", true ).replace( "\"", "" ); prop = data.splitTo( ",", true ).replace( "\"", "" ).replace( " ", "" ); val = data.splitTo( ",", true ).replace( "\"", "" ).replace( " ", "" ); if ( val.contains( "\r\n" ) ) val = val.splitTo( "\r\n", true ); TRMItem item; item.push( DtName, name ); item.push( DtCustomizedProperties, prop ); SortableData.updateItemAppend( item, DtName ); data.splitTo( "\t", true ); CSString fileName, str, output; fileName = CPath::lookup( name, false, false, true ); // check if file exists if ( !fileName.empty() ) { CSString zone = prop.splitTo( ".", true ); str.readFromFile( fileName ); if ( !str.contains( zone.c_str() ) ) { output = "\n \n \n ", prop.c_str(), val.c_str() ); // check if property is not already inserted if ( !str.contains( output.c_str() ) ) { str = str.replace( "", output.c_str() ); str.writeToFile( fileName ); } } else { output = toString( " \n", zone.c_str() ); output += toString( " \n", prop.c_str(), val.c_str() ); // check if property is not already inserted if ( !str.contains( toString( "%s\" Value=\"%s\"/>\n", prop.c_str(), val.c_str() ).c_str() ) ) { str = str.replace( toString( " \n", zone.c_str() ).c_str(), output.c_str() ); str.writeToFile( fileName ); } } } } } // Generate _ic_families.forage_source() void SaveFamiliesForageSource() { CSString output; printf( "-- GROUP ICONS FOR _ic_groups.forage_source --\n"); output = "\n"; output+= "
\n"; output+= " \n"; output+= " \n"; for ( uint i=0; i!=MPFamilies.size(); ++i ) { output+= toString(" \n", MPFamilies[i].Icon.c_str()); } output+= " \n"; output+= " \n"; output+= " \n"; output+= " \n"; output+= " \n"; output+= " \n"; output+= " \n"; output+= "\n"; output.writeToFile( IC_FAMILIES_FORAGE_SOURCE.c_str() ); } // Generate documentation void GenerateDoc() { CProducedDocHtml MainDoc; CFile::createDirectory("doc"); MainDoc.open( "doc\\rm.html", "Raw materials by generation order", true ); MainDoc.write( "\n" ); MainDoc.write( "" ); for ( uint32 c=0; c!=DtNbCols; ++c ) { MainDoc.write( "" ); } MainDoc.write( "" ); for ( CRMData::CItems::const_iterator isd=SortableData.items().begin(); isd!=SortableData.items().end(); ++isd ) { MainDoc.write( (*isd).toHTMLRow() ); } MainDoc.write( "
" + string(DataColStr[c]) + "
\n" ); // Produce alt docs CProducedDocHtml AltDocs[DtNbCols]; for ( uint32 c=0; c!=DtNbCols; ++c ) { AltDocs[c].open( "doc\\rm_" + string(DataColStr[c]) + ".html", "Raw materials by " + string(DataColStr[c]), true ); AltDocs[c].write( "
\n" ); AltDocs[c].write( "" ); for ( uint32 cc=0; cc!=DtNbCols; ++cc ) if ( cc == c ) AltDocs[c].write( "" ); else AltDocs[c].write( "" ); AltDocs[c].write( "" ); string previousKey = "[NO PREVIOUS]"; // not a blank string, because it may be a valid value string previousName; for ( CRMData::CLookup::const_iterator isd=SortableData.lookup( c ).begin(); isd!=SortableData.lookup( c ).end(); ++isd ) { const TRMItem& item = SortableData.getRow( (*isd).second ); AltDocs[c].write( item.toHTMLRow( c, (*isd).first, previousKey, DtName, previousName ) ); previousKey = (*isd).first; previousName = item.Fields[DtName][0]; } AltDocs[c].write( "
" + string(DataColStr[cc]) + "" + string(DataColStr[cc]) + "
\n" ); AltDocs[c].save(); } } // Initialize directories from raw_material_generation.cfg void SetupDirectories() { CSString data; if ( ! CFile::fileExists( "raw_material_generation.cfg" ) ) { nlError( "raw_material_generation.cfg not found\n"); exit( 1 ); } data.readFromFile( "raw_material_generation.cfg" ); // beurk :s Use CConfigFile instead LEVEL_DESIGN_PATH = data.splitFrom( "LevelDesignPath = \"").splitTo( "\"" ); TRANSLATION_PATH = data.splitFrom( "TranslationPath = \"" ).splitTo( "\"" ); printf( "Level Design Path : %s\nTranslation Path : %s\n\n", LEVEL_DESIGN_PATH.c_str(), TRANSLATION_PATH.c_str() ); ITEM_MP_FAMILY_TYP = LEVEL_DESIGN_PATH + "leveldesign\\DFN\\game_elem\\_item\\item_mp_family.typ"; ITEM_MP_GROUPE_TYP = LEVEL_DESIGN_PATH + "leveldesign\\DFN\\game_elem\\_item\\item_mp_group.typ"; ITEM_MP_PARAM_DFN = LEVEL_DESIGN_PATH + "leveldesign\\DFN\\game_elem\\_item\\_item_mp_param.dfn"; MP_DIRECTORY = LEVEL_DESIGN_PATH + "leveldesign\\game_element\\sitem\\raw_material\\"; DEPOSIT_MPS = LEVEL_DESIGN_PATH + "leveldesign\\game_element\\deposit_system\\mps\\"; RAW_MATERIAL_ASSIGN = LEVEL_DESIGN_PATH + "leveldesign\\Game_elem\\Creature\\raw_material_assignment\\"; IC_FAMILIES_FORAGE_SOURCE = LEVEL_DESIGN_PATH + "leveldesign\\game_element\\forage_source\\_ic_families.forage_source"; WK_UXT = TRANSLATION_PATH + "work\\wk.uxt"; ITEM_WORDS_WK = TRANSLATION_PATH + "work\\item_words_wk.txt"; } // Browse all raw mats families to do all related processes void LoadFamillesMP() { printf( "-- LOADING RAW MATERIAL FAMILIES --\n" ); // Preload wk.uxt, item_mp_family.typ, and item_mp_group.typ (avoid to reload them each time) FamilyTypContent.readFromFile( ITEM_MP_FAMILY_TYP ); GroupTypContent.readFromFile( ITEM_MP_GROUPE_TYP ); WKContent.readFromFile( WK_UXT ); // avoid huge resize of vector MPFamilies.reserve(1000); CSString fileData, ligne; if ( ! CFile::fileExists( "rm_fam_prop.csv" ) ) { nlError( "rm_fam_prop.csv not found\n"); exit( 1 ); } fileData.readFromFile( "rm_fam_prop.csv" ); ligne = fileData.splitTo( "\n", true ); while ( !ligne.empty() ) { NewMP( ligne ); ligne = fileData.splitTo( "\n", true ); } // we manually add Primitive Necklace because it's not specified in raw mats list CreatePrimitiveNecklace(); } // Programme principal int main( int argc, char* argv[] ) { new CApplicationContext; SortableData.init( true ); SetupDirectories(); LoadCraftParts(); LoadCreatureFiles(); InitCreatureMP(); LoadFamillesMP(); ItemNamesSave(); LoadCustomizedProperties(); SaveFamiliesForageSource(); printf( "-- GENERATING DOCUMENTATION --\n" ); try { GenerateDoc(); } catch(const Exception &e) { nlwarning(e.what()); nlwarning("HTML Doc generation failed\n"); } printf( "-- DONE --\n" ); return 0; }