-
Total de itens
14 -
Registro em
-
Última visita
Sobre ellendil
ellendil's Achievements
-
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
Vc não copiou o meu inteiro pro seu não né??? Ahuehae era só pra ver a parte em negrito ^^'. -
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
Esse é o meu commands.h, da uma olhada. -
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
Tenha certeza de que isso ta no lugar certo no seu commands.h Depois de: Adicione: struct Teleports{ Position dest; std::string name; }; -
[svn]the Chaos Style Quest-xml Manager
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
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. -
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
É 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' -
[svn]the Chaos Style Quest-xml Manager
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
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 ^^ -
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
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 -
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
-
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
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 -
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
@Up refaz a parte do commands.h, certeza que vc esqueceu algo. -
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
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é? -
Teleport Manager @ Thechaos Style - V0.1a
tópico respondeu ao ellendil de ellendil em Linguagens de Programação
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 ^^. -
Teleport Manager @ Thechaos Style - V0.1a
um tópico no fórum postou ellendil Linguagens de Programação
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~. -
[7.92]command Editor Ingame
tópico respondeu ao Jackson Zani de ellendil em Linguagens de Programação
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.