Converted the skill database to YAML (#4531)
* Combines skill_cast_db, skill_castnodex_db, skill_copyable_db, skill_nonearnpc_db, skill_require_db, and skill_unit_db into skill_db. * Introduces a cached YAML class for quicker lookups. * General cleanups and optimizations. * Includes CSV2YAML conversion tool. Thanks to @Lemongrass3110! Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
parent
de9f667d2f
commit
dca3797d44
@ -1,18 +0,0 @@
|
||||
// Skill Times Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// SkillID,CastingTime,AfterCastActDelay,AfterCastWalkDelay,Duration1,Duration2,Cool Down,Fixed Casting Time
|
||||
//
|
||||
// CastingTime: time to cast this skill, in miliseconds
|
||||
// AfterCastActDelay: "normal" delay, character cannot use skills, in miliseconds
|
||||
// AfterCastWalkDleay: amount of time before character can move again, in miliseconds
|
||||
// Duration1/Duration2: usually the durations used by the skill, at special cases it is used to hold special data
|
||||
// Cool Down: amount of time until character can re-use this skill, in miliseconds
|
||||
// Fixed Casting Time: the skills fixed casting time (when 0, uses 20% of cast time and less than 0 means no fixed cast time)
|
||||
//
|
||||
// On all fields you can use ':' as a delimiter for level-specific values.
|
||||
// For example:
|
||||
// - Original: 6,0,0,0,30000,0,1000
|
||||
// - Modified: 6,0,0,0,30000,0,1000:2500:3000:...
|
||||
// Gives Level 1 1000ms cool down, Level 2 2500ms, Level 3 3000ms, and so on.
|
||||
|
@ -1,16 +0,0 @@
|
||||
// <Skill id>,<Cast>,<Delay (optional)>
|
||||
//
|
||||
// Cast: 0 - everything affects the skill's cast time
|
||||
// 1 - skill's cast time is not affected by dex
|
||||
// 2 - skill's cast time is not affected by statuses (Suffragium, etc)
|
||||
// 4 - skill's cast time is not affected by item bonuses (equip, cards)
|
||||
//
|
||||
// Delay: 0 - everything affects the skill's delay
|
||||
// 1 - skill's delay is not affected by dex
|
||||
// 2 - skill's delay is not affected by Magic Strings / Bragi
|
||||
// 4 - skill's delay is not affected by item bonuses (equip, cards)
|
||||
//
|
||||
// Note: Values are bit fields, add them up to combine their effects.
|
||||
// Note: Delay setting '1' only makes sense when delay_dependon_dex is enabled.
|
||||
// Example: 46,1,1 = Double Strafe's cast time and delay is not affected by dex.
|
||||
|
@ -1,52 +0,0 @@
|
||||
// Copyable Skills Database
|
||||
// List of skills able to be copied by Intimidate/Plagiarism and Reproduce.
|
||||
//
|
||||
// Sources:
|
||||
// http://irowiki.org/wiki/Intimidate
|
||||
// -> "Intimidate will copy any 2nd class skill"
|
||||
// http://irowiki.org/wiki/Reproduce/List_of_reproducible_skills
|
||||
// -> "Players can reproduce 1-x, 2-x, and 3-x skills and Expanded Class,
|
||||
// but cannot reproduce transcendent skills"
|
||||
//
|
||||
// Structure of Database:
|
||||
// SkillName,Option{,JobAllowed{,RequirementRemoved}}
|
||||
//
|
||||
// Option (bitmask) determines how a skill can be copied.
|
||||
// 1 = Plagiarism
|
||||
// 2 = Reproduce
|
||||
//
|
||||
// JobAllowed (bitmask) restricts copying the skill to certain classes.
|
||||
// By default, all jobs can copy the skill (0).
|
||||
// 1 = Rogue
|
||||
// 2 = Stalker
|
||||
// 4 = Shadow Chaser
|
||||
// 8 = Trans. Shadow Chaser
|
||||
// 16 = Baby Rouge
|
||||
// 32 = Baby Shadow Chaser
|
||||
//
|
||||
// RequirementRemoved (bitmask) removes requirements when casting a copied skill.
|
||||
// See 'skill_require_db.txt' for specific skill requirements.
|
||||
// 0 = uses original requirement(s)
|
||||
// 1 = hp
|
||||
// 2 = maxhptrigger
|
||||
// 4 = sp
|
||||
// 8 = hprate
|
||||
// 16 = sprate
|
||||
// 32 = zeny
|
||||
// 64 = weapon type
|
||||
// 128 = ammo (with the amount)
|
||||
// 256 = state
|
||||
// 512 = statuses
|
||||
// 1024 = spirit sphere
|
||||
// 2048 = items (with the amount)
|
||||
// 4096 = equipments
|
||||
//
|
||||
// Examples:
|
||||
// AS_SONICBLOW,2,63,64
|
||||
// Sonic Blow can be copied by all jobs with only Plagiarism.
|
||||
// To use the copied skill, a Katar is not needed (a Sonic Blow weapon type requirement).
|
||||
//
|
||||
// CR_ACIDDEMONSTRATION,3,10
|
||||
// Acid Demonstration can only be copied by Stalker/Trans. Shadow Chaser with Plagiarism or Reproduce.
|
||||
// This mode simulates the previous battle config, which allowed only Trans. classes to copy Trans. skills.
|
||||
|
@ -1,79 +0,0 @@
|
||||
//id,range,hit,inf,element,nk,splash,max,list_num,castcancel,cast_defence_rate,inf2,maxcount,skill_type,blow_count,inf3,name,description
|
||||
// 01 ID
|
||||
// 02 range (combo skills do not check for range when used,
|
||||
// if range is < 5, the skill is considered melee-range)
|
||||
// 03 hit (8- repeated hitting, 6- single-hit)
|
||||
// 04 inf (0- passive, 1- enemy, 2- place, 4- self, 16- friend, 32- trap)
|
||||
// 05 element (0 - neutral, 1 - water, 2 - earth, 3 - fire, 4 - wind, 5 - poison,
|
||||
// 6 - holy, 7 - dark, 8 - ghost, 9 - undead, -1 - use weapon element
|
||||
// -2 - use endowed element, -3 - use random element.)
|
||||
// 06 nk (skill damage properties):
|
||||
// 0x01 - No damage skill
|
||||
// 0x02 - Has splash area
|
||||
// 0x04 - Damage should be split among targets
|
||||
// 0x08 - Skill ignores caster's % damage cards (misc type always ignores)
|
||||
// 0x10 - Skill ignores elemental adjustments
|
||||
// 0x20 - Skill ignores target's defense (misc type always ignores)
|
||||
// 0x40 - Skill ignores target's flee (magic type always ignores)
|
||||
// 0x80 - Skill ignores target's def cards
|
||||
// 07 splash/effect range
|
||||
// -1 - for screen-wide
|
||||
// 0 - no splash
|
||||
// all other values follow the formula: value * 2 + 1
|
||||
// 1 - 3x3
|
||||
// 2 - 5x5
|
||||
// 3 - 7x7
|
||||
// 08 MaxLv
|
||||
// 09 Number of hits (when positive, damage is increased by hits,
|
||||
// negative values just show number of hits without increasing total damage)
|
||||
// 10 Cast interrupted when hit?
|
||||
// 11 defense-reduction rate during cast.
|
||||
// 12 inf2 (skill information 2):
|
||||
// 0x00001 - quest skill
|
||||
// 0x00002 - npc skill
|
||||
// 0x00004 - wedding skill
|
||||
// 0x00008 - spirit skill
|
||||
// 0x00010 - guild skill
|
||||
// 0x00020 - song/dance
|
||||
// 0x00040 - ensemble skill
|
||||
// 0x00080 - trap
|
||||
// 0x00100 - skill that damages/targets yourself
|
||||
// 0x00200 - cannot be casted on self (if inf = 4, auto-select target skill)
|
||||
// 0x00400 - usable only on party-members (and enemies if skill is offensive)
|
||||
// 0x00800 - usable only on guild-mates (and enemies if skill is offensive)
|
||||
// 0x01000 - disable usage on enemies (for non-offensive skills).
|
||||
// 0x02000 - available skill for SC_AUTOSHADOWSPELL
|
||||
// 0x04000 - chorus skill
|
||||
// 0x08000 - skill that ignore bg reduction
|
||||
// 0x10000 - skill that ignore gvg reduction
|
||||
// 0x20000 - makes 'self'/'place' skill cannot be casted/placed when near NPC (see 'db/skill_nonearnpc_db.txt' for more options)
|
||||
// 0x40000 - skill that can hit trap-type skill (inf2 has 0x00080)
|
||||
// 13 maxcount: 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.
|
||||
// 14 attack type (none, weapon, magic, misc)
|
||||
// 15 Blowcount (amount of tiles skill knockbacks)
|
||||
// 16 inf3 (skill information 3):
|
||||
// 0x00001 - skill ignores land protector
|
||||
// 0x00002 - free
|
||||
// 0x00004 - usable skills while hiding
|
||||
// 0x00008 - skill that can be use while in dancing state
|
||||
// 0x00010 - skill that could hit emperium
|
||||
// 0x00020 - skill ignores SC_STASIS
|
||||
// 0x00040 - skill blocked by kagehumi
|
||||
// 0x00080 - skill range affected by AC_VULTURE
|
||||
// 0x00100 - skill range affected by GS_SNAKEEYE
|
||||
// 0x00200 - skill range affected by NJ_SHADOWJUMP
|
||||
// 0x00400 - skill range affected by WL_RADIUS
|
||||
// 0x00800 - skill range affected by RA_RESEARCHTRAP
|
||||
// 0x01000 - skill that does not affect user that has NC_HOVERING active
|
||||
// 0x02000 - skill that can be using while riding warg
|
||||
// 0x04000 - skill that can be used while on Madogear
|
||||
// 0x08000 - skill that can be used to target while under SC__MANHOLE effect
|
||||
// 0x10000 - skill that affects hidden targets
|
||||
// 0x20000 - skill that affects SC_GLOOMYDAY_SK
|
||||
// 0x40000 - skill that is affected by SC_DANCEWITHWUG
|
||||
// 0x80000 - skill blocked by RA_WUGBITE
|
||||
// 17 Name
|
||||
// 18 Description
|
||||
|
132
db/import-tmpl/skill_db.yml
Normal file
132
db/import-tmpl/skill_db.yml
Normal file
@ -0,0 +1,132 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2019 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Skill Database
|
||||
###########################################################################
|
||||
#
|
||||
# Skill Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Unique skill ID.
|
||||
# Name Skill Aegis name.
|
||||
# Description Skill description.
|
||||
# MaxLevel Max skill level.
|
||||
# Type Skill type. (Default: None)
|
||||
# TargetType Skill target type. (Default: Passive)
|
||||
# DamageFlags: Skill damage properties.
|
||||
# Flags: Skill information flags.
|
||||
# Range: Skill range. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Range at specific skill level.
|
||||
# Hit Skill hit type. (Default: Normal)
|
||||
# HitCount: Skill hit count. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Count Number of hits at specific skill level.
|
||||
# Element: Skill element. (Default: Neutral)
|
||||
# - Level Skill level.
|
||||
# Element Element at specific skill level.
|
||||
# SplashArea: Skill splash area of effect. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Area Splash area at specific skill level.
|
||||
# ActiveInstance: Maximum amount of active skill instances that can be on the ground. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Max Active instances at specific skill level.
|
||||
# Knockback: Amount of tiles the skill knockbacks. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Knockback count at specific skill level.
|
||||
# CopyFlags: Determines if the skill is copyable. (Optional)
|
||||
# Skill: Type of skill that can copy.
|
||||
# RemoveRequirement: Remove a requirement type. (Optional)
|
||||
# NoNearNPC: Determines if the skill can be used near a NPC. (Optional)
|
||||
# AdditionalRange Number of cells from an NPC where the skill can be cast. (Optional)
|
||||
# Type: Type of NPC.
|
||||
# CastCancel Cancel cast when hit. (Default: true)
|
||||
# CastDefenseReduction Defense reduction rate during skill cast. (Default: 0)
|
||||
# CastTime: Time to cast the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Cast time at specific skill level in milliseconds.
|
||||
# AfterCastActDelay: Time the character cannot use skills in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast action delay at specific skill level in milliseconds.
|
||||
# AfterCastWalkDelay: Time before the character can move again in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast walk delay at specific skill level in milliseconds.
|
||||
# Duration1: Duration of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Skill duration at specific skill level in milliseconds.
|
||||
# Duration2: Duration of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Skill duration at specific skill level in milliseconds.
|
||||
# Cooldown: Time before the character can use the same skill again in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Cooldown at specific skill level in milliseconds.
|
||||
# FixedCastTime: Time that is fixed during cast of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast action delay at specific skill level in milliseconds.
|
||||
# CastTimeFlags: Effects of the skill's cast time. (Optional)
|
||||
# CastDelayFlags: Effects of the skill's delay. (Optional)
|
||||
# Requires: List of requirements to cast the skill. (Optional)
|
||||
# HpCost: HP required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount HP required at specific skill level.
|
||||
# SpCost: SP required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount SP required at specific skill level.
|
||||
# HpRateCost: HP rate required to cast. If positive, uses current HP, else uses Max HP. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount HP rate required at specific skill level.
|
||||
# SpRateCost: SP rate required to cast. If positive, uses current SP, else uses Max SP. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount SP rate required at specific skill level.
|
||||
# MaxHpTrigger: Maximum amount of HP to cast the skill. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Maximum HP trigger required at specific skill level.
|
||||
# ZenyCost: Zeny required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Zeny required at specific skill level.
|
||||
# Weapon: Weapon required to cast. (Default: All)
|
||||
# Ammo: Ammo required to cast. (Default: None)
|
||||
# AmmoAmount: Ammo amount required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Ammo amount required at specific skill level.
|
||||
# State Special state required to cast. (Default: None)
|
||||
# Status: Status change required to cast. (Default: nullptr)
|
||||
# SphereCost: Spirit sphere required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Spirit sphere required at specific skill level.
|
||||
# ItemCost: Item required to cast. (Default: 0)
|
||||
# - Item Item name.
|
||||
# Amount Item amount.
|
||||
# Equipment: Equipped item required to cast. (Default: nullptr)
|
||||
# Unit: Skill unit values. (Optional)
|
||||
# Id Skill unit ID.
|
||||
# AlternateId: Alternate skill unit ID. (Default: 0)
|
||||
# Layout: Skill unit layout. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Unit layout at specific skill level.
|
||||
# Range: Skill unit range. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Unit range at specific skill level.
|
||||
# Interval Skill unit interval in milliseconds. (Default: 0)
|
||||
# Target Skill unit target type. (Default: All)
|
||||
# Flag: Skill unit flags. (Default: None)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: SKILL_DB
|
||||
Version: 1
|
@ -1,28 +0,0 @@
|
||||
// Skill Distance-to-NPC Database
|
||||
// Prevents skills from being used near NPC types using INF2_NO_NEARNPC.
|
||||
//
|
||||
// Structure of Database:
|
||||
// SkillName,AdditionalRange{,NPC Type}
|
||||
//
|
||||
// AdditionalRange:
|
||||
// Number of cells from an NPC where the skill can be cast.
|
||||
// If zero, this will read the splash range value from skill_db;
|
||||
// if that is also zero, range+layout's range from skill_unit_db will be used.
|
||||
//
|
||||
// NPC Type (bitmask):
|
||||
// 1 = warp portal, 2 = shop NPC, 4 = normal NPC script, 8 = tomb
|
||||
//
|
||||
// Examples:
|
||||
// MG_SAFETYWALL,2
|
||||
// Safety Wall can't be placed within 2 ground cells of an NPC.
|
||||
// (MG_SAFETYWALL doesn't have splash, layout range, and range value,
|
||||
// so we must add the 'additional_range', or it will be pointless.)
|
||||
//
|
||||
// GS_DESPERADO,2
|
||||
// Desperado can't be casted if the caster is standing within 5 cells of an NPC.
|
||||
// (Why? GS_DESPERADO has 3 cells of splash range +2 'additional_range' here.)
|
||||
//
|
||||
// SC_CHAOSPANIC,0,1
|
||||
// Chaos Panic can't be placed within 2 ground cells of a warp portal.
|
||||
// (Because SC_CHAOSPANIC doesn't have splash range, it uses layout range.)
|
||||
|
@ -1,33 +0,0 @@
|
||||
// Skill Requirements Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// SkillID,HPCost,MaxHPTrigger,SPCost,HPRateCost,SPRateCost,ZenyCost,RequiredWeapons,RequiredAmmoTypes,RequiredAmmoAmount,RequiredState,RequiredStatuses,SpiritSphereCost,RequiredItemID1,RequiredItemAmount1,RequiredItemID2,RequiredItemAmount2,RequiredItemID3,RequiredItemAmount3,RequiredItemID4,RequiredItemAmount4,RequiredItemID5,RequiredItemAmount5,RequiredItemID6,RequiredItemAmount6,RequiredItemID7,RequiredItemAmount7,RequiredItemID8,RequiredItemAmount8,RequiredItemID9,RequiredItemAmount9,RequiredItemID10,RequiredItemAmount10,RequiredEquipment
|
||||
//
|
||||
// If HP/SPratecost is positive, it is a percent of your current life, otherwise it is a percent of your max life.
|
||||
//
|
||||
// Legend for 'RequiredState' field:
|
||||
// none = Nothing special
|
||||
// hidden = Requires on hidden status by using Hiding, Cloaking, or maybe Chasewalk
|
||||
// riding = Requires to ride either a peco or a dragon
|
||||
// falcon = Requires a Falcon
|
||||
// cart = Requires a Pushcart (for renewal can replace this state by SC_PUSH_CART in 'RequiredStatuses' field)
|
||||
// shield = Requires a 0,shield equipped
|
||||
// recover_weight_rate = Requires to be less than 50% weight
|
||||
// move_enable = Requires to be able to move
|
||||
// water = Requires to be standing on a water cell
|
||||
// dragon = Requires to ride a Dragon
|
||||
// warg = Requires a Warg
|
||||
// ridingwarg = Requires to ride a Warg
|
||||
// mado = Requires to have an active mado
|
||||
// elementalspirit = Requires to have an Elemental Spirit summoned.
|
||||
// peco = Requires riding a peco
|
||||
//
|
||||
// 'RequiredStatuses'
|
||||
// Fill the value only with SC_STATUS (see db/const.txt for more details)
|
||||
// Usage for multiple status requirements: SC_STATUS1:SC_STATUS2:SC_STATUS3
|
||||
// Max. multiple value is 3 (skill.h: MAX_SKILL_STATUS_REQUIRE)
|
||||
// Use any number or SC_ALL will disable status requirements
|
||||
// 'RequiredEquipment'
|
||||
// Specified equipment to be equipped. For multiple values, use : as delimiter.
|
||||
// Max. multiple value is 10 (skill.h: MAX_SKILL_EQUIP_REQUIRE)
|
||||
|
@ -1,29 +0,0 @@
|
||||
// Skill Unit Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// ID,unit ID,unit ID 2,layout,range,interval,target,flag
|
||||
//
|
||||
// layout = -1:special, 0:1*1, 1:3*3, 2:5*5, up to 5:11*11
|
||||
// target = friend (party +guildmates +neutral players) / party / guild
|
||||
// ally (party +guildmates) / all / enemy
|
||||
// flag 0x0001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
// 0x0002(UF_NOREITERRATION) Spell cannot be stacked
|
||||
// 0x0004(UF_NOFOOTSET) Spell cannot be cast near/on targets
|
||||
// 0x0008(UF_NOOVERLAP) Spell effects do not overlap
|
||||
// 0x0010(UF_PATHCHECK) Only cells with a shootable path will be placed
|
||||
// 0x0020(UF_NOPC) Spell cannot affect players.
|
||||
// 0x0040(UF_NOMOB) Spell cannot affect mobs.
|
||||
// 0x0080(UF_SKILL) Spell CAN affect skills.
|
||||
// 0x0100(UF_DANCE) Dance skill
|
||||
// 0x0200(UF_ENSEMBLE) Ensemble skill
|
||||
// 0x0400(UF_SONG) Song skill
|
||||
// 0x0800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
|
||||
// 0x2000(UF_RANGEDSINGLEUNIT) Layout hack, use layout range propriety but only display center.
|
||||
// Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets
|
||||
//
|
||||
// Notes:
|
||||
// 0x89,0x8a,0x8b without indication
|
||||
//
|
||||
// u1 u2 lay r intr target flag
|
||||
//
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +0,0 @@
|
||||
// <Skill id>,<Cast>,<Delay (optional)>
|
||||
//
|
||||
// Cast: 0 - everything affects the skill's cast time
|
||||
// 1 - skill's cast time is not affected by dex
|
||||
// 2 - skill's cast time is not affected by statuses (Suffragium, etc)
|
||||
// 4 - skill's cast time is not affected by item bonuses (equip, cards)
|
||||
//
|
||||
// Delay: 0 - everything affects the skill's delay
|
||||
// 1 - skill's delay is not affected by dex
|
||||
// 2 - skill's delay is not affected by Magic Strings / Bragi
|
||||
// 4 - skill's delay is not affected by item bonuses (equip, cards)
|
||||
//
|
||||
// Note: Values are bit fields, add them up to combine their effects.
|
||||
// Note: Delay setting '1' only makes sense when delay_dependon_dex is enabled.
|
||||
// Example: 46,1,1 = Double Strafe's cast time and delay is not affected by dex.
|
||||
|
||||
136,0,2 //AS_SONICBLOW
|
||||
263,0,2 //MO_TRIPLEATTACK
|
||||
272,0,2 //MO_CHAINCOMBO
|
||||
273,0,2 //MO_COMBOFINISH
|
||||
336,1 //WE_CALLPARTNER
|
||||
366,7 //HW_MAGICPOWER
|
||||
370,1 //CH_PALMSTRIKE
|
||||
371,0,2 //CH_TIGERFIST
|
||||
372,0,2 //CH_CHAINCRUSH
|
||||
394,0,2 //CG_ARROWVULCAN
|
||||
403,3 //PF_MEMORIZE
|
||||
408,1 //WE_BABY
|
||||
409,1 //WE_CALLPARENT
|
||||
410,1 //WE_CALLBABY
|
||||
482,1 //PF_DOUBLECASTING
|
||||
462,1 //SL_KAIZEL
|
||||
496,1 //AM_TWILIGHT1
|
||||
497,1 //AM_TWILIGHT2
|
||||
498,1 //AM_TWILIGHT3
|
||||
512,3 //GS_TRACKING
|
||||
1014,1 //PR_REDEMPTIO
|
||||
|
||||
2012,7 //RK_CRUSHSTRIKE
|
||||
2013,7 //RK_REFRESH
|
||||
2014,7 //RK_GIANTGROWTH
|
||||
2015,7 //RK_STONEHARDSKIN
|
||||
2022,0,2 //GC_CROSSIMPACT
|
||||
2032,7 //GC_POISONSMOKE
|
||||
2234,7 //RA_FEARBREEZE
|
||||
//2267,7 //NC_SELFDESTRUCTION
|
||||
2268,7 //NC_SHAPESHIFT
|
||||
//2270,7 //NC_INFRAREDSCAN
|
||||
2271,7 //NC_ANALYZE
|
||||
2281,7 //NC_SILVERSNIPER
|
||||
2282,7 //NC_MAGICDECOY
|
||||
2313,7 //LG_FORCEOFVANGUARD
|
||||
2462,7 //SO_EL_ANALYSIS
|
||||
|
||||
2534,7,7 //RETURN_TO_ELDICASTES
|
||||
2536,7,7 //ALL_GUARDIAN_RECALL
|
||||
2537,0,7 //ALL_ODINS_POWER
|
||||
|
||||
5067,7,7 //ALL_EQSWITCH
|
||||
|
||||
// Mercenary Skills
|
||||
8214,7 //MA_CHARGEARROW
|
||||
8215,7 //MA_SHARPSHOOTING
|
||||
8217,7 //ML_BRANDISHSPEAR
|
||||
8218,7 //ML_SPIRALPIERCE
|
||||
8221,7 //ML_DEVOTION
|
||||
8222,7 //MER_MAGNIFICAT
|
||||
8225,7 //MER_CRASH
|
||||
8234,7 //MER_DECAGI
|
||||
8235,7 //MER_SCAPEGOAT
|
||||
8238,7 //MER_KYRIE
|
||||
8240,7 //MER_INCAGI
|
||||
|
||||
// Guild Skills
|
||||
10010,3 //GD_BATTLEORDER
|
||||
10011,3 //GD_REGENERATION
|
||||
10012,6 //GD_RESTORE
|
||||
10013,7 //GD_EMERGENCYCALL
|
File diff suppressed because it is too large
Load Diff
33136
db/pre-re/skill_db.yml
Normal file
33136
db/pre-re/skill_db.yml
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,198 +0,0 @@
|
||||
// Skill Unit Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// Skill ID,Unit ID,Unit ID 2,Layout,Range,Interval,Target,Flag
|
||||
//
|
||||
// layout = -1:special, 0:1*1, 1:3*3, 2:5*5, up to 5:11*11
|
||||
// target = friend (party +guildmates +neutral players) / party / guild
|
||||
// ally (party +guildmates) / all / sameguild (guild but no allies) / enemy
|
||||
// flag 0x00001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
// 0x00002(UF_NOREITERATION) Spell cannot be stacked
|
||||
// 0x00004(UF_NOFOOTSET) Spell cannot be cast near/on targets
|
||||
// 0x00008(UF_NOOVERLAP) Spell effects do not overlap
|
||||
// 0x00010(UF_PATHCHECK) Only cells with a shootable path will be placed
|
||||
// 0x00020(UF_NOPC) Spell cannot affect players.
|
||||
// 0x00040(UF_NOMOB) Spell cannot affect mobs.
|
||||
// 0x00080(UF_SKILL) Spell CAN affect skills.
|
||||
// 0x00100(UF_DANCE) Dance skill
|
||||
// 0x00200(UF_ENSEMBLE) Ensemble skill
|
||||
// 0x00400(UF_SONG) Song skill
|
||||
// 0x00800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
|
||||
// 0x01000(UF_NOKNOCKBACK) Cannot be knocked back (only unit that can be damaged)
|
||||
// 0x02000(UF_RANGEDSINGLEUNIT) Layout hack, use layout range propriety but only display center.
|
||||
// 0x04000(UF_CRAZYWEED_IMMUNE) Immune to GN_CRAZYWEED removal
|
||||
// 0x08000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN
|
||||
// 0x10000(UF_KNOCKBACK_GROUP) Knock back a whole skill group (by default, skill unit is knocked back each unit)
|
||||
// 0x20000(UF_HIDDEN_TRAP) Hidden trap, see 'traps_setting' skill config to enable this flag
|
||||
// Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets
|
||||
//
|
||||
// Notes:
|
||||
// 0x89,0x8a,0x8b without indication
|
||||
//
|
||||
// u1 u2 lay r intr target flag
|
||||
//
|
||||
|
||||
12,0x7e, , 0, 0, -1,all, 0x003 //MG_SAFETYWALL
|
||||
18,0x7f, , -1, 0, 20,enemy, 0x8010 //MG_FIREWALL
|
||||
21,0x86, , 0, 2:2:2:2:2:2:2:2:2:2:3,1000,enemy, 0x010 //MG_THUNDERSTORM
|
||||
25,0x85, , 1, 0, -1,all, 0x2003 //AL_PNEUMA
|
||||
27,0x81,0x80, 0, 0, -1,all, 0x00E //AL_WARP
|
||||
70,0x83, , -1, 1,1000,all, 0x018 //PR_SANCTUARY
|
||||
79,0x84, , -1, 1,3000,enemy, 0x8018 //PR_MAGNUS
|
||||
80,0x87,0x88, 0, 1,2000,enemy, 0x006 //WZ_FIREPILLAR
|
||||
83,0x86, , 0, 3,1000,enemy, 0x010 //WZ_METEOR
|
||||
85,0x86, , 5:5:5:5:5:5:5:5:5:5:7, 1,1250,enemy,0x018 //WZ_VERMILION
|
||||
86,0x86, , 0:1:1:2:2:2:2:2:2:2, 0,-1,noone, 0x010 //WZ_WATERBALL
|
||||
87,0x8d, , -1, 0,1000,all, 0x9010 //WZ_ICEWALL
|
||||
89,0x86, , 4, 1, 450,enemy, 0x018 //WZ_STORMGUST
|
||||
91,0x86, , 2, 0,1000,enemy, 0x010 //WZ_HEAVENDRIVE
|
||||
92,0x8e, , 2, 0, -1,enemy, 0x8010 //WZ_QUAGMIRE
|
||||
115,0x90, , 0, 1,1000,enemy, 0x8006 //HT_SKIDTRAP
|
||||
116,0x93, , 0, 1,1000,enemy, 0x8006 //HT_LANDMINE
|
||||
117,0x91, , 0, 1,1000,enemy, 0x9006 //HT_ANKLESNARE
|
||||
118,0x94, , 0, 1,1000,enemy, 0x8006 //HT_SHOCKWAVE
|
||||
119,0x95, , 0, 1,1000,enemy, 0x8006 //HT_SANDMAN
|
||||
120,0x96, , 0, 1,1000,enemy, 0x8006 //HT_FLASHER
|
||||
121,0x97, , 0, 1,1000,enemy, 0x8006 //HT_FREEZINGTRAP
|
||||
122,0x8f, , 0, 1,1000,enemy, 0x8006 //HT_BLASTMINE
|
||||
123,0x98, , 0, 1,1000,enemy, 0x8006 //HT_CLAYMORETRAP
|
||||
125,0x99, , 0, 1,1000,all, 0x8040 //HT_TALKIEBOX
|
||||
140,0x92, , -1, 1,1000,enemy, 0x8000 //AS_VENOMDUST
|
||||
220,0xb0, , 0, 0, -1,all, 0x8002 //RG_GRAFFITI
|
||||
229,0xb1, , 0, 1,1000,enemy, 0x006 //AM_DEMONSTRATION
|
||||
254,0x86, , -1, 0, 300,enemy, 0x010 //CR_GRANDCROSS
|
||||
285,0x9a, , 3, 0, -1,all, 0x8010 //SA_VOLCANO
|
||||
286,0x9b, , 3, 0, -1,all, 0x8010 //SA_DELUGE
|
||||
287,0x9c, , 3, 0, -1,all, 0x8010 //SA_VIOLENTGALE
|
||||
288,0x9d, , 3:3:4:4:5,0, -1,all, 0x8010 //SA_LANDPROTECTOR
|
||||
306,0x9e, , 4, 0,6000,enemy, 0x200 //BD_LULLABY
|
||||
307,0x9f, , 4, 0, -1,enemy, 0x220 //BD_RICHMANKIM
|
||||
308,0xa0, , 4, 0, -1,enemy, 0x200 //BD_ETERNALCHAOS
|
||||
309,0xa1, , 4, 0, -1,party, 0x200 //BD_DRUMBATTLEFIELD
|
||||
310,0xa2, , 4, 0, -1,party, 0x200 //BD_RINGNIBELUNGEN
|
||||
311,0xa3, , 4, 0, -1,all, 0x200 //BD_ROKISWEIL
|
||||
312,0xa4, , 4, 0, -1,party, 0x240 //BD_INTOABYSS
|
||||
313,0xa5, , 4, 0, -1,party, 0x200 //BD_SIEGFRIED
|
||||
317,0xa6, , 3, 0,3000,enemy, 0x400 //BA_DISSONANCE
|
||||
319,0xa7, , 3, 0, -1,all, 0x440 //BA_WHISTLE
|
||||
320,0xa8, , 3, 0, -1,all, 0x440 //BA_ASSASSINCROSS
|
||||
321,0xa9, , 3, 0, -1,all, 0x440 //BA_POEMBRAGI
|
||||
322,0xaa, , 3, 0,6000,all, 0xC40 //BA_APPLEIDUN
|
||||
325,0xab, , 3, 0,3000,enemy, 0x100 //DC_UGLYDANCE
|
||||
327,0xac, , 3, 0, -1,all, 0x140 //DC_HUMMING
|
||||
328,0xad, , 3, 0, -1,enemy, 0x100 //DC_DONTFORGETME
|
||||
329,0xae, , 3, 0, -1,all, 0x140 //DC_FORTUNEKISS
|
||||
330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU
|
||||
336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER
|
||||
339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_GRANDDARKNESS
|
||||
362,0xb4, , 2, 0, 300,all, 0x2000 //HP_BASILICA
|
||||
369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL
|
||||
395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT
|
||||
404,0xb6, , -1, 0, -1,all, 0x8000 //PF_FOGWALL
|
||||
405,0xb7, , 0, 0, -1,enemy, 0x8000 //PF_SPIDERWEB
|
||||
409,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLBABY
|
||||
410,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARENT
|
||||
428,0x86, , 0, 1, 100,enemy, 0x000 //SG_SUN_WARM
|
||||
429,0x86, , 0, 1, 100,enemy, 0x000 //SG_MOON_WARM
|
||||
430,0x86, , 0, 1, 100,enemy, 0x000 //SG_STAR_WARM
|
||||
484,0xb8, , 2, 0,1000,enemy, 0x8818 //HW_GRAVITATION
|
||||
488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE
|
||||
516,0x86, , 3, 0, 100,enemy, 0x000 //GS_DESPERADO
|
||||
521,0xbe, , 0, 1,1000,enemy, 0x000 //GS_GROUNDDRIFT
|
||||
527,0xbc, , -1, 0,2000,enemy, 0x018 //NJ_TATAMIGAESHI
|
||||
535,0xbd, , -1, 0, 100,enemy, 0x8010 //NJ_KAENSIN
|
||||
536,0x86, , 2, 0,1000,enemy, 0x010 //NJ_BAKUENRYU
|
||||
538,0xbb, , 1:1:1:2:2:2:3:3:3:4,0,-1,all,0x8010 //NJ_SUITON
|
||||
539,0x86, , 3, 0,1000,enemy, 0x010 //NJ_HYOUSYOURAKU
|
||||
541,0x86, , 2:2:3:3:4, 0,1000,enemy, 0x010 //NJ_RAIGEKISAI
|
||||
670,0xc7, , 1, 5:5:5:5:5:5:5:5:5:13,1000,all,0x008 //NPC_EVILLAND
|
||||
|
||||
706,0xfd, , 2, 0,1000,enemy, 0x018 //NPC_VENOMFOG
|
||||
725,0xda, , 0, 0,1000,enemy, 0x1000 //NPC_REVERBERATION
|
||||
|
||||
2044,0xca, , 0, 2,1000,all, 0x018 //AB_EPICLESIS
|
||||
|
||||
2032,0xe1, , 2, 0,1000,enemy, 0x8018 //GC_POISONSMOKE
|
||||
|
||||
2213,0x86, , 0, 9,1000,enemy, 0x018 //WL_COMET
|
||||
2216,0xcb, , -1, 2,2000,enemy, 0x018 //WL_EARTHSTRAIN
|
||||
|
||||
2238,0xd8, , 0, 1,1000,enemy, 0x9006 //RA_ELECTRICSHOCKER
|
||||
2239,0xd9, , 0, 1,1000,enemy, 0x8006 //RA_CLUSTERBOMB
|
||||
2249,0xd2, , 0, 1,1000,enemy, 0x8022 //RA_MAGENTATRAP
|
||||
2250,0xd3, , 0, 1,1000,enemy, 0x8022 //RA_COBALTTRAP
|
||||
2251,0xd4, , 0, 1,1000,enemy, 0x8022 //RA_MAIZETRAP
|
||||
2252,0xd5, , 0, 1,1000,enemy, 0x8022 //RA_VERDURETRAP
|
||||
2253,0xd6, , 0, 1,1000,enemy, 0x8002 //RA_FIRINGTRAP
|
||||
2254,0xd7, , 0, 1,1000,enemy, 0x8002 //RA_ICEBOUNDTRAP
|
||||
|
||||
2273,0xe2, , 2, 0, -1,all, 0x000 //NC_NEUTRALBARRIER
|
||||
2274,0xe3, , 2, 0, -1,all, 0x000 //NC_STEALTHFIELD
|
||||
|
||||
2299,0xcc, , 0, 1,1000,all, 0x8006 //SC_MANHOLE
|
||||
2300,0xcd, , 0, 0,1000,all, 0x8006 //SC_DIMENSIONDOOR
|
||||
2301,0xce, , 2, 0,1000,all, 0xA00E //SC_CHAOSPANIC
|
||||
2302,0xcf, , 2, 0, -1,all, 0xA002 //SC_MAELSTROM
|
||||
2303,0xd0, , 3, 0, -1,all, 0xA058 //SC_BLOODYLUST
|
||||
2304,0xd1, , 0, 2, -1,enemy, 0x018 //SC_FEINTBOMB
|
||||
|
||||
2319,0xec, , 0, 3,5000,all, 0x000 //LG_BANDING
|
||||
|
||||
2414,0xda, , 0, 0,1000,enemy, 0x1000 //WM_REVERBERATION
|
||||
2418,0xdb, , 0, 5, 300,enemy, 0x800 //WM_SEVERE_RAINSTORM
|
||||
2419,0xde, , 0, 1,1000,enemy, 0x1014 //WM_POEMOFNETHERWORLD
|
||||
|
||||
2443,0xdc, , 0, 0,1000,enemy, 0x00A //SO_FIREWALK
|
||||
2444,0xdd, , 0, 0,1000,enemy, 0x00A //SO_ELECTRICWALK
|
||||
2446,0x86, , 0, 3:3:3:4:4,1000,enemy, 0x018 //SO_EARTHGRAVE
|
||||
2447,0x86, , 0, 3:3:3:4:4,1000,enemy, 0x018 //SO_DIAMONDDUST
|
||||
2449,0xdf, , 0, 3:3:4:4:5,500,enemy, 0x018 //SO_PSYCHIC_WAVE
|
||||
2450,0xe0, , 0, 3, 500,enemy, 0x8010 //SO_CLOUD_KILL
|
||||
2452,0xe4, , 3, 0, -1,all, 0xA010 //SO_WARMER
|
||||
2453,0xeb, , 0, 1:1:2:2:3,500,enemy,0x8010 //SO_VACUUM_EXTREME
|
||||
2465,0xf1, , 1, 0, -1,all, 0x2010 //SO_FIRE_INSIGNIA
|
||||
2466,0xf2, , 1, 0, -1,all, 0x2010 //SO_WATER_INSIGNIA
|
||||
2467,0xf3, , 1, 0, -1,all, 0x2010 //SO_WIND_INSIGNIA
|
||||
2468,0xf4, , 1, 0, -1,all, 0x2010 //SO_EARTH_INSIGNIA
|
||||
|
||||
2479,0xe5, , 0, 1,1000,enemy, 0x8006 //GN_THORNS_TRAP
|
||||
2482,0xe6,0x7f, -1, 1, 300,enemy, 0x8000 //GN_WALLOFTHORN
|
||||
2484,0x86, , 0, 1, 100,enemy, 0x080 //GN_CRAZYWEED_ATK
|
||||
2485,0xe7, , 0, 2,2000,enemy, 0x8098 //GN_DEMONIC_FIRE
|
||||
2487,0xe8, , 2, 0, -1,all, 0x2000 //GN_FIRE_EXPANSION_SMOKE_POWDER
|
||||
2488,0xe9, , 2, 0, -1,all, 0x2000 //GN_FIRE_EXPANSION_TEAR_GAS
|
||||
2490,0xea, , 0, 1,1000,enemy, 0x8002 //GN_HELLS_PLANT
|
||||
|
||||
2555,0x104, , 0, 1:2:2:3:3,500,enemy,0x6 //RL_B_TRAP
|
||||
2567,0x105, , -1, 0,1000,enemy, 0x98 //RL_FIRE_RAIN
|
||||
|
||||
3006,0x86, , 0, 1,1000,enemy, 0x018 //KO_BAKURETSU
|
||||
3008,0x86, , 0, 1:1:1:1:1:1:1:1:1:2,1000,enemy, 0x018 //KO_MUCHANAGE
|
||||
3009,0x86, , 0, 3,1000,enemy, 0x018 //KO_HUUMARANKA
|
||||
3010,0xfc, , 0, 1,5000,enemy, 0x018 //KO_MAKIBISHI
|
||||
3020,0xf8, , 0, 2, 500,all, 0x018 //KO_ZENKAI
|
||||
|
||||
5006,0x101, , 0, 3, 500,enemy, 0x018 //NC_MAGMA_ERUPTION
|
||||
5010,0x91, , 0, 1,1000,all, 0x002 //SC_ESCAPE
|
||||
5013,0x102, , 3, 0, -1,all, 0x2002 //LG_KINGS_GRACE
|
||||
|
||||
8020,0xf5, , 3, 0,2300:2100:1900:1700:1500,enemy, 0x018 //MH_POISON_MIST
|
||||
8033,0x7e, , 0, 0, -1,all, 0x003 //MH_STEINWAND
|
||||
8025,0x86, , 0, 2:2:3:3:4,1000,enemy, 0x018 //MH_XENO_SLASHER
|
||||
8041,0xf6, , 1:1:2:2:3, 0,2000,enemy, 0x01A //MH_LAVA_SLIDE
|
||||
8043,0xf7, , 1, 0,-1,all, 0x2018 //MH_VOLCANIC_ASH
|
||||
|
||||
8209,0x90, , 0, 1,1000,enemy, 0x006 //MA_SKIDTRAP
|
||||
8210,0x93, , 0, 0,1000,enemy, 0x006 //MA_LANDMINE
|
||||
8211,0x95, , 0, 1,1000,enemy, 0x006 //MA_SANDMAN
|
||||
8212,0x97, , 0, 1,1000,enemy, 0x006 //MA_FREEZINGTRAP
|
||||
|
||||
8403,0xed, , -1, 1,1000,enemy, 0x018 //EL_FIRE_MANTLE
|
||||
8406,0xee, , 1, 0, -1,friend,0x2018 //EL_WATER_BARRIER
|
||||
8409,0xef, , 1, 0, -1,friend,0x2018 //EL_ZEPHYR
|
||||
8412,0xf0, , 1, 0, -1,friend,0x2018 //EL_POWER_OF_GAIA
|
||||
|
||||
10006,0xc1, , 2, 0, -1,guild, 0x040 //GD_LEADERSHIP
|
||||
10007,0xc2, , 2, 0, -1,guild, 0x040 //GD_GLORYWOUNDS
|
||||
10008,0xc3, , 2, 0, -1,guild, 0x040 //GD_SOULCOLD
|
||||
10009,0xc4, , 2, 0, -1,guild, 0x040 //GD_HAWKEYES
|
File diff suppressed because it is too large
Load Diff
@ -1,83 +0,0 @@
|
||||
// <Skill id>,<Cast>,<Delay (optional)>
|
||||
//
|
||||
// Cast: 0 - everything affects the skill's cast time
|
||||
// 1 - skill's cast time is not affected by dex
|
||||
// 2 - skill's cast time is not affected by statuses (Suffragium, etc)
|
||||
// 4 - skill's cast time is not affected by item bonuses (equip, cards)
|
||||
//
|
||||
// Delay: 0 - everything affects the skill's delay
|
||||
// 1 - skill's delay is not affected by dex
|
||||
// 2 - skill's delay is not affected by Magic Strings / Bragi
|
||||
// 4 - skill's delay is not affected by item bonuses (equip, cards)
|
||||
//
|
||||
// Note: Values are bit fields, add them up to combine their effects.
|
||||
// Note: Delay setting '1' only makes sense when delay_dependon_dex is enabled.
|
||||
// Example: 46,1,1 = Double Strafe's cast time and delay is not affected by dex.
|
||||
|
||||
136,0,2 //AS_SONICBLOW
|
||||
263,0,2 //MO_TRIPLEATTACK
|
||||
272,0,2 //MO_CHAINCOMBO
|
||||
273,0,2 //MO_COMBOFINISH
|
||||
336,1 //WE_CALLPARTNER
|
||||
366,3 //HW_MAGICPOWER
|
||||
370,1 //CH_PALMSTRIKE
|
||||
371,0,2 //CH_TIGERFIST
|
||||
372,0,2 //CH_CHAINCRUSH
|
||||
394,0,2 //CG_ARROWVULCAN
|
||||
403,3 //PF_MEMORIZE
|
||||
408,1 //WE_BABY
|
||||
409,1 //WE_CALLPARENT
|
||||
410,1 //WE_CALLBABY
|
||||
482,1 //PF_DOUBLECASTING
|
||||
462,1 //SL_KAIZEL
|
||||
496,1 //AM_TWILIGHT1
|
||||
497,1 //AM_TWILIGHT2
|
||||
498,1 //AM_TWILIGHT3
|
||||
512,3 //GS_TRACKING
|
||||
1014,1 //PR_REDEMPTIO
|
||||
|
||||
5063,1 //WE_CALLALLFAMILY
|
||||
5064,1 //WE_ONEFOREVER
|
||||
5065,1 //WE_CHEERUP
|
||||
|
||||
2012,7 //RK_CRUSHSTRIKE
|
||||
2013,7 //RK_REFRESH
|
||||
2014,7 //RK_GIANTGROWTH
|
||||
2015,7 //RK_STONEHARDSKIN
|
||||
2022,0,2 //GC_CROSSIMPACT
|
||||
2032,7 //GC_POISONSMOKE
|
||||
2234,7 //RA_FEARBREEZE
|
||||
//2267,7 //NC_SELFDESTRUCTION
|
||||
2268,7 //NC_SHAPESHIFT
|
||||
//2270,7 //NC_INFRAREDSCAN
|
||||
2271,7 //NC_ANALYZE
|
||||
2281,7 //NC_SILVERSNIPER
|
||||
2282,7 //NC_MAGICDECOY
|
||||
2313,7 //LG_FORCEOFVANGUARD
|
||||
2462,7 //SO_EL_ANALYSIS
|
||||
|
||||
2534,7,7 //RETURN_TO_ELDICASTES
|
||||
2536,7,7 //ALL_GUARDIAN_RECALL
|
||||
2537,0,7 //ALL_ODINS_POWER
|
||||
3035,7,7 //ECLAGE_RECALL
|
||||
|
||||
5067,7,7 //ALL_EQSWITCH
|
||||
|
||||
// Mercenary Skills
|
||||
8214,7 //MA_CHARGEARROW
|
||||
8215,7 //MA_SHARPSHOOTING
|
||||
8217,7 //ML_BRANDISHSPEAR
|
||||
8218,7 //ML_SPIRALPIERCE
|
||||
8221,7 //ML_DEVOTION
|
||||
8222,7 //MER_MAGNIFICAT
|
||||
8225,7 //MER_CRASH
|
||||
8234,7 //MER_DECAGI
|
||||
8235,7 //MER_SCAPEGOAT
|
||||
8238,7 //MER_KYRIE
|
||||
8240,7 //MER_INCAGI
|
||||
|
||||
// Guild Skills
|
||||
10010,3 //GD_BATTLEORDER
|
||||
10011,3 //GD_REGENERATION
|
||||
10012,6 //GD_RESTORE
|
||||
10013,7 //GD_EMERGENCYCALL
|
1618
db/re/skill_db.txt
1618
db/re/skill_db.txt
File diff suppressed because it is too large
Load Diff
36040
db/re/skill_db.yml
Normal file
36040
db/re/skill_db.yml
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,206 +0,0 @@
|
||||
// Skill Unit Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// Skill ID,Unit ID,Unit ID 2,Layout,Range,Interval,Target,Flag
|
||||
//
|
||||
// layout = -1:special, 0:1*1, 1:3*3, 2:5*5, up to 5:11*11
|
||||
// target = friend (party +guildmates +neutral players) / party / guild
|
||||
// ally (party +guildmates) / all / sameguild (guild but no allies) / enemy
|
||||
// flag 0x00001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
// 0x00002(UF_NOREITERATION) Spell cannot be stacked
|
||||
// 0x00004(UF_NOFOOTSET) Spell cannot be cast near/on targets
|
||||
// 0x00008(UF_NOOVERLAP) Spell effects do not overlap
|
||||
// 0x00010(UF_PATHCHECK) Only cells with a shootable path will be placed
|
||||
// 0x00020(UF_NOPC) Spell cannot affect players.
|
||||
// 0x00040(UF_NOMOB) Spell cannot affect mobs.
|
||||
// 0x00080(UF_SKILL) Spell CAN affect skills.
|
||||
// 0x00100(UF_DANCE) Dance skill
|
||||
// 0x00200(UF_ENSEMBLE) Ensemble skill
|
||||
// 0x00400(UF_SONG) Song skill
|
||||
// 0x00800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
|
||||
// 0x01000(UF_NOKNOCKBACK) Cannot be knocked back (only unit that can be damaged)
|
||||
// 0x02000(UF_RANGEDSINGLEUNIT) Layout hack, use layout range propriety but only display center.
|
||||
// 0x04000(UF_CRAZYWEED_IMMUNE) Immune to GN_CRAZYWEED removal
|
||||
// 0x08000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN
|
||||
// 0x10000(UF_KNOCKBACK_GROUP) Knock back a whole skill group (by default, skill unit is knocked back each unit)
|
||||
// 0x20000(UF_HIDDEN_TRAP) Hidden trap, see 'traps_setting' skill config to enable this flag
|
||||
// Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets
|
||||
//
|
||||
// Notes:
|
||||
// 0x89,0x8a,0x8b without indication
|
||||
//
|
||||
// u1 u2 lay r intr target flag
|
||||
//
|
||||
|
||||
12,0x7e, , 0, 0, -1,all, 0x003 //MG_SAFETYWALL
|
||||
18,0x7f, , -1, 0, 20,enemy, 0x8010 //MG_FIREWALL
|
||||
21,0x86, , 0, 2:2:2:2:2:2:2:2:2:2:3,1000,enemy, 0x010 //MG_THUNDERSTORM
|
||||
25,0x85, , 1, 0, -1,all, 0x2003 //AL_PNEUMA
|
||||
27,0x81,0x80, 0, 0, -1,all, 0x00E //AL_WARP
|
||||
70,0x83, , -1, 1,1000,all, 0x018 //PR_SANCTUARY
|
||||
79,0x84, , -1, 1,3000,enemy, 0x8018 //PR_MAGNUS
|
||||
80,0x87,0x88, 0, 1,2000,enemy, 0x006 //WZ_FIREPILLAR
|
||||
83,0x86, , 0, 3,1000,enemy, 0x010 //WZ_METEOR
|
||||
85,0x86, , 5:5:5:5:5:5:5:5:5:5:7, 1,1250,enemy,0x018 //WZ_VERMILION
|
||||
86,0x86, , 0:1:1:2:2:2:2:2:2:2, 0,-1,noone, 0x010 //WZ_WATERBALL
|
||||
87,0x8d, , -1, 0,1000,all, 0x9010 //WZ_ICEWALL
|
||||
89,0x86, , 4, 1, 450,enemy, 0x018 //WZ_STORMGUST
|
||||
91,0x86, , 2, 0,1000,enemy, 0x010 //WZ_HEAVENDRIVE
|
||||
92,0x8e, , 2, 0, -1,enemy, 0x8010 //WZ_QUAGMIRE
|
||||
115,0x90, , 0, 1,1000,enemy, 0x28006 //HT_SKIDTRAP
|
||||
116,0x93, , 0, 1,1000,enemy, 0x28006 //HT_LANDMINE
|
||||
117,0x91, , 0, 1,1000,enemy, 0x29006 //HT_ANKLESNARE
|
||||
118,0x94, , 0, 1,1000,enemy, 0x28006 //HT_SHOCKWAVE
|
||||
119,0x95, , 0, 1,1000,enemy, 0x28006 //HT_SANDMAN
|
||||
120,0x96, , 0, 1,1000,enemy, 0x28006 //HT_FLASHER
|
||||
121,0x97, , 0, 1,1000,enemy, 0x28006 //HT_FREEZINGTRAP
|
||||
122,0x8f, , 0, 1,1000,enemy, 0x8006 //HT_BLASTMINE
|
||||
123,0x98, , 0, 1,1000,enemy, 0x8006 //HT_CLAYMORETRAP
|
||||
125,0x99, , 0, 1,1000,all, 0x28040 //HT_TALKIEBOX
|
||||
140,0x92, , -1, 1,1000,enemy, 0x8000 //AS_VENOMDUST
|
||||
220,0xb0, , 0, 0, -1,all, 0x8002 //RG_GRAFFITI
|
||||
229,0xb1, , 0, 1, 500,enemy, 0x006 //AM_DEMONSTRATION
|
||||
254,0x86, , -1, 0, 300,enemy, 0x010 //CR_GRANDCROSS
|
||||
285,0x9a, , 3, 0, -1,all, 0x8010 //SA_VOLCANO
|
||||
286,0x9b, , 3, 0, -1,all, 0x8010 //SA_DELUGE
|
||||
287,0x9c, , 3, 0, -1,all, 0x8010 //SA_VIOLENTGALE
|
||||
288,0x9d, , 3:3:4:4:5,0, -1,all, 0x8010 //SA_LANDPROTECTOR
|
||||
306,0x9e, , 4, 0,6000,enemy, 0x200 //BD_LULLABY
|
||||
307,0x9f, , 4, 0, -1,enemy, 0x220 //BD_RICHMANKIM
|
||||
308,0xa0, , 4, 0, -1,enemy, 0x8200 //BD_ETERNALCHAOS
|
||||
309,0xa1, , 4, 0, -1,party, 0x200 //BD_DRUMBATTLEFIELD
|
||||
310,0xa2, , 4, 0, -1,party, 0x200 //BD_RINGNIBELUNGEN
|
||||
311,0xa3, , 4, 0, -1,all, 0x8200 //BD_ROKISWEIL
|
||||
312,0xa4, , 4, 0, -1,party, 0x240 //BD_INTOABYSS
|
||||
313,0xa5, , 4, 0, -1,party, 0x200 //BD_SIEGFRIED
|
||||
317,0xa6, , 3, 0,3000,enemy, 0x8400 //BA_DISSONANCE
|
||||
319,0xa7, , 3, 0, -1,all, 0x440 //BA_WHISTLE
|
||||
320,0xa8, , 3, 0, -1,all, 0x440 //BA_ASSASSINCROSS
|
||||
321,0xa9, , 3, 0, -1,all, 0x440 //BA_POEMBRAGI
|
||||
322,0xaa, , 3, 0,6000,all, 0xC40 //BA_APPLEIDUN
|
||||
325,0xab, , 3, 0,3000,enemy, 0x100 //DC_UGLYDANCE
|
||||
327,0xac, , 3, 0, -1,all, 0x140 //DC_HUMMING
|
||||
328,0xad, , 3, 0, -1,enemy, 0x100 //DC_DONTFORGETME
|
||||
329,0xae, , 3, 0, -1,all, 0x140 //DC_FORTUNEKISS
|
||||
330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU
|
||||
336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER
|
||||
339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_GRANDDARKNESS
|
||||
362,0xb4, , 2, 0, 300,all, 0x2000 //HP_BASILICA
|
||||
369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL
|
||||
395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT
|
||||
404,0xb6, , -1, 0, -1,all, 0x8000 //PF_FOGWALL
|
||||
405,0xb7, , 0, 0, -1,enemy, 0x8000 //PF_SPIDERWEB
|
||||
409,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLBABY
|
||||
410,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARENT
|
||||
428,0x86, , 0, 1, 100,enemy, 0x000 //SG_SUN_WARM
|
||||
429,0x86, , 0, 1, 100,enemy, 0x000 //SG_MOON_WARM
|
||||
430,0x86, , 0, 1, 100,enemy, 0x000 //SG_STAR_WARM
|
||||
484,0xb8, , 2, 0, 500,enemy, 0x8818 //HW_GRAVITATION
|
||||
488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE
|
||||
516,0x86, , 3, 0, 100,enemy, 0x000 //GS_DESPERADO
|
||||
521,0xbe, , 0, 1,1000,enemy, 0x000 //GS_GROUNDDRIFT
|
||||
527,0xbc, , -1, 0,2000,enemy, 0x018 //NJ_TATAMIGAESHI
|
||||
535,0xbd, , -1, 0, 100,enemy, 0x8010 //NJ_KAENSIN
|
||||
536,0x86, , 2, 0,1000,enemy, 0x010 //NJ_BAKUENRYU
|
||||
538,0xbb, , 1:1:1:2:2:2:3:3:3:4,0,-1,all,0x8010 //NJ_SUITON
|
||||
539,0x86, , 3, 0,1000,enemy, 0x010 //NJ_HYOUSYOURAKU
|
||||
541,0x86, , 1:1:2:2:3, 0,1000,enemy, 0x010 //NJ_RAIGEKISAI
|
||||
670,0xc7, , 1, 5:5:5:5:5:5:5:5:5:13,1000,all,0x008 //NPC_EVILLAND
|
||||
|
||||
706,0xfd, , 2, 0,1000,enemy, 0x018 //NPC_VENOMFOG
|
||||
708,0x86, , 0, 9,1000,enemy, 0x018 //NPC_COMET
|
||||
709,0xfe, , 0, 3,1000,enemy, 0x8018 //NPC_ICEMINE
|
||||
711,0xff, , -1, 0,1000,enemy, 0x8018 //NPC_FLAMECROSS
|
||||
725,0xda, , 0, 0,1000,enemy, 0x1000 //NPC_REVERBERATION
|
||||
|
||||
2044,0xca, , 0, 2,1000,all, 0x018 //AB_EPICLESIS
|
||||
|
||||
2032,0xe1, , 2, 0,1000,enemy, 0x8018 //GC_POISONSMOKE
|
||||
|
||||
2213,0x86, , 0, 9,1000,enemy, 0x018 //WL_COMET
|
||||
2216,0xcb, , -1, 2,2000,enemy, 0x018 //WL_EARTHSTRAIN
|
||||
|
||||
2238,0xd8, , 0, 1,1000,enemy, 0x8006 //RA_ELECTRICSHOCKER
|
||||
2239,0xd9, , 0, 1,1000,enemy, 0x8006 //RA_CLUSTERBOMB
|
||||
2249,0xd2, , 0, 1,1000,enemy, 0x8022 //RA_MAGENTATRAP
|
||||
2250,0xd3, , 0, 1,1000,enemy, 0x8022 //RA_COBALTTRAP
|
||||
2251,0xd4, , 0, 1,1000,enemy, 0x8022 //RA_MAIZETRAP
|
||||
2252,0xd5, , 0, 1,1000,enemy, 0x8022 //RA_VERDURETRAP
|
||||
2253,0xd6, , 0, 1,1000,enemy, 0x8002 //RA_FIRINGTRAP
|
||||
2254,0xd7, , 0, 1,1000,enemy, 0x8002 //RA_ICEBOUNDTRAP
|
||||
|
||||
2273,0xe2, , 2, 0, -1,all, 0x000 //NC_NEUTRALBARRIER
|
||||
2274,0xe3, , 2, 0, -1,all, 0x000 //NC_STEALTHFIELD
|
||||
|
||||
2299,0xcc, , 0, 1,1000,all, 0x8006 //SC_MANHOLE
|
||||
2300,0xcd, , 0, 0,1000,all, 0x8006 //SC_DIMENSIONDOOR
|
||||
2301,0xce, , 2, 0,1000,all, 0xA00E //SC_CHAOSPANIC
|
||||
2302,0xcf, , 2, 0, -1,all, 0xA002 //SC_MAELSTROM
|
||||
2303,0xd0, , 3, 0, -1,all, 0xA058 //SC_BLOODYLUST
|
||||
2304,0xd1, , 0, 2, -1,enemy, 0x018 //SC_FEINTBOMB
|
||||
|
||||
2319,0xec, , 0, 3,5000,all, 0x000 //LG_BANDING
|
||||
|
||||
2414,0xda, , 0, 0,1000,enemy, 0x1000 //WM_REVERBERATION
|
||||
2418,0xdb, , 0, 5, 300,enemy, 0x800 //WM_SEVERE_RAINSTORM
|
||||
2419,0xde, , 0, 1,1000,enemy, 0x1014 //WM_POEMOFNETHERWORLD
|
||||
|
||||
2443,0xdc, , 0, 0,1000,enemy, 0x00A //SO_FIREWALK
|
||||
2444,0xdd, , 0, 0,1000,enemy, 0x00A //SO_ELECTRICWALK
|
||||
2446,0x86, , 0, 3:3:3:4:4,1000,enemy, 0x018 //SO_EARTHGRAVE
|
||||
2447,0x86, , 0, 3:3:3:4:4,1000,enemy, 0x018 //SO_DIAMONDDUST
|
||||
2449,0xdf, , 0, 3:3:4:4:5,500,enemy, 0x018 //SO_PSYCHIC_WAVE
|
||||
2450,0xe0, , 0, 3, 500,enemy, 0x8010 //SO_CLOUD_KILL
|
||||
2452,0xe4, , 3, 0, -1,all, 0xA010 //SO_WARMER
|
||||
2453,0xeb, , 0, 1:1:2:2:3,500,enemy,0x8010 //SO_VACUUM_EXTREME
|
||||
2465,0xf1, , 1, 0, -1,all, 0x2010 //SO_FIRE_INSIGNIA
|
||||
2466,0xf2, , 1, 0, -1,all, 0x2010 //SO_WATER_INSIGNIA
|
||||
2467,0xf3, , 1, 0, -1,all, 0x2010 //SO_WIND_INSIGNIA
|
||||
2468,0xf4, , 1, 0, -1,all, 0x2010 //SO_EARTH_INSIGNIA
|
||||
|
||||
2479,0xe5, , 0, 1,1000,enemy, 0x8006 //GN_THORNS_TRAP
|
||||
2482,0xe6,0x7f, -1, 1, 300,enemy, 0x8000 //GN_WALLOFTHORN
|
||||
2484,0x86, , 0, 1, 100,enemy, 0x080 //GN_CRAZYWEED_ATK
|
||||
2485,0xe7, , 0, 2,2000,enemy, 0x8098 //GN_DEMONIC_FIRE
|
||||
2487,0xe8, , 2, 0, -1,all, 0x2000 //GN_FIRE_EXPANSION_SMOKE_POWDER
|
||||
2488,0xe9, , 2, 0, -1,all, 0x2000 //GN_FIRE_EXPANSION_TEAR_GAS
|
||||
2490,0xea, , 0, 1,1000,enemy, 0x8002 //GN_HELLS_PLANT
|
||||
|
||||
2555,0x104, , 0, 1:2:2:3:3,500,enemy,0x6 //RL_B_TRAP
|
||||
2567,0x105, , -1, 0,1000,enemy, 0x98 //RL_FIRE_RAIN
|
||||
|
||||
3006,0x86, , 0, 1,1000,enemy, 0x018 //KO_BAKURETSU
|
||||
3008,0x86, , 0, 1:1:1:1:1:1:1:1:1:2,1000,enemy, 0x018 //KO_MUCHANAGE
|
||||
3009,0x86, , 0, 3,1000,enemy, 0x018 //KO_HUUMARANKA
|
||||
3010,0xfc, , 0, 0,5000,enemy, 0x018 //KO_MAKIBISHI
|
||||
3020,0xf8, , 0, 2, 500,all, 0x018 //KO_ZENKAI
|
||||
|
||||
5006,0x101, , 0, 3, 500,enemy, 0x018 //NC_MAGMA_ERUPTION
|
||||
5010,0x91, , 0, 1,1000,all, 0x002 //SC_ESCAPE
|
||||
5013,0x102, , 3, 0, -1,all, 0x2002 //LG_KINGS_GRACE
|
||||
|
||||
5027,0x106, , 1:1:2:2:3, 0, -1,enemy, 0x2010 // SU_CN_POWDERING
|
||||
5028,0x86, , 0, 3, 500,enemy, 0x10 // SU_CN_METEOR
|
||||
5042,0x86, , 0, 3, 500,enemy, 0x10 // SU_CN_METEOR2
|
||||
5048,0x107, , 2:2:3:3:4, 0, -1, enemy, 0x2010 // SU_NYANGGRASS
|
||||
|
||||
8020,0xf5, , 3, 0,2300:2100:1900:1700:1500,enemy, 0x018 //MH_POISON_MIST
|
||||
8033,0x7e, , 0, 0, -1,all, 0x003 //MH_STEINWAND
|
||||
8025,0x86, , 0, 2:2:3:3:4,1000,enemy, 0x018 //MH_XENO_SLASHER
|
||||
8041,0xf6, , 1:1:2:2:3, 0,2000,enemy, 0x01A //MH_LAVA_SLIDE
|
||||
8043,0xf7, , 1, 0,-1,all, 0x2018 //MH_VOLCANIC_ASH
|
||||
|
||||
8209,0x90, , 0, 1,1000,enemy, 0x8006 //MA_SKIDTRAP
|
||||
8210,0x93, , 0, 0,1000,enemy, 0x8006 //MA_LANDMINE
|
||||
8211,0x95, , 0, 1,1000,enemy, 0x8006 //MA_SANDMAN
|
||||
8212,0x97, , 0, 1,1000,enemy, 0x8006 //MA_FREEZINGTRAP
|
||||
|
||||
8403,0xed, , -1, 1,1000,enemy, 0x018 //EL_FIRE_MANTLE
|
||||
8406,0xee, , 1, 0, -1,friend,0x2018 //EL_WATER_BARRIER
|
||||
8409,0xef, , 1, 0, -1,friend,0x2018 //EL_ZEPHYR
|
||||
8412,0xf0, , 1, 0, -1,friend,0x2018 //EL_POWER_OF_GAIA
|
||||
|
||||
10006,0xc1, , 2, 0, -1,guild, 0x040 //GD_LEADERSHIP
|
||||
10007,0xc2, , 2, 0, -1,guild, 0x040 //GD_GLORYWOUNDS
|
||||
10008,0xc3, , 2, 0, -1,guild, 0x040 //GD_SOULCOLD
|
||||
10009,0xc4, , 2, 0, -1,guild, 0x040 //GD_HAWKEYES
|
@ -1,282 +0,0 @@
|
||||
// Copyable Skills Database
|
||||
// List of skills able to be copied by Intimidate/Plagiarism and Reproduce.
|
||||
//
|
||||
// Sources:
|
||||
// http://irowiki.org/wiki/Intimidate
|
||||
// -> "Intimidate will copy any 2nd class skill"
|
||||
// http://irowiki.org/wiki/Reproduce/List_of_reproducible_skills
|
||||
// -> "Players can reproduce 1-x, 2-x, and 3-x skills and Expanded Class,
|
||||
// but cannot reproduce transcendent skills"
|
||||
//
|
||||
// Structure of Database:
|
||||
// SkillName,Option{,JobAllowed{,RequirementRemoved}}
|
||||
//
|
||||
// Option (bitmask) determines how a skill can be copied.
|
||||
// 1 = Plagiarism
|
||||
// 2 = Reproduce
|
||||
//
|
||||
// JobAllowed (bitmask) restricts copying the skill to certain classes.
|
||||
// By default, all jobs can copy the skill (0).
|
||||
// 1 = Rogue
|
||||
// 2 = Stalker
|
||||
// 4 = Shadow Chaser
|
||||
// 8 = Trans. Shadow Chaser
|
||||
// 16 = Baby Rouge
|
||||
// 32 = Baby Shadow Chaser
|
||||
//
|
||||
// RequirementRemoved (bitmask) removes requirements when casting a copied skill.
|
||||
// See 'skill_require_db.txt' for specific skill requirements.
|
||||
// 0 = uses original requirement(s)
|
||||
// 1 = hp
|
||||
// 2 = maxhptrigger
|
||||
// 4 = sp
|
||||
// 8 = hprate
|
||||
// 16 = sprate
|
||||
// 32 = zeny
|
||||
// 64 = weapon type
|
||||
// 128 = ammo (with the amount)
|
||||
// 256 = state
|
||||
// 512 = statuses
|
||||
// 1024 = spirit sphere
|
||||
// 2048 = items (with the amount)
|
||||
// 4096 = equipments
|
||||
//
|
||||
// Examples:
|
||||
// AS_SONICBLOW,2,63,64
|
||||
// Sonic Blow can be copied by all jobs with only Plagiarism.
|
||||
// To use the copied skill, a Katar is not needed (a Sonic Blow weapon type requirement).
|
||||
//
|
||||
// CR_ACIDDEMONSTRATION,3,10
|
||||
// Acid Demonstration can only be copied by Stalker/Trans. Shadow Chaser with Plagiarism or Reproduce.
|
||||
// This mode simulates the previous battle config, which allowed only Trans. classes to copy Trans. skills.
|
||||
|
||||
// Swordsman
|
||||
SM_BASH,3 //Bash
|
||||
SM_MAGNUM,3 //Magnum Break
|
||||
|
||||
// Mage
|
||||
MG_NAPALMBEAT,3 // Napalm Beat
|
||||
MG_SOULSTRIKE,3 // Soul Strike
|
||||
MG_COLDBOLT,3 // Cold Bolt
|
||||
MG_FROSTDIVER,3 // Frost Diver
|
||||
MG_FIREBALL,3 // Fire Ball
|
||||
MG_FIREWALL,3 // Fire Wall
|
||||
MG_FIREBOLT,3 // Fire Bolt
|
||||
MG_LIGHTNINGBOLT,3 // Lightning Bolt
|
||||
MG_THUNDERSTORM,3 // Thunderstorm
|
||||
|
||||
// Acolyte
|
||||
AL_RUWACH,3 // Ruwach
|
||||
AL_HEAL,3 // Heal
|
||||
|
||||
// Merchant
|
||||
MC_MAMMONITE,3 // Mammonite
|
||||
|
||||
// Archer
|
||||
AC_DOUBLE,3 // Double Strafe
|
||||
AC_SHOWER,3 // Arrow Shower
|
||||
|
||||
// Thief
|
||||
TF_POISON,3 // Envenom
|
||||
|
||||
// Resurrection
|
||||
ALL_RESURRECTION,3 // Resurrection
|
||||
|
||||
// Knight
|
||||
KN_BOWLINGBASH,3 // Bowling Bash
|
||||
|
||||
// Priest
|
||||
PR_ASPERSIO,3 // Asperio
|
||||
PR_BENEDICTIO,3 // B.S Sacramenti
|
||||
PR_SANCTUARY,3 // Sanctuary
|
||||
PR_TURNUNDEAD,3 // Turn Undead
|
||||
PR_MAGNUS,3 // Magnus Exorcismus
|
||||
|
||||
// Wizard
|
||||
WZ_FIREPILLAR,3 // Fire Pillar
|
||||
WZ_SIGHTRASHER,3 // Sightrasher
|
||||
WZ_METEOR,3 // Meteor Storm
|
||||
WZ_JUPITEL,3 // Jupitel Thunder
|
||||
WZ_VERMILION,3 // Lord of Vermillion
|
||||
WZ_WATERBALL,3 // Water Ball
|
||||
WZ_FROSTNOVA,3 // Frost Nova
|
||||
WZ_STORMGUST,3 // Storm Gust
|
||||
WZ_EARTHSPIKE,3 // Earth Spike
|
||||
WZ_HEAVENDRIVE,3 // Heaven's Drive
|
||||
|
||||
// Hunter
|
||||
HT_LANDMINE,3 // Land Mine
|
||||
HT_FREEZINGTRAP,3 // Freezing Trap
|
||||
HT_BLASTMINE,3 // Blast Mine
|
||||
HT_CLAYMORETRAP,3 // Claymore Trap
|
||||
|
||||
// Assassin
|
||||
AS_SPLASHER,3 // Venom Splasher
|
||||
|
||||
// 1st Job Quest Skills
|
||||
AC_CHARGEARROW,3 // Arrow Repel
|
||||
TF_THROWSTONE,3 // Stone Fling
|
||||
AL_HOLYLIGHT,3 // Holy Light
|
||||
|
||||
// Rogue
|
||||
RG_BACKSTAP,3 // Backstab
|
||||
|
||||
// Alchemist
|
||||
AM_DEMONSTRATION,3 // Bomb
|
||||
AM_ACIDTERROR,3 // Acid Terror
|
||||
|
||||
// Crusader
|
||||
CR_SHIELDCHARGE,3 // Smite
|
||||
CR_SHIELDBOOMERANG,3 // Shield Boomerang
|
||||
CR_HOLYCROSS,3 // Holy Cross
|
||||
CR_GRANDCROSS,3 // Grand Cross
|
||||
|
||||
// Monk
|
||||
MO_TRIPLEATTACK,3 // Raging Trifecta Blow
|
||||
MO_INVESTIGATE,3 // Occult Impaction
|
||||
MO_FINGEROFFENSIVE,3 // Throw Spirit Sphere
|
||||
MO_EXTREMITYFIST,3 // Asura Strike
|
||||
MO_CHAINCOMBO,3 // Raging Quadruple Blow
|
||||
|
||||
// Item Skill
|
||||
ITM_TOMAHAWK,3 // Throw Tomahawk
|
||||
|
||||
// TaeKwon Kid
|
||||
TK_JUMPKICK,3 // Flying Kick
|
||||
|
||||
// Ninja
|
||||
NJ_ZENYNAGE,3 // Throw Zeny
|
||||
NJ_TATAMIGAESHI,3 // Improvised Defense
|
||||
NJ_KASUMIKIRI,3 // Vanishing Slash
|
||||
NJ_SHADOWJUMP,3 // Shadow Leap
|
||||
NJ_KIRIKAGE,3 // Shadow Slash
|
||||
NJ_UTSUSEMI,3 // Cicada Skin Sheeding
|
||||
NJ_KOUENKA,3 // Crimson Fire Petal
|
||||
NJ_KAENSIN,3 // Crimson Fire Formation
|
||||
NJ_BAKUENRYU,3 // Raging Fire Dragon
|
||||
NJ_HYOUSENSOU,3 // Spear of Ice
|
||||
NJ_HYOUSYOURAKU,3 // Ice Meteor
|
||||
NJ_HUUJIN,3 // Wind Blade
|
||||
NJ_RAIGEKISAI,3 // Lightning Strike of Destruction
|
||||
NJ_KAMAITACHI,3 // Kamaitachi
|
||||
|
||||
// 2nd Job Quest Skills
|
||||
KN_CHARGEATK,3 // Charge Attack
|
||||
AS_VENOMKNIFE,3 // Venom Knife
|
||||
WZ_SIGHTBLASTER,3 // Sight Blaster
|
||||
HT_PHANTASMIC,3 // Phantasmic Arrow
|
||||
MO_KITRANSLATION,3 // Excruciating Palm
|
||||
|
||||
// Rune Knight
|
||||
RK_SONICWAVE,2 // Sonic Wave
|
||||
RK_WINDCUTTER,2 // Wind Cutter
|
||||
RK_IGNITIONBREAK,2 // Ignition Break
|
||||
|
||||
// Guillotine Cross
|
||||
GC_CROSSIMPACT,2 // Cross Impact
|
||||
GC_DARKILLUSION,2 // Dark Illusion
|
||||
GC_PHANTOMMENACE,2 // Phantom Menace
|
||||
GC_DARKCROW,2 // Dark Claw
|
||||
|
||||
// Arch Bishop
|
||||
AB_JUDEX,2 // Judex
|
||||
AB_ADORAMUS,2 // Adoramus
|
||||
AB_RENOVATIO,2 // Renovatio
|
||||
AB_HIGHNESSHEAL,2 // Highness Heal
|
||||
AB_DUPLELIGHT,2 // Duple Light
|
||||
AB_DUPLELIGHT_MELEE,2 // Dummy skill for Duple Light
|
||||
AB_DUPLELIGHT_MAGIC,2 // Dummy skill for Duple Light
|
||||
|
||||
// Warlock
|
||||
WL_SOULEXPANSION,2 // Soul Expansion
|
||||
WL_FROSTMISTY,2 // Frosty Misty
|
||||
WL_JACKFROST,2 // Jack Frost
|
||||
WL_DRAINLIFE,2 // Drain Life
|
||||
WL_CRIMSONROCK,2 // Crimson Rock
|
||||
WL_HELLINFERNO,2 // Hell Inferno
|
||||
WL_COMET,2 // Comet
|
||||
WL_CHAINLIGHTNING,2 // Chain Lightning
|
||||
WL_EARTHSTRAIN,2 // Earth Strain
|
||||
WL_TETRAVORTEX,2 // Tetra Vortex
|
||||
WL_SUMMONFB,2 // Summon Fire Ball
|
||||
WL_SUMMONBL,2 // Summon Lightning Ball
|
||||
WL_SUMMONWB,2 // Summon Water Ball
|
||||
WL_SUMMONSTONE,2 // Summon Stone
|
||||
WL_CHAINLIGHTNING_ATK,2 // Dummy skill for Chain Lightning
|
||||
WL_TETRAVORTEX_FIRE,2 // Dummy skill for Tetra Vortex
|
||||
WL_TETRAVORTEX_WATER,2 // Dummy skill for Tetra Vortex
|
||||
WL_TETRAVORTEX_WIND,2 // Dummy skill for Tetra Vortex
|
||||
WL_TETRAVORTEX_GROUND,2 // Dummy skill for Tetra Vortex
|
||||
WL_SUMMON_ATK_FIRE,2 // Dummy skill for Summon Fire Ball
|
||||
WL_SUMMON_ATK_WIND,2 // Dummy skill for Summon Lightning Ball
|
||||
WL_SUMMON_ATK_WATER,2 // Dummy skill for Summon Water Ball
|
||||
WL_SUMMON_ATK_GROUND,2 // Dummy skill for Summon Stone
|
||||
|
||||
// Ranger
|
||||
RA_ARROWSTORM,2 // Arrow Storm
|
||||
RA_AIMEDBOLT,2 // Aimed Bolt
|
||||
RA_CLUSTERBOMB,2 // Cluster Bomb
|
||||
RA_FIRINGTRAP,2 // Firing Trap
|
||||
RA_ICEBOUNDTRAP,2 // Icebound Trap
|
||||
|
||||
// Mechanic
|
||||
NC_MAGMA_ERUPTION,2 // Magma Eruption
|
||||
|
||||
// Shadow Chaser
|
||||
SC_FATALMENACE,2 // Fatal Menace
|
||||
SC_TRIANGLESHOT,2 // Triangle Shot
|
||||
SC_FEINTBOMB,2 // Feint Bomb
|
||||
|
||||
// Royal Guard
|
||||
LG_SHIELDPRESS,2 // Shield Press
|
||||
LG_SHIELDSPELL,2 // Shield Spell
|
||||
LG_EXEEDBREAK,2 // Exceed Break
|
||||
LG_MOONSLASHER,2 // Moon Slasher
|
||||
LG_EARTHDRIVE,2 // Earth Drive
|
||||
LG_OVERBRAND_BRANDISH,2 // Dummy skill for Over Brand
|
||||
LG_OVERBRAND_PLUSATK,2 // Dummy skill for Over Brand
|
||||
|
||||
// Sura
|
||||
SR_DRAGONCOMBO,2 // Dragon Combo
|
||||
SR_SKYNETBLOW,2 // Sky Net Blow
|
||||
SR_EARTHSHAKER,2 // Earth Shaker
|
||||
SR_TIGERCANNON,2 // Tiger Cannon
|
||||
SR_RAMPAGEBLASTER,2 // Rampage Blaster
|
||||
SR_KNUCKLEARROW,2 // Knuckle Arrow
|
||||
SR_WINDMILL,2 // Windmill
|
||||
SR_GATEOFHELL,2 // Gate of Hell
|
||||
SR_GENTLETOUCH_QUIET,2 // Gentle Touch - Quiet
|
||||
SR_HOWLINGOFLION,2 // Howling of Lion
|
||||
SR_RIDEINLIGHTNING,2 // Riding Lightning
|
||||
|
||||
// Minstrel/Wanderer
|
||||
WM_METALICSOUND,2 // Metallic Sound
|
||||
WM_REVERBERATION,2 // Reverberation
|
||||
WM_SEVERE_RAINSTORM,2 // Severe Rainstorm
|
||||
WM_SEVERE_RAINSTORM_MELEE,2 // Dummy skill for Severe Rainstorm
|
||||
WM_REVERBERATION_MELEE,2 // Dummy skill for Reverberation
|
||||
WM_REVERBERATION_MAGIC,2 // Dummy skill for Reverberation
|
||||
|
||||
// Sorcerer
|
||||
SO_FIREWALK,2 // Fire Walk
|
||||
SO_ELECTRICWALK,2 // Electric Walk
|
||||
SO_EARTHGRAVE,2 // Earth Grave
|
||||
SO_DIAMONDDUST,2 // Diamond Dust
|
||||
SO_POISON_BUSTER,2 // Poison Buster
|
||||
SO_PSYCHIC_WAVE,2 // Psychic Wave
|
||||
SO_CLOUD_KILL,2 // Cloud Kill
|
||||
SO_VARETYR_SPEAR,2 // Varetyr Spear
|
||||
|
||||
// Genetic
|
||||
GN_THORNS_TRAP,2 // Thorn Trap
|
||||
GN_BLOOD_SUCKER,2 // Blood Sucker
|
||||
GN_SPORE_EXPLOSION,2 // Spore Explosion
|
||||
GN_WALLOFTHORN,2 // Wall of Thorns
|
||||
GN_CRAZYWEED,2 // Crazy Weed
|
||||
GN_HELLS_PLANT,2 // Hell's Plant
|
||||
GN_CRAZYWEED_ATK,2 // Dummy skill for Crazy Weed
|
||||
GN_HELLS_PLANT_ATK,2 // Dummy skil for Hell's Plant
|
||||
GN_ILLUSIONDOPING,2 // Illusion Doping
|
||||
|
||||
// Kagerou/Oboro
|
||||
KO_MUCHANAGE,3 // Rapid Throw
|
140
db/skill_db.yml
Normal file
140
db/skill_db.yml
Normal file
@ -0,0 +1,140 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2019 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Skill Database
|
||||
###########################################################################
|
||||
#
|
||||
# Skill Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Unique skill ID.
|
||||
# Name Skill Aegis name.
|
||||
# Description Skill description.
|
||||
# MaxLevel Max skill level.
|
||||
# Type Skill type. (Default: None)
|
||||
# TargetType Skill target type. (Default: Passive)
|
||||
# DamageFlags: Skill damage properties.
|
||||
# Flags: Skill information flags.
|
||||
# Range: Skill range. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Range at specific skill level.
|
||||
# Hit Skill hit type. (Default: Normal)
|
||||
# HitCount: Skill hit count. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Count Number of hits at specific skill level.
|
||||
# Element: Skill element. (Default: Neutral)
|
||||
# - Level Skill level.
|
||||
# Element Element at specific skill level.
|
||||
# SplashArea: Skill splash area of effect. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Area Splash area at specific skill level.
|
||||
# ActiveInstance: Maximum amount of active skill instances that can be on the ground. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Max Active instances at specific skill level.
|
||||
# Knockback: Amount of tiles the skill knockbacks. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Knockback count at specific skill level.
|
||||
# CopyFlags: Determines if the skill is copyable. (Optional)
|
||||
# Skill: Type of skill that can copy.
|
||||
# RemoveRequirement: Remove a requirement type. (Optional)
|
||||
# NoNearNPC: Determines if the skill can be used near a NPC. (Optional)
|
||||
# AdditionalRange Number of cells from an NPC where the skill can be cast. (Optional)
|
||||
# Type: Type of NPC.
|
||||
# CastCancel Cancel cast when hit. (Default: true)
|
||||
# CastDefenseReduction Defense reduction rate during skill cast. (Default: 0)
|
||||
# CastTime: Time to cast the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Cast time at specific skill level in milliseconds.
|
||||
# AfterCastActDelay: Time the character cannot use skills in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast action delay at specific skill level in milliseconds.
|
||||
# AfterCastWalkDelay: Time before the character can move again in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast walk delay at specific skill level in milliseconds.
|
||||
# Duration1: Duration of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Skill duration at specific skill level in milliseconds.
|
||||
# Duration2: Duration of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Skill duration at specific skill level in milliseconds.
|
||||
# Cooldown: Time before the character can use the same skill again in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Cooldown at specific skill level in milliseconds.
|
||||
# FixedCastTime: Time that is fixed during cast of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast action delay at specific skill level in milliseconds.
|
||||
# CastTimeFlags: Effects of the skill's cast time. (Optional)
|
||||
# CastDelayFlags: Effects of the skill's delay. (Optional)
|
||||
# Requires: List of requirements to cast the skill. (Optional)
|
||||
# HpCost: HP required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount HP required at specific skill level.
|
||||
# SpCost: SP required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount SP required at specific skill level.
|
||||
# HpRateCost: HP rate required to cast. If positive, uses current HP, else uses Max HP. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount HP rate required at specific skill level.
|
||||
# SpRateCost: SP rate required to cast. If positive, uses current SP, else uses Max SP. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount SP rate required at specific skill level.
|
||||
# MaxHpTrigger: Maximum amount of HP to cast the skill. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Maximum HP trigger required at specific skill level.
|
||||
# ZenyCost: Zeny required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Zeny required at specific skill level.
|
||||
# Weapon: Weapon required to cast. (Default: All)
|
||||
# Ammo: Ammo required to cast. (Default: None)
|
||||
# AmmoAmount: Ammo amount required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Ammo amount required at specific skill level.
|
||||
# State Special state required to cast. (Default: None)
|
||||
# Status: Status change required to cast. (Default: nullptr)
|
||||
# SphereCost: Spirit sphere required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Spirit sphere required at specific skill level.
|
||||
# ItemCost: Item required to cast. (Default: 0)
|
||||
# - Item Item name.
|
||||
# Amount Item amount.
|
||||
# Equipment: Equipped item required to cast. (Default: nullptr)
|
||||
# Unit: Skill unit values. (Optional)
|
||||
# Id Skill unit ID.
|
||||
# AlternateId: Alternate skill unit ID. (Default: 0)
|
||||
# Layout: Skill unit layout. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Unit layout at specific skill level.
|
||||
# Range: Skill unit range. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Unit range at specific skill level.
|
||||
# Interval Skill unit interval in milliseconds. (Default: 0)
|
||||
# Target Skill unit target type. (Default: All)
|
||||
# Flag: Skill unit flags. (Default: None)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: SKILL_DB
|
||||
Version: 1
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
- Path: db/pre-re/skill_db.yml
|
||||
Mode: Prerenewal
|
||||
- Path: db/re/skill_db.yml
|
||||
Mode: Renewal
|
||||
- Path: db/import/skill_db.yml
|
@ -1,30 +0,0 @@
|
||||
// Skill Distance-to-NPC Database
|
||||
// Prevents skills from being used near NPC types using INF2_NO_NEARNPC.
|
||||
//
|
||||
// Structure of Database:
|
||||
// SkillName,AdditionalRange{,NPC Type}
|
||||
//
|
||||
// AdditionalRange:
|
||||
// Number of cells from an NPC where the skill can be cast.
|
||||
// If zero, this will read the splash range value from skill_db;
|
||||
// if that is also zero, range+layout's range from skill_unit_db will be used.
|
||||
//
|
||||
// NPC Type (bitmask):
|
||||
// 1 = warp portal, 2 = shop NPC, 4 = normal NPC script, 8 = tomb
|
||||
//
|
||||
// Examples:
|
||||
// MG_SAFETYWALL,2
|
||||
// Safety Wall can't be placed within 2 ground cells of an NPC.
|
||||
// (MG_SAFETYWALL doesn't have splash, layout range, and range value,
|
||||
// so we must add the 'additional_range', or it will be pointless.)
|
||||
//
|
||||
// GS_DESPERADO,2
|
||||
// Desperado can't be casted if the caster is standing within 5 cells of an NPC.
|
||||
// (Why? GS_DESPERADO has 3 cells of splash range +2 'additional_range' here.)
|
||||
//
|
||||
// SC_CHAOSPANIC,0,1
|
||||
// Chaos Panic can't be placed within 2 ground cells of a warp portal.
|
||||
// (Because SC_CHAOSPANIC doesn't have splash range, it uses layout range.)
|
||||
|
||||
SC_CHAOSPANIC,0,1
|
||||
SC_MAELSTROM,0,1
|
836
doc/skill_db.txt
Normal file
836
doc/skill_db.txt
Normal file
@ -0,0 +1,836 @@
|
||||
//===== rAthena Documentation ================================
|
||||
//= Skill Database Structure
|
||||
//===== By: ==================================================
|
||||
//= rAthena Dev Team
|
||||
//===== Last Updated: ========================================
|
||||
//= 20191220
|
||||
//===== Description: =========================================
|
||||
//= Explanation of the skill_db.yml file and structure.
|
||||
//============================================================
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Id: Unique skill ID.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Name: Skill Aegis name.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Description: Skill description.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
MaxLevel: Max skill level.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Type: Skill type.
|
||||
|
||||
None - No specific type. (Default)
|
||||
Weapon - Weapon type damage.
|
||||
Magic - Magic type damage.
|
||||
Misc - Misc type damage.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
TargetType: Skill target type.
|
||||
|
||||
Passive - Passive skill. (Default)
|
||||
Attack - Damage enemies.
|
||||
Ground - Ground placement skill.
|
||||
Self - Self cast skill.
|
||||
Support - Friendly cast skill.
|
||||
Trap - Trap cast skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
DamageFlags: Skill damage properties.
|
||||
|
||||
NoDamage - No damage skill. (Default)
|
||||
Splash - Has splash area.
|
||||
SplashSplit - Damage should be split among targets.
|
||||
IgnoreAtkCard - Skill ignores caster's % damage cards (Misc type always ignores).
|
||||
IgnoreElement - Skill ignores elemental adjustments.
|
||||
IgnoreDefense - Skill ignores target's defense (Misc type always ignores).
|
||||
IgnoreFlee - Skill ignores target's flee (Magic type always ignores)
|
||||
IgnoreDefCard - Skill ignores target's defense cards.
|
||||
Critical - Skill can critical.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Flags: Skill information flags.
|
||||
|
||||
IsQuest - Quest skill.
|
||||
IsNpc - NPC skill.
|
||||
IsWedding - Wedding skill.
|
||||
IsSpirit - Spirit skill.
|
||||
IsGuild - Guild skill.
|
||||
IsSong - Song/Dance skill.
|
||||
IsEnsemble - Ensemble skill.
|
||||
IsTrap - Trap skill.
|
||||
TargetSelf - Damages/targets self.
|
||||
NoTargetSelf - Cannot target self. If TargetType is Self_Skill, changes to Attack_Skill.
|
||||
PartyOnly - Usable on party (and enemies if offensive).
|
||||
GuildOnly - Usable on guild (and enemies if offensive).
|
||||
NoTargetEnemy - Disable on enemies (for non-offensive).
|
||||
IsShadowSpell - Make skill available for SC_AUTOSHADOWSPELL.
|
||||
IsChorus - Chorus skill.
|
||||
IgnoreBgReduction - Ignore Battleground reduction.
|
||||
IgnoreGvgReduction - Ignore GvG reduction.
|
||||
DisableNearNpc - Disable self/ground skills near NPC. In tandem with NoNearNpc node.
|
||||
TargetTrap - Damage traps. If TargetType is Trap.
|
||||
IgnoreLandProtector - Ignore SA_LANDPROTECTOR.
|
||||
AllowWhenHidden - Usable while hiding.
|
||||
AllowWhenPerforming - Usable while in dancing state.
|
||||
TargetEmperium - Damages/targets Emperium.
|
||||
IgnoreStasis - Ignore SC_STASIS.
|
||||
IgnoreKagehumi - Ignore KG_KAGEHUMI.
|
||||
AlterRangeVulture - Skill range affected by AC_VULTURE.
|
||||
AlterRangeSnakeEye - Skill range affected by GS_SNAKEEYE.
|
||||
AlterRangeShadowJump - Skill range affected by NJ_SHADOWJUMP.
|
||||
AlterRangeRadius - Skill range affected by WL_RADIUS.
|
||||
AlterRangeResearchTrap - Skill range affected by RA_RESEARCHTRAP.
|
||||
IgnoreHovering - Ignore SC_HOVERING.
|
||||
AllowOnWarg - Usable while riding Warg.
|
||||
AllowOnMado - Usable while on Madogear.
|
||||
TargetManHole - Target enemy with SC__MANHOLE.
|
||||
TargetHidden - Target enemy with OPTION_HIDE.
|
||||
IncreaseGloomyDayDamage - Increase SC_GLOOMYDAY_SK damage.
|
||||
IncreaseDanceWithWugDamage - Increase SC_DANCEWITHWUG damage.
|
||||
IgnoreWugBite - Ignore RA_WUGBITE.
|
||||
IgnoreAutoGuard - Not blocked by SC_AUTOGUARD (Weapon_Skill only).
|
||||
IgnoreCicada - Not blocked by SC_UTSUSEMI or SC_BUNSINJYUTSU (Weapon_Skill only).
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Range: Skill range. Combo skills do not check for range when used. If range is < 5 the skill is considered melee-range.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Range: 1
|
||||
|
||||
Sequence Map Form
|
||||
Range:
|
||||
- Level: 1
|
||||
Size: 1
|
||||
- Level: 2
|
||||
Size: 1
|
||||
- Level: 3
|
||||
Size: 2
|
||||
- Level: 4
|
||||
Size: 2
|
||||
- Level: 5
|
||||
Size: 3
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Hit: Skill hit type.
|
||||
|
||||
Normal - Passive/No damage skill. (Default)
|
||||
Single - Single hit.
|
||||
Repeat - Multiple hits.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
HitCount: Skill hit count. When positive the damage is increased by hits. Negative values the number of hits without increasing the total damage.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
HitCount: 1
|
||||
|
||||
Sequence Map Form
|
||||
HitCount:
|
||||
- Level: 1
|
||||
Count: 2
|
||||
- Level: 2
|
||||
Count: 4
|
||||
- Level: 3
|
||||
Count: 6
|
||||
- Level: 4
|
||||
Count: 8
|
||||
- Level: 5
|
||||
Count: 10
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Element: Skill element.
|
||||
|
||||
Neutral (Default)
|
||||
Water
|
||||
Earth
|
||||
Fire
|
||||
Wind
|
||||
Poison
|
||||
Holy
|
||||
Dark
|
||||
Ghost
|
||||
Undead
|
||||
Weapon - Uses weapon element.
|
||||
Endowed - Uses endowed element.
|
||||
Random - Uses random element.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Element: Fire
|
||||
|
||||
Sequence Map Form
|
||||
Element:
|
||||
- Level: 1
|
||||
Element: Neutral
|
||||
- Level: 2
|
||||
Element: Neutral
|
||||
- Level: 3
|
||||
Element: Poison
|
||||
- Level: 4
|
||||
Element: Poison
|
||||
- Level: 5
|
||||
Element: Poison
|
||||
|
||||
---------------------------------------
|
||||
|
||||
SplashArea: Skill splash area of effect.
|
||||
|
||||
-1 - Screen-wide.
|
||||
0 - No splash.
|
||||
All other values follow the formula: value * 2 + 1
|
||||
1 - 3x3
|
||||
2 - 5x5
|
||||
3 - 7x7
|
||||
4 - 9x9
|
||||
5 - 11x11
|
||||
6 - 13x13
|
||||
7 - 15x15
|
||||
8 - 17x17
|
||||
9 - 19x19
|
||||
10 - 21x21
|
||||
11 - 23x32
|
||||
12 - 25x25
|
||||
13 - 27x27
|
||||
14 - 29x29
|
||||
15 - 31x31
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
SplashArea: 1
|
||||
|
||||
Sequence Map Form
|
||||
SplashArea:
|
||||
- Level: 1
|
||||
Area: 1
|
||||
- Level: 2
|
||||
Area: 1
|
||||
- Level: 3
|
||||
Area: 2
|
||||
- Level: 4
|
||||
Area: 2
|
||||
- Level: 5
|
||||
Area: 3
|
||||
|
||||
---------------------------------------
|
||||
|
||||
ActiveInstance: Maximum amount of active skill instances that can be on the ground.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
ActiveInstance: 1
|
||||
|
||||
Sequence Map Form
|
||||
ActiveInstance:
|
||||
- Level: 1
|
||||
Max: 1
|
||||
- Level: 2
|
||||
Max: 1
|
||||
- Level: 3
|
||||
Max: 2
|
||||
- Level: 4
|
||||
Max: 2
|
||||
- Level: 5
|
||||
Max: 3
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Knockback: Amount of tiles the skill knockbacks.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Knockback: 1
|
||||
|
||||
Sequence Map Form
|
||||
Range:
|
||||
- Level: 1
|
||||
Amount: 1
|
||||
- Level: 2
|
||||
Amount: 1
|
||||
- Level: 3
|
||||
Amount: 2
|
||||
- Level: 4
|
||||
Amount: 2
|
||||
- Level: 5
|
||||
Amount: 3
|
||||
|
||||
---------------------------------------
|
||||
|
||||
CopyFlags: Determines if the skill is copyable.
|
||||
|
||||
Skill - Type of skill that can copy.
|
||||
Plagiarism
|
||||
Reproduce
|
||||
RemoveRequirement - Ability to remove skill cast requirement.
|
||||
HpCost
|
||||
SpCost
|
||||
HpRateCost
|
||||
SpRateCost
|
||||
MaxHpTrigger
|
||||
ZenyCost
|
||||
Weapon
|
||||
Ammo
|
||||
State
|
||||
Status
|
||||
SpiritSphereCost
|
||||
ItemCost
|
||||
Equipment
|
||||
|
||||
---------------------------------------
|
||||
|
||||
NoNearNPC: Determines if the skill can be used near a NPC.
|
||||
|
||||
AdditionalRange - Number of cells from an NPC where the skill can be cast.
|
||||
If zero this will read the splash range value.
|
||||
If that is also zero then Unit Range + Unit Layout Range will be used.
|
||||
|
||||
Type - Type of NPC that will block the skill.
|
||||
WarpPortal
|
||||
Shop
|
||||
Npc
|
||||
Tomb
|
||||
|
||||
---------------------------------------
|
||||
|
||||
CastCancel: Cancel cast when hit.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
CastDefenseReduction: Defense reduction rate during skill cast.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
CastTime: Time to cast the skill in milliseconds.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
CastTime: 1000
|
||||
|
||||
Sequence Map Form
|
||||
CastTime:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 2000
|
||||
- Level: 3
|
||||
Time: 3000
|
||||
- Level: 4
|
||||
Time: 4000
|
||||
- Level: 5
|
||||
Time: 5000
|
||||
|
||||
---------------------------------------
|
||||
|
||||
AfterCastActDelay: Time the character cannot use skills in milliseconds.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
AfterCastActDelay: 1000
|
||||
|
||||
Sequence Map Form
|
||||
AfterCastActDelay:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 2000
|
||||
- Level: 3
|
||||
Time: 3000
|
||||
- Level: 4
|
||||
Time: 4000
|
||||
- Level: 5
|
||||
Time: 5000
|
||||
|
||||
---------------------------------------
|
||||
|
||||
AfterCastWalkDelay: Time before the character can move again in milliseconds.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
AfterCastWalkDelay: 1000
|
||||
|
||||
Sequence Map Form
|
||||
AfterCastWalkDelay:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 2000
|
||||
- Level: 3
|
||||
Time: 3000
|
||||
- Level: 4
|
||||
Time: 4000
|
||||
- Level: 5
|
||||
Time: 5000
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Duration1: Duration of the skill in milliseconds.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Duration1: 1000
|
||||
|
||||
Sequence Map Form
|
||||
Duration1:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 2000
|
||||
- Level: 3
|
||||
Time: 3000
|
||||
- Level: 4
|
||||
Time: 4000
|
||||
- Level: 5
|
||||
Time: 5000
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Duration2: Duration of the skill in milliseconds.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Duration2: 1000
|
||||
|
||||
Sequence Map Form
|
||||
Duration2:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 2000
|
||||
- Level: 3
|
||||
Time: 3000
|
||||
- Level: 4
|
||||
Time: 4000
|
||||
- Level: 5
|
||||
Time: 5000
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Cooldown: Time before the character can use the same skill again in milliseconds.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Cooldown: 1000
|
||||
|
||||
Sequence Map Form
|
||||
Cooldown:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 2000
|
||||
- Level: 3
|
||||
Time: 3000
|
||||
- Level: 4
|
||||
Time: 4000
|
||||
- Level: 5
|
||||
Time: 5000
|
||||
|
||||
---------------------------------------
|
||||
|
||||
FixedCastTime: Time that is fixed during cast of the skill in milliseconds.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
FixedCastTime: 1000
|
||||
|
||||
Sequence Map Form
|
||||
FixedCastTime:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 2000
|
||||
- Level: 3
|
||||
Time: 3000
|
||||
- Level: 4
|
||||
Time: 4000
|
||||
- Level: 5
|
||||
Time: 5000
|
||||
|
||||
---------------------------------------
|
||||
|
||||
CastTimeFlags: Effects of the skill's cast time.
|
||||
|
||||
IgnoreDex - Cast time not affected by DEX.
|
||||
IgnoreStatus - Cast time not affected by statuses (Suffragium, etc).
|
||||
IgnoreItemBonus - Cast time not affected by item bonuses.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
CastDelayFlags: Effects of the skill's delay.
|
||||
|
||||
IgnoreDex - Delay not affected by DEX.
|
||||
IgnoreStatus - Delay not affected by statuses (Suffragium, etc).
|
||||
IgnoreItemBonus - Delay not affected by item bonuses.
|
||||
|
||||
IgnoreDex only makes sense when battle_config::delay_dependon_dex is enabled.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Requires: List of requirements to cast the skill.
|
||||
|
||||
HpCost: HP required to cast.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
HpCost: 10
|
||||
|
||||
Sequence Map Form
|
||||
HpCost:
|
||||
- Level: 1
|
||||
Amount: 10
|
||||
- Level: 2
|
||||
Amount: 20
|
||||
- Level: 3
|
||||
Amount: 30
|
||||
- Level: 4
|
||||
Amount: 40
|
||||
- Level: 5
|
||||
Amount: 50
|
||||
|
||||
------------------
|
||||
|
||||
SpCost: SP required to cast.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
SpCost: 10
|
||||
|
||||
Sequence Map Form
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 10
|
||||
- Level: 2
|
||||
Amount: 20
|
||||
- Level: 3
|
||||
Amount: 30
|
||||
- Level: 4
|
||||
Amount: 40
|
||||
- Level: 5
|
||||
Amount: 50
|
||||
|
||||
------------------
|
||||
|
||||
HpRateCost: HP rate required to cast. If positive, uses current HP, else uses Max HP.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
HpRateCost: 10
|
||||
|
||||
Sequence Map Form
|
||||
HpRateCost:
|
||||
- Level: 1
|
||||
Amount: 10
|
||||
- Level: 2
|
||||
Amount: 20
|
||||
- Level: 3
|
||||
Amount: 30
|
||||
- Level: 4
|
||||
Amount: 40
|
||||
- Level: 5
|
||||
Amount: 50
|
||||
|
||||
------------------
|
||||
|
||||
SpRateCost: SP rate required to cast. If positive, uses current SP, else uses Max SP.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
SpRateCost: 10
|
||||
|
||||
Sequence Map Form
|
||||
SpRateCost:
|
||||
- Level: 1
|
||||
Amount: 10
|
||||
- Level: 2
|
||||
Amount: 20
|
||||
- Level: 3
|
||||
Amount: 30
|
||||
- Level: 4
|
||||
Amount: 40
|
||||
- Level: 5
|
||||
Amount: 50
|
||||
|
||||
------------------
|
||||
|
||||
MaxHpTrigger: Maximum amount of HP to cast the skill.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
MaxHpTrigger: 10
|
||||
|
||||
Sequence Map Form
|
||||
MaxHpTrigger:
|
||||
- Level: 1
|
||||
Amount: 10
|
||||
- Level: 2
|
||||
Amount: 20
|
||||
- Level: 3
|
||||
Amount: 30
|
||||
- Level: 4
|
||||
Amount: 40
|
||||
- Level: 5
|
||||
Amount: 50
|
||||
|
||||
------------------
|
||||
|
||||
ZenyCost: Zeny required to cast.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
ZenyCost: 10
|
||||
|
||||
Sequence Map Form
|
||||
ZenyCost:
|
||||
- Level: 1
|
||||
Amount: 10
|
||||
- Level: 2
|
||||
Amount: 20
|
||||
- Level: 3
|
||||
Amount: 30
|
||||
- Level: 4
|
||||
Amount: 40
|
||||
- Level: 5
|
||||
Amount: 50
|
||||
|
||||
------------------
|
||||
|
||||
Weapon: Weapon required to cast.
|
||||
|
||||
All (Default)
|
||||
Fist
|
||||
Dagger
|
||||
1hSword
|
||||
2hSword
|
||||
1hSpear
|
||||
2hSpear
|
||||
1hAxe
|
||||
2hAxe
|
||||
Mace
|
||||
2hMace
|
||||
Staff
|
||||
Bow
|
||||
Knuckle
|
||||
Musical
|
||||
Whip
|
||||
Book
|
||||
Katar
|
||||
Revolver
|
||||
Rifle
|
||||
Gatling
|
||||
Shotgun
|
||||
Grenade
|
||||
Huuma
|
||||
2hStaff
|
||||
|
||||
------------------
|
||||
|
||||
Ammo: Ammo required to cast.
|
||||
|
||||
None (Default)
|
||||
Arrow
|
||||
Dagger
|
||||
Bullet
|
||||
Shell
|
||||
Grenade
|
||||
Shuriken
|
||||
Kunai
|
||||
Cannonball
|
||||
Throwweapon
|
||||
|
||||
------------------
|
||||
|
||||
AmmoAmount: Ammo amount required to cast.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
AmmoAmount: 10
|
||||
|
||||
Sequence Map Form
|
||||
AmmoAmount:
|
||||
- Level: 1
|
||||
Amount: 1
|
||||
- Level: 2
|
||||
Amount: 2
|
||||
- Level: 3
|
||||
Amount: 3
|
||||
- Level: 4
|
||||
Amount: 4
|
||||
- Level: 5
|
||||
Amount: 5
|
||||
|
||||
------------------
|
||||
|
||||
State: Special state required to cast.
|
||||
|
||||
None - No special state required.
|
||||
Hidden - Requires OPTION_HIDE, OPTION_CLOAK, or OPTION_CHASEWALK.
|
||||
Riding - Requires OPTION_RIDING or OPTION_DRAGON.
|
||||
Falcon - Requires OPTION_FALCON.
|
||||
Cart - Requires OPTION_CART for pre-renewal or SC_PUSH_CART for renewal.
|
||||
Shield - Requires a shield to be equipped.
|
||||
Recover_Weight_Rate - Requires weight to be less than 50% for pre-renewal or 70% for renewal.
|
||||
Move_Enable - Requires to be able to move.
|
||||
Water - Requires to be standing in water.
|
||||
RidingDragon - Requires OPTION_DRAGON.
|
||||
Wug - Requires OPTION_WUG.
|
||||
RidingWug - Requires OPTION_WUGRIDER.
|
||||
Mado - Requires OPTION_MADOGEAR.
|
||||
ElementalSpirit - Requires an Elemental Spirit to be summoned.
|
||||
ElementalSpirit2 - Requires an Elemental Spirit to be summoned and will be removed after.
|
||||
Peco - Requires OPTION_RIDING.
|
||||
|
||||
------------------
|
||||
|
||||
Status: Status change required to cast.
|
||||
|
||||
For a full list, see src/map/status.hpp::sc_type.
|
||||
|
||||
------------------
|
||||
|
||||
SphereCost: Spirit sphere required to cast.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
SphereCost: 10
|
||||
|
||||
Sequence Map Form
|
||||
SphereCost:
|
||||
- Level: 1
|
||||
Amount: 1
|
||||
- Level: 2
|
||||
Amount: 2
|
||||
- Level: 3
|
||||
Amount: 3
|
||||
- Level: 4
|
||||
Amount: 4
|
||||
- Level: 5
|
||||
Amount: 5
|
||||
|
||||
------------------
|
||||
|
||||
ItemCost: Item required to cast.
|
||||
|
||||
------------------
|
||||
|
||||
Equipment: Equipped item required to cast.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Unit: Skill unit values.
|
||||
|
||||
Id: Skill unit ID.
|
||||
|
||||
For a full list, see src/map/skill.hpp::e_skill_unit_id.
|
||||
|
||||
------------------
|
||||
|
||||
AlternateId: Alternate skill unit ID.
|
||||
|
||||
For a full list, see src/map/skill.hpp::e_skill_unit_id.
|
||||
|
||||
------------------
|
||||
|
||||
Layout: Skill unit layout.
|
||||
|
||||
-1 - Screen-wide.
|
||||
0 - No splash.
|
||||
All other values follow the formula: value * 2 + 1
|
||||
1 - 3x3
|
||||
2 - 5x5
|
||||
3 - 7x7
|
||||
4 - 9x9
|
||||
5 - 11x11
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Layout: 10
|
||||
|
||||
Sequence Map Form
|
||||
Layout:
|
||||
- Level: 1
|
||||
Size: 1
|
||||
- Level: 2
|
||||
Size: 2
|
||||
- Level: 3
|
||||
Size: 3
|
||||
- Level: 4
|
||||
Size: 4
|
||||
- Level: 5
|
||||
Size: 5
|
||||
|
||||
------------------
|
||||
|
||||
Range: Skill unit range.
|
||||
|
||||
Can be defined in scalar form or sequence map form:
|
||||
Scalar Form
|
||||
Range: 10
|
||||
|
||||
Sequence Map Form
|
||||
Range:
|
||||
- Level: 1
|
||||
Size: 1
|
||||
- Level: 2
|
||||
Size: 2
|
||||
- Level: 3
|
||||
Size: 3
|
||||
- Level: 4
|
||||
Size: 4
|
||||
- Level: 5
|
||||
Size: 5
|
||||
|
||||
------------------
|
||||
|
||||
Interval: Skill unit interval in milliseconds.
|
||||
|
||||
------------------
|
||||
|
||||
Target: Skill unit target type.
|
||||
|
||||
Friend - Targets Party, Guild, Guild Allies, and neutral players.
|
||||
Party - Targets Party.
|
||||
Ally - Targets Party and Guild and Guild Allies.
|
||||
Guild - Targets Guild and Guild Allies.
|
||||
All - Targets all. (Default)
|
||||
Enemy - Targets enemy.
|
||||
Self - Targets self.
|
||||
SameGuild - Targets Guild but not Guild Allies.
|
||||
|
||||
------------------
|
||||
|
||||
Flag: Skill unit flags.
|
||||
|
||||
None - No flags.
|
||||
NoEnemy - If battle_config::defunit_not_enemy is enabled, the Target is changed to Friend.
|
||||
NoReiteration - Spell cannot be stacked.
|
||||
NoFootSet - Spell cannot be cast near/on targets.
|
||||
NoOverlap - Spell effects do not overlap.
|
||||
PathCheck - Only cells with a shootable path will be placed.
|
||||
NoPc - Spell cannot affect players.
|
||||
NoMob - Spell cannot affect mobs.
|
||||
Skill - Spell can affect skills.
|
||||
Dance - Dance unit.
|
||||
Ensemble - Duet unit.
|
||||
Song - Song unit.
|
||||
DualMode - Spell has effects both at an interval and when you step in/out.
|
||||
NoKnockback - Cannot be knocked back (only unit that can be damaged).
|
||||
RangedSingleUnit - Layout hack, use layout range property but only display center.
|
||||
CrazyWeedImmune - Immune to GN_CRAZYWEED.
|
||||
RemovedByFireRain - Removed by RL_FIRE_RAIN.
|
||||
KnockbackGroup - Knock back a whole skill group (by default, skill unit is knocked back by each unit).
|
||||
HiddenTrap - Hidden trap. See battle_config::traps_setting to enable this flag.
|
@ -1,163 +0,0 @@
|
||||
//===== rAthena Documentation ================================
|
||||
//= rAthena Skill Requirement Reference
|
||||
//===== By: ==================================================
|
||||
//= rAthena Dev Team
|
||||
//===== Last Updated: ========================================
|
||||
//= 20140831
|
||||
//===== Description: =========================================
|
||||
//= Explanation of the skill_require_db.txt file and structure.
|
||||
//============================================================
|
||||
|
||||
Structure:
|
||||
SkillID,HPCost,MaxHPTrigger,SPCost,HPRateCost,SPRateCost,ZenyCost,RequiredWeapons,RequiredAmmoTypes,RequiredAmmoAmount,RequiredState,RequiredStatuses,SpiritSphereCost,RequiredItemID1,RequiredItemAmount1,RequiredItemID2,RequiredItemAmount2,RequiredItemID3,RequiredItemAmount3,RequiredItemID4,RequiredItemAmount4,RequiredItemID5,RequiredItemAmount5,RequiredItemID6,RequiredItemAmount6,RequiredItemID7,RequiredItemAmount7,RequiredItemID8,RequiredItemAmount8,RequiredItemID9,RequiredItemAmount9,RequiredItemID10,RequiredItemAmount10,RequiredEquipment
|
||||
|
||||
---------------------------------------
|
||||
|
||||
SkillID: The ID of the skill.
|
||||
See 'db\(pre-)re\skill_db.txt' for more details.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
HPCost: Amount of HP needed to use the skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
MaxHPTrigger: Player's HP must be below this % of Max HP in order to use the skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
SPCost: Amount of SP needed to use the skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
HPRateCost: If more than 0, the percentage of the player's current HP.
|
||||
If less than 0, the percentage of the player's Max HP.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
SPRateCost: If more than 0, the percentage of the player's current SP.
|
||||
If less than 0, the percentage of the player's Max SP.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
ZenyCost: Amount of Zeny needed to use the skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredWeapons: Weapon type needed to use the skill.
|
||||
0: bare fist
|
||||
1: Daggers
|
||||
2: One-handed swords
|
||||
3: Two-handed swords
|
||||
4: One-handed spears
|
||||
5: Two-handed spears
|
||||
6: One-handed axes
|
||||
7: Two-handed axes
|
||||
8: Maces
|
||||
9: Unused
|
||||
10: Staves
|
||||
11: Bows
|
||||
12: Knuckles
|
||||
13: Musical Instruments
|
||||
14: Whips
|
||||
15: Books
|
||||
16: Katars
|
||||
17: Revolvers
|
||||
18: Rifles
|
||||
19: Gatling guns
|
||||
20: Shotguns
|
||||
21: Grenade launchers
|
||||
22: Fuuma Shurikens
|
||||
23: Two-handed staves
|
||||
24: Max Type
|
||||
25: Dual-wield Daggers
|
||||
26: Dual-wield Swords
|
||||
27: Dual-wield Axes
|
||||
28: Dagger + Sword
|
||||
29: Dagger + Axe
|
||||
30: Sword + Axe
|
||||
|
||||
Up to 30 ':'-separated values can be used, e.g.
|
||||
type1:type2:type3
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredAmmoTypes: Ammo type needed to use the skill.
|
||||
1: Arrows
|
||||
2: Throwable daggers
|
||||
3: Bullets
|
||||
4: Shells
|
||||
5: Grenades
|
||||
6: Shuriken
|
||||
7: Kunai
|
||||
8: Cannonballs
|
||||
9: Throwable Items (Sling Item)
|
||||
|
||||
Up to 9 ':'-separated values can be used, e.g.
|
||||
type1:type2:type3
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredAmmoAmount: Amount of ammo needed to use the skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredState: The active 'State' needed to use the skill.
|
||||
|
||||
none = Nothing.
|
||||
hidden = Requires hidden status by using Hiding, Cloaking, or Chasewalk.
|
||||
riding = Requires the player to ride either a Peco or a Dragon.
|
||||
falcon = Requires a Falcon.
|
||||
cart = Requires a Pushcart.
|
||||
For renewal, this state can be replaced by SC_PUSH_CART in 'RequiredStatuses' field.
|
||||
shield = Requires an equipped shield.
|
||||
recover_weight_rate = Requires to be less than 50% weight.
|
||||
move_enable = Requires to be able to move.
|
||||
water = Requires to be standing on a water cell.
|
||||
dragon = Requires to ride a Dragon.
|
||||
warg = Requires a Warg.
|
||||
ridingwarg = Requires to ride a Warg.
|
||||
mado = Requires to have an active Mado.
|
||||
elementalspirit = Requires to have an Elemental Spirit summoned.
|
||||
peco = Requires riding a Peco.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredStatuses: The active statuses needed to use the skill.
|
||||
|
||||
Up to 3 ':'-separated values can be used, e.g.
|
||||
SC_STATUS1:SC_STATUS2:SC_STATUS3
|
||||
|
||||
See MAX_SKILL_STATUS_REQUIRE in 'src/map/skill.hpp' to modify the max number
|
||||
of possible values, and 'src/map/script_constants.hpp' for a list of status constants.
|
||||
|
||||
Use any number or SC_ALL to disable status requirements.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
SpiritSphereCost: Amount of Spirit Sphere needed to use the skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredItemID1..10: Items to be consumed when the skill is used (max 10).
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredItemAmount1..10: Amount of each item consumed when the skill is used.
|
||||
If 0, the item is required to be in the inventory but won't be consumed.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
RequiredEquipment: Specific equipment IDs needed to use the skill.
|
||||
|
||||
Up to 10 ':'-separated values can be used, e.g.
|
||||
item1:item2:item3
|
||||
|
||||
See MAX_SKILL_EQUIP_REQUIRE in 'src/map/skill.hpp' to modify the max number
|
||||
of possible values.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
NOTE: On some fields, the ':' delimiter means for each skill level, but there
|
||||
are some level dependent checks. See 'skill_get_requirement()' in
|
||||
'src/map/skill.cpp'.
|
111
doc/yaml/db/skill_db.yml
Normal file
111
doc/yaml/db/skill_db.yml
Normal file
@ -0,0 +1,111 @@
|
||||
###########################################################################
|
||||
# Skill Database
|
||||
###########################################################################
|
||||
#
|
||||
# Skill Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Unique skill ID.
|
||||
# Name Skill Aegis name.
|
||||
# Description Skill description.
|
||||
# MaxLevel Max skill level.
|
||||
# Type Skill type. (Default: None)
|
||||
# TargetType Skill target type. (Default: Passive_Skill)
|
||||
# DamageFlags: Skill damage properties.
|
||||
# Flags: Skill information flags.
|
||||
# Range: Skill range. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Range at specific skill level.
|
||||
# Hit Skill hit type. (Default: Normal)
|
||||
# HitCount: Skill hit count. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Count Number of hits at specific skill level.
|
||||
# Element: Skill element. (Default: Neutral)
|
||||
# - Level Skill level.
|
||||
# Element Element at specific skill level.
|
||||
# SplashArea: Skill splash area of effect. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Area Splash area at specific skill level.
|
||||
# ActiveInstance: Maximum amount of active skill instances that can be on the ground. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Max Active instances at specific skill level.
|
||||
# Knockback: Amount of tiles the skill knockbacks. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Knockback count at specific skill level.
|
||||
# CopyFlags: Determines if the skill is copyable. (Optional)
|
||||
# Skill: Type of skill that can copy.
|
||||
# RemoveRequirement: Remove a requirement type. (Optional)
|
||||
# NoNearNPC: Determines if the skill can be used near a NPC. (Optional)
|
||||
# AdditionalRange Number of cells from an NPC where the skill can be cast. (Optional)
|
||||
# Type: Type of NPC.
|
||||
# CastCancel Cancel cast when hit. (Default: true)
|
||||
# CastDefenseReduction Defense reduction rate during skill cast. (Default: 0)
|
||||
# CastTime: Time to cast the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Cast time at specific skill level in milliseconds.
|
||||
# AfterCastActDelay: Time the character cannot use skills in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast action delay at specific skill level in milliseconds.
|
||||
# AfterCastWalkDelay: Time before the character can move again in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast walk delay at specific skill level in milliseconds.
|
||||
# Duration1: Duration of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Skill duration at specific skill level in milliseconds.
|
||||
# Duration2: Duration of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Skill duration at specific skill level in milliseconds.
|
||||
# Cooldown: Time before the character can use the same skill again in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time Cooldown at specific skill level in milliseconds.
|
||||
# FixedCastTime: Time that is fixed during cast of the skill in milliseconds. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Time After cast action delay at specific skill level in milliseconds.
|
||||
# CastTimeFlags: Effects of the skill's cast time. (Optional)
|
||||
# CastDelayFlags: Effects of the skill's delay. (Optional)
|
||||
# Requires: List of requirements to cast the skill. (Optional)
|
||||
# HpCost: HP required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount HP required at specific skill level.
|
||||
# SpCost: SP required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount SP required at specific skill level.
|
||||
# HpRateCost: HP rate required to cast. If positive, uses current HP, else uses Max HP. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount HP rate required at specific skill level.
|
||||
# SpRateCost: SP rate required to cast. If positive, uses current SP, else uses Max SP. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount SP rate required at specific skill level.
|
||||
# MaxHpTrigger: Maximum amount of HP to cast the skill. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Maximum HP trigger required at specific skill level.
|
||||
# ZenyCost: Zeny required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Zeny required at specific skill level.
|
||||
# Weapon: Weapon required to cast. (Default: All)
|
||||
# Ammo: Ammo required to cast. (Default: None)
|
||||
# AmmoAmount: Ammo amount required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Ammo amount required at specific skill level.
|
||||
# State Special state required to cast. (Default: None)
|
||||
# Status: Status change required to cast. (Default: nullptr)
|
||||
# SphereCost: Spirit sphere required to cast. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Amount Spirit sphere required at specific skill level.
|
||||
# ItemCost: Item required to cast. (Default: 0)
|
||||
# - Item Item name.
|
||||
# Amount Item amount.
|
||||
# Equipment: Equipped item required to cast. (Default: nullptr)
|
||||
# Unit: Skill unit values. (Optional)
|
||||
# Id Skill unit ID.
|
||||
# AlternateId: Alternate skill unit ID. (Default: 0)
|
||||
# Layout: Skill unit layout. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Unit layout at specific skill level.
|
||||
# Range: Skill unit range. (Default: 0)
|
||||
# - Level Skill level.
|
||||
# Size Unit range at specific skill level.
|
||||
# Interval Skill unit interval in milliseconds. (Default: 0)
|
||||
# Target Skill unit target type. (Default: All)
|
||||
# Flag: Skill unit flags. (Default: None)
|
||||
###########################################################################
|
@ -125,9 +125,15 @@ bool YamlDatabase::load(const std::string& path) {
|
||||
|
||||
this->parseImports( rootNode );
|
||||
|
||||
this->loadingFinished();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void YamlDatabase::loadingFinished(){
|
||||
// Does nothing by default, just for hooking
|
||||
}
|
||||
|
||||
void YamlDatabase::parse( const YAML::Node& rootNode ){
|
||||
uint64 count = 0;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define DATABASE_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
@ -50,6 +51,8 @@ protected:
|
||||
bool asUInt16Rate(const YAML::Node& node, const std::string& name, uint16& out, uint16 maximum=10000);
|
||||
bool asUInt32Rate(const YAML::Node& node, const std::string& name, uint32& out, uint32 maximum=10000);
|
||||
|
||||
virtual void loadingFinished();
|
||||
|
||||
public:
|
||||
YamlDatabase( const std::string type_, uint16 version_, uint16 minimumVersion_ ){
|
||||
this->type = type_;
|
||||
@ -93,7 +96,7 @@ public:
|
||||
return this->find( key ) != nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<datatype> find( keytype key ){
|
||||
virtual std::shared_ptr<datatype> find( keytype key ){
|
||||
auto it = this->data.find( key );
|
||||
|
||||
if( it != this->data.end() ){
|
||||
@ -128,4 +131,59 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename keytype, typename datatype> class TypesafeCachedYamlDatabase : public TypesafeYamlDatabase<keytype, datatype>{
|
||||
private:
|
||||
std::vector<std::shared_ptr<datatype>> cache;
|
||||
|
||||
public:
|
||||
TypesafeCachedYamlDatabase( const std::string type_, uint16 version_, uint16 minimumVersion_ ) : TypesafeYamlDatabase<keytype, datatype>( type_, version_, minimumVersion_ ){
|
||||
|
||||
}
|
||||
|
||||
TypesafeCachedYamlDatabase( const std::string& type_, uint16 version_ ) : TypesafeYamlDatabase<keytype, datatype>( type_, version_, version_ ){
|
||||
|
||||
}
|
||||
|
||||
void clear() override{
|
||||
TypesafeYamlDatabase<keytype, datatype>::clear();
|
||||
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
std::shared_ptr<datatype> find( keytype key ) override{
|
||||
if( this->cache.empty() || key >= this->cache.capacity() ){
|
||||
return TypesafeYamlDatabase<keytype, datatype>::find( key );
|
||||
}else{
|
||||
return cache[this->calculateCacheKey( key )];
|
||||
}
|
||||
}
|
||||
|
||||
virtual size_t calculateCacheKey( keytype key ){
|
||||
return key;
|
||||
}
|
||||
|
||||
void loadingFinished() override{
|
||||
// Cache all known values
|
||||
for (auto &pair : *this) {
|
||||
// Calculate the key that should be used
|
||||
size_t key = this->calculateCacheKey(pair.first);
|
||||
|
||||
// Check if the key fits into the current cache size
|
||||
if (this->cache.capacity() < key) {
|
||||
// Double the current size, so we do not have to resize that often
|
||||
size_t new_size = key * 2;
|
||||
|
||||
// Very important => initialize everything to nullptr
|
||||
this->cache.resize(new_size, nullptr);
|
||||
}
|
||||
|
||||
// Insert the value into the cache
|
||||
this->cache[key] = pair.second;
|
||||
}
|
||||
|
||||
// Free the memory that was allocated too much
|
||||
this->cache.shrink_to_fit();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* DATABASE_HPP */
|
||||
|
@ -4,10 +4,12 @@
|
||||
#ifndef UTILILITIES_HPP
|
||||
#define UTILILITIES_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "cbasetypes.hpp"
|
||||
#include "random.hpp"
|
||||
@ -135,6 +137,31 @@ namespace rathena {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator element
|
||||
* @param vec: Vector to search through
|
||||
* @param value: Value wanted
|
||||
* @return Key value iterator on success or vector end iterator on failure
|
||||
*/
|
||||
template <typename K, typename V> typename std::vector<K>::iterator vector_get(std::vector<K> &vec, V key) {
|
||||
return std::find(vec.begin(), vec.end(), key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a value exists in the vector
|
||||
* @param vec: Vector to search through
|
||||
* @param value: Value wanted
|
||||
* @return True on success or false on failure
|
||||
*/
|
||||
template <typename K, typename V> bool vector_exists(std::vector<K> &vec, V value) {
|
||||
auto it = std::find(vec.begin(), vec.end(), value);
|
||||
|
||||
if (it != vec.end())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool safe_addition( int64 a, int64 b, int64& result );
|
||||
bool safe_substraction( int64 a, int64 b, int64& result );
|
||||
bool safe_multiplication( int64 a, int64 b, int64& result );
|
||||
|
@ -3401,7 +3401,7 @@ ACMD_FUNC(questskill)
|
||||
clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
|
||||
return -1;
|
||||
}
|
||||
if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
|
||||
if (!skill_get_inf2(skill_id, INF2_ISQUEST)) {
|
||||
clif_displaymessage(fd, msg_txt(sd,197)); // This skill number doesn't exist or isn't a quest skill.
|
||||
return -1;
|
||||
}
|
||||
@ -3445,7 +3445,7 @@ ACMD_FUNC(lostskill)
|
||||
clif_displaymessage(fd, msg_txt(sd,198)); // This skill number doesn't exist.
|
||||
return -1;
|
||||
}
|
||||
if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
|
||||
if (!skill_get_inf2(skill_id, INF2_ISQUEST)) {
|
||||
clif_displaymessage(fd, msg_txt(sd,197)); // This skill number doesn't exist or isn't a quest skill.
|
||||
return -1;
|
||||
}
|
||||
@ -5754,9 +5754,6 @@ ACMD_FUNC(clearcart)
|
||||
#define MAX_SKILLID_PARTIAL_RESULTS_LEN 74 // "skill " (6) + "%d:" (up to 5) + "%s" (up to 30) + " (%s)" (up to 33)
|
||||
ACMD_FUNC(skillid) {
|
||||
int skillen, i, found = 0;
|
||||
DBIterator* iter;
|
||||
DBKey key;
|
||||
DBData *data;
|
||||
char partials[MAX_SKILLID_PARTIAL_RESULTS][MAX_SKILLID_PARTIAL_RESULTS_LEN];
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
@ -5768,20 +5765,20 @@ ACMD_FUNC(skillid) {
|
||||
|
||||
skillen = strlen(message);
|
||||
|
||||
iter = db_iterator(skilldb_name2id);
|
||||
for(const auto & skill : skill_db) {
|
||||
uint16 skill_id = skill.second->nameid;
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
const char *name = skill.second->name;
|
||||
const char *desc = skill.second->desc;
|
||||
|
||||
for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) {
|
||||
int idx = skill_get_index(db_data2i(data));
|
||||
if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill_db[idx]->desc, message, skillen) == 0) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1164), db_data2i(data), skill_db[idx]->desc, key.str); // skill %d: %s (%s)
|
||||
if (strnicmp(name, message, skillen) == 0 || strnicmp(desc, message, skillen) == 0) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1164), skill_id, desc, name); // skill %d: %s (%s)
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
} else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill_db[idx]->desc,message) ) ) {
|
||||
snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(sd,1164), db_data2i(data), skill_db[idx]->desc, key.str); // // skill %d: %s (%s)
|
||||
} else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(name,message) || stristr(desc,message) ) ) {
|
||||
snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(sd,1164), skill_id, desc, name); // // skill %d: %s (%s)
|
||||
}
|
||||
}
|
||||
|
||||
dbi_destroy(iter);
|
||||
|
||||
if( found ) {
|
||||
sprintf(atcmd_output, msg_txt(sd,1398), found); // -- Displaying first %d partial matches
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
@ -5912,7 +5909,7 @@ ACMD_FUNC(skilltree)
|
||||
{
|
||||
if( ent->need[j].skill_id && pc_checkskill(sd,ent->need[j].skill_id) < ent->need[j].skill_lv)
|
||||
{
|
||||
sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].skill_lv, skill_db[skill_get_index(ent->need[j].skill_id)]->desc); // Player requires level %d of skill %s.
|
||||
sprintf(atcmd_output, msg_txt(sd,1170), ent->need[j].skill_lv, skill_get_desc(ent->need[j].skill_id)); // Player requires level %d of skill %s.
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
meets = 0;
|
||||
}
|
||||
|
@ -593,7 +593,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
|
||||
* @param attack_type @see enum e_battle_flag
|
||||
* @param src Attacker
|
||||
* @param target Target
|
||||
* @param nk Skill's nk @see enum e_skill_nk [NK_NO_CARDFIX_ATK|NK_NO_ELEFIX|NK_NO_CARDFIX_DEF]
|
||||
* @param nk Skill's nk @see enum e_skill_nk [NK_IGNOREATKCARD|NK_IGNOREELEMENT|NK_IGNOREDEFCARD]
|
||||
* @param rh_ele Right-hand weapon element
|
||||
* @param lh_ele Left-hand weapon element (BF_MAGIC and BF_MISC ignore this value)
|
||||
* @param damage Original damage
|
||||
@ -604,7 +604,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
|
||||
* @param flag Misc value of skill & damage flags
|
||||
* @return damage Damage diff between original damage and after calculation
|
||||
*/
|
||||
int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int rh_ele, int lh_ele, int64 damage, int left, int flag){
|
||||
int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, std::bitset<NK_MAX> nk, int rh_ele, int lh_ele, int64 damage, int left, int flag){
|
||||
struct map_session_data *sd, ///< Attacker session data if BL_PC
|
||||
*tsd; ///< Target session data if BL_PC
|
||||
short cardfix = 1000;
|
||||
@ -638,9 +638,9 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
switch( attack_type ) {
|
||||
case BF_MAGIC:
|
||||
// Affected by attacker ATK bonuses
|
||||
if( sd && !(nk&NK_NO_CARDFIX_ATK) ) {
|
||||
if( sd && !nk[NK_IGNOREATKCARD] ) {
|
||||
cardfix = cardfix * (100 + sd->magic_addrace[tstatus->race] + sd->magic_addrace[RC_ALL] + sd->magic_addrace2[t_race2]) / 100;
|
||||
if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
if( !nk[NK_IGNOREELEMENT] ) { // Affected by Element modifier bonuses
|
||||
cardfix = cardfix * (100 + sd->magic_addele[tstatus->def_ele] + sd->magic_addele[ELE_ALL] +
|
||||
sd->magic_addele_script[tstatus->def_ele] + sd->magic_addele_script[ELE_ALL]) / 100;
|
||||
cardfix = cardfix * (100 + sd->magic_atk_ele[rh_ele] + sd->magic_atk_ele[ELE_ALL]) / 100;
|
||||
@ -657,10 +657,10 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
}
|
||||
|
||||
// Affected by target DEF bonuses
|
||||
if( tsd && !(nk&NK_NO_CARDFIX_DEF) ) {
|
||||
if( tsd && !nk[NK_IGNOREDEFCARD] ) {
|
||||
cardfix = 1000; // reset var for target
|
||||
|
||||
if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
if( !nk[NK_IGNOREELEMENT] ) { // Affected by Element modifier bonuses
|
||||
int ele_fix = tsd->subele[rh_ele] + tsd->subele[ELE_ALL] + tsd->subele_script[rh_ele] + tsd->subele_script[ELE_ALL];
|
||||
|
||||
for (const auto &it : tsd->subele2) {
|
||||
@ -704,13 +704,13 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
|
||||
case BF_WEAPON:
|
||||
// Affected by attacker ATK bonuses
|
||||
if( sd && !(nk&NK_NO_CARDFIX_ATK) && (left&2) ) {
|
||||
if( sd && !nk[NK_IGNOREATKCARD] && (left&2) ) {
|
||||
short cardfix_ = 1000;
|
||||
|
||||
if( sd->state.arrow_atk ) { // Ranged attack
|
||||
cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->arrow_addrace[tstatus->race] +
|
||||
sd->right_weapon.addrace[RC_ALL] + sd->arrow_addrace[RC_ALL]) / 100;
|
||||
if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
if( !nk[NK_IGNOREELEMENT] ) { // Affected by Element modifier bonuses
|
||||
int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele] +
|
||||
sd->right_weapon.addele[ELE_ALL] + sd->arrow_addele[ELE_ALL];
|
||||
|
||||
@ -737,7 +737,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
if( !battle_config.left_cardfix_to_right ) {
|
||||
// Right-handed weapon
|
||||
cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->right_weapon.addrace[RC_ALL]) / 100;
|
||||
if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
if( !nk[NK_IGNOREELEMENT] ) { // Affected by Element modifier bonuses
|
||||
int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->right_weapon.addele[ELE_ALL];
|
||||
|
||||
for (const auto &it : sd->right_weapon.addele2) {
|
||||
@ -757,7 +757,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
|
||||
if( left&1 ) { // Left-handed weapon
|
||||
cardfix_ = cardfix_ * (100 + sd->left_weapon.addrace[tstatus->race] + sd->left_weapon.addrace[RC_ALL]) / 100;
|
||||
if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
if( !nk[NK_IGNOREELEMENT] ) { // Affected by Element modifier bonuses
|
||||
int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[ELE_ALL];
|
||||
|
||||
for (const auto &it : sd->left_weapon.addele2) {
|
||||
@ -778,8 +778,8 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
}
|
||||
// Calculates right & left hand weapon as unity
|
||||
else {
|
||||
//! CHECKME: If 'left_cardfix_to_right' is yes, doesn't need to check NK_NO_ELEFIX?
|
||||
//if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
//! CHECKME: If 'left_cardfix_to_right' is yes, doesn't need to check NK_IGNOREELEMENT?
|
||||
//if( !nk[&]K_IGNOREELEMENT) ) { // Affected by Element modifier bonuses
|
||||
int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele]
|
||||
+ sd->right_weapon.addele[ELE_ALL] + sd->left_weapon.addele[ELE_ALL];
|
||||
|
||||
@ -841,8 +841,8 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
}
|
||||
}
|
||||
// Affected by target DEF bonuses
|
||||
else if( tsd && !(nk&NK_NO_CARDFIX_DEF) && !(left&2) ) {
|
||||
if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
else if( tsd && !nk[NK_IGNOREDEFCARD] && !(left&2) ) {
|
||||
if( !nk[NK_IGNOREELEMENT] ) { // Affected by Element modifier bonuses
|
||||
int ele_fix = tsd->subele[rh_ele] + tsd->subele[ELE_ALL] + tsd->subele_script[rh_ele] + tsd->subele_script[ELE_ALL];
|
||||
|
||||
for (const auto &it : tsd->subele2) {
|
||||
@ -895,8 +895,8 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
|
||||
|
||||
case BF_MISC:
|
||||
// Affected by target DEF bonuses
|
||||
if( tsd && !(nk&NK_NO_CARDFIX_DEF) ) {
|
||||
if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
|
||||
if( tsd && !nk[NK_IGNOREDEFCARD] ) {
|
||||
if( !nk[NK_IGNOREELEMENT] ) { // Affected by Element modifier bonuses
|
||||
int ele_fix = tsd->subele[rh_ele] + tsd->subele[ELE_ALL] + tsd->subele_script[rh_ele] + tsd->subele_script[ELE_ALL];
|
||||
|
||||
for (const auto &it : tsd->subele2) {
|
||||
@ -1135,7 +1135,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( (sce = sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill_get_inf3(skill_id)&INF3_NO_EFF_AUTOGUARD) && rnd()%100 < sce->val2) {
|
||||
if( (sce = sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !skill_get_inf2(skill_id, INF2_IGNOREAUTOGUARD) && rnd()%100 < sce->val2) {
|
||||
int delay;
|
||||
struct status_change_entry *sce_d = sc->data[SC_DEVOTION];
|
||||
struct block_list *d_bl = NULL;
|
||||
@ -1227,7 +1227,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((sce = sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU]) && flag&BF_WEAPON && !(skill_get_inf3(skill_id)&INF3_NO_EFF_CICADA)) {
|
||||
if (((sce = sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU]) && flag&BF_WEAPON && !skill_get_inf2(skill_id, INF2_IGNORECICADA)) {
|
||||
skill_additional_effect (src, bl, skill_id, skill_lv, flag, ATK_BLOCK, gettick() );
|
||||
if (!status_isdead(src))
|
||||
skill_counter_additional_effect( src, bl, skill_id, skill_lv, flag, gettick() );
|
||||
@ -1638,7 +1638,7 @@ int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64
|
||||
if( !damage )
|
||||
return 0;
|
||||
|
||||
if(skill_get_inf2(skill_id)&INF2_NO_BG_DMG)
|
||||
if(skill_get_inf2(skill_id, INF2_IGNOREBGREDUCTION))
|
||||
return damage; //skill that ignore bg map reduction
|
||||
|
||||
if( flag&BF_SKILL ) { //Skills get a different reduction than non-skills. [Skotlex]
|
||||
@ -1676,7 +1676,7 @@ bool battle_can_hit_gvg_target(struct block_list *src,struct block_list *bl,uint
|
||||
if (ud && ud->immune_attack)
|
||||
return false;
|
||||
if(md && md->guardian_data) {
|
||||
if ((status_bl_has_mode(bl,MD_SKILL_IMMUNE) || (class_ == MOBID_EMPERIUM && !(skill_get_inf3(skill_id)&INF3_HIT_EMP))) && flag&BF_SKILL) //Skill immunity.
|
||||
if ((status_bl_has_mode(bl,MD_SKILL_IMMUNE) || (class_ == MOBID_EMPERIUM && !skill_get_inf2(skill_id, INF2_TARGETEMPERIUM))) && flag&BF_SKILL) //Skill immunity.
|
||||
return false;
|
||||
if( src->type != BL_MOB || mob_is_clone( ((struct mob_data*)src)->mob_id ) ){
|
||||
struct guild *g = src->type == BL_PC ? ((TBL_PC *)src)->guild : guild_search(status_get_guild_id(src));
|
||||
@ -1708,7 +1708,7 @@ int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64
|
||||
if (!battle_can_hit_gvg_target(src,bl,skill_id,flag))
|
||||
return 0;
|
||||
|
||||
if (skill_get_inf2(skill_id)&INF2_NO_GVG_DMG) //Skills with no gvg damage reduction.
|
||||
if (skill_get_inf2(skill_id, INF2_IGNOREGVGREDUCTION)) //Skills with no gvg damage reduction.
|
||||
return damage;
|
||||
|
||||
if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
|
||||
@ -2112,7 +2112,7 @@ void battle_consume_ammo(struct map_session_data*sd, int skill, int lv)
|
||||
static int battle_range_type(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv)
|
||||
{
|
||||
// [Akinari] , [Xynvaroth]: Traps are always short range.
|
||||
if( skill_get_inf2( skill_id ) & INF2_TRAP )
|
||||
if (skill_get_inf2(skill_id, INF2_ISTRAP))
|
||||
return BF_SHORT;
|
||||
|
||||
// When monsters use Arrow Shower or Bomb, it is always short range
|
||||
@ -2169,13 +2169,14 @@ static enum e_skill_damage_type battle_skill_damage_type( struct block_list* bl
|
||||
* @return Skill damage rate
|
||||
*/
|
||||
static int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id) {
|
||||
uint16 idx = skill_get_index(skill_id), m = src->m;
|
||||
int16 m = src->m;
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
||||
struct s_skill_damage *damage = NULL;
|
||||
|
||||
if (!idx || !skill_db[idx]->damage.map)
|
||||
if (!skill || !skill->damage.map)
|
||||
return 0;
|
||||
|
||||
damage = &skill_db[idx]->damage;
|
||||
damage = &skill->damage;
|
||||
|
||||
//check the adjustment works for specified type
|
||||
if (!(damage->caster&src->type))
|
||||
@ -2387,7 +2388,7 @@ static bool is_attack_critical(struct Damage* wd, struct block_list *src, struct
|
||||
if (skill_id == NPC_CRITICALSLASH || skill_id == LG_PINPOINTATTACK) //Always critical skills
|
||||
return true;
|
||||
|
||||
if( sstatus->cri && ( !skill_id || skill_get_nk(skill_id)&NK_CRITICAL ) )
|
||||
if( sstatus->cri && ( !skill_id || skill_get_nk(skill_id, NK_CRITICAL) ) )
|
||||
{
|
||||
short cri = sstatus->cri;
|
||||
|
||||
@ -2485,12 +2486,20 @@ static int is_attack_piercing(struct Damage* wd, struct block_list *src, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int battle_skill_get_damage_properties(uint16 skill_id, int is_splash)
|
||||
static std::bitset<NK_MAX> battle_skill_get_damage_properties(uint16 skill_id, int is_splash)
|
||||
{
|
||||
int nk = skill_get_nk(skill_id);
|
||||
if( !skill_id && is_splash ) //If flag, this is splash damage from Baphomet Card and it always hits.
|
||||
nk |= NK_NO_CARDFIX_ATK|NK_IGNORE_FLEE;
|
||||
return nk;
|
||||
if (skill_id == 0) {
|
||||
if (is_splash) {
|
||||
std::bitset<NK_MAX> tmp_nk;
|
||||
|
||||
tmp_nk.set(NK_IGNOREATKCARD);
|
||||
tmp_nk.set(NK_IGNOREFLEE);
|
||||
|
||||
return tmp_nk;
|
||||
} else
|
||||
return 0;
|
||||
} else
|
||||
return skill_db.find(skill_id)->nk;
|
||||
}
|
||||
|
||||
/*=============================
|
||||
@ -2508,7 +2517,7 @@ static bool is_attack_hitting(struct Damage* wd, struct block_list *src, struct
|
||||
struct status_change *sc = status_get_sc(src);
|
||||
struct status_change *tsc = status_get_sc(target);
|
||||
struct map_session_data *sd = BL_CAST(BL_PC, src);
|
||||
int nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
std::bitset<NK_MAX> nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
short flee, hitrate;
|
||||
|
||||
if (!first_call)
|
||||
@ -2525,7 +2534,7 @@ static bool is_attack_hitting(struct Damage* wd, struct block_list *src, struct
|
||||
return true;
|
||||
else if (tsc && tsc->opt1 && tsc->opt1 != OPT1_STONEWAIT && tsc->opt1 != OPT1_BURNING)
|
||||
return true;
|
||||
else if (nk&NK_IGNORE_FLEE)
|
||||
else if (nk[NK_IGNOREFLEE])
|
||||
return true;
|
||||
|
||||
if( tsc && tsc->data[SC_NEUTRALBARRIER] && (wd->flag&(BF_LONG|BF_MAGIC)) == BF_LONG )
|
||||
@ -2671,7 +2680,7 @@ static bool attack_ignores_def(struct Damage* wd, struct block_list *src, struct
|
||||
struct status_data *tstatus = status_get_status_data(target);
|
||||
struct status_change *sc = status_get_sc(src);
|
||||
struct map_session_data *sd = BL_CAST(BL_PC, src);
|
||||
int nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
std::bitset<NK_MAX> nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
|
||||
#ifndef RENEWAL
|
||||
if (is_attack_critical(wd, src, target, skill_id, skill_lv, false))
|
||||
@ -2704,7 +2713,7 @@ static bool attack_ignores_def(struct Damage* wd, struct block_list *src, struct
|
||||
}
|
||||
}
|
||||
|
||||
return (nk&NK_IGNORE_DEF) != 0;
|
||||
return nk[NK_IGNOREDEFENSE] != 0;
|
||||
}
|
||||
|
||||
/*================================================
|
||||
@ -2836,10 +2845,10 @@ static void battle_calc_element_damage(struct Damage* wd, struct block_list *src
|
||||
int element = skill_get_ele(skill_id, skill_lv);
|
||||
int left_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_L, true);
|
||||
int right_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_R, true);
|
||||
int nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
std::bitset<NK_MAX> nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
|
||||
//Elemental attribute fix
|
||||
if(!(nk&NK_NO_ELEFIX)) {
|
||||
if(!nk[NK_IGNOREELEMENT]) {
|
||||
//Non-pc physical melee attacks (mob, pet, homun) are "non elemental", they deal 100% to all target elements
|
||||
//However the "non elemental" attacks still get reduced by "Neutral resistance"
|
||||
//Also non-pc units have only a defending element, but can inflict elemental attacks using skills [exneval]
|
||||
@ -3065,7 +3074,7 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
struct status_data *tstatus = status_get_status_data(target);
|
||||
struct map_session_data *sd = BL_CAST(BL_PC, src);
|
||||
uint16 i;
|
||||
int nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
std::bitset<NK_MAX> nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
|
||||
switch (skill_id) { //Calc base damage according to skill
|
||||
case PA_SACRIFICE:
|
||||
@ -3238,7 +3247,7 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
if (is_attack_left_handed(src, skill_id))
|
||||
wd->damage2 = battle_calc_base_damage(src, sstatus, &sstatus->lhw, sc, tstatus->size, i);
|
||||
#endif
|
||||
if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
|
||||
if (nk[NK_SPLASHSPLIT]){ // Divide ATK among targets
|
||||
if(wd->miscflag > 0) {
|
||||
wd->damage /= wd->miscflag;
|
||||
#ifdef RENEWAL
|
||||
@ -4461,7 +4470,6 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
|
||||
struct status_change *sc = status_get_sc(src);
|
||||
struct status_data *sstatus = status_get_status_data(src);
|
||||
struct status_data *tstatus = status_get_status_data(target);
|
||||
int inf3 = skill_get_inf3(skill_id);
|
||||
uint8 anger_id = 0; // SLS Anger
|
||||
|
||||
// Kagerou/Oboro Earth Charm effect +15% wATK
|
||||
@ -4553,12 +4561,12 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (sc->data[SC_GLOOMYDAY_SK] && (inf3&INF3_SC_GLOOMYDAY_SK)) {
|
||||
if (sc->data[SC_GLOOMYDAY_SK] && skill_get_inf2(skill_id, INF2_INCREASEGLOOMYDAYDAMAGE)) {
|
||||
ATK_ADDRATE(wd->damage, wd->damage2, sc->data[SC_GLOOMYDAY_SK]->val2);
|
||||
RE_ALLATK_ADDRATE(wd, sc->data[SC_GLOOMYDAY_SK]->val2);
|
||||
}
|
||||
if (sc->data[SC_DANCEWITHWUG]) {
|
||||
if (inf3&INF3_SC_DANCEWITHWUG) {
|
||||
if (skill_get_inf2(skill_id, INF2_INCREASEDANCEWITHWUGDAMAGE)) {
|
||||
ATK_ADDRATE(wd->damage, wd->damage2, sc->data[SC_DANCEWITHWUG]->val1 * 10 * battle_calc_chorusbonus(sd));
|
||||
RE_ALLATK_ADDRATE(wd, sc->data[SC_DANCEWITHWUG]->val1 * 10 * battle_calc_chorusbonus(sd));
|
||||
}
|
||||
@ -5122,7 +5130,7 @@ static void battle_calc_weapon_final_atk_modifiers(struct Damage* wd, struct blo
|
||||
rdamage = (int64)rdamage * ratio / 100 + wd->damage * (10 + tsc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
|
||||
skill_blown(target, src, skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), BLOWN_NONE);
|
||||
clif_skill_damage(target, src, gettick(), status_get_amotion(src), 0, rdamage,
|
||||
1, SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1, DMG_SKILL); // This is how official does
|
||||
1, SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1, DMG_SINGLE); // This is how official does
|
||||
clif_damage(src, target, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, DMG_NORMAL, 0, false);
|
||||
status_damage(target, src, rdamage, 0, 0, 0);
|
||||
status_damage(src, target, rdamage/10, 0, 0, 1);
|
||||
@ -5481,16 +5489,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RENEWAL
|
||||
if (skill_id == NJ_KUNAI) {
|
||||
short nk = battle_skill_get_damage_properties(skill_id, wd.miscflag);
|
||||
|
||||
ATK_ADD(wd.damage, wd.damage2, 90);
|
||||
nk |= NK_IGNORE_DEF;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (skill_id) {
|
||||
#ifndef RENEWAL
|
||||
case NJ_KUNAI:
|
||||
ATK_ADD(wd.damage, wd.damage2, 90);
|
||||
break;
|
||||
#endif
|
||||
case TK_DOWNKICK:
|
||||
case TK_STORMKICK:
|
||||
case TK_TURNKICK:
|
||||
@ -5677,7 +5681,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
*/
|
||||
struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag)
|
||||
{
|
||||
int i, nk, skill_damage = 0;
|
||||
int i, skill_damage = 0;
|
||||
short s_ele = 0;
|
||||
|
||||
TBL_PC *sd;
|
||||
@ -5706,8 +5710,14 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
ad.blewcount = skill_get_blewcount(skill_id, skill_lv);
|
||||
ad.flag = BF_MAGIC|BF_SKILL;
|
||||
ad.dmg_lv = ATK_DEF;
|
||||
nk = skill_get_nk(skill_id);
|
||||
flag.imdef = (nk&NK_IGNORE_DEF ? 1 : 0);
|
||||
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
||||
std::bitset<NK_MAX> nk;
|
||||
|
||||
if (skill)
|
||||
nk = skill->nk;
|
||||
|
||||
flag.imdef = nk[NK_IGNOREDEFENSE] ? 1 : 0;
|
||||
|
||||
sd = BL_CAST(BL_PC, src);
|
||||
tsd = BL_CAST(BL_PC, target);
|
||||
@ -5843,7 +5853,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
MATK_ADD(sstatus->matk_min);
|
||||
}
|
||||
|
||||
if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
|
||||
if (nk[NK_SPLASHSPLIT]) { // Divide MATK in case of multiple targets skill
|
||||
if (mflag>0)
|
||||
ad.damage /= mflag;
|
||||
else
|
||||
@ -6363,7 +6373,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
}
|
||||
}
|
||||
|
||||
if (!(nk&NK_NO_ELEFIX) && skill_id != ASC_BREAKER) // Soul Breaker's magic portion is non-elemental. [Secret]
|
||||
if (!nk[NK_IGNOREELEMENT] && skill_id != ASC_BREAKER) // Soul Breaker's magic portion is non-elemental. [Secret]
|
||||
ad.damage = battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
|
||||
|
||||
//Apply the physical part of the skill's damage. [Skotlex]
|
||||
@ -6433,8 +6443,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag)
|
||||
{
|
||||
int skill_damage = 0;
|
||||
short i, nk;
|
||||
short s_ele;
|
||||
short i, s_ele;
|
||||
|
||||
struct map_session_data *sd, *tsd;
|
||||
struct Damage md; //DO NOT CONFUSE with md of mob_data!
|
||||
@ -6457,7 +6466,11 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
md.dmg_lv = ATK_DEF;
|
||||
md.flag = BF_MISC|BF_SKILL;
|
||||
|
||||
nk = skill_get_nk(skill_id);
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
||||
std::bitset<NK_MAX> nk;
|
||||
|
||||
if (skill)
|
||||
nk = skill->nk;
|
||||
|
||||
sd = BL_CAST(BL_PC, src);
|
||||
tsd = BL_CAST(BL_PC, target);
|
||||
@ -6512,7 +6525,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
skill = 0;
|
||||
md.damage = (sstatus->dex / 10 + sstatus->int_ / 2 + skill * 3 + 40) * 2;
|
||||
if(mflag > 1) //Autocasted Blitz
|
||||
nk |= NK_SPLASHSPLIT;
|
||||
nk.set(NK_SPLASHSPLIT);
|
||||
if (skill_id == SN_FALCONASSAULT) {
|
||||
//Div fix of Blitzbeat
|
||||
DAMAGE_DIV_FIX2(md.damage, skill_get_num(HT_BLITZBEAT, 5));
|
||||
@ -6549,7 +6562,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
struct Damage atk, matk;
|
||||
|
||||
atk = battle_calc_weapon_attack(src, target, skill_id, skill_lv, 0);
|
||||
nk |= NK_NO_ELEFIX; // atk part takes on weapon element, matk part is non-elemental
|
||||
nk.set(NK_IGNOREELEMENT); // atk part takes on weapon element, matk part is non-elemental
|
||||
matk = battle_calc_magic_attack(src, target, skill_id, skill_lv, 0);
|
||||
|
||||
// (atk + matk) * (3 + (.5 * skill level))
|
||||
@ -6562,7 +6575,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
}
|
||||
#else
|
||||
md.damage = 500 + rnd()%500 + 5 * skill_lv * sstatus->int_;
|
||||
nk |= NK_IGNORE_FLEE|NK_NO_ELEFIX; //These two are not properties of the weapon based part.
|
||||
nk.set(NK_IGNOREFLEE);
|
||||
nk.set(NK_IGNOREELEMENT); //These two are not properties of the weapon based part.
|
||||
#endif
|
||||
break;
|
||||
case HW_GRAVITATION:
|
||||
@ -6670,7 +6684,9 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
md.damage = 0;
|
||||
} else
|
||||
md.damage = md.damage * 200 / (skill_id == RA_CLUSTERBOMB ? 50 : 100);
|
||||
nk |= NK_NO_ELEFIX|NK_IGNORE_FLEE|NK_NO_CARDFIX_DEF;
|
||||
nk.set(NK_IGNOREELEMENT);
|
||||
nk.set(NK_IGNOREFLEE);
|
||||
nk.set(NK_IGNOREDEFCARD);
|
||||
break;
|
||||
case NC_MAGMA_ERUPTION_DOTDAMAGE: // 'Eruption' damage
|
||||
md.damage = 800 + 200 * skill_lv;
|
||||
@ -6706,14 +6722,14 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
break;
|
||||
}
|
||||
|
||||
if (nk&NK_SPLASHSPLIT) { // Divide ATK among targets
|
||||
if (nk[NK_SPLASHSPLIT]) { // Divide ATK among targets
|
||||
if(mflag > 0)
|
||||
md.damage /= mflag;
|
||||
else
|
||||
ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
|
||||
}
|
||||
|
||||
if (!(nk&NK_IGNORE_FLEE)) {
|
||||
if (!nk[NK_IGNOREFLEE]) {
|
||||
struct status_change *sc = status_get_sc(target);
|
||||
|
||||
i = 0; //Temp for "hit or no hit"
|
||||
@ -6765,7 +6781,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
if (tsd && (i = pc_sub_skillatk_bonus(tsd, skill_id)))
|
||||
md.damage -= (int64)md.damage*i/100;
|
||||
|
||||
if(!(nk&NK_NO_ELEFIX))
|
||||
if(!nk[NK_IGNOREELEMENT])
|
||||
md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
|
||||
|
||||
//Plant damage
|
||||
@ -6920,7 +6936,7 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
|
||||
return 0; // White Imprison does not reflect any damage
|
||||
|
||||
if (flag & BF_SHORT) {//Bounces back part of the damage.
|
||||
if ( (skill_get_inf2(skill_id)&INF2_TRAP || !status_reflect) && sd && sd->bonus.short_weapon_damage_return ) {
|
||||
if ( (skill_get_inf2(skill_id, INF2_ISTRAP) || !status_reflect) && sd && sd->bonus.short_weapon_damage_return ) {
|
||||
rdamage += damage * sd->bonus.short_weapon_damage_return / 100;
|
||||
rdamage = i64max(rdamage,1);
|
||||
} else if( status_reflect && sc && sc->count ) {
|
||||
@ -6937,7 +6953,7 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if( sc->data[SC_REFLECTDAMAGE] && !(skill_get_inf2(skill_id)&INF2_TRAP)) {
|
||||
if( sc->data[SC_REFLECTDAMAGE] && !skill_get_inf2(skill_id, INF2_ISTRAP)) {
|
||||
if( rnd()%100 <= sc->data[SC_REFLECTDAMAGE]->val1*10 + 30 ){
|
||||
max_damage = (int64)max_damage * status_get_lv(bl) / 100;
|
||||
rdamage = (*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100;
|
||||
@ -6962,7 +6978,7 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
|
||||
|
||||
rd1 = min(damage,status_get_max_hp(bl)) * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
|
||||
*dmg = rd1 * 30 / 100; // Received damage = 30% of amplified damage.
|
||||
clif_skill_damage(src, bl, gettick(), status_get_amotion(src), 0, -30000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, DMG_SKILL);
|
||||
clif_skill_damage(src, bl, gettick(), status_get_amotion(src), 0, -30000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, DMG_SINGLE);
|
||||
skill_blown(bl, src, skill_get_blewcount(RK_DEATHBOUND, 1), unit_getdir(src), BLOWN_NONE);
|
||||
status_change_end(bl, SC_DEATHBOUND, INVALID_TIMER);
|
||||
rdamage += rd1 * 70 / 100; // Target receives 70% of the amplified damage. [Rytech]
|
||||
@ -7435,7 +7451,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
struct elemental_data *ed = ((TBL_PC*)target)->ed;
|
||||
|
||||
if (ed) {
|
||||
clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, DMG_SKILL);
|
||||
clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, DMG_SINGLE);
|
||||
skill_attack(BF_WEAPON,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
|
||||
}
|
||||
}
|
||||
@ -7499,13 +7515,12 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
int type;
|
||||
if( (type = skill_get_casttype(r_skill)) == CAST_GROUND ) {
|
||||
int maxcount = 0;
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(r_skill);
|
||||
|
||||
if( !(BL_PC&battle_config.skill_reiteration) &&
|
||||
skill_get_unit_flag(r_skill)&UF_NOREITERATION )
|
||||
if( !(BL_PC&battle_config.skill_reiteration) && skill->unit_flag[UF_NOREITERATION] )
|
||||
type = -1;
|
||||
|
||||
if( BL_PC&battle_config.skill_nofootset &&
|
||||
skill_get_unit_flag(r_skill)&UF_NOFOOTSET )
|
||||
if( BL_PC&battle_config.skill_nofootset && skill->unit_flag[UF_NOFOOTSET] )
|
||||
type = -1;
|
||||
|
||||
if( BL_PC&battle_config.land_skill_limit &&
|
||||
@ -7731,11 +7746,11 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
|
||||
uint16 skill_id = battle_getcurrentskill(src);
|
||||
if( !su || !su->group)
|
||||
return 0;
|
||||
if( skill_get_inf2(su->group->skill_id)&INF2_TRAP && su->group->unit_id != UNT_USED_TRAPS) {
|
||||
if( skill_get_inf2(su->group->skill_id, INF2_ISTRAP) && su->group->unit_id != UNT_USED_TRAPS) {
|
||||
if (!skill_id || su->group->skill_id == WM_REVERBERATION || su->group->skill_id == NPC_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) {
|
||||
;
|
||||
}
|
||||
else if (skill_get_inf2(skill_id)&INF2_HIT_TRAP) { // Only a few skills can target traps
|
||||
else if (skill_get_inf2(skill_id, INF2_TARGETTRAP)) { // Only a few skills can target traps
|
||||
switch (skill_id) {
|
||||
case RK_DRAGONBREATH:
|
||||
case RK_DRAGONBREATH_WATER:
|
||||
@ -7768,7 +7783,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
|
||||
return 0;
|
||||
default:
|
||||
// Usually BCT_ALL stands for only hitting chars, but skills specifically set to hit traps also hit icewall
|
||||
if ((flag&BCT_ALL) == BCT_ALL && !(skill_get_inf2(skill_id)&INF2_HIT_TRAP))
|
||||
if ((flag&BCT_ALL) == BCT_ALL && !skill_get_inf2(skill_id, INF2_TARGETTRAP))
|
||||
return -1;
|
||||
}
|
||||
state |= BCT_ENEMY;
|
||||
@ -7832,15 +7847,17 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
|
||||
struct status_change* sc = status_get_sc(target);
|
||||
if (!su || !su->group)
|
||||
return 0;
|
||||
|
||||
std::bitset<INF2_MAX> inf2 = skill_db.find(su->group->skill_id)->inf2;
|
||||
|
||||
if (su->group->src_id == target->id) {
|
||||
int inf2 = skill_get_inf2(su->group->skill_id);
|
||||
if (inf2&INF2_NO_TARGET_SELF)
|
||||
if (inf2[INF2_NOTARGETSELF])
|
||||
return -1;
|
||||
if (inf2&INF2_TARGET_SELF)
|
||||
if (inf2[INF2_TARGETSELF])
|
||||
return 1;
|
||||
}
|
||||
//Status changes that prevent traps from triggering
|
||||
if (sc && sc->count && skill_get_inf2(su->group->skill_id)&INF2_TRAP) {
|
||||
if (sc && sc->count && inf2[INF2_ISTRAP]) {
|
||||
if( sc->data[SC_SIGHTBLASTER] && sc->data[SC_SIGHTBLASTER]->val2 > 0 && sc->data[SC_SIGHTBLASTER]->val4%2 == 0)
|
||||
return -1;
|
||||
}
|
||||
|
@ -4,11 +4,14 @@
|
||||
#ifndef BATTLE_HPP
|
||||
#define BATTLE_HPP
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "../common/cbasetypes.hpp"
|
||||
#include "../common/mmo.hpp"
|
||||
#include "../config/core.hpp"
|
||||
|
||||
#include "map.hpp" //ELE_MAX
|
||||
#include "skill.hpp"
|
||||
|
||||
//fwd declaration
|
||||
struct map_session_data;
|
||||
@ -29,6 +32,7 @@ enum damage_lv : uint8 {
|
||||
|
||||
/// Flag of the final calculation
|
||||
enum e_battle_flag : uint16 {
|
||||
BF_NONE = 0x0000, /// None
|
||||
BF_WEAPON = 0x0001, /// Weapon attack
|
||||
BF_MAGIC = 0x0002, /// Magic attack
|
||||
BF_MISC = 0x0004, /// Misc attack
|
||||
@ -61,6 +65,8 @@ enum e_battle_check_target : uint32 {
|
||||
BCT_NOGUILD = BCT_ALL&~BCT_GUILD, ///< Except guildmates
|
||||
BCT_NOPARTY = BCT_ALL&~BCT_PARTY, ///< Except party members
|
||||
BCT_NOENEMY = BCT_ALL&~BCT_ENEMY, ///< Except enemy
|
||||
BCT_ALLY = BCT_PARTY|BCT_GUILD,
|
||||
BCT_FRIEND = BCT_NOENEMY,
|
||||
};
|
||||
|
||||
/// Damage structure
|
||||
@ -94,7 +100,7 @@ void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rda
|
||||
|
||||
int battle_attr_ratio(int atk_elem,int def_type, int def_lv);
|
||||
int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv);
|
||||
int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int64 damage, int left, int flag);
|
||||
int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, std::bitset<NK_MAX> nk, int s_ele, int s_ele_, int64 damage, int left, int flag);
|
||||
|
||||
// Final calculation Damage
|
||||
int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv);
|
||||
|
@ -5031,9 +5031,9 @@ void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *unit,
|
||||
if (unit->group->state.guildaura)
|
||||
return;
|
||||
|
||||
if (unit->group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)
|
||||
unit_id = unit->val2&UF_SONG ? UNT_DISSONANCE : UNT_UGLYDANCE;
|
||||
else if (skill_get_unit_flag(unit->group->skill_id) & UF_RANGEDSINGLEUNIT && !(unit->val2 & UF_RANGEDSINGLEUNIT))
|
||||
if (unit->group->state.song_dance&0x1 && unit->val2&(1 << UF_ENSEMBLE))
|
||||
unit_id = unit->val2&(1 << UF_SONG) ? UNT_DISSONANCE : UNT_UGLYDANCE;
|
||||
else if (skill_get_unit_flag(unit->group->skill_id, UF_RANGEDSINGLEUNIT) && !(unit->val2 & (1 << UF_RANGEDSINGLEUNIT)))
|
||||
unit_id = UNT_DUMMYSKILL; // Use invisible unit id for other case of rangedsingle unit
|
||||
else
|
||||
unit_id = unit->group->unit_id;
|
||||
@ -5622,7 +5622,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick,
|
||||
#if PACKETVER < 20131223
|
||||
WBUFB(buf,32)=type;
|
||||
#else
|
||||
WBUFB(buf,32)=( type == DMG_SKILL ) ? DMG_MULTI_HIT : type;
|
||||
WBUFB(buf,32)=( type == DMG_SINGLE ) ? DMG_MULTI_HIT : type;
|
||||
#endif
|
||||
if (disguised(dst)) {
|
||||
clif_send(buf,packet_len(0x1de),dst,AREA_WOS);
|
||||
@ -18500,7 +18500,7 @@ int clif_autoshadowspell_list(struct map_session_data *sd) {
|
||||
//AEGIS listed the specified skills that available for SC_AUTOSHADOWSPELL
|
||||
for( i = 0, c = 0; i < MAX_SKILL; i++ )
|
||||
if( sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].id > 0 &&
|
||||
(skill_get_inf2(sd->status.skill[i].id)&INF2_AUTOSHADOWSPELL))
|
||||
skill_get_inf2(sd->status.skill[i].id, INF2_ISAUTOSHADOWSPELL))
|
||||
{
|
||||
WFIFOW(fd,8+c*2) = sd->status.skill[i].id;
|
||||
c++;
|
||||
|
@ -542,7 +542,7 @@ enum e_damage_type : uint8_t {
|
||||
DMG_STAND_UP, /// stand up
|
||||
DMG_ENDURE, /// damage (endure)
|
||||
DMG_SPLASH, /// (splash?)
|
||||
DMG_SKILL, /// (skill?)
|
||||
DMG_SINGLE, /// (skill?)
|
||||
DMG_REPEAT, /// (repeat damage?)
|
||||
DMG_MULTI_HIT, /// multi-hit damage
|
||||
DMG_MULTI_HIT_ENDURE, /// multi-hit damage (endure)
|
||||
|
@ -386,7 +386,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
|
||||
}
|
||||
|
||||
int elemental_action(struct elemental_data *ed, struct block_list *bl, t_tick tick) {
|
||||
struct skill_condition req;
|
||||
struct s_skill_condition req;
|
||||
uint16 skill_id, skill_lv;
|
||||
int i;
|
||||
|
||||
@ -562,19 +562,16 @@ bool elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) {
|
||||
return idx == 0 ? false : skill_isNotOk(skill_id,ed->master); // return false or check if it,s ok for master as well
|
||||
}
|
||||
|
||||
struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
|
||||
struct skill_condition req;
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
struct s_skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
|
||||
struct s_skill_condition req = {};
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
||||
|
||||
memset(&req,0,sizeof(req));
|
||||
|
||||
if( idx == 0 ) // invalid skill id
|
||||
if( !skill ) // invalid skill id
|
||||
return req;
|
||||
|
||||
skill_lv = cap_value(skill_lv, 1, MAX_SKILL_LEVEL);
|
||||
|
||||
req.hp = skill_db[idx]->require.hp[skill_lv-1];
|
||||
req.sp = skill_db[idx]->require.sp[skill_lv-1];
|
||||
req.hp = skill->require.hp[skill_lv - 1];
|
||||
req.sp = skill->require.sp[skill_lv - 1];
|
||||
|
||||
return req;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ int elemental_set_target( struct map_session_data *sd, struct block_list *bl );
|
||||
int elemental_clean_single_effect(struct elemental_data *ed, uint16 skill_id);
|
||||
int elemental_clean_effect(struct elemental_data *ed);
|
||||
int elemental_action(struct elemental_data *ed, struct block_list *bl, t_tick tick);
|
||||
struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv);
|
||||
struct s_skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv);
|
||||
|
||||
#define elemental_stop_walking(ed, type) unit_stop_walking(&(ed)->bl, type)
|
||||
#define elemental_stop_attack(ed) unit_stop_attack(&(ed)->bl)
|
||||
|
@ -239,8 +239,10 @@ int hom_vaporize(struct map_session_data *sd, int flag)
|
||||
//Delete timers when vaporized.
|
||||
hom_hungry_timer_delete(hd);
|
||||
hd->homunculus.vaporize = flag ? flag : HOM_ST_REST;
|
||||
if (battle_config.hom_setting&HOMSET_RESET_REUSESKILL_VAPORIZED)
|
||||
memset(hd->blockskill, 0, sizeof(hd->blockskill));
|
||||
if (battle_config.hom_setting&HOMSET_RESET_REUSESKILL_VAPORIZED) {
|
||||
hd->blockskill.clear();
|
||||
hd->blockskill.shrink_to_fit();
|
||||
}
|
||||
clif_hominfo(sd, sd->hd, 0);
|
||||
hom_save(hd);
|
||||
return unit_remove_map(&hd->bl, CLR_OUTSIGHT);
|
||||
|
@ -66,7 +66,7 @@ struct homun_data {
|
||||
struct map_session_data *master; //pointer back to its master
|
||||
int hungry_timer; //[orn]
|
||||
unsigned int exp_next;
|
||||
char blockskill[MAX_SKILL]; // [orn]
|
||||
std::vector<uint16> blockskill; // [orn]
|
||||
};
|
||||
|
||||
#define MAX_HOM_SKILL_REQUIRE 5
|
||||
|
@ -359,17 +359,11 @@
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\quest_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\quest_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\refine_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\refine_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\size_fix.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\size_fix.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_cast_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_cast_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_castnodex_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_castnodex_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_changematerial_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_changematerial_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_copyable_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_copyable_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_damage_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_damage_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_nocast_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_nocast_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_nonearnpc_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_nonearnpc_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_require_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_require_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_tree.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_tree.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_unit_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_unit_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\spellbook_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\spellbook_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\statpoint.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\statpoint.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\status_disabled.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\status_disabled.txt')" />
|
||||
|
@ -337,7 +337,10 @@ enum e_element : int8{
|
||||
ELE_GHOST,
|
||||
ELE_UNDEAD,
|
||||
ELE_ALL,
|
||||
ELE_MAX
|
||||
ELE_MAX,
|
||||
ELE_WEAPON,
|
||||
ELE_ENDOWED,
|
||||
ELE_RANDOM,
|
||||
};
|
||||
|
||||
#define MAX_ELE_LEVEL 4 /// Maximum Element level
|
||||
|
@ -50,7 +50,7 @@ struct mercenary_data {
|
||||
|
||||
struct s_mercenary_db *db;
|
||||
struct s_mercenary mercenary;
|
||||
char blockskill[MAX_SKILL];
|
||||
std::vector<uint16> blockskill;
|
||||
|
||||
int masterteleport_timer;
|
||||
struct map_session_data *master;
|
||||
|
@ -3907,8 +3907,9 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
|
||||
for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) {
|
||||
uint16 skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].skill_id;
|
||||
uint16 sk_idx = 0;
|
||||
|
||||
if (!skill_id || !(sk_idx = skill_get_index(skill_id)) || sd->status.skill[sk_idx].lv < 1 ||
|
||||
(skill_get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ||
|
||||
skill_get_inf2_(skill_id, { INF2_ISWEDDING, INF2_ISGUILD }) ||
|
||||
mob_clone_disabled_skills(skill_id)
|
||||
)
|
||||
continue;
|
||||
@ -3916,8 +3917,8 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
|
||||
//against players (those with flags UF_NOMOB and UF_NOPC are specific
|
||||
//to always aid players!) [Skotlex]
|
||||
if (!(flag&1) &&
|
||||
skill_get_unit_id(skill_id, 0) &&
|
||||
skill_get_unit_flag(skill_id)&(UF_NOMOB|UF_NOPC))
|
||||
skill_get_unit_id(skill_id) &&
|
||||
skill_get_unit_flag_(skill_id, { UF_NOMOB, UF_NOPC }))
|
||||
continue;
|
||||
/**
|
||||
* The clone should be able to cast the skill (e.g. have the required weapon) bugreport:5299)
|
||||
@ -3945,7 +3946,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
|
||||
else
|
||||
ms[i].state = MSS_BERSERK;
|
||||
} else if(inf&INF_GROUND_SKILL) {
|
||||
if (skill_get_inf2(skill_id)&INF2_TRAP) { //Traps!
|
||||
if (skill_get_inf2(skill_id, INF2_ISTRAP)) { //Traps!
|
||||
ms[i].state = MSS_IDLE;
|
||||
ms[i].target = MST_AROUND2;
|
||||
ms[i].delay = 60000;
|
||||
@ -3959,7 +3960,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
|
||||
ms[i].cond2 = 95;
|
||||
}
|
||||
} else if (inf&INF_SELF_SKILL) {
|
||||
if (skill_get_inf2(skill_id)&INF2_NO_TARGET_SELF) { //auto-select target skill.
|
||||
if (skill_get_inf2(skill_id, INF2_NOTARGETSELF)) { //auto-select target skill.
|
||||
ms[i].target = MST_TARGET;
|
||||
ms[i].cond1 = MSC_ALWAYS;
|
||||
if (skill_get_range(skill_id, ms[i].skill_lv) > 3) {
|
||||
|
@ -138,26 +138,28 @@ struct view_data* npc_get_viewdata(int class_) {
|
||||
|
||||
int npc_isnear_sub(struct block_list* bl, va_list args) {
|
||||
struct npc_data *nd = (struct npc_data*)bl;
|
||||
|
||||
if (nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE))
|
||||
return 0;
|
||||
|
||||
int skill_id = va_arg(args, int);
|
||||
|
||||
if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_DISABLENEARNPC [Cydh]
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
||||
|
||||
if (idx > 0 && skill_db[idx]->unit_nonearnpc_type) {
|
||||
while (1) {
|
||||
if (skill_db[idx]->unit_nonearnpc_type&1 && nd->subtype == NPCTYPE_WARP) break;
|
||||
if (skill_db[idx]->unit_nonearnpc_type&2 && nd->subtype == NPCTYPE_SHOP) break;
|
||||
if (skill_db[idx]->unit_nonearnpc_type&4 && nd->subtype == NPCTYPE_SCRIPT) break;
|
||||
if (skill_db[idx]->unit_nonearnpc_type&8 && nd->subtype == NPCTYPE_TOMB) break;
|
||||
return 0;
|
||||
}
|
||||
if (skill && skill->unit_nonearnpc_type) {
|
||||
if (skill->unit_nonearnpc_type&SKILL_NONEAR_WARPPORTAL && nd->subtype == NPCTYPE_WARP)
|
||||
return 1;
|
||||
if (skill->unit_nonearnpc_type&SKILL_NONEAR_SHOP && nd->subtype == NPCTYPE_SHOP)
|
||||
return 1;
|
||||
if (skill->unit_nonearnpc_type&SKILL_NONEAR_NPC && nd->subtype == NPCTYPE_SCRIPT)
|
||||
return 1;
|
||||
if (skill->unit_nonearnpc_type&SKILL_NONEAR_TOMB && nd->subtype == NPCTYPE_TOMB)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE) )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool npc_isnear(struct block_list * bl) {
|
||||
|
211
src/map/pc.cpp
211
src/map/pc.cpp
@ -1755,9 +1755,10 @@ static int pc_calc_skillpoint(struct map_session_data* sd)
|
||||
|
||||
for(i = 1; i < MAX_SKILL; i++) {
|
||||
if( sd->status.skill[i].id && sd->status.skill[i].lv > 0) {
|
||||
uint16 inf2 = skill_get_inf2(sd->status.skill[i].id);
|
||||
if ((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
|
||||
!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(sd->status.skill[i].id);
|
||||
|
||||
if ((!skill->inf2[INF2_ISQUEST] || battle_config.quest_skill_learn) &&
|
||||
(!skill->inf2[INF2_ISWEDDING] || skill->inf2[INF2_ISSPIRIT]) //Do not count wedding/link skills. [Skotlex]
|
||||
)
|
||||
{
|
||||
if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
|
||||
@ -1772,9 +1773,7 @@ static int pc_calc_skillpoint(struct map_session_data* sd)
|
||||
}
|
||||
|
||||
static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
|
||||
uint16 i = 0;
|
||||
|
||||
if (!sd || !pc_has_permission(sd, PC_PERM_ALL_SKILL) || !SKILL_MAX_DB())
|
||||
if (!sd || !pc_has_permission(sd, PC_PERM_ALL_SKILL))
|
||||
return false;
|
||||
|
||||
/**
|
||||
@ -1783,9 +1782,10 @@ static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
|
||||
* Get ALL skills except npc/guild ones. [Skotlex]
|
||||
* Don't add SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
|
||||
**/
|
||||
for( i = 0; i < MAX_SKILL; i++ ) {
|
||||
uint16 skill_id = skill_idx2id(i);
|
||||
if (!skill_id || (skill_get_inf2(skill_id)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)))
|
||||
for (const auto &skill : skill_db) {
|
||||
uint16 skill_id = skill.second->nameid;
|
||||
|
||||
if (skill_id == 0 || skill.second->inf2[INF2_ISNPC]|| skill.second->inf2[INF2_ISGUILD])
|
||||
continue;
|
||||
switch (skill_id) {
|
||||
case SM_SELFPROVOKE:
|
||||
@ -1811,10 +1811,13 @@ static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
|
||||
default:
|
||||
{
|
||||
uint8 lv = (uint8)skill_get_max(skill_id);
|
||||
|
||||
if (lv > 0) {
|
||||
sd->status.skill[i].id = skill_id;
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
sd->status.skill[idx].id = skill_id;
|
||||
if (addlv)
|
||||
sd->status.skill[i].lv = lv;
|
||||
sd->status.skill[idx].lv = lv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1829,72 +1832,74 @@ static bool pc_grant_allskills(struct map_session_data *sd, bool addlv) {
|
||||
*------------------------------------------*/
|
||||
void pc_calc_skilltree(struct map_session_data *sd)
|
||||
{
|
||||
int i, flag;
|
||||
int c = 0;
|
||||
|
||||
nullpo_retv(sd);
|
||||
i = pc_calc_skilltree_normalize_job(sd);
|
||||
c = pc_mapid2jobid(i, sd->status.sex);
|
||||
if( c == -1 )
|
||||
|
||||
int job = pc_calc_skilltree_normalize_job(sd);
|
||||
int class_ = pc_mapid2jobid(job, sd->status.sex);
|
||||
|
||||
if( class_ == -1 )
|
||||
{ //Unable to normalize job??
|
||||
ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
|
||||
ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", job, sd->status.name, sd->status.account_id, sd->status.char_id);
|
||||
return;
|
||||
}
|
||||
c = pc_class2idx(c);
|
||||
class_ = pc_class2idx(class_);
|
||||
|
||||
for( i = 0; i < MAX_SKILL; i++ ) {
|
||||
if( sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED ) //Don't touch these
|
||||
sd->status.skill[i].id = 0; //First clear skills.
|
||||
for (const auto &skill : skill_db) {
|
||||
uint16 skill_id = skill.second->nameid;
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
if( sd->status.skill[idx].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[idx].flag != SKILL_FLAG_PERM_GRANTED ) //Don't touch these
|
||||
sd->status.skill[idx].id = 0; //First clear skills.
|
||||
/* permanent skills that must be re-checked */
|
||||
if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED ) {
|
||||
uint16 sk_id = skill_idx2id(i);
|
||||
if (!sk_id) {
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
if( sd->status.skill[idx].flag == SKILL_FLAG_PERM_GRANTED ) {
|
||||
if (skill_id == 0) {
|
||||
sd->status.skill[idx].id = 0;
|
||||
sd->status.skill[idx].lv = 0;
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_PERMANENT;
|
||||
continue;
|
||||
}
|
||||
switch (sk_id) {
|
||||
switch (skill_id) {
|
||||
case NV_TRICKDEAD:
|
||||
if( (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) {
|
||||
sd->status.skill[i].id = 0;
|
||||
sd->status.skill[i].lv = 0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
sd->status.skill[idx].id = 0;
|
||||
sd->status.skill[idx].lv = 0;
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_PERMANENT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_SKILL; i++ ) {
|
||||
uint16 skill_id = 0;
|
||||
for (const auto &skill : skill_db) {
|
||||
uint16 skill_id = skill.second->nameid;
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
// Restore original level of skills after deleting earned skills.
|
||||
if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) {
|
||||
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
|
||||
if( sd->status.skill[idx].flag != SKILL_FLAG_PERMANENT && sd->status.skill[idx].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[idx].flag != SKILL_FLAG_PLAGIARIZED ) {
|
||||
sd->status.skill[idx].lv = (sd->status.skill[idx].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[idx].flag - SKILL_FLAG_REPLACED_LV_0;
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_PERMANENT;
|
||||
}
|
||||
|
||||
//Enable Bard/Dancer spirit linked skills.
|
||||
if (!(skill_id = skill_idx2id(i)) || skill_id < DC_HUMMING || skill_id > DC_SERVICEFORYOU)
|
||||
if (skill_id < DC_HUMMING || skill_id > DC_SERVICEFORYOU)
|
||||
continue;
|
||||
|
||||
if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER ) {
|
||||
//Link Dancer skills to bard.
|
||||
if( sd->status.sex ) {
|
||||
if( sd->status.skill[i-8].lv < 10 )
|
||||
if( sd->status.skill[idx - 8].lv < 10 )
|
||||
continue;
|
||||
sd->status.skill[i].id = skill_id;
|
||||
sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
|
||||
sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
|
||||
sd->status.skill[idx].id = skill_id;
|
||||
sd->status.skill[idx].lv = sd->status.skill[idx - 8].lv; // Set the level to the same as the linking skill
|
||||
sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
|
||||
}
|
||||
//Link Bard skills to dancer.
|
||||
else {
|
||||
if( sd->status.skill[i].lv < 10 )
|
||||
if( sd->status.skill[idx].lv < 10 )
|
||||
continue;
|
||||
sd->status.skill[i-8].id = skill_id - 8;
|
||||
sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
|
||||
sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
|
||||
sd->status.skill[idx - 8].id = skill_id - 8;
|
||||
sd->status.skill[idx - 8].lv = sd->status.skill[idx].lv; // Set the level to the same as the linking skill
|
||||
sd->status.skill[idx - 8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1903,7 +1908,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
if ((sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON) {
|
||||
uint16 c_ = pc_class2idx(JOB_TAEKWON);
|
||||
|
||||
for (i = 0; i < MAX_SKILL_TREE; i++) {
|
||||
for (uint16 i = 0; i < MAX_SKILL_TREE; i++) {
|
||||
uint16 sk_id = skill_tree[c_][i].skill_id;
|
||||
uint16 sk_idx = 0;
|
||||
|
||||
@ -1921,11 +1926,13 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
// Grant all skills
|
||||
pc_grant_allskills(sd, false);
|
||||
|
||||
int flag;
|
||||
|
||||
do {
|
||||
uint16 skid = 0;
|
||||
|
||||
flag = 0;
|
||||
for (i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].skill_id) > 0; i++) {
|
||||
for (uint16 i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[class_][i].skill_id) > 0; i++) {
|
||||
bool fail = false;
|
||||
uint16 sk_idx = skill_get_index(skid);
|
||||
|
||||
@ -1933,11 +1940,9 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
continue; //Skill already known.
|
||||
|
||||
if (!battle_config.skillfree) {
|
||||
uint8 j;
|
||||
|
||||
// Checking required skills
|
||||
for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
|
||||
uint16 sk_need_id = skill_tree[c][i].need[j].skill_id;
|
||||
for(uint8 j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
|
||||
uint16 sk_need_id = skill_tree[class_][i].need[j].skill_id;
|
||||
uint16 sk_need_idx = 0;
|
||||
|
||||
if (sk_need_id && (sk_need_idx = skill_get_index(sk_need_id))) {
|
||||
@ -1950,40 +1955,42 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
else
|
||||
sk_need = pc_checkskill(sd,sk_need_id);
|
||||
|
||||
if (sk_need < skill_tree[c][i].need[j].skill_lv) {
|
||||
if (sk_need < skill_tree[class_][i].need[j].skill_lv) {
|
||||
fail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sd->status.base_level < skill_tree[c][i].baselv) { //We need to get the actual class in this case
|
||||
int class_ = pc_mapid2jobid(sd->class_, sd->status.sex);
|
||||
class_ = pc_class2idx(class_);
|
||||
if (class_ == c || (class_ != c && sd->status.base_level < skill_tree[class_][i].baselv))
|
||||
if (sd->status.base_level < skill_tree[class_][i].baselv) { //We need to get the actual class in this case
|
||||
int c_ = pc_mapid2jobid(sd->class_, sd->status.sex);
|
||||
|
||||
c_ = pc_class2idx(c_);
|
||||
if (class_ == c_ || (class_ != c_ && sd->status.base_level < skill_tree[class_][i].baselv))
|
||||
fail = true; // base level requirement wasn't satisfied
|
||||
}
|
||||
if (sd->status.job_level < skill_tree[c][i].joblv) { //We need to get the actual class in this case
|
||||
int class_ = pc_mapid2jobid(sd->class_, sd->status.sex);
|
||||
class_ = pc_class2idx(class_);
|
||||
if (class_ == c || (class_ != c && sd->status.job_level < skill_tree[class_][i].joblv))
|
||||
if (sd->status.job_level < skill_tree[class_][i].joblv) { //We need to get the actual class in this case
|
||||
int c_ = pc_mapid2jobid(sd->class_, sd->status.sex);
|
||||
|
||||
c_ = pc_class2idx(c_);
|
||||
if (class_ == c_ || (class_ != c_ && sd->status.job_level < skill_tree[class_][i].joblv))
|
||||
fail = true; // job level requirement wasn't satisfied
|
||||
}
|
||||
}
|
||||
|
||||
if (!fail) {
|
||||
int inf2 = skill_get_inf2(skid);
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skid);
|
||||
|
||||
if (!sd->status.skill[sk_idx].lv && (
|
||||
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
|
||||
inf2&INF2_WEDDING_SKILL ||
|
||||
(inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
|
||||
(skill->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn) ||
|
||||
skill->inf2[INF2_ISWEDDING] ||
|
||||
(skill->inf2[INF2_ISSPIRIT] && !sd->sc.data[SC_SPIRIT])
|
||||
))
|
||||
continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
|
||||
|
||||
sd->status.skill[sk_idx].id = skid;
|
||||
|
||||
if(inf2&INF2_SPIRIT_SKILL) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
|
||||
if(skill->inf2[INF2_ISSPIRIT]) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
|
||||
sd->status.skill[sk_idx].lv = 1; // need to manually specify a skill level
|
||||
sd->status.skill[sk_idx].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
|
||||
}
|
||||
@ -1992,19 +1999,22 @@ void pc_calc_skilltree(struct map_session_data *sd)
|
||||
}
|
||||
} while(flag);
|
||||
|
||||
if( c > 0 && sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) ) {
|
||||
unsigned short skid = 0;
|
||||
if( class_ > 0 && sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) ) {
|
||||
uint16 skid = 0;
|
||||
|
||||
/* Taekwon Ranker Bonus Skill Tree
|
||||
============================================
|
||||
- Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
|
||||
- (c > 0) to avoid grant Novice Skill Tree in case of Skill Reset (need more logic)
|
||||
- (sd->status.skill_point == 0) to wait until all skill points are assigned to avoid problems with Job Change quest. */
|
||||
|
||||
for( i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[c][i].skill_id) > 0; i++ ) {
|
||||
uint16 sk_idx = 0;
|
||||
if (!(sk_idx = skill_get_index(skid)))
|
||||
for( uint16 i = 0; i < MAX_SKILL_TREE && (skid = skill_tree[class_][i].skill_id) > 0; i++ ) {
|
||||
uint16 sk_idx = skill_get_index(skid);
|
||||
|
||||
if (sk_idx == 0)
|
||||
continue;
|
||||
if( (skill_get_inf2(skid)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) )
|
||||
|
||||
if( skill_get_inf2_(skid, { INF2_ISQUEST, INF2_ISWEDDING }) )
|
||||
continue; //Do not include Quest/Wedding skills.
|
||||
if( sd->status.skill[sk_idx].id == 0 ) {
|
||||
sd->status.skill[sk_idx].id = skid;
|
||||
@ -2072,11 +2082,12 @@ static void pc_check_skilltree(struct map_session_data *sd)
|
||||
if (sd->status.base_level < skill_tree[c][i].baselv || sd->status.job_level < skill_tree[c][i].joblv)
|
||||
continue;
|
||||
|
||||
j = skill_get_inf2(skid);
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skid);
|
||||
|
||||
if( !sd->status.skill[sk_idx].lv && (
|
||||
(j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
|
||||
j&INF2_WEDDING_SKILL ||
|
||||
(j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
|
||||
(skill->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn) ||
|
||||
skill->inf2[INF2_ISWEDDING] ||
|
||||
(skill->inf2[INF2_ISSPIRIT] && !sd->sc.data[SC_SPIRIT])
|
||||
) )
|
||||
continue; //Cannot be learned via normal means.
|
||||
|
||||
@ -4106,7 +4117,7 @@ void pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
|
||||
if(sd->state.lr_flag != 2)
|
||||
{
|
||||
int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
|
||||
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
|
||||
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !skill_get_inf2(type2, INF2_NOTARGETSELF));
|
||||
pc_bonus_autospell(sd->autospell, target?-type2:type2, type3, val, 0, current_equip_card_id);
|
||||
}
|
||||
break;
|
||||
@ -4114,7 +4125,7 @@ void pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
|
||||
if(sd->state.lr_flag != 2)
|
||||
{
|
||||
int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
|
||||
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
|
||||
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !skill_get_inf2(type2, INF2_NOTARGETSELF));
|
||||
pc_bonus_autospell(sd->autospell2, target?-type2:type2, type3, val, BF_NORMAL|BF_SKILL, current_equip_card_id);
|
||||
}
|
||||
break;
|
||||
@ -4242,7 +4253,7 @@ void pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type
|
||||
if(sd->state.lr_flag != 2)
|
||||
{
|
||||
int target = skill_get_inf(type3); //Support or Self (non-auto-target) skills should pick self.
|
||||
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type3)&INF2_NO_TARGET_SELF));
|
||||
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !skill_get_inf2(type3, INF2_NOTARGETSELF));
|
||||
|
||||
pc_bonus_autospell_onskill(sd->autospell3, type2, target?-type3:type3, type4, val, current_equip_card_id);
|
||||
}
|
||||
@ -6009,12 +6020,11 @@ bool pc_memo(struct map_session_data* sd, int pos)
|
||||
* @return player skill cooldown
|
||||
*/
|
||||
int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv) {
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
int cooldown = 0;
|
||||
|
||||
if (!idx) return 0;
|
||||
if (skill_db[idx]->cooldown[skill_lv - 1])
|
||||
cooldown = skill_db[idx]->cooldown[skill_lv - 1];
|
||||
int cooldown = skill_get_cooldown(skill_id, skill_lv);
|
||||
|
||||
if (cooldown == 0)
|
||||
return 0;
|
||||
|
||||
if (skill_id == SU_TUNABELLY && pc_checkskill(sd, SU_SPIRITOFSEA))
|
||||
cooldown -= skill_get_time(SU_TUNABELLY, skill_lv);
|
||||
|
||||
@ -7479,14 +7489,16 @@ int pc_allskillup(struct map_session_data *sd)
|
||||
if (!pc_grant_allskills(sd, true)) {
|
||||
uint16 sk_id;
|
||||
for (i = 0; i < MAX_SKILL_TREE && (sk_id = skill_tree[pc_class2idx(sd->status.class_)][i].skill_id) > 0;i++){
|
||||
int inf2 = 0;
|
||||
uint16 sk_idx = 0;
|
||||
if (!sk_id || !(sk_idx = skill_get_index(sk_id)))
|
||||
uint16 sk_idx = skill_get_index(sk_id);
|
||||
|
||||
if (sk_id == 0 || sk_idx == 0)
|
||||
continue;
|
||||
inf2 = skill_get_inf2(sk_id);
|
||||
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(sk_id);
|
||||
|
||||
if (
|
||||
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
|
||||
(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
|
||||
(skill->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn) ||
|
||||
((skill->inf2[INF2_ISWEDDING] || skill->inf2[INF2_ISSPIRIT])) ||
|
||||
sk_id == SG_DEVIL
|
||||
)
|
||||
continue; //Cannot be learned normally.
|
||||
@ -7708,17 +7720,14 @@ int pc_resetskill(struct map_session_data* sd, int flag)
|
||||
status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER);
|
||||
}
|
||||
|
||||
for( i = 1; i < MAX_SKILL; i++ )
|
||||
{
|
||||
for (const auto &skill : skill_db) {
|
||||
uint8 lv = sd->status.skill[i].lv;
|
||||
int inf2;
|
||||
uint16 skill_id = skill_idx2id(i);
|
||||
uint16 skill_id = skill.second->nameid;
|
||||
|
||||
if (lv == 0 || skill_id == 0)
|
||||
continue;
|
||||
|
||||
inf2 = skill_get_inf2(skill_id);
|
||||
|
||||
if( inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL) ) //Avoid reseting wedding/linker skills.
|
||||
if( skill.second->inf2[INF2_ISWEDDING] || skill.second->inf2[INF2_ISSPIRIT] ) //Avoid reseting wedding/linker skills.
|
||||
continue;
|
||||
|
||||
// Don't reset trick dead if not a novice/baby
|
||||
@ -7739,7 +7748,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
|
||||
if( flag&4 && !skill_ischangesex(skill_id) )
|
||||
continue;
|
||||
|
||||
if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn )
|
||||
if( skill.second->inf2[INF2_ISQUEST] && !battle_config.quest_skill_learn )
|
||||
{ //Only handle quest skills in a special way when you can't learn them manually
|
||||
if( battle_config.quest_skill_reset && !(flag&2) )
|
||||
{ //Wipe them
|
||||
@ -9290,7 +9299,7 @@ void pc_setoption(struct map_session_data *sd,int type)
|
||||
for (uint8 i = 0; i < ARRAYLENGTH(statuses); i++) {
|
||||
int skill_id = status_sc2skill(statuses[i]);
|
||||
|
||||
if (skill_id >= 0 && !(skill_get_inf3(skill_id)&INF3_USABLE_MADO))
|
||||
if (skill_id > 0 && !skill_get_inf2(skill_id, INF2_ALLOWONMADO))
|
||||
status_change_end(&sd->bl,statuses[i],INVALID_TIMER);
|
||||
}
|
||||
pc_bonus_script_clear(sd,BSF_REM_ON_MADOGEAR);
|
||||
@ -11510,7 +11519,7 @@ static bool pc_readdb_skilltree(char* fields[], int columns, int current)
|
||||
idx = pc_class2idx(class_);
|
||||
|
||||
if (!skill_get_index(skill_id)) {
|
||||
ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree.", skill_id, class_);
|
||||
ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree.\n", skill_id, class_);
|
||||
return false;
|
||||
}
|
||||
if (skill_lv > (skill_lv_max = skill_get_max(skill_id))) {
|
||||
|
@ -382,7 +382,7 @@ struct map_session_data {
|
||||
uint16 skill_id_dance,skill_lv_dance;
|
||||
short cook_mastery; // range: [0,1999] [Inkfish]
|
||||
struct skill_cooldown_entry * scd[MAX_SKILLCOOLDOWN]; // Skill Cooldown
|
||||
short cloneskill_idx, ///Stores index of copied skill by Intimidate/Plagiarism
|
||||
uint16 cloneskill_idx, ///Stores index of copied skill by Intimidate/Plagiarism
|
||||
reproduceskill_idx; ///Stores index of copied skill by Reproduce
|
||||
int menuskill_id, menuskill_val, menuskill_val2;
|
||||
|
||||
|
@ -3504,6 +3504,9 @@
|
||||
export_constant(ELE_GHOST);
|
||||
export_constant(ELE_UNDEAD);
|
||||
export_constant(ELE_ALL);
|
||||
export_constant(ELE_WEAPON);
|
||||
export_constant(ELE_ENDOWED);
|
||||
export_constant(ELE_RANDOM);
|
||||
|
||||
/* races */
|
||||
export_constant(RC_FORMLESS);
|
||||
@ -3570,6 +3573,7 @@
|
||||
export_constant(AI_FAW);
|
||||
|
||||
/* battle flags */
|
||||
export_constant(BF_NONE);
|
||||
export_constant(BF_WEAPON);
|
||||
export_constant(BF_MAGIC);
|
||||
export_constant(BF_MISC);
|
||||
@ -7403,6 +7407,284 @@
|
||||
export_constant(CPC_CHAR);
|
||||
export_constant(CPC_ACCOUNT);
|
||||
|
||||
/* skill hit */
|
||||
export_constant(DMG_SINGLE);
|
||||
export_constant(DMG_MULTI_HIT);
|
||||
|
||||
/* skill nk */
|
||||
export_constant(NK_NODAMAGE);
|
||||
export_constant(NK_SPLASH);
|
||||
export_constant(NK_SPLASHSPLIT);
|
||||
export_constant(NK_IGNOREATKCARD);
|
||||
export_constant(NK_IGNOREELEMENT);
|
||||
export_constant(NK_IGNOREDEFENSE);
|
||||
export_constant(NK_IGNOREFLEE);
|
||||
export_constant(NK_IGNOREDEFCARD);
|
||||
export_constant(NK_CRITICAL);
|
||||
|
||||
/* skill inf */
|
||||
export_constant(INF_PASSIVE_SKILL);
|
||||
export_constant(INF_ATTACK_SKILL);
|
||||
export_constant(INF_GROUND_SKILL);
|
||||
export_constant(INF_SELF_SKILL);
|
||||
export_constant(INF_SUPPORT_SKILL);
|
||||
export_constant(INF_TRAP_SKILL);
|
||||
|
||||
/* skill inf2 */
|
||||
export_constant(INF2_ISQUEST);
|
||||
export_constant(INF2_ISNPC);
|
||||
export_constant(INF2_ISWEDDING);
|
||||
export_constant(INF2_ISSPIRIT);
|
||||
export_constant(INF2_ISGUILD);
|
||||
export_constant(INF2_ISSONG);
|
||||
export_constant(INF2_ISENSEMBLE);
|
||||
export_constant(INF2_ISTRAP);
|
||||
export_constant(INF2_TARGETSELF);
|
||||
export_constant(INF2_NOTARGETSELF);
|
||||
export_constant(INF2_PARTYONLY);
|
||||
export_constant(INF2_GUILDONLY);
|
||||
export_constant(INF2_NOTARGETENEMY);
|
||||
export_constant(INF2_ISAUTOSHADOWSPELL);
|
||||
export_constant(INF2_ISCHORUS);
|
||||
export_constant(INF2_IGNOREBGREDUCTION);
|
||||
export_constant(INF2_IGNOREGVGREDUCTION);
|
||||
export_constant(INF2_DISABLENEARNPC);
|
||||
export_constant(INF2_TARGETTRAP);
|
||||
export_constant(INF2_IGNORELANDPROTECTOR);
|
||||
export_constant(INF2_ALLOWWHENHIDDEN);
|
||||
export_constant(INF2_ALLOWWHENPERFORMING);
|
||||
export_constant(INF2_TARGETEMPERIUM);
|
||||
export_constant(INF2_IGNORESTASIS);
|
||||
export_constant(INF2_IGNOREKAGEHUMI);
|
||||
export_constant(INF2_ALTERRANGEVULTURE);
|
||||
export_constant(INF2_ALTERRANGESNAKEEYE);
|
||||
export_constant(INF2_ALTERRANGESHADOWJUMP);
|
||||
export_constant(INF2_ALTERRANGERADIUS);
|
||||
export_constant(INF2_ALTERRANGERESEARCHTRAP);
|
||||
export_constant(INF2_IGNOREHOVERING);
|
||||
export_constant(INF2_ALLOWONWARG);
|
||||
export_constant(INF2_ALLOWONMADO);
|
||||
export_constant(INF2_TARGETMANHOLE);
|
||||
export_constant(INF2_TARGETHIDDEN);
|
||||
export_constant(INF2_INCREASEGLOOMYDAYDAMAGE);
|
||||
export_constant(INF2_INCREASEDANCEWITHWUGDAMAGE);
|
||||
export_constant(INF2_IGNOREWUGBITE);
|
||||
export_constant(INF2_IGNOREAUTOGUARD);
|
||||
export_constant(INF2_IGNORECICADA);
|
||||
|
||||
/* skill no near npc flags */
|
||||
export_constant(SKILL_NONEAR_WARPPORTAL);
|
||||
export_constant(SKILL_NONEAR_SHOP);
|
||||
export_constant(SKILL_NONEAR_NPC);
|
||||
export_constant(SKILL_NONEAR_TOMB);
|
||||
|
||||
/* skill cast flags */
|
||||
export_constant(SKILL_CAST_IGNOREDEX);
|
||||
export_constant(SKILL_CAST_IGNORESTATUS);
|
||||
export_constant(SKILL_CAST_IGNOREITEMBONUS);
|
||||
|
||||
/* skill require cost flags */
|
||||
export_constant(SKILL_REQ_HPCOST);
|
||||
export_constant(SKILL_REQ_SPCOST);
|
||||
export_constant(SKILL_REQ_HPRATECOST);
|
||||
export_constant(SKILL_REQ_SPRATECOST);
|
||||
export_constant(SKILL_REQ_MAXHPTRIGGER);
|
||||
export_constant(SKILL_REQ_ZENYCOST);
|
||||
export_constant(SKILL_REQ_WEAPON);
|
||||
export_constant(SKILL_REQ_AMMO);
|
||||
export_constant(SKILL_REQ_STATE);
|
||||
export_constant(SKILL_REQ_STATUS);
|
||||
export_constant(SKILL_REQ_SPIRITSPHERECOST);
|
||||
export_constant(SKILL_REQ_ITEMCOST);
|
||||
export_constant(SKILL_REQ_EQUIPMENT);
|
||||
|
||||
/* skill require state */
|
||||
export_constant(ST_NONE);
|
||||
export_constant(ST_HIDDEN);
|
||||
export_constant(ST_RIDING);
|
||||
export_constant(ST_FALCON);
|
||||
export_constant(ST_CART);
|
||||
export_constant(ST_SHIELD);
|
||||
export_constant(ST_RECOVER_WEIGHT_RATE);
|
||||
export_constant(ST_MOVE_ENABLE);
|
||||
export_constant(ST_WATER);
|
||||
export_constant(ST_RIDINGDRAGON);
|
||||
export_constant(ST_WUG);
|
||||
export_constant(ST_RIDINGWUG);
|
||||
export_constant(ST_MADO);
|
||||
export_constant(ST_ELEMENTALSPIRIT);
|
||||
export_constant(ST_ELEMENTALSPIRIT2);
|
||||
export_constant(ST_PECO);
|
||||
|
||||
/* skill unit flags */
|
||||
export_constant(UF_NOENEMY);
|
||||
export_constant(UF_NOREITERATION);
|
||||
export_constant(UF_NOFOOTSET);
|
||||
export_constant(UF_NOOVERLAP);
|
||||
export_constant(UF_PATHCHECK);
|
||||
export_constant(UF_NOPC);
|
||||
export_constant(UF_NOMOB);
|
||||
export_constant(UF_SKILL);
|
||||
export_constant(UF_DANCE);
|
||||
export_constant(UF_ENSEMBLE);
|
||||
export_constant(UF_SONG);
|
||||
export_constant(UF_DUALMODE);
|
||||
export_constant(UF_NOKNOCKBACK);
|
||||
export_constant(UF_RANGEDSINGLEUNIT);
|
||||
export_constant(UF_CRAZYWEEDIMMUNE);
|
||||
export_constant(UF_REMOVEDBYFIRERAIN);
|
||||
export_constant(UF_KNOCKBACKGROUP);
|
||||
export_constant(UF_HIDDENTRAP);
|
||||
|
||||
/* battle check target */
|
||||
export_constant(BCT_SELF);
|
||||
export_constant(BCT_ENEMY);
|
||||
export_constant(BCT_PARTY);
|
||||
export_constant(BCT_GUILDALLY);
|
||||
export_constant(BCT_NEUTRAL);
|
||||
export_constant(BCT_SAMEGUILD);
|
||||
export_constant(BCT_ALL);
|
||||
export_constant(BCT_WOS);
|
||||
export_constant(BCT_GUILD);
|
||||
export_constant(BCT_NOGUILD);
|
||||
export_constant(BCT_NOPARTY);
|
||||
export_constant(BCT_NOENEMY);
|
||||
export_constant(BCT_ALLY);
|
||||
export_constant(BCT_FRIEND);
|
||||
|
||||
/* skill unit */
|
||||
export_constant(UNT_SAFETYWALL);
|
||||
export_constant(UNT_FIREWALL);
|
||||
export_constant(UNT_WARP_WAITING);
|
||||
export_constant(UNT_WARP_ACTIVE);
|
||||
export_constant(UNT_SANCTUARY);
|
||||
export_constant(UNT_MAGNUS);
|
||||
export_constant(UNT_PNEUMA);
|
||||
export_constant(UNT_DUMMYSKILL);
|
||||
export_constant(UNT_FIREPILLAR_WAITING);
|
||||
export_constant(UNT_FIREPILLAR_ACTIVE);
|
||||
export_constant(UNT_USED_TRAPS);
|
||||
export_constant(UNT_ICEWALL);
|
||||
export_constant(UNT_QUAGMIRE);
|
||||
export_constant(UNT_BLASTMINE);
|
||||
export_constant(UNT_SKIDTRAP);
|
||||
export_constant(UNT_ANKLESNARE);
|
||||
export_constant(UNT_VENOMDUST);
|
||||
export_constant(UNT_LANDMINE);
|
||||
export_constant(UNT_SHOCKWAVE);
|
||||
export_constant(UNT_SANDMAN);
|
||||
export_constant(UNT_FLASHER);
|
||||
export_constant(UNT_FREEZINGTRAP);
|
||||
export_constant(UNT_CLAYMORETRAP);
|
||||
export_constant(UNT_TALKIEBOX);
|
||||
export_constant(UNT_VOLCANO);
|
||||
export_constant(UNT_DELUGE);
|
||||
export_constant(UNT_VIOLENTGALE);
|
||||
export_constant(UNT_LANDPROTECTOR);
|
||||
export_constant(UNT_LULLABY);
|
||||
export_constant(UNT_RICHMANKIM);
|
||||
export_constant(UNT_ETERNALCHAOS);
|
||||
export_constant(UNT_DRUMBATTLEFIELD);
|
||||
export_constant(UNT_RINGNIBELUNGEN);
|
||||
export_constant(UNT_ROKISWEIL);
|
||||
export_constant(UNT_INTOABYSS);
|
||||
export_constant(UNT_SIEGFRIED);
|
||||
export_constant(UNT_DISSONANCE);
|
||||
export_constant(UNT_WHISTLE);
|
||||
export_constant(UNT_ASSASSINCROSS);
|
||||
export_constant(UNT_POEMBRAGI);
|
||||
export_constant(UNT_APPLEIDUN);
|
||||
export_constant(UNT_UGLYDANCE);
|
||||
export_constant(UNT_HUMMING);
|
||||
export_constant(UNT_DONTFORGETME);
|
||||
export_constant(UNT_FORTUNEKISS);
|
||||
export_constant(UNT_SERVICEFORYOU);
|
||||
export_constant(UNT_GRAFFITI);
|
||||
export_constant(UNT_DEMONSTRATION);
|
||||
export_constant(UNT_CALLFAMILY);
|
||||
export_constant(UNT_GOSPEL);
|
||||
export_constant(UNT_BASILICA);
|
||||
export_constant(UNT_MOONLIT);
|
||||
export_constant(UNT_FOGWALL);
|
||||
export_constant(UNT_SPIDERWEB);
|
||||
export_constant(UNT_GRAVITATION);
|
||||
export_constant(UNT_HERMODE);
|
||||
export_constant(UNT_SUITON);
|
||||
export_constant(UNT_TATAMIGAESHI);
|
||||
export_constant(UNT_KAEN);
|
||||
export_constant(UNT_GROUNDDRIFT_WIND);
|
||||
export_constant(UNT_GROUNDDRIFT_DARK);
|
||||
export_constant(UNT_GROUNDDRIFT_POISON);
|
||||
export_constant(UNT_GROUNDDRIFT_WATER);
|
||||
export_constant(UNT_GROUNDDRIFT_FIRE);
|
||||
export_constant(UNT_EVILLAND);
|
||||
export_constant(UNT_EPICLESIS);
|
||||
export_constant(UNT_EARTHSTRAIN);
|
||||
export_constant(UNT_MANHOLE);
|
||||
export_constant(UNT_DIMENSIONDOOR);
|
||||
export_constant(UNT_CHAOSPANIC);
|
||||
export_constant(UNT_MAELSTROM);
|
||||
export_constant(UNT_BLOODYLUST);
|
||||
export_constant(UNT_FEINTBOMB);
|
||||
export_constant(UNT_MAGENTATRAP);
|
||||
export_constant(UNT_COBALTTRAP);
|
||||
export_constant(UNT_MAIZETRAP);
|
||||
export_constant(UNT_VERDURETRAP);
|
||||
export_constant(UNT_FIRINGTRAP);
|
||||
export_constant(UNT_ICEBOUNDTRAP);
|
||||
export_constant(UNT_ELECTRICSHOCKER);
|
||||
export_constant(UNT_CLUSTERBOMB);
|
||||
export_constant(UNT_REVERBERATION);
|
||||
export_constant(UNT_SEVERE_RAINSTORM);
|
||||
export_constant(UNT_FIREWALK);
|
||||
export_constant(UNT_ELECTRICWALK);
|
||||
export_constant(UNT_NETHERWORLD);
|
||||
export_constant(UNT_PSYCHIC_WAVE);
|
||||
export_constant(UNT_CLOUD_KILL);
|
||||
export_constant(UNT_POISONSMOKE);
|
||||
export_constant(UNT_NEUTRALBARRIER);
|
||||
export_constant(UNT_STEALTHFIELD);
|
||||
export_constant(UNT_WARMER);
|
||||
export_constant(UNT_THORNS_TRAP);
|
||||
export_constant(UNT_WALLOFTHORN);
|
||||
export_constant(UNT_DEMONIC_FIRE);
|
||||
export_constant(UNT_FIRE_EXPANSION_SMOKE_POWDER);
|
||||
export_constant(UNT_FIRE_EXPANSION_TEAR_GAS);
|
||||
export_constant(UNT_HELLS_PLANT);
|
||||
export_constant(UNT_VACUUM_EXTREME);
|
||||
export_constant(UNT_BANDING);
|
||||
export_constant(UNT_FIRE_MANTLE);
|
||||
export_constant(UNT_WATER_BARRIER);
|
||||
export_constant(UNT_ZEPHYR);
|
||||
export_constant(UNT_POWER_OF_GAIA);
|
||||
export_constant(UNT_FIRE_INSIGNIA);
|
||||
export_constant(UNT_WATER_INSIGNIA);
|
||||
export_constant(UNT_WIND_INSIGNIA);
|
||||
export_constant(UNT_EARTH_INSIGNIA);
|
||||
export_constant(UNT_POISON_MIST);
|
||||
export_constant(UNT_LAVA_SLIDE);
|
||||
export_constant(UNT_VOLCANIC_ASH);
|
||||
export_constant(UNT_ZENKAI_WATER);
|
||||
export_constant(UNT_ZENKAI_LAND);
|
||||
export_constant(UNT_ZENKAI_FIRE);
|
||||
export_constant(UNT_ZENKAI_WIND);
|
||||
export_constant(UNT_MAKIBISHI);
|
||||
export_constant(UNT_VENOMFOG);
|
||||
export_constant(UNT_ICEMINE);
|
||||
export_constant(UNT_FLAMECROSS);
|
||||
export_constant(UNT_HELLBURNING);
|
||||
export_constant(UNT_MAGMA_ERUPTION);
|
||||
export_constant(UNT_KINGS_GRACE);
|
||||
export_constant(UNT_GLITTERING_GREED);
|
||||
export_constant(UNT_B_TRAP);
|
||||
export_constant(UNT_FIRE_RAIN);
|
||||
export_constant(UNT_CATNIPPOWDER);
|
||||
export_constant(UNT_NYANGGRASS);
|
||||
export_constant(UNT_GD_LEADERSHIP);
|
||||
export_constant(UNT_GD_GLORYWOUNDS);
|
||||
export_constant(UNT_GD_SOULCOLD);
|
||||
export_constant(UNT_GD_HAWKEYES);
|
||||
|
||||
#undef export_constant
|
||||
#undef export_constant2
|
||||
#undef export_parameter
|
||||
|
2470
src/map/skill.cpp
2470
src/map/skill.cpp
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@
|
||||
#define SKILL_HPP
|
||||
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
|
||||
#include "../common/cbasetypes.hpp"
|
||||
#include "../common/database.hpp"
|
||||
@ -18,6 +19,8 @@ enum damage_lv : uint8;
|
||||
enum sc_type : int16;
|
||||
enum send_target : uint8;
|
||||
enum e_damage_type : uint8;
|
||||
enum e_battle_flag : uint16;
|
||||
enum e_battle_check_target : uint32;
|
||||
struct map_session_data;
|
||||
struct homun_data;
|
||||
struct skill_unit;
|
||||
@ -34,81 +37,138 @@ struct status_change_entry;
|
||||
#define SKILL_NAME_LENGTH 31 /// Max Skill Name length
|
||||
#define SKILL_DESC_LENGTH 31 /// Max Skill Desc length
|
||||
|
||||
extern DBMap* skilldb_name2id;
|
||||
|
||||
/// Constants to identify a skill's nk value (damage properties)
|
||||
/// The NK value applies only to non INF_GROUND_SKILL skills
|
||||
/// when determining skill castend function to invoke.
|
||||
enum e_skill_nk : uint16 {
|
||||
NK_NO_DAMAGE = 0x01,
|
||||
NK_SPLASH = 0x02|0x04, // 0x4 = splash & split
|
||||
NK_SPLASHSPLIT = 0x04,
|
||||
NK_NO_CARDFIX_ATK = 0x08,
|
||||
NK_NO_ELEFIX = 0x10,
|
||||
NK_IGNORE_DEF = 0x20,
|
||||
NK_IGNORE_FLEE = 0x40,
|
||||
NK_NO_CARDFIX_DEF = 0x80,
|
||||
NK_CRITICAL = 0x100,
|
||||
enum e_skill_nk : uint8 {
|
||||
NK_NODAMAGE = 0,
|
||||
NK_SPLASH,
|
||||
NK_SPLASHSPLIT,
|
||||
NK_IGNOREATKCARD,
|
||||
NK_IGNOREELEMENT,
|
||||
NK_IGNOREDEFENSE,
|
||||
NK_IGNOREFLEE,
|
||||
NK_IGNOREDEFCARD,
|
||||
NK_CRITICAL,
|
||||
NK_MAX,
|
||||
};
|
||||
|
||||
/// Constants to identify the skill's inf value:
|
||||
enum e_skill_inf {
|
||||
/// Constants to identify the skill's inf value.
|
||||
enum e_skill_inf : uint16 {
|
||||
INF_PASSIVE_SKILL = 0x00, // Used just for skill_db parsing
|
||||
INF_ATTACK_SKILL = 0x01,
|
||||
INF_GROUND_SKILL = 0x02,
|
||||
INF_SELF_SKILL = 0x04, // Skills casted on self where target is automatically chosen
|
||||
// 0x08 not assigned
|
||||
INF_SUPPORT_SKILL = 0x10,
|
||||
INF_TARGET_TRAP = 0x20,
|
||||
INF_TRAP_SKILL = 0x20,
|
||||
};
|
||||
|
||||
/// A skill with 3 would be no damage + splash: area of effect.
|
||||
/// Constants to identify a skill's inf2 value.
|
||||
enum e_skill_inf2 {
|
||||
INF2_QUEST_SKILL = 0x00001,
|
||||
INF2_NPC_SKILL = 0x00002, //NPC skills are those that players can't have in their skill tree.
|
||||
INF2_WEDDING_SKILL = 0x00004,
|
||||
INF2_SPIRIT_SKILL = 0x00008,
|
||||
INF2_GUILD_SKILL = 0x00010,
|
||||
INF2_SONG_DANCE = 0x00020,
|
||||
INF2_ENSEMBLE_SKILL = 0x00040,
|
||||
INF2_TRAP = 0x00080,
|
||||
INF2_TARGET_SELF = 0x00100, //Refers to ground placed skills that will target the caster as well (like Grandcross)
|
||||
INF2_NO_TARGET_SELF = 0x00200,
|
||||
INF2_PARTY_ONLY = 0x00400,
|
||||
INF2_GUILD_ONLY = 0x00800,
|
||||
INF2_NO_ENEMY = 0x01000,
|
||||
INF2_AUTOSHADOWSPELL = 0x02000, // Skill that available for SC_AUTOSHADOWSPELL
|
||||
INF2_CHORUS_SKILL = 0x04000, // Chorus skill
|
||||
INF2_NO_BG_DMG = 0x08000, // Skill that ignore bg reduction
|
||||
INF2_NO_GVG_DMG = 0x10000, // Skill that ignore gvg reduction
|
||||
INF2_NO_NEARNPC = 0x20000, // disable to cast skill if near with NPC [Cydh]
|
||||
INF2_HIT_TRAP = 0x40000, // can hit trap-type skill (INF2_TRAP) [Cydh]
|
||||
/// Constants to identify the skill's inf2 value.
|
||||
enum e_skill_inf2 : uint8 {
|
||||
INF2_ISQUEST = 0,
|
||||
INF2_ISNPC, //NPC skills are those that players can't have in their skill tree.
|
||||
INF2_ISWEDDING,
|
||||
INF2_ISSPIRIT,
|
||||
INF2_ISGUILD,
|
||||
INF2_ISSONG,
|
||||
INF2_ISENSEMBLE,
|
||||
INF2_ISTRAP,
|
||||
INF2_TARGETSELF, //Refers to ground placed skills that will target the caster as well (like Grandcross)
|
||||
INF2_NOTARGETSELF,
|
||||
INF2_PARTYONLY,
|
||||
INF2_GUILDONLY,
|
||||
INF2_NOTARGETENEMY,
|
||||
INF2_ISAUTOSHADOWSPELL, // Skill that available for SC_AUTOSHADOWSPELL
|
||||
INF2_ISCHORUS, // Chorus skill
|
||||
INF2_IGNOREBGREDUCTION, // Skill that ignore bg reduction
|
||||
INF2_IGNOREGVGREDUCTION, // Skill that ignore gvg reduction
|
||||
INF2_DISABLENEARNPC, // disable to cast skill if near with NPC [Cydh]
|
||||
INF2_TARGETTRAP, // can hit trap-type skill (INF2_ISTRAP) [Cydh]
|
||||
INF2_IGNORELANDPROTECTOR, // Skill that can ignore Land Protector
|
||||
INF2_ALLOWWHENHIDDEN, // Skill that can be use in hiding
|
||||
INF2_ALLOWWHENPERFORMING, // Skill that can be use while in dancing state
|
||||
INF2_TARGETEMPERIUM, // Skill that could hit emperium
|
||||
INF2_IGNORESTASIS, // Skill that can ignore SC_STASIS
|
||||
INF2_IGNOREKAGEHUMI, // Skill blocked by kagehumi
|
||||
INF2_ALTERRANGEVULTURE, // Skill range affected by AC_VULTURE
|
||||
INF2_ALTERRANGESNAKEEYE, // Skill range affected by GS_SNAKEEYE
|
||||
INF2_ALTERRANGESHADOWJUMP, // Skill range affected by NJ_SHADOWJUMP
|
||||
INF2_ALTERRANGERADIUS, // Skill range affected by WL_RADIUS
|
||||
INF2_ALTERRANGERESEARCHTRAP, // Skill range affected by RA_RESEARCHTRAP
|
||||
INF2_IGNOREHOVERING, // Skill that does not affect user that has SC_HOVERING active
|
||||
INF2_ALLOWONWARG, // Skill that can be use while riding warg
|
||||
INF2_ALLOWONMADO, // Skill that can be used while on Madogear
|
||||
INF2_TARGETMANHOLE, // Skill that can be used to target while under SC__MANHOLE effect
|
||||
INF2_TARGETHIDDEN, // Skill that affects hidden targets
|
||||
INF2_INCREASEGLOOMYDAYDAMAGE, // Skill that affects SC_GLOOMYDAY_SK
|
||||
INF2_INCREASEDANCEWITHWUGDAMAGE, // Skill that is affected by SC_DANCEWITHWUG
|
||||
INF2_IGNOREWUGBITE, // Skill blocked by RA_WUGBITE
|
||||
INF2_IGNOREAUTOGUARD , // Skill is not blocked by SC_AUTOGUARD (physical-skill only)
|
||||
INF2_IGNORECICADA, // Skill is not blocked by SC_UTSUSEMI or SC_BUNSINJYUTSU (physical-skill only)
|
||||
INF2_MAX,
|
||||
};
|
||||
|
||||
/// Skill info type 3
|
||||
enum e_skill_inf3 {
|
||||
INF3_NOLP = 0x000001, // Skill that can ignore Land Protector
|
||||
INF3_FREE = 0x000002, // Free
|
||||
INF3_USABLE_HIDING = 0x000004, // Skill that can be use in hiding
|
||||
INF3_USABLE_DANCE = 0x000008, // Skill that can be use while in dancing state
|
||||
INF3_HIT_EMP = 0x000010, // Skill that could hit emperium
|
||||
INF3_STASIS_BL = 0x000020, // Skill that can ignore SC_STASIS
|
||||
INF3_KAGEHUMI_BL = 0x000040, // Skill blocked by kagehumi
|
||||
INF3_EFF_VULTURE = 0x000080, // Skill range affected by AC_VULTURE
|
||||
INF3_EFF_SNAKEEYE = 0x000100, // Skill range affected by GS_SNAKEEYE
|
||||
INF3_EFF_SHADOWJUMP = 0x000200, // Skill range affected by NJ_SHADOWJUMP
|
||||
INF3_EFF_RADIUS = 0x000400, // Skill range affected by WL_RADIUS
|
||||
INF3_EFF_RESEARCHTRAP = 0x000800, // Skill range affected by RA_RESEARCHTRAP
|
||||
INF3_NO_EFF_HOVERING = 0x001000, // Skill that does not affect user that has SC_HOVERING active
|
||||
INF3_USABLE_WARG = 0x002000, // Skill that can be use while riding warg
|
||||
INF3_USABLE_MADO = 0x004000, // Skill that can be used while on Madogear
|
||||
INF3_USABLE_MANHOLE = 0x008000, // Skill that can be used to target while under SC__MANHOLE effect
|
||||
INF3_HIT_HIDING = 0x010000, // Skill that affects hidden targets
|
||||
INF3_SC_GLOOMYDAY_SK = 0x020000, // Skill that affects SC_GLOOMYDAY_SK
|
||||
INF3_SC_DANCEWITHWUG = 0x040000, // Skill that is affected by SC_DANCEWITHWUG
|
||||
INF3_BITE_BLOCK = 0x080000, // Skill blocked by RA_WUGBITE
|
||||
INF3_NO_EFF_AUTOGUARD = 0x100000, // Skill is not blocked by SC_AUTOGUARD (physical-skill only)
|
||||
INF3_NO_EFF_CICADA = 0x200000, // Skill is not blocked by SC_UTSUSEMI or SC_BUNSINJYUTSU (physical-skill only)
|
||||
/// Constants for skill requirements
|
||||
enum e_skill_require : uint16 {
|
||||
SKILL_REQ_HPCOST = 0x1,
|
||||
SKILL_REQ_SPCOST = 0x2,
|
||||
SKILL_REQ_HPRATECOST = 0x4,
|
||||
SKILL_REQ_SPRATECOST = 0x8,
|
||||
SKILL_REQ_MAXHPTRIGGER = 0x10,
|
||||
SKILL_REQ_ZENYCOST = 0x20,
|
||||
SKILL_REQ_WEAPON = 0x40,
|
||||
SKILL_REQ_AMMO = 0x80,
|
||||
SKILL_REQ_STATE = 0x100,
|
||||
SKILL_REQ_STATUS = 0x200,
|
||||
SKILL_REQ_SPIRITSPHERECOST = 0x400,
|
||||
SKILL_REQ_ITEMCOST = 0x800,
|
||||
SKILL_REQ_EQUIPMENT = 0x1000,
|
||||
};
|
||||
|
||||
/// Constants for skill cast near NPC.
|
||||
enum e_skill_nonear_npc : uint8 {
|
||||
SKILL_NONEAR_WARPPORTAL = 0x1,
|
||||
SKILL_NONEAR_SHOP = 0x2,
|
||||
SKILL_NONEAR_NPC = 0x4,
|
||||
SKILL_NONEAR_TOMB = 0x8,
|
||||
};
|
||||
|
||||
/// Constants for skill cast adjustments.
|
||||
enum e_skill_cast_flags : uint8 {
|
||||
SKILL_CAST_IGNOREDEX = 0x1,
|
||||
SKILL_CAST_IGNORESTATUS = 0x2,
|
||||
SKILL_CAST_IGNOREITEMBONUS = 0x4,
|
||||
};
|
||||
|
||||
/// Constants for skill copyable options.
|
||||
enum e_skill_copyable_option : uint8 {
|
||||
SKILL_COPY_PLAGIARISM = 0x1,
|
||||
SKILL_COPY_REPRODUCE = 0x2,
|
||||
};
|
||||
|
||||
/// Constants for skill unit flags.
|
||||
enum e_skill_unit_flag : uint8 {
|
||||
UF_NONE = 0,
|
||||
UF_NOENEMY, // If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
UF_NOREITERATION, // Spell cannot be stacked
|
||||
UF_NOFOOTSET, // Spell cannot be cast near/on targets
|
||||
UF_NOOVERLAP, // Spell effects do not overlap
|
||||
UF_PATHCHECK, // Only cells with a shootable path will be placed
|
||||
UF_NOPC, // May not target players
|
||||
UF_NOMOB, // May not target mobs
|
||||
UF_SKILL, // May target skills
|
||||
UF_DANCE, // Dance
|
||||
UF_ENSEMBLE, // Duet
|
||||
UF_SONG, // Song
|
||||
UF_DUALMODE, // Spells should trigger both ontimer and onplace/onout/onleft effects.
|
||||
UF_NOKNOCKBACK, // Skill unit cannot be knocked back
|
||||
UF_RANGEDSINGLEUNIT, // hack for ranged layout, only display center
|
||||
UF_CRAZYWEEDIMMUNE, // Immune to Crazy Weed removal
|
||||
UF_REMOVEDBYFIRERAIN, // removed by Fire Rain
|
||||
UF_KNOCKBACKGROUP, // knockback skill unit with its group instead of single unit
|
||||
UF_HIDDENTRAP, // Hidden trap [Cydh]
|
||||
UF_MAX,
|
||||
};
|
||||
|
||||
/// Walk intervals at which chase-skills are attempted to be triggered.
|
||||
@ -132,112 +192,124 @@ enum e_skill_display {
|
||||
#define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item
|
||||
|
||||
/// Single skill requirement. !TODO: Cleanup the variable types
|
||||
struct skill_condition {
|
||||
int32 hp; ///< HP cost
|
||||
int32 mhp; ///< Max HP to trigger
|
||||
int32 sp; /// SP cost
|
||||
int16 hp_rate; /// HP cost (%)
|
||||
int16 sp_rate; /// SP cost (%)
|
||||
uint32 zeny; /// Zeny cost
|
||||
uint32 weapon; /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
|
||||
uint16 ammo; /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
|
||||
int8 ammo_qty; /// Amount of ammo
|
||||
uint8 state; /// State/condition. @see enum e_require_state
|
||||
int8 spiritball; /// Spiritball cost
|
||||
uint16 itemid[MAX_SKILL_ITEM_REQUIRE]; /// Required item
|
||||
uint16 amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
struct s_skill_condition {
|
||||
int32 hp; ///< HP cost
|
||||
int32 mhp; ///< Max HP to trigger
|
||||
int32 sp; /// SP cost
|
||||
int32 hp_rate; /// HP cost (%)
|
||||
int32 sp_rate; /// SP cost (%)
|
||||
int32 zeny; /// Zeny cost
|
||||
int32 weapon; /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
|
||||
int32 ammo; /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
|
||||
int32 ammo_qty; /// Amount of ammo
|
||||
int32 state; /// State/condition. @see enum e_require_state
|
||||
int32 spiritball; /// Spiritball cost
|
||||
int32 itemid[MAX_SKILL_ITEM_REQUIRE]; /// Required item
|
||||
int32 amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
std::vector<int32> eqItem; /// List of equipped item
|
||||
std::vector<sc_type> status; /// List of Status required (SC)
|
||||
};
|
||||
|
||||
/// Skill requirement structure. !TODO: Cleanup the variable types that use array [MAX_SKILL_LEVEL]
|
||||
/// Skill requirement structure.
|
||||
struct s_skill_require {
|
||||
int hp[MAX_SKILL_LEVEL]; ///< HP cost
|
||||
int mhp[MAX_SKILL_LEVEL]; ///< Max HP to trigger
|
||||
int sp[MAX_SKILL_LEVEL]; /// SP cost
|
||||
int hp_rate[MAX_SKILL_LEVEL]; /// HP cost (%)
|
||||
int sp_rate[MAX_SKILL_LEVEL]; /// SP cost (%)
|
||||
int zeny[MAX_SKILL_LEVEL]; /// Zeny cost
|
||||
uint32 weapon; /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
|
||||
uint16 ammo; /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
|
||||
int ammo_qty[MAX_SKILL_LEVEL]; /// Amount of ammo
|
||||
uint8 state; /// State/condition. @see enum e_require_state
|
||||
int spiritball[MAX_SKILL_LEVEL]; /// Spiritball cost
|
||||
uint16 itemid[MAX_SKILL_ITEM_REQUIRE]; /// Required item
|
||||
uint16 amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
int32 hp[MAX_SKILL_LEVEL]; ///< HP cost
|
||||
int32 mhp[MAX_SKILL_LEVEL]; ///< Max HP to trigger
|
||||
int32 sp[MAX_SKILL_LEVEL]; /// SP cost
|
||||
int32 hp_rate[MAX_SKILL_LEVEL]; /// HP cost (%)
|
||||
int32 sp_rate[MAX_SKILL_LEVEL]; /// SP cost (%)
|
||||
int32 zeny[MAX_SKILL_LEVEL]; /// Zeny cost
|
||||
int32 weapon; /// Weapon type. Combined bitmask of enum weapon_type (1<<weapon)
|
||||
int32 ammo; /// Ammo type. Combine bitmask of enum ammo_type (1<<ammo)
|
||||
int32 ammo_qty[MAX_SKILL_LEVEL]; /// Amount of ammo
|
||||
int32 state; /// State/condition. @see enum e_require_state
|
||||
int32 spiritball[MAX_SKILL_LEVEL]; /// Spiritball cost
|
||||
int32 itemid[MAX_SKILL_ITEM_REQUIRE]; /// Required item
|
||||
int32 amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
std::vector<int32> eqItem; /// List of equipped item
|
||||
std::vector<sc_type> status; /// List of Status required (SC)
|
||||
};
|
||||
|
||||
/// Database skills. !TODO: Cleanup the variable types that use array [MAX_SKILL_LEVEL]
|
||||
struct s_skill_db {
|
||||
// skill_db.txt
|
||||
uint16 nameid; ///< Skill ID
|
||||
char name[SKILL_NAME_LENGTH]; ///< AEGIS_Name
|
||||
char desc[SKILL_DESC_LENGTH]; ///< English Name
|
||||
int range[MAX_SKILL_LEVEL]; ///< Range
|
||||
int8 hit; ///< Hit type
|
||||
uint8 inf; ///< Inf: 0- passive, 1- enemy, 2- place, 4- self, 16- friend, 32- trap
|
||||
int element[MAX_SKILL_LEVEL]; ///< Element
|
||||
uint16 nk; ///< Damage properties
|
||||
int splash[MAX_SKILL_LEVEL]; ///< Splash effect
|
||||
uint8 max; ///< Max level
|
||||
int num[MAX_SKILL_LEVEL]; ///< Number of hit
|
||||
bool castcancel; ///< Cancel cast when being hit
|
||||
int16 cast_def_rate; ///< Def rate during cast a skill
|
||||
uint16 skill_type; ///< Skill type
|
||||
int blewcount[MAX_SKILL_LEVEL]; ///< Blew count
|
||||
uint32 inf2; ///< Skill flags @see enum e_skill_inf2
|
||||
uint32 inf3; ///< Skill flags @see enum e_skill_inf3
|
||||
int maxcount[MAX_SKILL_LEVEL]; ///< Max number skill can be casted in same map
|
||||
/// Skill Copyable structure.
|
||||
struct s_skill_copyable { // [Cydh]
|
||||
uint8 option;
|
||||
uint16 req_opt;
|
||||
};
|
||||
|
||||
// skill_castnodex_db.txt
|
||||
uint8 castnodex; ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
|
||||
uint8 delaynodex; ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
|
||||
/// Skill Reading Spellbook structure.
|
||||
struct s_skill_spellbook {
|
||||
uint16 nameid, point;
|
||||
};
|
||||
|
||||
/// Database skills
|
||||
struct s_skill_db {
|
||||
uint16 nameid; ///< Skill ID
|
||||
char name[SKILL_NAME_LENGTH]; ///< AEGIS_Name
|
||||
char desc[SKILL_DESC_LENGTH]; ///< English Name
|
||||
int32 range[MAX_SKILL_LEVEL]; ///< Range
|
||||
e_damage_type hit; ///< Hit type
|
||||
uint16 inf; ///< Inf: 0- passive, 1- enemy, 2- place, 4- self, 16- friend, 32- trap
|
||||
e_element element[MAX_SKILL_LEVEL]; ///< Element
|
||||
std::bitset<NK_MAX> nk; ///< Damage properties
|
||||
int32 splash[MAX_SKILL_LEVEL]; ///< Splash effect
|
||||
uint16 max; ///< Max level
|
||||
int32 num[MAX_SKILL_LEVEL]; ///< Number of hit
|
||||
bool castcancel; ///< Cancel cast when being hit
|
||||
uint16 cast_def_rate; ///< Def rate during cast a skill
|
||||
e_battle_flag skill_type; ///< Skill type
|
||||
int32 blewcount[MAX_SKILL_LEVEL]; ///< Blew count
|
||||
std::bitset<INF2_MAX> inf2; ///< Skill flags @see enum e_skill_inf2
|
||||
int32 maxcount[MAX_SKILL_LEVEL]; ///< Max number skill can be casted in same map
|
||||
|
||||
uint8 castnodex; ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
|
||||
uint8 delaynodex; ///< 1 - Not affected by dex, 2 - Not affected by SC, 4 - Not affected by item
|
||||
|
||||
// skill_nocast_db.txt
|
||||
uint32 nocast; ///< Skill cannot be casted at this zone
|
||||
uint32 nocast; ///< Skill cannot be casted at this zone
|
||||
|
||||
// skill_unit_db.txt
|
||||
uint16 unit_id[2]; ///< Unit ID. @see enum s_skill_unit_id
|
||||
int unit_layout_type[MAX_SKILL_LEVEL]; ///< Layout type. -1 is special layout, others are square with lenght*width: (val*2+1)^2
|
||||
int unit_range[MAX_SKILL_LEVEL]; ///< Unit cell effect range
|
||||
int16 unit_interval; ///< Interval
|
||||
uint32 unit_target; ///< Unit target. @see enum e_battle_check_target
|
||||
uint32 unit_flag; ///< Unit flags. @see enum e_skill_unit_flag
|
||||
uint16 unit_id; ///< Unit ID. @see enum e_skill_unit_id
|
||||
uint16 unit_id2; ///< Alternate unit ID. @see enum e_skill_unit_id
|
||||
int32 unit_layout_type[MAX_SKILL_LEVEL]; ///< Layout type. -1 is special layout, others are square with lenght*width: (val*2+1)^2
|
||||
int32 unit_range[MAX_SKILL_LEVEL]; ///< Unit cell effect range
|
||||
int16 unit_interval; ///< Interval
|
||||
int32 unit_target; ///< Unit target.
|
||||
std::bitset<UF_MAX> unit_flag; ///< Unit flags.
|
||||
|
||||
// skill_cast_db.txt
|
||||
int cast[MAX_SKILL_LEVEL]; ///< Variable casttime
|
||||
int32 cast[MAX_SKILL_LEVEL]; ///< Variable casttime
|
||||
int32 delay[MAX_SKILL_LEVEL]; ///< Global delay (delay before reusing all skills)
|
||||
int32 walkdelay[MAX_SKILL_LEVEL]; ///< Delay to walk after casting
|
||||
int32 upkeep_time[MAX_SKILL_LEVEL]; ///< Duration
|
||||
int32 upkeep_time2[MAX_SKILL_LEVEL]; ///< Duration2
|
||||
int32 cooldown[MAX_SKILL_LEVEL]; ///< Cooldown (delay before reusing same skill)
|
||||
#ifdef RENEWAL_CAST
|
||||
int fixed_cast[MAX_SKILL_LEVEL]; ///< If -1 means 20% than 'cast'
|
||||
int32 fixed_cast[MAX_SKILL_LEVEL]; ///< If -1 means 20% than 'cast'
|
||||
#endif
|
||||
int walkdelay[MAX_SKILL_LEVEL]; ///< Delay to walk after casting
|
||||
int delay[MAX_SKILL_LEVEL]; ///< Global delay (delay before reusing all skills)
|
||||
int cooldown[MAX_SKILL_LEVEL]; ///< Cooldown (delay before reusing same skill)
|
||||
int upkeep_time[MAX_SKILL_LEVEL]; ///< Duration
|
||||
int upkeep_time2[MAX_SKILL_LEVEL]; ///< Duration2
|
||||
|
||||
// skill_require_db.txt
|
||||
struct s_skill_require require; ///< Skill requirement
|
||||
struct s_skill_require require; ///< Skill requirement
|
||||
|
||||
// skill_nonearnpc_db.txt
|
||||
uint8 unit_nonearnpc_range; //additional range for UF_NONEARNPC or INF2_NO_NEARNPC [Cydh]
|
||||
uint8 unit_nonearnpc_type; //type of NPC [Cydh]
|
||||
uint16 unit_nonearnpc_range; ///< Additional range for UF_NONEARNPC or INF2_DISABLENEARNPC [Cydh]
|
||||
uint16 unit_nonearnpc_type; ///< Type of NPC [Cydh]
|
||||
|
||||
// skill_damage_db.txt
|
||||
struct s_skill_damage damage;
|
||||
struct s_skill_copyable copyable;
|
||||
|
||||
// skill_copyable_db.txt
|
||||
struct s_copyable { // [Cydh]
|
||||
uint8 option;
|
||||
uint16 joballowed, req_opt;
|
||||
} copyable;
|
||||
int32 abra_probability[MAX_SKILL_LEVEL];
|
||||
s_skill_spellbook reading_spellbook;
|
||||
uint16 improvisedsong_rate;
|
||||
};
|
||||
extern struct s_skill_db **skill_db;
|
||||
|
||||
class SkillDatabase : public TypesafeCachedYamlDatabase <uint16, s_skill_db> {
|
||||
public:
|
||||
SkillDatabase() : TypesafeCachedYamlDatabase("SKILL_DB", 1) {
|
||||
|
||||
}
|
||||
|
||||
const std::string getDefaultLocation();
|
||||
template<typename T, size_t S> bool parseNode(std::string nodeName, std::string subNodeName, YAML::Node node, T (&arr)[S]);
|
||||
uint64 parseBodyNode(const YAML::Node &node);
|
||||
void clear();
|
||||
};
|
||||
|
||||
extern SkillDatabase skill_db;
|
||||
|
||||
#define MAX_SQUARE_LAYOUT 7 // 15*15 unit placement maximum
|
||||
#define MAX_SKILL_UNIT_LAYOUT (48+MAX_SQUARE_LAYOUT) // 47 special ones + the square ones
|
||||
@ -315,28 +387,6 @@ struct skill_unit_group_tickset {
|
||||
int id;
|
||||
};
|
||||
|
||||
|
||||
enum e_skill_unit_flag {
|
||||
UF_DEFNOTENEMY = 0x00001, // If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
UF_NOREITERATION = 0x00002, // Spell cannot be stacked
|
||||
UF_NOFOOTSET = 0x00004, // Spell cannot be cast near/on targets
|
||||
UF_NOOVERLAP = 0x00008, // Spell effects do not overlap
|
||||
UF_PATHCHECK = 0x00010, // Only cells with a shootable path will be placed
|
||||
UF_NOPC = 0x00020, // May not target players
|
||||
UF_NOMOB = 0x00040, // May not target mobs
|
||||
UF_SKILL = 0x00080, // May target skills
|
||||
UF_DANCE = 0x00100, // Dance
|
||||
UF_ENSEMBLE = 0x00200, // Duet
|
||||
UF_SONG = 0x00400, // Song
|
||||
UF_DUALMODE = 0x00800, // Spells should trigger both ontimer and onplace/onout/onleft effects.
|
||||
UF_NOKNOCKBACK = 0x01000, // Skill unit cannot be knocked back
|
||||
UF_RANGEDSINGLEUNIT = 0x02000, // hack for ranged layout, only display center
|
||||
UF_CRAZYWEED_IMMUNE = 0x04000, // Immune to Crazy Weed removal
|
||||
UF_REM_FIRERAIN = 0x08000, // removed by Fire Rain
|
||||
UF_KNOCKBACK_GROUP = 0x10000, // knockback skill unit with its group instead of single unit
|
||||
UF_HIDDEN_TRAP = 0x20000, // Hidden trap [Cydh]
|
||||
};
|
||||
|
||||
/// Enum for skill_blown
|
||||
enum e_skill_blown {
|
||||
BLOWN_NONE = 0x00,
|
||||
@ -410,14 +460,12 @@ const char* skill_get_desc( uint16 skill_id ); // [Skotlex]
|
||||
int skill_tree_get_max( uint16 skill_id, int b_class ); // Celest
|
||||
|
||||
// Accessor to the skills database
|
||||
int skill_get_index_( uint16 skill_id, bool silent, const char *func, const char *file, int line );
|
||||
uint16 skill_get_index_(uint16 skill_id, bool silent, const char *func, const char *file, int line);
|
||||
#define skill_get_index(skill_id) skill_get_index_((skill_id), false, __FUNCTION__, __FILE__, __LINE__) /// Get skill index from skill_id (common usage on source)
|
||||
#define skill_get_index2(skill_id) skill_get_index_((skill_id), true, __FUNCTION__, __FILE__, __LINE__) /// Get skill index from skill_id (used when reading skill_db files)
|
||||
int skill_get_type( uint16 skill_id );
|
||||
enum e_damage_type skill_get_hit( uint16 skill_id );
|
||||
e_damage_type skill_get_hit( uint16 skill_id );
|
||||
int skill_get_inf( uint16 skill_id );
|
||||
int skill_get_ele( uint16 skill_id , uint16 skill_lv );
|
||||
int skill_get_nk( uint16 skill_id );
|
||||
int skill_get_max( uint16 skill_id );
|
||||
int skill_get_range( uint16 skill_id , uint16 skill_lv );
|
||||
int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv, bool isServer);
|
||||
@ -431,15 +479,19 @@ int skill_get_time2( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_castnodex( uint16 skill_id );
|
||||
int skill_get_castdef( uint16 skill_id );
|
||||
int skill_get_nocast( uint16 skill_id );
|
||||
int skill_get_unit_id(uint16 skill_id,int flag);
|
||||
int skill_get_inf2( uint16 skill_id );
|
||||
int skill_get_unit_id( uint16 skill_id );
|
||||
int skill_get_unit_id2( uint16 skill_id );
|
||||
int skill_get_castcancel( uint16 skill_id );
|
||||
int skill_get_maxcount( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_unit_flag( uint16 skill_id );
|
||||
int skill_get_cooldown( uint16 skill_id, uint16 skill_lv );
|
||||
int skill_get_unit_target( uint16 skill_id );
|
||||
int skill_get_inf3( uint16 skill_id );
|
||||
#define skill_get_nk(skill_id, nk) skill_get_nk_(skill_id, { nk })
|
||||
bool skill_get_nk_(uint16 skill_id, std::vector<e_skill_nk> nk);
|
||||
#define skill_get_inf2(skill_id, inf2) skill_get_inf2_(skill_id, { inf2 })
|
||||
bool skill_get_inf2_(uint16 skill_id, std::vector<e_skill_inf2> inf2);
|
||||
#define skill_get_unit_flag(skill_id, unit) skill_get_unit_flag_(skill_id, { unit })
|
||||
bool skill_get_unit_flag_(uint16 skill_id, std::vector<e_skill_unit_flag> unit);
|
||||
// Accessor for skill requirements
|
||||
int skill_get_hp( uint16 skill_id ,uint16 skill_lv );
|
||||
int skill_get_mhp( uint16 skill_id ,uint16 skill_lv );
|
||||
@ -452,15 +504,11 @@ int skill_get_weapontype( uint16 skill_id );
|
||||
int skill_get_ammotype( uint16 skill_id );
|
||||
int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv );
|
||||
int skill_get_state(uint16 skill_id);
|
||||
//int skill_get_status( uint16 skill_id, int idx );
|
||||
int skill_get_status_count( uint16 skill_id );
|
||||
int skill_get_spiritball( uint16 skill_id, uint16 skill_lv );
|
||||
int skill_get_itemid( uint16 skill_id, int idx );
|
||||
int skill_get_itemqty( uint16 skill_id, int idx );
|
||||
unsigned short skill_dummy2skill_id(unsigned short skill_id);
|
||||
|
||||
int skill_name2id(const char* name);
|
||||
uint16 skill_idx2id(uint16 idx);
|
||||
uint16 skill_name2id(const char* name);
|
||||
|
||||
uint16 SKILL_MAX_DB(void);
|
||||
|
||||
@ -508,7 +556,7 @@ bool skill_check_condition_castbegin(struct map_session_data *sd, uint16 skill_i
|
||||
bool skill_check_condition_castend(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
int skill_check_condition_char_sub (struct block_list *bl, va_list ap);
|
||||
void skill_consume_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type);
|
||||
struct skill_condition skill_get_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
struct s_skill_condition skill_get_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
int skill_disable_check(struct status_change *sc, uint16 skill_id);
|
||||
bool skill_pos_maxcount_check(struct block_list *src, int16 x, int16 y, uint16 skill_id, uint16 skill_lv, enum bl_type type, bool display_failure);
|
||||
|
||||
@ -565,14 +613,14 @@ int64 skill_attack( int attack_type, struct block_list* src, struct block_list *
|
||||
void skill_reload(void);
|
||||
|
||||
/// List of State Requirements
|
||||
enum e_require_state {
|
||||
enum e_require_state : uint8 {
|
||||
ST_NONE,
|
||||
ST_HIDDEN,
|
||||
ST_RIDING,
|
||||
ST_FALCON,
|
||||
ST_CART,
|
||||
ST_SHIELD,
|
||||
ST_RECOV_WEIGHT_RATE,
|
||||
ST_RECOVER_WEIGHT_RATE,
|
||||
ST_MOVE_ENABLE,
|
||||
ST_WATER,
|
||||
ST_RIDINGDRAGON,
|
||||
@ -2019,7 +2067,7 @@ enum e_skill {
|
||||
};
|
||||
|
||||
/// The client view ids for land skills.
|
||||
enum s_skill_unit_id {
|
||||
enum e_skill_unit_id : uint16 {
|
||||
UNT_SAFETYWALL = 0x7e,
|
||||
UNT_FIREWALL,
|
||||
UNT_WARP_WAITING,
|
||||
|
@ -2184,17 +2184,20 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
}
|
||||
|
||||
if (sc->data[SC_DANCING] && flag!=2) {
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
||||
|
||||
if (!skill)
|
||||
return false;
|
||||
|
||||
if (src->type == BL_PC && ((skill_id >= WA_SWING_DANCE && skill_id <= WM_UNLIMITED_HUMMING_VOICE ) ||
|
||||
skill_id == WM_FRIGG_SONG))
|
||||
{ // Lvl 5 Lesson or higher allow you use 3rd job skills while dancing.
|
||||
if( pc_checkskill((TBL_PC*)src,WM_LESSON) < 5 )
|
||||
return false;
|
||||
} else if(sc->data[SC_LONGING]) { // Allow everything except dancing/re-dancing. [Skotlex]
|
||||
if (skill_id == BD_ENCORE ||
|
||||
skill_get_inf2(skill_id)&(INF2_SONG_DANCE|INF2_ENSEMBLE_SKILL)
|
||||
)
|
||||
if (skill_id == BD_ENCORE || skill->inf2[INF2_ISSONG] || skill->inf2[INF2_ISENSEMBLE])
|
||||
return false;
|
||||
} else if(!(skill_get_inf3(skill_id)&INF3_USABLE_DANCE)) // Skills that can be used in dancing state
|
||||
} else if(!skill->inf2[INF2_ALLOWWHENPERFORMING]) // Skills that can be used in dancing state
|
||||
return false;
|
||||
if ((sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE && skill_id == BD_ADAPTATION)
|
||||
return false; // Can't amp out of Wand of Hermode :/ [Skotlex]
|
||||
@ -2226,7 +2229,10 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
}
|
||||
|
||||
if (sc->option) {
|
||||
if ((sc->option&OPTION_HIDE) && src->type == BL_PC && (!skill_id || !(skill_get_inf3(skill_id)&INF3_USABLE_HIDING))) {
|
||||
if (skill_id == 0) // Normal attack
|
||||
return false;
|
||||
|
||||
if ((sc->option&OPTION_HIDE) && src->type == BL_PC && !skill_get_inf2(skill_id, INF2_ALLOWWHENHIDDEN)) {
|
||||
// Non players can use all skills while hidden.
|
||||
return false;
|
||||
}
|
||||
@ -2254,7 +2260,7 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
return false;
|
||||
if(skill_id == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
|
||||
return false;
|
||||
if (tsc->data[SC__MANHOLE] && !(skill_get_inf3(skill_id)&INF3_USABLE_MANHOLE))
|
||||
if (tsc->data[SC__MANHOLE] && !skill_get_inf2(skill_id, INF2_TARGETMANHOLE))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2262,7 +2268,7 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
|
||||
|
||||
// Skill that can hit hidden target
|
||||
if( skill_get_inf3(skill_id)&INF3_HIT_HIDING )
|
||||
if( skill_get_inf2(skill_id, INF2_TARGETHIDDEN) )
|
||||
hide_flag &= ~OPTION_HIDE;
|
||||
|
||||
switch( target->type ) {
|
||||
@ -12628,11 +12634,14 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
||||
|
||||
if (sce->val3 || status_isdead(bl) || !(caster = map_id2sd(sce->val2)))
|
||||
break;
|
||||
if (!itemdb_exists(skill_get_itemid(RL_H_MINE,0)))
|
||||
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(RL_H_MINE);
|
||||
|
||||
if (!itemdb_exists(skill->require.itemid[0]))
|
||||
break;
|
||||
memset(&it, 0, sizeof(it));
|
||||
it.nameid = skill_get_itemid(RL_H_MINE,0);
|
||||
it.amount = max(skill_get_itemqty(RL_H_MINE,0),1);
|
||||
it.nameid = skill->require.itemid[0];
|
||||
it.amount = max(skill->require.amount[0],1);
|
||||
it.identify = 1;
|
||||
map_addflooritem(&it, it.amount, bl->m,bl->x, bl->y, caster->status.char_id, 0, 0, 4, 0);
|
||||
}
|
||||
@ -13899,7 +13908,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
|
||||
if(bl->type == BL_SKILL)
|
||||
su = (struct skill_unit *)bl;
|
||||
if (skill_attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,sce->val1,tick,0x1000000)
|
||||
&& (!su || !su->group || !(skill_get_inf2(su->group->skill_id)&INF2_TRAP))) { // The hit is not counted if it's against a trap
|
||||
&& (!su || !su->group || !skill_get_inf2(su->group->skill_id, INF2_ISTRAP))) { // The hit is not counted if it's against a trap
|
||||
sce->val2 = 0; // This signals it to end.
|
||||
} else if((bl->type&BL_SKILL) && sce->val4%2 == 0) {
|
||||
//Remove trap immunity temporarily so it triggers if you still stand on it
|
||||
|
@ -1087,7 +1087,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, enum e_skill_bl
|
||||
map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
|
||||
|
||||
if(su) {
|
||||
if (su->group && skill_get_unit_flag(su->group->skill_id)&UF_KNOCKBACK_GROUP)
|
||||
if (su->group && skill_get_unit_flag(su->group->skill_id, UF_KNOCKBACKGROUP))
|
||||
skill_unit_move_unit_group(su->group, bl->m, dx, dy);
|
||||
else
|
||||
skill_unit_move_unit(bl, nx, ny);
|
||||
@ -1159,7 +1159,7 @@ enum e_unit_blown unit_blown_immune(struct block_list* bl, uint8 flag)
|
||||
case BL_SKILL: {
|
||||
struct skill_unit* su = (struct skill_unit *)bl;
|
||||
// Trap cannot be knocked back
|
||||
if (su && su->group && skill_get_unit_flag(su->group->skill_id)&UF_NOKNOCKBACK)
|
||||
if (su && su->group && skill_get_unit_flag(su->group->skill_id, UF_NOKNOCKBACK))
|
||||
return UB_TARGET_TRAP;
|
||||
}
|
||||
break;
|
||||
@ -1375,7 +1375,7 @@ int unit_can_move(struct block_list *bl) {
|
||||
if (!ud)
|
||||
return 0;
|
||||
|
||||
if (ud->skilltimer != INVALID_TIMER && ud->skill_id != LG_EXEEDBREAK && (!sd || !pc_checkskill(sd, SA_FREECAST) || skill_get_inf2(ud->skill_id)&INF2_GUILD_SKILL))
|
||||
if (ud->skilltimer != INVALID_TIMER && ud->skill_id != LG_EXEEDBREAK && (!sd || !pc_checkskill(sd, SA_FREECAST) || skill_get_inf2(ud->skill_id, INF2_ISGUILD)))
|
||||
return 0; // Prevent moving while casting
|
||||
|
||||
if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
|
||||
@ -1515,8 +1515,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
struct block_list * target = NULL;
|
||||
t_tick tick = gettick();
|
||||
int combo = 0, range;
|
||||
uint8 inf = 0;
|
||||
uint32 inf2 = 0;
|
||||
|
||||
nullpo_ret(src);
|
||||
|
||||
@ -1537,8 +1535,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
if (sc && !sc->count)
|
||||
sc = NULL; // Unneeded
|
||||
|
||||
inf = skill_get_inf(skill_id);
|
||||
inf2 = skill_get_inf2(skill_id);
|
||||
int inf = skill_get_inf(skill_id);
|
||||
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
||||
|
||||
// temp: used to signal combo-skills right now.
|
||||
if (sc && sc->data[SC_COMBO] &&
|
||||
@ -1552,13 +1550,13 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
else if (target_id == src->id || ud->target > 0)
|
||||
target_id = ud->target;
|
||||
|
||||
if (inf&INF_SELF_SKILL && skill_get_nk(skill_id)&NK_NO_DAMAGE)// exploit fix
|
||||
if (inf&INF_SELF_SKILL && skill->nk[NK_NODAMAGE])// exploit fix
|
||||
target_id = src->id;
|
||||
|
||||
combo = 1;
|
||||
} else if ( target_id == src->id &&
|
||||
inf&INF_SELF_SKILL &&
|
||||
(inf2&INF2_NO_TARGET_SELF ||
|
||||
(skill->inf2[INF2_NOTARGETSELF] ||
|
||||
(skill_id == RL_QD_SHOT && sc && sc->data[SC_QD_SHOT_READY])) ) {
|
||||
target_id = ud->target; // Auto-select target. [Skotlex]
|
||||
combo = 1;
|
||||
@ -1632,14 +1630,14 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
if(ud->skilltimer != INVALID_TIMER && skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST)
|
||||
return 0;
|
||||
|
||||
if(inf2&INF2_NO_TARGET_SELF && src->id == target_id)
|
||||
if(skill->inf2[INF2_NOTARGETSELF] && src->id == target_id)
|
||||
return 0;
|
||||
|
||||
if(!status_check_skilluse(src, target, skill_id, 0))
|
||||
return 0;
|
||||
|
||||
// Fail if the targetted skill is near NPC [Cydh]
|
||||
if(inf2&INF2_NO_NEARNPC && skill_isNotOk_npcRange(src,skill_id,skill_lv,target->x,target->y)) {
|
||||
if(skill->inf2[INF2_DISABLENEARNPC] && skill_isNotOk_npcRange(src,skill_id,skill_lv,target->x,target->y)) {
|
||||
if (sd)
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
|
||||
@ -2016,7 +2014,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
return 0;
|
||||
|
||||
// Fail if the targetted skill is near NPC [Cydh]
|
||||
if(skill_get_inf2(skill_id)&INF2_NO_NEARNPC && skill_isNotOk_npcRange(src,skill_id,skill_lv,skill_x,skill_y)) {
|
||||
if(skill_get_inf2(skill_id, INF2_DISABLENEARNPC) && skill_isNotOk_npcRange(src,skill_id,skill_lv,skill_x,skill_y)) {
|
||||
if (sd)
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user