From dad4da7241e22c5a294277510c4004724e06cb62 Mon Sep 17 00:00:00 2001 From: glighta Date: Tue, 26 Mar 2013 12:01:07 +0000 Subject: [PATCH] -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 --- db/re/skill_cast_db.txt | 28 +++++----- src/map/battle.c | 47 ++++++++-------- src/map/mob.h | 1 + src/map/skill.c | 66 ++++++++++++++--------- src/map/status.c | 116 +++++++++++++++++++++++----------------- src/map/status.h | 4 +- 6 files changed, 149 insertions(+), 113 deletions(-) diff --git a/db/re/skill_cast_db.txt b/db/re/skill_cast_db.txt index f900e9964c..d8f514d431 100644 --- a/db/re/skill_cast_db.txt +++ b/db/re/skill_cast_db.txt @@ -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 diff --git a/src/map/battle.c b/src/map/battle.c index 50b7fef3ad..aa93675cda 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -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; } diff --git a/src/map/mob.h b/src/map/mob.h index 34e5a81c0c..9db60fdef2 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -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 { diff --git a/src/map/skill.c b/src/map/skill.c index 76274083ba..655af080ac 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -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; im, 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; diff --git a/src/map/status.c b/src/map/status.c index a90c7b3a63..9ae88afce4 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -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; diff --git a/src/map/status.h b/src/map/status.h index f51521a7ac..0f6653ccda 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -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,