summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/int_elemental.c34
-rw-r--r--src/common/mmo.h3
-rw-r--r--src/map/battle.c213
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/elemental.c134
-rw-r--r--src/map/elemental.h5
-rw-r--r--src/map/pc.c4
-rw-r--r--src/map/skill.c107
-rw-r--r--src/map/status.c358
-rw-r--r--src/map/status.h6
-rw-r--r--src/map/unit.c17
11 files changed, 510 insertions, 373 deletions
diff --git a/src/char/int_elemental.c b/src/char/int_elemental.c
index 7c76c4496..3c2f6672d 100644
--- a/src/char/int_elemental.c
+++ b/src/char/int_elemental.c
@@ -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);
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 5f6108b33..ad2800010 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -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;
};
diff --git a/src/map/battle.c b/src/map/battle.c
index 810b44e48..0c3c2c24d 100644
--- a/src/map/battle.c
+++ b/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;
- }
- 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;
- }
- }
+ case MG_FIREWALL:
+ skillratio -= 50;
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;
- }
+ 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_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:
diff --git a/src/map/clif.c b/src/map/clif.c
index 5ae67d77b..5c2f56d38 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -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
}
diff --git a/src/map/elemental.c b/src/map/elemental.c
index 770047138..7bcb9a294 100644
--- a/src/map/elemental.c
+++ b/src/map/elemental.c
@@ -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]);
diff --git a/src/map/elemental.h b/src/map/elemental.h
index 1f99bcba9..ce8818563 100644
--- a/src/map/elemental.h
+++ b/src/map/elemental.h
@@ -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)
diff --git a/src/map/pc.c b/src/map/pc.c
index c6c28edcc..a4796e347 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -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;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index ad7749828..1939fe948 100644
--- a/src/map/skill.c
+++ b/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) ){
diff --git a/src/map/status.c b/src/map/status.c
index 7cf76c56e..d9081ede8 100644
--- a/src/map/status.c
+++ b/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;
-
- status_calc_misc(&ed->bl, status, ed->db->lv);
+ if( !ele->mode )
+ status->mode = EL_MODE_PASSIVE;
+ else
+ status->mode = ele->mode;
+
+ 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,14 +4463,26 @@ 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_MERC_ATKUP])
+ watk += sc->data[SC_MERC_ATKUP]->val2;
+ if(sc->data[SC_FIGHTINGSPIRIT])
+ watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
+ if(sc->data[SC_STRIKING])
+ watk += sc->data[SC_STRIKING]->val2;
+ if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
+ watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
+ if(sc->data[SC_INSPIRATION])
+ watk += sc->data[SC_INSPIRATION]->val2;
+ if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
+ watk += (10 + 10 * sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
+ if( sc->data[SC_TROPIC_OPTION] )
+ watk += sc->data[SC_TROPIC_OPTION]->val2;
+ if( sc->data[SC_HEATER_OPTION] )
+ watk += sc->data[SC_HEATER_OPTION]->val2;
+ if( sc->data[SC_WATER_BARRIER] )
+ 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;
@@ -4481,6 +4495,15 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
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])
@@ -4489,28 +4512,8 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
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)
- watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
- if(sc->data[SC_INSPIRATION])
- watk += sc->data[SC_INSPIRATION]->val2;
- if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
- watk += (10 + 10 * sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
- if( sc->data[SC_TROPIC_OPTION] )
- watk += sc->data[SC_TROPIC_OPTION]->val2;
- if( sc->data[SC_HEATER_OPTION] )
- watk += sc->data[SC_HEATER_OPTION]->val2;
- if( sc->data[SC_WATER_BARRIER] )
- watk -= sc->data[SC_WATER_BARRIER]->val3;
- if( sc->data[SC_PYROTECHNIC_OPTION] )
- watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
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_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_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_GATLINGFEVER])
- flee -= sc->data[SC_GATLINGFEVER]->val4;
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_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:
diff --git a/src/map/status.h b/src/map/status.h
index 82bd7ba8a..9871128b0 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -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
diff --git a/src/map/unit.c b/src/map/unit.c
index a49385071..e3a371b74 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -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