Rebalancing of 1st/2nd/Transcendent class skills (#4072)

* Fixes #3715.
* kRO changelog: http://ro.gnjoy.com/news/notice/View.asp?seq=7040
* Refactored size_fix database to YAML.
Thanks to @flamefury for his translations!
Thanks to @Angelic234, @mrjnumber1, @Badarosk0, @OptimusM, @attackjom, @Playtester, Melvo, @cydh, @cahya1992, Sigma, @whupdo, @teededung, @ecdarreola, @hotspicy945, @RagnaWay, @sader1992 for bug testing!
This commit is contained in:
Aleos 2020-03-06 10:57:19 -05:00 committed by GitHub
parent 850904ab3e
commit ea8da71cdd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 2154 additions and 1185 deletions

View File

@ -38,7 +38,7 @@ hide_woe_damage: no
pet_hair_style: 100
// Visible area size (how many squares away from a player they can see)
area_size: 14
area_size: 15
// Maximum walk path (how many cells a player can walk going to cursor)
max_walk_path: 17

View File

@ -1,7 +0,0 @@
// Size Fix Tables
// Contains size fixes for weapon damage.
//
// Struture of Database:
// Columns - Weapon type
// Rows - Target size

View File

@ -0,0 +1,33 @@
# This file is a part of rAthena.
# Copyright(C) 2019 rAthena Development Team
# https://rathena.org - https://github.com/rathena
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###########################################################################
# Size Fix Database
###########################################################################
#
# Size Fix Settings
#
###########################################################################
# - Weapon Weapon type.
# Small Small size modifier. (Default: 100)
# Medium Medium size modifier. (Default: 100)
# Large Large size modifier. (Default: 100)
###########################################################################
Header:
Type: SIZE_FIX_DB
Version: 1

38
db/pre-re/size_fix.yml Normal file
View File

@ -0,0 +1,38 @@
# This file is a part of rAthena.
# Copyright(C) 2019 rAthena Development Team
# https://rathena.org - https://github.com/rathena
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###########################################################################
# Size Fix Database
###########################################################################
#
# Size Fix Settings
#
###########################################################################
# - Weapon Weapon type.
# Small Small size modifier. (Default: 100)
# Medium Medium size modifier. (Default: 100)
# Large Large size modifier. (Default: 100)
###########################################################################
Header:
Type: SIZE_FIX_DB
Version: 1
Body:
- Weapon: Knuckle
Medium: 75
Large: 50

37
db/re/size_fix.yml Normal file
View File

@ -0,0 +1,37 @@
# This file is a part of rAthena.
# Copyright(C) 2019 rAthena Development Team
# https://rathena.org - https://github.com/rathena
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###########################################################################
# Size Fix Database
###########################################################################
#
# Size Fix Settings
#
###########################################################################
# - Weapon Weapon type.
# Small Small size modifier. (Default: 100)
# Medium Medium size modifier. (Default: 100)
# Large Large size modifier. (Default: 100)
###########################################################################
Header:
Type: SIZE_FIX_DB
Version: 1
Body:
- Weapon: Knuckle
Large: 75

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,11 @@
//----------------------------------------------------------------------------
// Normal
//----------------------------------------------------------------------------
308,1 //BD_ETERNALCHAOS
311,1 //BD_ROKISWEIL
317,1 //BA_DISSONANCE
325,1 //DC_UGLYDANCE
328,1 //DC_DONTFORGETME
2422,1 //WM_LULLABY_DEEPSLEEP
2423,1 //WM_SIRCLEOFNATURE
2430,1 //WM_SATURDAY_NIGHT_FEVER

View File

@ -1306,7 +1306,8 @@
4020,394,10,47,5,316,1,46,5,0,0,0,0 //CG_ARROWVULCAN#Vulcan Arrow#
4020,395,5,45,5,315,7,0,0,0,0,0,0 //CG_MOONLIT#Sheltering Bliss#
4020,396,1,45,10,315,5,0,0,0,0,0,0 //CG_MARIONETTE#Marionette Control#
4020,487,5,315,10,396,1,317,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom#
//4020,487,5,315,10,396,1,317,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom# // Replaced with Skilled Special Singer
4020,5068,1,315,10,396,1,317,3,0,0,0,0 //CG_SPECIALSINGER#Skilled Special Singer#
4020,488,5,45,10,315,10,0,0,0,0,0,0 //CG_HERMODE#Wand of Hermod#
4020,489,5,45,10,317,3,0,0,0,0,0,0 //CG_TAROTCARD#Tarot Card of Fate#
4020,410,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLBABY#Call Baby#
@ -1342,7 +1343,8 @@
4021,394,10,47,5,324,1,46,5,0,0,0,0 //CG_ARROWVULCAN#Vulcan Arrow#
4021,395,5,45,5,323,7,0,0,0,0,0,0 //CG_MOONLIT#Sheltering Bliss#
4021,396,1,45,10,323,5,0,0,0,0,0,0 //CG_MARIONETTE#Marionette Control#
4021,487,5,323,10,396,1,325,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom#
//4021,487,5,323,10,396,1,325,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom# // Replaced with Skilled Special Singer
4021,5068,1,323,10,396,1,325,3,0,0,0,0 //CG_SPECIALSINGER#Skilled Special Singer#
4021,488,5,45,10,323,10,0,0,0,0,0,0 //CG_HERMODE#Wand of Hermod#
4021,489,5,45,10,325,3,0,0,0,0,0,0 //CG_TAROTCARD#Tarot Card of Fate#
4021,410,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLBABY#Call Baby#
@ -3668,7 +3670,8 @@
4075,394,10,47,5,316,1,46,5,0,0,0,0 //CG_ARROWVULCAN#Vulcan Arrow#
4075,395,5,45,5,315,7,0,0,0,0,0,0 //CG_MOONLIT#Sheltering Bliss#
4075,396,1,45,10,315,5,0,0,0,0,0,0 //CG_MARIONETTE#Marionette Control#
4075,487,5,315,10,396,1,317,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom#
//4075,487,5,315,10,396,1,317,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom# // Replaced with Skilled Special Singer
4075,5068,1,315,10,396,1,317,3,0,0,0,0 //CG_SPECIALSINGER#Skilled Special Singer#
4075,488,5,45,10,315,10,0,0,0,0,0,0 //CG_HERMODE#Wand of Hermod#
4075,489,5,45,10,317,3,0,0,0,0,0,0 //CG_TAROTCARD#Tarot Card of Fate#
4075,410,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLBABY#Call Baby#
@ -3730,7 +3733,8 @@
4076,394,10,47,5,324,1,46,5,0,0,0,0 //CG_ARROWVULCAN#Vulcan Arrow#
4076,395,5,45,5,323,7,0,0,0,0,0,0 //CG_MOONLIT#Sheltering Bliss#
4076,396,1,45,10,323,5,0,0,0,0,0,0 //CG_MARIONETTE#Marionette Control#
4076,487,5,323,10,396,1,325,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom#
//4076,487,5,323,10,396,1,325,3,0,0,0,0 //CG_LONGINGFREEDOM#Longing for Freedom# // Replaced with Skilled Special Singer
4076,5068,1,323,10,396,1,325,3,0,0,0,0 //CG_SPECIALSINGER#Skilled Special Singer#
4076,488,5,45,10,323,10,0,0,0,0,0,0 //CG_HERMODE#Wand of Hermod#
4076,489,5,45,10,325,3,0,0,0,0,0,0 //CG_TAROTCARD#Tarot Card of Fate#
4076,410,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLBABY#Call Baby#

View File

@ -1,11 +0,0 @@
// Size Fix Tables
// Contains size fixes for weapon damage.
//
// Struture of Database:
// Columns - Weapon type
// Rows - Target size
//Unarmed, Knife, 1H Sword, 2H Sword, 1H Spear, 2H Spears, 1H Axe, 2H Axe, Mace, 2H Mace, Staff, Bow, Knuckle, Musical Instrument, Whip, Book, Katar, Revolver, Rifle, Shotgun, Gatling Gun, Grenade Launcher, Fuuma Shuriken, 2H Staff
100,100, 75, 75, 75, 75, 50, 50, 75,100,100,100,100, 75, 75,100, 75,100,100,100,100,100,100,100 // Size: Small
100, 75,100, 75, 75, 75, 75, 75,100,100,100,100, 75,100,100,100,100,100,100,100,100,100,100,100 // Size: Medium
100, 50, 75,100,100,100,100,100,100,100,100, 75, 50, 75, 50, 50, 75,100,100,100,100,100,100,100 // Size: Large

89
db/size_fix.yml Normal file
View File

@ -0,0 +1,89 @@
# This file is a part of rAthena.
# Copyright(C) 2019 rAthena Development Team
# https://rathena.org - https://github.com/rathena
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###########################################################################
# Size Fix Database
###########################################################################
#
# Size Fix Settings
#
###########################################################################
# - Weapon Weapon type.
# Small Small size modifier. (Default: 100)
# Medium Medium size modifier. (Default: 100)
# Large Large size modifier. (Default: 100)
###########################################################################
Header:
Type: SIZE_FIX_DB
Version: 1
Body:
- Weapon: Fist
- Weapon: Dagger
Medium: 75
Large: 50
- Weapon: 1hSword
Small: 75
Large: 75
- Weapon: 2hSword
Small: 75
Medium: 75
- Weapon: 1hSpear
Small: 75
Medium: 75
- Weapon: 2hSpear
Small: 75
Medium: 75
- Weapon: 1hAxe
Small: 50
Medium: 75
- Weapon: 2hAxe
Small: 50
Medium: 75
- Weapon: Mace
Small: 75
- Weapon: 2hMace
- Weapon: Staff
- Weapon: Bow
Large: 75
- Weapon: Musical
Small: 75
Large: 75
- Weapon: Whip
Small: 75
Large: 50
- Weapon: Book
Large: 50
- Weapon: Katar
Small: 75
Large: 75
- Weapon: Revolver
- Weapon: Rifle
- Weapon: Gatling
- Weapon: Shotgun
- Weapon: Grenade
- Weapon: Huuma
- Weapon: 2hStaff
Footer:
Imports:
- Path: db/pre-re/size_fix.yml
Mode: Prerenewal
- Path: db/re/size_fix.yml
Mode: Renewal
- Path: db/import/size_fix.yml

View File

@ -352,7 +352,11 @@ int battle_delay_damage(t_tick tick, int amotion, struct block_list *src, struct
}
if( ((d_tbl && check_distance_bl(target, d_tbl, sc->data[SC_DEVOTION]->val3)) || e_tbl) &&
damage > 0 && skill_id != PA_PRESSURE && skill_id != CR_REFLECTSHIELD ){
damage > 0 && skill_id != CR_REFLECTSHIELD
#ifndef RENEWAL
&& skill_id != PA_PRESSURE
#endif
) {
struct map_session_data* tsd = BL_CAST( BL_PC, target );
if( tsd && pc_issit( tsd ) && battle_config.devotion_standup_fix ){
@ -416,6 +420,7 @@ int battle_attr_ratio(int atk_elem, int def_type, int def_lv)
* @param atk_elem
* @param def_type
* @param def_lv
* @param flag
* @return damage
*/
int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv)
@ -1091,15 +1096,24 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if (sc && sc->data[SC_MAXPAIN])
return 0;
if (skill_id == PA_PRESSURE || skill_id == HW_GRAVITATION)
#ifndef RENEWAL
if (skill_id == PA_PRESSURE
|| skill_id == HW_GRAVITATION
)
return damage; //These skills bypass everything else.
#endif
if( sc && sc->count ) { // SC_* that reduce damage to 0.
if( sc->data[SC_BASILICA] && !status_bl_has_mode(src,MD_STATUS_IMMUNE) ) {
#ifdef RENEWAL
if (sc->data[SC_BASILICA_CELL]
#else
if (sc->data[SC_BASILICA]
#endif
&& !status_bl_has_mode(src,MD_STATUS_IMMUNE) ) {
d->dmg_lv = ATK_BLOCK;
return 0;
}
if( sc->data[SC_WHITEIMPRISON] ) { // Gravitation and Pressure do damage without removing the effect
if( sc->data[SC_WHITEIMPRISON] ) { // Pre-Renewal: Gravitation and Pressure do damage without removing the effect
if( skill_id == MG_NAPALMBEAT ||
skill_id == MG_SOULSTRIKE ||
skill_id == WL_SOULEXPANSION ||
@ -1258,12 +1272,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
#ifdef RENEWAL
if( sc->data[SC_RAID] ) {
if (status_get_class_(bl) == CLASS_BOSS)
damage += damage * 10 / 100;
damage += damage * 15 / 100;
else
damage += damage * 20 / 100;
if (--sc->data[SC_RAID]->val1 == 0)
status_change_end(bl, SC_RAID, INVALID_TIMER);
damage += damage * 30 / 100;
}
#endif
@ -1303,7 +1314,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
}
// Damage reductions
// Assumptio doubles the def & mdef on RE mode, otherwise gives a reduction on the final damage. [Igniz]
// Assumptio increases DEF on RE mode, otherwise gives a reduction on the final damage. [Igniz]
#ifndef RENEWAL
if( sc->data[SC_ASSUMPTIO] ) {
if( map_flag_vs(bl->m) )
@ -2276,6 +2287,10 @@ static int battle_skill_damage(struct block_list *src, struct block_list *target
* @return Bonus value based on party count
*/
int battle_calc_chorusbonus(struct map_session_data *sd) {
#ifdef RENEWAL // No bonus in renewal
return 0;
#endif
int members = 0;
if (!sd || !sd->status.party_id)
@ -2468,7 +2483,11 @@ static bool is_attack_critical(struct Damage* wd, struct block_list *src, struct
break;
case SN_SHARPSHOOTING:
case MA_SHARPSHOOTING:
#ifdef RENEWAL
cri += 300; // !TODO: Confirm new bonus
#else
cri += 200;
#endif
break;
case NJ_KIRIKAGE:
cri += 250 + 50*skill_lv;
@ -2657,6 +2676,11 @@ static bool is_attack_hitting(struct Damage* wd, struct block_list *src, struct
if(sd && pc_checkskill(sd,AS_SONICACCEL) > 0)
hitrate += hitrate * 50 / 100;
break;
#ifdef RENEWAL
case RG_BACKSTAP:
hitrate += skill_lv; // !TODO: What's the rate increase?
break;
#endif
case RK_SONICWAVE:
hitrate += hitrate * 3 * skill_lv / 100; // !TODO: Confirm the hitrate bonus
break;
@ -3152,6 +3176,7 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
}
switch (tstatus->size) { //Size-fix. Is this modified by weapon perfection?
// !TODO: Confirm new size modifiers
case SZ_SMALL: //Small: 125%
ATK_RATE(wd->damage, wd->damage2, 125);
RE_ALLATK_RATE(wd, 125);
@ -3547,7 +3572,11 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
break;
case KN_BRANDISHSPEAR:
case ML_BRANDISH: {
#ifdef RENEWAL
int ratio = 100 + 20 * skill_lv + sstatus->str; // !TODO: Confirm STR role
#else
int ratio = 100 + 20 * skill_lv;
#endif
skillratio += -100 + ratio;
if(skill_lv > 3 && wd->miscflag == 0)
@ -3576,6 +3605,10 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
break;
case AS_SONICBLOW:
skillratio += 300 + 40 * skill_lv;
#ifdef RENEWAL
if (tstatus->hp < tstatus->max_hp >> 1)
skillratio += skillratio / 2;
#endif
break;
case TF_SPRINKLESAND:
skillratio += 30;
@ -3621,13 +3654,17 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio += (200 + 40 * skill_lv) / 2;
else
skillratio += 200 + 40 * skill_lv;
#ifdef RENEWAL
if (sd && sd->status.weapon == W_DAGGER)
skillratio *= 2;
#endif
break;
case RG_RAID:
#ifdef RENEWAL
if (status_get_class_(target) == CLASS_BOSS)
skillratio += 10 * skill_lv;
skillratio += 10 * skill_lv; // !TODO: Did this change as well?
else
skillratio += 20 * skill_lv;
skillratio += 50 + skill_lv * 150;
#else
skillratio += 40 * skill_lv;
#endif
@ -3639,7 +3676,11 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio += 20 * skill_lv;
break;
case CR_SHIELDBOOMERANG:
#ifdef RENEWAL
skillratio += -100 + skill_lv * 80;
#else
skillratio += 30 * skill_lv;
#endif
break;
case NPC_DARKCROSS:
case CR_HOLYCROSS:
@ -3655,18 +3696,36 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
break;
case AM_ACIDTERROR:
#ifdef RENEWAL
skillratio += 200 + 80 * skill_lv;
skillratio += -100 + 200 * skill_lv;
if (sd && pc_checkskill(sd, AM_LEARNINGPOTION))
skillratio += 100; // !TODO: What's this bonus increase?
#else
skillratio += 40 * skill_lv;
#endif
break;
case MO_FINGEROFFENSIVE:
#ifdef RENEWAL
skillratio += 500 + skill_lv * 2;
if (tsc && tsc->data[SC_BLADESTOP])
skillratio += skillratio / 2;
#else
skillratio += 50 * skill_lv;
#endif
break;
case MO_INVESTIGATE:
#ifdef RENEWAL
skillratio += -100 + 100 * skill_lv;
if (tsc && tsc->data[SC_BLADESTOP])
skillratio += skillratio / 2;
#else
skillratio += 75 * skill_lv;
#endif
break;
case MO_EXTREMITYFIST:
#ifdef RENEWAL
if (wd->miscflag&1)
skillratio += 100; // More than 5 spirit balls active
#endif
skillratio += 100 * (7 + sstatus->sp / 10);
skillratio = min(500000,skillratio); //We stop at roughly 50k SP for overflow protection
break;
@ -3674,29 +3733,56 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio += 20 * skill_lv;
break;
case MO_CHAINCOMBO:
#ifdef RENEWAL
skillratio += 150 + 50 * skill_lv;
#else
skillratio += 50 + 50 * skill_lv;
#endif
break;
case MO_COMBOFINISH:
#ifdef RENEWAL
skillratio += 450 + 50 * skill_lv + sstatus->str; // !TODO: How does STR play a role?
#else
skillratio += 140 + 60 * skill_lv;
#endif
if (sc->data[SC_GT_ENERGYGAIN])
skillratio += skillratio * 50 / 100;
break;
case BA_MUSICALSTRIKE:
case DC_THROWARROW:
#ifdef RENEWAL
skillratio += 10 + 40 * skill_lv;
#else
skillratio += 25 + 25 * skill_lv;
#endif
break;
case CH_TIGERFIST:
#ifdef RENEWAL
skillratio += 400 + 150 * skill_lv;
RE_LVL_DMOD(100);
#else
skillratio += -60 + 100 * skill_lv;
#endif
if (sc->data[SC_GT_ENERGYGAIN])
skillratio += skillratio * 50 / 100;
break;
case CH_CHAINCRUSH:
#ifdef RENEWAL
skillratio += -100 + 200 * skill_lv;
RE_LVL_DMOD(100);
#else
skillratio += 300 + 100 * skill_lv;
#endif
if (sc->data[SC_GT_ENERGYGAIN])
skillratio += skillratio * 50 / 100;
break;
case CH_PALMSTRIKE:
#ifdef RENEWAL
skillratio += 100 + 100 * skill_lv + sstatus->str; // !TODO: How does STR play a role?
RE_LVL_DMOD(100);
#else
skillratio += 100 + 100 * skill_lv;
#endif
break;
case LK_HEADCRUSH:
skillratio += 40 * skill_lv;
@ -3710,21 +3796,41 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
// Renewal: skill ratio applies to entire damage [helvetica]
case LK_SPIRALPIERCE:
case ML_SPIRALPIERCE:
skillratio += 50 * skill_lv;
skillratio += 50 + 50 * skill_lv;
RE_LVL_DMOD(100);
break;
#endif
case ASC_METEORASSAULT:
#ifdef RENEWAL
skillratio += 100 + 120 * skill_lv;
RE_LVL_DMOD(100);
#else
skillratio += -60 + 40 * skill_lv;
#endif
break;
case SN_SHARPSHOOTING:
case MA_SHARPSHOOTING:
#ifdef RENEWAL
skillratio += 50 + 200 * skill_lv;
RE_LVL_DMOD(100);
#else
skillratio += 100 + 50 * skill_lv;
#endif
break;
case CG_ARROWVULCAN:
#ifdef RENEWAL
skillratio += 400 + 100 * skill_lv;
RE_LVL_DMOD(100);
#else
skillratio += 100 + 100 * skill_lv;
#endif
break;
case AS_SPLASHER:
#ifdef RENEWAL
skillratio += 400 + 100 * skill_lv;
#else
skillratio += 400 + 50 * skill_lv;
#endif
if(sd)
skillratio += 20 * pc_checkskill(sd,AS_POISONREACT);
break;
@ -3738,7 +3844,12 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
skillratio += -10 + 10 * skill_lv;
break;
case PA_SHIELDCHAIN:
#ifdef RENEWAL
skillratio = 60 + 40 * skill_lv;
RE_LVL_DMOD(100);
#else
skillratio += 30 * skill_lv;
#endif
break;
case WS_CARTTERMINATION:
i = 10 * (16 - skill_lv);
@ -4529,10 +4640,6 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
#ifdef RENEWAL
if (sc->data[SC_WATK_ELEMENT] && skill_id != ASC_METEORASSAULT)
ATK_ADDRATE(wd->weaponAtk, wd->weaponAtk2, sc->data[SC_WATK_ELEMENT]->val2);
if (sc->data[SC_IMPOSITIO])
ATK_ADD(wd->equipAtk, wd->equipAtk2, sc->data[SC_IMPOSITIO]->val2);
if (sc->data[SC_VOLCANO])
ATK_ADD(wd->equipAtk, wd->equipAtk2, sc->data[SC_VOLCANO]->val2);
if (sc->data[SC_DRUMBATTLE])
ATK_ADD(wd->equipAtk, wd->equipAtk2, sc->data[SC_DRUMBATTLE]->val2);
if (sc->data[SC_MADNESSCANCEL])
@ -4579,18 +4686,6 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
break; // skills above have no effect with EDP
#ifdef RENEWAL
// renewal EDP mode requires renewal enabled as well
// Renewal EDP: damage gets a half modifier on top of EDP bonus for skills [helvetica]
// * Sonic Blow
// * Soul Breaker
// * Counter Slash
// * Cross Impact
case AS_SONICBLOW:
case ASC_BREAKER:
case GC_COUNTERSLASH:
case GC_CROSSIMPACT:
ATK_RATE(wd->weaponAtk, wd->weaponAtk2, 50);
ATK_RATE(wd->equipAtk, wd->equipAtk2, 50);
default: // fall through to apply EDP bonuses
// Renewal EDP formula [helvetica]
// weapon atk * (1 + (edp level * .8))
@ -4729,11 +4824,6 @@ static void battle_calc_defense_reduction(struct Damage* wd, struct block_list *
defType def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions.
short def2 = tstatus->def2;
#ifdef RENEWAL
if( tsc && tsc->data[SC_ASSUMPTIO] )
def1 <<= 1; // only eDEF is doubled
#endif
if (sd) {
int i = sd->ignore_def_by_race[tstatus->race] + sd->ignore_def_by_race[RC_ALL];
i += sd->ignore_def_by_class[tstatus->class_] + sd->ignore_def_by_class[CLASS_ALL];
@ -4894,11 +4984,11 @@ static void battle_calc_attack_post_defense(struct Damage* wd, struct block_list
&& skill_id != LK_SPIRALPIERCE && skill_id != ML_SPIRALPIERCE
#endif
) {
int lv = sc->data[SC_AURABLADE]->val1;
#ifdef RENEWAL
lv *= ((skill_id == LK_SPIRALPIERCE || skill_id == ML_SPIRALPIERCE)?wd->div_:1); // +100 per hit in lv 5
ATK_ADD(wd->damage, wd->damage2, (3 + sc->data[SC_AURABLADE]->val1) * status_get_lv(src)); // !TODO: Confirm formula
#else
ATK_ADD(wd->damage, wd->damage2, 20 * sc->data[SC_AURABLADE]->val1);
#endif
ATK_ADD(wd->damage, wd->damage2, 20*lv);
}
}
@ -5274,12 +5364,8 @@ static struct Damage initialize_weapon_data(struct block_list *src, struct block
}
break;
case MO_FINGEROFFENSIVE:
if(sd) {
if (battle_config.finger_offensive_type)
if (sd && battle_config.finger_offensive_type)
wd.div_ = 1;
else
wd.div_ = sd->spiritball_old;
}
break;
case KN_PIERCE:
@ -5297,6 +5383,10 @@ static struct Damage initialize_weapon_data(struct block_list *src, struct block
//Fall through
case KN_SPEARSTAB:
case KN_BOWLINGBASH:
#ifdef RENEWAL
if (skill_id == KN_BOWLINGBASH && sd && sd->status.weapon == W_2HSWORD)
wd.div_ = cap_value(wd.miscflag, 2, 4);
#endif
case MS_BOWLINGBASH:
case MO_BALKYOUNG:
case TK_TURNKICK:
@ -5960,10 +6050,25 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio += 30 * skill_lv;
break;
case WZ_STORMGUST:
#ifdef RENEWAL
skillratio -= 30; // Offset only once
skillratio += 50 * skill_lv;
#else
skillratio += 40 * skill_lv;
#endif
break;
#ifdef RENEWAL
case WZ_EARTHSPIKE:
skillratio += 100;
break;
#endif
case HW_NAPALMVULCAN:
#ifdef RENEWAL
skillratio += -100 + 70 * skill_lv;
RE_LVL_DMOD(100);
#else
skillratio += 25;
#endif
break;
case SL_STIN: //Target size must be small (0) for full damage
skillratio += (tstatus->size != SZ_SMALL ? -99 : 10 * skill_lv);
@ -6032,22 +6137,38 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
#ifdef RENEWAL
case WZ_HEAVENDRIVE:
skillratio += -100 + skill_lv * 100 + skill_lv * 25;
break;
case WZ_METEOR:
skillratio += 25;
break;
case WZ_VERMILION:
if(sd) {
int per = 0;
while ((++per) < skill_lv)
skillratio += per * 5; //100% 105% 115% 130% 150% 175% 205% 240% 280% 325%
} else {
if(sd)
skillratio += 25 + skill_lv * 5;
else
skillratio += 20 * skill_lv - 20; //Monsters use old formula
}
break;
case BA_DISSONANCE:
skillratio += skill_lv * 10;
if (sd)
skillratio += 3 * pc_checkskill(sd, BA_MUSICALLESSON);
break;
case HW_GRAVITATION:
skillratio += -100 + 50 * skill_lv;
RE_LVL_DMOD(100);
break;
case PA_PRESSURE:
skillratio += -100 + 500 + 150 * skill_lv;
RE_LVL_DMOD(100);
break;
#else
case WZ_VERMILION:
skillratio += 20 * skill_lv - 20;
break;
case PR_MAGNUS:
if (battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON)
skillratio += 30;
break;
#endif
case AB_JUDEX:
skillratio += -100 + 300 + 40 * skill_lv;
@ -6333,10 +6454,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if(!flag.imdef){
defType mdef = tstatus->mdef;
int mdef2= tstatus->mdef2;
#ifdef RENEWAL
if(tsc && tsc->data[SC_ASSUMPTIO])
mdef <<= 1; // only eMDEF is doubled
#endif
if (sc && sc->data[SC_EXPIATIO]) {
i = 5 * sc->data[SC_EXPIATIO]->val1; // 5% per level
@ -6419,12 +6537,17 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
struct Damage wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40 * skill_lv) / 100;
#ifdef RENEWAL
if (src == target)
ad.damage = 0;
#else
if(src == target) {
if(src->type == BL_PC)
ad.damage = ad.damage / 2;
else
ad.damage = 0;
}
#endif
}
break;
}
@ -6553,9 +6676,14 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
//Blitz-beat Damage
if(!sd || !(skill = pc_checkskill(sd,HT_STEELCROW)))
skill = 0;
#ifdef RENEWAL
md.damage = (sstatus->dex / 10 + sstatus->agi / 2 + skill * 3 + 40) * 2;
RE_LVL_MDMOD(100);
#else
md.damage = (sstatus->dex / 10 + sstatus->int_ / 2 + skill * 3 + 40) * 2;
if(mflag > 1) //Autocasted Blitz
nk.set(NK_SPLASHSPLIT);
#endif
if (skill_id == SN_FALCONASSAULT) {
//Div fix of Blitzbeat
DAMAGE_DIV_FIX2(md.damage, skill_get_num(HT_BLITZBEAT, 5));
@ -6564,11 +6692,13 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
}
break;
#ifndef RENEWAL
case BA_DISSONANCE:
md.damage = 30 + skill_lv * 10;
if (sd)
md.damage += 3 * pc_checkskill(sd,BA_MUSICALLESSON);
break;
#endif
case NPC_SELFDESTRUCTION:
md.damage = sstatus->hp;
break;
@ -6609,17 +6739,15 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
nk.set(NK_IGNOREELEMENT); //These two are not properties of the weapon based part.
#endif
break;
#ifndef RENEWAL
case HW_GRAVITATION:
#ifdef RENEWAL
md.damage = 500 + 100 * skill_lv;
#else
md.damage = 200 + 200 * skill_lv;
#endif
md.dmotion = 0; //No flinch animation
break;
case PA_PRESSURE:
md.damage = 500 + 300 * skill_lv;
break;
#endif
case PA_GOSPEL:
if (mflag > 0)
md.damage = (rnd() % 4000) + 1500;
@ -7284,10 +7412,19 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
}
if( tsc && tsc->data[SC_BLADESTOP_WAIT] && status_get_class_(src) != CLASS_BOSS && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) )
if( tsc && tsc->data[SC_BLADESTOP_WAIT] &&
#ifndef RENEWAL
status_get_class_(src) != CLASS_BOSS &&
#endif
(src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) )
{
uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1;
int duration = skill_get_time2(MO_BLADESTOP,skill_lv);
#ifdef RENEWAL
if (status_get_class_(src) == CLASS_BOSS)
duration = 2000; // Only lasts 2 seconds for Boss monsters
#endif
status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
if(sc_start4(src,src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration))
{ //Target locked.
@ -7299,7 +7436,12 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if(sd && (skillv = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0) {
int triple_rate= 30 - skillv; //Base Rate
#ifdef RENEWAL
int triple_rate = 30; //Base Rate
#else
int triple_rate = 30 - skillv; //Base Rate
#endif
if (sc && sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == MO_TRIPLEATTACK) {
triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP]->val2)/100;
status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);

View File

@ -8030,11 +8030,34 @@ void clif_pet_food(struct map_session_data *sd,int foodid,int fail)
/// 01cd { <skill id>.L }*7
void clif_autospell(struct map_session_data *sd,uint16 skill_lv)
{
int fd;
nullpo_retv(sd);
fd=sd->fd;
int fd = sd->fd;
#ifdef RENEWAL
uint16 autospell_skill[][2] = {
{ MG_FIREBOLT, 0 }, { MG_COLDBOLT, 0 }, { MG_LIGHTNINGBOLT, 0 },
{ MG_SOULSTRIKE, 3 }, { MG_FIREBALL, 3 },
{ WZ_EARTHSPIKE, 6 }, { MG_FROSTDIVER, 6 },
{ MG_THUNDERSTORM, 9 }, { WZ_HEAVENDRIVE, 9 }
};
int count = 0;
WFIFOHEAD(fd, 2 * 6 + 4);
WFIFOW(fd, 0) = 0x442;
for (int i = 0; i < ARRAYLENGTH(autospell_skill); i++) {
if (skill_lv > autospell_skill[i][1] && pc_checkskill(sd, autospell_skill[i][0])) {
WFIFOW(fd, 8 + count * 2) = autospell_skill[i][0];
count++;
}
}
WFIFOW(fd, 2) = 8 + count * 2;
WFIFOL(fd, 4) = count;
WFIFOSET(fd, WFIFOW(fd, 2));
#else
WFIFOHEAD(fd,packet_len(0x1cd));
WFIFOW(fd, 0)=0x1cd;
@ -8068,6 +8091,8 @@ void clif_autospell(struct map_session_data *sd,uint16 skill_lv)
WFIFOL(fd,26)= 0x00000000;
WFIFOSET(fd,packet_len(0x1cd));
#endif
sd->menuskill_id = SA_AUTOSPELL;
sd->menuskill_val = skill_lv;
}
@ -12190,7 +12215,11 @@ static void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_ses
return;
}
if( hd->sc.data[SC_BASILICA] )
#ifdef RENEWAL
if (hd->sc.data[SC_BASILICA_CELL])
#else
if (hd->sc.data[SC_BASILICA])
#endif
return;
lv = hom_checkskill(hd, skill_id);
if( skill_lv > lv )
@ -12239,7 +12268,11 @@ static void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct
return;
}
if( md->sc.data[SC_BASILICA] )
#ifdef RENEWAL
if (md->sc.data[SC_BASILICA_CELL])
#else
if (md->sc.data[SC_BASILICA])
#endif
return;
lv = mercenary_checkskill(md, skill_id);
if( skill_lv > lv )
@ -12317,8 +12350,10 @@ void clif_parse_skill_toid( struct map_session_data* sd, uint16 skill_id, uint16
if( sd->sc.option&OPTION_COSTUME )
return;
#ifndef RENEWAL
if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
return; // On basilica only caster can use Basilica again to stop it.
#endif
if( sd->menuskill_id ) {
if( sd->menuskill_id == SA_TAMINGMONSTER ) {
@ -12427,8 +12462,10 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
if( sd->sc.option&OPTION_COSTUME )
return;
#ifndef RENEWAL
if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
return; // On basilica only caster can use Basilica again to stop it.
#endif
if( sd->menuskill_id ) {
if( sd->menuskill_id == SA_TAMINGMONSTER ) {
@ -18740,23 +18777,27 @@ int clif_skill_itemlistwindow( struct map_session_data *sd, uint16 skill_id, uin
}
/*==========================================
* Select a skill into a given list (used by SC_AUTOSHADOWSPELL)
* Select a skill into a given list (used by SA_AUTOSPELL/SC_AUTOSHADOWSPELL)
* 0443 <type>.L <skill_id>.W (CZ_SKILL_SELECT_RESPONSE)
* RFIFOL(fd,2) - type (currently not used)
*------------------------------------------*/
void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) {
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
//int type = RFIFOL(fd,info->pos[0]); //WHY_LOWERVER_COMPATIBILITY = 0x0, WHY_SC_AUTOSHADOWSPELL = 0x1,
if( sd->menuskill_id != SC_AUTOSHADOWSPELL )
return;
if( pc_istrading(sd) ) {
clif_skill_fail(sd,sd->ud.skill_id,USESKILL_FAIL_LEVEL,0);
if (sd->menuskill_id == SA_AUTOSPELL) {
sd->state.workinprogress = WIP_DISABLE_NONE;
skill_autospell(sd, RFIFOW(fd, info->pos[1]));
} else if (sd->menuskill_id == SC_AUTOSHADOWSPELL) {
if (pc_istrading(sd)) {
clif_skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0);
clif_menuskill_clear(sd);
return;
}
skill_select_menu(sd,RFIFOW(fd,info->pos[1]));
skill_select_menu(sd, RFIFOW(fd, info->pos[1]));
} else
return;
clif_menuskill_clear(sd);
}

View File

@ -359,6 +359,7 @@
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\produce_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\produce_db.txt')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\quest_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\quest_db.txt')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\refine_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\refine_db.yml')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\size_fix.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\size_fix.yml')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\size_fix.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\size_fix.txt')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_changematerial_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_changematerial_db.txt')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_damage_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_damage_db.txt')" />

View File

@ -2534,8 +2534,13 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
) { //Experience calculation.
int bonus = 100; //Bonus on top of your share (common to all attackers).
int pnum = 0;
#ifndef RENEWAL
if (md->sc.data[SC_RICHMANKIM])
bonus += md->sc.data[SC_RICHMANKIM]->val2;
#else
if (sd && sd->sc.data[SC_RICHMANKIM])
bonus += sd->sc.data[SC_RICHMANKIM]->val2;
#endif
if(sd) {
temp = status_get_class(&md->bl);
if(sd->sc.data[SC_MIRACLE]) i = 2; //All mobs are Star Targets

View File

@ -8851,6 +8851,11 @@ int pc_itemheal(struct map_session_data *sd, int itemid, int hp, int sp)
sp += sp / 10;
}
#ifdef RENEWAL
if (sd->sc.data[SC_APPLEIDUN])
hp += sd->sc.data[SC_APPLEIDUN]->val3 / 100;
#endif
if (penalty > 0) {
hp -= hp * penalty / 100;
sp -= sp * penalty / 100;
@ -9449,7 +9454,12 @@ bool pc_can_attack( struct map_session_data *sd, int target_id ) {
if (sd->state.block_action & PCBLOCK_ATTACK)
return false;
if( sd->sc.data[SC_BASILICA] ||
if(
#ifdef RENEWAL
sd->sc.data[SC_BASILICA_CELL] ||
#else
sd->sc.data[SC_BASILICA] ||
#endif
sd->sc.data[SC__SHADOWFORM] ||
sd->sc.data[SC_CURSEDCIRCLE_ATKER] ||
sd->sc.data[SC_CURSEDCIRCLE_TARGET] ||
@ -10560,6 +10570,12 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
}
// On equipment change
#ifndef RENEWAL
if (!(flag&4))
status_change_end(&sd->bl, SC_CONCENTRATION, INVALID_TIMER);
#endif
// On ammo change
if (sd->inventory_data[n]->type == IT_AMMO && (sd->inventory_data[n]->nameid != ITEMID_SILVER_BULLET || sd->inventory_data[n]->nameid != ITEMID_PURIFICATION_BULLET || sd->inventory_data[n]->nameid != ITEMID_SILVER_BULLET_))
status_change_end(&sd->bl, SC_P_ALTER, INVALID_TIMER);
@ -12703,12 +12719,18 @@ void pc_bonus_script_clear(struct map_session_data *sd, uint16 flag) {
void pc_cell_basilica(struct map_session_data *sd) {
nullpo_retv(sd);
#ifdef RENEWAL
enum sc_type type = SC_BASILICA_CELL;
#else
enum sc_type type = SC_BASILICA;
#endif
if (!map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKBASILICA)) {
if (sd->sc.data[SC_BASILICA])
status_change_end(&sd->bl,SC_BASILICA,INVALID_TIMER);
if (sd->sc.data[type])
status_change_end(&sd->bl, type,INVALID_TIMER);
}
else if (!sd->sc.data[SC_BASILICA])
sc_start(&sd->bl,&sd->bl,SC_BASILICA,100,0,INFINITE_TICK);
else if (!sd->sc.data[type])
sc_start(&sd->bl,&sd->bl, type,100,0,INFINITE_TICK);
}
/** [Cydh]

View File

@ -148,7 +148,7 @@ struct s_addele2 {
};
struct weapon_data {
int atkmods[3];
int atkmods[SZ_ALL];
// all the variables except atkmods get zero'ed in each call of status_calc_pc
// NOTE: if you want to add a non-zeroed variable, you need to update the memset call
// in status_calc_pc as well! All the following are automatically zero'ed. [Skotlex]

View File

@ -1544,6 +1544,8 @@
export_constant(SC_WEAPONBLOCK_ON);
export_constant(SC_ENTRY_QUEUE_APPLY_DELAY);
export_constant(SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT);
export_constant(SC_ADAPTATION);
export_constant(SC_BASILICA_CELL);
#ifdef RENEWAL
export_constant(SC_EXTREMITYFIST2);
#endif

View File

@ -532,15 +532,13 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
tsc = status_get_sc(target);
switch( skill_id ) {
#ifndef RENEWAL
case BA_APPLEIDUN:
#ifdef RENEWAL
hp = 100 + 5 * skill_lv + (status_get_vit(src) / 2); // HP recovery
#else
hp = 30 + 5 * skill_lv + (status_get_vit(src) / 2); // HP recovery
#endif
if (sd)
hp += 5 * pc_checkskill(sd, BA_MUSICALLESSON);
break;
#endif
case PR_SANCTUARY:
hp = (skill_lv > 6) ? 777 : skill_lv * 100;
break;
@ -638,6 +636,10 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
hp_bonus += sc->data[SC_GLASTHEIM_HEAL]->val1;
#else
hp += hp * sc->data[SC_GLASTHEIM_HEAL]->val1 / 100;
#endif
#ifdef RENEWAL
if (sc->data[SC_ASSUMPTIO])
hp_bonus += sc->data[SC_ASSUMPTIO]->val1 * 2;
#endif
}
@ -1386,7 +1388,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case WZ_VERMILION:
#ifdef RENEWAL
sc_start(src,bl,SC_BLIND,10 + 5 * skill_lv,skill_lv,skill_get_time2(skill_id,skill_lv));
#else
sc_start(src,bl,SC_BLIND,min(4*skill_lv,40),skill_lv,skill_get_time2(skill_id,skill_lv));
#endif
break;
case WZ_HEAVENDRIVE:
@ -1444,18 +1450,27 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case AM_ACIDTERROR:
sc_start2(src,bl,SC_BLEEDING,(skill_lv*3),skill_lv,src->id,skill_get_time2(skill_id,skill_lv));
#ifdef RENEWAL
if (skill_break_equip(src,bl, EQP_ARMOR, (1000 * skill_lv + 500) - 1000, BCT_ENEMY))
#else
if (skill_break_equip(src,bl, EQP_ARMOR, 100*skill_get_time(skill_id,skill_lv), BCT_ENEMY))
#endif
clif_emotion(bl,ET_HUK);
break;
case AM_DEMONSTRATION:
#ifdef RENEWAL
skill_break_equip(src,bl, EQP_WEAPON, 300 * skill_lv, BCT_ENEMY);
#else
skill_break_equip(src,bl, EQP_WEAPON, 100*skill_lv, BCT_ENEMY);
#endif
break;
case CR_SHIELDCHARGE:
sc_start(src,bl,SC_STUN,(15+skill_lv*5),skill_lv,skill_get_time2(skill_id,skill_lv));
break;
#ifndef RENEWAL
case PA_PRESSURE:
status_percent_damage(src, bl, 0, 15+5*skill_lv, false);
//Fall through
@ -1464,13 +1479,13 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
attack_type |= BF_NORMAL;
attack_type |= BF_WEAPON;
break;
#endif
case RG_RAID:
sc_start(src,bl,SC_STUN,(10+3*skill_lv),skill_lv,skill_get_time(skill_id,skill_lv));
sc_start(src,bl,SC_BLIND,(10+3*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
#ifdef RENEWAL
sc_start(src,bl,SC_RAID,100,7,5000);
sc_start(src, bl, SC_RAID, 100, skill_lv, 10000); // Hardcoded to 10 seconds since skill_cast_db is full
break;
case RG_BACKSTAP:
@ -1494,7 +1509,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
rate = 5+5*skill_lv;
if(sd && (skill=pc_checkskill(sd,DC_DANCINGLESSON)))
rate += 5+skill;
#ifdef RENEWAL
status_zap(bl, 0, 2 * skill_lv + 10); // !TODO: How does caster's DEX/AGI play a role?
#else
status_zap(bl, 0, rate);
#endif
break;
case SL_STUN:
if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs.
@ -1813,7 +1832,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
status_change_end(bl, SC_HUMMING, INVALID_TIMER);
status_change_end(bl, SC_FORTUNE, INVALID_TIMER);
status_change_end(bl, SC_SERVICE4U, INVALID_TIMER);
#ifndef RENEWAL
status_change_end(bl, SC_LONGING, INVALID_TIMER);
#endif
status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
@ -2105,6 +2126,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
if( sd && battle_config.equip_self_break_rate )
{ // Self weapon breaking
rate = battle_config.equip_natural_break_rate;
#ifndef RENEWAL
if( sc )
{
if(sc->data[SC_OVERTHRUST])
@ -2112,6 +2134,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
if(sc->data[SC_MAXOVERTHRUST])
rate += 10;
}
#endif
if( rate )
skill_break_equip(src,src, EQP_WEAPON, rate, BCT_SELF);
}
@ -2805,7 +2828,7 @@ bool skill_strip_equip(struct block_list *src, struct block_list *target, uint16
BLOWN_NO_KNOCKBACK_MAP - at WOE/BG map
BLOWN_MD_KNOCKBACK_IMMUNE - if target is MD_KNOCKBACK_IMMUNE
BLOWN_TARGET_NO_KNOCKBACK - if target has 'special_state.no_knockback'
BLOWN_TARGET_BASILICA - if target is in Basilica area
BLOWN_TARGET_BASILICA - if target is in Basilica area (Pre-Renewal)
* @return Number of knocked back cells done
*/
short skill_blown(struct block_list* src, struct block_list* target, char count, int8 dir, enum e_skill_blown flag)
@ -3304,9 +3327,11 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
if (tsc && tsc->data[SC_TRICKDEAD])
return 0;
#ifndef RENEWAL
//When Gravitational Field is active, damage can only be dealt by Gravitational Field and Autospells
if(sd && sc && sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && skill_id != HW_GRAVITATION && !sd->state.autocast)
return 0;
#endif
dmg = battle_calc_attack(attack_type,src,bl,skill_id,skill_lv,flag&0xFFF);
@ -3649,7 +3674,11 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
// Instant damage
if( !dmg.amotion ) {
if( (!tsc || (!tsc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD && !tsc->data[SC_WATER_SCREEN_OPTION]) || skill_id == HW_GRAVITATION || skill_id == NPC_EVILLAND) && !shadow_flag )
if( (!tsc || (!tsc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD && !tsc->data[SC_WATER_SCREEN_OPTION])
#ifndef RENEWAL
|| skill_id == HW_GRAVITATION
#endif
|| skill_id == NPC_EVILLAND) && !shadow_flag )
status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
if( !status_isdead(bl) && additional_effects )
skill_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick);
@ -3672,7 +3701,11 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects, false);
}
if (tsc && skill_id != PA_PRESSURE && skill_id != HW_GRAVITATION && skill_id != NPC_EVILLAND) {
if (tsc && skill_id != NPC_EVILLAND
#ifndef RENEWAL
&& skill_id != PA_PRESSURE && skill_id != HW_GRAVITATION
#endif
) {
if (tsc->data[SC_DEVOTION]) {
struct status_change_entry *sce = tsc->data[SC_DEVOTION];
struct block_list *d_bl = map_id2bl(sce->val1);
@ -3867,7 +3900,9 @@ static int skill_check_unit_range_sub(struct block_list *bl, va_list ap)
case HT_BLASTMINE:
case HT_CLAYMORETRAP:
case HT_TALKIEBOX:
#ifndef RENEWAL
case HP_BASILICA:
#endif
case RA_ELECTRICSHOCKER:
case RA_CLUSTERBOMB:
case RA_MAGENTATRAP:
@ -3923,8 +3958,10 @@ static int skill_check_unit_range2_sub (struct block_list *bl, va_list ap)
if( status_isdead(bl) && skill_id != AL_WARP )
return 0;
#ifndef RENEWAL
if( skill_id == HP_BASILICA && bl->type == BL_PC )
return 0;
#endif
if( skill_id == AM_DEMONSTRATION && bl->type == BL_MOB && ((TBL_MOB*)bl)->mob_id == MOBID_EMPERIUM )
return 0; //Allow casting Bomb/Demonstration Right under emperium [Skotlex]
@ -4931,23 +4968,49 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case RG_BACKSTAP:
{
if (!check_distance_bl(src, bl, 0)) {
#ifdef RENEWAL
uint8 dir = map_calc_dir(src, bl->x, bl->y);
short x, y;
if (dir > 0 && dir < 4)
x = -1;
else if (dir > 4)
x = 1;
else
x = 0;
if (dir > 2 && dir < 6)
y = -1;
else if (dir == 7 || dir < 2)
y = 1;
else
y = 0;
if (battle_check_target(src, bl, BCT_ENEMY) > 0 && unit_movepos(src, bl->x + x, bl->y + y, 2, true)) { // Display movement + animation.
#else
uint8 dir = map_calc_dir(src, bl->x, bl->y), t_dir = unit_getdir(bl);
if ((!check_distance_bl(src, bl, 0) && !map_check_dir(dir, t_dir)) || bl->type == BL_SKILL) {
if (!map_check_dir(dir, t_dir) || bl->type == BL_SKILL) {
#endif
status_change_end(src, SC_HIDING, INVALID_TIMER);
skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest]
unit_setdir(bl,dir);
#ifdef RENEWAL
clif_blown(src);
#endif
skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
}
else if (sd)
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
}
break;
case MO_FINGEROFFENSIVE:
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
if (battle_config.finger_offensive_type && sd) {
int i;
for (i = 1; i < sd->spiritball_old; i++)
for (int i = 1; i < sd->spiritball_old; i++)
skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
}
status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
@ -4967,6 +5030,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
short x, y, i = 2; // Move 2 cells (From target)
short dir = map_calc_dir(src,bl->x,bl->y);
#ifdef RENEWAL
if (skill_id == MO_EXTREMITYFIST && sd && sd->spiritball_old > 5)
flag |= 1; // Give +100% damage increase
#endif
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
if (skill_id == MO_EXTREMITYFIST) {
status_set_sp(src, 0, 0);
@ -5251,15 +5318,18 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
if(map_getcell(bl->m,tx,ty,CELL_CHKWALL))
break;
skill_blown(src,bl,1,dir,BLOWN_NONE);
int count;
// Splash around target cell, but only cells inside area; we first have to check the area is not negative
if((max(min_x,tx-1) <= min(max_x,tx+1)) &&
(max(min_y,ty-1) <= min(max_y,ty+1)) &&
(map_foreachinallarea(skill_area_sub, bl->m, max(min_x,tx-1), max(min_y,ty-1), min(max_x,tx+1), min(max_y,ty+1), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill_area_sub_count))) {
(count = map_foreachinallarea(skill_area_sub, bl->m, max(min_x,tx-1), max(min_y,ty-1), min(max_x,tx+1), min(max_y,ty+1), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill_area_sub_count))) {
// Recursive call
map_foreachinallarea(skill_area_sub, bl->m, max(min_x,tx-1), max(min_y,ty-1), min(max_x,tx+1), min(max_y,ty+1), splash_target(src), src, skill_id, skill_lv, tick, (flag|BCT_ENEMY)+1, skill_castend_damage_id);
// Self-collision
if(bl->x >= min_x && bl->x <= max_x && bl->y >= min_y && bl->y <= max_y)
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,(flag&0xFFF)>0?SD_ANIMATION:0);
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,(flag&0xFFF)>0?SD_ANIMATION|count:count);
break;
}
}
@ -5329,6 +5399,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case MG_FROSTDIVER:
case WZ_SIGHTBLASTER:
case WZ_SIGHTRASHER:
#ifdef RENEWAL
case PA_PRESSURE:
#endif
case NJ_KOUENKA:
case NJ_HYOUSENSOU:
case NJ_HUUJIN:
@ -5392,7 +5465,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case NPC_DARKBREATH:
clif_emotion(src,ET_ANGER);
case SN_FALCONASSAULT:
#ifndef RENEWAL
case PA_PRESSURE:
#endif
case CR_ACIDDEMONSTRATION:
case TF_THROWSTONE:
#ifdef RENEWAL
@ -6148,6 +6223,97 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
return 0;
}
/**
* Give a song's buff/debuff or damage to all targets around
* @param target: Target
* @param ap: Argument list
* @return 1 on success or 0 otherwise
*/
static int skill_apply_songs(struct block_list* target, va_list ap)
{
int flag = va_arg(ap, int);
struct block_list* src = va_arg(ap, struct block_list*);
uint16 skill_id = static_cast<uint16>(va_arg(ap, int));
uint16 skill_lv = static_cast<uint16>(va_arg(ap, int));
t_tick tick = va_arg(ap, t_tick);
if (flag & BCT_WOS && src == target)
return 0;
if (battle_check_target(src, target, flag) > 0) {
switch (skill_id) {
// Attack type songs
case BA_DISSONANCE:
skill_attack(BF_MAGIC, src, src, target, skill_id, skill_lv, tick, 0);
return 1;
case DC_UGLYDANCE:
case BD_LULLABY:
return skill_additional_effect(src, target, skill_id, skill_lv, BF_LONG | BF_SKILL | BF_MISC, ATK_DEF, tick);
default: // Buff/Debuff type songs
if (skill_id == CG_HERMODE && src->id != target->id)
status_change_clear_buffs(target, SCCB_BUFFS); // Should dispell only allies.
return sc_start(src, target, status_skill2sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
}
}
return 0;
}
/**
* Calculate a song's bonus values
* @param src: Caster
* @param skill_id: Song skill ID
* @param skill_lv: Song skill level
* @param tick: Timer tick
* @return Number of targets or 0 otherwise
*/
static int skill_castend_song(struct block_list* src, uint16 skill_id, uint16 skill_lv, t_tick tick)
{
nullpo_ret(src);
if (src->type != BL_PC) {
ShowWarning("skill_castend_song: Expected player type for src!\n");
return 0;
}
if (!(skill_get_inf2_(skill_id, { INF2_ISSONG, INF2_ISENSEMBLE }))) {
ShowWarning("skill_castend_song: Unknown song skill ID: %u\n", skill_id);
return 0;
}
struct map_session_data* sd = BL_CAST(BL_PC, src);
int flag = BCT_PARTY;
switch (skill_id) {
case BD_ROKISWEIL:
flag = BCT_ENEMY | BCT_WOS;
break;
case BD_LULLABY:
case BD_ETERNALCHAOS:
case BA_DISSONANCE:
case DC_UGLYDANCE:
case DC_DONTFORGETME:
flag = BCT_ENEMY;
break;
case CG_HERMODE:
flag |= BCT_GUILD;
break;
}
clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
sd->skill_id_dance = skill_id;
sd->skill_lv_dance = skill_lv;
if (skill_get_inf2(skill_id, INF2_ISENSEMBLE)) {
sc_start(src, src, status_skill2sc(CG_SPECIALSINGER), 100, 1, skill_get_time(CG_SPECIALSINGER, skill_lv));
skill_check_pc_partner(sd, skill_id, &skill_lv, 3, 1);
// todo, apply ensemble fatigue if it hits you + ensemble partner.. ??
// or maybe we do that in skill_check_pc_partner or something ??
}
return map_foreachinrange(skill_apply_songs, src, skill_get_splash(skill_id, skill_lv), splash_target(src), flag, src, skill_id, skill_lv, tick);
}
/**
* Use no-damage skill from 'src' to 'bl
* @param src Caster
@ -6615,6 +6781,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif_skill_nodamage(src,bl,skill_id,skill_lv,0);
break;
}
#ifdef RENEWAL
clif_skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
#else
// 100% success rate at lv4 & 5, but lasts longer at lv5
if(!clif_skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,type,(60+skill_lv*10),skill_lv, skill_get_time(skill_id,skill_lv)))) {
if (dstsd){
@ -6625,6 +6794,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (sd)
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
#endif
break;
case PR_ASPERSIO:
@ -6700,9 +6870,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
}
case PR_SLOWPOISON:
case PR_IMPOSITIO:
case PR_LEXAETERNA:
#ifndef RENEWAL
case PR_IMPOSITIO:
case PR_SUFFRAGIUM:
#endif
case LK_BERSERK:
case MS_BERSERK:
case KN_TWOHANDQUICKEN:
@ -6712,7 +6884,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case CR_REFLECTSHIELD:
case MS_REFLECTSHIELD:
case AS_POISONREACT:
#ifndef RENEWAL
case MC_LOUD:
#endif
case MG_ENERGYCOAT:
case MO_EXPLOSIONSPIRITS:
case MO_STEELBODY:
@ -6721,6 +6895,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case LK_PARRYING:
case MS_PARRYING:
case LK_CONCENTRATION:
#ifdef RENEWAL
case HP_BASILICA:
#endif
case WS_CARTBOOST:
case SN_SIGHT:
case WS_MELTDOWN:
@ -7238,6 +7415,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case AL_ANGELUS:
#ifdef RENEWAL
case MC_LOUD:
case PR_SUFFRAGIUM:
#endif
case PR_MAGNIFICAT:
case PR_GLORIA:
case SN_WINDWALK:
@ -7374,11 +7555,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
case CG_SPECIALSINGER:
if (tsc && tsc->data[SC_LONGING]) {
clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
status_change_end(bl, SC_LONGING, INVALID_TIMER);
}
break;
case BD_ADAPTATION:
#ifdef RENEWAL
clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
#else
if(tsc && tsc->data[SC_DANCING]){
clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
status_change_end(bl, SC_DANCING, INVALID_TIMER);
}
#endif
break;
case BA_FROSTJOKER:
@ -7417,6 +7610,29 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
#ifdef RENEWAL
case BD_LULLABY:
case BD_RICHMANKIM:
case BD_ETERNALCHAOS:
case BD_DRUMBATTLEFIELD:
case BD_RINGNIBELUNGEN:
case BD_ROKISWEIL:
case BD_INTOABYSS:
case BD_SIEGFRIED:
case BA_DISSONANCE:
case BA_POEMBRAGI:
case BA_WHISTLE:
case BA_ASSASSINCROSS:
case BA_APPLEIDUN:
case DC_UGLYDANCE:
case DC_HUMMING:
case DC_DONTFORGETME:
case DC_FORTUNEKISS:
case DC_SERVICEFORYOU:
skill_castend_song(src, skill_id, skill_lv, tick);
break;
#endif
case TF_STEAL:
if(sd) {
if(pc_steal_item(sd,bl,skill_lv))
@ -8151,6 +8367,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
} else {
int maxlv=1,spellid=0;
static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT };
if(skill_lv >= 10) {
spellid = MG_FROSTDIVER;
// if (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SA_SAGE)
@ -8175,6 +8392,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
spellid = MG_NAPALMBEAT;
maxlv = 3;
}
if(spellid > 0)
sc_start4(src,src,SC_AUTOSPELL,100,skill_lv,spellid,maxlv,0,
skill_get_time(SA_AUTOSPELL,skill_lv));
@ -8720,6 +8938,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
#ifndef RENEWAL
case CG_LONGINGFREEDOM:
{
if (tsc && !tsce && (tsce=tsc->data[SC_DANCING]) && tsce->val4
@ -8730,6 +8949,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
}
break;
#endif
case CG_TAROTCARD:
{
@ -8739,7 +8959,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
map_freeblock_unlock();
return 0;
}
if( rnd() % 100 > skill_lv * 8 || (tsc && tsc->data[SC_BASILICA]) ||
if( rnd() % 100 > skill_lv * 8 ||
#ifndef RENEWAL
(tsc && tsc->data[SC_BASILICA]) ||
#endif
(dstmd && ((dstmd->guardian_data && dstmd->mob_id == MOBID_EMPERIUM) || status_get_class_(bl) == CLASS_BATTLEFIELD)) ) {
if( sd )
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@ -9282,6 +9505,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AB_PRAEFATIO:
case AB_RENOVATIO:
#ifdef RENEWAL
case PR_IMPOSITIO:
#endif
if( !sd || sd->status.party_id == 0 || flag&1 ) {
if (skill_id == AB_PRAEFATIO)
clif_skill_nodamage(bl, bl, skill_id, skill_lv, sc_start4(src, bl, type, 100, skill_lv, 0, 0, (sd && sd->status.party_id ? party_foreachsamemap(party_sub_count, sd, 0) : 1 ), skill_get_time(skill_id, skill_lv)));
@ -11155,8 +11381,14 @@ static int8 skill_castend_id_check(struct block_list *src, struct block_list *ta
break;
case RG_BACKSTAP:
{
uint8 dir = map_calc_dir(src,target->x,target->y),t_dir = unit_getdir(target);
if (check_distance_bl(src, target, 0) || map_check_dir(dir,t_dir))
#ifndef RENEWAL
uint8 dir = map_calc_dir(src,target->x,target->y), t_dir = unit_getdir(target);
if (map_check_dir(dir, t_dir))
return USESKILL_FAIL_MAX;
#endif
if (check_distance_bl(src, target, 0))
return USESKILL_FAIL_MAX;
}
break;
@ -11466,18 +11698,28 @@ TIMER_FUNC(skill_castend_id){
case RL_FIREDANCE:
sd->canequip_tick = tick + skill_get_time(ud->skill_id, ud->skill_lv);
break;
case KN_BRANDISHSPEAR:
case KN_BOWLINGBASH:
case CR_GRANDCROSS:
case NPC_GRANDDARKNESS:
if( (sc = status_get_sc(src)) && sc->data[SC_STRIPSHIELD] )
{
const struct TimerData *timer = get_timer(sc->data[SC_STRIPSHIELD]->timer);
if( timer && timer->func == status_change_timer && DIFF_TICK(timer->tick,gettick()+skill_get_time(ud->skill_id, ud->skill_lv)) > 0 )
case NPC_GRANDDARKNESS: {
sc_type type;
if (ud->skill_id == KN_BRANDISHSPEAR || ud->skill_id == KN_BOWLINGBASH)
type = SC_STRIPWEAPON;
else
type = SC_STRIPSHIELD;
if ((sc = status_get_sc(src)) && sc->data[type]) {
const struct TimerData* timer = get_timer(sc->data[type]->timer);
if (timer && timer->func == status_change_timer && DIFF_TICK(timer->tick, gettick() + skill_get_time(ud->skill_id, ud->skill_lv)) > 0)
break;
}
sc_start2(src,src, SC_STRIPSHIELD, 100, 0, 1, skill_get_time(ud->skill_id, ud->skill_lv));
sc_start2(src, src, type, 100, 0, 1, skill_get_time(ud->skill_id, ud->skill_lv));
break;
}
}
}
if (skill_get_state(ud->skill_id) != ST_MOVE_ENABLE)
unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill_get_walkdelay(ud->skill_id, ud->skill_lv), 1);
@ -11502,9 +11744,10 @@ TIMER_FUNC(skill_castend_id){
sc->data[SC_SPIRIT]->val3 == ud->skill_id &&
ud->skill_id != WZ_WATERBALL)
sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
#ifndef RENEWAL
if( sc->data[SC_DANCING] && sd && skill_get_inf2(ud->skill_id, INF2_ISSONG) )
skill_blockpc_start(sd,BD_ADAPTATION,3000);
#endif
}
if (sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL) // they just set the data so leave it as it is.[Inkfish]
@ -11846,6 +12089,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case WE_CALLPARENT:
case WE_CALLBABY:
case SA_LANDPROTECTOR:
#ifndef RENEWAL
case BD_LULLABY:
case BD_RICHMANKIM:
case BD_ETERNALCHAOS:
@ -11864,6 +12108,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case DC_DONTFORGETME:
case DC_FORTUNEKISS:
case DC_SERVICEFORYOU:
#endif
case CG_MOONLIT:
case GS_DESPERADO:
case NJ_KAENSIN:
@ -11872,6 +12117,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case NJ_HYOUSYOURAKU:
case NJ_RAIGEKISAI:
case NJ_KAMAITACHI:
#ifdef RENEWAL
case HW_GRAVITATION:
#endif
case NPC_EVILLAND:
case NPC_VENOMFOG:
case NPC_ICEMINE:
@ -11927,6 +12175,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
skill_unitsetting(src,skill_id,skill_lv,x,y,0);
flag|=1;
break;
#ifndef RENEWAL
case HP_BASILICA:
if( sc->data[SC_BASILICA] ) {
status_change_end(src, SC_BASILICA, INVALID_TIMER); // Cancel Basilica and return so requirement isn't consumed again
@ -11941,12 +12190,17 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
flag|=1;
}
break;
#endif
case CG_HERMODE:
#ifdef RENEWAL
skill_castend_song(src, skill_id, skill_lv, tick);
#else
skill_clear_unitgroup(src);
if ((sg = skill_unitsetting(src,skill_id,skill_lv,x,y,0)))
sc_start4(src,src,SC_DANCING,100,
skill_id,0,skill_lv,sg->group_id,skill_get_time(skill_id,skill_lv));
flag|=1;
#endif
break;
case RG_CLEANER: // [Valaris]
i = skill_get_splash(skill_id, skill_lv);
@ -12109,11 +12363,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
}
break;
#ifndef RENEWAL
case HW_GRAVITATION:
if ((sg = skill_unitsetting(src,skill_id,skill_lv,x,y,0)))
sc_start4(src,src,type,100,skill_lv,0,BCT_SELF,sg->group_id,skill_get_time(skill_id,skill_lv));
flag|=1;
break;
#endif
// Plant Cultivation [Celest]
case CR_CULTIVATION:
@ -12850,9 +13106,11 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
val3 = group->val3; //as well as the mapindex to warp to.
}
break;
#ifndef RENEWAL
case HP_BASILICA:
val1 = src->id; // Store caster id.
break;
#endif
case PR_SANCTUARY:
case NPC_EVILLAND:
@ -12942,11 +13200,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
}
case BA_WHISTLE:
#ifdef RENEWAL
val1 = 3 * skill_lv + status->agi / 15; // Flee increase
#else
val1 = skill_lv + status->agi / 10; // Flee increase
#endif
val2 = (skill_lv + 1) / 2 + status->luk / 30; // Perfect dodge increase
if (sd) {
val1 += pc_checkskill(sd, BA_MUSICALLESSON) / 2;
@ -12954,11 +13208,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
}
break;
case DC_HUMMING:
#ifdef RENEWAL
val1 = 20 + 2 * skill_lv + status->dex / 15; // Hit increase
#else
val1 = 1 + 2 * skill_lv + status->dex / 10; // Hit increase
#endif
if (sd)
val1 += pc_checkskill(sd, DC_DANCINGLESSON);
break;
@ -13000,12 +13250,8 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
case BA_ASSASSINCROSS:
if (sd)
val1 = pc_checkskill(sd, BA_MUSICALLESSON) / 2;
#ifdef RENEWAL // ASPD increase
val1 += skill_lv + (status->agi / 20);
#else
val1 += 5 + skill_lv + (status->agi / 20);
val1 *= 10; // ASPD works with 1000 as 100%
#endif
break;
case DC_FORTUNEKISS:
val1 = 10 + skill_lv + (status->luk / 10); // Critical increase
@ -13014,13 +13260,8 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
val1 += 5 * pc_checkskill(sd, DC_DANCINGLESSON);
break;
case BD_DRUMBATTLEFIELD:
#ifdef RENEWAL
val1 = (skill_lv+5)*25; //Atk increase
val2 = skill_lv*10; //Def increase
#else
val1 = (skill_lv+1)*25; //Atk increase
val2 = (skill_lv+1)*2; //Def increase
#endif
break;
case BD_RINGNIBELUNGEN:
val1 = (skill_lv+2)*25; //Atk increase
@ -13148,10 +13389,12 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
pc_delspiritcharm(sd,sd->spiritcharm,sd->spiritcharm_type);
}
break;
#ifndef RENEWAL
case HW_GRAVITATION:
if(sc && sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
link_group_id = sc->data[SC_GRAVITATION]->val4;
break;
#endif
case SO_VACUUM_EXTREME:
// Coordinates
val1 = x;
@ -13575,6 +13818,7 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, t_
}
break;
#ifndef RENEWAL
case UNT_GRAVITATION:
if (!sce)
sc_start4(ss, bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit);
@ -13592,6 +13836,7 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, t_
sc_start4(ss, bl, type, 100, 0, 0, sg->group_id, ss->id, sg->limit);
}
break;
#endif
case UNT_MOONLIT:
//Knockback out of area if affected char isn't in Moonlit effect
@ -13874,8 +14119,10 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t
break;
case UNT_MAGNUS:
#ifndef RENEWAL
if (!battle_check_undead(tstatus->race,tstatus->def_ele) && tstatus->race!=RC_DEMON)
break;
#endif
skill_attack(BF_MAGIC,ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
@ -14137,6 +14384,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t
}
break;
#ifndef RENEWAL
case UNT_BASILICA:
{
int i = battle_check_target(&unit->bl, bl, BCT_ENEMY);
@ -14149,6 +14397,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t
sc_start4(ss, bl, type, 100, 0, 0, sg->group_id, ss->id, sg->limit);
}
break;
#endif
case UNT_GROUNDDRIFT_WIND:
case UNT_GROUNDDRIFT_DARK:
@ -14434,10 +14683,12 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, t_tick tick)
status_change_end(bl, type, INVALID_TIMER);
break;
#ifndef RENEWAL
case UNT_BASILICA:
if (sce && sce->val4 != bl->id)
status_change_end(bl, type, INVALID_TIMER);
break;
#endif
case UNT_HERMODE: //Clear Hermode if the owner moved.
if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id)
@ -14522,8 +14773,10 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, t_tick tick)
case SA_DELUGE:
case SA_VIOLENTGALE:
case CG_HERMODE:
#ifndef RENEWAL
case HW_GRAVITATION:
case HP_BASILICA:
#endif
case NJ_SUITON:
case SC_MAELSTROM:
case EL_WATER_BARRIER:
@ -14828,9 +15081,10 @@ int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16
status_charge(&tsd->bl, 0, i);
}
break;
default: //Warning: Assuming Ensemble skills here (for speed)
default:
if( is_chorus )
break;//Chorus skills are not to be parsed as ensambles
break;//Chorus skills are not to be parsed as ensembles
if (skill_get_inf2(skill_id, INF2_ISENSEMBLE)) {
if (c > 0 && sd->sc.data[SC_DANCING] && (tsd = map_id2sd(p_sd[0])) != NULL) {
sd->sc.data[SC_DANCING]->val4 = tsd->bl.id;
sc_start4(&sd->bl,&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill_get_time(skill_id,*skill_lv)+1000);
@ -14838,6 +15092,7 @@ int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16
tsd->skill_id_dance = skill_id;
tsd->skill_lv_dance = *skill_lv;
}
}
return c;
}
}
@ -15193,6 +15448,9 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return false;
}
#ifdef RENEWAL
sd->spiritball_old = sd->spiritball;
#endif
break;
case TK_MISSION:
if( (sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON ) { // Cannot be used by Non-Taekwon classes
@ -15241,6 +15499,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
return false;
}
break; //Combo ready.
#ifndef RENEWAL
case BD_ADAPTATION:
{
int time;
@ -15259,6 +15518,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
}
}
break;
#endif
case PR_BENEDICTIO:
if (skill_check_pc_partner(sd, skill_id, &skill_lv, 1, 0) < 2) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@ -15273,12 +15533,14 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == AC_DOUBLE))
return false;
break;
#ifndef RENEWAL
case CG_HERMODE:
if(!npc_check_areanpc(1,sd->bl.m,sd->bl.x,sd->bl.y,skill_get_splash(skill_id, skill_lv))) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return false;
}
break;
#endif
case CG_MOONLIT: //Check there's no wall in the range+1 area around the caster. [Skotlex]
{
int s,range = skill_get_splash(skill_id, skill_lv)+1;
@ -15311,6 +15573,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
}
break;
}
#ifndef RENEWAL
case HP_BASILICA:
if( !sc || (sc && !sc->data[SC_BASILICA])) {
if( sd ) {
@ -15332,6 +15595,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
}
}
break;
#endif
case AM_TWILIGHT2:
case AM_TWILIGHT3:
if (!party_skill_check(sd, sd->status.party_id, skill_id, skill_lv)) {
@ -16280,6 +16544,12 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint
req.sp += req.sp * sc->data[SC_OFFERTORIUM]->val3 / 100;
if( sc->data[SC_TELEKINESIS_INTENSE] && skill_get_ele(skill_id, skill_lv) == ELE_GHOST)
req.sp -= req.sp * sc->data[SC_TELEKINESIS_INTENSE]->val2 / 100;
#ifdef RENEWAL
if (sc->data[SC_ADAPTATION] && (skill_get_inf2(skill_id, INF2_ISSONG)))
req.sp -= req.sp * 20 / 100;
if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_SPCONSUM)
req.sp -= req.sp * 30 / 100;
#endif
}
req.zeny = skill->require.zeny[skill_lv-1];
@ -16440,6 +16710,7 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint
if( sc->data[SC_BLADESTOP] )
req.spiritball--;
else if( sc->data[SC_COMBO] ) {
#ifndef RENEWAL
switch( sc->data[SC_COMBO]->val1 ) {
case MO_COMBOFINISH:
req.spiritball = 4;
@ -16451,6 +16722,9 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint
req.spiritball = sd->spiritball?sd->spiritball:1;
break;
}
#else
req.spiritball = sd->spiritball ? sd->spiritball : 1;
#endif
} else if( sc->data[SC_RAISINGDRAGON] && sd->spiritball > 5)
req.spiritball = sd->spiritball; // must consume all regardless of the amount required
}
@ -16723,7 +16997,9 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
VARCAST_REDUCTION(-sc->data[SC__LAZINESS]->val2);
if (sc->data[SC_SUFFRAGIUM]) {
VARCAST_REDUCTION(sc->data[SC_SUFFRAGIUM]->val2);
#ifndef RENEWAL
status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
#endif
}
if (sc->data[SC_MEMORIZE]) {
reduce_cast_rate += 50;
@ -16810,10 +17086,12 @@ int skill_delayfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
time = 1000;
time -= (4 * status_get_agi(bl) + 2 * status_get_dex(bl));
break;
#ifndef RENEWAL
case HP_BASILICA:
if (sc && !sc->data[SC_BASILICA])
time = 0; // There is no Delay on Basilica creation, only on cancel
break;
#endif
default:
if (battle_config.delay_dependon_dex && !(delaynodex&1)) { // if skill delay is allowed to be reduced by dex
int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
@ -17036,18 +17314,21 @@ int skill_autospell(struct map_session_data *sd, uint16 skill_id)
{
nullpo_ret(sd);
uint16 skill_lv = sd->menuskill_val;
if (SKILL_CHK_GUILD(skill_id))
return 0;
uint16 idx = skill_get_index(skill_id);
uint16 lv = (sd->status.skill[idx].id == skill_id) ? sd->status.skill[idx].lv : 0;
uint16 lv = pc_checkskill(sd, skill_id), skill_lv = sd->menuskill_val;
if(!skill_lv || !lv) return 0; // Player must learn the skill before doing auto-spell [Lance]
uint16 maxlv = 1;
#ifdef RENEWAL
if ((skill_id == MG_COLDBOLT || skill_id == MG_FIREBOLT || skill_id == MG_LIGHTNINGBOLT) && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SAGE)
maxlv = 10; //Soul Linker bonus. [Skotlex]
else
maxlv = skill_lv / 2; // Half of Autospell's level unless player learned a lower level (capped below)
#else
if(skill_id==MG_NAPALMBEAT) maxlv=3;
else if(skill_id==MG_COLDBOLT || skill_id==MG_FIREBOLT || skill_id==MG_LIGHTNINGBOLT){
if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SAGE)
@ -17067,9 +17348,9 @@ int skill_autospell(struct map_session_data *sd, uint16 skill_id)
}
else if(skill_id==MG_FROSTDIVER) maxlv=1;
else return 0;
#endif
if(maxlv > lv)
maxlv = lv;
maxlv = min(lv, maxlv);
sc_start4(&sd->bl,&sd->bl,SC_AUTOSPELL,100,skill_lv,skill_id,maxlv,0,
skill_get_time(SA_AUTOSPELL,skill_lv));
@ -17617,8 +17898,10 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
}
break;
case WZ_ICEWALL:
#ifndef RENEWAL
case HP_BASILICA:
case HW_GRAVITATION:
#endif
//These can't be placed on top of themselves (duration can't be refreshed)
if (unit->group->skill_id == skill_id)
{
@ -18074,9 +18357,11 @@ struct skill_unit *skill_initunit(struct skill_unit_group *group, int idx, int x
case SA_LANDPROTECTOR:
skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,true);
break;
#ifndef RENEWAL
case HP_BASILICA:
skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,true);
break;
#endif
case SC_MAELSTROM:
skill_unitsetmapcell(unit,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,true);
break;
@ -18134,9 +18419,11 @@ int skill_delunit(struct skill_unit* unit)
case SA_LANDPROTECTOR:
skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false);
break;
#ifndef RENEWAL
case HP_BASILICA:
skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,false);
break;
#endif
case RA_ELECTRICSHOCKER: {
struct block_list* target = map_id2bl(group->val2);
@ -18328,7 +18615,9 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
i = SC_NONE;
switch (group->unit_id) {
case UNT_GOSPEL: i = SC_GOSPEL; break;
#ifndef RENEWAL
case UNT_BASILICA: i = SC_BASILICA; break;
#endif
}
if (i != SC_NONE) {
struct status_change *sc = status_get_sc(src);

View File

@ -387,6 +387,22 @@ struct skill_unit_group_tickset {
int id;
};
/// Ring of Nibelungen bonuses
enum e_nibelungen_status : uint8 {
RINGNBL_ASPDRATE = 1, ///< ASPD + 20%
RINGNBL_ATKRATE, ///< Physical damage + 20%
RINGNBL_MATKRATE, ///< MATK + 20%
RINGNBL_HPRATE, ///< Maximum HP + 30%
RINGNBL_SPRATE, ///< Maximum SP + 30%
RINGNBL_ALLSTAT, ///< All stats + 15
RINGNBL_HIT, ///< HIT + 50
RINGNBL_FLEE, ///< FLEE + 50
RINGNBL_SPCONSUM, ///< SP consumption - 30%
RINGNBL_HPREGEN, ///< HP recovery + 100%
RINGNBL_SPREGEN, ///< SP recovery + 100%
RINGNBL_MAX,
};
/// Enum for skill_blown
enum e_skill_blown {
BLOWN_NONE = 0x00,
@ -1933,6 +1949,8 @@ enum e_skill {
ALL_EQSWITCH = 5067,
CG_SPECIALSINGER,
AB_VITUPERATUM = 5072,
AB_CONVENIO,

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
#ifndef STATUS_HPP
#define STATUS_HPP
#include "../common/database.hpp"
#include "../common/mmo.hpp"
#include "../common/timer.hpp"
@ -59,6 +60,23 @@ struct refine_cost {
int status_get_refine_chance(enum refine_type wlv, int refine, bool enriched);
int status_get_refine_cost(int weapon_lv, int type, bool what);
/// Weapon attack modification for size
struct s_sizefix_db {
uint16 small, medium, large;
};
class SizeFixDatabase : public TypesafeYamlDatabase<int32, s_sizefix_db> {
public:
SizeFixDatabase() : TypesafeYamlDatabase("SIZE_FIX_DB", 1) {
}
const std::string getDefaultLocation();
uint64 parseBodyNode(const YAML::Node &node);
};
extern SizeFixDatabase size_fix_db;
/// Status changes listing. These code are for use by the server.
enum sc_type : int16 {
SC_NONE = -1,
@ -863,6 +881,8 @@ enum sc_type : int16 {
SC_EARTHSHAKER,
SC_WEAPONBLOCK_ON,
SC_SPORE_EXPLOSION,
SC_ADAPTATION,
SC_BASILICA_CELL, // Used in renewal mode for cell_basilica only
SC_ENTRY_QUEUE_APPLY_DELAY,
SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT,

View File

@ -1128,7 +1128,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, enum e_skill_bl
* UB_KNOCKABLE - can be knocked back / stopped
* UB_NO_KNOCKBACK_MAP - at WOE/BG map
* UB_MD_KNOCKBACK_IMMUNE - target is MD_KNOCKBACK_IMMUNE
* UB_TARGET_BASILICA - target is in Basilica area
* UB_TARGET_BASILICA - target is in Basilica area (Pre-Renewal)
* UB_TARGET_NO_KNOCKBACK - target has 'special_state.no_knockback'
* UB_TARGET_TRAP - target is trap that cannot be knocked back
*/
@ -1148,9 +1148,12 @@ enum e_unit_blown unit_blown_immune(struct block_list* bl, uint8 flag)
break;
case BL_PC: {
struct map_session_data *sd = BL_CAST(BL_PC, bl);
#ifndef RENEWAL
// Basilica caster can't be knocked-back by normal monsters.
if( !(flag&0x4) && sd->sc.data[SC_BASILICA] && sd->sc.data[SC_BASILICA]->val4 == sd->bl.id)
return UB_TARGET_BASILICA;
#endif
// Target has special_state.no_knockback (equip)
if( (flag&(0x1|0x2)) && !(flag&0x8) && sd->special_state.no_knockback )
return UB_TARGET_NO_KNOCKBACK;
@ -1389,7 +1392,9 @@ int unit_can_move(struct block_list *bl) {
if( sc->cant.move // status placed here are ones that cannot be cached by sc->cant.move for they depend on other conditions other than their availability
|| sc->data[SC_SPIDERWEB]
|| (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
#ifndef RENEWAL
!sc->data[SC_LONGING] ||
#endif
(sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
(sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
) )
@ -1799,10 +1804,12 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
if (sc && sc->data[SC_RUN])
casttime = -1;
break;
#ifndef RENEWAL
case HP_BASILICA:
if( sc && sc->data[SC_BASILICA] )
casttime = -1; // No Casting time on basilica cancel
break;
#endif
#ifndef RENEWAL_CAST
case KN_CHARGEATK:
{
@ -2879,7 +2886,11 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
if(sc && sc->count ) { // map-change/warp dispells.
status_change_end(bl, SC_BLADESTOP, INVALID_TIMER);
#ifdef RENEWAL
status_change_end(bl, SC_BASILICA_CELL, INVALID_TIMER);
#else
status_change_end(bl, SC_BASILICA, INVALID_TIMER);
#endif
status_change_end(bl, SC_ANKLE, INVALID_TIMER);
status_change_end(bl, SC_TRICKDEAD, INVALID_TIMER);
status_change_end(bl, SC_BLADESTOP_WAIT, INVALID_TIMER);