--- 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;i<c;i++){
- if (!skill_blown(src,bl,1,(unit_getdir(src)+4)%8,0x1))
- break; //Can't knockback
+ // No damage when exactly on gutter line
+ if((bl->x)%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;