inline void cGrannyLoader::InsertAnimset(TiXmlElement *set_node) { if (!set_node) return; XML::Node value; cAnimSet * animset = new cAnimSet; value = set_node->FirstChildElement("ID"); animset->id = value.asInteger(); if (value = set_node->FirstChildElement("DEFAULTANIM")) { animset->defaultanim = mulpath + to_lower(value.asString()); // animtype 을 anim_typeid 로 변경 int anim_typeid = TypeData::GetAnimType("default.animation"); if (anim_typeid != -1) animset->anim_names.insert(make_pair(anim_typeid, animset->defaultanim)); } TiXmlElement *anim_node = set_node->FirstChildElement("ANIMATION"); while (anim_node) { std::string animtype = "", filename = ""; if (value = anim_node->FirstChildElement("TYPE")) animtype = value.asString(); if ((value = anim_node->FirstChildElement("FILE"))) filename = mulpath + to_lower(value.asString()); // animtype 을 anim_typeid 로 변경 int anim_typeid = TypeData::GetAnimType(animtype); if (anim_typeid != -1) animset->anim_names.insert(make_pair(anim_typeid, filename)); anim_node = anim_node->NextSiblingElement("ANIMATION"); } m_animsets.insert(make_pair(animset->id, animset)); }
bool cGrannyLoader::Load(std::string filename, std::string mulpath) { tick = 0; XML::Parser parser; XML::Node *granny=NULL, *document=NULL; try { parser.loadData(filename); document = parser.parseDocument(); granny = document->findNode( "GRANNY" ); if( !granny ) throw "Couldn't find granny node."; } catch( ... ) { pDebug.Log ("Couldn't load Granny Definitions"); return false; } XML::Node value; TiXmlNode *tgranny = granny->getTinyNode(); bool ext = false; std::string texpath, smdpath; if (value = tgranny->FirstChildElement("TEXTUREPATH")) texpath = value.asString(); if (value = tgranny->FirstChildElement("SMDPATH")) smdpath = value.asString(); if (smdpath==".") { CString strPath = CFileString::GetModuleDir()+"/"; strPath.Replace('\\','/'); mulpath = strPath; } else if (!smdpath.empty()) { mulpath = smdpath; } this->mulpath = mulpath; if (texpath.find(":/") != std::string::npos || texpath.find(":\\") != std::string::npos) tex_basepath = texpath; else tex_basepath = mulpath + texpath; assert(!pGrannyTextureLoader); pGrannyTextureLoader = new cGrannyTextureLoader(tex_basepath); TiXmlHandle hgranny(granny->getTinyNode()); #if 0 TiXmlElement *set_node = hgranny.FirstChild("ANIMSET_LIST").FirstChild("ANIMSET").Element(); while (set_node) { InsertAnimset(set_node); set_node = set_node->NextSiblingElement(set_node->Value()); } TiXmlElement *char_node = hgranny.FirstChild("CHARACTER_AOS_LIST").FirstChild("CHARACTER_AOS").Element(); while (char_node) { InsertCharacterAOS(char_node); char_node = char_node->NextSiblingElement(char_node->Value()); } char_node = hgranny.FirstChild("CHARACTER_LIST").FirstChild("CHARACTER").Element(); while (char_node) { InsertCharacter(char_node); char_node = char_node->NextSiblingElement(char_node->Value()); } #else TiXmlElement *anim_node = tgranny->FirstChildElement("ANIMSET"); while (anim_node) { InsertAnimset(anim_node); anim_node = anim_node->NextSiblingElement("ANIMSET"); } TiXmlElement * char_node = tgranny->FirstChildElement(); while (char_node) { if (char_node->ValueStr()=="CHARACTER") InsertCharacter(char_node); else if (char_node->ValueStr()=="CHARACTER_AOS") InsertCharacterAOS(char_node); char_node = char_node->NextSiblingElement(); } #endif delete document; return true; }
inline void cGrannyLoader::InsertCharacterAOS(TiXmlElement *char_node) { if (!char_node) return; XML::Node value; std::string filename, default_anim, desc; int animset = -1; int left_hand_bone = -1; int right_hand_bone = -1; int hand = HAND_NONE; value = char_node->FirstChildElement("ID"); Uint32 id = value.asInteger(); if (value = char_node->FirstChildElement("ANIMSET")) animset = value.asInteger(); if (value = char_node->FirstChildElement ("LEFT_HAND_BONE")) { left_hand_bone = value.asInteger (); hand = HAND_OWNER; } if (value = char_node->FirstChildElement ("RIGHT_HAND_BONE")) { right_hand_bone = value.asInteger (); hand = HAND_OWNER; } if (value = char_node->FirstChildElement("DESCRIPTION")) desc = value.asString(); Uint16 assign = 0; if (value = char_node->FirstChildElement("ASSIGN")) assign = value.asInteger(); id |= assign << 16; map <int, cAnimSet *>::iterator iter; map <int, string>::iterator name_iter; iter = m_animsets.find(animset); if (id && (iter != m_animsets.end())) { assert(iter->second); cGrannyModelAOS * model = new cGrannyModelAOS (tex_basepath, iter->second->defaultanim); model->SetHandBones (left_hand_bone, right_hand_bone); model->SetHand (hand); model->SetAnimset (animset); model->desc = desc; // HARKON : bodypart is freed by loader model->setFreeBodyParts(false); for(int i = 0; AOSBodyInfo[i].id != 0; i++) { const AOSBodyData& Data = AOSBodyInfo[i]; TiXmlElement *submodel = char_node->FirstChildElement(Data.name); if (submodel) { cGrannyModel *m = model->AddModel(Data.id, mulpath + to_lower(submodel->GetText())); UINT id2 = 0xC000 | id << 4 | Data.id; models.insert(make_pair(id2, m)); } } for (name_iter=iter->second->anim_names.begin(); name_iter!=iter->second->anim_names.end();name_iter++) { model->AddAnimation(name_iter->first, name_iter->second); } //models.erase(id); if (models.find(id)!=models.end()) { pDebug.Log("Warning: duplicated model id : %d\n", id); delete models.find(id)->second; models.erase(id); } models.insert(make_pair(id, model)); } else { pDebug.Log ("Warning: Invalid Granny AOS Definition"); } }
inline void cGrannyLoader::InsertCharacter(TiXmlElement *char_node) { if (!char_node) return; XML::Node value; std::string filename = "", default_anim = "", prefix = "", desc; int left_hand_bone = -1; int right_hand_bone = -1; int animset = -1; int hand = HAND_NONE; value = char_node->FirstChildElement("ID"); Uint32 id = (value != NULL) ? value.asInteger() : 0; if (value = char_node->FirstChildElement("FILE")) filename = mulpath + to_lower(value.asString()); if (value = char_node->FirstChildElement("ANIMSET")) animset = value.asInteger(); if (value = char_node->FirstChildElement("PREFIX")) prefix = to_lower(value.asString()); if (value = char_node->FirstChildElement("LEFT_HAND_BONE")) { left_hand_bone = value.asInteger(); hand = HAND_OWNER; } if (value = char_node->FirstChildElement("RIGHT_HAND_BONE")) { right_hand_bone = value.asInteger(); hand = HAND_OWNER; } if (value = char_node->FirstChildElement("HAND")) { if (value.asString () == "left") hand = HAND_LEFT; if (value.asString () == "right") hand = HAND_RIGHT; } if (value = char_node->FirstChildElement("DESCRIPTION")) desc = value.asString(); Uint16 assign = 0; if (value = char_node->FirstChildElement("ASSIGN")) assign = value.asInteger(); id |= assign << 16; // humonoid, monster can hold weapons. if (assign == 0 && (animset <= 1 || animset == 3)) hand = HAND_OWNER; map <int, cAnimSet *>::iterator iter; map <int, string>::iterator name_iter; iter = m_animsets.find(animset); if (id && (iter != m_animsets.end())) { assert(iter->second); cGrannyModel * model = new cGrannyModelTD (filename, tex_basepath, iter->second->defaultanim, prefix); model->SetHandBones(left_hand_bone, right_hand_bone); model->SetHand(hand); model->desc = desc; model->SetAnimset (animset); for (name_iter=iter->second->anim_names.begin(); name_iter!=iter->second->anim_names.end();name_iter++) { model->AddAnimation(name_iter->first, name_iter->second); } //models.erase(id); if (models.find(id)!=models.end()) { pDebug.Log("Warning: duplicated model id : %d", id); delete models.find(id)->second; models.erase(id); } models.insert(make_pair(id, model)); } else { pDebug.Log ("Warning: Invalid Granny Definition"); } }
cGrannyLoader::cGrannyLoader( string filename, string mulpath ) { this->mulpath = mulpath; tick = 0; XML::Parser parser; XML::Node *granny, *document; try { parser.loadData( filename ); document = parser.parseDocument(); granny = document->findNode( "GRANNY" ); if ( !granny ) { throw "Couldn't find granny node."; } } catch (...) { Logger::WriteLine( "Couldn't load Granny Definitions" ); return; } XML::Node *char_node, *set_node, *value; if ( (value = granny->findNode( "TEXTUREPATH" ) ) ) { tex_basepath = mulpath + value->asString(); } assert( !pGrannyTextureLoader ); pGrannyTextureLoader = new cGrannyTextureLoader( tex_basepath ); std::map<int, cAnimSet *> animsets; std::map<int, cAnimSet *>::iterator iter; std::map<int, string>::iterator name_iter; int idx = 0; while ( (set_node = granny->findNode("ANIMSET", idx)) ) { cAnimSet *animset = new cAnimSet(); value = set_node->findNode( "ID" ); animset->id = (value != NULL) ? value->asInteger() : 0; if ( ( value = set_node->findNode( "DEFAULTANIM" )) ) { animset->defaultanim = mulpath + to_lower( value->asString() ); } int idx2 = 0; XML::Node *anim_node; while ( (anim_node = set_node->findNode( "ANIMATION", idx2 )) ) { std::string animtype = "", filename = ""; if ( (value = anim_node->findNode( "TYPE" )) ) { animtype = value->asString(); } if ( (value = anim_node->findNode ("FILE")) ) { filename = mulpath + to_lower( value->asString() ); } int anim_typeid = -1; for ( int i = 0; TypeInfo[i].blockid != -1; i++ ) { const TypeData &Data = TypeInfo[i]; if ( Data.name == animtype ) { anim_typeid = Data.blockid; } } if ( anim_typeid != -1 ) { animset->anim_names.insert( std::make_pair( anim_typeid, filename ) ); } idx2++; } //animsets.erase(animset->id); animsets.insert( std::make_pair( animset->id, animset ) ); idx++; } idx = 0; while ((char_node = granny->findNode ("CHARACTER", idx))) { std::string filename = "", default_anim = "", prefix = ""; int left_hand_bone = -1; int right_hand_bone = -1; int animset = -1; int hand = HAND_NONE; value = char_node->findNode ("ID"); Uint32 id = (value != NULL) ? value->asInteger () : 0; if ((value = char_node->findNode ("FILE"))) filename = mulpath + to_lower (value->asString ()); if ((value = char_node->findNode ("ANIMSET"))) animset = value->asInteger (); if ((value = char_node->findNode ("PREFIX"))) prefix = to_lower (value->asString ()); if ((value = char_node->findNode ("LEFT_HAND_BONE"))) { left_hand_bone = value->asInteger (); hand = HAND_OWNER; } if ((value = char_node->findNode ("RIGHT_HAND_BONE"))) { right_hand_bone = value->asInteger (); hand = HAND_OWNER; } if ((value = char_node->findNode ("HAND"))) { if (value->asString () == "left") hand = HAND_LEFT; if (value->asString () == "right") hand = HAND_RIGHT; } Uint16 assign = 0; if ((value = char_node->findNode ("ASSIGN"))) assign = value->asInteger (); //SiENcE: if female id-1000, to show female clothes // (i dont know why it needs a subtract of 1000!, ids are correct) //if (assign == 401) id=id-1000; //HARKON: recevied clothes id is equals male/female(runuo 1.0). but weapon isn't equals. // examples, ganny_aos.xml male kilt id is 455, female kilt id is 1455. server only sends 455. if (assign == 401 && hand == HAND_NONE) id -= 1000; id |= assign << 16; iter = animsets.find (animset); if (id && (iter != animsets.end ())) { assert (iter->second); cGrannyModel *model = new cGrannyModelTD( filename, tex_basepath, iter->second->defaultanim, prefix ); model->SetHandBones( left_hand_bone, right_hand_bone ); model->SetHand( hand ); model->SetAnimset( animset ); for ( name_iter=iter->second->anim_names.begin(); name_iter != iter->second->anim_names.end(); name_iter++ ) { model->AddAnimation( name_iter->first, name_iter->second ); } //models.erase(id); if ( models.find( id ) != models.end() ) { //Logger::WriteLine("Warning: duplicated model id : %d", id); SAFE_DELETE( models.find( id )->second ); models.erase( id ); } models.insert( make_pair( id, model ) ); } else { Logger::WriteLine ("Warning: Invalid Granny Definition"); } idx++; } idx = 0; while ((char_node = granny->findNode ("CHARACTER_AOS", idx))) { std::string filename = "", default_anim = ""; int animset = -1; int left_hand_bone = -1; int right_hand_bone = -1; int hand = HAND_NONE; value = char_node->findNode ("ID"); Uint32 id = (value != NULL) ? value->asInteger () : 0; if ((value = char_node->findNode ("ANIMSET"))) animset = value->asInteger (); if ((value = char_node->findNode ("LEFT_HAND_BONE"))) { left_hand_bone = value->asInteger (); hand = HAND_OWNER; } if ((value = char_node->findNode ("RIGHT_HAND_BONE"))) { right_hand_bone = value->asInteger (); hand = HAND_OWNER; } Uint16 assign = 0; if ((value = char_node->findNode ("ASSIGN"))) assign = value->asInteger (); id |= assign << 16; iter = animsets.find (animset); if ( id && ( iter != animsets.end() ) ) { assert (iter->second); cGrannyModelAOS *model = new cGrannyModelAOS (tex_basepath, iter->second->defaultanim); model->SetHandBones (left_hand_bone, right_hand_bone); model->SetHand (hand); model->SetAnimset (animset); for (int i = 0; AOSBodyInfo[i].id != 0; i++) { const AOSBodyData &Data = AOSBodyInfo[i]; XML::Node *submodel = char_node->findNode (Data.name); if ( submodel ) { model->AddModel( i, mulpath + to_lower( submodel->asString() ) ); } } for ( name_iter = iter->second->anim_names.begin(); name_iter != iter->second->anim_names.end(); name_iter++ ) { model->AddAnimation( name_iter->first, name_iter->second ); } //models.erase(id); if ( models.find( id ) != models.end() ) { //Logger::WriteLine("Warning: duplicated model id : %d\n", id); SAFE_DELETE( models.find( id )->second ); models.erase( id ); } models.insert( std::make_pair( id, model ) ); } else { Logger::WriteLine ("Warning: Invalid Granny AOS Definition"); } idx++; } for ( iter = animsets.begin(); iter != animsets.end(); iter++ ) { SAFE_DELETE( iter->second ); } animsets.clear(); //delete document; }
bool Config::Init() { // Default values, if they are not set under config.xml those will be used. // Section GFX m_vParserInfo.push_back( ParserData( "GFX", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "WIDTH", IS_INTEGER, &m_iWidth ) ); m_vParserInfo.push_back( ParserData( "HEIGHT", IS_INTEGER, &m_iHeight ) ); m_vParserInfo.push_back( ParserData( "BPP", IS_INTEGER, &m_iBPP ) ); m_vParserInfo.push_back( ParserData( "CURSOR", IS_INTEGER, &m_iCursor ) ); m_vParserInfo.push_back( ParserData( "PERSPECTIVE", IS_INTEGER, &m_iPerspective ) ); m_vParserInfo.push_back( ParserData( "FULLSCREEN", IS_INTEGER, &m_iStartFullScreen ) ); m_vParserInfo.push_back( ParserData( "ROOF_FADE_TIME", IS_INTEGER, &m_iRoofFadeTime ) ); m_vParserInfo.push_back( ParserData( "ROOF_FADE_ALPHA", IS_INTEGER, &m_iRoofFadeAlpha ) ); m_vParserInfo.push_back( ParserData( "ZBUFFER_SIZE", IS_INTEGER, &m_iDepthBuffer ) ); m_vParserInfo.push_back( ParserData( "MAXZOOM", IS_INTEGER, &m_iMaxZoom ) ); m_vParserInfo.push_back( ParserData( "MAXANGLE", IS_INTEGER, &m_iMaxAngle ) ); m_vParserInfo.push_back( ParserData( "VIEWDISTANCE", IS_INTEGER, &m_iViewDistance ) ); m_vParserInfo.push_back( ParserData( "BRIGHTNESS", IS_INTEGER, &m_iBrightness ) ); // Section UO m_vParserInfo.push_back( ParserData( "UO", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "STARTX", IS_INTEGER, &m_iStartX ) ); m_vParserInfo.push_back( ParserData( "STARTY", IS_INTEGER, &m_iStartY ) ); m_vParserInfo.push_back( ParserData( "STARTZ", IS_INTEGER, &m_iStartZ ) ); m_vParserInfo.push_back( ParserData( "MULPATH", IS_STRING, &m_sMulPath ) ); // m_vParserInfo.push_back( ParserData( "COMPRESSED_MAP", IS_STRING, &m_sCompressedMap ) ); m_vParserInfo.push_back( ParserData( "POPUP_MENU", IS_INTEGER, &m_iPopup ) ); m_vParserInfo.push_back( ParserData( "AOS", IS_INTEGER, &m_iAOSToolTips ) ); m_vParserInfo.push_back( ParserData( "CLIENT_IDENTIFICATION", IS_STRING, &m_sClientVersion ) ); m_vParserInfo.push_back( ParserData( "USE_CLILOCS", IS_INTEGER, &m_iClilocs ) ); m_vParserInfo.push_back( ParserData( "CLILOC_LANGUAGE", IS_STRING, &m_sClilocLang ) ); m_vParserInfo.push_back( ParserData( "SPEECH_HUE", IS_INTEGER, &m_iSpeechHue ) ); m_vParserInfo.push_back( ParserData( "AOSTOOLTIPS", IS_INTEGER, &m_iAOSToolTips ) ); //Artix added speech.mul config option m_vParserInfo.push_back( ParserData( "USE_SPEECH", IS_INTEGER, &m_iSpeech ) ); // Section NET m_vParserInfo.push_back( ParserData( "NET", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "PORT", IS_INTEGER, &m_iServerPort ) ); m_vParserInfo.push_back( ParserData( "SERVER", IS_STRING, &m_sServer ) ); m_vParserInfo.push_back( ParserData( "LOGIN", IS_STRING, &m_sLogin ) ); m_vParserInfo.push_back( ParserData( "PASSWORD", IS_STRING, &m_sPassword ) ); m_vParserInfo.push_back( ParserData( "IS_SPHERE", IS_INTEGER, &m_iIsSphere ) ); m_vParserInfo.push_back( ParserData( "IS_SPHERE55R", IS_INTEGER, &m_iIsSphere55R ) ); m_vParserInfo.push_back( ParserData( "IS_POL", IS_INTEGER, &m_iIsPol ) ); m_vParserInfo.push_back( ParserData( "IS_RUNUO", IS_INTEGER, &m_iIsRunUO ) ); m_vParserInfo.push_back( ParserData( "IS_UOX3", IS_INTEGER, &m_iIsUox3 ) ); m_vParserInfo.push_back( ParserData( "CLIENT_KEY", IS_INTEGER, &m_iClientKey ) ); // Section Sound m_vParserInfo.push_back( ParserData( "SOUND", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "MUSIC", IS_INTEGER, &m_iMusic ) ); m_vParserInfo.push_back( ParserData( "SOUND", IS_INTEGER, &m_iSound ) ); m_vParserInfo.push_back( ParserData( "FREQUENCY", IS_INTEGER, &m_iFrequency ) ); m_vParserInfo.push_back( ParserData( "STEREO", IS_INTEGER, &m_iStereo ) ); m_vParserInfo.push_back( ParserData( "CHUNKSIZE", IS_INTEGER, &m_iChunkSize ) ); m_vParserInfo.push_back( ParserData( "MUSICVOLUME", IS_INTEGER, &m_iMusicVolume ) ); m_vParserInfo.push_back( ParserData( "SOUNDVOLUME", IS_INTEGER, &m_iSoundVolume ) ); m_vParserInfo.push_back( ParserData( "MP3", IS_INTEGER, &m_iMP3 ) ); m_vParserInfo.push_back( ParserData( "FOOTSTEPS", IS_INTEGER, &m_iFootSteps ) ); // Section Iris Client m_vParserInfo.push_back( ParserData( "IRIS", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "SCRIPTS_PATH", IS_STRING, &m_sScriptPath ) ); m_vParserInfo.push_back( ParserData( "MOUSEOVER_TIMER", IS_INTEGER, &m_iMouseMotionTimer ) ); m_vParserInfo.push_back( ParserData( "", IS_END, NULL ) ); // After adding to the vector our struct start filling it with actual values XML::Parser kParser; kParser.loadData( "./xml/config.xml" ); XML::Node *kDocument = kParser.parseDocument(); XML::Node *kConfig = kDocument->findNode( "CONFIG" ); if ( !kConfig ) { THROWEXCEPTION( "Could not find configuration node." ); return false; } XML::Node *kValue = NULL, *kSection = NULL; // Read all values from config.xml for ( int i = 0; m_vParserInfo[i].iType != IS_END; i++ ) { const ParserData &Data = m_vParserInfo[i]; if ( Data.iType == IS_SECTION ) { kSection = kConfig->findNode( Data.sName ); } else { // If no section is loaded get from <config> kValue = kSection != NULL ? kSection->findNode( Data.sName ) : kConfig->findNode( Data.sName ); if ( kValue != NULL ) { if ( Data.iType == IS_BOOL ) { *reinterpret_cast<bool *>( Data.pData ) = kValue->asBool(); } else if ( Data.iType == IS_INTEGER ) { *reinterpret_cast<int *>( Data.pData ) = kValue->asInteger(); } else if ( Data.iType == IS_STRING ) { *reinterpret_cast<std::string *>( Data.pData ) = kValue->asString(); } } } } // Read Fonts bit of the file XML::Node *kFontSet = kConfig->findNode( "FONTSET" ); if ( kFontSet ) { int idx = 0; XML::Node *kFontNode = NULL; FontInfo kFontInfo; while ( ( kFontNode = kFontSet->findNode( "FONT", idx++ ) ) ) { if ( !kFontNode->lookupAttribute( "ID", kFontInfo.iId ) ) { continue; } if ( !kFontNode->lookupAttribute( "FILE", kFontInfo.sFileName ) ) { continue; } if ( !kFontNode->lookupAttribute( "NAME", kFontInfo.sFontName ) ) { continue; } if ( !kFontNode->lookupAttribute( "SIZE", kFontInfo.iSize ) ) { continue; } if ( !kFontNode->lookupAttribute( "HUE", kFontInfo.iHue ) ) { continue; } FontManager::GetInstance()->AddTTFFont( kFontInfo.iId, kFontInfo.sFileName, kFontInfo.sFontName, kFontInfo.iSize, kFontInfo.iHue ); } } // Depth Buffer if ( m_iDepthBuffer <= 0 ) { m_iDepthBuffer = 16; } // View Distance if ( m_iViewDistance < 3 ) { m_iViewDistance = 3; } // Max Zoom if ( m_iMaxZoom <= 0 ) { m_iMaxZoom = 0; } // Max Angle if ( m_iMaxAngle < 10 ) { m_iMaxAngle = 10; } // Max Angle if ( m_iMaxAngle > 90 ) { m_iMaxAngle = 90; } // Fix Mul path if no / at the end if ( m_sMulPath.size() ) { char cLastChar = m_sMulPath[m_sMulPath.length() - 1]; if ( ( cLastChar != '/' ) && ( cLastChar != '\\' ) ) { m_sMulPath += "/"; } } return true; }