Like it~*
New member
- Messages
- 175
- Points
- 0
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
Code:
EL_STONE_HAMMER,
EL_ROCK_CRUSHER,
EL_ROCK_CRUSHER_ATK,
EL_STONE_RAIN,
Depois disso, adicione
Code:
MG_EARTHBOLT = 8443,
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:
Code:
case AB_RENOVATIO:
case AB_HIGHNESSHEAL:
case AB_DUPLELIGHT_MAGIC:
case WM_METALICSOUND:
case MH_ERASER_CUTTER:
case KO_KAIHOU:
Code:
skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag);
Code:
case MG_EARTHBOLT:
Habilidades baseadas em armas
No caso de querer adicionar uma habilidade que é baseada em Arma, em vez de Magia, encontre:
Code:
case WM_GREAT_ECHO:
case GN_SLINGITEM_RANGEMELEEATK:
case KO_JYUMONJIKIRI:
case KO_SETSUDAN:
case GC_DARKCROW:
case LG_OVERBRAND_BRANDISH:
case LG_OVERBRAND:
Code:
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:
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:
Code:
case NPC_EARTHQUAKE:
skillratio += 100 +100*skill_lv +100*(skill_lv/2);
break;
Code:
case MG_EARTHBOLT:
skillratio += 50;
break;
Átaques baseado em armas
Para ataques baseados em armas, os modificadores são encontrados em battle_calc_weapon_attack. Basta encontrar:
Code:
case NPC_VAMPIRE_GIFT:
skillratio += ((skill_lv-1)%5+1)*100;
break;
Code:
case MG_EARTHBOLT:
skillratio += 50;
break;
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:
Code:
// 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
//=================================================================*/
Code:
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
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:
Code:
// 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.
//==========================================
Code:
8443,2000,1,000,0,0,0
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:
Code:
// 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
Code:
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
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
Code:
{
// ------------------------------ 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)
}
}
}
Code:
{
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:
Code:
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
}
}
Code:
MG_EARTHBOLT: {
MaxLevel: 10
MG_FIREBOLT: 5
MG_LIGHTNINGBOLT: 5
}
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:
Code:
{"MG_FIREWALL", 18; Pos = 19, MaxLv = 10, NeedSkillList = {6, 12}}
{"MG_EARTHBOLT",8443; Pos = 20, MaxLv = 10, NeedSkillList = {19,20}}
Com arquivos skillinfoz
Em skillid.lua encontre:
Code:
ECLAGE_RECALL = 3035,
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:
Code:
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
Last edited by a moderator: