summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c8
-rw-r--r--src/map/battle.c59
-rw-r--r--src/map/clif.c23
-rw-r--r--src/map/pc.c8
-rw-r--r--src/map/pc.h1
-rw-r--r--src/map/skill.c93
-rw-r--r--src/map/skill.h1
-rw-r--r--src/map/status.c64
-rw-r--r--src/map/unit.c4
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))