Browse Source

-upd homonS skills with Yommy leak infos, thx !
-fix summon_legion multiple spawn exploit and set summon stats.
-fix MH_LIGHT_OF_REGENE being broken since eleanor upd (typo)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17213 54d463be-8e91-2dee-dedb-b68131a5f0ec

glighta 12 years ago
parent
commit
dad4da7241
6 changed files with 149 additions and 113 deletions
  1. 14 14
      db/re/skill_cast_db.txt
  2. 25 22
      src/map/battle.c
  3. 1 0
      src/map/mob.h
  4. 40 26
      src/map/skill.c
  5. 67 49
      src/map/status.c
  6. 2 2
      src/map/status.h

+ 14 - 14
db/re/skill_cast_db.txt

@@ -1730,45 +1730,45 @@
 //-- MH_OVERED_BOOST
 8023,800:700:600:500:400,0,0,30000:45000:60000:75000:90000,0,0,200:300:400:500:600
 //-- MH_ERASER_CUTTER
-8024,1000:1500:2000:2500:3000,0,0,0,0,0,-1
+8024,1000:1500:2000:2500:3000,2000,0,0,0,0,-1
 //-- MH_XENO_SLASHER
-8025,1500:2500:3500:4500:5500,0,0,500,0,0,500
+8025,1500:2500:3500:4500:5500,0,0,500,120000,0,500
 //-- MH_SILENT_BREEZE
 8026,2000,0,0,9000:12000:15000:18000:21000,0,0,1000:800:600:400:200
 //-- MH_STYLE_CHANGE
-8027,0,0,0,0,0,0,0
+8027,0,1000,0,0,0,0,500
 //-- MH_SONIC_CRAW
 //8028,0,0,0,0,0,0,0
 //-- MH_SILVERVEIN_RUSH
-//8029,0,0,0,0,0,0,0
+8029,0,0,0,5000,0,2000,0
 //-- MH_MIDNIGHT_FRENZY
-//8030,0,0,0,0,0,0,0
+8030,0,0,0,10000,0,2000,0
 //-- MH_STAHL_HORN 
-8031,800:600:400:200:0,0,0,5000,0,0,200:400:600:800:1000
+8031,800:600:400:200:0,3000,0,5000,0,0,200:400:600:800:1000
 //-- MH_GOLDENE_FERSE
 8032,1000:1200:1400:1600:1800,0,0,30000:45000:60000:75000:90000,0,0,-1
 //-- MH_STEINWAND
 8033,1000,0,0,30000:45000:60000:75000:90000,0,0,-1
 //-- MH_HEILIGE_STANGE
-8034,200:400:600:800:1000,0,0,0,0,0,1800:1600:1400:1200:1000
+8034,200:400:600:800:1000,5000,0,0,0,0,1800:1600:1400:1200:1000
 //-- MH_ANGRIFFS_MODUS
 8035,200:400:600:800:1000,0,0,30000:45000:60000:75000:90000,0,0,-1
 //-- MH_TINDER_BREAKER
-8036,0,0,0,5000,0,0,0
+8036,1000,0,0,5000,0,0,0
 //-- MH_CBC
 8037,0,0,0,0,0,0,0
 //-- MH_EQC
-8038,0,0,0,0,0,0,0
+8038,0,1000,0,0,0,0,0
 //-- MH_MAGMA_FLOW
-8039,2000:2500:3000:3500:4000,0,0,30000:45000:60000:75000:90000,0,0,2000:1500:1000:500:-1
+8039,2000:2500:3000:3500:4000,1000,0,30000:45000:60000:75000:90000,0,0,2000:1500:1000:500:-1
 //-- MH_GRANITIC_ARMOR
-8040,6000:5500:5000:4500:4000,0,0,60000,0,0,1000
+8040,5000:4500:4000:3500:3000,1000,0,60000,0,0,1000
 //-- MH_LAVA_SLIDE
-8041,6000:5500:5000:4500:4000,0,0,12000:14000:16000:18000:20000,0,0,1000
+8041,5000:4500:4000:3500:3000,1000,0,12000:14000:16000:18000:20000,10000,0,1000
 //-- MH_PYROCLASTIC
-8042,5000:4500:4000:3500:3000,0,0,60000:90000:120000:150000:180000,0,0,1000
+8042,1000:1500:2000:2500:3000,1000,0,60000:90000:120000:150000:180000,0,0,200
 //-- MH_VOLCANIC_ASH
-8043,5000:4500:4000:3500:3000,0,0,12000:14000:16000:18000:20000,0,0,1000
+8043,4000:3500:3000:2500:2000,0,0,12000:14000:16000:18000:20000,0,0,1000
 
 //===== Mercenary Skills ===================
 //-- MS_MAGNUM

+ 25 - 22
src/map/battle.c

@@ -803,15 +803,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 			struct skill_unit_group* group = skill_id2group(sc->data[SC_SAFETYWALL]->val3);
 			uint16 skill_id = sc->data[SC_SAFETYWALL]->val2;
 			if (group) {
-				if(skill_id == MH_STEINWAND){
-				    if (--group->val2<=0)
-					    skill_delunitgroup(group);
-				    d->dmg_lv = ATK_BLOCK;
-				    return 0;
-				}
-				/**
-				 * in RE, SW possesses a lifetime equal to 3 times the caster's health
-				 **/
+			//in RE, SW possesses a lifetime equal to group val2, (3x caster hp, or homon formula)
 			#ifdef RENEWAL
 				d->dmg_lv = ATK_BLOCK;
 				if ( ( group->val2 - damage) > 0 ) {
@@ -1059,7 +1051,8 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 			DAMAGE_SUBRATE(sc->data[SC_GRANITIC_ARMOR]->val2)
 		}
 		if(sc->data[SC_PAIN_KILLER]){
-			DAMAGE_SUBRATE(sc->data[SC_PAIN_KILLER]->val3)
+			damage -= sc->data[SC_PAIN_KILLER]->val3;
+			damage = max(0,damage);
 		}
 		if((sce=sc->data[SC_MAGMA_FLOW]) && (rnd()%100 <= sce->val2) ){
 			skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
@@ -1137,9 +1130,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 
 		if( sd && (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2 )
 			pc_addspiritball(sd,skill_get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
-		if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
-                    TBL_HOM *hd = BL_CAST(BL_HOM,bl);
-                    if (hd) hom_addspiritball(hd, 10); //add a sphere
+		if (sc->data[SC_STYLE_CHANGE]) {
+                    TBL_HOM *hd = BL_CAST(BL_HOM,bl); //when being hit
+                    if (hd && (rnd()%100<(status_get_lv(bl)/2)) ) hom_addspiritball(hd, 10); //add a sphere
                 }
 
 		if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
@@ -1200,9 +1193,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 			sc_start(src,bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1));
 		if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
 			status_change_spread(src, bl);
-                if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
-                    TBL_HOM *hd = BL_CAST(BL_HOM,src);
-                    if (hd) hom_addspiritball(hd, 10);
+                if (sc->data[SC_STYLE_CHANGE]) {
+                    TBL_HOM *hd = BL_CAST(BL_HOM,src); //when attacking
+                    if (hd && (rnd()%100<(20+status_get_lv(bl)/5)) ) hom_addspiritball(hd, 10);
                 }
 	}
 
@@ -2974,23 +2967,32 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 					skillratio += 600 + 100 * skill_lv;
 					break;
 				case MH_STAHL_HORN:
-					skillratio += 400 + 100 * skill_lv;
+					skillratio += 400 + 100 * skill_lv * status_get_lv(src);
+					skillratio = skillratio/100; //@TODO uv1 factor need to be confirmed
 					break;
 				case MH_LAVA_SLIDE:
 					skillratio += -100 + 70 * skill_lv;
 					break;
 				case MH_SONIC_CRAW:
-					skillratio += -100 + 40 * skill_lv;
+					skillratio += -100 + 40 * skill_lv * status_get_lv(src);
+					skillratio = skillratio/100; //@TODO uv1 factor need to be confirmed
 					break;
 				case MH_SILVERVEIN_RUSH:
-					skillratio += -100 + 150 * skill_lv;
+					skillratio += -100 + (150 * skill_lv * status_get_lv(src)) / 100;
 					break;
 				case MH_MIDNIGHT_FRENZY:
-					skillratio += -100 + 300 * skill_lv;
+					skillratio += -100 + (300 * skill_lv * status_get_lv(src)) / 150;
 					break;
 				case MH_TINDER_BREAKER:
+					skillratio += -100 + (100 * skill_lv + status_get_str(src));
+					skillratio = (skillratio * status_get_lv(src)) / 120;
+					break;
+				case MH_CBC:
+					skillratio += 300 * skill_lv + 4 * status_get_lv(src);
+					break;
 				case MH_MAGMA_FLOW:
-					skillratio += -100 + 100 * skill_lv;
+					skillratio += -100 + 100 * skill_lv + 3 * status_get_lv(src);
+					skillratio = (skillratio * status_get_lv(src)) / 120;
 					break;
 			}
 #ifdef RENEWAL
@@ -4111,9 +4113,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						break;
 					case MH_HEILIGE_STANGE:
 						skillratio += 400 + 250 * skill_lv;
+						skillratio = (skillratio * status_get_lv(src))/150;
 						break;
 					case MH_POISON_MIST:
-						skillratio += 100 * skill_lv;
+						skillratio += -100 + 40 * skill_lv * status_get_lv(src) / 100;
 						break;
 				}
 

+ 1 - 0
src/map/mob.h

@@ -135,6 +135,7 @@ struct mob_data {
 							//2: Alchemist Marine Sphere
 							//3: Alchemist Summon Flora
 							//4: Summon Zanzou
+							//5: Summon Legion
 		unsigned int clone : 1;/* is clone? 1:0 */
 	} special_state; //Special mob information that does not needs to be zero'ed on mob respawn.
 	struct {

+ 40 - 26
src/map/skill.c

@@ -122,6 +122,7 @@ int skill_block_check(struct block_list *bl, enum sc_type type, uint16 skill_id)
 static int skill_check_unit_range (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
 static int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
 static int skill_destroy_trap( struct block_list *bl, va_list ap );
+static int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap);
 //Since only mob-casted splash skills can hit ice-walls
 static inline int splash_target(struct block_list* bl)
 {
@@ -664,7 +665,7 @@ int skillnotok_hom(uint16 skill_id, struct homun_data *hd)
 		if(hd->homunculus.hunger <= 1) //if we starving
 		    return 1;
 		break;
-	    case MH_GOLDENE_FERSE: //can be used with angriff
+	    case MH_GOLDENE_FERSE: //cant be used with angriff
 		if(hd->sc.data[SC_ANGRIFFS_MODUS])
 		    return 1;
 		break;
@@ -933,7 +934,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
 						(2000 - 4*sstatus->agi - 2*sstatus->dex));
 				}
 			}
-			if(sc && sc->data[SC_PYROCLASTIC] && (rnd() % 1000 <= sstatus->luk * 10 / 3 + 1) )
+			if(sc && sc->data[SC_PYROCLASTIC] && ((rnd()%100)<=sc->data[SC_PYROCLASTIC]->val3) )
 				skill_castend_pos2(src, bl->x, bl->y, BS_HAMMERFALL,sc->data[SC_PYROCLASTIC]->val1, tick, 0);
 		}
 
@@ -1489,8 +1490,14 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
 	case MH_SILVERVEIN_RUSH:
 		sc_start4(src,bl,SC_STUN,20 + (5*skill_lv),skill_lv,src->id,0,0,skill_get_time(skill_id,skill_lv));
 		break;
-	case MH_MIDNIGHT_FRENZY:
-		sc_start4(src,bl,SC_FEAR,20 + (4*skill_lv),skill_lv,src->id,0,0,skill_get_time(skill_id,skill_lv));
+	case MH_MIDNIGHT_FRENZY: {
+		TBL_HOM *hd = BL_CAST(BL_HOM,src);
+		int spiritball = (hd?hd->homunculus.spiritball:1);
+		sc_start4(src,bl,SC_FEAR,spiritball*(10+2*skill_lv),skill_lv,src->id,0,0,skill_get_time(skill_id,skill_lv));
+		break;
+	}
+	case MH_XENO_SLASHER:
+		sc_start4(src,bl,SC_BLEEDING,skill_lv,skill_lv,src->id,0,0,skill_get_time2(skill_id,skill_lv)); //@TODO need real duration
 		break;
 	}
 
@@ -4700,10 +4707,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 
 	//recursive homon skill
 	case MH_MAGMA_FLOW:
-	case MH_XENO_SLASHER:
 	case MH_HEILIGE_STANGE:
-		if(flag & 1)
+		if(flag & 1){
+		    if((skill_id == MH_MAGMA_FLOW) && ((rnd()%100)>(3*skill_lv)) ) break;//chance to not trigger atk for magma
 		    skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+		}
 		else {
 		    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 | SD_SPLASH | 1, skill_castend_damage_id);
 		}
@@ -4721,7 +4729,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	case MH_EQC: {
 		TBL_HOM *hd = BL_CAST(BL_HOM,src);
 		int8 k=0;
-		int duration;
+		int duration=0;
 		struct status_change_entry *sce;
 		struct block_list *tbl = NULL; //target
 
@@ -4759,17 +4767,15 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 				clif_skill_poseffect(src,skill_id,skill_lv,bl->x,bl->y,tick);
 #endif
 			}
-
 		    case MH_CBC:
 		    case MH_EQC:
-			    duration = (status_get_str(src)*2 - status_get_str(bl))/10;//custom need real formula
+			    duration = max(skill_lv,(status_get_str(src)/7 - status_get_str(bl)/10))*1000; //Yommy formula
 			    hom_delspiritball(hd,skill_id==MH_EQC?2:1,0); //only EQC consume 2 in grp 2
 			    if(skill_id==MH_TINDER_BREAKER)
 				sc_start2(src,src,status_skill2sc(skill_id),100,skill_lv,bl->id,duration);
 			    else
 				sc_start(src,bl,status_skill2sc(skill_id),100,skill_lv,duration);
 			    skill_attack(skill_get_type(skill_id),src,src,tbl,skill_id,skill_lv,tick,flag);
-			    //TODO add bonus for dmg SP ? on battle
 			    break;
 		}
 		break;
@@ -9136,7 +9142,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
                 if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target
                         status_change_start(src,bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill_get_time(skill_id, skill_lv),1|2|8);
 	    }
-	    heal = status_get_matk_min(src)*4;
+	    heal = status_get_sp(src) + status_get_lv(src); //cur_sp+blvl @TODO need real value
             status_heal(bl, heal, 0, 7);
 
 	    //now inflict silence on everyone
@@ -9176,12 +9182,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
             }
             break;
 
-        case MH_LIGHT_OF_REGENE:
+        case MH_LIGHT_OF_REGENE: //self
+		sc_start2(src, src, type, 100, skill_lv, hd->homunculus.level, skill_get_time(skill_id, skill_lv));
 		if(hd){
 		    hd->homunculus.intimacy = 251; //change to neutral (can't be cast if < 750)
 		    if(sd) clif_send_homdata(sd, SP_INTIMATE, hd->homunculus.intimacy); //refresh intimacy info
+		    skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 		}
-		//don't break need to start status and start block timer
+		break;
 	case MH_STYLE_CHANGE: {
 	    struct status_change_entry *sce;
 	    if(hd && (sce=hd->sc.data[SC_STYLE_CHANGE])){ //in preparation for other bl usage
@@ -9208,13 +9216,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
                 int summons[5] = {2158, 2159, 2159, 2160, 2160};
                 int qty[5] =     {3   , 3   , 4   , 4   , 5};
                 struct mob_data *sum_md;
-                int i;
+                int i,c=0;
+
+		int maxcount = qty[skill_lv-1];
+		i = map_foreachinmap(skill_check_condition_mob_master_sub ,hd->bl.m, BL_MOB, hd->bl.id, summons[skill_lv-1], skill_id, &c);
+		if(c >= maxcount) return 0; //max qty already spawned
 
                 for(i=0; i<qty[skill_lv - 1]; i++){ //easy way
                     sum_md = mob_once_spawn_sub(src, src->m, src->x, src->y, status_get_name(src), summons[skill_lv - 1], "", SZ_SMALL, AI_ATTACK);
                     if (sum_md) {
                         sum_md->master_id =  src->id;
-			sum_md->special_state.ai = 1;
+			sum_md->special_state.ai = 5;
                         if (sum_md->deletetimer != INVALID_TIMER)
                             delete_timer(sum_md->deletetimer, mob_timer_delete);
                         sum_md->deletetimer = add_timer(gettick() + skill_get_time(skill_id, skill_lv), mob_timer_delete, sum_md->bl.id, 0);
@@ -10759,14 +10771,12 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
 
 	switch( skill_id ) {
 	case MH_STEINWAND:
-	    val2 = 4 + skill_lv; //nb of attack blocked
-	    break;
 	case MG_SAFETYWALL:
 	#ifdef RENEWAL
-		/**
-		 * According to data provided in RE, SW life is equal to 3 times caster's health
-		 **/
-		val2 = status_get_max_hp(src) * 3;
+		if(skill_id == MH_STEINWAND)
+			val2 = 300 * skill_lv + 65 * ( status->int_ +  status_get_lv(src) ) + status->max_sp; //nb hp
+		else
+			val2 = status_get_max_hp(src) * 3;
 	#else
 		val2 = skill_lv+1;
 	#endif
@@ -12141,7 +12151,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 			break;
 		case UNT_POISON_MIST:
 			skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
-			status_change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 2|8);
+			status_change_start(ss, bl, SC_BLIND, (10 + 10 * sg->skill_lv)*100, sg->skill_lv, sg->skill_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 2|8);
 			break;
 	}
 
@@ -12544,11 +12554,14 @@ int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, short*
 }
 
 /*==========================================
- *
+ * Sub function to count how many spawned mob is around
+ * return :
+ *  x : numbers of mob of class with special ai
  *------------------------------------------*/
 static int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap)
 {
 	int *c,src_id,mob_class,skill;
+	uint16 ai;
 	struct mob_data *md;
 
 	md=(struct mob_data*)bl;
@@ -12557,7 +12570,8 @@ static int skill_check_condition_mob_master_sub (struct block_list *bl, va_list
 	skill=va_arg(ap,int);
 	c=va_arg(ap,int *);
 
-	if( md->master_id != src_id || md->special_state.ai != (unsigned)(skill == AM_SPHEREMINE?2:skill == KO_ZANZOU?4:3) )
+	ai = (unsigned)(skill == AM_SPHEREMINE?2:skill == KO_ZANZOU?4:skill == MH_SUMMON_LEGION?5:3);
+	if( md->master_id != src_id || md->special_state.ai != ai)
 		return 0; //Non alchemist summoned mobs have nothing to do here.
 
 	if(md->class_==mob_class)
@@ -13509,10 +13523,10 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
 				if( c >= skill_get_maxcount(skill_id,skill_lv) || c != i)
 				{
 					clif_skill_fail(sd , skill_id, USESKILL_FAIL_LEVEL, 0);
-					return 0;
-				}
+				return 0;
 			}
 			break;
+		}
 	}
 	status = &sd->battle_status;
 

+ 67 - 49
src/map/status.c

@@ -494,9 +494,8 @@ void initChangeTables(void) {
 	// Homunculus S
 	add_sc(MH_STAHL_HORN, SC_STUN);
 	set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SI_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
-	set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE,  SCB_ASPD|SCB_MAXHP);
+	set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE,  SCB_ASPD|SCB_FLEE);
 	add_sc( MH_STEINWAND, SC_SAFETYWALL );
-	add_sc(MH_ERASER_CUTTER, SC_ERASER_CUTTER);
 	set_sc(MH_OVERED_BOOST, SC_OVERED_BOOST, SI_BLANK, SCB_FLEE|SCB_ASPD);
 	add_sc(MH_LIGHT_OF_REGENE, SC_LIGHT_OF_REGENE);
 	set_sc(MH_VOLCANIC_ASH, SC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
@@ -511,7 +510,7 @@ void initChangeTables(void) {
 	add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
 	set_sc(MH_TINDER_BREAKER, SC_TINDER_BREAKER, SI_TINDER_BREAKER, SCB_FLEE);
 	set_sc(MH_CBC, SC_CBC, SI_CBC, SCB_FLEE);
-	set_sc(MH_EQC, SC_EQC, SI_EQC, SCB_DEF2|SCB_BATK);
+	set_sc(MH_EQC, SC_EQC, SI_EQC, SCB_DEF2|SCB_BATK|SCB_MAXHP);
 
 	add_sc( MER_CRASH            , SC_STUN            );
 	set_sc( MER_PROVOKE          , SC_PROVOKE         , SI_PROVOKE         , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
@@ -1320,7 +1319,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
         TBL_HOM *hd = sd->hd;
         if(hd && hd->sc.data[SC_LIGHT_OF_REGENE]){
             clif_skillcasting(&hd->bl, hd->bl.id, target->id, 0,0, MH_LIGHT_OF_REGENE, skill_get_ele(MH_LIGHT_OF_REGENE, 1), 10); //just to display usage
-            clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,10*hd->sc.data[SC_LIGHT_OF_REGENE]->val1,0));
+            clif_skill_nodamage(&sd->bl, target, ALL_RESURRECTION, 1, status_revive(&sd->bl,hd->sc.data[SC_LIGHT_OF_REGENE]->val2,0));
             status_change_end(&sd->hd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER);
             return hp + sp;
         }
@@ -2040,13 +2039,26 @@ int status_calc_mob_(struct mob_data* md, bool first)
 			md->special_state.ai = 0;
 		if (ud)
 		{	// different levels of HP according to skill level
-			if (ud->skill_id == AM_SPHEREMINE) {
-				status->max_hp = 2000 + 400*ud->skill_lv;
-			} else if(ud->skill_id == KO_ZANZOU){
-				status->max_hp = 3000 + 3000 * ud->skill_lv;
-			} else { //AM_CANNIBALIZE
-				status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
-				status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
+			switch(ud->skill_id){
+				case AM_SPHEREMINE:
+				    status->max_hp = 2000 + 400*ud->skill_lv;
+				    break;
+				case KO_ZANZOU:
+				    status->max_hp = 3000 + 3000 * ud->skill_lv;
+				    break;
+				case AM_CANNIBALIZE:
+				    status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
+				    status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
+				    break;
+				case MH_SUMMON_LEGION:{
+				    int homblvl = status_get_lv(mbl);
+				    status->max_hp = 10 * (100 * (ud->skill_lv + 2) + homblvl);
+				    status->batk = 100 * (ud->skill_lv+5) / 2;
+				    status->def = 10 * (100 * (ud->skill_lv+2) + homblvl);
+				//    status->aspd_rate = 10 * (2 * (20 - ud->skill_lv) - homblvl/10);
+				//    status->aspd_rate = max(100,status->aspd_rate);
+				    break;
+				}
 			}
 			status->hp = status->max_hp;
 		}
@@ -4525,10 +4537,8 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 		batk += sc->data[SC_FULL_SWING_K]->val1;
 	if(sc->data[SC_ODINS_POWER])
 		batk += 70;
-	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
-		if(status_get_element(bl) == ELE_WATER) //water type
-			batk /= 2;
-	}
+	if(sc->data[SC_ASH])
+		batk -= batk * sc->data[SC_ASH]->val4 / 100;
 	if(sc->data[SC_PYROCLASTIC])
 		batk += sc->data[SC_PYROCLASTIC]->val2;
 	if (sc->data[SC_ANGRIFFS_MODUS])
@@ -4786,7 +4796,7 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
 	if(sc->data[SC_FEAR])
 		hit -= hit * 20 / 100;
 	if (sc->data[SC_ASH])
-		hit /= 2;
+		hit -= (hit * sc->data[SC_ASH]->val2) / 100;
 
 	return (short)cap_value(hit,1,SHRT_MAX);
 }
@@ -4867,10 +4877,10 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
 		flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
 	if( sc->data[SC_ZEPHYR] )
 		flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
-	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){ //mob
-		if(status_get_element(bl) == ELE_WATER) //water type
-			flee /= 2;
-	}
+	if(sc->data[SC_ASH])
+		flee -= flee * sc->data[SC_ASH]->val4 / 100;
+	if (sc->data[SC_GOLDENE_FERSE])
+		flee += flee * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
 
 	return (short)cap_value(flee,1,SHRT_MAX);
 }
@@ -4957,10 +4967,10 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
 		def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
 	if( sc->data[SC_PRESTIGE] )
 		def += def * sc->data[SC_PRESTIGE]->val1 / 100;
-	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
-		if(status_get_race(bl)==RC_PLANT)
-			def /= 2;
-	}
+	if(sc->data[SC_ASH])
+		def -= def * sc->data[SC_ASH]->val3/100;
+	if( sc->data[SC_OVERED_BOOST] )
+		def -= def * sc->data[SC_OVERED_BOOST]->val3 / 100;
 
 	return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
 }
@@ -5012,10 +5022,8 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
 		def2 -= def2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
 	if( sc->data[SC_ECHOSONG] )
 		def2 += def2 * sc->data[SC_ECHOSONG]->val2/100;
-	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
-		if(status_get_race(bl)==RC_PLANT)
-			def2 /= 2;
-	}
+	if(sc->data[SC_ASH])
+		def2 -= def2 * sc->data[SC_ASH]->val3/100;
 	if (sc->data[SC_PARALYSIS])
 		def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
 	if(sc->data[SC_EQC])
@@ -5628,8 +5636,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
 		maxhp += maxhp * sc->data[SC_PETROLOGY_OPTION]->val2 / 100;
 	if (sc->data[SC_ANGRIFFS_MODUS])
 		maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
-	if (sc->data[SC_GOLDENE_FERSE])
-		maxhp += maxhp * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
+	if(sc->data[SC_EQC])
+		maxhp -= maxhp * sc->data[SC_EQC]->val4 / 100;
 
 	return (unsigned int)cap_value(maxhp,1,UINT_MAX);
 }
@@ -6209,7 +6217,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
 	struct map_session_data *sd;
 
 	nullpo_ret(bl);
-	nullpo_retr(tick?tick:1, src); //If no source, it can't be resisted (NPC given)
+	if(src==NULL) return tick?tick:1;//If no source, it can't be resisted (NPC given)
 
 	//Status that are blocked by Golden Thief Bug card or Wand of Hermod
 	if (status_isimmune(bl))
@@ -8681,31 +8689,37 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			    tick_time = 1000;
 			    break;
 			case SC_GOLDENE_FERSE:
-			    val2 = 10 + 10*val1; //max hp bonus
+			    val2 = 10 + 10*val1; //flee bonus
 			    val3 = 6 + 4 * val1; // Aspd Bonus
 			    val4 = 2 + 2 * val1; // Chance of holy attack
 			    break;
 			case SC_OVERED_BOOST:
 			    val2 = 300 + 40*val1; //flee bonus
 			    val3 = 179 + 2*val1; //aspd bonus
+			    val4 = 50; //def reduc %
 			    break;
 			case SC_GRANITIC_ARMOR:
-			    val2 = 2*val1; //dmg reduction
-			    val3 = 6*val1; //dmg on status end
+			    val2 = 2*val1; //dmg hp reduction
+			    val3 = (6*status_get_max_hp(src))/100; //dmg hp on status end
+			    val4 = 5 * val1; //unknow formula
 			    break;
 			case SC_MAGMA_FLOW:
 			    val2 = 3*val1; //activation chance
 			    break;
 			case SC_PYROCLASTIC:
-			    val2 += 10*val1; //atk bonus
+			    val2 += 10*val1*status_get_lv(src); //atk bonus
+			    val3 = 2*val1;//Chance To AutoCast Hammer Fall %
 			    break;
 			case SC_PARALYSIS: //[Lighta] need real info
 			    val2 = 2*val1; //def reduction
 			    val3 = 500*val1; //varcast augmentation
 			    break;
-			case SC_PAIN_KILLER: //[Lighta] need real info
-			    val2 = 2*val1; //aspd reduction %
-			    val3 = 2*val1; //dmg reduction %
+			case SC_LIGHT_OF_REGENE: //Yommy leak need confirm
+			    val2 = 20 * val1; //hp reco on death %
+			    break;
+			case SC_PAIN_KILLER: //Yommy leak need confirm
+			    val2 = 10 * val1; //aspd reduction %
+			    val3 = (( 200 * val1 ) * status_get_lv(src)) / 150; //dmg reduction linear
 			    if(sc->data[SC_PARALYSIS])
 				sc_start(src,bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
 			    break;
@@ -8713,21 +8727,23 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
                             tick = -1;
                             break;
 			case SC_CBC:
-			    val2 = 10; //hp % dmg [not sure]
-			    val3 = 10; //sp % dmg [not sure]
-			    tick = max(tick,5000); //min 5s (test)
+			    val3 = 10; //drain sp % dmg
 			    val4 = tick/1000; //dmg each sec
 			    tick = 1000;
 			    break;
 			case SC_EQC:
-			    val2 = 25; //def % reduc [not sure]
-			    val3 = 25; //atk % reduc [not sure]
-			    tick = max(tick,5000); //min 5s (test)
+			    val2 = 5 * val1; //def % reduc
+			    val3 = 5 * val1; //atk % reduc
+			    val4 = 2 * val1; //maxhp % reduc
 			    break;
-			case SC_TINDER_BREAKER:
-			    //val1 = skilllv
-			    //val2 = src->id
-			    tick = max(tick,5000); //min 5s (test)
+			case SC_ASH:
+			    val2 = 50; //hit % reduc
+			    val3 = 0;//def % reduc
+			    val4 = 0;//atk flee & reduc
+			    if(status_get_race(bl) == RC_PLANT) //plant type
+				val3 = 50;
+			    if(status_get_element(bl) == ELE_WATER) // defense water type
+				val4 = 50;
 			    break;
 		default:
 			if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
@@ -9090,6 +9106,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			sc_start2(src, map_id2bl(val2),SC_CLOSECONFINE2,100,val1,bl->id,tick);
 			break;
 		case SC_EQC:
+			sc_start2(src, bl,SC_STUN,100,val1,bl->id,(1000*status_get_lv(src))/50+500*val1);
 			status_change_end(bl,SC_TINDER_BREAKER,INVALID_TIMER);
 			break;
 	}
@@ -10749,8 +10766,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 		break;
 	case SC_CBC:
 	    if(--(sce->val4) >= 0) { //drain hp/sp
-		int hp = (status->max_hp * sce->val2) / 100;
+		int hp=0;
 		int sp = (status->max_sp * sce->val3) / 100;
+		if(bl->type == BL_MOB) hp = sp*10;
 		if( !status_charge(bl,hp,sp) ) break;
 		sc_timer_next(1000+tick,status_change_timer,bl->id, data);
 		return 0;

+ 2 - 2
src/map/status.h

@@ -634,12 +634,12 @@ typedef enum sc_type {
 
 	//homon S
 	SC_STYLE_CHANGE,
-	SC_TINDER_BREAKER,
+	SC_TINDER_BREAKER, //@TODO rewritte me plz
+	SC_TINDER_BREAKER2, //for rewritte and other icone
 	SC_CBC,
 	SC_EQC,
 	SC_GOLDENE_FERSE,
 	SC_ANGRIFFS_MODUS,
-	SC_ERASER_CUTTER,
 	SC_OVERED_BOOST,
 	SC_LIGHT_OF_REGENE,
 	SC_ASH,