viewing paste Unknown #5686 | Diff

Posted on the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
--- 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;
Viewed 713 times, submitted by lighta.