diff options
author | malufett <malufett.eat.my.binaries@gmail.com> | 2013-07-07 11:02:29 -0700 |
---|---|---|
committer | malufett <malufett.eat.my.binaries@gmail.com> | 2013-07-07 11:02:29 -0700 |
commit | cf56f7c9142ae164d4e093807f1e7def3471afbd (patch) | |
tree | 4207a2dec5349c47ef844b2f35080cdb0050c3f5 /src/map | |
parent | 8a127e11bfaf108cc66865dd4b1a379da2416f46 (diff) | |
download | hercules-cf56f7c9142ae164d4e093807f1e7def3471afbd.tar.gz hercules-cf56f7c9142ae164d4e093807f1e7def3471afbd.tar.bz2 hercules-cf56f7c9142ae164d4e093807f1e7def3471afbd.tar.xz hercules-cf56f7c9142ae164d4e093807f1e7def3471afbd.zip |
Fixed Bug#6503
-where SR_GENTLETOUCH_REVITALIZE is not working properly.
Fixed Bug#6547 & Bug#6141
-SC_BLOODYLUST should now work properly like as official behavior.
Fixed Bug#7395
-SO_SPELLFIST should now work properly.
Fixed Bug#7477
-removed hidden walkdaley that makes character stop when hit even if SC_ENDURE is active.
Fixed Bug#7475
-fixed error message in SA_AUTOSPELL when cancel button is pressed.
Fixed Bug#7337
-MG_CHANGECART should now work properly.
Fixed Bug#7474
-SC_MAELSTROM should now work properly like as official behavior.
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/atcommand.c | 8 | ||||
-rw-r--r-- | src/map/battle.c | 59 | ||||
-rw-r--r-- | src/map/clif.c | 23 | ||||
-rw-r--r-- | src/map/pc.c | 8 | ||||
-rw-r--r-- | src/map/pc.h | 1 | ||||
-rw-r--r-- | src/map/skill.c | 93 | ||||
-rw-r--r-- | src/map/skill.h | 1 | ||||
-rw-r--r-- | src/map/status.c | 64 | ||||
-rw-r--r-- | src/map/unit.c | 4 |
9 files changed, 141 insertions, 120 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 2aaf89107..e8165e4a3 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -6177,7 +6177,7 @@ ACMD(npctalk) unsigned long color=0; if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] || + (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; @@ -6228,7 +6228,7 @@ ACMD(pettalk) } if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] || + (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; @@ -6994,7 +6994,7 @@ ACMD(homtalk) } if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] || + (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; @@ -7377,7 +7377,7 @@ ACMD(me) memset(atcmd_output, '\0', sizeof(atcmd_output)); if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] || + (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; diff --git a/src/map/battle.c b/src/map/battle.c index cf952a3b9..b25971c4c 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -653,13 +653,12 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int case W_1HSPEAR: case W_2HSPEAR: if((skill = pc->checkskill(sd,KN_SPEARMASTERY)) > 0) { - - if(!pc_isriding(sd)) - damage += (skill * 4); - else if(pc_isridingdragon(sd)) + if(pc_isridingdragon(sd)) damage += (skill * 10); - else + else if(pc_isriding(sd)) damage += (skill * 5); + else + damage += (skill * 4); } break; case W_1HAXE: @@ -845,7 +844,7 @@ int battle_calc_elefix(struct block_list *src, struct block_list *target, uint16 tstatus = iStatus->get_status_data(target); sc = iStatus->get_sc(src); - if( (nk&NK_NO_ELEFIX) && n_ele ) + if( (nk&NK_NO_ELEFIX) || n_ele ) return damage; if( damage > 0 ) @@ -1950,8 +1949,12 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block #ifndef RENEWAL case ASC_BREAKER: skillratio += 100*skill_lv-100; - break; + #else + case LK_SPIRALPIERCE: + case ML_SPIRALPIERCE: + skillratio += 50 * skill_lv; #endif + break; case PA_SACRIFICE: skillratio += 10 * skill_lv - 10; break; @@ -2522,7 +2525,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag return 0; if( battle_config.ksprotection && mob_ksprotected(src, bl) ) return 0; - + if( iMap->getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) && skill->get_type(skill_id) != BF_MISC + && skill->get_casttype(skill_id) == CAST_GROUND ) + return 0; if (bl->type == BL_PC) { sd=(struct map_session_data *)bl; //Special no damage states @@ -3379,7 +3384,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list ad.flag = BF_WEAPON|BF_SHORT; ad.type = 0; } - break; default: MATK_RATE(battle->calc_skillratio(BF_MAGIC, src, target, skill_id, skill_lv, skillratio, mflag)); } @@ -4546,7 +4550,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list skillratio += sc->data[SC_OVERTHRUST]->val3; if(sc->data[SC_OVERTHRUSTMAX]) skillratio += sc->data[SC_OVERTHRUSTMAX]->val2; - if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC__BLOODYLUST]) + if(sc->data[SC_BERSERK] || sc->data[SC_SATURDAY_NIGHT_FEVER]) skillratio += 100; #ifdef RENEWAL if( sc->data[SC_TRUESIGHT] ) @@ -4578,21 +4582,30 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list #endif switch(skill_id){ #ifdef RENEWAL - case LK_SPIRALPIERCE: - case ML_SPIRALPIERCE: - {// Formula: Floor[Floor(Weapon Weight/2)*skill level + ATK ]*(100%+50%*s.lvl) * 5 multi-hits - short index = sd?sd->equip_index[EQI_HAND_R]:0; - int weight = 0; - - if (sd && index >= 0 && - sd->inventory_data[index] && - sd->inventory_data[index]->type == IT_WEAPON) - weight = sd->inventory_data[index]->weight/20; - ATK_ADD(weight * skill_lv); - } case NJ_TATAMIGAESHI: - if( skill_id != LK_SPIRALPIERCE && skill_id != ML_SPIRALPIERCE ) ATK_RATE(200); + case LK_SPIRALPIERCE: + case ML_SPIRALPIERCE: // [malufett] + if( skill_id != NJ_TATAMIGAESHI ){ + short index = sd?sd->equip_index[EQI_HAND_R]:0; + GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) ); + wd.damage = wd.damage * 70 / 100; + n_ele = true; + + if (sd && index >= 0 && + sd->inventory_data[index] && + sd->inventory_data[index]->type == IT_WEAPON) + ATK_ADD(sd->inventory_data[index]->weight * 7 / 100); + + switch (tstatus->size) { + case SZ_SMALL: //Small: 115% + ATK_RATE(115); + break; + case SZ_BIG: //Large: 85% + ATK_RATE(85); + } + wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon); + } #endif default: ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag)); diff --git a/src/map/clif.c b/src/map/clif.c index b2461d8d5..a314dc6d2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9919,7 +9919,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) if( atcommand->parse(fd, sd, message, 1) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) { //[Skotlex] @@ -10378,7 +10378,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) if ( atcommand->parse(fd, sd, message, 1) ) return; - if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)) + if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)) return; if (battle_config.min_chat_delay) { //[Skotlex] @@ -11794,11 +11794,18 @@ void clif_parse_SelectArrow(int fd,struct map_session_data *sd) /// 01ce <skill id>.L void clif_parse_AutoSpell(int fd,struct map_session_data *sd) { - if (sd->menuskill_id != SA_AUTOSPELL) + uint16 skill_id = RFIFOL(fd,2); + + sd->state.workinprogress = 0; + + if( sd->menuskill_id != SA_AUTOSPELL ) return; - skill->autospell(sd,RFIFOL(fd,2)); + + if( !skill_id ) + return; + + skill->autospell(sd, skill_id); clif_menuskill_clear(sd); - sd->state.workinprogress = 0; } @@ -12180,7 +12187,7 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd) if( atcommand->parse(fd, sd, message, 1) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) @@ -13021,7 +13028,7 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd) if( atcommand->parse(fd, sd, message, 1) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) @@ -15908,7 +15915,7 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd) if( atcommand->parse(fd, sd, message, 1) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) { diff --git a/src/map/pc.c b/src/map/pc.c index b14a02ed4..87e80c264 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4193,7 +4193,7 @@ int pc_isUseitem(struct map_session_data *sd,int n) case 12243: // Mercenary's Berserk Potion if( sd->md == NULL || sd->md->db == NULL ) return 0; - if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAY_NIGHT_FEVER] || sd->md->sc.data[SC__BLOODYLUST]) + if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAY_NIGHT_FEVER]) return 0; if( nameid == 12242 && sd->md->db->lv < 40 ) return 0; @@ -4294,7 +4294,7 @@ int pc_useitem(struct map_session_data *sd,int n) { return 0; if (sd->sc.count && ( - sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || + sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) || sd->sc.data[SC_TRICKDEAD] || sd->sc.data[SC_HIDING] || @@ -8544,7 +8544,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) return 0; } - if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER] || sd->sc.data[SC__BLOODYLUST]) + if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER]) { clif->equipitemack(sd,n,0,0); // fail return 0; @@ -8740,7 +8740,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { } // if player is berserk then cannot unequip - if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER] || sd->sc.data[SC__BLOODYLUST])) + if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER])) { clif->unequipitemack(sd,n,0,0); return 0; diff --git a/src/map/pc.h b/src/map/pc.h index 9f96486c9..7f0e8cf46 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -229,7 +229,6 @@ struct map_session_data { unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files unsigned int cansendmail_tick; // [Mail System Flood Protection] unsigned int ks_floodprotect_tick; // [Kill Steal Protection] - unsigned int bloodylust_tick; // bloodylust player timer [out/in re full-heal protection] struct { short nameid; unsigned int tick; diff --git a/src/map/skill.c b/src/map/skill.c index da35bbbd3..caee534ba 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5072,7 +5072,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui dstsd = sd; } } - else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAY_NIGHT_FEVER] || tsc->data[SC__BLOODYLUST]) + else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAY_NIGHT_FEVER]) heal = 0; //Needed so that it actually displays 0 when healing. } clif->skill_nodamage (src, bl, skill_id, heal, 1); @@ -5670,8 +5670,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case MC_CHANGECART: - if( sd ) - sd->state.workinprogress = 3; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; @@ -9571,7 +9569,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char sd->sc.data[SC_AUTOCOUNTER] || sd->sc.data[SC_STEELBODY] || (sd->sc.data[SC_DANCING] && skill_id < RK_ENCHANTBLADE && !pc->checkskill(sd, WM_LESSON)) || - sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || + sd->sc.data[SC_BERSERK] || sd->sc.data[SC_BASILICA] || sd->sc.data[SC_MARIONETTE_MASTER] || sd->sc.data[SC_WHITEIMPRISON] || @@ -9859,6 +9857,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case SC_DIMENSIONDOOR: case SC_CHAOSPANIC: case SC_MAELSTROM: + case SC_BLOODYLUST: case WM_REVERBERATION: case WM_SEVERE_RAINSTORM: case WM_POEMOFNETHERWORLD: @@ -10348,11 +10347,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui sc_start2(src, type, 100, skill_id, skill_lv, skill->get_time(skill_id, skill_lv))); break; - case SC_BLOODYLUST: //set in another group so instance will move if recasted - flag |= 33; - skill->unitsetting(src, skill_id, skill_lv, x, y, 0); - break; - case KO_MAKIBISHI: for( i = 0; i < (skill_lv+2); i++ ) { x = src->x - 1 + rnd()%3; @@ -10829,9 +10823,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill case SO_VACUUM_EXTREME: range++; break; - case SC_BLOODYLUST: - skill->clear_group(src, 32); - break; case GN_WALLOFTHORN: if( flag&1 ) limit = 3000; @@ -10959,6 +10950,9 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill if (skill->get_unit_flag(skill_id) & UF_RANGEDSINGLEUNIT && i == (layout->count / 2)) val2 |= UF_RANGEDSINGLEUNIT; // center. + if( sd && iMap->getcell(src->m, ux, uy, CELL_CHKMAELSTROM) ) //Does not recover SP from monster skills + iMap->foreachincell(skill->maelstrom_suction,src->m,ux,uy,BL_SKILL,skill_id,skill_lv); + if( range <= 0 ) iMap->foreachincell(skill->cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src); if( !alive ) @@ -11019,7 +11013,8 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned if( skill->get_type(sg->skill_id) == BF_MAGIC && iMap->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR ) return 0; //AoE skills are ineffective. [Skotlex] - + if( iMap->getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) ) + return 0; sc = iStatus->get_sc(bl); if (sc && sc->option&OPTION_HIDE && sg->skill_id != WZ_HEAVENDRIVE && sg->skill_id != WL_EARTHSTRAIN ) @@ -11053,28 +11048,18 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned if (!sce) sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit); break; - + + case UNT_BLOODYLUST: + if (sg->src_id == bl->id) + break; //Does not affect the caster. + if( !sce && sc_start4(bl,type,100,sg->skill_lv,0,SC__BLOODYLUST,0,sg->limit) ) + sc_start(bl,SC__BLOODYLUST,100,sg->skill_lv,sg->limit); + break; case UNT_PNEUMA: case UNT_CHAOSPANIC: - case UNT_MAELSTROM: if (!sce) sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); break; - case UNT_BLOODYLUST: - if (sg->src_id == bl->id) - break; //Does not affect the caster. - if (!sce) { - TBL_PC *sd = BL_CAST(BL_PC, bl); //prevent fullheal exploit - if (sd && sd->bloodylust_tick && DIFF_TICK(iTimer->gettick(), sd->bloodylust_tick) < skill->get_time2(SC_BLOODYLUST, 1)) - clif->skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv, - sc_start4(bl, type, 100, sg->skill_lv, 1, 0, 0, skill->get_time(LK_BERSERK, sg->skill_lv))); - else { - if (sd) sd->bloodylust_tick = iTimer->gettick(); - clif->skill_nodamage(&src->bl,bl,sg->skill_id,sg->skill_lv, - sc_start4(bl, type, 100, sg->skill_lv, 0, 0, 0, skill->get_time(LK_BERSERK, sg->skill_lv))); - } - } - break; case UNT_WARP_WAITING: { int working = sg->val1&0xffff; @@ -12041,14 +12026,9 @@ static int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned i case SO_WATER_INSIGNIA: case SO_WIND_INSIGNIA: case SO_EARTH_INSIGNIA: - if (sce) - status_change_end(bl, type, INVALID_TIMER); - break; case SC_BLOODYLUST: - if (sce) { + if (sce) status_change_end(bl, type, INVALID_TIMER); - iStatus->set_sp(bl, 0, 0); //set sp to 0 when quitting zone - } break; case BA_POEMBRAGI: @@ -14653,10 +14633,6 @@ int skill_clear_group (struct block_list *bl, int flag) if( flag&8 ) group[count++]= ud->skillunit[i]; break; - case SC_BLOODYLUST: - if (flag & 32) - group[count++] = ud->skillunit[i]; - break; default: if (flag&2 && skill->get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP) group[count++]= ud->skillunit[i]; @@ -14686,7 +14662,6 @@ struct skill_unit_group *skill_locate_element_field(struct block_list *bl) { case SA_LANDPROTECTOR: case NJ_SUITON: case SO_WARMER: - case SC_BLOODYLUST: return ud->skillunit[i]; } } @@ -14782,9 +14757,9 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) { alive = va_arg(ap,int *); unit = (struct skill_unit *)bl; - if (unit == NULL || unit->group == NULL || (*alive) == 0) + if( unit == NULL || unit->group == NULL || (*alive) == 0 ) return 0; - + switch (skill_id) { case SA_LANDPROTECTOR: if( unit->group->skill_id == SA_LANDPROTECTOR ) {//Check for offensive Land Protector to delete both. [Skotlex] @@ -14996,6 +14971,33 @@ int skill_trap_splash (struct block_list *bl, va_list ap) { return 1; } +int skill_maelstrom_suction(struct block_list *bl, va_list ap) { + uint16 skill_id, skill_lv; + struct skill_unit *unit; + + skill_id = va_arg(ap,int); + skill_lv = va_arg(ap,int); + unit = (struct skill_unit *)bl; + + if( unit == NULL || unit->group == NULL ) + return 0; + + if( skill->get_inf2(skill_id)&INF2_TRAP ) + return 0; + + if( unit->group->skill_id == SC_MAELSTROM ){ + struct block_list *src; + if( (src = iMap->id2bl(unit->group->src_id)) ){ + int sp = unit->group->skill_lv * skill_lv; + if( src->type == BL_PC ) + sp += ((TBL_PC*)src)->status.job_level / 5; + iStatus->heal(src, 0, sp/2, 1); + } + } + + return 0; +} + /*========================================== * *------------------------------------------*/ @@ -15087,6 +15089,9 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int nullpo_retr(NULL, group->unit); // crash-protection against poor coding nullpo_retr(NULL, unit=&group->unit[idx]); + if( iMap->getcell(iMap->id2bl(group->src_id)->m, x, y, CELL_CHKMAELSTROM) ) + return unit; + if(!unit->alive) group->alive_count++; @@ -18268,5 +18273,5 @@ void skill_defaults(void) { skill->changematerial = skill_changematerial; skill->get_elemental_type = skill_get_elemental_type; skill->cooldown_save = skill_cooldown_save; - + skill->maelstrom_suction = skill_maelstrom_suction; } diff --git a/src/map/skill.h b/src/map/skill.h index cff2fc0cf..35cb36809 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1937,6 +1937,7 @@ struct skill_interface { int (*changematerial) (struct map_session_data *sd, int n, unsigned short *item_list); int (*get_elemental_type) (uint16 skill_id, uint16 skill_lv); void (*cooldown_save) (struct map_session_data * sd); + int (*maelstrom_suction) (struct block_list *bl, va_list ap); }; struct skill_interface *skill; diff --git a/src/map/status.c b/src/map/status.c index 682d7410c..20d88e296 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -659,7 +659,7 @@ void initChangeTables(void) { set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSARY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK ); set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE ); add_sc( SC_CHAOSPANIC , SC_CONFUSION ); - set_sc_with_vfx( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF | SCB_DEF2 | SCB_MDEF | SCB_MDEF2 | SCB_FLEE | SCB_SPEED | SCB_ASPD | SCB_MAXHP | SCB_REGEN ); + add_sc( SC_BLOODYLUST , SC_BERSERK ); /** * Sura **/ @@ -1236,8 +1236,6 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER); if (sc->data[SC_SATURDAY_NIGHT_FEVER] && status->hp <= 100) status_change_end(target, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER); - if (sc->data[SC__BLOODYLUST] && status->hp <= 100) - status_change_end(target, SC__BLOODYLUST, INVALID_TIMER); } switch (target->type) { @@ -1248,7 +1246,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s case BL_ELEM: elemental_heal((TBL_ELEM*)target,hp,sp); break; } - if( src && target->type == BL_PC && ((TBL_PC*)target)->disguise ) {// stop walking when attacked in disguise to prevent walk-delay bug + if( src && target->type == BL_PC && (((TBL_PC*)target)->disguise) > 0 ) {// stop walking when attacked in disguise to prevent walk-delay bug unit_stop_walking( target, 1 ); } @@ -1375,7 +1373,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag) } if(hp) { - if( sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) ) { + if( sc && sc->data[SC_BERSERK] ) { if( flag&1 ) flag &= ~2; else @@ -1668,7 +1666,6 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin sc->data[SC_SILENCE] || sc->data[SC_STEELBODY] || sc->data[SC_BERSERK] || - sc->data[SC__BLOODYLUST] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_WHITEIMPRISON] || sc->data[SC__INVISIBILITY] || @@ -3480,7 +3477,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str if ( (sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON]) || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON]) - || sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST] + || sc->data[SC_BERSERK] || sc->data[SC_TRICKDEAD] || sc->data[SC_BLOODING] || sc->data[SC_MAGICMUSHROOM] @@ -4813,7 +4810,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change 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]) + if (sc->data[SC_BERSERK]) flee -= flee * 50/100; if(sc->data[SC_BLIND]) flee -= flee * 25/100; @@ -4874,7 +4871,7 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX); } - if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) + if (sc->data[SC_BERSERK]) return 0; if(sc->data[SC_SKA]) return sc->data[SC_SKA]->val3; @@ -4967,7 +4964,7 @@ signed short status_calc_def2(struct block_list *bl, struct status_change *sc, i #endif } - if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) + if (sc->data[SC_BERSERK]) return 0; if(sc->data[SC_ETERNALCHAOS]) return 0; @@ -5028,7 +5025,7 @@ defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int md return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX); } - if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) + if (sc->data[SC_BERSERK]) return 0; if(sc->data[SC_BARRIER]) return 100; @@ -5086,7 +5083,7 @@ signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, #endif } - if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) + if (sc->data[SC_BERSERK]) return 0; if(sc->data[SC_SKA]) return 90; @@ -5232,7 +5229,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha val = max( val, 1 * pc->checkskill(sd,TF_MISS) ); if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1 ) val = max( val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3 ); - if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) + if (sc->data[SC_BERSERK]) val = max( val, 25 ); if( sc->data[SC_RUN] ) val = max( val, 55 ); @@ -5325,7 +5322,7 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s skills1 = 5; } - if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) && skills1 < 15) + if((sc->data[SC_BERSERK]) && skills1 < 15) skills1 = 15; else if(sc->data[SC_GS_MADNESSCANCEL] && skills1 < 20) skills1 = 20; @@ -5491,7 +5488,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change * } aspd_rate -= max; - if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])) + if(sc->data[SC_BERSERK]) aspd_rate -= 300; else if(sc->data[SC_GS_MADNESSCANCEL]) aspd_rate -= 200; @@ -5591,7 +5588,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100; if(sc->data[SC_DELUGE]) maxhp += maxhp * sc->data[SC_DELUGE]->val2/100; - if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) + if(sc->data[SC_BERSERK]) maxhp += maxhp * 2; if(sc->data[SC_MARIONETTE_MASTER]) maxhp -= 1000; @@ -6246,7 +6243,6 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti case SC__LAZINESS: case SC__UNLUCKY: case SC__WEAKNESS: - case SC__BLOODYLUST: return 0; } @@ -6649,12 +6645,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; //There all like berserk, do not everlap each other - case SC__BLOODYLUST: - if(!sd) return 0; //should only affect player case SC_BERSERK: - if (((type == SC_BERSERK) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC__BLOODYLUST])) - || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC_BERSERK])) - ) + if( sc->data[SC__BLOODYLUST] || sc->data[SC_SATURDAY_NIGHT_FEVER] ) return 0; break; @@ -6898,7 +6890,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val } break; case SC_SATURDAY_NIGHT_FEVER: - if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST]) + if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION]) return 0; break; case SC_OFFERTORIUM: @@ -7007,8 +6999,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER); status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER); break; - case SC__BLOODYLUST: case SC_BERSERK: + if( val3 == SC__BLOODYLUST ) + break; if(battle_config.berserk_cancels_buffs) { status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER); status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER); @@ -7266,7 +7259,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val val4 = sce->val4; break; case SC_LERADS_DEW: - if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])) + if (sc && sc->data[SC_BERSERK]) return 0; case SC_SHAPESHIFT: case SC_PROPERTYWALK: @@ -7713,9 +7706,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_BERSERK: - if (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) + if( val3 == SC__BLOODYLUST ) + sc_start(bl,(sc_type)val3,100,val1,tick); + if( !val3 && !(!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) ) sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick); - case SC__BLOODYLUST: //HP healing is performing after the calc_status call. //Val2 holds HP penalty if (!val4) val4 = skill->get_time2(iStatus->sc2skill(type),val1); @@ -8950,7 +8944,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_BERSERK: opt_flag = 0; - // case SC__BLOODYLUST: sc->opt3 |= OPT3_BERSERK; break; // case ???: // doesn't seem to do anything @@ -9093,7 +9086,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing switch (type) { - case SC__BLOODYLUST: case SC_BERSERK: if (!(sce->val2)) { //don't heal if already set iStatus->heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block. @@ -9166,8 +9158,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; } break; - case SC_RAISINGDRAGON: - sce->val2 = status->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie] + case SC_RAISINGDRAGON: + sce->val2 = status->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie] break; } @@ -9537,15 +9529,18 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const case SC_BERSERK: case SC_SATURDAY_NIGHT_FEVER: + if(status->hp > 200 && sc && sc->data[SC__BLOODYLUST]){ + status_percent_heal(bl, 100, 0); + status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER); + }else //If val2 is removed, no HP penalty (dispelled?) [Skotlex] - if (status->hp > 100 && sce->val2) + if(status->hp > 100 && sce->val2) iStatus->set_hp(bl, 100, 0); if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) { sc->data[SC_ENDURE]->val4 = 0; status_change_end(bl, SC_ENDURE, INVALID_TIMER); } - case SC__BLOODYLUST: sc_start4(bl, SC_GDSKILL_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill->get_time(LK_BERSERK, sce->val1)); if( type == SC_SATURDAY_NIGHT_FEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds. sc_start(bl,SC_SITDOWN_FORCE,100,sce->val1,skill->get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1)); @@ -9860,7 +9855,6 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const break; case SC_BERSERK: opt_flag = 0; - // case SC__BLOODYLUST: sc->opt3 &= ~OPT3_BERSERK; break; // case ???: // doesn't seem to do anything @@ -10249,7 +10243,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) return 0; } break; - case SC__BLOODYLUST: case SC_BERSERK: // 5% every 10 seconds [DracoRPG] if( --( sce->val3 ) > 0 && iStatus->charge(bl, sce->val2, 0) && status->hp > 100 ) @@ -11070,7 +11063,6 @@ int status_change_clear_buffs (struct block_list* bl, int type) if(!(type&4)) continue; break; - case SC__BLOODYLUST: case SC_BERSERK: case SC_SATURDAY_NIGHT_FEVER: if(type&4) diff --git a/src/map/unit.c b/src/map/unit.c index 3e72cd793..72e4b136e 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1442,6 +1442,10 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } + if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && iMap->getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) { + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + return 0; + } } if (!iStatus->check_skilluse(src, NULL, skill_id, 0)) |