-upd homonS skills with Yommy leak infos, thx !

-fix summon_legion multiple spawn exploit and set summon stats.
-fix MH_LIGHT_OF_REGENE being broken since eleanor upd (typo)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17213 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
glighta 2013-03-26 12:01:07 +00:00
parent 9a1076b7e9
commit dad4da7241
6 changed files with 149 additions and 113 deletions

View File

@ -1730,45 +1730,45 @@
//-- MH_OVERED_BOOST
8023,800:700:600:500:400,0,0,30000:45000:60000:75000:90000,0,0,200:300:400:500:600
//-- MH_ERASER_CUTTER
8024,1000:1500:2000:2500:3000,0,0,0,0,0,-1
8024,1000:1500:2000:2500:3000,2000,0,0,0,0,-1
//-- MH_XENO_SLASHER
8025,1500:2500:3500:4500:5500,0,0,500,0,0,500
8025,1500:2500:3500:4500:5500,0,0,500,120000,0,500
//-- MH_SILENT_BREEZE
8026,2000,0,0,9000:12000:15000:18000:21000,0,0,1000:800:600:400:200
//-- MH_STYLE_CHANGE
8027,0,0,0,0,0,0,0
8027,0,1000,0,0,0,0,500
//-- MH_SONIC_CRAW
//8028,0,0,0,0,0,0,0
//-- MH_SILVERVEIN_RUSH
//8029,0,0,0,0,0,0,0
8029,0,0,0,5000,0,2000,0
//-- MH_MIDNIGHT_FRENZY
//8030,0,0,0,0,0,0,0
8030,0,0,0,10000,0,2000,0
//-- MH_STAHL_HORN
8031,800:600:400:200:0,0,0,5000,0,0,200:400:600:800:1000
8031,800:600:400:200:0,3000,0,5000,0,0,200:400:600:800:1000
//-- MH_GOLDENE_FERSE
8032,1000:1200:1400:1600:1800,0,0,30000:45000:60000:75000:90000,0,0,-1
//-- MH_STEINWAND
8033,1000,0,0,30000:45000:60000:75000:90000,0,0,-1
//-- MH_HEILIGE_STANGE
8034,200:400:600:800:1000,0,0,0,0,0,1800:1600:1400:1200:1000
8034,200:400:600:800:1000,5000,0,0,0,0,1800:1600:1400:1200:1000
//-- MH_ANGRIFFS_MODUS
8035,200:400:600:800:1000,0,0,30000:45000:60000:75000:90000,0,0,-1
//-- MH_TINDER_BREAKER
8036,0,0,0,5000,0,0,0
8036,1000,0,0,5000,0,0,0
//-- MH_CBC
8037,0,0,0,0,0,0,0
//-- MH_EQC
8038,0,0,0,0,0,0,0
8038,0,1000,0,0,0,0,0
//-- MH_MAGMA_FLOW
8039,2000:2500:3000:3500:4000,0,0,30000:45000:60000:75000:90000,0,0,2000:1500:1000:500:-1
8039,2000:2500:3000:3500:4000,1000,0,30000:45000:60000:75000:90000,0,0,2000:1500:1000:500:-1
//-- MH_GRANITIC_ARMOR
8040,6000:5500:5000:4500:4000,0,0,60000,0,0,1000
8040,5000:4500:4000:3500:3000,1000,0,60000,0,0,1000
//-- MH_LAVA_SLIDE
8041,6000:5500:5000:4500:4000,0,0,12000:14000:16000:18000:20000,0,0,1000
8041,5000:4500:4000:3500:3000,1000,0,12000:14000:16000:18000:20000,10000,0,1000
//-- MH_PYROCLASTIC
8042,5000:4500:4000:3500:3000,0,0,60000:90000:120000:150000:180000,0,0,1000
8042,1000:1500:2000:2500:3000,1000,0,60000:90000:120000:150000:180000,0,0,200
//-- MH_VOLCANIC_ASH
8043,5000:4500:4000:3500:3000,0,0,12000:14000:16000:18000:20000,0,0,1000
8043,4000:3500:3000:2500:2000,0,0,12000:14000:16000:18000:20000,0,0,1000
//===== Mercenary Skills ===================
//-- MS_MAGNUM

View File

@ -803,15 +803,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
struct skill_unit_group* group = skill_id2group(sc->data[SC_SAFETYWALL]->val3);
uint16 skill_id = sc->data[SC_SAFETYWALL]->val2;
if (group) {
if(skill_id == MH_STEINWAND){
if (--group->val2<=0)
skill_delunitgroup(group);
d->dmg_lv = ATK_BLOCK;
return 0;
}
/**
* in RE, SW possesses a lifetime equal to 3 times the caster's health
**/
//in RE, SW possesses a lifetime equal to group val2, (3x caster hp, or homon formula)
#ifdef RENEWAL
d->dmg_lv = ATK_BLOCK;
if ( ( group->val2 - damage) > 0 ) {
@ -1059,7 +1051,8 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
DAMAGE_SUBRATE(sc->data[SC_GRANITIC_ARMOR]->val2)
}
if(sc->data[SC_PAIN_KILLER]){
DAMAGE_SUBRATE(sc->data[SC_PAIN_KILLER]->val3)
damage -= sc->data[SC_PAIN_KILLER]->val3;
damage = max(0,damage);
}
if((sce=sc->data[SC_MAGMA_FLOW]) && (rnd()%100 <= sce->val2) ){
skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
@ -1137,9 +1130,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( sd && (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2 )
pc_addspiritball(sd,skill_get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) hom_addspiritball(hd, 10); //add a sphere
if (sc->data[SC_STYLE_CHANGE]) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl); //when being hit
if (hd && (rnd()%100<(status_get_lv(bl)/2)) ) hom_addspiritball(hd, 10); //add a sphere
}
if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
@ -1200,9 +1193,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
sc_start(src,bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1));
if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
status_change_spread(src, bl);
if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
TBL_HOM *hd = BL_CAST(BL_HOM,src);
if (hd) hom_addspiritball(hd, 10);
if (sc->data[SC_STYLE_CHANGE]) {
TBL_HOM *hd = BL_CAST(BL_HOM,src); //when attacking
if (hd && (rnd()%100<(20+status_get_lv(bl)/5)) ) hom_addspiritball(hd, 10);
}
}
@ -2974,23 +2967,32 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
skillratio += 600 + 100 * skill_lv;
break;
case MH_STAHL_HORN:
skillratio += 400 + 100 * skill_lv;
skillratio += 400 + 100 * skill_lv * status_get_lv(src);
skillratio = skillratio/100; //@TODO uv1 factor need to be confirmed
break;
case MH_LAVA_SLIDE:
skillratio += -100 + 70 * skill_lv;
break;
case MH_SONIC_CRAW:
skillratio += -100 + 40 * skill_lv;
skillratio += -100 + 40 * skill_lv * status_get_lv(src);
skillratio = skillratio/100; //@TODO uv1 factor need to be confirmed
break;
case MH_SILVERVEIN_RUSH:
skillratio += -100 + 150 * skill_lv;
skillratio += -100 + (150 * skill_lv * status_get_lv(src)) / 100;
break;
case MH_MIDNIGHT_FRENZY:
skillratio += -100 + 300 * skill_lv;
skillratio += -100 + (300 * skill_lv * status_get_lv(src)) / 150;
break;
case MH_TINDER_BREAKER:
skillratio += -100 + (100 * skill_lv + status_get_str(src));
skillratio = (skillratio * status_get_lv(src)) / 120;
break;
case MH_CBC:
skillratio += 300 * skill_lv + 4 * status_get_lv(src);
break;
case MH_MAGMA_FLOW:
skillratio += -100 + 100 * skill_lv;
skillratio += -100 + 100 * skill_lv + 3 * status_get_lv(src);
skillratio = (skillratio * status_get_lv(src)) / 120;
break;
}
#ifdef RENEWAL
@ -4111,9 +4113,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
case MH_HEILIGE_STANGE:
skillratio += 400 + 250 * skill_lv;
skillratio = (skillratio * status_get_lv(src))/150;
break;
case MH_POISON_MIST:
skillratio += 100 * skill_lv;
skillratio += -100 + 40 * skill_lv * status_get_lv(src) / 100;
break;
}

View File

@ -135,6 +135,7 @@ struct mob_data {
//2: Alchemist Marine Sphere
//3: Alchemist Summon Flora
//4: Summon Zanzou
//5: Summon Legion
unsigned int clone : 1;/* is clone? 1:0 */
} special_state; //Special mob information that does not needs to be zero'ed on mob respawn.
struct {

View File

@ -122,6 +122,7 @@ int skill_block_check(struct block_list *bl, enum sc_type type, uint16 skill_id)
static int skill_check_unit_range (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
static int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
static int skill_destroy_trap( struct block_list *bl, va_list ap );
static int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap);
//Since only mob-casted splash skills can hit ice-walls
static inline int splash_target(struct block_list* bl)
{
@ -664,7 +665,7 @@ int skillnotok_hom(uint16 skill_id, struct homun_data *hd)
if(hd->homunculus.hunger <= 1) //if we starving
return 1;
break;
case MH_GOLDENE_FERSE: //can be used with angriff
case MH_GOLDENE_FERSE: //cant be used with angriff
if(hd->sc.data[SC_ANGRIFFS_MODUS])
return 1;
break;
@ -933,7 +934,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
(2000 - 4*sstatus->agi - 2*sstatus->dex));
}
}
if(sc && sc->data[SC_PYROCLASTIC] && (rnd() % 1000 <= sstatus->luk * 10 / 3 + 1) )
if(sc && sc->data[SC_PYROCLASTIC] && ((rnd()%100)<=sc->data[SC_PYROCLASTIC]->val3) )
skill_castend_pos2(src, bl->x, bl->y, BS_HAMMERFALL,sc->data[SC_PYROCLASTIC]->val1, tick, 0);
}
@ -1489,8 +1490,14 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
case MH_SILVERVEIN_RUSH:
sc_start4(src,bl,SC_STUN,20 + (5*skill_lv),skill_lv,src->id,0,0,skill_get_time(skill_id,skill_lv));
break;
case MH_MIDNIGHT_FRENZY:
sc_start4(src,bl,SC_FEAR,20 + (4*skill_lv),skill_lv,src->id,0,0,skill_get_time(skill_id,skill_lv));
case MH_MIDNIGHT_FRENZY: {
TBL_HOM *hd = BL_CAST(BL_HOM,src);
int spiritball = (hd?hd->homunculus.spiritball:1);
sc_start4(src,bl,SC_FEAR,spiritball*(10+2*skill_lv),skill_lv,src->id,0,0,skill_get_time(skill_id,skill_lv));
break;
}
case MH_XENO_SLASHER:
sc_start4(src,bl,SC_BLEEDING,skill_lv,skill_lv,src->id,0,0,skill_get_time2(skill_id,skill_lv)); //@TODO need real duration
break;
}
@ -4700,10 +4707,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
//recursive homon skill
case MH_MAGMA_FLOW:
case MH_XENO_SLASHER:
case MH_HEILIGE_STANGE:
if(flag & 1)
if(flag & 1){
if((skill_id == MH_MAGMA_FLOW) && ((rnd()%100)>(3*skill_lv)) ) break;//chance to not trigger atk for magma
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
}
else {
map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
}
@ -4721,7 +4729,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case MH_EQC: {
TBL_HOM *hd = BL_CAST(BL_HOM,src);
int8 k=0;
int duration;
int duration=0;
struct status_change_entry *sce;
struct block_list *tbl = NULL; //target
@ -4759,17 +4767,15 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
clif_skill_poseffect(src,skill_id,skill_lv,bl->x,bl->y,tick);
#endif
}
case MH_CBC:
case MH_EQC:
duration = (status_get_str(src)*2 - status_get_str(bl))/10;//custom need real formula
duration = max(skill_lv,(status_get_str(src)/7 - status_get_str(bl)/10))*1000; //Yommy formula
hom_delspiritball(hd,skill_id==MH_EQC?2:1,0); //only EQC consume 2 in grp 2
if(skill_id==MH_TINDER_BREAKER)
sc_start2(src,src,status_skill2sc(skill_id),100,skill_lv,bl->id,duration);
else
sc_start(src,bl,status_skill2sc(skill_id),100,skill_lv,duration);
skill_attack(skill_get_type(skill_id),src,src,tbl,skill_id,skill_lv,tick,flag);
//TODO add bonus for dmg SP ? on battle
break;
}
break;
@ -9136,7 +9142,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target
status_change_start(src,bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill_get_time(skill_id, skill_lv),1|2|8);
}
heal = status_get_matk_min(src)*4;
heal = status_get_sp(src) + status_get_lv(src); //cur_sp+blvl @TODO need real value
status_heal(bl, heal, 0, 7);
//now inflict silence on everyone
@ -9176,12 +9182,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
case MH_LIGHT_OF_REGENE:
case MH_LIGHT_OF_REGENE: //self
sc_start2(src, src, type, 100, skill_lv, hd->homunculus.level, skill_get_time(skill_id, skill_lv));
if(hd){
hd->homunculus.intimacy = 251; //change to neutral (can't be cast if < 750)
if(sd) clif_send_homdata(sd, SP_INTIMATE, hd->homunculus.intimacy); //refresh intimacy info
skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
}
//don't break need to start status and start block timer
break;
case MH_STYLE_CHANGE: {
struct status_change_entry *sce;
if(hd && (sce=hd->sc.data[SC_STYLE_CHANGE])){ //in preparation for other bl usage
@ -9208,13 +9216,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
int summons[5] = {2158, 2159, 2159, 2160, 2160};
int qty[5] = {3 , 3 , 4 , 4 , 5};
struct mob_data *sum_md;
int i;
int i,c=0;
int maxcount = qty[skill_lv-1];
i = map_foreachinmap(skill_check_condition_mob_master_sub ,hd->bl.m, BL_MOB, hd->bl.id, summons[skill_lv-1], skill_id, &c);
if(c >= maxcount) return 0; //max qty already spawned
for(i=0; i<qty[skill_lv - 1]; i++){ //easy way
sum_md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), summons[skill_lv - 1], "", SZ_SMALL, AI_ATTACK);
if (sum_md) {
sum_md->master_id = src->id;
sum_md->special_state.ai = 1;
sum_md->special_state.ai = 5;
if (sum_md->deletetimer != INVALID_TIMER)
delete_timer(sum_md->deletetimer, mob_timer_delete);
sum_md->deletetimer = add_timer(gettick() + skill_get_time(skill_id, skill_lv), mob_timer_delete, sum_md->bl.id, 0);
@ -10759,14 +10771,12 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
switch( skill_id ) {
case MH_STEINWAND:
val2 = 4 + skill_lv; //nb of attack blocked
break;
case MG_SAFETYWALL:
#ifdef RENEWAL
/**
* According to data provided in RE, SW life is equal to 3 times caster's health
**/
val2 = status_get_max_hp(src) * 3;
if(skill_id == MH_STEINWAND)
val2 = 300 * skill_lv + 65 * ( status->int_ + status_get_lv(src) ) + status->max_sp; //nb hp
else
val2 = status_get_max_hp(src) * 3;
#else
val2 = skill_lv+1;
#endif
@ -12141,7 +12151,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
break;
case UNT_POISON_MIST:
skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
status_change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 2|8);
status_change_start(ss, bl, SC_BLIND, (10 + 10 * sg->skill_lv)*100, sg->skill_lv, sg->skill_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 2|8);
break;
}
@ -12544,11 +12554,14 @@ int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, short*
}
/*==========================================
*
* Sub function to count how many spawned mob is around
* return :
* x : numbers of mob of class with special ai
*------------------------------------------*/
static int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap)
{
int *c,src_id,mob_class,skill;
uint16 ai;
struct mob_data *md;
md=(struct mob_data*)bl;
@ -12557,7 +12570,8 @@ static int skill_check_condition_mob_master_sub (struct block_list *bl, va_list
skill=va_arg(ap,int);
c=va_arg(ap,int *);
if( md->master_id != src_id || md->special_state.ai != (unsigned)(skill == AM_SPHEREMINE?2:skill == KO_ZANZOU?4:3) )
ai = (unsigned)(skill == AM_SPHEREMINE?2:skill == KO_ZANZOU?4:skill == MH_SUMMON_LEGION?5:3);
if( md->master_id != src_id || md->special_state.ai != ai)
return 0; //Non alchemist summoned mobs have nothing to do here.
if(md->class_==mob_class)
@ -13509,10 +13523,10 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
if( c >= skill_get_maxcount(skill_id,skill_lv) || c != i)
{
clif_skill_fail(sd , skill_id, USESKILL_FAIL_LEVEL, 0);
return 0;
}
return 0;
}
break;
}
}
status = &sd->battle_status;

View File

@ -494,9 +494,8 @@ void initChangeTables(void) {
// Homunculus S
add_sc(MH_STAHL_HORN, SC_STUN);
set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SI_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE, SCB_ASPD|SCB_MAXHP);
set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE, SCB_ASPD|SCB_FLEE);
add_sc( MH_STEINWAND, SC_SAFETYWALL );
add_sc(MH_ERASER_CUTTER, SC_ERASER_CUTTER);
set_sc(MH_OVERED_BOOST, SC_OVERED_BOOST, SI_BLANK, SCB_FLEE|SCB_ASPD);
add_sc(MH_LIGHT_OF_REGENE, SC_LIGHT_OF_REGENE);
set_sc(MH_VOLCANIC_ASH, SC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
@ -511,7 +510,7 @@ void initChangeTables(void) {
add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
set_sc(MH_TINDER_BREAKER, SC_TINDER_BREAKER, SI_TINDER_BREAKER, SCB_FLEE);
set_sc(MH_CBC, SC_CBC, SI_CBC, SCB_FLEE);
set_sc(MH_EQC, SC_EQC, SI_EQC, SCB_DEF2|SCB_BATK);
set_sc(MH_EQC, SC_EQC, SI_EQC, SCB_DEF2|SCB_BATK|SCB_MAXHP);
add_sc( MER_CRASH , SC_STUN );
set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
@ -1320,7 +1319,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
TBL_HOM *hd = sd->hd;
if(hd && hd->sc.data[SC_LIGHT_OF_REGENE]){
clif_skillcasting(&hd->bl, hd->bl.id, target->id, 0,0, MH_LIGHT_OF_REGENE, skill_get_ele(MH_LIGHT_OF_REGENE, 1), 10); //just to display usage
clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,10*hd->sc.data[SC_LIGHT_OF_REGENE]->val1,0));
clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,hd->sc.data[SC_LIGHT_OF_REGENE]->val2,0));
status_change_end(&sd->hd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER);
return hp + sp;
}
@ -2040,13 +2039,26 @@ int status_calc_mob_(struct mob_data* md, bool first)
md->special_state.ai = 0;
if (ud)
{ // different levels of HP according to skill level
if (ud->skill_id == AM_SPHEREMINE) {
status->max_hp = 2000 + 400*ud->skill_lv;
} else if(ud->skill_id == KO_ZANZOU){
status->max_hp = 3000 + 3000 * ud->skill_lv;
} else { //AM_CANNIBALIZE
status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
switch(ud->skill_id){
case AM_SPHEREMINE:
status->max_hp = 2000 + 400*ud->skill_lv;
break;
case KO_ZANZOU:
status->max_hp = 3000 + 3000 * ud->skill_lv;
break;
case AM_CANNIBALIZE:
status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
break;
case MH_SUMMON_LEGION:{
int homblvl = status_get_lv(mbl);
status->max_hp = 10 * (100 * (ud->skill_lv + 2) + homblvl);
status->batk = 100 * (ud->skill_lv+5) / 2;
status->def = 10 * (100 * (ud->skill_lv+2) + homblvl);
// status->aspd_rate = 10 * (2 * (20 - ud->skill_lv) - homblvl/10);
// status->aspd_rate = max(100,status->aspd_rate);
break;
}
}
status->hp = status->max_hp;
}
@ -4525,10 +4537,8 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
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_ASH])
batk -= batk * sc->data[SC_ASH]->val4 / 100;
if(sc->data[SC_PYROCLASTIC])
batk += sc->data[SC_PYROCLASTIC]->val2;
if (sc->data[SC_ANGRIFFS_MODUS])
@ -4786,7 +4796,7 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
if(sc->data[SC_FEAR])
hit -= hit * 20 / 100;
if (sc->data[SC_ASH])
hit /= 2;
hit -= (hit * sc->data[SC_ASH]->val2) / 100;
return (short)cap_value(hit,1,SHRT_MAX);
}
@ -4867,10 +4877,10 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
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_ASH] && (bl->type==BL_MOB)){ //mob
if(status_get_element(bl) == ELE_WATER) //water type
flee /= 2;
}
if(sc->data[SC_ASH])
flee -= flee * sc->data[SC_ASH]->val4 / 100;
if (sc->data[SC_GOLDENE_FERSE])
flee += flee * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
return (short)cap_value(flee,1,SHRT_MAX);
}
@ -4957,10 +4967,10 @@ 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_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def /= 2;
}
if(sc->data[SC_ASH])
def -= def * sc->data[SC_ASH]->val3/100;
if( sc->data[SC_OVERED_BOOST] )
def -= def * sc->data[SC_OVERED_BOOST]->val3 / 100;
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
}
@ -5012,10 +5022,8 @@ 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_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def2 /= 2;
}
if(sc->data[SC_ASH])
def2 -= def2 * sc->data[SC_ASH]->val3/100;
if (sc->data[SC_PARALYSIS])
def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
if(sc->data[SC_EQC])
@ -5628,8 +5636,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
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;
if(sc->data[SC_EQC])
maxhp -= maxhp * sc->data[SC_EQC]->val4 / 100;
return (unsigned int)cap_value(maxhp,1,UINT_MAX);
}
@ -6209,7 +6217,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
struct map_session_data *sd;
nullpo_ret(bl);
nullpo_retr(tick?tick:1, src); //If no source, it can't be resisted (NPC given)
if(src==NULL) return tick?tick:1;//If no source, it can't be resisted (NPC given)
//Status that are blocked by Golden Thief Bug card or Wand of Hermod
if (status_isimmune(bl))
@ -8681,31 +8689,37 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
tick_time = 1000;
break;
case SC_GOLDENE_FERSE:
val2 = 10 + 10*val1; //max hp bonus
val2 = 10 + 10*val1; //flee bonus
val3 = 6 + 4 * val1; // Aspd Bonus
val4 = 2 + 2 * val1; // Chance of holy attack
break;
case SC_OVERED_BOOST:
val2 = 300 + 40*val1; //flee bonus
val3 = 179 + 2*val1; //aspd bonus
val4 = 50; //def reduc %
break;
case SC_GRANITIC_ARMOR:
val2 = 2*val1; //dmg reduction
val3 = 6*val1; //dmg on status end
val2 = 2*val1; //dmg hp reduction
val3 = (6*status_get_max_hp(src))/100; //dmg hp on status end
val4 = 5 * val1; //unknow formula
break;
case SC_MAGMA_FLOW:
val2 = 3*val1; //activation chance
break;
case SC_PYROCLASTIC:
val2 += 10*val1; //atk bonus
val2 += 10*val1*status_get_lv(src); //atk bonus
val3 = 2*val1;//Chance To AutoCast Hammer Fall %
break;
case SC_PARALYSIS: //[Lighta] need real info
val2 = 2*val1; //def reduction
val3 = 500*val1; //varcast augmentation
break;
case SC_PAIN_KILLER: //[Lighta] need real info
val2 = 2*val1; //aspd reduction %
val3 = 2*val1; //dmg reduction %
case SC_LIGHT_OF_REGENE: //Yommy leak need confirm
val2 = 20 * val1; //hp reco on death %
break;
case SC_PAIN_KILLER: //Yommy leak need confirm
val2 = 10 * val1; //aspd reduction %
val3 = (( 200 * val1 ) * status_get_lv(src)) / 150; //dmg reduction linear
if(sc->data[SC_PARALYSIS])
sc_start(src,bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
break;
@ -8713,21 +8727,23 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
tick = -1;
break;
case SC_CBC:
val2 = 10; //hp % dmg [not sure]
val3 = 10; //sp % dmg [not sure]
tick = max(tick,5000); //min 5s (test)
val3 = 10; //drain sp % dmg
val4 = tick/1000; //dmg each sec
tick = 1000;
break;
case SC_EQC:
val2 = 25; //def % reduc [not sure]
val3 = 25; //atk % reduc [not sure]
tick = max(tick,5000); //min 5s (test)
val2 = 5 * val1; //def % reduc
val3 = 5 * val1; //atk % reduc
val4 = 2 * val1; //maxhp % reduc
break;
case SC_TINDER_BREAKER:
//val1 = skilllv
//val2 = src->id
tick = max(tick,5000); //min 5s (test)
case SC_ASH:
val2 = 50; //hit % reduc
val3 = 0;//def % reduc
val4 = 0;//atk flee & reduc
if(status_get_race(bl) == RC_PLANT) //plant type
val3 = 50;
if(status_get_element(bl) == ELE_WATER) // defense water type
val4 = 50;
break;
default:
if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
@ -9090,6 +9106,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
sc_start2(src, map_id2bl(val2),SC_CLOSECONFINE2,100,val1,bl->id,tick);
break;
case SC_EQC:
sc_start2(src, bl,SC_STUN,100,val1,bl->id,(1000*status_get_lv(src))/50+500*val1);
status_change_end(bl,SC_TINDER_BREAKER,INVALID_TIMER);
break;
}
@ -10749,8 +10766,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_CBC:
if(--(sce->val4) >= 0) { //drain hp/sp
int hp = (status->max_hp * sce->val2) / 100;
int hp=0;
int sp = (status->max_sp * sce->val3) / 100;
if(bl->type == BL_MOB) hp = sp*10;
if( !status_charge(bl,hp,sp) ) break;
sc_timer_next(1000+tick,status_change_timer,bl->id, data);
return 0;

View File

@ -634,12 +634,12 @@ typedef enum sc_type {
//homon S
SC_STYLE_CHANGE,
SC_TINDER_BREAKER,
SC_TINDER_BREAKER, //@TODO rewritte me plz
SC_TINDER_BREAKER2, //for rewritte and other icone
SC_CBC,
SC_EQC,
SC_GOLDENE_FERSE,
SC_ANGRIFFS_MODUS,
SC_ERASER_CUTTER,
SC_OVERED_BOOST,
SC_LIGHT_OF_REGENE,
SC_ASH,