Ir para conteúdo

ellendil

Campones
  • Total de itens

    14
  • Registro em

  • Última visita

Sobre ellendil

ellendil's Achievements

  1. Vc não copiou o meu inteiro pro seu não né??? Ahuehae era só pra ver a parte em negrito ^^'.
  2. Tenha certeza de que isso ta no lugar certo no seu commands.h Depois de: Adicione: struct Teleports{ Position dest; std::string name; };
  3. Ok, Patches em 05Set07: Mudanças: Opção Moveable: Para alguns items é melhor não poder move-los, mas bloquear todos os items seria um problema, então você pode definir na quests.xml como o exemplo abaixo: 0 Não pode mecher; 1 Pode mecher (default); Também adicionei um check pra stackables (contaveis), tavam bugando (Não era grande coisa), e um check pra ver se o item usado é a quest mesmo, tava podendo jogar qualquer item em cima que ele contava como a quest (não causa nenhum bug maior, mas era feio). Item.h Mude: Para: #ifndef _QUEST_XML_ bool isNotMoveable() const {return !items[id].moveable;} #else bool isNotMoveable() const; #endif Item.cpp: Na função: Depois de: Adicione: #ifdef _QUEST_XML_ quest = false; questmoveable = true; #endif Na função: Depois de: Adicione: #ifdef _QUEST_XML_ quest = false; questmoveable = true; #endif No fim do arquivo adicione: #ifdef _QUEST_XML_ bool Item::isNotMoveable() const{ if(quest && !questmoveable) return true; return !items[id].moveable; } #endif Actions.cpp Mude: For if(quest && item && item->quest){ Quest.cpp Depois de: Adicione: thatItem->quest = true; if( readXMLInteger(p,"moveable",intValue) ) { thatItem->questmoveable = (bool)intValue; } else { thatItem->questmoveable = true; } Game.cpp: Na função: Depois de: Adicione: #ifdef _QUEST_XML_ //Nova linha if(toItem && toItem->quest && item->getID() == toItem->getID() && item->isStackable()) return RET_CANNOTTHROW; #endif E ela ta funfando na SVN mais nova mesmo, testado aqui. Isso é tudo.
  4. É eu vi sabado isso. Tava fuçando a RoadMap ja que eu to bem afastado e conferi. To sem acesso até ao email do msn, onde eu trabalho é bloqueado por proxy, depois mando email com o 'funcional'
  5. Na verdade não devia ser TheChaos Style e sim gambiarra style... Tem q limpa isso é só pra saber do pessoal se ta funfando, o que tem pra melhora, pra tira, bugs e talz, ta incompleto pacas, quero coloca mto mais coisa ^^
  6. sim sim, apesar de eu ser péssimo com lua, da sim ja li algo sobre isso, mas eu penso mais na praticidade pra editar (pra mim é mais pratico xml do que lua) ^^. E também, so carrega quando tem alteração grande, não e carregado a cada teleport pois ja ta na memoria ne, então agiliza
  7. Atualmente - Versão 0.3.2.1 Atualizada em: 05/09/07 - 12:30 SVN ChangeLog da v0.1 pra 0.2b: Arrumados alguns bugs. Opção de Teleport. Opção de Mensagem. Melhora nos items. Descrição especial nos items. E mais algumas coisas. ChangeLog da v0.2 pra 0.3.2: Re-Escrito. Limpo (tem muito pra limpa ainda...) É possivel por os items de recompensa dentro de containers agora (um bom numero). Respeite sempre a capacidade do container, eu não coloquei nenhum check pra isso... Colocar o ActionID do item. E mais algumas coisas.. ------------------------------------------------------------------- Olá de novo. Como eu disse eu ia tentar fazer, não está completo ainda mas a base principal ta feita. O dovia do Vitor disse que ia re-escreve, mas nao fez nada então eu refiz. Eu tava tentando testa meu C++ (que ta horrivel como todos podem ver), mas até que saiu a bagaça Todo: Limpeza? Achar e corrigir bugs. Melhorar as listas que eu fiz uma zona.... Definir que os players só podem realizar a quest 1x. [done] Melhorar Containers [done] Teleports [done] Setar ActionID nas recompensas [done] Opção de movimentar (moveable) [done] Bom, não está completa ainda, então ela TEM bugs Features: Nome da quest: quando o player der look no item, ele vai ver o nome da quest (pode ser setado no xml o nome lógico e você pode ligar/desligar essa opção por lá também). Quest ID: é a chave das nossas quests, devem ser sempre unicas a não ser que ela tenha segmentos. Segment: é uma parte da quest, você pode ter X segmentos dentro da quest principal. sempre seguindo em ordem crescente. X, Y, Z: É a localização do item no map, pode ser QUALQUER ITEM. Moveable: Se vai poder mover ou não o item (DEFAULT = 1 = MOVEABLE, 0 = NOTMOVEABLE - não pode mover) backpack: Pode dar items dentro de containers, como o Tibia da Cip. Foi mudado: *Você tem que por o id da backpack, se não por, ela vai usa o id padrão. *Quando você por pra dar o item dentro de uma bp, vai ligar essa opção automaticamente no id padrão (bp marrom). Type: pode ser o id do item ou o nome dele. Preste atenção pra items que tem o mesmo nome... Desc: Adiciona uma descrição especial ao item. Ex: 19:28 You see a boots of haste.It weighs 7.5 oz. It was made by and old and unknow guy. A rare masterpiece. Message: Manda uma mensagem pro player quando ele 'realiza a quest'. Teleport: teleporta o player quando ele 'realiza a quest'. ActionId: define uma actionID pro item de recompensa (cada recompensa pode ter o seu). Container ID: vai dar o item definido em um container que você deve ter posto acima: Ex: O warrior helmet vai ir no container 2 (o de id 1995) Eu acho que é tudo, vamo pro code. ------------------------------------------------------------------- Actions.cpp Depois de: Adicione: #ifdef _QUEST_XML_ #include "quest.h" extern Quests quests; #endif Na função: Depois de: Adicione: #ifdef _QUEST_XML_ Quests* quest = quests.getQuest(item->getPosition()); if(quest && item && item->quest){ std::stringstream message; int32_t value; player->getStorageValue((uint32_t)quest->id, value); if(value){ if(value >= quest->sgId){ player->sendTextMessage(MSG_INFO_DESCR, "Its empty."); return RET_NOERROR; } if(value != quest->sgId-1){ player->sendTextMessage(MSG_INFO_DESCR, "You are not prepared yet."); return RET_NOERROR; } } else{ if(quest->sgId != 1){ player->sendTextMessage(MSG_INFO_DESCR, "You are not prepared yet."); return RET_NOERROR; } } Container* backpack = NULL; Container* rewarded = NULL; std::list<Container*> listContainer;//Vo usar no rewarded. std::list<Container*> adicionar; std::list<Container*>::iterator Adding; std::list<Item*> removel; //I couldnt find any other way... bool error = false; ReturnValue ret = RET_NOERROR, ret2 = RET_NOERROR, ret3 = RET_NOERROR, ret4 = RET_NOERROR; int nova=1; int bpcids; if(quest->bId != 0 || quest->containers != 0){ backpack = Item::CreateItem(quest->bId != 0 ? quest->bId : 1988)->getContainer(); removel.push_back(backpack); } RewardList2::iterator get = quest->rewardList.begin(); if(quest->containers != 0){ int atd; for(atd = 0; atd < quest->containers; atd++){ rewarded = Item::CreateItem(quest->bpType[atd])->getContainer(); if(rewarded) { listContainer.push_back(rewarded); } } } for(get; get != quest->rewardList.end(); ++get){ Item* reward = Item::CreateItem((*get).first->getID(), (*get).first->getItemCountOrSubtype()); if(reward){ if((*get).first->getSpecialDescription() != "") reward->setSpecialDescription((*get).first->getSpecialDescription()); if((*get).first->getActionId() != 0) reward->setActionId((*get).first->getActionId()); } if((*get).second != 0){ Adding = listContainer.begin(); int add=0; while(Adding != listContainer.end()){ add++; if((*get).second == add){ Container* toAdd = (*Adding); toAdd->__addThing(reward); } Adding++; } } else if(backpack) backpack->__addThing(reward); else{ ret = g_game.internalAddItem(player, reward); //Nao da pra usar o test, pois ele não ocupa o slot... if(ret != RET_NOERROR) error = true; else{ removel.push_back(reward); message << "You have found " << reward->getDescription(2); player->sendTextMessage(MSG_INFO_DESCR, message.str().c_str()); } } } if(backpack){ for(Adding = listContainer.begin(); Adding != listContainer.end(); Adding++){ Container* toAdd2 = (*Adding); backpack->__addThing(toAdd2); } ret2 = g_game.internalAddItem(player, backpack, INDEX_WHEREEVER, 0, true); if(ret2 == RET_NOERROR){ g_game.internalAddItem(player, backpack); message << "You have found " << backpack->getDescription(2); player->sendTextMessage(MSG_INFO_DESCR, message.str().c_str()); } else return ret2; } if(error){//Then we Add it... for(std::list<Item*>::iterator remove = removel.begin(); remove != removel.end(); ++remove){ ret3 = g_game.internalRemoveItem((*remove), (*remove)->getItemCount(), true);//Testing befre, if we get an error it could crash the server if(ret3 == RET_NOERROR) g_game.internalRemoveItem((*remove), (*remove)->getItemCount()); else{//Ok, this should not happen... std::stringstream bug; bug << "Atention!!! Player: "<<player->getName()<<" bugged the quest: "<<quest->name<<"."; for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it){ if((*it).second && (*it).second->getAccessLevel() > 0) (*it).second->sendTextMessage(MSG_STATUS_WARNING, bug.str().c_str()); } player->sendTextMessage(MSG_STATUS_WARNING, "You have bugged the quest, we are contacting a gm now (you should do it also)"); return ret3; } } return RET_CANNOTUSETHISOBJECT; } player->addStorageValue(quest->id, quest->sgId); if(quest->teleport.x != 0xFFFF){ if(g_game.internalTeleport(player,quest->teleport) == RET_NOERROR) g_game.addMagicEffect(quest->teleport, NM_ME_ENERGY_AREA); } if(quest->questDesc != "") player->sendTextMessage(MSG_INFO_DESCR, quest->questDesc); return ret; } #endif Actions.h Depois de: Adcione: #ifdef _QUEST_XML_ typedef std::list<std::pair<Item*, int> > RewardList2; typedef RewardList2::value_type RewardList2_Pair; RewardList2 rewardList2; #endif Otserv.cpp Depois de: Adicione: #ifdef _QUEST_XML_ #include "quest.h" Quests quests; #endif Depois de: Adicione: #ifdef _QUEST_XML_ std::cout << ":: Loading The Chaos Style Quest System "; if(!quests.loadQuests()) std::cout << ":: Unable to load!"; else std::cout << "[done]" << std::endl; #endif Game.cpp: Na função: Depois de: Adicione: #ifdef _QUEST_XML_ //Nova linha if(toItem && toItem->quest && item->getID() == toItem->getID() && item->isStackable()) return RET_CANNOTTHROW; #endif Item.h Mude: Para: #ifndef _QUEST_XML_ bool isNotMoveable() const {return !items[id].moveable;} #else bool isNotMoveable() const; #endif Item.cpp: Na função: Depois de: Adicione: #ifdef _QUEST_XML_ quest = false; questmoveable = true; #endif Na função: Depois de: Adicione: #ifdef _QUEST_XML_ quest = false; questmoveable = true; #endif No fim do arquivo adicione: #ifdef _QUEST_XML_ bool Item::isNotMoveable() const{ if(quest && !questmoveable) return true; return !items[id].moveable; } #endif Agora crie 2 arquivos no seu projeto: quest.cpp #ifdef _QUEST_XML_ ////////////////////////////////////////////////////////////////////// // OpenTibia - an opensource roleplaying game ////////////////////////////////////////////////////////////////////// // Quests system loaded on XML base - By The Chaos // Thanks to LooS!k for help also. ////////////////////////////////////////////////////////////////////// // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ////////////////////////////////////////////////////////////////////// #include <string> #include <sstream> #include "quest.h" #include "configmanager.h" #include "game.h" extern Game g_game; extern ConfigManager g_config; Quests::Quests(){ id = 0; sgId = 1; containers = 0; } bool Quests::loadQuests() { std::string filename = g_config.getString(ConfigManager::DATA_DIRECTORY) + "quests.xml"; xmlDocPtr doc; doc = xmlParseFile(filename.c_str()); std::stringstream desc; int itId, itCount, bpId; std::string Ident; std::string strCmd; int intValue; if( doc ) { xmlNodePtr root,p; root = xmlDocGetRootElement(doc); if( xmlStrcmp(root->name,(const xmlChar*) "quests") != 0 ) { std::cout << "- Problem: Check the quests.xml file."<< std::endl; return false; } p = root->children; while( p ) { if( xmlStrcmp(p->name, (const xmlChar*) "quest") == 0 ) { Quests* quest = new Quests; if( readXMLString(p, "name", strCmd) ) { quest->name = strCmd; } else { std::cout << "missing name for quest..." << std::endl; strCmd = "unknown"; } if( readXMLInteger(p, "showname", intValue) ) { quest->showName = (bool)intValue; } else { quest->showName = false; } if( readXMLInteger(p,"questId",intValue) ) { quest->id = intValue; } else { std::cout << "Error: Missing questId for quest: " << quest->name << std::endl; return false; } if( readXMLInteger(p,"segment",intValue) ) { quest->sgId = intValue; } else { std::cout << "Error: Missing segment value for quest: " << quest->name << std::endl; return false; } if( readXMLInteger(p,"x",intValue) ) { quest->pos.x = intValue; } else { std::cout << "Error: Missing X Value for quest: " << quest->name << std::endl; return false; } if( readXMLInteger(p,"y",intValue) ) { quest->pos.y = intValue; } else { std::cout << "Error: Missing Y Value for quest: " << quest->name << std::endl; return false; } if( readXMLInteger(p,"z",intValue) ) { quest->pos.z = intValue; } else { std::cout << "Error: Missing Z Value for quest: " << quest->name << std::endl; return false; } if( readXMLInteger(p,"backpack",intValue) ) { quest->bId = intValue; } else { quest->bId = 0; } Tile* thatTile = g_game.getTile(quest->pos.x, quest->pos.y, quest->pos.z); if( !thatTile ) { std::cout << "Error: Tile not found on quest: "<< quest->name << std::endl; return false; } Item *thatItem = thatTile->getTopThing()->getItem(); if( !thatItem ) { std::cout << "Error: Internal error - check map on: " << quest->pos.x << "/" << quest->pos.y <<"/"<< quest->pos.z << std::endl; return false; } thatItem->quest = true; if( readXMLInteger(p,"moveable",intValue) ) { thatItem->questmoveable = (bool)intValue; } else { thatItem->questmoveable = true; } if( quest->name != "unknown" && quest->showName ) { desc << " It seems to be sealed somehow. You can read "<< quest->name << " on it."; thatItem->setSpecialDescription(desc.str()); desc.str(""); } xmlNodePtr tmp = p->children; while( tmp ) { if( xmlStrcmp(tmp->name, (const xmlChar*) "reward") == 0 ) { xmlNodePtr slot = tmp->children; while( slot ) { if( xmlStrcmp(slot->name, (const xmlChar*)"item") == 0 ) { itId = 0, itCount = 0; if( readXMLString(slot,"type",strCmd) ) { Ident = strCmd; } if( isdigit(Ident[0]) ) { itId = atoi(Ident.c_str()); } else { itId = Item::items.getItemIdByName(Ident); } if( readXMLInteger(slot,"count",intValue) ) { itCount = intValue; } else { itCount = 1; } if( itCount > 100 ) { itCount = 100; std::cout << "Warning: Count on " << Ident << " is higher than 100. Quest: " << quest->name << std::endl; } Item* reward = Item::CreateItem(itId, itCount); if( !reward ) { std::cout << "Error: Error while creating reward item." << quest->name << std::endl; return false; } if( readXMLString(slot, "desc", strCmd) ) { reward->setSpecialDescription(strCmd.c_str()); } if( readXMLInteger(slot,"actId",intValue) ) { reward->setActionId(intValue); } /* container id*/ int cid = 0; if( readXMLInteger(slot,"containerId", intValue) ) { cid = intValue; } quest->rewardList.push_back( RewardList_Pair(reward, cid) ); } slot = slot->next; } } if( xmlStrcmp(tmp->name, (const xmlChar*) "message") == 0 ) { if(readXMLString(tmp, "value", strCmd)) { quest->questDesc += strCmd; } } if( xmlStrcmp(tmp->name, (const xmlChar*) "backpack") == 0 ) { if( readXMLString(tmp,"id",strCmd) ) { Ident = strCmd; } if( isdigit(Ident[0]) ) { bpId = atoi(Ident.c_str()); } else { bpId = Item::items.getItemIdByName(Ident); } quest->bpType[quest->containers] = bpId; quest->containers++; } if( xmlStrcmp(tmp->name, (const xmlChar*) "teleport") == 0 ) { if( readXMLInteger(tmp,"x",intValue) ) { quest->teleport.x = intValue; } if( readXMLInteger(tmp,"y",intValue) ) { quest->teleport.y = intValue; } if( readXMLInteger(tmp,"z",intValue) ) { quest->teleport.z = intValue; } } tmp = tmp->next; } questMap[quest->pos] = quest; } p=p->next; } xmlFreeDoc(doc); } else { std::cout << filename << " not found!" << std::endl; return false; } return true; } Quests::~Quests() { //std::cout << "Quest " << this->name << std::endl; QuestMap::iterator it = questMap.find(this->pos); if(it != questMap.end()) { delete it->second; questMap.erase(it); } } void Quests::erase(bool loadxml) { QuestMap::iterator it = questMap.begin(); while(it != questMap.end()) { delete it->second; questMap.erase(it); it = questMap.begin(); } if(loadxml){ if(!loadQuests()){ std::cout << "\n::Error while reloading the quests.xml. "<<std::endl; return; } } } Quests* Quests::getQuest(Position pos) { QuestMap::iterator it = questMap.find(pos); while(it != questMap.end()) { return it->second; } return NULL; } #endif E quest.h #ifdef _QUEST_XML_ ////////////////////////////////////////////////////////////////////// // OpenTibia - an opensource roleplaying game ////////////////////////////////////////////////////////////////////// // Quests system loaded on XML base - By The Chaos ////////////////////////////////////////////////////////////////////// // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ////////////////////////////////////////////////////////////////////// /*#include <string> #include <map>*/ #include "position.h" #include "definitions.h" #include "item.h" class Quests{ public: Quests(); ~Quests(); bool showName; int bpType[99], sgId, bId, containers; //Não deve ter mais que 99 containers... pelo amor... uint32_t id; std::string questDesc, name; Position teleport, pos; //Centalizar na posição da quest na action... vai facilitar e nao meche no items... bool loadQuests(); void erase(bool loadxml); typedef std::list<std::pair<Item* , int> > RewardList; typedef RewardList::value_type RewardList_Pair; RewardList rewardList; //std::list<Item *> rewardList; Quests* getQuest(Position pos); typedef std::map<Position,Quests*> QuestMap; QuestMap questMap; protected: }; #endif Adicione nas opções do seu projeto: -D_QUEST_XML_ E DE REBUILD ALL. Crie um arquivo chamado quests.xml na sua pasta DATA e siga o exemplo:: <quests> <quest name="DelOownage" showname="1" questId="803" segment="1" x="121" y="92" z="7" movement="0"> <backpack type="1988"/> <backpack type="1995"/> <message is="Uhuulll"/> <reward> <item type="knight axe" containerId="1"/> <item type="warrior helmet" desc="It was made by and old and unknow guy. A rare masterpiece." containerId="2"/> <item type="royal helmet" desc="Este item tem uma action" containerId="1" actId="9876"/> </reward> </quest> </quests> Como vocês podem ver, você pode por nome na quest, mudar pra mostar o nome ou não, a posição você TEM que por, pois ela é essencial, se os items vão vim em containers, e por ae vai (obedeça a cap do container...), colocar actionID e mais coisinhas. There is nothing important that i remember right now, so start the tests and remember, its not finished yet. Signed, The Chaos. Ps.: Se alguem tiver bugs ou lag, qualquer coisa anormal, poste aqui por favor pra gente ta vendo. E eu gostaria de algumas ideias Ps².: Eu sei que muitos adoram e acham facil por lua, mas eu prefiro ainda desse jeito e sei que muita gente vai ter mais facilidade, apesar de saber que o lua tem mais funcionalidades e talz. Oka? Atualizado pra versão v0.3.2 em 31Ago07
  8. Não sou de mecher com distros, então nao conheco essa evolutions (parece ser bem usada =p). Tipo, deve funfa sim, acho que na svn mesmo que eu usei de base nao teve mudanças que afetem, e ele se baseia nos items/monstros de cada server sem problema. Vale a pena tenta
  9. @Up refaz a parte do commands.h, certeza que vc esqueceu algo.
  10. Aham, mas você sabe que na maioria desses ots, você só pode usar quando tem cidades x programadas no map, adicionando pelo map editor né? Nesse não, vc adiciona 300 teleports se quiser na mesma cidade, mudando o nome do jeito que você quiser. /teleport demon quest Tem uma cidade demon quest? Pode ter mas... bom cya mustorze né?
  11. Gambiarras S.A. É que quando a função ta sendo chamada pelo protocolo (vindo da janela de texto que o player ta editando) a primeira string que ele vai procura vai ser a "Teleports", isso foi um jeito simples e rapido de pula ela só. é um parametro simples da função, não uma string realmente nula ^^.
  12. Vamos lá, eu fiz isso pq era um saco esses comandos que você tinha que editar no config.lua, num sei onde, num sei nas sources e sempre muito limitado. Com esse não, você tem um grande leque de opções, com nome e podendo editar tudo dentro do próprio jogo, sem mecher na xml, mas você também pode editar por ela caso preciso Vamos lá, abra suas sources e vamos começar! Commands.cpp Depois de: Adicione: {"/teleport",&Commands::teleportManager}, Essa linha vai ser nosso comando ingame. (faz sentido...) Na função dos reloads nos commands, depois de: Adicione: else if(param == "teleports"){ this->reloadTeleports(true); } Pra quando a gente der um "/reload teleports" dentro do jogo, ele vai limpa os teleports atuais e carregar os do xml de novo. Bom pra edições manuais no xml. Tá agora vá la no fim do arquivo, e adicione: bool Commands::teleportManager(Creature* creature, const std::string& cmd, const std::string& param){ Player* player = creature->getPlayer(); if(!player) return false; std::stringstream teste; std::string func, cname; bool jump = false; std::string::size_type pos = param.find(",", 0); if(pos == std::string::npos){ jump = true; pos = param.size(); } func = param.substr(0, pos).c_str(); TeleportMap::iterator it; if(func == "edit"){ Item* book = Item::CreateItem(2597); std::stringstream tds; tds << "Teleport\n"; for(it = teleportMap.begin(); it != teleportMap.end(); ++it){ tds << it->second->name << ": x:\""<<it->second->dest.x<<"\" y:\""<<it->second->dest.y<<"\" z:\""<<it->second->dest.z<<"\"."<<std::endl; } book->setText(tds.str().c_str()); player->sendTextWindow(book,65535, true); return false; } if(func.substr(0,3) == "add"){ it = teleportMap.find(func.substr(4,func.size())); if(it != teleportMap.end()) player->sendTextMessage(MSG_INFO_DESCR, "This name is already being used as teleport position."); else{ Teleports* tp = new Teleports; tp->name = func.substr(4,func.size()); tp->dest.x = player->getPosition().x; tp->dest.y = player->getPosition().y; tp->dest.z = player->getPosition().z; player->sendTextMessage(MSG_INFO_DESCR, "New Teleport Added."); teleportMap[tp->name] = tp; saveTeleportXml("NULL"); } } if(func.substr(0,6) == "remove"){ it = teleportMap.find(func.substr(7, func.size())); if(it != teleportMap.end()){ teleportMap.erase(it); saveTeleportXml("NULL"); player->sendTextMessage(MSG_INFO_DESCR, "Teleport deleted."); } } Creature* toMove = creature; if(!jump){ cname = param.substr(pos+2, param.size()).c_str(); toMove = game->getCreatureByName(cname); if(!toMove){ player->sendTextMessage(MSG_INFO_DESCR, "This name doesnt belong to any creature online."); return false; } } it = teleportMap.find(func); if(it != teleportMap.end()){ if(game->internalTeleport(toMove, it->second->dest) == RET_NOERROR){ game->addMagicEffect(it->second->dest, NM_ME_ENERGY_AREA); return true; } } } bool Commands::saveTeleportXml(const std::string& text) { std::string tmp = text; std::string::size_type pos; std::stringstream sb; std::string datadir = g_config.getString(ConfigManager::DATA_DIRECTORY); std::string filename = datadir + "teleports.xml"; xmlNodePtr pn, root; if(tmp != "NULL"){ reloadTeleports(false); tmp.erase(0,9);//Erase Teleports\n while(tmp.size() > 1){ Teleports* temp = new Teleports; pos = tmp.find(':', 0); sb.str(""); sb << tmp.substr(0, pos).c_str();// Nome da cidade temp->name = sb.str().c_str(); tmp.erase(0, pos+5); pos = tmp.find('y', 0); sb.str(""); sb <<tmp.substr(0,pos-2);//Tirar X temp->dest.x = atoi(sb.str().c_str()); tmp.erase(0, pos+3); pos = tmp.find('z',0); sb.str(""); sb <<tmp.substr(0,pos-2);//Tirar Y temp->dest.y = atoi(sb.str().c_str()); tmp.erase(0, pos+3); pos = tmp.find('.',0); sb.str(""); sb <<tmp.substr(0,pos-1);//Tirar Z temp->dest.z = atoi(sb.str().c_str()); tmp.erase(0, pos+2); teleportMap[temp->name] = temp; } } xmlDocPtr doc = xmlNewDoc((const xmlChar*)"1.0"); doc->children = xmlNewDocNode(doc, NULL, (const xmlChar*)"teleports", NULL); root = doc->children; TeleportMap::iterator it = teleportMap.begin(); while(it != teleportMap.end()){ pn = xmlNewNode(NULL,(const xmlChar*)"teleport"); sb.str(""); sb << it->second->name; xmlSetProp(pn, (const xmlChar*)"name", (const xmlChar*)sb.str().c_str()); sb.str(""); sb << it->second->dest.x; xmlSetProp(pn, (const xmlChar*)"posX", (const xmlChar*)sb.str().c_str()); sb.str(""); sb << it->second->dest.y; xmlSetProp(pn, (const xmlChar*)"posY", (const xmlChar*)sb.str().c_str()); sb.str(""); sb << it->second->dest.z; xmlSetProp(pn, (const xmlChar*)"posZ", (const xmlChar*)sb.str().c_str()); xmlAddChild(root, pn); ++it; } xmlSaveFormatFileEnc(filename.c_str(), doc, "UTF-8", 1); return true; } bool Commands::loadTeleportsXml(const std::string& _datadir) { datadir = _datadir; std::string filename = datadir + "teleports.xml"; xmlDocPtr doc = xmlParseFile(filename.c_str()); if(doc){ loaded = true; xmlNodePtr root, p; root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"teleports") != 0){ xmlFreeDoc(doc); return false; } std::string strCmd; p = root->children; while (p){ if(xmlStrcmp(p->name, (const xmlChar*)"teleport") == 0){ if(readXMLString(p, "name", strCmd)){ Teleports* tp = new Teleports; tp->name = strCmd; int dest; if(readXMLInteger(p,"posX",dest)) tp->dest.x = dest; else{ std::cout << "missing x for " << strCmd << std::endl; } if(readXMLInteger(p,"posY",dest)) tp->dest.y = dest; else{ std::cout << "missing y for " << strCmd << std::endl; } if(readXMLInteger(p,"posZ",dest)) tp->dest.z = dest; else{ std::cout << "missing z for " << strCmd << std::endl; } teleportMap[strCmd] = tp; } else{ std::cout << "missing teleport name." << std::endl; } } p = p->next; } xmlFreeDoc(doc); } return true; } void Commands::reloadTeleports(bool loadxml){ TeleportMap::iterator it = teleportMap.begin(); while(it != teleportMap.end()){ delete it->second; teleportMap.erase(it); it = teleportMap.begin(); } if(loadxml) loadTeleportsXml(g_config.getString(ConfigManager::DATA_DIRECTORY)); } Todas as principais funções tão ae dentro, a reload, a load, a save e o manager em si. Vamos agora pra: Commands.h PRESTEM MUITA ATENÇÃO PELO AMOR, qualquer erro aqui da dor de cabeça... Depois de: Adicione: bool loadTeleportsXml(const std::string& _datadir); void reloadTeleports(bool loadxml); bool saveTeleportXml(const std::string& text); São as declarações das 3 funções que a gente talvez faça uso externo (a load é a principal). Por isso tem que estar no public do commands.h Depois de: Adicione: bool teleportManager(Creature* creature, const std::string& cmd, const std::string& param); typedef std::map<std::string,Teleports*> TeleportMap; TeleportMap teleportMap; Ok, agora vá la em baixo do commands.h Depois de: Adicione: struct Teleports{ Position dest; std::string name; }; Beleza. Vamos pra outro arquivo. OTserv.cpp Vamos por a parte que vai carrega o nosso teleports.xml assim que o ot for carregado. Você pode por em qualquer posição que preferir, mas pra quem não souber como, façam assim: Depois de: Adicione: std::cout << ":: Loading The Chaos Style Teleport System... "; if(!commands.loadTeleportsXml(g_config.getString(ConfigManager::DATA_DIRECTORY))){ std::stringstream errormsg; errormsg << "Unable to load " << filename.str() << "!"; ErrorMessage(errormsg.str().c_str()); return -1; } std::cout << "[done]" << std::endl; Beleza. Outro arquivo. ProtocolXX.cpp: Onde XX representa a versão do seu OT/Protocolo~ Na função: Depois de: Adicione: if(new_text.substr(0,8)=="Teleport"){ commands.saveTeleportXml(new_text); return; } Ok Ok. Isso serve pra filtra o texto da janela de edição do teleport, se não ela vai assumi como se tivesse editando o texto de algum item, e isso não seria bom. ^^ Bom, só compilar, eu recomendo um rebuild-all pra variar. Esse code vai criar um arquivo chamado teleports.xml na sua pasta data. Ele vai segui sempre esse exemplo: <?xml version="1.0" encoding="UTF-8"?> <teleports> <teleport name="depot" posX="103" posY="100" posZ="8"/> <teleport name="edron" posX="112" posY="95" posZ="7"/> <teleport name="thais" posX="119" posY="95" posZ="7"/> <teleport name="venore" posX="116" posY="96" posZ="7"/> </teleports> É bem basicão mesmo, nome do teleport (que você vai usar no comando) e a posição dos eixos x, y e z. Sem muita complicação, você pode adiciona mais teleports seguindo o exemplo ae. Como usar: O comando funciona assim: /teleport opção¹, opção² Obs.: (GM Seria aquele que executou o comando lógico...) As opções são as seguintes: add nome = Adiciona um teleport com o nome especificado, pegando a posição atual do GM. remove nome = remove um teleport que tenha aquele nome. edit = Abre uma janela pra editar os teleports atuais. O comando edit não aceita nem requer opção². Muita atenção no comando edit... Siga muito atentamente o exemplo que ele joga na janela, ou pode ferrar a estrutura dos teleports e parar todos eles. Você pode adicionar, editar e remover teleports, mas sempre com muito cuidado. Ele assim que você confirma, salva tudo no xml e da reload. Obs.: Tanto pro add, quanto pro remove, nao use: "," E por último e talvez a mais importante (lol? ^^'): Nome_do_teleport, nome_do_teleportado Nome_do_teleport = Ja diz tudo, o nome do teleport que você quer ir. Atenção: Pra teleportar outra criatura, você tem que por virgula e o nome dela, ficando assim por exemplo: /teleport Venore, The Chaos Se você digitar o nome de uma criatura que não exista/estja off, ela vai retornar uma msg pra você dizendo isso. pra teleportar você mesmo, é só digiar: /teleport Venore Sem por mais nada na frente do nome do teleport (, The Chaos) Bom acho que é só. Duvidas, sugestões, flames, elogios, postem aki Tks, The Chaos~.
  13. foi bolado numa svn, não foi feita em distro não, os codes que tem a mais ali fui eu que tava fuçando.
  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...