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:
parent
872c6bf810
commit
aa7031075c
47
db/const.txt
47
db/const.txt
@ -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
|
||||
|
@ -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 Elemental’s STATs are affected by the Caster’s 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
9
sql-files/upgrades/upgrade_svn17014.sql
Normal file
9
sql-files/upgrades/upgrade_svn17014.sql
Normal 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`;
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
215
src/map/battle.c
215
src/map/battle.c
@ -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 Caster’s 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 ) + ( Caster’s INT x Varetyr Spear Skill level )} x Caster’s 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:
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
//[(Caster’s Max HP/ 3 ) + (Caster’s INT x 10 )+ (Caster’s 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;
|
||||
//Caster’s Max SP /4
|
||||
ele.sp = ele.max_sp = sd->battle_status.max_sp/4 * 5 * pc_checkskill(sd,SO_EL_SYMPATHY) / 100;
|
||||
//Caster’s [ 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);
|
||||
//Caster’s [ Max SP / (18 / Elemental Summon Skill Level) ]
|
||||
ele.atk2 = sd->battle_status.max_sp / 18 + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
|
||||
//Caster’s HIT + (Caster’s Base Level )
|
||||
ele.hit = sd->battle_status.hit + sd->status.base_level;
|
||||
//[Elemental Summon Skill Level x (Caster’s INT / 2 + Caster’s DEX / 4)]
|
||||
ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4) + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
|
||||
//150 + [Caster’s DEX / 10] + [Elemental Summon Skill Level x 3 ]
|
||||
ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3;
|
||||
//Caster’s DEF + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
|
||||
ele.def = sd->battle_status.def + sd->status.base_level / (5-i);
|
||||
//Caster’s MDEF + (Caster’s INT / (5 - Elemental Summon Skill Level)
|
||||
ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i);
|
||||
//Caster’s FLEE + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
|
||||
ele.flee = sd->status.base_level / (5-i);
|
||||
//Caster’s HIT + (Caster’s 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]);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
107
src/map/skill.c
107
src/map/skill.c
@ -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) ){
|
||||
|
364
src/map/status.c
364
src/map/status.c
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user