Browse Source

Happy Holidays and Happy 12/12/12 :)
Update Elemental summon to its official behavior
- Fixed missing skill features of Ventus(bugreport:6792,bugreport:6723,bugreport:6511)
- Note: upgrade_svn17014.sql
- And other elemental skills are to follow :)
Fixed bugreport:6889 updated const.txt where it cause error to some items.
Fixed bugreport:6999 where matk damage deals miss atk to plant type targets.
Fixed status calculation where it doesn't give accurate result or how official calculation does.

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

rud0lp20 12 years ago
parent
commit
aa7031075c

+ 44 - 3
db/const.txt

@@ -1232,9 +1232,50 @@ SC_TIDAL_WEAPON	504
 SC_TIDAL_WEAPON_OPTION	505
 SC_ROCK_CRUSHER	506
 SC_ROCK_CRUSHER_ATK	507
-SC_INCMHP	529
-SC_INCMSP	530
-SC_PARTYFLEE	531
+SC_LEADERSHIP	508
+SC_GLORYWOUNDS	509
+SC_SOULCOLD	510
+SC_HAWKEYES	511
+SC_ODINS_POWER	512
+SC_RAID	513
+SC_FIRE_INSIGNIA	514
+SC_WATER_INSIGNIA	515
+SC_WIND_INSIGNIA	516
+SC_EARTH_INSIGNIA	517
+SC_PUSH_CART	518
+SC_SPELLBOOK1	519
+SC_SPELLBOOK2	520
+SC_SPELLBOOK3	521
+SC_SPELLBOOK4	522
+SC_SPELLBOOK5	523
+SC_SPELLBOOK6	524
+SC_MAXSPELLBOOK	525
+SC_INCMHP	526
+SC_INCMSP	527
+SC_PARTYFLEE	528
+SC_MEIKYOUSISUI	529
+SC_JYUMONJIKIRI	530
+SC_KYOUGAKU	531
+SC_IZAYOI	532
+SC_ZENKAI	533
+SC_KAGEHUMI	534
+SC_KYOMU	535
+SC_KAGEMUSYA	536
+SC_ZANGETSU	537
+SC_GENSOU	538
+SC_AKAITSUKI	539
+SC_STYLE_CHANGE	540
+SC_GOLDENE_FERSE	541
+SC_ANGRIFFS_MODUS	542
+SC_ERASER_CUTTER	543
+SC_OVERED_BOOST	544
+SC_LIGHT_OF_REGENE	545
+SC_ASH	546
+SC_GRANITIC_ARMOR	547
+SC_MAGMA_FLOW	548
+SC_PYROCLASTIC	549
+SC_PARALYSIS	550
+SC_PAIN_KILLER	551
 
 e_gasp	0
 e_what	1

+ 17 - 24
db/elemental_db.txt

@@ -2,30 +2,23 @@
 //
 // Structure of Database:
 // ID,Sprite_Name,Name,LV,HP,SP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Speed,aDelay,aMotion,dMotion
+// NOTE
+// Summoned Elemental’s STATs are affected by the Caster’s Base Level and STATs.
+// So all value added here will be added and will not override the calculated STATs of the summoned elemental.
 
 // Monster Elementals
-2114,EL_AGNI_S,Agni,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,83,200,504,1020,360
-2115,EL_AGNI_M,Agni,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,83,200,504,1020,360
-2116,EL_AGNI_L,Agni,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,83,200,504,1020,360
-2117,EL_AQUA_S,Aqua,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,81,200,504,1020,360
-2118,EL_AQUA_M,Aqua,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,81,200,504,1020,360
-2119,EL_AQUA_L,Aqua,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,81,200,504,1020,360
-2120,EL_VENTUS_S,Ventus,100,5000,1,4,100,100,10,10,1,1,1,1,1,1,5,12,0,0,84,200,504,1020,360
-2121,EL_VENTUS_M,Ventus,100,7500,1,4,250,250,25,25,1,1,1,1,1,1,5,12,1,0,84,200,504,1020,360
-2122,EL_VENTUS_L,Ventus,100,10000,1,4,500,500,50,50,1,1,1,1,1,1,5,12,2,0,84,200,504,1020,360
-2123,EL_TERA_S,Tera,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,82,200,504,1020,360
-2124,EL_TERA_M,Tera,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,82,200,504,1020,360
-2125,EL_TERA_L,Tera,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,82,200,504,1020,360
+2114,EL_AGNI_S,Agni,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,83,200,504,1020,360
+2115,EL_AGNI_M,Agni,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,83,200,504,1020,360
+2116,EL_AGNI_L,Agni,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,2,0,83,200,504,1020,360
 
-//2114,EL_AGNI_S,Agni		,100,5000,500	,1,250,250	,10,10,	25,25,25,25,25,25,		10,12,0,0,83,200,504,1020,360
-//2115,EL_AGNI_M,Agni		,100,7500,750	,1,500,500	,25,25,	50,50,50,50,50,50,		10,12,1,0,83,200,504,1020,360
-//2116,EL_AGNI_L,Agni		,100,10000,1000	,1,1000,1000	,50,50,	100,100,100,100,100,100,	10,12,2,0,83,200,504,1020,360
-//2117,EL_AQUA_S,Aqua		,100,5000,500	,1,250,250	,10,10,	25,25,25,25,25,25,		10,12,0,0,81,200,504,1020,360
-//2118,EL_AQUA_M,Aqua		,100,7500,750	,1,500,500	,25,25,	50,50,50,50,50,50,		10,12,1,0,81,200,504,1020,360
-//2119,EL_AQUA_L,Aqua		,100,10000,1000	,1,1000,1000	,50,50,	100,100,100,100,100,100,	10,12,2,0,81,200,504,1020,360
-//2120,EL_VENTUS_S,Ventus	,100,5000,500	,4,250,250	,10,10,	25,25,25,25,25,25,		10,12,0,0,84,200,504,1020,360
-//2121,EL_VENTUS_M,Ventus	,100,7500,750	,4,500,500	,25,25,	50,50,50,50,50,50,		10,12,1,0,84,200,504,1020,360
-//2122,EL_VENTUS_L,Ventus	,100,10000,1000	,4,1000,1000	,50,50,	100,100,100,100,100,100,	10,12,2,0,84,200,504,1020,360
-//2123,EL_TERA_S,Tera		,100,5000,500	,1,250,250	,10,10,	25,25,25,25,25,25,		10,12,0,0,82,200,504,1020,360
-//2124,EL_TERA_M,Tera		,100,7500,750	,1,500,500	,25,25,	50,50,50,50,50,50,		10,12,1,0,82,200,504,1020,360
-//2125,EL_TERA_L,Tera		,100,10000,1000	,1,1000,1000	,50,50,	100,100,100,100,100,100,	10,12,2,0,82,200,504,1020,360
+2117,EL_AQUA_S,Aqua,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,81,200,504,1020,360
+2118,EL_AQUA_M,Aqua,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,81,200,504,1020,360
+2119,EL_AQUA_L,Aqua,100,0,1,1,0,0,0,0,1,1,1,1,1,1,5,12,2,0,81,200,504,1020,360
+
+2120,EL_VENTUS_S,Ventus,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,84,200,504,1020,360
+2121,EL_VENTUS_M,Ventus,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,84,200,504,1020,360
+2122,EL_VENTUS_L,Ventus,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,2,0,84,200,504,1020,360
+
+2123,EL_TERA_S,Tera,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,0,0,82,200,504,1020,360
+2124,EL_TERA_M,Tera,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,1,0,82,200,504,1020,360
+2125,EL_TERA_L,Tera,100,0,1,1,0,0,0,0,0,0,0,0,0,0,5,12,2,0,82,200,504,1020,360

+ 5 - 1
db/pre-re/skill_cast_db.txt

@@ -1884,8 +1884,12 @@
 8424,0,0,0,-1,0,0
 //-- EL_TIDAL_WEAPON 
 8433,0,0,0,-1,0,0
+//-- EL_WIND_SLASH
+8434,1000,0,0,0,0,0
+//-- EL_HURRICANE
+8435,1000,0,0,0,0,0
 //-- EL_TYPOON_MIS 
-8437,0,0,0,15000,0,0
+8437,1000,0,0,15000,0,0
 //-- EL_STONE_HAMMER 
 8439,0,0,0,5000,0,0
 //-- EL_ROCK_CRUSHER 

+ 2 - 2
db/pre-re/skill_db.txt

@@ -1180,8 +1180,8 @@
 8434,11,6,1,4,0,0,1,1,no,0,0,0,weapon,0,	EL_WIND_SLASH,Wind Slasher
 8435,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0,	EL_HURRICANE,Hurricane Rage
 8436,7,6,1,4,0,0,1,1,no,0,0,0,magic,0,		EL_HURRICANE_ATK,Hurricane Rage Attack
-8437,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0,	EL_TYPOON_MIS,Typhoon Missile
-8438,11,6,1,4,0,1,1,1,no,0,0,0,magic,0,		EL_TYPOON_MIS_ATK,Typhoon Missile Attack
+8437,11,8,1,4,0,1,1,-3,no,0,0,0,weapon,0,	EL_TYPOON_MIS,Typhoon Missile
+8438,11,8,1,4,0,1,1,-3,no,0,0,0,magic,0,	EL_TYPOON_MIS_ATK,Typhoon Missile Attack
 8439,5,6,1,2,0,0,1,1,no,0,0,0,weapon,0,		EL_STONE_HAMMER,Stone Hammer
 8440,3,6,1,2,0,1,1,1,no,0,0,0,weapon,0,		EL_ROCK_CRUSHER,Rock Launcher
 8441,5,6,1,2,0,1,1,1,no,0,0,0,magic,0,		EL_ROCK_CRUSHER_ATK,Rock Launcher Attack

+ 5 - 1
db/re/skill_cast_db.txt

@@ -1884,8 +1884,12 @@
 8424,0,0,0,-1,0,0,-1
 //-- EL_TIDAL_WEAPON
 8433,0,0,0,-1,0,0,-1
+//-- EL_WIND_SLASH
+8434,1000,0,0,0,0,0,-1
+//-- EL_HURRICANE
+8435,1000,0,0,0,0,0,-1
 //-- EL_TYPOON_MIS
-8437,0,0,0,15000,0,0,-1
+8437,1000,0,0,15000,0,0,-1
 //-- EL_STONE_HAMMER
 8439,0,0,0,5000,0,0,-1
 //-- EL_ROCK_CRUSHER

+ 2 - 2
db/re/skill_db.txt

@@ -1181,8 +1181,8 @@
 8434,11,6,1,4,0,0,1,1,no,0,0,0,weapon,0,	EL_WIND_SLASH,Wind Slasher
 8435,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0,	EL_HURRICANE,Hurricane Rage
 8436,7,6,1,4,0,0,1,1,no,0,0,0,magic,0,		EL_HURRICANE_ATK,Hurricane Rage Attack
-8437,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0,	EL_TYPOON_MIS,Typhoon Missile
-8438,11,6,1,4,0,1,1,1,no,0,0,0,magic,0,		EL_TYPOON_MIS_ATK,Typhoon Missile Attack
+8437,11,8,1,4,0,1,1,-3,no,0,0,0,weapon,0,	EL_TYPOON_MIS,Typhoon Missile
+8438,11,8,1,4,0,1,1,-3,no,0,0,0,magic,0,		EL_TYPOON_MIS_ATK,Typhoon Missile Attack
 8439,5,6,1,2,0,0,1,1,no,0,0,0,weapon,0,		EL_STONE_HAMMER,Stone Hammer
 8440,3,6,1,2,0,1,1,1,no,0,0,0,weapon,0,		EL_ROCK_CRUSHER,Rock Launcher
 8441,5,6,1,2,0,1,1,1,no,0,0,0,magic,0,		EL_ROCK_CRUSHER_ATK,Rock Launcher Attack

+ 8 - 6
sql-files/main.sql

@@ -146,12 +146,14 @@ CREATE TABLE IF NOT EXISTS `elemental` (
   `sp` int(12) NOT NULL default '1',
   `max_hp` mediumint(8) unsigned NOT NULL default '0',
   `max_sp` mediumint(6) unsigned NOT NULL default '0',
-  `str` smallint(4) unsigned NOT NULL default '0',
-  `agi` smallint(4) unsigned NOT NULL default '0',
-  `vit` smallint(4) unsigned NOT NULL default '0',
-  `int` smallint(4) unsigned NOT NULL default '0',
-  `dex` smallint(4) unsigned NOT NULL default '0',
-  `luk` smallint(4) unsigned NOT NULL default '0',
+  `atk` MEDIUMINT(6) unsigned NOT NULL default '0',
+  `atk2` MEDIUMINT(6) unsigned NOT NULL default '0',
+  `matk` MEDIUMINT(6) unsigned NOT NULL default '0',
+  `aspd` smallint(4) unsigned NOT NULL default '0',
+  `def` smallint(4) unsigned NOT NULL default '0',
+  `mdef` smallint(4) unsigned NOT NULL default '0',
+  `flee` smallint(4) unsigned NOT NULL default '0',
+  `hit` smallint(4) unsigned NOT NULL default '0',
   `life_time` int(11) NOT NULL default '0',
   PRIMARY KEY  (`ele_id`)
 ) ENGINE=MyISAM;

+ 9 - 0
sql-files/upgrades/upgrade_svn17014.sql

@@ -0,0 +1,9 @@
+ALTER TABLE `elemental` CHANGE COLUMN `str` `atk1` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT 0,
+ CHANGE COLUMN `agi` `atk2` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT 0,
+ CHANGE COLUMN `vit` `matk` MEDIUMINT(6) UNSIGNED NOT NULL DEFAULT 0,
+ CHANGE COLUMN `int` `aspd` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
+ CHANGE COLUMN `dex` `def` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
+ CHANGE COLUMN `luk` `mdef` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
+ CHANGE COLUMN `life_time` `flee` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0,
+ ADD COLUMN `hit` SMALLINT(4) UNSIGNED NOT NULL DEFAULT 0 AFTER `flee`,
+ ADD COLUMN `life_time` INT(11) NOT NULL DEFAULT 0 AFTER `hit`;

+ 18 - 16
src/char/int_elemental.c

@@ -20,9 +20,9 @@ bool mapif_elemental_save(struct s_elemental* ele) {
 	
 	if( ele->elemental_id == 0 ) { // Create new DB entry
 		if( SQL_ERROR == Sql_Query(sql_handle,
-								   "INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`life_time`)"
-								   "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u')",
-								   ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi, ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time) )
+								   "INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`atk1`,`atk2`,`matk`,`aspd`,`def`,`mdef`,`flee`,`hit`,`life_time`)"
+								   "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u')",
+								   ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2, ele->matk, ele->amotion, ele->def, ele->mdef, ele->flee, ele->hit, ele->life_time) )
 		{
 			Sql_ShowDebug(sql_handle);
 			flag = false;
@@ -31,10 +31,10 @@ bool mapif_elemental_save(struct s_elemental* ele) {
 			ele->elemental_id = (int)Sql_LastInsertId(sql_handle);
 	} else if( SQL_ERROR == Sql_Query(sql_handle,
 									"UPDATE `elemental` SET `char_id` = '%d', `class` = '%d', `mode` = '%d', `hp` = '%d', `sp` = '%d',"
-									"`max_hp` = '%d', `max_sp` = '%d', `str` = '%d', `agi` = '%d', `vit` = '%d', `int` = '%d', `dex` = '%d',"
-									"`luk` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'",
-									ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi,
-									ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time, ele->elemental_id) )
+									"`max_hp` = '%d', `max_sp` = '%d', `atk1` = '%d', `atk2` = '%d', `matk` = '%d', `aspd` = '%d', `def` = '%d',"
+									"`mdef` = '%d', `flee` = '%d', `hit` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'",
+									ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2,
+									ele->matk, ele->amotion, ele->def, ele->mdef, ele->flee, ele->hit, ele->life_time, ele->elemental_id) )
 	{ // Update DB entry
 		Sql_ShowDebug(sql_handle);
 		flag = false;
@@ -49,8 +49,8 @@ bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) {
 	ele->elemental_id = ele_id;
 	ele->char_id = char_id;
 	
-	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `str`, `agi`, `vit`, `int`, `dex`,"
-							   "`luk`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `atk1`, `atk2`, `matk`, `aspd`,"
+							   "`def`, `mdef`, `flee`, `hit`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
 							   ele_id, char_id) ) {
 		Sql_ShowDebug(sql_handle);
 		return false;
@@ -67,13 +67,15 @@ bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) {
 	Sql_GetData(sql_handle,  3, &data, NULL); ele->sp = atoi(data);
 	Sql_GetData(sql_handle,  4, &data, NULL); ele->max_hp = atoi(data);
 	Sql_GetData(sql_handle,  5, &data, NULL); ele->max_sp = atoi(data);
-	Sql_GetData(sql_handle,  6, &data, NULL); ele->str = atoi(data);
-	Sql_GetData(sql_handle,  7, &data, NULL); ele->agi = atoi(data);
-	Sql_GetData(sql_handle,  8, &data, NULL); ele->vit = atoi(data);
-	Sql_GetData(sql_handle,  9, &data, NULL); ele->int_ = atoi(data);
-	Sql_GetData(sql_handle, 10, &data, NULL); ele->dex = atoi(data);
-	Sql_GetData(sql_handle, 11, &data, NULL); ele->luk = atoi(data);
-	Sql_GetData(sql_handle, 12, &data, NULL); ele->life_time = atoi(data);
+	Sql_GetData(sql_handle,  6, &data, NULL); ele->atk = atoi(data);
+	Sql_GetData(sql_handle,  7, &data, NULL); ele->atk2 = atoi(data);
+	Sql_GetData(sql_handle,  8, &data, NULL); ele->matk = atoi(data);
+	Sql_GetData(sql_handle,  9, &data, NULL); ele->amotion = atoi(data);
+	Sql_GetData(sql_handle, 10, &data, NULL); ele->def = atoi(data);
+	Sql_GetData(sql_handle, 11, &data, NULL); ele->mdef = atoi(data);
+	Sql_GetData(sql_handle, 12, &data, NULL); ele->flee = atoi(data);
+	Sql_GetData(sql_handle, 13, &data, NULL); ele->hit = atoi(data);
+	Sql_GetData(sql_handle, 14, &data, NULL); ele->life_time = atoi(data);
 	Sql_FreeResult(sql_handle);
 	if( save_log )
 		ShowInfo("Elemental loaded (%d - %d).\n", ele->elemental_id, ele->char_id);

+ 2 - 1
src/common/mmo.h

@@ -306,7 +306,8 @@ struct s_elemental {
 	int char_id;
 	short class_;
 	int mode;
-	int hp, sp, max_hp, max_sp, str, agi, vit, int_, dex, luk;
+	int hp, sp, max_hp, max_sp, matk, atk, atk2;
+	short hit, flee, amotion, def, mdef;
 	int life_time;
 };
 

+ 83 - 130
src/map/battle.c

@@ -2868,10 +2868,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 					} else
 						skillratio += 300;	// Bombs
 					break;
-				case SO_VARETYR_SPEAR: //Assumed Formula.
-					skillratio += -100 + 200 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 1 );
+				case SO_VARETYR_SPEAR://ATK [{( Striking Level x 50 ) + ( Varetyr Spear Skill Level x 50 )} x Caster’s Base Level / 100 ] %
+					skillratio =  50 * skill_lv + ( sd ? pc_checkskill(sd, SO_STRIKING) * 50 : 0 );
 					if( sc && sc->data[SC_BLAST_OPTION] )
-						skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
+						skillratio += sd ? sd->status.job_level * 5 : 0;
 					break;
 					// Physical Elemantal Spirits Attack Skills
 				case EL_CIRCLE_OF_FIRE:
@@ -3513,6 +3513,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 
     TBL_PC *sd;
 //    TBL_PC *tsd;
+	struct status_change *sc, *tsc;
 	struct Damage ad;
 	struct status_data *sstatus = status_get_status_data(src);
 	struct status_data *tstatus = status_get_status_data(target);
@@ -3530,6 +3531,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 		return ad;
 	}
 	//Initial Values
+	ad.damage = 1;
 	ad.div_=skill_get_num(skill_num,skill_lv);
 	ad.amotion=skill_get_inf(skill_num)&INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
 	ad.dmotion=tstatus->dmotion;
@@ -3541,43 +3543,32 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 
 	sd = BL_CAST(BL_PC, src);
 //    tsd = BL_CAST(BL_PC, target);
+	sc = status_get_sc(src);
+	tsc = status_get_sc(target);
+
+	//Initialize variables that will be used afterwards
+	s_ele = skill_get_ele(skill_num, skill_lv);
+
+	if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
+		s_ele = sstatus->rhw.ele;
+		if( sd ){ //Summoning 10 talisman will endow your weapon
+			ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
+			if( i < 5 ) s_ele = i;
+		}
+	}else if (s_ele == -2) //Use status element
+		s_ele = status_get_attack_sc_element(src,status_get_sc(src));
+	else if( s_ele == -3 ) //Use random element
+		s_ele = rnd()%ELE_MAX;
 
 	if( skill_num == SO_PSYCHIC_WAVE ) {
-		struct status_change *sc = status_get_sc(src);
-		if( sc && sc->count && ( sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] ||
-								sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] ) ) {
+		if( sc && sc->count ) {
 			if( sc->data[SC_HEATER_OPTION] ) s_ele = sc->data[SC_HEATER_OPTION]->val4;
 			else if( sc->data[SC_COOLER_OPTION] ) s_ele = sc->data[SC_COOLER_OPTION]->val4;
 			else if( sc->data[SC_BLAST_OPTION] ) s_ele = sc->data[SC_BLAST_OPTION]->val3;
 			else if( sc->data[SC_CURSED_SOIL_OPTION] ) s_ele = sc->data[SC_CURSED_SOIL_OPTION]->val4;
-		} else {
-			//#HALP# I didn't get a clue on how to do this without unnecessary adding a overhead of status_change on every call while this is a per-skill case.
-			//, - so i duplicated this code. make yourself comfortable to fix if you have any better ideas.
-			//Initialize variables that will be used afterwards
-			s_ele = skill_get_ele(skill_num, skill_lv);
-
-			if (s_ele == -1) // pl=-1 : the skill takes the weapon's element
-				s_ele = sstatus->rhw.ele;
-			else if (s_ele == -2) //Use status element
-				s_ele = status_get_attack_sc_element(src,status_get_sc(src));
-			else if( s_ele == -3 ) //Use random element
-				s_ele = rnd()%ELE_MAX;
 		}
-	} else {
-		//Initialize variables that will be used afterwards
-		s_ele = skill_get_ele(skill_num, skill_lv);
-
-		if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
-			s_ele = sstatus->rhw.ele;
-			if( sd ){ //Summoning 10 talisman will endow your weapon
-				ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
-				if( i < 5 ) s_ele = i;
-			}
-		}else if (s_ele == -2) //Use status element
-			s_ele = status_get_attack_sc_element(src,status_get_sc(src));
-		else if( s_ele == -3 ) //Use random element
-			s_ele = rnd()%ELE_MAX;
 	}
+	
 	//Set miscellaneous data that needs be filled
 	if(sd) {
 		sd->state.arrow_atk = 0;
@@ -3608,7 +3599,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 
 	if (!flag.infdef) //No need to do the math for plants
 	{
-
+#ifdef RENEWAL
+		ad.damage = 0; //reinitialize..
+#endif
 //MATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
 #define MATK_RATE( a ) { ad.damage= ad.damage*(a)/100; }
 //Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
@@ -3695,66 +3688,26 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						if (battle_check_undead(tstatus->race,tstatus->def_ele))
 							skillratio += 5*skill_lv;
 						break;
-					case MG_FIREWALL: {
-							struct status_change *sc = status_get_sc(src);
-							skillratio -= 50;
-							if( sc && sc->data[SC_PYROTECHNIC_OPTION] )
-								skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
-						}
-						break;
-					case MG_COLDBOLT: {
-							struct status_change *sc = status_get_sc(src);
-							if ( sc && sc->count ) {
-								if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT )  {
-									skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
-									ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
-									ad.flag = BF_WEAPON|BF_SHORT;
-									ad.type = 0;
-								}
-								if( sc->data[SC_AQUAPLAY_OPTION] )
-									skillratio += skillratio * sc->data[SC_AQUAPLAY_OPTION]->val3 / 100;
-							}
-						}
-						break;
-					case MG_FIREBOLT: {
-							struct status_change *sc = status_get_sc(src);
-							if ( sc && sc->count ) {
-								if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
-									skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
-									ad.div_ = 1;
-									ad.flag = BF_WEAPON|BF_SHORT;
-									ad.type = 0;
-								}
-								if( sc->data[SC_PYROTECHNIC_OPTION] )
-									skillratio += skillratio * sc->data[SC_PYROTECHNIC_OPTION]->val3 / 100;
-							}
-						}
+					case MG_FIREWALL:
+						skillratio -= 50;
 						break;
-					case MG_LIGHTNINGBOLT: {
-							struct status_change *sc = status_get_sc(src);
-							if ( sc && sc->count ) {
-								if ( sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
-									skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;
-									ad.div_ = 1;
-									ad.flag = BF_WEAPON|BF_SHORT;
-									ad.type = 0;
-								}
-								if( sc->data[SC_GUST_OPTION] )
-									skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
-							}
+					case MG_FIREBOLT:
+					case MG_COLDBOLT:
+					case MG_LIGHTNINGBOLT:
+						if ( sc && sc->data[SC_SPELLFIST] && mflag&BF_SHORT )  {
+							skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
+							ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
+							ad.flag = BF_WEAPON|BF_SHORT;
+							ad.type = 0;
 						}
 						break;
-					case MG_THUNDERSTORM: {
-						struct status_change *sc = status_get_sc(src);
+					case MG_THUNDERSTORM:
 						/**
 						 * in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
 						 **/
 						#ifndef RENEWAL
 							skillratio -= 20;
 						#endif
-						if( sc && sc->data[SC_GUST_OPTION] )
-							skillratio += skillratio * sc->data[SC_GUST_OPTION]->val2 / 100;
-						}
 						break;
 					case MG_FROSTDIVER:
 						skillratio += 10*skill_lv;
@@ -3870,15 +3823,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						skillratio += 100 + 100 * skill_lv;
 						RE_LVL_DMOD(100);
 						break;
-					case WL_JACKFROST: {
-							struct status_change *tsc = status_get_sc(target);
-							if( tsc && tsc->data[SC_FREEZING] ){
-								skillratio += 900 + 300 * skill_lv;
-								RE_LVL_DMOD(100);
-							}else{
-								skillratio += 400 + 100 * skill_lv;
-								RE_LVL_DMOD(150);
-							}
+					case WL_JACKFROST:
+						if( tsc && tsc->data[SC_FREEZING] ){
+							skillratio += 900 + 300 * skill_lv;
+							RE_LVL_DMOD(100);
+						}else{
+							skillratio += 400 + 100 * skill_lv;
+							RE_LVL_DMOD(150);
 						}
 						break;
 					case WL_DRAINLIFE:
@@ -3954,76 +3905,60 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						skillratio += 100 * (sd ? pc_checkskill(sd, WM_REVERBERATION) : 1);
 						RE_LVL_DMOD(100);
 						break;
-					case SO_FIREWALK: {
-						struct status_change * sc = status_get_sc(src);
+					case SO_FIREWALK:
 						skillratio = 300;
 						RE_LVL_DMOD(100);
 						if( sc && sc->data[SC_HEATER_OPTION] )
-							skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
-						}
+							skillratio += sc->data[SC_HEATER_OPTION]->val3;
 						break;
-					case SO_ELECTRICWALK: {
-						struct status_change * sc = status_get_sc(src);
+					case SO_ELECTRICWALK:
 						skillratio = 300;
 						RE_LVL_DMOD(100);
 						if( sc && sc->data[SC_BLAST_OPTION] )
-							skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
-						}
+							skillratio += sd ? sd->status.job_level / 2 : 0;
 						break;
-					case SO_EARTHGRAVE: {
-						struct status_change * sc = status_get_sc(src);
+					case SO_EARTHGRAVE:
 						skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_SEISMICWEAPON) : 10 ) + sstatus->int_ * skill_lv );
 						RE_LVL_DMOD(100);
 						if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
-							skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
-						}
+							skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
 						break;
-					case SO_DIAMONDDUST: {
-						struct status_change * sc = status_get_sc(src);
+					case SO_DIAMONDDUST:
 						skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_FROSTWEAPON) : 10 ) + sstatus->int_ * skill_lv );
 						RE_LVL_DMOD(100);
 						if( sc && sc->data[SC_COOLER_OPTION] )
-							skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
-						}
+							skillratio += sc->data[SC_COOLER_OPTION]->val3;
 						break;
-					case SO_POISON_BUSTER: {
-						struct status_change * sc = status_get_sc(src);
+					case SO_POISON_BUSTER:
 						skillratio += 1100 + 300 * skill_lv;
 						if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
-							skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
-						}
+							skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
 						break;
-					case SO_PSYCHIC_WAVE: {
-						struct status_change * sc = status_get_sc(src);
+					case SO_PSYCHIC_WAVE:
 						skillratio += -100 + skill_lv * 70 + (sstatus->int_ * 3);
 						RE_LVL_DMOD(100);
 						if( sc ){
 							if( sc->data[SC_HEATER_OPTION] )
-								skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100;
+								skillratio += sc->data[SC_HEATER_OPTION]->val3;
 							else if(sc->data[SC_COOLER_OPTION] )
-								skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100;
+								skillratio +=  sc->data[SC_COOLER_OPTION]->val3;
 							else if(sc->data[SC_BLAST_OPTION] )
-								skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
+								skillratio += sc->data[SC_BLAST_OPTION]->val2;
 							else if(sc->data[SC_CURSED_SOIL_OPTION] )
-								skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val3 / 100;
-						}
+								skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3;
 						}
 						break;
-					case SO_VARETYR_SPEAR: {
-						struct status_change * sc = status_get_sc(src);
-						skillratio += -100 + ( 100 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 10 ) + sstatus->int_ * skill_lv );
+					case SO_VARETYR_SPEAR: //MATK [{( Endow Tornado skill level x 50 ) + ( Caster’s INT x Varetyr Spear Skill level )} x Caster’s Base Level / 100 ] %
+						skillratio = status_get_int(src) * skill_lv + ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) * 50 : 0 );
 						RE_LVL_DMOD(100);
 						if( sc && sc->data[SC_BLAST_OPTION] )
-							skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
-						}
+							skillratio += sd ? sd->status.job_level * 5 : 0;
 						break;
-					case SO_CLOUD_KILL: {
-						struct status_change * sc = status_get_sc(src);
+					case SO_CLOUD_KILL:
 						skillratio += -100 + skill_lv * 40;
 						RE_LVL_DMOD(100);
 						if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
-							skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
-						}
+							skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
 						break;
 					case GN_DEMONIC_FIRE:
 						if( skill_lv > 20)
@@ -4136,6 +4071,23 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 
 		if(ad.damage<1)
 			ad.damage=1;
+		else if(sc){//only applies when hit
+			// TODO: there is another factor that contribute with the damage and need to be formulated. [malufett]
+			switch(skill_num){
+				case MG_LIGHTNINGBOLT:
+				case MG_THUNDERSTORM:
+				case MG_FIREBOLT:
+				case MG_FIREWALL:
+				case MG_COLDBOLT:
+				case MG_FROSTDIVER:
+				case WZ_EARTHSPIKE:
+				case WZ_HEAVENDRIVE:
+					if(sc->data[SC_GUST_OPTION] || sc->data[SC_PETROLOGY_OPTION] 
+						|| sc->data[SC_PYROTECHNIC_OPTION] || sc->data[SC_AQUAPLAY_OPTION])
+						ad.damage += (6 + sstatus->int_/4) + max(sstatus->dex-10,0)/30;
+					break;
+			}
+		}
 
 		if (!(nk&NK_NO_ELEFIX))
 			ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
@@ -4172,7 +4124,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 	switch( skill_num ) { /* post-calc modifiers */
 		case SO_VARETYR_SPEAR: { // Physical damage.
 			struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
-			ad.damage += wd.damage;
+			if(!flag.infdef && ad.damage > 1)
+				ad.damage += wd.damage;
 			break;
 		}
 		//case HM_ERASER_CUTTER:

+ 1 - 1
src/map/clif.c

@@ -9251,7 +9251,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		clif_spawn(&sd->ed->bl);
 		clif_elemental_info(sd);
 		clif_elemental_updatestatus(sd,SP_HP);
-		clif_hpmeter_single(sd->fd,sd->ed->bl.id,sd->ed->battle_status.hp,sd->ed->battle_status.matk_max);
+		clif_hpmeter_single(sd->fd,sd->ed->bl.id,sd->ed->battle_status.hp,sd->ed->battle_status.max_hp);
 		clif_elemental_updatestatus(sd,SP_SP);
 		status_calc_bl(&sd->ed->bl, SCB_SPEED); //Elemental mimic their master's speed on each map change
 	}

+ 121 - 13
src/map/elemental.c

@@ -73,8 +73,56 @@ int elemental_create(struct map_session_data *sd, int class_, unsigned int lifet
 	ele.char_id = sd->status.char_id;
 	ele.class_ = class_;
 	ele.mode = EL_MODE_PASSIVE; // Initial mode
-	ele.hp = db->status.max_hp;
-	ele.sp = db->status.max_sp;
+	i = db->status.size+1; // summon level
+
+	//[(Caster’s Max HP/ 3 ) + (Caster’s INT x 10 )+ (Caster’s Job Level x 20 )] x [(Elemental Summon Level + 2) / 3]
+	ele.hp = ele.max_hp = (sd->battle_status.max_hp/3 + sd->battle_status.int_*10 + sd->status.job_level) * ((i + 2) / 3) * 5 * pc_checkskill(sd,SO_EL_SYMPATHY) / 100;
+	//Caster’s Max SP /4
+	ele.sp = ele.max_sp = sd->battle_status.max_sp/4 * 5 * pc_checkskill(sd,SO_EL_SYMPATHY) / 100;
+	//Caster’s [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ]
+	ele.atk = (sd->battle_status.max_sp / (18 / i)  * 1 - 100) + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
+	//Caster’s [ Max SP / (18 / Elemental Summon Skill Level) ]
+	ele.atk2 = sd->battle_status.max_sp / 18 + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
+	//Caster’s HIT + (Caster’s Base Level )
+	ele.hit = sd->battle_status.hit + sd->status.base_level;
+	//[Elemental Summon Skill Level x (Caster’s INT / 2 + Caster’s DEX / 4)]
+	ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4) + 25 * pc_checkskill(sd,SO_EL_SYMPATHY);
+	//150 + [Caster’s DEX / 10] + [Elemental Summon Skill Level x 3 ]
+	ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3;
+	//Caster’s DEF + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
+	ele.def = sd->battle_status.def + sd->status.base_level / (5-i);
+	//Caster’s MDEF + (Caster’s INT / (5 - Elemental Summon Skill Level)
+	ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i);
+	//Caster’s FLEE + (Caster’s Base Level / (5 – Elemental Summon Skill Level)
+	ele.flee = sd->status.base_level / (5-i);
+	//Caster’s HIT + (Caster’s Base Level )
+	ele.hit = sd->battle_status.hit + sd->status.base_level;
+	
+	//per individual bonuses
+	switch(db->class_){
+	case 2114:	case 2115:
+	case 2116: //ATK + (Summon Agni Skill Level x 20) / HIT + (Summon Agni Skill Level x 10)
+		ele.atk += i * 20;
+		ele.atk2 += i * 20;
+		ele.hit += i * 10;
+		break;
+	case 2117:	case 2118:
+	case 2119: //MDEF + (Summon Aqua Skill Level x 10) / MATK + (Summon Aqua Skill Level x 20)
+		ele.mdef += i * 10;
+		ele.matk += i * 20;
+		break;
+	case 2120:	case 2121:
+	case 2122: //FLEE + (Summon Ventus Skill Level x 20) / MATK + (Summon Ventus Skill Level x 10)
+		ele.flee += i * 20;
+		ele.matk += i * 10;
+		break;
+	case 2123:	case 2124:
+	case 2125: //DEF + (Summon Tera Skill Level x 25) / ATK + (Summon Tera Skill Level x 5)
+		ele.def += i * 25;
+		ele.atk += i * 5;
+		ele.atk2 += i * 5;
+		break;
+	}
 	ele.life_time = lifetime;
 	
 	// Request Char Server to create this elemental
@@ -93,10 +141,19 @@ int elemental_get_lifetime(struct elemental_data *ed) {
 }
 
 int elemental_save(struct elemental_data *ed) {
+	ed->elemental.mode = ed->battle_status.mode;
 	ed->elemental.hp = ed->battle_status.hp;
 	ed->elemental.sp = ed->battle_status.sp;
+	ed->elemental.max_hp = ed->battle_status.max_hp;
+	ed->elemental.max_sp = ed->battle_status.max_sp;
+	ed->elemental.atk = ed->battle_status.rhw.atk;
+	ed->elemental.atk2 = ed->battle_status.rhw.atk2;
+	ed->elemental.matk = ed->battle_status.matk_min;
+	ed->elemental.def = ed->battle_status.def;
+	ed->elemental.mdef = ed->battle_status.mdef;
+	ed->elemental.flee = ed->battle_status.flee;
+	ed->elemental.hit = ed->battle_status.hit;
 	ed->elemental.life_time = elemental_get_lifetime(ed);
-	
 	intif_elemental_save(&ed->elemental);
 	return 1;
 }
@@ -192,9 +249,8 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
 		
 		map_addiddb(&ed->bl);
 		status_calc_elemental(ed,1);
-		ed->last_thinktime = gettick();
+		ed->last_spdrain_time = ed->last_thinktime = gettick();
 		ed->summon_timer = INVALID_TIMER;
-		ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
 		elemental_summon_init(ed);
 	} else {
 		memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental));
@@ -202,14 +258,13 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
 	}
 	
 	sd->status.ele_id = ele->elemental_id;
-	ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
 	
 	if( ed->bl.prev == NULL && sd->bl.prev != NULL ) {
 		map_addblock(&ed->bl);
 		clif_spawn(&ed->bl);
 		clif_elemental_info(sd);
 		clif_elemental_updatestatus(sd,SP_HP);
-		clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.matk_max);
+		clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.max_hp);
 		clif_elemental_updatestatus(sd,SP_SP);
 	}
 	
@@ -259,8 +314,6 @@ int elemental_clean_single_effect(struct elemental_data *ed, int skill_num) {
 				break;
 		}
 	}
-	if( skill_get_unit_id(skill_num,0) )
-		skill_clear_unitgroup(&ed->bl);
 	
 	return 1;
 }
@@ -292,9 +345,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
 	status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER);
 	status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER);
 	status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER);
-	
-	skill_clear_unitgroup(&ed->bl);
-	
+		
 	if( (sd = ed->master) == NULL )
 		return 0;
 	
@@ -328,6 +379,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
 }
 
 int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) {
+	struct skill_condition req;
 	short skillnum, skilllv;
 	int i;
 	
@@ -377,6 +429,20 @@ int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned
 		return 1;
 		
 	}
+
+	req = elemental_skill_get_requirements(skillnum, skilllv);
+
+	if(req.hp || req.sp){
+		struct map_session_data *sd = BL_CAST(BL_PC, battle_get_master(&ed->bl));
+		if( sd ){
+			if( sd->skillid_old != SO_EL_ACTION && //regardless of remaining HP/SP it can be cast
+				(status_get_hp(&ed->bl) < req.hp || status_get_sp(&ed->bl) < req.sp) )
+				return 1;
+			else
+				status_zap(&ed->bl, req.hp, req.sp);
+		}
+	}
+
 	//Otherwise, just cast the skill.
 	if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
 		unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
@@ -488,6 +554,24 @@ int elemental_skillnotok(int skillid, struct elemental_data *ed) {
 	return skillnotok(skillid, ed->master);
 }
 
+struct skill_condition elemental_skill_get_requirements(int skill, int lv){
+	struct skill_condition req;
+	int id = skill_get_index(skill);
+
+	memset(&req,0,sizeof(req));
+
+	if( id == 0 ) // invalid skill id
+  		return req;
+
+	if( lv < 1 || lv > MAX_SKILL_LEVEL )
+		return req;
+
+	req.hp = skill_db[id].hp[lv-1];
+	req.sp = skill_db[id].sp[lv-1];
+
+	return req;
+}
+
 int elemental_set_target( struct map_session_data *sd, struct block_list *bl ) {
 	struct elemental_data *ed = sd->ed;
 	
@@ -551,6 +635,30 @@ static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_
 	
 	if( ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL )
 		return 0;
+
+	// Check if caster can sustain the summoned elemental
+	if( DIFF_TICK(tick,ed->last_spdrain_time) >= 10000 ){// Drain SP every 10 seconds
+		int sp = 5;
+
+		switch(ed->vd->class_){
+			case 2115:	case 2118:
+			case 2121:	case 2124:
+				sp = 8;
+				break;
+			case 2116:	case 2119:
+			case 2122:	case 2125:
+				sp = 11;
+				break;
+		}
+
+		if( status_get_sp(&sd->bl) < sp ){ // Can't sustain delete it. 
+			elemental_delete(sd->ed,0);
+			return 0;
+		}
+
+		status_zap(&sd->bl,0,sp);
+		ed->last_spdrain_time = tick;
+	}
 	
 	if( DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME )
 		return 0;
@@ -687,7 +795,7 @@ int read_elementaldb(void) {
 		status->max_sp = atoi(str[5]);
 		status->rhw.range = atoi(str[6]);
 		status->rhw.atk = atoi(str[7]);
-		status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
+		status->rhw.atk2 = atoi(str[8]);
 		status->def = atoi(str[9]);
 		status->mdef = atoi(str[10]);
 		status->str = atoi(str[11]);

+ 3 - 2
src/map/elemental.h

@@ -9,7 +9,7 @@
 
 #define MIN_ELETHINKTIME 100
 #define MIN_ELEDISTANCE 2
-#define MAX_ELEDISTANCE 6
+#define MAX_ELEDISTANCE 5
 
 #define EL_MODE_AGGRESSIVE (MD_CANMOVE|MD_AGGRESSIVE|MD_CANATTACK)
 #define EL_MODE_ASSIST (MD_CANMOVE|MD_ASSIST)
@@ -51,7 +51,7 @@ struct elemental_data {
 	int summon_timer;
 	int skill_timer;
 	
-	unsigned last_thinktime, last_linktime;
+	unsigned last_thinktime, last_linktime, last_spdrain_time;
 	short min_chase;
 	int target_id, attacked_id;
 };
@@ -80,6 +80,7 @@ int elemental_set_target( struct map_session_data *sd, struct block_list *bl );
 int elemental_clean_single_effect(struct elemental_data *ed, int skill_num);
 int elemental_clean_effect(struct elemental_data *ed);
 int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick);
+struct skill_condition elemental_skill_get_requirements(int skill, int lv);
 
 #define elemental_stop_walking(ed, type) unit_stop_walking(&(ed)->bl, type)
 #define elemental_stop_attack(ed) unit_stop_attack(&(ed)->bl)

+ 4 - 0
src/map/pc.c

@@ -6343,10 +6343,14 @@ int pc_resethate(struct map_session_data* sd)
 int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
 {
 	int i, bonus = 0;
+	nullpo_ret(sd);
 
 	ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == skill_num);
 	if( i < ARRAYLENGTH(sd->skillatk) ) bonus = sd->skillatk[i].val;
 
+	if(sd->sc.data[SC_PYROTECHNIC_OPTION] || sd->sc.data[SC_AQUAPLAY_OPTION])
+		bonus += 10;
+
 	return bonus;
 }
 

+ 78 - 29
src/map/skill.c

@@ -1467,6 +1467,34 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		}
 	}
 
+	if( sd && sd->ed && sc && !status_isdead(bl) && !skillid ){
+		struct unit_data *ud = unit_bl2ud(src);
+
+		if( sc->data[SC_WILD_STORM_OPTION] )
+			skill = sc->data[SC_WILD_STORM_OPTION]->val2;
+		else if( sc->data[SC_UPHEAVAL_OPTION] )
+			skill = sc->data[SC_WILD_STORM_OPTION]->val2;
+		else if( sc->data[SC_TROPIC_OPTION] )
+			skill = sc->data[SC_TROPIC_OPTION]->val3;
+		else if( sc->data[SC_CHILLY_AIR_OPTION] )
+			skill = sc->data[SC_CHILLY_AIR_OPTION]->val3;
+		else
+			skill = 0;
+
+		if ( rnd()%100 < 25 && skill ){
+			skill_castend_damage_id(src, bl, skill, 5, tick, 0);
+		
+			if (ud) {
+				rate = skill_delayfix(src, skill, skilllv);
+				if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
+					ud->canact_tick = tick+rate;
+					if ( battle_config.display_status_timers )
+						clif_status_change(src, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
+				}
+			}
+		}
+	}
+
 	// Autospell when attacking
 	if( sd && !status_isdead(bl) && sd->autospell[0].id )
 	{
@@ -2443,8 +2471,6 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 	case EL_ROCK_CRUSHER_ATK:
 	case EL_HURRICANE:
 	case EL_HURRICANE_ATK:
-	case EL_TYPOON_MIS:
-	case EL_TYPOON_MIS_ATK:
 	case KO_BAKURETSU:
 	case GN_CRAZYWEED_ATK:
 		dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,5);
@@ -4518,7 +4544,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 		else {
 			int i = skill_get_splash(skillid,skilllv);
 			clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
-			clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+			clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
 			if( rnd()%100 < 30 )
 				map_foreachinrange(skill_area_sub,bl,i,BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
 			else
@@ -4554,7 +4580,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 	case EL_WIND_SLASH:
 	case EL_STONE_HAMMER:
 		clif_skill_nodamage(src,battle_get_master(src),skillid,skilllv,1);
-		clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+		clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
 		skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,flag);
 		break;
 
@@ -5859,6 +5885,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 
 	case MG_STONECURSE:
 		{
+			int brate = 0;
 			if (tstatus->mode&MD_BOSS) {
 				if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
 				break;
@@ -5866,12 +5893,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			if(status_isimmune(bl) || !tsc)
 				break;
 
+			if (sd && sd->sc.data[SC_PETROLOGY_OPTION])
+				brate = sd->sc.data[SC_PETROLOGY_OPTION]->val3;
+
 			if (tsc->data[SC_STONE]) {
 				status_change_end(bl, SC_STONE, INVALID_TIMER);
 				if (sd) clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
 				break;
 			}
-			if (sc_start4(bl,SC_STONE,(skilllv*4+20),
+			if (sc_start4(bl,SC_STONE,(skilllv*4+20)+brate,
 				skilllv, 0, 0, skill_get_time(skillid, skilllv),
 				skill_get_time2(skillid,skilllv)))
 					clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -8573,10 +8603,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			int elemental_class = skill_get_elemental_type(skillid,skilllv);
 
 			// Remove previous elemental fisrt.
-			if( sd->ed && elemental_delete(sd->ed,0) ) {
-				clif_skill_fail(sd,skillid,0,0);
-				break;
-			}
+			if( sd->ed )
+				elemental_delete(sd->ed,0);
+
 			// Summoning the new one.
 			if( !elemental_create(sd,elemental_class,skill_get_time(skillid,skilllv)) ) {
 				clif_skill_fail(sd,skillid,0,0);
@@ -8589,22 +8618,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case SO_EL_CONTROL:
 		if( sd ) {
 			int mode = EL_MODE_PASSIVE;	// Standard mode.
-			if( !sd->ed ) {
-				clif_skill_fail(sd,skillid,0,0);
-				break;
-			}
+
+			if( !sd->ed )	break;
+
 			if( skilllv == 4 ) {// At level 4 delete elementals.
-				if( elemental_delete(sd->ed, 0) )
-					clif_skill_fail(sd,skillid,0,0);
+				elemental_delete(sd->ed, 0);
 				break;
 			}
 			switch( skilllv ) {// Select mode bassed on skill level used.
-				case 1: mode = EL_MODE_PASSIVE; break;
 				case 2: mode = EL_MODE_ASSIST; break;
 				case 3: mode = EL_MODE_AGGRESSIVE; break;
 			}
 			if( !elemental_change_mode(sd->ed,mode) ) {
-				clif_skill_fail(sd,skillid,0,0);
+				clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
 				break;
 			}
 			clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -8614,8 +8640,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case SO_EL_ACTION:
 		if( sd ) {
 				int duration = 3000;
-			if( !sd->ed )
-				break;
+			if( !sd->ed )	break;
+			sd->skillid_old = skillid;
 			elemental_action(sd->ed, bl, tick);
 			clif_skill_nodamage(src,bl,skillid,skilllv,1);
 				switch(sd->ed->db->class_){
@@ -8637,12 +8663,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			struct elemental_data *ed = sd->ed;
 			int s_hp = sd->battle_status.hp * 10 / 100, s_sp = sd->battle_status.sp * 10 / 100;
 			int e_hp, e_sp;
-			if( !ed ) {
-				clif_skill_fail(sd,skillid,0,0);
-				break;
-			}
+
+			if( !ed )	break;
 			if( !status_charge(&sd->bl,s_hp,s_sp) ) {
-				clif_skill_fail(sd,skillid,0,0);
+				clif_skill_fail(sd,skillid,USESKILL_FAIL_LEVEL,0);
 				break;
 			}
 			e_hp = ed->battle_status.max_hp * 10 / 100;
@@ -8761,10 +8785,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
 					elemental_clean_single_effect(ele, skillid);
 				} else {
-					clif_skill_nodamage(src,bl,skillid,skilllv,1);
-					clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
-					if( skillid == EL_WIND_STEP )	// There aren't telemport, just push to the master.
-						skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),(map_calc_dir(src,bl->x,bl->y)+4)%8,0);
+					clif_skill_nodamage(src,src,skillid,skilllv,1);
+					clif_skill_damage(src, ( skillid == EL_GUST || skillid == EL_BLAST || skillid == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+					if( skillid == EL_WIND_STEP )	// There aren't teleport, just push the master away.
+						skill_blown(src,bl,(rnd()%skill_get_blewcount(skillid,skilllv))+1,rand()%8,0);
 					sc_start(src,type2,100,skilllv,skill_get_time(skillid,skilllv));
 					sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
 				}
@@ -8777,7 +8801,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case EL_ZEPHYR:
 	case EL_POWER_OF_GAIA:
 		clif_skill_nodamage(src,src,skillid,skilllv,1);
-		clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+		clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
 		skill_unitsetting(src,skillid,skilllv,bl->x,bl->y,0);
 		break;
 
@@ -13512,6 +13536,25 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
 				if( i < 3 )
 					continue;
 				break;
+			case SA_SEISMICWEAPON:
+				if( sc->data[SC_UPHEAVAL_OPTION] && rnd()%100 < 50 )
+					continue;
+				break;
+			case SA_FLAMELAUNCHER:
+			case SA_VOLCANO:
+				if( sc->data[SC_TROPIC_OPTION] && rnd()%100 < 50 )
+					continue;
+				break;
+			case SA_FROSTWEAPON:
+			case SA_DELUGE:
+				if( sc->data[SC_CHILLY_AIR_OPTION] && rnd()%100 < 50 )
+					continue;
+				break;
+			case SA_LIGHTNINGLOADER:
+			case SA_VIOLENTGALE:
+				if( sc && sc->data[SC_WILD_STORM_OPTION] && rnd()%100 < 50 )
+					continue;
+				break;
 		}
 
 		req.itemid[i] = skill_db[j].itemid[i];
@@ -13632,6 +13675,10 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
 		case SO_SUMMON_TERA:
 			req.sp -= req.sp * (5 + 5 * pc_checkskill(sd,SO_EL_SYMPATHY)) / 100;
 			break;
+		case SO_PSYCHIC_WAVE:
+			if( sc && sc->data[SC_BLAST_OPTION] )
+				req.sp += req.sp * 150 / 100;
+			break;
 	}
 
 	return req;
@@ -13791,6 +13838,8 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill
 			fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
 		if (sc->data[SC_IZAYOI]  && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN))
 			fixed = 0;
+		if( sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION] )
+			fixed -= 1000;
 	}
 
 	if( sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){

+ 180 - 178
src/map/status.c

@@ -723,10 +723,10 @@ void initChangeTables(void) {
 	set_sc( EL_AQUAPLAY        , SC_AQUAPLAY_OPTION      , SI_AQUAPLAY_OPTION      , SCB_MATK );
 	set_sc( EL_COOLER          , SC_COOLER_OPTION        , SI_COOLER_OPTION        , SCB_MATK );
 	set_sc( EL_CHILLY_AIR      , SC_CHILLY_AIR_OPTION    , SI_CHILLY_AIR_OPTION    , SCB_MATK );
-	set_sc( EL_GUST            , SC_GUST_OPTION          , SI_GUST_OPTION          , SCB_NONE );
-	set_sc( EL_BLAST           , SC_BLAST_OPTION         , SI_BLAST_OPTION         , SCB_NONE );
-	set_sc( EL_WILD_STORM      , SC_WILD_STORM_OPTION    , SI_WILD_STORM_OPTION    , SCB_NONE );
-	set_sc( EL_PETROLOGY       , SC_PETROLOGY_OPTION     , SI_PETROLOGY_OPTION     , SCB_NONE );
+	set_sc( EL_GUST            , SC_GUST_OPTION          , SI_GUST_OPTION          , SCB_ASPD );
+	set_sc( EL_BLAST           , SC_BLAST_OPTION         , SI_BLAST_OPTION         , SCB_ASPD );
+	set_sc( EL_WILD_STORM      , SC_WILD_STORM_OPTION    , SI_WILD_STORM_OPTION    , SCB_ASPD );
+	set_sc( EL_PETROLOGY       , SC_PETROLOGY_OPTION     , SI_PETROLOGY_OPTION     , SCB_MAXHP );
 	set_sc( EL_CURSED_SOIL     , SC_CURSED_SOIL_OPTION   , SI_CURSED_SOIL_OPTION   , SCB_NONE );
 	set_sc( EL_UPHEAVAL        , SC_UPHEAVAL_OPTION      , SI_UPHEAVAL_OPTION      , SCB_NONE );
 	set_sc( EL_TIDAL_WEAPON    , SC_TIDAL_WEAPON_OPTION  , SI_TIDAL_WEAPON_OPTION  , SCB_ALL );
@@ -3196,31 +3196,31 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) {
 	if( !sd )
 		return 0;
 
-	status->str = ele->str;
-	status->agi = ele->agi;
-	status->vit = ele->vit;
-	status->dex = ele->dex;
-	status->int_ = ele->int_;
-	status->luk = ele->luk;
-
 	if( first ) {
 		memcpy(status, &ed->db->status, sizeof(struct status_data));
-		status->mode = MD_CANMOVE|MD_CANATTACK;
-		status->max_hp += 4000 + 500 * pc_checkskill(sd,SO_EL_SYMPATHY);
-		status->max_sp += 300 + 50 * pc_checkskill(sd,SO_EL_SYMPATHY);
-		status->hp = status->max_hp;
-		status->sp = status->max_sp;
-		status->str += sd->base_status.str * 25 / 100;
-		status->agi += sd->base_status.agi * 25 / 100;
-		status->vit += sd->base_status.vit * 25 / 100;
-		status->int_ += sd->base_status.int_ * 25 / 100;
-		status->def += sd->base_status.dex * 25 / 100;
-		status->luk += sd->base_status.luk * 25 / 100;
-
-		status_calc_misc(&ed->bl, status, ed->db->lv);
+		if( !ele->mode )
+			status->mode = EL_MODE_PASSIVE;
+		else
+			status->mode = ele->mode;
+
+		status_calc_misc(&ed->bl, status, 0);
+
+		status->max_hp = ele->max_hp;
+		status->max_sp = ele->max_sp;
+		status->hp = ele->hp;
+		status->sp = ele->sp;
+		status->rhw.atk = ele->atk;
+		status->rhw.atk2 = ele->atk2;
+
+		status->matk_min += ele->matk;
+		status->def += ele->def;
+		status->mdef += ele->mdef;
+		status->flee = ele->flee;
+		status->hit = ele->hit;
+		
 		memcpy(&ed->battle_status,status,sizeof(struct status_data));
 	} else {
-		status_calc_misc(&ed->bl, status, ed->db->lv);
+		status_calc_misc(&ed->bl, status, 0);
 		status_cpy(&ed->battle_status, status);
 	}
 
@@ -3827,9 +3827,6 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
 			if(status->aspd_rate != 1000) // absolute percentage modifier
 				amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
 #endif
-			//@TODO move FIGHTINGSPIRIT in fix_aspd
-			if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
-				amotion -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) / 10 * 40;
 			amotion = status_calc_fix_aspd(bl, sc, amotion);
 			status->amotion = cap_value(amotion,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
 
@@ -4202,8 +4199,6 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
 		vit += sc->data[SC_GLORYWOUNDS]->val1;
 	if(sc->data[SC_TRUESIGHT])
 		vit += 5;
-	if(sc->data[SC_STRIPARMOR])
-		vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
 	if(sc->data[SC_MARIONETTE])
 		vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
 	if(sc->data[SC_MARIONETTE2])
@@ -4219,6 +4214,9 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
 	if(sc->data[SC_KYOUGAKU])
 		vit -= sc->data[SC_KYOUGAKU]->val2;
 
+	if(sc->data[SC_STRIPARMOR])
+		vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
+
 	return (unsigned short)cap_value(vit,0,USHRT_MAX);
 }
 
@@ -4253,8 +4251,6 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
 		else
 			int_ >>= 1;
 	}
-	if(sc->data[SC_STRIPHELM])
-		int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
 	if(sc->data[SC_NEN])
 		int_ += sc->data[SC_NEN]->val1;
 	if(sc->data[SC_MARIONETTE])
@@ -4263,8 +4259,6 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
 		int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
 	if(sc->data[SC_MANDRAGORA])
 		int_ -= 5 + 5 * sc->data[SC_MANDRAGORA]->val1;
-	if(sc->data[SC__STRIPACCESSORY])
-		int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
 	if(sc->data[SC_COCKTAIL_WARG_BLOOD])
 		int_ += sc->data[SC_COCKTAIL_WARG_BLOOD]->val1;
 	if(sc->data[SC_INSPIRATION])
@@ -4273,6 +4267,11 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
 		int_ -= sc->data[SC_STOMACHACHE]->val1;
 	if(sc->data[SC_KYOUGAKU])
 		int_ -= sc->data[SC_KYOUGAKU]->val2;
+	
+	if(sc->data[SC_STRIPHELM])
+		int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
+	if(sc->data[SC__STRIPACCESSORY])
+		int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
 
 	return (unsigned short)cap_value(int_,0,USHRT_MAX);
 }
@@ -4318,8 +4317,6 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
 		dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
 	if(sc->data[SC_MARIONETTE2])
 		dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
-	if(sc->data[SC__STRIPACCESSORY])
-		dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
 	if(sc->data[SC_SIROMA_ICE_TEA])
 		dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
 	if(sc->data[SC_INSPIRATION])
@@ -4329,6 +4326,9 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
 	if(sc->data[SC_KYOUGAKU])
 		dex -= sc->data[SC_KYOUGAKU]->val2;
 
+	if(sc->data[SC__STRIPACCESSORY])
+		dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+
 	return (unsigned short)cap_value(dex,0,USHRT_MAX);
 }
 
@@ -4361,20 +4361,21 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
 		luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
 	if(sc->data[SC_MARIONETTE2])
 		luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
-	if(sc->data[SC_LAUDARAMUS])
-		luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
-	if(sc->data[SC__STRIPACCESSORY])
-		luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
 	if(sc->data[SC_PUTTI_TAILS_NOODLES])
 		luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
 	if(sc->data[SC_INSPIRATION])
 		luk += sc->data[SC_INSPIRATION]->val3;
 	if(sc->data[SC_STOMACHACHE])
 		luk -= sc->data[SC_STOMACHACHE]->val1;
-	if(sc->data[SC_BANANA_BOMB])
-		luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
 	if(sc->data[SC_KYOUGAKU])
 		luk -= sc->data[SC_KYOUGAKU]->val2;
+	if(sc->data[SC_LAUDARAMUS])
+		luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
+
+	if(sc->data[SC__STRIPACCESSORY])
+		luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+	if(sc->data[SC_BANANA_BOMB])
+		luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
 
 	return (unsigned short)cap_value(luk,0,USHRT_MAX);
 }
@@ -4388,6 +4389,32 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 		batk += sc->data[SC_ATKPOTION]->val1;
 	if(sc->data[SC_BATKFOOD])
 		batk += sc->data[SC_BATKFOOD]->val1;
+	if(sc->data[SC_GATLINGFEVER])
+		batk += sc->data[SC_GATLINGFEVER]->val3;
+	if(sc->data[SC_MADNESSCANCEL])
+		batk += 100;
+	if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
+		batk += 50;
+	if(bl->type == BL_ELEM
+	   && ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
+		   || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
+		   || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
+		   || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
+	   )
+		batk += batk / 5;
+	if(sc->data[SC_FULL_SWING_K])
+		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_PYROCLASTIC])
+		batk += sc->data[SC_PYROCLASTIC]->val2;
+	if (sc->data[SC_ANGRIFFS_MODUS])
+		batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
+
 	if(sc->data[SC_INCATKRATE])
 		batk += batk * sc->data[SC_INCATKRATE]->val1/100;
 	if(sc->data[SC_PROVOKE])
@@ -4407,10 +4434,6 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 //		batk -= batk * 25/100;
 	if(sc->data[SC_FLEET])
 		batk += batk * sc->data[SC_FLEET]->val3/100;
-	if(sc->data[SC_GATLINGFEVER])
-		batk += sc->data[SC_GATLINGFEVER]->val3;
-	if(sc->data[SC_MADNESSCANCEL])
-		batk += 100;
 	if(sc->data[SC__ENERVATION])
 		batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
 	if(sc->data[SC_RUSHWINDMILL])
@@ -4421,29 +4444,8 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 		batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100;
 	if(sc->data[SC_BEYONDOFWARCRY])
 		batk += batk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
-	if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
-		batk += 50;
-	if(bl->type == BL_ELEM
-	   && ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
-		   || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
-		   || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
-		   || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
-	   )
-		batk += batk / 5;
-	if(sc->data[SC_FULL_SWING_K])
-		batk += sc->data[SC_FULL_SWING_K]->val1;
-	if(sc->data[SC_ODINS_POWER])
-		batk += 70;
 	if( sc->data[SC_ZANGETSU] )
 		batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
-	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
-		if(status_get_element(bl) == ELE_WATER) //water type
-			batk /= 2;
-	}
-	if(sc->data[SC_PYROCLASTIC])
-		batk += sc->data[SC_PYROCLASTIC]->val2;
-	if (sc->data[SC_ANGRIFFS_MODUS])
-		batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
 
 	return (unsigned short)cap_value(batk,0,USHRT_MAX);
 }
@@ -4461,14 +4463,26 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
 		watk += sc->data[SC_DRUMBATTLE]->val2;
 	if(sc->data[SC_VOLCANO])
 		watk += sc->data[SC_VOLCANO]->val2;
-	if(sc->data[SC_INCATKRATE])
-		watk += watk * sc->data[SC_INCATKRATE]->val1/100;
-	if(sc->data[SC_PROVOKE])
-		watk += watk * sc->data[SC_PROVOKE]->val3/100;
-	if(sc->data[SC_CONCENTRATION])
-		watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
-	if(sc->data[SC_SKE])
-		watk += watk * 3;
+	if(sc->data[SC_MERC_ATKUP])
+		watk += sc->data[SC_MERC_ATKUP]->val2;
+	if(sc->data[SC_FIGHTINGSPIRIT])
+		watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
+	if(sc->data[SC_STRIKING])
+		watk += sc->data[SC_STRIKING]->val2;
+	if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
+		watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
+	if(sc->data[SC_INSPIRATION])
+		watk += sc->data[SC_INSPIRATION]->val2;
+	if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
+		watk += (10 + 10 * sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
+	if( sc->data[SC_TROPIC_OPTION] )
+		watk += sc->data[SC_TROPIC_OPTION]->val2;
+	if( sc->data[SC_HEATER_OPTION] )
+		watk += sc->data[SC_HEATER_OPTION]->val2;
+	if( sc->data[SC_WATER_BARRIER] )
+		watk -= sc->data[SC_WATER_BARRIER]->val3;
+	if( sc->data[SC_PYROTECHNIC_OPTION] )
+		watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
 	if(sc->data[SC_NIBELUNGEN]) {
 		if (bl->type != BL_PC)
 			watk += sc->data[SC_NIBELUNGEN]->val2;
@@ -4481,6 +4495,15 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
 				watk += sc->data[SC_NIBELUNGEN]->val2;
 		}
 	}
+
+	if(sc->data[SC_INCATKRATE])
+		watk += watk * sc->data[SC_INCATKRATE]->val1/100;
+	if(sc->data[SC_PROVOKE])
+		watk += watk * sc->data[SC_PROVOKE]->val3/100;
+	if(sc->data[SC_CONCENTRATION])
+		watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
+	if(sc->data[SC_SKE])
+		watk += watk * 3;
 	if(sc->data[SC__ENERVATION])
 		watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
 	if(sc->data[SC_FLEET])
@@ -4489,28 +4512,8 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
 		watk -= watk * 25/100;
 	if(sc->data[SC_STRIPWEAPON])
 		watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
-	if(sc->data[SC_MERC_ATKUP])
-		watk += sc->data[SC_MERC_ATKUP]->val2;
-	if(sc->data[SC_FIGHTINGSPIRIT])
-		watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
 	if(sc->data[SC__ENERVATION])
 		watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
-	if(sc->data[SC_STRIKING])
-		watk += sc->data[SC_STRIKING]->val2;
-	if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
-		watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
-	if(sc->data[SC_INSPIRATION])
-		watk += sc->data[SC_INSPIRATION]->val2;
-	if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
-		watk += (10 + 10 * sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
-	if( sc->data[SC_TROPIC_OPTION] )
-		watk += sc->data[SC_TROPIC_OPTION]->val2;
-	if( sc->data[SC_HEATER_OPTION] )
-		watk += sc->data[SC_HEATER_OPTION]->val2;
-	if( sc->data[SC_WATER_BARRIER] )
-		watk -= sc->data[SC_WATER_BARRIER]->val3;
-	if( sc->data[SC_PYROTECHNIC_OPTION] )
-		watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
 	if((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
 	   || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
 	   || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
@@ -4615,15 +4618,16 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
 		critical += critical;
 	if(sc->data[SC_STRIKING])
 		critical += sc->data[SC_STRIKING]->val1;
-	if(sc->data[SC__INVISIBILITY])
-		critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
-	if(sc->data[SC__UNLUCKY])
-		critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
 #ifdef RENEWAL
 	if (sc->data[SC_SPEARQUICKEN])
 		critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10;
 #endif
 
+	if(sc->data[SC__INVISIBILITY])
+		critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
+	if(sc->data[SC__UNLUCKY])
+		critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
+
 	return (short)cap_value(critical,10,SHRT_MAX);
 }
 
@@ -4643,22 +4647,23 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
 		hit += sc->data[SC_HUMMING]->val2;
 	if(sc->data[SC_CONCENTRATION])
 		hit += sc->data[SC_CONCENTRATION]->val3;
-	if(sc->data[SC_INCHITRATE])
-		hit += hit * sc->data[SC_INCHITRATE]->val1/100;
-	if(sc->data[SC_BLIND])
-		hit -= hit * 25/100;
+	if(sc->data[SC_INSPIRATION])
+		hit += 5 * sc->data[SC_INSPIRATION]->val1;
 	if(sc->data[SC_ADJUSTMENT])
 		hit -= 30;
 	if(sc->data[SC_INCREASING])
 		hit += 20; // RockmanEXE; changed based on updated [Reddozen]
 	if(sc->data[SC_MERC_HITUP])
 		hit += sc->data[SC_MERC_HITUP]->val2;
+
+	if(sc->data[SC_INCHITRATE])
+		hit += hit * sc->data[SC_INCHITRATE]->val1/100;
+	if(sc->data[SC_BLIND])
+		hit -= hit * 25/100;
 	if(sc->data[SC__GROOMY])
 		hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
 	if(sc->data[SC_FEAR])
 		hit -= hit * 20 / 100;
-	if(sc->data[SC_INSPIRATION])
-		hit += 5 * sc->data[SC_INSPIRATION]->val1;
 	if (sc->data[SC_ASH])
 		hit /= 2;
 
@@ -4686,30 +4691,45 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
 		flee += sc->data[SC_WHISTLE]->val2;
 	if(sc->data[SC_WINDWALK])
 		flee += sc->data[SC_WINDWALK]->val2;
-	if(sc->data[SC_INCFLEERATE])
-		flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
 	if(sc->data[SC_VIOLENTGALE])
 		flee += sc->data[SC_VIOLENTGALE]->val2;
 	if(sc->data[SC_MOON_COMFORT]) //SG skill [Komurka]
 		flee += sc->data[SC_MOON_COMFORT]->val2;
 	if(sc->data[SC_CLOSECONFINE])
 		flee += 10;
-	if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
-		flee -= flee * 50/100;
-	if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
-		flee -= flee * 50/100;
-	if(sc->data[SC_BLIND])
-		flee -= flee * 25/100;
+	if (sc->data[SC_ANGRIFFS_MODUS])
+		flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
+	if (sc->data[SC_OVERED_BOOST])
+		flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
 	if(sc->data[SC_ADJUSTMENT])
 		flee += 30;
-	if(sc->data[SC_GATLINGFEVER])
-		flee -= sc->data[SC_GATLINGFEVER]->val4;
 	if(sc->data[SC_SPEED])
 		flee += 10 + sc->data[SC_SPEED]->val1 * 10;
+	if(sc->data[SC_GATLINGFEVER])
+		flee -= sc->data[SC_GATLINGFEVER]->val4;
 	if(sc->data[SC_PARTYFLEE])
 		flee += sc->data[SC_PARTYFLEE]->val1 * 10;
 	if(sc->data[SC_MERC_FLEEUP])
 		flee += sc->data[SC_MERC_FLEEUP]->val2;
+	if( sc->data[SC_HALLUCINATIONWALK] )
+		flee += sc->data[SC_HALLUCINATIONWALK]->val2;
+	if( sc->data[SC_WATER_BARRIER] )
+		flee -= sc->data[SC_WATER_BARRIER]->val3;
+	if( sc->data[SC_MARSHOFABYSS] )
+		flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
+#ifdef RENEWAL
+	if( sc->data[SC_SPEARQUICKEN] )
+		flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
+#endif
+	
+	if(sc->data[SC_INCFLEERATE])
+		flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
+	if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
+		flee -= flee * 50/100;
+	if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
+		flee -= flee * 50/100;
+	if(sc->data[SC_BLIND])
+		flee -= flee * 25/100;
 	if(sc->data[SC_FEAR])
 		flee -= flee * 20 / 100;
 	if(sc->data[SC_PARALYSE])
@@ -4720,26 +4740,12 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
 		flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
 	if( sc->data[SC_GLOOMYDAY] )
 		flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
-	if( sc->data[SC_HALLUCINATIONWALK] )
-		flee += sc->data[SC_HALLUCINATIONWALK]->val2;
 	if( sc->data[SC_SATURDAYNIGHTFEVER] )
 		flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
-	if( sc->data[SC_WATER_BARRIER] )
-		flee -= sc->data[SC_WATER_BARRIER]->val3;
 	if( sc->data[SC_WIND_STEP_OPTION] )
 		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_MARSHOFABYSS] )
-		flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
-#ifdef RENEWAL
-	if( sc->data[SC_SPEARQUICKEN] )
-		flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
-#endif
-	if (sc->data[SC_ANGRIFFS_MODUS])
-		flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
-	if (sc->data[SC_OVERED_BOOST])
-		flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
 	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){ //mob
 		if(status_get_element(bl) == ELE_WATER) //water type
 			flee /= 2;
@@ -4788,6 +4794,14 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
 		def += sc->data[SC_DEFENCE]->val2 ;
 	if(sc->data[SC_INCDEFRATE])
 		def += def * sc->data[SC_INCDEFRATE]->val1/100;
+	if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
+		def += 50;
+	if(sc->data[SC_ODINS_POWER])
+		def -= 20;
+	if( sc->data[SC_ANGRIFFS_MODUS] )
+		def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
+	if(sc->data[SC_STONEHARDSKIN])// Final DEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
+		def += sc->data[SC_STONEHARDSKIN]->val1;
 	if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
 		def >>=1;
 	if(sc->data[SC_FREEZE])
@@ -4808,8 +4822,6 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
 		def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
 	if (sc->data[SC_FLING])
 		def -= def * (sc->data[SC_FLING]->val2)/100;
-	if(sc->data[SC_STONEHARDSKIN])// Final DEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
-		def += sc->data[SC_STONEHARDSKIN]->val1;
 	if( sc->data[SC_FREEZING] )
 		def -= def * 10 / 100;
 	if( sc->data[SC_MARSHOFABYSS] )
@@ -4828,12 +4840,6 @@ 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_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
-		def += 50;
-	if(sc->data[SC_ODINS_POWER])
-		def -= 20;
-	if( sc->data[SC_ANGRIFFS_MODUS] )
-		def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
 	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
 		if(status_get_race(bl)==RC_PLANT)
 			def /= 2;
@@ -4857,6 +4863,10 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
 		return 0;
 	if(sc->data[SC_SUN_COMFORT])
 		def2 += sc->data[SC_SUN_COMFORT]->val2;
+	if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
+		def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
+	if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
+		def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
 
 	if(sc->data[SC_ANGELUS])
 #ifdef RENEWAL //in renewal only the VIT stat bonus is boosted by angelus
@@ -4889,10 +4899,6 @@ 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_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
-		def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
-	if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
-		def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
 	if( sc->data[SC_GT_REVITALIZE] && sc->data[SC_GT_REVITALIZE]->val4)
 		def2 += def2 * sc->data[SC_GT_REVITALIZE]->val4 / 100;
 	if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
@@ -4927,20 +4933,26 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
 
 	if(sc->data[SC_ARMORCHANGE])
 		mdef += sc->data[SC_ARMORCHANGE]->val3;
-	if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
-		mdef += 25*mdef/100;
-	if(sc->data[SC_FREEZE])
-		mdef += 25*mdef/100;
+	if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
+		mdef += 50;
 	if(sc->data[SC_ENDURE])// It has been confirmed that eddga card grants 1 MDEF, not 0, not 10, but 1.
 		mdef += (sc->data[SC_ENDURE]->val4 == 0) ? sc->data[SC_ENDURE]->val1 : 1;
 	if(sc->data[SC_CONCENTRATION])
 		mdef += 1; //Skill info says it adds a fixed 1 Mdef point.
+	if(sc->data[SC_STONEHARDSKIN])// Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
+		mdef += sc->data[SC_STONEHARDSKIN]->val1;
+	if(sc->data[SC_WATER_BARRIER])
+		mdef += sc->data[SC_WATER_BARRIER]->val2;
+
 #ifdef RENEWAL
 		if(sc->data[SC_ASSUMPTIO])
 		mdef *= 2;
 #endif
-	if(sc->data[SC_STONEHARDSKIN])// Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
-		mdef += sc->data[SC_STONEHARDSKIN]->val1;
+
+	if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+		mdef += 25*mdef/100;
+	if(sc->data[SC_FREEZE])
+		mdef += 25*mdef/100;
 	if( sc->data[SC_MARSHOFABYSS] )
 		mdef -= mdef * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
 	if(sc->data[SC_ANALYZE])
@@ -4949,12 +4961,8 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
 		mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val2 / 100;
 	if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val4)
 		mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100;
-	if(sc->data[SC_WATER_BARRIER])
-		mdef += sc->data[SC_WATER_BARRIER]->val2;
 	if (sc->data[SC_ODINS_POWER])
 		mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
-	if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
-		mdef += 50;
 
 	return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
 }
@@ -5295,20 +5303,16 @@ static short status_calc_fix_aspd(struct block_list *bl, struct status_change *s
         return cap_value(aspd, 0, 2000);
 
     if (!sc->data[SC_QUAGMIRE]) {
-        if (sc->data[SC_FIGHTINGSPIRIT])
-            aspd += sc->data[SC_FIGHTINGSPIRIT]->val3;
-        if ((sc->data[SC_GUST_OPTION]
-                || sc->data[SC_BLAST_OPTION]
-                || sc->data[SC_WILD_STORM_OPTION])
-                )
-            aspd -= 50; // ventus passive = +5 ASPD
-        if (sc->data[SC_OVERED_BOOST]){
-	    aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
-        }
-//	if(sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
-//	    aspd -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) * 4;
+        if (sc->data[SC_OVERED_BOOST])
+			aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10;
     }
 
+	if ((sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION]
+		|| sc->data[SC_WILD_STORM_OPTION]))
+		aspd -= 50; // +5 ASPD
+	if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
+		aspd -= (bl->type==BL_PC?pc_checkskill((TBL_PC *)bl, RK_RUNEMASTERY):10) / 10 * 40;
+
     return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway
 }
 
@@ -5485,6 +5489,12 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
 		maxhp += maxhp * 2;
 	if(sc->data[SC_MARIONETTE])
 		maxhp -= 1000;
+	if(sc->data[SC_SOLID_SKIN_OPTION])
+		maxhp += 2000;// Fix amount.
+	if(sc->data[SC_POWER_OF_GAIA])
+		maxhp += 3000;
+	if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
+		maxhp += 500;
 
 	if(sc->data[SC_MERC_HPUP])
 		maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
@@ -5509,18 +5519,14 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
 		maxhp += maxhp * (2 * sc->data[SC_GT_REVITALIZE]->val1) / 100;
 	if(sc->data[SC_MUSTLE_M])
 		maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100;
-	if(sc->data[SC_SOLID_SKIN_OPTION])
-		maxhp += 2000;// Fix amount.
-	if(sc->data[SC_POWER_OF_GAIA])
-		maxhp += 3000;
 	if(sc->data[SC_MYSTERIOUS_POWDER])
 		maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
-	if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
-		maxhp += 500;
+	if(sc->data[SC_PETROLOGY_OPTION])
+		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;
+		maxhp += maxhp * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
 
 	return cap_value(maxhp,1,UINT_MAX);
 }
@@ -8328,8 +8334,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			}
 			break;
 		case SC_PYROTECHNIC_OPTION:
-			val2 = 60;	// Watk TODO: Renewal (Atk2)
-			val3 = 11;	// % Increase damage.
 			val_flag |= 1|2|4;
 			break;
 		case SC_HEATER_OPTION:
@@ -8343,8 +8347,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			val3 = MG_FIREBOLT;
 			break;
 		case SC_AQUAPLAY_OPTION:
-			val2 = 40; // Matk. TODO: Renewal (Matk1)
-			val3 = 33;	// % Increase effects.
+			val2 = 40; 
 			val_flag |= 1|2|4;
 			break;
 		case SC_COOLER_OPTION:
@@ -8359,15 +8362,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			val_flag |= 1|2;
 			break;
 		case SC_GUST_OPTION:
-			val2 = 33;
 			val_flag |= 1|2;
 			break;
 		case SC_WIND_STEP_OPTION:
 			val2 = 50;	// % Increase speed and flee.
 			break;
 		case SC_BLAST_OPTION:
-			val2 = 33;
-			val3 = 4;
+			val2 = 20;
+			val3 = ELE_WIND;
 			val_flag |= 1|2|4;
 			break;
 		case SC_WILD_STORM_OPTION:
@@ -8376,7 +8378,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			break;
 		case SC_PETROLOGY_OPTION:
 			val2 = 5;
-			val3 = 33;
+			val3 = 50;
 			val_flag |= 1|2|4;
 			break;
 		case SC_CURSED_SOIL_OPTION:

+ 3 - 3
src/map/status.h

@@ -1554,11 +1554,11 @@ enum scb_flag
 };
 
 //Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex]
-#define BL_CONSUME (BL_PC|BL_HOM|BL_MER)
+#define BL_CONSUME (BL_PC|BL_HOM|BL_MER|BL_ELEM)
 //Define to determine who has regen
-#define BL_REGEN (BL_PC|BL_HOM|BL_MER)
+#define BL_REGEN (BL_PC|BL_HOM|BL_MER|BL_ELEM)
 //Define to determine who will receive a clif_status_change packet for effects that require one to display correctly
-#define BL_SCEFFECT (BL_PC|BL_HOM|BL_MER|BL_MOB)
+#define BL_SCEFFECT (BL_PC|BL_HOM|BL_MER|BL_MOB|BL_ELEM)
 
 //Basic damage info of a weapon
 //Required because players have two of these, one in status_data

+ 17 - 0
src/map/unit.c

@@ -1250,6 +1250,23 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
 		if (sc && sc->data[SC_WUGDASH])
 			casttime = -1;
         break;
+	case EL_WIND_SLASH:
+	case EL_HURRICANE:
+	case EL_TYPOON_MIS:
+	case EL_STONE_HAMMER:
+	case EL_ROCK_CRUSHER:
+	case EL_STONE_RAIN:
+	case EL_ICE_NEEDLE:
+	case EL_WATER_SCREW:
+	case EL_TIDAL_WEAPON:
+		if( src->type == BL_ELEM ){
+			sd = BL_CAST(BL_PC, battle_get_master(src));
+			if( sd && sd->skillid_old == SO_EL_ACTION ){
+				casttime = -1;
+				sd->skillid_old = 0;
+			}
+		}
+		break;
 	}
 
 	// moved here to prevent Suffragium from ending if skill fails