Happy Holidays and Happy 12/12/12 :)

Update Elemental summon to its official behavior
  - Fixed missing skill features of Ventus(bugreport:6792,bugreport:6723,bugreport:6511)
  - Note: upgrade_svn17014.sql
  - And other elemental skills are to follow :)
Fixed bugreport:6889 updated const.txt where it cause error to some items.
Fixed bugreport:6999 where matk damage deals miss atk to plant type targets.
Fixed status calculation where it doesn't give accurate result or how official calculation does.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17014 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
rud0lp20 2012-12-11 17:20:44 +00:00
parent 872c6bf810
commit aa7031075c
19 changed files with 606 additions and 416 deletions

View File

@ -1232,9 +1232,50 @@ SC_TIDAL_WEAPON 504
SC_TIDAL_WEAPON_OPTION 505
SC_ROCK_CRUSHER 506
SC_ROCK_CRUSHER_ATK 507
SC_INCMHP 529
SC_INCMSP 530
SC_PARTYFLEE 531
SC_LEADERSHIP 508
SC_GLORYWOUNDS 509
SC_SOULCOLD 510
SC_HAWKEYES 511
SC_ODINS_POWER 512
SC_RAID 513
SC_FIRE_INSIGNIA 514
SC_WATER_INSIGNIA 515
SC_WIND_INSIGNIA 516
SC_EARTH_INSIGNIA 517
SC_PUSH_CART 518
SC_SPELLBOOK1 519
SC_SPELLBOOK2 520
SC_SPELLBOOK3 521
SC_SPELLBOOK4 522
SC_SPELLBOOK5 523
SC_SPELLBOOK6 524
SC_MAXSPELLBOOK 525
SC_INCMHP 526
SC_INCMSP 527
SC_PARTYFLEE 528
SC_MEIKYOUSISUI 529
SC_JYUMONJIKIRI 530
SC_KYOUGAKU 531
SC_IZAYOI 532
SC_ZENKAI 533
SC_KAGEHUMI 534
SC_KYOMU 535
SC_KAGEMUSYA 536
SC_ZANGETSU 537
SC_GENSOU 538
SC_AKAITSUKI 539
SC_STYLE_CHANGE 540
SC_GOLDENE_FERSE 541
SC_ANGRIFFS_MODUS 542
SC_ERASER_CUTTER 543
SC_OVERED_BOOST 544
SC_LIGHT_OF_REGENE 545
SC_ASH 546
SC_GRANITIC_ARMOR 547
SC_MAGMA_FLOW 548
SC_PYROCLASTIC 549
SC_PARALYSIS 550
SC_PAIN_KILLER 551
e_gasp 0
e_what 1

View File

@ -2,30 +2,23 @@
//
// Structure of Database:
// ID,Sprite_Name,Name,LV,HP,SP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Speed,aDelay,aMotion,dMotion
// NOTE
// Summoned Elementals STATs are affected by the Casters Base Level and STATs.
// So all value added here will be added and will not override the calculated STATs of the summoned elemental.
// Monster Elementals
2114,EL_AGNI_S,Agni,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,83,200,504,1020,360
2115,EL_AGNI_M,Agni,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,83,200,504,1020,360
2116,EL_AGNI_L,Agni,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,83,200,504,1020,360
2117,EL_AQUA_S,Aqua,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,81,200,504,1020,360
2118,EL_AQUA_M,Aqua,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,81,200,504,1020,360
2119,EL_AQUA_L,Aqua,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,81,200,504,1020,360
2120,EL_VENTUS_S,Ventus,100,5000,1,4,100,100,10,10,1,1,1,1,1,1,5,12,0,0,84,200,504,1020,360
2121,EL_VENTUS_M,Ventus,100,7500,1,4,250,250,25,25,1,1,1,1,1,1,5,12,1,0,84,200,504,1020,360
2122,EL_VENTUS_L,Ventus,100,10000,1,4,500,500,50,50,1,1,1,1,1,1,5,12,2,0,84,200,504,1020,360
2123,EL_TERA_S,Tera,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,82,200,504,1020,360
2124,EL_TERA_M,Tera,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,82,200,504,1020,360
2125,EL_TERA_L,Tera,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,82,200,504,1020,360
2114,EL_AGNI_S,Agni,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,83,200,504,1020,360
2115,EL_AGNI_M,Agni,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,83,200,504,1020,360
2116,EL_AGNI_L,Agni,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,2,0,83,200,504,1020,360
//2114,EL_AGNI_S,Agni ,100,5000,500 ,1,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,83,200,504,1020,360
//2115,EL_AGNI_M,Agni ,100,7500,750 ,1,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,83,200,504,1020,360
//2116,EL_AGNI_L,Agni ,100,10000,1000 ,1,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,83,200,504,1020,360
//2117,EL_AQUA_S,Aqua ,100,5000,500 ,1,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,81,200,504,1020,360
//2118,EL_AQUA_M,Aqua ,100,7500,750 ,1,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,81,200,504,1020,360
//2119,EL_AQUA_L,Aqua ,100,10000,1000 ,1,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,81,200,504,1020,360
//2120,EL_VENTUS_S,Ventus ,100,5000,500 ,4,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,84,200,504,1020,360
//2121,EL_VENTUS_M,Ventus ,100,7500,750 ,4,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,84,200,504,1020,360
//2122,EL_VENTUS_L,Ventus ,100,10000,1000 ,4,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,84,200,504,1020,360
//2123,EL_TERA_S,Tera ,100,5000,500 ,1,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,82,200,504,1020,360
//2124,EL_TERA_M,Tera ,100,7500,750 ,1,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,82,200,504,1020,360
//2125,EL_TERA_L,Tera ,100,10000,1000 ,1,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,82,200,504,1020,360
2117,EL_AQUA_S,Aqua,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,81,200,504,1020,360
2118,EL_AQUA_M,Aqua,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,81,200,504,1020,360
2119,EL_AQUA_L,Aqua,100,0,1,1,0,0,0,0,1,1,1,1,1,1,5,12,2,0,81,200,504,1020,360
2120,EL_VENTUS_S,Ventus,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,84,200,504,1020,360
2121,EL_VENTUS_M,Ventus,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,84,200,504,1020,360
2122,EL_VENTUS_L,Ventus,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,2,0,84,200,504,1020,360
2123,EL_TERA_S,Tera,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,82,200,504,1020,360
2124,EL_TERA_M,Tera,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,82,200,504,1020,360
2125,EL_TERA_L,Tera,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,2,0,82,200,504,1020,360

View File

@ -1884,8 +1884,12 @@
8424,0,0,0,-1,0,0
//-- EL_TIDAL_WEAPON
8433,0,0,0,-1,0,0
//-- EL_WIND_SLASH
8434,1000,0,0,0,0,0
//-- EL_HURRICANE
8435,1000,0,0,0,0,0
//-- EL_TYPOON_MIS
8437,0,0,0,15000,0,0
8437,1000,0,0,15000,0,0
//-- EL_STONE_HAMMER
8439,0,0,0,5000,0,0
//-- EL_ROCK_CRUSHER

View File

@ -1180,8 +1180,8 @@
8434,11,6,1,4,0,0,1,1,no,0,0,0,weapon,0, EL_WIND_SLASH,Wind Slasher
8435,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0, EL_HURRICANE,Hurricane Rage
8436,7,6,1,4,0,0,1,1,no,0,0,0,magic,0, EL_HURRICANE_ATK,Hurricane Rage Attack
8437,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0, EL_TYPOON_MIS,Typhoon Missile
8438,11,6,1,4,0,1,1,1,no,0,0,0,magic,0, EL_TYPOON_MIS_ATK,Typhoon Missile Attack
8437,11,8,1,4,0,1,1,-3,no,0,0,0,weapon,0, EL_TYPOON_MIS,Typhoon Missile
8438,11,8,1,4,0,1,1,-3,no,0,0,0,magic,0, EL_TYPOON_MIS_ATK,Typhoon Missile Attack
8439,5,6,1,2,0,0,1,1,no,0,0,0,weapon,0, EL_STONE_HAMMER,Stone Hammer
8440,3,6,1,2,0,1,1,1,no,0,0,0,weapon,0, EL_ROCK_CRUSHER,Rock Launcher
8441,5,6,1,2,0,1,1,1,no,0,0,0,magic,0, EL_ROCK_CRUSHER_ATK,Rock Launcher Attack

View File

@ -1884,8 +1884,12 @@
8424,0,0,0,-1,0,0,-1
//-- EL_TIDAL_WEAPON
8433,0,0,0,-1,0,0,-1
//-- EL_WIND_SLASH
8434,1000,0,0,0,0,0,-1
//-- EL_HURRICANE
8435,1000,0,0,0,0,0,-1
//-- EL_TYPOON_MIS
8437,0,0,0,15000,0,0,-1
8437,1000,0,0,15000,0,0,-1
//-- EL_STONE_HAMMER
8439,0,0,0,5000,0,0,-1
//-- EL_ROCK_CRUSHER

View File

@ -1181,8 +1181,8 @@
8434,11,6,1,4,0,0,1,1,no,0,0,0,weapon,0, EL_WIND_SLASH,Wind Slasher
8435,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0, EL_HURRICANE,Hurricane Rage
8436,7,6,1,4,0,0,1,1,no,0,0,0,magic,0, EL_HURRICANE_ATK,Hurricane Rage Attack
8437,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0, EL_TYPOON_MIS,Typhoon Missile
8438,11,6,1,4,0,1,1,1,no,0,0,0,magic,0, EL_TYPOON_MIS_ATK,Typhoon Missile Attack
8437,11,8,1,4,0,1,1,-3,no,0,0,0,weapon,0, EL_TYPOON_MIS,Typhoon Missile
8438,11,8,1,4,0,1,1,-3,no,0,0,0,magic,0, EL_TYPOON_MIS_ATK,Typhoon Missile Attack
8439,5,6,1,2,0,0,1,1,no,0,0,0,weapon,0, EL_STONE_HAMMER,Stone Hammer
8440,3,6,1,2,0,1,1,1,no,0,0,0,weapon,0, EL_ROCK_CRUSHER,Rock Launcher
8441,5,6,1,2,0,1,1,1,no,0,0,0,magic,0, EL_ROCK_CRUSHER_ATK,Rock Launcher Attack

View File

@ -146,12 +146,14 @@ CREATE TABLE IF NOT EXISTS `elemental` (
`sp` int(12) NOT NULL default '1',
`max_hp` mediumint(8) unsigned NOT NULL default '0',
`max_sp` mediumint(6) unsigned NOT NULL default '0',
`str` smallint(4) unsigned NOT NULL default '0',
`agi` smallint(4) unsigned NOT NULL default '0',
`vit` smallint(4) unsigned NOT NULL default '0',
`int` smallint(4) unsigned NOT NULL default '0',
`dex` smallint(4) unsigned NOT NULL default '0',
`luk` smallint(4) unsigned NOT NULL default '0',
`atk` MEDIUMINT(6) unsigned NOT NULL default '0',
`atk2` MEDIUMINT(6) unsigned NOT NULL default '0',
`matk` MEDIUMINT(6) unsigned NOT NULL default '0',
`aspd` smallint(4) unsigned NOT NULL default '0',
`def` smallint(4) unsigned NOT NULL default '0',
`mdef` smallint(4) unsigned NOT NULL default '0',
`flee` smallint(4) unsigned NOT NULL default '0',
`hit` smallint(4) unsigned NOT NULL default '0',
`life_time` int(11) NOT NULL default '0',
PRIMARY KEY (`ele_id`)
) ENGINE=MyISAM;

View File

@ -0,0 +1,9 @@
ALTER TABLE `elemental` CHANGE COLUMN `str` `atk1` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT 0,
CHANGE COLUMN `agi` `atk2` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT 0,
CHANGE COLUMN `vit` `matk` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT 0,
CHANGE COLUMN `int` `aspd` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
CHANGE COLUMN `dex` `def` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
CHANGE COLUMN `luk` `mdef` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
CHANGE COLUMN `life_time` `flee` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
ADD COLUMN `hit` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0 AFTER `flee`,
ADD COLUMN `life_time` INT(11) NOT NULL DEFAULT 0 AFTER `hit`;

View File

@ -20,9 +20,9 @@ bool mapif_elemental_save(struct s_elemental* ele) {
if( ele->elemental_id == 0 ) { // Create new DB entry
if( SQL_ERROR == Sql_Query(sql_handle,
"INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`life_time`)"
"VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u')",
ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi, ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time) )
"INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`atk1`,`atk2`,`matk`,`aspd`,`def`,`mdef`,`flee`,`hit`,`life_time`)"
"VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u')",
ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2, ele->matk, ele->amotion, ele->def, ele->mdef, ele->flee, ele->hit, ele->life_time) )
{
Sql_ShowDebug(sql_handle);
flag = false;
@ -31,10 +31,10 @@ bool mapif_elemental_save(struct s_elemental* ele) {
ele->elemental_id = (int)Sql_LastInsertId(sql_handle);
} else if( SQL_ERROR == Sql_Query(sql_handle,
"UPDATE `elemental` SET `char_id` = '%d', `class` = '%d', `mode` = '%d', `hp` = '%d', `sp` = '%d',"
"`max_hp` = '%d', `max_sp` = '%d', `str` = '%d', `agi` = '%d', `vit` = '%d', `int` = '%d', `dex` = '%d',"
"`luk` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'",
ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi,
ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time, ele->elemental_id) )
"`max_hp` = '%d', `max_sp` = '%d', `atk1` = '%d', `atk2` = '%d', `matk` = '%d', `aspd` = '%d', `def` = '%d',"
"`mdef` = '%d', `flee` = '%d', `hit` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'",
ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2,
ele->matk, ele->amotion, ele->def, ele->mdef, ele->flee, ele->hit, ele->life_time, ele->elemental_id) )
{ // Update DB entry
Sql_ShowDebug(sql_handle);
flag = false;
@ -49,8 +49,8 @@ bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) {
ele->elemental_id = ele_id;
ele->char_id = char_id;
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `str`, `agi`, `vit`, `int`, `dex`,"
"`luk`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `atk1`, `atk2`, `matk`, `aspd`,"
"`def`, `mdef`, `flee`, `hit`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
ele_id, char_id) ) {
Sql_ShowDebug(sql_handle);
return false;
@ -67,13 +67,15 @@ bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) {
Sql_GetData(sql_handle, 3, &data, NULL); ele->sp = atoi(data);
Sql_GetData(sql_handle, 4, &data, NULL); ele->max_hp = atoi(data);
Sql_GetData(sql_handle, 5, &data, NULL); ele->max_sp = atoi(data);
Sql_GetData(sql_handle, 6, &data, NULL); ele->str = atoi(data);
Sql_GetData(sql_handle, 7, &data, NULL); ele->agi = atoi(data);
Sql_GetData(sql_handle, 8, &data, NULL); ele->vit = atoi(data);
Sql_GetData(sql_handle, 9, &data, NULL); ele->int_ = atoi(data);
Sql_GetData(sql_handle, 10, &data, NULL); ele->dex = atoi(data);
Sql_GetData(sql_handle, 11, &data, NULL); ele->luk = atoi(data);
Sql_GetData(sql_handle, 12, &data, NULL); ele->life_time = atoi(data);
Sql_GetData(sql_handle, 6, &data, NULL); ele->atk = atoi(data);
Sql_GetData(sql_handle, 7, &data, NULL); ele->atk2 = atoi(data);
Sql_GetData(sql_handle, 8, &data, NULL); ele->matk = atoi(data);
Sql_GetData(sql_handle, 9, &data, NULL); ele->amotion = atoi(data);
Sql_GetData(sql_handle, 10, &data, NULL); ele->def = atoi(data);
Sql_GetData(sql_handle, 11, &data, NULL); ele->mdef = atoi(data);
Sql_GetData(sql_handle, 12, &data, NULL); ele->flee = atoi(data);
Sql_GetData(sql_handle, 13, &data, NULL); ele->hit = atoi(data);
Sql_GetData(sql_handle, 14, &data, NULL); ele->life_time = atoi(data);
Sql_FreeResult(sql_handle);
if( save_log )
ShowInfo("Elemental loaded (%d - %d).\n", ele->elemental_id, ele->char_id);

View File

@ -306,7 +306,8 @@ struct s_elemental {
int char_id;
short class_;
int mode;
int hp, sp, max_hp, max_sp, str, agi, vit, int_, dex, luk;
int hp, sp, max_hp, max_sp, matk, atk, atk2;
short hit, flee, amotion, def, mdef;
int life_time;
};

View File

@ -2868,10 +2868,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
} else
skillratio += 300; // Bombs
break;
case SO_VARETYR_SPEAR: //Assumed Formula.
skillratio += -100 + 200 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 1 );
case SO_VARETYR_SPEAR://ATK [{( Striking Level x 50 ) + ( Varetyr Spear Skill Level x 50 )} x Casters Base Level / 100 ] %
skillratio = 50 * skill_lv + ( sd ? pc_checkskill(sd, SO_STRIKING) * 50 : 0 );
if( sc && sc->data[SC_BLAST_OPTION] )
skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
skillratio += sd ? sd->status.job_level * 5 : 0;
break;
// Physical Elemantal Spirits Attack Skills
case EL_CIRCLE_OF_FIRE:
@ -3513,6 +3513,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
TBL_PC *sd;
// TBL_PC *tsd;
struct status_change *sc, *tsc;
struct Damage ad;
struct status_data *sstatus = status_get_status_data(src);
struct status_data *tstatus = status_get_status_data(target);
@ -3530,6 +3531,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
return ad;
}
//Initial Values
ad.damage = 1;
ad.div_=skill_get_num(skill_num,skill_lv);
ad.amotion=skill_get_inf(skill_num)&INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
ad.dmotion=tstatus->dmotion;
@ -3541,43 +3543,32 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
sd = BL_CAST(BL_PC, src);
// tsd = BL_CAST(BL_PC, target);
sc = status_get_sc(src);
tsc = status_get_sc(target);
//Initialize variables that will be used afterwards
s_ele = skill_get_ele(skill_num, skill_lv);
if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
s_ele = sstatus->rhw.ele;
if( sd ){ //Summoning 10 talisman will endow your weapon
ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
if( i < 5 ) s_ele = i;
}
}else if (s_ele == -2) //Use status element
s_ele = status_get_attack_sc_element(src,status_get_sc(src));
else if( s_ele == -3 ) //Use random element
s_ele = rnd()%ELE_MAX;
if( skill_num == SO_PSYCHIC_WAVE ) {
struct status_change *sc = status_get_sc(src);
if( sc && sc->count && ( sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] ||
sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] ) ) {
if( sc && sc->count ) {
if( sc->data[SC_HEATER_OPTION] ) s_ele = sc->data[SC_HEATER_OPTION]->val4;
else if( sc->data[SC_COOLER_OPTION] ) s_ele = sc->data[SC_COOLER_OPTION]->val4;
else if( sc->data[SC_BLAST_OPTION] ) s_ele = sc->data[SC_BLAST_OPTION]->val3;
else if( sc->data[SC_CURSED_SOIL_OPTION] ) s_ele = sc->data[SC_CURSED_SOIL_OPTION]->val4;
} else {
//#HALP# I didn't get a clue on how to do this without unnecessary adding a overhead of status_change on every call while this is a per-skill case.
//, - so i duplicated this code. make yourself comfortable to fix if you have any better ideas.
//Initialize variables that will be used afterwards
s_ele = skill_get_ele(skill_num, skill_lv);
if (s_ele == -1) // pl=-1 : the skill takes the weapon's element
s_ele = sstatus->rhw.ele;
else if (s_ele == -2) //Use status element
s_ele = status_get_attack_sc_element(src,status_get_sc(src));
else if( s_ele == -3 ) //Use random element
s_ele = rnd()%ELE_MAX;
}
} else {
//Initialize variables that will be used afterwards
s_ele = skill_get_ele(skill_num, skill_lv);
if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
s_ele = sstatus->rhw.ele;
if( sd ){ //Summoning 10 talisman will endow your weapon
ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
if( i < 5 ) s_ele = i;
}
}else if (s_ele == -2) //Use status element
s_ele = status_get_attack_sc_element(src,status_get_sc(src));
else if( s_ele == -3 ) //Use random element
s_ele = rnd()%ELE_MAX;
}
//Set miscellaneous data that needs be filled
if(sd) {
sd->state.arrow_atk = 0;
@ -3608,7 +3599,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if (!flag.infdef) //No need to do the math for plants
{
#ifdef RENEWAL
ad.damage = 0; //reinitialize..
#endif
//MATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
#define MATK_RATE( a ) { ad.damage= ad.damage*(a)/100; }
//Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
@ -3695,66 +3688,26 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if (battle_check_undead(tstatus->race,tstatus->def_ele))
skillratio += 5*skill_lv;
break;
case MG_FIREWALL: {
struct status_change *sc = status_get_sc(src);
skillratio -= 50;
if( sc && sc->data[SC_PYROTECHNIC_OPTION] )
skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
case MG_FIREWALL:
skillratio -= 50;
break;
case MG_FIREBOLT:
case MG_COLDBOLT:
case MG_LIGHTNINGBOLT:
if ( sc && sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
ad.flag = BF_WEAPON|BF_SHORT;
ad.type = 0;
}
break;
case MG_COLDBOLT: {
struct status_change *sc = status_get_sc(src);
if ( sc && sc->count ) {
if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
ad.flag = BF_WEAPON|BF_SHORT;
ad.type = 0;
}
if( sc->data[SC_AQUAPLAY_OPTION] )
skillratio += skillratio * sc->data[SC_AQUAPLAY_OPTION]->val3 / 100;
}
}
break;
case MG_FIREBOLT: {
struct status_change *sc = status_get_sc(src);
if ( sc && sc->count ) {
if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
ad.div_ = 1;
ad.flag = BF_WEAPON|BF_SHORT;
ad.type = 0;
}
if( sc->data[SC_PYROTECHNIC_OPTION] )
skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
}
}
break;
case MG_LIGHTNINGBOLT: {
struct status_change *sc = status_get_sc(src);
if ( sc && sc->count ) {
if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
ad.div_ = 1;
ad.flag = BF_WEAPON|BF_SHORT;
ad.type = 0;
}
if( sc->data[SC_GUST_OPTION] )
skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
}
}
break;
case MG_THUNDERSTORM: {
struct status_change *sc = status_get_sc(src);
case MG_THUNDERSTORM:
/**
* in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
**/
#ifndef RENEWAL
skillratio -= 20;
#endif
if( sc && sc->data[SC_GUST_OPTION] )
skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
}
break;
case MG_FROSTDIVER:
skillratio += 10*skill_lv;
@ -3870,15 +3823,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio += 100 + 100 * skill_lv;
RE_LVL_DMOD(100);
break;
case WL_JACKFROST: {
struct status_change *tsc = status_get_sc(target);
if( tsc && tsc->data[SC_FREEZING] ){
skillratio += 900 + 300 * skill_lv;
RE_LVL_DMOD(100);
}else{
skillratio += 400 + 100 * skill_lv;
RE_LVL_DMOD(150);
}
case WL_JACKFROST:
if( tsc && tsc->data[SC_FREEZING] ){
skillratio += 900 + 300 * skill_lv;
RE_LVL_DMOD(100);
}else{
skillratio += 400 + 100 * skill_lv;
RE_LVL_DMOD(150);
}
break;
case WL_DRAINLIFE:
@ -3954,76 +3905,60 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio += 100 * (sd ? pc_checkskill(sd, WM_REVERBERATION) : 1);
RE_LVL_DMOD(100);
break;
case SO_FIREWALK: {
struct status_change * sc = status_get_sc(src);
case SO_FIREWALK:
skillratio = 300;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_HEATER_OPTION] )
skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
}
skillratio += sc->data[SC_HEATER_OPTION]->val3;
break;
case SO_ELECTRICWALK: {
struct status_change * sc = status_get_sc(src);
case SO_ELECTRICWALK:
skillratio = 300;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_BLAST_OPTION] )
skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
}
skillratio += sd ? sd->status.job_level / 2 : 0;
break;
case SO_EARTHGRAVE: {
struct status_change * sc = status_get_sc(src);
case SO_EARTHGRAVE:
skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_SEISMICWEAPON) : 10 ) + sstatus->int_ * skill_lv );
RE_LVL_DMOD(100);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
}
skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
break;
case SO_DIAMONDDUST: {
struct status_change * sc = status_get_sc(src);
case SO_DIAMONDDUST:
skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_FROSTWEAPON) : 10 ) + sstatus->int_ * skill_lv );
RE_LVL_DMOD(100);
if( sc && sc->data[SC_COOLER_OPTION] )
skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
}
skillratio += sc->data[SC_COOLER_OPTION]->val3;
break;
case SO_POISON_BUSTER: {
struct status_change * sc = status_get_sc(src);
case SO_POISON_BUSTER:
skillratio += 1100 + 300 * skill_lv;
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
}
skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
break;
case SO_PSYCHIC_WAVE: {
struct status_change * sc = status_get_sc(src);
case SO_PSYCHIC_WAVE:
skillratio += -100 + skill_lv * 70 + (sstatus->int_ * 3);
RE_LVL_DMOD(100);
if( sc ){
if( sc->data[SC_HEATER_OPTION] )
skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
skillratio += sc->data[SC_HEATER_OPTION]->val3;
else if(sc->data[SC_COOLER_OPTION] )
skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
skillratio += sc->data[SC_COOLER_OPTION]->val3;
else if(sc->data[SC_BLAST_OPTION] )
skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
skillratio += sc->data[SC_BLAST_OPTION]->val2;
else if(sc->data[SC_CURSED_SOIL_OPTION] )
skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val3 / 100;
}
skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3;
}
break;
case SO_VARETYR_SPEAR: {
struct status_change * sc = status_get_sc(src);
skillratio += -100 + ( 100 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 10 ) + sstatus->int_ * skill_lv );
case SO_VARETYR_SPEAR: //MATK [{( Endow Tornado skill level x 50 ) + ( Casters INT x Varetyr Spear Skill level )} x Casters Base Level / 100 ] %
skillratio = status_get_int(src) * skill_lv + ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) * 50 : 0 );
RE_LVL_DMOD(100);
if( sc && sc->data[SC_BLAST_OPTION] )
skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
}
skillratio += sd ? sd->status.job_level * 5 : 0;
break;
case SO_CLOUD_KILL: {
struct status_change * sc = status_get_sc(src);
case SO_CLOUD_KILL:
skillratio += -100 + skill_lv * 40;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
}
skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
break;
case GN_DEMONIC_FIRE:
if( skill_lv > 20)
@ -4136,6 +4071,23 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if(ad.damage<1)
ad.damage=1;
else if(sc){//only applies when hit
// TODO: there is another factor that contribute with the damage and need to be formulated. [malufett]
switch(skill_num){
case MG_LIGHTNINGBOLT:
case MG_THUNDERSTORM:
case MG_FIREBOLT:
case MG_FIREWALL:
case MG_COLDBOLT:
case MG_FROSTDIVER:
case WZ_EARTHSPIKE:
case WZ_HEAVENDRIVE:
if(sc->data[SC_GUST_OPTION] || sc->data[SC_PETROLOGY_OPTION]
|| sc->data[SC_PYROTECHNIC_OPTION] || sc->data[SC_AQUAPLAY_OPTION])
ad.damage += (6 + sstatus->int_/4) + max(sstatus->dex-10,0)/30;
break;
}
}
if (!(nk&NK_NO_ELEFIX))
ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
@ -4172,7 +4124,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
switch( skill_num ) { /* post-calc modifiers */
case SO_VARETYR_SPEAR: { // Physical damage.
struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
ad.damage += wd.damage;
if(!flag.infdef && ad.damage > 1)
ad.damage += wd.damage;
break;
}
//case HM_ERASER_CUTTER:

View File

@ -9251,7 +9251,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
clif_spawn(&sd->ed->bl);
clif_elemental_info(sd);
clif_elemental_updatestatus(sd,SP_HP);
clif_hpmeter_single(sd->fd,sd->ed->bl.id,sd->ed->battle_status.hp,sd->ed->battle_status.matk_max);
clif_hpmeter_single(sd->fd,sd->ed->bl.id,sd->ed->battle_status.hp,sd->ed->battle_status.max_hp);
clif_elemental_updatestatus(sd,SP_SP);
status_calc_bl(&sd->ed->bl, SCB_SPEED); //Elemental mimic their master's speed on each map change
}

View File

@ -73,8 +73,56 @@ int elemental_create(struct map_session_data *sd, int class_, unsigned int lifet
ele.char_id = sd->status.char_id;
ele.class_ = class_;
ele.mode = EL_MODE_PASSIVE; // Initial mode
ele.hp = db->status.max_hp;
ele.sp = db->status.max_sp;
i = db->status.size+1; // summon level
//[(Casters Max HP/ 3 ) + (Casters INT x 10 )+ (Casters Job Level x 20 )] x [(Elemental Summon Level + 2) / 3]
ele.hp = ele.max_hp = (sd->battle_status.max_hp/3 + sd->battle_status.int_*10 + sd->status.job_level) * ((i + 2) / 3) * 5 * pc_checkskill(sd,SO_EL_SYMPATHY) / 100;
//Casters Max SP /4
ele.sp = ele.max_sp = sd->battle_status.max_sp/4 * 5 * pc_checkskill(sd,SO_EL_SYMPATHY) / 100;
//Casters [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ]
ele.atk = (sd->battle_status.max_sp / (18 / i) * 1 - 100) + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
//Casters [ Max SP / (18 / Elemental Summon Skill Level) ]
ele.atk2 = sd->battle_status.max_sp / 18 + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
//Casters HIT + (Casters Base Level )
ele.hit = sd->battle_status.hit + sd->status.base_level;
//[Elemental Summon Skill Level x (Casters INT / 2 + Casters DEX / 4)]
ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4) + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
//150 + [Casters DEX / 10] + [Elemental Summon Skill Level x 3 ]
ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3;
//Casters DEF + (Casters Base Level / (5 Elemental Summon Skill Level)
ele.def = sd->battle_status.def + sd->status.base_level / (5-i);
//Casters MDEF + (Casters INT / (5 - Elemental Summon Skill Level)
ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i);
//Casters FLEE + (Casters Base Level / (5 Elemental Summon Skill Level)
ele.flee = sd->status.base_level / (5-i);
//Casters HIT + (Casters Base Level )
ele.hit = sd->battle_status.hit + sd->status.base_level;
//per individual bonuses
switch(db->class_){
case 2114: case 2115:
case 2116: //ATK + (Summon Agni Skill Level x 20) / HIT + (Summon Agni Skill Level x 10)
ele.atk += i * 20;
ele.atk2 += i * 20;
ele.hit += i * 10;
break;
case 2117: case 2118:
case 2119: //MDEF + (Summon Aqua Skill Level x 10) / MATK + (Summon Aqua Skill Level x 20)
ele.mdef += i * 10;
ele.matk += i * 20;
break;
case 2120: case 2121:
case 2122: //FLEE + (Summon Ventus Skill Level x 20) / MATK + (Summon Ventus Skill Level x 10)
ele.flee += i * 20;
ele.matk += i * 10;
break;
case 2123: case 2124:
case 2125: //DEF + (Summon Tera Skill Level x 25) / ATK + (Summon Tera Skill Level x 5)
ele.def += i * 25;
ele.atk += i * 5;
ele.atk2 += i * 5;
break;
}
ele.life_time = lifetime;
// Request Char Server to create this elemental
@ -93,10 +141,19 @@ int elemental_get_lifetime(struct elemental_data *ed) {
}
int elemental_save(struct elemental_data *ed) {
ed->elemental.mode = ed->battle_status.mode;
ed->elemental.hp = ed->battle_status.hp;
ed->elemental.sp = ed->battle_status.sp;
ed->elemental.max_hp = ed->battle_status.max_hp;
ed->elemental.max_sp = ed->battle_status.max_sp;
ed->elemental.atk = ed->battle_status.rhw.atk;
ed->elemental.atk2 = ed->battle_status.rhw.atk2;
ed->elemental.matk = ed->battle_status.matk_min;
ed->elemental.def = ed->battle_status.def;
ed->elemental.mdef = ed->battle_status.mdef;
ed->elemental.flee = ed->battle_status.flee;
ed->elemental.hit = ed->battle_status.hit;
ed->elemental.life_time = elemental_get_lifetime(ed);
intif_elemental_save(&ed->elemental);
return 1;
}
@ -192,9 +249,8 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
map_addiddb(&ed->bl);
status_calc_elemental(ed,1);
ed->last_thinktime = gettick();
ed->last_spdrain_time = ed->last_thinktime = gettick();
ed->summon_timer = INVALID_TIMER;
ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
elemental_summon_init(ed);
} else {
memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental));
@ -202,14 +258,13 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
}
sd->status.ele_id = ele->elemental_id;
ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
if( ed->bl.prev == NULL && sd->bl.prev != NULL ) {
map_addblock(&ed->bl);
clif_spawn(&ed->bl);
clif_elemental_info(sd);
clif_elemental_updatestatus(sd,SP_HP);
clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.matk_max);
clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.max_hp);
clif_elemental_updatestatus(sd,SP_SP);
}
@ -259,8 +314,6 @@ int elemental_clean_single_effect(struct elemental_data *ed, int skill_num) {
break;
}
}
if( skill_get_unit_id(skill_num,0) )
skill_clear_unitgroup(&ed->bl);
return 1;
}
@ -292,9 +345,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER);
status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER);
status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER);
skill_clear_unitgroup(&ed->bl);
if( (sd = ed->master) == NULL )
return 0;
@ -328,6 +379,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
}
int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) {
struct skill_condition req;
short skillnum, skilllv;
int i;
@ -377,6 +429,20 @@ int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned
return 1;
}
req = elemental_skill_get_requirements(skillnum, skilllv);
if(req.hp || req.sp){
struct map_session_data *sd = BL_CAST(BL_PC, battle_get_master(&ed->bl));
if( sd ){
if( sd->skillid_old != SO_EL_ACTION && //regardless of remaining HP/SP it can be cast
(status_get_hp(&ed->bl) < req.hp || status_get_sp(&ed->bl) < req.sp) )
return 1;
else
status_zap(&ed->bl, req.hp, req.sp);
}
}
//Otherwise, just cast the skill.
if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
@ -488,6 +554,24 @@ int elemental_skillnotok(int skillid, struct elemental_data *ed) {
return skillnotok(skillid, ed->master);
}
struct skill_condition elemental_skill_get_requirements(int skill, int lv){
struct skill_condition req;
int id = skill_get_index(skill);
memset(&req,0,sizeof(req));
if( id == 0 ) // invalid skill id
return req;
if( lv < 1 || lv > MAX_SKILL_LEVEL )
return req;
req.hp = skill_db[id].hp[lv-1];
req.sp = skill_db[id].sp[lv-1];
return req;
}
int elemental_set_target( struct map_session_data *sd, struct block_list *bl ) {
struct elemental_data *ed = sd->ed;
@ -551,6 +635,30 @@ static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_
if( ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL )
return 0;
// Check if caster can sustain the summoned elemental
if( DIFF_TICK(tick,ed->last_spdrain_time) >= 10000 ){// Drain SP every 10 seconds
int sp = 5;
switch(ed->vd->class_){
case 2115: case 2118:
case 2121: case 2124:
sp = 8;
break;
case 2116: case 2119:
case 2122: case 2125:
sp = 11;
break;
}
if( status_get_sp(&sd->bl) < sp ){ // Can't sustain delete it.
elemental_delete(sd->ed,0);
return 0;
}
status_zap(&sd->bl,0,sp);
ed->last_spdrain_time = tick;
}
if( DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME )
return 0;
@ -687,7 +795,7 @@ int read_elementaldb(void) {
status->max_sp = atoi(str[5]);
status->rhw.range = atoi(str[6]);
status->rhw.atk = atoi(str[7]);
status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
status->rhw.atk2 = atoi(str[8]);
status->def = atoi(str[9]);
status->mdef = atoi(str[10]);
status->str = atoi(str[11]);

View File

@ -9,7 +9,7 @@
#define MIN_ELETHINKTIME 100
#define MIN_ELEDISTANCE 2
#define MAX_ELEDISTANCE 6
#define MAX_ELEDISTANCE 5
#define EL_MODE_AGGRESSIVE (MD_CANMOVE|MD_AGGRESSIVE|MD_CANATTACK)
#define EL_MODE_ASSIST (MD_CANMOVE|MD_ASSIST)
@ -51,7 +51,7 @@ struct elemental_data {
int summon_timer;
int skill_timer;
unsigned last_thinktime, last_linktime;
unsigned last_thinktime, last_linktime, last_spdrain_time;
short min_chase;
int target_id, attacked_id;
};
@ -80,6 +80,7 @@ int elemental_set_target( struct map_session_data *sd, struct block_list *bl );
int elemental_clean_single_effect(struct elemental_data *ed, int skill_num);
int elemental_clean_effect(struct elemental_data *ed);
int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick);
struct skill_condition elemental_skill_get_requirements(int skill, int lv);
#define elemental_stop_walking(ed, type) unit_stop_walking(&(ed)->bl, type)
#define elemental_stop_attack(ed) unit_stop_attack(&(ed)->bl)

View File

@ -6343,10 +6343,14 @@ int pc_resethate(struct map_session_data* sd)
int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
{
int i, bonus = 0;
nullpo_ret(sd);
ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == skill_num);
if( i < ARRAYLENGTH(sd->skillatk) ) bonus = sd->skillatk[i].val;
if(sd->sc.data[SC_PYROTECHNIC_OPTION] || sd->sc.data[SC_AQUAPLAY_OPTION])
bonus += 10;
return bonus;
}

View File

@ -1467,6 +1467,34 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
}
}
if( sd && sd->ed && sc && !status_isdead(bl) && !skillid ){
struct unit_data *ud = unit_bl2ud(src);
if( sc->data[SC_WILD_STORM_OPTION] )
skill = sc->data[SC_WILD_STORM_OPTION]->val2;
else if( sc->data[SC_UPHEAVAL_OPTION] )
skill = sc->data[SC_WILD_STORM_OPTION]->val2;
else if( sc->data[SC_TROPIC_OPTION] )
skill = sc->data[SC_TROPIC_OPTION]->val3;
else if( sc->data[SC_CHILLY_AIR_OPTION] )
skill = sc->data[SC_CHILLY_AIR_OPTION]->val3;
else
skill = 0;
if ( rnd()%100 < 25 && skill ){
skill_castend_damage_id(src, bl, skill, 5, tick, 0);
if (ud) {
rate = skill_delayfix(src, skill, skilllv);
if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
ud->canact_tick = tick+rate;
if ( battle_config.display_status_timers )
clif_status_change(src, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
}
}
}
}
// Autospell when attacking
if( sd && !status_isdead(bl) && sd->autospell[0].id )
{
@ -2443,8 +2471,6 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case EL_ROCK_CRUSHER_ATK:
case EL_HURRICANE:
case EL_HURRICANE_ATK:
case EL_TYPOON_MIS:
case EL_TYPOON_MIS_ATK:
case KO_BAKURETSU:
case GN_CRAZYWEED_ATK:
dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,5);
@ -4518,7 +4544,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
else {
int i = skill_get_splash(skillid,skilllv);
clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
if( rnd()%100 < 30 )
map_foreachinrange(skill_area_sub,bl,i,BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
else
@ -4554,7 +4580,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case EL_WIND_SLASH:
case EL_STONE_HAMMER:
clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
break;
@ -5859,6 +5885,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case MG_STONECURSE:
{
int brate = 0;
if (tstatus->mode&MD_BOSS) {
if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
break;
@ -5866,12 +5893,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if(status_isimmune(bl) || !tsc)
break;
if (sd && sd->sc.data[SC_PETROLOGY_OPTION])
brate = sd->sc.data[SC_PETROLOGY_OPTION]->val3;
if (tsc->data[SC_STONE]) {
status_change_end(bl, SC_STONE, INVALID_TIMER);
if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
break;
}
if (sc_start4(bl,SC_STONE,(skilllv*4+20),
if (sc_start4(bl,SC_STONE,(skilllv*4+20)+brate,
skilllv, 0, 0, skill_get_time(skillid, skilllv),
skill_get_time2(skillid,skilllv)))
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@ -8573,10 +8603,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
int elemental_class = skill_get_elemental_type(skillid,skilllv);
// Remove previous elemental fisrt.
if( sd->ed && elemental_delete(sd->ed,0) ) {
clif_skill_fail(sd,skillid,0,0);
break;
}
if( sd->ed )
elemental_delete(sd->ed,0);
// Summoning the new one.
if( !elemental_create(sd,elemental_class,skill_get_time(skillid,skilllv)) ) {
clif_skill_fail(sd,skillid,0,0);
@ -8589,22 +8618,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SO_EL_CONTROL:
if( sd ) {
int mode = EL_MODE_PASSIVE; // Standard mode.
if( !sd->ed ) {
clif_skill_fail(sd,skillid,0,0);
break;
}
if( !sd->ed ) break;
if( skilllv == 4 ) {// At level 4 delete elementals.
if( elemental_delete(sd->ed, 0) )
clif_skill_fail(sd,skillid,0,0);
elemental_delete(sd->ed, 0);
break;
}
switch( skilllv ) {// Select mode bassed on skill level used.
case 1: mode = EL_MODE_PASSIVE; break;
case 2: mode = EL_MODE_ASSIST; break;
case 3: mode = EL_MODE_AGGRESSIVE; break;
}
if( !elemental_change_mode(sd->ed,mode) ) {
clif_skill_fail(sd,skillid,0,0);
clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
break;
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@ -8614,8 +8640,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SO_EL_ACTION:
if( sd ) {
int duration = 3000;
if( !sd->ed )
break;
if( !sd->ed ) break;
sd->skillid_old = skillid;
elemental_action(sd->ed, bl, tick);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
switch(sd->ed->db->class_){
@ -8637,12 +8663,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
struct elemental_data *ed = sd->ed;
int s_hp = sd->battle_status.hp * 10 / 100, s_sp = sd->battle_status.sp * 10 / 100;
int e_hp, e_sp;
if( !ed ) {
clif_skill_fail(sd,skillid,0,0);
break;
}
if( !ed ) break;
if( !status_charge(&sd->bl,s_hp,s_sp) ) {
clif_skill_fail(sd,skillid,0,0);
clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
break;
}
e_hp = ed->battle_status.max_hp * 10 / 100;
@ -8761,10 +8785,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
elemental_clean_single_effect(ele, skillid);
} else {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
if( skillid == EL_WIND_STEP ) // There aren't telemport, just push to the master.
skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),(map_calc_dir(src,bl->x,bl->y)+4)%8,0);
clif_skill_nodamage(src,src,skillid,skilllv,1);
clif_skill_damage(src, ( skillid == EL_GUST || skillid == EL_BLAST || skillid == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
if( skillid == EL_WIND_STEP ) // There aren't teleport, just push the master away.
skill_blown(src,bl,(rnd()%skill_get_blewcount(skillid,skilllv))+1,rand()%8,0);
sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
}
@ -8777,7 +8801,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case EL_ZEPHYR:
case EL_POWER_OF_GAIA:
clif_skill_nodamage(src,src,skillid,skilllv,1);
clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
skill_unitsetting(src,skillid,skilllv,bl->x,bl->y,0);
break;
@ -13512,6 +13536,25 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
if( i < 3 )
continue;
break;
case SA_SEISMICWEAPON:
if( sc->data[SC_UPHEAVAL_OPTION] && rnd()%100 < 50 )
continue;
break;
case SA_FLAMELAUNCHER:
case SA_VOLCANO:
if( sc->data[SC_TROPIC_OPTION] && rnd()%100 < 50 )
continue;
break;
case SA_FROSTWEAPON:
case SA_DELUGE:
if( sc->data[SC_CHILLY_AIR_OPTION] && rnd()%100 < 50 )
continue;
break;
case SA_LIGHTNINGLOADER:
case SA_VIOLENTGALE:
if( sc && sc->data[SC_WILD_STORM_OPTION] && rnd()%100 < 50 )
continue;
break;
}
req.itemid[i] = skill_db[j].itemid[i];
@ -13632,6 +13675,10 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
case SO_SUMMON_TERA:
req.sp -= req.sp * (5 + 5 * pc_checkskill(sd,SO_EL_SYMPATHY)) / 100;
break;
case SO_PSYCHIC_WAVE:
if( sc && sc->data[SC_BLAST_OPTION] )
req.sp += req.sp * 150 / 100;
break;
}
return req;
@ -13791,6 +13838,8 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill
fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
if (sc->data[SC_IZAYOI] && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN))
fixed = 0;
if( sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION] )
fixed -= 1000;
}
if( sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){

View File

@ -723,10 +723,10 @@ void initChangeTables(void) {
set_sc( EL_AQUAPLAY , SC_AQUAPLAY_OPTION , SI_AQUAPLAY_OPTION , SCB_MATK );
set_sc( EL_COOLER , SC_COOLER_OPTION , SI_COOLER_OPTION , SCB_MATK );
set_sc( EL_CHILLY_AIR , SC_CHILLY_AIR_OPTION , SI_CHILLY_AIR_OPTION , SCB_MATK );
set_sc( EL_GUST , SC_GUST_OPTION , SI_GUST_OPTION , SCB_NONE );
set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_NONE );
set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_NONE );
set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_NONE );
set_sc( EL_GUST , SC_GUST_OPTION , SI_GUST_OPTION , SCB_ASPD );
set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_ASPD );
set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_ASPD );
set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_MAXHP );
set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_NONE );
set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_NONE );
set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL );
@ -3196,31 +3196,31 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) {
if( !sd )
return 0;
status->str = ele->str;
status->agi = ele->agi;
status->vit = ele->vit;
status->dex = ele->dex;
status->int_ = ele->int_;
status->luk = ele->luk;
if( first ) {
memcpy(status, &ed->db->status, sizeof(struct status_data));
status->mode = MD_CANMOVE|MD_CANATTACK;
status->max_hp += 4000 + 500 * pc_checkskill(sd,SO_EL_SYMPATHY);
status->max_sp += 300 + 50 * pc_checkskill(sd,SO_EL_SYMPATHY);
status->hp = status->max_hp;
status->sp = status->max_sp;
status->str += sd->base_status.str * 25 / 100;
status->agi += sd->base_status.agi * 25 / 100;
status->vit += sd->base_status.vit * 25 / 100;
status->int_ += sd->base_status.int_ * 25 / 100;
status->def += sd->base_status.dex * 25 / 100;
status->luk += sd->base_status.luk * 25 / 100;
if( !ele->mode )
status->mode = EL_MODE_PASSIVE;
else
status->mode = ele->mode;
status_calc_misc(&ed->bl, status, ed->db->lv);
status_calc_misc(&ed->bl, status, 0);
status->max_hp = ele->max_hp;
status->max_sp = ele->max_sp;
status->hp = ele->hp;
status->sp = ele->sp;
status->rhw.atk = ele->atk;
status->rhw.atk2 = ele->atk2;
status->matk_min += ele->matk;
status->def += ele->def;
status->mdef += ele->mdef;
status->flee = ele->flee;
status->hit = ele->hit;
memcpy(&ed->battle_status,status,sizeof(struct status_data));
} else {
status_calc_misc(&ed->bl, status, ed->db->lv);
status_calc_misc(&ed->bl, status, 0);
status_cpy(&ed->battle_status, status);
}
@ -3827,9 +3827,6 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(status->aspd_rate != 1000) // absolute percentage modifier
amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
#endif
//@TODO move FIGHTINGSPIRIT in fix_aspd
if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
amotion -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) / 10 * 40;
amotion = status_calc_fix_aspd(bl, sc, amotion);
status->amotion = cap_value(amotion,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
@ -4202,8 +4199,6 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
vit += sc->data[SC_GLORYWOUNDS]->val1;
if(sc->data[SC_TRUESIGHT])
vit += 5;
if(sc->data[SC_STRIPARMOR])
vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
if(sc->data[SC_MARIONETTE])
vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
if(sc->data[SC_MARIONETTE2])
@ -4219,6 +4214,9 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
if(sc->data[SC_KYOUGAKU])
vit -= sc->data[SC_KYOUGAKU]->val2;
if(sc->data[SC_STRIPARMOR])
vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
@ -4253,8 +4251,6 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
else
int_ >>= 1;
}
if(sc->data[SC_STRIPHELM])
int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
if(sc->data[SC_NEN])
int_ += sc->data[SC_NEN]->val1;
if(sc->data[SC_MARIONETTE])
@ -4263,8 +4259,6 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
if(sc->data[SC_MANDRAGORA])
int_ -= 5 + 5 * sc->data[SC_MANDRAGORA]->val1;
if(sc->data[SC__STRIPACCESSORY])
int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
if(sc->data[SC_COCKTAIL_WARG_BLOOD])
int_ += sc->data[SC_COCKTAIL_WARG_BLOOD]->val1;
if(sc->data[SC_INSPIRATION])
@ -4273,6 +4267,11 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
int_ -= sc->data[SC_STOMACHACHE]->val1;
if(sc->data[SC_KYOUGAKU])
int_ -= sc->data[SC_KYOUGAKU]->val2;
if(sc->data[SC_STRIPHELM])
int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
if(sc->data[SC__STRIPACCESSORY])
int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
@ -4318,8 +4317,6 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
if(sc->data[SC_MARIONETTE2])
dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
if(sc->data[SC__STRIPACCESSORY])
dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
if(sc->data[SC_SIROMA_ICE_TEA])
dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
if(sc->data[SC_INSPIRATION])
@ -4329,6 +4326,9 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
if(sc->data[SC_KYOUGAKU])
dex -= sc->data[SC_KYOUGAKU]->val2;
if(sc->data[SC__STRIPACCESSORY])
dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
@ -4361,20 +4361,21 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
if(sc->data[SC_MARIONETTE2])
luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
if(sc->data[SC_LAUDARAMUS])
luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
if(sc->data[SC__STRIPACCESSORY])
luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
if(sc->data[SC_PUTTI_TAILS_NOODLES])
luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
if(sc->data[SC_INSPIRATION])
luk += sc->data[SC_INSPIRATION]->val3;
if(sc->data[SC_STOMACHACHE])
luk -= sc->data[SC_STOMACHACHE]->val1;
if(sc->data[SC_BANANA_BOMB])
luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
if(sc->data[SC_KYOUGAKU])
luk -= sc->data[SC_KYOUGAKU]->val2;
if(sc->data[SC_LAUDARAMUS])
luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
if(sc->data[SC__STRIPACCESSORY])
luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
if(sc->data[SC_BANANA_BOMB])
luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
return (unsigned short)cap_value(luk,0,USHRT_MAX);
}
@ -4388,6 +4389,32 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += sc->data[SC_ATKPOTION]->val1;
if(sc->data[SC_BATKFOOD])
batk += sc->data[SC_BATKFOOD]->val1;
if(sc->data[SC_GATLINGFEVER])
batk += sc->data[SC_GATLINGFEVER]->val3;
if(sc->data[SC_MADNESSCANCEL])
batk += 100;
if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
batk += 50;
if(bl->type == BL_ELEM
&& ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
)
batk += batk / 5;
if(sc->data[SC_FULL_SWING_K])
batk += sc->data[SC_FULL_SWING_K]->val1;
if(sc->data[SC_ODINS_POWER])
batk += 70;
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
if(status_get_element(bl) == ELE_WATER) //water type
batk /= 2;
}
if(sc->data[SC_PYROCLASTIC])
batk += sc->data[SC_PYROCLASTIC]->val2;
if (sc->data[SC_ANGRIFFS_MODUS])
batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
if(sc->data[SC_INCATKRATE])
batk += batk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
@ -4407,10 +4434,6 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
// batk -= batk * 25/100;
if(sc->data[SC_FLEET])
batk += batk * sc->data[SC_FLEET]->val3/100;
if(sc->data[SC_GATLINGFEVER])
batk += sc->data[SC_GATLINGFEVER]->val3;
if(sc->data[SC_MADNESSCANCEL])
batk += 100;
if(sc->data[SC__ENERVATION])
batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_RUSHWINDMILL])
@ -4421,29 +4444,8 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100;
if(sc->data[SC_BEYONDOFWARCRY])
batk += batk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
batk += 50;
if(bl->type == BL_ELEM
&& ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
)
batk += batk / 5;
if(sc->data[SC_FULL_SWING_K])
batk += sc->data[SC_FULL_SWING_K]->val1;
if(sc->data[SC_ODINS_POWER])
batk += 70;
if( sc->data[SC_ZANGETSU] )
batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
if(status_get_element(bl) == ELE_WATER) //water type
batk /= 2;
}
if(sc->data[SC_PYROCLASTIC])
batk += sc->data[SC_PYROCLASTIC]->val2;
if (sc->data[SC_ANGRIFFS_MODUS])
batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
@ -4461,40 +4463,10 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk += sc->data[SC_DRUMBATTLE]->val2;
if(sc->data[SC_VOLCANO])
watk += sc->data[SC_VOLCANO]->val2;
if(sc->data[SC_INCATKRATE])
watk += watk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
watk += watk * sc->data[SC_PROVOKE]->val3/100;
if(sc->data[SC_CONCENTRATION])
watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
if(sc->data[SC_SKE])
watk += watk * 3;
if(sc->data[SC_NIBELUNGEN]) {
if (bl->type != BL_PC)
watk += sc->data[SC_NIBELUNGEN]->val2;
else {
#ifndef RENEWAL
TBL_PC *sd = (TBL_PC*)bl;
int index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
#endif
watk += sc->data[SC_NIBELUNGEN]->val2;
}
}
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_FLEET])
watk += watk * sc->data[SC_FLEET]->val3/100;
if(sc->data[SC_CURSE])
watk -= watk * 25/100;
if(sc->data[SC_STRIPWEAPON])
watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
if(sc->data[SC_MERC_ATKUP])
watk += sc->data[SC_MERC_ATKUP]->val2;
if(sc->data[SC_FIGHTINGSPIRIT])
watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_STRIKING])
watk += sc->data[SC_STRIKING]->val2;
if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
@ -4511,6 +4483,37 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk -= sc->data[SC_WATER_BARRIER]->val3;
if( sc->data[SC_PYROTECHNIC_OPTION] )
watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
if(sc->data[SC_NIBELUNGEN]) {
if (bl->type != BL_PC)
watk += sc->data[SC_NIBELUNGEN]->val2;
else {
#ifndef RENEWAL
TBL_PC *sd = (TBL_PC*)bl;
int index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
#endif
watk += sc->data[SC_NIBELUNGEN]->val2;
}
}
if(sc->data[SC_INCATKRATE])
watk += watk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
watk += watk * sc->data[SC_PROVOKE]->val3/100;
if(sc->data[SC_CONCENTRATION])
watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
if(sc->data[SC_SKE])
watk += watk * 3;
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_FLEET])
watk += watk * sc->data[SC_FLEET]->val3/100;
if(sc->data[SC_CURSE])
watk -= watk * 25/100;
if(sc->data[SC_STRIPWEAPON])
watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
@ -4615,15 +4618,16 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
critical += critical;
if(sc->data[SC_STRIKING])
critical += sc->data[SC_STRIKING]->val1;
if(sc->data[SC__INVISIBILITY])
critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
if(sc->data[SC__UNLUCKY])
critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
#ifdef RENEWAL
if (sc->data[SC_SPEARQUICKEN])
critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10;
#endif
if(sc->data[SC__INVISIBILITY])
critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
if(sc->data[SC__UNLUCKY])
critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
return (short)cap_value(critical,10,SHRT_MAX);
}
@ -4643,22 +4647,23 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
hit += sc->data[SC_HUMMING]->val2;
if(sc->data[SC_CONCENTRATION])
hit += sc->data[SC_CONCENTRATION]->val3;
if(sc->data[SC_INCHITRATE])
hit += hit * sc->data[SC_INCHITRATE]->val1/100;
if(sc->data[SC_BLIND])
hit -= hit * 25/100;
if(sc->data[SC_INSPIRATION])
hit += 5 * sc->data[SC_INSPIRATION]->val1;
if(sc->data[SC_ADJUSTMENT])
hit -= 30;
if(sc->data[SC_INCREASING])
hit += 20; // RockmanEXE; changed based on updated [Reddozen]
if(sc->data[SC_MERC_HITUP])
hit += sc->data[SC_MERC_HITUP]->val2;
if(sc->data[SC_INCHITRATE])
hit += hit * sc->data[SC_INCHITRATE]->val1/100;
if(sc->data[SC_BLIND])
hit -= hit * 25/100;
if(sc->data[SC__GROOMY])
hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
if(sc->data[SC_FEAR])
hit -= hit * 20 / 100;
if(sc->data[SC_INSPIRATION])
hit += 5 * sc->data[SC_INSPIRATION]->val1;
if (sc->data[SC_ASH])
hit /= 2;
@ -4686,30 +4691,45 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee += sc->data[SC_WHISTLE]->val2;
if(sc->data[SC_WINDWALK])
flee += sc->data[SC_WINDWALK]->val2;
if(sc->data[SC_INCFLEERATE])
flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
if(sc->data[SC_VIOLENTGALE])
flee += sc->data[SC_VIOLENTGALE]->val2;
if(sc->data[SC_MOON_COMFORT]) //SG skill [Komurka]
flee += sc->data[SC_MOON_COMFORT]->val2;
if(sc->data[SC_CLOSECONFINE])
flee += 10;
if (sc->data[SC_ANGRIFFS_MODUS])
flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
if (sc->data[SC_OVERED_BOOST])
flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
if(sc->data[SC_ADJUSTMENT])
flee += 30;
if(sc->data[SC_SPEED])
flee += 10 + sc->data[SC_SPEED]->val1 * 10;
if(sc->data[SC_GATLINGFEVER])
flee -= sc->data[SC_GATLINGFEVER]->val4;
if(sc->data[SC_PARTYFLEE])
flee += sc->data[SC_PARTYFLEE]->val1 * 10;
if(sc->data[SC_MERC_FLEEUP])
flee += sc->data[SC_MERC_FLEEUP]->val2;
if( sc->data[SC_HALLUCINATIONWALK] )
flee += sc->data[SC_HALLUCINATIONWALK]->val2;
if( sc->data[SC_WATER_BARRIER] )
flee -= sc->data[SC_WATER_BARRIER]->val3;
if( sc->data[SC_MARSHOFABYSS] )
flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
#ifdef RENEWAL
if( sc->data[SC_SPEARQUICKEN] )
flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
#endif
if(sc->data[SC_INCFLEERATE])
flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
flee -= flee * 50/100;
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
flee -= flee * 50/100;
if(sc->data[SC_BLIND])
flee -= flee * 25/100;
if(sc->data[SC_ADJUSTMENT])
flee += 30;
if(sc->data[SC_GATLINGFEVER])
flee -= sc->data[SC_GATLINGFEVER]->val4;
if(sc->data[SC_SPEED])
flee += 10 + sc->data[SC_SPEED]->val1 * 10;
if(sc->data[SC_PARTYFLEE])
flee += sc->data[SC_PARTYFLEE]->val1 * 10;
if(sc->data[SC_MERC_FLEEUP])
flee += sc->data[SC_MERC_FLEEUP]->val2;
if(sc->data[SC_FEAR])
flee -= flee * 20 / 100;
if(sc->data[SC_PARALYSE])
@ -4720,26 +4740,12 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
if( sc->data[SC_GLOOMYDAY] )
flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
if( sc->data[SC_HALLUCINATIONWALK] )
flee += sc->data[SC_HALLUCINATIONWALK]->val2;
if( sc->data[SC_SATURDAYNIGHTFEVER] )
flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
if( sc->data[SC_WATER_BARRIER] )
flee -= sc->data[SC_WATER_BARRIER]->val3;
if( sc->data[SC_WIND_STEP_OPTION] )
flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
if( sc->data[SC_ZEPHYR] )
flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
if( sc->data[SC_MARSHOFABYSS] )
flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
#ifdef RENEWAL
if( sc->data[SC_SPEARQUICKEN] )
flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
#endif
if (sc->data[SC_ANGRIFFS_MODUS])
flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
if (sc->data[SC_OVERED_BOOST])
flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){ //mob
if(status_get_element(bl) == ELE_WATER) //water type
flee /= 2;
@ -4788,6 +4794,14 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def += sc->data[SC_DEFENCE]->val2 ;
if(sc->data[SC_INCDEFRATE])
def += def * sc->data[SC_INCDEFRATE]->val1/100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
def += 50;
if(sc->data[SC_ODINS_POWER])
def -= 20;
if( sc->data[SC_ANGRIFFS_MODUS] )
def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
if(sc->data[SC_STONEHARDSKIN])// Final DEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
def += sc->data[SC_STONEHARDSKIN]->val1;
if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
def >>=1;
if(sc->data[SC_FREEZE])
@ -4808,8 +4822,6 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
if (sc->data[SC_FLING])
def -= def * (sc->data[SC_FLING]->val2)/100;
if(sc->data[SC_STONEHARDSKIN])// Final DEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
def += sc->data[SC_STONEHARDSKIN]->val1;
if( sc->data[SC_FREEZING] )
def -= def * 10 / 100;
if( sc->data[SC_MARSHOFABYSS] )
@ -4828,12 +4840,6 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
if( sc->data[SC_PRESTIGE] )
def += def * sc->data[SC_PRESTIGE]->val1 / 100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
def += 50;
if(sc->data[SC_ODINS_POWER])
def -= 20;
if( sc->data[SC_ANGRIFFS_MODUS] )
def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def /= 2;
@ -4857,6 +4863,10 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
return 0;
if(sc->data[SC_SUN_COMFORT])
def2 += sc->data[SC_SUN_COMFORT]->val2;
if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
if(sc->data[SC_ANGELUS])
#ifdef RENEWAL //in renewal only the VIT stat bonus is boosted by angelus
@ -4889,10 +4899,6 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
def2 -= def2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
if( sc->data[SC_ECHOSONG] )
def2 += def2 * sc->data[SC_ECHOSONG]->val2/100;
if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
if( sc->data[SC_GT_REVITALIZE] && sc->data[SC_GT_REVITALIZE]->val4)
def2 += def2 * sc->data[SC_GT_REVITALIZE]->val4 / 100;
if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
@ -4927,20 +4933,26 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_ARMORCHANGE])
mdef += sc->data[SC_ARMORCHANGE]->val3;
if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
mdef += 25*mdef/100;
if(sc->data[SC_FREEZE])
mdef += 25*mdef/100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
mdef += 50;
if(sc->data[SC_ENDURE])// It has been confirmed that eddga card grants 1 MDEF, not 0, not 10, but 1.
mdef += (sc->data[SC_ENDURE]->val4 == 0) ? sc->data[SC_ENDURE]->val1 : 1;
if(sc->data[SC_CONCENTRATION])
mdef += 1; //Skill info says it adds a fixed 1 Mdef point.
if(sc->data[SC_STONEHARDSKIN])// Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
mdef += sc->data[SC_STONEHARDSKIN]->val1;
if(sc->data[SC_WATER_BARRIER])
mdef += sc->data[SC_WATER_BARRIER]->val2;
#ifdef RENEWAL
if(sc->data[SC_ASSUMPTIO])
mdef *= 2;
#endif
if(sc->data[SC_STONEHARDSKIN])// Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
mdef += sc->data[SC_STONEHARDSKIN]->val1;
if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
mdef += 25*mdef/100;
if(sc->data[SC_FREEZE])
mdef += 25*mdef/100;
if( sc->data[SC_MARSHOFABYSS] )
mdef -= mdef * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
if(sc->data[SC_ANALYZE])
@ -4949,12 +4961,8 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val2 / 100;
if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val4)
mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100;
if(sc->data[SC_WATER_BARRIER])
mdef += sc->data[SC_WATER_BARRIER]->val2;
if (sc->data[SC_ODINS_POWER])
mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
mdef += 50;
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
}
@ -5295,20 +5303,16 @@ static short status_calc_fix_aspd(struct block_list *bl, struct status_change *s
return cap_value(aspd, 0, 2000);
if (!sc->data[SC_QUAGMIRE]) {
if (sc->data[SC_FIGHTINGSPIRIT])
aspd += sc->data[SC_FIGHTINGSPIRIT]->val3;
if ((sc->data[SC_GUST_OPTION]
|| sc->data[SC_BLAST_OPTION]
|| sc->data[SC_WILD_STORM_OPTION])
)
aspd -= 50; // ventus passive = +5 ASPD
if (sc->data[SC_OVERED_BOOST]){
aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
}
// if(sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
// aspd -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) * 4;
if (sc->data[SC_OVERED_BOOST])
aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
}
if ((sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION]
|| sc->data[SC_WILD_STORM_OPTION]))
aspd -= 50; // +5 ASPD
if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
aspd -= (bl->type==BL_PC?pc_checkskill((TBL_PC *)bl, RK_RUNEMASTERY):10) / 10 * 40;
return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway
}
@ -5485,6 +5489,12 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp += maxhp * 2;
if(sc->data[SC_MARIONETTE])
maxhp -= 1000;
if(sc->data[SC_SOLID_SKIN_OPTION])
maxhp += 2000;// Fix amount.
if(sc->data[SC_POWER_OF_GAIA])
maxhp += 3000;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
maxhp += 500;
if(sc->data[SC_MERC_HPUP])
maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
@ -5509,18 +5519,14 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp += maxhp * (2 * sc->data[SC_GT_REVITALIZE]->val1) / 100;
if(sc->data[SC_MUSTLE_M])
maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100;
if(sc->data[SC_SOLID_SKIN_OPTION])
maxhp += 2000;// Fix amount.
if(sc->data[SC_POWER_OF_GAIA])
maxhp += 3000;
if(sc->data[SC_MYSTERIOUS_POWDER])
maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
maxhp += 500;
if(sc->data[SC_PETROLOGY_OPTION])
maxhp += maxhp * sc->data[SC_PETROLOGY_OPTION]->val2 / 100;
if (sc->data[SC_ANGRIFFS_MODUS])
maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
if (sc->data[SC_GOLDENE_FERSE])
maxhp += (maxhp * sc->data[SC_GOLDENE_FERSE]->val2) / 100;
maxhp += maxhp * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
return cap_value(maxhp,1,UINT_MAX);
}
@ -8328,8 +8334,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
break;
case SC_PYROTECHNIC_OPTION:
val2 = 60; // Watk TODO: Renewal (Atk2)
val3 = 11; // % Increase damage.
val_flag |= 1|2|4;
break;
case SC_HEATER_OPTION:
@ -8343,8 +8347,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = MG_FIREBOLT;
break;
case SC_AQUAPLAY_OPTION:
val2 = 40; // Matk. TODO: Renewal (Matk1)
val3 = 33; // % Increase effects.
val2 = 40;
val_flag |= 1|2|4;
break;
case SC_COOLER_OPTION:
@ -8359,15 +8362,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val_flag |= 1|2;
break;
case SC_GUST_OPTION:
val2 = 33;
val_flag |= 1|2;
break;
case SC_WIND_STEP_OPTION:
val2 = 50; // % Increase speed and flee.
break;
case SC_BLAST_OPTION:
val2 = 33;
val3 = 4;
val2 = 20;
val3 = ELE_WIND;
val_flag |= 1|2|4;
break;
case SC_WILD_STORM_OPTION:
@ -8376,7 +8378,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_PETROLOGY_OPTION:
val2 = 5;
val3 = 33;
val3 = 50;
val_flag |= 1|2|4;
break;
case SC_CURSED_SOIL_OPTION:

View File

@ -1554,11 +1554,11 @@ enum scb_flag
};
//Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex]
#define BL_CONSUME (BL_PC|BL_HOM|BL_MER)
#define BL_CONSUME (BL_PC|BL_HOM|BL_MER|BL_ELEM)
//Define to determine who has regen
#define BL_REGEN (BL_PC|BL_HOM|BL_MER)
#define BL_REGEN (BL_PC|BL_HOM|BL_MER|BL_ELEM)
//Define to determine who will receive a clif_status_change packet for effects that require one to display correctly
#define BL_SCEFFECT (BL_PC|BL_HOM|BL_MER|BL_MOB)
#define BL_SCEFFECT (BL_PC|BL_HOM|BL_MER|BL_MOB|BL_ELEM)
//Basic damage info of a weapon
//Required because players have two of these, one in status_data

View File

@ -1250,6 +1250,23 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if (sc && sc->data[SC_WUGDASH])
casttime = -1;
break;
case EL_WIND_SLASH:
case EL_HURRICANE:
case EL_TYPOON_MIS:
case EL_STONE_HAMMER:
case EL_ROCK_CRUSHER:
case EL_STONE_RAIN:
case EL_ICE_NEEDLE:
case EL_WATER_SCREW:
case EL_TIDAL_WEAPON:
if( src->type == BL_ELEM ){
sd = BL_CAST(BL_PC, battle_get_master(src));
if( sd && sd->skillid_old == SO_EL_ACTION ){
casttime = -1;
sd->skillid_old = 0;
}
}
break;
}
// moved here to prevent Suffragium from ending if skill fails