Like it~* 15 Posted March 31, 2017 (edited) Criando habilidades ou clonando-as Introdução Uma grande área onde os jogadores têm dificuldade é adicionar novas habilidades para a fonte e o cliente. Abaixo será documentado como implementar essas novas habilidades. A habilidade A habilidade que estaremos trabalhando é simples. Nome: Earth Bolt Level Máx: 10 Tipo: Ativa Custo de SP: 20 + 5*SkillLV Alvo: 1 inimigo Tempo de conjuração: 2 seg Delay: 1 seg Duração: Instantânea Descrição: Causa dano mágico de elemento terra ao inimigo, conforme level da habilidade, a 150% MATK por hit. Basicamente, essa habilidade deve atingir 1 inimigo e lidar com 10 hits de 150% MATK, propriedade elemental da Terra e deve ser baseada em dano mágico. Abra /src/map/skill.h Role para baixo até encontrar EL_STONE_HAMMER, EL_ROCK_CRUSHER, EL_ROCK_CRUSHER_ATK, EL_STONE_RAIN, Depois daqui é onde nós adicionamos quaisquer habilidades adicionais. É melhor dar às habilidades um ID personalizado para começar. Então, vamos adicionar a nossa habilidade "Earth Bolt". Depois disso, adicione MG_EARTHBOLT = 8443, MG_ definição significa "Mago", você vai trabalhar para fora as siglas como você percorrer as habilidades. Definimos a base da habilidade. Como você pode ver, o id de habilidade é definido como '8443' desde Stone Elemental's Stone Rain é definido como 8442 (e é o última habilidade de jogador acessível). Abra /src/map/skill.c Esse arquivo é onde definimos as implementações de habilidades reais. Para habilidades de alvo único, todo o processamento dessa habilidade irá em skill_castend_damage_id (para habilidades prejudiciais) ou skill_castend_nodamage_id (para skills que não causam danos). Habilidades baseadas em mágica ou mágia. Como o Earth Bolt é baseado em danos, encontre a função skill_castend_damage_id e localize: case AB_RENOVATIO: case AB_HIGHNESSHEAL: case AB_DUPLELIGHT_MAGIC: case WM_METALICSOUND: case MH_ERASER_CUTTER: case KO_KAIHOU: A razão pela qual estaremos colocando a case para Earth Bolt aqui é porque: skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag); A definição BF_MAGIC significa que a habilidade é baseada em magia e deve ser calculada sob cálculos de batalha mágica. Assim, após a case NJ_HUUJIN adicionar: case MG_EARTHBOLT: Habilidades baseadas em armas No caso de querer adicionar uma habilidade que é baseada em Arma, em vez de Magia, encontre: case WM_GREAT_ECHO: case GN_SLINGITEM_RANGEMELEEATK: case KO_JYUMONJIKIRI: case KO_SETSUDAN: case GC_DARKCROW: case LG_OVERBRAND_BRANDISH: case LG_OVERBRAND: E adicione a case depois disso. Se quiséssemos que o Earth Bolt fosse baseado em armas, ficaria assim: case WM_GREAT_ECHO: case GN_SLINGITEM_RANGEMELEEATK: case KO_JYUMONJIKIRI: case KO_SETSUDAN: case GC_DARKCROW: case LG_OVERBRAND_BRANDISH: case LG_OVERBRAND: case MG_EARTHBOLT: No entanto, vamos manter a função Magic em vez disso. Abra /src/map/battle.c Nesta função, todos os cálculos de danos principais são realizados. E em funções separadas, as % modificadoras para as habilidades são armazenados. Portanto, para os nossos danos de 150%, adicionamos o extra de 50% (já que 100% é o padrão) na função apropriada. Ataques baseado em mágica Para ataques baseados em Magia, os modificadores são encontrados em battle_calc_magic_attack. Basta encontrar: case NPC_EARTHQUAKE: skillratio += 100 +100*skill_lv +100*(skill_lv/2); break; E adicione o modificador de danos abaixo. Como Earth Bolt é baseado em magia, nós adicionaremos-a aqui. case MG_EARTHBOLT: skillratio += 50; break; Isso agora significa que o Earth Bolt causará dano mágico de 150% MATK. Átaques baseado em armas Para ataques baseados em armas, os modificadores são encontrados em battle_calc_weapon_attack. Basta encontrar: case NPC_VAMPIRE_GIFT: skillratio += ((skill_lv-1)%5+1)*100; break; E adicione seu modificador de dano lá. Por exemplo, se o Earth Bolt fosse baseado em Weapon, acrescentaríamos: case MG_EARTHBOLT: skillratio += 50; break; O + = 50 significa simplesmente "Adicionar 50% ao 100%" para danos de ATK de 150%. Suporte a banco de dados de habilidades Tecnicamente falando, a base da habilidade está agora correta. Claro, se você quiser implementar habilidades mais complexas, há muito mais para isso. A seção separada será criada no futuro para isso. Mas, por enquanto, precisamos implementar as entradas do banco de dados de habilidades. Os arquivos abaixo podem ser encontrados em db / (pre / re) /. Apenas um de ambos (pre / re) precisa ser atualizado, é o qual você usa em seu servidor. Nessa parte é sempre aconselhável que você tenha alguma habilidade escolhida para se utilizar como base, pois facilitará muito a criação e/ou clonagem de sua habilidade. Aqui há diferenças, então dependendo do emulador usado, cada forma será de um jeito, caso o seu emulador seja alguns dos abaixos, continue. Caso não, pule para a parte: ** p/ Hercules. ** p/ rAthena, brAthena, Cronus. Skill_db.txt Para a nossa habilidade Earth Bolt, podemos agora digitar o seguinte: Estrutura: // ID,Alcance,Dano,Inf,Elemento,Nk,Splash,MaxLv,ListNum,CastCancel,ChanceDefCast,Inf2,MaxCount,TipoSkill,BlowCount,Nome,Descrição // 01 ID // 02 Alcance (Habilidades de combo não verificam pelo alcance // Se o alcance < 5, então a habilidade é considerada melee) // 03 Dano (8- dano repetitivo, 6- dano único) // 04 inf (0- passivo, 1- inimigo, 2- local, 4- si próprio, 16- amigo, 32- armadilha) // 05 Elemento (0 - neutro, 1 - água, 2 - terra, 3 - fogo, 4 - vento, 5 - veneno, // 6 - sagrado, 7 - sombrio, 8 - fantasma, 9 - morto-vivo, -1 - elemento da arma // -2 - elemento endowed, -3 - elemento aleatório.) // 06 nk (Propriedade de Dano das Habilidades): // 0x01 - habilidade sem dano // 0x02 - tem área visual (necessária modificação na source) // 0x04 - dano dividido entre os alvos (necessário 0x02 em ordem de trabalho) // 0x08 - habilidade ignora dano bônus dado por cartas de quem a conjura // 0x10 - habilidade ignora bônus elementais // 0x20 - habilidade ignora a defesa do alvo (tipo variado sempre ingnora) // 0x40 - habilidade ignora a esquiva do alvo (tipo mágido sempre ignora) // 0x80 - habilidade ignora defesa do alvo dada por cartas // 07 Área de efeito (-1 para wide) // 08 Nível máximo da habilidade // 09 Número de danos (Quando positivo, acresenta o dano por dano, // valores negativos apenas mostraram o número de acertos, sem aumentar os danos totais) // 10 A conjuração pode ser cancelada? // 11 Redução de defesa durante conjuração. // 12 inf2 (Informações de Habilidades 2): // 0x0001- habilidade de quest // 0x0002- habilidade de npc // 0x0004- habilidade de casamento // 0x0008- habilidade de espírito // 0x0010- habilidade de clã // 0x0020- habilidade de música // 0x0040- habilidade de dueto // 0x0080- armadilha // 0x0100- habilidade que o alvo é quem invoca // 0x0200- não pode ser usada em si próprio // 0x0400- apenas pode ser usada em membros de grupo // 0x0800- apenas pode ser usada em membros de clã // 0x1000- não pode ser usada em inimigos // 0x2000- habilidade ignora proteção terrestre (exemplo: Chuva de Flechas) // 0x4000- chorus skill // 13 maxcount: Quantidade máxima de habilidades colocadas no chão. // player_land_skill_limit/monster_land_skill_limit está ativo. Para Habilidades // que atacam usando um caminho, este é o comprimento do caminho a ser utilizado. // 14 Tipo de Ataque (nenhum, arma, magia, misc) // 15 Blowcount (amount of tiles skill knockbacks) // 16 Nome // 17 Descrição //=================================================================*/ 8443,5,8,1,2,0,0,10,1:2:3:4:5:6:7:8:9:10,yes,0,0,0,magic, 0, MG_EARTHBOLT, Earth Bolt Isso define que: Earth Bolt tem um intervalo de 5 células, bate várias vezes, é elemento da Terra e alvos 1 inimigo. Ele pode ser interrompido, e é de dano de tipo mágico. A quantidade de acessos aumenta em 1 em cada nível, com um nível máximo de 10. Skill_cast_db.txt Para a nossa habilidade Earth Bolt, podemos agora digitar o seguinte: Estrutura: // SkillID,TempoConjuracao,AfterCastActDelay,AfterCastWalkDelay,Duracao1,Duracao2,Cool Down,Tempo de Cast Fixo //== Explanando: // TempoConjuracao: Tempo para lançar esta habilidade, em milissegundos. // AfterCastActDelay: Atraso "normal",o personagem não pode usar habilidades,em milésimos de segundo. // AfterCastWalkDleay: Tempo necessário para que o personagem possa mover-se novamente, em milésimos de segundo. // Duracao1 / Duracao2: Geralmente, o tempo ultilizado pela habilidade, em alguns casos é usado para salvar dados especiais. // Cool Down: Tempo necessário até que o personagem possa voltar a usar essa habilidade, em milésimos de segundo. // Tempo de Cast Fixo: Tempo de execução das habilidades em milissegundos (quando 0, usa-se 20% do tempo de cast e menor que 0 significa que não há tempo de cast fixo) //== Extra // Em todos os campos você pode usar ":" como delimitador de valores específicos do nível, // - Exemplo usando SM_PROVOKE // - Original:6,0,0,0,30000,0,1000 // - Modificado:6,0,0,0,30000,0,1000:2500:3000:etc // - Faz no nível 1 ter 1000 (1s) cool down, lvl 2 2500 (2.5s), lvl 3 3000, e assim por diante. //========================================== 8443,2000,1,000,0,0,0 Isso define que: Earth Bolt tem um segundo tempo de ligação e um tempo de atraso de 1 segundo. Não há atraso de caminhada após o lançamento. Skill_require_db.txt Para o nosso Earth Bolt, podemos agora digitar o seguinte: Estrutura: // SkillID,HPCost,MaxHPTrigger,SPCost,HPRateCost,SPRateCost,ZenyCost,RequiredWeapons,RequiredAmmoTypes,RequiredAmmoAmount,RequiredState,SpiritSphereCost,RequiredItemID1,RequiredItemAmount1,RequiredItemID2,RequiredItemAmount2,RequiredItemID3,RequiredItemAmount3,RequiredItemID4,RequiredItemAmount4,RequiredItemID5,RequiredItemAmount5,RequiredItemID6,RequiredItemAmount6,RequiredItemID7,RequiredItemAmount7,RequiredItemID8,RequiredItemAmount8,RequiredItemID9,RequiredItemAmount9,RequiredItemID10,RequiredItemAmount10 // // 01 ID // 02 HP cost // 03 Max HP trigger // 04 SP cost // 05 HP rate // If positive, it is a percent of your current hp, otherwise it is a percent of your max hp. // 06 SP rate // If positive, it is a percent of your current sp, otherwise it is a percent of your max sp. // 07 Zeny cost // 08 Required Weapon // See doc/item_db.txt for weapon types // 99 any weapon **includes bare fists** // To include more than one weapon type use type1:type2:type3 // 09 Required Ammo // See doc/item_db.txt for ammo types // 99 any ammo type // To include more than one ammo type use type1:type2:type3 // 10 Required ammo ammount // 11 Required State // none = Nothing special // move_enable = Requires to be able to move // recover_weight_rate = Requires to be less than 50% weight // water = Requires to be standing on a water cell // cart = Requires a Pushcart // riding = Requires to ride either a peco or a dragon // falcon = Requires a Falcon // sight = Requires Sight skill activated // hiding = Requires Hiding skill activated // cloaking = Requires Cloaking skill activated // explosionspirits = Requires Fury skill activated // cartboost = Requires a Pushcart and Cart Boost skill activated // shield = Requires a 0,shield equipped // warg = Requires a Warg // dragon = Requires to ride a Dragon // ridingwarg = Requires to ride a Warg // mado = Requires to have an active mado // poisonweapon = Requires to be under Poisoning Weapon. // rollingcutter = Requires at least one Rotation Counter from Rolling Cutter. // elementalspirit = Requires to have an Elemental Spirit summoned. // mh_fighting = Requires Eleanor fighthing mode // mh_grappling = Requires Eleanor grappling mode // peco = Requires riding a peco // 12 Spirit sphere cos 8443,0,0,25: 30: 35: 40: 45: 50: 55: 60: 65: 70,0,0,0,0,0,0,0,0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Isso define que: Earth Bolt requer 25 SP no nível 1, 30 SP no nível 2 .. 70 SP no nível 10. Pode ser lançado com qualquer arma, não requer nenhum estado e não requer nenhum item para ser consumido. =========================================================================== ** p/ Hercules. Skill_db.txt { // ------------------------------ Mandatory Fields ---------------------------- Id: ID (int) (Required) Name: "Skill Name" (string) (Required) MaxLevel: Skill Level (int) (Required) // ------------------------------ Optional Fields ----------------------------- Description: "Skill Description" (string) (optional but recommended) Range: Skill Range (int) (optional, defaults to 0) (can be grouped by Levels) Note: Range < 5 is considered Melee range. Hit: Hit Type (int) (optional, default "BDT_NORMAL") Types - "BDT_SKILL", "BDT_MULTIHIT" or "BDT_NORMAL" SkillType: { (bool, defaults to "Passive") Passive: true/false (boolean, defaults to false) Enemy: true/false (boolean, defaults to false) Place: true/false (boolean, defaults to false) Self: true/false (boolean, defaults to false) Friend: true/false (boolean, defaults to false) Trap: true/false (boolean, defaults to false) } SkillInfo: { (bool, defaults to "None") Quest: true/false (boolean, defaults to false) NPC: true/false (boolean, defaults to false) Wedding: true/false (boolean, defaults to false) Spirit: true/false (boolean, defaults to false) Guild: true/false (boolean, defaults to false) Song: true/false (boolean, defaults to false) Ensemble: true/false (boolean, defaults to false) Trap: true/false (boolean, defaults to false) TargetSelf: true/false (boolean, defaults to false) NoCastSelf: true/false (boolean, defaults to false) PartyOnly: true/false (boolean, defaults to false) GuildOnly: true/false (boolean, defaults to false) NoEnemy: true/false (boolean, defaults to false) IgnoreLandProtector: true/false (boolean, defaults to false) Chorus: true/false (boolean, defaults to false) FreeCastReduced: true/false (boolean, defaults to false) Works like skill SA_FREECAST, allow move and attack with reduced speed. FreeCastNormal: true/false (boolean, defaults to false) Works like FreeCastReduced, but not reduce speed. } AttackType: "Attack Type" (string, defaults to "None") Types: "None", "Weapon", "Magic" or "Misc" Element: "Element Type" (string) (Optional field - Default "Ele_Neutral") (can be grouped by Levels) Types: "Ele_Neutral", "Ele_Water", "Ele_Earth", "Ele_Fire", "Ele_Wind" "Ele_Poison", "Ele_Holy", "Ele_Dark", "Ele_Ghost", "Ele_Undead" "Ele_Weapon" - Uses weapon's element. "Ele_Endowed" - Uses Endowed element. "Ele_Random" - Uses random element. DamageType: { (bool, default to "NoDamage") NoDamage: true/false No damage skill SplashArea: true/false Has splash area (requires source modification) SplitDamage: true/false Damage should be split among targets (requires 'SplashArea' in order to work) IgnoreCards: true/false Skill ignores caster's % damage cards (misc type always ignores) IgnoreElement: true/false Skill ignores elemental adjustments IgnoreDefense: true/false Skill ignores target's defense (misc type always ignores) IgnoreFlee: true/false Skill ignores target's flee (magic type always ignores) IgnoreDefCards: true/false Skill ignores target's def cards } SplashRange: Damage Splash Area (int, defaults to 0) (can be grouped by Levels) Note: -1 for screen-wide. NumberOfHits: Number of Hits (int, defaults to 1) (can be grouped by Levels) Note: when positive, damage is increased by hits, negative values just show number of hits without increasing total damage. InterruptCast: Cast Interruption (bool, defaults to false) CastDefRate: Cast Defense Reduction (int, defaults to 0) SkillInstances: Skill instances (int, defaults to 0) (can be grouped by Levels) Notes: max amount of skill instances to place on the ground when player_land_skill_limit/monster_land_skill_limit is enabled. For skills that attack using a path, this is the path length to be used. KnockBackTiles: Knock-back by 'n' Tiles (int, defaults to 0) (can be grouped by Levels) CastTime: Skill cast Time (in ms) (int, defaults to 0) (can be grouped by Levels) AfterCastActDelay: Skill Delay (in ms) (int, defaults to 0) (can be grouped by Levels) AfterCastWalkDelay: Walk Delay (in ms) (int, defaults to 0) (can be grouped by Levels) SkillData1: Skill Data/Duration (in ms) (int, defaults to 0) (can be grouped by Levels) SkillData2: Skill Data/Duration (in ms) (int, defaults to 0) (can be grouped by Levels) CoolDown: Skill Cooldown (in ms) (int, defaults to 0) (can be grouped by Levels) FixedCastTime: Fixed Cast Time (in ms) (int, defaults to 0) (can be grouped by Levels) Note: when 0, uses 20% of cast time and less than 0 means no fixed cast time. CastTimeOptions: { IgnoreDex: true/false (boolean, defaults to false) IgnoreStatusEffect: true/false (boolean, defaults to false) IgnoreItemBonus: true/false (boolean, defaults to false) Note: Delay setting 'IgnoreDex' only makes sense when delay_dependon_dex is enabled. } SkillDelayOptions: { IgnoreDex: true/false (boolean, defaults to false) IgnoreStatusEffect: true/false (boolean, defaults to false) IgnoreItemBonus: true/false (boolean, defaults to false) Note: Delay setting 'IgnoreDex' only makes sense when delay_dependon_dex is enabled. } Requirements: { HPCost: HP Cost (int, defaults to 0) (can be grouped by Levels) SPCost: SP Cost (int, defaults to 0) (can be grouped by Levels) HPRateCost: HP % Cost (int, defaults to 0) (can be grouped by Levels) Note: If positive, it is a percent of your current hp, otherwise it is a percent of your max hp. SPRateCost: SP % Cost (int, defaults to 0) (can be grouped by Levels) Note: If positive, it is a percent of your current sp, otherwise it is a percent of your max sp. ZenyCost: Zeny Cost (int, defaults to 0) (can be grouped by Levels) WeaponTypes: { (bool or string, defaults to "All") NoWeapon: true/false (boolean, defaults to false) Daggers: true/false (boolean, defaults to false) 1HSwords: true/false (boolean, defaults to false) 2HSwords: true/false (boolean, defaults to false) 1HSpears: true/false (boolean, defaults to false) 2HSpears: true/false (boolean, defaults to false) 1HAxes: true/false (boolean, defaults to false) 2HAxes: true/false (boolean, defaults to false) Maces: true/false (boolean, defaults to false) 2HMaces: true/false (boolean, defaults to false) Staves: true/false (boolean, defaults to false) Bows: true/false (boolean, defaults to false) Knuckles: true/false (boolean, defaults to false) Instruments: true/false (boolean, defaults to false) Whips: true/false (boolean, defaults to false) Books: true/false (boolean, defaults to false) Katars: true/false (boolean, defaults to false) Revolvers: true/false (boolean, defaults to false) Rifles: true/false (boolean, defaults to false) GatlingGuns: true/false (boolean, defaults to false) Shotguns: true/false (boolean, defaults to false) GrenadeLaunchers: true/false (boolean, defaults to false) FuumaShurikens: true/false (boolean, defaults to false) 2HStaves: true/false (boolean, defaults to false) MaxSingleWeaponType: true/false (boolean, defaults to false) DWDaggers: true/false (boolean, defaults to false) DWSwords: true/false (boolean, defaults to false) DWAxes: true/false (boolean, defaults to false) DWDaggerSword: true/false (boolean, defaults to false) DWDaggerAxe: true/false (boolean, defaults to false) DWSwordAxe: true/false (boolean, defaults to false) } AmmoTypes: { (for all types use string "All") A_ARROW: true/false (boolean, defaults to false) A_DAGGER: true/false (boolean, defaults to false) A_BULLET: true/false (boolean, defaults to false) A_SHELL: true/false (boolean, defaults to false) A_GRENADE: true/false (boolean, defaults to false) A_SHURIKEN: true/false (boolean, defaults to false) A_KUNAI: true/false (boolean, defaults to false) A_CANNONBALL: true/false (boolean, defaults to false) A_THROWWEAPON: true/false (boolean, defaults to false) } AmmoAmount: Ammunition Amount (int, defaults to 0) (can be grouped by Levels) State: "Required State" (string, defaults to "None") (can be grouped by Levels) Types : 'None' = Nothing special 'Moveable' = Requires to be able to move 'NotOverWeight' = Requires to be less than 50% weight 'InWater' = Requires to be standing on a water cell 'Cart' = Requires a Pushcart 'Riding' = Requires to ride either a peco or a dragon 'Falcon' = Requires a Falcon 'Sight' = Requires Sight skill activated 'Hiding' = Requires Hiding skill activated 'Cloaking' = Requires Cloaking skill activated 'ExplosionSpirits' = Requires Fury skill activated 'CartBoost' = Requires a Pushcart and Cart Boost skill activated 'Shield' = Requires a 0,shield equipped 'Warg' = Requires a Warg 'Dragon' = Requires to ride a Dragon 'RidingWarg' = Requires to ride a Warg 'Mado' = Requires to have an active mado 'PoisonWeapon' = Requires to be under Poisoning Weapon. 'RollingCutter' = Requires at least one Rotation Counter from Rolling Cutter. 'ElementalSpirit' = Requires to have an Elemental Spirit summoned. 'MH_Fighting' = Requires Eleanor fighthing mode 'MH_Grappling' = Requires Eleanor grappling mode 'Peco' = Requires riding a peco SpiritSphereCost: Spirit Sphere Cost (int, defaults to 0) (can be grouped by Levels) Items: { ItemID or Aegis_Name : Amount (int, defaults to 0) (can be grouped by Levels) Item example: "ID717" or "Blue_Gemstone". Notes: Items with amount 0 will not be consumed. Amount can also be grouped by levels. } } Unit: { Id: [ UnitID, UnitID2 ] (int, defaults to 0) (can be grouped by Levels) Layout: Unit Layout (int, defaults to 0) (can be grouped by Levels) Range: Unit Range (int, defaults to 0) (can be grouped by Levels) Interval: Unit Interval (int, defaults to 0) (can be grouped by Levels) Target: "Unit Target" (string, defaults to "None") Types: All - affects everyone NotEnemy - affects anyone who isn't an enemy Friend - affects party, guildmates and neutral players Party - affects party only Guild - affects guild only Ally - affects party and guildmates only Sameguild - affects guild but not allies Enemy - affects enemies only None - affects nobody Flag: { UF_DEFNOTENEMY: true/false (boolean, defaults to false) UF_NOREITERATION: true/false (boolean, defaults to false) UF_NOFOOTSET: true/false (boolean, defaults to false) UF_NOOVERLAP: true/false (boolean, defaults to false) UF_PATHCHECK: true/false (boolean, defaults to false) UF_NOPC: true/false (boolean, defaults to false) UF_NOMOB: true/false (boolean, defaults to false) UF_SKILL: true/false (boolean, defaults to false) UF_DANCE: true/false (boolean, defaults to false) UF_ENSEMBLE: true/false (boolean, defaults to false) UF_SONG: true/false (boolean, defaults to false) UF_DUALMODE: true/false (boolean, defaults to false) UF_RANGEDSINGLEUNI: true/false (boolean, defaults to false) } } } { Id: 8443 Name: "MG_EARTHBOLT" Description: "Earth Bolt" MaxLevel: 10 Range: 9 Hit: "BDT_MULTIHIT" SkillType: { Enemy: true } } AttackType: "Magic" Element: "Ele_Earth" NumberOfHits: { Lv1: 1 Lv2: 2 Lv3: 3 Lv4: 4 Lv5: 5 Lv6: 6 Lv7: 7 Lv8: 8 Lv9: 9 Lv10: 10 } InterruptCast: true CastTime: { Lv1: 640 Lv2: 960 Lv3: 1280 Lv4: 1600 Lv5: 1920 Lv6: 2100 Lv7: 1560 Lv8: 2880 Lv9: 3200 Lv10: 3520 } AfterCastActDelay: { Lv1: 1000 Lv2: 1200 Lv3: 1400 Lv4: 1600 Lv5: 1800 Lv6: 2000 Lv7: 2200 Lv8: 2400 Lv9: 2600 Lv10: 2800 } FixedCastTime: { Lv1: 160 Lv2: 240 Lv3: 320 Lv4: 400 Lv5: 480 Lv6: 700 Lv7: 640 Lv8: 720 Lv9: 800 Lv10: 880 } Requirements: { SPCost: { Lv1: 25 Lv2: 50 Lv3: 75 Lv4: 100 Lv5: 125 Lv6: 150 Lv7: 175 Lv8: 200 Lv9: 225 Lv10: 250 } } }, =========================================================================== Skill_tree.txt Esta parte do banco de dados não é necessária se não for lida por uma classe. No entanto, se você quiser que uma classe aprenda uma habilidade, você deve fazer uma entrada em skill_tree.txt. Um exemplo abaixo: Job_Name: { // Job names as in src/map/pc.c (they are hardcoded at the moment so if you want to add a new job you should add it there) inherit: ( "Other_Job_Name" ); // Base job from which this job will inherit its skill tree. NV_TRICKDEAD inheritance is skipped for non-novices from the source skills: { // SKILL_NAMEs come from the Name (16th column) value in db/re/skill_db.txt SKILL_NAME1: Max_Level // Use this for skills that don't have other skill prerequisite; Max_Level is a numeric value that should match your client side files SKILL_NAME2: { // Use this for skills which have other skills as prerequisites MaxLevel: Max_Level // Max_Level is a numeric value that should match your client side files SKILL_NAME_PREREQUISITE: Level_Prerequisite // The prerequisite skill and min level for having this skill available. Should also match your client side files SKILL_NAME_PREREQUISITE2: Level_Prerequisite2 // You can add as many prerequisite skills as you want. Minimum of 1 if you add a skill this way } } MG_EARTHBOLT: { MaxLevel: 10 MG_FIREBOLT: 5 MG_LIGHTNINGBOLT: 5 } Isso define que: Earth Bolt pode ser aprendido por Mago, tem um nível máximo de 10 (para esta classe), e requer habilidade MG_FIREBOLT no nível 5 e habilidade MG_LIGHTNINGBOLT no nível 5. Tecnicamente, estas são as partes geralmente utilizas com arquivos de banco de dados de habilidade. Há mais, mas isso ficará pra vocês explorarem. Arquivos .lua e .lub As seguintes implementações estão de acordo com a Revisão 228 do Projeto Lua (2012-05-23). A implementação é diferente entre muitas versões de cliente, mas geralmente há 2 implementações: Sem arquivos skillinfoz Em data/lua files/skillinfo/skilltreeview.lua encontre: {"MG_FIREWALL", 18; Pos = 19, MaxLv = 10, NeedSkillList = {6, 12}} Adicione a baixo: {"MG_EARTHBOLT",8443; Pos = 20, MaxLv = 10, NeedSkillList = {19,20}} Com arquivos skillinfoz Em skillid.lua encontre: ECLAGE_RECALL = 3035, Depois adicione: MG_EARTHBOLT = 8443, in data/lua files/skillinfo/skilldescript.lua localize: [SKID.MG_THUNDERSTORM] = { "Thunder Storm", "Max Level:^777777 10 ^000000", "Type:^777777 Offensive ^000000", "SP Cost:^777777 24 + 5*SkillLV ^000000", "Target:^777777 cell ^000000", "Range:^777777 9 cells ^000000", "Cast Time:^777777 1*SkillLV sec ^000000", "Cool Down:^777777 2 sec ^000000", "Duration:^777777 0.2*SkillLV sec ^000000", "Effect:^777777 Hits every Enemy in a 5x5 area around the targeted cell with 1 Wind Element Bolt per level at a rate of 1 bolt every 0.2 seconds. Each bolt does 0.8*MATK Wind element damage. ^000000", "[LV 1]^777777 1 Bolt ^000000", "[LV 2]^777777 2 Bolts ^000000", "[LV 3]^777777 3 Bolts ^000000", "[LV 4]^777777 4 Bolts ^000000", "[LV 5]^777777 5 Bolts ^000000", "[LV 6]^777777 6 Bolts ^000000", "[LV 7]^777777 7 Bolts ^000000", "[LV 8]^777777 8 Bolts ^000000", "[LV 9]^777777 9 Bolts ^000000", "[LV 10]^777777 10 Bolts ^000000", }, Depois adicione: [SKID.MG_EARTHBOLT] = { "Earth Bolt", "Max Level:^777777 10 ^000000" "Type:^77777 Active ^000000" "SP Cost:^777777 20 + 5*SkillLV ^000000" "Target:^777777 1 Enemy ^000000" "Cast Time:^777777 2 sec ^000000" "Cool Down:^777777 1 sec ^000000" "Duration:^777777 Instant ^000000" "Effect: ^777777 Deals SkillLV bolts of Earth magic damage to one enemy, at 150% MATK per hit.^000000", }, skilltreeview.lua mude: [JOBID.JT_MAGICIAN] = { [1] = SKID.MG_STONECURSE, [2] = SKID.MG_COLDBOLT, [3] = SKID.MG_LIGHTNINGBOLT, [4] = SKID.MG_NAPALMBEAT, [5] = SKID.MG_FIREBOLT, [6] = SKID.MG_SIGHT, [8] = SKID.MG_SRECOVERY, [9] = SKID.MG_FROSTDIVER, [10] = SKID.MG_THUNDERSTORM, [11] = SKID.MG_SOULSTRIKE, [12] = SKID.MG_FIREBALL, [13] = SKID.MG_ENERGYCOAT, [18] = SKID.MG_SAFETYWALL, [19] = SKID.MG_FIREWALL }, para: [JOBID.JT_MAGICIAN] = { [1] = SKID.MG_STONECURSE, [2] = SKID.MG_COLDBOLT, [3] = SKID.MG_LIGHTNINGBOLT, [4] = SKID.MG_NAPALMBEAT, [5] = SKID.MG_FIREBOLT, [6] = SKID.MG_SIGHT, [8] = SKID.MG_SRECOVERY, [9] = SKID.MG_FROSTDIVER, [10] = SKID.MG_THUNDERSTORM, [11] = SKID.MG_SOULSTRIKE, [12] = SKID.MG_FIREBALL, [13] = SKID.MG_ENERGYCOAT, [18] = SKID.MG_SAFETYWALL, [19] = SKID.MG_FIREWALL, [20] = SKID.MG_EARTHBOLT }, skillinfolist.lua Mude: [SKID.ECL_SEQUOIADUST] = { "ECL_SEQUOIADUST"; SkillName = "Sequoia Dust", MaxLv = 1, SpAmount = { 0 }, bSeperateLv = false, AttackRange = { 7 }, } Para: [SKID.ECL_SEQUOIADUST] = { "ECL_SEQUOIADUST"; SkillName = "Sequoia Dust", MaxLv = 1, SpAmount = { 0 }, bSeperateLv = false, AttackRange = { 7 }, }, [SKID.MG_EARTHBOLT] = { "MG_EARTHBOLT"; SkillName = "Earth Bolt", MaxLv = 10, SpAmount = { 25, 30, 35, 40, 45, 50, 55, 60, 65, 70 }, _NeedSkillList = { { SKID.MG_FIREBOLT, 5}, { SKID.MG_LIGHTNINGBOLT, 5} } Finalizando Não se esqueça que você precisará de adicionar o arquivo Sprite e BMP apropriado para a habilidade. Use o nome MG_EARTHBOLT como o nome do arquivo em: data\texture\À¯ÀúÀÎÅÍÆäÀ̽º\item data\sprite\¾ÆÀÌÅÛ Efeitos Vá a src/map/skill.h, Procure a skill que deseja adicionar/editar o efeito: case WE_BABY: if(sd) { struct map_session_data *f_sd = pc->get_father(sd); struct map_session_data *m_sd = pc->get_mother(sd); bool we_baby_parents = false; if(m_sd && check_distance_bl(bl,&m_sd->bl,AREA_SIZE)) { sc_start(src,&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); clif->specialeffect(&m_sd->bl,408,AREA); we_baby_parents = true; } Aqui está sendo utilizado como exemplo a habilidade de convocação das classes bebês. Onde 408 é o efeito adicionado para que seja mostrado ao utilizar a skill. Para a sua habilidade customizada, como ela é uma habilidade nova, não há nenhum efeito, então você terá que adicioná-lo ao arquivo, seguindo de exemplo a mesma forma mostrada acima. Para saber a lista de todos os efeitos, basta utilizar doc/effect_list.txt. Fontes e créditos https://github.com/HerculesWS/ https://github.com/Cronus-Emulator/ https://github.com/brAthena/ https://github.com/rAthena/ http://forum.cronus-emulator.com/ https://forum.brathena.org/ http://herc.ws/wiki/Adding_new_skills http://herc.ws/ https://google.com/ Comentários Decidi fazer esse tutorial pois percebi que ainda não há nenhum guia com esse assunto em PT-BR e havia uma grande demanda de pessoas procurando. Tinha dado uma olhada no Hercules e percebi que é um bom tutorial, mas ainda estava incompleto e bem desatualizado, então decidi usa-lo como base e também pensei, por que não criar um? Espero que esteja de boa compreensão, caso estiver faltando algo que eu esqueci ou que eu não saiba, por favor me informe para torná-lo o melhor possível. Estou aberto a sugestões e críticas construtivas. Façam um bom proveito Edited March 31, 2017 by Like it~* 9 Senos, Ragno, Fou-lu and 6 others reacted to this Quote Share this post Link to post Share on other sites
JulioCF 105 Posted April 5, 2017 Obrigado pela contribuição! Quote Share this post Link to post Share on other sites
Senos 54 Posted April 8, 2017 Bem legal, parabéns Quote Share this post Link to post Share on other sites
fxfreitas 102 Posted April 8, 2017 +1 Hercules e BrA agradecem. Quote Share this post Link to post Share on other sites