diff options
48 files changed, 9228 insertions, 939 deletions
diff --git a/conf/battle/battle.conf b/conf/battle/battle.conf index 94f80a2a6..70062a16e 100644 --- a/conf/battle/battle.conf +++ b/conf/battle/battle.conf @@ -94,7 +94,7 @@ vit_penalty_num: 5 // Use alternate method of DEF calculation for physical attacks. // With 0, disabled (use normal def% reduction with further def2 reduction) -// At 1 or more defense is substraction of (DEF* value). +// At 1 or more defense is subtraction of (DEF* value). // eg: 10 + 50 def becomes 0 + (10*type + 50) weapon_defense_type: 0 diff --git a/conf/battle/drops.conf b/conf/battle/drops.conf index 3704b9a0e..9006cfeb1 100644 --- a/conf/battle/drops.conf +++ b/conf/battle/drops.conf @@ -7,10 +7,10 @@ // Note 2: Value is in percents (100 means 100%) //-------------------------------------------------------------- -// If an item is dropped, does it go stright into the users inventory? (Note 1) +// If an item is dropped, does it go straight into the users inventory? (Note 1) item_auto_get: no -// How long does it take for an item to disappear from the floor after it is dropped? (in miliseconds) +// How long does it take for an item to disappear from the floor after it is dropped? (in milliseconds) flooritem_lifetime: 60000 // Grace time during which only the person who did the most damage to a monster can get the item? (in milliseconds) diff --git a/conf/battle/homunc.conf b/conf/battle/homunc.conf index fb34792ce..5e1b1c9d2 100644 --- a/conf/battle/homunc.conf +++ b/conf/battle/homunc.conf @@ -35,7 +35,7 @@ homunculus_show_growth: yes // Does autoloot work, when a monster is killed by homunculus only? homunculus_autoloot: yes -// Should homunculii Vaporize when Master dies? +// Should homunculi Vaporize when Master dies? homunculus_auto_vapor: yes // Max level for regular Homunculus diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf index 32b9c511e..9814a2140 100644 --- a/conf/battle/misc.conf +++ b/conf/battle/misc.conf @@ -85,7 +85,7 @@ duel_only_on_same_map: no // Cell Stack Limit support (see src/map/map.h) cell_stack_limit: 1 -// Allow autrade only in map with autotrade flag? +// Allow autotrade only in map with autotrade flag? // Set this to "no" will allow autotrade where no "autotrade" mapflag is set // Set this to "yes" to only allow autotrade on maps with "autotrade" mapflag at_mapflag: no diff --git a/conf/battle/monster.conf b/conf/battle/monster.conf index 51136fbe0..50d661087 100644 --- a/conf/battle/monster.conf +++ b/conf/battle/monster.conf @@ -30,13 +30,13 @@ monster_max_aspd: 199 // (distance player/mob < 3), otherwise mobs may change target and chase // ranged attackers. This flag also overrides the 'provoke' target. // 0x008: If set, when a mob loses track of their target, they stop walking -// inmediately. Otherwise, they continue to their last target tile. When +// immediately. Otherwise, they continue to their last target tile. When // set mobs also scatter as soon as they lose their target. Use this mode // to make it much harder to mob-train by hiding and collecting them on a // single spot (ie: GrimTooth training) // 0x010: If set, mob skills defined for friends will also trigger on themselves. // 0x020: When set, the monster ai is executed for all monsters in maps that -// have players on them, instead of only for mobs who are in the vecinity +// have players on them, instead of only for mobs who are in the vicinity // of players. // 0x040: When set, when the mob's target changes map, the mob will walk towards // any npc-warps in it's sight of view (use with mob_warp below) @@ -60,7 +60,7 @@ monster_ai: 0 mob_warp: 0 // If these are set above 0, they define the time (in ms) during which monsters -// will have their 'AI' active after all players have left their vecinity. +// will have their 'AI' active after all players have left their vicinity. mob_active_time: 0 boss_active_time: 0 @@ -105,7 +105,7 @@ mob_skill_delay: 100 mob_count_rate: 100 // Respawn rate of monsters on a map. 50 would make mobs respawn twice as fast (half delay time) (Note 2) -//Note: This does not affects mobs with inmediate respawn (most normal mobs) +//Note: This does not affects mobs with immediate respawn (most normal mobs) mob_spawn_delay: 100 plant_spawn_delay: 100 boss_spawn_delay: 100 @@ -158,7 +158,7 @@ mob_changetarget_byskill: no monster_class_change_full_recover: yes // Display some mob info next to their name? (add as needed) -// (does not works on guardian or emperium) +// (does not works on guardian or Emperium) // 1: Display mob HP (Hp/MaxHp format) // 2: Display mob HP (Percent of full life format) // 4: Display mob's level @@ -189,7 +189,7 @@ mob_remove_delay: 300000 // NOTE: This affects who gains the Castle when the Emperium is broken. mob_npc_event_type: 1 -// Time in milliseconds to actitave protection against Kill Steal +// Time in milliseconds to activate protection against Kill Steal // Set to 0 to disable it. // If this is activated and a player is using @noks, damage from others players (KS) not in the party // will be reduced to 0. diff --git a/conf/battle/party.conf b/conf/battle/party.conf index 7339b2e3c..14d5f47c8 100644 --- a/conf/battle/party.conf +++ b/conf/battle/party.conf @@ -44,7 +44,7 @@ party_item_share_type: 0 // A character's idle status is reset upon item use/skill use/attack (auto attack counts too)/movement. idle_no_share: no -// Give additional experience bonus per party-member involved on even-share parties (excluding youself)? +// Give additional experience bonus per party-member involved on even-share parties (excluding yourself)? // ex. If set to 10, an even-share party of 5 people will receive +40% exp (4 members * 10% exp): // 140% party experience in total, so each member receives 140%/5 = 28% exp (instead of 20%). party_even_share_bonus: 0 diff --git a/conf/battle/skill.conf b/conf/battle/skill.conf index df419b262..bc107f3d7 100644 --- a/conf/battle/skill.conf +++ b/conf/battle/skill.conf @@ -20,7 +20,7 @@ delay_rate: 100 delay_dependon_dex: no delay_dependon_agi: no -// Minimum allowed delay for ANY skills after casting (in miliseconds) (Note 1) +// Minimum allowed delay for ANY skills after casting (in milliseconds) (Note 1) // Note: Setting this to anything above 0 can stop speedhacks. min_skill_delay_limit: 100 @@ -91,7 +91,7 @@ defunit_not_enemy: no // Do skills do at least 'hits' damage when they don't miss/are blocked? //(for example, will firebolts always do "number of bolts" damage versus plants?) -//Values (add as appropiate): 1 for weapon-based attacks, 2 for magic attacks, 4 for misc attacks. +//Values (add as appropriate): 1 for weapon-based attacks, 2 for magic attacks, 4 for misc attacks. skill_min_damage: 6 // The delay rate of monk's combo (Note 2) @@ -128,7 +128,7 @@ traps_setting: 0 summon_flora_setting: 3 // Whether placed down skills will check walls (Note 1) -// (Makes it so that Storm Gust/Lord of Vermillion/etc when casted next to a wall, won't hit on the other side) +// (Makes it so that Storm Gust/Lord of Vermillion/etc when cast next to a wall, won't hit on the other side) skill_wall_check: yes // When cloaking, Whether the wall is checked or not. (Note 1) @@ -168,7 +168,7 @@ sense_type: 1 // 1 = Athena style (multiple consecutive attacks) finger_offensive_type: 0 -// Grandcross Settings (Dont mess with these) +// Grandcross Settings (Don't mess with these) // If set to no, hit interval is increased based on the amount of mobs standing on the same cell // (means that when there's stacked mobs in the same cell, they won't receive all hits) gx_allhit: no @@ -212,7 +212,7 @@ berserk_cancels_buffs: no max_heal: 9999 max_heal_lv: 11 -// Emergency Recall Guild Skill setting (add as appropiate). +// Emergency Recall Guild Skill setting (add as appropriate). // Note that for the skill to be usable at all, // you need at least one of 1/2 and 4/8 // 1: Skill is usable outside of woe. @@ -223,7 +223,7 @@ max_heal_lv: 11 // (it will work on GVG castles even if they are set to nowarpto, though) emergency_call: 11 -// Guild Aura Skills setting (add as appropiate). +// Guild Aura Skills setting (add as appropriate). // (This affects GD_LEADERSHIP, GD_GLORYWOUNDS, GD_SOULCOLD and GD_HAWKEYES) // Note that for the skill to be usable at all, // you need at least one of 1/2 and 4/8 @@ -258,7 +258,7 @@ sg_angel_skill_ratio: 10 skill_add_heal_rate: 7 // Whether the damage of EarthQuake with a single target on screen is able to be reflected. -// Note: On offcial server, EQ is reflectable when there is only one target on the screen, +// Note: On official server, EQ is reflectable when there is only one target on the screen, // which might be an exploit to hunt the MVPs. eq_single_target_reflectable: yes diff --git a/conf/help.txt b/conf/help.txt index 16e7c2981..18630bf59 100644 --- a/conf/help.txt +++ b/conf/help.txt @@ -32,7 +32,7 @@ mobsearch: "Params: <monster name|ID>\n" "Shows the location of a certain mob on who: "Params: [<name>]\n" "Shows a list of online players and their party and guild." who2: "Params: [<name>]\n" "Shows a list of online players and their job." who3: "Params: [<name>]\n" "Shows a list of online players and their location." -whomap: "@whomap/@whomap2/@whomap3 [map] - like @who/@who2/@who3 but only for specifical map." +whomap: "@whomap/@whomap2/@whomap3 [map] - like @who/@who2/@who3 but only for specified map." whogm: "Params: [match_text] - Like @who+@who2+who3, but only for GM." guildspy: "Params: <guild name|id> - You will receive all messages of the guild channel (Chat logging must be enabled)" partyspy: "@partyspy <party name|id> - You will receive all messages of the party channel (Chat logging must be enabled)" @@ -221,7 +221,7 @@ request: "Params: <message>\n" "Sends a message to all connected GMs (via the gm sound: "Params: <path to file in data folder or GRF file>\n" "Plays a sound from the data folder or GRF file located on the client." clone: "Params: <charname>\n" "Spawns a supportive clone of the given player." slaveclone: "Params: <charname>\n" "Spawns a supportive clone of the given player that follows the creator around." -evilclone: "Params: <charname>\n" "Spawns an agressive clone of the given player." +evilclone: "Params: <charname>\n" "Spawns an aggressive clone of the given player." changesex: "Changes your gender." duel: "Starts a duel." invite: "Invites a player to a duel." diff --git a/conf/inter-server.conf b/conf/inter-server.conf index 0e9808077..3cf5211df 100644 --- a/conf/inter-server.conf +++ b/conf/inter-server.conf @@ -24,7 +24,7 @@ party_share_level: 15 // and you have localhost, switch it to 127.0.0.1 // Global SQL settings -// overriden by local settings when the hostname is defined there +// overridden by local settings when the hostname is defined there // (currently only the login-server reads/obeys these settings) sql.db_hostname: 127.0.0.1 sql.db_port: 3306 diff --git a/conf/login-server.conf b/conf/login-server.conf index 8f2fa1bf1..fd1ef45f5 100644 --- a/conf/login-server.conf +++ b/conf/login-server.conf @@ -25,7 +25,7 @@ login_port: 6900 //If redirected output contains escape sequences (color codes) stdout_with_ansisequence: no -//Makes server output more silent by ommitting certain types of messages: +//Makes server output more silent by omitting certain types of messages: //1: Hide Information messages //2: Hide Status messages //4: Hide Notice Messages diff --git a/conf/logs.conf b/conf/logs.conf index 2aeb1b52e..f036cbccf 100644 --- a/conf/logs.conf +++ b/conf/logs.conf @@ -25,7 +25,7 @@ // 0x02000 - (E) Log mail system transactions. // 0x04000 - (I) Log auction system transactions. // 0x08000 - (B) Log buying store transactions -// 0x10000 - (X) Log all other transcations (rentals expiring/inserting cards/items removed by item_check/ +// 0x10000 - (X) Log all other transactions (rentals expiring/inserting cards/items removed by item_check/ // rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill) // Example: Log trades+vending+script items+created items: 1+2+32+1024 = 1059 // Please note that moving items from inventory to cart and back is not logged by design. @@ -77,7 +77,7 @@ log_branch: no // Track Zeny Changes // Filter settings -// 0 - don't log; 1 - log any zeny changes; 2.....1000000 - minimal absolut logging zeny value +// 0 - don't log; 1 - log any zeny changes; 2.....1000000 - minimal absolute logging zeny value log_zeny: 0 // Log MVP Monster Drops (Note 1) diff --git a/conf/map-server.conf b/conf/map-server.conf index 446bb0d0e..fb4614ca3 100644 --- a/conf/map-server.conf +++ b/conf/map-server.conf @@ -55,7 +55,7 @@ stdout_with_ansisequence: no //Messages logged by this overrides console_silent setting console_msg_log: 0 -//Makes server output more silent by ommitting certain types of messages: +//Makes server output more silent by omitting certain types of messages: //1: Hide Information messages //2: Hide Status messages //4: Hide Notice Messages diff --git a/conf/messages.conf b/conf/messages.conf index e2886a57d..d9472952d 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -828,7 +828,7 @@ 1031: Please enter part of an item name (usage: @idsearch <part_of_item_name>). // @recallall / @guildrecall / @partyrecall -1032: You are not authorized to warp somenone to your current map. +1032: You are not authorized to warp someone to your current map. 1033: Because you are not authorized to warp from some maps, %d player(s) have not been recalled. // @guildrecall diff --git a/conf/plugins.conf b/conf/plugins.conf index 264592fa9..779783d3e 100644 --- a/conf/plugins.conf +++ b/conf/plugins.conf @@ -14,7 +14,11 @@ //== Description ===================================== //The plugin system allows you to create customized scripts //outside of the source. These scripts won't conflict with any +<<<<<<< HEAD //future source updates - think about it as a /conf/import/ version of the source. +======= +//future source updates - think of it as a /conf/import/ for the source. +>>>>>>> upstream/master //==================================================== /* --------------- Format --------------- diff --git a/db/castle_db.txt b/db/castle_db.txt index 4e0f2e880..45a1443d5 100644 --- a/db/castle_db.txt +++ b/db/castle_db.txt @@ -3,33 +3,33 @@ // Structure of Database: // CastleID,MapName,CastleName,OnGuildBreakEventName,Flag // -// 01. CastleID Unique ID of the castle. Must remain unique across all map-servers. -// 02. MapName Map name to be considered as the castle map. -// 03. CastleName Name of the castle (used by scripts and guardian name tags). -// 04. OnGuildBreakEventName NPC unique name to invoke ::OnGuildBreak on, when a occupied -// castle is abandoned during guild break. -// 05. Flag Switch flag (reserved as of athena-dev mod0796~0801, not used by server). +// 01. CastleID Unique ID of the castle. Must remain unique across all map-servers. +// 02. MapName Map name to be considered as the castle map. +// 03. CastleName Name of the castle (used by scripts and guardian name tags). +// 04. OnGuildBreakEventName NPC unique name to invoke ::OnGuildBreak on, when a occupied +// castle is abandoned during guild break. +// 05. Flag Switch flag (reserved as of athena-dev mod0796~0801, not used by server). 0,aldeg_cas01,Neuschwanstein,Agit#aldeg_cas01,1 // kRO : Noisyubantian 1,aldeg_cas02,Hohenschwangau,Agit#aldeg_cas02,1 // kRO : Hohensyubangawoo 2,aldeg_cas03,Nuernberg,Agit#aldeg_cas03,1 // kRO : Nyirenverk 3,aldeg_cas04,Wuerzburg,Agit#aldeg_cas04,1 // kRO : Byirtsburi -4,aldeg_cas05,Rothenburg,Agit#aldeg_cas05,1 // kRO : Rotenburk +4,aldeg_cas05,Rothenburg,Agit#aldeg_cas05,1 // kRO : Rotenburk 5,gefg_cas01,Repherion,Agit#gefg_cas01,1 // kRO : Reprion -6,gefg_cas02,Eeyolbriggar,Agit#gefg_cas02,1 // kRO : Yolbriger -7,gefg_cas03,Yesnelph,Agit#gefg_cas03,1 // kRO : Isinlife -8,gefg_cas04,Bergel,Agit#gefg_cas04,1 // kRO : Berigel -9,gefg_cas05,Mersetzdeitz,Agit#gefg_cas05,1 // kRO : Melsedetsu +6,gefg_cas02,Eeyolbriggar,Agit#gefg_cas02,1 // kRO : Yolbriger +7,gefg_cas03,Yesnelph,Agit#gefg_cas03,1 // kRO : Isinlife +8,gefg_cas04,Bergel,Agit#gefg_cas04,1 // kRO : Berigel +9,gefg_cas05,Mersetzdeitz,Agit#gefg_cas05,1 // kRO : Melsedetsu 10,payg_cas01,Bright Arbor,Agit#payg_cas01,1 // kRO : Mingting 11,payg_cas02,Scarlet Palace,Agit#payg_cas02,1 // kRO : Tiantan -12,payg_cas03,Holy Shadow,Agit#payg_cas03,1 // kRO : Fuying +12,payg_cas03,Holy Shadow,Agit#payg_cas03,1 // kRO : Fuying 13,payg_cas04,Sacred Altar,Agit#payg_cas04,1 // kRO : Honglou 14,payg_cas05,Bamboo Grove Hill,Agit#payg_cas05,1 // kRO : Zhulinxian 15,prtg_cas01,Kriemhild,Agit#prtg_cas01,1 // kRO : Creamhilt 16,prtg_cas02,Swanhild,Agit#prtg_cas02,1 // kRO : Sbanhealt 17,prtg_cas03,Fadhgridh,Agit#prtg_cas03,1 // kRO : Lazrigees -18,prtg_cas04,Skoegul,Agit#prtg_cas04,1 // kRO : Squagul -19,prtg_cas05,Gondul,Agit#prtg_cas05,1 // kRO : Guindull +18,prtg_cas04,Skoegul,Agit#prtg_cas04,1 // kRO : Squagul +19,prtg_cas05,Gondul,Agit#prtg_cas05,1 // kRO : Guindull 20,nguild_alde,Earth,Agit_N01,2 21,nguild_gef,Air,Agit_N02,2 22,nguild_pay,Water,Agit_N03,2 @@ -38,9 +38,9 @@ 25,schg_cas02,Andlangr,Manager#schg_cas02,1 // kRO : Andlangr 26,schg_cas03,Viblainn,Manager#schg_cas03,1 // kRO : Viblainn 27,schg_cas04,Hljod,Manager#schg_cas04,1 // kRO : Hljod -28,schg_cas05,Skidbladnir,Manager#schg_cas05,1 // kRO : Skidbladnir +28,schg_cas05,Skidbladnir,Manager#schg_cas05,1 // kRO : Skidbladnir 29,arug_cas01,Mardol,Manager#arug_cas01,1 // kRO : Mardol -30,arug_cas02,Cyr,Manager#arug_cas02,1 // kRO : Cyr -31,arug_cas03,Horn,Manager#arug_cas03,1 // kRO : Horn -32,arug_cas04,Gefn,Manager#arug_cas04,1 // kRO : Gefn +30,arug_cas02,Cyr,Manager#arug_cas02,1 // kRO : Cyr +31,arug_cas03,Horn,Manager#arug_cas03,1 // kRO : Horn +32,arug_cas04,Gefn,Manager#arug_cas04,1 // kRO : Gefn 33,arug_cas05,Bandis,Manager#arug_cas05,1 // kRO : Bandis diff --git a/db/const.txt b/db/const.txt index f006a4d38..a5e52cb38 100644 --- a/db/const.txt +++ b/db/const.txt @@ -6,13 +6,13 @@ // Alternatively: // Identifier,Value[,Type] // -// 01. Identifier Unique name for the constant, must not have same name as script commands, functions or variables. -// 02. Value Value assigned to the constant. This value cannot be changed during the runtime of the server. -// 03. Type Specifies whether the identifier is a constant (0) or a parameter (1) (optional, defaults to 0). +// 01. Identifier Unique name for the constant, must not have same name as script commands, functions or variables. +// 02. Value Value assigned to the constant. This value cannot be changed during the runtime of the server. +// 03. Type Specifies whether the identifier is a constant (0) or a parameter (1) (optional, defaults to 0). // -// NOTE: Parameters are special in that they retrieve certain runtime values depending on the specified ID -// in field Value. Depending on the implementation values assigned by scripts to parameters will affect -// runtime values, such as Zeny, as well (see pc_readparam/pc_setparam). +// NOTE: Parameters are special in that they retrieve certain runtime values depending on the specified ID +// in field Value. Depending on the implementation values assigned by scripts to parameters will affect +// runtime values, such as Zeny, as well (see pc_readparam/pc_setparam). Job_Novice 0 Job_Swordman 1 diff --git a/db/pre-re/skill_tree.conf b/db/pre-re/skill_tree.conf new file mode 100644 index 000000000..9853c97f2 --- /dev/null +++ b/db/pre-re/skill_tree.conf @@ -0,0 +1,3836 @@ +//==================================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//= +//= http://hercules.ws/board/ +//================= More Information ================= +// http://hercules.ws/board/topic/1188-skill-tree-db-redesign/ <desc~!> +//==================================================== +Novice: { + skills: { + NV_BASIC: 9 + NV_FIRSTAID: 1 + NV_TRICKDEAD: 1 + WE_CALLBABY: 1 + ALL_INCCARRY: 1 + } +} +Swordsman: { + inherit: ( "Novice" ); + + skills: { + SM_SWORD: 10 + SM_TWOHAND: { + MaxLevel: 10 + SM_SWORD: 1 + } + SM_RECOVERY: 10 + SM_BASH: 10 + SM_PROVOKE: 10 + SM_MAGNUM: { + MaxLevel: 10 + SM_BASH: 5 + } + SM_ENDURE: { + MaxLevel: 10 + SM_PROVOKE: 5 + } + SM_MOVINGRECOVERY: 1 + SM_FATALBLOW: 1 + SM_AUTOBERSERK: 1 + } +} +Magician: { + inherit: ( "Novice" ); + + skills: { + MG_SRECOVERY: 10 + MG_SIGHT: 1 + MG_NAPALMBEAT: 10 + MG_SAFETYWALL: { + MaxLevel: 10 + MG_NAPALMBEAT: 7 + MG_SOULSTRIKE: 5 + } + MG_SOULSTRIKE: { + MaxLevel: 10 + MG_NAPALMBEAT: 4 + } + MG_COLDBOLT: 10 + MG_FROSTDIVER: { + MaxLevel: 10 + MG_COLDBOLT: 5 + } + MG_STONECURSE: 10 + MG_FIREBALL: { + MaxLevel: 10 + MG_FIREBOLT: 4 + } + MG_FIREWALL: { + MaxLevel: 10 + MG_FIREBALL: 5 + MG_SIGHT: 1 + } + MG_FIREBOLT: 10 + MG_LIGHTNINGBOLT: 10 + MG_THUNDERSTORM: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 4 + } + MG_ENERGYCOAT: 1 + } +} +Archer: { + inherit: ( "Novice" ); + + skills: { + AC_OWL: 10 + AC_VULTURE: { + MaxLevel: 10 + AC_OWL: 3 + } + AC_CONCENTRATION: { + MaxLevel: 10 + AC_VULTURE: 1 + } + AC_DOUBLE: 10 + AC_SHOWER: { + MaxLevel: 10 + AC_DOUBLE: 5 + } + AC_MAKINGARROW: 1 + AC_CHARGEARROW: 1 + } +} +Acolyte: { + inherit: ( "Novice" ); + + skills: { + AL_DP: 10 + AL_DEMONBANE: { + MaxLevel: 10 + AL_DP: 3 + } + AL_RUWACH: 1 + AL_PNEUMA: { + MaxLevel: 1 + AL_WARP: 4 + } + AL_TELEPORT: { + MaxLevel: 2 + AL_RUWACH: 1 + } + AL_WARP: { + MaxLevel: 4 + AL_TELEPORT: 2 + } + AL_HEAL: 10 + AL_INCAGI: { + MaxLevel: 10 + AL_HEAL: 3 + } + AL_DECAGI: { + MaxLevel: 10 + AL_INCAGI: 1 + } + AL_HOLYWATER: 1 + AL_CRUCIS: { + MaxLevel: 10 + AL_DEMONBANE: 3 + } + AL_ANGELUS: { + MaxLevel: 10 + AL_DP: 3 + } + AL_BLESSING: { + MaxLevel: 10 + AL_DP: 5 + } + AL_CURE: { + MaxLevel: 1 + AL_HEAL: 2 + } + AL_HOLYLIGHT: 1 + } +} +Merchant: { + inherit: ( "Novice" ); + + skills: { + MC_INCCARRY: 10 + MC_DISCOUNT: { + MaxLevel: 10 + MC_INCCARRY: 3 + } + MC_OVERCHARGE: { + MaxLevel: 10 + MC_DISCOUNT: 3 + } + MC_PUSHCART: { + MaxLevel: 10 + MC_INCCARRY: 5 + } + MC_IDENTIFY: 1 + MC_VENDING: { + MaxLevel: 10 + MC_PUSHCART: 3 + } + MC_MAMMONITE: 10 + MC_CARTREVOLUTION: 1 + MC_CHANGECART: 1 + MC_LOUD: 1 + ALL_BUYING_STORE: { + MaxLevel: 1 + MC_VENDING: 1 + } + } +} +Thief: { + inherit: ( "Novice" ); + + skills: { + TF_DOUBLE: 10 + TF_MISS: 10 + TF_STEAL: 10 + TF_HIDING: { + MaxLevel: 10 + TF_STEAL: 5 + } + TF_POISON: 10 + TF_DETOXIFY: { + MaxLevel: 1 + TF_POISON: 3 + } + TF_SPRINKLESAND: 1 + TF_BACKSLIDING: 1 + TF_PICKSTONE: 1 + TF_THROWSTONE: 1 + } +} +Knight: { + inherit: ( "Swordsman" ); + + skills: { + KN_SPEARMASTERY: 10 + KN_PIERCE: { + MaxLevel: 10 + KN_SPEARMASTERY: 1 + } + KN_BRANDISHSPEAR: { + MaxLevel: 10 + KN_RIDING: 1 + KN_SPEARSTAB: 3 + } + KN_SPEARSTAB: { + MaxLevel: 10 + KN_PIERCE: 5 + } + KN_SPEARBOOMERANG: { + MaxLevel: 5 + KN_PIERCE: 3 + } + KN_TWOHANDQUICKEN: { + MaxLevel: 10 + SM_TWOHAND: 1 + } + KN_AUTOCOUNTER: { + MaxLevel: 5 + SM_TWOHAND: 1 + } + KN_BOWLINGBASH: { + MaxLevel: 10 + SM_BASH: 10 + SM_MAGNUM: 3 + SM_TWOHAND: 5 + KN_TWOHANDQUICKEN: 10 + KN_AUTOCOUNTER: 5 + } + KN_RIDING: { + MaxLevel: 1 + SM_ENDURE: 1 + } + KN_CAVALIERMASTERY: { + MaxLevel: 5 + KN_RIDING: 1 + } + KN_CHARGEATK: 1 + KN_ONEHAND: { + MaxLevel: 1 + KN_TWOHANDQUICKEN: 10 + } + } +} +Priest: { + inherit: ( "Acolyte" ); + + skills: { + MG_SRECOVERY: 10 + MG_SAFETYWALL: { + MaxLevel: 10 + PR_ASPERSIO: 4 + PR_SANCTUARY: 3 + } + ALL_RESURRECTION: { + MaxLevel: 4 + PR_STRECOVERY: 1 + MG_SRECOVERY: 4 + } + PR_MACEMASTERY: 10 + PR_IMPOSITIO: 5 + PR_SUFFRAGIUM: { + MaxLevel: 3 + PR_IMPOSITIO: 2 + } + PR_ASPERSIO: { + MaxLevel: 5 + AL_HOLYWATER: 1 + PR_IMPOSITIO: 3 + } + PR_BENEDICTIO: { + MaxLevel: 5 + PR_GLORIA: 3 + PR_ASPERSIO: 5 + } + PR_SANCTUARY: { + MaxLevel: 10 + AL_HEAL: 1 + } + PR_SLOWPOISON: 4 + PR_STRECOVERY: 1 + PR_KYRIE: { + MaxLevel: 10 + AL_ANGELUS: 2 + } + PR_MAGNIFICAT: 5 + PR_GLORIA: { + MaxLevel: 5 + PR_KYRIE: 4 + PR_MAGNIFICAT: 3 + } + PR_LEXDIVINA: { + MaxLevel: 10 + AL_RUWACH: 1 + } + PR_TURNUNDEAD: { + MaxLevel: 10 + ALL_RESURRECTION: 1 + PR_LEXDIVINA: 3 + } + PR_LEXAETERNA: { + MaxLevel: 1 + PR_LEXDIVINA: 5 + } + PR_MAGNUS: { + MaxLevel: 10 + MG_SAFETYWALL: 1 + PR_LEXAETERNA: 1 + PR_TURNUNDEAD: 3 + } + PR_REDEMPTIO: 1 + } +} +Wizard: { + inherit: ( "Magician" ); + + skills: { + WZ_FIREPILLAR: { + MaxLevel: 10 + MG_FIREWALL: 1 + } + WZ_SIGHTRASHER: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 1 + MG_SIGHT: 1 + } + WZ_METEOR: { + MaxLevel: 10 + WZ_SIGHTRASHER: 2 + MG_THUNDERSTORM: 1 + } + WZ_JUPITEL: { + MaxLevel: 10 + MG_NAPALMBEAT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_VERMILION: { + MaxLevel: 10 + MG_THUNDERSTORM: 1 + WZ_JUPITEL: 5 + } + WZ_WATERBALL: { + MaxLevel: 5 + MG_COLDBOLT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_ICEWALL: { + MaxLevel: 10 + MG_STONECURSE: 1 + MG_FROSTDIVER: 1 + } + WZ_FROSTNOVA: { + MaxLevel: 10 + WZ_ICEWALL: 1 + } + WZ_STORMGUST: { + MaxLevel: 10 + MG_FROSTDIVER: 1 + WZ_JUPITEL: 3 + } + WZ_EARTHSPIKE: { + MaxLevel: 5 + MG_STONECURSE: 1 + } + WZ_HEAVENDRIVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 3 + } + WZ_QUAGMIRE: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 1 + } + WZ_ESTIMATION: 1 + WZ_SIGHTBLASTER: 1 + } +} +Blacksmith: { + inherit: ( "Merchant" ); + + skills: { + BS_IRON: 5 + BS_STEEL: { + MaxLevel: 5 + BS_IRON: 1 + } + BS_ENCHANTEDSTONE: { + MaxLevel: 5 + BS_IRON: 1 + } + BS_ORIDEOCON: { + MaxLevel: 5 + BS_ENCHANTEDSTONE: 1 + } + BS_DAGGER: 3 + BS_SWORD: { + MaxLevel: 3 + BS_DAGGER: 1 + } + BS_TWOHANDSWORD: { + MaxLevel: 3 + BS_SWORD: 1 + } + BS_AXE: { + MaxLevel: 3 + BS_SWORD: 2 + } + BS_MACE: { + MaxLevel: 3 + BS_KNUCKLE: 1 + } + BS_KNUCKLE: { + MaxLevel: 3 + BS_DAGGER: 1 + } + BS_SPEAR: { + MaxLevel: 3 + BS_DAGGER: 2 + } + BS_HILTBINDING: 1 + BS_FINDINGORE: { + MaxLevel: 1 + BS_STEEL: 1 + BS_HILTBINDING: 1 + } + BS_WEAPONRESEARCH: { + MaxLevel: 10 + BS_HILTBINDING: 1 + } + BS_REPAIRWEAPON: { + MaxLevel: 1 + BS_WEAPONRESEARCH: 1 + } + BS_SKINTEMPER: 5 + BS_HAMMERFALL: 5 + BS_ADRENALINE: { + MaxLevel: 5 + BS_HAMMERFALL: 2 + } + BS_WEAPONPERFECT: { + MaxLevel: 5 + BS_WEAPONRESEARCH: 2 + BS_ADRENALINE: 2 + } + BS_OVERTHRUST: { + MaxLevel: 5 + BS_ADRENALINE: 3 + } + BS_MAXIMIZE: { + MaxLevel: 5 + BS_WEAPONPERFECT: 3 + BS_OVERTHRUST: 2 + } + BS_UNFAIRLYTRICK: 1 + BS_GREED: 1 + BS_ADRENALINE2: { + MaxLevel: 1 + BS_ADRENALINE: 5 + } + } +} +Hunter: { + inherit: ( "Archer" ); + + skills: { + HT_SKIDTRAP: 5 + HT_LANDMINE: 5 + HT_ANKLESNARE: { + MaxLevel: 5 + HT_SKIDTRAP: 1 + } + HT_SHOCKWAVE: { + MaxLevel: 5 + HT_ANKLESNARE: 1 + } + HT_SANDMAN: { + MaxLevel: 5 + HT_FLASHER: 1 + } + HT_FLASHER: { + MaxLevel: 5 + HT_SKIDTRAP: 1 + } + HT_FREEZINGTRAP: { + MaxLevel: 5 + HT_FLASHER: 1 + } + HT_BLASTMINE: { + MaxLevel: 5 + HT_LANDMINE: 1 + HT_SANDMAN: 1 + HT_FREEZINGTRAP: 1 + } + HT_CLAYMORETRAP: { + MaxLevel: 5 + HT_SHOCKWAVE: 1 + HT_BLASTMINE: 1 + } + HT_REMOVETRAP: { + MaxLevel: 1 + HT_LANDMINE: 1 + } + HT_TALKIEBOX: { + MaxLevel: 1 + HT_SHOCKWAVE: 1 + HT_REMOVETRAP: 1 + } + HT_BEASTBANE: 10 + HT_FALCON: { + MaxLevel: 1 + HT_BEASTBANE: 1 + } + HT_STEELCROW: { + MaxLevel: 10 + HT_BLITZBEAT: 5 + } + HT_BLITZBEAT: { + MaxLevel: 5 + HT_FALCON: 1 + } + HT_DETECTING: { + MaxLevel: 4 + AC_CONCENTRATION: 1 + HT_FALCON: 1 + } + HT_SPRINGTRAP: { + MaxLevel: 5 + HT_REMOVETRAP: 1 + HT_FALCON: 1 + } + HT_PHANTASMIC: 1 + HT_POWER: { + MaxLevel: 1 + AC_DOUBLE: 10 + } + } +} +Assassin: { + inherit: ( "Thief" ); + + skills: { + AS_RIGHT: 5 + AS_LEFT: { + MaxLevel: 5 + AS_RIGHT: 2 + } + AS_KATAR: 10 + AS_CLOAKING: { + MaxLevel: 10 + TF_HIDING: 2 + } + AS_SONICBLOW: { + MaxLevel: 10 + AS_KATAR: 4 + } + AS_GRIMTOOTH: { + MaxLevel: 5 + AS_CLOAKING: 2 + AS_SONICBLOW: 5 + } + AS_ENCHANTPOISON: { + MaxLevel: 10 + TF_POISON: 1 + } + AS_POISONREACT: { + MaxLevel: 10 + AS_ENCHANTPOISON: 3 + } + AS_VENOMDUST: { + MaxLevel: 10 + AS_ENCHANTPOISON: 5 + } + AS_SPLASHER: { + MaxLevel: 10 + AS_POISONREACT: 5 + AS_VENOMDUST: 5 + } + AS_SONICACCEL: 1 + AS_VENOMKNIFE: 1 + } +} +Crusader: { + inherit: ( "Swordsman" ); + + skills: { + KN_RIDING: { + MaxLevel: 1 + SM_ENDURE: 1 + } + KN_CAVALIERMASTERY: { + MaxLevel: 5 + KN_RIDING: 1 + } + KN_SPEARMASTERY: 10 + AL_CURE: { + MaxLevel: 1 + CR_TRUST: 5 + } + AL_DP: { + MaxLevel: 10 + AL_CURE: 1 + } + AL_DEMONBANE: { + MaxLevel: 10 + AL_DP: 3 + } + AL_HEAL: { + MaxLevel: 10 + AL_DEMONBANE: 5 + CR_TRUST: 10 + } + CR_TRUST: 10 + CR_AUTOGUARD: 10 + CR_SHIELDCHARGE: { + MaxLevel: 5 + CR_AUTOGUARD: 5 + } + CR_SHIELDBOOMERANG: { + MaxLevel: 5 + CR_SHIELDCHARGE: 3 + } + CR_REFLECTSHIELD: { + MaxLevel: 10 + CR_SHIELDBOOMERANG: 3 + } + CR_HOLYCROSS: { + MaxLevel: 10 + CR_TRUST: 7 + } + CR_GRANDCROSS: { + MaxLevel: 10 + CR_HOLYCROSS: 6 + CR_TRUST: 10 + } + CR_DEVOTION: { + MaxLevel: 5 + CR_REFLECTSHIELD: 5 + CR_GRANDCROSS: 4 + } + CR_PROVIDENCE: { + MaxLevel: 5 + AL_DP: 5 + AL_HEAL: 5 + } + CR_DEFENDER: { + MaxLevel: 5 + CR_SHIELDBOOMERANG: 1 + } + CR_SPEARQUICKEN: { + MaxLevel: 10 + KN_SPEARMASTERY: 10 + } + CR_SHRINK: 1 + } +} +Monk: { + inherit: ( "Acolyte" ); + + skills: { + MO_IRONHAND: { + MaxLevel: 10 + AL_DEMONBANE: 10 + AL_DP: 10 + } + MO_SPIRITSRECOVERY: { + MaxLevel: 5 + MO_BLADESTOP: 2 + } + MO_CALLSPIRITS: { + MaxLevel: 5 + MO_IRONHAND: 2 + } + MO_ABSORBSPIRITS: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + } + MO_TRIPLEATTACK: { + MaxLevel: 10 + MO_DODGE: 5 + } + MO_BODYRELOCATION: { + MaxLevel: 1 + MO_EXTREMITYFIST: 3 + MO_SPIRITSRECOVERY: 2 + MO_STEELBODY: 3 + } + MO_DODGE: { + MaxLevel: 10 + MO_IRONHAND: 5 + MO_CALLSPIRITS: 5 + } + MO_INVESTIGATE: { + MaxLevel: 5 + MO_CALLSPIRITS: 5 + } + MO_FINGEROFFENSIVE: { + MaxLevel: 5 + MO_INVESTIGATE: 3 + } + MO_STEELBODY: { + MaxLevel: 5 + MO_COMBOFINISH: 3 + } + MO_BLADESTOP: { + MaxLevel: 5 + MO_DODGE: 5 + } + MO_EXPLOSIONSPIRITS: { + MaxLevel: 5 + MO_ABSORBSPIRITS: 1 + } + MO_EXTREMITYFIST: { + MaxLevel: 5 + MO_EXPLOSIONSPIRITS: 3 + MO_FINGEROFFENSIVE: 3 + } + MO_CHAINCOMBO: { + MaxLevel: 5 + MO_TRIPLEATTACK: 5 + } + MO_COMBOFINISH: { + MaxLevel: 5 + MO_CHAINCOMBO: 3 + } + MO_KITRANSLATION: 1 + MO_BALKYOUNG: 1 + } +} +Sage: { + inherit: ( "Magician" ); + + skills: { + WZ_ESTIMATION: 1 + WZ_EARTHSPIKE: { + MaxLevel: 5 + SA_SEISMICWEAPON: 1 + } + WZ_HEAVENDRIVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 1 + } + SA_ADVANCEDBOOK: 10 + SA_CASTCANCEL: { + MaxLevel: 5 + SA_ADVANCEDBOOK: 2 + } + SA_MAGICROD: { + MaxLevel: 5 + SA_ADVANCEDBOOK: 4 + } + SA_SPELLBREAKER: { + MaxLevel: 5 + SA_MAGICROD: 1 + } + SA_FREECAST: { + MaxLevel: 10 + SA_CASTCANCEL: 1 + } + SA_AUTOSPELL: { + MaxLevel: 10 + SA_FREECAST: 4 + } + SA_FLAMELAUNCHER: { + MaxLevel: 5 + MG_FIREBOLT: 1 + SA_ADVANCEDBOOK: 5 + } + SA_FROSTWEAPON: { + MaxLevel: 5 + MG_COLDBOLT: 1 + SA_ADVANCEDBOOK: 5 + } + SA_LIGHTNINGLOADER: { + MaxLevel: 5 + MG_LIGHTNINGBOLT: 1 + SA_ADVANCEDBOOK: 5 + } + SA_SEISMICWEAPON: { + MaxLevel: 5 + MG_STONECURSE: 1 + SA_ADVANCEDBOOK: 5 + } + SA_DRAGONOLOGY: { + MaxLevel: 5 + SA_ADVANCEDBOOK: 9 + } + SA_VOLCANO: { + MaxLevel: 5 + SA_FLAMELAUNCHER: 2 + } + SA_DELUGE: { + MaxLevel: 5 + SA_FROSTWEAPON: 2 + } + SA_VIOLENTGALE: { + MaxLevel: 5 + SA_LIGHTNINGLOADER: 2 + } + SA_LANDPROTECTOR: { + MaxLevel: 5 + SA_VOLCANO: 3 + SA_DELUGE: 3 + SA_VIOLENTGALE: 3 + } + SA_DISPELL: { + MaxLevel: 5 + SA_SPELLBREAKER: 3 + } + SA_ABRACADABRA: { + MaxLevel: 10 + SA_AUTOSPELL: 5 + SA_DISPELL: 1 + SA_LANDPROTECTOR: 1 + } + SA_CREATECON: 1 + SA_ELEMENTWATER: 1 + SA_ELEMENTGROUND: 1 + SA_ELEMENTFIRE: 1 + SA_ELEMENTWIND: 1 + } +} +Rogue: { + inherit: ( "Thief" ); + + skills: { + SM_SWORD: 10 + AC_VULTURE: 10 + AC_DOUBLE: { + MaxLevel: 10 + AC_VULTURE: 10 + } + HT_REMOVETRAP: { + MaxLevel: 1 + AC_DOUBLE: 5 + } + RG_SNATCHER: { + MaxLevel: 10 + TF_STEAL: 1 + } + RG_STEALCOIN: { + MaxLevel: 10 + RG_SNATCHER: 4 + } + RG_BACKSTAP: { + MaxLevel: 10 + RG_STEALCOIN: 4 + } + RG_TUNNELDRIVE: { + MaxLevel: 5 + TF_HIDING: 1 + } + RG_RAID: { + MaxLevel: 5 + RG_BACKSTAP: 2 + RG_TUNNELDRIVE: 2 + } + RG_STRIPWEAPON: { + MaxLevel: 5 + RG_STRIPARMOR: 5 + } + RG_STRIPSHIELD: { + MaxLevel: 5 + RG_STRIPHELM: 5 + } + RG_STRIPARMOR: { + MaxLevel: 5 + RG_STRIPSHIELD: 5 + } + RG_STRIPHELM: { + MaxLevel: 5 + RG_STEALCOIN: 2 + } + RG_INTIMIDATE: { + MaxLevel: 5 + RG_BACKSTAP: 4 + RG_RAID: 5 + } + RG_GRAFFITI: { + MaxLevel: 1 + RG_FLAGGRAFFITI: 5 + } + RG_FLAGGRAFFITI: { + MaxLevel: 5 + RG_CLEANER: 1 + } + RG_CLEANER: { + MaxLevel: 1 + RG_GANGSTER: 1 + } + RG_GANGSTER: { + MaxLevel: 1 + RG_STRIPSHIELD: 3 + } + RG_COMPULSION: { + MaxLevel: 5 + RG_GANGSTER: 1 + } + RG_PLAGIARISM: { + MaxLevel: 10 + RG_INTIMIDATE: 5 + } + RG_CLOSECONFINE: 1 + } +} +Alchemist: { + inherit: ( "Merchant" ); + + skills: { + AM_AXEMASTERY: 10 + AM_LEARNINGPOTION: 10 + AM_PHARMACY: { + MaxLevel: 10 + AM_LEARNINGPOTION: 5 + } + AM_DEMONSTRATION: { + MaxLevel: 5 + AM_PHARMACY: 4 + } + AM_ACIDTERROR: { + MaxLevel: 5 + AM_PHARMACY: 5 + } + AM_POTIONPITCHER: { + MaxLevel: 5 + AM_PHARMACY: 3 + } + AM_CANNIBALIZE: { + MaxLevel: 5 + AM_PHARMACY: 6 + } + AM_SPHEREMINE: { + MaxLevel: 5 + AM_PHARMACY: 2 + } + AM_CP_WEAPON: { + MaxLevel: 5 + AM_CP_ARMOR: 3 + } + AM_CP_SHIELD: { + MaxLevel: 5 + AM_CP_HELM: 3 + } + AM_CP_ARMOR: { + MaxLevel: 5 + AM_CP_SHIELD: 3 + } + AM_CP_HELM: { + MaxLevel: 5 + AM_PHARMACY: 2 + } + AM_BIOETHICS: 1 + AM_CALLHOMUN: { + MaxLevel: 1 + AM_REST: 1 + } + AM_REST: { + MaxLevel: 1 + AM_BIOETHICS: 1 + } + AM_RESURRECTHOMUN: { + MaxLevel: 5 + AM_CALLHOMUN: 1 + } + AM_BERSERKPITCHER: 1 + AM_TWILIGHT1: { + MaxLevel: 1 + AM_PHARMACY: 10 + } + AM_TWILIGHT2: { + MaxLevel: 1 + AM_PHARMACY: 10 + } + AM_TWILIGHT3: { + MaxLevel: 1 + AM_PHARMACY: 10 + } + } +} +Bard: { + inherit: ( "Archer" ); + + skills: { + BA_MUSICALLESSON: 10 + BA_MUSICALSTRIKE: { + MaxLevel: 5 + BA_MUSICALLESSON: 3 + } + BA_DISSONANCE: { + MaxLevel: 5 + BA_MUSICALLESSON: 1 + BD_ADAPTATION: 1 + } + BA_FROSTJOKER: { + MaxLevel: 5 + BD_ENCORE: 1 + } + BA_WHISTLE: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BA_ASSASSINCROSS: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BA_POEMBRAGI: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BA_APPLEIDUN: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BD_ADAPTATION: 1 + BD_ENCORE: { + MaxLevel: 1 + BD_ADAPTATION: 1 + } + BD_LULLABY: { + MaxLevel: 1 + BA_WHISTLE: 10 + } + BD_RICHMANKIM: { + MaxLevel: 5 + BD_SIEGFRIED: 3 + } + BD_ETERNALCHAOS: { + MaxLevel: 1 + BD_ROKISWEIL: 1 + } + BD_DRUMBATTLEFIELD: { + MaxLevel: 5 + BA_APPLEIDUN: 10 + } + BD_RINGNIBELUNGEN: { + MaxLevel: 5 + BD_DRUMBATTLEFIELD: 3 + } + BD_ROKISWEIL: { + MaxLevel: 1 + BA_ASSASSINCROSS: 10 + } + BD_INTOABYSS: { + MaxLevel: 1 + BD_LULLABY: 1 + } + BD_SIEGFRIED: { + MaxLevel: 5 + BA_POEMBRAGI: 10 + } + BA_PANGVOICE: 1 + } +} +Dancer: { + inherit: ( "Archer" ); + + skills: { + DC_DANCINGLESSON: 10 + DC_THROWARROW: { + MaxLevel: 5 + DC_DANCINGLESSON: 3 + } + DC_UGLYDANCE: { + MaxLevel: 5 + DC_DANCINGLESSON: 1 + BD_ADAPTATION: 1 + } + DC_SCREAM: { + MaxLevel: 5 + BD_ENCORE: 1 + } + DC_HUMMING: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + DC_DONTFORGETME: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + DC_FORTUNEKISS: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + DC_SERVICEFORYOU: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + BD_ADAPTATION: 1 + BD_ENCORE: { + MaxLevel: 1 + BD_ADAPTATION: 1 + } + BD_LULLABY: { + MaxLevel: 1 + DC_HUMMING: 10 + } + BD_RICHMANKIM: { + MaxLevel: 5 + BD_SIEGFRIED: 3 + } + BD_ETERNALCHAOS: { + MaxLevel: 1 + BD_ROKISWEIL: 1 + } + BD_DRUMBATTLEFIELD: { + MaxLevel: 5 + DC_SERVICEFORYOU: 10 + } + BD_RINGNIBELUNGEN: { + MaxLevel: 5 + BD_DRUMBATTLEFIELD: 3 + } + BD_ROKISWEIL: { + MaxLevel: 1 + DC_DONTFORGETME: 10 + } + BD_INTOABYSS: { + MaxLevel: 1 + BD_LULLABY: 1 + } + BD_SIEGFRIED: { + MaxLevel: 5 + DC_FORTUNEKISS: 10 + } + DC_WINKCHARM: 1 + } +} +Super_Novice: { + inherit: ( "Novice" ); + + skills: { + SM_SWORD: 10 + SM_RECOVERY: 10 + SM_BASH: 10 + SM_PROVOKE: 10 + SM_MAGNUM: { + MaxLevel: 10 + SM_BASH: 5 + } + SM_ENDURE: { + MaxLevel: 10 + SM_PROVOKE: 5 + } + MG_SRECOVERY: 10 + MG_SIGHT: 1 + MG_NAPALMBEAT: 10 + MG_SAFETYWALL: { + MaxLevel: 10 + MG_NAPALMBEAT: 7 + MG_SOULSTRIKE: 5 + } + MG_SOULSTRIKE: { + MaxLevel: 10 + MG_NAPALMBEAT: 4 + } + MG_COLDBOLT: 10 + MG_FROSTDIVER: { + MaxLevel: 10 + MG_COLDBOLT: 5 + } + MG_STONECURSE: 10 + MG_FIREBALL: { + MaxLevel: 10 + MG_FIREBOLT: 4 + } + MG_FIREWALL: { + MaxLevel: 10 + MG_FIREBALL: 5 + MG_SIGHT: 1 + } + MG_FIREBOLT: 10 + MG_LIGHTNINGBOLT: 10 + MG_THUNDERSTORM: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 4 + } + AL_DP: 10 + AL_DEMONBANE: { + MaxLevel: 10 + AL_DP: 3 + } + AL_RUWACH: 1 + AL_PNEUMA: { + MaxLevel: 1 + AL_WARP: 4 + } + AL_TELEPORT: { + MaxLevel: 2 + AL_RUWACH: 1 + } + AL_WARP: { + MaxLevel: 4 + AL_TELEPORT: 2 + } + AL_HEAL: 10 + AL_INCAGI: { + MaxLevel: 10 + AL_HEAL: 3 + } + AL_DECAGI: { + MaxLevel: 10 + AL_INCAGI: 1 + } + AL_HOLYWATER: 1 + AL_CRUCIS: { + MaxLevel: 10 + AL_DEMONBANE: 3 + } + AL_ANGELUS: { + MaxLevel: 10 + AL_DP: 3 + } + AL_BLESSING: { + MaxLevel: 10 + AL_DP: 5 + } + AL_CURE: { + MaxLevel: 1 + AL_HEAL: 2 + } + MC_INCCARRY: 10 + MC_DISCOUNT: { + MaxLevel: 10 + MC_INCCARRY: 3 + } + MC_OVERCHARGE: { + MaxLevel: 10 + MC_DISCOUNT: 3 + } + MC_PUSHCART: { + MaxLevel: 10 + MC_INCCARRY: 5 + } + MC_IDENTIFY: 1 + MC_VENDING: { + MaxLevel: 10 + MC_PUSHCART: 3 + } + MC_MAMMONITE: 10 + AC_OWL: 10 + AC_VULTURE: { + MaxLevel: 10 + AC_OWL: 3 + } + AC_CONCENTRATION: { + MaxLevel: 10 + AC_VULTURE: 1 + } + TF_DOUBLE: 10 + TF_MISS: 10 + TF_STEAL: 10 + TF_HIDING: { + MaxLevel: 10 + TF_STEAL: 5 + } + TF_POISON: 10 + TF_DETOXIFY: { + MaxLevel: 1 + TF_POISON: 3 + } + ALL_BUYING_STORE: { + MaxLevel: 1 + MC_VENDING: 1 + } + } +} +Gunslinger: { + inherit: ( "Novice" ); + + skills: { + GS_GLITTERING: 5 + GS_FLING: { + MaxLevel: 1 + GS_GLITTERING: 1 + } + GS_TRIPLEACTION: { + MaxLevel: 1 + GS_GLITTERING: 1 + GS_CHAINACTION: 10 + } + GS_BULLSEYE: { + MaxLevel: 1 + GS_GLITTERING: 5 + GS_TRACKING: 10 + } + GS_MADNESSCANCEL: { + MaxLevel: 1 + GS_GLITTERING: 4 + GS_GATLINGFEVER: 10 + } + GS_ADJUSTMENT: { + MaxLevel: 1 + GS_GLITTERING: 4 + GS_DISARM: 5 + } + GS_INCREASING: { + MaxLevel: 1 + GS_GLITTERING: 2 + GS_SNAKEEYE: 10 + } + GS_MAGICALBULLET: { + MaxLevel: 1 + GS_GLITTERING: 1 + } + GS_CRACKER: { + MaxLevel: 1 + GS_GLITTERING: 1 + } + GS_SINGLEACTION: 10 + GS_SNAKEEYE: 10 + GS_CHAINACTION: { + MaxLevel: 10 + GS_SINGLEACTION: 1 + } + GS_TRACKING: { + MaxLevel: 10 + GS_SINGLEACTION: 5 + } + GS_DISARM: { + MaxLevel: 5 + GS_TRACKING: 7 + } + GS_PIERCINGSHOT: { + MaxLevel: 5 + GS_TRACKING: 5 + } + GS_RAPIDSHOWER: { + MaxLevel: 10 + GS_CHAINACTION: 3 + } + GS_DESPERADO: { + MaxLevel: 10 + GS_RAPIDSHOWER: 5 + } + GS_GATLINGFEVER: { + MaxLevel: 10 + GS_RAPIDSHOWER: 7 + GS_DESPERADO: 5 + } + GS_DUST: { + MaxLevel: 10 + GS_SINGLEACTION: 5 + } + GS_FULLBUSTER: { + MaxLevel: 10 + GS_DUST: 3 + } + GS_SPREADATTACK: { + MaxLevel: 10 + GS_FULLBUSTER: 5 + } + GS_GROUNDDRIFT: { + MaxLevel: 10 + GS_SPREADATTACK: 7 + } + } +} +Ninja: { + inherit: ( "Novice" ); + + skills: { + NJ_TOBIDOUGU: 10 + NJ_SYURIKEN: { + MaxLevel: 10 + NJ_TOBIDOUGU: 1 + } + NJ_KUNAI: { + MaxLevel: 5 + NJ_SYURIKEN: 5 + } + NJ_HUUMA: { + MaxLevel: 5 + NJ_TOBIDOUGU: 5 + NJ_KUNAI: 5 + } + NJ_ZENYNAGE: { + MaxLevel: 10 + NJ_TOBIDOUGU: 10 + NJ_HUUMA: 5 + } + NJ_TATAMIGAESHI: 5 + NJ_KASUMIKIRI: { + MaxLevel: 10 + NJ_SHADOWJUMP: 1 + } + NJ_SHADOWJUMP: { + MaxLevel: 5 + NJ_TATAMIGAESHI: 1 + } + NJ_KIRIKAGE: { + MaxLevel: 5 + NJ_KASUMIKIRI: 5 + } + NJ_UTSUSEMI: { + MaxLevel: 5 + NJ_SHADOWJUMP: 5 + } + NJ_BUNSINJYUTSU: { + MaxLevel: 10 + NJ_UTSUSEMI: 4 + NJ_KIRIKAGE: 3 + NJ_NEN: 1 + } + NJ_NINPOU: 10 + NJ_KOUENKA: { + MaxLevel: 10 + NJ_NINPOU: 1 + } + NJ_KAENSIN: { + MaxLevel: 10 + NJ_KOUENKA: 5 + } + NJ_BAKUENRYU: { + MaxLevel: 5 + NJ_NINPOU: 10 + NJ_KAENSIN: 7 + } + NJ_HYOUSENSOU: { + MaxLevel: 10 + NJ_NINPOU: 1 + } + NJ_SUITON: { + MaxLevel: 10 + NJ_HYOUSENSOU: 5 + } + NJ_HYOUSYOURAKU: { + MaxLevel: 5 + NJ_NINPOU: 10 + NJ_SUITON: 7 + } + NJ_HUUJIN: { + MaxLevel: 10 + NJ_NINPOU: 1 + } + NJ_RAIGEKISAI: { + MaxLevel: 5 + NJ_HUUJIN: 5 + } + NJ_KAMAITACHI: { + MaxLevel: 5 + NJ_NINPOU: 10 + NJ_RAIGEKISAI: 5 + } + NJ_NEN: { + MaxLevel: 5 + NJ_NINPOU: 5 + } + NJ_ISSEN: { + MaxLevel: 10 + NJ_TOBIDOUGU: 7 + NJ_KIRIKAGE: 5 + NJ_NEN: 1 + } + } +} +Novice_High: { + inherit: ( "Novice" ); +} +Swordsman_High: { + inherit: ( "Swordsman" ); +} +Magician_High: { + inherit: ( "Magician" ); +} +Archer_High: { + inherit: ( "Archer" ); +} +Acolyte_High: { + inherit: ( "Acolyte" ); +} +Merchant_High: { + inherit: ( "Merchant" ); +} +Thief_High: { + inherit: ( "Thief" ); +} +Lord_Knight: { + inherit: ( "Knight" ); + skills: { + LK_AURABLADE: { + MaxLevel: 5 + SM_BASH: 5 + SM_MAGNUM: 5 + SM_TWOHAND: 5 + } + LK_PARRYING: { + MaxLevel: 10 + SM_TWOHAND: 10 + SM_PROVOKE: 5 + KN_TWOHANDQUICKEN: 3 + } + LK_CONCENTRATION: { + MaxLevel: 5 + SM_RECOVERY: 5 + KN_SPEARMASTERY: 5 + KN_RIDING: 1 + } + LK_TENSIONRELAX: { + MaxLevel: 1 + SM_RECOVERY: 10 + SM_PROVOKE: 5 + SM_ENDURE: 3 + } + LK_BERSERK: { + MaxLevel: 1 + MinJobLevel: 50 + } + LK_SPIRALPIERCE: { + MaxLevel: 5 + KN_SPEARMASTERY: 10 + KN_PIERCE: 5 + KN_SPEARSTAB: 5 + KN_RIDING: 1 + } + LK_HEADCRUSH: { + MaxLevel: 5 + KN_SPEARMASTERY: 9 + KN_RIDING: 1 + } + LK_JOINTBEAT: { + MaxLevel: 10 + KN_SPEARMASTERY: 9 + KN_CAVALIERMASTERY: 3 + LK_HEADCRUSH: 3 + } + } +} +High_Priest: { + inherit: ( "Priest" ); + + skills: { + HP_ASSUMPTIO: { + MaxLevel: 5 + AL_ANGELUS: 1 + MG_SRECOVERY: 3 + PR_IMPOSITIO: 3 + } + HP_BASILICA: { + MaxLevel: 5 + PR_GLORIA: 2 + MG_SRECOVERY: 1 + PR_KYRIE: 3 + } + HP_MEDITATIO: { + MaxLevel: 10 + PR_ASPERSIO: 3 + MG_SRECOVERY: 5 + PR_LEXDIVINA: 5 + } + HP_MANARECHARGE: { + MaxLevel: 5 + PR_MACEMASTERY: 10 + AL_DEMONBANE: 10 + } + } +} +High_Wizard: { + inherit: ( "Wizard" ); + + skills: { + HW_SOULDRAIN: { + MaxLevel: 10 + MG_SRECOVERY: 5 + MG_SOULSTRIKE: 7 + } + HW_MAGICCRASHER: { + MaxLevel: 1 + MG_SRECOVERY: 1 + } + HW_MAGICPOWER: 10 + HW_NAPALMVULCAN: { + MaxLevel: 5 + MG_NAPALMBEAT: 5 + } + HW_GANBANTEIN: { + MaxLevel: 1 + WZ_ESTIMATION: 1 + WZ_ICEWALL: 1 + } + HW_GRAVITATION: { + MaxLevel: 5 + HW_MAGICCRASHER: 1 + HW_MAGICPOWER: 10 + WZ_QUAGMIRE: 1 + } + } +} +Whitesmith: { + inherit: ( "Blacksmith" ); + + skills: { + WS_MELTDOWN: { + MaxLevel: 10 + BS_SKINTEMPER: 3 + BS_HILTBINDING: 1 + BS_WEAPONRESEARCH: 5 + BS_OVERTHRUST: 3 + } + WS_CARTBOOST: { + MaxLevel: 1 + MC_PUSHCART: 5 + MC_CARTREVOLUTION: 1 + MC_CHANGECART: 1 + BS_HILTBINDING: 1 + } + WS_WEAPONREFINE: { + MaxLevel: 10 + BS_WEAPONRESEARCH: 10 + } + WS_CARTTERMINATION: { + MaxLevel: 10 + MC_MAMMONITE: 10 + BS_HAMMERFALL: 5 + WS_CARTBOOST: 1 + } + WS_OVERTHRUSTMAX: { + MaxLevel: 5 + BS_OVERTHRUST: 5 + } + } +} +Sniper: { + inherit: ( "Hunter" ); + + skills: { + SN_SIGHT: { + MaxLevel: 10 + AC_OWL: 10 + AC_VULTURE: 10 + AC_CONCENTRATION: 10 + HT_FALCON: 1 + } + SN_FALCONASSAULT: { + MaxLevel: 5 + HT_STEELCROW: 3 + AC_VULTURE: 5 + HT_BLITZBEAT: 5 + HT_FALCON: 1 + } + SN_SHARPSHOOTING: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + AC_DOUBLE: 5 + } + SN_WINDWALK: { + MaxLevel: 10 + AC_CONCENTRATION: 9 + } + } +} +Assassin_Cross: { + inherit: ( "Assassin" ); + + skills: { + ASC_KATAR: { + MaxLevel: 5 + TF_DOUBLE: 5 + AS_KATAR: 7 + } + ASC_EDP: { + MaxLevel: 5 + ASC_CDP: 1 + } + ASC_BREAKER: { + MaxLevel: 10 + TF_DOUBLE: 5 + AS_CLOAKING: 3 + AS_ENCHANTPOISON: 6 + TF_POISON: 5 + } + ASC_METEORASSAULT: { + MaxLevel: 10 + AS_RIGHT: 3 + AS_KATAR: 5 + AS_SONICBLOW: 5 + ASC_BREAKER: 1 + } + ASC_CDP: { + MaxLevel: 1 + TF_POISON: 10 + TF_DETOXIFY: 1 + AS_ENCHANTPOISON: 5 + } + } +} +Paladin: { + inherit: ( "Crusader" ); + + skills: { + PA_PRESSURE: { + MaxLevel: 5 + SM_ENDURE: 5 + CR_TRUST: 5 + CR_SHIELDCHARGE: 2 + } + PA_SACRIFICE: { + MaxLevel: 5 + SM_ENDURE: 1 + CR_TRUST: 5 + CR_DEVOTION: 3 + } + PA_GOSPEL: { + MaxLevel: 10 + CR_TRUST: 8 + AL_DP: 3 + AL_DEMONBANE: 5 + } + PA_SHIELDCHAIN: { + MaxLevel: 5 + CR_SHIELDBOOMERANG: 5 + } + } +} +Champion: { + inherit: ( "Monk" ); + + skills: { + CH_PALMSTRIKE: { + MaxLevel: 5 + MO_IRONHAND: 7 + MO_CALLSPIRITS: 5 + } + CH_TIGERFIST: { + MaxLevel: 5 + MO_IRONHAND: 5 + MO_TRIPLEATTACK: 5 + MO_CALLSPIRITS: 5 + MO_COMBOFINISH: 3 + } + CH_CHAINCRUSH: { + MaxLevel: 10 + MO_IRONHAND: 5 + MO_CALLSPIRITS: 5 + CH_TIGERFIST: 2 + } + CH_SOULCOLLECT: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + MO_ABSORBSPIRITS: 1 + MO_EXPLOSIONSPIRITS: 5 + } + } +} +Professor: { + inherit: ( "Sage" ); + + skills: { + PF_HPCONVERSION: { + MaxLevel: 5 + MG_SRECOVERY: 1 + SA_MAGICROD: 1 + } + PF_SOULCHANGE: { + MaxLevel: 1 + SA_MAGICROD: 3 + SA_SPELLBREAKER: 2 + } + PF_SOULBURN: { + MaxLevel: 5 + SA_CASTCANCEL: 5 + SA_MAGICROD: 3 + SA_DISPELL: 3 + } + PF_MINDBREAKER: { + MaxLevel: 5 + MG_SRECOVERY: 3 + PF_SOULBURN: 1 + } + PF_MEMORIZE: { + MaxLevel: 1 + SA_ADVANCEDBOOK: 5 + SA_FREECAST: 5 + SA_AUTOSPELL: 1 + } + PF_FOGWALL: { + MaxLevel: 1 + SA_DELUGE: 2 + SA_VIOLENTGALE: 2 + } + PF_SPIDERWEB: { + MaxLevel: 1 + SA_DRAGONOLOGY: 4 + } + PF_DOUBLECASTING: { + MaxLevel: 5 + SA_AUTOSPELL: 1 + } + } +} +Stalker: { + inherit: ( "Rogue" ); + + skills: { + ST_CHASEWALK: { + MaxLevel: 5 + TF_HIDING: 5 + RG_TUNNELDRIVE: 3 + } + ST_REJECTSWORD: { + MaxLevel: 5 + RG_STRIPWEAPON: 1 + } + ST_PRESERVE: { + MaxLevel: 1 + RG_PLAGIARISM: 10 + } + ST_FULLSTRIP: { + MaxLevel: 5 + RG_STRIPWEAPON: 5 + RG_STRIPSHIELD: 5 + RG_STRIPARMOR: 5 + RG_STRIPHELM: 5 + } + } +} +Creator: { + inherit: ( "Alchemist" ); + + skills: { + CR_SLIMPITCHER: { + MaxLevel: 10 + AM_POTIONPITCHER: 5 + } + CR_FULLPROTECTION: { + MaxLevel: 5 + AM_CP_WEAPON: 5 + AM_CP_SHIELD: 5 + AM_CP_ARMOR: 5 + AM_CP_HELM: 5 + } + CR_ACIDDEMONSTRATION: { + MaxLevel: 10 + AM_DEMONSTRATION: 5 + AM_ACIDTERROR: 5 + } + CR_CULTIVATION: 2 + } +} +Clown: { + inherit: ( "Bard" ); + + skills: { + CG_ARROWVULCAN: { + MaxLevel: 10 + AC_SHOWER: 5 + BA_MUSICALSTRIKE: 1 + } + CG_MOONLIT: { + MaxLevel: 5 + AC_CONCENTRATION: 5 + BA_MUSICALLESSON: 7 + } + CG_MARIONETTE: { + MaxLevel: 1 + AC_CONCENTRATION: 5 + BA_MUSICALLESSON: 5 + } + CG_LONGINGFREEDOM: { + MaxLevel: 5 + BA_MUSICALLESSON: 10 + CG_MARIONETTE: 1 + } + CG_HERMODE: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + BA_MUSICALLESSON: 10 + } + CG_TAROTCARD: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + BA_DISSONANCE: 3 + } + } +} +Gypsy: { + inherit: ( "Dancer" ); + + skills: { + CG_ARROWVULCAN: { + MaxLevel: 10 + AC_SHOWER: 5 + DC_THROWARROW: 1 + } + CG_MOONLIT: { + MaxLevel: 5 + AC_CONCENTRATION: 5 + DC_DANCINGLESSON: 7 + } + CG_MARIONETTE: { + MaxLevel: 1 + AC_CONCENTRATION: 5 + DC_DANCINGLESSON: 5 + } + CG_LONGINGFREEDOM: { + MaxLevel: 5 + DC_DANCINGLESSON: 10 + CG_MARIONETTE: 1 + } + CG_HERMODE: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + DC_DANCINGLESSON: 10 + } + CG_TAROTCARD: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + DC_UGLYDANCE: 3 + } + } +} +Baby_Novice: { + inherit: ( "Novice" ); +} +Baby_Swordsman: { + inherit: ( "Swordsman" ); +} +Baby_Magician: { + inherit: ( "Priest" ); +} +Baby_Archer: { + inherit: ( "Archer" ); +} +Baby_Acolyte: { + inherit: ( "Acolyte" ); +} +Baby_Merchant: { + inherit: ( "Merchant" ); +} +Baby_Thief: { + inherit: ( "Thief" ); +} +Baby_Knight: { + inherit: ( "Knight" ); +} +Baby_Priest: { + inherit: ( "Priest" ); +} +Baby_Wizard: { + inherit: ( "Wizard" ); +} +Baby_Blacksmith: { + inherit: ( "Blacksmith" ); +} +Baby_Hunter: { + inherit: ( "Hunter" ); +} +Baby_Assassin: { + inherit: ( "Assassin" ); +} +Baby_Crusader: { + inherit: ( "Crusader" ); +} +Baby_Monk: { + inherit: ( "Monk" ); +} +Baby_Sage: { + inherit: ( "Sage" ); +} +Baby_Rogue: { + inherit: ( "Rogue" ); +} +Baby_Alchemist: { + inherit: ( "Alchemist" ); +} +Baby_Bard: { + inherit: ( "Bard" ); +} +Baby_Dancer: { + inherit: ( "Dancer" ); +} +Super_Baby: { + inherit: ( "Super_Novice" ); +} +Taekwon: { + inherit: ( "Novice" ); + + skills: { + TK_RUN: 10 + TK_READYSTORM: { + MaxLevel: 1 + TK_STORMKICK: 1 + } + TK_STORMKICK: 7 + TK_READYDOWN: { + MaxLevel: 1 + TK_DOWNKICK: 1 + } + TK_DOWNKICK: 7 + TK_READYTURN: { + MaxLevel: 1 + TK_TURNKICK: 1 + } + TK_TURNKICK: 7 + TK_READYCOUNTER: { + MaxLevel: 1 + TK_COUNTER: 1 + } + TK_COUNTER: 7 + TK_DODGE: { + MaxLevel: 1 + TK_JUMPKICK: 7 + } + TK_JUMPKICK: 7 + TK_HPTIME: 10 + TK_SPTIME: 10 + TK_POWER: 5 + TK_SEVENWIND: { + MaxLevel: 7 + TK_HPTIME: 5 + TK_SPTIME: 5 + TK_POWER: 5 + } + TK_HIGHJUMP: 5 + TK_MISSION: { + MaxLevel: 1 + TK_POWER: 5 + } + } +} +Star_Gladiator: { + inherit: ( "Taekwon" ); + + skills: { + SG_FEEL: 3 + SG_SUN_WARM: { + MaxLevel: 3 + SG_FEEL: 1 + } + SG_MOON_WARM: { + MaxLevel: 3 + SG_FEEL: 2 + } + SG_STAR_WARM: { + MaxLevel: 3 + SG_FEEL: 3 + } + SG_SUN_COMFORT: { + MaxLevel: 4 + SG_FEEL: 1 + } + SG_MOON_COMFORT: { + MaxLevel: 4 + SG_FEEL: 2 + } + SG_STAR_COMFORT: { + MaxLevel: 4 + SG_FEEL: 3 + } + SG_HATE: 3 + SG_SUN_ANGER: { + MaxLevel: 3 + SG_HATE: 1 + } + SG_MOON_ANGER: { + MaxLevel: 3 + SG_HATE: 2 + } + SG_STAR_ANGER: { + MaxLevel: 3 + SG_HATE: 3 + } + SG_SUN_BLESS: { + MaxLevel: 5 + SG_FEEL: 1 + SG_HATE: 1 + } + SG_MOON_BLESS: { + MaxLevel: 5 + SG_FEEL: 2 + SG_HATE: 2 + } + SG_STAR_BLESS: { + MaxLevel: 5 + SG_FEEL: 3 + SG_HATE: 3 + } + SG_DEVIL: 10 + SG_FRIEND: 3 + SG_KNOWLEDGE: 10 + SG_FUSION: { + MaxLevel: 1 + MinJobLevel: 443 + MG_SRECOVERY: 0 + } + } +} +Soul_Linker: { + inherit: ( "Taekwon" ); + + skills: { + SL_ALCHEMIST: 5 + SL_MONK: 5 + SL_STAR: 5 + SL_SAGE: 5 + SL_CRUSADER: 5 + SL_SUPERNOVICE: 5 + SL_KNIGHT: { + MaxLevel: 5 + SL_CRUSADER: 1 + } + SL_WIZARD: { + MaxLevel: 5 + SL_SAGE: 1 + } + SL_PRIEST: { + MaxLevel: 5 + SL_MONK: 1 + } + SL_BARDDANCER: 5 + SL_ROGUE: { + MaxLevel: 5 + SL_ASSASIN: 1 + } + SL_ASSASIN: 5 + SL_BLACKSMITH: { + MaxLevel: 5 + SL_ALCHEMIST: 1 + } + SL_HUNTER: { + MaxLevel: 5 + SL_BARDDANCER: 1 + } + SL_SOULLINKER: { + MaxLevel: 5 + SL_STAR: 1 + } + SL_KAIZEL: { + MaxLevel: 7 + SL_PRIEST: 1 + } + SL_KAAHI: { + MaxLevel: 7 + SL_PRIEST: 1 + SL_CRUSADER: 1 + } + SL_KAUPE: { + MaxLevel: 3 + SL_ROGUE: 1 + } + SL_KAITE: { + MaxLevel: 7 + SL_WIZARD: 1 + } + SL_KAINA: { + MaxLevel: 7 + TK_SPTIME: 1 + } + SL_STIN: { + MaxLevel: 7 + SL_WIZARD: 1 + } + SL_STUN: { + MaxLevel: 7 + SL_WIZARD: 1 + } + SL_SMA: { + MaxLevel: 10 + SL_STIN: 7 + SL_STUN: 7 + } + SL_SWOO: { + MaxLevel: 7 + SL_PRIEST: 1 + } + SL_SKE: { + MaxLevel: 3 + SL_KNIGHT: 1 + } + SL_SKA: { + MaxLevel: 3 + SL_MONK: 1 + } + SL_HIGH: { + MaxLevel: 5 + SL_SUPERNOVICE: 5 + } + } +} +Gangsi: { + inherit: ( "Novice" ); +} +Death_Knight: { + inherit: ( "Novice" ); +} +Dark_Collector: { + inherit: ( "Novice" ); +} +Rune_Knight: { + inherit: ( "Knight" ); + + skills: { + RK_ENCHANTBLADE: { + MaxLevel: 5 + RK_RUNEMASTERY: 2 + } + RK_SONICWAVE: { + MaxLevel: 5 + RK_ENCHANTBLADE: 3 + } + RK_DEATHBOUND: { + MaxLevel: 10 + KN_AUTOCOUNTER: 1 + RK_ENCHANTBLADE: 2 + } + RK_HUNDREDSPEAR: { + MaxLevel: 10 + RK_PHANTOMTHRUST: 3 + } + RK_WINDCUTTER: { + MaxLevel: 5 + RK_ENCHANTBLADE: 5 + } + RK_IGNITIONBREAK: { + MaxLevel: 5 + RK_SONICWAVE: 2 + RK_DEATHBOUND: 5 + RK_WINDCUTTER: 3 + } + RK_DRAGONTRAINING: { + MaxLevel: 5 + KN_CAVALIERMASTERY: 1 + } + RK_DRAGONBREATH: { + MaxLevel: 10 + RK_DRAGONTRAINING: 2 + } + RK_DRAGONHOWLING: { + MaxLevel: 5 + RK_DRAGONTRAINING: 2 + } + RK_RUNEMASTERY: 10 + RK_PHANTOMTHRUST: { + MaxLevel: 5 + KN_BRANDISHSPEAR: 2 + } + RK_DRAGONBREATH_WATER: { + MaxLevel: 10 + RK_DRAGONTRAINING: 2 + } + ALL_FULL_THROTTLE: 5 + } +} +Warlock: { + inherit: ( "Wizard" ); + + skills: { + WL_WHITEIMPRISON: { + MaxLevel: 5 + WL_SOULEXPANSION: 3 + } + WL_SOULEXPANSION: { + MaxLevel: 5 + WL_DRAINLIFE: 1 + } + WL_FROSTMISTY: { + MaxLevel: 5 + WL_SUMMONWB: 1 + } + WL_JACKFROST: { + MaxLevel: 5 + WL_FROSTMISTY: 2 + } + WL_MARSHOFABYSS: { + MaxLevel: 5 + WZ_QUAGMIRE: 1 + } + WL_RECOGNIZEDSPELL: { + MaxLevel: 5 + WL_WHITEIMPRISON: 1 + WL_STASIS: 1 + WL_RELEASE: 2 + } + WL_SIENNAEXECRATE: { + MaxLevel: 5 + WL_SUMMONSTONE: 1 + } + WL_RADIUS: 3 + WL_STASIS: { + MaxLevel: 5 + WL_DRAINLIFE: 1 + } + WL_DRAINLIFE: { + MaxLevel: 5 + WL_RADIUS: 1 + } + WL_CRIMSONROCK: { + MaxLevel: 5 + WL_SUMMONFB: 1 + } + WL_HELLINFERNO: { + MaxLevel: 5 + WL_CRIMSONROCK: 2 + } + WL_COMET: { + MaxLevel: 5 + WL_HELLINFERNO: 3 + } + WL_CHAINLIGHTNING: { + MaxLevel: 5 + WL_SUMMONBL: 1 + } + WL_EARTHSTRAIN: { + MaxLevel: 5 + WL_SIENNAEXECRATE: 2 + } + WL_TETRAVORTEX: { + MaxLevel: 5 + WL_JACKFROST: 5 + WL_HELLINFERNO: 5 + WL_CHAINLIGHTNING: 5 + WL_EARTHSTRAIN: 5 + } + WL_SUMMONFB: { + MaxLevel: 5 + WZ_METEOR: 1 + } + WL_SUMMONBL: { + MaxLevel: 5 + WZ_VERMILION: 1 + } + WL_SUMMONWB: { + MaxLevel: 5 + WZ_STORMGUST: 1 + } + WL_SUMMONSTONE: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 1 + } + WL_RELEASE: 2 + WL_READING_SB: 1 + WL_FREEZE_SP: 5 + WL_TELEKINESIS_INTENSE: { + MaxLevel: 5 + WL_SOULEXPANSION: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Ranger: { + inherit: ( "Hunter" ); + + skills: { + RA_ARROWSTORM: { + MaxLevel: 10 + RA_AIMEDBOLT: 5 + } + RA_FEARBREEZE: { + MaxLevel: 5 + RA_ARROWSTORM: 5 + RA_CAMOUFLAGE: 1 + } + RA_RANGERMAIN: 10 + RA_AIMEDBOLT: { + MaxLevel: 10 + HT_ANKLESNARE: 5 + } + RA_DETONATOR: { + MaxLevel: 1 + RA_CLUSTERBOMB: 3 + } + RA_ELECTRICSHOCKER: { + MaxLevel: 5 + HT_SHOCKWAVE: 5 + } + RA_CLUSTERBOMB: { + MaxLevel: 5 + RA_RESEARCHTRAP: 3 + } + RA_WUGMASTERY: 1 + RA_WUGRIDER: { + MaxLevel: 3 + RA_WUGMASTERY: 1 + } + RA_WUGDASH: { + MaxLevel: 1 + RA_WUGRIDER: 1 + } + RA_WUGSTRIKE: { + MaxLevel: 5 + RA_TOOTHOFWUG: 1 + } + RA_WUGBITE: { + MaxLevel: 5 + RA_WUGMASTERY: 1 + } + RA_TOOTHOFWUG: { + MaxLevel: 10 + RA_WUGMASTERY: 1 + } + RA_SENSITIVEKEEN: { + MaxLevel: 5 + RA_TOOTHOFWUG: 3 + } + RA_CAMOUFLAGE: { + MaxLevel: 5 + RA_RANGERMAIN: 1 + } + RA_RESEARCHTRAP: { + MaxLevel: 5 + HT_CLAYMORETRAP: 1 + HT_REMOVETRAP: 1 + } + RA_MAGENTATRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_COBALTTRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_MAIZETRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_VERDURETRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_FIRINGTRAP: { + MaxLevel: 5 + RA_DETONATOR: 1 + } + RA_ICEBOUNDTRAP: { + MaxLevel: 5 + RA_DETONATOR: 1 + } + RA_UNLIMIT: { + MaxLevel: 5 + RA_FEARBREEZE: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Arch_Bishop: { + inherit: ( "Priest" ); + + skills: { + AB_JUDEX: { + MaxLevel: 5 + PR_TURNUNDEAD: 1 + } + AB_ANCILLA: { + MaxLevel: 1 + AB_CLEMENTIA: 3 + } + AB_ADORAMUS: { + MaxLevel: 10 + PR_MAGNUS: 1 + AB_JUDEX: 1 + AB_ANCILLA: 1 + } + AB_CLEMENTIA: { + MaxLevel: 3 + AL_BLESSING: 1 + } + AB_CANTO: { + MaxLevel: 3 + AL_INCAGI: 1 + } + AB_CHEAL: { + MaxLevel: 3 + AL_HEAL: 1 + } + AB_EPICLESIS: { + MaxLevel: 5 + AB_ANCILLA: 1 + AB_HIGHNESSHEAL: 1 + } + AB_PRAEFATIO: { + MaxLevel: 10 + PR_KYRIE: 1 + } + AB_ORATIO: { + MaxLevel: 10 + AB_PRAEFATIO: 5 + } + AB_LAUDAAGNUS: { + MaxLevel: 4 + PR_STRECOVERY: 1 + } + AB_LAUDARAMUS: { + MaxLevel: 4 + AB_LAUDAAGNUS: 2 + } + AB_EUCHARISTICA: { + MaxLevel: 10 + AB_EPICLESIS: 1 + AB_EXPIATIO: 1 + } + AB_RENOVATIO: { + MaxLevel: 1 + AB_CHEAL: 3 + } + AB_HIGHNESSHEAL: { + MaxLevel: 5 + AB_RENOVATIO: 1 + } + AB_CLEARANCE: { + MaxLevel: 5 + AB_LAUDARAMUS: 2 + } + AB_EXPIATIO: { + MaxLevel: 5 + AB_ORATIO: 5 + AB_DUPLELIGHT: 5 + } + AB_DUPLELIGHT: { + MaxLevel: 10 + PR_ASPERSIO: 1 + } + AB_SILENTIUM: { + MaxLevel: 5 + AB_CLEARANCE: 1 + } + AB_SECRAMENT: { + MaxLevel: 5 + AB_EPICLESIS: 1 + AB_EXPIATIO: 1 + } + AB_OFFERTORIUM: { + MaxLevel: 5 + AB_HIGHNESSHEAL: 2 + } + ALL_FULL_THROTTLE: 5 + } +} +Mechanic: { + inherit: ( "Blacksmith" ); + + skills: { + NC_MADOLICENCE: 5 + NC_BOOSTKNUCKLE: { + MaxLevel: 5 + NC_MADOLICENCE: 1 + } + NC_PILEBUNKER: { + MaxLevel: 3 + NC_BOOSTKNUCKLE: 2 + } + NC_VULCANARM: { + MaxLevel: 3 + NC_BOOSTKNUCKLE: 2 + } + NC_FLAMELAUNCHER: { + MaxLevel: 3 + NC_VULCANARM: 3 + } + NC_COLDSLOWER: { + MaxLevel: 3 + NC_VULCANARM: 3 + } + NC_ARMSCANNON: { + MaxLevel: 3 + NC_FLAMELAUNCHER: 2 + NC_COLDSLOWER: 2 + } + NC_ACCELERATION: { + MaxLevel: 3 + NC_MADOLICENCE: 1 + } + NC_HOVERING: { + MaxLevel: 1 + NC_ACCELERATION: 1 + } + NC_F_SIDESLIDE: { + MaxLevel: 1 + NC_HOVERING: 1 + } + NC_B_SIDESLIDE: { + MaxLevel: 1 + NC_HOVERING: 1 + } + NC_MAINFRAME: { + MaxLevel: 4 + NC_MADOLICENCE: 4 + } + NC_SELFDESTRUCTION: { + MaxLevel: 3 + NC_MAINFRAME: 2 + } + NC_SHAPESHIFT: { + MaxLevel: 4 + NC_MAINFRAME: 2 + } + NC_EMERGENCYCOOL: { + MaxLevel: 1 + NC_SELFDESTRUCTION: 2 + } + NC_INFRAREDSCAN: { + MaxLevel: 1 + NC_SHAPESHIFT: 2 + } + NC_ANALYZE: { + MaxLevel: 3 + NC_INFRAREDSCAN: 1 + } + NC_MAGNETICFIELD: { + MaxLevel: 3 + NC_EMERGENCYCOOL: 1 + } + NC_NEUTRALBARRIER: { + MaxLevel: 3 + NC_MAGNETICFIELD: 2 + } + NC_STEALTHFIELD: { + MaxLevel: 3 + NC_ANALYZE: 3 + NC_NEUTRALBARRIER: 2 + } + NC_REPAIR: { + MaxLevel: 5 + NC_MADOLICENCE: 1 + } + NC_TRAININGAXE: 10 + NC_RESEARCHFE: 5 + NC_AXEBOOMERANG: { + MaxLevel: 5 + NC_TRAININGAXE: 1 + } + NC_POWERSWING: { + MaxLevel: 5 + NC_AXEBOOMERANG: 3 + } + NC_AXETORNADO: { + MaxLevel: 5 + NC_TRAININGAXE: 1 + } + NC_SILVERSNIPER: { + MaxLevel: 5 + NC_RESEARCHFE: 2 + } + NC_MAGICDECOY: { + MaxLevel: 5 + NC_RESEARCHFE: 2 + } + NC_DISJOINT: { + MaxLevel: 1 + NC_SILVERSNIPER: 1 + } + NC_MAGMA_ERUPTION: 5 + ALL_FULL_THROTTLE: 5 + } +} +Guillotine_Cross: { + inherit: ( "Assassin" ); + + skills: { + GC_VENOMIMPRESS: { + MaxLevel: 5 + AS_ENCHANTPOISON: 3 + } + GC_CROSSIMPACT: { + MaxLevel: 5 + AS_SONICBLOW: 10 + } + GC_DARKILLUSION: { + MaxLevel: 5 + GC_CROSSIMPACT: 3 + } + GC_RESEARCHNEWPOISON: 10 + GC_CREATENEWPOISON: { + MaxLevel: 1 + GC_RESEARCHNEWPOISON: 1 + } + GC_ANTIDOTE: { + MaxLevel: 1 + GC_RESEARCHNEWPOISON: 5 + } + GC_POISONINGWEAPON: { + MaxLevel: 5 + GC_CREATENEWPOISON: 1 + } + GC_WEAPONBLOCKING: { + MaxLevel: 5 + AS_LEFT: 5 + } + GC_COUNTERSLASH: { + MaxLevel: 5 + GC_WEAPONBLOCKING: 1 + } + GC_WEAPONCRUSH: { + MaxLevel: 5 + GC_WEAPONBLOCKING: 1 + } + GC_VENOMPRESSURE: { + MaxLevel: 5 + GC_POISONINGWEAPON: 3 + GC_WEAPONBLOCKING: 1 + } + GC_POISONSMOKE: { + MaxLevel: 5 + GC_POISONINGWEAPON: 5 + GC_VENOMPRESSURE: 5 + } + GC_CLOAKINGEXCEED: { + MaxLevel: 5 + AS_CLOAKING: 3 + } + GC_PHANTOMMENACE: { + MaxLevel: 1 + GC_DARKILLUSION: 5 + GC_CLOAKINGEXCEED: 5 + } + GC_HALLUCINATIONWALK: { + MaxLevel: 5 + GC_PHANTOMMENACE: 1 + } + GC_ROLLINGCUTTER: { + MaxLevel: 5 + AS_SONICBLOW: 10 + } + GC_CROSSRIPPERSLASHER: { + MaxLevel: 5 + GC_ROLLINGCUTTER: 1 + } + GC_DARKCROW: { + MaxLevel: 5 + GC_DARKILLUSION: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Rune_Knight_Trans: { + inherit: ( "Lord_Knight", "Rune_Knight" ); +} +Warlock_Trans: { + inherit: ( "High_Wizard", "Warlock" ); +} +Ranger_Trans: { + inherit: ( "Sniper", "Ranger" ); +} +Arch_Bishop_Trans: { + inherit: ( "High_Priest", "Arch_Bishop" ); +} +Mechanic_Trans: { + inherit: ( "Whitesmith", "Mechanic" ); +} +Guillotine_Cross_Trans: { + inherit: ( "Assassin_Cross", "Guillotine_Cross" ); +} +Royal_Guard: { + inherit: ( "Crusader" ); + + skills: { + LG_CANNONSPEAR: { + MaxLevel: 5 + LG_PINPOINTATTACK: 1 + } + LG_BANISHINGPOINT: { + MaxLevel: 10 + KN_SPEARMASTERY: 1 + } + LG_TRAMPLE: 3 + LG_SHIELDPRESS: { + MaxLevel: 5 + CR_SHIELDCHARGE: 3 + } + LG_REFLECTDAMAGE: { + MaxLevel: 5 + CR_REFLECTSHIELD: 5 + } + LG_PINPOINTATTACK: { + MaxLevel: 5 + LG_BANISHINGPOINT: 5 + } + LG_FORCEOFVANGUARD: 5 + LG_RAGEBURST: { + MaxLevel: 1 + LG_FORCEOFVANGUARD: 1 + } + LG_SHIELDSPELL: { + MaxLevel: 3 + LG_SHIELDPRESS: 3 + LG_EARTHDRIVE: 2 + } + LG_EXEEDBREAK: { + MaxLevel: 5 + LG_BANISHINGPOINT: 3 + } + LG_OVERBRAND: { + MaxLevel: 5 + LG_PINPOINTATTACK: 1 + LG_MOONSLASHER: 3 + } + LG_PRESTIGE: { + MaxLevel: 5 + LG_TRAMPLE: 3 + } + LG_BANDING: { + MaxLevel: 5 + LG_PINPOINTATTACK: 3 + LG_RAGEBURST: 1 + } + LG_MOONSLASHER: { + MaxLevel: 5 + KN_SPEARMASTERY: 1 + } + LG_RAYOFGENESIS: { + MaxLevel: 5 + CR_GRANDCROSS: 5 + } + LG_PIETY: { + MaxLevel: 5 + CR_TRUST: 3 + } + LG_EARTHDRIVE: { + MaxLevel: 5 + LG_REFLECTDAMAGE: 3 + } + LG_HESPERUSLIT: { + MaxLevel: 5 + LG_PRESTIGE: 3 + LG_BANDING: 3 + } + LG_INSPIRATION: { + MaxLevel: 5 + LG_SHIELDSPELL: 3 + LG_RAYOFGENESIS: 4 + LG_PIETY: 5 + } + LG_KINGS_GRACE: { + MaxLevel: 5 + LG_REFLECTDAMAGE: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Sorcerer: { + inherit: ( "Sage" ); + + skills: { + SO_FIREWALK: { + MaxLevel: 5 + SA_VOLCANO: 1 + } + SO_ELECTRICWALK: { + MaxLevel: 5 + SA_VIOLENTGALE: 1 + } + SO_SPELLFIST: { + MaxLevel: 5 + SA_AUTOSPELL: 4 + } + SO_EARTHGRAVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 5 + } + SO_DIAMONDDUST: { + MaxLevel: 5 + SA_DELUGE: 3 + } + SO_POISON_BUSTER: { + MaxLevel: 5 + SO_CLOUD_KILL: 2 + } + SO_PSYCHIC_WAVE: { + MaxLevel: 5 + SA_DISPELL: 2 + } + SO_CLOUD_KILL: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 5 + } + SO_STRIKING: { + MaxLevel: 5 + SA_FLAMELAUNCHER: 1 + SA_FROSTWEAPON: 1 + SA_LIGHTNINGLOADER: 1 + SA_SEISMICWEAPON: 1 + } + SO_WARMER: { + MaxLevel: 5 + SA_VOLCANO: 1 + SA_VIOLENTGALE: 1 + } + SO_VACUUM_EXTREME: { + MaxLevel: 5 + SA_LANDPROTECTOR: 2 + } + SO_VARETYR_SPEAR: { + MaxLevel: 5 + SA_SEISMICWEAPON: 1 + SA_VIOLENTGALE: 4 + } + SO_ARRULLO: { + MaxLevel: 5 + SO_WARMER: 2 + } + SO_EL_CONTROL: { + MaxLevel: 4 + SO_EL_ANALYSIS: 1 + } + SO_SUMMON_AGNI: { + MaxLevel: 3 + SO_WARMER: 3 + SO_EL_CONTROL: 1 + } + SO_SUMMON_AQUA: { + MaxLevel: 3 + SO_DIAMONDDUST: 3 + SO_EL_CONTROL: 1 + } + SO_SUMMON_VENTUS: { + MaxLevel: 3 + SO_VARETYR_SPEAR: 3 + SO_EL_CONTROL: 1 + } + SO_SUMMON_TERA: { + MaxLevel: 3 + SO_EARTHGRAVE: 3 + SO_EL_CONTROL: 1 + } + SO_EL_ACTION: { + MaxLevel: 1 + SO_EL_CONTROL: 3 + } + SO_EL_ANALYSIS: { + MaxLevel: 2 + SA_FLAMELAUNCHER: 1 + SA_FROSTWEAPON: 1 + SA_LIGHTNINGLOADER: 1 + SA_SEISMICWEAPON: 1 + } + SO_EL_SYMPATHY: { + MaxLevel: 5 + SO_EL_CONTROL: 3 + } + SO_EL_CURE: { + MaxLevel: 1 + SO_EL_SYMPATHY: 1 + } + SO_FIRE_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_AGNI: 3 + } + SO_WATER_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_AQUA: 3 + } + SO_WIND_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_VENTUS: 3 + } + SO_EARTH_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_TERA: 3 + } + ALL_FULL_THROTTLE: 5 + } +} +Minstrel: { + inherit: ( "Bard" ); + + skills: { + MI_RUSH_WINDMILL: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + MI_ECHOSONG: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + MI_HARMONIZE: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WM_LESSON: 10 + WM_METALICSOUND: { + MaxLevel: 5 + WM_DOMINION_IMPULSE: 1 + } + WM_REVERBERATION: { + MaxLevel: 5 + BA_DISSONANCE: 5 + } + WM_DOMINION_IMPULSE: { + MaxLevel: 1 + WM_REVERBERATION: 1 + } + WM_SEVERE_RAINSTORM: { + MaxLevel: 5 + BA_MUSICALSTRIKE: 5 + } + WM_POEMOFNETHERWORLD: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_VOICEOFSIREN: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 3 + } + WM_DEADHILLHERE: { + MaxLevel: 5 + WM_SIRCLEOFNATURE: 3 + } + WM_LULLABY_DEEPSLEEP: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_SIRCLEOFNATURE: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_RANDOMIZESPELL: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 1 + } + WM_GLOOMYDAY: { + MaxLevel: 5 + WM_RANDOMIZESPELL: 1 + } + WM_GREAT_ECHO: { + MaxLevel: 5 + WM_METALICSOUND: 1 + } + WM_SONG_OF_MANA: { + MaxLevel: 5 + MI_RUSH_WINDMILL: 1 + MI_ECHOSONG: 1 + MI_HARMONIZE: 1 + } + WM_DANCE_WITH_WUG: { + MaxLevel: 5 + MI_RUSH_WINDMILL: 1 + MI_ECHOSONG: 1 + MI_HARMONIZE: 1 + } + WM_SOUND_OF_DESTRUCTION: { + MaxLevel: 5 + WM_SATURDAY_NIGHT_FEVER: 3 + WM_MELODYOFSINK: 3 + } + WM_SATURDAY_NIGHT_FEVER: { + MaxLevel: 5 + WM_DANCE_WITH_WUG: 1 + } + WM_LERADS_DEW: { + MaxLevel: 5 + MI_RUSH_WINDMILL: 1 + MI_ECHOSONG: 1 + MI_HARMONIZE: 1 + } + WM_MELODYOFSINK: { + MaxLevel: 5 + WM_SONG_OF_MANA: 1 + } + WM_BEYOND_OF_WARCRY: { + MaxLevel: 5 + WM_LERADS_DEW: 1 + } + WM_UNLIMITED_HUMMING_VOICE: { + MaxLevel: 5 + WM_SOUND_OF_DESTRUCTION: 1 + WM_BEYOND_OF_WARCRY: 1 + } + WM_FRIGG_SONG: { + MaxLevel: 5 + WM_LESSON: 1 + } + ALL_FULL_THROTTLE: 5 + } +} +Wanderer: { + inherit: ( "Dancer" ); + + skills: { + WA_SWING_DANCE: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WA_SYMPHONY_OF_LOVER: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WA_MOONLIT_SERENADE: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WM_LESSON: 10 + WM_METALICSOUND: { + MaxLevel: 5 + WM_DOMINION_IMPULSE: 1 + } + WM_REVERBERATION: { + MaxLevel: 5 + DC_UGLYDANCE: 5 + } + WM_DOMINION_IMPULSE: { + MaxLevel: 1 + WM_REVERBERATION: 1 + } + WM_SEVERE_RAINSTORM: { + MaxLevel: 5 + DC_THROWARROW: 5 + } + WM_POEMOFNETHERWORLD: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_VOICEOFSIREN: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 3 + } + WM_DEADHILLHERE: { + MaxLevel: 5 + WM_SIRCLEOFNATURE: 3 + } + WM_LULLABY_DEEPSLEEP: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_SIRCLEOFNATURE: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_RANDOMIZESPELL: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 1 + } + WM_GLOOMYDAY: { + MaxLevel: 5 + WM_RANDOMIZESPELL: 1 + } + WM_GREAT_ECHO: { + MaxLevel: 5 + WM_METALICSOUND: 1 + } + WM_SONG_OF_MANA: { + MaxLevel: 5 + WA_SWING_DANCE: 1 + WA_SYMPHONY_OF_LOVER: 1 + WA_MOONLIT_SERENADE: 1 + } + WM_DANCE_WITH_WUG: { + MaxLevel: 5 + WA_SWING_DANCE: 1 + WA_SYMPHONY_OF_LOVER: 1 + WA_MOONLIT_SERENADE: 1 + } + WM_SOUND_OF_DESTRUCTION: { + MaxLevel: 5 + WM_SATURDAY_NIGHT_FEVER: 3 + WM_MELODYOFSINK: 3 + } + WM_SATURDAY_NIGHT_FEVER: { + MaxLevel: 5 + WM_DANCE_WITH_WUG: 1 + } + WM_LERADS_DEW: { + MaxLevel: 5 + WA_SWING_DANCE: 1 + WA_SYMPHONY_OF_LOVER: 1 + WA_MOONLIT_SERENADE: 1 + } + WM_MELODYOFSINK: { + MaxLevel: 5 + WM_SONG_OF_MANA: 1 + } + WM_BEYOND_OF_WARCRY: { + MaxLevel: 5 + WM_LERADS_DEW: 1 + } + WM_UNLIMITED_HUMMING_VOICE: { + MaxLevel: 5 + WM_SOUND_OF_DESTRUCTION: 1 + WM_BEYOND_OF_WARCRY: 1 + } + WM_FRIGG_SONG: { + MaxLevel: 5 + WM_LESSON: 1 + } + ALL_FULL_THROTTLE: 5 + } +} +Sura: { + inherit: ( "Monk" ); + + skills: { + SR_DRAGONCOMBO: { + MaxLevel: 10 + MO_TRIPLEATTACK: 5 + } + SR_SKYNETBLOW: { + MaxLevel: 5 + SR_DRAGONCOMBO: 3 + } + SR_EARTHSHAKER: { + MaxLevel: 5 + SR_DRAGONCOMBO: 1 + SR_CURSEDCIRCLE: 1 + } + SR_FALLENEMPIRE: { + MaxLevel: 5 + SR_DRAGONCOMBO: 1 + } + SR_TIGERCANNON: { + MaxLevel: 10 + SR_FALLENEMPIRE: 3 + } + SR_RAMPAGEBLASTER: { + MaxLevel: 5 + SR_EARTHSHAKER: 2 + } + SR_CRESCENTELBOW: { + MaxLevel: 5 + SR_SKYNETBLOW: 1 + } + SR_CURSEDCIRCLE: { + MaxLevel: 5 + MO_BLADESTOP: 2 + SR_GENTLETOUCH_QUIET: 2 + } + SR_LIGHTNINGWALK: { + MaxLevel: 5 + SR_WINDMILL: 1 + } + SR_KNUCKLEARROW: { + MaxLevel: 5 + SR_RAMPAGEBLASTER: 3 + SR_LIGHTNINGWALK: 3 + } + SR_WINDMILL: { + MaxLevel: 1 + SR_CURSEDCIRCLE: 1 + } + SR_RAISINGDRAGON: { + MaxLevel: 10 + SR_RAMPAGEBLASTER: 3 + SR_GENTLETOUCH_ENERGYGAIN: 3 + } + SR_ASSIMILATEPOWER: { + MaxLevel: 1 + MO_ABSORBSPIRITS: 1 + SR_POWERVELOCITY: 1 + } + SR_POWERVELOCITY: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + } + SR_GATEOFHELL: { + MaxLevel: 10 + SR_TIGERCANNON: 5 + SR_RAISINGDRAGON: 5 + } + SR_GENTLETOUCH_QUIET: { + MaxLevel: 5 + SR_POWERVELOCITY: 1 + } + SR_GENTLETOUCH_CURE: { + MaxLevel: 5 + SR_POWERVELOCITY: 1 + } + SR_GENTLETOUCH_ENERGYGAIN: { + MaxLevel: 5 + SR_GENTLETOUCH_QUIET: 3 + } + SR_GENTLETOUCH_CHANGE: { + MaxLevel: 5 + SR_GENTLETOUCH_CURE: 4 + } + SR_GENTLETOUCH_REVITALIZE: { + MaxLevel: 5 + SR_GENTLETOUCH_CHANGE: 5 + } + SR_HOWLINGOFLION: { + MaxLevel: 5 + SR_ASSIMILATEPOWER: 1 + SR_RIDEINLIGHTNING: 3 + } + SR_RIDEINLIGHTNING: { + MaxLevel: 5 + MO_FINGEROFFENSIVE: 3 + } + SR_FLASHCOMBO: { + MaxLevel: 5 + SR_DRAGONCOMBO: 3 + SR_FALLENEMPIRE: 3 + SR_TIGERCANNON: 1 + SR_SKYNETBLOW: 1 + } + ALL_FULL_THROTTLE: 5 + } +} +Genetic: { + inherit: ( "Alchemist" ); + + skills: { + GN_TRAINING_SWORD: 5 + GN_REMODELING_CART: 5 + GN_CART_TORNADO: { + MaxLevel: 5 + GN_REMODELING_CART: 1 + } + GN_CARTCANNON: { + MaxLevel: 5 + GN_REMODELING_CART: 2 + } + GN_CARTBOOST: { + MaxLevel: 5 + GN_REMODELING_CART: 3 + } + GN_THORNS_TRAP: { + MaxLevel: 5 + GN_S_PHARMACY: 2 + } + GN_BLOOD_SUCKER: { + MaxLevel: 5 + GN_S_PHARMACY: 3 + } + GN_SPORE_EXPLOSION: { + MaxLevel: 5 + GN_S_PHARMACY: 4 + } + GN_WALLOFTHORN: { + MaxLevel: 5 + GN_THORNS_TRAP: 3 + } + GN_CRAZYWEED: { + MaxLevel: 10 + GN_WALLOFTHORN: 3 + } + GN_DEMONIC_FIRE: { + MaxLevel: 5 + GN_SPORE_EXPLOSION: 3 + } + GN_FIRE_EXPANSION: { + MaxLevel: 5 + GN_DEMONIC_FIRE: 3 + } + GN_HELLS_PLANT: { + MaxLevel: 5 + GN_BLOOD_SUCKER: 3 + } + GN_MANDRAGORA: { + MaxLevel: 5 + GN_HELLS_PLANT: 3 + } + GN_SLINGITEM: { + MaxLevel: 1 + GN_CHANGEMATERIAL: 1 + } + GN_CHANGEMATERIAL: 1 + GN_MIX_COOKING: { + MaxLevel: 2 + GN_S_PHARMACY: 1 + } + GN_MAKEBOMB: { + MaxLevel: 2 + GN_MIX_COOKING: 1 + } + GN_S_PHARMACY: 10 +// GN_ILLUSIONDOOPING: { +// MaxLevel: 5 +// GN_S_PHARMACY: 1 +// } + ALL_FULL_THROTTLE: 5 + } +} +Shadow_Chaser: { + inherit: ( "Rogue" ); + + skills: { + SC_FATALMENACE: { + MaxLevel: 5 + RG_INTIMIDATE: 5 + } + SC_REPRODUCE: { + MaxLevel: 10 + RG_PLAGIARISM: 5 + } + SC_AUTOSHADOWSPELL: { + MaxLevel: 10 + SC_REPRODUCE: 5 + } + SC_SHADOWFORM: { + MaxLevel: 5 + RG_TUNNELDRIVE: 3 + } + SC_TRIANGLESHOT: { + MaxLevel: 10 + AC_DOUBLE: 7 + } + SC_BODYPAINT: 5 + SC_INVISIBILITY: { + MaxLevel: 5 + SC_AUTOSHADOWSPELL: 7 + SC_DEADLYINFECT: 5 + SC_UNLUCKY: 3 + } + SC_DEADLYINFECT: { + MaxLevel: 5 + SC_AUTOSHADOWSPELL: 5 + SC_SHADOWFORM: 3 + } + SC_ENERVATION: { + MaxLevel: 3 + SC_BODYPAINT: 1 + } + SC_GROOMY: { + MaxLevel: 3 + SC_BODYPAINT: 1 + } + SC_IGNORANCE: { + MaxLevel: 3 + SC_BODYPAINT: 1 + } + SC_LAZINESS: { + MaxLevel: 3 + SC_ENERVATION: 1 + SC_GROOMY: 1 + SC_IGNORANCE: 1 + } + SC_UNLUCKY: { + MaxLevel: 3 + SC_LAZINESS: 1 + SC_WEAKNESS: 1 + } + SC_WEAKNESS: { + MaxLevel: 3 + SC_ENERVATION: 1 + SC_GROOMY: 1 + SC_IGNORANCE: 1 + } + SC_STRIPACCESSARY: { + MaxLevel: 5 + RG_STRIPWEAPON: 1 + } + SC_MANHOLE: { + MaxLevel: 3 + RG_FLAGGRAFFITI: 1 + } + SC_DIMENSIONDOOR: { + MaxLevel: 3 + SC_MANHOLE: 1 + } + SC_CHAOSPANIC: { + MaxLevel: 3 + SC_MANHOLE: 1 + } + SC_MAELSTROM: { + MaxLevel: 3 + SC_UNLUCKY: 3 + SC_CHAOSPANIC: 3 + } + SC_BLOODYLUST: { + MaxLevel: 3 + SC_DIMENSIONDOOR: 3 + } + SC_FEINTBOMB: { + MaxLevel: 3 + SC_DIMENSIONDOOR: 3 + } +// SC_SCAPE: { +// MaxLevel: 5 +// SC_TRIANGLESHOT: 2 +// } + ALL_FULL_THROTTLE: 5 + } +} +Royal_Guard_Trans: { + inherit: ( "Paladin", "Royal_Guard" ); +} +Sorcerer_Trans: { + inherit: ( "Professor", "Sorcerer" ); +} +Minstrel_Trans: { + inherit: ( "Clown", "Minstrel" ); +} +Wanderer_Trans: { + inherit: ( "Gypsy", "Wanderer" ); +} +Sura_Trans: { + inherit: ( "Champion", "Sura" ); +} +Genetic_Trans: { + inherit: ( "Creator", "Genetic" ); +} +Shadow_Chaser_Trans: { + inherit: ( "Stalker", "Shadow_Chaser" ); +} +Baby_Rune_Knight: { + inherit: ( "Rune_Knight" ); +} +Baby_Warlock: { + inherit: ( "Warlock" ); +} +Baby_Ranger: { + inherit: ( "Ranger" ); +} +Baby_Arch_Bishop: { + inherit: ( "Arch_Bishop" ); +} +Baby_Mechanic: { + inherit: ( "Mechanic" ); +} +Baby_Guillotine_Cross: { + inherit: ( "Guillotine_Cross" ); +} +Baby_Royal_Guard: { + inherit: ( "Royal_Guard" ); +} +Baby_Sorcerer: { + inherit: ( "Sorcerer" ); +} +Baby_Minstrel: { + inherit: ( "Minstrel" ); +} +Baby_Wanderer: { + inherit: ( "Wanderer" ); +} +Baby_Sura: { + inherit: ( "Sura" ); +} +Baby_Genetic: { + inherit: ( "Genetic" ); +} +Baby_Shadow_Chaser: { + inherit: ( "Shadow_Chaser" ); +} +Expanded_Super_Novice: { + inherit: ( "Super_Novice" ); + + skills: { + PR_IMPOSITIO: 5 + PR_SANCTUARY: { + MaxLevel: 10 + AL_HEAL: 1 + } + PR_STRECOVERY: 1 + PR_GLORIA: { + MaxLevel: 5 + PR_SANCTUARY: 7 + } + WZ_FIREPILLAR: { + MaxLevel: 10 + MG_FIREWALL: 1 + } + WZ_SIGHTRASHER: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 1 + MG_SIGHT: 1 + } + WZ_JUPITEL: { + MaxLevel: 10 + MG_NAPALMBEAT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_WATERBALL: { + MaxLevel: 5 + MG_COLDBOLT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_ICEWALL: { + MaxLevel: 10 + MG_STONECURSE: 1 + MG_FROSTDIVER: 1 + } + WZ_FROSTNOVA: { + MaxLevel: 10 + WZ_ICEWALL: 1 + } + WZ_EARTHSPIKE: { + MaxLevel: 5 + MG_STONECURSE: 1 + } + WZ_HEAVENDRIVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 3 + } + WZ_QUAGMIRE: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 1 + } + WZ_ESTIMATION: 1 + BS_HILTBINDING: 1 + BS_WEAPONRESEARCH: { + MaxLevel: 10 + BS_HILTBINDING: 1 + } + HT_SKIDTRAP: 5 + HT_SANDMAN: { + MaxLevel: 5 + HT_FLASHER: 1 + } + HT_FLASHER: { + MaxLevel: 5 + HT_SKIDTRAP: 1 + } + HT_FREEZINGTRAP: { + MaxLevel: 5 + HT_FLASHER: 1 + } + AS_ENCHANTPOISON: { + MaxLevel: 10 + TF_POISON: 1 + } + RG_TUNNELDRIVE: { + MaxLevel: 5 + TF_HIDING: 1 + } + AM_AXEMASTERY: 10 + CR_TRUST: 10 + CR_HOLYCROSS: { + MaxLevel: 10 + CR_TRUST: 7 + } + MO_IRONHAND: { + MaxLevel: 10 + AL_DEMONBANE: 10 + AL_DP: 10 + } + MO_CALLSPIRITS: { + MaxLevel: 5 + MO_IRONHAND: 2 + } + MO_ABSORBSPIRITS: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + } + HW_MAGICCRASHER: { + MaxLevel: 1 + MG_SRECOVERY: 1 + } + ALL_BUYING_STORE: { + MaxLevel: 1 + MC_VENDING: 1 + } + } +} +Expanded_Super_Baby: { + inherit: ( "Expanded_Super_Novice" ); +} +Kagerou: { + inherit: ( "Ninja" ); + + skills: { + KO_YAMIKUMO: { + MaxLevel: 1 + NJ_KIRIKAGE: 5 + } + KO_RIGHT: 5 + KO_LEFT: 5 + KO_JYUMONJIKIRI: { + MaxLevel: 5 + KO_YAMIKUMO: 1 + } + KO_SETSUDAN: { + MaxLevel: 5 + KO_JYUMONJIKIRI: 2 + } + KO_BAKURETSU: { + MaxLevel: 5 + NJ_KUNAI: 5 + } + KO_HAPPOKUNAI: { + MaxLevel: 5 + KO_BAKURETSU: 1 + } + KO_MUCHANAGE: { + MaxLevel: 10 + KO_MAKIBISHI: 3 + } + KO_HUUMARANKA: { + MaxLevel: 5 + NJ_HUUMA: 5 + } + KO_MAKIBISHI: { + MaxLevel: 5 + NJ_ZENYNAGE: 1 + } + KO_MEIKYOUSISUI: { + MaxLevel: 5 + NJ_NINPOU: 10 + } + KO_ZANZOU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_KYOUGAKU: { + MaxLevel: 5 + KO_GENWAKU: 2 + } + KO_JYUSATSU: { + MaxLevel: 5 + KO_KYOUGAKU: 3 + } + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + KO_KAIHOU: { + MaxLevel: 1 + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + } + KO_ZENKAI: { + MaxLevel: 1 + KO_KAIHOU: 1 + KO_IZAYOI: 1 + } + KO_GENWAKU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_IZAYOI: { + MaxLevel: 5 + NJ_NINPOU: 5 + } + KG_KAGEHUMI: { + MaxLevel: 5 + KO_ZANZOU: 1 + } + KG_KYOMU: { + MaxLevel: 5 + KG_KAGEHUMI: 2 + } + KG_KAGEMUSYA: { + MaxLevel: 5 + KG_KYOMU: 3 + } + } +} +Oboro: { + inherit: ( "Ninja" ); + + skills: { + KO_YAMIKUMO: { + MaxLevel: 1 + NJ_KIRIKAGE: 5 + } + KO_RIGHT: 5 + KO_LEFT: 5 + KO_JYUMONJIKIRI: { + MaxLevel: 5 + KO_YAMIKUMO: 1 + } + KO_SETSUDAN: { + MaxLevel: 5 + KO_JYUMONJIKIRI: 2 + } + KO_BAKURETSU: { + MaxLevel: 5 + NJ_KUNAI: 5 + } + KO_HAPPOKUNAI: { + MaxLevel: 5 + KO_BAKURETSU: 1 + } + KO_MUCHANAGE: { + MaxLevel: 10 + KO_MAKIBISHI: 3 + } + KO_HUUMARANKA: { + MaxLevel: 5 + NJ_HUUMA: 5 + } + KO_MAKIBISHI: { + MaxLevel: 5 + NJ_ZENYNAGE: 1 + } + KO_MEIKYOUSISUI: { + MaxLevel: 5 + NJ_NINPOU: 10 + } + KO_ZANZOU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_KYOUGAKU: { + MaxLevel: 5 + KO_GENWAKU: 2 + } + KO_JYUSATSU: { + MaxLevel: 5 + KO_KYOUGAKU: 3 + } + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + KO_KAIHOU: { + MaxLevel: 1 + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + } + KO_ZENKAI: { + MaxLevel: 1 + KO_KAIHOU: 1 + KO_IZAYOI: 1 + } + KO_GENWAKU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_IZAYOI: { + MaxLevel: 5 + NJ_NINPOU: 5 + } + OB_ZANGETSU: { + MaxLevel: 5 + KO_GENWAKU: 1 + } + OB_OBOROGENSOU: { + MaxLevel: 5 + OB_AKAITSUKI: 3 + } + OB_AKAITSUKI: { + MaxLevel: 5 + OB_ZANGETSU: 2 + } + } +}
\ No newline at end of file diff --git a/db/re/skill_tree.conf b/db/re/skill_tree.conf new file mode 100644 index 000000000..f61205cfa --- /dev/null +++ b/db/re/skill_tree.conf @@ -0,0 +1,3833 @@ +//==================================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//= +//= http://hercules.ws/board/ +//================= More Information ================= +// http://hercules.ws/board/topic/1188-skill-tree-db-redesign/ <desc~!> +//==================================================== +Novice: { + skills: { + NV_BASIC: 9 + NV_FIRSTAID: 1 + NV_TRICKDEAD: 1 + WE_CALLBABY: 1 + ALL_INCCARRY: 1 + } +} +Swordsman: { + inherit: ( "Novice" ); + + skills: { + SM_SWORD: 10 + SM_TWOHAND: { + MaxLevel: 10 + SM_SWORD: 1 + } + SM_RECOVERY: 10 + SM_BASH: 10 + SM_PROVOKE: 10 + SM_MAGNUM: { + MaxLevel: 10 + SM_BASH: 5 + } + SM_ENDURE: { + MaxLevel: 10 + SM_PROVOKE: 5 + } + SM_MOVINGRECOVERY: 1 + SM_FATALBLOW: 1 + SM_AUTOBERSERK: 1 + } +} +Magician: { + inherit: ( "Novice" ); + + skills: { + MG_SRECOVERY: 10 + MG_SIGHT: 1 + MG_NAPALMBEAT: 10 + MG_SAFETYWALL: { + MaxLevel: 10 + MG_NAPALMBEAT: 7 + MG_SOULSTRIKE: 5 + } + MG_SOULSTRIKE: { + MaxLevel: 10 + MG_NAPALMBEAT: 4 + } + MG_COLDBOLT: 10 + MG_FROSTDIVER: { + MaxLevel: 10 + MG_COLDBOLT: 5 + } + MG_STONECURSE: 10 + MG_FIREBALL: { + MaxLevel: 10 + MG_FIREBOLT: 4 + } + MG_FIREWALL: { + MaxLevel: 10 + MG_FIREBALL: 5 + MG_SIGHT: 1 + } + MG_FIREBOLT: 10 + MG_LIGHTNINGBOLT: 10 + MG_THUNDERSTORM: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 4 + } + MG_ENERGYCOAT: 1 + } +} +Archer: { + inherit: ( "Novice" ); + + skills: { + AC_OWL: 10 + AC_VULTURE: { + MaxLevel: 10 + AC_OWL: 3 + } + AC_CONCENTRATION: { + MaxLevel: 10 + AC_VULTURE: 1 + } + AC_DOUBLE: 10 + AC_SHOWER: { + MaxLevel: 10 + AC_DOUBLE: 5 + } + AC_MAKINGARROW: 1 + AC_CHARGEARROW: 1 + } +} +Acolyte: { + inherit: ( "Novice" ); + + skills: { + AL_DP: 10 + AL_DEMONBANE: { + MaxLevel: 10 + AL_DP: 3 + } + AL_RUWACH: 1 + AL_PNEUMA: { + MaxLevel: 1 + AL_WARP: 4 + } + AL_TELEPORT: { + MaxLevel: 2 + AL_RUWACH: 1 + } + AL_WARP: { + MaxLevel: 4 + AL_TELEPORT: 2 + } + AL_HEAL: 10 + AL_INCAGI: { + MaxLevel: 10 + AL_HEAL: 3 + } + AL_DECAGI: { + MaxLevel: 10 + AL_INCAGI: 1 + } + AL_HOLYWATER: 1 + AL_CRUCIS: { + MaxLevel: 10 + AL_DEMONBANE: 3 + } + AL_ANGELUS: { + MaxLevel: 10 + AL_DP: 3 + } + AL_BLESSING: { + MaxLevel: 10 + AL_DP: 5 + } + AL_CURE: { + MaxLevel: 1 + AL_HEAL: 2 + } + AL_HOLYLIGHT: 1 + } +} +Merchant: { + inherit: ( "Novice" ); + + skills: { + MC_INCCARRY: 10 + MC_DISCOUNT: { + MaxLevel: 10 + MC_INCCARRY: 3 + } + MC_OVERCHARGE: { + MaxLevel: 10 + MC_DISCOUNT: 3 + } + MC_PUSHCART: { + MaxLevel: 10 + MC_INCCARRY: 5 + } + MC_IDENTIFY: 1 + MC_VENDING: { + MaxLevel: 10 + MC_PUSHCART: 3 + } + MC_MAMMONITE: 10 + MC_CARTREVOLUTION: 1 + MC_CHANGECART: 1 + MC_LOUD: 1 + ALL_BUYING_STORE: { + MaxLevel: 1 + MC_VENDING: 1 + } + } +} +Thief: { + inherit: ( "Novice" ); + + skills: { + TF_DOUBLE: 10 + TF_MISS: 10 + TF_STEAL: 10 + TF_HIDING: { + MaxLevel: 10 + TF_STEAL: 5 + } + TF_POISON: 10 + TF_DETOXIFY: { + MaxLevel: 1 + TF_POISON: 3 + } + TF_SPRINKLESAND: 1 + TF_BACKSLIDING: 1 + TF_PICKSTONE: 1 + TF_THROWSTONE: 1 + } +} +Knight: { + inherit: ( "Swordsman" ); + + skills: { + KN_SPEARMASTERY: 10 + KN_PIERCE: { + MaxLevel: 10 + KN_SPEARMASTERY: 1 + } + KN_BRANDISHSPEAR: { + MaxLevel: 10 + KN_RIDING: 1 + KN_SPEARSTAB: 3 + } + KN_SPEARSTAB: { + MaxLevel: 10 + KN_PIERCE: 5 + } + KN_SPEARBOOMERANG: { + MaxLevel: 5 + KN_PIERCE: 3 + } + KN_TWOHANDQUICKEN: { + MaxLevel: 10 + SM_TWOHAND: 1 + } + KN_AUTOCOUNTER: { + MaxLevel: 5 + SM_TWOHAND: 1 + } + KN_BOWLINGBASH: { + MaxLevel: 10 + SM_BASH: 10 + SM_MAGNUM: 3 + SM_TWOHAND: 5 + KN_TWOHANDQUICKEN: 10 + KN_AUTOCOUNTER: 5 + } + KN_RIDING: { + MaxLevel: 1 + SM_ENDURE: 1 + } + KN_CAVALIERMASTERY: { + MaxLevel: 5 + KN_RIDING: 1 + } + KN_CHARGEATK: 1 + KN_ONEHAND: { + MaxLevel: 1 + KN_TWOHANDQUICKEN: 10 + } + } +} +Priest: { + inherit: ( "Acolyte" ); + + skills: { + MG_SRECOVERY: 10 + MG_SAFETYWALL: { + MaxLevel: 10 + PR_ASPERSIO: 4 + PR_SANCTUARY: 3 + } + ALL_RESURRECTION: { + MaxLevel: 4 + PR_STRECOVERY: 1 + MG_SRECOVERY: 4 + } + PR_MACEMASTERY: 10 + PR_IMPOSITIO: 5 + PR_SUFFRAGIUM: { + MaxLevel: 3 + PR_IMPOSITIO: 2 + } + PR_ASPERSIO: { + MaxLevel: 5 + AL_HOLYWATER: 1 + PR_IMPOSITIO: 3 + } + PR_BENEDICTIO: { + MaxLevel: 5 + PR_GLORIA: 3 + PR_ASPERSIO: 5 + } + PR_SANCTUARY: { + MaxLevel: 10 + AL_HEAL: 1 + } + PR_SLOWPOISON: 4 + PR_STRECOVERY: 1 + PR_KYRIE: { + MaxLevel: 10 + AL_ANGELUS: 2 + } + PR_MAGNIFICAT: 5 + PR_GLORIA: { + MaxLevel: 5 + PR_KYRIE: 4 + PR_MAGNIFICAT: 3 + } + PR_LEXDIVINA: { + MaxLevel: 10 + AL_RUWACH: 1 + } + PR_TURNUNDEAD: { + MaxLevel: 10 + ALL_RESURRECTION: 1 + PR_LEXDIVINA: 3 + } + PR_LEXAETERNA: { + MaxLevel: 1 + PR_LEXDIVINA: 5 + } + PR_MAGNUS: { + MaxLevel: 10 + MG_SAFETYWALL: 1 + PR_LEXAETERNA: 1 + PR_TURNUNDEAD: 3 + } + PR_REDEMPTIO: 1 + } +} +Wizard: { + inherit: ( "Magician" ); + + skills: { + WZ_FIREPILLAR: { + MaxLevel: 10 + MG_FIREWALL: 1 + } + WZ_SIGHTRASHER: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 1 + MG_SIGHT: 1 + } + WZ_METEOR: { + MaxLevel: 10 + WZ_SIGHTRASHER: 2 + MG_THUNDERSTORM: 1 + } + WZ_JUPITEL: { + MaxLevel: 10 + MG_NAPALMBEAT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_VERMILION: { + MaxLevel: 10 + MG_THUNDERSTORM: 1 + WZ_JUPITEL: 5 + } + WZ_WATERBALL: { + MaxLevel: 5 + MG_COLDBOLT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_ICEWALL: { + MaxLevel: 10 + MG_STONECURSE: 1 + MG_FROSTDIVER: 1 + } + WZ_FROSTNOVA: { + MaxLevel: 10 + WZ_ICEWALL: 1 + } + WZ_STORMGUST: { + MaxLevel: 10 + MG_FROSTDIVER: 1 + WZ_JUPITEL: 3 + } + WZ_EARTHSPIKE: { + MaxLevel: 5 + MG_STONECURSE: 1 + } + WZ_HEAVENDRIVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 3 + } + WZ_QUAGMIRE: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 1 + } + WZ_ESTIMATION: 1 + WZ_SIGHTBLASTER: 1 + } +} +Blacksmith: { + inherit: ( "Merchant" ); + + skills: { + BS_IRON: 5 + BS_STEEL: { + MaxLevel: 5 + BS_IRON: 1 + } + BS_ENCHANTEDSTONE: { + MaxLevel: 5 + BS_IRON: 1 + } + BS_ORIDEOCON: { + MaxLevel: 5 + BS_ENCHANTEDSTONE: 1 + } + BS_DAGGER: 3 + BS_SWORD: { + MaxLevel: 3 + BS_DAGGER: 1 + } + BS_TWOHANDSWORD: { + MaxLevel: 3 + BS_SWORD: 1 + } + BS_AXE: { + MaxLevel: 3 + BS_SWORD: 2 + } + BS_MACE: { + MaxLevel: 3 + BS_KNUCKLE: 1 + } + BS_KNUCKLE: { + MaxLevel: 3 + BS_DAGGER: 1 + } + BS_SPEAR: { + MaxLevel: 3 + BS_DAGGER: 2 + } + BS_HILTBINDING: 1 + BS_FINDINGORE: { + MaxLevel: 1 + BS_STEEL: 1 + BS_HILTBINDING: 1 + } + BS_WEAPONRESEARCH: { + MaxLevel: 10 + BS_HILTBINDING: 1 + } + BS_REPAIRWEAPON: { + MaxLevel: 1 + BS_WEAPONRESEARCH: 1 + } + BS_SKINTEMPER: 5 + BS_HAMMERFALL: 5 + BS_ADRENALINE: { + MaxLevel: 5 + BS_HAMMERFALL: 2 + } + BS_WEAPONPERFECT: { + MaxLevel: 5 + BS_WEAPONRESEARCH: 2 + BS_ADRENALINE: 2 + } + BS_OVERTHRUST: { + MaxLevel: 5 + BS_ADRENALINE: 3 + } + BS_MAXIMIZE: { + MaxLevel: 5 + BS_WEAPONPERFECT: 3 + BS_OVERTHRUST: 2 + } + BS_UNFAIRLYTRICK: 1 + BS_GREED: 1 + BS_ADRENALINE2: { + MaxLevel: 1 + BS_ADRENALINE: 5 + } + } +} +Hunter: { + inherit: ( "Archer" ); + + skills: { + HT_SKIDTRAP: 5 + HT_LANDMINE: 5 + HT_ANKLESNARE: { + MaxLevel: 5 + HT_SKIDTRAP: 1 + } + HT_SHOCKWAVE: { + MaxLevel: 5 + HT_ANKLESNARE: 1 + } + HT_SANDMAN: { + MaxLevel: 5 + HT_FLASHER: 1 + } + HT_FLASHER: { + MaxLevel: 5 + HT_SKIDTRAP: 1 + } + HT_FREEZINGTRAP: { + MaxLevel: 5 + HT_FLASHER: 1 + } + HT_BLASTMINE: { + MaxLevel: 5 + HT_LANDMINE: 1 + HT_SANDMAN: 1 + HT_FREEZINGTRAP: 1 + } + HT_CLAYMORETRAP: { + MaxLevel: 5 + HT_SHOCKWAVE: 1 + HT_BLASTMINE: 1 + } + HT_REMOVETRAP: { + MaxLevel: 1 + HT_LANDMINE: 1 + } + HT_TALKIEBOX: { + MaxLevel: 1 + HT_SHOCKWAVE: 1 + HT_REMOVETRAP: 1 + } + HT_BEASTBANE: 10 + HT_FALCON: { + MaxLevel: 1 + HT_BEASTBANE: 1 + } + HT_STEELCROW: { + MaxLevel: 10 + HT_BLITZBEAT: 5 + } + HT_BLITZBEAT: { + MaxLevel: 5 + HT_FALCON: 1 + } + HT_DETECTING: { + MaxLevel: 4 + AC_CONCENTRATION: 1 + HT_FALCON: 1 + } + HT_SPRINGTRAP: { + MaxLevel: 5 + HT_REMOVETRAP: 1 + HT_FALCON: 1 + } + HT_PHANTASMIC: 1 + HT_POWER: { + MaxLevel: 1 + AC_DOUBLE: 10 + } + } +} +Assassin: { + inherit: ( "Thief" ); + + skills: { + AS_RIGHT: 5 + AS_LEFT: { + MaxLevel: 5 + AS_RIGHT: 2 + } + AS_KATAR: 10 + AS_CLOAKING: { + MaxLevel: 10 + TF_HIDING: 2 + } + AS_SONICBLOW: { + MaxLevel: 10 + AS_KATAR: 4 + } + AS_GRIMTOOTH: { + MaxLevel: 5 + AS_CLOAKING: 2 + AS_SONICBLOW: 5 + } + AS_ENCHANTPOISON: { + MaxLevel: 10 + TF_POISON: 1 + } + AS_POISONREACT: { + MaxLevel: 10 + AS_ENCHANTPOISON: 3 + } + AS_VENOMDUST: { + MaxLevel: 10 + AS_ENCHANTPOISON: 5 + } + AS_SPLASHER: { + MaxLevel: 10 + AS_POISONREACT: 5 + AS_VENOMDUST: 5 + } + AS_SONICACCEL: 1 + AS_VENOMKNIFE: 1 + } +} +Crusader: { + inherit: ( "Swordsman" ); + + skills: { + KN_RIDING: { + MaxLevel: 1 + SM_ENDURE: 1 + } + KN_CAVALIERMASTERY: { + MaxLevel: 5 + KN_RIDING: 1 + } + KN_SPEARMASTERY: 10 + AL_CURE: { + MaxLevel: 1 + CR_TRUST: 5 + } + AL_DP: { + MaxLevel: 10 + AL_CURE: 1 + } + AL_DEMONBANE: { + MaxLevel: 10 + AL_DP: 3 + } + AL_HEAL: { + MaxLevel: 10 + AL_DEMONBANE: 5 + CR_TRUST: 10 + } + CR_TRUST: 10 + CR_AUTOGUARD: 10 + CR_SHIELDCHARGE: { + MaxLevel: 5 + CR_AUTOGUARD: 5 + } + CR_SHIELDBOOMERANG: { + MaxLevel: 5 + CR_SHIELDCHARGE: 3 + } + CR_REFLECTSHIELD: { + MaxLevel: 10 + CR_SHIELDBOOMERANG: 3 + } + CR_HOLYCROSS: { + MaxLevel: 10 + CR_TRUST: 7 + } + CR_GRANDCROSS: { + MaxLevel: 10 + CR_HOLYCROSS: 6 + CR_TRUST: 10 + } + CR_DEVOTION: { + MaxLevel: 5 + CR_REFLECTSHIELD: 5 + CR_GRANDCROSS: 4 + } + CR_PROVIDENCE: { + MaxLevel: 5 + AL_DP: 5 + AL_HEAL: 5 + } + CR_DEFENDER: { + MaxLevel: 5 + CR_SHIELDBOOMERANG: 1 + } + CR_SPEARQUICKEN: { + MaxLevel: 10 + KN_SPEARMASTERY: 10 + } + CR_SHRINK: 1 + } +} +Monk: { + inherit: ( "Acolyte" ); + + skills: { + MO_IRONHAND: { + MaxLevel: 10 + AL_DEMONBANE: 10 + AL_DP: 10 + } + MO_SPIRITSRECOVERY: { + MaxLevel: 5 + MO_BLADESTOP: 2 + } + MO_CALLSPIRITS: { + MaxLevel: 5 + MO_IRONHAND: 2 + } + MO_ABSORBSPIRITS: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + } + MO_TRIPLEATTACK: { + MaxLevel: 10 + MO_DODGE: 5 + } + MO_BODYRELOCATION: { + MaxLevel: 1 + MO_EXTREMITYFIST: 3 + MO_SPIRITSRECOVERY: 2 + MO_STEELBODY: 3 + } + MO_DODGE: { + MaxLevel: 10 + MO_IRONHAND: 5 + MO_CALLSPIRITS: 5 + } + MO_INVESTIGATE: { + MaxLevel: 5 + MO_CALLSPIRITS: 5 + } + MO_FINGEROFFENSIVE: { + MaxLevel: 5 + MO_INVESTIGATE: 3 + } + MO_STEELBODY: { + MaxLevel: 5 + MO_COMBOFINISH: 3 + } + MO_BLADESTOP: { + MaxLevel: 5 + MO_DODGE: 5 + } + MO_EXPLOSIONSPIRITS: { + MaxLevel: 5 + MO_ABSORBSPIRITS: 1 + } + MO_EXTREMITYFIST: { + MaxLevel: 5 + MO_EXPLOSIONSPIRITS: 3 + MO_FINGEROFFENSIVE: 3 + } + MO_CHAINCOMBO: { + MaxLevel: 5 + MO_TRIPLEATTACK: 5 + } + MO_COMBOFINISH: { + MaxLevel: 5 + MO_CHAINCOMBO: 3 + } + MO_KITRANSLATION: 1 + MO_BALKYOUNG: 1 + } +} +Sage: { + inherit: ( "Magician" ); + + skills: { + WZ_ESTIMATION: 1 + WZ_EARTHSPIKE: { + MaxLevel: 5 + SA_SEISMICWEAPON: 1 + } + WZ_HEAVENDRIVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 1 + } + SA_ADVANCEDBOOK: 10 + SA_CASTCANCEL: { + MaxLevel: 5 + SA_ADVANCEDBOOK: 2 + } + SA_MAGICROD: { + MaxLevel: 5 + SA_ADVANCEDBOOK: 4 + } + SA_SPELLBREAKER: { + MaxLevel: 5 + SA_MAGICROD: 1 + } + SA_FREECAST: { + MaxLevel: 10 + SA_CASTCANCEL: 1 + } + SA_AUTOSPELL: { + MaxLevel: 10 + SA_FREECAST: 4 + } + SA_FLAMELAUNCHER: { + MaxLevel: 5 + MG_FIREBOLT: 1 + SA_ADVANCEDBOOK: 5 + } + SA_FROSTWEAPON: { + MaxLevel: 5 + MG_COLDBOLT: 1 + SA_ADVANCEDBOOK: 5 + } + SA_LIGHTNINGLOADER: { + MaxLevel: 5 + MG_LIGHTNINGBOLT: 1 + SA_ADVANCEDBOOK: 5 + } + SA_SEISMICWEAPON: { + MaxLevel: 5 + MG_STONECURSE: 1 + SA_ADVANCEDBOOK: 5 + } + SA_DRAGONOLOGY: { + MaxLevel: 5 + SA_ADVANCEDBOOK: 9 + } + SA_VOLCANO: { + MaxLevel: 5 + SA_FLAMELAUNCHER: 2 + } + SA_DELUGE: { + MaxLevel: 5 + SA_FROSTWEAPON: 2 + } + SA_VIOLENTGALE: { + MaxLevel: 5 + SA_LIGHTNINGLOADER: 2 + } + SA_LANDPROTECTOR: { + MaxLevel: 5 + SA_VOLCANO: 3 + SA_DELUGE: 3 + SA_VIOLENTGALE: 3 + } + SA_DISPELL: { + MaxLevel: 5 + SA_SPELLBREAKER: 3 + } + SA_ABRACADABRA: { + MaxLevel: 10 + SA_AUTOSPELL: 5 + SA_DISPELL: 1 + SA_LANDPROTECTOR: 1 + } + SA_CREATECON: 1 + SA_ELEMENTWATER: 1 + SA_ELEMENTGROUND: 1 + SA_ELEMENTFIRE: 1 + SA_ELEMENTWIND: 1 + } +} +Rogue: { + inherit: ( "Thief" ); + + skills: { + SM_SWORD: 10 + AC_VULTURE: 10 + AC_DOUBLE: { + MaxLevel: 10 + AC_VULTURE: 10 + } + HT_REMOVETRAP: { + MaxLevel: 1 + AC_DOUBLE: 5 + } + RG_SNATCHER: { + MaxLevel: 10 + TF_STEAL: 1 + } + RG_STEALCOIN: { + MaxLevel: 10 + RG_SNATCHER: 4 + } + RG_BACKSTAP: { + MaxLevel: 10 + RG_STEALCOIN: 4 + } + RG_TUNNELDRIVE: { + MaxLevel: 5 + TF_HIDING: 1 + } + RG_RAID: { + MaxLevel: 5 + RG_BACKSTAP: 2 + RG_TUNNELDRIVE: 2 + } + RG_STRIPWEAPON: { + MaxLevel: 5 + RG_STRIPARMOR: 5 + } + RG_STRIPSHIELD: { + MaxLevel: 5 + RG_STRIPHELM: 5 + } + RG_STRIPARMOR: { + MaxLevel: 5 + RG_STRIPSHIELD: 5 + } + RG_STRIPHELM: { + MaxLevel: 5 + RG_STEALCOIN: 2 + } + RG_INTIMIDATE: { + MaxLevel: 5 + RG_BACKSTAP: 4 + RG_RAID: 5 + } + RG_GRAFFITI: { + MaxLevel: 1 + RG_FLAGGRAFFITI: 5 + } + RG_FLAGGRAFFITI: { + MaxLevel: 5 + RG_CLEANER: 1 + } + RG_CLEANER: { + MaxLevel: 1 + RG_GANGSTER: 1 + } + RG_GANGSTER: { + MaxLevel: 1 + RG_STRIPSHIELD: 3 + } + RG_COMPULSION: { + MaxLevel: 5 + RG_GANGSTER: 1 + } + RG_PLAGIARISM: { + MaxLevel: 10 + RG_INTIMIDATE: 5 + } + RG_CLOSECONFINE: 1 + } +} +Alchemist: { + inherit: ( "Merchant" ); + + skills: { + AM_AXEMASTERY: 10 + AM_LEARNINGPOTION: 10 + AM_PHARMACY: { + MaxLevel: 10 + AM_LEARNINGPOTION: 5 + } + AM_DEMONSTRATION: { + MaxLevel: 5 + AM_PHARMACY: 4 + } + AM_ACIDTERROR: { + MaxLevel: 5 + AM_PHARMACY: 5 + } + AM_POTIONPITCHER: { + MaxLevel: 5 + AM_PHARMACY: 3 + } + AM_CANNIBALIZE: { + MaxLevel: 5 + AM_PHARMACY: 6 + } + AM_SPHEREMINE: { + MaxLevel: 5 + AM_PHARMACY: 2 + } + AM_CP_WEAPON: { + MaxLevel: 5 + AM_CP_ARMOR: 3 + } + AM_CP_SHIELD: { + MaxLevel: 5 + AM_CP_HELM: 3 + } + AM_CP_ARMOR: { + MaxLevel: 5 + AM_CP_SHIELD: 3 + } + AM_CP_HELM: { + MaxLevel: 5 + AM_PHARMACY: 2 + } + AM_BIOETHICS: 1 + AM_CALLHOMUN: { + MaxLevel: 1 + AM_REST: 1 + } + AM_REST: { + MaxLevel: 1 + AM_BIOETHICS: 1 + } + AM_RESURRECTHOMUN: { + MaxLevel: 5 + AM_CALLHOMUN: 1 + } + AM_BERSERKPITCHER: 1 + AM_TWILIGHT1: { + MaxLevel: 1 + AM_PHARMACY: 10 + } + AM_TWILIGHT2: { + MaxLevel: 1 + AM_PHARMACY: 10 + } + AM_TWILIGHT3: { + MaxLevel: 1 + AM_PHARMACY: 10 + } + } +} +Bard: { + inherit: ( "Archer" ); + + skills: { + BA_MUSICALLESSON: 10 + BA_MUSICALSTRIKE: { + MaxLevel: 5 + BA_MUSICALLESSON: 3 + } + BA_DISSONANCE: { + MaxLevel: 5 + BA_MUSICALLESSON: 1 + BD_ADAPTATION: 1 + } + BA_FROSTJOKER: { + MaxLevel: 5 + BD_ENCORE: 1 + } + BA_WHISTLE: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BA_ASSASSINCROSS: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BA_POEMBRAGI: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BA_APPLEIDUN: { + MaxLevel: 10 + BA_DISSONANCE: 3 + } + BD_ADAPTATION: 1 + BD_ENCORE: { + MaxLevel: 1 + BD_ADAPTATION: 1 + } + BD_LULLABY: { + MaxLevel: 1 + BA_WHISTLE: 10 + } + BD_RICHMANKIM: { + MaxLevel: 5 + BD_SIEGFRIED: 3 + } + BD_ETERNALCHAOS: { + MaxLevel: 1 + BD_ROKISWEIL: 1 + } + BD_DRUMBATTLEFIELD: { + MaxLevel: 5 + BA_APPLEIDUN: 10 + } + BD_RINGNIBELUNGEN: { + MaxLevel: 5 + BD_DRUMBATTLEFIELD: 3 + } + BD_ROKISWEIL: { + MaxLevel: 1 + BA_ASSASSINCROSS: 10 + } + BD_INTOABYSS: { + MaxLevel: 1 + BD_LULLABY: 1 + } + BD_SIEGFRIED: { + MaxLevel: 5 + BA_POEMBRAGI: 10 + } + BA_PANGVOICE: 1 + } +} +Dancer: { + inherit: ( "Archer" ); + + skills: { + DC_DANCINGLESSON: 10 + DC_THROWARROW: { + MaxLevel: 5 + DC_DANCINGLESSON: 3 + } + DC_UGLYDANCE: { + MaxLevel: 5 + DC_DANCINGLESSON: 1 + BD_ADAPTATION: 1 + } + DC_SCREAM: { + MaxLevel: 5 + BD_ENCORE: 1 + } + DC_HUMMING: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + DC_DONTFORGETME: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + DC_FORTUNEKISS: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + DC_SERVICEFORYOU: { + MaxLevel: 10 + DC_UGLYDANCE: 3 + } + BD_ADAPTATION: 1 + BD_ENCORE: { + MaxLevel: 1 + BD_ADAPTATION: 1 + } + BD_LULLABY: { + MaxLevel: 1 + DC_HUMMING: 10 + } + BD_RICHMANKIM: { + MaxLevel: 5 + BD_SIEGFRIED: 3 + } + BD_ETERNALCHAOS: { + MaxLevel: 1 + BD_ROKISWEIL: 1 + } + BD_DRUMBATTLEFIELD: { + MaxLevel: 5 + DC_SERVICEFORYOU: 10 + } + BD_RINGNIBELUNGEN: { + MaxLevel: 5 + BD_DRUMBATTLEFIELD: 3 + } + BD_ROKISWEIL: { + MaxLevel: 1 + DC_DONTFORGETME: 10 + } + BD_INTOABYSS: { + MaxLevel: 1 + BD_LULLABY: 1 + } + BD_SIEGFRIED: { + MaxLevel: 5 + DC_FORTUNEKISS: 10 + } + DC_WINKCHARM: 1 + } +} +Super_Novice: { + inherit: ( "Novice" ); + + skills: { + SM_SWORD: 10 + SM_RECOVERY: 10 + SM_BASH: 10 + SM_PROVOKE: 10 + SM_MAGNUM: { + MaxLevel: 10 + SM_BASH: 5 + } + SM_ENDURE: { + MaxLevel: 10 + SM_PROVOKE: 5 + } + MG_SRECOVERY: 10 + MG_SIGHT: 1 + MG_NAPALMBEAT: 10 + MG_SAFETYWALL: { + MaxLevel: 10 + MG_NAPALMBEAT: 7 + MG_SOULSTRIKE: 5 + } + MG_SOULSTRIKE: { + MaxLevel: 10 + MG_NAPALMBEAT: 4 + } + MG_COLDBOLT: 10 + MG_FROSTDIVER: { + MaxLevel: 10 + MG_COLDBOLT: 5 + } + MG_STONECURSE: 10 + MG_FIREBALL: { + MaxLevel: 10 + MG_FIREBOLT: 4 + } + MG_FIREWALL: { + MaxLevel: 10 + MG_FIREBALL: 5 + MG_SIGHT: 1 + } + MG_FIREBOLT: 10 + MG_LIGHTNINGBOLT: 10 + MG_THUNDERSTORM: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 4 + } + AL_DP: 10 + AL_DEMONBANE: { + MaxLevel: 10 + AL_DP: 3 + } + AL_RUWACH: 1 + AL_PNEUMA: { + MaxLevel: 1 + AL_WARP: 4 + } + AL_TELEPORT: { + MaxLevel: 2 + AL_RUWACH: 1 + } + AL_WARP: { + MaxLevel: 4 + AL_TELEPORT: 2 + } + AL_HEAL: 10 + AL_INCAGI: { + MaxLevel: 10 + AL_HEAL: 3 + } + AL_DECAGI: { + MaxLevel: 10 + AL_INCAGI: 1 + } + AL_HOLYWATER: 1 + AL_CRUCIS: { + MaxLevel: 10 + AL_DEMONBANE: 3 + } + AL_ANGELUS: { + MaxLevel: 10 + AL_DP: 3 + } + AL_BLESSING: { + MaxLevel: 10 + AL_DP: 5 + } + AL_CURE: { + MaxLevel: 1 + AL_HEAL: 2 + } + MC_INCCARRY: 10 + MC_DISCOUNT: { + MaxLevel: 10 + MC_INCCARRY: 3 + } + MC_OVERCHARGE: { + MaxLevel: 10 + MC_DISCOUNT: 3 + } + MC_PUSHCART: { + MaxLevel: 10 + MC_INCCARRY: 5 + } + MC_IDENTIFY: 1 + MC_VENDING: { + MaxLevel: 10 + MC_PUSHCART: 3 + } + MC_MAMMONITE: 10 + AC_OWL: 10 + AC_VULTURE: { + MaxLevel: 10 + AC_OWL: 3 + } + AC_CONCENTRATION: { + MaxLevel: 10 + AC_VULTURE: 1 + } + TF_DOUBLE: 10 + TF_MISS: 10 + TF_STEAL: 10 + TF_HIDING: { + MaxLevel: 10 + TF_STEAL: 5 + } + TF_POISON: 10 + TF_DETOXIFY: { + MaxLevel: 1 + TF_POISON: 3 + } + ALL_BUYING_STORE: { + MaxLevel: 1 + MC_VENDING: 1 + } + } +} +Gunslinger: { + inherit: ( "Novice" ); + + skills: { + GS_GLITTERING: 5 + GS_FLING: { + MaxLevel: 1 + GS_GLITTERING: 1 + } + GS_TRIPLEACTION: { + MaxLevel: 1 + GS_GLITTERING: 1 + GS_CHAINACTION: 10 + } + GS_BULLSEYE: { + MaxLevel: 1 + GS_GLITTERING: 5 + GS_TRACKING: 10 + } + GS_MADNESSCANCEL: { + MaxLevel: 1 + GS_GLITTERING: 4 + GS_GATLINGFEVER: 10 + } + GS_ADJUSTMENT: { + MaxLevel: 1 + GS_GLITTERING: 4 + GS_DISARM: 5 + } + GS_INCREASING: { + MaxLevel: 1 + GS_GLITTERING: 2 + GS_SNAKEEYE: 10 + } + GS_MAGICALBULLET: { + MaxLevel: 1 + GS_GLITTERING: 1 + } + GS_CRACKER: { + MaxLevel: 1 + GS_GLITTERING: 1 + } + GS_SINGLEACTION: 10 + GS_SNAKEEYE: 10 + GS_CHAINACTION: { + MaxLevel: 10 + GS_SINGLEACTION: 1 + } + GS_TRACKING: { + MaxLevel: 10 + GS_SINGLEACTION: 5 + } + GS_DISARM: { + MaxLevel: 5 + GS_TRACKING: 7 + } + GS_PIERCINGSHOT: { + MaxLevel: 5 + GS_TRACKING: 5 + } + GS_RAPIDSHOWER: { + MaxLevel: 10 + GS_CHAINACTION: 3 + } + GS_DESPERADO: { + MaxLevel: 10 + GS_RAPIDSHOWER: 5 + } + GS_GATLINGFEVER: { + MaxLevel: 10 + GS_RAPIDSHOWER: 7 + GS_DESPERADO: 5 + } + GS_DUST: { + MaxLevel: 10 + GS_SINGLEACTION: 5 + } + GS_FULLBUSTER: { + MaxLevel: 10 + GS_DUST: 3 + } + GS_SPREADATTACK: { + MaxLevel: 10 + GS_FULLBUSTER: 5 + } + GS_GROUNDDRIFT: { + MaxLevel: 10 + GS_SPREADATTACK: 7 + } + } +} +Ninja: { + inherit: ( "Novice" ); + + skills: { + NJ_TOBIDOUGU: 10 + NJ_SYURIKEN: { + MaxLevel: 10 + NJ_TOBIDOUGU: 1 + } + NJ_KUNAI: { + MaxLevel: 5 + NJ_SYURIKEN: 5 + } + NJ_HUUMA: { + MaxLevel: 5 + NJ_TOBIDOUGU: 5 + NJ_KUNAI: 5 + } + NJ_ZENYNAGE: { + MaxLevel: 10 + NJ_TOBIDOUGU: 10 + NJ_HUUMA: 5 + } + NJ_TATAMIGAESHI: 5 + NJ_KASUMIKIRI: { + MaxLevel: 10 + NJ_SHADOWJUMP: 1 + } + NJ_SHADOWJUMP: { + MaxLevel: 5 + NJ_TATAMIGAESHI: 1 + } + NJ_KIRIKAGE: { + MaxLevel: 5 + NJ_KASUMIKIRI: 5 + } + NJ_UTSUSEMI: { + MaxLevel: 5 + NJ_SHADOWJUMP: 5 + } + NJ_BUNSINJYUTSU: { + MaxLevel: 10 + NJ_UTSUSEMI: 4 + NJ_KIRIKAGE: 3 + NJ_NEN: 1 + } + NJ_NINPOU: 10 + NJ_KOUENKA: { + MaxLevel: 10 + NJ_NINPOU: 1 + } + NJ_KAENSIN: { + MaxLevel: 10 + NJ_KOUENKA: 5 + } + NJ_BAKUENRYU: { + MaxLevel: 5 + NJ_NINPOU: 10 + NJ_KAENSIN: 7 + } + NJ_HYOUSENSOU: { + MaxLevel: 10 + NJ_NINPOU: 1 + } + NJ_SUITON: { + MaxLevel: 10 + NJ_HYOUSENSOU: 5 + } + NJ_HYOUSYOURAKU: { + MaxLevel: 5 + NJ_NINPOU: 10 + NJ_SUITON: 7 + } + NJ_HUUJIN: { + MaxLevel: 10 + NJ_NINPOU: 1 + } + NJ_RAIGEKISAI: { + MaxLevel: 5 + NJ_HUUJIN: 5 + } + NJ_KAMAITACHI: { + MaxLevel: 5 + NJ_NINPOU: 10 + NJ_RAIGEKISAI: 5 + } + NJ_NEN: { + MaxLevel: 5 + NJ_NINPOU: 5 + } + NJ_ISSEN: { + MaxLevel: 10 + NJ_TOBIDOUGU: 7 + NJ_KIRIKAGE: 5 + NJ_NEN: 1 + } + } +} +Novice_High: { + inherit: ( "Novice" ); +} +Swordsman_High: { + inherit: ( "Swordsman" ); +} +Magician_High: { + inherit: ( "Magician" ); +} +Archer_High: { + inherit: ( "Archer" ); +} +Acolyte_High: { + inherit: ( "Acolyte" ); +} +Merchant_High: { + inherit: ( "Merchant" ); +} +Thief_High: { + inherit: ( "Thief" ); +} +Lord_Knight: { + inherit: ( "Knight" ); + skills: { + LK_AURABLADE: { + MaxLevel: 5 + SM_BASH: 5 + SM_MAGNUM: 5 + SM_TWOHAND: 5 + } + LK_PARRYING: { + MaxLevel: 10 + SM_TWOHAND: 10 + SM_PROVOKE: 5 + KN_TWOHANDQUICKEN: 3 + } + LK_CONCENTRATION: { + MaxLevel: 5 + SM_RECOVERY: 5 + KN_SPEARMASTERY: 5 + KN_RIDING: 1 + } + LK_TENSIONRELAX: { + MaxLevel: 1 + SM_RECOVERY: 10 + SM_PROVOKE: 5 + SM_ENDURE: 3 + } + LK_BERSERK: { + MaxLevel: 1 + MinJobLevel: 50 + } + LK_SPIRALPIERCE: { + MaxLevel: 5 + KN_SPEARMASTERY: 5 + KN_PIERCE: 5 + KN_SPEARSTAB: 5 + KN_RIDING: 1 + } + LK_HEADCRUSH: { + MaxLevel: 5 + KN_SPEARMASTERY: 9 + KN_RIDING: 1 + } + LK_JOINTBEAT: { + MaxLevel: 10 + KN_SPEARMASTERY: 9 + KN_CAVALIERMASTERY: 3 + LK_HEADCRUSH: 3 + } + } +} +High_Priest: { + inherit: ( "Priest" ); + + skills: { + HP_ASSUMPTIO: { + MaxLevel: 5 + AL_ANGELUS: 1 + MG_SRECOVERY: 3 + PR_IMPOSITIO: 3 + } + HP_BASILICA: { + MaxLevel: 5 + PR_GLORIA: 2 + MG_SRECOVERY: 1 + PR_KYRIE: 3 + } + HP_MEDITATIO: { + MaxLevel: 10 + PR_ASPERSIO: 3 + MG_SRECOVERY: 5 + PR_LEXDIVINA: 5 + } + HP_MANARECHARGE: { + MaxLevel: 5 + PR_MACEMASTERY: 10 + AL_DEMONBANE: 10 + } + } +} +High_Wizard: { + inherit: ( "Wizard" ); + + skills: { + HW_SOULDRAIN: { + MaxLevel: 10 + MG_SRECOVERY: 5 + MG_SOULSTRIKE: 7 + } + HW_MAGICCRASHER: { + MaxLevel: 1 + MG_SRECOVERY: 1 + } + HW_MAGICPOWER: 10 + HW_NAPALMVULCAN: { + MaxLevel: 5 + MG_NAPALMBEAT: 5 + } + HW_GANBANTEIN: { + MaxLevel: 1 + WZ_ESTIMATION: 1 + WZ_ICEWALL: 1 + } + HW_GRAVITATION: { + MaxLevel: 5 + HW_MAGICCRASHER: 1 + HW_MAGICPOWER: 10 + WZ_QUAGMIRE: 1 + } + } +} +Whitesmith: { + inherit: ( "Blacksmith" ); + + skills: { + WS_MELTDOWN: { + MaxLevel: 10 + BS_SKINTEMPER: 3 + BS_HILTBINDING: 1 + BS_WEAPONRESEARCH: 5 + BS_OVERTHRUST: 3 + } + WS_CARTBOOST: { + MaxLevel: 1 + MC_PUSHCART: 5 + MC_CARTREVOLUTION: 1 + MC_CHANGECART: 1 + BS_HILTBINDING: 1 + } + WS_WEAPONREFINE: { + MaxLevel: 10 + BS_WEAPONRESEARCH: 10 + } + WS_CARTTERMINATION: { + MaxLevel: 10 + MC_MAMMONITE: 10 + BS_HAMMERFALL: 5 + WS_CARTBOOST: 1 + } + WS_OVERTHRUSTMAX: { + MaxLevel: 5 + BS_OVERTHRUST: 5 + } + } +} +Sniper: { + inherit: ( "Hunter" ); + + skills: { + SN_SIGHT: { + MaxLevel: 10 + AC_OWL: 10 + AC_VULTURE: 10 + AC_CONCENTRATION: 10 + HT_FALCON: 1 + } + SN_FALCONASSAULT: { + MaxLevel: 5 + HT_STEELCROW: 3 + AC_VULTURE: 5 + HT_BLITZBEAT: 5 + HT_FALCON: 1 + } + SN_SHARPSHOOTING: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + AC_DOUBLE: 5 + } + SN_WINDWALK: { + MaxLevel: 10 + AC_CONCENTRATION: 9 + } + } +} +Assassin_Cross: { + inherit: ( "Assassin" ); + + skills: { + ASC_KATAR: { + MaxLevel: 5 + TF_DOUBLE: 5 + AS_KATAR: 7 + } + ASC_EDP: { + MaxLevel: 5 + ASC_CDP: 1 + } + ASC_BREAKER: { + MaxLevel: 10 + TF_DOUBLE: 5 + AS_CLOAKING: 3 + AS_ENCHANTPOISON: 6 + TF_POISON: 5 + } + ASC_METEORASSAULT: { + MaxLevel: 10 + AS_RIGHT: 3 + AS_KATAR: 5 + AS_SONICBLOW: 5 + ASC_BREAKER: 1 + } + ASC_CDP: { + MaxLevel: 1 + TF_POISON: 10 + TF_DETOXIFY: 1 + AS_ENCHANTPOISON: 5 + } + } +} +Paladin: { + inherit: ( "Crusader" ); + + skills: { + PA_PRESSURE: { + MaxLevel: 5 + SM_ENDURE: 5 + CR_TRUST: 5 + CR_SHIELDCHARGE: 2 + } + PA_SACRIFICE: { + MaxLevel: 5 + SM_ENDURE: 1 + CR_TRUST: 5 + CR_DEVOTION: 3 + } + PA_GOSPEL: { + MaxLevel: 10 + CR_TRUST: 8 + AL_DP: 3 + AL_DEMONBANE: 5 + } + PA_SHIELDCHAIN: { + MaxLevel: 5 + CR_SHIELDBOOMERANG: 5 + } + } +} +Champion: { + inherit: ( "Monk" ); + + skills: { + CH_PALMSTRIKE: { + MaxLevel: 5 + MO_IRONHAND: 7 + MO_CALLSPIRITS: 5 + } + CH_TIGERFIST: { + MaxLevel: 5 + MO_IRONHAND: 5 + MO_TRIPLEATTACK: 5 + MO_CALLSPIRITS: 5 + MO_COMBOFINISH: 3 + } + CH_CHAINCRUSH: { + MaxLevel: 10 + MO_IRONHAND: 5 + MO_CALLSPIRITS: 5 + CH_TIGERFIST: 2 + } + CH_SOULCOLLECT: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + MO_ABSORBSPIRITS: 1 + MO_EXPLOSIONSPIRITS: 5 + } + } +} +Professor: { + inherit: ( "Sage" ); + + skills: { + PF_HPCONVERSION: { + MaxLevel: 5 + MG_SRECOVERY: 1 + SA_MAGICROD: 1 + } + PF_SOULCHANGE: { + MaxLevel: 1 + SA_MAGICROD: 3 + SA_SPELLBREAKER: 2 + } + PF_SOULBURN: { + MaxLevel: 5 + SA_CASTCANCEL: 5 + SA_MAGICROD: 3 + SA_DISPELL: 3 + } + PF_MINDBREAKER: { + MaxLevel: 5 + MG_SRECOVERY: 3 + PF_SOULBURN: 1 + } + PF_MEMORIZE: { + MaxLevel: 1 + SA_ADVANCEDBOOK: 5 + SA_FREECAST: 5 + SA_AUTOSPELL: 1 + } + PF_FOGWALL: { + MaxLevel: 1 + SA_DELUGE: 2 + SA_VIOLENTGALE: 2 + } + PF_SPIDERWEB: { + MaxLevel: 1 + SA_DRAGONOLOGY: 4 + } + PF_DOUBLECASTING: { + MaxLevel: 5 + SA_AUTOSPELL: 1 + } + } +} +Stalker: { + inherit: ( "Rogue" ); + + skills: { + ST_CHASEWALK: { + MaxLevel: 5 + TF_HIDING: 5 + RG_TUNNELDRIVE: 3 + } + ST_REJECTSWORD: 5 + ST_PRESERVE: { + MaxLevel: 1 + RG_PLAGIARISM: 10 + } + ST_FULLSTRIP: { + MaxLevel: 5 + RG_STRIPWEAPON: 5 + RG_STRIPSHIELD: 5 + RG_STRIPARMOR: 5 + RG_STRIPHELM: 5 + } + } +} +Creator: { + inherit: ( "Alchemist" ); + + skills: { + CR_SLIMPITCHER: { + MaxLevel: 10 + AM_POTIONPITCHER: 5 + } + CR_FULLPROTECTION: { + MaxLevel: 5 + AM_CP_WEAPON: 5 + AM_CP_SHIELD: 5 + AM_CP_ARMOR: 5 + AM_CP_HELM: 5 + } + CR_ACIDDEMONSTRATION: { + MaxLevel: 10 + AM_DEMONSTRATION: 5 + AM_ACIDTERROR: 5 + } + CR_CULTIVATION: 2 + } +} +Clown: { + inherit: ( "Bard" ); + + skills: { + CG_ARROWVULCAN: { + MaxLevel: 10 + AC_SHOWER: 5 + BA_MUSICALSTRIKE: 1 + } + CG_MOONLIT: { + MaxLevel: 5 + AC_CONCENTRATION: 5 + BA_MUSICALLESSON: 7 + } + CG_MARIONETTE: { + MaxLevel: 1 + AC_CONCENTRATION: 5 + BA_MUSICALLESSON: 5 + } + CG_LONGINGFREEDOM: { + MaxLevel: 5 + BA_MUSICALLESSON: 10 + CG_MARIONETTE: 1 + } + CG_HERMODE: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + BA_MUSICALLESSON: 10 + } + CG_TAROTCARD: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + BA_DISSONANCE: 3 + } + } +} +Gypsy: { + inherit: ( "Dancer" ); + + skills: { + CG_ARROWVULCAN: { + MaxLevel: 10 + AC_SHOWER: 5 + DC_THROWARROW: 1 + } + CG_MOONLIT: { + MaxLevel: 5 + AC_CONCENTRATION: 5 + DC_DANCINGLESSON: 7 + } + CG_MARIONETTE: { + MaxLevel: 1 + AC_CONCENTRATION: 5 + DC_DANCINGLESSON: 5 + } + CG_LONGINGFREEDOM: { + MaxLevel: 5 + DC_DANCINGLESSON: 10 + CG_MARIONETTE: 1 + } + CG_HERMODE: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + DC_DANCINGLESSON: 10 + } + CG_TAROTCARD: { + MaxLevel: 5 + AC_CONCENTRATION: 10 + DC_UGLYDANCE: 3 + } + } +} +Baby_Novice: { + inherit: ( "Novice" ); +} +Baby_Swordsman: { + inherit: ( "Swordsman" ); +} +Baby_Magician: { + inherit: ( "Priest" ); +} +Baby_Archer: { + inherit: ( "Archer" ); +} +Baby_Acolyte: { + inherit: ( "Acolyte" ); +} +Baby_Merchant: { + inherit: ( "Merchant" ); +} +Baby_Thief: { + inherit: ( "Thief" ); +} +Baby_Knight: { + inherit: ( "Knight" ); +} +Baby_Priest: { + inherit: ( "Priest" ); +} +Baby_Wizard: { + inherit: ( "Wizard" ); +} +Baby_Blacksmith: { + inherit: ( "Blacksmith" ); +} +Baby_Hunter: { + inherit: ( "Hunter" ); +} +Baby_Assassin: { + inherit: ( "Assassin" ); +} +Baby_Crusader: { + inherit: ( "Crusader" ); +} +Baby_Monk: { + inherit: ( "Monk" ); +} +Baby_Sage: { + inherit: ( "Sage" ); +} +Baby_Rogue: { + inherit: ( "Rogue" ); +} +Baby_Alchemist: { + inherit: ( "Alchemist" ); +} +Baby_Bard: { + inherit: ( "Bard" ); +} +Baby_Dancer: { + inherit: ( "Dancer" ); +} +Super_Baby: { + inherit: ( "Super_Novice" ); +} +Taekwon: { + inherit: ( "Novice" ); + + skills: { + TK_RUN: 10 + TK_READYSTORM: { + MaxLevel: 1 + TK_STORMKICK: 1 + } + TK_STORMKICK: 7 + TK_READYDOWN: { + MaxLevel: 1 + TK_DOWNKICK: 1 + } + TK_DOWNKICK: 7 + TK_READYTURN: { + MaxLevel: 1 + TK_TURNKICK: 1 + } + TK_TURNKICK: 7 + TK_READYCOUNTER: { + MaxLevel: 1 + TK_COUNTER: 1 + } + TK_COUNTER: 7 + TK_DODGE: { + MaxLevel: 1 + TK_JUMPKICK: 7 + } + TK_JUMPKICK: 7 + TK_HPTIME: 10 + TK_SPTIME: 10 + TK_POWER: 5 + TK_SEVENWIND: { + MaxLevel: 7 + TK_HPTIME: 5 + TK_SPTIME: 5 + TK_POWER: 5 + } + TK_HIGHJUMP: 5 + TK_MISSION: { + MaxLevel: 1 + TK_POWER: 5 + } + } +} +Star_Gladiator: { + inherit: ( "Taekwon" ); + + skills: { + SG_FEEL: 3 + SG_SUN_WARM: { + MaxLevel: 3 + SG_FEEL: 1 + } + SG_MOON_WARM: { + MaxLevel: 3 + SG_FEEL: 2 + } + SG_STAR_WARM: { + MaxLevel: 3 + SG_FEEL: 3 + } + SG_SUN_COMFORT: { + MaxLevel: 4 + SG_FEEL: 1 + } + SG_MOON_COMFORT: { + MaxLevel: 4 + SG_FEEL: 2 + } + SG_STAR_COMFORT: { + MaxLevel: 4 + SG_FEEL: 3 + } + SG_HATE: 3 + SG_SUN_ANGER: { + MaxLevel: 3 + SG_HATE: 1 + } + SG_MOON_ANGER: { + MaxLevel: 3 + SG_HATE: 2 + } + SG_STAR_ANGER: { + MaxLevel: 3 + SG_HATE: 3 + } + SG_SUN_BLESS: { + MaxLevel: 5 + SG_FEEL: 1 + SG_HATE: 1 + } + SG_MOON_BLESS: { + MaxLevel: 5 + SG_FEEL: 2 + SG_HATE: 2 + } + SG_STAR_BLESS: { + MaxLevel: 5 + SG_FEEL: 3 + SG_HATE: 3 + } + SG_DEVIL: 10 + SG_FRIEND: 3 + SG_KNOWLEDGE: 10 + SG_FUSION: { + MaxLevel: 1 + MinJobLevel: 443 + MG_SRECOVERY: 0 + } + } +} +Soul_Linker: { + inherit: ( "Taekwon" ); + + skills: { + SL_ALCHEMIST: 5 + SL_MONK: 5 + SL_STAR: 5 + SL_SAGE: 5 + SL_CRUSADER: 5 + SL_SUPERNOVICE: 5 + SL_KNIGHT: { + MaxLevel: 5 + SL_CRUSADER: 1 + } + SL_WIZARD: { + MaxLevel: 5 + SL_SAGE: 1 + } + SL_PRIEST: { + MaxLevel: 5 + SL_MONK: 1 + } + SL_BARDDANCER: 5 + SL_ROGUE: { + MaxLevel: 5 + SL_ASSASIN: 1 + } + SL_ASSASIN: 5 + SL_BLACKSMITH: { + MaxLevel: 5 + SL_ALCHEMIST: 1 + } + SL_HUNTER: { + MaxLevel: 5 + SL_BARDDANCER: 1 + } + SL_SOULLINKER: { + MaxLevel: 5 + SL_STAR: 1 + } + SL_KAIZEL: { + MaxLevel: 7 + SL_PRIEST: 1 + } + SL_KAAHI: { + MaxLevel: 7 + SL_PRIEST: 1 + SL_CRUSADER: 1 + } + SL_KAUPE: { + MaxLevel: 3 + SL_ROGUE: 1 + } + SL_KAITE: { + MaxLevel: 7 + SL_WIZARD: 1 + } + SL_KAINA: { + MaxLevel: 7 + TK_SPTIME: 1 + } + SL_STIN: { + MaxLevel: 7 + SL_WIZARD: 1 + } + SL_STUN: { + MaxLevel: 7 + SL_WIZARD: 1 + } + SL_SMA: { + MaxLevel: 10 + SL_STIN: 7 + SL_STUN: 7 + } + SL_SWOO: { + MaxLevel: 7 + SL_PRIEST: 1 + } + SL_SKE: { + MaxLevel: 3 + SL_KNIGHT: 1 + } + SL_SKA: { + MaxLevel: 3 + SL_MONK: 1 + } + SL_HIGH: { + MaxLevel: 5 + SL_SUPERNOVICE: 5 + } + } +} +Gangsi: { + inherit: ( "Novice" ); +} +Death_Knight: { + inherit: ( "Novice" ); +} +Dark_Collector: { + inherit: ( "Novice" ); +} +Rune_Knight: { + inherit: ( "Knight" ); + + skills: { + RK_ENCHANTBLADE: { + MaxLevel: 5 + RK_RUNEMASTERY: 2 + } + RK_SONICWAVE: { + MaxLevel: 5 + RK_ENCHANTBLADE: 3 + } + RK_DEATHBOUND: { + MaxLevel: 10 + KN_AUTOCOUNTER: 1 + RK_ENCHANTBLADE: 2 + } + RK_HUNDREDSPEAR: { + MaxLevel: 10 + RK_PHANTOMTHRUST: 3 + } + RK_WINDCUTTER: { + MaxLevel: 5 + RK_ENCHANTBLADE: 5 + } + RK_IGNITIONBREAK: { + MaxLevel: 5 + RK_SONICWAVE: 2 + RK_DEATHBOUND: 5 + RK_WINDCUTTER: 3 + } + RK_DRAGONTRAINING: { + MaxLevel: 5 + KN_CAVALIERMASTERY: 1 + } + RK_DRAGONBREATH: { + MaxLevel: 10 + RK_DRAGONTRAINING: 2 + } + RK_DRAGONHOWLING: { + MaxLevel: 5 + RK_DRAGONTRAINING: 2 + } + RK_RUNEMASTERY: 10 + RK_PHANTOMTHRUST: { + MaxLevel: 5 + KN_BRANDISHSPEAR: 2 + } + RK_DRAGONBREATH_WATER: { + MaxLevel: 10 + RK_DRAGONTRAINING: 2 + } + ALL_FULL_THROTTLE: 5 + } +} +Warlock: { + inherit: ( "Wizard" ); + + skills: { + WL_WHITEIMPRISON: { + MaxLevel: 5 + WL_SOULEXPANSION: 3 + } + WL_SOULEXPANSION: { + MaxLevel: 5 + WL_DRAINLIFE: 1 + } + WL_FROSTMISTY: { + MaxLevel: 5 + WL_SUMMONWB: 1 + } + WL_JACKFROST: { + MaxLevel: 5 + WL_FROSTMISTY: 2 + } + WL_MARSHOFABYSS: { + MaxLevel: 5 + WZ_QUAGMIRE: 1 + } + WL_RECOGNIZEDSPELL: { + MaxLevel: 5 + WL_WHITEIMPRISON: 1 + WL_STASIS: 1 + WL_RELEASE: 2 + } + WL_SIENNAEXECRATE: { + MaxLevel: 5 + WL_SUMMONSTONE: 1 + } + WL_RADIUS: 3 + WL_STASIS: { + MaxLevel: 5 + WL_DRAINLIFE: 1 + } + WL_DRAINLIFE: { + MaxLevel: 5 + WL_RADIUS: 1 + } + WL_CRIMSONROCK: { + MaxLevel: 5 + WL_SUMMONFB: 1 + } + WL_HELLINFERNO: { + MaxLevel: 5 + WL_CRIMSONROCK: 2 + } + WL_COMET: { + MaxLevel: 5 + WL_HELLINFERNO: 3 + } + WL_CHAINLIGHTNING: { + MaxLevel: 5 + WL_SUMMONBL: 1 + } + WL_EARTHSTRAIN: { + MaxLevel: 5 + WL_SIENNAEXECRATE: 2 + } + WL_TETRAVORTEX: { + MaxLevel: 5 + WL_JACKFROST: 5 + WL_HELLINFERNO: 5 + WL_CHAINLIGHTNING: 5 + WL_EARTHSTRAIN: 5 + } + WL_SUMMONFB: { + MaxLevel: 5 + WZ_METEOR: 1 + } + WL_SUMMONBL: { + MaxLevel: 5 + WZ_VERMILION: 1 + } + WL_SUMMONWB: { + MaxLevel: 5 + WZ_STORMGUST: 1 + } + WL_SUMMONSTONE: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 1 + } + WL_RELEASE: 2 + WL_READING_SB: 1 + WL_FREEZE_SP: 5 + WL_TELEKINESIS_INTENSE: { + MaxLevel: 5 + WL_SOULEXPANSION: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Ranger: { + inherit: ( "Hunter" ); + + skills: { + RA_ARROWSTORM: { + MaxLevel: 10 + RA_AIMEDBOLT: 5 + } + RA_FEARBREEZE: { + MaxLevel: 5 + RA_ARROWSTORM: 5 + RA_CAMOUFLAGE: 1 + } + RA_RANGERMAIN: 10 + RA_AIMEDBOLT: { + MaxLevel: 10 + HT_ANKLESNARE: 5 + } + RA_DETONATOR: { + MaxLevel: 1 + RA_CLUSTERBOMB: 3 + } + RA_ELECTRICSHOCKER: { + MaxLevel: 5 + HT_SHOCKWAVE: 5 + } + RA_CLUSTERBOMB: { + MaxLevel: 5 + RA_RESEARCHTRAP: 3 + } + RA_WUGMASTERY: 1 + RA_WUGRIDER: { + MaxLevel: 3 + RA_WUGMASTERY: 1 + } + RA_WUGDASH: { + MaxLevel: 1 + RA_WUGRIDER: 1 + } + RA_WUGSTRIKE: { + MaxLevel: 5 + RA_TOOTHOFWUG: 1 + } + RA_WUGBITE: { + MaxLevel: 5 + RA_WUGMASTERY: 1 + } + RA_TOOTHOFWUG: { + MaxLevel: 10 + RA_WUGMASTERY: 1 + } + RA_SENSITIVEKEEN: { + MaxLevel: 5 + RA_TOOTHOFWUG: 3 + } + RA_CAMOUFLAGE: { + MaxLevel: 5 + RA_RANGERMAIN: 1 + } + RA_RESEARCHTRAP: { + MaxLevel: 5 + HT_CLAYMORETRAP: 1 + HT_REMOVETRAP: 1 + } + RA_MAGENTATRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_COBALTTRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_MAIZETRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_VERDURETRAP: { + MaxLevel: 1 + RA_RESEARCHTRAP: 1 + } + RA_FIRINGTRAP: { + MaxLevel: 5 + RA_DETONATOR: 1 + } + RA_ICEBOUNDTRAP: { + MaxLevel: 5 + RA_DETONATOR: 1 + } + RA_UNLIMIT: { + MaxLevel: 5 + RA_FEARBREEZE: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Arch_Bishop: { + inherit: ( "Priest" ); + + skills: { + AB_JUDEX: { + MaxLevel: 5 + PR_TURNUNDEAD: 1 + } + AB_ANCILLA: { + MaxLevel: 1 + AB_CLEMENTIA: 3 + } + AB_ADORAMUS: { + MaxLevel: 10 + PR_MAGNUS: 1 + AB_JUDEX: 1 + AB_ANCILLA: 1 + } + AB_CLEMENTIA: { + MaxLevel: 3 + AL_BLESSING: 1 + } + AB_CANTO: { + MaxLevel: 3 + AL_INCAGI: 1 + } + AB_CHEAL: { + MaxLevel: 3 + AL_HEAL: 1 + } + AB_EPICLESIS: { + MaxLevel: 5 + AB_ANCILLA: 1 + AB_HIGHNESSHEAL: 1 + } + AB_PRAEFATIO: { + MaxLevel: 10 + PR_KYRIE: 1 + } + AB_ORATIO: { + MaxLevel: 10 + AB_PRAEFATIO: 5 + } + AB_LAUDAAGNUS: { + MaxLevel: 4 + PR_STRECOVERY: 1 + } + AB_LAUDARAMUS: { + MaxLevel: 4 + AB_LAUDAAGNUS: 2 + } + AB_EUCHARISTICA: { + MaxLevel: 10 + AB_EPICLESIS: 1 + AB_EXPIATIO: 1 + } + AB_RENOVATIO: { + MaxLevel: 1 + AB_CHEAL: 3 + } + AB_HIGHNESSHEAL: { + MaxLevel: 5 + AB_RENOVATIO: 1 + } + AB_CLEARANCE: { + MaxLevel: 5 + AB_LAUDARAMUS: 2 + } + AB_EXPIATIO: { + MaxLevel: 5 + AB_ORATIO: 5 + AB_DUPLELIGHT: 5 + } + AB_DUPLELIGHT: { + MaxLevel: 10 + PR_ASPERSIO: 1 + } + AB_SILENTIUM: { + MaxLevel: 5 + AB_CLEARANCE: 1 + } + AB_SECRAMENT: { + MaxLevel: 5 + AB_EPICLESIS: 1 + AB_EXPIATIO: 1 + } + AB_OFFERTORIUM: { + MaxLevel: 5 + AB_HIGHNESSHEAL: 2 + } + ALL_FULL_THROTTLE: 5 + } +} +Mechanic: { + inherit: ( "Blacksmith" ); + + skills: { + NC_MADOLICENCE: 5 + NC_BOOSTKNUCKLE: { + MaxLevel: 5 + NC_MADOLICENCE: 1 + } + NC_PILEBUNKER: { + MaxLevel: 3 + NC_BOOSTKNUCKLE: 2 + } + NC_VULCANARM: { + MaxLevel: 3 + NC_BOOSTKNUCKLE: 2 + } + NC_FLAMELAUNCHER: { + MaxLevel: 3 + NC_VULCANARM: 3 + } + NC_COLDSLOWER: { + MaxLevel: 3 + NC_VULCANARM: 3 + } + NC_ARMSCANNON: { + MaxLevel: 3 + NC_FLAMELAUNCHER: 2 + NC_COLDSLOWER: 2 + } + NC_ACCELERATION: { + MaxLevel: 3 + NC_MADOLICENCE: 1 + } + NC_HOVERING: { + MaxLevel: 1 + NC_ACCELERATION: 1 + } + NC_F_SIDESLIDE: { + MaxLevel: 1 + NC_HOVERING: 1 + } + NC_B_SIDESLIDE: { + MaxLevel: 1 + NC_HOVERING: 1 + } + NC_MAINFRAME: { + MaxLevel: 4 + NC_MADOLICENCE: 4 + } + NC_SELFDESTRUCTION: { + MaxLevel: 3 + NC_MAINFRAME: 2 + } + NC_SHAPESHIFT: { + MaxLevel: 4 + NC_MAINFRAME: 2 + } + NC_EMERGENCYCOOL: { + MaxLevel: 1 + NC_SELFDESTRUCTION: 2 + } + NC_INFRAREDSCAN: { + MaxLevel: 1 + NC_SHAPESHIFT: 2 + } + NC_ANALYZE: { + MaxLevel: 3 + NC_INFRAREDSCAN: 1 + } + NC_MAGNETICFIELD: { + MaxLevel: 3 + NC_EMERGENCYCOOL: 1 + } + NC_NEUTRALBARRIER: { + MaxLevel: 3 + NC_MAGNETICFIELD: 2 + } + NC_STEALTHFIELD: { + MaxLevel: 3 + NC_ANALYZE: 3 + NC_NEUTRALBARRIER: 2 + } + NC_REPAIR: { + MaxLevel: 5 + NC_MADOLICENCE: 1 + } + NC_TRAININGAXE: 10 + NC_RESEARCHFE: 5 + NC_AXEBOOMERANG: { + MaxLevel: 5 + NC_TRAININGAXE: 1 + } + NC_POWERSWING: { + MaxLevel: 5 + NC_AXEBOOMERANG: 3 + } + NC_AXETORNADO: { + MaxLevel: 5 + NC_TRAININGAXE: 1 + } + NC_SILVERSNIPER: { + MaxLevel: 5 + NC_RESEARCHFE: 2 + } + NC_MAGICDECOY: { + MaxLevel: 5 + NC_RESEARCHFE: 2 + } + NC_DISJOINT: { + MaxLevel: 1 + NC_SILVERSNIPER: 1 + } + NC_MAGMA_ERUPTION: 5 + ALL_FULL_THROTTLE: 5 + } +} +Guillotine_Cross: { + inherit: ( "Assassin" ); + + skills: { + GC_VENOMIMPRESS: { + MaxLevel: 5 + AS_ENCHANTPOISON: 3 + } + GC_CROSSIMPACT: { + MaxLevel: 5 + AS_SONICBLOW: 10 + } + GC_DARKILLUSION: { + MaxLevel: 5 + GC_CROSSIMPACT: 3 + } + GC_RESEARCHNEWPOISON: 10 + GC_CREATENEWPOISON: { + MaxLevel: 1 + GC_RESEARCHNEWPOISON: 1 + } + GC_ANTIDOTE: { + MaxLevel: 1 + GC_RESEARCHNEWPOISON: 5 + } + GC_POISONINGWEAPON: { + MaxLevel: 5 + GC_CREATENEWPOISON: 1 + } + GC_WEAPONBLOCKING: { + MaxLevel: 5 + AS_LEFT: 5 + } + GC_COUNTERSLASH: { + MaxLevel: 5 + GC_WEAPONBLOCKING: 1 + } + GC_WEAPONCRUSH: { + MaxLevel: 5 + GC_WEAPONBLOCKING: 1 + } + GC_VENOMPRESSURE: { + MaxLevel: 5 + GC_POISONINGWEAPON: 3 + GC_WEAPONBLOCKING: 1 + } + GC_POISONSMOKE: { + MaxLevel: 5 + GC_POISONINGWEAPON: 5 + GC_VENOMPRESSURE: 5 + } + GC_CLOAKINGEXCEED: { + MaxLevel: 5 + AS_CLOAKING: 3 + } + GC_PHANTOMMENACE: { + MaxLevel: 1 + GC_DARKILLUSION: 5 + GC_CLOAKINGEXCEED: 5 + } + GC_HALLUCINATIONWALK: { + MaxLevel: 5 + GC_PHANTOMMENACE: 1 + } + GC_ROLLINGCUTTER: { + MaxLevel: 5 + AS_SONICBLOW: 10 + } + GC_CROSSRIPPERSLASHER: { + MaxLevel: 5 + GC_ROLLINGCUTTER: 1 + } + GC_DARKCROW: { + MaxLevel: 5 + GC_DARKILLUSION: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Rune_Knight_Trans: { + inherit: ( "Lord_Knight", "Rune_Knight" ); +} +Warlock_Trans: { + inherit: ( "High_Wizard", "Warlock" ); +} +Ranger_Trans: { + inherit: ( "Sniper", "Ranger" ); +} +Arch_Bishop_Trans: { + inherit: ( "High_Priest", "Arch_Bishop" ); +} +Mechanic_Trans: { + inherit: ( "Whitesmith", "Mechanic" ); +} +Guillotine_Cross_Trans: { + inherit: ( "Assassin_Cross", "Guillotine_Cross" ); +} +Royal_Guard: { + inherit: ( "Crusader" ); + + skills: { + LG_CANNONSPEAR: { + MaxLevel: 5 + LG_PINPOINTATTACK: 1 + } + LG_BANISHINGPOINT: { + MaxLevel: 10 + KN_SPEARMASTERY: 1 + } + LG_TRAMPLE: 3 + LG_SHIELDPRESS: { + MaxLevel: 5 + CR_SHIELDCHARGE: 3 + } + LG_REFLECTDAMAGE: { + MaxLevel: 5 + CR_REFLECTSHIELD: 5 + } + LG_PINPOINTATTACK: { + MaxLevel: 5 + LG_BANISHINGPOINT: 5 + } + LG_FORCEOFVANGUARD: 5 + LG_RAGEBURST: { + MaxLevel: 1 + LG_FORCEOFVANGUARD: 1 + } + LG_SHIELDSPELL: { + MaxLevel: 3 + LG_SHIELDPRESS: 3 + LG_EARTHDRIVE: 2 + } + LG_EXEEDBREAK: { + MaxLevel: 5 + LG_BANISHINGPOINT: 3 + } + LG_OVERBRAND: { + MaxLevel: 5 + LG_PINPOINTATTACK: 1 + LG_MOONSLASHER: 3 + } + LG_PRESTIGE: { + MaxLevel: 5 + LG_TRAMPLE: 3 + } + LG_BANDING: { + MaxLevel: 5 + LG_PINPOINTATTACK: 3 + LG_RAGEBURST: 1 + } + LG_MOONSLASHER: { + MaxLevel: 5 + KN_SPEARMASTERY: 1 + } + LG_RAYOFGENESIS: { + MaxLevel: 5 + CR_GRANDCROSS: 5 + } + LG_PIETY: { + MaxLevel: 5 + CR_TRUST: 3 + } + LG_EARTHDRIVE: { + MaxLevel: 5 + LG_REFLECTDAMAGE: 3 + } + LG_HESPERUSLIT: { + MaxLevel: 5 + LG_PRESTIGE: 3 + LG_BANDING: 3 + } + LG_INSPIRATION: { + MaxLevel: 5 + LG_SHIELDSPELL: 3 + LG_RAYOFGENESIS: 4 + LG_PIETY: 5 + } + LG_KINGS_GRACE: { + MaxLevel: 5 + LG_REFLECTDAMAGE: 5 + } + ALL_FULL_THROTTLE: 5 + } +} +Sorcerer: { + inherit: ( "Sage" ); + + skills: { + SO_FIREWALK: { + MaxLevel: 5 + SA_VOLCANO: 1 + } + SO_ELECTRICWALK: { + MaxLevel: 5 + SA_VIOLENTGALE: 1 + } + SO_SPELLFIST: { + MaxLevel: 5 + SA_AUTOSPELL: 4 + } + SO_EARTHGRAVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 5 + } + SO_DIAMONDDUST: { + MaxLevel: 5 + SA_DELUGE: 3 + } + SO_POISON_BUSTER: { + MaxLevel: 5 + SO_CLOUD_KILL: 2 + } + SO_PSYCHIC_WAVE: { + MaxLevel: 5 + SA_DISPELL: 2 + } + SO_CLOUD_KILL: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 5 + } + SO_STRIKING: { + MaxLevel: 5 + SA_FLAMELAUNCHER: 1 + SA_FROSTWEAPON: 1 + SA_LIGHTNINGLOADER: 1 + SA_SEISMICWEAPON: 1 + } + SO_WARMER: { + MaxLevel: 5 + SA_VOLCANO: 1 + SA_VIOLENTGALE: 1 + } + SO_VACUUM_EXTREME: { + MaxLevel: 5 + SA_LANDPROTECTOR: 2 + } + SO_VARETYR_SPEAR: { + MaxLevel: 5 + SA_SEISMICWEAPON: 1 + SA_VIOLENTGALE: 4 + } + SO_ARRULLO: { + MaxLevel: 5 + SO_WARMER: 2 + } + SO_EL_CONTROL: { + MaxLevel: 4 + SO_EL_ANALYSIS: 1 + } + SO_SUMMON_AGNI: { + MaxLevel: 3 + SO_WARMER: 3 + SO_EL_CONTROL: 1 + } + SO_SUMMON_AQUA: { + MaxLevel: 3 + SO_DIAMONDDUST: 3 + SO_EL_CONTROL: 1 + } + SO_SUMMON_VENTUS: { + MaxLevel: 3 + SO_VARETYR_SPEAR: 3 + SO_EL_CONTROL: 1 + } + SO_SUMMON_TERA: { + MaxLevel: 3 + SO_EARTHGRAVE: 3 + SO_EL_CONTROL: 1 + } + SO_EL_ACTION: { + MaxLevel: 1 + SO_EL_CONTROL: 3 + } + SO_EL_ANALYSIS: { + MaxLevel: 2 + SA_FLAMELAUNCHER: 1 + SA_FROSTWEAPON: 1 + SA_LIGHTNINGLOADER: 1 + SA_SEISMICWEAPON: 1 + } + SO_EL_SYMPATHY: { + MaxLevel: 5 + SO_EL_CONTROL: 3 + } + SO_EL_CURE: { + MaxLevel: 1 + SO_EL_SYMPATHY: 1 + } + SO_FIRE_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_AGNI: 3 + } + SO_WATER_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_AQUA: 3 + } + SO_WIND_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_VENTUS: 3 + } + SO_EARTH_INSIGNIA: { + MaxLevel: 3 + SO_SUMMON_TERA: 3 + } + ALL_FULL_THROTTLE: 5 + } +} +Minstrel: { + inherit: ( "Bard" ); + + skills: { + MI_RUSH_WINDMILL: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + MI_ECHOSONG: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + MI_HARMONIZE: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WM_LESSON: 10 + WM_METALICSOUND: { + MaxLevel: 5 + WM_DOMINION_IMPULSE: 1 + } + WM_REVERBERATION: { + MaxLevel: 5 + BA_DISSONANCE: 5 + } + WM_DOMINION_IMPULSE: { + MaxLevel: 1 + WM_REVERBERATION: 1 + } + WM_SEVERE_RAINSTORM: { + MaxLevel: 5 + BA_MUSICALSTRIKE: 5 + } + WM_POEMOFNETHERWORLD: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_VOICEOFSIREN: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 3 + } + WM_DEADHILLHERE: { + MaxLevel: 5 + WM_SIRCLEOFNATURE: 3 + } + WM_LULLABY_DEEPSLEEP: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_SIRCLEOFNATURE: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_RANDOMIZESPELL: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 1 + } + WM_GLOOMYDAY: { + MaxLevel: 5 + WM_RANDOMIZESPELL: 1 + } + WM_GREAT_ECHO: { + MaxLevel: 5 + WM_METALICSOUND: 1 + } + WM_SONG_OF_MANA: { + MaxLevel: 5 + MI_RUSH_WINDMILL: 1 + MI_ECHOSONG: 1 + MI_HARMONIZE: 1 + } + WM_DANCE_WITH_WUG: { + MaxLevel: 5 + MI_RUSH_WINDMILL: 1 + MI_ECHOSONG: 1 + MI_HARMONIZE: 1 + } + WM_SOUND_OF_DESTRUCTION: { + MaxLevel: 5 + WM_SATURDAY_NIGHT_FEVER: 3 + WM_MELODYOFSINK: 3 + } + WM_SATURDAY_NIGHT_FEVER: { + MaxLevel: 5 + WM_DANCE_WITH_WUG: 1 + } + WM_LERADS_DEW: { + MaxLevel: 5 + MI_RUSH_WINDMILL: 1 + MI_ECHOSONG: 1 + MI_HARMONIZE: 1 + } + WM_MELODYOFSINK: { + MaxLevel: 5 + WM_SONG_OF_MANA: 1 + } + WM_BEYOND_OF_WARCRY: { + MaxLevel: 5 + WM_LERADS_DEW: 1 + } + WM_UNLIMITED_HUMMING_VOICE: { + MaxLevel: 5 + WM_SOUND_OF_DESTRUCTION: 1 + WM_BEYOND_OF_WARCRY: 1 + } + WM_FRIGG_SONG: { + MaxLevel: 5 + WM_LESSON: 1 + } + ALL_FULL_THROTTLE: 5 + } +} +Wanderer: { + inherit: ( "Dancer" ); + + skills: { + WA_SWING_DANCE: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WA_SYMPHONY_OF_LOVER: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WA_MOONLIT_SERENADE: { + MaxLevel: 5 + WM_LULLABY_DEEPSLEEP: 1 + } + WM_LESSON: 10 + WM_METALICSOUND: { + MaxLevel: 5 + WM_DOMINION_IMPULSE: 1 + } + WM_REVERBERATION: { + MaxLevel: 5 + DC_UGLYDANCE: 5 + } + WM_DOMINION_IMPULSE: { + MaxLevel: 1 + WM_REVERBERATION: 1 + } + WM_SEVERE_RAINSTORM: { + MaxLevel: 5 + DC_THROWARROW: 5 + } + WM_POEMOFNETHERWORLD: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_VOICEOFSIREN: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 3 + } + WM_DEADHILLHERE: { + MaxLevel: 5 + WM_SIRCLEOFNATURE: 3 + } + WM_LULLABY_DEEPSLEEP: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_SIRCLEOFNATURE: { + MaxLevel: 5 + WM_LESSON: 1 + } + WM_RANDOMIZESPELL: { + MaxLevel: 5 + WM_POEMOFNETHERWORLD: 1 + } + WM_GLOOMYDAY: { + MaxLevel: 5 + WM_RANDOMIZESPELL: 1 + } + WM_GREAT_ECHO: { + MaxLevel: 5 + WM_METALICSOUND: 1 + } + WM_SONG_OF_MANA: { + MaxLevel: 5 + WA_SWING_DANCE: 1 + WA_SYMPHONY_OF_LOVER: 1 + WA_MOONLIT_SERENADE: 1 + } + WM_DANCE_WITH_WUG: { + MaxLevel: 5 + WA_SWING_DANCE: 1 + WA_SYMPHONY_OF_LOVER: 1 + WA_MOONLIT_SERENADE: 1 + } + WM_SOUND_OF_DESTRUCTION: { + MaxLevel: 5 + WM_SATURDAY_NIGHT_FEVER: 3 + WM_MELODYOFSINK: 3 + } + WM_SATURDAY_NIGHT_FEVER: { + MaxLevel: 5 + WM_DANCE_WITH_WUG: 1 + } + WM_LERADS_DEW: { + MaxLevel: 5 + WA_SWING_DANCE: 1 + WA_SYMPHONY_OF_LOVER: 1 + WA_MOONLIT_SERENADE: 1 + } + WM_MELODYOFSINK: { + MaxLevel: 5 + WM_SONG_OF_MANA: 1 + } + WM_BEYOND_OF_WARCRY: { + MaxLevel: 5 + WM_LERADS_DEW: 1 + } + WM_UNLIMITED_HUMMING_VOICE: { + MaxLevel: 5 + WM_SOUND_OF_DESTRUCTION: 1 + WM_BEYOND_OF_WARCRY: 1 + } + WM_FRIGG_SONG: { + MaxLevel: 5 + WM_LESSON: 1 + } + ALL_FULL_THROTTLE: 5 + } +} +Sura: { + inherit: ( "Monk" ); + + skills: { + SR_DRAGONCOMBO: { + MaxLevel: 10 + MO_TRIPLEATTACK: 5 + } + SR_SKYNETBLOW: { + MaxLevel: 5 + SR_DRAGONCOMBO: 3 + } + SR_EARTHSHAKER: { + MaxLevel: 5 + SR_DRAGONCOMBO: 1 + SR_CURSEDCIRCLE: 1 + } + SR_FALLENEMPIRE: { + MaxLevel: 5 + SR_DRAGONCOMBO: 1 + } + SR_TIGERCANNON: { + MaxLevel: 10 + SR_FALLENEMPIRE: 3 + } + SR_RAMPAGEBLASTER: { + MaxLevel: 5 + SR_EARTHSHAKER: 2 + } + SR_CRESCENTELBOW: { + MaxLevel: 5 + SR_SKYNETBLOW: 1 + } + SR_CURSEDCIRCLE: { + MaxLevel: 5 + MO_BLADESTOP: 2 + SR_GENTLETOUCH_QUIET: 2 + } + SR_LIGHTNINGWALK: { + MaxLevel: 5 + SR_WINDMILL: 1 + } + SR_KNUCKLEARROW: { + MaxLevel: 5 + SR_RAMPAGEBLASTER: 3 + SR_LIGHTNINGWALK: 3 + } + SR_WINDMILL: { + MaxLevel: 1 + SR_CURSEDCIRCLE: 1 + } + SR_RAISINGDRAGON: { + MaxLevel: 10 + SR_RAMPAGEBLASTER: 3 + SR_GENTLETOUCH_ENERGYGAIN: 3 + } + SR_ASSIMILATEPOWER: { + MaxLevel: 1 + MO_ABSORBSPIRITS: 1 + SR_POWERVELOCITY: 1 + } + SR_POWERVELOCITY: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + } + SR_GATEOFHELL: { + MaxLevel: 10 + SR_TIGERCANNON: 5 + SR_RAISINGDRAGON: 5 + } + SR_GENTLETOUCH_QUIET: { + MaxLevel: 5 + SR_POWERVELOCITY: 1 + } + SR_GENTLETOUCH_CURE: { + MaxLevel: 5 + SR_POWERVELOCITY: 1 + } + SR_GENTLETOUCH_ENERGYGAIN: { + MaxLevel: 5 + SR_GENTLETOUCH_QUIET: 3 + } + SR_GENTLETOUCH_CHANGE: { + MaxLevel: 5 + SR_GENTLETOUCH_CURE: 4 + } + SR_GENTLETOUCH_REVITALIZE: { + MaxLevel: 5 + SR_GENTLETOUCH_CHANGE: 5 + } + SR_HOWLINGOFLION: { + MaxLevel: 5 + SR_ASSIMILATEPOWER: 1 + SR_RIDEINLIGHTNING: 3 + } + SR_RIDEINLIGHTNING: { + MaxLevel: 5 + MO_FINGEROFFENSIVE: 3 + } + SR_FLASHCOMBO: { + MaxLevel: 5 + SR_DRAGONCOMBO: 3 + SR_FALLENEMPIRE: 3 + SR_TIGERCANNON: 1 + SR_SKYNETBLOW: 1 + } + ALL_FULL_THROTTLE: 5 + } +} +Genetic: { + inherit: ( "Alchemist" ); + + skills: { + GN_TRAINING_SWORD: 5 + GN_REMODELING_CART: 5 + GN_CART_TORNADO: { + MaxLevel: 5 + GN_REMODELING_CART: 1 + } + GN_CARTCANNON: { + MaxLevel: 5 + GN_REMODELING_CART: 2 + } + GN_CARTBOOST: { + MaxLevel: 5 + GN_REMODELING_CART: 3 + } + GN_THORNS_TRAP: { + MaxLevel: 5 + GN_S_PHARMACY: 2 + } + GN_BLOOD_SUCKER: { + MaxLevel: 5 + GN_S_PHARMACY: 3 + } + GN_SPORE_EXPLOSION: { + MaxLevel: 5 + GN_S_PHARMACY: 4 + } + GN_WALLOFTHORN: { + MaxLevel: 5 + GN_THORNS_TRAP: 3 + } + GN_CRAZYWEED: { + MaxLevel: 10 + GN_WALLOFTHORN: 3 + } + GN_DEMONIC_FIRE: { + MaxLevel: 5 + GN_SPORE_EXPLOSION: 3 + } + GN_FIRE_EXPANSION: { + MaxLevel: 5 + GN_DEMONIC_FIRE: 3 + } + GN_HELLS_PLANT: { + MaxLevel: 5 + GN_BLOOD_SUCKER: 3 + } + GN_MANDRAGORA: { + MaxLevel: 5 + GN_HELLS_PLANT: 3 + } + GN_SLINGITEM: { + MaxLevel: 1 + GN_CHANGEMATERIAL: 1 + } + GN_CHANGEMATERIAL: 1 + GN_MIX_COOKING: { + MaxLevel: 2 + GN_S_PHARMACY: 1 + } + GN_MAKEBOMB: { + MaxLevel: 2 + GN_MIX_COOKING: 1 + } + GN_S_PHARMACY: 10 +// GN_ILLUSIONDOOPING: { +// MaxLevel: 5 +// GN_S_PHARMACY: 1 +// } + ALL_FULL_THROTTLE: 5 + } +} +Shadow_Chaser: { + inherit: ( "Rogue" ); + + skills: { + SC_FATALMENACE: { + MaxLevel: 5 + RG_INTIMIDATE: 5 + } + SC_REPRODUCE: { + MaxLevel: 10 + RG_PLAGIARISM: 5 + } + SC_AUTOSHADOWSPELL: { + MaxLevel: 10 + SC_REPRODUCE: 5 + } + SC_SHADOWFORM: { + MaxLevel: 5 + RG_TUNNELDRIVE: 3 + } + SC_TRIANGLESHOT: { + MaxLevel: 10 + AC_DOUBLE: 7 + } + SC_BODYPAINT: 5 + SC_INVISIBILITY: { + MaxLevel: 5 + SC_AUTOSHADOWSPELL: 7 + SC_DEADLYINFECT: 5 + SC_UNLUCKY: 3 + } + SC_DEADLYINFECT: { + MaxLevel: 5 + SC_AUTOSHADOWSPELL: 5 + SC_SHADOWFORM: 3 + } + SC_ENERVATION: { + MaxLevel: 3 + SC_BODYPAINT: 1 + } + SC_GROOMY: { + MaxLevel: 3 + SC_BODYPAINT: 1 + } + SC_IGNORANCE: { + MaxLevel: 3 + SC_BODYPAINT: 1 + } + SC_LAZINESS: { + MaxLevel: 3 + SC_ENERVATION: 1 + SC_GROOMY: 1 + SC_IGNORANCE: 1 + } + SC_UNLUCKY: { + MaxLevel: 3 + SC_LAZINESS: 1 + SC_WEAKNESS: 1 + } + SC_WEAKNESS: { + MaxLevel: 3 + SC_ENERVATION: 1 + SC_GROOMY: 1 + SC_IGNORANCE: 1 + } + SC_STRIPACCESSARY: { + MaxLevel: 5 + RG_STRIPWEAPON: 1 + } + SC_MANHOLE: { + MaxLevel: 3 + RG_FLAGGRAFFITI: 1 + } + SC_DIMENSIONDOOR: { + MaxLevel: 3 + SC_MANHOLE: 1 + } + SC_CHAOSPANIC: { + MaxLevel: 3 + SC_MANHOLE: 1 + } + SC_MAELSTROM: { + MaxLevel: 3 + SC_UNLUCKY: 3 + SC_CHAOSPANIC: 3 + } + SC_BLOODYLUST: { + MaxLevel: 3 + SC_DIMENSIONDOOR: 3 + } + SC_FEINTBOMB: { + MaxLevel: 3 + SC_DIMENSIONDOOR: 3 + } +// SC_SCAPE: { +// MaxLevel: 5 +// SC_TRIANGLESHOT: 2 +// } + ALL_FULL_THROTTLE: 5 + } +} +Royal_Guard_Trans: { + inherit: ( "Paladin", "Royal_Guard" ); +} +Sorcerer_Trans: { + inherit: ( "Professor", "Sorcerer" ); +} +Minstrel_Trans: { + inherit: ( "Clown", "Minstrel" ); +} +Wanderer_Trans: { + inherit: ( "Gypsy", "Wanderer" ); +} +Sura_Trans: { + inherit: ( "Champion", "Sura" ); +} +Genetic_Trans: { + inherit: ( "Creator", "Genetic" ); +} +Shadow_Chaser_Trans: { + inherit: ( "Stalker", "Shadow_Chaser" ); +} +Baby_Rune_Knight: { + inherit: ( "Rune_Knight" ); +} +Baby_Warlock: { + inherit: ( "Warlock" ); +} +Baby_Ranger: { + inherit: ( "Ranger" ); +} +Baby_Arch_Bishop: { + inherit: ( "Arch_Bishop" ); +} +Baby_Mechanic: { + inherit: ( "Mechanic" ); +} +Baby_Guillotine_Cross: { + inherit: ( "Guillotine_Cross" ); +} +Baby_Royal_Guard: { + inherit: ( "Royal_Guard" ); +} +Baby_Sorcerer: { + inherit: ( "Sorcerer" ); +} +Baby_Minstrel: { + inherit: ( "Minstrel" ); +} +Baby_Wanderer: { + inherit: ( "Wanderer" ); +} +Baby_Sura: { + inherit: ( "Sura" ); +} +Baby_Genetic: { + inherit: ( "Genetic" ); +} +Baby_Shadow_Chaser: { + inherit: ( "Shadow_Chaser" ); +} +Expanded_Super_Novice: { + inherit: ( "Super_Novice" ); + + skills: { + PR_IMPOSITIO: 5 + PR_SANCTUARY: { + MaxLevel: 10 + AL_HEAL: 1 + } + PR_STRECOVERY: 1 + PR_GLORIA: { + MaxLevel: 5 + PR_SANCTUARY: 7 + } + WZ_FIREPILLAR: { + MaxLevel: 10 + MG_FIREWALL: 1 + } + WZ_SIGHTRASHER: { + MaxLevel: 10 + MG_LIGHTNINGBOLT: 1 + MG_SIGHT: 1 + } + WZ_JUPITEL: { + MaxLevel: 10 + MG_NAPALMBEAT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_WATERBALL: { + MaxLevel: 5 + MG_COLDBOLT: 1 + MG_LIGHTNINGBOLT: 1 + } + WZ_ICEWALL: { + MaxLevel: 10 + MG_STONECURSE: 1 + MG_FROSTDIVER: 1 + } + WZ_FROSTNOVA: { + MaxLevel: 10 + WZ_ICEWALL: 1 + } + WZ_EARTHSPIKE: { + MaxLevel: 5 + MG_STONECURSE: 1 + } + WZ_HEAVENDRIVE: { + MaxLevel: 5 + WZ_EARTHSPIKE: 3 + } + WZ_QUAGMIRE: { + MaxLevel: 5 + WZ_HEAVENDRIVE: 1 + } + WZ_ESTIMATION: 1 + BS_HILTBINDING: 1 + BS_WEAPONRESEARCH: { + MaxLevel: 10 + BS_HILTBINDING: 1 + } + HT_SKIDTRAP: 5 + HT_SANDMAN: { + MaxLevel: 5 + HT_FLASHER: 1 + } + HT_FLASHER: { + MaxLevel: 5 + HT_SKIDTRAP: 1 + } + HT_FREEZINGTRAP: { + MaxLevel: 5 + HT_FLASHER: 1 + } + AS_ENCHANTPOISON: { + MaxLevel: 10 + TF_POISON: 1 + } + RG_TUNNELDRIVE: { + MaxLevel: 5 + TF_HIDING: 1 + } + AM_AXEMASTERY: 10 + CR_TRUST: 10 + CR_HOLYCROSS: { + MaxLevel: 10 + CR_TRUST: 7 + } + MO_IRONHAND: { + MaxLevel: 10 + AL_DEMONBANE: 10 + AL_DP: 10 + } + MO_CALLSPIRITS: { + MaxLevel: 5 + MO_IRONHAND: 2 + } + MO_ABSORBSPIRITS: { + MaxLevel: 1 + MO_CALLSPIRITS: 5 + } + HW_MAGICCRASHER: { + MaxLevel: 1 + MG_SRECOVERY: 1 + } + ALL_BUYING_STORE: { + MaxLevel: 1 + MC_VENDING: 1 + } + } +} +Expanded_Super_Baby: { + inherit: ( "Expanded_Super_Novice" ); +} +Kagerou: { + inherit: ( "Ninja" ); + + skills: { + KO_YAMIKUMO: { + MaxLevel: 1 + NJ_KIRIKAGE: 5 + } + KO_RIGHT: 5 + KO_LEFT: 5 + KO_JYUMONJIKIRI: { + MaxLevel: 5 + KO_YAMIKUMO: 1 + } + KO_SETSUDAN: { + MaxLevel: 5 + KO_JYUMONJIKIRI: 2 + } + KO_BAKURETSU: { + MaxLevel: 5 + NJ_KUNAI: 5 + } + KO_HAPPOKUNAI: { + MaxLevel: 5 + KO_BAKURETSU: 1 + } + KO_MUCHANAGE: { + MaxLevel: 10 + KO_MAKIBISHI: 3 + } + KO_HUUMARANKA: { + MaxLevel: 5 + NJ_HUUMA: 5 + } + KO_MAKIBISHI: { + MaxLevel: 5 + NJ_ZENYNAGE: 1 + } + KO_MEIKYOUSISUI: { + MaxLevel: 5 + NJ_NINPOU: 10 + } + KO_ZANZOU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_KYOUGAKU: { + MaxLevel: 5 + KO_GENWAKU: 2 + } + KO_JYUSATSU: { + MaxLevel: 5 + KO_KYOUGAKU: 3 + } + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + KO_KAIHOU: { + MaxLevel: 1 + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + } + KO_ZENKAI: { + MaxLevel: 1 + KO_KAIHOU: 1 + KO_IZAYOI: 1 + } + KO_GENWAKU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_IZAYOI: { + MaxLevel: 5 + NJ_NINPOU: 5 + } + KG_KAGEHUMI: { + MaxLevel: 5 + KO_ZANZOU: 1 + } + KG_KYOMU: { + MaxLevel: 5 + KG_KAGEHUMI: 2 + } + KG_KAGEMUSYA: { + MaxLevel: 5 + KG_KYOMU: 3 + } + } +} +Oboro: { + inherit: ( "Ninja" ); + + skills: { + KO_YAMIKUMO: { + MaxLevel: 1 + NJ_KIRIKAGE: 5 + } + KO_RIGHT: 5 + KO_LEFT: 5 + KO_JYUMONJIKIRI: { + MaxLevel: 5 + KO_YAMIKUMO: 1 + } + KO_SETSUDAN: { + MaxLevel: 5 + KO_JYUMONJIKIRI: 2 + } + KO_BAKURETSU: { + MaxLevel: 5 + NJ_KUNAI: 5 + } + KO_HAPPOKUNAI: { + MaxLevel: 5 + KO_BAKURETSU: 1 + } + KO_MUCHANAGE: { + MaxLevel: 10 + KO_MAKIBISHI: 3 + } + KO_HUUMARANKA: { + MaxLevel: 5 + NJ_HUUMA: 5 + } + KO_MAKIBISHI: { + MaxLevel: 5 + NJ_ZENYNAGE: 1 + } + KO_MEIKYOUSISUI: { + MaxLevel: 5 + NJ_NINPOU: 10 + } + KO_ZANZOU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_KYOUGAKU: { + MaxLevel: 5 + KO_GENWAKU: 2 + } + KO_JYUSATSU: { + MaxLevel: 5 + KO_KYOUGAKU: 3 + } + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + KO_KAIHOU: { + MaxLevel: 1 + KO_KAHU_ENTEN: 1 + KO_HYOUHU_HUBUKI: 1 + KO_KAZEHU_SEIRAN: 1 + KO_DOHU_KOUKAI: 1 + } + KO_ZENKAI: { + MaxLevel: 1 + KO_KAIHOU: 1 + KO_IZAYOI: 1 + } + KO_GENWAKU: { + MaxLevel: 5 + NJ_UTSUSEMI: 1 + } + KO_IZAYOI: { + MaxLevel: 5 + NJ_NINPOU: 5 + } + OB_ZANGETSU: { + MaxLevel: 5 + KO_GENWAKU: 1 + } + OB_OBOROGENSOU: { + MaxLevel: 5 + OB_AKAITSUKI: 3 + } + OB_AKAITSUKI: { + MaxLevel: 5 + OB_ZANGETSU: 2 + } + } +}
\ No newline at end of file diff --git a/db/sc_config.txt b/db/sc_config.txt index b0d0e5ba4..9007adcc2 100644 --- a/db/sc_config.txt +++ b/db/sc_config.txt @@ -3,6 +3,7 @@ // Structure of Database: // SC_NAME, flag // +<<<<<<< HEAD // flag 0x1 - SC cannot be removed by death. // 0x2 - SC cannot be saved. // 0x4 - SC cannot be reset by dispell. @@ -10,6 +11,17 @@ // 0x10 - SC considered as buff and be removed by Hermode and etc. // 0x20 - SC considered as debuff and be removed by Gospel and etc. // 0x40 - SC cannot be reset when MADO Gear is taken off. +======= +// flag 1 - SC cannot be removed by death. +// 2 - SC cannot be saved. +// 4 - SC cannot be reset by dispell. +// 8 - SC cannot be reset by clearance. +// 16 - SC considered as buff and be removed by Hermode and etc. +// 32 - SC considered as debuff and be removed by Gospel and etc. +// 64 - SC cannot be reset when MADO Gear is taken off. +//Example: +//SC_ENDURE, 21 //SC_ENDURE: cannot be removed by death and dispell and cosidered as buff. (16 + 4 + 1 = 21) +>>>>>>> upstream/master SC_PROVOKE, 32 SC_ENDURE, 21 diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index fce54b24e..ada0cf8ec 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -386,8 +386,8 @@ bonus2 bWeaponAtk,x,n; Adds n ATK when weapon of type x is equipped. bonus2 bWeaponAtkRate,x,n; Adds n% damage to normal attacks when weapon of type x is equipped. x: see doc/item_db.txt -> view -> weapons for possible values bonus bDelayrate,n; Increases skill delay by n%. -bonus3 bHPDrainRateRace,r,n,x; Adds a n/10% chance to receive x% of dealed damage as HP from a monster of race r with normal attack. -bonus3 bSPDrainRateRace,r,n,x; Adds a n/10% chance to receive x% of dealed damage as SP from a monster of race r with normal attack. +bonus3 bHPDrainRateRace,r,n,x; Adds a n/10% chance to receive x% of damage dealt as HP from a monster of race r with normal attack. +bonus3 bSPDrainRateRace,r,n,x; Adds a n/10% chance to receive x% of damage dealt as SP from a monster of race r with normal attack. bonus3 bAddEffOnSkill,s,x,n; Adds a n/100% chance to cause status change x on enemy when using skill s (supports skill names) bonus4 bAddEffOnSkill,s,x,n,t; Adds a n/100% chance to cause status change x when using skill s (supports skill names) t: ATF_SELF = causes status change to oneself diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 0441d385a..f6de42316 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -67,8 +67,7 @@ expression, like a bunch of functions or operators returning a value, in (round brackets) instead of most numbers. Round brackets will not always be required, but they're often a good idea. -Wherever you refer to a map name, it's always 'mapname' or 'mapname.gat' -(Please, don't use .gat suffix anymore. It's useless.) +Wherever you refer to a map, use 'mapname' instead of 'mapname.gat'. Script loading structure @@ -780,7 +779,7 @@ Logical bitwise operators work only on numbers, and they are the following: hand, it sets to 1 if they have different values in the said binary position. This is another way of setting and unsetting bits in bit-masks. - + Example: - First let's set the quests that are currently in progress: set inProgress,1|8|16; // quest 1,8 and 16 are in progress @@ -1793,93 +1792,93 @@ above. Anything that is returned by a function can be used in a condition check without bothering to store it in a specific variable: - if (strcharinfo(0)=="Daniel Jackson") mes "It is true, you are Daniel!"; + if (strcharinfo(0)=="Daniel Jackson") mes "It is true, you are Daniel!"; More examples of using the 'if' command in the real world: Example 1: - set @var1,1; - input @var2; - if(@var1==@var2) goto L_Same; - mes "Sorry that is wrong"; - close; - L_Same: - close; + set @var1,1; + input @var2; + if(@var1==@var2) goto L_Same; + mes "Sorry that is wrong"; + close; + L_Same: + close; Example 2: - - set @var1,1; - input @var2; - if(@var1!=@var2) mes "Sorry that is wrong"; - close; + + set @var1,1; + input @var2; + if(@var1!=@var2) mes "Sorry that is wrong"; + close; (Notice examples 1 and 2 have the same effect.) Example 3: - set @var1,@var1+1; - mes "[Forgetfull Man]"; - if (@var==1) mes "This is the first time you have talked to me"; - if (@var==2) mes "This is the second time you have talked to me"; - if (@var==3) mes "This is the third time you have talked to me"; - if (@var==4) mes "This is the forth time you have talked to me, but I think I am getting amnesia, I have forgotten about you"; - if (@var==4) set @var,0; - close; + set @var1,@var1+1; + mes "[Forgetfull Man]"; + if (@var==1) mes "This is the first time you have talked to me"; + if (@var==2) mes "This is the second time you have talked to me"; + if (@var==3) mes "This is the third time you have talked to me"; + if (@var==4) mes "This is the forth time you have talked to me, but I think I am getting amnesia, I have forgotten about you"; + if (@var==4) set @var,0; + close; Example 4: - mes "[Quest Person]"; - if(countitem(512)>=1) goto L_GiveApple; - // The number 512 was found from item_db, it is the item number - // for the Apple. - mes "Can you please bring me an apple?"; - close; - L_GiveApple: - mes "Oh an apple, I didn't want it, I just wanted to see one"; - close; + mes "[Quest Person]"; + if(countitem(512)>=1) goto L_GiveApple; + // The number 512 was found from item_db, it is the item number + // for the Apple. + mes "Can you please bring me an apple?"; + close; + L_GiveApple: + mes "Oh an apple, I didn't want it, I just wanted to see one"; + close; Example 5: - mes "[Person Checker]"; - if($name$!=null) goto L_Check; - mes "Please tell me someones name"; - next; - input $name$; - set $name2$,strcharinfo(0); - mes "[Person Checker]"; - mes "Thank you"; - L_Check: - if($name$==strcharinfo(0) ) goto L_SameName; - mes "[Person Checker]"; - mes "You are not the person that " +$name2$+ " mentioned"; - L_End: - set $name$,null; - set $name2$,null; - close; - L_SameName: - mes "[Person Checker]"; - mes "You are the person that " +$name2$+ " just mentioned"; - mes "nice to meet you"; - goto L_End; + mes "[Person Checker]"; + if($name$!=null) goto L_Check; + mes "Please tell me someones name"; + next; + input $name$; + set $name2$,strcharinfo(0); + mes "[Person Checker]"; + mes "Thank you"; + L_Check: + if($name$==strcharinfo(0) ) goto L_SameName; + mes "[Person Checker]"; + mes "You are not the person that " +$name2$+ " mentioned"; + L_End: + set $name$,null; + set $name2$,null; + close; + L_SameName: + mes "[Person Checker]"; + mes "You are the person that " +$name2$+ " just mentioned"; + mes "nice to meet you"; + goto L_End; See 'strcharinfo' for explanation of what this function does. Example 6: Using complex conditions. - mes "[Multi Checker]"; - if( (@queststarted==1) && (countitem(512)>=5) ) goto L_MultiCheck; - // Only if the quest has been started AND You have 5 apples will it goto "L_MultiCheck" - mes "Please get me 5 apples"; - set @queststarted,1; - close; - L_MultiCheck: - mes "[Multi Checker]"; - mes "Well done you have started the quest of got me 5 apples"; - mes "Thank you"; - set @queststarted,0; - delitem 512,5; - close; + mes "[Multi Checker]"; + if( (@queststarted==1) && (countitem(512)>=5) ) goto L_MultiCheck; + // Only if the quest has been started AND You have 5 apples will it goto "L_MultiCheck" + mes "Please get me 5 apples"; + set @queststarted,1; + close; + L_MultiCheck: + mes "[Multi Checker]"; + mes "Well done you have started the quest of got me 5 apples"; + mes "Thank you"; + set @queststarted,0; + delitem 512,5; + close; With the Advanced scripting engine, we got nested if's. That is: @@ -2042,7 +2041,7 @@ Example: dothis; // will sleep the script for 1ms when detect an infinity loop to // let Hercules do what it need to do (socket, timer, process, - // etc.) + // etc.) } freeloop(0); // disable @@ -2059,14 +2058,14 @@ Example: This command will allow you to quickly fill up an array in one go. Check the Kafra scripts in the distribution to see this used a lot. - setarray @array[0], 100, 200, 300, 400, 500, 600; + setarray @array[0], 100, 200, 300, 400, 500, 600; First value is the index of the first element of the array to alter. For example: - setarray @array[0],200,200,200; - setarray @array[1],300,150; - + setarray @array[0],200,200,200; + setarray @array[1],300,150; + will produce: @array[0]=200 @@ -2080,13 +2079,13 @@ will produce: This command will change many array values at the same time to the same value. - setarray @array[0], 100, 200, 300, 400, 500, 600; - // This will make all 6 values 0 - cleararray @array[0],0,6; - // This will make array element 0 change to 245 - cleararray @array[0],245,1; - // This will make elements 1 and 2 change to 345 - cleararray @array[1],345,2; + setarray @array[0], 100, 200, 300, 400, 500, 600; + // This will make all 6 values 0 + cleararray @array[0],0,6; + // This will make array element 0 change to 245 + cleararray @array[0],245,1; + // This will make elements 1 and 2 change to 345 + cleararray @array[1],345,2; See 'setarray'. @@ -2097,12 +2096,12 @@ See 'setarray'. This command lets you quickly shuffle a lot of data between arrays, which is in some cases invaluable. - setarray @array[0], 100, 200, 300, 400, 500, 600; - // So we have made @array[] - copyarray @array2[0],@array[2],2; - - // Now, @array2[0] will be equal to @array[2] (300) and - // @array2[1] will be equal to @array[3]. + setarray @array[0], 100, 200, 300, 400, 500, 600; + // So we have made @array[] + copyarray @array2[0],@array[2],2; + + // Now, @array2[0] will be equal to @array[2] (300) and + // @array2[1] will be equal to @array[3]. So using the examples above: @array[0] = 100 @@ -2128,14 +2127,13 @@ and it will return a 0. This command will delete a specified number of array elements totally from an array, shifting all the elements beyond this towards the beginning. - // This will delete array element 0, and move all the other array - // elements up one place. - deletearray @array[0],1 - -// This would delete array elements numbered 1, 2 and 3, leave element 0 -// in its place, and move the other elements ups, so there are no gaps. + // This will delete array element 0, and move all the other array + // elements up one place. + deletearray @array[0],1 - deletearray @array[1],3 + // This would delete array elements numbered 1, 2 and 3, leave element 0 + // in its place, and move the other elements ups, so there are no gaps. + deletearray @array[1],3 --------------------------------------- @@ -2180,14 +2178,14 @@ array are not counted towards this number. For example: - setarray @array[0], 100, 200, 300, 400, 500, 600; - set @arraysize,getarraysize(@array); + setarray @array[0], 100, 200, 300, 400, 500, 600; + set @arraysize,getarraysize(@array); This will make @arraysize == 6. But if you try this: - setarray @array[0], 100, 200, 300, 400, 500, 600, 0; - set @arraysize,getarraysize(@array); - + setarray @array[0], 100, 200, 300, 400, 500, 600, 0; + set @arraysize,getarraysize(@array); + @arraysize will still equal 6, even though you've set 7 values. --------------------------------------- @@ -2197,15 +2195,15 @@ This will make @arraysize == 6. But if you try this: This command retrieves the value of the element of given array at given index. This is equivalent to using: - <array name>[<index>] + <array name>[<index>] The reason for this is, that this short form is internally converted into a call to getelementofarray, when the script is loaded. Also useful when passing arrays to functions or accessing another npc's arrays: - getelementofarray(getarg(0),<index>) - getelementofarray(getvariableofnpc(.var, "testNPC"),<index>) + getelementofarray(getarg(0),<index>) + getelementofarray(getvariableofnpc(.var, "testNPC"),<index>) --------------------------------------- @@ -2226,20 +2224,20 @@ All of these also behave as variables, but don't expect to be able to just Example 1: - // Returns how many status points you haven't spent yet. - mes "Unused status points: "+readparam(9); + // Returns how many status points you haven't spent yet. + mes "Unused status points: "+readparam(9); Using this particular information as a function call is not required. Typing this will return the same result: - mes "Unused status points: "+StatusPoint; + mes "Unused status points: "+StatusPoint; Example 2: You can also use this command to get stat values. - if (readparam(bVit) > 77) - mes "Only people with over 77 Vit are reading this!"; + if (readparam(bVit) > 77) + mes "Only people with over 77 Vit are reading this!"; --------------------------------------- @@ -2278,7 +2276,7 @@ Retrieves IDs of the currently invoked NPC. If a unique npc name is given, IDs of that NPC are retrieved instead. Type specifies what ID to retrieve and can be one of the following: - 0 - Unit ID (GID) + 0 - Unit ID (GID) If an invalid type is given or the NPC does not exist, 0 is returned. @@ -2291,7 +2289,7 @@ If an invalid type is given or the NPC does not exist, 0 is returned. These functions return the character ID of the attached player's child, mother, mother, or father, respectively. It returns 0 if no ID is found. - if (getmotherid()) mes "Your mother's ID is: "+getmotherid(); + if (getmotherid()) mes "Your mother's ID is: "+getmotherid(); --------------------------------------- @@ -2308,8 +2306,8 @@ This function returns the character ID of the invoking character's marriage partner, if any. If the invoking character is not married, it will return 0, which is a quick way to see if they are married: - if (!getpartnerid()) mes "I'm not going to be your girlfriend!"; - if (getpartnerid()) mes "You're married already!"; + if (!getpartnerid()) mes "I'm not going to be your girlfriend!"; + if (getpartnerid()) mes "You're married already!"; --------------------------------------- @@ -2320,9 +2318,9 @@ number. If there is no such party ID, "null" will be returned. Lets say the ID of a party was saved as a global variable: - // This would return the name of the party from the ID stored in a - // variable - mes "You're in the '"+getpartyname($@var)+"' party, I know!"; + // This would return the name of the party from the ID stored in a + // variable + mes "You're in the '"+getpartyname($@var)+"' party, I know!"; --------------------------------------- @@ -2371,9 +2369,9 @@ Example 1: list party member names // It's a good idea to copy the global temporary $@partymember***** // variables to your own scope variables because if you have pauses in - // this script (sleep, sleep2, next, close2, input, menu, select, or - // prompt), another player could click this NPC, trigger - // 'getpartymember', and overwrite the $@partymember***** variables. + // this script (sleep, sleep2, next, close2, input, menu, select, or + // prompt), another player could click this NPC, trigger + // 'getpartymember', and overwrite the $@partymember***** variables. set .@count, $@partymembercount; copyarray .@name$[0], $@partymembername$[0], $@partymembercount; @@ -2402,10 +2400,10 @@ Example 2: check party count (with a 'next' pause), before warping to event if ( isloggedin( $@partymemberaid[.@i], $@partymembercid[.@i] ) ) set .@count_online, .@count_online +1 ; // We search accountID & charID because a single party can have - // multiple characters from the same account. Without searching - // through the charID, if a player has 2 characters from the same - // account inside the party but only 1 char online, it would count - // their online char twice. + // multiple characters from the same account. Without searching + // through the charID, if a player has 2 characters from the same + // account inside the party but only 1 char online, it would count + // their online char twice. if ( .@count_online != .register_num ) { mes "All your party members must be online to continue"; @@ -2420,9 +2418,9 @@ Example 2: check party count (with a 'next' pause), before warping to event select "Yes"; // When a script hits a next, menu, sleep or input that pauses the - // script, players can invite or /leave and make changes in their - // party. To prevent this, we call getpartymember again and compare - // with the original values. + // script, players can invite or /leave and make changes in their + // party. To prevent this, we call getpartymember again and compare + // with the original values. getpartymember getcharid(1), 1; if ( $@partymembercount != .register_num ) { @@ -2529,33 +2527,33 @@ for either slot. Can be used to check if you have something equipped, or if you haven't got something equipped: - if(getequipid(EQI_HEAD_TOP)==2234) goto L_WearingTiara; - mes "Come back when you have a Tiara on"; - close; - L_WearingTiara: - mes "What a lovely Tiara you have on"; - close; + if(getequipid(EQI_HEAD_TOP)==2234) goto L_WearingTiara; + mes "Come back when you have a Tiara on"; + close; + L_WearingTiara: + mes "What a lovely Tiara you have on"; + close; You can also use it to make sure people don't pass a point before removing an item totally from them. Let's say you don't want people to wear Legion Plate armor, but also don't want them to equip if after the check, you would do this: - if ((getequipid(EQI_ARMOR) == 2341) || (getequipid(EQI_ARMOR) == 2342) goto L_EquipedLegionPlate; - // the || is used as an or argument, there is 2341 and 2342 cause - // there are two different legion plate armors, one with a slot one - // without. - if ((countitem(2341) > 0) || (countitem(2432) > 0) goto L_InventoryLegionPlate; - mes "I will lets you pass"; - close2; - warp "place",50,50; - end; - L_EquipedLegionPlate: - mes "You are wearing some Legion Plate Armor, please drop that in your stash before continuing"; - close; - L_InventoryLegionPlate: - mes "You have some Legion Plate Armor in your inventory, please drop that in your stash before continuing"; - close; + if ((getequipid(EQI_ARMOR) == 2341) || (getequipid(EQI_ARMOR) == 2342) goto L_EquipedLegionPlate; + // the || is used as an or argument, there is 2341 and 2342 cause + // there are two different legion plate armors, one with a slot one + // without. + if ((countitem(2341) > 0) || (countitem(2432) > 0) goto L_InventoryLegionPlate; + mes "I will lets you pass"; + close2; + warp "place",50,50; + end; + L_EquipedLegionPlate: + mes "You are wearing some Legion Plate Armor, please drop that in your stash before continuing"; + close; + L_InventoryLegionPlate: + mes "You have some Legion Plate Armor in your inventory, please drop that in your stash before continuing"; + close; --------------------------------------- @@ -2568,10 +2566,10 @@ Does the same thing as getitemname(getequipid()). Useful for an NPC to state what your are wearing, or maybe saving as a string variable. See 'getequipid' for a full list of valid equipment slots. - if( getequipname(EQI_HEAD_TOP) != "" ) - mes "So you are wearing a "+getequipname(EQI_HEAD_TOP)+" on your head"; + if( getequipname(EQI_HEAD_TOP) != "" ) + mes "So you are wearing a "+getequipname(EQI_HEAD_TOP)+" on your head"; else - mes "You are not wearing any head gear"; + mes "You are not wearing any head gear"; --------------------------------------- @@ -2591,12 +2589,12 @@ may have several broken items, 1 given as an argument will return the first one found, 2 will return the second one, etc. Will return 0 if no such item is found. - // Let's see if they have anything broken: - if (getbrokenid(1)==0) goto Skip; - // They do, so let's print the name of the first broken item: - mes "Oh, I see you have a broken "+getitemname(getbrokenid(1))+" here!"; - Skip: - mes "You don't have anything broken, quit bothering me."; + // Let's see if they have anything broken: + if (getbrokenid(1)==0) goto Skip; + // They do, so let's print the name of the first broken item: + mes "Oh, I see you have a broken "+getitemname(getbrokenid(1))+" here!"; + Skip: + mes "You don't have anything broken, quit bothering me."; --------------------------------------- @@ -2606,14 +2604,14 @@ This functions will return 1 if there is an equipment placed on the specified equipment slot and 0 otherwise. For a list of equipment slots see 'getequipid'. Function originally used by the refining NPCs: - if (getequipisequiped(EQI_HEAD_TOP)) goto L_equipped; - mes "[Refiner]"; - mes "Do you want me to refine your dumb head?"; - close; - L_equipped: - mes "[Refiner]"; - mes "That's a fine hat you are wearing there..."; - close; + if (getequipisequiped(EQI_HEAD_TOP)) goto L_equipped; + mes "[Refiner]"; + mes "Do you want me to refine your dumb head?"; + close; + L_equipped: + mes "[Refiner]"; + mes "That's a fine hat you are wearing there..."; + close; --------------------------------------- @@ -2623,14 +2621,14 @@ Will return 1 if the item equipped on the invoking character in the specified equipment slot is refinable, and 0 if it isn't. For a list of equipment slots see 'getequipid'. - if (getequipisenableref(EQI_HEAD_TOP)) goto L_Refine; - mes "[Refiner]"; - mes "I can't refine this hat!..."; - close; - L_Refine: - mes "[Refiner]"; - mes "Ok I can refine this"; - close; + if (getequipisenableref(EQI_HEAD_TOP)) goto L_Refine; + mes "[Refiner]"; + mes "I can't refine this hat!..."; + close; + L_Refine: + mes "[Refiner]"; + mes "Ok I can refine this"; + close; --------------------------------------- @@ -2642,11 +2640,11 @@ equipment slot. For a list of equipment slots see 'getequipid'. Can be used to check if you have reached a maximum refine value, default for this is +10: - if(getequiprefinerycnt(EQI_HEAD_TOP) < 10) goto L_Refine_HeadGear; - mes "Sorry, it's not possible to refine hats better than +10"; - close; - L_Refine_HeadGear: - mes "I will now upgrade your "+getequipname(EQI_HEAD_TOP); + if(getequiprefinerycnt(EQI_HEAD_TOP) < 10) goto L_Refine_HeadGear; + mes "Sorry, it's not possible to refine hats better than +10"; + close; + L_Refine_HeadGear: + mes "I will now upgrade your "+getequipname(EQI_HEAD_TOP); --------------------------------------- @@ -2666,28 +2664,28 @@ according to the database, 0 will be returned. Examples: // Right hand can only contain a weapon. - switch (getequipweaponlv(EQI_HAND_R)) { - case 1: mes "You are holding a lvl 1 weapon."; break; - case 2: mes "You are holding a lvl 2 weapon."; break; - case 3: mes "You are holding a lvl 3 weapon."; break; - case 4: mes "You are holding a lvl 4 weapon."; break; - case 5: mes "You are holding a lvl 5 weapon, hm, must be a custom design..."; break; - default: mes "Seems you don't have a weapon on."; break; - } + switch (getequipweaponlv(EQI_HAND_R)) { + case 1: mes "You are holding a lvl 1 weapon."; break; + case 2: mes "You are holding a lvl 2 weapon."; break; + case 3: mes "You are holding a lvl 3 weapon."; break; + case 4: mes "You are holding a lvl 4 weapon."; break; + case 5: mes "You are holding a lvl 5 weapon, hm, must be a custom design..."; break; + default: mes "Seems you don't have a weapon on."; break; + } // Left hand can hold either a weapon or shield. - if (getequipid(EQI_HAND_R) == 0) { - mes "Seems you have nothing equipped here."; - close; - } - switch (getequipweaponlv(EQI_HAND_L)) { - case 0: mes "You are holding a shield, so it doesn't have a level."; break; - case 1: mes "You are holding a lvl 1 weapon."; break; - case 2: mes "You are holding a lvl 2 weapon."; break; - case 3: mes "You are holding a lvl 3 weapon."; break; - case 4: mes "You are holding a lvl 4 weapon."; break; - case 5: mes "You are holding a lvl 5 weapon, hm, must be a custom design..."; break; - } + if (getequipid(EQI_HAND_R) == 0) { + mes "Seems you have nothing equipped here."; + close; + } + switch (getequipweaponlv(EQI_HAND_L)) { + case 0: mes "You are holding a shield, so it doesn't have a level."; break; + case 1: mes "You are holding a lvl 1 weapon."; break; + case 2: mes "You are holding a lvl 2 weapon."; break; + case 3: mes "You are holding a lvl 3 weapon."; break; + case 4: mes "You are holding a lvl 4 weapon."; break; + case 5: mes "You are holding a lvl 5 weapon, hm, must be a custom design..."; break; + } --------------------------------------- @@ -2705,7 +2703,7 @@ with it (which is what the official NPC refinery scripts use it for). // This will find a random number from 0 - 99 and if that is equal to or // more than the value recovered by this command it will go to L_Fail - if (getequippercentrefinery(EQI_HAND_L)<=rand(100)) goto L_Fail; + if (getequippercentrefinery(EQI_HAND_L)<=rand(100)) goto L_Fail; --------------------------------------- @@ -2774,7 +2772,7 @@ This function will return the number of cards inserted into the weapon currently equipped on the invoking character. While this function was meant for item scripts, it will work outside them: - if (cardscnt()==4) mes "So you've stuck four cards into that weapon, think you're cool now?"; + if (cardscnt()==4) mes "So you've stuck four cards into that weapon, think you're cool now?"; --------------------------------------- @@ -2783,7 +2781,7 @@ While this function was meant for item scripts, it will work outside them: This function will return the refine count of the equipment from which the function is called. This function is intended for use in item scripts. - if (getrefine()==10) mes "Wow. That's a murder weapon."; + if (getrefine()==10) mes "Wow. That's a murder weapon."; --------------------------------------- @@ -2864,14 +2862,14 @@ parameters given were not variables or the search was not successful. Type is the type of object to search for: - 0 - Character object - 1 - NPC object - 2 - Pet object - 3 - Monster object - 4 - Homunculus object - 5 - Mercenary object - 6 - Elemental object - + 0 - Character object + 1 - NPC object + 2 - Pet object + 3 - Monster object + 4 - Homunculus object + 5 - Mercenary object + 6 - Elemental object + While 3 is meant to look for a monster object, no searching will be done if you specify type 3, and the function will always return -1. @@ -2885,22 +2883,22 @@ string, it will NOT locate a pet by name. What a mess. Example, a working and tested one now: - prontera,164,301,3%TAB%script%TAB%Meh%TAB%730,{ - mes "My name is Meh. I'm here so that Nyah can find me."; - close; - } - - prontera,164,299,3%TAB%script%TAB%Nyah%TAB%730,{ - mes "My name is Nyah."; - mes "I will now search for Meh all across the world!"; - if (getmapxy(@mapname$,@mapx,@mapy,1,"Meh")!=0) goto Notfound; - mes "And I found him on map "+@mapname$+" at X:"+@mapx+" Y:"+@mapy+" !"; - close; - Notfound: - mes "I can't seem to find Meh anywhere!"; - close; - } - + prontera,164,301,3%TAB%script%TAB%Meh%TAB%730,{ + mes "My name is Meh. I'm here so that Nyah can find me."; + close; + } + + prontera,164,299,3%TAB%script%TAB%Nyah%TAB%730,{ + mes "My name is Nyah."; + mes "I will now search for Meh all across the world!"; + if (getmapxy(@mapname$,@mapx,@mapy,1,"Meh")!=0) goto Notfound; + mes "And I found him on map "+@mapname$+" at X:"+@mapx+" Y:"+@mapy+" !"; + close; + Notfound: + mes "I can't seem to find Meh anywhere!"; + close; + } + Notice that NPC objects disabled with 'disablenpc' will still be located. --------------------------------------- @@ -2915,8 +2913,8 @@ account has no GM level. This allows you to make NPC's only accessible for certain GM levels, or behave specially when talked to by GMs. - if (getgmlevel()) mes "What is your command, your godhood?"; - if (getgmlevel()) goto Wherever; + if (getgmlevel()) mes "What is your command, your godhood?"; + if (getgmlevel()) goto Wherever; --------------------------------------- @@ -2959,7 +2957,7 @@ This function returns specified information about the current system time. It will only return numbers. - if (gettime(4)==6) mes "It's a Saturday. I don't work on Saturdays."; + if (gettime(4)==6) mes "It's a Saturday. I don't work on Saturdays."; --------------------------------------- @@ -2976,8 +2974,8 @@ Max length is the maximum length of a time string to generate. The example given in Hercules sample scripts works like this: - mes gettimestr("%Y-%m/%d %H:%M:%S",21); - + mes gettimestr("%Y-%m/%d %H:%M:%S",21); + This will print a full date and time like 'YYYY-MM/DD HH:MM:SS'. --------------------------------------- @@ -2989,10 +2987,10 @@ What it returns is specified by Type. Type can be one of the following values, which control what is returned: - 0 - Count of all characters on the map of the invoking character. - 1 - Count of all characters in the entire server. - 8 - Count of all characters on the map of the NPC the script is - running in. + 0 - Count of all characters on the map of the invoking character. + 1 - Count of all characters in the entire server. + 8 - Count of all characters on the map of the NPC the script is + running in. --------------------------------------- @@ -3036,12 +3034,12 @@ You need to put a 'close' after that yourself. This function returns a guild's name given an ID number. If there is no such guild, "null" will be returned; - // Would print whatever guild 10007 name is. - mes "The guild "+GetGuildName(10007)+" are all nice people."; + // Would print whatever guild 10007 name is. + mes "The guild "+GetGuildName(10007)+" are all nice people."; - // This will do the same as above: - set @var,10007; - mes "We have some friends in "+GetGuildName(@var)+", you know."; + // This will do the same as above: + set @var,10007; + mes "We have some friends in "+GetGuildName(@var)+", you know."; This is used all over the WoE controlling scripts. You could also use it for a guild-based event. @@ -3054,24 +3052,24 @@ This function return the name of the master of the guild which has the specified ID number. If there is no such guild, "null" will be returned. // Would return the guild master of guild 10007, whatever that might be. - mes getguildmaster(10007)+" runs "+getguildname(10007); + mes getguildmaster(10007)+" runs "+getguildname(10007); Can be used to check if the character is the guild master of the specified guild. Maybe you want to make a room only guild masters can enter: - set @GID,getcharid(2); - if(@GID==0) goto L_NoGuild; - if(strcharinfo(0)==getguildmaster(@GID)) goto L_GuildMaster; - mes "Sorry you don't own the guild you are in"; - close; - L_NoGuild: - mes "Sorry you are not in a guild"; - close; - L_GuildMaster: - mes "Welcome guild master of "+GetGuildName(@GID); - close; + set @GID,getcharid(2); + if(@GID==0) goto L_NoGuild; + if(strcharinfo(0)==getguildmaster(@GID)) goto L_GuildMaster; + mes "Sorry you don't own the guild you are in"; + close; + L_NoGuild: + mes "Sorry you are not in a guild"; + close; + L_GuildMaster: + mes "Welcome guild master of "+GetGuildName(@GID); + close; --------------------------------------- @@ -3182,25 +3180,25 @@ enough. Example 1: - if (getskilllv(152)) goto L_HasSkillThrowStone; - mes "You don't have Throw Stone"; - close; - L_HasSkillThrowStone: - mes "You have got the skill Throw Stone"; - close; + if (getskilllv(152)) goto L_HasSkillThrowStone; + mes "You don't have Throw Stone"; + close; + L_HasSkillThrowStone: + mes "You have got the skill Throw Stone"; + close; Example 2: - if (getskilllv(28) >= 5) goto L_HasSkillHeallvl5orMore; - if (getskilllv(28) == 10) goto L_HasSkillHealMaxed; - mes "You heal skill is below lvl 5"; - close; - L_HasSkillHeallvl6orMore: - mes "Your heal lvl is 5 or more"; - close; - L_HasSkillHealMaxed: - mes "Your heal lvl has been maxed"; - close; + if (getskilllv(28) >= 5) goto L_HasSkillHeallvl5orMore; + if (getskilllv(28) == 10) goto L_HasSkillHealMaxed; + mes "You heal skill is below lvl 5"; + close; + L_HasSkillHeallvl6orMore: + mes "Your heal lvl is 5 or more"; + close; + L_HasSkillHealMaxed: + mes "Your heal lvl has been maxed"; + close; --------------------------------------- @@ -3325,9 +3323,9 @@ Example: if (getmobdrops(.@mob_id)) { // 'getmobdrops' returns 1 on success // immediately copy global temporary variables into scope - // variables, since we don't know when 'getmobdrops' will get - // called again for another mob, overwriting your global temporary - // variables. + // variables, since we don't know when 'getmobdrops' will get + // called again for another mob, overwriting your global temporary + // variables. set .@count, $@MobDrop_count; copyarray .@item[0],$@MobDrop_item[0],.@count; copyarray .@rate[0],$@MobDrop_rate[0],.@count; @@ -3373,8 +3371,8 @@ invoking character, in percent, modified by the their current defense against said status. The 'base rate' is the base chance of the status effect being inflicted, in percent. - if (rand(100) > getscrate(Eff_Blind, 50)) goto BlindHimNow; - + if (rand(100) > getscrate(Eff_Blind, 50)) goto BlindHimNow; + You can see the full list of available effect types you can possibly inflict in 'db/const.txt' under 'Eff_'. @@ -3551,7 +3549,7 @@ Note: the character needs to have the skill HT_FALCON to gain a falcon. The accompanying function will return 1 if the invoking character has a falcon and 0 if they don't. - if (checkfalcon()) mes "But you already have a falcon!"; + if (checkfalcon()) mes "But you already have a falcon!"; --------------------------------------- @@ -3568,7 +3566,7 @@ Note: the character needs to have the skill KN_RIDING to gain a mount. The accompanying function will return 1 if the invoking character is riding a bird and 0 if they aren't. - if (checkriding()) mes "PLEASE leave your bird outside! No riding birds on the floor here!"; + if (checkriding()) mes "PLEASE leave your bird outside! No riding birds on the floor here!"; --------------------------------------- @@ -3586,7 +3584,7 @@ If the character can mount a dragon, the <color> options are: 5 - Red Dragon Note: the character must be a Rune Knight and have the skill - RK_DRAGONTRAINING to gain a mount. + RK_DRAGONTRAINING to gain a mount. The accompanying function will return 1 if the invoking character is riding a dragon and 0 if they aren't. @@ -3611,7 +3609,7 @@ The 'setmounting' function toggles cash mount for the invoking character. It will return 1 if successful, 0 otherwise. Note: Character must not be mounting a non-cash mount (eg. dragon, peco, - wug, etc.) + wug, etc.) The accompanying function will return 1 if the invoking character has a cash mount and 0 if they don't. @@ -3640,7 +3638,7 @@ Return values for 'checkvending' are Examples: //This will check if Aaron is vending, and if so, put a message in - //front of the attached player saying Aaron is vending. + //front of the attached player saying Aaron is vending. if (checkvending("Aaron")) mes "Aaron is currently vending!"; @@ -3674,9 +3672,9 @@ night mode or day mode. 'isnight' returns 1 if it's night and 0 if it isn't, 'isday' the other way around. They can be used interchangeably, pick the one you like more: - // These two are equivalent: - if (isday()) mes "I only prowl in the night."; - if (isnight()!=1) mes "I only prowl in the night."; + // These two are equivalent: + if (isday()) mes "I only prowl in the night."; + if (isnight()!=1) mes "I only prowl in the night."; --------------------------------------- @@ -3708,11 +3706,11 @@ Theoretically there is no limit to the number of items that may be tested for at the same time. If even one of the items given is not equipped, 0 will be returned. - // (Poring,Santa Poring,Poporing,Marin) - if (isequipped(4001,4005,4033,4196)) mes "Wow! You're wearing a full complement of possible poring cards!"; - // (Poring) - if (isequipped(4001)) mes "A poring card is useful, don't you think?"; - + // (Poring,Santa Poring,Poporing,Marin) + if (isequipped(4001,4005,4033,4196)) mes "Wow! You're wearing a full complement of possible poring cards!"; + // (Poring) + if (isequipped(4001)) mes "A poring card is useful, don't you think?"; + The function was meant for item scripts to support the cards released by Gravity in February 2005, but it will work just fine in normal NPC scripts. @@ -3724,7 +3722,7 @@ This function is similar to 'isequipped', but instead of 1 or 0, it will return the number of cards in the list given that were found on the invoking character. - if (isequippedcnt(4001,4005,4033,4196) == 4) mes "Finally got all four poring cards?"; + if (isequippedcnt(4001,4005,4033,4196) == 4) mes "Finally got all four poring cards?"; --------------------------------------- @@ -3801,13 +3799,13 @@ chat window. This command will take the invoking character to the specified map, and if wanted, specified coordinates too, but these can be random. - warp "place",50,55; + warp "place",50,55; This would take them to X 50 Y 55 on the map called "place". If your X and Y coordinates land on an unwalkable map square, it will send the warped character to a random place. Same will happen if they are both zero: - warp "place",0,0; + warp "place",0,0; Notice that while warping people to coordinates 0,0 will normally get them into a random place, it's not certain to always be so. Darned if I know @@ -3829,19 +3827,19 @@ defined by the x1/y1-x2/y2 square, will be warped. Nobody outside the area will be affected, including the activating character, if they are outside the area. - areawarp "place",10,10,120,120,"place2",150,150; + areawarp "place",10,10,120,120,"place2",150,150; Everyone that is in the area between X 10 Y 10 and X 120 Y 120, in a square shape, on the map called "place", will be affected, and warped to "place2" X 150 Y 150. - areawarp "place",10,10,120,120,"place2",0,0; + areawarp "place",10,10,120,120,"place2",0,0; By using ,0,0; as the destination coordinates it will take all the characters in the affected area to a random set of co-ordinates on the "place2" map. - areawarp "place",10,10,120,120,"place2",150,150,200,200; + areawarp "place",10,10,120,120,"place2",150,150,200,200; By using the optional x4 and y4 parameters, the destination coordinates will be a random place within the defined x3/y3-x4/y4 square. @@ -3860,15 +3858,15 @@ you can get with getcharid(1). You can also request another party id given a member's name with getcharid(1,<player_name>). You can use the following "map names" for special warping behavior: -Random: All party members are randomly warped in their current map - (as if they all used a fly wing). -SavePointAll: All party members are warped to their respective save point. -SavePoint: All party members are warped to the save point of the - currently attached player (will fail if there's no player - attached). -Leader: All party members are warped to the leader's position. The - leader must be online and in the current map-server for this - to work. +Random: All party members are randomly warped in their current map + (as if they all used a fly wing). +SavePointAll: All party members are warped to their respective save point. +SavePoint: All party members are warped to the save point of the + currently attached player (will fail if there's no player + attached). +Leader: All party members are warped to the leader's position. The + leader must be online and in the current map-server for this + to work. If you specify a from_mapname, warpparty will only affect those on that map. @@ -3881,38 +3879,38 @@ close2; set @id,getcharid(1); warpparty "prontera",150,100,@id; close; - + --------------------------------------- - + *warpchar "<mapname>",<x>,<y>,<char_id>; - + Warps another player to specified map and coordinate given the char id, which you can get with getcharid(0,<player_name>). Obviously this is useless if you want to warp the same player that is executing this script, unless it's some kind of "chosen" script. - + Example: - + warpchar "prontera",150,100,150001; - + --------------------------------------- - + *warpguild "<mapname>",<x>,<y>,<guild_id>; - + Warps a guild to specified map and coordinate given the guild id, which you can get with getcharid(2). You can also request another guild id given the member's name with getcharid(2,<player_name>). - + You can use the following "map names" for special warping behavior: -Random: All guild members are randomly warped in their current map - (as if they all used a fly wing) -SavePointAll: All guild members are warped to their respective save point. -SavePoint: All guild members are warped to the save point of the - currently attached player (will fail if there's no player - attached). +Random: All guild members are randomly warped in their current map + (as if they all used a fly wing) +SavePointAll: All guild members are warped to their respective save point. +SavePoint: All guild members are warped to the save point of the + currently attached player (will fail if there's no player + attached). Example: - + warpguild "prontera",x,y,Guild_ID; --------------------------------------- @@ -3936,7 +3934,7 @@ are equivalent. Map name, X coordinate and Y coordinate should be perfectly obvious. This ignores any and all map flags, and can make a character respawn where no teleportation is otherwise possible. - savepoint "place",350,75; + savepoint "place",350,75; --------------------------------------- @@ -3945,9 +3943,9 @@ character respawn where no teleportation is otherwise possible. This command will heal a set amount of HP and/or SP on the invoking character. - heal 30000,0; // This will heal 30,000 HP - heal 0,30000; // This will heal 30,000 SP - heal 300,300; // This will heal 300 HP and 300 SP + heal 30000,0; // This will heal 30,000 HP + heal 0,30000; // This will heal 30,000 SP + heal 300,300; // This will heal 300 HP and 300 SP This command just alters the hit points and spell points of the invoking character and produces no other output whatsoever. @@ -3965,8 +3963,8 @@ omitted. There is also a nice example on using this with the 'rand' function, to give you a random amount of healing. - // This will heal anything thing from 100 to 150 HP and no SP - itemheal rand(100,150),0; + // This will heal anything thing from 100 to 150 HP and no SP + itemheal rand(100,150),0; --------------------------------------- @@ -3975,9 +3973,9 @@ give you a random amount of healing. This command will heal the invoking character. It heals the character, but not by a set value - it adds percent of their maximum HP/SP. - percentheal 100,0; // This will heal 100% HP - percentheal 0,100; // This will heal 100% SP - percentheal 50,50; // This will heal 50% HP and 50% SP + percentheal 100,0; // This will heal 100% HP + percentheal 0,100; // This will heal 100% SP + percentheal 50,50; // This will heal 50% HP and 50% SP So the amount that this will heal will depend on the total amount of HP or SP you have maximum. Like 'heal', this will not call up any animations or @@ -3996,17 +3994,17 @@ currently connected to the server. This command will change the job class of the invoking character. - jobchange 1; // This would change your player into a Swordman - jobchange 4002; // This would change your player into a Swordman High + jobchange 1; // This would change your player into a Swordman + jobchange 4002; // This would change your player into a Swordman High This command does work with numbers, but you can also use job names. The full list of job names and the numbers they correspond to can be found in 'db/const.txt'. - // This would change your player into a Swordman - jobchange Job_Swordman; - // This would change your player into a Swordman High - jobchange Job_Swordman_High; + // This would change your player into a Swordman + jobchange Job_Swordman; + // This would change your player into a Swordman High + jobchange Job_Swordman_High; 'upper flag' can alternatively be used to specify the type of job one changes to. For example, jobchange Job_Swordman,1; will change the @@ -4137,18 +4135,18 @@ This command will give the invoking character a specified number of base and job experience points. Can be used as a quest reward. Negative values won't work. - getexp 10000,5000; + getexp 10000,5000; You can also use the "set" command with the constants defined in 'db/const.txt': - // These 2 combined has the same effect as the above command - set BaseExp,BaseExp+10000; - set JobExp,JobExp+5000; + // These 2 combined has the same effect as the above command + set BaseExp,BaseExp+10000; + set JobExp,JobExp+5000; You can also reduce the amount of experience points: - set BaseExp,BaseExp-10000; + set BaseExp,BaseExp-10000; Note that 'getexp' is now subject to the 'quest_exp_rate' config option, which adjusts the gained value. If you want to bypass this, use the 'set' @@ -4166,19 +4164,19 @@ sure you specify a palette number that exists/is usable by the client you use. 'changelook' works the same, but is only client side (it doesn't save the look value). - // This will change your hair(6), so that it uses palette 8, what ever - // your palette 8 is, your hair will use that color. + // This will change your hair(6), so that it uses palette 8, what ever + // your palette 8 is, your hair will use that color. - setlook 6,8; + setlook 6,8; - // This will change your clothes(7), so they are using palette 1, - // whatever your palette 1 is, your clothes will then use that set of - // colors. - - setlook 7,1; + // This will change your clothes(7), so they are using palette 1, + // whatever your palette 1 is, your clothes will then use that set of + // colors. + + setlook 7,1; Here are the possible look types: - + 0 - Base sprite 1 - Hairstyle 2 - Weapon @@ -4224,9 +4222,9 @@ The knock-back is not restricted by items or map flags, only obstacles are taken into account. If there is not enough space to perform the push (e.g. due to a wall), the character is pushed only up to the obstacle. - // pushes the character 5 cells in 3 o'clock direction from it's - // current position. - pushpc DIR_EAST, 5; + // pushes the character 5 cells in 3 o'clock direction from it's + // current position. + pushpc DIR_EAST, 5; --------------------------------------- @@ -4236,8 +4234,8 @@ This command will return the SVN revision number or Git SHA-1 hash the server is currently running on (depends on whether you used a SVN or Git client for getting Hercules). - if ( get_version() >= 15000 ) - mes "Welcome Hercules!"; + if ( get_version() >= 15000 ) + mes "Welcome Hercules!"; --------------------------------------- \\ @@ -4256,8 +4254,8 @@ character inventory instead. In the first and most commonly used version of this command, items are referred to by their database ID number found in 'db/(pre-)re/item_db.txt'. - getitem 502,10 // The person will receive 10 apples - getitem 617,1 // The person will receive 1 Old Violet Box + getitem 502,10 // The person will receive 10 apples + getitem 617,1 // The person will receive 1 Old Violet Box Giving an item ID of -1 will give a specified number of random items from the list of those that fall out of Old Blue Box. Unlike in all other @@ -4303,12 +4301,12 @@ but is a lot more flexible. Those parameters that are different from 'getitem' are: -identify - Whether you want the item to be identified (1) or not (0). -refine - For how many pluses will it be refined. It will not let you - refine an item higher than the max refine. -attribute - Whether the item is broken (1) or not (0). -card1,2,3,4 - If you want a card compound to it, place the card ID number - into the specific card slot. +identify - Whether you want the item to be identified (1) or not (0). +refine - For how many pluses will it be refined. It will not let you + refine an item higher than the max refine. +attribute - Whether the item is broken (1) or not (0). +card1,2,3,4 - If you want a card compound to it, place the card ID number + into the specific card slot. Card1-card4 values are also used to store name information for named items, as well as the elemental property of weapons and armor. You can @@ -4323,64 +4321,64 @@ If you still want to try creating a named item with this command because 'getnameditem' won't do it for you cause it's too limited, you can do it like this. Careful, minor magic ahead. - // First, let's get an ID of a character who's name will be on the - // item. Only an existing character's name may be there. - // Let's assume our character is 'Adam' and find his ID. - - set @charid,getcharid(0,"Adam"); + // First, let's get an ID of a character who's name will be on the + // item. Only an existing character's name may be there. + // Let's assume our character is 'Adam' and find his ID. - // Now we split the character ID number into two portions with a - // binary shift operation. If you don't understand what this does, - // just copy it. - - set @card3, @charid & 65535; - set @card4, @charid >> 16; + set @charid,getcharid(0,"Adam"); - // If you're inscribing non-equipment, @card1 must be 254. - // Arrows are also not equipment. :) - set @card1,254; - - // For named equipment, card2 means the Star Crumbs and elemental - // crystals used to make this equipment. For everything else, it's 0. - - set @card2,0; - - // Now, let's give the character who invoked the script some - // Adam's Apples: - - getitem2 512,1,1,0,0,@card1,@card2,@card3,@card4; + // Now we split the character ID number into two portions with a + // binary shift operation. If you don't understand what this does, + // just copy it. + + set @card3, @charid & 65535; + set @card4, @charid >> 16; + + // If you're inscribing non-equipment, @card1 must be 254. + // Arrows are also not equipment. :) + set @card1,254; + + // For named equipment, card2 means the Star Crumbs and elemental + // crystals used to make this equipment. For everything else, it's 0. + + set @card2,0; + + // Now, let's give the character who invoked the script some + // Adam's Apples: + + getitem2 512,1,1,0,0,@card1,@card2,@card3,@card4; This wasn't tested with all possible items, so I can't give any promises, experiment first before relying on it. To create equipment, continue this example it like this: - // We've already have card3 and card4 loaded with correct - // values so we'll just set up card1 and card2 with data - // for an Ice Stiletto. + // We've already have card3 and card4 loaded with correct + // values so we'll just set up card1 and card2 with data + // for an Ice Stiletto. - // If you're inscribing equipment, @card1 must be 255. - set @card1,255; - - // That's the number of star crumbs in a weapon. - set @sc,2; - - // That's the number of elemental property of the weapon. - set @ele,1; + // If you're inscribing equipment, @card1 must be 255. + set @card1,255; - // And that's the wacky formula that makes them into - // a single number. - set @card2,@ele+((@sc*5)<<8); + // That's the number of star crumbs in a weapon. + set @sc,2; - // That will make us an Adam's +2 VVS Ice Stiletto: - - getitem2 1216,1,1,2,0,@card1,@card2,@card3,@card4; + // That's the number of elemental property of the weapon. + set @ele,1; + + // And that's the wacky formula that makes them into + // a single number. + set @card2,@ele+((@sc*5)<<8); + + // That will make us an Adam's +2 VVS Ice Stiletto: + + getitem2 1216,1,1,2,0,@card1,@card2,@card3,@card4; Experiment with the number of star crumbs - I'm not certain just how much will work most and what it depends on. The valid element numbers are: 1 - Ice, 2 - Earth 3 - Fire 4 - Wind. - + You can, apparently, even create duplicates of the same pet egg with this command, creating a pet which is the same, but simultaneously exists in two eggs, and may hatch from either, although, I'm not sure what kind of a @@ -4434,11 +4432,11 @@ Note: 'delitem' in an NPC script can still remove rental items. This command will create an item lying around on a specified map in the specified location. - itemid - Found in 'db/(pre-)re/item_db.txt' - amount - Amount you want produced - map name - The map name - X - The X coordinate - Y - The Y coordinate. + itemid - Found in 'db/(pre-)re/item_db.txt' + amount - Amount you want produced + map name - The map name + X - The X coordinate + Y - The Y coordinate. This item will still disappear just like any other dropped item. Like 'getitem', it also accepts an 'english name' field from the database and @@ -4479,8 +4477,8 @@ This command will remove a specified amount of items from the invoking or target character. Like all the item commands, it uses the item ID found inside 'db/(pre-)re/item_db.txt'. - delitem 502,10; // The person will lose 10 apples - delitem 617,1; // The person will lose 1 Old Violet Box + delitem 502,10; // The person will lose 10 apples + delitem 617,1; // The person will lose 1 Old Violet Box It is always a good idea to check if the player actually has the items before you delete them. If you try to delete more items that the player @@ -4507,9 +4505,9 @@ Check 'getitem2' to understand its expanded parameters. This function will return the number of items for the specified item ID that the invoking character has in the inventory. - mes "[Item Checker]"; - mes "Hmmm, it seems you have "+countitem(502)+" apples"; - close; + mes "[Item Checker]"; + mes "Hmmm, it seems you have "+countitem(502)+" apples"; + close; Like 'getitem', this function will also accept an 'english name' from the database as an argument. @@ -4517,10 +4515,10 @@ database as an argument. If you want to state the number at the end of a sentence, you can do it by adding up strings: - mes "[Item Checker]"; - mes "Hmmm, the total number of apples you are holding is "+countitem("APPLE"); - close; - + mes "[Item Checker]"; + mes "Hmmm, the total number of apples you are holding is "+countitem("APPLE"); + close; + --------------------------------------- *countitem2(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>) @@ -4826,8 +4824,8 @@ happens when a result item is double-clicked and can be one of the following: 0 = Shows the store's position on the mini-map and highlights the shop - sign with yellow color, when the store is on same map as the - invoking player. + sign with yellow color, when the store is on same map as the + invoking player. 1 = Directly opens the shop, regardless of distance. Example: @@ -4851,10 +4849,10 @@ The storage window opens regardless of whether there are open NPC dialogs or not, but it is preferred to close the dialog before displaying the storage window, to avoid any disruption when both windows overlap. - mes "I will now open your stash for you"; - close2; - openstorage; - end; + mes "I will now open your stash for you"; + close2; + openstorage; + end; --------------------------------------- @@ -4863,10 +4861,10 @@ storage window, to avoid any disruption when both windows overlap. This will open a character's Mail window on the client connected to the invoking character. - mes "Close this window to open your mail inbox."; - close2; - openmail; - end; + mes "Close this window to open your mail inbox."; + close2; + openmail; + end; --------------------------------------- @@ -4875,10 +4873,10 @@ invoking character. This will open the Auction window on the client connected to the invoking character. - mes "Close this window to open the Auction window."; - close2; - openauction; - end; + mes "Close this window to open the Auction window."; + close2; + openauction; + end; --------------------------------------- \\ @@ -4934,7 +4932,7 @@ possible maximum. The full list of guild skills is available in // (GD_APPROVAL ID 10000). Notice that if you try to add two levels of // Approval, or add Approval when the guild already has it, it will only // have one level of Approval afterwards. - guildskill 10000,1; + guildskill 10000,1; You might want to make a quest for getting a certain guild skill, make it hard enough that all the guild needs to help or something. Doing this for @@ -5001,16 +4999,16 @@ Used in reset NPC's (duh!). These command bestow a status effect on the invoking character. This command is used a lot in the item scripts. - // This would poison them for 10 min - sc_start SC_Poison,600000,0; + // This would poison them for 10 min + sc_start SC_Poison,600000,0; Effect type is a number of effect, 'db/const.txt' lists the common (mostly negative) status effect types as constants, starting with 'SC_'. You can also use this to give someone an effect of a player-cast spell: - // This will bless someone as if with Bless 10: - sc_start 10,240000,10; - + // This will bless someone as if with Bless 10: + sc_start 10,240000,10; + Extra argument's meaning differs depending on the effect type, for most effects caused by a player skill the extra argument means the level of the skill that would have been used to create that effect, for others it might @@ -5073,16 +5071,16 @@ command will not actually use the skill: it is intended for scripts which simulate skill usage by the NPC, such as buffs, by setting appropriate status and displaying the skill's effect. - mes "Be blessed!"; - // Heal of 2000 HP - heal 2000,0; - skilleffect 28,2000; - // Blessing Level 10 - sc_start 10,240000,10; - skilleffect 34,0; - // Increase AGI Level 5 - sc_start 12,140000,5; - skilleffect 29,0; + mes "Be blessed!"; + // Heal of 2000 HP + heal 2000,0; + skilleffect 28,2000; + // Blessing Level 10 + sc_start 10,240000,10; + skilleffect 34,0; + // Increase AGI Level 5 + sc_start 12,140000,5; + skilleffect 29,0; This will heal the character with 2000 HP, buff it with Blessing Lv 10 and Increase AGI Lv 5, and display appropriate effects. @@ -5155,7 +5153,7 @@ This command will bump a specified stat of the invoking character up by the specified amount permanently. Amount can be negative. See 'statusup'. // This will decrease a character's Vit forever. - statusup bVit,-1; + statusup bVit,-1; --------------------------------------- @@ -5412,7 +5410,7 @@ the RID of the killing character. 3 = flora (Alchemist skill) 4 = zanzou (Kagerou/Oboro skill) - monster "place",60,100,"Poring",1002,1,"NPCNAME::OnLabel"; + monster "place",60,100,"Poring",1002,1,"NPCNAME::OnLabel"; The coordinates of 0,0 will spawn the monster on a random place on the map. Both 'monster' and 'areamonster' return the GID of the monster @@ -5420,19 +5418,19 @@ spawned if there was ONLY ONE monster to be spawned. This is useful for controlling each of the spawned mobs with the unit* commands shown below. For example: - // We'll make a poring which will automatically attack invoking player: - set .@mobGID, monster "Prontera",150,150,"Poring",1002,1; - unitattack .@mobGID, getcharid(3); // Attacker GID, attacked GID + // We'll make a poring which will automatically attack invoking player: + set .@mobGID, monster "Prontera",150,150,"Poring",1002,1; + unitattack .@mobGID, getcharid(3); // Attacker GID, attacked GID The way you can get the GID of more than only one monster is looping through all the summons to get their individual GIDs and do whatever you want with them. For example: - // We want to summon .mobnumber porings which will give us a kiss - for (set .@i, 0; .@i < .mobnumber; set .@i, .@i + 1){ - set .@mobGID, monster "map",.x,.y,"Kisser Poring",1002,1; - unitemote .@mobGID, e_kis; - } + // We want to summon .mobnumber porings which will give us a kiss + for (set .@i, 0; .@i < .mobnumber; set .@i, .@i + 1){ + set .@mobGID, monster "map",.x,.y,"Kisser Poring",1002,1; + unitemote .@mobGID, e_kis; + } Refer to the unit* commands below. @@ -5442,29 +5440,29 @@ by x1/y1-x2/y2. Simple monster killing script: - <NPC object definition. Let's assume you called him NPCNAME.> - mes "[Summon Man]"; - mes "Want to start the kill?"; - next; - menu "Yes",L_Yes,"No",-; - mes "[Summon Man]"; - mes "Come back later"; - close; - L_Yes: - monster "prontera",0,0,"Quest Poring",1002,10,"NPCNAME::OnPoringKilled"; - // By using 0,0 it will spawn them in a random place. - mes "[Summon Man]"; - mes "Now go and kill all the Poring I summoned"; - // He summoned ten. - close; - OnPoringKilled: - set $PoringKilled,$PoringKilled+1; - if ($PoringKilled==10) goto L_AllDead; - end; - L_AllDead: - announce "Summon Man: Well done all the poring are dead",3; - set $PoringKilled,0; - end; + <NPC object definition. Let's assume you called him NPCNAME.> + mes "[Summon Man]"; + mes "Want to start the kill?"; + next; + menu "Yes",L_Yes,"No",-; + mes "[Summon Man]"; + mes "Come back later"; + close; + L_Yes: + monster "prontera",0,0,"Quest Poring",1002,10,"NPCNAME::OnPoringKilled"; + // By using 0,0 it will spawn them in a random place. + mes "[Summon Man]"; + mes "Now go and kill all the Poring I summoned"; + // He summoned ten. + close; + OnPoringKilled: + set $PoringKilled,$PoringKilled+1; + if ($PoringKilled==10) goto L_AllDead; + end; + L_AllDead: + announce "Summon Man: Well done all the poring are dead",3; + set $PoringKilled,0; + end; For more examples see just about any official 2-1 or 2-2 job quest script. @@ -5747,17 +5745,17 @@ The script of the NPC object invoked in this manner will run as if it's been invoked by the RID that was active in the script that issued a 'doevent'. As such, the command will not work if an RID is not attached. - place,100,100,1%TAB%script%TAB%NPC%TAB%53,{ - mes "This is what you will see when you click me"; - close; - OnLabel: - mes "This is what you will see if the doevent is activated"; - close; - } + place,100,100,1%TAB%script%TAB%NPC%TAB%53,{ + mes "This is what you will see when you click me"; + close; + OnLabel: + mes "This is what you will see if the doevent is activated"; + close; + } - .... + .... - doevent "NPC::OnLabel"; + doevent "NPC::OnLabel"; --------------------------------------- @@ -5779,25 +5777,25 @@ This command can be used to make other NPCs act, as if they were responding to the invoking NPC's actions, such as using an emotion or talking. - place,100,100,1%TAB%script%TAB%NPC%TAB%53,{ - mes "Hey NPC2 copy what I do"; - close2; - set .@emote, rand(1,30); - donpcevent "NPC2::OnEmote"; - OnEmote: - emotion .@emote; - end; - } - - place,102,100,1%TAB%script%TAB%NPC2%TAB%53,{ - mes "Hey NPC copy what I do"; - close2; - set .@emote, rand(1,30); - donpcevent "NPC::OnEmote"; - OnEmote: - emotion .@emote; - end; - } + place,100,100,1%TAB%script%TAB%NPC%TAB%53,{ + mes "Hey NPC2 copy what I do"; + close2; + set .@emote, rand(1,30); + donpcevent "NPC2::OnEmote"; + OnEmote: + emotion .@emote; + end; + } + + place,102,100,1%TAB%script%TAB%NPC2%TAB%53,{ + mes "Hey NPC copy what I do"; + close2; + set .@emote, rand(1,30); + donpcevent "NPC::OnEmote"; + OnEmote: + emotion .@emote; + end; + } Whichever of the both NPCs is talked to, both will show a random emotion at the same time. @@ -5821,9 +5819,9 @@ object running it was a player talking - that is, above their head and in the chat window. The display name of the NPC will get appended in front of the message to complete the effect. - // This will make everyone in the area see the NPC greet the character - // who just invoked it. - npctalk "Hello "+strcharinfo(0)+", how are you?"; + // This will make everyone in the area see the NPC greet the character + // who just invoked it. + npctalk "Hello "+strcharinfo(0)+", how are you?"; --------------------------------------- @@ -5875,16 +5873,16 @@ On5secs: --------------------------------------- -*initnpctimer{ "<NPC name>" {, <Attach Flag>} } | - { "<NPC name>" | <Attach Flag> }; -*stopnpctimer{ "<NPC name>" {, <Detach Flag>} } | - { "<NPC name>" | <Detach Flag> }; -*startnpctimer{ "<NPC name>" {, <Attach Flag>} } | - { "<NPC name>" | <Attach Flag> }; -*setnpctimer <tick>{,"<NPC name>"}; -*getnpctimer(<type of information>{,"<NPC name>"}) -*attachnpctimer {"<character name>"}; -*detachnpctimer {"<NPC name>"}; +*initnpctimer { "<NPC name>" {, <Attach Flag>} } | + { "<NPC name>" | <Attach Flag> }; +*stopnpctimer { "<NPC name>" {, <Detach Flag>} } | + { "<NPC name>" | <Detach Flag> }; +*startnpctimer { "<NPC name>" {, <Attach Flag>} } | + { "<NPC name>" | <Attach Flag> }; +*setnpctimer <tick>{,"<NPC name>"}; +*getnpctimer (<type of information>{,"<NPC name>"}) +*attachnpctimer {"<character name>"}; +*detachnpctimer {"<NPC name>"}; This set of commands and functions will create and manage an NPC-based timer. The NPC name may be omitted, in which case the calling NPC is used @@ -5930,80 +5928,80 @@ The 'setnpctimer' command will explicitly set the timer to a given tick. 0 - Will return the current tick count of the timer. 1 - Will return 1 if there are remaining "OnTimer<ticks>:" labels in the - specified NPC waiting for execution. + specified NPC waiting for execution. 2 - Will return the number of times the timer has triggered and will - trigger an "OnTimer<tick>:" label in the specified NPC. + trigger an "OnTimer<tick>:" label in the specified NPC. Example 1: - <NPC Header> { - // We need to use attachnpctimer because the mes command below - // needs RID attach - attachnpctimer; - initnpctimer; - npctalk "I cant talk right now, give me 10 seconds"; - end; - OnTimer5000: - npctalk "Ok 5 seconds more"; - end; - OnTimer6000: - npctalk "4"; - end; - OnTimer7000: - npctalk "3"; - end; - OnTimer8000: - npctalk "2"; - end; - OnTimer9000: - npctalk "1"; - end; - OnTimer10000: - stopnpctimer; - mes "[Man]"; - mes "Ok we can talk now"; - detachnpctimer; - // and remember attachnpctimer and detachnpctimer can only be used - // while the NPC timer is not running! - } + <NPC Header> { + // We need to use attachnpctimer because the mes command below + // needs RID attach + attachnpctimer; + initnpctimer; + npctalk "I cant talk right now, give me 10 seconds"; + end; + OnTimer5000: + npctalk "Ok 5 seconds more"; + end; + OnTimer6000: + npctalk "4"; + end; + OnTimer7000: + npctalk "3"; + end; + OnTimer8000: + npctalk "2"; + end; + OnTimer9000: + npctalk "1"; + end; + OnTimer10000: + stopnpctimer; + mes "[Man]"; + mes "Ok we can talk now"; + detachnpctimer; + // and remember attachnpctimer and detachnpctimer can only be used + // while the NPC timer is not running! + } Example 2: - OnTimer15000: - npctalk "Another 15 seconds have passed."; + OnTimer15000: + npctalk "Another 15 seconds have passed."; - // You have to use 'initnpctimer' instead of 'setnpctimer 0'. - // This is equal to 'setnpctimer 0' + 'startnpctimer'. - // Alternatively, you can also insert another 'OnTimer15001' label - // so that the timer won't stop. - initnpctimer; - end; - - // This OnInit label will run when the script is loaded, so that the - // timer is initialized immediately as the server starts. It is - // dropped back to 0 every time the NPC says something, so it will - // cycle continuously. - OnInit: - initnpctimer; - end; + // You have to use 'initnpctimer' instead of 'setnpctimer 0'. + // This is equal to 'setnpctimer 0' + 'startnpctimer'. + // Alternatively, you can also insert another 'OnTimer15001' label + // so that the timer won't stop. + initnpctimer; + end; + + // This OnInit label will run when the script is loaded, so that the + // timer is initialized immediately as the server starts. It is + // dropped back to 0 every time the NPC says something, so it will + // cycle continuously. + OnInit: + initnpctimer; + end; Example 3: - mes "[Man]"; - mes "I have been waiting "+(getnpctimer(0)/1000)+" seconds for you."; - // We divide the timer returned by 1000 to convert milliseconds to - // seconds. - close; + mes "[Man]"; + mes "I have been waiting "+(getnpctimer(0)/1000)+" seconds for you."; + // We divide the timer returned by 1000 to convert milliseconds to + // seconds. + close; Example 4: - mes "[Man]"; - mes "Ok, I will let you have 30 more seconds..."; - close2; - setnpctimer (getnpctimer(0)-30000); - // Notice the 'close2'. If there were a 'next' there the timer would - // be changed only after the player pressed the 'next' button. - end; + mes "[Man]"; + mes "Ok, I will let you have 30 more seconds..."; + close2; + setnpctimer (getnpctimer(0)-30000); + // Notice the 'close2'. If there were a 'next' there the timer would + // be changed only after the player pressed the 'next' button. + end; --------------------------------------- @@ -6021,11 +6019,11 @@ will not keep the rid, while sleep2 does. Examples: // This will pause the script for 10 seconds and ditch the RID - // (so no player is attached anymore) - sleep 10000; - // Pauses the script for 5 seconds, and continue with the RID attached. + // (so no player is attached anymore) + sleep 10000; + // Pauses the script for 5 seconds, and continue with the RID attached. sleep2 5000; - //Cancels any running sleep timers on the NPC 'NPC'. + //Cancels any running sleep timers on the NPC 'NPC'. awake "NPC"; --------------------------------------- @@ -6049,7 +6047,7 @@ client and appears always green. This command will broadcast a message to all or most players, similar to @kami/@kamib GM commands. - announce "This will be shown to everyone at all in yellow.",0; + announce "This will be shown to everyone at all in yellow.",0; The region the broadcast is heard in (target), source of the broadcast and the color the message will come up as is determined by the flags. @@ -6058,25 +6056,25 @@ The flag values are coded as constants in db/const.txt to make them easier to use. Target flags: -- bc_all: Broadcast message is sent server-wide (default). -- bc_map: Message is sent to everyone in the same map as the source of - the broadcast (see below). -- bc_area: Message is sent to players in the vicinity of the source. -- bc_self: Message is sent only to current player. -You cannot use more than one target flag. +- bc_all: Broadcast message is sent server-wide (default). +- bc_map: Message is sent to everyone in the same map as the source of + the broadcast (see below). +- bc_area: Message is sent to players in the vicinity of the source. +- bc_self: Message is sent only to current player. +You cannot use more than one target flag. Source flags: -- bc_pc: Broadcast source is the attached player (default). -- bc_npc: Broadcast source is the NPC, not the player attached to the - script (useful when a player is not attached or the message - should be sent to those nearby the NPC). +- bc_pc: Broadcast source is the attached player (default). +- bc_npc: Broadcast source is the NPC, not the player attached to the + script (useful when a player is not attached or the message + should be sent to those nearby the NPC). You cannot use more than one source flag. Special flags: -- bc_yellow: Broadcast will be displayed in yellow color (default). -- bc_blue: Broadcast will be displayed in blue color. -- bc_woe: Indicates that this broadcast is 'WoE Information' that can - be disabled client-side. +- bc_yellow:Broadcast will be displayed in yellow color (default). +- bc_blue: Broadcast will be displayed in blue color. +- bc_woe: Indicates that this broadcast is 'WoE Information' that can + be disabled client-side. Due to the way client handles broadcasts, it is impossible to set both bc_blue and bc_woe. @@ -6089,7 +6087,7 @@ The color parameter is a single number which can be in hexadecimal notation. For example: - announce "This will be shown to everyone at all in green.",bc_all,0x00FF00; + announce "This will be shown to everyone at all in green.",bc_all,0x00FF00; Will display a global announce in green. The color format is in RGB (0xRRGGBB). @@ -6102,12 +6100,12 @@ Default font size is 12. Using this for private messages to players is probably not that good an idea, but it can be used instead in NPCs to "preview" an announce. - // This will be a private message to the player using the NPC that - // made the announcement - announce "This is my message just for you",bc_blue|bc_self; + // This will be a private message to the player using the NPC that + // made the announcement + announce "This is my message just for you",bc_blue|bc_self; - // This will be shown on everyones screen that is in sight of the NPC. - announce "This is my message just for you people here",bc_npc|bc_area; + // This will be shown on everyones screen that is in sight of the NPC. + announce "This is my message just for you people here",bc_npc|bc_area; --------------------------------------- @@ -6127,7 +6125,7 @@ residing in the specified x1/y1-x2/y2 rectangle on the map given. The flags and optional parameters are the same as in 'announce', but target and source flags are ignored. - areaannounce "prt_church",0,0,350,350,"God's in his heaven, all right with the world",0; + areaannounce "prt_church",0,0,350,350,"God's in his heaven, all right with the world",0; --------------------------------------- @@ -6241,7 +6239,7 @@ amount. // The NPC will just show a box above its head that says "Hello World", // clicking it will do nothing, since the limit is zero. - waitingroom "Hello World",0; + waitingroom "Hello World",0; // The NPC will have a box above its head, with "Disco - Waiting Room" // written on it, and will have 8 waiting slots. Clicking this will enter @@ -6249,7 +6247,7 @@ amount. // accumulate. Once this happens, it will cause the NPC "Bouncer" run the // label "OnStart". - waitingroom "Disco - Waiting Room",8,"Bouncer::OnStart",7; + waitingroom "Disco - Waiting Room",8,"Bouncer::OnStart",7; // The NPC will have a box above its head, with "Party - Waiting Room" // written on it, and will have 8 waiting slots. Clicking this will allow @@ -6257,7 +6255,7 @@ amount. // the player will be able to wait until 7 players accumulate. Once this // happens, it will cause the NPC "Bouncer" run the label "OnStart". - waitingroom "Party - Waiting Room",8,"Bouncer::OnStart",7,5000,50,99; + waitingroom "Party - Waiting Room",8,"Bouncer::OnStart",7,5000,50,99; Creating a waiting room does not stop the execution of the script and it will continue to the next line. @@ -6534,7 +6532,7 @@ which returns a guild id: // This will change the emblem on the flag to that of the guild that owns // "guildcastle" - flagemblem GetCastleData("guildcastle",1); + flagemblem GetCastleData("guildcastle",1); --------------------------------------- @@ -6614,7 +6612,7 @@ Example: // This will move Bugga from to the coordinates 100,20 (if those // coordinates are legit). moveNPC "Bugga",100,20; - + --------------------------------------- ===================== @@ -6627,8 +6625,8 @@ Example: This command will send the message to the server console (map-server window). It will not be displayed anywhere else. - // Displays "NAME has clicked me!" in the map-server window. - debugmes strcharinfo(0)+" has clicked me!"; + // Displays "NAME has clicked me!" in the map-server window. + debugmes strcharinfo(0)+" has clicked me!"; --------------------------------------- @@ -6681,23 +6679,23 @@ Point number is the number of the point - you can have several. If more than one point is drawn at the same coordinates, they will cycle, which can be used to create flashing marks. - // This command will show a mark at coordinates X 30 Y 40, is mark - // number 1, and will be red. - - viewpoint 1,30,40,1,0xFF0000; + // This command will show a mark at coordinates X 30 Y 40, is mark + // number 1, and will be red. + + viewpoint 1,30,40,1,0xFF0000; This will create three points: - viewpoint 1,30,40,1,0xFF0000; - viewpoint 1,35,45,2,0xFF0000; - viewpoint 1,40,50,3,0xFF0000; + viewpoint 1,30,40,1,0xFF0000; + viewpoint 1,35,45,2,0xFF0000; + viewpoint 1,40,50,3,0xFF0000; And this is how you remove them: - viewpoint 2,30,40,1,0xFF0000; - viewpoint 2,35,45,2,0xFF0000; - viewpoint 2,40,50,3,0xFF0000; - + viewpoint 2,30,40,1,0xFF0000; + viewpoint 2,35,45,2,0xFF0000; + viewpoint 2,40,50,3,0xFF0000; + The client determines what it does with the points entirely, the server keeps no memory of where the points are set whatsoever. @@ -6709,11 +6707,11 @@ This command will display a picture, usually an NPC illustration, also called cutin, for the currently attached client. The position parameter determines the placement of the illustration and takes following values: - 0 - bottom left corner - 1 - bottom middle - 2 - bottom right corner - 3 - middle of screen in a movable window with an empty title bar - 4 - middle of screen without the window header, but still movable + 0 - bottom left corner + 1 - bottom middle + 2 - bottom right corner + 3 - middle of screen in a movable window with an empty title bar + 4 - middle of screen without the window header, but still movable The picture is read from data\texture\???????\illust, from both the GRF archive and data folder, and is required to be a bitmap. The file @@ -6729,15 +6727,15 @@ one will cause the old one to disappear. To delete the currently displayed illustration without displaying a new one, an empty file name and position 255 must be used. - // Displays the Comodo Kafra illustration in lower right corner. - cutin "kafra_07",2; + // Displays the Comodo Kafra illustration in lower right corner. + cutin "kafra_07",2; - // Typical way to end a script, which displayed an illustration during a - // dialog with a player. - mes "See you."; - close2; - cutin "",255; - end; + // Typical way to end a script, which displayed an illustration during a + // dialog with a player. + mes "See you."; + close2; + cutin "",255; + end; --------------------------------------- @@ -6842,10 +6840,10 @@ This command will run the given command line exactly as if it was typed in from the keyboard by the player connected to the invoking character, and that character belonged to an account which had GM level 99. - // This will ask the invoker for a character name and then use the - // '@nuke' GM command on them, killing them mercilessly. - input @player$; - atcommand "@nuke "+@player$; + // This will ask the invoker for a character name and then use the + // '@nuke' GM command on them, killing them mercilessly. + input @player$; + atcommand "@nuke "+@player$; This command has a lot of good uses, I am sure you can have some fun with this one. @@ -6860,9 +6858,9 @@ GM level 99. The commands can also run without an attached rid. - // This would do the same as above, but now - // it doesn't need a player attached by default. - charcommand "#option 0 0 0 Roy"; + // This would do the same as above, but now + // it doesn't need a player attached by default. + charcommand "#option 0 0 0 Roy"; --------------------------------------- @@ -6940,9 +6938,9 @@ value, and "NPC level" is the temporary level of the NPC (used in some skills). Neither value can be greater than the max level defined in config, and will not work properly if the NPC has a mob sprite. - // Casts Level 10 Heal on the attached player, calculated with - // all stats 99 and base level 60. - npcskill "AL_HEAL",10,99,60; + // Casts Level 10 Heal on the attached player, calculated with + // all stats 99 and base level 60. + npcskill "AL_HEAL",10,99,60; --------------------------------------- @@ -7183,47 +7181,47 @@ The first letter is position 0. Returns char at specified index. If index is out of range, returns an empty string. - + Example: - + charat("This is a string", 10); //returns "s" - + --------------------------------------- - + *setchar(<string>,<char>,<index>) Returns the original string with the char at the specified index set to the specified char. If index is out of range, the original string will be returned. Only the 1st char in the <char> parameter will be used. - + Example: setchar("Cat", "B", 0); //returns "Bat" - + --------------------------------------- *insertchar(<string>,<char>,<index>) - + Returns the original string with the specified char inserted at the specified index. If index is out of range, the char will be inserted on the end of the string that it is closest. Only the 1st char in the <char> parameter will be used. - + Example: - + insertchar("laughter", "s", 0); //returns "slaughter" - + --------------------------------------- *delchar(<string>,<index>) Returns the original string with the char at the specified index removed. If index is out of range, original string will be returned. - + Example: - + delchar("Diet", 3); //returns "Die" - + --------------------------------------- *strtoupper(<string>) @@ -7231,9 +7229,9 @@ Example: Returns the specified string in it's uppercase/lowercase form. All non-alpha characters will be preserved. - + Example: - + strtoupper("The duck is blue!!"); //returns "THE DUCK IS BLUE!!" --------------------------------------- @@ -7246,21 +7244,21 @@ uppercase for 'charisupper' or lowercase for 'charislower'. Otherwise, 0. Characters not of the alphabelt will return 0. Example: - + charisupper("Hercules", 0); //returns 1 - + --------------------------------------- *substr(<string>,<start_index>,<end_index>) - + Returns the sub-string of the specified string inclusively between the set indexes. If indexes are out of range, or the start index is after the end index, an empty string will be returned. Example: - + substr("foobar", 3, 5); //returns "bar" - + --------------------------------------- *explode(<dest_array>,<string>,<delimiter>) @@ -7272,7 +7270,7 @@ as a delimiter, the string will be placed in the array in its original form, without any changes. Example: - + explode(.@my_array$, "Explode:Test:1965:red:PIE", ":"); //.@my_array$ contents will be... //.@my_array$[0]: "Explode" @@ -7288,7 +7286,7 @@ Example: Combines all substrings within the specified string array into a single string. If the glue parameter is specified, it will be inserted inbetween each substring. - + Example: setarray .@my_array$[0], "This", "is", "a", "test"; implode(.@my_array$, " "); //returns "This is a test" @@ -7305,11 +7303,11 @@ Number of params is only limited by Hercules' script engine. Example: .@format$ = 'The %s contains %d monkeys'; dispbottom(sprintf(.@format$, "zoo", 5)); - //prints "The zoo contains 5 monkeys" + //prints "The zoo contains 5 monkeys" + + dispbottom(sprintf(.@format$, "barrel", 82)); + //prints "The barrel contains 82 monkeys" - dispbottom(sprintf(.@format$, "barrel", 82)); - //prints "The barrel contains 82 monkeys" - --------------------------------------- *sscanf(<string>,<format>[,param[,param[,...]]]) @@ -7321,7 +7319,7 @@ limited by Hercules' script engine. Example: sscanf("This is a test: 42 foobar", "This is a test: %d %s", .@num, .@str$); dispbottom(.@num + " " + .@str$); //prints "42 foobar" - + --------------------------------------- *strpos(<haystack>,<needle>{,<offset>}) @@ -7335,7 +7333,7 @@ Example: strpos("foobar", "bar", 0); //returns 3 strpos("foobarfoo", "foo", 0); //returns 0 strpos("foobarfoo", "foo", 1); //returns 6 - + --------------------------------------- *replacestr(<input>, <search>, <replace>{, <usecase>{, <count>}}) @@ -7349,7 +7347,7 @@ Example: replacestr("testing tester", "test", "dash"); //returns "dashing dasher" replacestr("Donkey", "don", "mon", 0); //returns "monkey" replacestr("test test test test test", "yay", 0, 3); //returns "yay yay yay test test" - + --------------------------------------- *countstr(<input>, <search>{, <usecase>}) @@ -7369,16 +7367,16 @@ This command sets the current RO client interface font to one of the fonts stored in data\*.eot by using an ID of the font. When the ID of the currently used font is used, default interface font is used again. - 0 - Default - 1 - RixLoveangel - 2 - RixSquirrel - 3 - NHCgogo - 4 - RixDiary - 5 - RixMiniHeart - 6 - RixFreshman - 7 - RixKid - 8 - RixMagic - 9 - RixJJangu + 0 - Default + 1 - RixLoveangel + 2 - RixSquirrel + 3 - NHCgogo + 4 - RixDiary + 5 - RixMiniHeart + 6 - RixFreshman + 7 - RixKid + 8 - RixMagic + 9 - RixJJangu --------------------------------------- @@ -7388,12 +7386,12 @@ Displays given numeric 'value' in large digital clock font on top of the screen. The optional parameter 'type' specifies visual aspects of the "clock" and can be one of the following values: - 0 - Displays the value for 5 seconds (default). - 1 - Incremental counter (1 tick/second). - 2 - Decremental counter (1 tick/second). Does not stop at zero, but - overflows. - 3 - Decremental counter (1 tick/second). Two digits only, stops at - zero. + 0 - Displays the value for 5 seconds (default). + 1 - Incremental counter (1 tick/second). + 2 - Decremental counter (1 tick/second). Does not stop at zero, but + overflows. + 3 - Decremental counter (1 tick/second). Two digits only, stops at + zero. For type 1 and 2 the start value is set by using negative number of the one intended to set (ex. -10 starts the counter at 10 seconds). Except for @@ -7401,11 +7399,11 @@ type 3 the value is interpreted as seconds and formatted as time in days, hours, minutes and seconds. Note, that the official script command does not have the optional parameter. - // displays 23:59:59 for 5 seconds - showdigit 86399; + // displays 23:59:59 for 5 seconds + showdigit 86399; - // counter that starts at 60 and runs for 60 seconds - showdigit 60,3; + // counter that starts at 60 and runs for 60 seconds + showdigit 60,3; --------------------------------------- @@ -7504,8 +7502,8 @@ inventory. The kind of pet is specified by pet ID numbers listed in 'db/pet_db.txt'. The egg is created exactly as if the character just successfully caught a pet in the normal way. - // This will make you a poring: - makepet 1002; + // This will make you a poring: + makepet 1002; Notice that you absolutely have to create pet eggs with this command. If you try to give a pet egg with 'getitem', pet data will not be created by @@ -7821,21 +7819,21 @@ If no additional argument supplied, return the state of the quest: 0 = Quest has been given, but the state is "inactive" 1 = Quest has been given, and the state is "active" 2 = Quest completed - + If parameter "PLAYTIME" is supplied: -1 = Quest not started (not in quest log) 0 = the time limit has not yet been reached 1 = the time limit has not been reached but the quest is marked as - complete + complete 2 = the time limit has been reached - + If parameter "HUNTING" is supplied: - -1 = Quest not started (not in quest log) - 0 = you haven't killed all of the target monsters and the time limit - has not been reached. - 1 = you haven't killed all of the target monsters but the time limit - has been reached. - 2 = you've killed all of the target monsters + -1 = Quest not started (not in quest log) + 0 = you haven't killed all of the target monsters and the time limit + has not been reached. + 1 = you haven't killed all of the target monsters but the time limit + has been reached. + 2 = you've killed all of the target monsters --------------------------------------- @@ -7847,11 +7845,11 @@ certain player/s. state can be: 0 = disable ( Used to disable and remove the mark and the emotion from - the NPC. ) + the NPC. ) 1 = exclamation emotion ( Used to show an important quest event to - certain player. ) + certain player. ) 2 = interrogation emotion ( Used to show an non-important quest event - to certain player. ) + to certain player. ) Other value may cause client crashes. color can be: @@ -7893,8 +7891,8 @@ If the option parameter is left out, the waiting room of the current NPC is used. Example: - // Battle Group will be referred to as $@KvM01BG_id1, and when they - // die, respawn at bat_c01,52,129. + // Battle Group will be referred to as $@KvM01BG_id1, and when they + // die, respawn at bat_c01,52,129. set $@KvM01BG_id1, waitingroom2bg("bat_c01",52,129,"KvM01_BG::OnGuillaumeQuit","KvM01_BG::OnGuillaumeDie"); end; @@ -7996,7 +7994,7 @@ Example: Retrieves data related to given battle group. Type can be one of the following: - 0 - Amount of players currently belonging to the group. + 0 - Amount of players currently belonging to the group. ---------------------------------------- @@ -8047,9 +8045,9 @@ currently attached character. Sets or gets the mercenary calls value for given guild for currently attached character. Guild can be one or the following constants: - ARCH_MERC_GUILD - SPEAR_MERC_GUILD - SWORD_MERC_GUILD + ARCH_MERC_GUILD + SPEAR_MERC_GUILD + SWORD_MERC_GUILD ---------------------------------------- @@ -8059,9 +8057,9 @@ attached character. Guild can be one or the following constants: Sets or gets the mercenary faith value for given guild for currently attached character. Guild can be one or the following constants: - ARCH_MERC_GUILD - SPEAR_MERC_GUILD - SWORD_MERC_GUILD + ARCH_MERC_GUILD + SPEAR_MERC_GUILD + SWORD_MERC_GUILD --------------------------------------- @@ -8072,14 +8070,14 @@ If char id is given, the information of that character is retrieved instead. Type specifies what information to retrieve and can be one of the following: - 0 - Database ID - 1 - Class - 2 - Name - 3 - Faith value for this mercenary's guild, if any - 4 - Calls value for this mercenary's guild, if any - 5 - Kill count - 6 - Remaining life time in msec - 7 - Level + 0 - Database ID + 1 - Class + 2 - Name + 3 - Faith value for this mercenary's guild, if any + 4 - Calls value for this mercenary's guild, if any + 5 - Kill count + 6 - Remaining life time in msec + 7 - Level If the character does not have a mercenary, the command returns "" for name and 0 for all other types. diff --git a/npc/mobs/citycleaners.txt b/npc/mobs/citycleaners.txt index 876017fd4..62a0f2c12 100644 --- a/npc/mobs/citycleaners.txt +++ b/npc/mobs/citycleaners.txt @@ -47,4 +47,8 @@ einbech,0,0,0,0 monster Tarou 1175,5,1800000,1500000,0 //================================================== payon_in02,23,68,5,5 monster Thief Bug Egg 1048,7,1200000,600000,0 +<<<<<<< HEAD job3_war01,19,33,5,5 monster Thief Bug Egg 1213,1,12,60,0 +======= +job3_war01,19,33,5,5 monster Thief Bug Egg 1048,1,12,60,0 +>>>>>>> upstream/master diff --git a/npc/re/instances/HazyForest.txt b/npc/re/instances/HazyForest.txt index cb65f11d7..cecdadd20 100644 --- a/npc/re/instances/HazyForest.txt +++ b/npc/re/instances/HazyForest.txt @@ -1,18 +1,18 @@ -//===== rAthena Script ======================================= +//===== Hercules Script ====================================== //= Hazy Forest -//===== By: ================================================== +//===== By: ================================================== //= Euphy -//===== Current Version: ===================================== +//===== Current Version: ===================================== //= 1.0 -//===== Compatible With: ===================================== -//= rAthena SVN -//===== Description: ========================================= +//===== Compatible With: ===================================== +//= Hercules +//===== Description: ========================================= //= [Official Conversion] //= Cross through the Hazy Forest to reach the Bifrost. //= Contains the Wandering Guardian quest. -//===== Additional Comments: ================================= +//===== Additional Comments: ================================= //= 1.0 First version. [Euphy] -//============================================================ +//============================================================ // Instance Creation //============================================================ diff --git a/npc/re/mobs/dungeons/gld_re.txt b/npc/re/mobs/dungeons/gld_re.txt index 29955c381..1280755a7 100644 --- a/npc/re/mobs/dungeons/gld_re.txt +++ b/npc/re/mobs/dungeons/gld_re.txt @@ -1,11 +1,11 @@ -//===== rAthena Script ======================================= +//===== Hercules Script ====================================== //= Renewal Guild Monster Spawn Script //===== By: ================================================== //= Euphy //===== Current Version: ===================================== //= 1.0 //===== Compatible With: ===================================== -//= rAthena SVN +//= Hercules //===== Additional Comments: ================================= //= 1.0 First version, Hall of Abyss update. [Euphy] //============================================================ diff --git a/npc/re/scripts_monsters.conf b/npc/re/scripts_monsters.conf index 25811f8b3..46ab419d8 100644 --- a/npc/re/scripts_monsters.conf +++ b/npc/re/scripts_monsters.conf @@ -18,7 +18,7 @@ npc: npc/re/mobs/dungeons/ein_dun.txt npc: npc/re/mobs/dungeons/gef_dun.txt npc: npc/re/mobs/dungeons/gefenia.txt npc: npc/re/mobs/dungeons/glastheim.txt -npc: npc/re/mobs/dungeons/gld_dun.txt +npc: npc/re/mobs/dungeons/gld_re.txt npc: npc/re/mobs/dungeons/gld_dunSE.txt npc: npc/re/mobs/dungeons/gon_dun.txt npc: npc/re/mobs/dungeons/ice_dun.txt diff --git a/sql-files/tools/convert_engine_innodb.sql b/sql-files/tools/convert_engine_innodb.sql index fcb240bb1..5d74b9309 100644 --- a/sql-files/tools/convert_engine_innodb.sql +++ b/sql-files/tools/convert_engine_innodb.sql @@ -1,11 +1,12 @@ -- --- rAthena Database Converter ( MyISAM -> InnoDB ) +-- Hercules Database Converter ( MyISAM -> InnoDB ) -- ALTER TABLE `auction` ENGINE = InnoDB; ALTER TABLE `cart_inventory` ENGINE = InnoDB; ALTER TABLE `char` ENGINE = InnoDB; ALTER TABLE `charlog` ENGINE = InnoDB; +ALTER TABLE `elemental` ENGINE = InnoDB; ALTER TABLE `friends` ENGINE = InnoDB; ALTER TABLE `global_reg_value` ENGINE = InnoDB; ALTER TABLE `guild` ENGINE = InnoDB; @@ -19,6 +20,7 @@ ALTER TABLE `guild_storage` ENGINE = InnoDB; ALTER TABLE `homunculus` ENGINE = InnoDB; ALTER TABLE `hotkey` ENGINE = InnoDB; ALTER TABLE `interlog` ENGINE = InnoDB; +ALTER TABLE `intereg` ENGINE = InnoDB; ALTER TABLE `inventory` ENGINE = InnoDB; ALTER TABLE `ipbanlist` ENGINE = InnoDB; #ALTER TABLE `item_db` ENGINE = InnoDB; @@ -38,5 +40,6 @@ ALTER TABLE `ragsrvinfo` ENGINE = InnoDB; ALTER TABLE `sc_data` ENGINE = InnoDB; ALTER TABLE `skill` ENGINE = InnoDB; ALTER TABLE `skill_homunculus` ENGINE = InnoDB; +ALTER TABLE `sql_updates` ENGINE = InnoDB; ALTER TABLE `sstatus` ENGINE = InnoDB; ALTER TABLE `storage` ENGINE = InnoDB; diff --git a/sql-files/tools/convert_engine_myisam.sql b/sql-files/tools/convert_engine_myisam.sql index 5af878f65..a05163f85 100644 --- a/sql-files/tools/convert_engine_myisam.sql +++ b/sql-files/tools/convert_engine_myisam.sql @@ -1,11 +1,12 @@ -- --- rAthena Database Converter ( InnoDB -> MyISAM ) +-- Hercules Database Converter ( InnoDB -> MyISAM ) -- ALTER TABLE `auction` ENGINE = MyISAM; ALTER TABLE `cart_inventory` ENGINE = MyISAM; ALTER TABLE `char` ENGINE = MyISAM; ALTER TABLE `charlog` ENGINE = MyISAM; +ALTER TABLE `elemental` ENGINE = MyISAM; ALTER TABLE `friends` ENGINE = MyISAM; ALTER TABLE `global_reg_value` ENGINE = MyISAM; ALTER TABLE `guild` ENGINE = MyISAM; @@ -19,6 +20,7 @@ ALTER TABLE `guild_storage` ENGINE = MyISAM; ALTER TABLE `homunculus` ENGINE = MyISAM; ALTER TABLE `hotkey` ENGINE = MyISAM; ALTER TABLE `interlog` ENGINE = MyISAM; +ALTER TABLE `intereg` ENGINE = MyISAM; ALTER TABLE `inventory` ENGINE = MyISAM; ALTER TABLE `ipbanlist` ENGINE = MyISAM; #ALTER TABLE `item_db` ENGINE = MyISAM; @@ -38,5 +40,6 @@ ALTER TABLE `ragsrvinfo` ENGINE = MyISAM; ALTER TABLE `sc_data` ENGINE = MyISAM; ALTER TABLE `skill` ENGINE = MyISAM; ALTER TABLE `skill_homunculus` ENGINE = MyISAM; +ALTER TABLE `sql_updates` ENGINE = MyISAM; ALTER TABLE `sstatus` ENGINE = MyISAM; ALTER TABLE `storage` ENGINE = MyISAM; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index b6a9e42ee..3d0dfb6a7 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -816,8 +816,7 @@ ACMD(storage) if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag) return false; - if (storage_storageopen(sd) == 1) - { //Already open. + if (storage->open(sd) == 1) { //Already open. clif->message(fd, msg_txt(250)); return false; } @@ -853,7 +852,7 @@ ACMD(guildstorage) return false; } - storage_guild_storageopen(sd); + gstorage->open(sd); clif->message(fd, msg_txt(920)); // Guild storage opened. return true; } @@ -5233,7 +5232,7 @@ ACMD(storeall) if (sd->state.storage_flag != 1) { //Open storage. - if( storage_storageopen(sd) == 1 ) { + if( storage->open(sd) == 1 ) { clif->message(fd, msg_txt(1161)); // You currently cannot open your storage. return false; } @@ -5243,10 +5242,14 @@ ACMD(storeall) if (sd->status.inventory[i].amount) { if(sd->status.inventory[i].equip != 0) pc->unequipitem(sd, i, 3); +<<<<<<< HEAD storage_storageadd(sd, i, sd->status.inventory[i].amount); +======= + storage->add(sd, i, sd->status.inventory[i].amount); +>>>>>>> upstream/master } } - storage_storageclose(sd); + storage->close(sd); clif->message(fd, msg_txt(1162)); // All items stored. return true; @@ -5264,9 +5267,9 @@ ACMD(clearstorage) j = sd->status.storage.storage_amount; for (i = 0; i < j; ++i) { - storage_delitem(sd, i, sd->status.storage.items[i].amount); + storage->delitem(sd, i, sd->status.storage.items[i].amount); } - storage_storageclose(sd); + storage->close(sd); clif->message(fd, msg_txt(1394)); // Your storage was cleaned. return true; @@ -5276,7 +5279,7 @@ ACMD(cleargstorage) { int i, j; struct guild *g; - struct guild_storage *gstorage; + struct guild_storage *guild_storage; nullpo_retr(-1, sd); g = sd->guild; @@ -5296,18 +5299,18 @@ ACMD(cleargstorage) return false; } - gstorage = guild2storage2(sd->status.guild_id); - if (gstorage == NULL) {// Doesn't have opened @gstorage yet, so we skip the deletion since *shouldn't* have any item there. + guild_storage = gstorage->id2storage2(sd->status.guild_id); + if (guild_storage == NULL) {// Doesn't have opened @gstorage yet, so we skip the deletion since *shouldn't* have any item there. return false; } - j = gstorage->storage_amount; - gstorage->lock = 1; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member + j = guild_storage->storage_amount; + guild_storage->lock = 1; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member for (i = 0; i < j; ++i) { - guild_storage_delitem(sd, gstorage, i, gstorage->items[i].amount); + gstorage->delitem(sd, guild_storage, i, guild_storage->items[i].amount); } - storage_guild_storageclose(sd); - gstorage->lock = 0; // Cleaning done, release lock + gstorage->close(sd); + guild_storage->lock = 0; // Cleaning done, release lock clif->message(fd, msg_txt(1395)); // Your guild storage was cleaned. return true; diff --git a/src/map/battle.c b/src/map/battle.c index 31fe502f6..f6695915b 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -753,8 +753,13 @@ int battle_calc_masteryfix(struct block_list *src, struct block_list *target, ui int ratio = sd->status.base_level + status_get_dex(src) + status_get_luk(src); if ( i == 2 ) ratio += status_get_str(src); //Star Anger if (skill < 4 ) +<<<<<<< HEAD ratio /= 12 - 3 * skill; damage += damage * ratio; +======= + ratio /= (12 - 3 * skill); + damage += damage * ratio / 100; +>>>>>>> upstream/master } if( sc ){ @@ -820,7 +825,11 @@ int battle_calc_elefix(struct block_list *src, struct block_list *target, uint16 { // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex] damage = #ifndef RENEWAL +<<<<<<< HEAD battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, ((TBL_PC*)src), (flag?2:0)) +======= + battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, BL_CAST(BL_PC, src), (flag?2:0)) +>>>>>>> upstream/master #else battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (flag?2:0)|(sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0) #endif @@ -830,7 +839,11 @@ int battle_calc_elefix(struct block_list *src, struct block_list *target, uint16 if( left ){ damage = #ifndef RENEWAL +<<<<<<< HEAD battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, ((TBL_PC*)src), (flag?2:0)) +======= + battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, BL_CAST(BL_PC, src), (flag?2:0)) +>>>>>>> upstream/master #else battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (flag?2:0)|(sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0) #endif @@ -4345,6 +4358,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.damage = sstatus->max_hp* 9/100; wd.damage2 = 0; break; +<<<<<<< HEAD #ifdef RENEWAL case MO_EXTREMITYFIST: // [malufett] @@ -4354,6 +4368,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list flag.tdef = 1; break; case NJ_ISSEN: // [malufett] +======= + case NJ_ISSEN: // [malufett] +#ifndef RENEWAL + wd.damage = 40*sstatus->str +skill_lv*(sstatus->hp/10 + 35); + wd.damage2 = 0; +#else +>>>>>>> upstream/master { short totaldef = status_get_total_def(target); i = 0; @@ -4367,12 +4388,23 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list ATK_RATE(50); flag.idef = 1; } +<<<<<<< HEAD #else wd.damage = 40*sstatus->str +skill_lv*(sstatus->hp/10 + 35); wd.damage2 = 0; #endif break; +======= + break; + case MO_EXTREMITYFIST: // [malufett] + wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|8, wd.flag); + // first value is still not confirm. + wd.damage = status_get_sp(src) + 10 * status_get_sp(src) * wd.damage / 100 + 8 * wd.damage; + flag.tdef = 1; +#endif + break; +>>>>>>> upstream/master #ifndef RENEWAL case LK_SPIRALPIERCE: case ML_SPIRALPIERCE: diff --git a/src/map/battleground.c b/src/map/battleground.c index 64bc25269..88cc323bf 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -420,9 +420,20 @@ int bg_id2pos ( int queue_id, int account_id ) { } return 0; } +void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bool response) { + if( arena->begin_timer == INVALID_TIMER || !sd->bg_queue.arena || sd->bg_queue.arena != arena ) { + bg->queue_pc_cleanup(sd); + return; + } + if( response ) { + sd->bg_queue.ready = 1; + /* check if all are ready then cancell timer, and start game */ + } else + bg->queue_pc_cleanup(sd); +} void bg_queue_player_cleanup(struct map_session_data *sd) { if ( sd->bg_queue.client_has_bg_data ) { - clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW, sd->bg_queue.arena->id); + clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW, sd->bg_queue.arena ? sd->bg_queue.arena->id : 0); } script->queue_remove(sd->bg_queue.arena->queue_id,sd->status.account_id); sd->bg_queue.arena = NULL; @@ -726,6 +737,7 @@ void battleground_defaults(void) { bg->begin_timer = bg_begin_timer; bg->queue_pregame = bg_queue_pregame; bg->fillup_timer = bg_fillup_timer; + bg->queue_ready_ack = bg_queue_ready_ack; /* */ bg->config_read = bg_config_read; } diff --git a/src/map/battleground.h b/src/map/battleground.h index 8fe9f3b77..030d13d90 100644 --- a/src/map/battleground.h +++ b/src/map/battleground.h @@ -96,6 +96,7 @@ struct battleground_interface { int (*begin_timer) (int tid, unsigned int tick, int id, intptr_t data); void (*queue_pregame) (struct bg_arena *arena); int (*fillup_timer) (int tid, unsigned int tick, int id, intptr_t data); + void (*queue_ready_ack) (struct bg_arena *arena, struct map_session_data *sd, bool response); /* */ void (*config_read) (void); } bg_s; diff --git a/src/map/chrif.c b/src/map/chrif.c index 6e076e6d8..a95193363 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -286,7 +286,7 @@ int chrif_save(struct map_session_data *sd, int flag) { //For data sync if (sd->state.storage_flag == 2) - storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); + gstorage->save(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. @@ -526,7 +526,7 @@ void chrif_on_ready(void) { auth_db->foreach(auth_db,chrif_reconnect); //Re-save any storages that were modified in the disconnection time. [Skotlex] - do_reconnect_storage(); + storage->reconnect(); //Re-save any guild castles that were modified in the disconnection time. guild->castle_reconnect(-1, 0, 0); diff --git a/src/map/clif.c b/src/map/clif.c index e8de09d70..4ac123c5a 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -5964,12 +5964,18 @@ void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len) safestrncpy((char*)WFIFOP(fd,28), mes, mes_len); WFIFOSET(fd,WFIFOW(fd,2)); #else + struct map_session_data *ssd = iMap->nick2sd(nick); + WFIFOHEAD(fd, mes_len + NAME_LENGTH + 8); WFIFOW(fd,0) = 0x97; WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8; safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH); +<<<<<<< HEAD WFIFOL(fd,28) = 0; // isAdmin; if nonzero, also displays text above char // TODO: WFIFOL(fd,28) = pc->get_group_level(ssd); +======= + WFIFOL(fd,28) = (ssd && pc->get_group_level(ssd) == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char +>>>>>>> upstream/master safestrncpy((char*)WFIFOP(fd,32), mes, mes_len); WFIFOSET(fd,WFIFOW(fd,2)); #endif @@ -9756,7 +9762,7 @@ void clif_parse_progressbar(int fd, struct map_session_data * sd) if( iTimer->gettick() < sd->progressbar.timeout && sd->st ) sd->st->state = END; - sd->progressbar.npc_id = sd->progressbar.timeout = 0; + sd->state.workinprogress = sd->progressbar.npc_id = sd->progressbar.timeout = 0; npc_scriptcont(sd, npc_id, false); } @@ -9776,8 +9782,8 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) if (sd->sc.opt1 && ( sd->sc.opt1 == OPT1_STONEWAIT || sd->sc.opt1 == OPT1_BURNING )) ; //You CAN walk on this OPT1 value. - else if( sd->progressbar.npc_id ) - clif->progressbar_abort(sd); + /*else if( sd->progressbar.npc_id ) + clif->progressbar_abort(sd);*/ else if (pc_cant_act(sd)) return; @@ -10572,7 +10578,7 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) if (pc_isdead(sd)) break; - if ( pc_cant_act2(sd) ) + if ( pc_cant_act2(sd) || sd->state.vending ) break; if (sd->sc.count && ( @@ -10794,7 +10800,11 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd) #endif return; } +<<<<<<< HEAD if ( pc_cant_act2(sd) || !(bl = iMap->id2bl(RFIFOL(fd,2))) ) +======= + if ( pc_cant_act2(sd) || !(bl = iMap->id2bl(RFIFOL(fd,2))) || sd->state.vending ) +>>>>>>> upstream/master return; switch (bl->type) { @@ -11848,10 +11858,9 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) return; if (sd->state.storage_flag == 1) - storage_storageadd(sd, item_index, item_amount); - else - if (sd->state.storage_flag == 2) - storage_guild_storageadd(sd, item_index, item_amount); + storage->add(sd, item_index, item_amount); + else if (sd->state.storage_flag == 2) + gstorage->add(sd, item_index, item_amount); } @@ -11867,9 +11876,9 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) item_amount = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[1]); if (sd->state.storage_flag == 1) - storage_storageget(sd, item_index, item_amount); + storage->get(sd, item_index, item_amount); else if(sd->state.storage_flag == 2) - storage_guild_storageget(sd, item_index, item_amount); + gstorage->get(sd, item_index, item_amount); } @@ -11883,10 +11892,9 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) return; if (sd->state.storage_flag == 1) - storage_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); - else - if (sd->state.storage_flag == 2) - storage_guild_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); + storage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); + else if (sd->state.storage_flag == 2) + gstorage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); } @@ -11900,10 +11908,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) return; if (sd->state.storage_flag == 1) - storage_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); - else - if (sd->state.storage_flag == 2) - storage_guild_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); + storage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); + else if (sd->state.storage_flag == 2) + gstorage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); } @@ -11912,9 +11919,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) void clif_parse_CloseKafra(int fd, struct map_session_data *sd) { if( sd->state.storage_flag == 1 ) - storage_storageclose(sd); + storage->close(sd); else if( sd->state.storage_flag == 2 ) - storage_guild_storageclose(sd); + gstorage->close(sd); } @@ -17399,8 +17406,14 @@ void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) { } void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) { - //struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd, bgqueue_checkstateType); - return; + struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd, bgqueue_checkstateType); + struct bg_arena *arena; + if( !bg->queue_on ) return; /* temp, until feature is complete */ + if( ( arena = bg->name2arena(p->bg_name) ) ) { + bg->queue_ready_ack(arena,sd, ( p->result == 1 ) ? true : false); + } else { + clif->bgqueue_ack(sd,BGQA_FAIL_BGNAME_INVALID, 0); + } //if ( p->result == 1 ) // bg->queue_pc_ready(sd); //else diff --git a/src/map/guild.c b/src/map/guild.c index b28c14db7..e093fdf92 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -921,7 +921,7 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c if(sd != NULL && sd->status.guild_id == guild_id) { // do stuff that needs the guild_id first, BEFORE we wipe it if (sd->state.storage_flag == 2) //Close the guild storage. - storage_guild_storageclose(sd); + gstorage->close(sd); guild->send_dot_remove(sd); if( hChSys.ally ) { clif->chsys_quitg(sd); @@ -1752,7 +1752,7 @@ int guild_broken(int guild_id,int flag) for(i=0;i<g->max_member;i++){ // Destroy all relationships if((sd=g->member[i].sd)!=NULL){ if(sd->state.storage_flag == 2) - storage_guild_storage_quit(sd,1); + gstorage->pc_quit(sd,1); sd->status.guild_id=0; sd->guild = NULL; clif->guild_broken(g->member[i].sd,0); @@ -1762,7 +1762,7 @@ int guild_broken(int guild_id,int flag) guild_db->foreach(guild_db,guild_broken_sub,guild_id); castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id); - guild_storage_delete(guild_id); + gstorage->delete(guild_id); if( hChSys.ally ) { if( g->channel != NULL ) { clif->chsys_delete(( struct hChSysCh * )g->channel); diff --git a/src/map/intif.c b/src/map/intif.c index f3931e79e..e364f5c25 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1011,7 +1011,7 @@ int intif_parse_LoadGuildStorage(int fd) ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4)); return 1; } - gstor=guild2storage(guild_id); + gstor=gstorage->id2storage(guild_id); if(!gstor) { ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id); return 1; @@ -1031,14 +1031,14 @@ int intif_parse_LoadGuildStorage(int fd) } memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage)); - storage_guild_storageopen(sd); + gstorage->open(sd); return 0; } // ACK guild_storage saved int intif_parse_SaveGuildStorage(int fd) { - storage_guild_storagesaved(/*RFIFOL(fd,2), */RFIFOL(fd,6)); + gstorage->saved(/*RFIFOL(fd,2), */RFIFOL(fd,6)); return 0; } diff --git a/src/map/map.c b/src/map/map.c index d74263d1a..a030515d8 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -5031,7 +5031,7 @@ void do_final(void) do_final_npc(); script->final(); do_final_itemdb(); - do_final_storage(); + storage->final(); guild->final(); party->do_final_party(); pc->do_final_pc(); @@ -5235,7 +5235,13 @@ void map_hp_symbols(void) { HPM->share(buyingstore,"buyingstore"); HPM->share(clif,"clif"); HPM->share(guild,"guild"); +<<<<<<< HEAD HPM->share(homun,"homun"); +======= + HPM->share(gstorage,"gstorage"); + HPM->share(homun,"homun"); + HPM->share(iMap,"iMap"); +>>>>>>> upstream/master HPM->share(ircbot,"ircbot"); HPM->share(itemdb,"itemdb"); HPM->share(logs,"logs"); @@ -5246,7 +5252,12 @@ void map_hp_symbols(void) { HPM->share(vending,"vending"); HPM->share(pc,"pc"); HPM->share(party,"party"); +<<<<<<< HEAD HPM->share(iMap,"iMap"); +======= + HPM->share(storage,"storage"); + HPM->share(trade,"trade"); +>>>>>>> upstream/master /* partial */ HPM->share(mapit,"mapit"); /* sql link */ @@ -5265,6 +5276,7 @@ void load_defaults(void) { buyingstore_defaults(); clif_defaults(); guild_defaults(); + gstorage_defaults(); homunculus_defaults(); instance_defaults(); ircbot_defaults(); @@ -5278,6 +5290,11 @@ void load_defaults(void) { vending_defaults(); pc_defaults(); party_defaults(); +<<<<<<< HEAD +======= + storage_defaults(); + trade_defaults(); +>>>>>>> upstream/master } int do_init(int argc, char *argv[]) { @@ -5468,7 +5485,7 @@ int do_init(int argc, char *argv[]) do_init_status(); party->do_init_party(); guild->init(); - do_init_storage(); + storage->init(); do_init_pet(); homun->init(); do_init_mercenary(); diff --git a/src/map/packets.h b/src/map/packets.h index c467090dd..8e070dd05 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -2035,6 +2035,12 @@ packet(0x020d,-1); #endif #endif +#ifndef PACKETVER_RE +#if PACKETVER >= 20120604 + packet(0x0861,18,clif->pPartyBookingRegisterReq,2,4,6); +#endif +#endif + //2012-06-18aRagexeRE #if PACKETVER >= 20120618 packet(0x0983,29); @@ -2249,8 +2255,193 @@ packet(0x020d,-1); packet(0x0883,36,clif->pStoragePassword,0); #endif +<<<<<<< HEAD #if PACKETVER >= 20130612 packetKeys(0x6D166F66, 0x3C000FCF, 0x295B0FCB); /* Thanks to Shakto */ #endif +======= +/* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */ +#if PACKETVER >= 20110817 + packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20110824 + packetKeys(0x35C91401,0x262A5556,0x28FA03AA); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20110831 + packetKeys(0x3AD67ED0,0x44703C69,0x6F876809); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20110906 + packetKeys(0x3AD67ED0,0x44703C69,0x6F876809); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111005 + packetKeys(0x291E6762,0x77CD391A,0x60AC2F16); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111012 + packetKeys(0x7F3C2D29,0x59B01DE6,0x1DBB44CA); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111021 + packetKeys(0x357D55DC,0x5A8D759F,0x245C30F5); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111025 + packetKeys(0x50AE1A63,0x3CE579B5,0x29C10406); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111102 + packetKeys(0x5324329D,0x5D545D52,0x06137269); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111109 + packetKeys(0x0B642BDA,0x6ECB1D1C,0x61C7454B); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111122 + packetKeys(0x3B550F07,0x1F666C7C,0x60304EF5); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111207 + packetKeys(0x2A610886,0x3E09165E,0x57C11888); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111214 + packetKeys(0x5151306B,0x7AE32886,0x53060628); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111220 + packetKeys(0x05D53871,0x7D0027B4,0x29975333); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20111228 + packetKeys(0x0FF87E93,0x6CFF7860,0x3A3D1DEC); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120104 + packetKeys(0x262034A1,0x674542A5,0x73A50BA5); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120111 + packetKeys(0x2B412AFC,0x4FF94487,0x6705339D); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120120 + packetKeys(0x504345D0,0x3D427B1B,0x794C2DCC); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120202 + packetKeys(0x2CFC0A71,0x2BA91D8D,0x087E39E0); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120207 + packetKeys(0x1D373F5D,0x5ACD604D,0x1C4D7C4D); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120214 + packetKeys(0x7A255EFA,0x30977276,0x2D4A0448); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120229 + packetKeys(0x520B4C64,0x2800407D,0x47651458); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120307 + packetKeys(0x382A6DEF,0x5CBE7202,0x61F46637); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120314 + packetKeys(0x689C1729,0x11812639,0x60F82967); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120321 + packetKeys(0x21F9683F,0x710C5CA5,0x1FD910E9); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120328 + packetKeys(0x75B8553B,0x37F20B12,0x385C2B40); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120404 + packetKeys(0x0036310C,0x2DCD0BED,0x1EE62A78); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120410 + packetKeys(0x01581359,0x452D6FFA,0x6AFB6E2E); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120418 + packetKeys(0x01540E48,0x13041224,0x31247924); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120424 + packetKeys(0x411D1DBB,0x4CBA4848,0x1A432FC4); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120509 + packetKeys(0x16CF3301,0x1F472B9B,0x0B4A3CD2); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120515 + packetKeys(0x4A715EF9,0x79103E4F,0x405C1238); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120525 + packetKeys(0x70EB4CCB,0x0487713C,0x398D4B08); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120605 + packetKeys(0x68CA3080,0x31B74BDD,0x505208F1); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120612 + packetKeys(0x32E45D64,0x35643564,0x35643564); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120618 + packetKeys(0x261F261F,0x261F261F,0x261F261F); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120702 + packetKeys(0x25733B31,0x53486CFD,0x398649BD); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20120716 + packetKeys(0x76052205,0x22052205,0x22052205); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20130320 + packetKeys(0x3F094C49,0x55F86C1E,0x58AA359A); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20130514 + packetKeys(0x75794A38,0x58A96BC1,0x296E6FB8); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20130522 + packetKeys(0x6948050B,0x06511D9D,0x725D4DF1); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20130529 + packetKeys(0x023A6C87,0x14BF1F1E,0x5CC70CC9); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20130605 + packetKeys(0x646E08D9,0x5F153AB5,0x61B509B5); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20130612 + packetKeys(0x6D166F66,0x3C000FCF,0x295B0FCB); /* Thanks to Shakto */ +#endif + +#if PACKETVER >= 20130618 + packetKeys(0x434115DE,0x34A10FE9,0x6791428E); /* Thanks to Shakto */ +#endif + + +>>>>>>> upstream/master #endif /* _PACKETS_H_ */ diff --git a/src/map/pc.c b/src/map/pc.c index ef70aad97..945925c86 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -12,6 +12,7 @@ #include "../common/strlib.h" // safestrncpy() #include "../common/timer.h" #include "../common/utils.h" +#include "../common/conf.h" #include "../common/mmo.h" //NAME_LENGTH #include "atcommand.h" // get_atcommand_level() @@ -4255,7 +4256,7 @@ int pc_useitem(struct map_session_data *sd,int n) nullpo_ret(sd); - if( sd->npc_id ){ + if( sd->npc_id || sd->state.workinprogress&1 ){ /* TODO: add to clif->messages enum */ #ifdef RENEWAL clif->msg(sd, 0x783); // TODO look for the client date that has this message. @@ -4295,8 +4296,8 @@ int pc_useitem(struct map_session_data *sd,int n) return 0; /* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */ - if( sd->inventory_data[n]->flag.delay_consume ) { - if( nameid != ITEMID_REINS_OF_MOUNT && sd->sc.data[SC_ALL_RIDING] ) + if( sd->inventory_data[n]->flag.delay_consume && nameid != ITEMID_REINS_OF_MOUNT ) { + if( sd->sc.data[SC_ALL_RIDING] ) return 0; else if( pc_issit(sd) ) return 0; @@ -4323,7 +4324,8 @@ int pc_useitem(struct map_session_data *sd,int n) } else {// not yet used item (all slots are initially empty) sd->item_delay[i].nameid = nameid; } - sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay; + if( !(nameid == ITEMID_REINS_OF_MOUNT && sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR)) ) + sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay; } else {// should not happen ShowError("pc_useitem: Exceeded item delay array capacity! (nameid=%d, char_id=%d)\n", nameid, sd->status.char_id); } @@ -9515,55 +9517,269 @@ int pc_split_atoui(char* str, unsigned int* val, char sep, int max) val[j] = 0; return i; } +/* [Ind/Hercules] */ +void pc_read_skill_tree(void) { + config_t skill_tree_conf; + config_setting_t *skt = NULL, *inherit = NULL, *skills = NULL, *sk = NULL; +#ifdef RENEWAL + const char *config_filename = "db/re/skill_tree.conf"; // FIXME hardcoded name +#else + const char *config_filename = "db/pre-re/skill_tree.conf"; // FIXME hardcoded name +#endif + int i = 0, jnamelen = 0; + struct { + const char *name; + int id; + } jnames[] = { + { "Novice", JOB_NOVICE }, + { "Swordsman", JOB_SWORDMAN }, + { "Magician", JOB_MAGE }, + { "Archer", JOB_ARCHER }, + { "Acolyte", JOB_ACOLYTE }, + { "Merchant", JOB_MERCHANT }, + { "Thief", JOB_THIEF }, + { "Knight", JOB_KNIGHT }, + { "Priest", JOB_PRIEST }, + { "Wizard", JOB_WIZARD }, + { "Blacksmith", JOB_BLACKSMITH }, + { "Hunter", JOB_HUNTER }, + { "Assassin", JOB_ASSASSIN }, + { "Crusader", JOB_CRUSADER }, + { "Monk", JOB_MONK }, + { "Sage", JOB_SAGE }, + { "Rogue", JOB_ROGUE }, + { "Alchemist", JOB_ALCHEMIST }, + { "Bard", JOB_BARD }, + { "Dancer", JOB_DANCER }, + { "Super_Novice", JOB_SUPER_NOVICE }, + { "Gunslinger", JOB_GUNSLINGER }, + { "Ninja", JOB_NINJA }, + { "Novice_High", JOB_NOVICE_HIGH }, + { "Swordsman_High", JOB_SWORDMAN_HIGH }, + { "Magician_High", JOB_MAGE_HIGH }, + { "Archer_High", JOB_ARCHER_HIGH }, + { "Acolyte_High", JOB_ACOLYTE_HIGH }, + { "Merchant_High", JOB_MERCHANT_HIGH }, + { "Thief_High", JOB_THIEF_HIGH }, + { "Lord_Knight", JOB_LORD_KNIGHT }, + { "High_Priest", JOB_HIGH_PRIEST }, + { "High_Wizard", JOB_HIGH_WIZARD }, + { "Whitesmith", JOB_WHITESMITH }, + { "Sniper", JOB_SNIPER }, + { "Assassin_Cross", JOB_ASSASSIN_CROSS }, + { "Paladin", JOB_PALADIN }, + { "Champion", JOB_CHAMPION }, + { "Professor", JOB_PROFESSOR }, + { "Stalker", JOB_STALKER }, + { "Creator", JOB_CREATOR }, + { "Clown", JOB_CLOWN }, + { "Gypsy", JOB_GYPSY }, + { "Baby_Novice", JOB_BABY }, + { "Baby_Swordsman", JOB_BABY_SWORDMAN }, + { "Baby_Magician", JOB_BABY_MAGE }, + { "Baby_Archer", JOB_BABY_ARCHER }, + { "Baby_Acolyte", JOB_BABY_ACOLYTE }, + { "Baby_Merchant", JOB_BABY_MERCHANT }, + { "Baby_Thief", JOB_BABY_THIEF }, + { "Baby_Knight", JOB_BABY_KNIGHT }, + { "Baby_Priest", JOB_BABY_PRIEST }, + { "Baby_Wizard", JOB_BABY_WIZARD }, + { "Baby_Blacksmith", JOB_BABY_BLACKSMITH }, + { "Baby_Hunter", JOB_BABY_HUNTER }, + { "Baby_Assassin", JOB_BABY_ASSASSIN }, + { "Baby_Crusader", JOB_BABY_CRUSADER }, + { "Baby_Monk", JOB_BABY_MONK }, + { "Baby_Sage", JOB_BABY_SAGE }, + { "Baby_Rogue", JOB_BABY_ROGUE }, + { "Baby_Alchemist", JOB_BABY_ALCHEMIST }, + { "Baby_Bard", JOB_BABY_BARD }, + { "Baby_Dancer", JOB_BABY_DANCER }, + { "Super_Baby", JOB_SUPER_BABY }, + { "Taekwon", JOB_TAEKWON }, + { "Star_Gladiator", JOB_STAR_GLADIATOR }, + { "Soul_Linker", JOB_SOUL_LINKER }, + { "Gangsi", JOB_GANGSI }, + { "Death_Knight", JOB_DEATH_KNIGHT }, + { "Dark_Collector", JOB_DARK_COLLECTOR }, + { "Rune_Knight", JOB_RUNE_KNIGHT }, + { "Warlock", JOB_WARLOCK }, + { "Ranger", JOB_RANGER }, + { "Arch_Bishop", JOB_ARCH_BISHOP }, + { "Mechanic", JOB_MECHANIC }, + { "Guillotine_Cross", JOB_GUILLOTINE_CROSS }, + { "Rune_Knight_Trans", JOB_RUNE_KNIGHT_T }, + { "Warlock_Trans", JOB_WARLOCK_T }, + { "Ranger_Trans", JOB_RANGER_T }, + { "Arch_Bishop_Trans", JOB_ARCH_BISHOP_T }, + { "Mechanic_Trans", JOB_MECHANIC_T }, + { "Guillotine_Cross_Trans", JOB_GUILLOTINE_CROSS_T }, + { "Royal_Guard", JOB_ROYAL_GUARD }, + { "Sorcerer", JOB_SORCERER }, + { "Minstrel", JOB_MINSTREL }, + { "Wanderer", JOB_WANDERER }, + { "Sura", JOB_SURA }, + { "Genetic", JOB_GENETIC }, + { "Shadow_Chaser", JOB_SHADOW_CHASER }, + { "Royal_Guard_Trans", JOB_ROYAL_GUARD_T }, + { "Sorcerer_Trans", JOB_SORCERER_T }, + { "Minstrel_Trans", JOB_MINSTREL_T }, + { "Wanderer_Trans", JOB_WANDERER_T }, + { "Sura_Trans", JOB_SURA_T }, + { "Genetic_Trans", JOB_GENETIC_T }, + { "Shadow_Chaser_Trans", JOB_SHADOW_CHASER_T }, + { "Baby_Rune_Knight", JOB_BABY_RUNE }, + { "Baby_Warlock", JOB_BABY_WARLOCK }, + { "Baby_Ranger", JOB_BABY_RANGER }, + { "Baby_Arch_Bishop", JOB_BABY_BISHOP }, + { "Baby_Mechanic", JOB_BABY_MECHANIC }, + { "Baby_Guillotine_Cross", JOB_BABY_CROSS }, + { "Baby_Royal_Guard", JOB_BABY_GUARD }, + { "Baby_Sorcerer", JOB_BABY_SORCERER }, + { "Baby_Minstrel", JOB_BABY_MINSTREL }, + { "Baby_Wanderer", JOB_BABY_WANDERER }, + { "Baby_Sura", JOB_BABY_SURA }, + { "Baby_Genetic", JOB_BABY_GENETIC }, + { "Baby_Shadow_Chaser", JOB_BABY_CHASER }, + { "Expanded_Super_Novice", JOB_SUPER_NOVICE_E }, + { "Expanded_Super_Baby", JOB_SUPER_BABY_E }, + { "Kagerou", JOB_KAGEROU }, + { "Oboro", JOB_OBORO }, + }; + + if (conf_read_file(&skill_tree_conf, config_filename)) { + ShowError("can't read %s\n", config_filename); + return; + } + + jnamelen = ARRAYLENGTH(jnames); + + while( (skt = config_setting_get_elem(skill_tree_conf.root,i++)) ) { + int k, idx; + const char *name = config_setting_name(skt); + + ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 ); + + if( k == jnamelen ) { + ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name); + continue; + } + + + if( ( skills = config_setting_get_member(skt,"skills") ) ) { + int c = 0; + + idx = pc->class2idx(jnames[k].id); + + while( ( sk = config_setting_get_elem(skills,c++) ) ) { + const char *sk_name = config_setting_name(sk); + int skill_id; + + if( ( skill_id = skill->name2id(sk_name) ) ) { + int skidx, offset = 0, h = 0, rlen = 0, rskid = 0; + + ARR_FIND( 0, MAX_SKILL_TREE, skidx, skill_tree[idx][skidx].id == 0 || skill_tree[idx][skidx].id == skill_id ); + if( skidx == MAX_SKILL_TREE ) { + ShowWarning("pc_read_skill_tree: Unable to load skill %hu (%s) into '%s's tree. Maximum number of skills per class has been reached.\n", skill_id, sk_name, name); + continue; + } else if(skill_tree[idx][skidx].id) { + ShowNotice("pc_read_skill_tree: Overwriting %hu for '%s' (%d)\n", skill_id, name, jnames[k].id); + } + + skill_tree[idx][skidx].id = skill_id; + skill_tree[idx][skidx].idx = skill->get_index(skill_id); + + if( config_setting_is_group(sk) ) { + int max = 0, jlevel = 0; + config_setting_lookup_int(sk, "MaxLevel", &max); + config_setting_lookup_int(sk, "MinJobLevel", &jlevel); + skill_tree[idx][skidx].max = (unsigned char)max; + skill_tree[idx][skidx].joblv = (unsigned char)jlevel; + rlen = config_setting_length(sk); + offset += jlevel ? 2 : 1; + } else { + skill_tree[idx][skidx].max = (unsigned char)config_setting_get_int(sk); + skill_tree[idx][skidx].joblv = 0; + } + + for( h = offset; h < rlen && h < MAX_PC_SKILL_REQUIRE; h++ ) { + config_setting_t *rsk = config_setting_get_elem(sk,h); + if( rsk && ( rskid = skill->name2id(config_setting_name(rsk)) ) ) { + skill_tree[idx][skidx].need[h].id = rskid; + skill_tree[idx][skidx].need[h].idx = skill->get_index(rskid); + skill_tree[idx][skidx].need[h].lv = (unsigned char)config_setting_get_int(rsk); + } else if( rsk ) { + ShowWarning("pc_read_skill_tree: unknown requirement '%s' for '%s' in '%s'\n",config_setting_name(rsk),sk_name,name); + } else { + ShowWarning("pc_read_skill_tree: error for '%s' in '%s'\n",sk_name,name); + } + } + + } else { + ShowWarning("pc_read_skill_tree: unknown skill '%s' in '%s'\n",sk_name,name); + } + } + } + } + + i = 0; + while( (skt = config_setting_get_elem(skill_tree_conf.root,i++)) ) { + int k, idx, v = 0; + const char *name = config_setting_name(skt); + const char *iname; -/*========================================== - * sub DB reading. - * Function used to read skill_tree.txt - *------------------------------------------*/ -static bool pc_readdb_skilltree(char* fields[], int columns, int current) -{ - unsigned char joblv = 0, skill_lv; - uint16 skill_id; - int idx, class_; - unsigned int i, offset = 3, skill_idx; + + ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 ); + + if( k == jnamelen ) { + ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name); + continue; + } + idx = pc->class2idx(jnames[k].id); - class_ = atoi(fields[0]); - skill_id = (uint16)atoi(fields[1]); - skill_lv = (unsigned char)atoi(fields[2]); + if( ( inherit = config_setting_get_member(skt,"inherit") ) ) { + while( ( iname = config_setting_get_string_elem(inherit, v++) ) ) { + int b = 0, a, d, f, fidx; - if(columns==4+MAX_PC_SKILL_REQUIRE*2) - {// job level requirement extra column - joblv = (unsigned char)atoi(fields[3]); - offset++; - } + ARR_FIND(0, jnamelen, b, strcmpi(jnames[b].name,iname) == 0 ); + + if( b == jnamelen ) { + ShowWarning("pc_read_skill_tree: '%s' trying to inherit unknown '%s'!\n",name,iname); + continue; + } + + fidx = pc->class2idx(jnames[b].id); + + ARR_FIND( 0, MAX_SKILL_TREE, d, skill_tree[fidx][d].id == 0 ); +<<<<<<< HEAD if(!pcdb_checkid(class_)) { ShowWarning("pc_readdb_skilltree: Invalid job class %d specified.\n", class_); return false; } idx = pc->class2idx(class_); - - //This is to avoid adding two lines for the same skill. [Skotlex] - ARR_FIND( 0, MAX_SKILL_TREE, skill_idx, skill_tree[idx][skill_idx].id == 0 || skill_tree[idx][skill_idx].id == skill_id ); - if( skill_idx == MAX_SKILL_TREE ) { - ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree. Maximum number of skills per class has been reached.\n", skill_id, class_); - return false; - } else if(skill_tree[idx][skill_idx].id) { - ShowNotice("pc_readdb_skilltree: Overwriting skill %hu for job class %d.\n", skill_id, class_); +======= + for( f = 0; f < d; f++ ) { + + ARR_FIND( 0, MAX_SKILL_TREE, a, skill_tree[idx][a].id == 0 || skill_tree[idx][a].id == skill_tree[fidx][f].id ); +>>>>>>> upstream/master + + if( a == MAX_SKILL_TREE ) { + ShowWarning("pc_read_skill_tree: '%s' can't inherit '%s', skill tree is full!\n", name,iname); + break; + } else if ( skill_tree[idx][a].id || ( skill_tree[idx][a].id == NV_TRICKDEAD && ((pc->jobid2mapid(jnames[k].id)&MAPID_UPPERMASK)!=MAPID_NOVICE) ) ) /* we skip trickdead for non-novices */ + continue;/* skip */ + + memcpy(&skill_tree[idx][a],&skill_tree[fidx][f],sizeof(skill_tree[fidx][f])); + } + + } + } + } + + config_destroy(&skill_tree_conf); - skill_tree[idx][skill_idx].id = skill_id; - skill_tree[idx][skill_idx].idx = skill->get_index(skill_id); - skill_tree[idx][skill_idx].max = skill_lv; - skill_tree[idx][skill_idx].joblv = joblv; - - for(i = 0; i < MAX_PC_SKILL_REQUIRE; i++) { - skill_tree[idx][skill_idx].need[i].id = atoi(fields[i*2+offset]); - skill_tree[idx][skill_idx].need[i].idx = skill->get_index(atoi(fields[i*2+offset])); - skill_tree[idx][skill_idx].need[i].lv = atoi(fields[i*2+offset+1]); - } - return true; } #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) static bool pc_readdb_levelpenalty(char* fields[], int columns, int current) @@ -9695,8 +9911,12 @@ int pc_readdb(void) count = 0; // Reset and read skilltree memset(skill_tree,0,sizeof(skill_tree)); +<<<<<<< HEAD sv->readdb(iMap->db_path, DBPATH"skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 4+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree); +======= + pc_read_skill_tree(); +>>>>>>> upstream/master #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) sv->readdb(iMap->db_path, "re/level_penalty.txt", ',', 4, 4, -1, &pc_readdb_levelpenalty); for( k=1; k < 3; k++ ){ // fill in the blanks diff --git a/src/map/pc.h b/src/map/pc.h index 5c585af1c..43d5d40c7 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -603,7 +603,7 @@ enum equip_pos { #define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) /* equals pc_cant_act except it doesn't check for chat rooms */ -#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) +#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) #define pc_setdir(sd,b,h) ( (sd)->ud.dir = (b) ,(sd)->head_dir = (h) ) #define pc_setchatid(sd,n) ( (sd)->chatID = n ) diff --git a/src/map/script.c b/src/map/script.c index 15870aaa7..4876111ef 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -8179,20 +8179,18 @@ BUILDIN(gettimestr) /*========================================== * Open player storage *------------------------------------------*/ -BUILDIN(openstorage) -{ +BUILDIN(openstorage) { TBL_PC* sd; sd = script_rid2sd(st); if( sd == NULL ) return true; - storage_storageopen(sd); + storage->open(sd); return true; } -BUILDIN(guildopenstorage) -{ +BUILDIN(guildopenstorage) { TBL_PC* sd; int ret; @@ -8200,7 +8198,7 @@ BUILDIN(guildopenstorage) if( sd == NULL ) return true; - ret = storage_guild_storageopen(sd); + ret = gstorage->open(sd); script_pushint(st,ret); return true; } @@ -16312,6 +16310,10 @@ BUILDIN(progressbar) sd->progressbar.npc_id = st->oid; sd->progressbar.timeout = iTimer->gettick() + second*1000; +<<<<<<< HEAD +======= + sd->state.workinprogress = 3; +>>>>>>> upstream/master clif->progressbar(sd, strtol(color, (char **)NULL, 0), second); return true; @@ -16520,9 +16522,10 @@ BUILDIN(setmounting) { TBL_PC* sd; if( (sd = script_rid2sd(st)) == NULL ) return true; - if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ) + if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ){ + clif->msgtable(sd->fd, 0X78b); script_pushint(st,0);//can't mount with one of these - else { + }else { if( sd->sc.data[SC_ALL_RIDING] ) status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER); else diff --git a/src/map/skill.c b/src/map/skill.c index 5a10038d8..1753f435a 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2395,6 +2395,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds //Can't attack nor use items until skill's delay expires. [Skotlex] sd->ud.attackabletime = sd->canuseitem_tick = sd->ud.canact_tick; break; + case TK_DODGE: + if( pc->checkskill(sd, TK_JUMPKICK) > 0 ) + flag = 1; + break; case SR_DRAGONCOMBO: if( pc->checkskill(sd, SR_FALLENEMPIRE) > 0 ) flag = 1; @@ -3761,7 +3765,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint int sflag = skill_area_temp[0] & 0xFFF, heal; if( flag&SD_LEVEL ) sflag |= SD_LEVEL; // -1 will be used in packets instead of the skill level - if( skill_area_temp[1] != bl->id && !(skill->get_inf2(skill_id)&INF2_NPC_SKILL) ) + if( (skill_area_temp[1] != bl->id && !(skill->get_inf2(skill_id)&INF2_NPC_SKILL)) || flag&SD_ANIMATION ) sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills) heal = skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag); @@ -3776,6 +3780,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case GN_CARTCANNON: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; + case SR_TIGERCANNON: + flag |= SD_ANIMATION; case LG_MOONSLASHER: clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); break; @@ -7965,12 +7971,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; for(i = 0; i < SC_MAX; i++) { +<<<<<<< HEAD if( SC_COMMON_MAX > i ){ if ( !tsc->data[i] || !status_get_sc_type(i) ) continue; if ( status_get_sc_type(i)&SC_NO_CLEARANCE ) continue; } +======= + if ( !tsc->data[i] ) + continue; + if( SC_COMMON_MAX > i ) + if ( status_get_sc_type(i)&SC_NO_CLEARANCE ) + continue; +>>>>>>> upstream/master switch (i) { case SC_ASSUMPTIO: if( bl->type == BL_MOB ) @@ -8551,7 +8565,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SR_FLASHCOMBO: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); for(i = SR_FLASHCOMBO_ATK_STEP1; i <= SR_FLASHCOMBO_ATK_STEP4; i++) +<<<<<<< HEAD skill->addtimerskill(src, tick + 600 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL); +======= + skill->addtimerskill(src, tick + 500 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL); +>>>>>>> upstream/master break; case WA_SWING_DANCE: case WA_MOONLIT_SERENADE: @@ -13101,12 +13119,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id case TK_STORMKICK: case TK_DOWNKICK: case TK_COUNTER: + case TK_JUMPKICK: case HT_POWER: case GC_COUNTERSLASH: case GC_WEAPONCRUSH: case SR_FALLENEMPIRE: case SR_DRAGONCOMBO: case SR_TIGERCANNON: + case SR_GATEOFHELL: break; default: return 0; } @@ -17848,7 +17868,7 @@ void skill_reload (void) { * *------------------------------------------*/ int do_init_skill (void) { - skilldb_name2id = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 0); + skilldb_name2id = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAX_SKILL_NAME_LENGTH); skill->read_db(); group_db = idb_alloc(DB_OPT_BASE); diff --git a/src/map/skill.h b/src/map/skill.h index cc9ac4bfc..921a682a2 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -37,6 +37,7 @@ struct square; #define MAX_SKILLUNITGROUP 25 #define MAX_SKILL_ITEM_REQUIRE 10 #define MAX_SKILLUNITGROUPTICKSET 25 +#define MAX_SKILL_NAME_LENGTH 30 // (Epoque:) To-do: replace this macro with some sort of skill tree check (rather than hard-coded skill names) #define skill_ischangesex(id) ( \ @@ -1599,7 +1600,7 @@ struct skill_condition { // Database skills struct s_skill_db { unsigned short nameid; - char name[NAME_LENGTH]; + char name[MAX_SKILL_NAME_LENGTH]; char desc[40]; int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max; int num[MAX_SKILL_LEVEL]; diff --git a/src/map/status.c b/src/map/status.c index 992cc0855..a43be5726 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -8329,10 +8329,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_BLOOD_SUCKER: { +<<<<<<< HEAD struct block_list *src = iMap->id2bl(sce->val2); val3 = 1; if(src) val3 = 200 + 100 * sce->val1 + status_get_int(src); +======= + struct block_list *src = iMap->id2bl(val2); + val3 = 1; + if(src) + val3 = 200 + 100 * val1 + status_get_int(src); +>>>>>>> upstream/master val4 = tick / 1000; tick_time = 1000; // [GodLesZ] tick time } diff --git a/src/map/storage.c b/src/map/storage.c index ea30f6c0f..c999ab07b 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/db.h" @@ -75,14 +76,13 @@ static int storage_reconnect_sub(DBKey key, DBData *data, va_list ap) { struct guild_storage *stor = DB->data2ptr(data); if (stor->dirty && stor->storage_status == 0) //Save closed storages. - storage_guild_storagesave(0, stor->guild_id,0); + gstorage->save(0, stor->guild_id,0); return 0; } //Function to be invoked upon server reconnection to char. To save all 'dirty' storages [Skotlex] -void do_reconnect_storage(void) -{ +void do_reconnect_storage(void) { guild_storage_db->foreach(guild_storage_db, storage_reconnect_sub); } @@ -253,7 +253,11 @@ int storage_storageget(struct map_session_data* sd, int index, int amount) return 0; if( (flag = pc->additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 ) +<<<<<<< HEAD storage_delitem(sd,index,amount); +======= + storage->delitem(sd,index,amount); +>>>>>>> upstream/master else clif->additem(sd,0,0,flag); @@ -310,7 +314,11 @@ int storage_storagegettocart(struct map_session_data* sd, int index, int amount) return 0; if( pc->cart_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE) == 0 ) +<<<<<<< HEAD storage_delitem(sd,index,amount); +======= + storage->delitem(sd,index,amount); +>>>>>>> upstream/master return 1; } @@ -399,7 +407,7 @@ int storage_guild_storageopen(struct map_session_data* sd) return 1; } - if((gstor = guild2storage2(sd->status.guild_id)) == NULL) { + if((gstor = gstorage->id2storage2(sd->status.guild_id)) == NULL) { intif_request_guild_storage(sd->status.account_id,sd->status.guild_id); return 0; } @@ -512,7 +520,7 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount) struct guild_storage *stor; nullpo_ret(sd); - nullpo_ret(stor=guild2storage2(sd->status.guild_id)); + nullpo_ret(stor=gstorage->id2storage2(sd->status.guild_id)); if( !stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE ) return 0; @@ -527,11 +535,15 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount) return 0; if( stor->lock ) { - storage_guild_storageclose(sd); + gstorage->close(sd); return 0; } +<<<<<<< HEAD if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0) +======= + if(gstorage->additem(sd,stor,&sd->status.inventory[index],amount)==0) +>>>>>>> upstream/master pc->delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE); return 1; @@ -565,12 +577,16 @@ int storage_guild_storageget(struct map_session_data* sd, int index, int amount) return 0; if( stor->lock ) { - storage_guild_storageclose(sd); + gstorage->close(sd); return 0; } if((flag = pc->additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0) +<<<<<<< HEAD guild_storage_delitem(sd,stor,index,amount); +======= + gstorage->delitem(sd,stor,index,amount); +>>>>>>> upstream/master else //inform fail clif->additem(sd,0,0,flag); // log_fromstorage(sd, index, 1); @@ -604,7 +620,11 @@ int storage_guild_storageaddfromcart(struct map_session_data* sd, int index, int if( amount < 1 || amount > sd->status.cart[index].amount ) return 0; +<<<<<<< HEAD if(guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0) +======= + if(gstorage->additem(sd,stor,&sd->status.cart[index],amount)==0) +>>>>>>> upstream/master pc->cart_delitem(sd,index,amount,0,LOG_TYPE_GSTORAGE); return 1; @@ -637,7 +657,11 @@ int storage_guild_storagegettocart(struct map_session_data* sd, int index, int a return 0; if(pc->cart_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)==0) +<<<<<<< HEAD guild_storage_delitem(sd,stor,index,amount); +======= + gstorage->delitem(sd,stor,index,amount); +>>>>>>> upstream/master return 1; } @@ -673,7 +697,7 @@ int storage_guild_storagesaved(int guild_id) { struct guild_storage *stor; - if((stor=guild2storage2(guild_id)) != NULL) { + if((stor=gstorage->id2storage2(guild_id)) != NULL) { if (stor->dirty && stor->storage_status == 0) { //Storage has been correctly saved. stor->dirty = 0; @@ -689,7 +713,7 @@ int storage_guild_storageclose(struct map_session_data* sd) struct guild_storage *stor; nullpo_ret(sd); - nullpo_ret(stor=guild2storage2(sd->status.guild_id)); + nullpo_ret(stor=gstorage->id2storage2(sd->status.guild_id)); clif->storageclose(sd); if (stor->storage_status) @@ -697,7 +721,7 @@ int storage_guild_storageclose(struct map_session_data* sd) if (iMap->save_settings&4) chrif_save(sd, 0); //This one also saves the storage. [Skotlex] else - storage_guild_storagesave(sd->status.account_id, sd->status.guild_id,0); + gstorage->save(sd->status.account_id, sd->status.guild_id,0); stor->storage_status=0; } sd->state.storage_flag = 0; @@ -710,7 +734,7 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) struct guild_storage *stor; nullpo_ret(sd); - nullpo_ret(stor=guild2storage2(sd->status.guild_id)); + nullpo_ret(stor=gstorage->id2storage2(sd->status.guild_id)); if(flag) { //Only during a guild break flag is 1 (don't save storage) @@ -726,10 +750,46 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) if (iMap->save_settings&4) chrif_save(sd,0); else - storage_guild_storagesave(sd->status.account_id,sd->status.guild_id,1); + gstorage->save(sd->status.account_id,sd->status.guild_id,1); } sd->state.storage_flag = 0; stor->storage_status = 0; return 0; } +void storage_defaults(void) { + storage = &storage_s; + + /* */ + storage->init = do_init_storage; + storage->final = do_final_storage; + /* */ + storage->reconnect = do_reconnect_storage; + /* */ + storage->delitem = storage_delitem; + storage->open = storage_storageopen; + storage->add = storage_storageadd; + storage->get = storage_storageget; + storage->addfromcart = storage_storageaddfromcart; + storage->gettocart = storage_storagegettocart; + storage->close = storage_storageclose; + storage->pc_quit = storage_storage_quit; +} +void gstorage_defaults(void) { + gstorage = &gstorage_s; + + gstorage->id2storage = guild2storage; + gstorage->id2storage2 = guild2storage2; + gstorage->delete = guild_storage_delete; + gstorage->open = storage_guild_storageopen; + gstorage->additem = guild_storage_additem; + gstorage->delitem = guild_storage_delitem; + gstorage->add = storage_guild_storageadd; + gstorage->get = storage_guild_storageget; + gstorage->addfromcart = storage_guild_storageaddfromcart; + gstorage->gettocart = storage_guild_storagegettocart; + gstorage->close = storage_guild_storageclose; + gstorage->pc_quit = storage_guild_storage_quit; + gstorage->save = storage_guild_storagesave; + gstorage->saved = storage_guild_storagesaved; +} diff --git a/src/map/storage.h b/src/map/storage.h index c08ec81cb..058b980b1 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -1,41 +1,52 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #ifndef _STORAGE_H_ #define _STORAGE_H_ -//#include "../common/mmo.h" struct storage_data; struct guild_storage; struct item; -//#include "map.h" struct map_session_data; -int storage_delitem(struct map_session_data* sd, int n, int amount); -int storage_storageopen(struct map_session_data *sd); -int storage_storageadd(struct map_session_data *sd,int index,int amount); -int storage_storageget(struct map_session_data *sd,int index,int amount); -int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount); -int storage_storagegettocart(struct map_session_data *sd,int index,int amount); -void storage_storageclose(struct map_session_data *sd); -int do_init_storage(void); -void do_final_storage(void); -void do_reconnect_storage(void); -void storage_storage_quit(struct map_session_data *sd, int flag); +struct storage_interface { + int (*init) (void); + void (*final) (void); + /* */ + void (*reconnect) (void); + /* */ + int (*delitem) (struct map_session_data* sd, int n, int amount); + int (*open) (struct map_session_data *sd); + int (*add) (struct map_session_data *sd,int index,int amount); + int (*get) (struct map_session_data *sd,int index,int amount); + int (*addfromcart) (struct map_session_data *sd,int index,int amount); + int (*gettocart) (struct map_session_data *sd,int index,int amount); + void (*close) (struct map_session_data *sd); + void (*pc_quit) (struct map_session_data *sd, int flag); +} storage_s; +struct storage_interface *storage; -struct guild_storage* guild2storage(int guild_id); -struct guild_storage *guild2storage2(int guild_id); -int guild_storage_delete(int guild_id); -int storage_guild_storageopen(struct map_session_data *sd); -int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount); -int guild_storage_delitem(struct map_session_data *sd,struct guild_storage *stor,int n,int amount); -int storage_guild_storageadd(struct map_session_data *sd,int index,int amount); -int storage_guild_storageget(struct map_session_data *sd,int index,int amount); -int storage_guild_storageaddfromcart(struct map_session_data *sd,int index,int amount); -int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amount); -int storage_guild_storageclose(struct map_session_data *sd); -int storage_guild_storage_quit(struct map_session_data *sd,int flag); -int storage_guild_storagesave(int account_id, int guild_id, int flag); -int storage_guild_storagesaved(int guild_id); //Ack from char server that guild store was saved. +struct guild_storage_interface { + struct guild_storage *(*id2storage) (int guild_id); + struct guild_storage *(*id2storage2) (int guild_id); + int (*delete) (int guild_id); + int (*open) (struct map_session_data *sd); + int (*additem) (struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount); + int (*delitem) (struct map_session_data *sd,struct guild_storage *stor,int n,int amount); + int (*add) (struct map_session_data *sd,int index,int amount); + int (*get) (struct map_session_data *sd,int index,int amount); + int (*addfromcart) (struct map_session_data *sd,int index,int amount); + int (*gettocart) (struct map_session_data *sd,int index,int amount); + int (*close) (struct map_session_data *sd); + int (*pc_quit) (struct map_session_data *sd,int flag); + int (*save) (int account_id, int guild_id, int flag); + int (*saved) (int guild_id); //Ack from char server that guild store was saved. +} gstorage_s; + +struct guild_storage_interface *gstorage; + +void storage_defaults(void); +void gstorage_defaults(void); #endif /* _STORAGE_H_ */ diff --git a/src/map/trade.h b/src/map/trade.h index 6bcefdb96..ba56872c2 100644 --- a/src/map/trade.h +++ b/src/map/trade.h @@ -1,10 +1,10 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #ifndef _TRADE_H_ #define _TRADE_H_ -//#include "map.h" struct map_session_data; struct trade_interface { @@ -20,6 +20,11 @@ struct trade_interface { } trade_s; struct trade_interface *trade; +<<<<<<< HEAD void trade_interface(void); +======= + +void trade_defaults(void); +>>>>>>> upstream/master #endif /* _TRADE_H_ */ diff --git a/src/map/unit.c b/src/map/unit.c index 021859bba..5e836dc2e 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2108,9 +2108,9 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, buyingstore->close(sd); searchstore->close(sd); if(sd->state.storage_flag == 1) - storage_storage_quit(sd,0); + storage->pc_quit(sd,0); else if (sd->state.storage_flag == 2) - storage_guild_storage_quit(sd,0); + gstorage->pc_quit(sd,0); sd->state.storage_flag = 0; //Force close it when being warped. if(sd->party_invite>0) party->reply_invite(sd,sd->party_invite,0); diff --git a/tools/check-doc b/tools/check-doc index 4a5dccc88..4b283fcea 100755 --- a/tools/check-doc +++ b/tools/check-doc @@ -3,26 +3,26 @@ # modified by lighta case $1 in - 'script') + 'script') #find which script commands are missing from doc/script_commands.txt echo "Missing script documentation for function :" awk '/BUILDIN_DEF\(.*\),/ {b=match($0,"BUILDIN_DEF(.*),");c=match($0,",");print substr($0,b+12,c-b-12);}' ../src/map/script.c | xargs -I{} sh -c '! grep -Lq {} ../doc/script_commands.txt && echo {}' awk '/BUILDIN_DEF2\(.*\),/ {b=match($0,"BUILDIN_DEF2(.*),");c=match($0,",");d=match($0 ,"\",\"");print substr($0,c+2,d-c-2);}' ../src/map/script.c | xargs -I{} sh -c '! grep -Lq {} ../doc/script_commands.txt && echo {}' ;; - 'atc') + 'atc') #find which atcommands are missing from doc/atcommands.txt echo "Missing atcommand documentation for function :" awk '/ACMD_DEF\(.*\),/ {b=match($0,"ACMD_DEF(.*),");c=match($0,",");print substr($0,b+9,c-b-10);}' ../src/map/atcommand.c | xargs -I{} sh -c '! grep -Lq {} ../doc/atcommands.txt && echo {}' awk '/ACMD_DEF2\(.*\),/ {b=match($0,"ACMD_DEF2(.*),");c=match($0,",");print substr($0,b+10,c-b-10);}' ../src/map/atcommand.c | xargs -I{} sh -c '! grep -Lq {} ../doc/atcommands.txt && echo {}' ;; - 'both') + 'both') $0 script $0 atc ;; *) - echo "Usage: check-doc { script | atc | both }" + echo "Usage: check-doc { script | atc | both }" ;; esac |