diff options
author | malufett <malufett.eat.my.binaries@gmail.com> | 2014-05-08 21:41:21 +0800 |
---|---|---|
committer | malufett <malufett.eat.my.binaries@gmail.com> | 2014-05-08 21:41:21 +0800 |
commit | f4f4b3310d83c10f72af525d86c58053411df5da (patch) | |
tree | 453c3b486786e9a8a484ff64b57968c225f5fcd0 | |
parent | db42e06f31fe98a28dce8cc05c480b897ab8cb99 (diff) | |
download | hercules-f4f4b3310d83c10f72af525d86c58053411df5da.tar.gz hercules-f4f4b3310d83c10f72af525d86c58053411df5da.tar.bz2 hercules-f4f4b3310d83c10f72af525d86c58053411df5da.tar.xz hercules-f4f4b3310d83c10f72af525d86c58053411df5da.zip |
Homonculus S Update
-Updated and fixed Eira skills to official behavior.
Fixed Bug#8168
-http://hercules.ws/board/tracker/issue-8168-crush-strike/?gopid=22703#entry22703
Signed-off-by: malufett <malufett.eat.my.binaries@gmail.com>
-rw-r--r-- | db/pre-re/skill_cast_db.txt | 16 | ||||
-rw-r--r-- | db/pre-re/skill_db.txt | 6 | ||||
-rw-r--r-- | db/re/skill_cast_db.txt | 8 | ||||
-rw-r--r-- | db/re/skill_db.txt | 6 | ||||
-rw-r--r-- | src/map/battle.c | 41 | ||||
-rw-r--r-- | src/map/clif.c | 19 | ||||
-rw-r--r-- | src/map/homunculus.c | 19 | ||||
-rw-r--r-- | src/map/homunculus.h | 1 | ||||
-rw-r--r-- | src/map/pc.c | 2 | ||||
-rw-r--r-- | src/map/skill.c | 92 | ||||
-rw-r--r-- | src/map/status.c | 88 |
11 files changed, 161 insertions, 137 deletions
diff --git a/db/pre-re/skill_cast_db.txt b/db/pre-re/skill_cast_db.txt index 0e2ad308e..2ee662070 100644 --- a/db/pre-re/skill_cast_db.txt +++ b/db/pre-re/skill_cast_db.txt @@ -1759,16 +1759,16 @@ 8020,500:700:900:1100:1300,0,0,12000:14000:16000:18000:20000,4000:6000:8000:10000:12000,0 //-- MH_PAIN_KILLER 8021,1000:1200:1400:1600:1800,0,0,20000:30000:40000:50000:60000,0,0 -//-- MH_LIGHT_OF_REGENE +//-- MH_LIGHT_OF_REGENE 8022,1600:1400:1200:1000:800,0,0,360000:420000:480000:540000:600000,0,0 -//-- MH_OVERED_BOOST +//-- MH_OVERED_BOOST 8023,800:700:600:500:400,0,0,30000:45000:60000:75000:90000,0,0 -//-- MH_ERASER_CUTTER -8024,1000:1500:2000:2500:3000,0,0,0,0,0 -//-- MH_XENO_SLASHER -8025,1500:2500:3500:4500:5500,0,0,500,0,0 -//-- MH_SILENT_BREEZE -8026,2000,0,0,9000:12000:15000:18000:21000,0,0 +//-- MH_ERASER_CUTTER +8024,1000:1500:2000:2500:3000,2000,0,0,0,0 +//-- MH_XENO_SLASHER +8025,1500:2500:3500:4500:5500,5000,0,500,0,0 +//-- MH_SILENT_BREEZE +8026,1000:1200:1400:1600:1800,0,0,9000:12000:15000:18000:21000,0,0 //-- MH_STYLE_CHANGE //8027,0,0,0,0,0,0,0 //-- MH_SONIC_CRAW diff --git a/db/pre-re/skill_db.txt b/db/pre-re/skill_db.txt index d5e5fc513..ffeadd5e9 100644 --- a/db/pre-re/skill_db.txt +++ b/db/pre-re/skill_db.txt @@ -1136,9 +1136,9 @@ 8021,1,6,1,0,0x1,0,5,1,no,0,0,0,none,0, MH_PAIN_KILLER,Pain Killer 8022,0,6,4,0,0,0x1,5,1,no,0,0,0,none,0, MH_LIGHT_OF_REGENE,Light of Regene 8023,0,6,4,0,0,0x1,5,1,no,0,0,0,none,0, MH_OVERED_BOOST,Overed Boost -8024,7,6,1,4:0:4:0:4,0,0,5,1,no,0,0,0,magic,0, MH_ERASER_CUTTER,Eraser Cutter -8025,7,6,2,4:0:4:0:4,0,0,5,1,no,0,0,0,magic,0, MH_XENO_SLASHER,Xeno Slasher -8026,5:5:7:7:9,6,16,0,0x1,0,5,1,no,0,0,0,magic,0, MH_SILENT_BREEZE,Silent Breeze +8024,7,8,1,4:0:4:0:4,0,0,5,-6,yes,0,0,0,magic,0, MH_ERASER_CUTTER,Eraser Cutter +8025,7,8,2,4:0:4:0:4,0x2,2:2:3:3:4,5,-6,no,0,0,0,magic,0, MH_XENO_SLASHER,Xeno Slasher +8026,5:5:7:7:9,6,1,0,0x1,0,5,1,no,0,0,0,magic,0, MH_SILENT_BREEZE,Silent Breeze 8027,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, MH_STYLE_CHANGE,Style Change 8028,1,8,1,0,0,0,5,1,no,0,0,0,weapon,0, MH_SONIC_CRAW,Sonic Claw 8029,1,6,4,0,0,0,5,1,no,0,0x200,0,weapon,0, MH_SILVERVEIN_RUSH,Silver Bain Rush diff --git a/db/re/skill_cast_db.txt b/db/re/skill_cast_db.txt index ee394f6a9..c19ecb20f 100644 --- a/db/re/skill_cast_db.txt +++ b/db/re/skill_cast_db.txt @@ -1761,15 +1761,15 @@ //-- MH_PAIN_KILLER 8021,1000:1200:1400:1600:1800,0,0,20000:30000:40000:50000:60000,0,0,1000:800:600:400:200 //-- MH_LIGHT_OF_REGENE -8022,1600:1400:1200:1000:800,0,0,360000:420000:480000:540000:600000,0,0,1600:1400:1200:1000:800 +8022,0,0,0,360000:420000:480000:540000:600000,0,0,1600:1400:1200:1000:800 //-- 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,5000,0,500,0,0,500 //-- MH_SILENT_BREEZE -8026,2000,0,0,9000:12000:15000:18000:21000,0,0,1000:800:600:400:200 +8026,1000:1200:1400:1600:1800,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 //-- MH_SONIC_CRAW diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index 152912337..0d498fc17 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -1149,9 +1149,9 @@ 8021,1,6,1,0,0x1,0,5,1,no,0,0,0,none,0, MH_PAIN_KILLER,Pain Killer 8022,0,6,4,0,0,0x1,5,1,no,0,0,0,none,0, MH_LIGHT_OF_REGENE,Light of Regene 8023,0,6,4,0,0,0x1,5,1,no,0,0,0,none,0, MH_OVERED_BOOST,Overed Boost -8024,7,6,1,4:0:4:0:4,0,0,5,1,no,0,0,0,magic,0, MH_ERASER_CUTTER,Eraser Cutter -8025,7,6,2,4:0:4:0:4,0,0,5,1,no,0,0,0,magic,0, MH_XENO_SLASHER,Xeno Slasher -8026,5:5:7:7:9,6,16,0,0x1,0,5,1,no,0,0,0,magic,0, MH_SILENT_BREEZE,Silent Breeze +8024,7,8,1,4:0:4:0:4,0,0,5,-6,yes,0,0,0,magic,0, MH_ERASER_CUTTER,Eraser Cutter +8025,7,8,2,4:0:4:0:4,0x2,2:2:3:3:4,5,-6,no,0,0,0,magic,0, MH_XENO_SLASHER,Xeno Slasher +8026,5:5:7:7:9,6,1,0,0x1,0,5,1,no,0,0,0,magic,0, MH_SILENT_BREEZE,Silent Breeze 8027,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, MH_STYLE_CHANGE,Style Change 8028,1,8,1,0,0,0,5,1,no,0,0,0,weapon,0, MH_SONIC_CRAW,Sonic Claw 8029,1,6,4,0,0,0,5,1,no,0,0x200,0,weapon,0, MH_SILVERVEIN_RUSH,Silver Bain Rush diff --git a/src/map/battle.c b/src/map/battle.c index 4c85e2c72..9089b7102 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1721,9 +1721,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 1100; break; case MH_ERASER_CUTTER: - if(skill_lv%2) skillratio += 400; //600:800:1000 - else skillratio += 700; //1000:1200 - skillratio += 100 * skill_lv; + skillratio += 400 + 100 * skill_lv + (skill_lv%2 > 0 ? 0 : 300); break; case MH_XENO_SLASHER: if(skill_lv%2) skillratio += 350 + 50 * skill_lv; //500:600:700 @@ -2108,15 +2106,6 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block if( st->rhw.ele == ELE_FIRE ) skillratio += 100 * skill_lv; break; - case RK_CRUSHSTRIKE: - if( sd ) - {//ATK [{Weapon Level * (Weapon Upgrade Level + 6) * 100} + (Weapon ATK) + (Weapon Weight)]% - short index = sd->equip_index[EQI_HAND_R]; - if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON ) - skillratio += -100 + sd->inventory_data[index]->weight/10 + st->rhw.atk + - 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6); - } - break; case RK_STORMBLAST: skillratio = ((sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + status_get_int(src) / 8) * 100; break; @@ -2546,7 +2535,18 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += sc->data[SC_LKCONCENTRATION]->val2; if( sd && sd->status.weapon == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0 ) skillratio += skillratio * (10 + 2 * i) / 100; -#endif +#endif + if( sc && sc->data[SC_CRUSHSTRIKE] ){ + if( sd ) + {//ATK [{Weapon Level * (Weapon Upgrade Level + 6) * 100} + (Weapon ATK) + (Weapon Weight)]% + short index = sd->equip_index[EQI_HAND_R]; + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON ) + skillratio += -100 + sd->inventory_data[index]->weight/10 + st->rhw.atk + + 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6); + } + status_change_end(src, SC_CRUSHSTRIKE, INVALID_TIMER); + skill->break_equip(src,EQP_WEAPON,2000,BCT_SELF); // 20% chance to destroy the weapon. + } } } if( skillratio < 1 ) @@ -4304,6 +4304,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list cri <<= 1; } switch (skill_id) { + case 0: + if(!(sc && sc->data[SC_AUTOCOUNTER])) + break; + status_change_end(src, SC_AUTOCOUNTER, INVALID_TIMER); case KN_AUTOCOUNTER: if(battle_config.auto_counter_type && (battle_config.auto_counter_type&src->type)) @@ -4653,6 +4657,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list ATK_ADDRATE(sc->data[SC_EXEEDBREAK]->val1); status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER); } + + #ifdef RENEWAL if( sd && skill_id == NJ_KUNAI ){ flag.tdef = 1; @@ -5647,7 +5653,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t return ATK_BLOCK; } } - if( tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) ) { uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1; @@ -5711,13 +5716,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t skill->get_time(MO_CALLSPIRITS, tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1), tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1); } - if( sc && sc->data[SC_CRUSHSTRIKE] ){ - uint16 skill_lv = sc->data[SC_CRUSHSTRIKE]->val1; - status_change_end(src, SC_CRUSHSTRIKE, INVALID_TIMER); - if( skill->attack(BF_WEAPON,src,src,target,RK_CRUSHSTRIKE,skill_lv,tick,0) ) - return ATK_DEF; - return ATK_MISS; - } + if( tsc && tsc->data[SC_MTF_MLEATKED] && rnd()%100 < 20 ) clif->skill_nodamage(target, target, SM_ENDURE, 5, sc_start(target,target, SC_ENDURE, 100, 5, skill->get_time(SM_ENDURE, 5))); diff --git a/src/map/clif.c b/src/map/clif.c index d3c4dd7f1..062a437a2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10109,7 +10109,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, if (sd->sc.count && (sd->sc.data[SC_TRICKDEAD] || - sd->sc.data[SC_AUTOCOUNTER] || + (sd->sc.data[SC_AUTOCOUNTER] && action_type != 0x07) || sd->sc.data[SC_BLADESTOP] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__MANHOLE] || @@ -14609,18 +14609,27 @@ void clif_parse_HomMenu(int fd, struct map_session_data *sd) { //[orn] /// 0292 void clif_parse_AutoRevive(int fd, struct map_session_data *sd) { int item_position = pc->search_inventory(sd, ITEMID_TOKEN_OF_SIEGFRIED); + int hpsp = 100; - if (item_position < 0) - return; + if (item_position < 0){ + if (sd->sc.data[SC_LIGHT_OF_REGENE]) + hpsp = 20 * sd->sc.data[SC_LIGHT_OF_REGENE]->val1; + else + return; + } if (sd->sc.data[SC_HELLPOWER]) //Cannot res while under the effect of SC_HELLPOWER. return; - if (!status->revive(&sd->bl, 100, 100)) + if (!status->revive(&sd->bl, hpsp, hpsp)) return; + if ( item_position > 0) + pc->delitem(sd, item_position, 1, 0, 1, LOG_TYPE_CONSUME); + else + status_change_end(&sd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER); + clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); - pc->delitem(sd, item_position, 1, 0, 1, LOG_TYPE_CONSUME); } diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 94c2ae5b1..ff9f7a5b1 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -1182,6 +1182,24 @@ bool homunculus_read_skill_db_sub(char* split[], int columns, int current) { return true; } +int8 homunculus_get_intimacy_grade(struct homun_data *hd) { + unsigned int val = hd->homunculus.intimacy / 100; + if( val > 100 ) { + if( val > 250 ) { + if( val > 750 ) { + if ( val > 900 ) + return 4; + else + return 3; + } else + return 2; + } else + return 1; + } + + return 0; +} + void homunculus_skill_db_read(void) { memset(homun->skill_tree,0,sizeof(homun->skill_tree)); sv->readdb(map->db_path, "homun_skill_tree.txt", ',', 13, 15, -1, homun->read_skill_db_sub); @@ -1303,4 +1321,5 @@ void homunculus_defaults(void) { homun->exp_db_read = homunculus_exp_db_read; homun->addspiritball = homunculus_addspiritball; homun->delspiritball = homunculus_delspiritball; + homun->get_intimacy_grade = homunculus_get_intimacy_grade; } diff --git a/src/map/homunculus.h b/src/map/homunculus.h index db250f511..e6d59e30e 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -140,6 +140,7 @@ struct homunculus_interface { void (*exp_db_read) (void); void (*addspiritball) (struct homun_data *hd, int max); void (*delspiritball) (struct homun_data *hd, int count, int type); + int8 (*get_intimacy_grade) (struct homun_data *hd); }; struct homunculus_interface *homun; diff --git a/src/map/pc.c b/src/map/pc.c index ba66bf7db..c8fb14e55 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6855,7 +6855,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { } if (sd->status.hom_id > 0){ - if(battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE]) + if(battle_config.homunculus_auto_vapor && sd->hd) homun->vaporize(sd, HOM_ST_REST); } diff --git a/src/map/skill.c b/src/map/skill.c index 30de1c4cf..c8388770a 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -585,12 +585,12 @@ int skillnotok_hom(uint16 skill_id, struct homun_data *hd) return 1; switch(skill_id){ case MH_LIGHT_OF_REGENE: - if(hd->homunculus.intimacy <= 75000) //if not cordial - return 1; - break; - case MH_OVERED_BOOST: - if(hd->homunculus.hunger <= 1) //if we starving - return 1; + if( homun->get_intimacy_grade(hd) != 4 ){ + if( hd->master ) + clif->skill_fail(hd->master, skill_id, USESKILL_FAIL_RELATIONGRADE, 0); + return 1; + } + break; case MH_GOLDENE_FERSE: //can be used with angriff if(hd->sc.data[SC_ANGRIFFS_MODUS]) return 1; @@ -1341,6 +1341,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 if( sc_start(src, bl, SC_ILLUSIONDOPING, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)) ) //custom rate. sc_start(src, bl, SC_ILLUSION, 100, skill_lv, skill->get_time(skill_id, skill_lv)); break; + case MH_XENO_SLASHER: + sc_start2(src, bl, SC_BLOODING, 10 * skill_lv, skill_lv, src->id, skill->get_time(skill_id,skill_lv)); + break; } if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai) { @@ -2730,9 +2733,6 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr * Post-damage effects **/ switch( skill_id ) { - case RK_CRUSHSTRIKE: - skill->break_equip(src,EQP_WEAPON,2000,BCT_SELF); // 20% chance to destroy the weapon. - break; case GC_VENOMPRESSURE: { struct status_change *ssc = status->get_sc(src); @@ -3122,6 +3122,9 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) { map->foreachinarea(skill->frostjoke_scream,skl->map,skl->x-range,skl->y-range, skl->x+range,skl->y+range,BL_CHAR,src,skl->skill_id,skl->skill_lv,tick); break; + case KN_AUTOCOUNTER: + clif->skill_nodamage(src,target,skl->skill_id,skl->skill_lv,1); + break; case NPC_EARTHQUAKE: if( skl->type > 1 ) skill->addtimerskill(src,tick+250,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag); @@ -3516,7 +3519,6 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case NPC_HELLPOWER: case RK_SONICWAVE: case RK_STORMBLAST: - case RK_CRUSHSTRIKE: case AB_DUPLELIGHT_MELEE: case RA_AIMEDBOLT: case NC_AXEBOOMERANG: @@ -3769,6 +3771,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case KO_MUCHANAGE: case KO_BAKURETSU: case GN_ILLUSIONDOPING: + case MH_XENO_SLASHER: if( flag&1 ) {//Recursive invocation // skill->area_temp[0] holds number of targets in area // skill->area_temp[1] holds the id of the original target @@ -3796,6 +3799,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case GC_ROLLINGCUTTER: flag |= SD_ANIMATION; case LG_MOONSLASHER: + case MH_XENO_SLASHER: clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); break; case NPC_EARTHQUAKE://FIXME: Isn't EarthQuake a ground skill after all? @@ -4558,7 +4562,6 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 //recursive homon skill case MH_MAGMA_FLOW: - case MH_XENO_SLASHER: case MH_HEILIGE_STANGE: if(flag & 1) skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag); @@ -5594,7 +5597,6 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case PR_BENEDICTIO: case LK_BERSERK: case MS_BERSERK: - case KN_AUTOCOUNTER: case KN_TWOHANDQUICKEN: case KN_ONEHAND: case MER_QUICKEN: @@ -5667,6 +5669,11 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; + + case KN_AUTOCOUNTER: + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + skill->addtimerskill(src, tick + 100, bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag); + break; case SO_STRIKING: if (sd) { @@ -9397,10 +9404,23 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } break; + case MH_LIGHT_OF_REGENE: + if( hd && battle->get_master(src) ) { + hd->homunculus.intimacy = (751 + rnd()%99) * 100; // random between 751 ~ 850 + clif->send_homdata(hd->master, SP_INTIMATE, hd->homunculus.intimacy / 100); //refresh intimacy info + sc_start(src, battle->get_master(src), type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + } + break; + + case MH_OVERED_BOOST: + if ( hd && battle->get_master(src) ) { + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, battle->get_master(src), type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + } + break; + case MH_SILENT_BREEZE: { - struct status_change *ssc = status->get_sc(src); - struct block_list *m_bl = battle->get_master(src); const enum sc_type scs[] = { SC_MANDRAGORA, SC_HARMONIZE, SC_DEEP_SLEEP, SC_SIREN, SC_SLEEP, SC_CONFUSION, SC_ILLUSION }; @@ -9410,40 +9430,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin for (i = 0; i < ARRAYLENGTH(scs); i++) { if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER); } - 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; - status->heal(bl, heal, 0, 7); - - //now inflict silence on everyone - if(ssc && !ssc->data[SC_SILENCE]) //put inavoidable silence on homun - status->change_start(src, src, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); - if(m_bl){ - struct status_change *msc = status->get_sc(m_bl); - if(msc && !msc->data[SC_SILENCE]) //put inavoidable silence on master - status->change_start(src, m_bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); } - if (hd) - skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv)); + heal = 5 * status->get_lv(&hd->bl) + status->base_matk(&hd->battle_status, status->get_lv(&hd->bl)); + status->heal(bl, heal, 0, 0); + clif->skill_nodamage(src, src, skill_id, skill_lv, clif->skill_nodamage(src, bl, AL_HEAL, heal, 1)); + status->change_start(src, bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); } break; - case MH_OVERED_BOOST: - if (hd) { - struct block_list *s_bl = battle->get_master(src); - if(hd->homunculus.hunger>50) //reduce hunger - hd->homunculus.hunger = hd->homunculus.hunger/2; - else - hd->homunculus.hunger = min(1,hd->homunculus.hunger); - if(s_bl && s_bl->type==BL_PC) { - status->set_sp(s_bl,status_get_max_sp(s_bl)/2,0); //master drain 50% sp - clif->send_homdata(((TBL_PC *)s_bl), SP_HUNGRY, hd->homunculus.hunger); //refresh hunger info - sc_start(src, s_bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); //gene bonus - } - sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); - skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv)); - } - break; + case MH_GRANITIC_ARMOR: case MH_PYROCLASTIC: if( hd ){ @@ -9458,12 +9452,6 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } break; - case MH_LIGHT_OF_REGENE: - if(hd) { - hd->homunculus.intimacy = 25100; //change to neutral (can't be cast if < 750) - if(sd) clif->send_homdata(sd, SP_INTIMATE, hd->homunculus.intimacy); //refresh intimacy info - } - //don't break need to start status and start block timer case MH_MAGMA_FLOW: case MH_PAIN_KILLER: sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); @@ -10052,10 +10040,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case MH_VOLCANIC_ASH: case MH_POISON_MIST: case MH_STEINWAND: - case MH_XENO_SLASHER: case NC_MAGMA_ERUPTION: case SO_ELEMENTAL_SHIELD: case RL_B_TRAP: + case MH_XENO_SLASHER: flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete). case GS_GROUNDDRIFT: //Ammo should be deleted right away. skill->unitsetting(src,skill_id,skill_lv,x,y,0); diff --git a/src/map/status.c b/src/map/status.c index 9a2151971..4c2bc6d22 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -466,13 +466,13 @@ void initChangeTables(void) { set_sc( HAMI_BLOODLUST , SC_HAMI_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK ); // Homunculus S + set_sc( MH_LIGHT_OF_REGENE , SC_LIGHT_OF_REGENE , SI_LIGHT_OF_REGENE , SCB_NONE ); + set_sc( MH_OVERED_BOOST , SC_OVERED_BOOST , SI_OVERED_BOOST , SCB_FLEE|SCB_ASPD|SCB_DEF ); + 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); 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_VOLCANIC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE); set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SI_GRANITIC_ARMOR, SCB_NONE); set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SI_MAGMA_FLOW, SCB_NONE); @@ -1319,16 +1319,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, return (int)(hp+sp); } - if(target->type == BL_PC) { - TBL_PC *sd = BL_CAST(BL_PC,target); - 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)); - status_change_end(&sd->hd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER); - return (int)(hp + sp); - } - } + if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*) target)->state.rebirth) { // Ensure the monster has not already rebirthed before doing so. status->revive(target, sc->data[SC_REBIRTH]->val2, 0); @@ -1648,7 +1639,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin if ( (sc->data[SC_TRICKDEAD] && skill_id != NV_TRICKDEAD) - || (sc->data[SC_AUTOCOUNTER] && !flag) + || (sc->data[SC_AUTOCOUNTER] && !flag && skill_id) || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_id != PA_GOSPEL) || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && flag != 2) ) @@ -4842,8 +4833,6 @@ signed short status_calc_flee(struct block_list *bl, struct status_change *sc, i flee += 10; if (sc->data[SC_ANGRIFFS_MODUS]) flee -= sc->data[SC_ANGRIFFS_MODUS]->val3; - if (sc->data[SC_OVERED_BOOST]) - flee = max(flee,sc->data[SC_OVERED_BOOST]->val2); if(sc->data[SC_GS_ADJUSTMENT]) flee += 30; if(sc->data[SC_HLIF_SPEED]) @@ -4891,6 +4880,9 @@ signed short status_calc_flee(struct block_list *bl, struct status_change *sc, i if(status_get_element(bl) == ELE_WATER) //water type flee /= 2; } + + if( sc->data[SC_OVERED_BOOST] ) // should be final and unmodifiable by any means + flee = sc->data[SC_OVERED_BOOST]->val2; return (short)cap_value(flee,1,SHRT_MAX); } @@ -4923,6 +4915,8 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def /* some statuses that are hidden in the status window */ if( sc && sc->data[SC_CAMOUFLAGE] ) def -= def * 5 * (10-sc->data[SC_CAMOUFLAGE]->val4) / 100; + if( sc->data[SC_OVERED_BOOST] && bl->type == BL_PC ) + def -= def * 50 / 100; if( sc && sc->data[SC_GENTLETOUCH_REVITALIZE] && sc->data[SC_GENTLETOUCH_REVITALIZE]->val4 ) def += 2 * sc->data[SC_GENTLETOUCH_REVITALIZE]->val4; if( sc->data[SC_FORCEOFVANGUARD] ) @@ -4942,27 +4936,32 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def if(sc->data[SC_STEELBODY]) return 90; #endif + + if(sc->data[SC_STONEHARDSKIN]) + def += sc->data[SC_STONEHARDSKIN]->val1; + if(sc->data[SC_DRUMBATTLE]) + def += sc->data[SC_DRUMBATTLE]->val3; if(sc->data[SC_STONESKIN]) def += sc->data[SC_STONESKIN]->val2; - if(sc->data[SC_DRUMBATTLE]) - def += sc->data[SC_DRUMBATTLE]->val3; if(sc->data[SC_HAMI_DEFENCE]) //[orn] - def += sc->data[SC_HAMI_DEFENCE]->val2 ; - if(sc->data[SC_INCDEFRATE]) - def += def * sc->data[SC_INCDEFRATE]->val1/100; + def += sc->data[SC_HAMI_DEFENCE]->val2; + 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]) - def += sc->data[SC_STONEHARDSKIN]->val1; + +#ifndef RENEWAL if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) def >>=1; if(sc->data[SC_FREEZE]) def >>=1; + if(sc->data[SC_INCDEFRATE]) + def += def * sc->data[SC_INCDEFRATE]->val1/100; +#endif + if( sc->data[SC_ANGRIFFS_MODUS] ) + def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1; if(sc->data[SC_CRUCIS]) def -= def * sc->data[SC_CRUCIS]->val2/100; if(sc->data[SC_LKCONCENTRATION]) @@ -4971,7 +4970,7 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def def >>=1; if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense-> def -= def * sc->data[SC_PROVOKE]->val4/100; - if(sc->data[SC_NOEQUIPSHIELD] && bl->type != BL_PC) + if(sc->data[SC_NOEQUIPSHIELD]) def -= def * sc->data[SC_NOEQUIPSHIELD]->val2/100; if (sc->data[SC_FLING]) def -= def * (sc->data[SC_FLING]->val2)/100; @@ -4981,20 +4980,17 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def def -= def * (10 + 10 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1) / 100; if(sc->data[SC_EARTHDRIVE]) def -= def * 25 / 100; - if(sc->data[SC_SOLID_SKIN_OPTION]) - def += def * sc->data[SC_SOLID_SKIN_OPTION]->val2 / 100; if( sc->data[SC_ROCK_CRUSHER] ) def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100; + if( sc->data[SC_FROSTMISTY] ) + def -= def * 10 / 100; + if( sc->data[SC_OVERED_BOOST] && bl->type == BL_HOM ) + def -= def * 50 / 100; + if( sc->data[SC_POWER_OF_GAIA] ) def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100; - if( sc->data[SC_NEUTRALBARRIER] ) - def += def * (5 * sc->data[SC_NEUTRALBARRIER]->val1 + 10) / 100; - if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 ) - def += sc->data[SC_SHIELDSPELL_REF]->val2; if( sc->data[SC_PRESTIGE] ) - def += sc->data[SC_PRESTIGE]->val1; - if( sc->data[SC_FROSTMISTY] ) - def -= def * 10 / 100; + def += def * sc->data[SC_PRESTIGE]->val1 / 100; if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ if(status_get_race(bl)==RC_PLANT) def /= 2; @@ -5471,11 +5467,6 @@ short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int if (!sc || !sc->count) return cap_value(aspd, 0, 2000); - if (!sc->data[SC_QUAGMIRE]) { - 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 @@ -5484,6 +5475,8 @@ short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int if( sc && sc->data[SC_MTF_ASPD] ) aspd -= 10; + if (sc->data[SC_OVERED_BOOST]) // should be final and unmodifiable by any means + aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3 * 10; return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway } @@ -7331,6 +7324,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER); break; case SC_FIGHTINGSPIRIT: + case SC_OVERED_BOOST: status_change_end(bl, type, INVALID_TIMER); // Remove previous one. break; case SC_MARSHOFABYSS: @@ -10114,6 +10108,20 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const } } break; + case SC_OVERED_BOOST: + switch( bl->type ){ + case BL_HOM: + { + struct homun_data *hd = BL_CAST(BL_HOM, bl); + if( hd ) + hd->homunculus.hunger = max(1, hd->homunculus.hunger - 50); + } + break; + case BL_PC: + status_zap(bl, 0, status_get_max_sp(bl) / 2); + break; + } + break; } opt_flag = 1; |