Ir para conteúdo
  • Cadastre-se

canary Como Adicionar uma Nova Vocação no Canary Server


Posts Recomendados

  • Administrador

 

Tutorial Completo: Como Adicionar uma Nova Vocação no Canary Server

 

 

Citar

Objetivo: Este guia detalhado explica como criar e configurar novas vocações (exemplo: Warrior e Elite Warrior) no Canary Server, abordando também a lógica por trás do sistema de vocações.

 

 


 

1. Entendendo a Lógica das Vocações

No servidor Canary, cada vocação representa uma classe de personagem com habilidades, atributos e características específicas. Para que o servidor reconheça uma nova vocação, é necessário:

- Definir um identificador único (ID);
- Registrar o ClientID (usado para exibição no cliente);
- Especificar um BaseID (para herança de características ou evolução);
- Configurar atributos, fórmulas e habilidades no XML.

 


 

2. Alterando a Enumeração das Vocações (Código Fonte C++)

Arquivo: `src/creatures/creatures_definitions.hpp`

Adicione os novos IDs no enum `Vocation_t`:

 

enum Vocation_t : uint16_t {
    VOCATION_NONE = 0,
    VOCATION_SORCERER = 1,
    VOCATION_DRUID = 2,
    VOCATION_PALADIN = 3,
    VOCATION_KNIGHT = 4,
    VOCATION_MASTER_SORCERER = 5,
    VOCATION_ELDER_DRUID = 6,
    VOCATION_ROYAL_PALADIN = 7,
    VOCATION_ELITE_KNIGHT = 8,
    VOCATION_WARRIOR = 9,
    VOCATION_ELITE_WARRIOR = 10,
    VOCATION_LAST = VOCATION_ELITE_WARRIOR
};

 

 

Citar

A constante `VOCATION_LAST` deve sempre apontar para o último ID definido para evitar problemas de indexação interna.

 

 


 

3. Atualizando o Script de Vocações (Lua)

Arquivo: `data/libs/vocation.lua`

Adicione os novos valores nas três seções do objeto `VOCATION`:

 

VOCATION = {
    ID = {
        WARRIOR = 9,
        ELITE_WARRIOR = 10,
        ...
    },
    CLIENT_ID = {
        WARRIOR = 0,
        ELITE_WARRIOR = 0,
        ...
    },
    BASE_ID = {
        WARRIOR = 5,
        ...
    }
}

 

 

Citar

`CLIENT_ID` com valor 0 indica que a vocação será exibida como "None" na seleção de personagem, mas isso não afeta o jogo em si.  


`BASE_ID` é usado para definir herança de habilidades e características entre vocações.

 

 


 

4. Criando Função de Verificação da Nova Vocação

Arquivo: `data/libs/functions/player.lua`

Adicione a seguinte função no final do arquivo:

 

function Player.isWarrior(self)
    return table.contains({VOCATION.ID.WARRIOR, VOCATION.ID.ELITE_WARRIOR}, self:getVocation():getId())
end

 

 

Citar

Essas funções são úteis para aplicar lógicas específicas por vocação em spells, quests ou sistemas customizados.

 

 


 

5. Configurando as Vocações no XML

Arquivo: `data/XML/vocations.xml`

Adicione o bloco de cada nova vocação com os atributos desejados:

 

<vocation id="9" clientid="0" baseid="5" name="Warrior" description="a warrior"
  magicshield="0" gaincap="25" gainhp="15" gainmana="5" gainhpticks="4000"
  gainhpamount="1" gainmanaticks="6000" gainmanaamount="2" manamultiplier="3.0"
  attackspeed="2000" basespeed="110" soulmax="200" gainsoulticks="15000" fromvoc="5">
    <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
    <skill id="0" multiplier="1.1" />
    <skill id="1" multiplier="1.1" />
    <skill id="2" multiplier="1.1" />
    <skill id="3" multiplier="1.1" />
    <skill id="4" multiplier="1.4" />
    <skill id="5" multiplier="1.1" />
    <skill id="6" multiplier="1.1" />
</vocation>

<vocation id="10" clientid="0" baseid="6" name="Elite Warrior" description="an elite warrior"
  magicshield="0" gaincap="25" gainhp="15" gainmana="5" gainhpticks="4000"
  gainhpamount="1" gainmanaticks="6000" gainmanaamount="2" manamultiplier="3.0"
  attackspeed="2000" basespeed="110" soulmax="200" gainsoulticks="15000" fromvoc="5">
    <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
    <skill id="0" multiplier="1.1" />
    <skill id="1" multiplier="1.1" />
    <skill id="2" multiplier="1.1" />
    <skill id="3" multiplier="1.1" />
    <skill id="4" multiplier="1.4" />
    <skill id="5" multiplier="1.1" />
    <skill id="6" multiplier="1.1" />
</vocation>

 

 

Citar

Esses atributos definem como a vocação evolui: vida/mana por level, velocidade de ataque, ganho de soul, atributos de combate, etc.

 

 


 

6. Compilando o Servidor

Após todas as alterações, é obrigatório recompilar o servidor para que as novas vocações sejam reconhecidas corretamente.

 


 

 

Conclusão:

 

Ao seguir todos os passos, suas novas vocações estarão totalmente integradas ao servidor. Você poderá usá-las para personagens.

 

 

Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

  • Conteúdo Similar

    • Por Anderson Sacani
      Venho publicar uma alteração que eu e minha equipe fizemos no script já existente do Canary.
      O arquivo do script se chama quest_system1.lua.
      Fizemos essa alteração, porque o sistema original não entregava chave com actionid ao jogador. A chave vinha com o código 0000, ou seja, não abria nenhuma porta.
      A alteração que fizemos foi justamente para arrumar esse bug, por tanto, agora quando o quest ter uma chave com actionid dentro do baú, o jogador receberá essa mesma chave com o actionid definido.
       
      local specialQuests = { -- {x = 32752, y = 32343, z = 14} [52167] = Storage.DreamersChallenge.Reward, -- {x = 32806, y = 32230, z = 11} [52003] = Storage.PitsOfInferno.WeaponReward, -- {x = 32311, y = 32211, z = 8} [51400] = Storage.ThievesGuild.Reward, [51324] = Storage.WrathoftheEmperor.mainReward, -- {x = 32232, y = 31066, z = 7} [51715] = Storage.SvargrondArena.RewardGreenhorn, -- {x = 32232, y = 31059, z = 7} [51716] = Storage.SvargrondArena.RewardScrapper, -- {x = 32232, y = 31052, z = 7} [51717] = Storage.SvargrondArena.RewardWarlord } local questsExperience = { [3101] = 1 -- dummy values } local questLog = { [8213] = Storage.HiddenCityOfBeregar.DefaultStart } local tutorialIds = { [50080] = 5, [50082] = 6, [50084] = 10, [50086] = 11 } local hotaQuest = { 50950, 50951, 50952, 50953, 50954, 50955 } local questSystem1 = Action() function questSystem1.onUse(player, item, fromPosition, target, toPosition, isHotkey) local storage = specialQuests[item.actionid] if not storage then storage = item.uid if storage > 65535 then return false end end if storage == 23644 or storage == 24632 or storage == 14338 then player:setStorageValue(Storage.SvargrondArena.PitDoor, -1) end if player:getStorageValue(storage) > 0 and player:getAccountType() < ACCOUNT_TYPE_GOD then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ' .. ItemType(item.itemid):getName() .. ' is empty.') return true end local function copyContainer(originalContainer, newContainer) for i = 0, originalContainer:getSize() - 1 do local originalItem = originalContainer:getItem(i) local newItem = Game.createItem(originalItem.itemid, originalItem.type) newItem:setActionId(originalItem:getActionId()) newItem:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, originalItem:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION)) if originalItem:isContainer() then copyContainer(Container(originalItem.uid), Container(newItem.uid)) end newContainer:addItemEx(newItem) end end local items, reward = {} local size = item:isContainer() and item:getSize() or 0 if size == 0 then local actionId = item:getActionId() reward = Game.createItem(item.itemid, item.type) reward:setActionId(actionId) reward:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, item:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION)) else local container = Container(item.uid) for i = 0, container:getSize() - 1 do local originalItem = container:getItem(i) local newItem = Game.createItem(originalItem.itemid, originalItem.type) newItem:setActionId(originalItem:getActionId()) newItem:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, originalItem:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION)) if originalItem:isContainer() then copyContainer(Container(originalItem.uid), Container(newItem.uid)) end items[#items + 1] = newItem end if size == 1 then reward = items[1] end end local result = '' if reward then local ret = ItemType(reward.itemid) if ret:isRune() then result = ret:getArticle() .. ' ' .. ret:getName() .. ' (' .. reward.type .. ' charges)' elseif ret:isStackable() and reward:getCount() > 1 then result = reward:getCount() .. ' ' .. ret:getPluralName() elseif ret:getArticle() ~= '' then result = ret:getArticle() .. ' ' .. ret:getName() else result = ret:getName() end else if size > 20 then reward = Game.createItem(item.itemid, 1) elseif size > 8 then reward = Game.createItem(2854, 1) else reward = Game.createItem(2853, 1) end for i = 1, size do local tmp = items[i] if reward:addItemEx(tmp) ~= RETURNVALUE_NOERROR then Spdlog.warn("[questSystem1.onUse] - Could not add quest reward to container") end end local ret = ItemType(reward.itemid) result = ret:getArticle() .. ' ' .. ret:getName() end if player:addItemEx(reward) ~= RETURNVALUE_NOERROR then local weight = reward:getWeight() if player:getFreeCapacity() < weight then player:sendCancelMessage(string.format('You have found %s weighing %.2f oz. You have no capacity.', result, (weight / 100))) else player:sendCancelMessage('You have found ' .. result .. ', but you have no room to take it.') end return true end if questsExperience[storage] then player:addExperience(questsExperience[storage], true) end if questLog[storage] then player:setStorageValue(questLog[storage], 1) end if tutorialIds[storage] then player:sendTutorial(tutorialIds[storage]) if item.uid == 50080 then player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 3) end end if isInArray(hotaQuest, item.uid) then if player:getStorageValue(Storage.TheAncientTombs.DefaultStart) ~= 1 then player:setStorageValue(Storage.TheAncientTombs.DefaultStart, 1) end end player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found ' .. result .. '.') player:setStorageValue(storage, 1) return true end for index, value in pairs(specialQuests) do questSystem1:aid(index) end questSystem1:aid(2000) questSystem1:register()  
    • Por fezeRa
      Estou com um problema chato. Seguinte:
       
      O player pega , compra promotion, dai fica lá "Elder Druid", dai se ele reloga, ele volta pra Druid.
      Ou seja não ta salvando a vocation, é algum problema no login.lua que nao salva a vocation atual? Alguem sabe?
    • Por dolver
      E ai pessoa do TK, tudo bem com vocês?
       
      Então brothers, eu não faço a mínima ideia de como trocar as spells de uma vocation... Ai você me pergunta, porque trocar as spells de uma voc cara?
      Então brother, eu to fazendo um servidor derivado, usando uma base 8.60 e no "vocations.XML" eu não criei novas vocações, eu apenas editei as existentes da forma que eu quis, e é isso que eu pretendo fazer, editar as vocações que já existem para o servidor não ficar lotado de coisa inútil depois de pronto.
       
      Obrigado desde já gurizada, abraço!
    • Por jonei
      Olá
      Eu adicionei novas vocats no meu ot junto com um npc pra entrega-las aos players vips, PORÉM depois que eles relogam, perdem a promote, e voltam a ser oque eram. alguém pode me ajudar a resolver este problema?... obrigado.
      Vocations,xml
       
    • Por KawoBR
      Eu acho que está no lugar errado, desculpa ae, mas to com dor de cabeça disso já
       
      Em 2017 eu criei um otserv mas parei, e ontem resolvi voltar, porem para criar uma Vocation eu lembro que nao era simplesmente chegar e escrever e pronto, tinha COISA A MAIS, eu entro no vocation escrevo no ID o ID DO NEWTYPE, mas nao sei se é isso, me ajudem um PASSO A PASSO DE TUDO PARA ADICIONAR UM PERSONAGEM NOVO, COM SKIN CERTA
       
      OBS: JA COLOQUEI NO TRANSFORMAR.LUA O NEWTYPE E AI SIM FUNCIONA, A SKIN VAI CERTA QUANDO FALO TRANSFORMAR, MAS QUANDO CRIA A CONTA NAO É UMA SKIN ALEATORIA
       
      AJUDAAAAAAAAAAAAAAAAAAAAAAAAAAA
  • Estatísticas dos Fóruns

    96842
    Tópicos
    519602
    Posts
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo