--- C:/Users/Benjamin/AppData/Local/Temp/skil-revBASE.svn003.tmp.c Mi Apr 17 19:57:44 2013 +++ C:/Users/Benjamin/Desktop/RO/rathena/src/map/skill.c Mi Apr 17 19:54:23 2013 @@ -59,6 +59,7 @@ #endif static struct eri *skill_unit_ers = NULL; //For handling skill_unit's [Skotlex] static struct eri *skill_timer_ers = NULL; //For handling skill_timerskills [Skotlex] +static DBMap* bowling_db = NULL; // int mob_id -> struct mob_data* DBMap* skillunit_db = NULL; // int id -> struct skill_unit* @@ -1074,7 +1075,7 @@ break; case NPC_MENTALBREAKER: { //Based on observations by Tharis, Mental Breaker should do SP damage - //equal to Matk*skLevel. + //equal to Matk*skLevel. rate = sstatus->matk_min; if (rate < sstatus->matk_max) rate += rnd()%(sstatus->matk_max - sstatus->matk_min); @@ -1138,7 +1139,7 @@ break; default: sc_start2(src,bl,SC_BLEEDING,(5+skill_lv*5),skill_lv,src->id,skill_get_time2(skill_id,3)); - } + } break; case HW_NAPALMVULCAN: @@ -3947,28 +3948,45 @@ case KN_BOWLINGBASH: case MS_BOWLINGBASH: - if(flag&1){ - if(bl->id==skill_area_temp[1]) - break; - //two hits for 500% + if(!(flag&1)){ + // Create an empty list of already hit targets + db_clear(bowling_db); + // Blowcount of bowling bash determines if the skill should chain further + skill_area_temp[2] = skill_get_blewcount(skill_id,skill_lv); + if(!skill_blown(src,bl,1,(unit_getdir(src)+4)%8,0x1)) + skill_area_temp[2] = 0; // No chain reaction when knockback not possible + // Chain reaction requires to have at least one monster in a 3x3 range around the target cell + skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill_area_sub_count); + clif_blown(bl); // Update target pos. + if(skill_area_temp[0] > 0) { // Splash if ennemys + // Add original target to the list of already hit targets + idb_put(bowling_db, bl->id, id); + map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); + } + // Two hits skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,SD_ANIMATION); skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,SD_ANIMATION); db_clear(bowling_db); } else { //recursive part - int i,c; - c = skill_get_blewcount(skill_id,skill_lv); - // keep moving target in the direction that src is looking, square by square - for(i=0;ix)%40 == 0 || (bl->y)%40 == 0) + break; + // Ignore monsters already in list + if(idb_exists(bowling_db, bl->id)) + break; + // Add current target to the list of already hit targets + idb_put(bowling_db, bl->id, id); + // Chain reaction when not close to gutter line and knockback possible + if((bl->x)%40 >= 5 && (bl->y)%40 >= 5 && skill_area_temp[2] > 0) { + if (!skill_blown(src,bl,1,rand()%8,0x1)) + skill_area_temp[2] = 0; // No chain reaction when knockback not possible + // Chain reaction requires to have at least one monster in a 3x3 range around the target cell skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill_area_sub_count); - if( skill_area_temp[0] > 1 ) break; // collision + clif_blown(bl); // Update target pos. + if (skill_area_temp[0] > 0) { // Splash + map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); + } } - clif_blown(bl); //Update target pos. - if (i!=c) { //Splash - skill_area_temp[1] = bl->id; - map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - } - //Weirdo dual-hit property, two attacks for 500% + // Two hits skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,0); skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,0); } @@ -11185,7 +11203,7 @@ //success, unit created. switch( skill_id ) { case WZ_ICEWALL: - map_foreachinrange(skill_icewall_block, src, AREA_SIZE, BL_MOB); + //map_foreachinrange(skill_icewall_block, src, AREA_SIZE, BL_MOB); break; case NJ_TATAMIGAESHI: //Store number of tiles. group->val1 = group->alive_count; @@ -18141,6 +18159,7 @@ skillunit_db = idb_alloc(DB_OPT_BASE); skillcd_db = idb_alloc(DB_OPT_RELEASE_DATA); skillusave_db = idb_alloc(DB_OPT_RELEASE_DATA); + bowling_db = idb_alloc(DB_OPT_BASE); skill_unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE); skill_timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE); @@ -18162,6 +18181,7 @@ db_destroy(skillunit_db); db_destroy(skillcd_db); db_destroy(skillusave_db); + db_destroy(bowling_db); ers_destroy(skill_unit_ers); ers_destroy(skill_timer_ers); return 0;