diff options
Diffstat (limited to 'src/map/skill.c')
-rw-r--r-- | src/map/skill.c | 210 |
1 files changed, 90 insertions, 120 deletions
diff --git a/src/map/skill.c b/src/map/skill.c index 4ab0ca1c7..d3c00a75b 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2123,6 +2123,7 @@ int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type) * packet shouldn't display a skill animation) * flag&0x2000 is used to signal that the skill_lv should be passed as -1 to the * client (causes player characters to not scream skill name) + * flag&0x4000 - Return 0 if damage was reflected *-------------------------------------------------------------------------*/ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { struct Damage dmg; @@ -2459,6 +2460,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case EL_HURRICANE_ATK: case EL_TYPOON_MIS: case EL_TYPOON_MIS_ATK: + case GN_CRAZYWEED_ATK: case KO_BAKURETSU: case NC_MAGMA_ERUPTION: dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5); @@ -2469,9 +2471,6 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case SC_FEINTBOMB: dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,5); break; - case GN_CRAZYWEED_ATK: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id, -2, 6); - break; case EL_STONE_RAIN: dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?8:5); break; @@ -2544,7 +2543,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr break; case WM_SEVERE_RAINSTORM_MELEE: copy_skill = WM_SEVERE_RAINSTORM; - break; + break; case GN_CRAZYWEED_ATK: copy_skill = GN_CRAZYWEED; break; @@ -2796,6 +2795,9 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr map->freeblock_unlock(); + if ((flag&0x4000) && rmdamage == 1) + return 0; //Should return 0 when damage was reflected + return (int)cap_value(damage,INT_MIN,INT_MAX); } @@ -3301,6 +3303,11 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) { else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) ) skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,skl->flag); break; + case GN_CRAZYWEED_ATK: { + int dummy = 1, i = skill->get_unit_range(skl->skill_id,skl->skill_lv); + + map->foreachinarea(skill->cell_overlap,src->m,skl->x-i,skl->y-i,skl->x+i,skl->y+i,BL_SKILL,skl->skill_id,&dummy,src); + } // fall through ... case WL_EARTHSTRAIN: skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag); @@ -3310,14 +3317,6 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) { map->foreachinpath(skill->attack_area,src->m,src->x,src->y,skl->x,skl->y,4,2,BL_CHAR, skill->get_type(skl->skill_id),src,src,skl->skill_id,skl->skill_lv,tick,skl->flag,BCT_ENEMY); break; - case GN_CRAZYWEED: - if( skl->type >= 0 ) { - int x = skl->type>>16, y = skl->type&0xFFFF; - if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) ) - skill->castend_pos2(src, x, y, GN_CRAZYWEED_ATK, skl->skill_lv, tick, skl->flag); - } else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) ) - skill->castend_pos2(src, skl->x, skl->y, GN_CRAZYWEED_ATK, skl->skill_lv, tick, skl->flag); - break; } } } while (0); @@ -3564,7 +3563,6 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case SR_GENTLETOUCH_QUIET: case WM_SEVERE_RAINSTORM_MELEE: case WM_GREAT_ECHO: - case GN_CRAZYWEED_ATK: case GN_SLINGITEM_RANGEMELEEATK: case KO_JYUMONJIKIRI: case KO_SETSUDAN: @@ -3808,11 +3806,15 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 // skill->area_temp[1] holds the id of the original target // skill->area_temp[2] counts how many targets have already been processed int sflag = skill->area_temp[0] & 0xFFF, heal; + struct status_change *tsc = status->get_sc(bl); if( flag&SD_LEVEL ) sflag |= SD_LEVEL; // -1 will be used in packets instead of the skill level if( (skill->area_temp[1] != bl->id && !(skill->get_inf2(skill_id)&INF2_NPC_SKILL)) || flag&SD_ANIMATION ) sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills) + if ( tsc && tsc->data[SC_HOVERING] && ( skill_id == SR_WINDMILL || skill_id == LG_MOONSLASHER ) ) + break; + heal = skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag); if( skill_id == NPC_VAMPIRE_GIFT && heal > 0 ) { clif->skill_nodamage(NULL, src, AL_HEAL, heal, 1); @@ -6626,9 +6628,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if( skill_id == GC_WEAPONCRUSH){ d = skill->get_time(skill_id,skill_lv); if(bl->type == BL_PC) - d += skill_lv * 15 + (sstatus->dex - tstatus->dex); + d += 1000 * ( skill_lv * 15 + ( sstatus->dex - tstatus->dex ) ); else - d += skill_lv * 30 + (sstatus->dex - tstatus->dex) / 2; + d += 1000 * ( skill_lv * 30 + ( sstatus->dex - tstatus->dex ) / 2 ); }else d = skill->get_time(skill_id,skill_lv) + (sstatus->dex - tstatus->dex)*500; @@ -6949,7 +6951,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } clif->skill_nodamage(src,bl,TK_HIGHJUMP,skill_lv,1); - if(!map->count_oncell(src->m,x,y,BL_PC|BL_NPC|BL_MOB) && map->getcell(src->m,x,y,CELL_CHKREACH)) { + if(!map->count_oncell(src->m,x,y,BL_PC|BL_NPC|BL_MOB,0) && map->getcell(src->m,x,y,CELL_CHKREACH)) { clif->slide(src,x,y); unit->movepos(src, x, y, 1, 0); } @@ -8326,7 +8328,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if( flag&1 || (splash = skill->get_splash(skill_id, skill_lv)) < 1 ) { int i; //As of the behavior in official server Clearance is just a super version of Dispell skill. [Jobbie] - if( bl->type != BL_MOB && battle->check_target(src,bl,BCT_PARTY) <= 0 ) // Only affect mob or party. + if( bl->type != BL_MOB && battle->check_target(src,bl,BCT_PARTY) <= 0 && sd ) // Only affect mob, party or self. break; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -8538,9 +8540,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case NC_SELFDESTRUCTION: - if( sd ) { - if( pc_ismadogear(sd) ) - pc->setmadogear(sd, 0); + if (sd) { + if (pc_ismadogear(sd)) + pc->setmadogear(sd, false); clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); skill->castend_damage_id(src, src, skill_id, skill_lv, tick, flag); status->set_sp(src, 0, 0); @@ -8932,10 +8934,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } break; case SR_GENTLETOUCH_CHANGE: - case SR_GENTLETOUCH_REVITALIZE: clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start2(src,bl,type,100,skill_lv,bl->id,skill->get_time(skill_id,skill_lv))); break; + case SR_GENTLETOUCH_REVITALIZE: + clif->skill_nodamage(src,bl,skill_id,skill_lv, + sc_start2(src,bl,type,100,skill_lv,status_get_vit(src),skill->get_time(skill_id,skill_lv))); + break; case SR_FLASHCOMBO: { const int combo[] = { @@ -9446,17 +9451,16 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case KO_KYOUGAKU: - { - int rate = max(5, (45 + 5 * skill_lv - status_get_int(bl) / 10)); - if( sd && !map_flag_gvg2(src->m) ){ - clif->skill_fail(sd, skill_id, USESKILL_FAIL_SIZE, 0); - break; - } - if( dstsd && tsc && !tsc->data[type] && rand()%100 < rate ){ - clif->skill_nodamage(src, bl, skill_id, skill_lv, - sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); - }else if( sd ) - clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); + if (!map_flag_vs(src->m) || !dstsd) { + if (sd) clif->skill_fail(sd, skill_id, USESKILL_FAIL_SIZE, 0); + break; + } else { + int time; + int rate = 45+ 5*skill_lv - status_get_int(bl)/10; + if (rate < 5) rate = 5; + + time = skill->get_time(skill_id, skill_lv) - 1000*status_get_int(bl)/20; + sc_start(src,bl, type, rate, skill_lv, time); } break; @@ -10077,7 +10081,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case MG_THUNDERSTORM: case AL_PNEUMA: - case WZ_ICEWALL: case WZ_FIREPILLAR: case WZ_QUAGMIRE: case WZ_VERMILION: @@ -10186,6 +10189,11 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui sc_start(src,src,SC_NO_SWITCH_EQUIP,100,0,skill->get_time(skill_id,skill_lv)); skill->unitsetting(src,skill_id,skill_lv,x,y,0); break; + case WZ_ICEWALL: + flag |= 1; + if( skill->unitsetting(src,skill_id,skill_lv,x,y,0) ) + map->list[src->m].setcell(src->m, x, y, CELL_NOICEWALL, true); + break; case RG_GRAFFITI: /* Graffiti [Valaris] */ skill->clear_unitgroup(src); skill->unitsetting(src,skill_id,skill_lv,x,y,0); @@ -10380,7 +10388,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui // Plant Cultivation [Celest] case CR_CULTIVATION: if (sd) { - if( map->count_oncell(src->m,x,y,BL_CHAR) > 0 ) { + if( map->count_oncell(src->m,x,y,BL_CHAR,0) > 0 ) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 1; } @@ -10599,33 +10607,17 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case GN_CRAZYWEED: { int area = skill->get_splash(skill_id, skill_lv); - short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0; for( r = 0; r < 3 + (skill_lv>>1); r++ ) { // Creates a random Cell in the Splash Area - tmpx = x - area + rnd()%(area * 2 + 1); - tmpy = y - area + rnd()%(area * 2 + 1); - - if( r > 0 ) - skill->addtimerskill(src,tick+r*250,0,tmpx,tmpy,GN_CRAZYWEED,skill_lv,(x1<<16)|y1,flag); + int tmpx = x - area + rnd()%(area * 2 + 1); + int tmpy = y - area + rnd()%(area * 2 + 1); - x1 = tmpx; - y1 = tmpy; + skill_addtimerskill(src,tick+r*250,0,tmpx,tmpy,GN_CRAZYWEED_ATK,skill_lv,-1,0); } - - skill->addtimerskill(src,tick+r*250,0,tmpx,tmpy,GN_CRAZYWEED,skill_lv,-1,flag); } break; - case GN_CRAZYWEED_ATK: { - int dummy = 1; - //Enable if any unique animation gets added to this skill ID in the future. [Rytech] - //clif_skill_poseffect(src,skillid,skilllv,x,y,tick); - r = skill->get_splash(skill_id, skill_lv); - map->foreachinarea(skill->cell_overlap, src->m, x-r, y-r, x+r, y+r, BL_SKILL, skill_id, &dummy, src); - map->foreachinarea(skill->area_sub, src->m, x-r, y-r, x+r, y+r, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id); - } - break; case GN_FIRE_EXPANSION: { int i; struct unit_data *ud = unit->bl2ud(src); @@ -10801,28 +10793,6 @@ bool skill_dance_switch(struct skill_unit* su, int flag) { return true; } -/** - * Upon Ice Wall cast it checks all nearby mobs to find any who may be blocked by the IW - **/ -int skill_icewall_block(struct block_list *bl,va_list ap) { - struct block_list *target = NULL; - struct mob_data *md = ((TBL_MOB*)bl); - - nullpo_ret(bl); - nullpo_ret(md); - if( !md->target_id || ( target = map->id2bl(md->target_id) ) == NULL ) - return 0; - - if( path->search_long(NULL,bl->m,bl->x,bl->y,target->x,target->y,CELL_CHKICEWALL) ) - return 0; - - if( !check_distance_bl(bl, target, status_get_range(bl) ) ) { - mob->unlocktarget(md,timer->gettick()); - mob_stop_walking(md,1); - } - - return 0; -} /*========================================== * Initializes and sets a ground skill. * flag&1 is used to determine when the skill 'morphs' (Warp portal becomes active, or Fire Pillar becomes active) @@ -11032,11 +11002,11 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ val1 += pc->checkskill(sd,BA_MUSICALLESSON); break; case DC_SERVICEFORYOU: - val1 = 15+skill_lv+(st->int_/10); // MaxSP percent increase TO-DO: this INT bonus value is guessed + val1 = 15+skill_lv+(st->int_/10); // MaxSP percent increase val2 = 20+3*skill_lv+(st->int_/10); // SP cost reduction if(sd){ - val1 += (pc->checkskill(sd,DC_DANCINGLESSON) + 1) / 2; - val2 += (pc->checkskill(sd,DC_DANCINGLESSON) + 1) / 2; + val1 += pc->checkskill(sd,DC_DANCINGLESSON) / 2; + val2 += pc->checkskill(sd,DC_DANCINGLESSON) / 2; } break; case BA_ASSASSINCROSS: @@ -11322,9 +11292,6 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ //success, unit created. switch( skill_id ) { - case WZ_ICEWALL: - map->foreachinrange(skill->icewall_block, src, AREA_SIZE, BL_MOB); - break; case NJ_TATAMIGAESHI: //Store number of tiles. group->val1 = group->alive_count; break; @@ -11363,6 +11330,9 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick if (sc && sc->data[SC_VACUUM_EXTREME] && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR)) status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER); + if ( sc && sc->data[SC_HOVERING] && ( sg->skill_id == SO_VACUUM_EXTREME || sg->skill_id == SO_ELECTRICWALK || sg->skill_id == SO_FIREWALK || sg->skill_id == WZ_QUAGMIRE ) ) + return 0; + type = status->skill2sc(sg->skill_id); sce = (sc && type != -1)?sc->data[type]:NULL; skill_id = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still. @@ -11583,9 +11553,6 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 tsc = status->get_sc(bl); ssc = status->get_sc(ss); // Status Effects for Unit caster. - if ( tsc && tsc->data[SC_HOVERING] ) - return 0; //Under hovering characters are immune to trap and ground target skills. - // Maestro or Wanderer is unaffected by traps of trappers he or she charmed [SuperHulk] if ( ssc && ssc->data[SC_SIREN] && ssc->data[SC_SIREN]->val2 == bl->id && (skill->get_inf2(sg->skill_id)&INF2_TRAP) ) return 0; @@ -11594,6 +11561,15 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 type = status->skill2sc(sg->skill_id); skill_id = sg->skill_id; + if ( tsc && tsc->data[SC_HOVERING] ) { + switch ( skill_id ) { + case HT_SKIDTRAP: case HT_LANDMINE: case HT_ANKLESNARE: case HT_FLASHER: case HT_SHOCKWAVE: + case HT_SANDMAN: case HT_FREEZINGTRAP: case HT_BLASTMINE: case HT_CLAYMORETRAP: case HW_GRAVITATION: + case SA_DELUGE: case SA_VOLCANO: case SA_VIOLENTGALE: case NJ_SUITON: + return 0; + } + } + if (sg->interval == -1) { switch (sg->unit_id) { case UNT_ANKLESNARE: //These happen when a trap is splash-triggered by multiple targets on the same cell. @@ -11615,7 +11591,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 ts->tick = tick+sg->interval; if ((skill_id==CR_GRANDCROSS || skill_id==NPC_GRANDDARKNESS) && !battle_config.gx_allhit) - ts->tick += sg->interval*(map->count_oncell(bl->m,bl->x,bl->y,BL_CHAR)-1); + ts->tick += sg->interval*(map->count_oncell(bl->m,bl->x,bl->y,BL_CHAR,0)-1); } switch (sg->unit_id) { @@ -12197,9 +12173,11 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 sg->limit -= 100 * tstatus->str/20; sc_start(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->limit); - if (unit->movepos(bl, sg->val1, sg->val2, 0, 0)) { - clif->slide(bl, sg->val1, sg->val2); - clif->fixpos(bl); + if ( !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !is_boss(bl) ) { + if (unit->movepos(bl, sg->val1, sg->val2, 0, 0)) { + clif->slide(bl, sg->val1, sg->val2); + clif->fixpos(bl); + } } } break; @@ -13199,17 +13177,6 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id } } break; - /** - * Keeping as a note: - * Bug Report #17 provides a link to a sep-2011 changelog that shows this requirement was removed - **/ - //case AB_LAUDAAGNUS: - //case AB_LAUDARAMUS: - // if( !sd->status.party_id ) { - // clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - // return 0; - // } - // break; case AB_ADORAMUS: /** @@ -13326,20 +13293,17 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id } break; case LG_RAYOFGENESIS: + case LG_HESPERUSLIT: if( sc && sc->data[SC_INSPIRATION] ) return 1; // Don't check for partner. if( !(sc && sc->data[SC_BANDING]) ) { clif->skill_fail(sd,skill_id,USESKILL_FAIL,0); return 0; - } else if( skill->check_pc_partner(sd,skill_id,&skill_lv,skill->get_range(skill_id,skill_lv),0) < 1 ) + } + if( sc->data[SC_BANDING] && + sc->data[SC_BANDING]->val2 < (skill_id == LG_RAYOFGENESIS ? 2 : 3) ) return 0; // Just fails, no msg here. break; - case LG_HESPERUSLIT: - if( !sc || !sc->data[SC_BANDING] ) { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - return 0; - } - break; case SR_FALLENEMPIRE: if( sc && sc->data[SC_COMBOATTACK] ) { if( sc->data[SC_COMBOATTACK]->val1 == SR_DRAGONCOMBO ) @@ -13397,6 +13361,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id return 0; } break; + case NC_HOVERING: + if (( sd->equip_index[EQI_ACC_L] >= 0 && sd->status.inventory[sd->equip_index[EQI_ACC_L]].nameid == ITEMID_HOVERING_BOOSTER ) || + ( sd->equip_index[EQI_ACC_R] >= 0 && sd->status.inventory[sd->equip_index[EQI_ACC_R]].nameid == ITEMID_HOVERING_BOOSTER )); + else { + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + return 0; + } + break; case SO_FIREWALK: case SO_ELECTRICWALK: // Can't be casted until you've walked all cells. if( sc && sc->data[SC_PROPERTYWALK] && @@ -13468,7 +13440,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id } break; case ST_RIDING: - if(!pc_isriding(sd) && !pc_isridingdragon(sd)) { + if (!pc_isridingpeco(sd) && !pc_isridingdragon(sd)) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } @@ -13583,7 +13555,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id return 0; } case ST_PECO: - if(!pc_isriding(sd)) { + if (!pc_isridingpeco(sd)) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } @@ -14336,9 +14308,8 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 break; } for( i = 0; i < ARRAYLENGTH(sd->skillfixcastrate) && sd->skillfixcastrate[i].id; i++ ) - if( sd->skillfixcastrate[i].id == skill_id ){ // bonus2 bFixedCastrate - fixcast_r = sd->skillfixcastrate[i].val; // just speculation + fixcast_r = sd->skillfixcastrate[i].val; break; } } @@ -15000,7 +14971,7 @@ int skill_frostjoke_scream(struct block_list *bl, va_list ap) { return 0; if (bl->type == BL_PC) { struct map_session_data *sd = (struct map_session_data *)bl; - if ( sd && sd->sc.option&(OPTION_INVISIBLE|OPTION_MADOGEAR) ) + if (sd && (pc_isinvisible(sd) || pc_ismadogear(sd))) return 0;//Frost Joke / Scream cannot target invisible or MADO Gear characters [Ind] } //It has been reported that Scream/Joke works the same regardless of woe-setting. [Skotlex] @@ -15282,9 +15253,10 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) { break; } break; + case WZ_ICEWALL: case HP_BASILICA: - if (su->group->skill_id == HP_BASILICA) { - //Basilica can't be placed on top of itself to avoid map-cell stacking problems. [Skotlex] + if (su->group->skill_id == skill_id) { + //These can't be placed on top of themselves (duration can't be refreshed) (*alive) = 0; return 1; } @@ -15602,7 +15574,6 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int map->setgatcell(su->bl.m,su->bl.x,su->bl.y,5); clif->changemapcell(0,su->bl.m,su->bl.x,su->bl.y,5,AREA); skill->unitsetmapcell(su,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,true); - map->list[su->bl.m].icewall_num++; break; case SA_LANDPROTECTOR: skill->unitsetmapcell(su,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,true); @@ -15651,10 +15622,10 @@ int skill_delunit (struct skill_unit* su) { } break; case WZ_ICEWALL: + map->list[su->bl.m].setcell(su->bl.m, su->bl.x, su->bl.y, CELL_NOICEWALL, false); map->setgatcell(su->bl.m,su->bl.x,su->bl.y,su->val2); clif->changemapcell(0,su->bl.m,su->bl.x,su->bl.y,su->val2,ALL_SAMEMAP); // hack to avoid clientside cell bug skill->unitsetmapcell(su,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false); - map->list[su->bl.m].icewall_num--; // AS_CLOAKING in low levels requires a wall to be cast, thus it needs to be // checked again when a wall disapears! issue:8182 [Panikon] map->foreachinarea(skill->check_cloaking_end, su->bl.m, @@ -15802,7 +15773,7 @@ int skill_delunitgroup(struct skill_unit_group *group, const char* file, int lin return 0; } - if( !status->isdead(src) && ((TBL_PC*)src)->state.warping && !((TBL_PC*)src)->state.changemap ) { + if( src->type == BL_PC && !status->isdead(src) && ((TBL_PC*)src)->state.warping && !((TBL_PC*)src)->state.changemap ) { switch( group->skill_id ) { case BA_DISSONANCE: case BA_POEMBRAGI: @@ -17525,12 +17496,12 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick) } else { int i; - for(i = 0; i < MAX_SKILL_TREE; i++) { + for(i = 0; i < cd->cursor; i++) { if( cd->entry[i] && cd->entry[i]->skidx == idx ) break; } - if( i != MAX_SKILL_TREE ) {/* duplicate, update necessary */ + if( i != cd->cursor ) {/* duplicate, update necessary */ cd->entry[i]->duration = tick; #if PACKETVER >= 20120604 cd->entry[i]->total = tick; @@ -18600,7 +18571,7 @@ int do_init_skill(bool minimal) { skill->unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); skill->timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE|ERS_OPT_FLEX_CHUNK); skill->cd_ers = ers_new(sizeof(struct skill_cd),"skill.c::skill_cd_ers",ERS_OPT_CLEAR|ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); - skill->cd_entry_ers = ers_new(sizeof(struct skill_cd_entry),"skill.c::skill_cd_entry_ers",ERS_OPT_CLEAR|ERS_OPT_FLEX_CHUNK); + skill->cd_entry_ers = ers_new(sizeof(struct skill_cd_entry),"skill.c::skill_cd_entry_ers",ERS_OPT_CLEAR|ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); ers_chunk_size(skill->cd_ers, 25); ers_chunk_size(skill->cd_entry_ers, 100); @@ -18806,7 +18777,6 @@ void skill_defaults(void) { skill->frostjoke_scream = skill_frostjoke_scream; skill->greed = skill_greed; skill->destroy_trap = skill_destroy_trap; - skill->icewall_block = skill_icewall_block; skill->unitgrouptickset_search = skill_unitgrouptickset_search; skill->dance_switch = skill_dance_switch; skill->check_condition_char_sub = skill_check_condition_char_sub; |