Explorar o código

Old Eleanor work :
-Implement MH_TINDER_BREAKER, STYLE_CHANGE

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

glighta %!s(int64=12) %!d(string=hai) anos
pai
achega
f82e7eb077

+ 1 - 1
db/re/skill_cast_db.txt

@@ -1758,7 +1758,7 @@
 //-- 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,0,0,0,0
+//8036,0,0,0,5000,0,0,0
 //-- MH_CBC
 //8037,0,0,0,0,0,0,0
 //-- MH_EQC

+ 5 - 3
db/re/skill_require_db.txt

@@ -26,6 +26,8 @@
 //  poisonweapon = Requires to be under Poisoning Weapon.
 //  rollingcutter = Requires at least one Rotation Counter from Rolling Cutter.
 //  elementalspirit = Requires to have an Elemental Spirit summoned.
+//  mh_fighting = eleanor fighthing mode
+//  mh_grappling = eleanor grappling mode
 
 5,0,0,8:8:8:8:8:15:15:15:15:15,0,0,0,0:1:2:3:4:5:6:7:8:9:10:12:13:14:15:16:17:18:19:20:21:22,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//SM_BASH#ƒoƒbƒVƒ…#
 6,0,0,4:5:6:7:8:9:10:11:12:13,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//SM_PROVOKE#ƒvƒ�ƒ{ƒbƒN#
@@ -855,7 +857,7 @@
 8025,0,0,90:100:110:120:130,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_XENO_SLASHER#Xeno Slasher#
 8026,0,0,45:54:63:72:81,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_SILENT_BREEZE#Silent Breeze#
 8027,0,0,35,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_STYLE_CHANGE#Style Change#
-8028,0,0,20:25:30:35:40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_SONIC_CRAW#Sonic Claw#
+8028,0,0,20:25:30:35:40,0,0,0,99,0,0,mh_fighting,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_SONIC_CRAW#Sonic Claw#
 8029,0,0,10:15:20:25:30,0,0,0,99,0,0,none,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_SILVERVEIN_RUSH#Silver Bain Rush#
 8030,0,0,8:16:24:32:40,0,0,0,99,0,0,none,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_MIDNIGHT_FRENZY#Midnight Frenzy#
 8031,0,0,40:45:50:55:60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_STAHL_HORN#Steel Horn#
@@ -863,8 +865,8 @@
 8033,0,0,80:90:100:110:120,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_STEINWAND#Stone Wall#
 8034,0,0,60:68:76:84:100,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_HEILIGE_STANGE#Holy Pole#
 8035,0,0,60:65:70:75:80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_ANGRIFFS_MODUS#Attack Mode#
-8036,0,0,20:25:30:35:40,0,0,0,99,0,0,none,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_TINDER_BREAKER#Tinder Breaker#
-8037,0,0,10:20:30:40:50,0,0,0,99,0,0,none,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_CBC#Continual Break Combo#
+8036,0,0,20:25:30:35:40,0,0,0,99,0,0,mh_grappling,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_TINDER_BREAKER#Tinder Breaker#
+8037,0,0,10:20:30:40:50,0,0,0,99,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_CBC#Continual Break Combo#
 8038,0,0,24:28:32:36:40,0,0,0,99,0,0,none,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_EQC#Eternal Quick Combo#
 8039,0,0,34:38:42:46:50,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_MAGMA_FLOW#Magma Flow#
 8040,0,0,54:58:62:66:70,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//MH_GRANITIC_ARMOR#Granitic Armor#

+ 7 - 5
src/common/mmo.h

@@ -51,7 +51,7 @@
 #endif
 
 //Remove/Comment this line to disable sc_data saving. [Skotlex]
-#define ENABLE_SC_SAVING 
+#define ENABLE_SC_SAVING
 //Remove/Comment this line to disable server-side hot-key saving support [Skotlex]
 //Note that newer clients no longer save hotkeys in the registry!
 #define HOTKEY_SAVING
@@ -176,7 +176,7 @@ enum item_types {
 	IT_AMMO,    //10
 	IT_DELAYCONSUME,//11
 	IT_CASH = 18,
-	IT_MAX 
+	IT_MAX
 };
 
 
@@ -292,6 +292,8 @@ struct s_homunculus {	//[orn]
 	int int_ ;
 	int dex ;
 	int luk ;
+
+	char spiritball; //for homun S [lighta]
 };
 
 struct s_mercenary {
@@ -416,7 +418,7 @@ struct auction_data {
 	char seller_name[NAME_LENGTH];
 	int buyer_id;
 	char buyer_name[NAME_LENGTH];
-	
+
 	struct item item;
 	// This data is required for searching, as itemdb is not read by char server
 	char item_name[ITEM_NAME_LENGTH];
@@ -539,7 +541,7 @@ struct fame_list {
 	char name[NAME_LENGTH];
 };
 
-enum { //Change Guild Infos 
+enum { //Change Guild Infos
 	GBI_EXP	=1,		// Guild Experience (EXP)
 	GBI_GUILDLV,		// Guild level
 	GBI_SKILLPOINT,		// Guild skillpoints
@@ -547,7 +549,7 @@ enum { //Change Guild Infos
 };
 
 enum { //Change Member Infos
-	GMI_POSITION	=0,		
+	GMI_POSITION	=0,
 	GMI_EXP,
 	GMI_HAIR,
 	GMI_HAIR_COLOR,

+ 12 - 12
src/map/battle.c

@@ -1121,10 +1121,10 @@ 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() % 100 < 50) {
-            TBL_HOM *hd = BL_CAST(BL_HOM,bl);
-            if (hd) hom_addspiritball(hd, 10); //add a sphere
-        }
+		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__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
 			status_change_spread(bl, src); // Deadly infect attacked side
@@ -1184,10 +1184,10 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 			sc_start(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() % 100 < 50) {
-            TBL_HOM *hd = BL_CAST(BL_HOM,bl);
-            if (hd) hom_addspiritball(hd, 10);
-        }
+                if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
+                    TBL_HOM *hd = BL_CAST(BL_HOM,bl);
+                    if (hd) hom_addspiritball(hd, 10);
+                }
 	}
 
 	if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp)
@@ -2928,6 +2928,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 				case MH_LAVA_SLIDE:
 					skillratio = 70 * skill_lv;
 					break;
+                                case MH_TINDER_BREAKER:
 				case MH_MAGMA_FLOW:
 					skillratio += -100 + 100 * skill_lv;
 					break;
@@ -3048,10 +3049,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 				}
 			}
 			if(sc->data[SC_STYLE_CHANGE]){
-                TBL_HOM *hd = BL_CAST(BL_HOM,src);
-                if (hd) ATK_ADD(hd->spiritball * 3);
-            }
-
+                                TBL_HOM *hd = BL_CAST(BL_HOM,src);
+                                if (hd) ATK_ADD(hd->homunculus.spiritball * 3);
+                        }
 		}
 
 		switch (skill_num) {

+ 2 - 2
src/map/clif.c

@@ -6916,7 +6916,7 @@ void clif_spiritball(struct block_list *bl) {
 	WBUFW(buf, 6) = 0; //init to 0
     switch(bl->type){
         case BL_PC: WBUFW(buf, 6) = sd->spiritball; break;
-        case BL_HOM: WBUFW(buf, 6) = hd->spiritball; break;
+        case BL_HOM: WBUFW(buf, 6) = hd->homunculus.spiritball; break;
     }
     clif_send(buf, packet_len(0x1d0), bl, AREA);
 }
@@ -13968,7 +13968,7 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd)
 	safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH);
 	safestrncpy(msg.dest_name, (char*)RFIFOP(fd,4), NAME_LENGTH);
 	safestrncpy(msg.title, (char*)RFIFOP(fd,28), MAIL_TITLE_LENGTH);
-	
+
 	if (msg.title[0] == '\0') {
 		return; // Message has no length and somehow client verification was skipped.
 	}

+ 52 - 52
src/map/homunculus.c

@@ -76,7 +76,7 @@ int hom_class2mapid(int hom_class)
 		case 6050:                           return MAPID_SERA;
 		case 6051:                           return MAPID_DIETER;
 		case 6052:                           return MAPID_ELANOR;
-		
+
 		default:                             return -1;
 	}
 }
@@ -86,15 +86,15 @@ int hom_addspiritball(TBL_HOM *hd, int max) {
 
     if (max > MAX_SKILL_LEVEL)
         max = MAX_SKILL_LEVEL;
-    if (hd->spiritball < 0)
-        hd->spiritball = 0;
+    if (hd->homunculus.spiritball < 0)
+        hd->homunculus.spiritball = 0;
 
-    if (hd->spiritball && hd->spiritball >= max) {
-        hd->spiritball = max;    
+    if (hd->homunculus.spiritball && hd->homunculus.spiritball >= max) {
+        hd->homunculus.spiritball = max;
     }
     else
-        hd->spiritball++;
- 
+        hd->homunculus.spiritball++;
+
     clif_spiritball(&hd->bl);
 
     return 0;
@@ -103,18 +103,18 @@ int hom_addspiritball(TBL_HOM *hd, int max) {
 int hom_delspiritball(TBL_HOM *hd, int count, int type) {
     nullpo_ret(hd);
 
-    if (hd->spiritball <= 0) {
-        hd->spiritball = 0;
+    if (hd->homunculus.spiritball <= 0) {
+        hd->homunculus.spiritball = 0;
         return 0;
     }
     if (count <= 0)
         return 0;
     if (count > MAX_SKILL_LEVEL)
         count = MAX_SKILL_LEVEL;
-    if (count > hd->spiritball)
-        count = hd->spiritball;
-    
-    hd->spiritball -= count;
+    if (count > hd->homunculus.spiritball)
+        count = hd->homunculus.spiritball;
+
+    hd->homunculus.spiritball -= count;
     if (!type)
         clif_spiritball(&hd->bl);
 
@@ -154,7 +154,7 @@ int merc_hom_vaporize(struct map_session_data *sd, int flag)
 	hd = sd->hd;
 	if (!hd || hd->homunculus.vaporize)
 		return 0;
-	
+
 	if (status_isdead(&hd->bl))
 		return 0; //Can't vaporize a dead homun.
 
@@ -172,7 +172,7 @@ int merc_hom_vaporize(struct map_session_data *sd, int flag)
 	return unit_remove_map(&hd->bl, CLR_OUTSIGHT);
 }
 
-//delete a homunculus, completely "killing it". 
+//delete a homunculus, completely "killing it".
 //Emote is the emotion the master should use, send negative to disable.
 int merc_hom_delete(struct homun_data *hd, int emote)
 {
@@ -204,7 +204,7 @@ int merc_hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
 	/* load previous homunculus form skills first. */
 	if( hd->homunculus.prev_class != 0 ) {
 		c = hd->homunculus.prev_class - HM_CLASS_BASE;
-		
+
 		for( i = 0; i < MAX_SKILL_TREE && ( id = hskill_tree[c][i].id ) > 0; i++ ) {
 			if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
 				continue; //Skill already known.
@@ -220,12 +220,12 @@ int merc_hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
 			if ( f )
 				hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
 		}
-		
+
 		f = 1;
 	}
-	
+
 	c = hd->homunculus.class_ - HM_CLASS_BASE;
-	
+
 	for( i = 0; i < MAX_SKILL_TREE && ( id = hskill_tree[c][i].id ) > 0; i++ ) {
 		if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
 			continue; //Skill already known.
@@ -244,7 +244,7 @@ int merc_hom_calc_skilltree(struct homun_data *hd, int flag_evolve)
 		if ( f )
 			hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
 	}
-	
+
 	if( hd->master )
 		clif_homskillinfoblock(hd->master);
 	return 0;
@@ -278,7 +278,7 @@ void merc_hom_skillup(struct homun_data *hd,int skillnum)
 
 	if(hd->homunculus.vaporize)
 		return;
-	
+
 	i = skillnum - HM_SKILLBASE;
 	if(hd->homunculus.skillpts > 0 &&
 		hd->homunculus.hskill[i].id &&
@@ -316,12 +316,12 @@ int merc_hom_levelup(struct homun_data *hd)
 
 	hom = &hd->homunculus;
 	hom->level++ ;
-	if (!(hom->level % 3)) 
+	if (!(hom->level % 3))
 		hom->skillpts++ ;	//1 skillpoint each 3 base level
 
 	hom->exp -= hd->exp_next ;
 	hd->exp_next = hexptbl[hom->level - 1] ;
-	
+
 	max  = &hd->homunculusDB->gmax;
 	min  = &hd->homunculusDB->gmin;
 
@@ -350,7 +350,7 @@ int merc_hom_levelup(struct homun_data *hd)
 	hom->dex += growth_dex;
 	hom->int_+= growth_int;
 	hom->luk += growth_luk;
-	
+
 	if ( battle_config.homunculus_show_growth ) {
 		sprintf(output,
 			"Growth: hp:%d sp:%d str(%.2f) agi(%.2f) vit(%.2f) int(%.2f) dex(%.2f) luk(%.2f) ",
@@ -390,7 +390,7 @@ int merc_hom_evolution(struct homun_data *hd)
 	sd = hd->master;
 	if (!sd)
 		return 0;
-	
+
 	if (!merc_hom_change_class(hd, hd->homunculusDB->evo_class)) {
 		ShowError("merc_hom_evolution: Can't evolve homunc from %d to %d", hd->homunculus.class_, hd->homunculusDB->evo_class);
 		return 0;
@@ -424,7 +424,7 @@ int merc_hom_evolution(struct homun_data *hd)
 
 	if (!(battle_config.hom_setting&0x2))
 		skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
-				
+
 	return 1 ;
 }
 
@@ -437,18 +437,18 @@ int hom_mutate(struct homun_data *hd, int homun_id)
 
 	m_class = hom_class2mapid(hd->homunculus.class_);
 	m_id    = hom_class2mapid(homun_id);
-	
+
 	if( m_class == -1 || m_id == -1 || !(m_class&HOM_EVO) || !(m_id&HOM_S) ) {
 		clif_emotion(&hd->bl, E_SWT);
 		return 0;
 	}
-	
+
 	sd = hd->master;
 	if (!sd)
 		return 0;
 
 	prev_class = hd->homunculus.class_;
-	
+
 	if (!merc_hom_change_class(hd, homun_id)) {
 		ShowError("hom_mutate: Can't evolve homunc from %d to %d", hd->homunculus.class_, homun_id);
 		return 0;
@@ -461,7 +461,7 @@ int hom_mutate(struct homun_data *hd, int homun_id)
 	clif_emotion(&sd->bl, E_NO1);
 	clif_specialeffect(&hd->bl,568,AREA);
 
-	
+
 	//status_Calc flag&1 will make current HP/SP be reloaded from hom structure
 	hom = &hd->homunculus;
 	hom->hp = hd->battle_status.hp;
@@ -471,7 +471,7 @@ int hom_mutate(struct homun_data *hd, int homun_id)
 
 	if (!(battle_config.hom_setting&0x2))
 		skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
-	
+
 	return 1;
 }
 
@@ -486,8 +486,8 @@ int merc_hom_gainexp(struct homun_data *hd,int exp)
 		ShowError("merc_hom_gainexp: Invalid class %d. \n", hd->homunculus.class_);
 		return 0;
 	}
-	
-	if( hd->exp_next == 0 || 
+
+	if( hd->exp_next == 0 ||
 	   ((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) ||
 	   ((m_class&HOM_S)   && hd->homunculus.level >= battle_config.hom_S_max_level) ) {
 	  	hd->homunculus.exp = 0;
@@ -507,7 +507,7 @@ int merc_hom_gainexp(struct homun_data *hd,int exp)
 		merc_hom_levelup(hd) ;
 	}
 	while(hd->homunculus.exp > hd->exp_next && hd->exp_next != 0 );
-		
+
 	if( hd->exp_next == 0 )
 		hd->homunculus.exp = 0 ;
 
@@ -550,7 +550,7 @@ void merc_save(struct homun_data *hd)
 	// copy data that must be saved in homunculus struct ( hp / sp )
 	TBL_PC * sd = hd->master;
 	//Do not check for max_hp/max_sp caps as current could be higher to max due
-	//to status changes/skills (they will be capped as needed upon stat 
+	//to status changes/skills (they will be capped as needed upon stat
 	//calculation on login)
 	hd->homunculus.hp = hd->battle_status.hp;
 	hd->homunculus.sp = hd->battle_status.sp;
@@ -562,7 +562,7 @@ int merc_menu(struct map_session_data *sd,int menunum)
 	nullpo_ret(sd);
 	if (sd->hd == NULL)
 		return 1;
-	
+
 	switch(menunum) {
 		case 0:
 			break;
@@ -645,7 +645,7 @@ static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data)
 	}
 
 	hd->hungry_timer = INVALID_TIMER;
-	
+
 	hd->homunculus.hunger-- ;
 	if(hd->homunculus.hunger <= 10) {
 		clif_emotion(&hd->bl, E_AN);
@@ -653,8 +653,8 @@ static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data)
 		clif_emotion(&hd->bl, E_HMM);
 	} else if(hd->homunculus.hunger == 75) {
 		clif_emotion(&hd->bl, E_OK);
-	}  
-	
+	}
+
 	if(hd->homunculus.hunger < 0) {
 		hd->homunculus.hunger = 0;
 		// Delete the homunculus if intimacy <= 100
@@ -704,7 +704,7 @@ int merc_hom_change_name_ack(struct map_session_data *sd, char* name, int flag)
 	if (!merc_is_hom_active(hd)) return 0;
 
 	normalize_name(name," ");//bugreport:3032
-	
+
 	if ( !flag || !strlen(name) ) {
 		clif_displaymessage(sd->fd, msg_txt(280)); // You cannot use this name
 		return 0;
@@ -748,7 +748,7 @@ int merc_hom_alloc(struct map_session_data *sd, struct s_homunculus *hom)
 
 	nullpo_retr(1, sd);
 
-	Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd); 
+	Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd);
 
 	i = search_homunculusDB_index(hom->class_,HOMUNCULUS_CLASS);
 	if(i < 0) {
@@ -778,7 +778,7 @@ int merc_hom_alloc(struct map_session_data *sd, struct s_homunculus *hom)
 	unit_calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
 	hd->bl.x = hd->ud.to_x;
 	hd->bl.y = hd->ud.to_y;
-	
+
 	map_addiddb(&hd->bl);
 	status_calc_homunculus(hd,1);
 
@@ -824,7 +824,7 @@ int merc_call_homunculus(struct map_session_data *sd)
 		clif_homskillinfoblock(sd);
 		if (battle_config.slaves_inherit_speed&1)
 			status_calc_bl(&hd->bl, SCB_SPEED);
-		merc_save(hd); 
+		merc_save(hd);
 	} else
 		//Warp him to master.
 		unit_warp(&hd->bl,sd->bl.m, sd->bl.x, sd->bl.y,CLR_OUTSIGHT);
@@ -858,7 +858,7 @@ int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag)
 		memcpy(&sd->hd->homunculus, sh, sizeof(struct s_homunculus));
 	else
 		merc_hom_alloc(sd, sh);
-	
+
 	hd = sd->hd;
 	if(hd && hd->homunculus.hp && !hd->homunculus.vaporize && hd->bl.prev == NULL && sd->bl.prev != NULL)
 	{
@@ -884,7 +884,7 @@ int merc_create_homunculus_request(struct map_session_data *sd, int class_)
 
 	i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
 	if(i < 0) return 0;
-	
+
 	memset(&homun, 0, sizeof(struct s_homunculus));
 	//Initial data
 	strncpy(homun.name, homunculus_db[i].name, NAME_LENGTH-1);
@@ -893,7 +893,7 @@ int merc_create_homunculus_request(struct map_session_data *sd, int class_)
 	homun.hunger = 32; //32%
 	homun.intimacy = 2100; //21/1000
 	homun.char_id = sd->status.char_id;
-	
+
 	homun.hp = 10 ;
 	base = &homunculus_db[i].base;
 	homun.max_hp = base->HP;
@@ -906,7 +906,7 @@ int merc_create_homunculus_request(struct map_session_data *sd, int class_)
 	homun.luk = base->luk *10;
 
 	// Request homunculus creation
-	intif_homunculus_create(sd->status.account_id, &homun); 
+	intif_homunculus_create(sd->status.account_id, &homun);
 	return 1;
 }
 
@@ -920,7 +920,7 @@ int merc_resurrect_homunculus(struct map_session_data* sd, unsigned char per, sh
 
 	if (!sd->hd) //Load homun data;
 		return intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
-	
+
 	hd = sd->hd;
 
   	if (hd->homunculus.vaporize)
@@ -1029,7 +1029,7 @@ int merc_hom_shuffle(struct homun_data *hd)
 
 static bool read_homunculusdb_sub(char* str[], int columns, int current)
 {
-	int classid; 
+	int classid;
 	struct s_homunculus_db *db;
 
 	//Base Class,Evo Class
@@ -1168,7 +1168,7 @@ int read_homunculusdb(void)
 
 static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
 {// <hom class>,<skill id>,<max level>[,<job level>],<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>,<intimacy lv req>
-	int k, classid; 
+	int k, classid;
 	int j;
 	int minJobLevelPresent = 0;
 
@@ -1202,7 +1202,7 @@ static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
 		hskill_tree[classid][j].need[k].id = atoi(split[3+k*2+minJobLevelPresent]);
 		hskill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]);
 	}
-	
+
 	hskill_tree[classid][j].intimacylv = atoi(split[13+minJobLevelPresent]);
 
 	return true;
@@ -1276,7 +1276,7 @@ int do_init_merc(void)
 
 	//Stock view data for homuncs
 	memset(&hom_viewdb, 0, sizeof(hom_viewdb));
-	for (class_ = 0; class_ < ARRAYLENGTH(hom_viewdb); class_++) 
+	for (class_ = 0; class_ < ARRAYLENGTH(hom_viewdb); class_++)
 		hom_viewdb[class_].class_ = HM_CLASS_BASE+class_;
 	return 0;
 }

+ 2 - 2
src/map/homunculus.h

@@ -25,6 +25,8 @@ struct s_homunculus_db {
 extern struct s_homunculus_db homunculus_db[MAX_HOMUNCULUS_CLASS];
 enum { HOMUNCULUS_CLASS, HOMUNCULUS_FOOD };
 
+enum { MH_MD_FIGHTING=1, MH_MD_GRAPPLING };
+
 enum {
 	SP_ACK      = 0x0,
 	SP_INTIMATE = 0x1,
@@ -45,8 +47,6 @@ struct homun_data {
 	int hungry_timer;	//[orn]
 	unsigned int exp_next;
 	char blockskill[MAX_SKILL];	// [orn]
-    
-    int spiritball; //for homun S [lighta]
 };
 
 #define MAX_HOM_SKILL_REQUIRE 5

+ 28 - 3
src/map/skill.c

@@ -432,7 +432,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, int skill
 		if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
 			hp += hp / 10;
 	}
- 
+
 #ifdef RENEWAL
     // MATK part of the RE heal formula [malufett]
     // Note: in this part matk bonuses from items or skills are not applied
@@ -4608,10 +4608,23 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 		    map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
 		}
 		break;
+
 	case MH_STAHL_HORN:
 	case MH_NEEDLE_OF_PARALYZE:
 		skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
 		break;
+        case MH_TINDER_BREAKER:
+                if (unit_movepos(src, bl->x, bl->y, 1, 1)) {
+#if PACKETVER >= 20111005
+			clif_snap(src, bl->x, bl->y);
+#else
+			clif_skill_poseffect(src,skillid,skilllv,bl->x,bl->y,tick);
+#endif
+		}
+                clif_skill_nodamage(src,bl,skillid,skilllv,
+			sc_start4(bl,SC_CLOSECONFINE2,100,skilllv,src->id,0,0,skill_get_time(skillid,skilllv)));
+                skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+		break;
 
 	case 0:/* no skill - basic/normal attack */
 		if(sd) {
@@ -8639,11 +8652,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			clif_skill_nodamage(src,bl,skillid,skilllv,1);
 				switch(sd->ed->db->class_){
 					case 2115:case 2124:
-					case 2118:case 2121: 
+					case 2118:case 2121:
 						duration = 6000;
 						break;
 					case 2116:case 2119:
-					case 2122:case 2125: 
+					case 2122:case 2125:
 						duration = 9000;
 						break;
 				}
@@ -13139,6 +13152,16 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
                 return 0;
             }
             break;
+        case ST_MH_FIGHTING:
+            if (!(sc && sc->data[SC_STYLE_CHANGE] && sc->data[SC_STYLE_CHANGE]->val2 == MH_MD_FIGHTING)){
+                clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+                return 0;
+            }
+        case ST_MH_GRAPPLING:
+            if (!(sc && sc->data[SC_STYLE_CHANGE] && sc->data[SC_STYLE_CHANGE]->val2 == MH_MD_GRAPPLING)){
+                clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+                return 0;
+            }
 	}
 
 	if(require.mhp > 0 && get_percentage(status->hp, status->max_hp) > require.mhp) {
@@ -17576,6 +17599,8 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	else if( strcmpi(split[10],"elementalspirit")==0 ) skill_db[i].state = ST_ELEMENTALSPIRIT;
 	else if (strcmpi(split[10], "poisonweapon") == 0) skill_db[i].state = ST_POISONINGWEAPON;
 	else if (strcmpi(split[10], "rollingcutter") == 0) skill_db[i].state = ST_ROLLINGCUTTER;
+        else if (strcmpi(split[10], "mh_fighting") == 0) skill_db[i].state = ST_MH_FIGHTING;
+        else if (strcmpi(split[10], "mh_grappling") == 0) skill_db[i].state = ST_MH_GRAPPLING;
 
 	/**
 	 * Unknown or no state

+ 4 - 2
src/map/skill.h

@@ -66,7 +66,7 @@ enum e_skill_inf2
 	INF2_GUILD_ONLY     = 0x0800,
 	INF2_NO_ENEMY       = 0x1000,
 	INF2_NOLP           = 0x2000, // Spells that can ignore Land Protector
-	INF2_CHORUS_SKILL	= 0x4000, // Chorus skill 
+	INF2_CHORUS_SKILL	= 0x4000, // Chorus skill
 };
 
 //Walk intervals at which chase-skills are attempted to be triggered.
@@ -402,6 +402,8 @@ enum {
 	ST_ELEMENTALSPIRIT,
 	ST_POISONINGWEAPON,
 	ST_ROLLINGCUTTER,
+	ST_MH_FIGHTING,
+	ST_MH_GRAPPLING,
 };
 
 enum e_skill {
@@ -1786,7 +1788,7 @@ enum {
 	UNT_ZENKAI_WIND,
 	UNT_MAKIBISHI,
 	UNT_VENOMFOG,
-	
+
 	/**
 	 * Guild Auras
 	 **/

+ 10 - 3
src/map/status.c

@@ -509,6 +509,8 @@ void initChangeTables(void) {
 	set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SI_PAIN_KILLER, SCB_ASPD);
 
 	add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
+        set_sc( MH_TINDER_BREAKER      , SC_CLOSECONFINE2   , SI_CLOSECONFINE2   , SCB_NONE );
+	set_sc( MH_TINDER_BREAKER      , SC_CLOSECONFINE    , SI_CLOSECONFINE    , SCB_FLEE );
 
 
 	add_sc( MER_CRASH            , SC_STUN            );
@@ -4617,7 +4619,7 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
 #ifdef RENEWAL
 static unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
 {
-	
+
     if (!sc || !sc->count)
         return cap_value(matk,0,USHRT_MAX);
     if (sc->data[SC_MATKPOTION])
@@ -8593,6 +8595,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			    if(sc->data[SC_PARALYSIS])
 				sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
 			    break;
+                        case SC_STYLE_CHANGE: //[Lighta] need real info
+                            tick = -1;
+                            if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
+                            else val2 = MH_MD_FIGHTING; 
+                            break;
 		default:
 			if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
 			{	//Status change with no calc, no icon, and no skill associated...?
@@ -9035,7 +9042,7 @@ int status_change_clear(struct block_list* bl, int type)
 			continue;
 
 		}
-		
+
 		if( type == 3 )
 		{
 			switch (i)
@@ -10681,7 +10688,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
 /*==========================================
  * Clears buffs/debuffs of a character.
  * type&1 -> buffs, type&2 -> debuffs
- * type&4 -> especific debuffs(implemented with refresh) 
+ * type&4 -> especific debuffs(implemented with refresh)
  *------------------------------------------*/
 int status_change_clear_buffs (struct block_list* bl, int type)
 {

+ 1 - 1
src/map/unit.c

@@ -1476,7 +1476,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, sh
 			if (!src->prev) return 0;
 		}
 	}
-	
+
 	unit_stop_walking(src,1);
 	// in official this is triggered even if no cast time.
 	clif_skillcasting(src, src->id, 0, skill_x, skill_y, skill_num, skill_get_ele(skill_num, skill_lv), casttime);